data/claims/ridge-racer.yamlRidge Racer (the kazuyette/rr-decomp decompilation)
Game: Ridge Racer.
In Ridge Racer's Japanese release (SLPS-00001), car_simulate (func_80019CF4) runs one of four handlers each update by the car's state at offset 0xB4: 0 func_80026E7C, 1 func_80027734, 2 func_80027F60, 3 func_80028294, which the atlas reads as grip, slide, slide recovery, and the start. In state 0 the heading turns a fifth of the way to the steering's target each update, and the car moves only along its heading: the code keeps the forward part of its velocity and drops the sideways part. ridge-racer/grip-state
About: Ridge Racer Drift boost
CodeRidge Racer decompilation (kazuyette/rr-decomp) ·src/fn/func_80019CF4.c#L204-L211if (D_801D9060 != 1) {
switch (q->type) {
case 0: func_80026E7C(car); break;
case 1: func_80027734(car); break;
case 2: func_80027F60(car); break;
case 3: func_80028294(car); break;Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_80026E7C.c#L23-L32car->ang += func_80019CA8(car->ang, car->u.c.steer) / 5;
…
v.vx = (c * car->u.c.vx - s * car->u.c.vz) / 4096;
v.vz = (s * car->u.c.vx + c * car->u.c.vz) / 4096;
car->u.c.vx = s * v.vz / 4096;
car->u.c.vz = c * v.vz / 4096;Checked by claude, 2026-10-22 — read car_simulate's dispatch and func_80026E7C at the pinned commit; the dispatch's `type` (Phys 0x5C) and func_80026E7C's `slide` (Phys 0x5C) are the same car offset, 0xB4, since both files put Phys at car + 0x58. v is the velocity rotated into the car's frame; vx/vz are rebuilt from v.vz alone, the forward part. func_8001C490 L74-75 adds vx and vz (Phys 0x8 and 0x10) to the car's position.Cited by: Ridge Racer
In Ridge Racer's Japanese release (SLPS-00001), a car in grip (state 0, func_80026E7C) enters a slide (state 1) in two ways. Pressing the accelerator again after lifting off: the code counts the updates the accelerator stays below half (0x80) without a fresh brake press, and on the update the accelerator is pressed again it multiplies the count by the car's speed; a speed above 960 and a product above the car's threshold start the slide. Or a fresh brake press with the accelerator off: the car's sideways velocity times its speed over 64, above the threshold at a speed above 320. The threshold is 14 times a value from the car model's spec table. The product that started the slide becomes the slide's budget (D_801732F0), and the car's yaw rate (D_8012CFE0) is set against its sideways velocity: at least twice it on the accelerator, once on the brake. ridge-racer/slide-entry
About: Ridge Racer Drift boost
CodeRidge Racer decompilation (kazuyette/rr-decomp) ·src/fn/func_80026E7C.c#L33-L61if (car->u.c.c4 == 1) {
t = car->u.c.spd * D_8007B1F0;
D_8007B1F0 = 0;
D_801732F0 = t;
if (car->u.c.spd > 960 && car->u.c.lim < t) {
car->u.c.slide = 1;
r = 1000 - (car->u.c.x98 - 1000) * 8;
if (r < 1000)
r = 1000;
D_8012CFE0 = -v.vx * r / 1000 * 2;
…
} else if (car->u.c.grip < 0x80) {
…Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_80019CF4.c#L41-L44if (D_801D9060 != 4 && D_8012CD20 >= 30) {
if (D_801D35A8.id == 0x41) {
car->u.c.C8 = ((D_801D35A8.btn & D_801D7778[2]) != 0) << 8;
car->u.c.CA = ((D_801D35A8.btn & D_801D7778[3]) != 0) << 8;Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_80019CF4.c#L91-L97if (q->h6C == 0) {
if (q->g70 >= 0x85)
q->h6C = 1;
} else if (q->h6C == 1)
q->h6C = 2;
else if (q->g70 < 0x7C)
q->h6C = 0;Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_80019CF4.c#L162-L166if (D_801D9060 >= 2) {
if (q->h60 == 0)
s0 += q->rpm / 256;
s2 = x * q->g70 / 256;
s0 += q->g72 * q->rpm / 256 / 32;Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_8001AA60.c#L91q->x3C = sp->h4 * 14;Checked by claude, 2026-10-22 — read func_80026E7C, car_simulate's pad and edge code, and the car init func_8001AA60 at the pinned commit. Offsets: 0xC8 is `grip` in func_80026E7C.c and `C8`/`g70` in func_80019CF4.c, 0xCA is `wear` and `CA`/`g72`, 0xC4/0xC6 are `c4`/`c6` and `h6C`/`h6E`, 0x94 is `lim` and Phys `x3C` in func_8001AA60.c. The accelerator and brake readings are the atlas's: on a digital pad (id 0x41) 0xC8 and 0xCA are 0x100 while a mapped button is held, 0xC8 scales the engine's torque into the revs (s2) and 0xCA adds to the revs' drag (s0). c4 == 1 only on the update the accelerator value rises past 0x85.The pad's buttons come from a mapping table (D_801D7778), and on a neGcon (id 0x23) the two values are analogue. Field 0x98 (x98), which raises the accelerator kick when it's below 1000, isn't identified. The two numbers the comparisons use, 960 and 320, are in the car's speed units at offset 0xA0.
Cited by: Ridge Racer
In Ridge Racer's Japanese release (SLPS-00001), a car in a slide (state 1, func_80027734) turns its heading by its yaw rate over 256 each update, with the yaw rate held within ±0x3600, so at most 54 of the 4,096 units of a full turn (computed: about 4.7°). While the slide's budget is above 0, a term from Phys 0x54 (w54), which the atlas reads as the steering target, adds to the yaw rate and the budget drains each update by 0x40, by the square of the slip angle (heading against direction of travel) over 65,536, by (0x3600 − |yaw rate|)/64, and by 4 times the brake value, with more drained below a speed of 400, below half the car's spec speed, or at a slip under 0x80 with a slow yaw. Once the budget is spent, the yaw rate falls to 15/16 each update, and the slide ends on the first update it starts below 0x1000. ridge-racer/slide-hold
About: Ridge Racer Drift boost
Value: 54 angle units per update (of 4096), the slide's top turn rate
CodeRidge Racer decompilation (kazuyette/rr-decomp) ·src/fn/func_80027734.c#L34-L69a = D_8012CFE0 < 0 ? -D_8012CFE0 : D_8012CFE0;
…
if (d < 0x80 && a < 0x800)
D_801732F0 -= (0x800 - a) * 4000 / 256;
if (q->spd < 400)
D_801732F0 -= (400 - q->spd) * 100;
if (D_801732F0 > 0) {
d = func_80019CA8(car->ang, q->w54) * 98 / 100;
d = d * (D_80173358 + 0x800) / 2048;
D_8012CFE0 += d * 16;
…
if (D_8012CFE0 > 0x3600)
…Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_80019C6C.c#L8-L18temp_v1 = arg0 & 0xFFF;
temp_a0 = arg1 & 0xFFF;
…
if (var_a0 >= 0x801) {
var_a0 = 0x1000 - var_a0;
}
return var_a0;Checked by claude, 2026-10-22 — read func_80027734 and the angle-difference helper func_80019C6C at the pinned commit. 4096 units a turn is the repo's note on rcos (m0_symbol_addrs.txt) and the helper's 0xFFF mask. 0x3600/256 = 54; 54 × 360/4096 = 4.75°. Phys 0x72 (`h72`) is car 0xCA, the brake value; Phys 0x44 (`w44`) is set at init from the car's spec (func_8001AA60 L72-L79). The slide handler sets `w54` to the heading at L83, and func_8001C490 L66 adds a steering-derived term to it before the next update's car_simulate call; that is the reading of it as the steering target. func_800275F0, called after L83, works on Phys 0x50, not `w54`.a is the yaw rate's size at the top of the update, so the exit test uses the value before that update's decay. The budget also loses 5000 in func_8001C490 L133 when the car hits something.
Cited by: Ridge Racer
In Ridge Racer's Japanese release (SLPS-00001), when a slide ends (func_80027734) the car's direction of travel snaps to its heading and its speed is multiplied by 1 − w²/2²⁰, where w is the slip angle between them folded to at most a quarter turn: a slide that ends at 45° keeps 75% of its speed and one at 90° keeps none (computed). The part taken off keeps moving the car along its old direction in state 2 (func_80027F60), shrinking to 31/32 each update with the leftover angle, and the car returns to grip (state 0) when both reach 0. ridge-racer/slide-exit
About: Ridge Racer Drift boost
Value: 0.75 share of speed kept by a slide ending at 45°
CodeRidge Racer decompilation (kazuyette/rr-decomp) ·src/fn/func_80027734.c#L71-L80D_801D7E30 = t = func_80019CA8(q->dir, car->ang);
D_80173438 = q->dir;
q->dir = car->ang;
w = t < 0 ? -t : t;
if (w > 0x400)
w = 0x800 - w;
w = w * w;
D_8007C4E8 = w * q->spd / 0x100000;
q->spd = (0x100000 - w) * q->spd / 0x100000;
q->w5C = 2;Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_80027F60.c#L26-L41car->u.c.vx = func_80044D0C(car->u.c.dir + D_801D7E30) * car->u.c.spd / 256;
…
car->u.c.vx = func_80044D0C(D_80173438) * D_8007C4E8 / 256 + s * v.vz / 4096;
…
D_8007C4E8 = D_8007C4E8 * 31 / 32;
D_801D7E30 = D_801D7E30 * 31 / 32;
if (D_8007C4E8 == 0 && D_801D7E30 == 0)
q->slide = 0;Checked by claude, 2026-10-22 — read the exit branch of func_80027734 and the whole of func_80027F60 at the pinned commit. Phys 0x5C is `w5C` there and `slide` in func_80027F60.c (car 0xB4, the state). 0x400 is a quarter turn; at 45° w = 0x200 and w² = 2¹⁸, a quarter of 2²⁰.The same branch sets the engine field at Phys 0x58 from the speed and the gear-like field at Phys 0x2A (L70), not read further. In state 2 the steering and the accelerator count from slide-entry carry on, but only state 0 tests for a new slide.
Cited by: Drift boost, Ridge Racer
In Ridge Racer's Japanese release (SLPS-00001), car_simulate gives a car in a slide (state 1) an eighth of the engine drive it gets in the other states, and lets its speed fall by 0.4% an update instead of 6%. The slide handler (func_80027734) then scales that drive by (0x200 − w)/0x200 for a slip angle w up to a quarter turn: full drive with no slip, none at 45°, and a pull against the motion beyond (computed). func_80026CA8 adds the drive along the heading, but the slide handler saves the direction of travel before the call and restores it after, so in a slide the drive changes only the speed. ridge-racer/slide-drive
About: Ridge Racer Drift boost
CodeRidge Racer decompilation (kazuyette/rr-decomp) ·src/fn/func_80019CF4.c#L191-L198q->w58 = q->rpm * e->a;
if (q->type == 1) {
q->w4C = q->w58 / 256 / 32 / 128;
q->spd = q->spd * 996 / 1000;
} else {
q->w4C = q->w58 / 256 / 32 / 16;
q->spd = q->spd * 94 / 100;
}Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_80027734.c#L85-L91d = func_80019C6C(car->ang, q->dir);
if (d > 0x400)
q->w4C = q->w4C / 2 + (u = (0x3600 - a) * 4) * q->w4C * (d - 0x400) / 1024 / 0x3600;
else
q->w4C = (0x200 - d) * q->w4C / 512;
d = q->dir;
func_80026CA8(car);Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_80026CA8.c#L12-L16v.vx = (func_80044D0C(p->b) * p->r) / 4 + func_80044D0C(p->a) * p->d;
…
p->r = func_80040B54(p->r * p->r + p->d * p->d + (p->r * 2 * p->d * (t / 4096)) / 4096) >> 6;
p->b = 0x400 - func_800187A0(v.vx, v.vz);Checked by claude, 2026-10-22 — read car_simulate's drive lines, the drive scaling in func_80027734, and func_80026CA8 at the pinned commit. func_80026CA8's r, d, b, a are car 0xA0 (speed), 0xA4 (Phys 0x4C, the drive `w4C`), 0xA8 (direction of travel) and 0x24 (heading); it sets the speed to the length of speed·direction + drive·heading (func_80040B54 is SquareRoot in m0_symbol_addrs.txt) and turns the direction toward the heading. /2¹⁷ against /2²⁰ is the eighth. Beyond a quarter turn of slip (d > 0x400) a different formula applies.The slide handler restores the direction of travel after func_80026CA8 (L90-L92), so in a slide the drive changes the speed but the turn of the direction comes from the next update's code; the atlas hasn't traced that order further.
Cited by: Ridge Racer
In Ridge Racer's Japanese release (SLPS-00001), the player's car starts a race in state 3 (func_80028294). When the grid phase ends at race update 211 and the race begins, func_8001B284 reads the rev counter shown on the tachometer (D_801D7800, the car's revs smoothed and held between 500 and 10000) and sets a counter to 1000 plus its distance below 7500, or 1000 plus six times its distance above 7500, in which case it also halves the engine field at car offset 0xB0. In state 3 the car moves a quarter of what its speed would carry it, and the counter falls each update by the accelerator plus the brake plus 8; at 10 or below the car goes to grip (state 0). With the accelerator held on a digital pad (0x100), revs of 7500 give 4 updates of this, 5000 give 14, and 10000 give 61 (computed). ridge-racer/start-wheelspin
About: Ridge Racer Rocket start
Value: 7500 tachometer revs that make the start shortest
CodeRidge Racer decompilation (kazuyette/rr-decomp) ·src/fn/func_8001AA60.c#L65q->x5C = 3;Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_80014C2C.c#L130-L134case 1:
if (D_80173310 >= 211) {
func_8001B284(p);
D_801D9060 = 2;Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_8001B284.c#L10-L17temp_a1 = D_801D7800 - 0x1D4C;
if (temp_a1 < 0) {
var_a1 = -temp_a1;
} else {
var_a1 = temp_a1 * 6;
M2C_FIELD(arg0, s32 *, 0xB0) = (s32) ((s32) M2C_FIELD(arg0, s32 *, 0xB0) / 2);
}
D_8012CFF0 = var_a1 + 0x3E8;Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_8001B0CC.c#L31-L35D_801D7800 += (D_8007C2DC - D_801D7800) / 4;
if (D_801D7800 > 10000)
D_801D7800 = 10000;
if (D_801D7800 < 500)
D_801D7800 = 500;Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_80028294.c#L27-L41car->u.c.vx = func_80044D0C(car->u.c.dir) * car->u.c.spd / 256;
…
car->u.c.vx = s * v.vz / 4096 / 4;
car->u.c.vz = c * v.vz / 4096 / 4;
if (D_8012CFF0 > 10) {
D_8012CFF0 -= car->u.c.wear;
w = car->u.c.grip + 8;
D_8012CFF0 -= w;
if (D_8012CFF0 <= 0)
car->u.c.slide = 0;
…
} else {
…Checked by claude, 2026-10-22 — read the car init (Phys x5C is car 0xB4, the state), st_race_main's grid case, func_8001B284, the tachometer smoothing in func_8001B0CC, and func_80028294 at the pinned commit. D_8007C2DC is the player car (D_8007C258) + 0x84, the `rpm` field of func_80019CF4.c. `wear` and `grip` are car 0xCA and 0xC8, the brake and accelerator (see slide-entry). Worked the updates with 0x100 + 8 = 264 a step: 1000 → 4, 3500 → 14, 16000 → 61.Grid phase is the atlas's reading of race phase 1 (g_race_phase in the repo's notes). The counter keeps falling in later phases only while the car is still in state 3; car_simulate also takes (D_8012CFF0 & 0x1F) << 5 off the revs each update of state 3 in phase 2 (L179-L180). The atlas reads this for the player's car (st_race_main passes D_8007C258); whether the other cars' start goes through it isn't read.
Cited by: Ridge Racer, Rocket start
In Ridge Racer's Japanese release (SLPS-00001), the computer car in entity slot 0 takes its target speed from func_80022C40 during the race (when its field 0x60 is 0 and the game state isn't 0x1A). Unless its mode field 0xAA is 2: when it's on an earlier lap than the player, or on the same lap and behind the player by more than a margin, its target is 1.01 times its field 0x10C; when it's on a later lap, or more than 0x600 ahead on the same lap, its target is 80% of the lower of the usual target and its field 0xF8. The margin is 0x800, or 0x300 times the player's lap count when D_801D35D0 is 0. Between the two the target is left as it was. When D_801D35D0 is 0 and the player is on the last lap, the target is held to field 0xF8. ridge-racer/rival-pace
About: Ridge Racer Rubber-band AI
CodeRidge Racer decompilation (kazuyette/rr-decomp) ·src/fn/func_80022C40.c#L10-L27if (car->hAA != 2) {
lim = 0x800;
if (D_801D35D0 == 0)
lim = D_8007C32C * 3 * 256;
if ((car->lap == D_8007C32C && lim < car->dist) || car->lap < D_8007C32C) {
*spd = car->x10C / 100 + car->x10C;
*acc = car->FC;
} else if ((car->lap == D_8007C32C && car->dist < -0x600) || D_8007C32C < car->lap) {
v = *spd;
if (car->F8 < v)
v = car->F8;
*spd = v * 8 / 10;Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_80022C40.c#L40-L46if (D_801D35D0 == 0) {
n = 3;
if (D_8007C210 == 1)
n = 2;
if (D_8007C32C == n) {
if (*spd > car->F8) {
if ((*spd = car->F8) < car->x88)Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_80022F88.c#L101-L104if (D_801D34F8 != 0x1A && car == &D_801E9250[0]) {
acc = s->wA4;
if (s->w60 == 0)
func_80022C40(car, &spd, &acc);Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_800217F4.c#L70-L76if (D_801D77B8 == 0) {
d = car->pos - D_8007C260;
if (d >= 0)
d = d >= half ? d - len : d;
else
d = half >= -d ? d : len + d;
car->E0 = d;Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_80025268.c#L47-L49if (D_801D77B8 == 0) {
if ((((D_801E90E0 << 16) + c->w8) % (D_801E90E0 << 8) & ~0xFF) == 0x2700
&& (((D_801E90E0 << 16) + c->w84) % (D_801E90E0 << 8) & ~0xFF) == 0x2800) c->h9C++;Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_8001384C.c#L87-L94D_801D35A0 = 3;
…
if (D_8007C210 == 1)
D_801D35A0--;Checked by claude, 2026-10-22 — read func_80022C40, its call in func_80022F88 (which then moves the speed at 0x88 toward the target by the acceleration, L132-L138), the distance in func_800217F4, and the other cars' lap count in func_80025268 at the pinned commit. `dist` (0xE0) is the car's track position minus the player's (D_8007C260, player + 8), wrapped to half a lap; position falls as a car goes forward when D_801D77B8 is 0 (a lap counts on the step from sector 0x2800 to 0x2700), and with D_801D77B8 = 1 both the subtraction and the count flip, so a positive `dist` is behind in either case. `lap` (0x9C) is that count; D_8007C32C is the player's lap (player + 0xD4). The last-lap reading: the race has 3 laps (2 on course 1, D_8007C210 == 1), the same n the cap tests.Fields 0xF8, 0xFC, 0x100 and 0x10C are per-car values the atlas hasn't traced to a table. With mode 2 (0xAA) the target is instead 97% or 87% of the player car's field 0x9C, set at init from its spec (func_8001AA60 L67-L70), by which side of the player it's on. Slot 11 has its own speed rules (func_80022B4C), and every car's target is cut in corners afterward (func_80022F88 L113-L131). The repo doesn't say which car slot 0 is.
Cited by: Ridge Racer
In Ridge Racer's Japanese release (SLPS-00001), a lap's time is counted in race updates and converted to milliseconds as if 30 updates were a second: whole seconds times 1000, plus the remaining updates times 100/3. When the player crosses the line from the race direction, the finished lap gets a random 0 to 31 ms added (rand() & 0x1F) before it's compared with the course's best lap. Backing over the line and crossing again doesn't count a lap: the code counts each backward crossing and spends one on the next forward one. The race time is the sum of the laps. ridge-racer/lap-time
src/fn/func_8001FBC0.c#L3-L4s32 func_8001FBC0(s32 arg0, s32 arg1) {
return ((arg0 / 30) * 0x3E8) + (((s32) ((arg0 % 30) * 0x64) / 3) + arg1);Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_80014C2C.c#L170-L177case 3:
D_8012CD20--;
f = p->lap;
if (f > 0) {
f--;
p->u[f] = func_8001FBC0(++p->t[f], 0);Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_80013D40.c#L20-L45if (SEC(c->pos) == D_8012CDA0 && SEC(c->prev) == dir + D_8012CDA0) {
if (c->back > 0) {
c->back--;
} else {
…
if (c->lap > 0) {
c->laps[c->lap - 1] += rand() & 0x1F;
if (c->laps[c->lap - 1] < D_801D7628[D_8012D088][D_801733B8][D_8007C210 - 1]) {
…
} else if (SEC(c->pos) == dir + D_8012CDA0 && SEC(c->prev) == D_8012CDA0) {
c->back++;Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_8001483C.c#L31-L37if (c->lap > D_801D35A0) {
t = 0;
for (i = 0; i < D_801D35A0; i++)
t += c->laps[i];
D_801D77C8 = t;
if (t < D_8012CD38[D_8012D088][D_801733B8][D_8007C210 - 1])
D_8012CD38[D_8012D088][D_801733B8][D_8007C210 - 1] = t;Checked by claude, 2026-10-22 — read the conversion, st_race_main's phase 3, the line test func_80013D40, and the race-end sum in func_8001483C at the pinned commit. `laps` (0xF0) in func_80013D40.c and func_8001483C.c is `u` (0xF0) in func_80014C2C.c, the converted times; `t` (0xDC) holds the update counts. The best-lap and best-race tables are the ones func_800201B0 draws with a 1000 divisor and func_800314BC/func_80031668 save and load. 0x1F = 31 is less than one update's 33.3 ms.The 30-a-second rate is the conversion's; the atlas hasn't measured the race loop's rate. The dither fills the millisecond digits a 30 Hz count can't resolve; it is the atlas's reading, not a comment in the code.
Cited by: Ridge Racer
In Ridge Racer's Japanese release (SLPS-00001), the race clock (D_8012CD20) starts at the course's row of a table (D_8005E90C) times 30 and falls by 1 each race update in phases 2 and 3. Each row also holds a lap bonus and two checkpoint bonuses. Crossing the line to start laps 2 up to the last adds the lap bonus times 30 (another field when D_801733B8 is set). On the course run in its usual direction (D_801733B8 clear), crossing the first checkpoint adds the first checkpoint bonus times 30, and on courses 3 and up a second checkpoint adds the second bonus times 30; backing over a checkpoint and crossing again pays once. While the clock is below 30 the pad is ignored and the car gets no accelerator or brake. Below −59, before the results, the race ends as over. ridge-racer/time-extension
src/fn/func_8001384C.c#L88-L91if (D_801733B8)
D_8012CD20 = D_8005E90C[D_8007C210 - 1].h8 * 30;
else
D_8012CD20 = D_8005E90C[D_8007C210 - 1].h0 * 30;Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_80013D40.c#L35-L41c->lap++;
if (c->lap >= 2 && c->lap <= D_801D35A0) {
D_8012CF58 = 150;
if (D_801733B8)
D_8012CD20 += D_8005E90C[D_8007C210 - 1].b * 30;
else
D_8012CD20 += D_8005E90C[D_8007C210 - 1].a * 30;Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_8001483C.c#L61-L65if (D_801733B8 == 0) {
func_800140A4(c);
if (D_8007C210 >= 3)
func_80014280(c);
}Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_800140A4.c#L16-L24if (SEC(p->pos) == D_801734B8 && SEC(p->prev) == D_801734B8 + 0x100) {
if (p->cnt > 0) {
p->cnt--;
} else {
D_8012CF58 = 150;
D_8012CD20 += D_8005E910[D_8007C210 - 1].bonus * 30;
}
} else if (SEC(p->pos) == D_801734B8 + 0x100 && SEC(p->prev) == D_801734B8) {
p->cnt++;Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_80014280.c#L16-L21if (SEC(p->pos) == D_801734C0 && SEC(p->prev) == D_801734C0 + 0x100) {
…
D_8012CD20 += D_8005E910[D_8007C210 - 1].bonus * 30;Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_80014C2C.c#L215-L220if (D_801D9060 < 5 && D_8012CD20 < -59) {
…
D_801D9060 = D_801D9060 == 2 ? 6 : 5;Ridge Racer decompilation (kazuyette/rr-decomp) · src/fn/func_80019CF4.c#L41-L85if (D_801D9060 != 4 && D_8012CD20 >= 30) {
…
} else {
car->u.c.CA = 0;
car->u.c.C8 = 0;
D_8007B1F8 = 0x100;
}Checked by claude, 2026-10-22 — read the clock's set-up in func_8001384C, its decrements in st_race_main's cases 2 and 3 (L147, L171), the line and checkpoint tests, the time-out test, and car_simulate's input gate at the pinned commit. The table rows are 12 bytes, D_8005E90C (h0, a, bonus, bonus2, h8, b); func_800140A4.c and func_80014280.c read them from D_8005E910, four bytes on, so their `bonus` fields are the row's `bonus` and `bonus2`. The atlas hasn't decoded the table's values. func_80014280 is func_800140A4 with its own checkpoint sector (D_801734C0). D_801733B8 also reverses the line's crossing direction (func_80013D40 L17-L19), hence the atlas's reading of it as the course direction.The table values are times 30 to match the 30-a-second lap clock (see lap-time); the atlas hasn't decoded them, so no extension is given in seconds. Phases 5 and 6 are the end states the time-out sets (6 when it happens in phase 2).
Cited by: Ridge Racer