forked from Ports/goldeneye-pc-port
- V0.4.0-PLAN: 2026-09-27 refresh (M-wave state, D393-D397 session additions, M7 deferral decision). - README: known-issues + options documentation for the landed crosshair/controller/options work. - GRAPHICS-BACKLOG / porting-notes: D392/D397 and crosshair entries. - .gitignore: per-landing sweep capture dirs.
30 KiB
30 KiB
GRAPHICS-BACKLOG — known cosmetic / rendering issues
Deferred below level-progression and crash work (user priority, M-11). Minor graphical glitches are acceptable in the current state. Fix these once the game is playable start-to-finish without crashes.
Open
| ID | Symptom | Status / notes |
|---|---|---|
CLOSED — NOT A BUG (M-33, §F D168). The GE_PCDUMP PPM writer never reversed glReadPixels rows, so every capture was upside-down; "mirrored" was a misread of inverted asymmetric content. The game renders correctly on hardware (developer-confirmed). Writer fixed (gfx_opengl.cpp). "Every stage verified non-mirrored" was correct — there was no mirror. |
||
gfx_pc.cpp:1546/1551 PORT block is dead code (guard cms & G_TX_WRAP always false; indexes per-texunit arrays with the vertex index → OOB if reached). |
RESOLVED (M-30, RC3/D167). The in-vertex-loop wrap block was reworked and hoisted to a per-texunit pre-wrap window (gfx_pc.cpp ~1574, now cms-correct and indexed by texunit not vertex), behind the Video.WrapFix knob (default OFF). No longer dead code or OOB. See §F "RC3 · D167". |
|
| D392 | In the opening attract-mode Train demo, a soldier consistently looks more hunched on PC than in 1964/GEPD; his hand intersects his body at the wrong position. User comparison: docs/img/animation-glitch-pc-port.png and docs/img/animation-glitch-1964gepd.png. |
FIXED — user visually verified (D392). Train's normal opening (-level_25) has a central firing guard (chr=5) whose torso/shoulder aim offsets reached aimupback=-0.855, shoulder=-0.606,+0.868 radians by tick 100. chrlvUpdateAimendbackShoulders used N64 ((f32*)arg1)[12/13/16/17] offsets into a firing table whose first member widens from a 4-byte to an 8-byte pointer union on PC; it read other floats and bent the torso/arms to wrong angles. #ifdef PORT now reads max_up/max_down/free_arm_frac_up/free_arm_frac_down by name; with the same short Train intro probe the torso offset stays 0, shoulders ~0.028/+0.014 at tick 100. User's original comparison: docs/img/animation-glitch-pc-port.png vs docs/img/animation-glitch-1964gepd.png. The user subsequently confirmed the soldier's pose looked fixed in-game; this session's image tool itself cannot display PNGs. No ramrom demo override needed; ordinary -level_25 reproduces. |
| D75 | Nintendo logo + GoldenEye logo + legal page FIXED (M-197, user-confirmed live 2026-09-21). Root cause: the D50 sidecar converter (tools_pc/d43_emit.py) reserved + remapped the model's embedded texture-blob span but never copied the pixel bytes into the emitted RZ image → TEXEL0 sampled a zeroed buffer → the texture-modulate logo rendered black (M-195/M-196 had proven emission/transform/combiner all correct). Same latent bug hit PgoldeneyelogoZ + PlegalpageZ. Fix = tooling-only (blob raw-copy + round-trip check); ntsc sidecars regenerated; logo window now renders 23k px (7.59%) vs 0–33 pre-fix. Gun-barrel Bond renders correctly (M-33). Cast roll still unverified — recheck with GE_PCDUMP="1400-2200:25". findings.md §F D75 (M-195/M-196/M-197 updates) + M-197 at file tail. |
|
| D76 | 2D disclaimer screen only partially drawn. | §F D76. |
RESOLVED (M-104, PR #42) — in-level music now plays. Root cause was a D6-class missing return in sub_GAME_7F0C0BF0 (mp_music.c) that zeroed the seqp volume on the only in-level trigger path; menu/intro music bypassed it and was always fine. The remaining audio-quality gap (wrong-sounding instruments on some tracks — elevator named specifically — plus occasional garbling) is tracked as D230. §F D77/D230. |
||
| CLOSED — NOT A BUG (M-33, §F D168). Same capture-orientation artifact as D114. | ||
| D148 | Level-end cinematics glitch. Dam: the Bond rappelling/bungee cutscene plays but the camera violently shakes and Bond's own model appears to duplicate/glitch. Cutscenes are buggy in many places across the game (D173 level-start floating, D292 death-sinking, Cradle spin) — treat D148/D243 as the tracking entry for the whole cutscene-reliability problem, not just Dam. | 2026-09-17 (D243 M-107 through M-168, ~18 session-passes): the mechanism is now understood in real depth, and the camera-shake half is fixed (diagnostically, live-confirmed). Full history + code citations: docs/dev/findings.md ## D243 (long, multi-pass — look up via findings-index.csv, read the M-159 through M-168 paragraphs for the current understanding, don't linear-read). Short version for planning purposes: (1) Root mechanism — the cutscene teleports the visible Bond chr between shot positions correctly (AI_TRYTeleportingChrToPad, chrai.c:4064), but the actual rappel animation commands run on a separate, invisible driver chr (M-145) — the visible chr never gets told to play it, so it just keeps ticking whatever animation it already had equipped before the cutscene grabbed it. Every tick, that stale animation's own root motion gets read back into the chr's render position (chrUpdateAnim→getsuboffset, model.c:684), producing a small repeating cycle that reads as "shaking"/"glitching" on screen. Whether this exact mechanism is itself decomp-faithful (with the real PC/N64 divergence being which animation phase Bond happens to inherit at the cutscene boundary, not a code-path bug) is still an open question (M-165/M-166) — not yet answered. (2) Two independent render paths, not one bug — the camera's look-at filter reads field_488.pos (derived from render_pos, the model's animated-skeleton transform); the model's own on-screen draw reads render_pos directly (objecthandler.c's drawjointlist). Fixing one does not fix the other; two live-test cycles were spent learning this the hard way (M-162/M-163 → M-167). (3) Camera shake: FIXED at the mechanism level, live-confirmed by the user ("camera shake is gone now") by freezing field_488.pos during the cutscene (GE_D243X3, bondview2.c:10495) — diagnostic-only, not shippable as-is (see next). (4) Bond's own model duplication: mechanism-level fix attempted (GE_D243X4, chr.c, freezing render_pos's contents) — stable after fixing two crashes (model-pointer-reuse hazard, see porting-notes.md's two D11 updates), but freezing unconditionally also breaks the cutscene's legitimate per-shot camera/model repositioning (the camera now looks the wrong direction for later shots; Bond still looks stuck) — not a fix yet. Next steps for whoever picks this up (none attempted yet): (a) re-baseline the GE_D243X3/GE_D243X4 freeze on a position-delta threshold (a jump much larger than the observed intra-shot cycling amplitude, already characterized in the M-153/M-160 captures, is very likely a real shot-change teleport, not cycling) instead of freezing forever; or (b) hook the freeze/re-baseline directly to AI_TRYTeleportingChrToPad firing, the precise, unambiguous signal for "a legitimate reposition just happened"; (c) separately, find the actual N64-vs-PC divergence point per M-165/M-166 (log aidx=/animframe=, already wired into D243M: onscreen) to determine whether a real, permanent fix is even a port/-layer timing correction or needs a rule-2 sign-off for a genuine behavioral difference — this determines which of (a)/(b) is worth turning into a real fix vs. a stopgap. |
| CLOSED — user-verified fixed (M-87 playtest). No longer reproduces; presumably fixed as a side effect of other front-end/D75-family work since M-49. D75 family. §F D146. | ||
| D170 | Named-NPC "flee" scripted behavior looks wrong on PC: on Silo, Ourumov breaks into a full run the instant he alerts ("Ourumov: Kill him!") rather than the N64 walk/retreat; developer reports Trevelyan behaves the same way on Cradle. M-49 full playthrough: escalated — Cradle (-level_51) is "bugged out completely" from Trevelyan's behavior; the final level's scripted progression breaks. Now folded into / superseded by §F D193 (NPC AI locomotion too slow). |
Observed, not investigated (M-34, from a Silo playtest capture; user bug report — no fix wanted yet). Could be a genuine ailist / chrTick divergence, OR the D155/D156 wall-clock deltaFrames locomotion-anim speed-up (a catch-up spike playing the walk cycle at 2–3×). Verify first: capture the same beat against N64 reference footage before assuming it diverges — Ourumov may be scripted to flee. If it's real, suspect the frametiming clamp (§F D155/D156) or the Cradle-family AI path (§F D123). |
| D171 | Silo missile-shaft: a large triangle sweeps across the frame while panning down the shaft. Promoted to docs/dev/findings.md §F D288 (M-141) with a user-reproduced, precisely-bounded, visually-documented repro (frames ~562-741 of a bare -level_20 boot) — read that entry for the current state, not this row. |
See D288. |
| D172 | Bullet-impact / blood particle spray renders magenta or cyan instead of dark red (visible on guards hit at close range on Silo). | M-82: ROOT CAUSE FOUND + FIXED (PR #34). GE_D172 probe on a user Silo firefight: 40/40 particle tris configure tile 1 = RGBA16 fire @ tmem 392 but fast3d samples tile 0 (smoke) for both texunits — gfx_lod_tile_offset() returns 0 unconditionally (D107 blurry-ceiling fix; video.c:225 disables gfx_detail_textures_enabled). G_CC_INTERFERENCE = smoke*smoke → magenta/cyan. Fix: return rdp.tex_lod ? 0 : i — only fold to base tile for real LOD/mip draws. (0xB9 + cycle-type were both false trails, ruled out earlier in M-82.) Owed: in-game eyeball — blood should be dark red. Detail: D172-PARTICLE-COLOR-RESEARCH.md. |
CLOSED — user-verified fixed (M-87 playtest): "main menu text is good now." No longer reproduces. M-36 triage below kept for reference. M-36 triage: the objective lines are BLANK, not wrong. GE_STARTMENU=10 Dam briefing renders the header fine ("OHMSS / Agent: James Bond / Mission 1: Arkangelsk / Part i: Dam / PRIMARY OBJECTIVES:") then just the bullet "a." with no text and no b/c/d. → D143/D151 blank-text family (langGet() → NULL → silent blank), not a propDef walk / difficulty decode. Family B in docs/dev/M-36-TRIAGE.md — find which lang bank the front-end briefing flow fails to load. Re-confirm the exact shape in a real briefing (the GE_STARTMENU boot skips real save state). Close relatives: D151 (watch objective text blank — type-35/23 text slot u16→u32 fix, M-28; interactive re-verify was still pending), D143 (briefing/objective text blank via langGet NULL), D157 (objective difficulty byte offset — could make difficulty-gated objectives appear/disappear wrongly). The pre-start briefing is a different surface from the in-level watch, so D151's fix may not cover it. Next: ask user which level + what exactly shows vs expected; compare against docs/dev/LEVEL-OBJECTIVES.md (regenerated post-D157); if lines are blank → D143/D151 family (langGet NULL guard = silent blank), if wrong objectives listed → propDef type-23 record walk / difficulty decode. |
||
| D175 | In-game stutter / brief hang during normal play — observed opening a door on Runway (mission 3, -level_35) and also on Surface. No backtrace captured (gdb attach missed the window; it self-recovered). |
Observed, not investigated (user QA report). Matches known transient-hang classes rather than looking new: D155 (post-slow-load catch-up spiral — clamped), D156 (anim NaN loop — guarded, prints one-shot stderr diag if it fires), D134 (SP/DP task-done event swallowed — fixed M-22, Runway was an original victim), D147/D152 (audio s_imLock steal = ~2 s hiccup). Door-open specifically = new room first visible → one-off texture-import/frame spike (likely benign). Next: reproduce under tools_pc/debug.ps1 with the box idle; check console for the D156 stderr diag; if it recurs, attach gdb mid-hang and pattern-match bt (import_texture = benign slow frame; model.c:3131 spin = D156; pthread_mutex_lock on s_imLock = D147/D152). |
| D176 | Surface exterior renders wrong (two co-located defects). (a) Sky is solid black — the skybox / sky gradient does not draw at all (reference: warm sunset cloud gradient). (b) The perimeter tree-line backdrop renders as grey TV-static / comb interlacing instead of snow-laden pines — the geometry is present and roughly the right silhouette but every tree texture is scrambled noise. Ground, tunnel and the dish/bunker building draw fine. | Observed, screenshots committed (M-35, user QA; docs/img/bugs/d176-surface-exterior-our-build.png vs -reference.png). Level is the shared Surface exterior — user reached it Dam→Surface on Agent so this is Surface (i) -level_36 (confirm it also affects -level_43). (a) black sky: M-36 partial (findings.md "D176(a)"). Env data is correct (Sky.Clouds=1, CloudRGB=240,120,30, SkyImageId=0); skyRender runs the cloud path and classifies corners correctly (switch case 12), but skyRenderTri/skyRenderFull emit nothing — not even the env->RGB fill shows. Not root-caused: next is probing sub_GAME_7F097388 projected coords, verifying skywaterimages[0] resolves on PC (image_bank.c GIMG offset 0xFB4), and a fast3d sky-tri trace. GE_D176=1 probe shipped. M-37: ROOT-CAUSED — skyRenderTri/skyRenderFull build geometry exclusively as G_RDPHALF_* immediates, which gfx_pc.cpp deliberately no-ops (identical no-op in the PD port); fix = decode the RDPHALF tri-raster stream in fast3d (~1 session, genuine new code). M-42: -level_22 (Statue) confirmed a clean headless repro — bare boot, frame ~360, upper half pure black; use it to verify the decoder. M-47 + read-only consolidation: Path B draft exists (scratchpad/sky.patch, skyPortRenderPoly PORT hook — geometry+texture reach GL, two unit defects open) and the full RDPHALF wire format is now decoded (S15.1 half-packing, 8-component perspective-interpolated vertex vectors); next session is mechanical per docs/dev/D176a-SKY-NOTES.md. -level_36/-43 intro cams face down (not a sky test without GE_INPUTSCRIPT). M-82: PR #18 rebased onto main + Defect-1 fix applied — cloud tile is s_skywaterimages[0] = 64×64 IA8; the patch's tc = S·32 scale is correct (matches GE's width<<5 idiom, glass2.c:678), the bug was (s16) overflow on the ±20k-texel horizon S/T; fix = per-primitive phase-fold to the 64-texel period (sky.c skyPortRenderPoly, #ifdef PORT). Builds clean, no crash (bunker1/statue/surface1 verify PASS). Unverified visually — owed: one -level_22 screenshot (see D176a-SKY-NOTES.md "verification ask"). Defect 2 (horizon-band coverage / straddling tris) still open → adaptive tessellation. (b) tree/rock static: M-36 triage — NOT the D159 family. texSwapAltRowBytes is a full #ifdef PORT no-op (image.c:2199), it cannot cause this. Real cause: port/fast3d/gfx_pc.cpp import_texture_* assume line_size_bytes == full_image_line_size_bytes (SUPPORT_CHECK; rgba16's is commented out "trips ... with a garbage size" :658) → non-PoT / sub-rect tiles get a flat linear read → diagonal row shear = grey static. Family A in docs/dev/M-36-TRIAGE.md. Fix: honour line_size_bytes as the real source pitch. Same defect as D182(2). |
FIXED + VISUALLY VERIFIED (M-107 fix, M-108 verify). port/fast3d/gfx_pc.cpp gfx_sp_tri1 was trivial-rejecting visible triangles that had a behind-camera (w<0) vertex. Status cell here was stale at "not investigated" — corrected M-119. §F D233. |
||
| FIXED + VISUALLY VERIFIED (M-108). Same underlying mechanism as D233. Status cell here was stale at "not investigated" — corrected M-119. §F D234. | ||
| D235 | Wrong textures load after dying/restarting a level — clarified: not Facility-specific, seen on multiple levels; trigger is death/restart (level reload), not a general build regression. | Observed, not investigated (M-106, user QA report, clarified same session). This is a state-leak on level re-entry, not a one-level texture-decode bug — prime suspect is the texture pool / CI-cache (D217/D228 neighbourhood) not fully resetting between a level teardown and reload (stale arena base, a palette-cache entry keyed by a reused address, or a texpool index not rewound). Needs: confirm it does NOT repro on a fresh level boot (only after death/restart); which surfaces; a screenshot. Next: instrument texInitPool/the CI-cache clear path for what does/doesn't reset on reload vs cold boot. |
| D236 | Surface 1: the 2D billboard trees that appear at the start of the level and around the map don't draw as discrete tree sprites — they render as a wall/sheet of tree texture instead of the proper 2D tree objects. | FIXED (M-198, pass 26) — awaiting user play-test sign-off. Root cause was a texture-BINDING bug, not decode/alpha/mip/geometry: GE binds the four Surface 1 treeline cards (tex1198-tex1201, RGBA5551 64x17 cut-outs) as TEXTURETYPE_DETAIL, where texHandleType1 (tex.c) loads the detail texture at TMEM 0 and the real base image at TMEM texGetSizeInBytes(detail,0) on tiles 1+. fast3d's gfx_lod_tile_offset folded every G_TL_LOD draw to tile 0 (D107, correct for TEXTURETYPE_LOD/MIPMAP), so the port drew the shared detail texture -- tex2465, an opaque 32x32 IA8 noise tile, which is exactly the 'noise painter' D267/D276 measured at 1023/1024 texels opaque -- and never imported the cards at all. Fix: when a tile pair differs in both TMEM address and fmt/siz under G_TL_LOD, sample the base image (tile 1). Video.DetailBaseTile, default on. Live-verified on Surface 1 (discrete snow-covered pines) and Surface 2; Depot clean; bunker1 golden bit-identical with the fix on/off; type=1 bindings exist only in sevx/depo/sevb/sev, so every other level is provably untouched. Full trail: findings.md D236 pass 26; generalised as porting-notes.md §D12. |
| D249 | Streets and Egyptian (the two biggest/most-open levels) show culling problems on far-away geometry at default FOV — distant geometry drops/pops incorrectly. Also a QoL ask: improve LOD in general, but gate it behind a toggle so N64-accurate ("old school") LOD stays selectable. | Observed, not investigated (M-119, user QA report). Distinct from D222 (high-FOV near-edge culling) and D218 (fog/far-clip tint). Two candidate mechanisms: (a) portal/room-visibility cutting off too aggressively at range on large multi-room layouts (D233/D234 neighbourhood — check for a far-plane/depth-range sibling to D233's w<0 trivial-reject fix), or (b) GE's own LOD/detail-swap system not ported faithfully (mip-tile / simple-model substitution at distance, gfx_lod_tile_offset family). First checks: GE_PCDUMP a long sightline on Streets/Egyptian where geometry visibly pops; determine which of (a)/(b) is firing before designing the fix or the requested toggle. §F D249. |
| D217 | 1P weapon viewmodel + character-model CI textures render with a wrong palette on many levels / multiple weapons — PP7 grip + hand render flat green on Facility & Depot, "weird or missing" gun textures elsewhere; Bond's watch face too. Surfaced by D215 (viewmodel now draws). Clean on Bunker1. | Defect ① FIXED (M-90), pending human playtest eyeball — full detail in findings.md §H "D217 — M-90" and §F D217. Root cause: weapon texpool arena bases land %8==4 on PC (memp bump drift from pointer bloat); texAlignIndices absolute 8-byte row padding then shifts every palette 4 bytes early while model-DL G_LOADTLUT reads the N64 offset (grip count=1 load lands on next tenant's header slot → 0x1A00 green; larger loads read a 2-entry zero pad — the M-86 tell). Fix: texInitPool rounds the base up to 8 under #ifdef PORT (no-op on N64); 21/21 sweep PASS. Two defects: ① visible green = misaligned texpool arena (fixed as above). ② CI texture-cache collision (no palette-content key) — proven, fix landed on branch fix/d217-model-texture-palette f6fc0399 (palette FNV-1a hash in the CI cache key), owes a 21-level verify.sh sweep; does not fix ①. |
| D174 | "No blood effect" — user reports no visible blood when shooting guards / into surfaces. | User QA report; likely D120, unverified. Decals: the D120 PointUsage[] converter fix (M-30) was never interactively verified and only takes effect after a full sidecar regen (d43 && d69 && d88 --regen) — check whether the playtest build had regenerated sidecars before concluding the fix failed. Spray: D172 observed the particle spray drawing (wrong color, magenta/cyan) on Silo — if the user sees no spray either, that's new info (different weapon/range, or the D172 decode is worse than "wrong color"). First step: BUNKER1 firefight with regenerated sidecars; if decals still absent, instrument the chr.c:3328 decal walk. |
| D173 | Third-person Bond model (the player-representing figure shown at level start) spawns too high — floats well above the ground "a lot of the time" while the actual player spawn is correct. Same symptom on the Cuba end credits: JB stands ~6 ft in the air above Natalya. | Confirmed still present across the full 21-level playthrough (M-49). Observed, not investigated (user QA report). D75 animated-model family but a position defect, not absence — M-33 confirmed the gun-barrel Bond renders fine upright. Suspects: (a) intro/credits puppet chr spawn position vs the model's base transform; (b) anim root-motion accumulation (modelSetAnimFrame2WithChrStuff, D156 area) offsetting the rendered joints above the body origin; (c) a coord3d/packed-float decode in the intro camera/model setup. "Player spawning is OK" localises it to the render-side model, not g_CurrentPlayer state. |
| D182 | SELECT FILE screen degrades after navigating away and back (main menu → file select, or backing out of file select and re-entering). On the fresh screen the 007 gun-barrel spiral / Bond silhouette renders behind the file boxes; after a round-trip the Bond image stops drawing entirely and the whole background gains the comb / interlacing artifact (horizontal line scramble). File boxes, text and the Copy/Erase icons still draw. | Observed, screenshot committed (M-35, user QA; docs/img/bugs/d182-file-select-backout-20260902.png). Two symptoms, likely linked: (1) background 3D image stops rendering after re-entry → a front-end model/DL whose render_pos / segment binding is only valid on first construction (D149 / D75 constructor_menuXX family — the dossier/wallet models have the same "renders once" behavior). (2) interlacing = M-36 triage: Family A, the import_texture_* line vs full_image_line shear (see D176(b) / docs/dev/M-36-TRIAGE.md) — not the D159 texSwapAltRowBytes path (that is a full PORT no-op). Open question: why only after a round-trip — first import may land line == width, re-import may not, or the tile descriptor is stale on re-entry. Repro: GE_STARTMENU to file-select, back out with ESC/B, re-enter; GE_DTEX on the spiral texture across both visits. Shares defect (2) with D176(b). 2026-09-27 (D397): user re-reported the comb/interlace on the file-select background AND on the intro gun-barrel — the latter is a first-time render, so the defect is persistent (not only after a round-trip), refuting the "stale descriptor on re-entry" hypothesis. D159 (odd-row swap) is no-op'd and D183 pitch shear is disproven for level_36 + a no-op for the 299×440×1 row-strip. Next step is a live GE_PCDUMP capture + ROM ground-truth decode of the gun-barrel RLE image to separate ground-truth dithered content from a GL sampling/texture-cache artifact. See findings.md D397. |
| D197 | Character face/head textures wrap wrong — the face texture repeats around the side of the head "and continues weird" instead of clamping to the front. Seen on Silo (M-49 playtest), intermittent ("sometimes"). Reads as G_TX_CLAMP not honoured for the character-skin tile in fast3d (→ GL_REPEAT, so the face UV region tiles around the skull), or wrong shifts/shiftt / LOD-tile selection on the head texture, or the D167 non-PoT wrap-period issue (head textures are often non-PoT) hitting skinned models. |
Observed, not investigated (M-49, user bug report — needs a capture + which chr/level). Distinct from D176(b)/D182(2) (those are bg wall pitch shear). Related: RC3/D167 (Video.WrapFix, non-PoT wrap period) + the texWriteTileLods shifts=shiftt=lod note in findings §F "D176(b) → 4. candidate 2". First checks: does gfx_pc.cpp map N64 cms/cmt G_TX_CLAMP → GL_CLAMP_TO_EDGE for character DLs; is the head tile getting the base tile vs an LOD tile (D107); try Video.WrapFix=1 on a repro. |
| D195 | Transparency / alpha-blended surfaces render wrong — reported on Control (Severnaya bunker basement — Natalya's console room; heavy on glass partitions and the translucent projected/holographic wall displays). Exact failure mode not yet pinned by the reporter (M-49 playtest): candidates are alpha-blended geometry drawing fully opaque, translucent panels drawing invisible, or draw-order/sort so translucent surfaces occlude what's behind. | Observed, not investigated (M-49, user bug report — needs a GE_PCDUMP capture + which surfaces). fast3d render-mode / combiner path. Same neighborhood as D161 (CI8 tile + G_TT_NONE → garbage), D172 (particle-sprite channel order), D176(b) (texture pitch shear) — but this is a blend/alpha defect, not a texture-decode one. Note D128 already touched Control's specialportalarray (portal struct stride) — check whether the affected surfaces are portal-adjacent. First checks: does gfx_pc.cpp honour G_RM_* XLU render modes + G_AC_THRESHOLD/G_CC alpha for these DLs; is gDPSetRenderMode w1 being parsed (cf. findings §F "zbuf-clear w1 scribble"); is Z-write-vs-blend ordering right for XLU surfaces. Get the reporter to say: opaque-where-should-be-clear, invisible, or wrong edges? |
| D252 | Particle effects cycle through a rainbow palette — bullet-impact sparks and lingering smoke/explosion residue drift through the full hue wheel over time (~10 shots to sweep it) instead of holding their intended grey/orange palette (M-124, user playtest). Full mechanism + suspect in findings §F D252: colour comes from 15 distinct IMAGE_SMOKE_N×IMAGE_FIRE_N (RGBA16) pairs the particles age through; prime suspect is import_texture_rgba16 deriving width/height from the tile line size (32×7 instead of 16×14 for the fire tiles), scrambling each stage's sprite into a different wrong hue. |
Documented only — not fixed for v0.2.0-pre (user instruction). Confirm with one dumped fire tile vs raw IMAGE_FIRE_N bytes, then derive width/height from the LOADBLOCK dtx/dlh. D172/M-82 lineage. |
| D323 | Distant geometry on 15 levels samples driver-generated mips from the finest texture level; N64 samples Rare's hand-authored mip chain for explicit-LOD textures bound under G_TL_LOD (heaviest: Statue 378 binds, Aztec 806). Overwhelmingly CI8/IA8 — subtle fidelity gap, no reported artifact; the only RGBA5551 cut-outs are the D236 set (already handled). |
OPEN / parked — mechanism confirmed, census in tools_pc/bg_lod_audit.py, fix path documented in findings §F D323 (upload GL mip chains for TEXTLOD-on bindings). Not worth doing speculatively; revisit only if a playtest flags mushy distant detail. |
| D335a | RESOLVED 2026-09-23. Gun-barrel backdrop (Bond's spotlight) leaked into the pillarbox bars while sliding in from off-canvas. Fix: menu_jump_constructor_handler emits a full-canvas gDPSetScissor right after the CENTER wrap (only when wider than 4:3), which fast3d squeezes to the pillarbox, so off-canvas draws clip at the 4:3 edge as the N64 RDP clips at the screen edge. Verified with a 16:9 barrel capture. |
|
| D335b | Native widescreen: the F10 options overlay still stretches with the window (legible, pre-existing look). Pillarboxing it needs optionsoverlay.c's click mapping (gfx_get_ui_screen_rect) remapped into the centred region in step. Polish, post-playtest. |
|
| 1P weapon viewmodel | RESOLVED (M-83, D215). In-level first-person weapon models drew nothing. Root cause: gunRenderFirstPersonGunModels built its ModelRenderData via *(ModelRenderData*)&D_80035CC0 — a reinterpret across two separately-declared adjacent globals that only lands right on the N64 linker + 4-byte pointers; on x86-64 renderdata.flags read 0, gating every weapon DL node off in modelRenderNodeGundl. All 3 ranked suspects in VIEWMODEL-RESEARCH.md were ruled out first by the GE_DVM=1 probe. Fixed #ifdef PORT (explicit field init). subdraw 1→153 gfx cmds; owed one BUNKER1 eyeball. |
Resolved (for reference)
- D70–D74: intro-logo pixels (Rareware logo renders correctly).
- D103: viewport / native-resolution half-frame.
- D105: room geometry Z-buffer never cleared (
G_CLEAR_DEPTH_EXT). - D106: sky-void through doorways (portal near-plane min>max).
- D107: blurry ceilings/wall-panels (LOD mip tile fabrication).
- D112: skeletal models were "3D lines" (
d43_emit.py put_f32byte order).