F-Zero X
Nintendo EAD's 1998 futuristic racer for the Nintendo 64, read through inspectredc's decompilation.
On this page
The atlas reads F-Zero X through inspectredc’s decompilation, work-in-progress C that builds the US and Japanese ROMs. Many of its functions and fields are named and many still carry addresses; the claims quote both as the decompilers’ and read the US build. Nothing has been measured in the game yet.
A machine’s energy is its health and its boost fuel. The meter holds 190 to 1421 by body grade, and in Death Race every machine but player 1’s starts with half1. Walls take 0.7 times the speed into them and a landmine 12.5; a hit that takes the meter below zero spins the machine out, though a machine out of the camera’s view is held at 0.1 instead2. A boost costs 0.15 of the meter3 over 100 updates3, and it unlocks only once a machine has finished its first lap, except in Practice and Death Race4. The pits give back 0.008 per update5 of the maximum, so an empty meter refills in about two seconds5. A player who touched a rival within 60 updates before it spins out gets an eighth of the meter back, which the atlas reads as a knock-out bonus from the counter’s name (gRacersKOd)6.
Machines also damage each other. Two machines that touch share the impact by strength, which comes from body grade and weight, and a machine that’s attacking when the other isn’t deals the whole impact, ten times it for player 1 in a one-player race; when both attack, each takes its share7. A dash plate keeps the boost timer full while the machine is on it and costs nothing8.
The machine-settings slider is a single number from 0 to 19. A curve maps it before the race, so the middle position becomes about 0.37, and nine of the machine’s values are blended between two ends by that number. Each end is a blend, by the machine’s weight, of numbers read from the cartridge’s own bytes, so the decompilation can’t say how far the slider moves them9. One draw routine also reads the cartridge, and if the lowest bit of the word it reads is set, from its 13th call it cuts every machine’s maximum energy to 110.
Mechanics
| Mechanic | Kind | How |
|---|---|---|
| Energy meter | Pays for boost | one meter of 142 to 190 by body grade takes the damage, pays 0.15 of itself for each boost from the second lap, and refills on the pits |
| Boost pad | Refresh | a dash plate sets the boost timer to 100 on each update the machine is on it, at no energy cost |
| Setup slider | Continuous | one engine setting from 0 to 1, curved so its middle reads 0.37, blends nine machine values between two ends |
Every claim about this game, by concept (10)
References
- ^ abIn F-Zero X's US build,
Racer_InitRacersets a machine'senergyandmaxEnergyfromgBodyHealthValuesby its body grade (BODY_STAT): 190 for grade A, 178 for B, 166 for C, 154 for D, and 142 for E, so a racer starts each race with a full meter. In Death Race (GAMEMODE_DEATH_RACE),Racer_Initthen halves both values for every racer aftergRacers[0], which holds player 1's machine, so the other machines run on half a meter (71 to 95).Codeinspectredc/fzeroxHow we know
440f32 gBodyHealthValues[] = { 441 190.0f, 178.0f, 166.0f, 154.0f, 142.0f,
src/game/racer.c lines 440–442 at 4b00f36 · upstream ↗ 58typedef enum BodyStat { 59 /* 0 */ BODY_A, ⋮ 63 /* 4 */ BODY_E, 64} BodyStat;
include/fzx_racer.h lines 58–64 at 4b00f36 · upstream ↗ 1660 racer->energy = racer->maxEnergy = gBodyHealthValues[machine->machineStats[BODY_STAT]];src/game/racer.c line 1660 at 4b00f36 · upstream ↗ 1823 if (gGameMode == GAMEMODE_DEATH_RACE) { 1824 for (racer = sLastRacer; racer > gRacers; racer--) { 1825 racer->energy *= 0.5f; 1826 racer->maxEnergy *= 0.5f;
src/game/racer.c lines 1823–1828 at 4b00f36 · upstream ↗ 862 for (i = gNumPlayers - 1; i >= 0; i--) { 863 gPlayerCharacters[i] = gRacers[i].character;
src/game/racer.c lines 862–866 at 4b00f36 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^In F-Zero X's US build,
Racer_ReceiveDamagesubtracts the damage it's given fromenergy, unless the machine is crashed or has finished (RACER_STATE_CRASHED,RACER_STATE_FINISHED). If that takes the energy below 0, a machine whosemachineLodis 0 is set to 0.1 instead, and nothing else happens;Racer_Drawsets that field to 0 for a machine outside the camera's view (behind it, more than 2500 ahead, or off the screen's edges), andRacer_Updatesets every machine's to 1 when more than one player is racing. Any other machine is set to 0 and, unless already crashed or spinning out, put into the state the decompilers nameRACER_STATE_SPINNING_OUT.Racer_HitWalldeals 0.7 times the machine's speed into the wall, when that speed is above 0.01, and a landmine (within 30 units of the machine) deals 12.5.Codeinspectredc/fzeroxHow we know
2240 if (racer->stateFlags & (RACER_STATE_CRASHED | RACER_STATE_FINISHED)) {src/game/racer.c line 2240 at 4b00f36 · upstream ↗ 2292 } else { 2293#if BUILD_REVISION >= REVISION_C ⋮ 2296 racer->energy -= damageStrength; 2297#if BUILD_REVISION >= REVISION_C ⋮ 2301 if (racer->energy < 0.0f) { 2302 if (racer->machineLod == 0) { 2303 racer->energy = 0.1f; 2304 return; ⋮ 2306 racer->energy = 0.0f; ⋮ 2315 if (!(racer->stateFlags & (RACER_STATE_CRASHED | RACER_STATE_SPINNING_OUT))) { 2316 racer->stateFlags |= RACER_STATE_SPINNING_OUT;
src/game/racer.c lines 2292–2316 at 4b00f36 · upstream ↗ 5609 for (racer = sLastRacer; racer >= gRacers; racer--) { 5610 racer->machineLod = racer->unk_2B2 = racer->unk_2B3 = 0; 5611 if (racer->stateFlags & RACER_STATE_ACTIVE) { ⋮ 5616 if ((temp_fa0 < 0.0f) || (temp_fa0 > 2500.0f)) { 5617 continue;
src/game/racer.c lines 5609–5618 at 4b00f36 · upstream ↗ 5094 if (gNumPlayers != 1) { 5095 for (racer = sLastRacer; racer >= gRacers; racer--) { 5096 racer->machineLod = racer->unk_2B2 = racer->unk_2B3 = 1;
src/game/racer.c lines 5094–5097 at 4b00f36 · upstream ↗ 2353 if (lateralVelocity * wallDirection > 0.01f) { ⋮ 2365 Racer_ReceiveDamage(racer, lateralVelocity * wallDirection * 0.7f);
src/game/racer.c lines 2353–2366 at 4b00f36 · upstream ↗ 3641 if ((SQ(var_fs1) + SQ(var_fs0) + SQ(var_ft4)) < 900.0f) { ⋮ 3645 racer->stateFlags |= RACER_STATE_TOUCHING_LANDMINE; 3646 Racer_ReceiveDamage(racer, 12.5f);
src/game/racer.c lines 3641–3646 at 4b00f36 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^ abIn F-Zero X's US build, pressing B starts a boost only when no boost is running (
boostTimeris 0),energyisn't exactly 0, and the machine hasRACER_STATE_CAN_BOOST. The boost setsboostTimerto 100 (sInitialBoostTimer), and on each update while it runs, the machine paysboostEnergyUsage, 0.0015 of itsmaxEnergy, fromenergy; if that takes the energy below 0, it's set to 0 and the boost ends on that update. A whole boost costs 0.15 of the meter and lasts 100 updates, about 1.7 seconds at 60 updates a second, the rate the race clock counts (computed). In a multiplayer race with the VS handicap on, the cost falls with distance behind the leader, linearly to 0.1 of it at 2000 or more behind.Codeinspectredc/fzeroxHow we know
3598 if ((buttonPressed & BTN_B) && (racer->boostTimer == 0) && (racer->energy != 0.0) && 3599 (racer->stateFlags & RACER_STATE_CAN_BOOST)) { ⋮ 3603 racer->boostTimer = sInitialBoostTimer;
src/game/racer.c lines 3598–3603 at 4b00f36 · upstream ↗ 386s32 sInitialBoostTimer = 100;src/game/racer.c line 386 at 4b00f36 · upstream ↗ 1661 racer->boostEnergyUsage = racer->maxEnergy * 0.0015f;src/game/racer.c line 1661 at 4b00f36 · upstream ↗ 4035 if (racer->boostTimer != 0) { 4036 if (racer->stateFlags & RACER_STATE_DASH_PAD_BOOST) { ⋮ 4040 } else { ⋮ 4047 if ((gNumPlayers == 1) || (gSettingVsHandicap == 0)) { 4048 sp128 = racer->boostEnergyUsage; 4049 } else { 4050 sp128 = (gRacersByPosition[0]->raceDistance - racer->raceDistance); 4051 sp128 /= D_800CE4D8; 4052 if (sp128 >= 1.0f) { 4053 sp128 = racer->boostEnergyUsage * 0.1f; 4054 } else { 4055 sp128 = (((1.0f - sp128) * 0.9f) + 0.1f) * racer->boostEnergyUsage; ⋮
src/game/racer.c lines 4035–4071 at 4b00f36 · upstream ↗ 343f32 D_800CE4D8 = 2000.0f;src/game/racer.c line 343 at 4b00f36 · upstream ↗ 4303 racer->unk_2A4++; 4304#if OS_TV_TYPE == OS_TV_TYPE_NTSC 4305 racer->raceTime = (s32) (racer->unk_2A4 * 50) / 3;
src/game/racer.c lines 4303–4305 at 4b00f36 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^In F-Zero X's US build, a machine starts the race without
RACER_STATE_CAN_BOOSTunless the race is the title demo, Practice, or Death Race, which set it from the start. A machine starts atlap0 withlapsCompleted1, andlapcounts up at each crossing of the line; when it reaches one more thanlapsCompleted(and no more than one past the last lap), the code records the lap and sets the flag. The first crossing, at the start, bringslapto 1 and doesn't set it; completing the first lap does, so in the Grand Prix and VS races boosting opens from the second lap (computed from the counters).Codeinspectredc/fzeroxHow we know
1580 if ((gTitleDemoState != TITLE_DEMO_INACTIVE) || (gGameMode == GAMEMODE_PRACTICE) || 1581 (gGameMode == GAMEMODE_DEATH_RACE)) { ⋮ 1583 if ((gTitleDemoState != TITLE_DEMO_INACTIVE) || (gGameMode == GAMEMODE_PRACTICE) || ⋮ 1586 racer->stateFlags = 1587 RACER_STATE_ACTIVE | RACER_STATE_FLAGS_20000000 | RACER_STATE_CAN_BOOST | RACER_STATE_FLAGS_8000; 1588 } else { 1589 racer->stateFlags = RACER_STATE_ACTIVE | RACER_STATE_FLAGS_20000000 | RACER_STATE_FLAGS_8000;
src/game/racer.c lines 1580–1590 at 4b00f36 · upstream ↗ 1614 racer->lapsCompletedDistance = -gCurrentCourseInfo->length; ⋮ 1619 racer->lapsCompleted = 1; ⋮ 1623 racer->bodyWhiteTimer = racer->spinOutTimer = racer->completedLapsTime = racer->raceTime = racer->lap = ⋮ 1625 racer->vibrationStrength = 0;
src/game/racer.c lines 1614–1625 at 4b00f36 · upstream ↗ 4309 if (sCourseHalfLength < sp128) { 4310 racer->lapsCompletedDistance += gCurrentCourseInfo->length; 4311 racer->lap++; 4312 if ((racer->lap == racer->lapsCompleted + 1) && (racer->lap <= (gTotalLapCount + 1))) { 4313 racer->lapsCompleted = racer->lap; 4314 racer->stateFlags |= RACER_STATE_CAN_BOOST;
src/game/racer.c lines 4309–4314 at 4b00f36 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^ abIn F-Zero X's US build, on each update that a machine is on a pit surface (
COURSE_EFFECT_PIT) and isn't crashed, airborne, or spinning out, it gainsenergyIncrease, 0.008 of itsmaxEnergy(sEnergyRefillScale), up to the maximum. An empty meter refills in 125 updates, about 2.1 seconds at 60 updates a second (computed).Codeinspectredc/fzeroxHow we know
387f32 sEnergyRefillScale = 0.008f;src/game/racer.c line 387 at 4b00f36 · upstream ↗ 1666 racer->energyIncrease = racer->maxEnergy * sEnergyRefillScale;src/game/racer.c line 1666 at 4b00f36 · upstream ↗ 4482 if ((racer->stateFlags & (RACER_STATE_CRASHED | RACER_STATE_AIRBORNE | RACER_STATE_SPINNING_OUT | 4483 COURSE_EFFECT_MASK)) == COURSE_EFFECT_PIT) { 4484 racer->energy += racer->energyIncrease; 4485 if (racer->maxEnergy < racer->energy) { 4486 racer->energy = racer->maxEnergy;
src/game/racer.c lines 4482–4487 at 4b00f36 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^In F-Zero X's US build, when two machines first touch and one belongs to a human player, the other records that player as its last contact (
unk_28C) and resets a counter (unk_288) that counts up on each update while the machine isn't crashed, finished, or falling off the track, the race intro timer (gRaceIntroTimer) is under 40, and the mode isn'tGAMEMODE_RECORDS. When damage puts a machine into its spin-out,func_8008DBB8credits that player if the contact was no more than 60 updates before and the player isn't finished, retired, or spinning out: it adds togRacersKOd(by the atlas's reading of the name, a count of knock-outs), and in the Grand Prix the fifth (gRacersKOd== 5) gives player 1 a life. The player gains an eighth of theirmaxEnergy(energyRegain), added on the next update they aren't crashed or spinning out, up to the maximum.Codeinspectredc/fzeroxrevisedHow we know
5148 if (!racerPair->areColliding) { 5149 if (racer->id < gNumPlayers) { 5150 racer2->unk_288 = 0; 5151 racer2->unk_28C = racer; ⋮ 5153 if (racer2->id < gNumPlayers) { 5154 racer->unk_288 = 0; 5155 racer->unk_28C = racer2;
src/game/racer.c lines 5148–5156 at 4b00f36 · upstream ↗ 4298 if (!(racer->stateFlags & (RACER_STATE_CRASHED | RACER_STATE_FINISHED | RACER_STATE_FALLING_OFF_TRACK)) && 4299 (gRaceIntroTimer < 40) && (gGameMode != GAMEMODE_RECORDS)) { ⋮ 4302 racer->unk_288++;
src/game/racer.c lines 4298–4302 at 4b00f36 · upstream ↗ 2315 if (!(racer->stateFlags & (RACER_STATE_CRASHED | RACER_STATE_SPINNING_OUT))) { 2316 racer->stateFlags |= RACER_STATE_SPINNING_OUT; ⋮ 2320 func_8008DBB8(racer, 60);
src/game/racer.c lines 2315–2320 at 4b00f36 · upstream ↗ 2196void func_8008DBB8(Racer* arg0, s32 arg1) { ⋮ 2199 if (arg1 < arg0->unk_288) { 2200 return; ⋮ 2203 temp_v0 = arg0->unk_28C; 2204 if (temp_v0 == NULL) { 2205 return; ⋮ 2207 if (temp_v0->stateFlags & (RACER_STATE_FINISHED | RACER_STATE_RETIRED | RACER_STATE_SPINNING_OUT)) { 2208 return; ⋮ 2212 gRacersKOd++; 2213 if ((gGameMode == GAMEMODE_GP_RACE) && (gRacersKOd == 5)) { 2214 gPlayerLives[0]++; ⋮ 2221 temp_v0->energyRegain += temp_v0->maxEnergy * 0.125f;
src/game/racer.c lines 2196–2221 at 4b00f36 · upstream ↗ 5085 if ((racer->energyRegain != 0.0f) && !(racer->stateFlags & (RACER_STATE_CRASHED | RACER_STATE_SPINNING_OUT))) { 5086 racer->energy += racer->energyRegain; 5087 if (racer->energy > racer->maxEnergy) { 5088 racer->energy = racer->maxEnergy; ⋮ 5090 racer->energyRegain = 0.0f;
src/game/racer.c lines 5085–5091 at 4b00f36 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Revised after a check by a second AI model, 2026-10-22.
- ^In F-Zero X's US build, when two machines first touch, the impact is 1.1 times their closing speed along the line between them. If neither is attacking (
attackState, whose states the decompilers name side and spin attacks), each takes that impact times the other's share of their twocollidingStrengths, a number set from body grade and weight, with a crashed machine's strength counted at a third (0.333). If only one is attacking, the other takes the whole impact, and ten times the impact when the attacker isgRacers[0]in a one-player race; the pair loop always puts the lower-numbered racer second, so player 1's machine is the attacker in that test whenever it attacks. If both attack, each takes its share as if neither were.Codeinspectredc/fzeroxHow we know
5107 racer2 = racer - 1;src/game/racer.c line 5107 at 4b00f36 · upstream ↗ 5132 if (racer->stateFlags & RACER_STATE_CRASHED) { 5133 var_fs2 = racer->collidingStrength * 0.333f; 5134 } else { 5135 var_fs2 = racer->collidingStrength; ⋮ 5137 if (racer2->stateFlags & RACER_STATE_CRASHED) { 5138 var_fs1 = racer2->collidingStrength * 0.333f; 5139 } else { 5140 var_fs1 = racer2->collidingStrength; ⋮ 5142 temp_fv1_3 = var_fs2 + var_fs1; 5143 var_fs2 /= temp_fv1_3; 5144 var_fs1 /= temp_fv1_3;
src/game/racer.c lines 5132–5144 at 4b00f36 · upstream ↗ 5168 var_fs0 = (var_fa0 * xVelocityDiff) + (var_fa1 * yVelocityDiff) + (var_ft4 * zVelocityDiff); ⋮ 5170 if (var_fs0 < 0.0f) { 5171 var_fs0 = -var_fs0;
src/game/racer.c lines 5168–5172 at 4b00f36 · upstream ↗ 5186 var_fs0 *= 1.1f; 5187 if (racer->attackState == ATTACK_STATE_NONE) { 5188 if (racer2->attackState == ATTACK_STATE_NONE) { 5189 Racer_ReceiveDamage(racer, var_fs1 * var_fs0); 5190 Racer_ReceiveDamage(racer2, var_fs2 * var_fs0); 5191 } else if ((racer2 == gRacers) && (gNumPlayers == 1)) { 5192 Racer_ReceiveDamage(racer, var_fs0 * 10.0f); 5193 } else { 5194 Racer_ReceiveDamage(racer, var_fs0); ⋮ 5196 } else if (racer2->attackState == ATTACK_STATE_NONE) { 5197 Racer_ReceiveDamage(racer2, var_fs0); 5198 } else { ⋮
src/game/racer.c lines 5186–5201 at 4b00f36 · upstream ↗ 89 /* 0 */ ATTACK_STATE_NONE, 90 /* 1 */ ATTACK_STATE_SIDE, 91 /* 2 */ ATTACK_STATE_SPIN,
include/fzx_racer.h lines 89–91 at 4b00f36 · upstream ↗ 1641 racer->collidingStrength = 1642 ((4 - machine->machineStats[BODY_STAT]) * 312.0f) + 780.0f + ((312.0f * (machine->weight - 780.0f)) / 1560.0f);
src/game/racer.c lines 1641–1642 at 4b00f36 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^In F-Zero X's US build, on each update that a machine isn't crashed and is on a dash surface (
COURSE_EFFECT_DASH), and B isn't starting a boost, the code holds A for it, setsRACER_STATE_DASH_PAD_BOOST, and setsboostTimerto 100, so a dash plate starts a boost or tops a running one back up. While that flag is set the boost costs no energy, and the boost multiplies the machine's two acceleration terms by at leastunk_1C4, a value set with grade C's boost number (0.204,D_800CF174[2]), where a B boost usesunk_1C0, set with the machine's own boost grade.Codeinspectredc/fzeroxHow we know
3608 } else { 3609#ifndef EXPANSION_KIT 3610 if ((racer->stateFlags & (RACER_STATE_CRASHED | COURSE_EFFECT_MASK)) == COURSE_EFFECT_DASH) { ⋮ 3615 buttonCurrent |= BTN_A; ⋮ 3620 racer->stateFlags |= RACER_STATE_DASH_PAD_BOOST; 3621 racer->boostTimer = sInitialBoostTimer;
src/game/racer.c lines 3608–3621 at 4b00f36 · upstream ↗ 4035 if (racer->boostTimer != 0) { 4036 if (racer->stateFlags & RACER_STATE_DASH_PAD_BOOST) { 4037 if (var_ft4 < racer->unk_1C4) { 4038 var_ft4 = racer->unk_1C4; ⋮ 4040 } else { 4041 if (var_ft4 < racer->unk_1C0) { 4042 var_ft4 = racer->unk_1C0;
src/game/racer.c lines 4035–4043 at 4b00f36 · upstream ↗ 4073 var_fs1 *= var_ft4; 4074 var_fs0 *= var_ft4;
src/game/racer.c lines 4073–4074 at 4b00f36 · upstream ↗ 1538 racer->unk_1C0 = (D_800CF174[temp_a1->machineStats[BOOST_STAT]] + temp_fa1) / racer->unk_1B8; 1539 temp_fs1 += racer->unk_1C0; 1540 racer->unk_1C4 = (D_800CF174[2] + temp_fa1) / racer->unk_1B8;
src/game/racer.c lines 1538–1540 at 4b00f36 · upstream ↗ 444f32 D_800CF174[] = { 445 0.210f, 0.207f, 0.204f, 0.201f, 0.198f,
src/game/racer.c lines 444–446 at 4b00f36 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Checked by a second AI model, 2026-10-22.
- ^ abIn F-Zero X's US build, the machine-settings screen holds each player's engine setting (
gPlayerEngine) between 0 and 1, set to 0.5 when the screen opens, except inGAMEMODE_LX_GP_RACE_NEXT_MACHINE_SETTINGS, which keeps the previous setting; in one-player races on the built-in courses, player 1's is then set to the character's last setting. The stick moves it by the square of 0.003 times its x position per update; with the stick under that threshold (a square below 0.001), D-pad left or right moves it by 1/128. The screen draws it with a texture the decompilers nameaMachineAccelerationMaxSpeedTex. At the race,func_8008960C, x ↦ 1/(1.69/x − 0.69), maps the setting tounk_1A8, keeping 0 and 1 and taking 0.5 to about 0.37 (computed).Racer_InitMachineStatsthen blends nine machine values (unk_1B0,unk_1B4,unk_1B8,unk_1BC,unk_1C8,unk_1F8,unk_1FC,unk_1CC's divisor, and a term in both boost multipliers) between two ends byunk_1A8; four of the blends add 0.2 times the gap between the ends times 1 − (2s − 1)², which is 0 at either end and largest at the middle. Each end is itself a blend by the machine's weight, (weight − 780)/1560, of two numbers the function reads from fixed offsets of the cartridge ROM, from 0x078 to 0xA20 (ROM_READ), so the repo doesn't hold the values.Codeinspectredc/fzeroxrevisedHow we know
615 if (gGameMode != GAMEMODE_LX_GP_RACE_NEXT_MACHINE_SETTINGS) { 616 gPlayerEngine[i] = 0.5f; ⋮ 620 if ((gNumPlayers == 1) && (gCourseIndex < COURSE_EDIT_1)) { 621 Save_UpdateCharacterSave(gCourseIndex); 622 gPlayerEngine[0] = gCharacterLastEngine[gRacers[0].character];
src/overlays/ovl_i4/machine.c lines 615–622 at 4b00f36 · upstream ↗ 840 stickX = temp_s1->stickX; 841 temp_fa0 = gPlayerEngine[i]; 842 temp_fv0 = (f32) stickX * 0.003; 843 var_fa1 = SQ(temp_fv0); 844 if (var_fa1 < 0.001) { 845 var_fa1 = 0.0078125f; 846 stickX = 0; 847 if (gInputPressed & BTN_LEFT) { 848 stickX = -1; 849 } else if (!(gInputPressed & BTN_RIGHT)) { 850 var_fa1 = 0.0f; ⋮ 853 if (stickX < 0) { ⋮
src/overlays/ovl_i4/machine.c lines 840–863 at 4b00f36 · upstream ↗ 426CacheTexInfo sMachineAccelerationMaxSpeedCacheTexInfo[] = 427 CACHE_TEX_INFO_COMP(TEX_CACHE_FMT_RGBA16, aMachineAccelerationMaxSpeedTex);
src/overlays/ovl_i4/machine.c lines 426–427 at 4b00f36 · upstream ↗ 836f32 func_8008960C(f32 arg0) { 837 if (arg0 != 0.0f) { 838 return 1.0f / (((1.0f + 0.6899998f) / arg0) - 0.6899998f); ⋮ 840 return 0.0f;
src/game/racer.c lines 836–841 at 4b00f36 · upstream ↗ 865 gRacers[i].unk_1A8 = func_8008960C(gPlayerEngine[i]);src/game/racer.c line 865 at 4b00f36 · upstream ↗ 1428 temp_fs0 = (racer->unk_1F0 - 780.0f) / 1560.0f; ⋮ 1432 temp_fv0 = ((((f32) ((ROM_READ(0x078) >> 0xF) & 0xFF) * 0.1f) - 1433 ((f32) (((ROM_READ(0x50C) >> 0x13) & 0xFF) | 0x600) * 0.001f)) * 1434 temp_fs0) + 1435 ((f32) (((ROM_READ(0x50C) >> 0x13) & 0xFF) | 0x600) * 0.001f); ⋮ 1438 temp_fs0) + ⋮ 1441 racer->unk_1B4 = 1442 ((temp_fv1 - temp_fv0) * arg1) + temp_fv0 + (0.2f * (temp_fv0 - temp_fv1) * (1.0f - SQ((2.0f * arg1) - 1.0f)));
src/game/racer.c lines 1428–1442 at 4b00f36 · upstream ↗ 1536 temp_fa1 = ((temp_fv1 - temp_fv0) * racer->unk_1A8) + temp_fv0;src/game/racer.c line 1536 at 4b00f36 · upstream ↗ 1640 racer->unk_1F0 = machine->weight; ⋮ 1649 temp_fv0_4 = Racer_InitMachineStats(racer, racer->unk_1A8);
src/game/racer.c lines 1640–1649 at 4b00f36 · upstream ↗ 40#define PHYS_TO_K1ROM(x) (((u32) (x) | 0xB0000000)) 41#define ROM_READ(addr) (*(vu32*) PHYS_TO_K1ROM(addr))
include/macros.h lines 40–41 at 4b00f36 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Revised after a check by a second AI model, 2026-10-22.
- ^In F-Zero X's US build,
Machine_DrawBlueFalconLod1, by its name a draw routine for the Blue Falcon, reads the word at offset 0x510 of the cartridge ROM until it has read the same value three times in a row (the first read is compared with 0). If its lowest bit is set, it counts the call (D_800CE784), and from the 13th such call it sets all fivegBodyHealthValuesto 1.0, the maximum energy machines are given when a race is set up, and callsfunc_i2_801039BC. The atlas hasn't read what the word holds on a retail cartridge.Codeinspectredc/fzeroxrevisedHow we know
4942Gfx* Machine_DrawBlueFalconLod1(Gfx* gfx) { ⋮ 4950 var_a0 = 0; ⋮ 4952 while (var_a0 < 2) { 4953 while (IO_READ(PI_STATUS_REG) & (PI_STATUS_IO_BUSY | PI_STATUS_DMA_BUSY)) {} ⋮ 4955 temp_v1 = ROM_READ(0x510); 4956 if (temp_v1 == var_a1) { 4957 var_a0++; 4958 } else { 4959 var_a0 = 0; ⋮ 4961 var_a1 = temp_v1; ⋮ 4964 if (temp_v1 & 1) { 4965 D_800CE784++; ⋮
src/overlays/ovl_i9/machine_draw.c lines 4941–4969 at 4b00f36 · upstream ↗ 1660 racer->energy = racer->maxEnergy = gBodyHealthValues[machine->machineStats[BODY_STAT]];src/game/racer.c line 1660 at 4b00f36 · upstream ↗ Checked against the evidence by its author, an AI model, 2026-10-22.
Revised after a check by a second AI model, 2026-10-22.
Sources
Code
- inspectredc and fzerox contributors. 2026. “F-Zero X decompilation (inspectredc/fzerox).” Commit 4b00f36. inspectredc/fzerox @ 4b00f36 · licence, all uses