Claim set · data/claims/pw64.yaml

Pilotwings 64 (the pw64 decompilation, n64decomp/pw64)

Game: Pilotwings 64.

In the US version of Pilotwings 64, the gyrocopter's update routine func_8030399C clears a vector (unk31C) and has five routines add terms to it: func_80307A9C, func_80307E2C, func_80308478, func_80307BAC, and func_80307EA8. A routine chosen by state can add to it after them (func_80304B98, for states 1 and 4, does), and func_80309090 copies the result to unk1AC. In state 1 (unkC0), the routine adds unk1AC times the frame time to the craft's velocity (unk190), with no mass dividing it; in state 0 it first combines unk1AC with cross terms of the velocity and the turn rates (unk1B8). func_80307E2C adds (0, 0, −9.8), z being the world's vertical, turned into the craft's frame through the inverse of its matrix (by the atlas's reading, gravity). func_80307A9C adds, on each of the craft's axes, a curve of the square of unk364's component on that axis, signed like the component: 0 at 0, 4.2 at 2661.2188, and 7.56 at 6944.389 and above, linear between (by the atlas's reading, air resistance). Those squares are speeds of about 51.59 and 83.33 (computed). func_80308478 sets unk364 to the vector env_802E1754 returns for the craft's position, in the craft's frame, less the craft's velocity, and adds 0.21 of that vector as a term of its own; by the atlas's reading the vector is the air's velocity and unk364 the airspeed. Below a speed (unk1A8) of 51.587303 the vector is scaled by the square of the speed over 51.587303, and outside state 0 it's taken as zero. The other two routines are in pw64/gyrocopter-lift. pw64/gyrocopter-forces

About: Pilotwings 64 Flight model

Value: 9.8 units per second squared (gravity)

Codepw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L251-L279void func_8030399C(GyrocopterData* gcData) { … gcData->unk31C.x = 0.0f; … func_80307A9C(gcData); func_80307E2C(gcData); func_80308478(gcData); func_80307BAC(gcData); func_80307EA8(gcData);pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L349-L365uvMat4Copy(&gcData->unk150, &gcData->unk10); uvMat4InvertTranslationRotation(&gcData->unk110, &gcData->unk150); if (gcData->unkC0 == 1) { gcData->unk190.x += D_8034F854 * gcData->unk1AC.x; … uvMat4LocalToWorld(&gcData->unk150, &gcData->unk19C, &gcData->unk190); } else { gcData->unk19C.x += D_8034F854 * gcData->unk1B8.x; … uvMat4LocalToWorld(&gcData->unk110, &gcData->unk190, &gcData->unk19C); … gcData->unk10.m[3][0] = (gcData->unk19C.x * D_8034F854) + spF4;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L280-L310switch (gcData->unkC0) { case 0: func_80304738(gcData); break; case 1: case 4: func_80304B98(gcData); … func_80309090(gcData); if ((gcData->unkC0 == 0) && (gcData->unk190.z < gcData->unk190.y) && (gcData->unk6D == 0)) { gcData->unk1B8.x = (gcData->unk1AC.x - (gcData->unk190.y * gcData->unk1C8.z)) + (gcData->unk190.z * gcData->unk1C8.y); … …pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L1818-L1837void func_80309090(GyrocopterData* gcData) { … gcData->unk1AC.x = gcData->unk31C.x;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L566-L623void func_80304B98(GyrocopterData* gcData) { … uvVec3Add(&gcData->unk31C, &gcData->unk31C, &sp11C);pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L1442-L1452void func_80307E2C(GyrocopterData* gcData) { … sp1C.z = -9.8f; uvMat4LocalToWorld(&gcData->unk110, &gcData->unk358, &sp1C); gcData->unk31C.x += gcData->unk358.x;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L122-L125D_80369528.count = 3; D_80369528.unk4[0].x = 0.f, D_80369528.unk4[0].y = 0.0f; D_80369528.unk4[1].x = 2661.2188f, D_80369528.unk4[1].y = 4.2f; D_80369528.unk4[2].x = 6944.389f, D_80369528.unk4[2].y = 7.5599995f;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L1360-L1380void func_80307A9C(GyrocopterData* gcData) { … sp24.x = func_80313F08(&D_80369528, SQ(gcData->unk364.x)); if (gcData->unk364.x < 0.0f) { sp24.x = -sp24.x; … gcData->unk31C.x += sp24.x;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_9A960.c#L257-L280f32 func_80313F08(Unk803599D0* arg0, f32 arg1) { … if (arg1 <= arg0->unk4[0].f[0]) { return arg0->unk4[0].f[1]; … if (arg0->unk4[arg0->count - 1].f[0] <= arg1) { return arg0->unk4[arg0->count - 1].f[1]; … temp_fv1 = (arg1 - prev->f[0]) / (cur->f[0] - prev->f[0]); return (cur->f[1] * temp_fv1) + (prev->f[1] * (1.0f - temp_fv1));pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L1563-L1605void func_80308478(GyrocopterData* gcData) { … if (gcData->unkC0 == 0) { env_802E1754(gcData->unk10.m[3][0], gcData->unk10.m[3][1], gcData->unk10.m[3][2], &sp38); uvMat4LocalToWorld(&gcData->unk110, &sp44, &sp38); … } else { sp44.x = sp44.y = sp44.z = 0.0f; … if (gcData->unk1A8 < 51.587303f) { temp_fv0 = gcData->unk1A8 / 51.587303f; temp_fv0 = SQ(temp_fv0); …pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L410gcData->unk1A8 = uvVec3Len(&gcData->unk19C);pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_7CF30.c#L471hud->altSeaLevel = gcData->unk10.m[3][2] * 0.7f;Checked by claude, 2026-10-22 — read func_8030399C to the call of func_80309090 and the unk1B8 branch after it, the velocity and position integration, the copy of unk31C into unk1AC in func_80309090, the addition to unk31C in func_80304B98, func_80307E2C, func_80307A9C and its curve, the curve reader func_80313F08, func_80308478 whole, the speed's definition, and the HUD's height line; no VERSION_JP conditional encloses these lines

The decompilers name none of these functions or fields. z being the world's vertical rests on the HUD reading the matrix's z translation as height above sea level. unk1A8 is the length of the world velocity, a ground speed, so the curve's knots (on unk364) match a speed readout only in still air; the readout figures are left out for that reason. State 0 is, from func_80305DC0, the state with no ground contact, but the atlas hasn't stated that rule.

Cited by: Flight model, Pilotwings 64

In the US version of Pilotwings 64, two of the terms the gyrocopter's func_8030399C sums give it lift, by the atlas's reading. The one the atlas calls the rotor term (func_80307BAC) is 0.3 times the square of the airspeed's component on the z axis of the matrix unk25C, signed like that component and capped at 200 when positive, times the square of the airspeed's y component over 25, held between 0.05 and 1; it's added along the z axis of the matrix unk21C. The one it calls the engine term (func_80307EA8), while usingFuel is set, is 35 × power (unkB4) × a factor of height (spD8, the atlas's altitude factor), split 0.24 onto y and 0.76 onto z, the z part also times a curve of the negated y airspeed: 0 at 0, 0.15 at 10, 0.4 at 20, 1.2 at 50, and 1.5 at 100 and above. It too goes through unk21C, and its y component is cut to 0.9 when unk1F0 is nonzero, unk190.y is positive, and unk7C is 0. That factor is 1 up to a height of 700 and falls by 0.01 per unit above it, held at 0 from 800 up; that hold is under #if !defined(VERSION_JP), so a Japanese build lets the factor go negative. Neither term applies while unkC1 is set or in state 2 (unkC0). pw64/gyrocopter-lift

About: Pilotwings 64 Flight model

Value: 700 height where engine thrust begins to fade

Codepw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L1382-L1440void func_80307BAC(GyrocopterData* gcData) { … if ((gcData->unkC1 != 0) || (gcData->unkC0 == 2)) { gcData->unkE8 = func_80313AF4(0.0f, gcData->unkE8, 0.5f); return; } uvMat4LocalToWorld(&gcData->unk25C, &sp34, &gcData->unk364); sp54 = -(0.3f * sp34.z * sp34.z); if (-sp34.z < 0.0f) { sp54 = -sp54; if (sp54 < -10.0f) { sp54 = -10.0f; …pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L1454-L1463void func_80307EA8(GyrocopterData* gcData) { … if ((gcData->unkC1 != 0) || (gcData->unkC0 == 2)) { gcData->unkF0 = func_80313AF4(0.0f, gcData->unkF0, 0.5f); return;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L1490-L1516if (gcData->unk10.m[3][2] > 700.0f) { spD8 = 1.0f - ((gcData->unk10.m[3][2] - 700.0f) / 100.0f); #if !defined(VERSION_JP) if (spD8 < 0.0f) { spD8 = 0.0f; } #endif } else { spD8 = 1.0f; } if (gcData->usingFuel) { temp_fv0 = func_80313F08(&D_803692C0, -gcData->unk364.y); …pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L74-L79D_803692C0.count = 5; D_803692C0.unk4[0].x = 0.0f, D_803692C0.unk4[0].y = 0.f; D_803692C0.unk4[1].x = 10.0f, D_803692C0.unk4[1].y = 0.15f; D_803692C0.unk4[2].x = 20.0f, D_803692C0.unk4[2].y = 0.4f; D_803692C0.unk4[3].x = 50.0f, D_803692C0.unk4[3].y = 1.2f; D_803692C0.unk4[4].x = 100.0f, D_803692C0.unk4[4].y = 1.5f;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_7CF30.c#L470-L474hud->altSeaLevel = gcData->unk10.m[3][2] * 0.7f; … if (hud->fuel > 0.0f) { hud->power = gcData->unkB4;Checked by claude, 2026-10-22 — read func_80307BAC whole, func_80307EA8's early return and its thrust block through the additions to unk31C, the thrust curve, and the HUD's height and power lines; the only VERSION_JP conditional in these lines is the one the statement names

Neither term is named by the decompilers; "rotor" and "engine" are the atlas's reading (the engine term runs only while fuel is in use, and the rotor term grows with air flowing along the rotor matrix's z axis). That the 0.24 part pushes the craft forward and the 0.76 part up, with lift rising with forward airspeed, is a reading of the axes, not stated in the code. The README lists only the US build as supported, so the Japanese behavior is read from the conditional, not a build.

Cited by: Flight model, Pilotwings 64

In the US version of Pilotwings 64, the gyrocopter's fuel is a number from 0 to 1, starting at the value the task's first start pad holds, or 0 if the task has no start pad (db_getstart). While usingFuel is set, func_80307EA8 takes off each update the frame time times a rate read from a curve of the power (unkB4, the throttle that A raises and B lowers, which the HUD shows as power; in the throttle's case 0 A sets usingFuel, and in cases 1 and 2 A sets it only with fuel above 0): 0.001 at 0, 0.002 at 0.5, and 0.005 at full, linear between. The frame time (D_8034F854) is the time since the last frame held between 0.01 and 0.1, so the rate is per second, and a full tank lasts 200 s at full power and 1,000 s at none (computed). At 0 it clears usingFuel. In a Class B task, each update that func_802E08F4 returns nonzero for the craft's position sets the fuel to 1, and SFX_UI_FUEL_ADDED plays on the first. func_80307EA8 does none of this, refill or drain, while unkC1 is set or in state 2 (unkC0). Separately, the HUD update in code_7CF30.c warns below 0.15 (TEXT_FUEL_WAR) and at 0 (TEXT_FUEL_OUT). pw64/gyrocopter-fuel

About: Pilotwings 64 Fuel gauge

Value: 0.005 tank per second at full power

Codepw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L84-L88D_803694D0.count = 3; D_803694D0.unk4[0].x = 0.0f, D_803694D0.unk4[0].y = 0.001f; D_803694D0.unk4[1].x = 0.5f, D_803694D0.unk4[1].y = 0.002f; D_803694D0.unk4[2].x = 1.f, D_803694D0.unk4[2].y = 0.005f;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/gyrocopter.c#L1454-L1488void func_80307EA8(GyrocopterData* gcData) { … if ((gcData->unkC1 != 0) || (gcData->unkC0 == 2)) { … return; } if (D_8036957E == CLASS_B) { if (func_802E08F4(gcData->unk10.m[3][0], gcData->unk10.m[3][1], gcData->unk10.m[3][2]) != 0) { if (gcData->unk67E == 0) { gcData->unk67E = 1; sndPlaySfx(SFX_UI_FUEL_ADDED); … …pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_9A960.c#L257-L280f32 func_80313F08(Unk803599D0* arg0, f32 arg1) { … temp_fv1 = (arg1 - prev->f[0]) / (cur->f[0] - prev->f[0]); return (cur->f[1] * temp_fv1) + (prev->f[1] * (1.0f - temp_fv1));pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_9A960.c#L9f32 D_8034F854 = 0.1000000015f; // actual time since last framepw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_9A960.c#L210-L220temp_fv0 = uvGfxGetFrameTime(); if (temp_fv0 < 0.01f) { D_8034F854 = 0.01f; } else if (temp_fv0 > 0.1f) { D_8034F854 = 0.1f; } else { D_8034F854 = temp_fv0;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_7CF30.c#L95db_getstart(&gcData->unk10, &gcData->unk190, &sp5F, &gcData->fuel);pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_66F70.c#L260-L294temp_v1 = taskGetTPAD(&sp44); if (temp_v1 == 0) { … if (fuel != NULL) { *fuel = 0.0f; } } else { … first = &sp44[0]; … if (fuel != NULL) { *fuel = first->unk2C;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_7CF30.c#L248-L309switch (gcData->unk5F) { case 0: if (buttons & A_BUTTON) { gcData->unkB0 += gcData->unk654 * D_8034F854; if (!gcData->usingFuel) { gcData->usingFuel = TRUE; … if (buttons & B_BUTTON) { gcData->unkB0 -= gcData->unk658 * D_8034F854; … case 2: … …pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_7CF30.c#L473-L474if (hud->fuel > 0.0f) { hud->power = gcData->unkB4;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_7CF30.c#L494-L499if ((gcData->fuel <= 0.0f) && !gcData->fuelEmpty) { hudWarningText(TEXT_FUEL_OUT, 1.5f, 8.0f); … } else if ((gcData->fuel < 0.15f) && !gcData->hasLowFuel) { hudWarningText(TEXT_FUEL_WAR, 1.5f, 8.0f);Checked by claude, 2026-10-22 — read func_80307EA8 from its start to the fuel clamp, the fuel curve, func_80313F08, D_8034F854's definition and func_80313D74, db_getstart, the throttle switch in code_7CF30.c through the copy into unkB4, and the HUD's power and warning lines; no VERSION_JP conditional encloses these lines

The 200 s and 1,000 s are 1 divided by the end rates. What func_802E08F4 tests (by its use, a refuelling area) isn't named. The start pad's value is task data from the ROM, so whether a test starts full isn't read.

Cited by: Fuel gauge, Pilotwings 64

In the US version of Pilotwings 64, a thermal is a vertical cylinder from the task's data (TaskTHER): a base position, a radius (scale), and a height. therm_80346C08 sums a vector from each thermal whose cylinder holds the point (by the atlas's reading, its air velocity): its horizontal distance d from the axis at most the radius r, and its height z above the base between 0 and the thermal's height. In therm_80346E04 the vector's vertical part (the atlas's updraft) is the thermal's unk24 × √((r − d)/r), full on the axis and 0 at the edge. Beyond 1 unit from the axis its horizontal part is at right angles to the axis direction, of length unk20 × (1 − 2|r/2 − d|/r) × d, longest halfway out (the atlas's swirl). Both fade in from 0 at the base to full at height unk18, and from unk1C fade out to 0 at the top. env_802E1754 adds the sum to the vector wind_8034D550 gives for the point (by the atlas's reading, the wind), along with, unless the task's unk8 is set, a further wind and a push from beyond 2050 units outside the map's bounds. The hang glider (hangGlider_802F391C) multiplies the total by its pilot's unk2F8: 1.2 for Lark and Kiwi, 1.0 for Goose and Ibis, and 0.8 for Hawk and Robin. pw64/thermal

About: Pilotwings 64 Thermal

Value
{
 "lark": 1.2,
 "goose": 1,
 "hawk": 0.8,
 "kiwi": 1.2,
 "ibis": 1,
 "robin": 0.8
}
Codepw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/task.h#L274-L283typedef struct { Vec3F pos; f32 scale; f32 height; … } TaskTHER; // size = 0x28pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/thermals.c#L156-L199void therm_80346C08(f32 x, f32 y, f32 z, Vec3F* dst) { … dx = x - therm->pos.x; dy = y - therm->pos.y; dz = z - therm->pos.z; dist = uvLength2D(dx, dy); if (taskTherm->scale < dist) { continue; } if (taskTherm->height < dz) { continue; } …pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/thermals.c#L201-L235temp_fv0 = therm->scale * 0.5f; if (dist > 1.0f) { if (dist < temp_fv0) { var_fa0 = temp_fv0 - dist; } else { var_fa0 = -(temp_fv0 - dist); } var_fv1 = 1.0f - ((2.0f * var_fa0) / therm->scale); dst->x = therm->unk20 * var_fv1 * dist * (y / dist); dst->y = -var_fv1 * therm->unk20 * dist * (x / dist); … var_fv1 = uvSqrtF((therm->scale - dist) / therm->scale); …pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/environment.c#L338-L382void env_802E1754(f32 arg0, f32 arg1, f32 arg2, Vec3F* arg3) { … wind_8034D550(arg0, arg1, arg2, &sp44); therm_80346C08(arg0, arg1, arg2, &sp38); … temp_fv0 = (temp_v0->unk0.unk0 - 2050.0f) - arg0; if (temp_fv0 > 0.0f) { sp2C = (50.0f * temp_fv0) / 2050.0f; … if (D_80362690->unkC[D_80362690->unk9C].unk8 == 0) { arg3->x = sp44.x + sp38.x + D_80359D80.unk0.x + sp2C; … …pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/hang_glider2.c#L574-L591STATIC_FUNC void hangGlider_802F391C(HangGliderData* hgData) { … if (hgData->unk8C != 2) { env_802E1754(hgData->unk10.m[3][0], hgData->unk10.m[3][1], hgData->unk10.m[3][2], &sp20); sp20.x *= hgData->unk2F8;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/hang_glider1.c#L519-L569void hangGliderLoadPilot(u8 pilot, HangGliderData* hgData) { switch (pilot) { case PILOT_LARK: … hgData->unk2F8 = 1.2f;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/hang_glider1.c#L572-L618case PILOT_GOOSE: … hgData->unk2F8 = 1.0f;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/hang_glider1.c#L623-L669case PILOT_HAWK: … hgData->unk2F8 = 0.8f;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/hang_glider1.c#L674-L722case PILOT_KIWI: … hgData->unk2F8 = 1.2f;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/hang_glider1.c#L725-L771case PILOT_IBIS: … hgData->unk2F8 = 1.0f;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/hang_glider1.c#L776-L822case PILOT_ROBIN: … hgData->unk2F8 = 0.8f;Checked by claude, 2026-10-22 — read TaskTHER, therm_80346C08 and therm_80346E04 whole, env_802E1754 whole, hangGlider_802F391C, and each pilot's case in hangGliderLoadPilot to its unk2F8; no VERSION_JP conditional encloses these lines

"Updraft" and "swirl" are the atlas's reading of the vertical and tangential parts; the decompilers name neither field. Each thermal's strengths and heights are task data from the ROM. The swirl's peak at d = r/2 is computed. How the hang glider's lift uses the air (the rest of hang_glider2.c) isn't read.

Cited by: Pilotwings 64, Thermal

In the US version of Pilotwings 64, the thermals switch off in one test: the hang glider's test with index 0 in the Pilot class (cls 3, CLASS_PILOT). There, from 240 on the clock D_8034F850 (by the decompilers' comment, the current time; the test's setup, gameUpdateStateTestSetup, sets it to 0, and each time func_80313D74 runs it adds the time since the last frame held between 0.01 and 0.1, so it counts seconds of game time), therm_8034695C narrows the drawn cylinders to nothing over the next 10, and at 250 (THERM_DISABLE_TIME) removes the thermals and shows TEXT_THERM_OFF. The narrowing scales only the model's matrix: the updraft reads the task's radius until the thermals are gone. pw64/thermal-cutoff

About: Pilotwings 64 Thermal

Value: 250 seconds

Codepw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/thermals.c#L14-L18#define THERM_ENABLE_DURATION (4 * 60) // 4 minutes in sec #define THERM_WEAKEN_DURATION (10) #define THERM_DISABLE_TIME (THERM_ENABLE_DURATION + THERM_WEAKEN_DURATION)pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/thermals.c#L98-L101sThermShouldDisable = 0; temp_v1_2 = &D_80362690->unkC[D_80362690->unk9C]; if ((temp_v1_2->veh == VEHICLE_HANG_GLIDER) && (temp_v1_2->cls == 3) && (temp_v1_2->test == 0)) { sThermShouldDisable = 1;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/task.h#L53-L56CLASS_BEGINNER = 0, … CLASS_PILOT = 3,pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/thermals.c#L114-L140var_fs0 = 1.0f; … if ((D_8034F850 >= THERM_DISABLE_TIME) && (gThermalCount != 0) && sThermShouldDisable) { thermDeinit(); gThermalCount = 0; gThermReady = 0; hudWarningText(TEXT_THERM_OFF, 1.5f, 8.0f); … if ((D_8034F850 >= THERM_ENABLE_DURATION) && (gThermalCount != 0) && sThermShouldDisable) { var_fs0 = (f32)(1.0 - (f64)((D_8034F850 - THERM_ENABLE_DURATION) / THERM_WEAKEN_DURATION)); … sp74.m[0][0] = taskTherm->scale * var_fs0; …pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/thermals.c#L182-L184if (taskTherm->scale < dist) { continue; }pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_9A960.c#L8f32 D_8034F850 = 0.0f; // current timepw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_9A960.c#L210-L221void func_80313D74(void) { … temp_fv0 = uvGfxGetFrameTime(); if (temp_fv0 < 0.01f) { D_8034F854 = 0.01f; } else if (temp_fv0 > 0.1f) { D_8034F854 = 0.1f; … D_8034F850 += D_8034F854;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/game.c#L431-L545s32 gameUpdateStateTestSetup(Unk80362690* arg0) { … func_80313E0C(0.0f); … return GAME_STATE_TEST_UPDATE;pw64: a decompilation of Pilotwings 64 (n64decomp/pw64) · src/app/code_9A960.c#L225-L227void func_80313E0C(f32 arg0) { D_8034F850 = arg0;Checked by claude, 2026-10-22 — read the three defines, the end of thermLoad, the class enum, therm_8034695C whole, the radius test in therm_80346C08, the clock's definition, func_80313D74's addition, func_80313E0C, and its call in gameUpdateStateTestSetup; no VERSION_JP conditional encloses these lines

func_80313D74 is called from game.c and a dozen other state updates; the atlas hasn't shown it runs exactly once per frame, so the clock is stated as the sum of its calls. Which test index 0 is in the game's numbering (most likely the class's first) isn't checked against the game. Whether the clock runs while paused isn't read. The radius test in therm_80346C08 and therm_80346E04 read sTaskTHER's scale, not the drawn matrix.

Cited by: Pilotwings 64

In a recording of the PAL version, Pilotwings 64's ending credits list a "Nintendo Staff" group, directed by Makoto Wada, then a separate "Paradigm Staff" group under project manager Dave Gatchel, and end on "Presented by Nintendo"; the credits never name Nintendo EAD. pw64/credits

VideoPilotWings 64 (N64, PAL) full-game longplay, with the ending credits · 1:15:27 — DIRECTOR / MAKOTO WADA at about 1:15:34NINTENDO STAFFPilotWings 64 (N64, PAL) full-game longplay, with the ending credits · 1:16:09 — PROJECT MANAGER / DAVE GATCHEL at about 1:16:16PARADIGM STAFFPilotWings 64 (N64, PAL) full-game longplay, with the ending credits · 1:18:49PRESENTED BY / NINTENDOThe Making of Pilotwings 64Nintendo handled the game design while Paradigm was responsible for the technologyChecked by scout, 2026-10-22 — read from frames of the pinned video at 1–3 s steps; no claude re-read of the frames

A recording of the game is a secondary source here, so the claim is T1; the credits screen itself would be primary. The Nintendo Life article's profile box lists "Nintendo EAD", the only place the scout found that name.

Cited by: Pilotwings 64