diff --git a/docs/ROADMAP.md b/docs/ROADMAP.md index 52400af0..3252a3d6 100644 --- a/docs/ROADMAP.md +++ b/docs/ROADMAP.md @@ -106,11 +106,11 @@ below). | Multiplayer isn't available yet | Missing feature | **Fixed on `release/v0.4.1`** (2–4 player split-screen, merged 2026-10-01); delete this row when it ships | #99, §1 | | PAL and JP ROMs aren't supported | NTSC-U only | Use an NTSC-U ROM | D258, §1 | | `All unlocked` may already have written fake unlocks into a save from an older build | Save corruption | **Fixed on `release/v0.4.1`**: `All unlocked` is now a RAM-only override (D442) and never writes the save. Fakes an older build already wrote are not repaired; back up `data/ge007.eep`. Delete this row when it ships. | D442, D387, §5a | -| `Game.SkipIntro` also skips the post-mission failure dossier | Minor | Leave SkipIntro off | D408, §2 | +| `Game.SkipIntro` also skips the post-mission failure dossier | Minor | **Fixed on `release/v0.4.1`** (D408, maintainer-verified 2026-10-02); delete this row when it ships | D408 | | F10 overlay stretches in native widescreen (menus pillarbox correctly) | Cosmetic | **Fixed on `release/v0.4.1`** (D472 pillarboxes the overlay card); delete this row when it ships | D335b, D472, §5a | -| Rareware logo shows a subtle texture-filtering artifact | Cosmetic | — | D75, §2 | +| Rareware logo shows a subtle texture-filtering artifact | Cosmetic | **Fixed on `release/v0.4.1`** (D75: the RAREWARE text was scrambled by a missing RDP odd-row TMEM swap; maintainer-verified 2026-10-02); delete this row when it ships | D75 | | Steam Deck: a first launch in Desktop Mode skips the Deck preset | Settings | **Fixed on `release/v0.4.1`** (real-Deck check owed); delete this row when it ships. Until then: first launch in Game Mode, or delete `ge007.ini` and relaunch | D283, §4 | -| ~30 fps on very low-end GPUs (e.g. Intel HD 400) | Performance | Set `Video.LowEndMode=1` in `ge007.ini` | D339, #92, §4 | +| ~30 fps on very low-end GPUs (e.g. Intel HD 400) | Performance | **Fixed on `release/v0.4.1`** (D481 render worker; an Intel HD 3000 laptop went from ~45 to 60 fps; D482 lowers draw/LOD distance and MSAA once on Atom/Celeron-class GPUs). Not yet confirmed on N3060-class hardware. Delete this row when it ships | D339, D481, D482, #92, §4 | | No macOS or ARM builds | Platform | — | #88, #95, #101, §4 | | Controller buttons can't be rebound in-game (keyboard/mouse can) | Missing feature | **Fixed on `release/v0.4.1`** (D469, F10 → Input → Controller); delete this row when it ships | D469, #109, §5a | @@ -120,8 +120,8 @@ below). | Item | Status | Refs | Notes | |---|---|---|---| -| **2–4 player split-screen multiplayer** | verify | #99, D416–D423, merged into `release/v0.4.1` 2026-10-01 (from `mp/virtual-seats`) | Merged 2026-10-01. D417 Rule-2 approved. Maintainer live test: every MP map in 2P (2–4 kills per map, each player scored), 4P Temple, two Xbox pads mapped P1/P2. Headless 2P/3P/4P pause, watch-menu pages, exit-confirm and F10-overlay runs clean. D420 fixed (Scores overrun), D421 closed (moot: no MP gadgets), D423 closed (faithful shadow). Still owed: 3P/4P with real pads, pads-only mode, MP audio, the full N64 MP setup screens (scenarios, handicaps, teams), D422 centred aim live on P2+ (`AimMode = 1`), D428 sway on P2+, and whether the `GE_STARTMP` harness skips something the ammo counter needs (seen only in harness launches). Per-pad seats (§5) done (D448/D450). | -| **PAL and JP ROM support** | open | D258, D75 (pal/jpn sidecar regen), #85 | **Scheduled for Stage B (decided 2026-09-30):** done just before 1.0 so that region-specific issues can be unwound in isolation. Conversion is broken at the source-data level (filelist naming). A repair path has been verified but not applied. Needs PAL/JP ROMs to test. #85 was closed as "retired for now", not won't-do, so public users currently have no tracker. Reopen it or file a fresh one when work starts. | +| **2–4 player split-screen multiplayer** | verify | #99, D416–D423, merged into `release/v0.4.1` 2026-10-01 (from `mp/virtual-seats`) | Merged 2026-10-01. D417 Rule-2 approved. Maintainer live test: every MP map in 2P (2–4 kills per map, each player scored), 4P Temple, two Xbox pads mapped P1/P2. Headless 2P/3P/4P pause, watch-menu pages, exit-confirm and F10-overlay runs clean. D420 fixed (Scores overrun), D421 closed (moot: no MP gadgets), D423 closed (faithful shadow). Still owed: 3P/4P with real pads, pads-only mode, MP audio, the full N64 MP setup screens (scenarios, handicaps, teams), D422 centred aim live on P2+ (`AimMode = 1`), D428 sway on P2+; the harness-only missing ammo counter was the `GE_STARTMP` shortcut skipping file-select's `selected_folder_num = -1` (fixed, D479). Per-pad seats (§5) done (D448/D450). | +| **PAL and JP ROM support** | partial | D258, D487, #85 | **2026-10-02: both regions convert, build and boot** (D258 fixed and byte-verified against real PAL and JP ROMs; region-aware emitters and ROM detection; PAL link fix). Both play Dam with no crash; NTSC-U unchanged (`verify.sh dam` PASS). Build: `BUILD_DIR=build-pal ./build-pc.sh pal-final` / `build-jpn ... jpn-final`, with `data/ge007..z64` and the emitters run for that region. **D487 fixed 2026-10-02** (PAL frame height decoded with the NTSC rule cut the bottom ~12% of every PAL frame). **D488 fixed 2026-10-02** (PAL build now reports the PAL TV type, not Brazil's MPAL). **Open:** full runtime passes per region (all levels, menus, audio, saves; PAL 50 Hz feel incl. the D427/D451/D486 2-ticks/frame gates; EU-only text paths); packaging (per-region exe names, CI matrix, drop-in converter region gate, #6). ROMs: `ge-port-reference/1964_GEPD_Edition/ROMs` (JP .n64 = v64, PAL `.z64`, both hash-verified). #85 needs reopening or a fresh tracker when this ships. | | Drop-in ROM converter, remaining parts | decision | #6, [`dev/release-dropin-rom-plan.md`](dev/release-dropin-rom-plan.md) | NTSC-U drop-in shipped. Left: per-region output names and re-exec guard (with PAL/JP), native C emitters to replace the PyInstaller converter. | | Cut content (TCRF weapons/items) | decision | [`dev/CUT-CONTENT-BACKLOG.md`](dev/CUT-CONTENT-BACKLOG.md) | Not part of the shipped game. Tier 0 already works via the debug/cheat menus. Tier 1 (config-toggle grants) is small and port-only. Tier 2/3 (placing props, re-enabling unused MP maps) need game data changes and are out of scope for this repo. | @@ -129,19 +129,15 @@ below). | Item | Status | Refs | Notes | |---|---|---|---| -| Auto-fire gunshot sound slightly differs from 1964/GEPD | open | D433, #114 | Cadence matches the N64 rules exactly. The residual is subtle differences in the click/empty-magazine sounds between shots during continuous AK47 fire. **Maintainer-owned (2026-09-30):** possibly already fixed; it needs a recorded A/B against 1964/GEPD, which isn't suited to agents. Done together with the WrapFix check below. **Decided 2026-10-01:** code-side audit of the fire/empty-click sound path first (with #130), before any by-ear A/B. | -| Auto-fire gate at unstable 40–55 fps | partial | D427 | Exact at a steady 60 or 30 fps. At fluctuating rates it can flip between 1× and 2×, because `field_88C` is never rescaled. | -| Third-person Bond offset residual | partial | D173, D292 | Mostly fixed. A small drift remains about 1 time in 10. | -| Statue corner flicker at max FOV | verify | D294 | Room-pool cap raised 2.0 -> 2.5 (2026-09-30; Statue needs about 2.17x). It is unproven: the exhaustion log never fired at spawn. **Owed:** strafe fast past the Statue corners at max FOV and max draw distance. | +| Third-person Bond offset residual | partial; intro puppet explained (2026-10-02) | D173, D292 | Mostly fixed. On the level-start puppet the variance is tick/PRNG-dependent idle timing (D13 class, faithful, no sign-off requested); one 1-frame first-tick Y transient is untraced. If the residual is seen elsewhere (cutscene body model), the maintainer should note where. | +| Turret fire rate, explosion density and shake at 60 fps | verify | #126, D486 | **Fixed 2026-10-02 (D486, RULE-2):** autogun shots/tracers, explosion-part spawning and shake decay were counted per frame (2-3x the N64 at 60 fps); now gated to the N64 2-ticks/frame pace (`portN64FrameStep`), damage per second unchanged; headless 60-vs-30 fps A/B identical. The dropped explosions themselves are faithful (1964/GEPD drops them the same way), so #126 closes as matching the N64. **Owed:** a turret fight at 60 fps (Cradle/Aztec) feels like 1964: fire rate, tracers, sound, shake; damage taken unchanged. | +| Dam ending cutscene: Bond placement; railing transparency | open | D173, D292; maintainer 2026-10-02 | **Maintainer to re-check the end of Dam** (the last place a Bond offset was seen; the D173 level-start probe found no defect). Also seen in the Dam cutscene: an edge railing texture (a 2D element, maintainer believes) with odd transparency; possibly already fixed by the alpha pass. Capture a screenshot of each if still present. | | Gameplay visibility vs modern view options (FOV, ultrawide) | verify | D466, D468, D334, D222; maintainer's local policy note | **Policy approved 2026-10-01 and implemented:** AI awareness may see what an N64 player could have seen in some configuration the cartridge supports. D466: the AI uses the authored draw distance (the player can still shoot, use and photograph whatever is drawn). Widescreen up to 16:9 is faithful (the cartridge's own Ratio 16:9 mode). **D468 (merged 2026-10-01):** under ultrawide or `Video.FovScale` > 100 the AI's on-screen view is clamped to the 16:9 / game-FOV view; option `Game.AIWideView` (F10 Gameplay, default off) gives the AI the full view. **Owed:** by-eye check on an ultrawide window or at a high FOV. D466 follow-up (2026-10-01, maintainer decision): movement/locomotion LOD follows the render, only awareness uses the N64 distance. | -| Golden Gun plays the empty click with each shot | open | #130 | Outside report: the out-of-ammo sound plays alongside the firing sound, unlike 1964. Check by ear together with the D433 auto-fire A/B (maintainer-owned). | -| A mine in Control's mainframe room didn't destroy anything | open | #126 | Outside report; the reporter is unsure. Sanity-check on 1964 first (the objects may be indestructible there). | +| Sniper rifle: can't crouch while using it; zoom feels slow | verify | #136, D483, D484, D485 | **Fixed 2026-10-02 on `release/v0.4.1`.** Crouch: partly faithful (the sniper's DISABLE_CROUCH flag blocks stance changes on the N64); the port's divergence (the PC crouch key stood you up on switching to the sniper) is fixed by **D483**. Zoom level: the port's FOV floor capped full zoom at 20 degrees instead of 7, fixed by **D484**. Zoom speed: per-frame stepping made the port zoom 2x faster than the N64; now tick-scaled (**D485**, Rule-2 approved). Owed: 1964 A/B of zoom level/speed and crouch-then-switch. Keep #136 open until the maintainer's 1964 check. | | Crash on save slots 1/3/4, plus a host BSOD (fltmgr.sys) | decided | #94 | Needs a repro. Two maintainer retest requests (v0.3.0, v0.4.0) got no reply. Likely D299/D301 (save-slot crash, fixed) and D344 (BSOD on exit, fixed). **Decided 2026-10-01: close as stale when the release ships**, pointing at D299/D301/D344; no GitHub activity before then. | -| SkipIntro skips the post-mission failure dossier | verify | D408, D216 | Fixed 2026-09-30: the hook is gated to first boot. **Owed:** fail or abort a mission with SkipIntro on and check the dossier shows; also listen for whether D216's audio break is gone. | -| Front-end: Rareware logo filtering, cast-roll models | partial | D75 | Cosmetic. The other front-end logos are fixed. The cast-roll character models have never been verified. | | Authored mip chains not sampled for explicit-LOD textures | post-1.0 | D323 | Distant textures use driver mips instead of Rare's hand-authored chain (heaviest on Statue/Aztec). Parked as a fidelity enhancement. **Decided 2026-10-01:** after 1.0, together with the LOD-fraction approximation as one "real RDP LOD" project. | -| Approximations in the software RSP | open | `gfx_pc.cpp` `G_CCMUX_LOD_FRACTION`; `Video.WrapFix` (§F row `RC3 · D167`, D74 family) | The LOD-fraction CC input is an eyeballed approximation. The non-power-of-two wrap fix is still opt-in (default off), with unknown visible impact. Both need a comparison against 1964. **2026-09-30 triage** (`docs/dev/notes/FIDELITY-TRIAGE.md`): the LOD-fraction input is bundled with D323 as one "real RDP LOD" project (fix later, large). **WrapFix is maintainer-owned:** a 1964 Depot-ceiling screenshot vs the port with WrapFix on/off decides the default. | -| Latent 64-bit ABI hazards | partial | D441, #107, #108; ~396 `-Wpointer-to-int-cast` sites at the start of the sweep (185 remain in the 17 touched files; many are intentional `(s32)&ANIM_DATA_*` offsets, D34); AUDIT-M6 `struct player`/`struct hand` raw offsets (porting-notes §A1) | Part 1 landed (D441): 17 files widened to `uintptr_t` under `#ifdef PORT`, build and Bunker/Silo runs verified. **Still owed:** the full census with per-site provenance (H/R/I/?, table not yet written) plus a **store-to-u32 vs arithmetic-only** tag per site (a `uintptr_t` widening is enough only for arithmetic; sites that store back into a u32 field need `portHostToN64` under the macOS port_addr model), an env-gated high-arena test mode, and a check under an arena above 4 GB. Harmless today because the arena sits low. They would bite on macOS/ARM/ASLR. **#108 concern:** widening the `sndPlaySfx` bound disables the guard on every platform; prefer a range check. **#107 will now conflict** with D441 in `bg.c` (`bgRoomCalcBB`), so rebase or close it during the outside-PR review. A read-only provenance pass over the remaining sites is a good local-Qwen delegate task. **2026-10-01:** D457(c)(d) merged (player matrix pointers, Model/PROMOTE/vtxstore pointer width); #107's two sites fixed (D441); read-side census part 2 (403 `-Wint-conversion`/`-Wint-to-pointer-cast` warnings, triaged by file) in the local note `ABI-CENSUS-D441-PART2.md`; model.c rows need a re-run after D457(d). **Stage B plan (2026-10-01, maintainer's local design note):** (1) centralise the hard-coded arena address windows: **done 2026-10-02** (`port/include/portaddr.h`: `PORT_DRAM_V1_BASE` / `PORT_DRAM_K0_BASE` / `PORT_DRAM_SIZE`, used by `OS_K0_TO_PHYSICAL`, `dram.c`, `libultra.c` bases, `n64stubs.c`, the fast3d window checks; compile-time constants, no codegen change; menu / Bunker / Statue smoke clean). Left: the three link-time symbols in `port/src/dram_syms.s` (needs a preprocessed `.S` or `--defsym`), and a runtime-derived base for macOS; (2) widen `mema.c` (`memaspace.addr` s32 with `0xffffffff` sentinels, `memaRealloc`/`_memaFree` s32 params; the deferred D453 item); (3) build the high-arena test flavour (`GE_HIGHARENA_BASE`, tier 1 at 0x90000000, tier 2 above 4 GiB) and iterate on the first failures; (4) the heap-backed animation-table slots (`initanitable.c`); converges with #95's port_addr chokepoint. | +| Approximations in the software RSP | post-1.0 | `gfx_pc.cpp` `G_CCMUX_LOD_FRACTION`; D323 | The LOD-fraction CC input is an eyeballed approximation, bundled with D323 as one "real RDP LOD" project after 1.0 (2026-09-30 triage). **WrapFix settled 2026-10-02:** the maintainer checked the Depot building ceilings against 1964 with the default `Video.WrapFix = 0` and they look right, so the default stays off (the opt-in knob remains; RC3/D167). | +| Latent 64-bit ABI hazards | partial | D441, #107, #108; ~396 `-Wpointer-to-int-cast` sites at the start of the sweep (185 remain in the 17 touched files; many are intentional `(s32)&ANIM_DATA_*` offsets, D34); AUDIT-M6 `struct player`/`struct hand` raw offsets (porting-notes §A1) | Part 1 landed (D441): 17 files widened to `uintptr_t` under `#ifdef PORT`, build and Bunker/Silo runs verified. **Still owed:** the full census with per-site provenance (H/R/I/?, table not yet written) plus a **store-to-u32 vs arithmetic-only** tag per site (a `uintptr_t` widening is enough only for arithmetic; sites that store back into a u32 field need `portHostToN64` under the macOS port_addr model), an env-gated high-arena test mode, and a check under an arena above 4 GB. Harmless today because the arena sits low. They would bite on macOS/ARM/ASLR. **#108 concern:** widening the `sndPlaySfx` bound disables the guard on every platform; prefer a range check. **#107 will now conflict** with D441 in `bg.c` (`bgRoomCalcBB`), so rebase or close it during the outside-PR review. A read-only provenance pass over the remaining sites is a good local-Qwen delegate task. **2026-10-01:** D457(c)(d) merged (player matrix pointers, Model/PROMOTE/vtxstore pointer width); #107's two sites fixed (D441); read-side census part 2 (403 `-Wint-conversion`/`-Wint-to-pointer-cast` warnings, triaged by file) in the local note `ABI-CENSUS-D441-PART2.md`; model.c rows need a re-run after D457(d). **Stage B plan (2026-10-01, maintainer's local design note):** (1) centralise the hard-coded arena address windows: **done 2026-10-02** (`port/include/portaddr.h`: `PORT_DRAM_V1_BASE` / `PORT_DRAM_K0_BASE` / `PORT_DRAM_SIZE`, used by `OS_K0_TO_PHYSICAL`, `dram.c`, `libultra.c` bases, `n64stubs.c`, the fast3d window checks; compile-time constants, no codegen change; menu / Bunker / Statue smoke clean). Left: the three link-time symbols in `port/src/dram_syms.s` (needs a preprocessed `.S` or `--defsym`), and a runtime-derived base for macOS; (2) widen `mema.c` (`memaspace.addr` s32 with `0xffffffff` sentinels, `memaRealloc`/`_memaFree` s32 params; the deferred D453 item); (3) build the high-arena test flavour (`GE_HIGHARENA_BASE`, tier 1 at 0x90000000, tier 2 above 4 GiB) and iterate on the first failures; (4) the heap-backed animation-table slots (`initanitable.c`); converges with #95's port_addr chokepoint. **2026-10-02 (D478):** read-side census re-run (319; 129 outside `chr.c` D34) triaged site by site: nothing live on the current layout; the remaining items are arena pointers in 32-bit slots and stack buffers through `s32` (safe only while stacks are low: `MAP_32BIT`, no ASLR on Windows), which is the Stage B / macOS list in the D478 entry. | ## 3. Verification debt (fixed; a live check is owed) @@ -168,12 +164,12 @@ A single campaign pass with these on the checklist would clear most of them. | Item | Status | Refs | Notes | |---|---|---|---| -| macOS (Intel + Apple Silicon) / ARM64 Linux | open | PRs #88, #95; #101 | Outside drafts, parked for `main` until after 1.0. **Address model decided (2026-09-30): port_addr (#95)**, i.e. a single `portN64ToHost`/`PORT_N64PTR` chokepoint with a `PORT_ADDR_STRICT` validator, over the dram-scoped alternative. The `macos` integration branch **exists on origin** (2026-09-30). It was cut from `origin/main` `0e8c2ce2`, and it takes #88 (merged as `c4153157`, using #95's conflict-resolved copy `ae1884cc`), #132 (Linux build fix, `39d4f8d0`: #88's `romdata.c` included `` before `ultra64.h`, and glibc's `errno` macro broke the `errno` fields in `PR/os.h`; #95 needs it on rebase) and #95 (retargeted to it, still open). italoarruda's work also goes there. Nothing merges from it to `main` before the post-1.0 pass. **Open against `macos`:** #131, the fork-friendly self-hosted sweep. It adds `platform` and `runner_labels` inputs, a macOS job running `level_sweep_mac.sh` with a JSON verdict, seed-dir-only ROM staging, and `docs/selfhosted-sweep.md`. It is a scaffold that has not been run on a Mac, and it needs #95 in `macos` first. **When `macos` is next rebased onto `main`** (after the v0.4.1 push), `selfhosted.yml` will conflict with the v0.4.1 ROM-cache fix. Take #131's version, which already includes that fix. The crouched-rifle table fix (`chr.c`), found three times (#95, italoarruda, #120), landed on `release/v0.4.1` via #120 (D445) on 2026-09-30. #120's shape is the correct one (it restores the N64 table length of 2; #95's terminator-only version leaves length 1), so **drop #95's `crouched_rifle` hunk** when `macos` is rebased. #95's finding labels (D29x, then D405–D421) clash with ours, so relabel on merge. The maintainer tests firsthand before merging. Needs the ABI-hazard sweep in §2 (store-to-u32 tagging). | +| macOS (Intel + Apple Silicon) / ARM64 Linux | open (target 0.9.0/1.0, maintainer 2026-10-02) | PRs #88, #95; #101 | Outside drafts, parked for `main` until after 1.0. **Address model decided (2026-09-30): port_addr (#95)**, i.e. a single `portN64ToHost`/`PORT_N64PTR` chokepoint with a `PORT_ADDR_STRICT` validator, over the dram-scoped alternative. The `macos` integration branch **exists on origin** (2026-09-30). It was cut from `origin/main` `0e8c2ce2`, and it takes #88 (merged as `c4153157`, using #95's conflict-resolved copy `ae1884cc`), #132 (Linux build fix, `39d4f8d0`: #88's `romdata.c` included `` before `ultra64.h`, and glibc's `errno` macro broke the `errno` fields in `PR/os.h`; #95 needs it on rebase) and #95 (retargeted to it, still open). italoarruda's work also goes there. Nothing merges from it to `main` before the post-1.0 pass. **Open against `macos`:** #131, the fork-friendly self-hosted sweep. It adds `platform` and `runner_labels` inputs, a macOS job running `level_sweep_mac.sh` with a JSON verdict, seed-dir-only ROM staging, and `docs/selfhosted-sweep.md`. It is a scaffold that has not been run on a Mac, and it needs #95 in `macos` first. **When `macos` is next rebased onto `main`** (after the v0.4.1 push), `selfhosted.yml` will conflict with the v0.4.1 ROM-cache fix. Take #131's version, which already includes that fix. The crouched-rifle table fix (`chr.c`), found three times (#95, italoarruda, #120), landed on `release/v0.4.1` via #120 (D445) on 2026-09-30. #120's shape is the correct one (it restores the N64 table length of 2; #95's terminator-only version leaves length 1), so **drop #95's `crouched_rifle` hunk** when `macos` is rebased. #95's finding labels (D29x, then D405–D421) clash with ours, so relabel on merge. The maintainer tests firsthand before merging. Needs the ABI-hazard sweep in §2 (store-to-u32 tagging). | | Platform parity gate (Linux co-equal with Windows) | open | — | **Decided 2026-09-30:** yes. Every released platform carries the same gate: a 21-level sweep plus a campaign pass. Needs the golden baselines on both platforms first (§7). The last known Linux crash (D190) was closed as not-a-bug. | -| Low-end GPUs (~30 fps on Celeron/HD 400) | open | D339, #92 | **Direction (maintainer, 2026-10-01): real optimizations, not a preset.** **2026-10-01 profile** (all-thread sampler, local note `PERF-HOTSPOTS.md`, probes on branch `perf/profile-hotspots`): the top render-thread hotspot was an uncached getenv per vertex batch, fixed as **D473** (Statue display-list CPU about -55%). After it, whole-process CPU is ~1.5-2 ms/frame on a fast machine (~8-10 ms scaled 5x), so the N3060 / HD 400 is probably GPU- or driver-bound (per-draw cost, MSAA, fill). **Next:** one `GE_PERFSTAT=1` run on that class of hardware (compare `gpu=` vs `run=` vs `interval=`), then target what dominates: draw-call/state-change reduction (needs a flush-reason histogram on the target), texture-bind lookups, per-triangle debug hooks, combiner lookup (ranked in the note). The D372 preset gets no further effort. | -| Statue/Cradle hitching (maintainer, 2026-09-30) | open | `GE_PERFSTAT` spike counters (2026-10-01) | **Diagnosed 2026-10-01 (D475):** no sustained load. The low-CPU ~33 ms frames are the game's own frame limiter skipping a retrace after a slightly late gfx task (`boss.c` tick-interval check; a D13-class timing interplay, needs a design look and possibly Rule-2). The CPU-side bursts are CI-palette re-imports (one texture re-imported with 51 palettes in ~8 frames), not first-sight loads; room-texture pre-warm was built and measured, with ~no gain (unmerged branch `perf/prewarm`). **CI8 palette re-imports ruled out as a CPU cost (D477, 2026-10-02):** decode+upload ~0.008 ms/frame, worst frame 0.44 ms; the cache already holds the animated palettes (10 re-misses in 1314); the same texture is drawn with several palettes per frame, so an in-place update path would thrash. GPU palette lookup is not justified by this data. CI4 part done (D476). Frame-limiter design look done 2026-10-02: no independent pacing bug; the skips follow long gfx tasks. **Next (if the hitches still matter):** a per-frame timeline probe (game-thread build + limiter decision, render-thread misses/new textures/shader compiles, per-frame GPU timestamps, swap time) over >=5 runs, PresentMon during real play at a spot that hitches, then a disable-falsifier per suspect (driver-deferred texture allocation, `glGenerateMipmap` under three-point filtering, shader compiles). Needs the maintainer's description of where the hitch shows. | +| Low-end GPUs (~30 fps on Celeron/HD 400) | fixed, verify on N3060 class | D339, D481, D482, #92 | **D482 (2026-10-02):** measured against the PD port on the X220, fast3d is as cheap per batch as PD's; the remaining gap is our heavier defaults. Atom/Celeron-class GPUs (HD 400-605, UHD 600/605, Bay Trail class, software renderers) now get DrawDistance/LodDistance 100 and MSAA 1 once, where still at the defaults (Cradle: 482 -> 146 batches, render CPU 8.2 -> 5.2 ms). **D481 (2026-10-02):** the root cause was architectural, not render cost: fast3d ran inline on the scheduler thread, delaying retrace delivery, so the game's tick gate skipped frames. With the render worker a Lenovo X220 (HD 3000) went from 44-46 to 60.0 fps at every setting; the PD port measured 60 on the same box. **Next only if N3060-class hardware still drops:** decide CPU vs GPU from `GE_PERFSTAT` there (`gpu=` vs `run=`), then either a renderer-keyed lighter default (GPU) or fast3d per-batch cuts diffed against PD's hot loop (CPU). **Earlier direction (maintainer, 2026-10-01): real optimizations, not a preset.** **2026-10-01 profile** (all-thread sampler, local note `PERF-HOTSPOTS.md`, probes on branch `perf/profile-hotspots`): the top render-thread hotspot was an uncached getenv per vertex batch, fixed as **D473** (Statue display-list CPU about -55%). After it, whole-process CPU is ~1.5-2 ms/frame on a fast machine (~8-10 ms scaled 5x), so the N3060 / HD 400 is probably GPU- or driver-bound (per-draw cost, MSAA, fill). **Next:** one `GE_PERFSTAT=1` run on that class of hardware (compare `gpu=` vs `run=` vs `interval=`), then target what dominates: draw-call/state-change reduction (needs a flush-reason histogram on the target), texture-bind lookups, per-triangle debug hooks, combiner lookup (ranked in the note). The D372 preset gets no further effort. | +| Statue/Cradle hitching (maintainer, 2026-09-30) | parked (not player-visible, 2026-10-02) | `GE_PERFSTAT` spike counters (2026-10-01) | **Diagnosed 2026-10-01 (D475):** no sustained load. The low-CPU ~33 ms frames are the game's own frame limiter skipping a retrace after a slightly late gfx task (`boss.c` tick-interval check; a D13-class timing interplay, needs a design look and possibly Rule-2). The CPU-side bursts are CI-palette re-imports (one texture re-imported with 51 palettes in ~8 frames), not first-sight loads; room-texture pre-warm was built and measured, with ~no gain (unmerged branch `perf/prewarm`). **CI8 palette re-imports ruled out as a CPU cost (D477, 2026-10-02):** decode+upload ~0.008 ms/frame, worst frame 0.44 ms; the cache already holds the animated palettes (10 re-misses in 1314); the same texture is drawn with several palettes per frame, so an in-place update path would thrash. GPU palette lookup is not justified by this data. CI4 part done (D476). Frame-limiter design look done 2026-10-02: no independent pacing bug; the skips follow long gfx tasks. **Next (if the hitches still matter):** a per-frame timeline probe (game-thread build + limiter decision, render-thread misses/new textures/shader compiles, per-frame GPU timestamps, swap time) over >=5 runs, PresentMon during real play at a spot that hitches, then a disable-falsifier per suspect (driver-deferred texture allocation, `glGenerateMipmap` under three-point filtering, shader compiles). Needs the maintainer's description of where the hitch shows. **Parked 2026-10-02:** the timeline probe was built (`probe/hitch-timeline`, `GE_HITCHTL`, never merge) and run during a ~2 min maintainer play session. The maintainer felt no hitching at their settings, only the FPS counter dipping to 58/59 as a level starts. The capture agrees: the long frames sit at level load and transitions (one 59 ms frame with 316 new textures + 4 shader compiles) plus one ~20 ms in-play cluster with 3-7 shader compiles and new GL textures (first-draw cost). Reopen only if a visible hitch is reported (e.g. on low-end hardware); the cheapest lever then is shader/texture pre-warm at level load. **D480 (2026-10-02, `perf/shader-prewarm`):** the in-play cluster was shader compiles; created shaders are now remembered in `ge007.shaders` and compiled at the first frame of the next session (0 in-play compiles on a warm run, output-identical). The level-start texture frame is left as is (see D480). | | Steam Deck preset skipped when first launched from Desktop Mode | verify | D283 | Fixed on `release/v0.4.1`: the Deck is detected by DMI hardware id (Valve Jupiter/Galileo; `STEAMOS` kept as a second signal) and the preset applies once per ini, only while Fullscreen/Maximized are untouched. Only the Windows build and a Linux `-fsyntax-only` check ran. **Owed: one run on a real Deck** (Desktop-Mode-created ini, then Game Mode; expect fullscreen 1280x800 and the log line `video: Steam Deck (DMI Valve ...)`). The Known-issues row above goes when this ships. | -| Windows 7 | decision | #98 | Recommend won't-fix (toolchain). | +| Windows 7 | open | #98 | **Re-checked 2026-10-02: likely feasible around 1.0.** The exe imports no Windows 8+ functions; the bundled SDL2 2.32.10 (still supports Windows 7) and winpthreads only load newer APIs dynamically with fallbacks; msvcrt runtime; OpenGL 3.0 drivers exist on Windows 7. The real blocker is the first-run asset converter `ge007-convert.exe` (PyInstaller on Python 3.9+, which does not run on Windows 7): the native C converter (#6 Part B) removes it, or a separate Python 3.8 build. Work: one Windows 7 VM test, then either converter route; CI cannot test Windows 7, so it is a manual per-release check. Supersedes the earlier 'won't-fix (toolchain)' recommendation. | ## 5. Modern-remaster layer (port features beyond the N64) @@ -203,7 +199,7 @@ Background research lives in the maintainer's local notes (gitignored): | Settings units and values cleanup | verify | D357, D443 | **Landed 2026-09-30 (D443):** mouse ×, whole-% deadzone and volume, FOV in horizontal degrees, MSAA 16×. FPS presets above 60 are deferred to the frame-rate-above-60 work (the sim ticks at 60 Hz). **Owed:** the new values in both settings UIs. | | Restart button in the settings menus | done | D443 | **Landed 2026-09-30 (D443):** a "Restart game" row (orderly D344 quit, then relaunch). **Owed:** click it once on Windows (no BSOD); the Linux relaunch path has never been compiled. | | Front-end PC Options: Previous/Next paging for mouse users | verify | D444 | **Landed 2026-09-30 (D444):** Previous/Next page buttons; hover no longer snaps the wheel selection. **Owed:** a mouse pass through Input and Graphics. | -| Outside PRs #107–#109, #122–#124 | decided | #122 hot-plugged pads never reopen, #123 persistent crosshair (`gunfire.c`), #124 compact health/armour bars (`bondview2.c`); #107/#108/#109 (italoarruda) | **Decided 2026-10-01 after design reviews (notes: `docs/dev/notes/PR-REVIEW-109.md`, `PR-REVIEW-123-124.md`, local):** **#120/#121/#122** merged locally (#122 = D450, with split-screen); close all three when the branch is pushed. **#123** (persistent crosshair): accept-with-changes, **deferred**; later, either amend their PR or do the work ourselves (add to the Original N64 preset, relabel D436, our Rule-2 line, 2P + sniper-zoom check). **#124** (compact health/armour bars): **deferred** (pre- or post-1.0); too many issues to merge now: ignores HudScale, overlaps the bottom-left status text, 4:3-edge anchoring on ultrawide, draws extra commands when off, mixed apparent/real values, a test knob in shipping code, not in the Original N64 preset, split-screen untested. Either we take it on or ask the author to address the list when GitHub activity resumes. **#109** (pad rebinding): **decline as-is**. It conflicts in all 4 files, would revert the D394 Jinx defaults, uses global (not per-seat) bindings, and its cancel is keyboard-only. Supersede with our own pad presets + rebinding (§5a row below), crediting the author's two-names format, menu lockout guard and release-before-capture arming (Co-authored-by); close with thanks and the change list when GitHub activity resumes. **#107**: folded into D441 on 2026-10-01 (both sites fixed with the author's `uintptr_t` arithmetic, Co-authored-by); close it on push. **#108**: belongs with `macos`; ask for a range check instead of widening the bound. Relabel any outside D-labels on merge. | +| Outside PRs #107–#109, #122–#124 | decided | #122 hot-plugged pads never reopen, #123 persistent crosshair (`gunfire.c`), #124 compact health/armour bars (`bondview2.c`); #107/#108/#109 (italoarruda) | **Decided 2026-10-01 after design reviews (notes: `docs/dev/notes/PR-REVIEW-109.md`, `PR-REVIEW-123-124.md`, local):** **#120/#121/#122** merged locally (#122 = D450, with split-screen); close all three when the branch is pushed. **#123** (persistent crosshair): accept-with-changes, **deferred**; later, either amend their PR or do the work ourselves (add to the Original N64 preset, relabel D436, our Rule-2 line, 2P + sniper-zoom check). **#124** (compact health/armour bars): **deferred** (pre- or post-1.0); too many issues to merge now: ignores HudScale, overlaps the bottom-left status text, 4:3-edge anchoring on ultrawide, draws extra commands when off, mixed apparent/real values, a test knob in shipping code, not in the Original N64 preset, split-screen untested. Either we take it on or ask the author to address the list when GitHub activity resumes. **#133** (F10 ultrawide aspect, JosephAHK, 2026-10-01): duplicates D472 (overlay card pillarboxed + mouse mapping, already on `release/v0.4.1`); close as superseded with thanks when the branch is pushed. **#109** (pad rebinding): **decline as-is**. It conflicts in all 4 files, would revert the D394 Jinx defaults, uses global (not per-seat) bindings, and its cancel is keyboard-only. Supersede with our own pad presets + rebinding (§5a row below), crediting the author's two-names format, menu lockout guard and release-before-capture arming (Co-authored-by); close with thanks and the change list when GitHub activity resumes. **#107**: folded into D441 on 2026-10-01 (both sites fixed with the author's `uintptr_t` arithmetic, Co-authored-by); close it on push. **#108**: belongs with `macos`; ask for a range check instead of widening the bound. Relabel any outside D-labels on merge. | | Gamepad rebinding + modern controller presets | verify | D469 (supersedes PR #109), D394 | **Landed 2026-10-01 (D469):** data-driven pad action table; `Input.PadPreset` (0 = Jinx 1.1, default, proven identical to the old mapping over 20,971,520 synthetic cases; 3 = Custom); per-seat `Input.Pad[N].` bindings; F10 / front-end "Controller..." page with pad capture (B/Back cancel, hold Back / Y clear); menu lockout guard; credited to italoarruda (#109). **Maintainer live test 2026-10-01:** bind, cancel, clear, 2P per-seat tables, hot-plug and relaunch persistence pass; the Restart row (D443) works. **Still owed:** more play with the default preset ("plays as before") and longer controller-only use. **Not done:** Jinx 1.2/1.3 tables (D394 has no reference tables; presets 1/2 hidden), a per-seat preset, a warning when two actions share a button. | | Per-pad tuning (device index, hot-plug seats) | verify | D448, D450 (#122) | Pad seats keyed by SDL instance id, reserved in a match; hot-plug events reach the input layer. Merged with split-screen 2026-10-01. **Owed:** unplug and replug a pad mid-match. | | Full-gamepad menu navigation audit, Xbox/PS button glyphs | verify | D471; local note `PAD-MENU-AUDIT.md` | **Audit done 2026-10-01:** a controller-only player is never trapped in the PC menus. **Glyphs: not wanted** (maintainer); instead D471 shows family-specific button **names** (PlayStation/Nintendo) in the help lines and binding column, Xbox text unchanged, plus player-index LEDs (PD-port parity). **Audit G1-G3 fixed by D472** (owner-pad input). **Owed:** a real PS/Nintendo pad check. | @@ -262,9 +258,9 @@ and a stage loader. | Security review follow-ups | open | maintainer's local security review | Three Low hardening items remain (local-input only; details are kept out of this public file). Done on `release/v0.4.1`: the Medium item (self-hosted workflow input handling), actions pinned by SHA, `pyinstaller` pinned to 6.22.3, and the ROM no longer stored in `actions/cache` by `selfhosted.yml` (fork PR workflows can restore base-branch caches; no cache entry ever existed, checked 2026-09-30; it is now staged from the runner's `_rom-seed` dir only). The Dependabot action bumps (#1/#2) would now need to land as SHA pins, not tag bumps. | | Deterministic 1964-vs-port comparison harness | open | — | Would replace by-eye/by-ear fidelity checks. Highest-leverage tooling item. | | Scripted-playthrough harness | open | `GE_INPUTSCRIPT` | Input script + `GE_PCDUMP` + crash-log check, for unattended regression runs. The tool exists; the harness doesn't. | -| Golden baselines | open | `tools_pc/verify.sh`, D117 | bunker1 has been noisy since M-84, so the per-patch gate is unreliable. Re-base it, extend to all 21 levels × both platforms, and finish `GE_DETERM`. | +| Golden baselines | partial | `tools_pc/verify.sh`, `tools_pc/golden/README.md`, D117 | **Windows done 2026-10-02:** all 21 levels re-based (`tools_pc/golden//win/`) with a near-deterministic recipe (pinned seed, START skips the intro flyby, frames 900-1500 of settled gameplay; Cuba captures its ending); two-tier gate (structural + per-pixel with per-level limits) catches a global texture-filter change (22% vs <= 2.3% noise). verify.sh now quits via `GE_QUITFRAME` and never kills other game instances. **Left:** Linux baselines (needs a real-GPU Linux box: `GE_PCDUMP` reads black on llvmpipe/WSLg), then the parity gate per platform. `GE_DETERM` stays experimental (not needed for this recipe). | | Self-hosted CI runner link failure | open | D244 | Needs a `pacman -Syu` on the runner (maintainer-only access). Release tag builds use GitHub runners, so it doesn't block a release. | -| Remove temporary scaffolding before a release | partial | [`dev/GE-ENV-PROBES.md`](dev/GE-ENV-PROBES.md), D302 | The 2026-09-30 pass removed D207S, D157, D252POOL, D245V, D288, D309, the D318B suite, the D320 repro harness and `scan_op12/13.py`, demoted the D318 watchdog to detect-and-log, and cached the per-frame `getenv` sites. **Left:** dead registry rows (D116, D51, D56, D60-D63, D69*, D71LOG, D85DUMP, D86-D88, D90, D96, D104, D154, D178); closed-finding TEMPs (`GE_D235_*` once D235 closes; **removed 2026-10-01:** `GE_D306C`, `GE_D318T` (batch 2); the whole D243 diagnostic set -- `GE_D243X2`, `GE_D243X4`, `GE_D243M` (+ its `d243mProbeActive`/frame-counter plumbing and all `D243M:` log lines in `bondview2.c`/`chr.c`/`chraction.c`/`chrai.c`/`model.c`/`objecthandler.c`), `GE_D243CAM`, `GE_D243SWIRL`, `GE_D243` (front.c menu trace) (batch 3, `chore/strip-d243-probes`; the shipped fix and the M-183/M-185 clamps are kept); `GE_DYNTEXHASH_OFF`, `GE_FORCEALARM`, `GE_D204_OLD`, `GE_D252`, `GE_RSEED_LV` were already gone); the now-inert sky tile-capture/shift machinery in `sky.c` (`skyPortCaptureTile`, `skyPortPickShift`, `GE_D245_FIXEDSHIFT`); and the M-183/M-185 clamps, which need a full cutscene re-check first. | +| Remove temporary scaffolding before a release | partial | [`dev/GE-ENV-PROBES.md`](dev/GE-ENV-PROBES.md), D302 | The 2026-09-30 pass removed D207S, D157, D252POOL, D245V, D288, D309, the D318B suite, the D320 repro harness and `scan_op12/13.py`, demoted the D318 watchdog to detect-and-log, and cached the per-frame `getenv` sites. **Left:** dead registry rows (D116, D51, D56, D60-D63, D69*, D71LOG, D85DUMP, D86-D88, D90, D96, D104, D154, D178); closed-finding TEMPs (**removed 2026-10-02 (batch 4, `chore/strip-batch4`):** `GE_D235_OFF`/`_RELOAD`/`_NEXT` (D235 closed; the fix and the `GE_D235` log stay), `GE_D245V`, `GE_D245_FIXEDSHIFT` and the inert sky tile-capture/shift code in `sky.c`; registry drift fixed and `gen_env_probes.py --check` passing again; **removed 2026-10-01:** `GE_D306C`, `GE_D318T` (batch 2); the whole D243 diagnostic set -- `GE_D243X2`, `GE_D243X4`, `GE_D243M` (+ its `d243mProbeActive`/frame-counter plumbing and all `D243M:` log lines in `bondview2.c`/`chr.c`/`chraction.c`/`chrai.c`/`model.c`/`objecthandler.c`), `GE_D243CAM`, `GE_D243SWIRL`, `GE_D243` (front.c menu trace) (batch 3, `chore/strip-d243-probes`; the shipped fix and the M-183/M-185 clamps are kept); `GE_DYNTEXHASH_OFF`, `GE_FORCEALARM`, `GE_D204_OLD`, `GE_D252`, `GE_RSEED_LV` were already gone); and the M-183/M-185 clamps, which need a full cutscene re-check first. | | Findings log and doc size | partial | `tools_pc/docs_budget.py` | The budget checker exists (per-file and tier-1 token budgets; `--toc FILE`), and everything is within budget. `findings.md` is still about 2 MB (~500k tokens), so agents must keep using the index. Remaining: nothing blocks; trim only if the budget check starts failing. | | Branch and PR housekeeping | open | — | 30 landed local branches pruned 2026-09-30 (tips kept in the notes archive, `prune-branches-2026-09-30.txt`). `docs/m138-security-disclosure` landed on `release/v0.4.1` with a stale-fact pass (SECURITY.md, the security-and-fidelity page, README roadmap bullet). `feat/unlocked-fps-phase1-audit`'s commit (Phase 0 resolved by D248, Phase 1 audit) landed as `docs/unlocked-fps-audit`. **On hold by the maintainer (2026-09-30, do not prune yet):** probe-only leftovers `d243-verify-local`, `investigate/d243-cutscene-race`, `park/d236-probes-m139`. Local `main` and `release/v0.4.1` are deliberately not pushed. **Pushed on 2026-09-30:** the `macos` integration branch; `ci/selfhosted-fork-runners` (PR #131 into `macos`, open); `fix/macos-errno-include` (PR #132, merged into `macos`). Pruned after merging, 2026-09-30: `fix/selfhosted-rom-no-cache`, `docs/macos-ci-tracking` and `fix/macos-errno-include` (local and remote), plus the `review/pr88` and `review/pr95` read-only refs. PR #62 (mouse dt-decouple) stays held until mouse feel is fundamentally better. | | Docs site: Web 1.0 phase 2 | decision | — | Phase 1 shipped. Phase 2 (centred serif page) is plan-only. | @@ -294,4 +290,4 @@ cross-play · Steamworks, achievements, cloud saves (no storefront) · HDR, frame generation, stereo 3D (ray tracing only as the opt-in post-1.0 experiment in §5c) · remake-scope assets (new models, music or voice) · new movement mechanics (jump, roll, melee) · the -007 Plus ROM patch as such (#110) · Windows 7 (#98, pending decision). +007 Plus ROM patch as such (#110). diff --git a/docs/dev/GE-ENV-PROBES.md b/docs/dev/GE-ENV-PROBES.md index 09252636..f75cb921 100644 --- a/docs/dev/GE-ENV-PROBES.md +++ b/docs/dev/GE-ENV-PROBES.md @@ -68,8 +68,8 @@ Two classes: | `GE_TEXDUMP` | `port/fast3d/gfx_pc.cpp:1020`, `port/fast3d/gfx_opengl.cpp:700` | PPM dump of every uploaded texture + a `fmt/siz/palfmt/palidx/pal[0..3]` line. Root-caused D161 (Depot ceiling). Kept as an inert diagnostic. | **live** (RC3 not finished) | | `GE_D116` | `port/fast3d/gfx_pc.cpp:1710,2362`, `src/game/textrelated.c:265,541` (cached `ge_d116`) | HUD/text "X-mirror" (D114/D116) vbo/uv trace. **D114/D116 CLOSED — NOT A BUG (M-33/D168): the captures were upside-down, not mirrored.** Probe is now dead scaffolding — strip on the next cleanup pass. | dead (D114/D116 closed) | | `GE_D288` | `port/fast3d/gfx_pc.cpp` (`gfx_sp_tri1`, right after the D233 trivial-reject guard; cached `ge_d288`) | M-152 diag for the Silo intro stray triangle: frame-gated to `num_dls` 550–755 (M-155), now **skips `any_behind_camera==1` triangles** (M-155 follow-up — the x/w divide is meaningless for w≤0; that subset was pure false-lead noise) and logs the render-mode word (`oml`) so a live capture can ID the culprit asset against level tables. Logs any triangle whose clip-space NDC bbox covers >50% of the screen or goes non-finite, with each vertex's `w`. Bare `-level_20` re-run: 1965 sane hits in the window, still zero for the target color RGB(83,62,44) — consistent with M-155's working theory that the bare boot's scripted camera never reaches the bug state; **headless probing is at its limit, live capture is next**. | **dead** (D288 closed) — removed 2026-09-30 (ROADMAP §7 strip pass, branch `chore/strip-temp-probes`); tombstone — the generator flags it GONE | -| `GE_D245V` | `src/game/sky.c:962` (`skyPortRenderPoly`-adjacent, `#ifdef PORT`) | D245 water-seam diag: per-call min/max of the recomputed S/T texture-coordinate ranges for the water fan vertices (rate-limited), to check whether the seam tracks a tc-shift boundary. Inert unset. | **live** (D245 OPEN) | -| `GE_D245_FIXEDSHIFT` | `src/game/sky.c:946` (`#ifdef PORT`) | D245 test override: pins the water tc shift `k` to the given integer (0..SKY_TC_MAX_SHIFT) instead of the computed per-vertex value, to A/B the allowShift=TRUE behavior. Off by default (unset = current behavior). | **inert** (D245 fixed) — since the s16 sky path was removed 2026-09-30 nothing consumes the forced shift; strip candidate | +| `GE_D245V` | `src/game/sky.c:962` (`skyPortRenderPoly`-adjacent, `#ifdef PORT`) | D245 water-seam diag: per-call min/max of the recomputed S/T texture-coordinate ranges for the water fan vertices (rate-limited), to check whether the seam tracks a tc-shift boundary. Inert unset. | **dead** (D245 fixed) — removed 2026-10-02 (strip batch 4, `chore/strip-batch4`); tombstone | +| `GE_D245_FIXEDSHIFT` | `src/game/sky.c:946` (`#ifdef PORT`) | D245 test override: pins the water tc shift `k` to the given integer (0..SKY_TC_MAX_SHIFT) instead of the computed per-vertex value, to A/B the allowShift=TRUE behavior. Off by default (unset = current behavior). | **dead** (D245 fixed) — removed 2026-10-02 with the inert sky tile-capture/shift code (strip batch 4); tombstone | | `GE_D252` | `port/fast3d/gfx_pc.cpp:733` (`import_texture`, cached `s_d252`) | D252 rainbow-particle diag: one-shot per (address,size) import log of the tile state (tmem/fmt/siz/addr/size/line) for small textures so a suspect particle tile can be checked against its source bytes by hand. Remove once D252 is resolved. | **dead** (D252 closed) — removed 2026-09-30 (ROADMAP §7 strip pass, batch 1, branch `chore/scaffolding-removal-1`); tombstone — the generator flags it GONE | | `GE_D252POOL` | `src/game/image.c` (`texLoad`), `src/game/initmttex.c`, `port/src/gimgfixup.c` | **TEMP** (M-201): one line per new texture load (pool main/other, free bytes) + `POOL-FULL` events + stage pool range; `D252SYNC: N slots re-synced, M changed` per stage load (the D252 fix at work: M>0 from the 2nd stage on). Load-time only, no fps cost. | **dead** (D252 fixed) — removed 2026-09-30 (ROADMAP §7 strip pass, branch `chore/strip-temp-probes`); tombstone — the generator flags it GONE | | `GE_D245_OLDVTX=1` / `GE_D245_OLDTEX=1` | `src/game/sky.c` (`skyPortRenderPoly`) / `port/fast3d/gfx_pc.cpp` (CI8 import + tri-path dims) | **A/B** (M-201): restore the pre-fix s16 sky/water vertex path / the pre-fix 32x43, 16-wide water texture geometry. | **dead** (D245 fixed) — removed 2026-09-30 (ROADMAP §7 strip pass, branch `chore/strip-temp-probes`); tombstone — the generator flags it GONE. The pre-fix s16 sky/water vertex path (`skyPortRenderPoly` tail + `skyPortEmitTileShift`) went with it; the float path is now unconditional | @@ -79,12 +79,15 @@ Two classes: | `GE_INTROCAM=` | `src/game/bondview_r.c` (`#ifdef PORT`, intro camera pick) | **TEMP/test-only**: force the level intro's first camera index (Dam truck shot = 5). The PRNG draw is still consumed. Logs `D306: intro camera index` when set (or with `GE_D306C`). | **TEMP** (useful repro tool) | | `GE_STARTWEAPON=` | `src/game/bondview_r.c` (`#ifdef PORT`, after the start-inventory setup) | **TEMP/test-only** (M-201, D303): adds the item + 400 rounds of its ammo and makes it the starting right-hand weapon (M16 = 13). Pair with `GE_INPUTSCRIPT` `ZHOLD`. | **TEMP** (useful repro tool) | | `GE_D235` | `src/boss.c` (per-stage `while (!done)` block, after `memaReset`; `#ifdef PORT`) | D235 evidence probe: logs how many GL-texture-cache entries the per-stage `videoResetTextureCache()` call purges at each level load. A cold boot into a level should log 0; a death/restart (or any transition from a level that uploaded textures) logs >0 — direct evidence of the stale-entry mechanism. The clear itself is **not** gated on this var (it's the fix, see below); the var only controls the log line. | **live** (D235) | -| `GE_D235_OFF` | `src/boss.c` (same block) | **TEMP** A/B switch: skips the per-stage `videoResetTextureCache()`, i.e. reverts the D235 fix for one run. For comparing a restart with and without the fix. | **TEMP** (D235; remove when D235 closes) | -| `GE_D235_RELOAD=` | `src/boss.c` (same block + `bossMainloop` retrace branch) | **TEMP** reload harness: once the title stage loads after the first level (e.g. after a scripted watch Abort), wait `` retraces, then re-enter that level via `bossSetLoadedStage()`, the front end's own mission-start call. A headless death/restart without the pointer-menu walk. Pair with `GE_INPUTSCRIPT="800:START;1200:A;1300:RIGHT;1400:A"` (abort) on `-level_XX`. | **TEMP** (D235; remove when D235 closes) | -| `GE_D235_NEXT=` | `src/boss.c` (with `GE_D235_RELOAD`) | **TEMP**: re-enter a *different* stage after the abort (level A → title → level B), used for D336 (Runway → Frigate). `GE_D85TEX=1` now also logs each stage's texture-pool size and address range (`src/game/initmttex.c`). | **TEMP** | +| `GE_D235_OFF` | `src/boss.c` (same block) | **TEMP** A/B switch: skips the per-stage `videoResetTextureCache()`, i.e. reverts the D235 fix for one run. For comparing a restart with and without the fix. | **dead** (D235 closed) — removed 2026-10-02 (strip batch 4); tombstone. The D235 fix (`videoResetTextureCache()` per stage load) and the `GE_D235` log stay | +| `GE_D235_RELOAD=` | `src/boss.c` (same block + `bossMainloop` retrace branch) | **TEMP** reload harness: once the title stage loads after the first level (e.g. after a scripted watch Abort), wait `` retraces, then re-enter that level via `bossSetLoadedStage()`, the front end's own mission-start call. A headless death/restart without the pointer-menu walk. Pair with `GE_INPUTSCRIPT="800:START;1200:A;1300:RIGHT;1400:A"` (abort) on `-level_XX`. | **dead** (D235 closed) — removed 2026-10-02 (strip batch 4); tombstone | +| `GE_D235_NEXT=` | `src/boss.c` (with `GE_D235_RELOAD`) | **TEMP**: re-enter a *different* stage after the abort (level A → title → level B), used for D336 (Runway → Frigate). `GE_D85TEX=1` now also logs each stage's texture-pool size and address range (`src/game/initmttex.c`). | **dead** (D235 closed) — removed 2026-10-02 (strip batch 4); tombstone | | `GE_D320R="tick:action;..."` | `port/src/d320repro.c` (hooked in `src/game/lv.c` per-tick PORT block) | **TEMP** forced-repro harness keyed on `g_GlobalTimer`. Actions: `roster`, `jump=,list=,off=`, `bit=`, `trace=`, `rename=,`, `seed=,` (D320); `explode=,` (explosionCreate ahead of Bond) and `cheat=gl|rl|inv|` (game cheat activation) for D252 headless explosion/debris captures. | **dead** (D320 fixed via D329) — removed 2026-09-30 (ROADMAP §7 strip pass, branch `chore/strip-temp-probes`); tombstone — the generator flags it GONE; `port/src/d320repro.c` + its `lv.c` hook deleted | | `GE_AIMLOG=1` (+ `GE_INPUTSCRIPT` tokens `MDX` `MDY` `RHOLD` `LHOLD` `RREL`) | `port/src/input.c` | D337 aim-model harness: scripted sustained mouse deltas (treated as a grabbed mouse) and aim holds, plus a per-poll line with aim state, active device, the game's drawn crosshair x, `crosshair_x/y_pos` and camera angles. Measures range, edge-scroll and jitter headlessly. | **live** | | `GE_PERFSTAT=1` | `port/fast3d/gfx_pc.cpp` (`gfx_run`/`gfx_end_frame`), `port/fast3d/gfx_opengl.cpp` (start/end_frame), `src/boss.c` (main loop) | #92/D339 perf probe: per-300-frame averages of render phases (pre / display-list / post / swap+pace), tris and draw batches per frame, game-thread busy time per scheduler message, and a GL_TIME_ELAPSED GPU timer (meaningful only when GPU-bound). 2026-10-01: also prints `PERFSTAT spikes: max=..ms at frame N (dl= run=) >20ms= >33ms=` per 300-frame window (hitches hide in the averages). | **live** | +| `GE_NOSHADERWARM=1` | `port/fast3d/gfx_pc.cpp` (`gfx_shader_list_open`) | D480 falsifier: disables the shader pre-warm (no read or write of `$S/ge007.shaders`), so first-seen combiners compile mid-frame as before. | **live** (D480) | +| `GE_RENDERINLINE=1` | `port/src/libultra.c` (`portRenderWorkerOn`) | D481 falsifier: run gfx tasks inline on the scheduler thread (the pre-D481 path) instead of on the render worker. `GE_DETERM` forces this too. | **live** (D481) | +| `GE_FAKE_LOWEND=1/0` | `port/src/video.c` (`videoApplyLowEndDefaults`) | D482: force the low-end GPU classification on (1) or off (0) for the one-time first-launch defaults check (`Video.LowEndConsidered`). Testing only, like `GE_FAKE_DECK`. | **live** (D482) | | `GE_D75V` | `port/fast3d/gfx_pc.cpp` (`gfx_sp_vertex`, end of the copy/transform loop; cached env check) | D75 (Nintendo logo) per-batch vertex probe: for each `G_VTX` batch in frames `lo..hi`, logs frame#, source pointer, n_vertices, original dest_index, raw ob[0..2] of the first vertex, min/max of the transformed x/y/z/w across the batch, and the MP translation row. Used to prove the transform is correct (M-195) and that every batch encodes v0=0 (slot-overwrite hypothesis). Value form `"lo-hi"` (e.g. `300-900` = the logo screen); unset = off. **D473 (2026-10-01): the cache was broken (re-read on every G_VTX when unset); now a real one-shot cache.** | **live** (D75) | | `GE_D75D` | `port/fast3d/gfx_pc.cpp` (`gfx_sp_vertex` G_VTX case + `gfx_sp_tri1` rejection/emit gates; cached env check) | D75 (Nintendo logo) per-frame draw-path probe (M-196): for frames `lo..hi`, logs one line/frame with the V/T token stream (`seq`), max triangle vertex index, cumulative vertices loaded, and per-triangle accounting — trivial-reject / backface-cull counts, how many tris reach GL, how many of those are on-screen (NDC bbox ⊂ [−1,1]²), invisible-flag count, vertex-color min/max, first oml word, depth z/w range + NaN count, texture-sampler presence (`utex` = GL shader, `cutex` = combiner), combine mode, prim/env color. Used to REFUTE the slot-overwrite hypothesis (DL is streamed, max index 15) and narrow the bug to a texture-modulate material rendering black. M-197 added logo-mode `lg_*` fields (sampled only on tris with the logo combine word — the frame-level `utex`/`cutex` are first-tri-wins and were the source of the "combiner claims 0" false anomaly): `lg_utex`/`lg_tex` + tile-0 descriptor + texture buffer address/id/size for the logo material. Value form `"lo-hi"` (logo window ≈ `244-320` on a bare front-end boot); unset = off. Companion one-shot `D75DCC:` log in `gfx_generate_cc` fires when `combine_mode==0x009ffe4f19ffe4f1` to decode the logo's combine slots. | **live** (D75) | @@ -96,6 +99,10 @@ Two classes: | `GE_PADFAMILY=xbox\|ps\|nintendo` | `port/src/input.c` (`inputPadFamily`) | D471 dev override: force the controller family used for button names in the PC menus (headless screenshots without the hardware). Cached. | **live** (D471 dev knob) | | `GE_D466_FORCE=1` | `port/src/drawdistgameplay.c` (`portD466Active`) | D466: run the authored-distance split even at DrawDistance 100% (identity test: authored set must equal extended). Cached. | **live** (D466 test hook) | | `GE_D466_OFF=1` | `port/src/drawdistgameplay.c` (`portD466Active`) | D466 kill switch: disable the gameplay/render split (every gameplay reader falls back to the extended-range state, i.e. the pre-fix #125 behaviour). For A/B only. Cached. | **live** (D466 kill switch) | +| `GE_INPUTSCRIPT_P1` | `port/src/input.c:1216` | Split-screen test harness: scripted input for player slot 1, same entry syntax as `GE_INPUTSCRIPT` (slot 0); mouse tokens and `CHOLD`/`CREL` ignored with one warning. Used with `GE_STARTMP` + `GE_MPVIRT`. | **live** (test harness) | +| `GE_INPUTSCRIPT_P2` | `port/src/input.c:1217` | As `GE_INPUTSCRIPT_P1`, for player slot 2. | **live** (test harness) | +| `GE_INPUTSCRIPT_P3` | `port/src/input.c:1217` | As `GE_INPUTSCRIPT_P1`, for player slot 3. | **live** (test harness) | +| `GE_MEMPREDZONE=1` | `src/memp.c:340`, `src/memp.c:369` (+ periodic check in `port/src/video.c`) | D464 red-zone checker: pads every stage-bank allocation with a 64-byte pattern trailer and logs `MEMPREDZONE: HIT ...` at level unload, every 60 frames and at quit. Unset = one cached branch per allocation. | **live** (D464 dev tool) | | `GE_CRASHTEST` | `port/src/crash.c` (`crashTestMaybe`, called at the end of `crashInit`) | Deliberate-crash hook for verifying the crash handler: `GE_CRASHTEST=` recurses N frames deep (capped at 64) right after the handler is installed and faults with a null write. `ge007.crash.log` should then show `#00`..`#N-1` in `crashTestRecurse`, then `SDL_main`, CRT and system frames; each frame line carries `va=0x…` for `addr2line -f -p -e build-pc/ge007.x86_64.exe `. Unset/0 = no effect. | **live** (harness) | | `GE_ROOMPOOL` | `port/src/video.c:371` (`portRoomPoolScale`) | Scales the port's room pool by a float factor — before/after captures, and a user opt-out if the larger pool ever causes trouble on a level. | **live** | | `GE_BINDPROBE` | `port/src/input.c:885` | One-shot dump of the resolved PC bindings after setup (D383 bind-capture verification). | **live** (diagnostic) | diff --git a/docs/dev/findings-index.csv b/docs/dev/findings-index.csv index 6a7eae21..bbbe6bbb 100644 --- a/docs/dev/findings-index.csv +++ b/docs/dev/findings-index.csv @@ -7,7 +7,7 @@ D43-D50,RESOLVED,"model-file loading → offline sidecar ""Plan B"" (d43_emit.py D51-D58,RESOLVED,"font pixeldata, osGetCount tick rate, model RW pools, cseq BE header, synth slots, RLE menu bg, watch raw offsets, gun-barrel DL",resolved D59-D68,RESOLVED,"intro render: blood-RLE clobber, DMA validate, OSMesgQueue, HEADS/BODIES sentinels, romCopy width, image_entry, Globalimagetable BE→LE",resolved D70-D74,RESOLVED,"intro-logo pixels: C-array bswap, UV path, sinf/cosf DVAL(), texture-import truncation",resolved -D75,PARTIAL,front-end 3D model transforms (D77 audio split out below —,PARTIAL (M-197 fixed the logo texture blobs; v0.4.0 campaign 2026-09-28: +D75,FIXED,front-end 3D model transforms (D77 audio split out below —,FIXED 2026-10-02 (branch fix/fidelity-gaps; by-eye check owed): D76 · D164,FIXED,Legal screen only draws line 1 —,"FIXED — this row and the ## D164 entry below were stale; the proposed one-line #ifdef PORT fix was actually committed 8dfc578f4 (2026-08-31), well before this correction (2026-09-18)." D159,FIXED,"front-end wallet-Bond photo ""interlaced""/combed (RC1 / D149) —",FIXED (#ifdef PORT no-op the swap in image.c) D161,FIXED,Depot (-level_30) ceiling = bright-blue speckle + radial rays (B2).,FIXED (port/fast3d/gfx_pc.cpp) @@ -337,4 +337,12 @@ D474,FIXED,fast3d micro-optimisations:,FIXED 2026-10-01 (local); output-identica D475,OPEN,Statue/Cradle hitches diagnosed:,OPEN (diagnosed 2026-10-01): D476,FIXED,CI4 textures keyed on their own 16-entry palette bank instead of the whole 256-entry table (D217 hash):,FIXED 2026-10-02 (local); Statue sweep CI4 cache misses 189 -> 36 D477,?,CI8 palette re-imports measured and ruled out as a CPU-side hitch cause:,MEASURED 2026-10-02 (local); premise of the D475/D476 follow-up refuted on the dev box; GPU/driver-side cost unmeasured +D478,FIXED,"D441 read-side census re-run (319 warnings, 129 outside the chr.c D34 initialisers) triaged against the current tree:","FIXED 2026-10-02 (local; snprintf bound); census triage recorded, Stage B items listed" +D479,FIXED,Split-screen GE_STARTMP harness hid the ammo counter:,"FIXED 2026-10-02 (local); harness-only, 2P frame shows the counter in both halves" +D480,FIXED,"Shader pre-warm: every created shader pair (shader_id0, shader_id1) is remembered in $S/ge007.shaders and compiled at the first frame of the next session, so a…","FIXED 2026-10-02 (local, perf/shader-prewarm); output-identical (menu frame exact), 0 in-play compiles on the warm run" +D481,FIXED,Low-end ~45/30 fps (#92):,"FIXED 2026-10-02 (local, perf/render-worker); X220 (HD 3000) 44-46 -> 60.0 fps, GE_RENDERINLINE=1 falsifier restores 45.9" +D482,FIXED,Lighter first-launch defaults on Atom/Celeron-class GPUs (#92 follow-up):,"FIXED 2026-10-02 (local, perf/lowend-defaults); X220 forced-path:" +D483,FIXED,#136: the PC crouch key stood Bond up when he switched to the sniper rifle; the N64 keeps the stance (the weapon's DISABLE_CROUCH flag blocks both crouch-down…,"FIXED 2026-10-02 (local, fix/d483-sniper); scripted crouch -> switch -> release keeps SQUAT" +D484,FIXED,"#136: portScaleFovY's 20-degree floor raised the game's own zoom FOVs, capping sniper/camera magnification at 20 degrees instead of the N64's 7 (about a third…","FIXED 2026-10-02 (local, fix/d483-sniper, maintainer-approved 2026-10-02); full zoom renders at 7 degrees, normal views pixel-identical" +D485,FIXED,"#136: sniper/camera zoom stepped once per game frame with no tick scaling, so at the port's 1 tick/frame it zoomed 2x faster in real time than the N64 at 2 tic…","FIXED 2026-10-02 (local, fix/d483-sniper); 15 -> 7 takes 16 frames at 60 fps (was 8) = the N64 at 30 fps" D450,FIXED,"Unplugging and replugging a controller was not picked up (user, GameSir-G7 Pro; 2026-09-29).","FIXED — port-only: the render thread's gfx_sdl_handle_events drains the same SDL queue as video.c's host pump but had no case for SDL_CONTROLLERDEVICEADDED/REMOVED, so it usually swallowed them and i…" diff --git a/docs/dev/findings.md b/docs/dev/findings.md index d5258bd6..064aace7 100644 --- a/docs/dev/findings.md +++ b/docs/dev/findings.md @@ -391,7 +391,7 @@ covers D24–D69; the log continues in §H (D32 procedure, D70–D121). | D59–D68 | intro render: blood-RLE clobber, DMA validate, OSMesgQueue, HEADS/BODIES sentinels, romCopy width, image_entry, Globalimagetable BE→LE | resolved | | D69 · D78–D84 | stage load (`load_bg_file`): bg/stan offline sidecar (`d69_emit.py`) + StandTile/bg_room_data ABI | resolved | | D70–D74 | intro-logo pixels: C-array bswap, UV path, sinf/cosf `DVAL()`, texture-import truncation | resolved | -| D75 | front-end 3D model transforms (D77 audio split out below — resolved, unrelated cause) | **PARTIAL (M-197 fixed the logo texture blobs; v0.4.0 campaign 2026-09-28: Nintendo + legal pages confirmed clean, but the Rareware logo still shows a minor texture-filtering artifact -- re-opened as a cosmetic known issue, README-disclosed): the D50 sidecar converter dropped the models' embedded texture blobs (`PnintendologoZ`/`PgoldeneyelogoZ`/`PlegalpageZ`) — `d43_emit.py` now raw-copies + round-trip-validates them; NTSC sidecars regenerated. Remaining: pal/jpn regen on ROM-holding machines.** Historical trail — M-32 triage (see §F "D75 ADDENDUM"): (a) D73-scope-gap RULED OUT (gu tree fully endian-clean). Splits in two: Bug 1 = logo/photo transform = the parked D114/D116 fast3d viewport mirror (not game code). Bug 2 = absent animated models = category (b). M-32b runtime probe (`GE_D75=1`): `render_pos`/`dynAllocate`-arena hypothesis RULED OUT (render_pos valid + fresh each frame), model instances valid (nMtx 21/1), zero fast3d DL warnings — failure is downstream in `drawjointlist`/`dotube` vtx/node-DL resolution or an off-screen `basemtx`. Needs a drawjointlist-level probe. M-33 (upright captures, D168 fixed): "Bug 1 = D114/D116 mirror" retracted; **gun-barrel Bond RENDERS fine** (walk + fire, upright) — the "absent" reports were the flipped capture; **Nintendo logo genuinely broken** (renders as 2 white blobs, shifted left — a real `logoinst` transform/geometry bug, not a flip); cast roll not re-captured. See §F "D75 Bug 2 — M-33 UPDATE". **v0.2.0-pre playtest (user):** Nintendo logo still broken; Rareware logo nearly right but its texture filtering looks off; MISSION COMPLETE / mode-select screens have no 3D models at all, so the earlier "absent mode-select model" framing was inaccurate.** | +| D75 | front-end 3D model transforms (D77 audio split out below — resolved, unrelated cause) | **FIXED 2026-10-02 (branch fix/fidelity-gaps; by-eye check owed): the Rareware logo's "texture-filtering artifact" was the RAREWARE text strip scrambled by a missing RDP odd-row TMEM swap, not filtering; see `### D75 round 2`.** Earlier: PARTIAL (M-197 fixed the logo texture blobs; v0.4.0 campaign 2026-09-28: Nintendo + legal pages confirmed clean, but the Rareware logo still shows a minor texture-filtering artifact -- re-opened as a cosmetic known issue, README-disclosed): the D50 sidecar converter dropped the models' embedded texture blobs (`PnintendologoZ`/`PgoldeneyelogoZ`/`PlegalpageZ`) — `d43_emit.py` now raw-copies + round-trip-validates them; NTSC sidecars regenerated. Remaining: pal/jpn regen on ROM-holding machines.** Historical trail — M-32 triage (see §F "D75 ADDENDUM"): (a) D73-scope-gap RULED OUT (gu tree fully endian-clean). Splits in two: Bug 1 = logo/photo transform = the parked D114/D116 fast3d viewport mirror (not game code). Bug 2 = absent animated models = category (b). M-32b runtime probe (`GE_D75=1`): `render_pos`/`dynAllocate`-arena hypothesis RULED OUT (render_pos valid + fresh each frame), model instances valid (nMtx 21/1), zero fast3d DL warnings — failure is downstream in `drawjointlist`/`dotube` vtx/node-DL resolution or an off-screen `basemtx`. Needs a drawjointlist-level probe. M-33 (upright captures, D168 fixed): "Bug 1 = D114/D116 mirror" retracted; **gun-barrel Bond RENDERS fine** (walk + fire, upright) — the "absent" reports were the flipped capture; **Nintendo logo genuinely broken** (renders as 2 white blobs, shifted left — a real `logoinst` transform/geometry bug, not a flip); cast roll not re-captured. See §F "D75 Bug 2 — M-33 UPDATE". **v0.2.0-pre playtest (user):** Nintendo logo still broken; Rareware logo nearly right but its texture filtering looks off; MISSION COMPLETE / mode-select screens have no 3D models at all, so the earlier "absent mode-select model" framing was inaccurate.** | | D76 · D164 | **Legal screen only draws line 1 — root-caused (M-31)**: linker-adjacency assumption broken by mingw. — full `## D164` entry at file tail | **FIXED** — this row and the `## D164` entry below were stale; the proposed one-line `#ifdef PORT` fix was actually committed `8dfc578f4` (2026-08-31), well before this correction (2026-09-18). Docs simply never caught up to the merge. | | D159 | front-end wallet-Bond photo "interlaced"/combed (RC1 / D149) — `texSwapAltRowBytes` odd-row 8-byte pre-swap (N64 RDP odd-line TMEM XOR compensation) not reversed by fast3d | FIXED (`#ifdef PORT` no-op the swap in `image.c`) | | D161 | Depot (`-level_30`) ceiling = bright-blue speckle + radial rays (B2). A CI8 tile drawn with `gsDPSetTextureLUT(G_TT_NONE)` was decoded against the stale `rdp.palette` → garbage. Fix: `#ifdef`-free narrow route CI→I when `palette_fmt == G_TT_NONE` in `gfx_pc.cpp import_texture()`. | FIXED (`port/fast3d/gfx_pc.cpp`) | @@ -437,7 +437,7 @@ covers D24–D69; the log continues in §H (D32 procedure, D70–D121). | D210 | **`chrToPatrol()` leaves `act_patrol.lastvisible60` uninitialised on PC — a raw-byte union alias (`act_init.padding[0x13]`) that shifts when `act_patrol` widens…** — full `## D210` entry at file tail | **FIXED (`chraction.c:3872`, `#ifdef PORT` → `self->act_patrol.lastvisible60 = -1;`, N64 line under `#else`).… | | D205 | **PC plays wrong/extra SFX for gameplay events (gunfire slap layer, explosion→scream, armour pickup, melee→Klobb idx 106) — user A/B vs N64 (M-71→M-78).** — full `## D205` entry at file tail | CLOSED (M-78) — root cause was D206; all four symptoms resolved + user-confirmed by ear. | | D152+ | **D152 addendum (M-31):** — full `## D152+` entry at file tail | FIXED (`src/snd.c`, `port/src/libultra.c`, `#ifdef PORT`) — fade-out repro playtest-gated, not headless-verified | -| RC3 · D167 | **Non-power-of-two texture wrap period (`docs/dev/TEXTURE-GLITCH-ANALYSIS.md` §6 RC3 — "textures repeat oddly", residual Depot-ceiling noise after D161).** The N64 RDP masks the texel coordinate of a wrapping render tile at `1< 36 | | D477 | **CI8 palette re-imports measured and ruled out as a CPU-side hitch cause: decode+upload averages ~0.008 ms/frame (worst frame 0.44 ms); the cache already holds the animated palettes (1314 misses, 10 re-misses); one CI8 texture is drawn with several palettes per frame, so an in-place update path would thrash** — full `## D477` entry at file tail | MEASURED 2026-10-02 (local); premise of the D475/D476 follow-up refuted on the dev box; GPU/driver-side cost unmeasured | +| D478 | **D441 read-side census re-run (319 warnings, 129 outside the `chr.c` D34 initialisers) triaged against the current tree: no live 32-bit truncation of a non-arena pointer found; one real port bug fixed (`libultra.c` crash-log `snprintf` passed a pointer as its size bound)** — full `## D478` entry at file tail | FIXED 2026-10-02 (local; snprintf bound); census triage recorded, Stage B items listed | +| D479 | **Split-screen `GE_STARTMP` harness hid the ammo counter: it skipped the file-select screen's `selected_folder_num = -1`, so the stage load applied a blank folder-1 record (options 0: ammo, sight, auto-aim off); harness now sets -1 like a real MP launch** — full `## D479` entry at file tail | FIXED 2026-10-02 (local); harness-only, 2P frame shows the counter in both halves | +| D480 | **Shader pre-warm: every created shader pair `(shader_id0, shader_id1)` is remembered in `$S/ge007.shaders` and compiled at the first frame of the next session, so a first-seen combiner no longer compiles mid-play (the one in-play stutter in the 2026-10-02 play capture: 7 compiles = 18.7 ms in one frame)** — full `## D480` entry at file tail | FIXED 2026-10-02 (local, `perf/shader-prewarm`); output-identical (menu frame exact), 0 in-play compiles on the warm run | +| D481 | **Low-end ~45/30 fps (#92): the port ran fast3d inline on the N64 scheduler thread, so a VI retrace arriving mid-render reached the game late and `boss.c`'s half-frame tick gate skipped the next one (33 ms frames whenever renders take ~8+ ms); gfx tasks now run on a render worker that posts SP/DP done like the hardware** — full `## D481` entry at file tail | FIXED 2026-10-02 (local, `perf/render-worker`); X220 (HD 3000) 44-46 -> 60.0 fps, `GE_RENDERINLINE=1` falsifier restores 45.9 | +| D482 | **Lighter first-launch defaults on Atom/Celeron-class GPUs (#92 follow-up): after D481 the remaining gap to the PD port is workload, not code (fast3d is as cheap per batch/triangle as PD's); on Intel HD 400-605 / UHD 600-605 / Bay Trail-class and software renderers, DrawDistance/LodDistance 250 -> 100 and MSAA 2 -> 1, only where still at the port default, once per ini** — full `## D482` entry at file tail | FIXED 2026-10-02 (local, `perf/lowend-defaults`); X220 forced-path: Cradle batches 482 -> 146, render CPU 8.2 -> 5.2 ms, GPU 12.7 -> 10.6 ms | +| D483 | **#136: the PC crouch key stood Bond up when he switched to the sniper rifle; the N64 keeps the stance (the weapon's DISABLE_CROUCH flag blocks both crouch-down and crouch-up)** — full `## D483` entry at file tail | FIXED 2026-10-02 (local, `fix/d483-sniper`); scripted crouch -> switch -> release keeps SQUAT | +| D484 | **#136: `portScaleFovY`'s 20-degree floor raised the game's own zoom FOVs, capping sniper/camera magnification at 20 degrees instead of the N64's 7 (about a third of the zoom)** — full `## D484` entry at file tail | FIXED 2026-10-02 (local, `fix/d483-sniper`, maintainer-approved 2026-10-02); full zoom renders at 7 degrees, normal views pixel-identical | +| D485 | **#136: sniper/camera zoom stepped once per game frame with no tick scaling, so at the port's 1 tick/frame it zoomed 2x faster in real time than the N64 at 2 ticks/frame; steps now scale to base^(ticks/2) (RULE-2, maintainer-approved)** — full `## D485` entry at file tail | FIXED 2026-10-02 (local, `fix/d483-sniper`); 15 -> 7 takes 16 frames at 60 fps (was 8) = the N64 at 30 fps | | D407 | **Tanks cannot be boarded/exited on PC — the v0.4.0 use/reload split (D378/D393) removed the B-button tap the engine's tank handlers in `bondview2.c` consume (user report 2026-09-28, Runway/Streets)** — full `## D407` entry at file tail | PARTIAL (fix landed in v0.4.0, port-only): present `GE_CONT_B` on the use (E / pad A) rising edge only while `g_PlayerIsInTank == 1` or `g_BondCanEnterTank != 0`; E keeps its D378 no-reload-fallback semantics elsewhere, N64 layout unaffected. D407(b) same cycle: front PC Options page-edge highlight clamp + mouse-wheel / W-S paging (wheel queue consumed on the menu, D223); its wheel mapping shipped inverted and was fixed to match W/S (wheel up = step up). D407(c): board-animation lockout, menu-accept B gate in tank states, in-tank aim routed through the legacy velocity stick + `Input.TankAimScale` knob. RESOLVED 2026-09-28: all port-only (src/game zero-diff), 10 TANKDBG probes stripped, release binary verified clean, user live tank drive signed off (board + exit OK, aim feel good). | | D408 | **`Game.SkipIntro` skips the post-mission failure dossier: with it on, entering a level then aborting (watch Z+A) or dying (KIA) returns straight to the menus — no REPORT / "Mission status: KILLED IN ACTION / ABORTED" screen** (user report 2026-09-28; save/AllUnlocked ruled out) — full `## D408` entry at file tail | OPEN (cosmetic, not root-caused past the handoff site). v0.4.0 decision: SkipIntro stays EXPERIMENTAL / not recommended for regular users — F10 row relabelled "Skip intro (EXPERIMENTAL)". | | D450 | **Unplugging and replugging a controller was not picked up (user, GameSir-G7 Pro; 2026-09-29).** — full `## D450` entry at file tail | FIXED — port-only: the render thread's `gfx_sdl_handle_events` drains the same SDL queue as video.c's host pump but had no case for `SDL_CONTROLLERDEVICEADDED/REMOVED`, so it usually swallowed them and `inputRescanPads` never ran. Both pumps now post a request; the rescan runs at the top of `inputUpdate`, on the thread that reads the pads. | @@ -10661,6 +10669,18 @@ This entry is long and multi-pass (M-87 through M-176, spanning several sessions D243 (cutscene shake/duplication, its own CONSOLIDATED NEXT STEPS block appears earlier in this file) and D292 (death sinking) are cross-referenced as the same general "third-person world model transform" family, though this session's D173 work found its specific root cause (a likely asset-decode issue in one named clip) rather than a shared code-level mechanism — don't assume D243/D292 share this exact cause without separately verifying each. +### D173 residual, 2026-10-02 probe pass (branch fix/fidelity-gaps; temporary `GE_D173P` probe in `chrTick`, removed) + +Probe: the intro puppet (`model == g_CurrentPlayer->bodyModel`) logged `prop->pos`, tickamount, `actiontype`, anim index and frame after the position update, every tick, on `-level_33` (Dam) to frame 1000. 16 free-seed boots (8 at `Video.FpsCap` 60 = 1 tick/frame, 8 at 30 = 2 ticks/frame) plus 9 boots with `GE_RSEED` pinned (6 at 60, 3 at 30). + +1. **No float, no per-tick drift.** `pos.y` is 2.48-2.59 (grounded) for the whole stand phase, identical across all boots and both tick rates; x/z constant. The D173 bulk (324 units) is gone. The phase 61 (`extending_left_hand`) to 106 transition is deterministic (T=102 at 60 fps, 104 at 30, in puppet ticks). +2. **The residual is the idle-to-walk transition time.** The 106 (`ACT_STAND`) to 99 (walk) switch lands at T = 364..382 across free-seed boots at both rates. `chrlvTickStand` (`chraction.c` ~5133) draws `sleep = rand%5+14` per run and decrements `wallcount` (initialised `rand%120+180`, `chraction.c:508`) by it, so the transition depends on the PRNG state and on how many stand-ticks ran. With the seed pinned it is no longer random but still tick-structure dependent: 60 fps with no 2-tick frames gives T=374 (3 of 3 boots identical, bit-identical positions); one 2-tick burst gives 370-372; all-2-tick (30 fps) gives 368-370. Bond then walks (about 2 units/tick root motion), so the position at a fixed time differs by up to ~40 units mid-walk (x 20177..20195 at T=400) and converges to within ~4 units by T=460 (x 20158.5-20160.5, z 16905-16909). That matches the size and character of the reported "off by a small amount". +3. **One deterministic one-frame transient:** the very first puppet tick reports `pos.y = -45.71` (-44.72 at 30 fps) before settling to 2.48 on the next tick, in every boot. Not the user's 1-in-10, and one frame; mechanism not traced (first `chrUpdateAnim` root-motion read at animation frame 95.0 before the first full tick). + +Interpretation (bucket): the variance is PRNG- and tick-count-driven AI idle timing, the D13/D329 class (1 tick/frame reaches states the N64's 2-3 ticks/frame did not), and the N64 is equally random from its own seed and frame-time jitter. No port defect, ABI/layout misread or stale-animation attach was found on the intro-puppet path, and nothing here justifies a game-logic change: **no Rule-2 sign-off is requested.** The user's residual may also live elsewhere (a cutscene body model: Cradle/Dam end, Cuba credits), which this intro-only probe cannot reach; the maintainer noting WHERE it appears is the next step. + +**Status:** residual not reproduced as a defect on the level-start puppet; explained there as faithful tick/PRNG-dependent idle timing. Confidence: medium that this accounts for "placed slightly differently"; low that it is the user's exact 1-in-10 case. Probe removed; tree clean. + ## D179 — Packaged build crashes after the logos — the D43/D69 model + bg sidecars are ROM-derived and absent from any build that has no ROM (M-34, alpha-release QA). **Packaged build crashes after the logos — the D43/D69 model + bg sidecars are ROM-derived and absent from any build that has no ROM (M-34, alpha-release QA).** The first `goldeneye-pc-port-*-win64.zip` from CI (bundle-win.sh) shows the Rare/Nintendo logos (compiled-in `assets/rarewarelogo.c`) then AVs at `0x6b157a88`/`0x70157a88` — symbolised: `modelPromoteNodeOffsetsToPointers` (`model.c`) ← `load_object_fill_header` (`objecthandler_2.c`) ← first prop/item model load. Root cause is **not** a code regression: the port loads PC-layout model geometry from `data/pcmodels-/{pcmodels.bin,manifest.csv}` and stage bg/stan from `data/pccg-/{pccg.bin,manifest.csv}`, both produced offline by `tools_pc/d43_emit.py` / `d69_emit.py` from the ROM (see `port/src/pcmodels.c` / `pccg.c`; `pcmodelsReserveSize` logs *"pcmodels.bin not found — model loads will fail"* and returns 0). CI has no ROM so it never runs the emit scripts, and the two `data/` dirs are (correctly) gitignored ROM-derived game data — **cannot be committed or shipped** (converted Nintendo/Rare geometry, DLs, collision, stan nav; = distributing assets). A local build with those dirs present runs clean (verified M-34: 1741 frames, `romdataInit ... mapped at 0x10000000`, `pcmodels: 512 sidecars`, `pccg: 73 sidecars`, no crash — so `0x10000000` is *not* the problem here). The `docs/building.md` sidecar-gen step was also missing entirely. **Fix = release-side, backlogged** (`docs/BACKLOG.md` → "Alpha release"): bundle the emit scripts + their committed inputs as a pure-stdlib-Python asset-prep tool the user runs once against their own ROM (~5 MB output, no MIPS toolchain). Secondary/latent: the fixed-address `VirtualAlloc((LPVOID)0x10000000)` in `romdata.c` has no working fallback (`"using heap copy — direct ROM reads will fail"` then limps into the same crash) — didn't bite M-34 but will on a machine where something occupies `0x10000000`; harden separately (reserve earliest in `main`, or retry low bases and derive all segment math from the base obtained). @@ -11868,6 +11888,25 @@ Superseded history below (the original OPEN investigation, root cause not found **Status (from §F table):** DEFERRED (user call 2026-09-28: v0.4.0 ships NTSC-only, README-disclosed; the verified repair path is post-v0.4 backlog). Superseded: OPEN — repair path verified, not applied (out of v0.2.0 scope). +**2026-10-02: FIXED for both regions, verified against real PAL and JP ROMs** (maintainer-supplied PAL dump `167c3c43...` and the JP dump `2a5dade3...`, both = the decomp's `.sha1`). Every repaired row was byte-compared with the real ROM, not inferred. +- **JP** (`filelist.j.csv`): the one font row renamed `fontZurichBold` -> `fontBankGothic_fontchartable` (its 8716 bytes at 3044276 equal the US BankGothic chartable). +- **PAL** (`filelist.e.csv`) had more than the 31 labels found statically: (a) **47** truncated model basenames (`Pbridge_console` x6, `Pchrgrenadelauncher`, ...) renamed to the table symbols, each 47/47 byte-identical to the US file of that name; (b) **96 missing rows** reconstructed: the whole pre-bg block (jfont/efont, animation tables, Globalimagetable, Rareware logo, the usedby7F008DE4 blob, fonts, sfx/instrument banks, music.sbk + all 63 music tracks) located at constant shifts (-77968 / -39872) with byte checks, the region-specific `jfont_chardata` by the gap, and the 14 PAL-specific **ramrom** demos by walking the block with each header's `filesize` field (offset 0x80, padded to 16), which lands exactly on the font block and matches every stage id; (c) the `ob__ob_end.seg` terminator row (16 bytes at 9402416, identical to US); (d) two **swapped label pairs** at shared offsets: `bg_len`/`bg_lip` and `bg_rit`/`bg_oat` (the non-empty file proven by bytes). No N64-build file reads `filelist.e/j.csv` (only `.u`), so these are port-tooling data fixes. +- The emitters (`d43/d69/d88_emit.py`) always read `filelist.u.csv`: now the region's own list. `port/src/romdata.c` knew only PAL vs "else NTSC": JP now expects country 'J' and `ge007.jpn-final.z64`/`baserom.j.z64`. `gen_romassets.py e|j` -> `port/src/romassets_e.s` (1773 symbols: US's 1685 + the 44 PAL-only `L*P` text banks with end markers) / `romassets_j.s` (1685). +- PAL also failed to link: port code referenced debug-menu globals that exist only with `LEFTOVERDEBUG` (US/JP, not PAL): the D243 `GE_DEBUGMENU` branch in `src/boss.c` and the `All unlocked` debug-flag seeding in `port/src/main.c`; both now `#if defined(LEFTOVERDEBUG)` (US/JP compile unchanged; D442's query-time hooks cover All unlocked on every region). +- **Verified (Windows, from the repo root with region-suffixed sidecars):** all six emitter runs "ALL CHECKS PASSED"; `BUILD_DIR=build-jpn ./build-pc.sh jpn-final` and `build-pal ... pal-final` link with 0 errors; both boot through legal / Nintendo / Rareware / gun barrel and play Dam (`-level_33`) with no crash; NTSC-U `verify.sh dam` still PASS. +- **Open:** PAL ammo counter missing (D487); PAL legal-screen bottom line partly cut (compare with 1964); full-level/menu/audio/save runtime passes for both; packaging (per-region exe names, CI matrix, drop-in converter region gate). +**Status:** FIXED (asset conversion + build + boot, PAL and JP). + +## D487 — PAL: the in-level ammo counter is not drawn (only a small dot where "7 | 93" should be) + +Found by the D258 PAL bring-up (2026-10-02): `-level_33` Dam on the PAL build (`build-pal`) shows the gun and gameplay normally, but the HUD ammo counter at bottom right renders as a single small yellow dot; the JP and NTSC-U builds draw "7 | 93" in the same capture. PAL takes EU-only HUD/text paths (`VERSION_EU` / `LANG_EU`) that have never run on PC, so a port-side ABI or font-table issue on an EU-only path was the first suspect. +**Root cause (2026-10-02, maintainer pointed at TCRF: "the European version renders at 320x269@50Hz with no borders"; the whole PAL bottom was cut, not just the HUD):** `port/src/libultra.c` `osViSetMode` recovers the CFB height from `yScale` assuming the NTSC encoding `bufy * 0x800 / 480` (`src/fr.c` non-EU `video_related_8`). The EU build compiles a different `video_related_8` (`fr.c` ~478, `#ifdef VERSION_EU`) that encodes `bufy * 0x800 / (0x220 + (bufy == 330 ? 28 : 0))`, i.e. against 544 (572) lines. A temp log showed the PAL mode arriving with `yScale 0x400` (= 272 lines in the EU encoding) decoded as 240, so fast3d's native viewport was 32 lines short and the bottom ~12% of every PAL frame (HUD ammo counter, legal-screen last line) fell off. The `OS_VI_BIT_PAL` test in `osViSetMode` never fired: the EU game runs with `osTvType = MPAL` (see below) and its modes don't carry that bit. +**Fix (port-only, `#ifdef VERSION_EU`):** decode with the EU rule (smallest height whose EU encoding reproduces `yScale`; fallback 272 = `fr.h` `SCREEN_HEIGHT_272`), keyed on the build. `video.c` `GE_NATIVE_H` for PAL (pre-VI seed only) corrected 400 -> 538 with the TCRF facts. NTSC-U/JP code unchanged. +**Verified:** PAL Dam frame 1500 shows the full "7 | 93" ammo counter; the PAL legal screen shows its last line ("Used by permission of EMI Unart Catalog Inc."); NTSC-U `verify.sh dam` PASS; JP build/run unchanged. +**Open question (resolved by D488, 2026-10-02):** the port set `osTvType = OS_TV_MPAL` for EU (libultra.c, comment says "PAL consoles report MPAL"). A real PAL N64 reports `OS_TV_PAL` (0). GE's `sched.c:287` and `init.c:237` test only for MPAL (else NTSC LAN1), so on real PAL hardware those take the NTSC branch while the port takes MPAL; the EU `video_related_8` then installs its own PAL-table modes (`osViModeTable[16]/[20]`), so the visible effect may be nil. Needs a 1964 PAL comparison before changing (it would also move the port's 50 Hz tick selection, which keys on MPAL||PAL). +**Status:** FIXED (maintainer by-eye check on PAL owed). + + ## D279 — Backfilled — this label was consumed by an undocumented partial session (2026-09-14 ~23:00) that left artifacts in `scratch/` (`d279_run.log`… **Backfilled — this label was consumed by an undocumented partial session (2026-09-14 ~23:00) that left artifacts in `scratch/` (`d279_run.log`, `d279_imgmap_run.log`, `d279_g110.png`, `d279_g220*.png`, `d279_gray_1500.png`) but no written conclusion; the logs carry no D279-tagged lines, so its exact probe/finding cannot be reconstructed from the tree.** Next available label after it: D280. @@ -12019,6 +12058,8 @@ Superseded history below (the original OPEN investigation, root cause not found **2026-09-30 (fix/d294-room-pool-cap): cap raised 2.0 -> 2.5, residual corner flicker fix landed (port-only, awaiting by-eye check).** The 3x 'regression' above was D336 (uninitialised head-anim placeholder fields), not pool size, so the cap is revisitable. `portRoomPoolScale()` (`port/src/video.c`): final cap 2.0 -> 2.5 (and the `GE_ROOMPOOL` clamp 2.0 -> 2.5); DD/Lod terms changed from `sqrtf` to `powf(x,0.66)` (4^0.66 = 2.497) because with sqrt the max-DD term is exactly 2.0 and a raised cap alone changes nothing; result is rounded UP to a quarter step because `boss.c` truncates `(s64)(scale*4)` (raw 2.497 truncated to 2.25 -> ma=506880, only 4% over Statue's 487 KB set). Statue at FovScale 150 / DD 400 now gets `ma` = 2.5 x 225280 = 563200 (was 450560), i.e. 1.16x the full 27-room set (measured sum of `D104 LOAD used` over 27 rooms = 498752). Worst case `-ma350` row = 875 KB, well inside the STAGE bank (~3.8 MB free per D336; `boss.c` still clamps to bank-left minus 128 KB). Identity at N64-faithful settings unchanged. Headless check (max FOV, DD 400, scripted walk, `GE_D294`/`GE_D104`): no `FAIL alloc` before or after -- the scripted walk cannot reproduce the fast-strafe churn, so the exhaustion counter is NOT falsified either way; maintainer to check Statue corners at max FOV by eye. No `src/game` change. +**Maintainer check 2026-10-02:** max FOV + max draw distance, fast strafe past the Statue plaza/park corners: no flicker. VERIFIED, closed. + ## D211 — PC FOV slider — `Video.FovScale` (M-83 QoL wave, port-only, `WIDESCREEN-FOV-PLAN.md` Phase 4). **PC FOV slider — `Video.FovScale` (M-83 QoL wave, port-only, `WIDESCREEN-FOV-PLAN.md` Phase 4).** fast3d applies a multiplicative half-angle scale to every *perspective* projection matrix as it is loaded (`gfx_apply_fov_scale()` in `gfx_pc.cpp gfx_sp_matrix`, on the `G_MTX_PROJECTION | G_MTX_LOAD` path only — GE always reloads its view projection via `guPerspectiveF` at `fr.c:725`, so a relative `G_MTX_MUL` onto an already-scaled matrix cannot compound). Columns 0 and 1 are scaled by the same factor `tan(half_orig)/tan(half_adj)` → H and V FOV widen uniformly, aspect ratio exactly preserved (no stretch), and because the game rewrites fovy every frame for aim-zoom the scale composes with zoom for free. Ortho matrices (`P[3][3]==1`) are left untouched so HUD/menu 2D is unaffected. `Video.FovScale` = percent of the original vertical FOV, 50–150, **default 100 ⇒ `g_fov_scale == 1.0f` ⇒ guarded early-return, zero FP ops on the matrix ⇒ golden dumps byte-identical**. F10 overlay row "FOV scale %". Math checked offline (`s=1.25 → fovy 60°→75°`, aspect held at 1.3333). @@ -12484,7 +12525,7 @@ Adversarial pre-ship review of the whole v0.3.0 window (147 commits since v0.2.2 **User report (2026-09-18):** crash on Cavern, early in the level, on the local v0.3.0 pre-release build this session deployed to the Deck (`~/Downloads/goldeneye-pc-port-0.3.0-deck-playtest/`). User's own hypothesis: likely related to `Game.AllUnlocked` (the F10 "unlock everything" toggle, D257), which had been previously enabled on that session/save. -**Fetched `ge007.crash.log` via SSH from the Deck (the LAN address) and symbolized it against the exact deployed binary** (confirmed identical build via matching ELF BuildID `d6ec0681d2e82a656c7a099f66264d6bfa4480b7` between the Deck's copy and this session's local `build-linux/ge007.x86_64` — the SHA256 differs only because `bundle`-style `patchelf --set-rpath` modifies the file after linking, not because the code differs): +**Fetched `ge007.crash.log` via SSH from the Deck and symbolized it against the exact deployed binary** (confirmed identical build via matching ELF BuildID `d6ec0681d2e82a656c7a099f66264d6bfa4480b7` between the Deck's copy and this session's local `build-linux/ge007.x86_64` — the SHA256 differs only because `bundle`-style `patchelf --set-rpath` modifies the file after linking, not because the code differs): ``` SIGNAL: 11 FAULT ADDR: 0x62 @@ -13003,6 +13044,20 @@ Full campaign (or at minimum Silo → Caverns/Cradle) with **`GE_D322=1 GE_D204= **Status:** **FIXED, user-confirmed live (2026-09-21)** — "the images and legal page and Nintendo logo are good now." Tooling fix + ntsc-final sidecars regenerated; headless-verified before the live check. Remaining: `pal-final`/`jpn-final` sidecar regeneration on machines holding those ROMs (`python tools_pc/d43_emit.py ` — the fix is in the tool, so any future regen is correct), and D75's last unverified scope: cast-roll models (status unknown since M-33; recheck with `GE_PCDUMP="1400-2200:25"`). +### D75 round 2 (2026-10-02): the Rareware logo "texture-filtering artifact" is the RAREWARE text strip, scrambled by a missing RDP odd-row TMEM swap + +**Symptom.** Maintainer reference (1964/GEPD, face-on logo): the RAREWARE lettering under the R is clean gold glyphs. Port: the same strip is interleaved/combed garbage (alternate texel rows horizontally shifted by 2 texels), identical at `Video.TextureFilter` 0, 1 and 2 (so not a filtering/clamp/wrap issue; the seam/half-texel suspects in the triage were wrong). The R, border and panel (different textures, `D_02004FE8`/`D_02005FF0`) are fine. Colour/brightness differences vs 1964 are emulator/plugin differences and were ruled out of scope by the maintainer. + +**Root cause.** `DL_RAREWARETEXT` (`assets/rarewarelogo.c:1153`) draws the four text pieces (`imgRAre_0x0020`, `img_raRE_0x0AE0`, `imgWAre_0x15A0`, `imgwaRE_0x2060`; each 32x32 RGBA16 plus mip chain, 2744 B) with `gsDPLoadBlock(7, 0, 0, 1371, 0)`, i.e. **dxt = 0**. On the RDP, LoadBlock only swaps odd rows' 32-bit halves on the way into TMEM when its dxt row counter advances; TMEM reads always swap odd rows (address bit 2). With dxt = 0 the load-side swap never happens, so the sampled image is the memory image with the two 32-bit halves of every 8-byte group swapped on odd rows. Rare's asset data is pre-swapped for exactly that. Decoding `imgRAre` offline both ways (scratch script, not kept): linear = garbled, odd-row 32-bit-pair swapped = clean lettering. fast3d ignored `dxt` (`gfx_dp_load_block`) and uploaded the memory image linearly. The same dxt = 0 loads are used by `tex.c` for the whole runtime texture pipeline (measured: ~580 imports in `-level_09`/`-level_33` boots, mostly CI8), but there the compensating pre-swap (`texSwapAltRowBytes`) is no-op'd by D159, so those images are already linear and must NOT be swapped again. + +**Fix (port-only, `port/fast3d/gfx_pc.cpp`, commit a2e812c3).** `gfx_dp_load_block` records `dxt == 0` on the `LoadedTexture` (`gfx_dp_load_tile` clears it); `import_texture` emulates the read swap (swap the two 4-byte halves of each 8-byte group on odd tile rows, after destride) only when the load was dxt = 0, the format is not 32b, the tile line is a whole number of qwords with more than one row, **and the source is a compiled-in exe-image C array** (`gfx_tex_source_is_c_array`, the D71 distinction: raw 0x70xxxxxx/cart sources are the D159-linearised runtime pipeline). The swap flag is folded into the texture-cache key (`palette_hash ^= 0xD75D75D7`). No game code touched. + +**Verification.** A temporary `GE_D75SW` log (removed): the first, ungated version fired ~260-330 times per level (the tex.c textures) and was caught and gated before commit; with the gate, over a full 3700-frame boot through the cast roll the swap fires exactly 4 times (the 4 text imports, `size=2048 line=64`), and in `-level_09` and `-level_33` (300 frames) 0 times, so non-logo output is unchanged by construction. Before/after captures at 1280x960, frame 950, filters 1 and 2: lettering garbled -> clean, crisp RAREWARE. + +**Cast roll (checked).** `GE_PCDUMP="0-3600:60"` over the whole intro. At the real 60 fps the D70 frame numbers are about 2x later: legal ~60-240, Nintendo ~300-720, Rare ~780-1000, gun barrel ~1000-1700, GoldenEye title ~1800-1900, cast roll ~1980-3600. Every cast card from "Starring 007 James Bond" through "Guest Star Mayday" renders a textured, lit, posed character model with its caption, placed left/centre and fading in/out. Seen at contact-sheet resolution only (1/4 scale); fine detail (head/body seams, hats) was not inspected. Verdict: renders, no gross placement/texture failure; maintainer by-eye pass owed for detail. + +**Status:** FIXED (port-only), headless-verified; by-eye confirmation owed. Confidence high that the strip defect is this swap (controlled before/after plus the offline decode agree) and that nothing outside the logo changed (0 swaps in two levels and the rest of the intro). + **2026-09-25 capture (user, Windows, ~46 min, Silo → Caverns, `GE_D322=1 GE_D204=1`, build `7baf4900`; log `scratch/d322_session.log`).** User: "sound gets glitchy… gunshots from your gun and other sounds start to drop out as things stack up"; "audio did get garbled" (times not noted). No crash. - **Pools: no leak.** SFX voices (`sfx`) fall back to 0–2 in quiet stretches; physical voices never exhausted (min free 4/24, `lame` always 0); event queue max 28/64. The voice-pool-exhaustion/counter-drift hypothesis (ranked #1 above) is **refuted** for this session length. @@ -13030,6 +13085,8 @@ The same device at the same moment drains at exactly real time through DirectSou **Fix:** `audioInit()` sets `SDL_HINT_AUDIODRIVER = "directsound,wasapi"` on Windows before `SDL_InitSubSystem(SDL_INIT_AUDIO)` (the only audio init in the port); `SDL_AUDIODRIVER` in the environment still overrides it (normal-priority hint). The init log line now names the driver. **Verified:** golden gate 3/3; Bunker 1 60 s with `GE_D204=1`: driver `directsound`, rt 0.997–0.999, q 240–624, one drop during the level load (pre-existing) and none after. **Owed:** a long play session on the maintainer's machine (the bursts came every ~5 min), expect `drop=` flat after the load. Then re-assess the firefight SFX drop-outs; D207's measurements found no sounds actually dropped by the 8-voice cap, so they were most likely this same block loss. +**Maintainer check 2026-10-02:** RAREWARE text clean in a live boot; the cast roll (all 9 cards, Bond to Mayday) renders correctly by eye, so D75 has no remaining scope (after refreshing the stale `build-pc/data` sidecars, which had shown the pre-M-197 Nintendo logo). VERIFIED. + ## D323 — G_TL_LOD bindings of explicit-LOD textures: PC samples driver mips from LOD0; N64 samples the authored mip chain (static census, 2026-09-21) **Context.** D107 established that GE's room DLs emit `G_TL_LOD` and that the port folds every LOD draw to tile 0 (driver-generated GL mips from the finest level). D236 then found + fixed the one case where that folding was *visibly* wrong for a type-1 (DETAIL) binding of an RGBA5551 cut-out. This entry closes the loop on the rest of the surface: how often do LOD-on draw classes bind textures that actually carry **authored** mip levels, and does the N64 hardware behavior differ from the port's? @@ -15628,6 +15685,8 @@ included; D281 keeps the shipped mitigation + disclosure, zero-saves root cause **Status:** OPEN — cosmetic (no crash, no data loss; the mission still records as failed/aborted and the menus are fully functional). Root-causing needs a side-by-side of front-end state (`current_menu`, `g_CurrentStageToLoad`, `mission_failed_or_aborted`, `g_isBondKIA`) on the fail return with SkipIntro off vs on — candidate for v0.5.0 alongside the D216 audio half. +**Maintainer check 2026-10-02:** SkipIntro on, aborted mission shows the failure screen; no menu music glitch on return. VERIFIED, closed. + ## D415 — Shooting a light fixture does not "kill" its flickering light (Bunker, Caverns) (community report, 2026-09-28) @@ -16224,6 +16283,8 @@ Whichever loop runs `SDL_PollEvent` first gets the event, and the render loop us ## D466 — #125: extended draw distance leaked into gameplay visibility (Xenia's boss fight triggers early) +**Credit:** MST246's investigation in #125 (developer handoff with a locally tested correction: the extended draw-distance setting also extends the room admission gameplay uses, so Xenia's original on-screen condition fires early) was used to remediate this; credited in the issue close-out. + **RULE-2-SIGNOFF (port-feature leak fix; approval delegated by the maintainer to a design review, 2026-10-01).** Touches `src/game` behaviour only to undo a port feature's leak into gameplay: every edit is `#ifdef PORT`, every `#else` arm is the original code, and every hook is a no-op at a draw-distance multiplier of 1 (unless `GE_D466_FORCE=1`). **Problem.** `Video.DrawDistance` (default 250%) scales the level's authored `FarFog` into `viSetZRange` (`bgfog.c`, D218). That one value fed both rendering and gameplay: (1) room admission (`bgIsRoomOnScreen`, `sub_GAME_7F0B5528` reject rooms beyond `zfar`), so more rooms became `room_rendered`; (2) the fog tests (`fogPositionIsVisibleThroughFog`, `g_ScaledFarFogIntensity`, and the D222/D218 `/ multiplier` hooks in `sub_GAME_7F054C58`). Guards 2.5x farther away were therefore "on screen" / "seen" to AI scripts, `chrCheckTargetInSight` and spawn-out-of-view picks, which the N64 never did. Measured on Jungle (static camera, DD 250): 8 chrs ONSCREEN, 3 gameplay-on-screen; the 3 equals the DD 100 count. @@ -16327,6 +16388,8 @@ Whichever loop runs `SDL_PollEvent` first gets the event, and the render loop us **Probes left on the branch (TEMP, `GE_D433LOG`, cached getenv):** `D433P` macro + SHOT/FIRESND/DRYCLICK/STATS hooks in `src/game/gunfire.c`. Strip before merge. **Confidence:** high for the code path and the log; medium for "the reporter's trigger-hold explains it" (unmeasured). +**Maintainer check 2026-10-02:** taps never click; a held trigger dry-clicks until release, same as the other guns and the N64. #130 closes (the report predated the D427/D432 fire-rate fixes). CLOSED faithful. + ## D469 **Status: DONE (port-only; live pad test owed).** Branch `feat/pad-presets-rebind` (cut from `release/v0.4.1`). No `src/game` edits. @@ -16439,3 +16502,111 @@ Whichever loop runs `SDL_PollEvent` first gets the event, and the render loop us - Spikes: 3 frames > 33 ms in 2420 (frames 3, 459, 762), each with render-thread `dl`/`run` 0.2-0.6 ms; none coincides with the worst CI8 frame (577). **Not measured:** driver-deferred work (first-draw allocation of a new texture, `glGenerateMipmap` forced by the three-point filter on every upload) shows up neither in these CPU timers nor in the averaged GPU timer. The D475 association between the bursts and palette re-imports was temporal, not a measured cost. **Conclusion:** GPU palette lookup / in-place update are not justified by this data. Next step if the hitches still matter: a per-frame timeline (game-thread build + limiter decision, render-thread misses/new textures/shader compiles, per-frame GPU timestamps, swap time) over >=5 runs, PresentMon for what reaches the screen, and a disable-falsifier per suspect. Low-end hardware may weigh these costs differently (a `GE_PERFSTAT` run there is still owed, ROADMAP §4). + +## D478 — D441 census re-run triaged; crash-log `snprintf` size bound fixed + +**Census:** `scratch/d441p2/run.py` (`-fsyntax-only -Wint-conversion -Wint-to-pointer-cast` over every compiled `.c`) on `release/v0.4.1` after strip batch 4: **319** warnings (320 on the previous run). 190 are the intentional `(s32)&ANIM_DATA_*` offset initialisers in `chr.c` (D34). The other 129 were read site by site (triage list in the local `scratch/d441p2/triage-2026-10-02.txt`). +**Rule used:** on the current layout a 32-bit truncation only breaks if the pointer is outside the DRAM arena (the 0x70000000 window): the exe image (ImageBase 0x140000000), the C heap, or a stack above 2 GiB. An arena pointer survives a `(s32)` round trip today (positive, below 2 GiB) and only becomes a hazard when Stage B moves the arena (`GE_HIGHARENA` flavour). A K0-mirror (0x80000000+) value held in an `s32` would sign-extend; none found on a live path. +**Fixed (port code, no game-code change):** `port/src/libultra.c` romCopy-bad-destination crash log passed `win + sizeof(win) - (wp - win)` (a pointer) as `snprintf`'s size, so the bound was meaningless; now `sizeof(win) - (size_t)(wp - win)`. Latent only (32 x `" %p"` fits in the 1200-byte buffer, and the path runs just before a FATAL). +**Not live today, by class:** +- *Arena pointers in `s32`/`u32` slots* (Stage B list): `stan.c` `stan_prefix.stanfile`, `bondview2.c` start-pad `stan`, `title.c` `dword_CODE_bss_8006958C`/`_80069588`/`barrelDisplayListPtr`, `initmenus.c` `ptr_menu_videobuffer`, `viewport.c` `z_buffer`, `rsp.c` RDP output buffer, `cleanup_objects.c` propDefs, `objecthandler_2.c` file arithmetic, `chr_b.c` head opcode, `initactorpropstuff.c`/`initanitable.c` animation table (the planned slot model), `mema.c` (planned `s32`+sentinel widening), `mpmenu.c` `q` = `langGet` result (bank in the arena; the neighbouring `h2` already has a PORT pointer type, `q` could follow), `audi.c` audio output buffer (`alHeapAlloc` on the music heap, `mempAlloc`ed). +- *Stack buffers through `s32`*: `image.c` texLoad's `compbuffer[4000]` reaches `texSetBitstring(s32)` and `rzipGetSomething()` (returns `s32`). Safe because game-thread stacks are forced low on purpose (`portAllocLowStack`, `MAP_32BIT` on Linux; the Windows exe has no `DYNAMIC_BASE`/`HIGH_ENTROPY_VA`, so its stacks are allocated low). **Hazard for macOS/ARM (no `MAP_32BIT`) and for any build that turns ASLR on** — belongs to the #95 `port_addr` / Stage B work. +- *Exe pointer truncated but never dereferenced on PC*: `fr.c` `cfb = cfb_16[0]` (exe bss) -> `sched.c` `osViSwapBuffer` (shim ignores it) and `CheckDisplayErrorBuffer` -> `crashRenderFrame` (stubbed in `n64stubs.c`). +- *Consistent truncation of both sides of a compare*: `blood_decrypt.c` `bloodImgTranspose` (`t1`, `var_t2`, `rowend` vs `(u32)var_v1`); breaks only if a buffer straddles a 4 GiB boundary. +- *Integers in mistyped pointer slots / prototypes* (no address involved): `bg.c` room-list `.next` flags, `stan.c` locus `rooms = 1`, `propobj.c` `save_img_index_to_obj_ani_slot(screen, m->time)`, `chraction.c` `set_actor_on_path(self, pathid)`, `audi.c` `osScAddClient(..., 1)`, `gunfire.c` fog args, `chrai.c` `ok = hatCreateForChr(...)` (truthiness). +- *Already full-width, warning only*: `lightfixture.c:218` (`gfx->dma.addr` is `uintptr_t`; the real hazard at the next line was fixed by #107). +- *N64-only or debug paths*: `init.c` boot decompression, `ramrom.c`/`ramromreplay.c`, `indy_*`, `othermodemicrocode.c`, `lv.c` `bgDebugRemoved7F0B9DE4`, `music.c`/`language.c`/`image.c` ROM offsets passed to `romCopy` (ROM addresses, not host pointers). +**Verified:** build clean; the `snprintf` warning is gone. No runtime path change outside the FATAL branch, so no frame diff. + +## D479 — `GE_STARTMP` harness: ammo counter missing (skipped file-select side effect) + +**Symptom:** in headless split-screen runs launched with `GE_STARTMP` the ammo counter never showed (seen 2026-10-01 with both players firing AK47s); the maintainer sees it in every menu-launched match. +**Probe** (`GE_AMMOPROBE`, TEMP, branch `probe/ammo-startmp`, never merge): in the harness match both players had `gunammooff = 0x1` (`GUNAMMOREASON_OPTION`) and `cur_player_get_ammo_onscreen_setting() == 0`. The stage load's `fileLoadSettingsForFolder(selected_folder_num)` (`options.c` -> `file.c` -> `file2.c`) ran with folder 0 and found a record with `options = 0x0000`; the solo `-level_26` shortcut, by contrast, found the real file 1 (`options = 0x013a`, ammo bit set) in a different `saves[]` slot. +**Cause:** porting-notes D10 class. A real MP launch passes the file-select screen, whose setup sets `selected_folder_num = -1` (`front.c`), so `fileGetSaveForFoldernum(-1)` returns NULL and no Bond file's options are applied in MP (the defaults stay: ammo on). The harness skipped that screen and kept the boot default `FOLDER1`. The record it then matched is very likely an all-zero `saves[]` entry (the MP harness also skips the legal screen's `fileValidateSaves()`, the only EEPROM -> `saves[]` load, see D299 and porting-notes D10); not separately verified. +**Fix (`src/game/lv.c`, inside the `#ifdef PORT` `GE_STARTMP` harness block only):** set `selected_folder_num = -1` before `init_mp_options_for_scenario`. No game-logic or menu-path change. +**Verified:** `GE_STARTMP=2 GE_MPVIRT=1 GE_STARTWEAPON=8`, pinned 1280x720 ini, frame 600: both halves draw "30 | 370" with the ammo icon; rc=0; ini and eep unchanged. +**Note:** other harness-only differences may remain because `saves[]` is unvalidated in `GE_STARTMP` runs (anything that reads save data during an MP match, e.g. unlock checks). Not observed so far. + +## D480 — Shader pre-warm (`$S/ge007.shaders`) + +**Symptom:** the ROADMAP §4 Statue/Cradle hitch row. The 2026-10-02 play capture (`GE_HITCHTL`, ~2 min; the maintainer felt no hitching, only the FPS counter dipping to 58/59 as a level starts) had one in-play stutter cluster, and it was shader compiles: frame 1076 spent 18.7 of its 19.2 ms display-list time compiling 7 GL programs, frame 1083 16.1 ms on 3. +**Cause:** `gfx_lookup_or_create_shader_program` (`port/fast3d/gfx_pc.cpp`) compiles a program the first time a combiner pair is drawn. The pool lives for the session (level changes don't clear it; only a texture-filter change does, via `reset_texture_state`), so the cost comes back every session. The GLSL from `gfx_opengl_create_and_load_new_shader` is a pure function of `(shader_id0, shader_id1)` and the GL version, so ahead-of-time compiling is exact. The draw path already passes the clamp-folded `id1` that `lookup_shader` keys on, so recording inside that function captures the right pairs. +**Fix (port layer only, `gfx_pc.cpp`):** each newly created pair is appended to `$S/ge007.shaders` (text: header `ge007-shaders v1`, then `%016llx %08x` per line; cap 1024; appended as created, so a crash loses nothing). At the top of `gfx_run` (render thread, GL context current; after the startup `videoApplyTexFilter` clear), a pending flag compiles every listed pair the pool misses, unloads it, and clears `rendering_state.shader_program` so the next draw rebinds as usual. `reset_texture_state` re-arms the flag. Logs `SHADERWARM: compiled N of M in X ms`. A missing, foreign or corrupt header rewrites the file; malformed lines are skipped; an unreadable/unwritable `$S` is skipped silently. `GE_NOSHADERWARM=1` disables reading and writing (falsifier). +**Not changed — the level-start frame:** the 59 ms first frame of a level (316 new GL textures, `gpu_ms` 58.99, CPU texture code 0.29 ms) is the D235 stage-change texture-cache clear (needed for correctness) re-uploading and mip-generating (`glGenerateMipmap` under three-point filtering) every visible texture. The previous screen is static, so it only lengthens the load by ~0.06 s. No output-identical cheap fix: spreading uploads draws missing textures, skipping mipmaps changes filtering, and the dry-run pre-warm (`perf/prewarm`) measured ~no gain. Left as is. +**Trade-offs:** the batch moves to frame 1 of a session: 22-28 pairs on Dam took 5.5-6.5 ms with the driver's disk cache warm, 56 ms once cold; the per-compile range in the capture is 2.5-11.5 ms, so the full-game list (unknown until it fills; capped at 1024) costs at most a few seconds once, at boot. After an F10 texture-filter change the pool is cleared and re-warmed in one stall on the next frame instead of a few compiles at a time as combiners reappear (expected; not a new hitch class). The driver's own disk cache already cuts repeat-session compiles to ~0.4 ms each (no-prewarm second run: 10 compiles, 3.6 ms total), so the gain is largest on the first session after a new exe or driver. +**Verified 2026-10-02** (pinned 1280x720, ini/eep backed up and restored, `ge007.shaders` deleted between runs): build clean. **Output:** held mission-select menu (`GE_STARTMENU=7`, frame 300): base vs base dmean 0.000, base vs pre-warmed 0.000. Dam frame 400 differs by camera position only, and base vs base varies just as much (0.56 and 9.5; D449 bimodal intro), with one pre-warmed run at 1.13 from a base run, so no rendering change. **Effect** (temporary merge with `probe/hitch-timeline`, Dam 1500 frames): fresh list = 8 in-play compiles in 6 frames (39 ms); warm = 0 in-play compiles (`SHADERWARM: compiled 27 of 27 in 6.2 ms`); `GE_NOSHADERWARM=1` = 10 in-play compiles. **Robustness:** corrupt header (rewritten), truncated/garbage lines (skipped), read-only file (pre-warms, appends fail silently), read-only + corrupt (silent, no warm): all rc=0, no crash log. **Smoke:** 60 s `-level_09` with `GE_MEMPREDZONE=1`: rc=0, 0 hits, no crash log. +**Owed (maintainer):** by eye, play a level you've already visited and watch the FPS counter in the first minute; one F10 texture-filter change (expect a single short stall). + +## D481 — Render worker: the scheduler thread no longer blocks on fast3d (#92 low-end frame rate) + +**Symptom:** #92: ~30 fps on a Celeron N3060 / Intel HD 400 where the Perfect Dark port holds 60. Reproduced on a Lenovo X220 (i7-2640M, Intel HD 3000, Mesa 23.0.3, Fedora 37): GE 44-49 fps on Dam/Statue/Cradle at EVERY setting (MSAA 1-8, anisotropy 1-16, draw distance 100-400, 640x480, vsync and FpsCap on/off), while PD built from the same toolchain held 59.4-60.0 fps on Defection/Investigation/Villa with as much or more work per frame (13-16 ms vs GE's 9-13 ms render thread; GE game thread < 0.5 ms/message; GPU 4-14 ms). +**Probe** (`probe/hitch-timeline`, `GE_HITCHTL`, X220, Dam 1200 frames): 312 frames were 33 ms; 97% failed `boss.c`'s tick gate (`mainTickElapsed < MAIN_LOOP_TICK_INTERVAL`, about half a frame since the previous frame START); `skip_pend` ~0. Not render cost, not pending-gfx. +**Cause (port architecture):** `osSpTaskStartGo` (`port/src/libultra.c`) ran the whole software RSP + GL present inline on the scheduler thread (`__scMain`). That thread also forwards each VI retrace to the game (`__scHandleRetrace`). A retrace arriving mid-render waited for the render to finish, so the game frame started late; the next retrace then came less than half a frame after that start and the tick gate skipped it. On the N64 the RSP/RDP are separate processors and the scheduler is never blocked; the PD port has no scheduler thread. With 1-3 ms renders (fast PCs) the delay stays under half a frame, which is why it was invisible on the dev box; at 8-12 ms (HD 3000) about one frame in four is lost, and slower machines fall to 30. D186's note in `gfx_sdl2.cpp` ("the pacing wait runs inline on the scheduler thread ... until pacing is moved off that thread") was the same mechanism seen from the FpsCap side. See porting-notes D20. +**Fix (port layer only; no game code):** gfx tasks go to a render worker thread (one-slot mailbox, mutex + condvar) that runs the unchanged frame body (`videoStartFrame`, `videoSyncSplitScreen`, `gfx_run`, `videoEndFrame`) and then posts `OS_EVENT_SP` + `OS_EVENT_DP` via `portPostEventForce`, exactly as the inline path did; `osSpTaskStartGo` returns at once. Audio tasks stay inline (no-op). The worker gets the same low stack as the game threads (`portAllocLowStack`). +- **Ordering:** the game submits frame N+1 only after frame N's done has round-tripped (worker -> interruptQ -> `__scTaskComplete` -> client DONE -> `boss.c`), so the slot is always empty at hand-off (a broken invariant is logged as an error; never seen). `__scExec` sets `curRSPTask` after `osSpTaskStartGo` returns and before the scheduler can read the done event, since it is the queue's only consumer. The VI framebuffer is a single constant in this port, so `__scTaskReady` is unaffected. Yield: `osSpTaskYielded` returns 0, so a yield-flagged gfx task completes normally when the worker posts SP done. +- **New overlap and its lock:** `optionsOverlayHandleInput` (scheduler thread, controller poll) and `optionsOverlayEmit` (render) both rebuild the overlay's visible-row state; they shared a thread before, now they share an `SDL_SpinLock`. The SDL event pump was already drained from two threads (host + render, D450), so a different render thread changes nothing there. +- **Quit (D344):** a running frame parks at its boundary as before. An idle worker that sees a quit request stops taking frames and never touches GL again. The host only waits while the renderer is inside a frame, so idle is already a safe exit point; adding a park + `glFinish` there would put a GL call where the host may be exiting. +- **Fallbacks:** `GE_DETERM` keeps the inline path (its retrace synthesis in `osRecvMesg` is call-sequenced on synchronous task execution); `GE_RENDERINLINE=1` restores the inline path as a falsifier. +**Verified 2026-10-02:** X220, 25 s runs, `GE_PERFSTAT`: Dam/Statue/Cradle at defaults 45.9/45.0/43.8 -> **60.0/60.0/60.0 fps**; at the maintainer's settings (MSAA 8, aniso 16, DD 400) also 60.0; 0 frames > 33 ms in all six runs. `GE_RENDERINLINE=1` reproduces 45.9 (Dam) and 43.8 (Cradle). Sim rate (`GE_D193`) 60-61 ticks per wall second. Windows (dev box): build clean; held mission-select menu frame, worker vs inline, dmean 0.000; Dam frame 400 differs by intro-camera timing only (same variance as base vs base); sim 60-61 ticks/s on both paths; `-level_09` with `GE_MEMPREDZONE=1` rc=0, 0 hits; 2P `GE_STARTMP` frame correct (both halves, HUD, ammo); `GE_DETERM` takes the inline path and runs; 10 launch/quit cycles at different frames and a quit during the briefing -> level load all exit cleanly, no crash log. +**Maintainer-verified 2026-10-02** (dev box, 120 Hz, ~9.5 min): play felt good with high performance, including rocket fights at turbo speed; F10 overlay with mouse and pad fine; real quit via the overlay's Quit to desktop parked and exited cleanly. Window close button not separately exercised. Not yet measured on N3060-class hardware; deciding CPU vs GPU margin there is the follow-up if that class still drops. + +## D482 — Lighter first-launch defaults on Atom/Celeron-class GPUs (#92 follow-up to D481) + +**Why:** D481 removed the scheduler stall; an Intel HD 3000 (Lenovo X220) now holds 60 at the port defaults. The #92 reporter's Celeron N3060 / Intel HD 400 is roughly half the X220's single-thread speed and GPU clock. Measured on the X220 against the Perfect Dark port built from the same toolchain (local PD build with a draw-batch counter, never committed): GE's fast3d costs no more per unit than PD's (GE ~31-44 us/batch and ~3.1 us/triangle at PD-like settings; PD ~40-68 us/batch, ~4.8 us/triangle). The gap is workload and defaults: PD ships the authored draw distance, no MSAA and a 640x480 window; our `DrawDistance`/`LodDistance` 250 send 2.5-3x the draw batches (Cradle 482 vs 146) and MSAA 2x adds ~25-30% GPU time. Anisotropy 4x measured no cost. Scaled to the N3060, Cradle's render CPU at our defaults (~8.2 ms on the X220) is ~17 ms, at the 16.7 ms budget; at the authored distance ~10 ms. +**Change (port layer):** `gfx_opengl.cpp` captures `GL_RENDERER` into a static buffer at init (`gfx_opengl_renderer_string()`; "" if the driver returns NULL; note `gfx_opengl_log_info()` only runs under `--debug-gl`, so the capture is separate). `video.c` `videoApplyLowEndDefaults()` runs in `videoInit` right after `gfx_init`, once per ini (`Video.LowEndConsidered`, written on every machine). On a low-end renderer it lowers `DrawDistance` 250 -> 100, `LodDistance` 250 -> 100 and `MSAA` 2 -> 1 (also `gfx_msaa_level`, which `videoInit` derived before `gfx_init`; the game framebuffer gets its storage per frame, so no restart), each only if still at the port default. Players raise them in F10; the D440 "Port defaults" preset restores 250/250. Not touched: window size (auto-fit stays; its GPU cost is similar to MSAA's and a small window is a visible UX change), anisotropy, FpsCap, texture filter. +**Classifier (`videoIsLowEndRenderer`, pure):** Mesa tags `(BYT)` `(BSW)` `(CHV)` `(APL)` `(GLK)`, older Mesa names Bay Trail / Braswell / Cherryview / Apollo Lake / Gemini Lake, software/virtual renderers (llvmpipe, softpipe, SVGA3D, Microsoft Basic Render, GDI Generic); otherwise the maximal digit run after `HD Graphics` (also inside `UHD Graphics`) must be one of 400, 405, 500, 505, 600, 605 (so 4000/5000/5500/6000 and 520/620 do not match). A numberless `Intel(R) HD Graphics` counts as low-end ON PURPOSE: Bay Trail and Celeron/Pentium parts report it, no Core-series part does, and a miss costs one reversible lightening. Do not tighten without measurements. `GE_FAKE_LOWEND=1/0` forces the decision (testing). +**Ordering (do not move):** this cannot sit next to `videoApplySteamDeckPreset` in `main.c`: the Deck preset runs before any GL context exists, and this needs `GL_RENDERER`. The two touch disjoint keys (Deck: window/fullscreen; this: DD/LOD/MSAA), so `GE_FAKE_DECK=1` + `GE_FAKE_LOWEND=1` compose. +**Verified 2026-10-02:** classifier compiled standalone against 21 real renderer strings, 0 mismatches (low-end: HD 400/405, Mesa HD 400 (BSW), numberless HD Graphics, UHD 600/605, Mesa HD 500 (APL 2), Mesa UHD 605 (GLK 3), Bay Trail, llvmpipe; not: HD 3000/4000/4600/5000/6000/520, UHD 620, Iris Xe, RTX 5090, Radeon, ""). Windows (RTX 5090): "not low-end", held menu frame identical to the D481 build (dmean 0.000), `-level_09` with `GE_MEMPREDZONE=1` rc=0, 0 hits. X220 (real string "Mesa Intel(R) HD Graphics 3000 (SNB GT2)"): fresh ini not low-end with the flag written; forced on: 100/100/1 written; second launch no re-apply; a pre-set DrawDistance=300 kept; flag already set: no change; forced on then user raises DD to 300: stays 300 on relaunch; forced off: not low-end, flag written. Evidence, forced path vs defaults (1224x918, 20 s, `GE_PERFSTAT`): Dam batches 105 -> 99, GPU 13.1 -> 9.6 ms; Statue batches 292 -> 171, render CPU 6.4 -> 5.1 ms, GPU 12.8 -> 8.0 ms; Cradle batches 482 -> 146, triangles 4562 -> 1650, render CPU 8.2 -> 5.2 ms, GPU 12.7 -> 10.6 ms; 60 fps in both (GPU-timer values are rough with vsync; relative only). Not verified: a real N3060. + +## D483 — #136: switching to the sniper rifle stood a crouched Bond up (PC crouch key) + +**Report (#136, outside):** "crouching with sniper rifle is not possible". +**Original code:** the sniper rifle's stats carry `WEAPONSTATBITFLAG_DISABLE_CROUCH` (`assets/obseg/gun/gunWeaponStats.inc.c`). `bondview2.c` (both control paths, ~5177-5209 and ~5448-5468) then turns aim-mode C-up/C-down (or stick Y) into zoom and leaves `crouchDown`/`crouchUp` false. So on the N64 you cannot change stance while holding the sniper; you keep the stance you had when you switched to it. The report is therefore partly faithful. +**Port divergence:** the PC crouch key (`port/src/input.c`, the free-crouch block) treated a disable-crouch weapon like "crouch not allowed" and called `inputDropCrouch()`, which stood a port-crouched Bond up as soon as he switched to the sniper. +**Fix (port layer):** while a disable-crouch weapon is out, the free-crouch block does nothing: no new crouch, no stand-up, and no injected C-down (which zooms out with this weapon). Switching back resumes the normal rules. `GE_INPUTLOG` logs `free crouch frozen (weapon N disables crouch, crouchpos=, key=)` once per entry. +**Verified 2026-10-02 (Dam, `GE_STARTWEAPON=17`, scripted CHOLD / weapon switches / CREL, `GE_INPUTLOG`):** crouch key held with the sniper out while standing: frozen, no crouch (`crouchpos=2`); switched to another weapon: crouch applied; switched back to the sniper: frozen while crouched (`crouchpos=0`, SQUAT); key released: no stand-up. Matches the N64 rules above. + +## D484 — #136: the port's FOV floor capped sniper/camera zoom at 20 degrees + +**Report (#136, outside):** "zoom rate is too low when using sniper rifle". +**Original code:** the sniper and camera zoom is a FOV in degrees, `sniper_zoom` 60 -> 7 (`gun.c` `camera_sniper_zoom_in/out`), fed to the projection through `g_ViBackData->fovy`. +**Port divergence:** `portScaleFovY` (`port/src/video.c`), applied to every in-level projection at `fr.c:735` since the widescreen-FOV work (`643785c2`), clamped the result to [20, 160] degrees even at default settings. The full sniper zoom therefore rendered at 20 degrees instead of 7: about a third of the N64's magnification. The same floor affected any game FOV below 20 (camera gadget, watch zoom). +**Fix (port layer):** the floor is now min(20, the game's own fovy): it still guards the port's widening (FovScale / widescreen boost) but never narrows the game's view less than the game asked for. The 160-degree ceiling is unchanged. +**Verified 2026-10-02:** scripted aim + C-up with the sniper on Dam: the full-zoom frame now matches a probe build with no floor (dmean 7.8, aim-timing variance) instead of the 20-degree frame (dmean 18.2); the gun model drops out of view at full zoom as on the N64; held mission-select menu frame pixel-identical (dmean 0.000), since normal FOVs never reach the floor. Mouse-aim sensitivity while zoomed now scales with the real zoom (input.c uses the same function). +**Related (fixed separately as D485):** the zoom *speed*. `camera_sniper_zoom_in/out` step once per game frame with no tick scaling; measured at `clk=1` (one tick per frame) on the port, so the full 60 -> 7 range takes ~22 frames = ~0.4 s at 60 fps against ~0.75-1.1 s on an N64 running 20-30 fps. Only the sniper and camera use this per-frame stepping; every other zoom (weapon aim zoom, watch zoom) advances by elapsed ticks (`zoomintime += speedgraphframes`, `bondview2.c` ~3151) and is already frame-rate independent. Same class as D13/D329. + +## D485 — #136: sniper/camera zoom speed follows game ticks (RULE-2) + +**RULE-2-SIGNOFF:** maintainer, 2026-10-02: "I approve the rule 2 change to match the N64 real time speed and be more accurate here." +**Divergence (class D13/D329):** `camera_sniper_zoom_in/out` (`src/game/gun.c`) multiply or divide the zoom FOV by `1 + rate*0.1` once per game frame, with no `g_ClockTimer` scaling. The N64 ran these frames at ~2 ticks each (30 fps; 3 at 20 fps); the port runs 1 tick per frame at 60 fps. Measured on the port before the fix: 15 -> 7 degrees in 8 frames, every call at `clk=1`; the full 60 -> 7 range ~22 frames (~0.4 s) against ~0.75 s on an N64 at 30 fps. Only the sniper and the camera gadget use this per-frame step; all other zooms advance by elapsed ticks (`zoomintime += speedgraphframes`, `bondview2.c`) and were already frame-rate independent. +**Fix (`#ifdef PORT`; the N64 build expands to the original expression):** the four call sites use `GUN_ZOOM_STEP(zoom)`. On PORT it is `sqrt(1 + rate*0.1)` multiplied once per tick in this frame, i.e. `base^(ticks/2)`: an N64-style frame of 2 ticks gets exactly the original factor, a 1-tick port frame gets its square root, and `g_ClockTimer == 0` (paused/locked) gives no step. Same "N64 frame = 2 ticks" convention as the D427 fire-gate sign-off. Behaviour at other port frame rates follows automatically (a 30 fps port frame has 2 ticks). +**Verified 2026-10-02 (Dam, `GE_STARTWEAPON=17`, scripted aim + C-up, temporary `SNIPERZOOM` log, removed before commit):** 15 -> 7 in 16 frames (947 -> 962) at `clk=1`, exactly twice the pre-fix 8 frames, i.e. the N64's real-time speed at 30 fps. Build clean; `-level_09` with `GE_MEMPREDZONE=1` rc=0, 0 hits, no crash log. +**Owed (maintainer):** feel check against 1964 GEPD (zoom level per D484 and speed per D485). + +## D486 — Explosions dropped in heavy firefights (#126; turrets on Cradle/Egypt/Aztec): the 6-slot explosion buffer fills with the player's own bullet-impact puffs + +**Report:** a remote mine in Control's mainframe room did nothing (#126, outside); the maintainer then reproduced missing or "bad" turret explosions on Cradle, Egypt and Aztec during heavy fire. One 1964 mine attempt did not reproduce. +**Mechanism (code + maintainer play log, temp `GE_D486` probe, since removed):** `explosionCreate` (`explosion.c` ~265) takes a free slot in `g_ExplosionBuffer[EXPLOSION_BUFFER_LEN = 6]` or silently does nothing (no visual, sound or damage). Nothing evicts a slot; `g_NumExplosionEntries` is only the screen-shake counter. Every player bullet that hits the background spawns a type-1 impact puff through the same call (`chrprop.c` ~1202, `chraiDefaultWeaponFireHandler`, player-only; NPC and autogun hits use the separate `explosionCreateBulletImpact` pool). A puff holds its slot exactly 46 ticks (duration 30 + 16 x flareanimspeed, tick-counted). Aztec log: 389 explosions created, 170 `NO FREE SLOT` (164 puffs, 3 x type 16, 3 x type 13, 1 turret type 8 at the moment slots 0-5 were all puffs aged 16-36, the player firing a puff every 4 ticks). No stuck slot, no `chrpropAllocate` failure, no missing stan (the first suspect, ruled out on Cradle). +**Faithfulness:** the buffer size, puff spawning, lifetime and no-eviction are all decomp code, so the N64 drops explosions the same way. One PC/N64 difference in *incidence*: the D427/D451 auto-fire gate matches the N64 at 2 ticks/frame (a shot per 4 ticks for rate-2 weapons = 11.5 puffs wanted vs 6 slots); when the N64 itself slowed to 3 ticks/frame in a firefight it fired every 6 ticks (7.7 puffs wanted), so it dropped fewer. Not a port bug by itself; the remaining question is a 1964 A/B. +**Related observations (same path):** +- (a) **Explosion parts spawn per frame** (`explosionTick`, `propagationrate*age/duration + 1` per call) into a 40-part pool while parts age per tick. Simulation for type 8 (dur 120): 77 parts and pool full by age 47 at 1 tick/frame, vs 58 / age 74 at 2 and 52 / never at 3. PC fireballs are ~1.3-1.5x denser and saturate early. D13 class; a fix is game logic (Rule-2). +- (b) **Stale parts on slot reuse:** parts are freed only in `explosionRenderPropExplosion`, and `explosionCreate` initialises only `parts[0]`, so an explosion that was offscreen for part of its life leaves up to 40 stale parts that the slot's next explosion inherits (seen: puffs starting with 22-40 parts). Same code on the N64; a plausible source of "bad looking" explosions. +- (c) **Autogun fire is per frame** (`propobj.c` ~6347 `autogun->unkAC++`, shot on even values): 2-3x the N64's shots, tracers (`unkAC & 3`), second-muzzle shots (`unkAC & 7`), sparks and impact sounds at 60 fps. Damage per second already matches (`unkD4 += 0.16 * g_GlobalTimerDelta` per shot) and autogun hits use no explosion slots. D13 class; a fix needs Rule-2. +- (d) Screen-shake decay (`g_NumExplosionEntries--` per call) runs per frame, so shake is 2-3x shorter in real time. D13 class, cosmetic. +- (e) `g_Textures[besttexture]` with `besttexture == -1` (`chrprop.c` ~1195, stan-hit case) reads before the array on both platforms; what it reads differs, so whether a puff spawns there is undefined. Low confidence it matters. +**1964 A/B (maintainer, 2026-10-02):** 1964/GEPD shows the exact same dropped explosions under heavy fire. The slot-buffer drop is **faithful** and stays; (b) stale parts is the same N64 code and stays. +**RULE-2-SIGNOFF (maintainer 2026-10-02, "Continue with your verified code fixes", replying to the request to tick-scale the turret fire rate, explosion-part spawning and shake decay):** scope = (a), (c), (d) only. +**Fix (`#ifdef PORT`, N64 branches byte-identical):** new `port/include/porttick.h` `portN64FrameStep()` (true on every call at >= 2 ticks/frame, every second tick below; stateless, from `g_GlobalTimer` crossing an even boundary). (c) `propobj.c` autogun fire block: `unkAC` (shot, tracer, second-muzzle cadence) advances only on a step; the per-shot damage charge uses a 2-tick frame's delta (`2.0f`) below 2 ticks/frame so damage per second is unchanged. (a) `explosion.c` `explosionTick`: no parts spawned on a non-step call (`sp9C = 0`); everything else in the block (room list, damage, gas-barrel rise) untouched. (d) `explosionScreenShake`: `g_NumSmokeEntries--` / `g_NumExplosionEntries--` only on a step; magnitude and sign logic untouched. +**Verified (headless, Cradle `-level_41`, turrets force-destroyed by a temp probe, since removed):** type-8 parts at age 40/60/100 = 17/27/40 at FpsCap 60 AND FpsCap 30 (before: pool full at age 47 at 60 fps; now 73 vs 74); shake 5 -> 0 over 9 vs 10 ticks. Autogun cadence not exercised headlessly (no turret tracks the player at spawn): by construction it is one `unkAC` step per 2 ticks = the N64's 2-ticks/frame rate. Clean build; Cradle smoke run exit 0. +**Status:** FIXED (a)(c)(d); drops + (b) faithful, closed. **Owed (maintainer):** a turret fight (Cradle/Aztec) at 60 fps: fire rate, tracer density and sound should feel like 1964, damage taken unchanged; explosion fireballs a little less dense; shake length like 1964. + +**D486 note 2026-10-02:** the maintainer confirmed the dropped explosions happen the same way in 1964/GEPD (faithful). The 60 fps turret-fight feel check of the fix is still owed. +**D433/D451 maintainer decision 2026-10-02:** auto-fire timing and the residual gunshot-sound difference accepted as good for now; no further work planned (reopen on a concrete report). + +## D488 — PAL build reported the Brazilian MPAL TV type instead of PAL (`osTvType`) + +`port/src/libultra.c` hard-codes `osTvType` (no hardware to read). Since the first scaffolding commit (`cd6cc158`, 2026-08-17) the PAL build set `OS_TV_MPAL` (2), with the comment "PAL consoles report MPAL" -- an inference from GE's shared code, which only ever tests for MPAL (`sched.c:287`, `init.c:237`, `fr.c` non-EU: MPAL LAN1 mode, else NTSC LAN1). Not copied from the PD reference, which hard-codes `OS_TV_NTSC` for every build and whose own game code tests `OS_TV_PAL` separately. A European N64 reports `OS_TV_PAL` (0); MPAL is Brazil's 60 Hz PAL-M console. So on real PAL hardware GE starts the scheduler in NTSC LAN1 and the EU `video_related_8` (`fr.c`, `#ifdef VERSION_EU`) then installs the PAL-table modes; the port took the Brazil-only MPAL branches instead. Never noticed because the PAL build was first compiled on 2026-10-02 (D258). +**Fix (port-only, maintainer go-ahead 2026-10-02):** `osTvType = OS_TV_PAL` for `REFRESH_PAL`, comment corrected; the port's 50 Hz tick now keys on `OS_TV_PAL` only (MPAL is 60 Hz; no build sets it). Not game logic (the value a console reports), so no Rule-2. +**Verified (headless):** PAL Dam frames 900/1200/1500 identical to the pre-change build (3/3); the boot sequence (legal, Nintendo, Rareware, gun barrel) identical to the post-D487 capture on every shared frame, timing unchanged; front-end mode select and mission select render, mode select identical to NTSC-U (the stamp running off the bottom is the shared 440x325 menu layout). US/JP unaffected (the change is under `REFRESH_PAL`). +**Owed:** a PAL 50 Hz feel check against 1964 when the maintainer plays PAL. +**Status:** FIXED. diff --git a/docs/porting-notes.md b/docs/porting-notes.md index ae159e2a..e3852ca6 100644 --- a/docs/porting-notes.md +++ b/docs/porting-notes.md @@ -1266,6 +1266,14 @@ non-flag ones (data loads, one-time validation, subsystem init) explicitly. Grepping the skipped `init_*`/`update_*` functions for calls with no matching state flag is the concrete check. +Second instance (D479): the `GE_STARTMP` split-screen harness skipped the +file-select screen, whose init sets `selected_folder_num = -1` for an MP +launch. The harness left the boot default `FOLDER1`, so every stage load ran +`fileLoadSettingsForFolder(0)` against an unvalidated (all-zero) `saves[]` +record: options 0, i.e. ammo counter, sight and auto-aim off in harness +matches only. A real menu launch never applies a Bond file in MP. Symptom +looked like a HUD bug; the tell was that it never reproduced from the menu. + ## D11. A chr's own per-tick animation-position logic can silently overwrite an AI script's scripted position in the same frame (D243) `chrTick` (`src/game/chr.c:2442`) always runs one of three `chr->actiontype`- @@ -1400,6 +1408,21 @@ A port stub that forces a value to `-1` (D154 `texnum`, D135) can hide latent la ## D19. A "click after the shot" report needs the trigger-hold duration, not just the state machine (D433/D467) State-machine audits of a gun's fire/dry-fire path (GE: `gunTickHandState`, CLICKY weapons) are tick-driven and match the console at any tick/frame ratio; an extra click/sound that appears "with the shot" is usually the trigger still being down when the recoil state ends (about 14 ticks for the Golden Gun). Measure with `GE_STARTWEAPON` + `GE_INPUTSCRIPT` holds of 4/9/16 frames and a `state/mag/88C/890/clk` log at the sound-play sites before suspecting the audio layer; and remember `GE_QUITFRAME` counts frames from boot, the level's `g_GlobalTimer` starts ~270 later. +## D20. Running an RCP task inline on the scheduler thread delays retrace delivery (D481) +The N64 scheduler (`src/sched.c` `__scMain`) both starts RSP/RDP tasks and forwards each VI retrace to the game. On hardware the task runs on separate processors, so the scheduler is never busy. If the port executes the task synchronously inside `osSpTaskStartGo`, any retrace that arrives during it reaches the game late, and `boss.c`'s half-frame tick gate then skips the following retrace (33 ms frames). Tell: frame rate stuck below 60 at every graphics setting, moderate render and GPU times, and the lost frames failing the tick check (`skip_tick`), not the pending-gfx check. It only shows when the task takes a large fraction of a frame (slow hardware), so a fast dev box never sees it. Run hardware-side work off the scheduler thread and signal completion with the same events the hardware would. + +## D21. `gDPLoadBlock` with dxt = 0 depends on the RDP's odd-row TMEM read swap; static assets need it emulated, the tex.c pipeline must not get it (D75) + +The RDP swaps the two 32-bit halves of every 8-byte group on odd TMEM rows when *reading*, and compensates on *load* only when LoadBlock's dxt counter advances. A `gsDPLoadBlock(..., dxt = 0)` of a multi-row image therefore samples as "memory with odd rows pair-swapped". Rare's compiled-in assets that load this way (the Rareware logo's RAREWARE text, `DL_RAREWARETEXT`) are pre-swapped in the data and look scrambled ("interleaved/combed", identical at every texture-filter setting) if fast3d uploads them linearly. `tex.c` uses dxt = 0 for the whole runtime texture pipeline too, but there `texSwapAltRowBytes` was the matching pre-swap and D159 no-ops it, so those images are already linear. fast3d (`import_texture`) therefore swaps only dxt = 0 loads whose source is a compiled-in C array (`gfx_tex_source_is_c_array`). Generalisable tells: a texture that looks identically garbled at filter 0/1/2, interlaced along ROWS with a 2-texel horizontal shift, drawn from `assets/*.c`; decode the C array offline both ways before suspecting filtering/clamp. Counting how often a new texture-path branch fires on a level boot (a temporary env-gated log) caught a ~300-per-level over-reach before it shipped. + +## D22. Per-frame counters: gate them with `portN64FrameStep()` (D486) + +Decomp code that advances a counter once per *call* (per rendered frame) instead of by `g_ClockTimer` runs 2-3x faster in real time at the port's 1 tick/frame (and every frame when uncapped, `clk == 0`). D486 found three on the explosion/turret path: autogun shot counter (`unkAC++`), explosion part spawning, explosion/smoke shake decay. `port/include/porttick.h` `portN64FrameStep()` is the shared Rule-2 gate: true on every call at >= 2 ticks/frame (N64-identical), every second tick below, so the counter keeps the N64's 2-ticks-per-frame pace (the D427/D451 reference). If the gated counter also scales a per-event quantity by `g_GlobalTimerDelta` (autogun damage per shot), charge the full 2-tick frame on gated calls or the rate halves. Verify by A/B at `Video.FpsCap` 60 vs 30: the two must match. Any such gate is game logic and needs Rule-2 sign-off. + +## D23. Region bring-up: tooling and port code silently assume NTSC-U (D258) + +PAL/JP had never been built. What broke was all port-side: (1) asset emitters hard-coded `scripts/filelist.u.csv` (so on a PAL/JP ROM they would use US offsets with no error); (2) `romdata.c` treated "not PAL" as NTSC-U (rejecting a JP ROM's country byte); (3) port code referenced globals that exist only under a region-specific define (`LEFTOVERDEBUG` is US/JP-only), which surfaces as a PAL-only link error; (4) the decomp's PAL/JP filelists were incomplete and mislabelled. With a real ROM, prove every filelist row by bytes (same-name US file comparison, constant-shift search, header-walk for variable files) instead of trusting labels. Whenever port code touches a symbol inside a `#if` region block, check all three `REGION_DEFS` sets. + ## E. Process / method notes - **Never `exit()` while another thread may be inside the GL driver (D344).** diff --git a/port/fast3d/gfx_opengl.cpp b/port/fast3d/gfx_opengl.cpp index 98316c4a..4b33b375 100644 --- a/port/fast3d/gfx_opengl.cpp +++ b/port/fast3d/gfx_opengl.cpp @@ -951,10 +951,19 @@ static bool gfx_opengl_supports_shaders(void) { return GLAD_GL_EXT_gpu_shader4; } +/* D482: GL_RENDERER as read at init, for video.c's low-end default check. + * A copy, never the driver's pointer; "" when the driver gave nothing. */ +static char gl_renderer_str[256] = ""; + +extern "C" const char *gfx_opengl_renderer_string(void) { + return gl_renderer_str; +} + static void gfx_opengl_log_info(void) { const char *version = (const char *)glGetString(GL_VERSION); const char *vendor = (const char *)glGetString(GL_VENDOR); const char *renderer = (const char *)glGetString(GL_RENDERER); + snprintf(gl_renderer_str, sizeof(gl_renderer_str), "%s", renderer ? renderer : ""); const char *glsl_version = (const char *)glGetString(GL_SHADING_LANGUAGE_VERSION); sysLogPrintf(LOG_NOTE, "GL: version: %s", version ? version : "unknown"); sysLogPrintf(LOG_NOTE, "GL: vendor: %s", vendor ? vendor : "unknown"); @@ -1033,6 +1042,11 @@ static void gfx_opengl_init(void) { gfx_opengl_init_extensions(); + { /* D482: always capture GL_RENDERER (log_info below is --debug-gl only). */ + const char *renderer = (const char *)glGetString(GL_RENDERER); + snprintf(gl_renderer_str, sizeof(gl_renderer_str), "%s", renderer ? renderer : ""); + } + if (sysArgCheck("--debug-gl")) { gfx_opengl_enable_debug(); // dump version info as early as possible diff --git a/port/fast3d/gfx_opengl.h b/port/fast3d/gfx_opengl.h index 21f9969e..37f57dba 100644 --- a/port/fast3d/gfx_opengl.h +++ b/port/fast3d/gfx_opengl.h @@ -8,6 +8,9 @@ extern struct GfxRenderingAPI gfx_opengl_api; #ifdef __cplusplus extern "C" { #endif +/* D482: GL_RENDERER captured at init ("" if unknown). */ +const char *gfx_opengl_renderer_string(void); + /* Frame capture (dev tool, env GE_PCDUMP=1) — see gfx_opengl.cpp. */ bool gfx_opengl_pcdump_enabled(void); bool gfx_opengl_dump_bound_fbo(uint32_t width, uint32_t height, const char* path); diff --git a/port/fast3d/gfx_pc.cpp b/port/fast3d/gfx_pc.cpp index 5af1b357..a46ff540 100644 --- a/port/fast3d/gfx_pc.cpp +++ b/port/fast3d/gfx_pc.cpp @@ -12,6 +12,7 @@ #include #include #include +#include #include #include #include @@ -27,6 +28,7 @@ #include "platform.h" #include "portaddr.h" /* Stage B: arena windows */ +#include "envflag.h" #include "gfx_pc.h" #include "gfx_cc.h" @@ -160,6 +162,13 @@ struct LoadedTexture { * a CI8 index stream apart from real RGBA16 pixels when a later tile * re-declares the same TMEM in another format -- see import_texture. */ uint8_t src_fmt = 0xFF; + /* D75: set by gfx_dp_load_block when the load used dxt == 0. The RDP's + * LoadBlock only swaps odd rows on the way INTO TMEM when its dxt counter + * advances; TMEM reads always swap odd rows (addr ^ 4). With dxt == 0 the + * load-side swap never happens, so the sampled image is the memory image + * with the two 32-bit halves of every 8-byte group swapped on odd rows. + * Rare relies on this for the Rareware logo's text mip textures. */ + bool dxt0 = false; }; static struct RDP { @@ -332,12 +341,95 @@ static void gfx_flush(void) { } } +/* D480: shader pre-warm. A combiner seen for the first time compiles its GL + * program mid-frame (2.5-11.5 ms each on the dev box; up to ~19 ms frames in + * play). The generated GLSL is a pure function of (shader_id0, shader_id1) and + * the GL version, so every pair ever created is remembered in $S/ge007.shaders + * and compiled at the top of the first gfx_run (and again after a filter change + * clears the pool). Output-identical; GE_NOSHADERWARM=1 turns it off. */ +#define SHADERWARM_HEADER "ge007-shaders v1" +#define SHADERWARM_MAX 1024 +static bool s_shader_warm_pending = true; +static int s_shader_list_state = 0; /* 0 = not opened, 1 = writable, -1 = disabled */ +static std::string s_shader_list_path; +static std::set> s_shader_list_known; + +static bool gfx_shader_list_open(void) { + if (s_shader_list_state == 0) { + s_shader_list_state = -1; + if (GE_ENVFLAG("GE_NOSHADERWARM")) { + return false; + } + s_shader_list_path = sysResolvePath("$S/ge007.shaders"); + bool header_ok = false; + if (FILE* f = fopen(s_shader_list_path.c_str(), "r")) { + char line[64]; + if (fgets(line, sizeof line, f) && !strncmp(line, SHADERWARM_HEADER, strlen(SHADERWARM_HEADER))) { + header_ok = true; + unsigned long long id0; + unsigned int id1; + while (s_shader_list_known.size() < SHADERWARM_MAX && fgets(line, sizeof line, f)) { + if (sscanf(line, "%llx %x", &id0, &id1) == 2) { + s_shader_list_known.insert(std::make_pair((uint64_t)id0, (uint32_t)id1)); + } + } + } + fclose(f); + } + if (!header_ok) { + /* missing, foreign or corrupt: start a fresh list */ + FILE* f = fopen(s_shader_list_path.c_str(), "w"); + if (f == NULL) { + return false; + } + fprintf(f, "%s\n", SHADERWARM_HEADER); + fclose(f); + } + s_shader_list_state = 1; + } + return s_shader_list_state == 1; +} + +static void gfx_shader_list_record(uint64_t shader_id0, uint32_t shader_id1) { + if (!gfx_shader_list_open() || s_shader_list_known.size() >= SHADERWARM_MAX) { + return; + } + if (!s_shader_list_known.insert(std::make_pair(shader_id0, shader_id1)).second) { + return; + } + if (FILE* f = fopen(s_shader_list_path.c_str(), "a")) { + fprintf(f, "%016llx %08x\n", (unsigned long long)shader_id0, (unsigned int)shader_id1); + fclose(f); + } +} + +static void gfx_shader_prewarm(void) { + s_shader_warm_pending = false; + if (!gfx_shader_list_open() || s_shader_list_known.empty()) { + return; + } + const auto t0 = std::chrono::steady_clock::now(); + int compiled = 0; + gfx_rapi->unload_shader(rendering_state.shader_program); + rendering_state.shader_program = nullptr; + for (const auto& id : s_shader_list_known) { + if (gfx_rapi->lookup_shader(id.first, id.second) == NULL) { + struct ShaderProgram* prg = gfx_rapi->create_and_load_new_shader(id.first, id.second); + gfx_rapi->unload_shader(prg); + compiled++; + } + } + const double ms = std::chrono::duration(std::chrono::steady_clock::now() - t0).count(); + sysLogPrintf(LOG_NOTE, "SHADERWARM: compiled %d of %d in %.1f ms", compiled, (int)s_shader_list_known.size(), ms); +} + static struct ShaderProgram* gfx_lookup_or_create_shader_program(uint64_t shader_id0, uint32_t shader_id1) { struct ShaderProgram* prg = gfx_rapi->lookup_shader(shader_id0, shader_id1); if (prg == NULL) { gfx_rapi->unload_shader(rendering_state.shader_program); prg = gfx_rapi->create_and_load_new_shader(shader_id0, shader_id1); rendering_state.shader_program = prg; + gfx_shader_list_record(shader_id0, shader_id1); } return prg; } @@ -1143,6 +1235,16 @@ static void import_texture(int i, int tile, bool importReplacement) { } else { key = { orig_addr, {}, fmt, siz, palette_index, loaded_texture.size_bytes, 0u }; } + /* D75: a dxt==0 load samples with swapped odd rows -> distinct image. + * Only compiled-in (exe-image) assets: the runtime texture pipeline + * (tex.c/image.c, 0x70xxxxxx) loads dxt==0 too, but D159 no-ops its + * compensating pre-swap, so those are already linear. */ + const bool d75_swap = loaded_texture.dxt0 && siz != G_IM_SIZ_32b && + gfx_tex_source_is_c_array(orig_addr) && + rdp.texture_tile[tile].line_size_bytes != 0 && + (rdp.texture_tile[tile].line_size_bytes & 7) == 0 && + loaded_texture.size_bytes > rdp.texture_tile[tile].line_size_bytes; + if (d75_swap) key.palette_hash ^= 0xD75D75D7u; /* Intro blood (M-201): textures the game regenerates IN PLACE in the * per-frame dynamic pool (dynAllocate, [g_VtxBuffers[0], g_VtxBuffers[2])) @@ -1212,6 +1314,26 @@ static void import_texture(int i, int tile, bool importReplacement) { } } + /* D75: emulate the RDP's odd-row TMEM read swap for dxt==0 loads (see + * LoadedTexture::dxt0). Done after destride so rows are contiguous. */ + std::vector d75_buf; + if (d75_swap) { + const uint32_t ln = rdp.texture_tile[tile].line_size_bytes; + const uint32_t rows = loaded_texture.size_bytes / ln; + d75_buf.assign(loaded_texture.addr, loaded_texture.addr + (size_t)rows * ln + + (loaded_texture.size_bytes - rows * ln)); + for (uint32_t r = 1; r < rows; r += 2) { + uint8_t* row = &d75_buf[(size_t)r * ln]; + for (uint32_t b = 0; b + 8 <= ln; b += 8) { + uint8_t t4[4]; + memcpy(t4, row + b, 4); + memcpy(row + b, row + b + 4, 4); + memcpy(row + b + 4, t4, 4); + } + } + loaded_texture.addr = d75_buf.data(); + } + /* GE_DTEX: dump the load parameters for the first N textures of a frame so * RC2 (mip-chain contamination -> over-tall upload) can be told apart from a * decode/row-swap bug. tile_h = base-tile height from SETTILESIZE; if the @@ -3195,6 +3317,7 @@ static void gfx_dp_load_block(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t loaded_texture.raw_tex_metadata = rdp.texture_to_load.raw_tex_metadata; loaded_texture.addr = rdp.texture_to_load.addr; loaded_texture.src_fmt = rdp.texture_to_load.fmt; /* D229 */ + loaded_texture.dxt0 = (dxt == 0); /* D75 */ rdp.textures_changed[0] = rdp.textures_changed[1] = true; } @@ -3236,6 +3359,7 @@ static void gfx_dp_load_tile(uint8_t tile, uint32_t uls, uint32_t ult, uint32_t loaded_texture.raw_tex_metadata = rdp.texture_to_load.raw_tex_metadata; loaded_texture.addr = rdp.texture_to_load.addr + start_offset_bytes; loaded_texture.src_fmt = rdp.texture_to_load.fmt; /* D229 */ + loaded_texture.dxt0 = false; /* D75 */ rdp.texture_tile[tile].uls = uls; rdp.texture_tile[tile].ult = ult; @@ -4235,6 +4359,10 @@ extern "C" void gfx_run(Gfx* commands) { } dropped_frame = false; + if (s_shader_warm_pending) { + gfx_shader_prewarm(); /* D480 */ + } + gfx_rapi->update_framebuffer_parameters(0, gfx_current_window_dimensions.width, gfx_current_window_dimensions.height, 1, false, true, true, !game_renders_to_framebuffer); @@ -4344,6 +4472,7 @@ extern "C" void reset_texture_state() { rendering_state.shader_program = nullptr; } gfx_rapi->clear_shaders(); + s_shader_warm_pending = true; /* D480: re-warm on the next frame */ color_combiner_pool.clear(); prev_combiner = color_combiner_pool.end(); } diff --git a/port/include/porttick.h b/port/include/porttick.h new file mode 100644 index 00000000..a86891d6 --- /dev/null +++ b/port/include/porttick.h @@ -0,0 +1,22 @@ +#ifndef PORT_PORTTICK_H +#define PORT_PORTTICK_H + +#include + +/* D486 (RULE-2, D13 class): some decomp code advances a counter once per + * rendered frame. The N64 rendered at 2 ticks per frame (more under load); + * the port renders 1 tick per frame at 60 fps (0 when uncapped), so those + * counters ran 2-3x faster in real time. portN64FrameStep() is true on every + * call at >= 2 ticks per frame (identical to the N64 path) and on every + * second tick below that, so a per-frame counter gated by it keeps the N64's + * 2-ticks-per-frame pace -- the same reference D427/D451 use for auto-fire. + * Stateless: it only looks at the tick counter crossing an even boundary. */ +extern s32 g_ClockTimer; +extern s32 g_GlobalTimer; + +static inline int portN64FrameStep(void) +{ + return g_ClockTimer >= 2 || ((g_GlobalTimer >> 1) != ((g_GlobalTimer - g_ClockTimer) >> 1)); +} + +#endif diff --git a/port/src/input.c b/port/src/input.c index 3cde3243..04be7597 100644 --- a/port/src/input.c +++ b/port/src/input.c @@ -2785,11 +2785,26 @@ static unsigned inputComputePadSlot(int idx, signed char *stick_x, signed char * !p->pause_state && !p->mpmenuon && !g_PlayerIsInTank && !lvlGetControlsLockedFlag() && !gameScriptedCameraActive(); + int weaponBlocks = 0; if (canCrouch && (crouchNow || s_crouchApplied)) { /* weapon lookup only when it can matter */ - canCrouch = !bondwalkItemCheckBitflags(p->hands[GUNRIGHT].weaponnum, - WEAPONSTATBITFLAG_DISABLE_CROUCH); + weaponBlocks = bondwalkItemCheckBitflags(p->hands[GUNRIGHT].weaponnum, + WEAPONSTATBITFLAG_DISABLE_CROUCH); + canCrouch = !weaponBlocks; } - if (canCrouch && crouchNow) { + static int frozenLogged = 0; + if (!weaponBlocks) frozenLogged = 0; + if (weaponBlocks) { + /* D483 (#136): a weapon with DISABLE_CROUCH (the sniper rifle) + * blocks the native crouch-down AND crouch-up (bondview2.c), so + * on the N64 Bond keeps whatever stance he had when he switched + * to it. Freeze the port stance the same way: don't apply a new + * crouch, don't stand up, and never feed C-down (it zooms out + * with this weapon). Switching back resumes the normal rules. */ + if (!frozenLogged && configGetInputLog()) + sysLogPrintf(LOG_NOTE, "GE_INPUTLOG free crouch frozen (weapon %d disables crouch, crouchpos=%d, key=%d)", + (int)p->hands[GUNRIGHT].weaponnum, (int)p->crouchpos, crouchNow); + frozenLogged = 1; + } else if (canCrouch && crouchNow) { /* In aim mode the native crouchUp branch runs every tick without * C-down, undoing the port stance by one step. Feed the native * axis ONLY while aiming; hipfire still crouches by stance alone. */ diff --git a/port/src/libultra.c b/port/src/libultra.c index 4b0075cd..d335f72a 100644 --- a/port/src/libultra.c +++ b/port/src/libultra.c @@ -68,11 +68,15 @@ extern void videoSyncSplitScreen(void); /* D416 */ u64 osClockRate = 6250000; /* RSP counter rate (Hz) — see PD port */ u32 osMemSize = 16 * 1024 * 1024; /* pretend 16MB RDRAM (+expansion) */ /* TV type (normally set from console hardware in os/initialize.c, excluded). - * The game reads it to pick PAL/NTSC behaviour (e.g. schedulerInitThread - * checks osTvType == OS_TV_MPAL). Set to match the emulated region: PAL - * consoles report MPAL, NTSC consoles report NTSC. */ + * Set to what the matching console reports: a European (PAL) N64 reports + * OS_TV_PAL (0); OS_TV_MPAL (2) is Brazil's 60 Hz PAL-M console. GE's shared + * code only tests for MPAL (sched.c / init.c / fr.c: MPAL LAN1 mode, else + * NTSC LAN1), so on a real PAL console those take the NTSC branch and the + * EU build's own video_related_8 (fr.c, #ifdef VERSION_EU) then installs + * the PAL modes. D488: this used to be MPAL (a scaffolding-era inference + * from those checks), which sent the port down the Brazil-only branches. */ #ifdef REFRESH_PAL -u32 osTvType = OS_TV_MPAL; /* EU: PAL (0=PAL 1=NTSC 2=MPAL) */ +u32 osTvType = OS_TV_PAL; /* EU: PAL (0=PAL 1=NTSC 2=MPAL) */ #else u32 osTvType = OS_TV_NTSC; /* US/JP: NTSC */ #endif @@ -329,7 +333,7 @@ void portKernelInit(void) g_lastFrameUs = sysGetMicroseconds(); g_lastHeartbeatUs = g_lastFrameUs; - if (osTvType == OS_TV_MPAL || osTvType == OS_TV_PAL) { + if (osTvType == OS_TV_PAL) { /* D488: MPAL (PAL-M) is a 60 Hz system */ g_tickIntervalUs = 1000000 / 50; /* PAL: 50 frames/s -> 20ms */ g_determQuantum = 931050; } else { @@ -820,7 +824,29 @@ void osViSetMode(OSViMode *vm) * every frame into a half-height band. */ u32 w = vm->comRegs.width; s32 h = (s32)(((vm->fldRegs[0].yScale & 0xFFF) * 480u) / 0x800u); +#ifdef VERSION_EU + /* D487: the EU build's video_related_8 (src/fr.c, #ifdef VERSION_EU) + * encodes yScale = bufy * 0x800 / (0x220 + (bufy == 330 ? 28 : 0)), + * i.e. against 544 (572) lines, not 480. Inverting with 480 gave a CFB + * ~12% too short (269 -> 237), so fast3d cropped the bottom of every + * PAL frame (HUD ammo counter reduced to a dot). Recover bufy exactly: + * the smallest height whose EU encoding reproduces this yScale. Keyed on + * the build, not the OS_VI_BIT_PAL ctrl bit: the modes reaching here + * (the scheduler's LAN1 start mode and the EU video_related_8 modes) do + * not reliably carry that bit (observed: yScale 0x400 = 272 without it). */ + { + u32 ys = vm->fldRegs[0].yScale & 0xFFF; + s32 cand; + for (cand = 1; cand <= 576; cand++) { + u32 den = 0x220u + (cand == 330 ? 28u : 0u); + if (((u32)cand * 0x800u) / den == ys) { h = cand; break; } + } + if (cand > 576) h = 0; + } + if (h <= 0 || h > 576) h = 272; /* fallback: the EU CFB height (fr.h SCREEN_HEIGHT_272) */ +#else if (h <= 0 || h > 480) h = pal ? 272 : 240; /* fallback: LAN1 CFB height */ +#endif if (w > 640) w = 640; videoUpdateNativeResolution((s32)w, h); } @@ -982,7 +1008,8 @@ static void piServiceDma(s32 direction, u32 srcPA, void *dstVA, u32 size) char win[1200] = ""; char *wp = win; for (int i = 0; i < 32; i++) { - wp += snprintf(wp, win + sizeof(win) - (wp - win), + /* D478: the bound is the bytes left, not a pointer. */ + wp += snprintf(wp, sizeof(win) - (size_t)(wp - win), " %p", (void *)sp[i]); } #if defined(PLATFORM_WINDOWS) @@ -1312,6 +1339,109 @@ s32 osMotorStop(OSPfs *pfs) void osSpTaskLoad(OSTask *t) { (void)t; /* nothing to load on the host */ } +static void portRenderGfxTask(Gfx *dl) +{ + uint64_t t0 = sysGetMicroseconds(); + videoStartFrame(); + videoSyncSplitScreen(); + gfx_run(dl); + videoEndFrame(); + g_lastFrameUs = sysGetMicroseconds(); + if (++g_framesRendered <= 5 || (g_framesRendered % 300) == 0) + sysLogPrintf(LOG_NOTE, "frame %d rendered in %llu us", + g_framesRendered, + (unsigned long long)(sysGetMicroseconds() - t0)); +} + +/* D481: render worker. The N64 RSP/RDP run beside the CPU; the scheduler + * starts a task and learns it finished from the SP/DP interrupts. The port + * used to run fast3d inline here, on the scheduler thread, so a VI retrace + * arriving mid-render was forwarded to the game only after the render: the + * game frame started late, the next retrace came < half a frame after it, and + * boss.c's tick gate skipped it (a 33 ms frame). Invisible with 1-3 ms + * renders, ~1 frame in 4 on an Intel HD 3000 (8-12 ms renders). Gfx tasks now + * go to this worker; it posts SP/DP done exactly as the inline path did. + * One-slot mailbox: the game submits frame N+1 only after frame N's done event + * has round-tripped (worker -> interruptQ -> __scTaskComplete -> client DONE + * -> boss.c), so the slot is always empty at hand-off. GE_DETERM keeps the + * inline path (its retrace synthesis is call-sequenced, see osRecvMesg), and + * GE_RENDERINLINE=1 restores it as a falsifier. */ +static pthread_mutex_t s_rwLock = PTHREAD_MUTEX_INITIALIZER; +static pthread_cond_t s_rwCond = PTHREAD_COND_INITIALIZER; +static Gfx *s_rwTask = NULL; /* submitted display list; NULL = worker idle */ +static int s_rwMode = 0; /* 0 = undecided, 1 = worker, -1 = inline */ + +static void *portRenderWorker(void *arg) +{ + (void)arg; + for (;;) { + pthread_mutex_lock(&s_rwLock); + while (s_rwTask == NULL) { + /* Quit while idle: stop taking frames and never touch GL again. + * The host only waits for the renderer while it is inside a frame + * (video.c videoHostExitIfRequested), so an idle worker is already + * a safe exit point; a frame that is running parks itself at its + * boundary as before (D344). */ + if (videoQuitRequested()) { + pthread_mutex_unlock(&s_rwLock); + for (;;) sysSleep(100000); + } + struct timespec ts; + clock_gettime(CLOCK_REALTIME, &ts); + ts.tv_nsec += 100 * 1000 * 1000; + if (ts.tv_nsec >= 1000000000L) { ts.tv_sec++; ts.tv_nsec -= 1000000000L; } + pthread_cond_timedwait(&s_rwCond, &s_rwLock, &ts); + } + Gfx *dl = s_rwTask; + pthread_mutex_unlock(&s_rwLock); + + portRenderGfxTask(dl); + + pthread_mutex_lock(&s_rwLock); + s_rwTask = NULL; + pthread_cond_broadcast(&s_rwCond); + pthread_mutex_unlock(&s_rwLock); + portPostEventForce(OS_EVENT_SP); /* D134: must not be dropped */ + portPostEventForce(OS_EVENT_DP); /* gfx task is its own DP task */ + } + return NULL; +} + +static int portRenderWorkerOn(void) +{ + if (s_rwMode == 0) { + s_rwMode = -1; + if (g_determEnabled) { + sysLogPrintf(LOG_NOTE, "D481: GE_DETERM -> gfx tasks run inline"); + } else if (getenv("GE_RENDERINLINE") != NULL) { + sysLogPrintf(LOG_NOTE, "D481: GE_RENDERINLINE -> gfx tasks run inline"); + } else { + pthread_attr_t attr; + pthread_t th; + pthread_attr_init(&attr); +#if !defined(_WIN32) + /* Same low stack as the game threads (see portAllocLowStack). */ + void *lowStack = portAllocLowStack(PORT_THREAD_STACK); + if (lowStack) + pthread_attr_setstack(&attr, lowStack, PORT_THREAD_STACK); + else + pthread_attr_setstacksize(&attr, PORT_THREAD_STACK); +#else + pthread_attr_setstacksize(&attr, PORT_THREAD_STACK); +#endif + if (pthread_create(&th, &attr, portRenderWorker, NULL) == 0) { + pthread_detach(th); + s_rwMode = 1; + sysLogPrintf(LOG_NOTE, "D481: render worker started"); + } else { + sysLogPrintf(LOG_ERROR, "D481: render worker failed to start; gfx tasks run inline"); + } + pthread_attr_destroy(&attr); + } + } + return s_rwMode == 1; +} + void osSpTaskStartGo(OSTask *t) { if (g_determTraceEnabled && !g_determTaskEverRun) { @@ -1324,18 +1454,23 @@ void osSpTaskStartGo(OSTask *t) /* Phase 3: execute the audio ucode against t->t.data_ptr (an Acmd * list). For now the task simply completes; libaudio's amMain still * runs its per-frame bookkeeping. */ + } else if (portRenderWorkerOn()) { + /* D481: hand the display list to the render worker; it posts the + * SP/DP done events when the frame is presented. */ + pthread_mutex_lock(&s_rwLock); + if (s_rwTask != NULL) { + sysLogPrintf(LOG_ERROR, "D481: gfx task submitted while the previous one is still rendering (invariant broken); waiting"); + while (s_rwTask != NULL) { + pthread_cond_wait(&s_rwCond, &s_rwLock); + } + } + s_rwTask = (Gfx *)t->t.data_ptr; + pthread_cond_broadcast(&s_rwCond); + pthread_mutex_unlock(&s_rwLock); + return; } else { - /* Graphics task: run the software RSP on the display list. */ - uint64_t t0 = sysGetMicroseconds(); - videoStartFrame(); - videoSyncSplitScreen(); - gfx_run((Gfx *)t->t.data_ptr); - videoEndFrame(); - g_lastFrameUs = sysGetMicroseconds(); - if (++g_framesRendered <= 5 || (g_framesRendered % 300) == 0) - sysLogPrintf(LOG_NOTE, "frame %d rendered in %llu us", - g_framesRendered, - (unsigned long long)(sysGetMicroseconds() - t0)); + /* Graphics task: run the software RSP on the display list inline. */ + portRenderGfxTask((Gfx *)t->t.data_ptr); } portPostEventForce(OS_EVENT_SP); /* D134: must not be dropped */ diff --git a/port/src/main.c b/port/src/main.c index 6f853997..663f44a1 100644 --- a/port/src/main.c +++ b/port/src/main.c @@ -151,6 +151,7 @@ int main(int argc, char **argv) * cheat-unlock bit in the save block at read time (per-slot CRC * recomputed via the game's own fileGenerateCRC), so the cheat * menu is fully populated without completed levels. */ +#if defined(LEFTOVERDEBUG) /* the debug unlock flags only exist with LEFTOVERDEBUG (not PAL); D442's query-time hooks cover All unlocked everywhere */ { extern s32 portAllUnlocked; /* port/src/video.c */ extern s32 debug_enable_all_levels_flag; /* src/game/debugmenu_handler.c */ @@ -162,6 +163,7 @@ int main(int argc, char **argv) "(Game.AllUnlocked=1)"); } } +#endif /* 2. Load the ROM and map segments. */ if (romdataInit() != 0) { diff --git a/port/src/optionsoverlay.c b/port/src/optionsoverlay.c index c58cad9d..2aec54e5 100644 --- a/port/src/optionsoverlay.c +++ b/port/src/optionsoverlay.c @@ -1809,7 +1809,20 @@ static int s_d314Enabled = -1; /* -1 = not yet resolved */ * changes it; its name only selects it. Reset actions use the whole row. */ static int overlayControlSpan(int i, s32 *x0, s32 *x1); +/* D481: HandleInput runs on the scheduler thread (controller poll) and Emit on + * the render worker; both rebuild s_visIdx/s_visN/s_scroll/s_sel. They used to + * share one thread, so serialise them now that rendering has its own. */ +static SDL_SpinLock s_ovLock; + +static void overlayHandleInputLocked(void); void optionsOverlayHandleInput(void) +{ + SDL_AtomicLock(&s_ovLock); + overlayHandleInputLocked(); + SDL_AtomicUnlock(&s_ovLock); +} + +static void overlayHandleInputLocked(void) { static int prevUp, prevDn, prevLf, prevRt, prevLmb, prevRmb, prevPadBack; /* D347: hold-to-repeat state (18/4-frame cadence, same as the options @@ -2416,7 +2429,16 @@ static Gfx *drawBodyFit(Gfx *gdl, s32 x, s32 y, s32 maxW, const char *str, u32 c return drawBody(gdl, x, y, out, colour); } +static Gfx *overlayEmitLocked(void); Gfx *optionsOverlayEmit(void) +{ + SDL_AtomicLock(&s_ovLock); /* D481: see optionsOverlayHandleInput */ + Gfx *dl = overlayEmitLocked(); + SDL_AtomicUnlock(&s_ovLock); + return dl; +} + +static Gfx *overlayEmitLocked(void) { if (!s_inited) { overlayInit(); diff --git a/port/src/romassets_e.s b/port/src/romassets_e.s new file mode 100644 index 00000000..ffed8093 --- /dev/null +++ b/port/src/romassets_e.s @@ -0,0 +1,3569 @@ +/* + * AUTO-GENERATED by scripts/gen_romassets.py (E) -- do not edit. + * + * Absolute ROM asset symbols for the PC port. Each symbol is the N64 + * cart address (0x10000000 + rom_offset) of the corresponding asset in + * scripts/filelist.e.csv, so `&symbol` / romCopy() work exactly as + * on hardware once romdata.c has mapped the .z64 at 0x10000000. + * Regenerate: python3 scripts/gen_romassets.py e + */ +.section .data + +/* --- assets/obseg (file_resource_table.inc.c order) ------------- */ +.global bg_sev_all_p_seg +.set bg_sev_all_p_seg, 0x1042EAA0 +.global end_bg_sev_all_p_seg +.set end_bg_sev_all_p_seg, 0x1043F890 +.global bg_silo_all_p_seg +.set bg_silo_all_p_seg, 0x1043F890 +.global end_bg_silo_all_p_seg +.set end_bg_silo_all_p_seg, 0x104907D0 +.global bg_stat_all_p_seg +.set bg_stat_all_p_seg, 0x104907D0 +.global end_bg_stat_all_p_seg +.set end_bg_stat_all_p_seg, 0x104B28A0 +.global bg_arec_all_p_seg +.set bg_arec_all_p_seg, 0x104B28A0 +.global end_bg_arec_all_p_seg +.set end_bg_arec_all_p_seg, 0x104E0C20 +.global bg_arch_all_p_seg +.set bg_arch_all_p_seg, 0x104E0C20 +.global end_bg_arch_all_p_seg +.set end_bg_arch_all_p_seg, 0x10506710 +.global bg_tra_all_p_seg +.set bg_tra_all_p_seg, 0x10506710 +.global end_bg_tra_all_p_seg +.set end_bg_tra_all_p_seg, 0x10526C80 +.global bg_dest_all_p_seg +.set bg_dest_all_p_seg, 0x10526C80 +.global end_bg_dest_all_p_seg +.set end_bg_dest_all_p_seg, 0x10554640 +.global bg_sevb_all_p_seg +.set bg_sevb_all_p_seg, 0x10554640 +.global end_bg_sevb_all_p_seg +.set end_bg_sevb_all_p_seg, 0x1056F3E0 +.global bg_azt_all_p_seg +.set bg_azt_all_p_seg, 0x1056F3E0 +.global end_bg_azt_all_p_seg +.set end_bg_azt_all_p_seg, 0x10590E30 +.global bg_pete_all_p_seg +.set bg_pete_all_p_seg, 0x10590E30 +.global end_bg_pete_all_p_seg +.set end_bg_pete_all_p_seg, 0x105AAA60 +.global bg_depo_all_p_seg +.set bg_depo_all_p_seg, 0x105AAA60 +.global end_bg_depo_all_p_seg +.set end_bg_depo_all_p_seg, 0x105D73D0 +.global bg_ref_all_p_seg +.set bg_ref_all_p_seg, 0x105D73D0 +.global end_bg_ref_all_p_seg +.set end_bg_ref_all_p_seg, 0x105E09E0 +.global bg_cryp_all_p_seg +.set bg_cryp_all_p_seg, 0x105E09E0 +.global end_bg_cryp_all_p_seg +.set end_bg_cryp_all_p_seg, 0x105F6090 +.global bg_dam_all_p_seg +.set bg_dam_all_p_seg, 0x105F6090 +.global end_bg_dam_all_p_seg +.set end_bg_dam_all_p_seg, 0x10626230 +.global bg_ark_all_p_seg +.set bg_ark_all_p_seg, 0x10626230 +.global end_bg_ark_all_p_seg +.set end_bg_ark_all_p_seg, 0x106571B0 +.global bg_run_all_p_seg +.set bg_run_all_p_seg, 0x106571B0 +.global end_bg_run_all_p_seg +.set end_bg_run_all_p_seg, 0x10661580 +.global bg_sevx_all_p_seg +.set bg_sevx_all_p_seg, 0x10661580 +.global end_bg_sevx_all_p_seg +.set end_bg_sevx_all_p_seg, 0x1067DB50 +.global bg_jun_all_p_seg +.set bg_jun_all_p_seg, 0x1067DB50 +.global end_bg_jun_all_p_seg +.set end_bg_jun_all_p_seg, 0x10692C40 +.global bg_dish_all_p_seg +.set bg_dish_all_p_seg, 0x10692C40 +.global end_bg_dish_all_p_seg +.set end_bg_dish_all_p_seg, 0x106974B0 +.global bg_cave_all_p_seg +.set bg_cave_all_p_seg, 0x106974B0 +.global end_bg_cave_all_p_seg +.set end_bg_cave_all_p_seg, 0x106BB9A0 +.global bg_cat_all_p_seg +.set bg_cat_all_p_seg, 0x106BB9A0 +.global end_bg_cat_all_p_seg +.set end_bg_cat_all_p_seg, 0x106C0ED0 +.global bg_crad_all_p_seg +.set bg_crad_all_p_seg, 0x106C0ED0 +.global end_bg_crad_all_p_seg +.set end_bg_crad_all_p_seg, 0x106D1220 +.global bg_sho_all_p_seg +.set bg_sho_all_p_seg, 0x106D1220 +.global end_bg_sho_all_p_seg +.set end_bg_sho_all_p_seg, 0x106D1220 +.global bg_imp_all_p_seg +.set bg_imp_all_p_seg, 0x106D1220 +.global end_bg_imp_all_p_seg +.set end_bg_imp_all_p_seg, 0x106D1220 +.global bg_rit_all_p_seg +.set bg_rit_all_p_seg, 0x106DB180 +.global end_bg_rit_all_p_seg +.set end_bg_rit_all_p_seg, 0x106DB180 +.global bg_oat_all_p_seg +.set bg_oat_all_p_seg, 0x106DB180 +.global end_bg_oat_all_p_seg +.set end_bg_oat_all_p_seg, 0x106E1FD0 +.global bg_ear_all_p_seg +.set bg_ear_all_p_seg, 0x106E1FD0 +.global end_bg_ear_all_p_seg +.set end_bg_ear_all_p_seg, 0x106E1FD0 +.global bg_lee_all_p_seg +.set bg_lee_all_p_seg, 0x106E1FD0 +.global end_bg_lee_all_p_seg +.set end_bg_lee_all_p_seg, 0x106E1FD0 +.global bg_lip_all_p_seg +.set bg_lip_all_p_seg, 0x106E1FD0 +.global end_bg_lip_all_p_seg +.set end_bg_lip_all_p_seg, 0x106E1FD0 +.global bg_len_all_p_seg +.set bg_len_all_p_seg, 0x106E1FD0 +.global end_bg_len_all_p_seg +.set end_bg_len_all_p_seg, 0x106E2F70 +.global bg_wax_all_p_seg +.set bg_wax_all_p_seg, 0x106E2F70 +.global end_bg_wax_all_p_seg +.set end_bg_wax_all_p_seg, 0x106E2F70 +.global bg_pam_all_p_seg +.set bg_pam_all_p_seg, 0x106E2F70 +.global end_bg_pam_all_p_seg +.set end_bg_pam_all_p_seg, 0x106E2F70 +.global CarmourguardZ +.set CarmourguardZ, 0x106E2F70 +.global end_CarmourguardZ +.set end_CarmourguardZ, 0x106E53F0 +.global CbaronsamediZ +.set CbaronsamediZ, 0x106E53F0 +.global end_CbaronsamediZ +.set end_CbaronsamediZ, 0x106E8AE0 +.global CbluecamguardZ +.set CbluecamguardZ, 0x106E8AE0 +.global end_CbluecamguardZ +.set end_CbluecamguardZ, 0x106EB1D0 +.global CbluemanZ +.set CbluemanZ, 0x106EB1D0 +.global end_CbluemanZ +.set end_CbluemanZ, 0x106ECFE0 +.global CbluewomanZ +.set CbluewomanZ, 0x106ECFE0 +.global end_CbluewomanZ +.set end_CbluewomanZ, 0x106EEEA0 +.global CboilerbondZ +.set CboilerbondZ, 0x106EEEA0 +.global end_CboilerbondZ +.set end_CboilerbondZ, 0x106F1AB0 +.global CboilertrevZ +.set CboilertrevZ, 0x106F1AB0 +.global end_CboilertrevZ +.set end_CboilertrevZ, 0x106F5130 +.global CborisZ +.set CborisZ, 0x106F5130 +.global end_CborisZ +.set end_CborisZ, 0x106F8250 +.global CcamguardZ +.set CcamguardZ, 0x106F8250 +.global end_CcamguardZ +.set end_CcamguardZ, 0x106FA930 +.global CcardimanZ +.set CcardimanZ, 0x106FA930 +.global end_CcardimanZ +.set end_CcardimanZ, 0x106FC730 +.global CcheckmanZ +.set CcheckmanZ, 0x106FC730 +.global end_CcheckmanZ +.set end_CcheckmanZ, 0x106FE5B0 +.global CcommguardZ +.set CcommguardZ, 0x106FE5B0 +.global end_CcommguardZ +.set end_CcommguardZ, 0x10700BB0 +.global CdjbondZ +.set CdjbondZ, 0x10700BB0 +.global end_CdjbondZ +.set end_CdjbondZ, 0x10703A40 +.global CfattechwomanZ +.set CfattechwomanZ, 0x10703A40 +.global end_CfattechwomanZ +.set end_CfattechwomanZ, 0x10705960 +.global Cgreatguard2Z +.set Cgreatguard2Z, 0x10705960 +.global end_Cgreatguard2Z +.set end_Cgreatguard2Z, 0x10708080 +.global CgreatguardZ +.set CgreatguardZ, 0x10708080 +.global end_CgreatguardZ +.set end_CgreatguardZ, 0x1070A700 +.global CgreyguardZ +.set CgreyguardZ, 0x1070A700 +.global end_CgreyguardZ +.set end_CgreyguardZ, 0x1070CDD0 +.global CgreymanZ +.set CgreymanZ, 0x1070CDD0 +.global end_CgreymanZ +.set end_CgreymanZ, 0x1070EB90 +.global CheadalanZ +.set CheadalanZ, 0x1070EB90 +.global end_CheadalanZ +.set end_CheadalanZ, 0x1070F160 +.global CheadbZ +.set CheadbZ, 0x1070F160 +.global end_CheadbZ +.set end_CheadbZ, 0x1070F6D0 +.global CheadbalaclavaZ +.set CheadbalaclavaZ, 0x1070F6D0 +.global end_CheadbalaclavaZ +.set end_CheadbalaclavaZ, 0x1070FAA0 +.global CheadbikeZ +.set CheadbikeZ, 0x1070FAA0 +.global end_CheadbikeZ +.set end_CheadbikeZ, 0x10710140 +.global CheadbrosnanZ +.set CheadbrosnanZ, 0x10710140 +.global end_CheadbrosnanZ +.set end_CheadbrosnanZ, 0x10710E90 +.global CheadbrosnanboilerZ +.set CheadbrosnanboilerZ, 0x10710E90 +.global end_CheadbrosnanboilerZ +.set end_CheadbrosnanboilerZ, 0x10711A30 +.global CheadbrosnansnowZ +.set CheadbrosnansnowZ, 0x10711A30 +.global end_CheadbrosnansnowZ +.set end_CheadbrosnansnowZ, 0x107128B0 +.global CheadbrosnansuitZ +.set CheadbrosnansuitZ, 0x107128B0 +.global end_CheadbrosnansuitZ +.set end_CheadbrosnansuitZ, 0x10713630 +.global CheadbrosnantimberZ +.set CheadbrosnantimberZ, 0x10713630 +.global end_CheadbrosnantimberZ +.set end_CheadbrosnantimberZ, 0x107141F0 +.global CheadchrisZ +.set CheadchrisZ, 0x107141F0 +.global end_CheadchrisZ +.set end_CheadchrisZ, 0x10714730 +.global CheaddaveZ +.set CheaddaveZ, 0x10714730 +.global end_CheaddaveZ +.set end_CheaddaveZ, 0x10714CB0 +.global CheaddesZ +.set CheaddesZ, 0x10714CB0 +.global end_CheaddesZ +.set end_CheaddesZ, 0x107151E0 +.global CheadduncanZ +.set CheadduncanZ, 0x107151E0 +.global end_CheadduncanZ +.set end_CheadduncanZ, 0x10715700 +.global CheaddwayneZ +.set CheaddwayneZ, 0x10715700 +.global end_CheaddwayneZ +.set end_CheaddwayneZ, 0x10715C80 +.global CheadgrahamZ +.set CheadgrahamZ, 0x10715C80 +.global end_CheadgrahamZ +.set end_CheadgrahamZ, 0x107161F0 +.global CheadgrantZ +.set CheadgrantZ, 0x107161F0 +.global end_CheadgrantZ +.set end_CheadgrantZ, 0x10716720 +.global CheadjimZ +.set CheadjimZ, 0x10716720 +.global end_CheadjimZ +.set end_CheadjimZ, 0x10716C50 +.global Cheadjoe2Z +.set Cheadjoe2Z, 0x10716C50 +.global end_Cheadjoe2Z +.set end_Cheadjoe2Z, 0x10717070 +.global CheadjoeZ +.set CheadjoeZ, 0x10717070 +.global end_CheadjoeZ +.set end_CheadjoeZ, 0x107175E0 +.global CheadjoelZ +.set CheadjoelZ, 0x107175E0 +.global end_CheadjoelZ +.set end_CheadjoelZ, 0x10717AF0 +.global CheadkarlZ +.set CheadkarlZ, 0x10717AF0 +.global end_CheadkarlZ +.set end_CheadkarlZ, 0x10718050 +.global CheadkenZ +.set CheadkenZ, 0x10718050 +.global end_CheadkenZ +.set end_CheadkenZ, 0x107185A0 +.global CheadleeZ +.set CheadleeZ, 0x107185A0 +.global end_CheadleeZ +.set end_CheadleeZ, 0x10718B20 +.global CheadmandyZ +.set CheadmandyZ, 0x10718B20 +.global end_CheadmandyZ +.set end_CheadmandyZ, 0x10718F10 +.global CheadmarionZ +.set CheadmarionZ, 0x10718F10 +.global end_CheadmarionZ +.set end_CheadmarionZ, 0x10719320 +.global CheadmarkZ +.set CheadmarkZ, 0x10719320 +.global end_CheadmarkZ +.set end_CheadmarkZ, 0x10719850 +.global CheadmartinZ +.set CheadmartinZ, 0x10719850 +.global end_CheadmartinZ +.set end_CheadmartinZ, 0x10719DB0 +.global CheadmishkinZ +.set CheadmishkinZ, 0x10719DB0 +.global end_CheadmishkinZ +.set end_CheadmishkinZ, 0x1071A310 +.global CheadneilZ +.set CheadneilZ, 0x1071A310 +.global end_CheadneilZ +.set end_CheadneilZ, 0x1071A830 +.global CheadpeteZ +.set CheadpeteZ, 0x1071A830 +.global end_CheadpeteZ +.set end_CheadpeteZ, 0x1071ADC0 +.global CheadrobinZ +.set CheadrobinZ, 0x1071ADC0 +.global end_CheadrobinZ +.set end_CheadrobinZ, 0x1071B2D0 +.global CheadsallyZ +.set CheadsallyZ, 0x1071B2D0 +.global end_CheadsallyZ +.set end_CheadsallyZ, 0x1071B6D0 +.global CheadscottZ +.set CheadscottZ, 0x1071B6D0 +.global end_CheadscottZ +.set end_CheadscottZ, 0x1071BC50 +.global CheadshaunZ +.set CheadshaunZ, 0x1071BC50 +.global end_CheadshaunZ +.set end_CheadshaunZ, 0x1071C230 +.global CheadsteveeZ +.set CheadsteveeZ, 0x1071C230 +.global end_CheadsteveeZ +.set end_CheadsteveeZ, 0x1071C780 +.global CheadstevehZ +.set CheadstevehZ, 0x1071C780 +.global end_CheadstevehZ +.set end_CheadstevehZ, 0x1071CCD0 +.global CheadvivienZ +.set CheadvivienZ, 0x1071CCD0 +.global end_CheadvivienZ +.set end_CheadvivienZ, 0x1071D160 +.global CjawsZ +.set CjawsZ, 0x1071D160 +.global end_CjawsZ +.set end_CjawsZ, 0x1071FDA0 +.global CjeanwomanZ +.set CjeanwomanZ, 0x1071FDA0 +.global end_CjeanwomanZ +.set end_CjeanwomanZ, 0x10721DB0 +.global CmaydayZ +.set CmaydayZ, 0x10721DB0 +.global end_CmaydayZ +.set end_CmaydayZ, 0x10724950 +.global CmoonfemaleZ +.set CmoonfemaleZ, 0x10724950 +.global end_CmoonfemaleZ +.set end_CmoonfemaleZ, 0x10726AA0 +.global CmoonguardZ +.set CmoonguardZ, 0x10726AA0 +.global end_CmoonguardZ +.set end_CmoonguardZ, 0x10729090 +.global CnatalyaZ +.set CnatalyaZ, 0x10729090 +.global end_CnatalyaZ +.set end_CnatalyaZ, 0x1072C950 +.global CnavyguardZ +.set CnavyguardZ, 0x1072C950 +.global end_CnavyguardZ +.set end_CnavyguardZ, 0x1072F030 +.global CoddjobZ +.set CoddjobZ, 0x1072F030 +.global end_CoddjobZ +.set end_CoddjobZ, 0x10732160 +.global ColiveguardZ +.set ColiveguardZ, 0x10732160 +.global end_ColiveguardZ +.set end_ColiveguardZ, 0x107347B0 +.global CorumovZ +.set CorumovZ, 0x107347B0 +.global end_CorumovZ +.set end_CorumovZ, 0x10737BE0 +.global CpilotZ +.set CpilotZ, 0x10737BE0 +.global end_CpilotZ +.set end_CpilotZ, 0x1073AC60 +.global CredmanZ +.set CredmanZ, 0x1073AC60 +.global end_CredmanZ +.set end_CredmanZ, 0x1073D390 +.global CrusguardZ +.set CrusguardZ, 0x1073D390 +.global end_CrusguardZ +.set end_CrusguardZ, 0x1073EFC0 +.global CsnowbondZ +.set CsnowbondZ, 0x1073EFC0 +.global end_CsnowbondZ +.set end_CsnowbondZ, 0x107422F0 +.global CsnowguardZ +.set CsnowguardZ, 0x107422F0 +.global end_CsnowguardZ +.set end_CsnowguardZ, 0x10744F70 +.global CspicebondZ +.set CspicebondZ, 0x10744F70 +.global end_CspicebondZ +.set end_CspicebondZ, 0x10748890 +.global Csuit_lf_handZ +.set Csuit_lf_handZ, 0x10748890 +.global end_Csuit_lf_handZ +.set end_Csuit_lf_handZ, 0x1074BAB0 +.global CsuitbondZ +.set CsuitbondZ, 0x1074BAB0 +.global end_CsuitbondZ +.set end_CsuitbondZ, 0x1074E840 +.global CtechmanZ +.set CtechmanZ, 0x1074E840 +.global end_CtechmanZ +.set end_CtechmanZ, 0x10750EF0 +.global CtechwomanZ +.set CtechwomanZ, 0x10750EF0 +.global end_CtechwomanZ +.set end_CtechwomanZ, 0x10752EE0 +.global CtimberbondZ +.set CtimberbondZ, 0x10752EE0 +.global end_CtimberbondZ +.set end_CtimberbondZ, 0x10755C10 +.global CtrevelyanZ +.set CtrevelyanZ, 0x10755C10 +.global end_CtrevelyanZ +.set end_CtrevelyanZ, 0x107593E0 +.global CtrevguardZ +.set CtrevguardZ, 0x107593E0 +.global end_CtrevguardZ +.set end_CtrevguardZ, 0x1075B9F0 +.global CvalentinZ +.set CvalentinZ, 0x1075B9F0 +.global end_CvalentinZ +.set end_CvalentinZ, 0x1075E960 +.global CxeniaZ +.set CxeniaZ, 0x1075E960 +.global end_CxeniaZ +.set end_CxeniaZ, 0x10762350 +.global Gak47Z +.set Gak47Z, 0x10762350 +.global end_Gak47Z +.set end_Gak47Z, 0x10762D60 +.global GaudiotapeZ +.set GaudiotapeZ, 0x10762D60 +.global end_GaudiotapeZ +.set end_GaudiotapeZ, 0x107630F0 +.global GautoshotZ +.set GautoshotZ, 0x107630F0 +.global end_GautoshotZ +.set end_GautoshotZ, 0x10764900 +.global GblackboxZ +.set GblackboxZ, 0x10764900 +.global end_GblackboxZ +.set end_GblackboxZ, 0x10764F00 +.global GblueprintsZ +.set GblueprintsZ, 0x10764F00 +.global end_GblueprintsZ +.set end_GblueprintsZ, 0x10765000 +.global GbombcaseZ +.set GbombcaseZ, 0x10765000 +.global end_GbombcaseZ +.set end_GbombcaseZ, 0x10765790 +.global GbombdefuserZ +.set GbombdefuserZ, 0x10765790 +.global end_GbombdefuserZ +.set end_GbombdefuserZ, 0x10765D80 +.global GbriefcaseZ +.set GbriefcaseZ, 0x10765D80 +.global end_GbriefcaseZ +.set end_GbriefcaseZ, 0x10766510 +.global GbugZ +.set GbugZ, 0x10766510 +.global end_GbugZ +.set end_GbugZ, 0x10766E80 +.global GbugdetectorZ +.set GbugdetectorZ, 0x10766E80 +.global end_GbugdetectorZ +.set end_GbugdetectorZ, 0x107671D0 +.global GbungeeZ +.set GbungeeZ, 0x107671D0 +.global end_GbungeeZ +.set end_GbungeeZ, 0x10767520 +.global GcameraZ +.set GcameraZ, 0x10767520 +.global end_GcameraZ +.set end_GcameraZ, 0x107679A0 +.global GcartblueZ +.set GcartblueZ, 0x107679A0 +.global end_GcartblueZ +.set end_GcartblueZ, 0x10767C00 +.global GcartridgeZ +.set GcartridgeZ, 0x10767C00 +.global end_GcartridgeZ +.set end_GcartridgeZ, 0x10767D30 +.global GcartrifleZ +.set GcartrifleZ, 0x10767D30 +.global end_GcartrifleZ +.set end_GcartrifleZ, 0x10767F40 +.global GcartshellZ +.set GcartshellZ, 0x10767F40 +.global end_GcartshellZ +.set end_GcartshellZ, 0x10768140 +.global GcircuitboardZ +.set GcircuitboardZ, 0x10768140 +.global end_GcircuitboardZ +.set end_GcircuitboardZ, 0x10768280 +.global GclipboardZ +.set GclipboardZ, 0x10768280 +.global end_GclipboardZ +.set end_GclipboardZ, 0x10768470 +.global GcreditcardZ +.set GcreditcardZ, 0x10768470 +.global end_GcreditcardZ +.set end_GcreditcardZ, 0x107687C0 +.global GdarkglassesZ +.set GdarkglassesZ, 0x107687C0 +.global end_GdarkglassesZ +.set end_GdarkglassesZ, 0x10768B10 +.global GdatathiefZ +.set GdatathiefZ, 0x10768B10 +.global end_GdatathiefZ +.set end_GdatathiefZ, 0x10768C50 +.global GdattapeZ +.set GdattapeZ, 0x10768C50 +.global end_GdattapeZ +.set end_GdattapeZ, 0x10768DC0 +.global GdoordecoderZ +.set GdoordecoderZ, 0x10768DC0 +.global end_GdoordecoderZ +.set end_GdoordecoderZ, 0x10769340 +.global GdoorexploderZ +.set GdoorexploderZ, 0x10769340 +.global end_GdoorexploderZ +.set end_GdoorexploderZ, 0x10769690 +.global GdossierredZ +.set GdossierredZ, 0x10769690 +.global end_GdossierredZ +.set end_GdossierredZ, 0x107699F0 +.global GdynamiteZ +.set GdynamiteZ, 0x107699F0 +.global end_GdynamiteZ +.set end_GdynamiteZ, 0x10769D40 +.global GexplosivefloppyZ +.set GexplosivefloppyZ, 0x10769D40 +.global end_GexplosivefloppyZ +.set end_GexplosivefloppyZ, 0x10769F90 +.global GexplosivepenZ +.set GexplosivepenZ, 0x10769F90 +.global end_GexplosivepenZ +.set end_GexplosivepenZ, 0x1076A2E0 +.global GextinguisherZ +.set GextinguisherZ, 0x1076A2E0 +.global end_GextinguisherZ +.set end_GextinguisherZ, 0x1076AAD0 +.global GfingergunZ +.set GfingergunZ, 0x1076AAD0 +.global end_GfingergunZ +.set end_GfingergunZ, 0x1076AE20 +.global GfistZ +.set GfistZ, 0x1076AE20 +.global end_GfistZ +.set end_GfistZ, 0x1076C520 +.global GflarepistolZ +.set GflarepistolZ, 0x1076C520 +.global end_GflarepistolZ +.set end_GflarepistolZ, 0x1076C870 +.global Gfnp90Z +.set Gfnp90Z, 0x1076C870 +.global end_Gfnp90Z +.set end_Gfnp90Z, 0x1076D510 +.global GgaskeyringZ +.set GgaskeyringZ, 0x1076D510 +.global end_GgaskeyringZ +.set end_GgaskeyringZ, 0x1076DF40 +.global GgoldbarZ +.set GgoldbarZ, 0x1076DF40 +.global end_GgoldbarZ +.set end_GgoldbarZ, 0x1076E290 +.global GgoldeneyekeyZ +.set GgoldeneyekeyZ, 0x1076E290 +.global end_GgoldeneyekeyZ +.set end_GgoldeneyekeyZ, 0x1076EC40 +.global GgoldengunZ +.set GgoldengunZ, 0x1076EC40 +.global end_GgoldengunZ +.set end_GgoldengunZ, 0x10770420 +.global GgoldwppkZ +.set GgoldwppkZ, 0x10770420 +.global end_GgoldwppkZ +.set end_GgoldwppkZ, 0x10771D80 +.global GgrenadeZ +.set GgrenadeZ, 0x10771D80 +.global end_GgrenadeZ +.set end_GgrenadeZ, 0x107727B0 +.global GgrenadelaunchZ +.set GgrenadelaunchZ, 0x107727B0 +.global end_GgrenadelaunchZ +.set end_GgrenadelaunchZ, 0x10773830 +.global GheroinZ +.set GheroinZ, 0x10773830 +.global end_GheroinZ +.set end_GheroinZ, 0x10773B80 +.global GjoypadZ +.set GjoypadZ, 0x10773B80 +.global end_GjoypadZ +.set end_GjoypadZ, 0x10775A30 +.global GkeyanalysercaseZ +.set GkeyanalysercaseZ, 0x10775A30 +.global end_GkeyanalysercaseZ +.set end_GkeyanalysercaseZ, 0x107761C0 +.global GkeyboltZ +.set GkeyboltZ, 0x107761C0 +.global end_GkeyboltZ +.set end_GkeyboltZ, 0x10776BB0 +.global GkeycardZ +.set GkeycardZ, 0x10776BB0 +.global end_GkeycardZ +.set end_GkeycardZ, 0x10776CE0 +.global GkeyyaleZ +.set GkeyyaleZ, 0x10776CE0 +.global end_GkeyyaleZ +.set end_GkeyyaleZ, 0x10777A30 +.global GknifeZ +.set GknifeZ, 0x10777A30 +.global end_GknifeZ +.set end_GknifeZ, 0x10779500 +.global GlaserZ +.set GlaserZ, 0x10779500 +.global end_GlaserZ +.set end_GlaserZ, 0x1077A2F0 +.global GlectreZ +.set GlectreZ, 0x1077A2F0 +.global end_GlectreZ +.set end_GlectreZ, 0x1077A640 +.global GlockexploderZ +.set GlockexploderZ, 0x1077A640 +.global end_GlockexploderZ +.set end_GlockexploderZ, 0x1077A990 +.global Gm16Z +.set Gm16Z, 0x1077A990 +.global end_Gm16Z +.set end_Gm16Z, 0x1077B3B0 +.global GmapZ +.set GmapZ, 0x1077B3B0 +.global end_GmapZ +.set end_GmapZ, 0x1077B4A0 +.global GmicrocameraZ +.set GmicrocameraZ, 0x1077B4A0 +.global end_GmicrocameraZ +.set end_GmicrocameraZ, 0x1077BAE0 +.global GmicrocodeZ +.set GmicrocodeZ, 0x1077BAE0 +.global end_GmicrocodeZ +.set end_GmicrocodeZ, 0x1077BE30 +.global GmicrofilmZ +.set GmicrofilmZ, 0x1077BE30 +.global end_GmicrofilmZ +.set end_GmicrofilmZ, 0x1077C180 +.global GmoneyZ +.set GmoneyZ, 0x1077C180 +.global end_GmoneyZ +.set end_GmoneyZ, 0x1077C4D0 +.global Gmp5kZ +.set Gmp5kZ, 0x1077C4D0 +.global end_Gmp5kZ +.set end_Gmp5kZ, 0x1077D0B0 +.global Gmp5ksilZ +.set Gmp5ksilZ, 0x1077D0B0 +.global end_Gmp5ksilZ +.set end_Gmp5ksilZ, 0x1077DDB0 +.global GpitongunZ +.set GpitongunZ, 0x1077DDB0 +.global end_GpitongunZ +.set end_GpitongunZ, 0x1077E100 +.global GplansZ +.set GplansZ, 0x1077E100 +.global end_GplansZ +.set end_GplansZ, 0x1077E2D0 +.global GplastiqueZ +.set GplastiqueZ, 0x1077E2D0 +.global end_GplastiqueZ +.set end_GplastiqueZ, 0x1077E620 +.global GpolarizedglassesZ +.set GpolarizedglassesZ, 0x1077E620 +.global end_GpolarizedglassesZ +.set end_GpolarizedglassesZ, 0x1077EB80 +.global GproximitymineZ +.set GproximitymineZ, 0x1077EB80 +.global end_GproximitymineZ +.set end_GproximitymineZ, 0x1077F370 +.global GremotemineZ +.set GremotemineZ, 0x1077F370 +.global end_GremotemineZ +.set end_GremotemineZ, 0x1077FD30 +.global GrocketlaunchZ +.set GrocketlaunchZ, 0x1077FD30 +.global end_GrocketlaunchZ +.set end_GrocketlaunchZ, 0x10780F50 +.global GrugerZ +.set GrugerZ, 0x10780F50 +.global end_GrugerZ +.set end_GrugerZ, 0x10782CE0 +.global GsafecrackercaseZ +.set GsafecrackercaseZ, 0x10782CE0 +.global end_GsafecrackercaseZ +.set end_GsafecrackercaseZ, 0x10783470 +.global GshotgunZ +.set GshotgunZ, 0x10783470 +.global end_GshotgunZ +.set end_GshotgunZ, 0x10784350 +.global GsilverwppkZ +.set GsilverwppkZ, 0x10784350 +.global end_GsilverwppkZ +.set end_GsilverwppkZ, 0x10785CB0 +.global GskorpionZ +.set GskorpionZ, 0x10785CB0 +.global end_GskorpionZ +.set end_GskorpionZ, 0x10786EB0 +.global GsniperrifleZ +.set GsniperrifleZ, 0x10786EB0 +.global end_GsniperrifleZ +.set end_GsniperrifleZ, 0x10787F20 +.global GspectreZ +.set GspectreZ, 0x10787F20 +.global end_GspectreZ +.set end_GspectreZ, 0x10788BA0 +.global GspooltapeZ +.set GspooltapeZ, 0x10788BA0 +.global end_GspooltapeZ +.set end_GspooltapeZ, 0x10788EF0 +.global GspyfileZ +.set GspyfileZ, 0x10788EF0 +.global end_GspyfileZ +.set end_GspyfileZ, 0x10789240 +.global GstafflistZ +.set GstafflistZ, 0x10789240 +.global end_GstafflistZ +.set end_GstafflistZ, 0x107893E0 +.global GtaserZ +.set GtaserZ, 0x107893E0 +.global end_GtaserZ +.set end_GtaserZ, 0x1078B240 +.global GthrowknifeZ +.set GthrowknifeZ, 0x1078B240 +.global end_GthrowknifeZ +.set end_GthrowknifeZ, 0x1078CD30 +.global GtimedmineZ +.set GtimedmineZ, 0x1078CD30 +.global end_GtimedmineZ +.set end_GtimedmineZ, 0x1078D7F0 +.global GtriggerZ +.set GtriggerZ, 0x1078D7F0 +.global end_GtriggerZ +.set end_GtriggerZ, 0x10790BF0 +.global Gtt33Z +.set Gtt33Z, 0x10790BF0 +.global end_Gtt33Z +.set end_Gtt33Z, 0x10792710 +.global GuziZ +.set GuziZ, 0x10792710 +.global end_GuziZ +.set end_GuziZ, 0x10793020 +.global GvideotapeZ +.set GvideotapeZ, 0x10793020 +.global end_GvideotapeZ +.set end_GvideotapeZ, 0x10793230 +.global GwatchcommunicatorZ +.set GwatchcommunicatorZ, 0x10793230 +.global end_GwatchcommunicatorZ +.set end_GwatchcommunicatorZ, 0x10794690 +.global GwatchgeigercounterZ +.set GwatchgeigercounterZ, 0x10794690 +.global end_GwatchgeigercounterZ +.set end_GwatchgeigercounterZ, 0x10795AF0 +.global GwatchidentifierZ +.set GwatchidentifierZ, 0x10795AF0 +.global end_GwatchidentifierZ +.set end_GwatchidentifierZ, 0x10796F50 +.global GwatchlaserZ +.set GwatchlaserZ, 0x10796F50 +.global end_GwatchlaserZ +.set end_GwatchlaserZ, 0x1079A350 +.global GwatchmagnetattractZ +.set GwatchmagnetattractZ, 0x1079A350 +.global end_GwatchmagnetattractZ +.set end_GwatchmagnetattractZ, 0x1079B7A0 +.global GwatchmagnetrepelZ +.set GwatchmagnetrepelZ, 0x1079B7A0 +.global end_GwatchmagnetrepelZ +.set end_GwatchmagnetrepelZ, 0x1079CC00 +.global GweaponcaseZ +.set GweaponcaseZ, 0x1079CC00 +.global end_GweaponcaseZ +.set end_GweaponcaseZ, 0x1079D390 +.global GwppkZ +.set GwppkZ, 0x1079D390 +.global end_GwppkZ +.set end_GwppkZ, 0x1079F020 +.global GwppksilZ +.set GwppksilZ, 0x1079F020 +.global end_GwppksilZ +.set end_GwppksilZ, 0x107A0D60 +.global GwristdartZ +.set GwristdartZ, 0x107A0D60 +.global end_GwristdartZ +.set end_GwristdartZ, 0x107A10B0 +.global PICBMZ +.set PICBMZ, 0x107A10B0 +.global end_PICBMZ +.set end_PICBMZ, 0x107A3630 +.global PICBM_noseZ +.set PICBM_noseZ, 0x107A3630 +.global end_PICBM_noseZ +.set end_PICBM_noseZ, 0x107A3DE0 +.global Pak47magZ +.set Pak47magZ, 0x107A3DE0 +.global end_Pak47magZ +.set end_Pak47magZ, 0x107A3FC0 +.global Palarm1Z +.set Palarm1Z, 0x107A3FC0 +.global end_Palarm1Z +.set end_Palarm1Z, 0x107A4120 +.global Palarm2Z +.set Palarm2Z, 0x107A4120 +.global end_Palarm2Z +.set end_Palarm2Z, 0x107A42C0 +.global Pammo_crate1Z +.set Pammo_crate1Z, 0x107A42C0 +.global end_Pammo_crate1Z +.set end_Pammo_crate1Z, 0x107A4500 +.global Pammo_crate2Z +.set Pammo_crate2Z, 0x107A4500 +.global end_Pammo_crate2Z +.set end_Pammo_crate2Z, 0x107A4740 +.global Pammo_crate3Z +.set Pammo_crate3Z, 0x107A4740 +.global end_Pammo_crate3Z +.set end_Pammo_crate3Z, 0x107A4990 +.global Pammo_crate4Z +.set Pammo_crate4Z, 0x107A4990 +.global end_Pammo_crate4Z +.set end_Pammo_crate4Z, 0x107A4C00 +.global Pammo_crate5Z +.set Pammo_crate5Z, 0x107A4C00 +.global end_Pammo_crate5Z +.set end_Pammo_crate5Z, 0x107A4EC0 +.global PapcZ +.set PapcZ, 0x107A4EC0 +.global end_PapcZ +.set end_PapcZ, 0x107A6B20 +.global Parchsecdoor1Z +.set Parchsecdoor1Z, 0x107A6B20 +.global end_Parchsecdoor1Z +.set end_Parchsecdoor1Z, 0x107A6D00 +.global Parchsecdoor2Z +.set Parchsecdoor2Z, 0x107A6D00 +.global end_Parchsecdoor2Z +.set end_Parchsecdoor2Z, 0x107A6ED0 +.global ParticZ +.set ParticZ, 0x107A6ED0 +.global end_ParticZ +.set end_ParticZ, 0x107A7CD0 +.global PartictrailerZ +.set PartictrailerZ, 0x107A7CD0 +.global end_PartictrailerZ +.set end_PartictrailerZ, 0x107A85E0 +.global PbarricadeZ +.set PbarricadeZ, 0x107A85E0 +.global end_PbarricadeZ +.set end_PbarricadeZ, 0x107A8820 +.global Pbin1Z +.set Pbin1Z, 0x107A8820 +.global end_Pbin1Z +.set end_Pbin1Z, 0x107A8B70 +.global Pblotter1Z +.set Pblotter1Z, 0x107A8B70 +.global end_Pblotter1Z +.set end_Pblotter1Z, 0x107A8C50 +.global PbodyarmourZ +.set PbodyarmourZ, 0x107A8C50 +.global end_PbodyarmourZ +.set end_PbodyarmourZ, 0x107A90F0 +.global PbodyarmourvestZ +.set PbodyarmourvestZ, 0x107A90F0 +.global end_PbodyarmourvestZ +.set end_PbodyarmourvestZ, 0x107A9510 +.global PbollardZ +.set PbollardZ, 0x107A9510 +.global end_PbollardZ +.set end_PbollardZ, 0x107A9710 +.global PbombZ +.set PbombZ, 0x107A9710 +.global end_PbombZ +.set end_PbombZ, 0x107A9880 +.global Pbook1Z +.set Pbook1Z, 0x107A9880 +.global end_Pbook1Z +.set end_Pbook1Z, 0x107A9A10 +.global Pbookshelf1Z +.set Pbookshelf1Z, 0x107A9A10 +.global end_Pbookshelf1Z +.set end_Pbookshelf1Z, 0x107AA100 +.global Pborg_crateZ +.set Pborg_crateZ, 0x107AA100 +.global end_Pborg_crateZ +.set end_Pborg_crateZ, 0x107AA270 +.global PboxcartridgesZ +.set PboxcartridgesZ, 0x107AA270 +.global end_PboxcartridgesZ +.set end_PboxcartridgesZ, 0x107AA470 +.global Pboxes2x4Z +.set Pboxes2x4Z, 0x107AA470 +.global end_Pboxes2x4Z +.set end_Pboxes2x4Z, 0x107AA8A0 +.global Pboxes3x4Z +.set Pboxes3x4Z, 0x107AA8A0 +.global end_Pboxes3x4Z +.set end_Pboxes3x4Z, 0x107AACE0 +.global Pboxes4x4Z +.set Pboxes4x4Z, 0x107AACE0 +.global end_Pboxes4x4Z +.set end_Pboxes4x4Z, 0x107AB340 +.global PbrakeunitZ +.set PbrakeunitZ, 0x107AB340 +.global end_PbrakeunitZ +.set end_PbrakeunitZ, 0x107AB6B0 +.global Pbridge_console1aZ +.set Pbridge_console1aZ, 0x107AB6B0 +.global end_Pbridge_console1aZ +.set end_Pbridge_console1aZ, 0x107ABC30 +.global Pbridge_console1bZ +.set Pbridge_console1bZ, 0x107ABC30 +.global end_Pbridge_console1bZ +.set end_Pbridge_console1bZ, 0x107AC190 +.global Pbridge_console2aZ +.set Pbridge_console2aZ, 0x107AC190 +.global end_Pbridge_console2aZ +.set end_Pbridge_console2aZ, 0x107AC710 +.global Pbridge_console2bZ +.set Pbridge_console2bZ, 0x107AC710 +.global end_Pbridge_console2bZ +.set end_Pbridge_console2bZ, 0x107ACC00 +.global Pbridge_console3aZ +.set Pbridge_console3aZ, 0x107ACC00 +.global end_Pbridge_console3aZ +.set end_Pbridge_console3aZ, 0x107AD150 +.global Pbridge_console3bZ +.set Pbridge_console3bZ, 0x107AD150 +.global end_Pbridge_console3bZ +.set end_Pbridge_console3bZ, 0x107AD6E0 +.global PcarbmwZ +.set PcarbmwZ, 0x107AD6E0 +.global end_PcarbmwZ +.set end_PcarbmwZ, 0x107AE3C0 +.global Pcard_box1Z +.set Pcard_box1Z, 0x107AE3C0 +.global end_Pcard_box1Z +.set end_Pcard_box1Z, 0x107AE5C0 +.global Pcard_box2Z +.set Pcard_box2Z, 0x107AE5C0 +.global end_Pcard_box2Z +.set end_Pcard_box2Z, 0x107AE800 +.global Pcard_box3Z +.set Pcard_box3Z, 0x107AE800 +.global end_Pcard_box3Z +.set end_Pcard_box3Z, 0x107AE9F0 +.global Pcard_box4_lgZ +.set Pcard_box4_lgZ, 0x107AE9F0 +.global end_Pcard_box4_lgZ +.set end_Pcard_box4_lgZ, 0x107AEBA0 +.global Pcard_box5_lgZ +.set Pcard_box5_lgZ, 0x107AEBA0 +.global end_Pcard_box5_lgZ +.set end_Pcard_box5_lgZ, 0x107AEDA0 +.global Pcard_box6_lgZ +.set Pcard_box6_lgZ, 0x107AEDA0 +.global end_Pcard_box6_lgZ +.set end_Pcard_box6_lgZ, 0x107AEF90 +.global PcarescortZ +.set PcarescortZ, 0x107AEF90 +.global end_PcarescortZ +.set end_PcarescortZ, 0x107AFB90 +.global PcargolfZ +.set PcargolfZ, 0x107AFB90 +.global end_PcargolfZ +.set end_PcargolfZ, 0x107B07C0 +.global PcarweirdZ +.set PcarweirdZ, 0x107B07C0 +.global end_PcarweirdZ +.set end_PcarweirdZ, 0x107B1900 +.global PcarzilZ +.set PcarzilZ, 0x107B1900 +.global end_PcarzilZ +.set end_PcarzilZ, 0x107B2F00 +.global PcctvZ +.set PcctvZ, 0x107B2F00 +.global end_PcctvZ +.set end_PcctvZ, 0x107B3280 +.global PchraudiotapeZ +.set PchraudiotapeZ, 0x107B3280 +.global end_PchraudiotapeZ +.set end_PchraudiotapeZ, 0x107B37E0 +.global PchrautoshotZ +.set PchrautoshotZ, 0x107B37E0 +.global end_PchrautoshotZ +.set end_PchrautoshotZ, 0x107B3B40 +.global PchrblackboxZ +.set PchrblackboxZ, 0x107B3B40 +.global end_PchrblackboxZ +.set end_PchrblackboxZ, 0x107B43C0 +.global PchrblueprintsZ +.set PchrblueprintsZ, 0x107B43C0 +.global end_PchrblueprintsZ +.set end_PchrblueprintsZ, 0x107B4510 +.global PchrbombcaseZ +.set PchrbombcaseZ, 0x107B4510 +.global end_PchrbombcaseZ +.set end_PchrbombcaseZ, 0x107B4700 +.global PchrbombdefuserZ +.set PchrbombdefuserZ, 0x107B4700 +.global end_PchrbombdefuserZ +.set end_PchrbombdefuserZ, 0x107B4FE0 +.global PchrbriefcaseZ +.set PchrbriefcaseZ, 0x107B4FE0 +.global end_PchrbriefcaseZ +.set end_PchrbriefcaseZ, 0x107B5170 +.global PchrbugZ +.set PchrbugZ, 0x107B5170 +.global end_PchrbugZ +.set end_PchrbugZ, 0x107B5F20 +.global PchrbugdetectorZ +.set PchrbugdetectorZ, 0x107B5F20 +.global end_PchrbugdetectorZ +.set end_PchrbugdetectorZ, 0x107B6090 +.global PchrbungeeZ +.set PchrbungeeZ, 0x107B6090 +.global end_PchrbungeeZ +.set end_PchrbungeeZ, 0x107B6200 +.global PchrcameraZ +.set PchrcameraZ, 0x107B6200 +.global end_PchrcameraZ +.set end_PchrcameraZ, 0x107B6890 +.global PchrcircuitboardZ +.set PchrcircuitboardZ, 0x107B6890 +.global end_PchrcircuitboardZ +.set end_PchrcircuitboardZ, 0x107B6A30 +.global PchrclipboardZ +.set PchrclipboardZ, 0x107B6A30 +.global end_PchrclipboardZ +.set end_PchrclipboardZ, 0x107B6CB0 +.global PchrcreditcardZ +.set PchrcreditcardZ, 0x107B6CB0 +.global end_PchrcreditcardZ +.set end_PchrcreditcardZ, 0x107B6E20 +.global PchrdarkglassesZ +.set PchrdarkglassesZ, 0x107B6E20 +.global end_PchrdarkglassesZ +.set end_PchrdarkglassesZ, 0x107B6F90 +.global PchrdatathiefZ +.set PchrdatathiefZ, 0x107B6F90 +.global end_PchrdatathiefZ +.set end_PchrdatathiefZ, 0x107B7130 +.global PchrdattapeZ +.set PchrdattapeZ, 0x107B7130 +.global end_PchrdattapeZ +.set end_PchrdattapeZ, 0x107B7320 +.global PchrdoordecoderZ +.set PchrdoordecoderZ, 0x107B7320 +.global end_PchrdoordecoderZ +.set end_PchrdoordecoderZ, 0x107B7B80 +.global PchrdoorexploderZ +.set PchrdoorexploderZ, 0x107B7B80 +.global end_PchrdoorexploderZ +.set end_PchrdoorexploderZ, 0x107B7CF0 +.global PchrdossierredZ +.set PchrdossierredZ, 0x107B7CF0 +.global end_PchrdossierredZ +.set end_PchrdossierredZ, 0x107B81C0 +.global PchrdynamiteZ +.set PchrdynamiteZ, 0x107B81C0 +.global end_PchrdynamiteZ +.set end_PchrdynamiteZ, 0x107B8330 +.global PchrexplosivepenZ +.set PchrexplosivepenZ, 0x107B8330 +.global end_PchrexplosivepenZ +.set end_PchrexplosivepenZ, 0x107B84A0 +.global PchrextinguisherZ +.set PchrextinguisherZ, 0x107B84A0 +.global end_PchrextinguisherZ +.set end_PchrextinguisherZ, 0x107B89A0 +.global PchrfingergunZ +.set PchrfingergunZ, 0x107B89A0 +.global end_PchrfingergunZ +.set end_PchrfingergunZ, 0x107B8B10 +.global PchrflarepistolZ +.set PchrflarepistolZ, 0x107B8B10 +.global end_PchrflarepistolZ +.set end_PchrflarepistolZ, 0x107B8C80 +.global Pchrfnp90Z +.set Pchrfnp90Z, 0x107B8C80 +.global end_Pchrfnp90Z +.set end_Pchrfnp90Z, 0x107B90E0 +.global PchrgaskeyringZ +.set PchrgaskeyringZ, 0x107B90E0 +.global end_PchrgaskeyringZ +.set end_PchrgaskeyringZ, 0x107B9FF0 +.global PchrgoldbarZ +.set PchrgoldbarZ, 0x107B9FF0 +.global end_PchrgoldbarZ +.set end_PchrgoldbarZ, 0x107BA160 +.global PchrgoldenZ +.set PchrgoldenZ, 0x107BA160 +.global end_PchrgoldenZ +.set end_PchrgoldenZ, 0x107BA3D0 +.global PchrgoldeneyekeyZ +.set PchrgoldeneyekeyZ, 0x107BA3D0 +.global end_PchrgoldeneyekeyZ +.set end_PchrgoldeneyekeyZ, 0x107BB270 +.global PchrgoldwppkZ +.set PchrgoldwppkZ, 0x107BB270 +.global end_PchrgoldwppkZ +.set end_PchrgoldwppkZ, 0x107BB3E0 +.global PchrgrenadeZ +.set PchrgrenadeZ, 0x107BB3E0 +.global end_PchrgrenadeZ +.set end_PchrgrenadeZ, 0x107BB750 +.global PchrgrenadelaunchZ +.set PchrgrenadelaunchZ, 0x107BB750 +.global end_PchrgrenadelaunchZ +.set end_PchrgrenadelaunchZ, 0x107BBAE0 +.global PchrgrenaderoundZ +.set PchrgrenaderoundZ, 0x107BBAE0 +.global end_PchrgrenaderoundZ +.set end_PchrgrenaderoundZ, 0x107BBD50 +.global PchrheroinZ +.set PchrheroinZ, 0x107BBD50 +.global end_PchrheroinZ +.set end_PchrheroinZ, 0x107BBEC0 +.global PchrkalashZ +.set PchrkalashZ, 0x107BBEC0 +.global end_PchrkalashZ +.set end_PchrkalashZ, 0x107BC2B0 +.global PchrkeyanalysercaseZ +.set PchrkeyanalysercaseZ, 0x107BC2B0 +.global end_PchrkeyanalysercaseZ +.set end_PchrkeyanalysercaseZ, 0x107BC4A0 +.global PchrkeyboltZ +.set PchrkeyboltZ, 0x107BC4A0 +.global end_PchrkeyboltZ +.set end_PchrkeyboltZ, 0x107BD340 +.global PchrkeyyaleZ +.set PchrkeyyaleZ, 0x107BD340 +.global end_PchrkeyyaleZ +.set end_PchrkeyyaleZ, 0x107BE7A0 +.global PchrknifeZ +.set PchrknifeZ, 0x107BE7A0 +.global end_PchrknifeZ +.set end_PchrknifeZ, 0x107BE9A0 +.global PchrlaserZ +.set PchrlaserZ, 0x107BE9A0 +.global end_PchrlaserZ +.set end_PchrlaserZ, 0x107BED60 +.global PchrlectreZ +.set PchrlectreZ, 0x107BED60 +.global end_PchrlectreZ +.set end_PchrlectreZ, 0x107BEED0 +.global PchrlockexploderZ +.set PchrlockexploderZ, 0x107BEED0 +.global end_PchrlockexploderZ +.set end_PchrlockexploderZ, 0x107BF040 +.global Pchrm16Z +.set Pchrm16Z, 0x107BF040 +.global end_Pchrm16Z +.set end_Pchrm16Z, 0x107BF410 +.global PchrmapZ +.set PchrmapZ, 0x107BF410 +.global end_PchrmapZ +.set end_PchrmapZ, 0x107BF560 +.global PchrmicrocameraZ +.set PchrmicrocameraZ, 0x107BF560 +.global end_PchrmicrocameraZ +.set end_PchrmicrocameraZ, 0x107BFE50 +.global PchrmicrocodeZ +.set PchrmicrocodeZ, 0x107BFE50 +.global end_PchrmicrocodeZ +.set end_PchrmicrocodeZ, 0x107BFFC0 +.global PchrmicrofilmZ +.set PchrmicrofilmZ, 0x107BFFC0 +.global end_PchrmicrofilmZ +.set end_PchrmicrofilmZ, 0x107C0130 +.global PchrmoneyZ +.set PchrmoneyZ, 0x107C0130 +.global end_PchrmoneyZ +.set end_PchrmoneyZ, 0x107C02A0 +.global Pchrmp5kZ +.set Pchrmp5kZ, 0x107C02A0 +.global end_Pchrmp5kZ +.set end_Pchrmp5kZ, 0x107C0620 +.global Pchrmp5ksilZ +.set Pchrmp5ksilZ, 0x107C0620 +.global end_Pchrmp5ksilZ +.set end_Pchrmp5ksilZ, 0x107C0A30 +.global PchrpitongunZ +.set PchrpitongunZ, 0x107C0A30 +.global end_PchrpitongunZ +.set end_PchrpitongunZ, 0x107C0BA0 +.global PchrplansZ +.set PchrplansZ, 0x107C0BA0 +.global end_PchrplansZ +.set end_PchrplansZ, 0x107C0E30 +.global PchrplastiqueZ +.set PchrplastiqueZ, 0x107C0E30 +.global end_PchrplastiqueZ +.set end_PchrplastiqueZ, 0x107C1290 +.global PchrpolarizedglassesZ +.set PchrpolarizedglassesZ, 0x107C1290 +.global end_PchrpolarizedglassesZ +.set end_PchrpolarizedglassesZ, 0x107C1B50 +.global PchrproximitymineZ +.set PchrproximitymineZ, 0x107C1B50 +.global end_PchrproximitymineZ +.set end_PchrproximitymineZ, 0x107C1FB0 +.global PchrremotemineZ +.set PchrremotemineZ, 0x107C1FB0 +.global end_PchrremotemineZ +.set end_PchrremotemineZ, 0x107C2410 +.global PchrrocketZ +.set PchrrocketZ, 0x107C2410 +.global end_PchrrocketZ +.set end_PchrrocketZ, 0x107C29C0 +.global PchrrocketlaunchZ +.set PchrrocketlaunchZ, 0x107C29C0 +.global end_PchrrocketlaunchZ +.set end_PchrrocketlaunchZ, 0x107C2DA0 +.global PchrrugerZ +.set PchrrugerZ, 0x107C2DA0 +.global end_PchrrugerZ +.set end_PchrrugerZ, 0x107C3180 +.global PchrsafecrackercaseZ +.set PchrsafecrackercaseZ, 0x107C3180 +.global end_PchrsafecrackercaseZ +.set end_PchrsafecrackercaseZ, 0x107C3370 +.global PchrshotgunZ +.set PchrshotgunZ, 0x107C3370 +.global end_PchrshotgunZ +.set end_PchrshotgunZ, 0x107C36C0 +.global PchrsilverwppkZ +.set PchrsilverwppkZ, 0x107C36C0 +.global end_PchrsilverwppkZ +.set end_PchrsilverwppkZ, 0x107C3830 +.global PchrskorpionZ +.set PchrskorpionZ, 0x107C3830 +.global end_PchrskorpionZ +.set end_PchrskorpionZ, 0x107C3BB0 +.global PchrsniperrifleZ +.set PchrsniperrifleZ, 0x107C3BB0 +.global end_PchrsniperrifleZ +.set end_PchrsniperrifleZ, 0x107C3F40 +.global PchrspectreZ +.set PchrspectreZ, 0x107C3F40 +.global end_PchrspectreZ +.set end_PchrspectreZ, 0x107C42B0 +.global PchrspooltapeZ +.set PchrspooltapeZ, 0x107C42B0 +.global end_PchrspooltapeZ +.set end_PchrspooltapeZ, 0x107C4420 +.global PchrspyfileZ +.set PchrspyfileZ, 0x107C4420 +.global end_PchrspyfileZ +.set end_PchrspyfileZ, 0x107C4590 +.global PchrstafflistZ +.set PchrstafflistZ, 0x107C4590 +.global end_PchrstafflistZ +.set end_PchrstafflistZ, 0x107C47B0 +.global PchrtesttubeZ +.set PchrtesttubeZ, 0x107C47B0 +.global end_PchrtesttubeZ +.set end_PchrtesttubeZ, 0x107C4970 +.global PchrthrowknifeZ +.set PchrthrowknifeZ, 0x107C4970 +.global end_PchrthrowknifeZ +.set end_PchrthrowknifeZ, 0x107C4B90 +.global PchrtimedmineZ +.set PchrtimedmineZ, 0x107C4B90 +.global end_PchrtimedmineZ +.set end_PchrtimedmineZ, 0x107C50C0 +.global Pchrtt33Z +.set Pchrtt33Z, 0x107C50C0 +.global end_Pchrtt33Z +.set end_Pchrtt33Z, 0x107C5350 +.global PchruziZ +.set PchruziZ, 0x107C5350 +.global end_PchruziZ +.set end_PchruziZ, 0x107C5620 +.global PchrvideotapeZ +.set PchrvideotapeZ, 0x107C5620 +.global end_PchrvideotapeZ +.set end_PchrvideotapeZ, 0x107C58F0 +.global PchrweaponcaseZ +.set PchrweaponcaseZ, 0x107C58F0 +.global end_PchrweaponcaseZ +.set end_PchrweaponcaseZ, 0x107C5AF0 +.global PchrwppkZ +.set PchrwppkZ, 0x107C5AF0 +.global end_PchrwppkZ +.set end_PchrwppkZ, 0x107C5D30 +.global PchrwppksilZ +.set PchrwppksilZ, 0x107C5D30 +.global end_PchrwppksilZ +.set end_PchrwppksilZ, 0x107C6010 +.global PchrwristdartZ +.set PchrwristdartZ, 0x107C6010 +.global end_PchrwristdartZ +.set end_PchrwristdartZ, 0x107C6180 +.global Pconsole1Z +.set Pconsole1Z, 0x107C6180 +.global end_Pconsole1Z +.set end_Pconsole1Z, 0x107C6800 +.global Pconsole2Z +.set Pconsole2Z, 0x107C6800 +.global end_Pconsole2Z +.set end_Pconsole2Z, 0x107C6E80 +.global Pconsole3Z +.set Pconsole3Z, 0x107C6E80 +.global end_Pconsole3Z +.set end_Pconsole3Z, 0x107C7510 +.global Pconsole_sev2aZ +.set Pconsole_sev2aZ, 0x107C7510 +.global end_Pconsole_sev2aZ +.set end_Pconsole_sev2aZ, 0x107C7930 +.global Pconsole_sev2bZ +.set Pconsole_sev2bZ, 0x107C7930 +.global end_Pconsole_sev2bZ +.set end_Pconsole_sev2bZ, 0x107C7DF0 +.global Pconsole_sev2cZ +.set Pconsole_sev2cZ, 0x107C7DF0 +.global end_Pconsole_sev2cZ +.set end_Pconsole_sev2cZ, 0x107C8230 +.global Pconsole_sev2dZ +.set Pconsole_sev2dZ, 0x107C8230 +.global end_Pconsole_sev2dZ +.set end_Pconsole_sev2dZ, 0x107C8660 +.global Pconsole_sev_GEaZ +.set Pconsole_sev_GEaZ, 0x107C8660 +.global end_Pconsole_sev_GEaZ +.set end_Pconsole_sev_GEaZ, 0x107C8A90 +.global Pconsole_sev_GEbZ +.set Pconsole_sev_GEbZ, 0x107C8A90 +.global end_Pconsole_sev_GEbZ +.set end_Pconsole_sev_GEbZ, 0x107C8EC0 +.global Pconsole_sevaZ +.set Pconsole_sevaZ, 0x107C8EC0 +.global end_Pconsole_sevaZ +.set end_Pconsole_sevaZ, 0x107C9340 +.global Pconsole_sevbZ +.set Pconsole_sevbZ, 0x107C9340 +.global end_Pconsole_sevbZ +.set end_Pconsole_sevbZ, 0x107C97B0 +.global Pconsole_sevcZ +.set Pconsole_sevcZ, 0x107C97B0 +.global end_Pconsole_sevcZ +.set end_Pconsole_sevcZ, 0x107C9BE0 +.global Pconsole_sevdZ +.set Pconsole_sevdZ, 0x107C9BE0 +.global end_Pconsole_sevdZ +.set end_Pconsole_sevdZ, 0x107CA010 +.global Pcryptdoor1aZ +.set Pcryptdoor1aZ, 0x107CA010 +.global end_Pcryptdoor1aZ +.set end_Pcryptdoor1aZ, 0x107CA1A0 +.global Pcryptdoor1bZ +.set Pcryptdoor1bZ, 0x107CA1A0 +.global end_Pcryptdoor1bZ +.set end_Pcryptdoor1bZ, 0x107CA330 +.global Pcryptdoor2aZ +.set Pcryptdoor2aZ, 0x107CA330 +.global end_Pcryptdoor2aZ +.set end_Pcryptdoor2aZ, 0x107CA4C0 +.global Pcryptdoor2bZ +.set Pcryptdoor2bZ, 0x107CA4C0 +.global end_Pcryptdoor2bZ +.set end_Pcryptdoor2bZ, 0x107CA650 +.global Pcryptdoor3Z +.set Pcryptdoor3Z, 0x107CA650 +.global end_Pcryptdoor3Z +.set end_Pcryptdoor3Z, 0x107CA8C0 +.global Pcryptdoor4Z +.set Pcryptdoor4Z, 0x107CA8C0 +.global end_Pcryptdoor4Z +.set end_Pcryptdoor4Z, 0x107CAA40 +.global PdamchaindoorZ +.set PdamchaindoorZ, 0x107CAA40 +.global end_PdamchaindoorZ +.set end_PdamchaindoorZ, 0x107CACC0 +.global PdamgatedoorZ +.set PdamgatedoorZ, 0x107CACC0 +.global end_PdamgatedoorZ +.set end_PdamgatedoorZ, 0x107CAEE0 +.global PdamtundoorZ +.set PdamtundoorZ, 0x107CAEE0 +.global end_PdamtundoorZ +.set end_PdamtundoorZ, 0x107CB250 +.global Pdepot_door_steelZ +.set Pdepot_door_steelZ, 0x107CB250 +.global end_Pdepot_door_steelZ +.set end_Pdepot_door_steelZ, 0x107CB3F0 +.global Pdepot_gate_entryZ +.set Pdepot_gate_entryZ, 0x107CB3F0 +.global end_Pdepot_gate_entryZ +.set end_Pdepot_gate_entryZ, 0x107CB630 +.global Pdesk1Z +.set Pdesk1Z, 0x107CB630 +.global end_Pdesk1Z +.set end_Pdesk1Z, 0x107CB7B0 +.global Pdesk2Z +.set Pdesk2Z, 0x107CB7B0 +.global end_Pdesk2Z +.set end_Pdesk2Z, 0x107CB930 +.global Pdesk_arecibo1Z +.set Pdesk_arecibo1Z, 0x107CB930 +.global end_Pdesk_arecibo1Z +.set end_Pdesk_arecibo1Z, 0x107CBB70 +.global Pdesk_lamp2Z +.set Pdesk_lamp2Z, 0x107CBB70 +.global end_Pdesk_lamp2Z +.set end_Pdesk_lamp2Z, 0x107CBE70 +.global Pdest_engineZ +.set Pdest_engineZ, 0x107CBE70 +.global end_Pdest_engineZ +.set end_Pdest_engineZ, 0x107CD760 +.global Pdest_exocetZ +.set Pdest_exocetZ, 0x107CD760 +.global end_Pdest_exocetZ +.set end_Pdest_exocetZ, 0x107CDDC0 +.global Pdest_gunZ +.set Pdest_gunZ, 0x107CDDC0 +.global end_Pdest_gunZ +.set end_Pdest_gunZ, 0x107CE430 +.global Pdest_harpoonZ +.set Pdest_harpoonZ, 0x107CE430 +.global end_Pdest_harpoonZ +.set end_Pdest_harpoonZ, 0x107CECD0 +.global Pdest_seawolfZ +.set Pdest_seawolfZ, 0x107CECD0 +.global end_Pdest_seawolfZ +.set end_Pdest_seawolfZ, 0x107CFC80 +.global Pdisc_readerZ +.set Pdisc_readerZ, 0x107CFC80 +.global end_Pdisc_readerZ +.set end_Pdisc_readerZ, 0x107CFE40 +.global Pdisk_drive1Z +.set Pdisk_drive1Z, 0x107CFE40 +.global end_Pdisk_drive1Z +.set end_Pdisk_drive1Z, 0x107CFFD0 +.global Pdoor_azt_chairZ +.set Pdoor_azt_chairZ, 0x107CFFD0 +.global end_Pdoor_azt_chairZ +.set end_Pdoor_azt_chairZ, 0x107D0150 +.global Pdoor_azt_deskZ +.set Pdoor_azt_deskZ, 0x107D0150 +.global end_Pdoor_azt_deskZ +.set end_Pdoor_azt_deskZ, 0x107D0590 +.global Pdoor_azt_desk_topZ +.set Pdoor_azt_desk_topZ, 0x107D0590 +.global end_Pdoor_azt_desk_topZ +.set end_Pdoor_azt_desk_topZ, 0x107D0920 +.global Pdoor_aztecZ +.set Pdoor_aztecZ, 0x107D0920 +.global end_Pdoor_aztecZ +.set end_Pdoor_aztecZ, 0x107D0B50 +.global Pdoor_dest1Z +.set Pdoor_dest1Z, 0x107D0B50 +.global end_Pdoor_dest1Z +.set end_Pdoor_dest1Z, 0x107D0E50 +.global Pdoor_dest2Z +.set Pdoor_dest2Z, 0x107D0E50 +.global end_Pdoor_dest2Z +.set end_Pdoor_dest2Z, 0x107D1210 +.global Pdoor_eyelidZ +.set Pdoor_eyelidZ, 0x107D1210 +.global end_Pdoor_eyelidZ +.set end_Pdoor_eyelidZ, 0x107D1770 +.global Pdoor_irisZ +.set Pdoor_irisZ, 0x107D1770 +.global end_Pdoor_irisZ +.set end_Pdoor_irisZ, 0x107D21C0 +.global Pdoor_mfZ +.set Pdoor_mfZ, 0x107D21C0 +.global end_Pdoor_mfZ +.set end_Pdoor_mfZ, 0x107D24B0 +.global Pdoor_roller1Z +.set Pdoor_roller1Z, 0x107D24B0 +.global end_Pdoor_roller1Z +.set end_Pdoor_roller1Z, 0x107D2820 +.global Pdoor_roller2Z +.set Pdoor_roller2Z, 0x107D2820 +.global end_Pdoor_roller2Z +.set end_Pdoor_roller2Z, 0x107D2A60 +.global Pdoor_roller3Z +.set Pdoor_roller3Z, 0x107D2A60 +.global end_Pdoor_roller3Z +.set end_Pdoor_roller3Z, 0x107D2CA0 +.global Pdoor_roller4Z +.set Pdoor_roller4Z, 0x107D2CA0 +.global end_Pdoor_roller4Z +.set end_Pdoor_roller4Z, 0x107D2F00 +.global Pdoor_rollertrainZ +.set Pdoor_rollertrainZ, 0x107D2F00 +.global end_Pdoor_rollertrainZ +.set end_Pdoor_rollertrainZ, 0x107D3030 +.global Pdoor_st_arec1Z +.set Pdoor_st_arec1Z, 0x107D3030 +.global end_Pdoor_st_arec1Z +.set end_Pdoor_st_arec1Z, 0x107D3290 +.global Pdoor_st_arec2Z +.set Pdoor_st_arec2Z, 0x107D3290 +.global end_Pdoor_st_arec2Z +.set end_Pdoor_st_arec2Z, 0x107D3570 +.global Pdoor_winZ +.set Pdoor_winZ, 0x107D3570 +.global end_Pdoor_winZ +.set end_Pdoor_winZ, 0x107D3710 +.global PdoorconsoleZ +.set PdoorconsoleZ, 0x107D3710 +.global end_PdoorconsoleZ +.set end_PdoorconsoleZ, 0x107D3B80 +.global PdoorpanelZ +.set PdoorpanelZ, 0x107D3B80 +.global end_PdoorpanelZ +.set end_PdoorpanelZ, 0x107D3EF0 +.global Pdoorprison1Z +.set Pdoorprison1Z, 0x107D3EF0 +.global end_Pdoorprison1Z +.set end_Pdoorprison1Z, 0x107D4040 +.global PdoorstatgateZ +.set PdoorstatgateZ, 0x107D4040 +.global end_PdoorstatgateZ +.set end_PdoorstatgateZ, 0x107D4240 +.global PexplosionbitZ +.set PexplosionbitZ, 0x107D4240 +.global end_PexplosionbitZ +.set end_PexplosionbitZ, 0x107D4360 +.global Pfiling_cabinet1Z +.set Pfiling_cabinet1Z, 0x107D4360 +.global end_Pfiling_cabinet1Z +.set end_Pfiling_cabinet1Z, 0x107D44E0 +.global PflagZ +.set PflagZ, 0x107D44E0 +.global end_PflagZ +.set end_PflagZ, 0x107D4610 +.global PfloppyZ +.set PfloppyZ, 0x107D4610 +.global end_PfloppyZ +.set end_PfloppyZ, 0x107D4930 +.global Pfnp90magZ +.set Pfnp90magZ, 0x107D4930 +.global end_Pfnp90magZ +.set end_Pfnp90magZ, 0x107D4AD0 +.global Pgas_plant_met1_do1Z +.set Pgas_plant_met1_do1Z, 0x107D4AD0 +.global end_Pgas_plant_met1_do1Z +.set end_Pgas_plant_met1_do1Z, 0x107D4E50 +.global Pgas_plant_sw2_do1Z +.set Pgas_plant_sw2_do1Z, 0x107D4E50 +.global end_Pgas_plant_sw2_do1Z +.set end_Pgas_plant_sw2_do1Z, 0x107D5030 +.global Pgas_plant_sw3_do1Z +.set Pgas_plant_sw3_do1Z, 0x107D5030 +.global end_Pgas_plant_sw3_do1Z +.set end_Pgas_plant_sw3_do1Z, 0x107D5230 +.global Pgas_plant_sw4_do1Z +.set Pgas_plant_sw4_do1Z, 0x107D5230 +.global end_Pgas_plant_sw4_do1Z +.set end_Pgas_plant_sw4_do1Z, 0x107D5390 +.global Pgas_plant_sw_do1Z +.set Pgas_plant_sw_do1Z, 0x107D5390 +.global end_Pgas_plant_sw_do1Z +.set end_Pgas_plant_sw_do1Z, 0x107D5620 +.global Pgas_plant_wc_cub1Z +.set Pgas_plant_wc_cub1Z, 0x107D5620 +.global end_Pgas_plant_wc_cub1Z +.set end_Pgas_plant_wc_cub1Z, 0x107D5830 +.global PgasbarrelZ +.set PgasbarrelZ, 0x107D5830 +.global end_PgasbarrelZ +.set end_PgasbarrelZ, 0x107D5A40 +.global PgasbarrelsZ +.set PgasbarrelsZ, 0x107D5A40 +.global end_PgasbarrelsZ +.set end_PgasbarrelsZ, 0x107D5F80 +.global Pgasplant_clear_doorZ +.set Pgasplant_clear_doorZ, 0x107D5F80 +.global end_Pgasplant_clear_doorZ +.set end_Pgasplant_clear_doorZ, 0x107D64E0 +.global PgastankZ +.set PgastankZ, 0x107D64E0 +.global end_PgastankZ +.set end_PgastankZ, 0x107D6A90 +.global Pglassware1Z +.set Pglassware1Z, 0x107D6A90 +.global end_Pglassware1Z +.set end_Pglassware1Z, 0x107D6BF0 +.global Pglassware2Z +.set Pglassware2Z, 0x107D6BF0 +.global end_Pglassware2Z +.set end_Pglassware2Z, 0x107D6E80 +.global Pglassware3Z +.set Pglassware3Z, 0x107D6E80 +.global end_Pglassware3Z +.set end_Pglassware3Z, 0x107D7090 +.global Pglassware4Z +.set Pglassware4Z, 0x107D7090 +.global end_Pglassware4Z +.set end_Pglassware4Z, 0x107D7610 +.global PgoldeneyelogoZ +.set PgoldeneyelogoZ, 0x107D7610 +.global end_PgoldeneyelogoZ +.set end_PgoldeneyelogoZ, 0x107D84C0 +.global PgoldenshellsZ +.set PgoldenshellsZ, 0x107D84C0 +.global end_PgoldenshellsZ +.set end_PgoldenshellsZ, 0x107D86C0 +.global PgroundgunZ +.set PgroundgunZ, 0x107D86C0 +.global end_PgroundgunZ +.set end_PgroundgunZ, 0x107D8E90 +.global Pgun_runway1Z +.set Pgun_runway1Z, 0x107D8E90 +.global end_Pgun_runway1Z +.set end_Pgun_runway1Z, 0x107D95D0 +.global PhatberetZ +.set PhatberetZ, 0x107D95D0 +.global end_PhatberetZ +.set end_PhatberetZ, 0x107D9870 +.global PhatberetblueZ +.set PhatberetblueZ, 0x107D9870 +.global end_PhatberetblueZ +.set end_PhatberetblueZ, 0x107D9B40 +.global PhatberetredZ +.set PhatberetredZ, 0x107D9B40 +.global end_PhatberetredZ +.set end_PhatberetredZ, 0x107D9E20 +.global PhatchboltZ +.set PhatchboltZ, 0x107D9E20 +.global end_PhatchboltZ +.set end_PhatchboltZ, 0x107D9EF0 +.global PhatchdoorZ +.set PhatchdoorZ, 0x107D9EF0 +.global end_PhatchdoorZ +.set end_PhatchdoorZ, 0x107DA110 +.global PhatchsevxZ +.set PhatchsevxZ, 0x107DA110 +.global end_PhatchsevxZ +.set end_PhatchsevxZ, 0x107DA280 +.global PhatfurryZ +.set PhatfurryZ, 0x107DA280 +.global end_PhatfurryZ +.set end_PhatfurryZ, 0x107DA4B0 +.global PhatfurryblackZ +.set PhatfurryblackZ, 0x107DA4B0 +.global end_PhatfurryblackZ +.set end_PhatfurryblackZ, 0x107DA6D0 +.global PhatfurrybrownZ +.set PhatfurrybrownZ, 0x107DA6D0 +.global end_PhatfurrybrownZ +.set end_PhatfurrybrownZ, 0x107DA8E0 +.global PhathelmetZ +.set PhathelmetZ, 0x107DA8E0 +.global end_PhathelmetZ +.set end_PhathelmetZ, 0x107DAB10 +.global PhathelmetgreyZ +.set PhathelmetgreyZ, 0x107DAB10 +.global end_PhathelmetgreyZ +.set end_PhathelmetgreyZ, 0x107DAD40 +.global PhatmoonZ +.set PhatmoonZ, 0x107DAD40 +.global end_PhatmoonZ +.set end_PhatmoonZ, 0x107DB120 +.global PhatpeakedZ +.set PhatpeakedZ, 0x107DB120 +.global end_PhatpeakedZ +.set end_PhatpeakedZ, 0x107DB430 +.global PhattbirdZ +.set PhattbirdZ, 0x107DB430 +.global end_PhattbirdZ +.set end_PhattbirdZ, 0x107DB680 +.global PhattbirdbrownZ +.set PhattbirdbrownZ, 0x107DB680 +.global end_PhattbirdbrownZ +.set end_PhattbirdbrownZ, 0x107DB8F0 +.global PhelicopterZ +.set PhelicopterZ, 0x107DB8F0 +.global end_PhelicopterZ +.set end_PhelicopterZ, 0x107DFB10 +.global PhindZ +.set PhindZ, 0x107DFB10 +.global end_PhindZ +.set end_PhindZ, 0x107E1280 +.global PjeepZ +.set PjeepZ, 0x107E1280 +.global end_PjeepZ +.set end_PjeepZ, 0x107E23E0 +.global Pjerry_can1Z +.set Pjerry_can1Z, 0x107E23E0 +.global end_Pjerry_can1Z +.set end_Pjerry_can1Z, 0x107E2640 +.global Pjungle3_treeZ +.set Pjungle3_treeZ, 0x107E2640 +.global end_Pjungle3_treeZ +.set end_Pjungle3_treeZ, 0x107E2DC0 +.global Pjungle5_treeZ +.set Pjungle5_treeZ, 0x107E2DC0 +.global end_Pjungle5_treeZ +.set end_Pjungle5_treeZ, 0x107E32F0 +.global Pkey_holderZ +.set Pkey_holderZ, 0x107E32F0 +.global end_Pkey_holderZ +.set end_Pkey_holderZ, 0x107E3640 +.global Pkeyboard1Z +.set Pkeyboard1Z, 0x107E3640 +.global end_Pkeyboard1Z +.set end_Pkeyboard1Z, 0x107E37B0 +.global Pkit_units1Z +.set Pkit_units1Z, 0x107E37B0 +.global end_Pkit_units1Z +.set end_Pkit_units1Z, 0x107E3A50 +.global PlabbenchZ +.set PlabbenchZ, 0x107E3A50 +.global end_PlabbenchZ +.set end_PlabbenchZ, 0x107E3E20 +.global PlandmineZ +.set PlandmineZ, 0x107E3E20 +.global end_PlandmineZ +.set end_PlandmineZ, 0x107E4090 +.global PlegalpageZ +.set PlegalpageZ, 0x107E4090 +.global end_PlegalpageZ +.set end_PlegalpageZ, 0x107E5050 +.global Pletter_tray1Z +.set Pletter_tray1Z, 0x107E5050 +.global end_Pletter_tray1Z +.set end_Pletter_tray1Z, 0x107E51B0 +.global Plocker3Z +.set Plocker3Z, 0x107E51B0 +.global end_Plocker3Z +.set end_Plocker3Z, 0x107E5340 +.global Plocker4Z +.set Plocker4Z, 0x107E5340 +.global end_Plocker4Z +.set end_Plocker4Z, 0x107E54D0 +.global Pm16magZ +.set Pm16magZ, 0x107E54D0 +.global end_Pm16magZ +.set end_Pm16magZ, 0x107E5610 +.global PmagnumshellsZ +.set PmagnumshellsZ, 0x107E5610 +.global end_PmagnumshellsZ +.set end_PmagnumshellsZ, 0x107E5810 +.global Pmainframe1Z +.set Pmainframe1Z, 0x107E5810 +.global end_Pmainframe1Z +.set end_Pmainframe1Z, 0x107E5B10 +.global Pmainframe2Z +.set Pmainframe2Z, 0x107E5B10 +.global end_Pmainframe2Z +.set end_Pmainframe2Z, 0x107E5DE0 +.global Pmetal_chair1Z +.set Pmetal_chair1Z, 0x107E5DE0 +.global end_Pmetal_chair1Z +.set end_Pmetal_chair1Z, 0x107E6120 +.global Pmetal_crate1Z +.set Pmetal_crate1Z, 0x107E6120 +.global end_Pmetal_crate1Z +.set end_Pmetal_crate1Z, 0x107E62E0 +.global Pmetal_crate2Z +.set Pmetal_crate2Z, 0x107E62E0 +.global end_Pmetal_crate2Z +.set end_Pmetal_crate2Z, 0x107E64A0 +.global Pmetal_crate3Z +.set Pmetal_crate3Z, 0x107E64A0 +.global end_Pmetal_crate3Z +.set end_Pmetal_crate3Z, 0x107E6660 +.global Pmetal_crate4Z +.set Pmetal_crate4Z, 0x107E6660 +.global end_Pmetal_crate4Z +.set end_Pmetal_crate4Z, 0x107E6820 +.global PmilcopterZ +.set PmilcopterZ, 0x107E6820 +.global end_PmilcopterZ +.set end_PmilcopterZ, 0x107E8100 +.global PmiltruckZ +.set PmiltruckZ, 0x107E8100 +.global end_PmiltruckZ +.set end_PmiltruckZ, 0x107EA400 +.global Pmissile_rack2Z +.set Pmissile_rack2Z, 0x107EA400 +.global end_Pmissile_rack2Z +.set end_Pmissile_rack2Z, 0x107EAE10 +.global Pmissile_rackZ +.set Pmissile_rackZ, 0x107EAE10 +.global end_Pmissile_rackZ +.set end_Pmissile_rackZ, 0x107EB1F0 +.global PmodemboxZ +.set PmodemboxZ, 0x107EB1F0 +.global end_PmodemboxZ +.set end_PmodemboxZ, 0x107EB530 +.global PmotorbikeZ +.set PmotorbikeZ, 0x107EB530 +.global end_PmotorbikeZ +.set end_PmotorbikeZ, 0x107EC3F0 +.global Pmp5kmagZ +.set Pmp5kmagZ, 0x107EC3F0 +.global end_Pmp5kmagZ +.set end_Pmp5kmagZ, 0x107EC540 +.global PnintendologoZ +.set PnintendologoZ, 0x107EC540 +.global end_PnintendologoZ +.set end_PnintendologoZ, 0x107EF020 +.global Poil_drum1Z +.set Poil_drum1Z, 0x107EF020 +.global end_Poil_drum1Z +.set end_Poil_drum1Z, 0x107EF290 +.global Poil_drum2Z +.set Poil_drum2Z, 0x107EF290 +.global end_Poil_drum2Z +.set end_Poil_drum2Z, 0x107EF580 +.global Poil_drum3Z +.set Poil_drum3Z, 0x107EF580 +.global end_Poil_drum3Z +.set end_Poil_drum3Z, 0x107EF870 +.global Poil_drum5Z +.set Poil_drum5Z, 0x107EF870 +.global end_Poil_drum5Z +.set end_Poil_drum5Z, 0x107EFB60 +.global Poil_drum6Z +.set Poil_drum6Z, 0x107EFB60 +.global end_Poil_drum6Z +.set end_Poil_drum6Z, 0x107EFE70 +.global Poil_drum7Z +.set Poil_drum7Z, 0x107EFE70 +.global end_Poil_drum7Z +.set end_Poil_drum7Z, 0x107F0170 +.global PpadlockZ +.set PpadlockZ, 0x107F0170 +.global end_PpadlockZ +.set end_PpadlockZ, 0x107F0BC0 +.global PpalmZ +.set PpalmZ, 0x107F0BC0 +.global end_PpalmZ +.set end_PpalmZ, 0x107F1010 +.global PpalmtreeZ +.set PpalmtreeZ, 0x107F1010 +.global end_PpalmtreeZ +.set end_PpalmtreeZ, 0x107F14E0 +.global Pphone1Z +.set Pphone1Z, 0x107F14E0 +.global end_Pphone1Z +.set end_Pphone1Z, 0x107F1620 +.global PplaneZ +.set PplaneZ, 0x107F1620 +.global end_PplaneZ +.set end_PplaneZ, 0x107F3C00 +.global Pplant11Z +.set Pplant11Z, 0x107F3C00 +.global end_Pplant11Z +.set end_Pplant11Z, 0x107F3FC0 +.global Pplant1Z +.set Pplant1Z, 0x107F3FC0 +.global end_Pplant1Z +.set end_Pplant1Z, 0x107F4350 +.global Pplant2Z +.set Pplant2Z, 0x107F4350 +.global end_Pplant2Z +.set end_Pplant2Z, 0x107F46B0 +.global Pplant2bZ +.set Pplant2bZ, 0x107F46B0 +.global end_Pplant2bZ +.set end_Pplant2bZ, 0x107F4AC0 +.global Pplant3Z +.set Pplant3Z, 0x107F4AC0 +.global end_Pplant3Z +.set end_Pplant3Z, 0x107F4F10 +.global Pradio_unit1Z +.set Pradio_unit1Z, 0x107F4F10 +.global end_Pradio_unit1Z +.set end_Pradio_unit1Z, 0x107F50C0 +.global Pradio_unit2Z +.set Pradio_unit2Z, 0x107F50C0 +.global end_Pradio_unit2Z +.set end_Pradio_unit2Z, 0x107F5280 +.global Pradio_unit3Z +.set Pradio_unit3Z, 0x107F5280 +.global end_Pradio_unit3Z +.set end_Pradio_unit3Z, 0x107F5440 +.global Pradio_unit4Z +.set Pradio_unit4Z, 0x107F5440 +.global end_Pradio_unit4Z +.set end_Pradio_unit4Z, 0x107F5600 +.global ProofgunZ +.set ProofgunZ, 0x107F5600 +.global end_ProofgunZ +.set end_ProofgunZ, 0x107F5C60 +.global PsafeZ +.set PsafeZ, 0x107F5C60 +.global end_PsafeZ +.set end_PsafeZ, 0x107F5FB0 +.global PsafedoorZ +.set PsafedoorZ, 0x107F5FB0 +.global end_PsafedoorZ +.set end_PsafedoorZ, 0x107F64A0 +.global Psat1_reflectZ +.set Psat1_reflectZ, 0x107F64A0 +.global end_Psat1_reflectZ +.set end_Psat1_reflectZ, 0x107F7A10 +.global PsatboxZ +.set PsatboxZ, 0x107F7A10 +.global end_PsatboxZ +.set end_PsatboxZ, 0x107F7B30 +.global PsatdishZ +.set PsatdishZ, 0x107F7B30 +.global end_PsatdishZ +.set end_PsatdishZ, 0x107F7F90 +.global Psec_panelZ +.set Psec_panelZ, 0x107F7F90 +.global end_Psec_panelZ +.set end_Psec_panelZ, 0x107F8130 +.global Psev_door3Z +.set Psev_door3Z, 0x107F8130 +.global end_Psev_door3Z +.set end_Psev_door3Z, 0x107F83C0 +.global Psev_door3_windZ +.set Psev_door3_windZ, 0x107F83C0 +.global end_Psev_door3_windZ +.set end_Psev_door3_windZ, 0x107F8750 +.global Psev_door4_windZ +.set Psev_door4_windZ, 0x107F8750 +.global end_Psev_door4_windZ +.set end_Psev_door4_windZ, 0x107F8B30 +.global Psev_doorZ +.set Psev_doorZ, 0x107F8B30 +.global end_Psev_doorZ +.set end_Psev_doorZ, 0x107F8E80 +.global Psev_door_v1Z +.set Psev_door_v1Z, 0x107F8E80 +.global end_Psev_door_v1Z +.set end_Psev_door_v1Z, 0x107F91B0 +.global Psev_trislideZ +.set Psev_trislideZ, 0x107F91B0 +.global end_Psev_trislideZ +.set end_Psev_trislideZ, 0x107F9560 +.global PsevdishZ +.set PsevdishZ, 0x107F9560 +.global end_PsevdishZ +.set end_PsevdishZ, 0x107FA480 +.global PsevdoormetslideZ +.set PsevdoormetslideZ, 0x107FA480 +.global end_PsevdoormetslideZ +.set end_PsevdoormetslideZ, 0x107FA760 +.global PsevdoornowindZ +.set PsevdoornowindZ, 0x107FA760 +.global end_PsevdoornowindZ +.set end_PsevdoornowindZ, 0x107FA8D0 +.global PsevdoorwindZ +.set PsevdoorwindZ, 0x107FA8D0 +.global end_PsevdoorwindZ +.set end_PsevdoorwindZ, 0x107FAD00 +.global PsevdoorwoodZ +.set PsevdoorwoodZ, 0x107FAD00 +.global end_PsevdoorwoodZ +.set end_PsevdoorwoodZ, 0x107FB0B0 +.global PshuttleZ +.set PshuttleZ, 0x107FB0B0 +.global end_PshuttleZ +.set end_PshuttleZ, 0x107FDAB0 +.global Pshuttle_door_lZ +.set Pshuttle_door_lZ, 0x107FDAB0 +.global end_Pshuttle_door_lZ +.set end_Pshuttle_door_lZ, 0x107FE6E0 +.global Pshuttle_door_rZ +.set Pshuttle_door_rZ, 0x107FE6E0 +.global end_Pshuttle_door_rZ +.set end_Pshuttle_door_rZ, 0x107FF3E0 +.global PsilencerZ +.set PsilencerZ, 0x107FF3E0 +.global end_PsilencerZ +.set end_PsilencerZ, 0x107FF580 +.global Psilo_lift_doorZ +.set Psilo_lift_doorZ, 0x107FF580 +.global end_Psilo_lift_doorZ +.set end_Psilo_lift_doorZ, 0x107FF7C0 +.global PsilotopdoorZ +.set PsilotopdoorZ, 0x107FF7C0 +.global end_PsilotopdoorZ +.set end_PsilotopdoorZ, 0x107FFAB0 +.global PskorpionmagZ +.set PskorpionmagZ, 0x107FFAB0 +.global end_PskorpionmagZ +.set end_PskorpionmagZ, 0x107FFC10 +.global PspectremagZ +.set PspectremagZ, 0x107FFC10 +.global end_PspectremagZ +.set end_PspectremagZ, 0x107FFD80 +.global PspeedboatZ +.set PspeedboatZ, 0x107FFD80 +.global end_PspeedboatZ +.set end_PspeedboatZ, 0x10800AC0 +.global Pst_pete_room_1iZ +.set Pst_pete_room_1iZ, 0x10800AC0 +.global end_Pst_pete_room_1iZ +.set end_Pst_pete_room_1iZ, 0x10803C00 +.global Pst_pete_room_2iZ +.set Pst_pete_room_2iZ, 0x10803C00 +.global end_Pst_pete_room_2iZ +.set end_Pst_pete_room_2iZ, 0x10806DE0 +.global Pst_pete_room_3tZ +.set Pst_pete_room_3tZ, 0x10806DE0 +.global end_Pst_pete_room_3tZ +.set end_Pst_pete_room_3tZ, 0x10809D20 +.global Pst_pete_room_5cZ +.set Pst_pete_room_5cZ, 0x10809D20 +.global end_Pst_pete_room_5cZ +.set end_Pst_pete_room_5cZ, 0x1080D2B0 +.global Pst_pete_room_6cZ +.set Pst_pete_room_6cZ, 0x1080D2B0 +.global end_Pst_pete_room_6cZ +.set end_Pst_pete_room_6cZ, 0x108106C0 +.global Psteel_door1Z +.set Psteel_door1Z, 0x108106C0 +.global end_Psteel_door1Z +.set end_Psteel_door1Z, 0x10810930 +.global Psteel_door2Z +.set Psteel_door2Z, 0x10810930 +.global end_Psteel_door2Z +.set end_Psteel_door2Z, 0x10810BE0 +.global Psteel_door2bZ +.set Psteel_door2bZ, 0x10810BE0 +.global end_Psteel_door2bZ +.set end_Psteel_door2bZ, 0x10810EB0 +.global Psteel_door3Z +.set Psteel_door3Z, 0x10810EB0 +.global end_Psteel_door3Z +.set end_Psteel_door3Z, 0x10811180 +.global Pstool1Z +.set Pstool1Z, 0x10811180 +.global end_Pstool1Z +.set end_Pstool1Z, 0x10811440 +.global Pswipe_card2Z +.set Pswipe_card2Z, 0x10811440 +.global end_Pswipe_card2Z +.set end_Pswipe_card2Z, 0x108115D0 +.global Pswivel_chair1Z +.set Pswivel_chair1Z, 0x108115D0 +.global end_Pswivel_chair1Z +.set end_Pswivel_chair1Z, 0x10811860 +.global PtankZ +.set PtankZ, 0x10811860 +.global end_PtankZ +.set end_PtankZ, 0x10813300 +.global PtigerZ +.set PtigerZ, 0x10813300 +.global end_PtigerZ +.set end_PtigerZ, 0x10815190 +.global Ptorpedo_rackZ +.set Ptorpedo_rackZ, 0x10815190 +.global end_Ptorpedo_rackZ +.set end_Ptorpedo_rackZ, 0x10815A10 +.global Ptrain_door2Z +.set Ptrain_door2Z, 0x10815A10 +.global end_Ptrain_door2Z +.set end_Ptrain_door2Z, 0x10815DE0 +.global Ptrain_door3Z +.set Ptrain_door3Z, 0x10815DE0 +.global end_Ptrain_door3Z +.set end_Ptrain_door3Z, 0x10816200 +.global Ptrain_doorZ +.set Ptrain_doorZ, 0x10816200 +.global end_Ptrain_doorZ +.set end_Ptrain_doorZ, 0x10816470 +.global PtrainextdoorZ +.set PtrainextdoorZ, 0x10816470 +.global end_PtrainextdoorZ +.set end_PtrainextdoorZ, 0x108167B0 +.global Ptt33magZ +.set Ptt33magZ, 0x108167B0 +.global end_Ptt33magZ +.set end_Ptt33magZ, 0x108168F0 +.global Ptuning_console1Z +.set Ptuning_console1Z, 0x108168F0 +.global end_Ptuning_console1Z +.set end_Ptuning_console1Z, 0x10816E10 +.global Ptv1Z +.set Ptv1Z, 0x10816E10 +.global end_Ptv1Z +.set end_Ptv1Z, 0x10816FE0 +.global Ptv4screenZ +.set Ptv4screenZ, 0x10816FE0 +.global end_Ptv4screenZ +.set end_Ptv4screenZ, 0x10817180 +.global Ptv_holderZ +.set Ptv_holderZ, 0x10817180 +.global end_Ptv_holderZ +.set end_Ptv_holderZ, 0x10817850 +.global PtvscreenZ +.set PtvscreenZ, 0x10817850 +.global end_PtvscreenZ +.set end_PtvscreenZ, 0x10817920 +.global PuzimagZ +.set PuzimagZ, 0x10817920 +.global end_PuzimagZ +.set end_PuzimagZ, 0x10817A60 +.global PvertdoorZ +.set PvertdoorZ, 0x10817A60 +.global end_PvertdoorZ +.set end_PvertdoorZ, 0x10818070 +.global PwalletbondZ +.set PwalletbondZ, 0x10818070 +.global end_PwalletbondZ +.set end_PwalletbondZ, 0x10819620 +.global PwindowZ +.set PwindowZ, 0x10819620 +.global end_PwindowZ +.set end_PwindowZ, 0x10819710 +.global Pwindow_cor11Z +.set Pwindow_cor11Z, 0x10819710 +.global end_Pwindow_cor11Z +.set end_Pwindow_cor11Z, 0x108197F0 +.global Pwindow_lib_lg1Z +.set Pwindow_lib_lg1Z, 0x108197F0 +.global end_Pwindow_lib_lg1Z +.set end_Pwindow_lib_lg1Z, 0x108198D0 +.global Pwindow_lib_sm1Z +.set Pwindow_lib_sm1Z, 0x108198D0 +.global end_Pwindow_lib_sm1Z +.set end_Pwindow_lib_sm1Z, 0x108199C0 +.global Pwood_lg_crate1Z +.set Pwood_lg_crate1Z, 0x108199C0 +.global end_Pwood_lg_crate1Z +.set end_Pwood_lg_crate1Z, 0x10819C40 +.global Pwood_lg_crate2Z +.set Pwood_lg_crate2Z, 0x10819C40 +.global end_Pwood_lg_crate2Z +.set end_Pwood_lg_crate2Z, 0x10819E60 +.global Pwood_md_crate3Z +.set Pwood_md_crate3Z, 0x10819E60 +.global end_Pwood_md_crate3Z +.set end_Pwood_md_crate3Z, 0x1081A080 +.global Pwood_sm_crate4Z +.set Pwood_sm_crate4Z, 0x1081A080 +.global end_Pwood_sm_crate4Z +.set end_Pwood_sm_crate4Z, 0x1081A2E0 +.global Pwood_sm_crate5Z +.set Pwood_sm_crate5Z, 0x1081A2E0 +.global end_Pwood_sm_crate5Z +.set end_Pwood_sm_crate5Z, 0x1081A540 +.global Pwood_sm_crate6Z +.set Pwood_sm_crate6Z, 0x1081A540 +.global end_Pwood_sm_crate6Z +.set end_Pwood_sm_crate6Z, 0x1081A760 +.global Pwooden_table1Z +.set Pwooden_table1Z, 0x1081A760 +.global end_Pwooden_table1Z +.set end_Pwooden_table1Z, 0x1081AAD0 +.global PwppkmagZ +.set PwppkmagZ, 0x1081AAD0 +.global end_PwppkmagZ +.set end_PwppkmagZ, 0x1081AC10 +.global Tbg_ame_all_p_stanZ +.set Tbg_ame_all_p_stanZ, 0x1081AC10 +.global end_Tbg_ame_all_p_stanZ +.set end_Tbg_ame_all_p_stanZ, 0x1081C540 +.global Tbg_arch_all_p_stanZ +.set Tbg_arch_all_p_stanZ, 0x1081C540 +.global end_Tbg_arch_all_p_stanZ +.set end_Tbg_arch_all_p_stanZ, 0x10822230 +.global Tbg_arec_all_p_stanZ +.set Tbg_arec_all_p_stanZ, 0x10822230 +.global end_Tbg_arec_all_p_stanZ +.set end_Tbg_arec_all_p_stanZ, 0x1082A580 +.global Tbg_ark_all_p_stanZ +.set Tbg_ark_all_p_stanZ, 0x1082A580 +.global end_Tbg_ark_all_p_stanZ +.set end_Tbg_ark_all_p_stanZ, 0x10833540 +.global Tbg_ash_all_p_stanZ +.set Tbg_ash_all_p_stanZ, 0x10833540 +.global end_Tbg_ash_all_p_stanZ +.set end_Tbg_ash_all_p_stanZ, 0x10834E70 +.global Tbg_azt_all_p_stanZ +.set Tbg_azt_all_p_stanZ, 0x10834E70 +.global end_Tbg_azt_all_p_stanZ +.set end_Tbg_azt_all_p_stanZ, 0x1083A3F0 +.global Tbg_cat_all_p_stanZ +.set Tbg_cat_all_p_stanZ, 0x1083A3F0 +.global end_Tbg_cat_all_p_stanZ +.set end_Tbg_cat_all_p_stanZ, 0x1083CB20 +.global Tbg_cave_all_p_stanZ +.set Tbg_cave_all_p_stanZ, 0x1083CB20 +.global end_Tbg_cave_all_p_stanZ +.set end_Tbg_cave_all_p_stanZ, 0x10841A10 +.global Tbg_crad_all_p_stanZ +.set Tbg_crad_all_p_stanZ, 0x10841A10 +.global end_Tbg_crad_all_p_stanZ +.set end_Tbg_crad_all_p_stanZ, 0x10844320 +.global Tbg_cryp_all_p_stanZ +.set Tbg_cryp_all_p_stanZ, 0x10844320 +.global end_Tbg_cryp_all_p_stanZ +.set end_Tbg_cryp_all_p_stanZ, 0x10847390 +.global Tbg_dam_all_p_stanZ +.set Tbg_dam_all_p_stanZ, 0x10847390 +.global end_Tbg_dam_all_p_stanZ +.set end_Tbg_dam_all_p_stanZ, 0x10851770 +.global Tbg_depo_all_p_stanZ +.set Tbg_depo_all_p_stanZ, 0x10851770 +.global end_Tbg_depo_all_p_stanZ +.set end_Tbg_depo_all_p_stanZ, 0x108586B0 +.global Tbg_dest_all_p_stanZ +.set Tbg_dest_all_p_stanZ, 0x108586B0 +.global end_Tbg_dest_all_p_stanZ +.set end_Tbg_dest_all_p_stanZ, 0x1085EFA0 +.global Tbg_dish_all_p_stanZ +.set Tbg_dish_all_p_stanZ, 0x1085EFA0 +.global end_Tbg_dish_all_p_stanZ +.set end_Tbg_dish_all_p_stanZ, 0x1085FAB0 +.global Tbg_imp_all_p_stanZ +.set Tbg_imp_all_p_stanZ, 0x1085FAB0 +.global end_Tbg_imp_all_p_stanZ +.set end_Tbg_imp_all_p_stanZ, 0x1085FAB0 +.global Tbg_jun_all_p_stanZ +.set Tbg_jun_all_p_stanZ, 0x108613E0 +.global end_Tbg_jun_all_p_stanZ +.set end_Tbg_jun_all_p_stanZ, 0x10868530 +.global Tbg_len_all_p_stanZ +.set Tbg_len_all_p_stanZ, 0x10868530 +.global end_Tbg_len_all_p_stanZ +.set end_Tbg_len_all_p_stanZ, 0x10868530 +.global Tbg_oat_all_p_stanZ +.set Tbg_oat_all_p_stanZ, 0x10868FF0 +.global end_Tbg_oat_all_p_stanZ +.set end_Tbg_oat_all_p_stanZ, 0x10868FF0 +.global Tbg_pete_all_p_stanZ +.set Tbg_pete_all_p_stanZ, 0x1086A8F0 +.global end_Tbg_pete_all_p_stanZ +.set end_Tbg_pete_all_p_stanZ, 0x1086A8F0 +.global Tbg_ref_all_p_stanZ +.set Tbg_ref_all_p_stanZ, 0x1086EF80 +.global end_Tbg_ref_all_p_stanZ +.set end_Tbg_ref_all_p_stanZ, 0x10870D50 +.global Tbg_run_all_p_stanZ +.set Tbg_run_all_p_stanZ, 0x10870D50 +.global end_Tbg_run_all_p_stanZ +.set end_Tbg_run_all_p_stanZ, 0x10870D50 +.global Tbg_sev_all_p_stanZ +.set Tbg_sev_all_p_stanZ, 0x108727D0 +.global end_Tbg_sev_all_p_stanZ +.set end_Tbg_sev_all_p_stanZ, 0x108765A0 +.global Tbg_sevb_all_p_stanZ +.set Tbg_sevb_all_p_stanZ, 0x108765A0 +.global end_Tbg_sevb_all_p_stanZ +.set end_Tbg_sevb_all_p_stanZ, 0x1087B4E0 +.global Tbg_sevx_all_p_stanZ +.set Tbg_sevx_all_p_stanZ, 0x1087B4E0 +.global end_Tbg_sevx_all_p_stanZ +.set end_Tbg_sevx_all_p_stanZ, 0x10884810 +.global Tbg_silo_all_p_stanZ +.set Tbg_silo_all_p_stanZ, 0x10884810 +.global end_Tbg_silo_all_p_stanZ +.set end_Tbg_silo_all_p_stanZ, 0x1088D8B0 +.global Tbg_stat_all_p_stanZ +.set Tbg_stat_all_p_stanZ, 0x1088D8B0 +.global end_Tbg_stat_all_p_stanZ +.set end_Tbg_stat_all_p_stanZ, 0x10892770 +.global Tbg_tra_all_p_stanZ +.set Tbg_tra_all_p_stanZ, 0x10892770 +.global end_Tbg_tra_all_p_stanZ +.set end_Tbg_tra_all_p_stanZ, 0x10894B40 +.global UbriefarchZ +.set UbriefarchZ, 0x10894B40 +.global end_UbriefarchZ +.set end_UbriefarchZ, 0x10894B40 +.global UbriefarkZ +.set UbriefarkZ, 0x10894B60 +.global end_UbriefarkZ +.set end_UbriefarkZ, 0x10894B80 +.global UbriefaztZ +.set UbriefaztZ, 0x10894B80 +.global end_UbriefaztZ +.set end_UbriefaztZ, 0x10894BA0 +.global UbriefcaveZ +.set UbriefcaveZ, 0x10894BA0 +.global end_UbriefcaveZ +.set end_UbriefcaveZ, 0x10894BC0 +.global UbriefcontrolZ +.set UbriefcontrolZ, 0x10894BC0 +.global end_UbriefcontrolZ +.set end_UbriefcontrolZ, 0x10894BE0 +.global UbriefcradZ +.set UbriefcradZ, 0x10894BE0 +.global end_UbriefcradZ +.set end_UbriefcradZ, 0x10894C00 +.global UbriefcrypZ +.set UbriefcrypZ, 0x10894C00 +.global end_UbriefcrypZ +.set end_UbriefcrypZ, 0x10894C20 +.global UbriefdamZ +.set UbriefdamZ, 0x10894C20 +.global end_UbriefdamZ +.set end_UbriefdamZ, 0x10894C40 +.global UbriefdepoZ +.set UbriefdepoZ, 0x10894C40 +.global end_UbriefdepoZ +.set end_UbriefdepoZ, 0x10894C60 +.global UbriefdestZ +.set UbriefdestZ, 0x10894C60 +.global end_UbriefdestZ +.set end_UbriefdestZ, 0x10894C80 +.global UbriefjunZ +.set UbriefjunZ, 0x10894C80 +.global end_UbriefjunZ +.set end_UbriefjunZ, 0x10894CA0 +.global UbriefpeteZ +.set UbriefpeteZ, 0x10894CA0 +.global end_UbriefpeteZ +.set end_UbriefpeteZ, 0x10894CC0 +.global UbriefrunZ +.set UbriefrunZ, 0x10894CC0 +.global end_UbriefrunZ +.set end_UbriefrunZ, 0x10894CE0 +.global UbriefsevbZ +.set UbriefsevbZ, 0x10894CE0 +.global end_UbriefsevbZ +.set end_UbriefsevbZ, 0x10894D00 +.global UbriefsevbunkerZ +.set UbriefsevbunkerZ, 0x10894D00 +.global end_UbriefsevbunkerZ +.set end_UbriefsevbunkerZ, 0x10894D20 +.global UbriefsevxZ +.set UbriefsevxZ, 0x10894D20 +.global end_UbriefsevxZ +.set end_UbriefsevxZ, 0x10894D40 +.global UbriefsevxbZ +.set UbriefsevxbZ, 0x10894D40 +.global end_UbriefsevxbZ +.set end_UbriefsevxbZ, 0x10894D60 +.global UbriefsiloZ +.set UbriefsiloZ, 0x10894D60 +.global end_UbriefsiloZ +.set end_UbriefsiloZ, 0x10894D80 +.global UbriefstatueZ +.set UbriefstatueZ, 0x10894D80 +.global end_UbriefstatueZ +.set end_UbriefstatueZ, 0x10894DA0 +.global UbrieftraZ +.set UbrieftraZ, 0x10894DA0 +.global end_UbrieftraZ +.set end_UbrieftraZ, 0x10894DC0 +.global Ump_setupameZ +.set Ump_setupameZ, 0x10894DC0 +.global end_Ump_setupameZ +.set end_Ump_setupameZ, 0x108954E0 +.global Ump_setuparchZ +.set Ump_setuparchZ, 0x108954E0 +.global end_Ump_setuparchZ +.set end_Ump_setuparchZ, 0x10898280 +.global Ump_setuparkZ +.set Ump_setuparkZ, 0x10898280 +.global end_Ump_setuparkZ +.set end_Ump_setuparkZ, 0x10899FC0 +.global Ump_setupashZ +.set Ump_setupashZ, 0x10899FC0 +.global end_Ump_setupashZ +.set end_Ump_setupashZ, 0x1089A6B0 +.global Ump_setupcaveZ +.set Ump_setupcaveZ, 0x1089A6B0 +.global end_Ump_setupcaveZ +.set end_Ump_setupcaveZ, 0x1089CC10 +.global Ump_setupcradZ +.set Ump_setupcradZ, 0x1089CC10 +.global end_Ump_setupcradZ +.set end_Ump_setupcradZ, 0x1089D570 +.global Ump_setupcrypZ +.set Ump_setupcrypZ, 0x1089D570 +.global end_Ump_setupcrypZ +.set end_Ump_setupcrypZ, 0x1089E2D0 +.global Ump_setupdishZ +.set Ump_setupdishZ, 0x1089E2D0 +.global end_Ump_setupdishZ +.set end_Ump_setupdishZ, 0x1089E6C0 +.global Ump_setupimpZ +.set Ump_setupimpZ, 0x1089E6C0 +.global end_Ump_setupimpZ +.set end_Ump_setupimpZ, 0x1089ED00 +.global Ump_setupoatZ +.set Ump_setupoatZ, 0x1089ED00 +.global end_Ump_setupoatZ +.set end_Ump_setupoatZ, 0x1089F050 +.global Ump_setuprefZ +.set Ump_setuprefZ, 0x1089F050 +.global end_Ump_setuprefZ +.set end_Ump_setuprefZ, 0x1089F460 +.global Ump_setupsevbZ +.set Ump_setupsevbZ, 0x1089F460 +.global end_Ump_setupsevbZ +.set end_Ump_setupsevbZ, 0x108A0770 +.global Ump_setupstatueZ +.set Ump_setupstatueZ, 0x108A0770 +.global end_Ump_setupstatueZ +.set end_Ump_setupstatueZ, 0x108A15F0 +.global UsetuparchZ +.set UsetuparchZ, 0x108A15F0 +.global end_UsetuparchZ +.set end_UsetuparchZ, 0x108A5C00 +.global UsetuparkZ +.set UsetuparkZ, 0x108A5C00 +.global end_UsetuparkZ +.set end_UsetuparkZ, 0x108A9790 +.global UsetupaztZ +.set UsetupaztZ, 0x108A9790 +.global end_UsetupaztZ +.set end_UsetupaztZ, 0x108AC090 +.global UsetupcaveZ +.set UsetupcaveZ, 0x108AC090 +.global end_UsetupcaveZ +.set end_UsetupcaveZ, 0x108AFEF0 +.global UsetupcontrolZ +.set UsetupcontrolZ, 0x108AFEF0 +.global end_UsetupcontrolZ +.set end_UsetupcontrolZ, 0x108B39F0 +.global UsetupcradZ +.set UsetupcradZ, 0x108B39F0 +.global end_UsetupcradZ +.set end_UsetupcradZ, 0x108B5620 +.global UsetupcrypZ +.set UsetupcrypZ, 0x108B5620 +.global end_UsetupcrypZ +.set end_UsetupcrypZ, 0x108B74B0 +.global UsetupdamZ +.set UsetupdamZ, 0x108B74B0 +.global end_UsetupdamZ +.set end_UsetupdamZ, 0x108BB780 +.global UsetupdepoZ +.set UsetupdepoZ, 0x108BB780 +.global end_UsetupdepoZ +.set end_UsetupdepoZ, 0x108BE710 +.global UsetupdestZ +.set UsetupdestZ, 0x108BE710 +.global end_UsetupdestZ +.set end_UsetupdestZ, 0x108C0A60 +.global UsetupjunZ +.set UsetupjunZ, 0x108C0A60 +.global end_UsetupjunZ +.set end_UsetupjunZ, 0x108C4170 +.global UsetuplenZ +.set UsetuplenZ, 0x108C4170 +.global end_UsetuplenZ +.set end_UsetuplenZ, 0x108C4760 +.global UsetuppeteZ +.set UsetuppeteZ, 0x108C4760 +.global end_UsetuppeteZ +.set end_UsetuppeteZ, 0x108C76E0 +.global UsetuprunZ +.set UsetuprunZ, 0x108C76E0 +.global end_UsetuprunZ +.set end_UsetuprunZ, 0x108C8F40 +.global UsetupsevbZ +.set UsetupsevbZ, 0x108C8F40 +.global end_UsetupsevbZ +.set end_UsetupsevbZ, 0x108CB5A0 +.global UsetupsevbunkerZ +.set UsetupsevbunkerZ, 0x108CB5A0 +.global end_UsetupsevbunkerZ +.set end_UsetupsevbunkerZ, 0x108CCFD0 +.global UsetupsevxZ +.set UsetupsevxZ, 0x108CCFD0 +.global end_UsetupsevxZ +.set end_UsetupsevxZ, 0x108D12E0 +.global UsetupsevxbZ +.set UsetupsevxbZ, 0x108D12E0 +.global end_UsetupsevxbZ +.set end_UsetupsevxbZ, 0x108D53D0 +.global UsetupsiloZ +.set UsetupsiloZ, 0x108D53D0 +.global end_UsetupsiloZ +.set end_UsetupsiloZ, 0x108D7E90 +.global UsetupstatueZ +.set UsetupstatueZ, 0x108D7E90 +.global end_UsetupstatueZ +.set end_UsetupstatueZ, 0x108DA660 +.global UsetuptraZ +.set UsetuptraZ, 0x108DA660 +.global end_UsetuptraZ +.set end_UsetuptraZ, 0x108DD8A0 +.global LameE +.set LameE, 0x108DD8A0 +.global end_LameE +.set end_LameE, 0x108DD8B0 +.global LameJ +.set LameJ, 0x108DD8B0 +.global end_LameJ +.set end_LameJ, 0x108DD8C0 +.global LameP +.set LameP, 0x108DD8C0 +.global end_LameP +.set end_LameP, 0x108DD8D0 +.global LarchE +.set LarchE, 0x108DD8D0 +.global end_LarchE +.set end_LarchE, 0x108DDF00 +.global LarchJ +.set LarchJ, 0x108DDF00 +.global end_LarchJ +.set end_LarchJ, 0x108DE560 +.global LarchP +.set LarchP, 0x108DE560 +.global end_LarchP +.set end_LarchP, 0x108DEB90 +.global LarecE +.set LarecE, 0x108DEB90 +.global end_LarecE +.set end_LarecE, 0x108DF160 +.global LarecJ +.set LarecJ, 0x108DF160 +.global end_LarecJ +.set end_LarecJ, 0x108DF700 +.global LarecP +.set LarecP, 0x108DF700 +.global end_LarecP +.set end_LarecP, 0x108DFCD0 +.global LarkE +.set LarkE, 0x108DFCD0 +.global end_LarkE +.set end_LarkE, 0x108E0370 +.global LarkJ +.set LarkJ, 0x108E0370 +.global end_LarkJ +.set end_LarkJ, 0x108E0A00 +.global LarkP +.set LarkP, 0x108E0A00 +.global end_LarkP +.set end_LarkP, 0x108E10A0 +.global LashE +.set LashE, 0x108E10A0 +.global end_LashE +.set end_LashE, 0x108E10B0 +.global LashJ +.set LashJ, 0x108E10B0 +.global end_LashJ +.set end_LashJ, 0x108E10C0 +.global LashP +.set LashP, 0x108E10C0 +.global end_LashP +.set end_LashP, 0x108E10D0 +.global LaztE +.set LaztE, 0x108E10D0 +.global end_LaztE +.set end_LaztE, 0x108E1510 +.global LaztJ +.set LaztJ, 0x108E1510 +.global end_LaztJ +.set end_LaztJ, 0x108E1960 +.global LaztP +.set LaztP, 0x108E1960 +.global end_LaztP +.set end_LaztP, 0x108E1DA0 +.global LcatE +.set LcatE, 0x108E1DA0 +.global end_LcatE +.set end_LcatE, 0x108E1DB0 +.global LcatJ +.set LcatJ, 0x108E1DB0 +.global end_LcatJ +.set end_LcatJ, 0x108E1DC0 +.global LcatP +.set LcatP, 0x108E1DC0 +.global end_LcatP +.set end_LcatP, 0x108E1DD0 +.global LcaveE +.set LcaveE, 0x108E1DD0 +.global end_LcaveE +.set end_LcaveE, 0x108E21D0 +.global LcaveJ +.set LcaveJ, 0x108E21D0 +.global end_LcaveJ +.set end_LcaveJ, 0x108E2630 +.global LcaveP +.set LcaveP, 0x108E2630 +.global end_LcaveP +.set end_LcaveP, 0x108E2A30 +.global LcradE +.set LcradE, 0x108E2A30 +.global end_LcradE +.set end_LcradE, 0x108E2F00 +.global LcradJ +.set LcradJ, 0x108E2F00 +.global end_LcradJ +.set end_LcradJ, 0x108E33A0 +.global LcradP +.set LcradP, 0x108E33A0 +.global end_LcradP +.set end_LcradP, 0x108E3870 +.global LcrypE +.set LcrypE, 0x108E3870 +.global end_LcrypE +.set end_LcrypE, 0x108E3AC0 +.global LcrypJ +.set LcrypJ, 0x108E3AC0 +.global end_LcrypJ +.set end_LcrypJ, 0x108E3D60 +.global LcrypP +.set LcrypP, 0x108E3D60 +.global end_LcrypP +.set end_LcrypP, 0x108E3FB0 +.global LdamE +.set LdamE, 0x108E3FB0 +.global end_LdamE +.set end_LdamE, 0x108E4400 +.global LdamJ +.set LdamJ, 0x108E4400 +.global end_LdamJ +.set end_LdamJ, 0x108E4850 +.global LdamP +.set LdamP, 0x108E4850 +.global end_LdamP +.set end_LdamP, 0x108E4CA0 +.global LdepoE +.set LdepoE, 0x108E4CA0 +.global end_LdepoE +.set end_LdepoE, 0x108E5010 +.global LdepoJ +.set LdepoJ, 0x108E5010 +.global end_LdepoJ +.set end_LdepoJ, 0x108E5340 +.global LdepoP +.set LdepoP, 0x108E5340 +.global end_LdepoP +.set end_LdepoP, 0x108E56B0 +.global LdestE +.set LdestE, 0x108E56B0 +.global end_LdestE +.set end_LdestE, 0x108E5B50 +.global LdestJ +.set LdestJ, 0x108E5B50 +.global end_LdestJ +.set end_LdestJ, 0x108E5FB0 +.global LdestP +.set LdestP, 0x108E5FB0 +.global end_LdestP +.set end_LdestP, 0x108E6450 +.global LdishE +.set LdishE, 0x108E6450 +.global end_LdishE +.set end_LdishE, 0x108E6460 +.global LdishJ +.set LdishJ, 0x108E6460 +.global end_LdishJ +.set end_LdishJ, 0x108E6470 +.global LdishP +.set LdishP, 0x108E6470 +.global end_LdishP +.set end_LdishP, 0x108E6480 +.global LearE +.set LearE, 0x108E6480 +.global end_LearE +.set end_LearE, 0x108E6490 +.global LearJ +.set LearJ, 0x108E6490 +.global end_LearJ +.set end_LearJ, 0x108E64A0 +.global LearP +.set LearP, 0x108E64A0 +.global end_LearP +.set end_LearP, 0x108E64B0 +.global LeldE +.set LeldE, 0x108E64B0 +.global end_LeldE +.set end_LeldE, 0x108E64C0 +.global LeldJ +.set LeldJ, 0x108E64C0 +.global end_LeldJ +.set end_LeldJ, 0x108E64D0 +.global LeldP +.set LeldP, 0x108E64D0 +.global end_LeldP +.set end_LeldP, 0x108E64E0 +.global LgunE +.set LgunE, 0x108E64E0 +.global end_LgunE +.set end_LgunE, 0x108E6C00 +.global LgunJ +.set LgunJ, 0x108E6C00 +.global end_LgunJ +.set end_LgunJ, 0x108E7340 +.global LgunP +.set LgunP, 0x108E7340 +.global end_LgunP +.set end_LgunP, 0x108E7A60 +.global LimpE +.set LimpE, 0x108E7A60 +.global end_LimpE +.set end_LimpE, 0x108E7A70 +.global LimpJ +.set LimpJ, 0x108E7A70 +.global end_LimpJ +.set end_LimpJ, 0x108E7A80 +.global LimpP +.set LimpP, 0x108E7A80 +.global end_LimpP +.set end_LimpP, 0x108E7A90 +.global LjunE +.set LjunE, 0x108E7A90 +.global end_LjunE +.set end_LjunE, 0x108E7FB0 +.global LjunJ +.set LjunJ, 0x108E7FB0 +.global end_LjunJ +.set end_LjunJ, 0x108E84E0 +.global LjunP +.set LjunP, 0x108E84E0 +.global end_LjunP +.set end_LjunP, 0x108E8A00 +.global LleeE +.set LleeE, 0x108E8A00 +.global end_LleeE +.set end_LleeE, 0x108E8A10 +.global LleeJ +.set LleeJ, 0x108E8A10 +.global end_LleeJ +.set end_LleeJ, 0x108E8A20 +.global LleeP +.set LleeP, 0x108E8A20 +.global end_LleeP +.set end_LleeP, 0x108E8A30 +.global LlenE +.set LlenE, 0x108E8A30 +.global end_LlenE +.set end_LlenE, 0x108E90E0 +.global LlenJ +.set LlenJ, 0x108E90E0 +.global end_LlenJ +.set end_LlenJ, 0x108E9800 +.global LlenP +.set LlenP, 0x108E9800 +.global end_LlenP +.set end_LlenP, 0x108E9EB0 +.global LlipE +.set LlipE, 0x108E9EB0 +.global end_LlipE +.set end_LlipE, 0x108E9EC0 +.global LlipJ +.set LlipJ, 0x108E9EC0 +.global end_LlipJ +.set end_LlipJ, 0x108E9ED0 +.global LlipP +.set LlipP, 0x108E9ED0 +.global end_LlipP +.set end_LlipP, 0x108E9EE0 +.global LlueE +.set LlueE, 0x108E9EE0 +.global end_LlueE +.set end_LlueE, 0x108E9EF0 +.global LlueJ +.set LlueJ, 0x108E9EF0 +.global end_LlueJ +.set end_LlueJ, 0x108E9F00 +.global LlueP +.set LlueP, 0x108E9F00 +.global end_LlueP +.set end_LlueP, 0x108E9F10 +.global LmiscE +.set LmiscE, 0x108E9F10 +.global end_LmiscE +.set end_LmiscE, 0x108EA1C0 +.global LmiscJ +.set LmiscJ, 0x108EA1C0 +.global end_LmiscJ +.set end_LmiscJ, 0x108EA480 +.global LmiscP +.set LmiscP, 0x108EA480 +.global end_LmiscP +.set end_LmiscP, 0x108EA730 +.global LmpmenuE +.set LmpmenuE, 0x108EA730 +.global end_LmpmenuE +.set end_LmpmenuE, 0x108EA8D0 +.global LmpmenuJ +.set LmpmenuJ, 0x108EA8D0 +.global end_LmpmenuJ +.set end_LmpmenuJ, 0x108EAA70 +.global LmpmenuP +.set LmpmenuP, 0x108EAA70 +.global end_LmpmenuP +.set end_LmpmenuP, 0x108EAC10 +.global LmpweaponsE +.set LmpweaponsE, 0x108EAC10 +.global end_LmpweaponsE +.set end_LmpweaponsE, 0x108EACD0 +.global LmpweaponsJ +.set LmpweaponsJ, 0x108EACD0 +.global end_LmpweaponsJ +.set end_LmpweaponsJ, 0x108EADA0 +.global LmpweaponsP +.set LmpweaponsP, 0x108EADA0 +.global end_LmpweaponsP +.set end_LmpweaponsP, 0x108EAE60 +.global LoatE +.set LoatE, 0x108EAE60 +.global end_LoatE +.set end_LoatE, 0x108EAE70 +.global LoatJ +.set LoatJ, 0x108EAE70 +.global end_LoatJ +.set end_LoatJ, 0x108EAE80 +.global LoatP +.set LoatP, 0x108EAE80 +.global end_LoatP +.set end_LoatP, 0x108EAE90 +.global LoptionsE +.set LoptionsE, 0x108EAE90 +.global end_LoptionsE +.set end_LoptionsE, 0x108EB0C0 +.global LoptionsJ +.set LoptionsJ, 0x108EB0C0 +.global end_LoptionsJ +.set end_LoptionsJ, 0x108EB300 +.global LoptionsP +.set LoptionsP, 0x108EB300 +.global end_LoptionsP +.set end_LoptionsP, 0x108EB530 +.global LpamE +.set LpamE, 0x108EB530 +.global end_LpamE +.set end_LpamE, 0x108EB540 +.global LpamJ +.set LpamJ, 0x108EB540 +.global end_LpamJ +.set end_LpamJ, 0x108EB550 +.global LpamP +.set LpamP, 0x108EB550 +.global end_LpamP +.set end_LpamP, 0x108EB560 +.global LpeteE +.set LpeteE, 0x108EB560 +.global end_LpeteE +.set end_LpeteE, 0x108EB9E0 +.global LpeteJ +.set LpeteJ, 0x108EB9E0 +.global end_LpeteJ +.set end_LpeteJ, 0x108EBE50 +.global LpeteP +.set LpeteP, 0x108EBE50 +.global end_LpeteP +.set end_LpeteP, 0x108EC2D0 +.global LpropobjE +.set LpropobjE, 0x108EC2D0 +.global end_LpropobjE +.set end_LpropobjE, 0x108EC570 +.global LpropobjJ +.set LpropobjJ, 0x108EC570 +.global end_LpropobjJ +.set end_LpropobjJ, 0x108EC810 +.global LpropobjP +.set LpropobjP, 0x108EC810 +.global end_LpropobjP +.set end_LpropobjP, 0x108ECAB0 +.global LrefE +.set LrefE, 0x108ECAB0 +.global end_LrefE +.set end_LrefE, 0x108ECAC0 +.global LrefJ +.set LrefJ, 0x108ECAC0 +.global end_LrefJ +.set end_LrefJ, 0x108ECAD0 +.global LrefP +.set LrefP, 0x108ECAD0 +.global end_LrefP +.set end_LrefP, 0x108ECAE0 +.global LritE +.set LritE, 0x108ECAE0 +.global end_LritE +.set end_LritE, 0x108ECAF0 +.global LritJ +.set LritJ, 0x108ECAF0 +.global end_LritJ +.set end_LritJ, 0x108ECB00 +.global LritP +.set LritP, 0x108ECB00 +.global end_LritP +.set end_LritP, 0x108ECB10 +.global LrunE +.set LrunE, 0x108ECB10 +.global end_LrunE +.set end_LrunE, 0x108ECD80 +.global LrunJ +.set LrunJ, 0x108ECD80 +.global end_LrunJ +.set end_LrunJ, 0x108ED010 +.global LrunP +.set LrunP, 0x108ED010 +.global end_LrunP +.set end_LrunP, 0x108ED280 +.global LsevE +.set LsevE, 0x108ED280 +.global end_LsevE +.set end_LsevE, 0x108ED7E0 +.global LsevJ +.set LsevJ, 0x108ED7E0 +.global end_LsevJ +.set end_LsevJ, 0x108EDCF0 +.global LsevP +.set LsevP, 0x108EDCF0 +.global end_LsevP +.set end_LsevP, 0x108EE250 +.global LsevbE +.set LsevbE, 0x108EE250 +.global end_LsevbE +.set end_LsevbE, 0x108EE9A0 +.global LsevbJ +.set LsevbJ, 0x108EE9A0 +.global end_LsevbJ +.set end_LsevbJ, 0x108EF190 +.global LsevbP +.set LsevbP, 0x108EF190 +.global end_LsevbP +.set end_LsevbP, 0x108EF8E0 +.global LsevxE +.set LsevxE, 0x108EF8E0 +.global end_LsevxE +.set end_LsevxE, 0x108EFD40 +.global LsevxJ +.set LsevxJ, 0x108EFD40 +.global end_LsevxJ +.set end_LsevxJ, 0x108F0110 +.global LsevxP +.set LsevxP, 0x108F0110 +.global end_LsevxP +.set end_LsevxP, 0x108F0570 +.global LsevxbE +.set LsevxbE, 0x108F0570 +.global end_LsevxbE +.set end_LsevxbE, 0x108F0A00 +.global LsevxbJ +.set LsevxbJ, 0x108F0A00 +.global end_LsevxbJ +.set end_LsevxbJ, 0x108F0E50 +.global LsevxbP +.set LsevxbP, 0x108F0E50 +.global end_LsevxbP +.set end_LsevxbP, 0x108F12E0 +.global LshoE +.set LshoE, 0x108F12E0 +.global end_LshoE +.set end_LshoE, 0x108F12F0 +.global LshoJ +.set LshoJ, 0x108F12F0 +.global end_LshoJ +.set end_LshoJ, 0x108F1300 +.global LshoP +.set LshoP, 0x108F1300 +.global end_LshoP +.set end_LshoP, 0x108F1310 +.global LsiloE +.set LsiloE, 0x108F1310 +.global end_LsiloE +.set end_LsiloE, 0x108F18C0 +.global LsiloJ +.set LsiloJ, 0x108F18C0 +.global end_LsiloJ +.set end_LsiloJ, 0x108F1EB0 +.global LsiloP +.set LsiloP, 0x108F1EB0 +.global end_LsiloP +.set end_LsiloP, 0x108F2460 +.global LstatE +.set LstatE, 0x108F2460 +.global end_LstatE +.set end_LstatE, 0x108F2D80 +.global LstatJ +.set LstatJ, 0x108F2D80 +.global end_LstatJ +.set end_LstatJ, 0x108F35D0 +.global LstatP +.set LstatP, 0x108F35D0 +.global end_LstatP +.set end_LstatP, 0x108F3EF0 +.global LtitleE +.set LtitleE, 0x108F3EF0 +.global end_LtitleE +.set end_LtitleE, 0x108F4A00 +.global LtitleJ +.set LtitleJ, 0x108F4A00 +.global end_LtitleJ +.set end_LtitleJ, 0x108F55F0 +.global LtitleP +.set LtitleP, 0x108F55F0 +.global end_LtitleP +.set end_LtitleP, 0x108F6100 +.global LtraE +.set LtraE, 0x108F6100 +.global end_LtraE +.set end_LtraE, 0x108F6530 +.global LtraJ +.set LtraJ, 0x108F6530 +.global end_LtraJ +.set end_LtraJ, 0x108F6980 +.global LtraP +.set LtraP, 0x108F6980 +.global end_LtraP +.set end_LtraP, 0x108F6DB0 +.global LwaxE +.set LwaxE, 0x108F6DB0 +.global end_LwaxE +.set end_LwaxE, 0x108F7310 +.global LwaxJ +.set LwaxJ, 0x108F7310 +.global end_LwaxJ +.set end_LwaxJ, 0x108F7820 +.global LwaxP +.set LwaxP, 0x108F7820 +.global end_LwaxP +.set end_LwaxP, 0x108F7830 +.global ob__ob_end_seg +.set ob__ob_end_seg, 0x108F7830 +.global end_ob__ob_end_seg +.set end_ob__ob_end_seg, 0x108F7840 + +/* --- assets/ramrom (demo replays) ---------------------------- */ +.global ramrom_Dam_1 +.set ramrom_Dam_1, 0x102AC240 +.global ramrom_Dam_1_end +.set ramrom_Dam_1_end, 0x102AE550 +.global ramrom_Dam_2 +.set ramrom_Dam_2, 0x102AE550 +.global ramrom_Dam_2_end +.set ramrom_Dam_2_end, 0x102B3300 +.global ramrom_Facility_1 +.set ramrom_Facility_1, 0x102B3300 +.global ramrom_Facility_1_end +.set ramrom_Facility_1_end, 0x102B6590 +.global ramrom_Facility_2 +.set ramrom_Facility_2, 0x102B6590 +.global ramrom_Facility_2_end +.set ramrom_Facility_2_end, 0x102B9B10 +.global ramrom_Facility_3 +.set ramrom_Facility_3, 0x102B9B10 +.global ramrom_Facility_3_end +.set ramrom_Facility_3_end, 0x102BD050 +.global ramrom_Runway_1 +.set ramrom_Runway_1, 0x102BD050 +.global ramrom_Runway_1_end +.set ramrom_Runway_1_end, 0x102BF740 +.global ramrom_Runway_2 +.set ramrom_Runway_2, 0x102BF740 +.global ramrom_Runway_2_end +.set ramrom_Runway_2_end, 0x102C6310 +.global ramrom_BunkerI_1 +.set ramrom_BunkerI_1, 0x102C6310 +.global ramrom_BunkerI_1_end +.set ramrom_BunkerI_1_end, 0x102CB3E0 +.global ramrom_BunkerI_2 +.set ramrom_BunkerI_2, 0x102CB3E0 +.global ramrom_BunkerI_2_end +.set ramrom_BunkerI_2_end, 0x102CF800 +.global ramrom_Silo_1 +.set ramrom_Silo_1, 0x102CF800 +.global ramrom_Silo_1_end +.set ramrom_Silo_1_end, 0x102D1D00 +.global ramrom_Silo_2 +.set ramrom_Silo_2, 0x102D1D00 +.global ramrom_Silo_2_end +.set ramrom_Silo_2_end, 0x102D5150 +.global ramrom_Frigate_1 +.set ramrom_Frigate_1, 0x102D5150 +.global ramrom_Frigate_1_end +.set ramrom_Frigate_1_end, 0x102D7B90 +.global ramrom_Frigate_2 +.set ramrom_Frigate_2, 0x102D7B90 +.global ramrom_Frigate_2_end +.set ramrom_Frigate_2_end, 0x102D9BB0 +.global ramrom_Train +.set ramrom_Train, 0x102D9BB0 +.global ramrom_Train_end +.set ramrom_Train_end, 0x102DC830 +.global _ramromDam1SegmentRomStart +.set _ramromDam1SegmentRomStart, 0x102AC240 + +/* --- assets/music ------------------------------------------------ */ +.global _musicsampletblSegmentRomStart +.set _musicsampletblSegmentRomStart, 0x1040FBD0 +.global number_music_samples +.set number_music_samples, 0x1040FBD0 +.global number_music_samples_end +.set number_music_samples_end, 0x1040FBD4 +.global table_music_data +.set table_music_data, 0x1040FBD4 +.global _musicsampletblSegmentRomEnd +.set _musicsampletblSegmentRomEnd, 0x1040FDCC +.global table_music_data_end +.set table_music_data_end, 0x1040FDCC +.global _sfxctlSegmentRomStart +.set _sfxctlSegmentRomStart, 0x102E2220 +.global _sfxctlSegmentRomEnd +.set _sfxctlSegmentRomEnd, 0x102E7DE0 +.global _sfxtblSegmentRomStart +.set _sfxtblSegmentRomStart, 0x102E7DE0 +.global _sfxtblSegmentRomEnd +.set _sfxtblSegmentRomEnd, 0x103AA890 +.global _instrumentsctlSegmentRomStart +.set _instrumentsctlSegmentRomStart, 0x103AA890 +.global _instrumentsctlSegmentRomEnd +.set _instrumentsctlSegmentRomEnd, 0x103AEC30 +.global _instrumentstblSegmentRomStart +.set _instrumentstblSegmentRomStart, 0x103AEC30 +.global _instrumentstblSegmentRomEnd +.set _instrumentstblSegmentRomEnd, 0x1040FBD0 +.global Mno_music +.set Mno_music, 0x1040FDCC +.global end_Mno_music +.set end_Mno_music, 0x1040FDF6 +.global Msolo_death_abrev +.set Msolo_death_abrev, 0x1040FDF6 +.global end_Msolo_death_abrev +.set end_Msolo_death_abrev, 0x1040FFCC +.global Mintro_eye +.set Mintro_eye, 0x1040FFCC +.global end_Mintro_eye +.set end_Mintro_eye, 0x1041087A +.global Mtrain +.set Mtrain, 0x1041087A +.global end_Mtrain +.set end_Mtrain, 0x10411464 +.global Mdepot +.set Mdepot, 0x10411464 +.global end_Mdepot +.set end_Mdepot, 0x10412204 +.global Mjungle_unused +.set Mjungle_unused, 0x10412204 +.global end_Mjungle_unused +.set end_Mjungle_unused, 0x10412F9C +.global Mcitadel +.set Mcitadel, 0x10412F9C +.global end_Mcitadel +.set end_Mcitadel, 0x10413D5C +.global Mfacility +.set Mfacility, 0x10413D5C +.global end_Mfacility +.set end_Mfacility, 0x1041482A +.global Mcontrol +.set Mcontrol, 0x1041482A +.global end_Mcontrol +.set end_Mcontrol, 0x10415388 +.global Mdam +.set Mdam, 0x10415388 +.global end_Mdam +.set end_Mdam, 0x1041618C +.global Mfrigate +.set Mfrigate, 0x1041618C +.global end_Mfrigate +.set end_Mfrigate, 0x10416F6C +.global Marchives +.set Marchives, 0x10416F6C +.global end_Marchives +.set end_Marchives, 0x104178C0 +.global Msilo +.set Msilo, 0x104178C0 +.global end_Msilo +.set end_Msilo, 0x10418730 +.global Mjungle_perimeter_unused +.set Mjungle_perimeter_unused, 0x10418730 +.global end_Mjungle_perimeter_unused +.set end_Mjungle_perimeter_unused, 0x1041969C +.global Mstreets +.set Mstreets, 0x1041969C +.global end_Mstreets +.set end_Mstreets, 0x1041A39E +.global Mbunker1 +.set Mbunker1, 0x1041A39E +.global end_Mbunker1 +.set end_Mbunker1, 0x1041AA10 +.global Mbunker2 +.set Mbunker2, 0x1041AA10 +.global end_Mbunker2 +.set end_Mbunker2, 0x1041B090 +.global Mstatue +.set Mstatue, 0x1041B090 +.global end_Mstatue +.set end_Mstatue, 0x1041BA28 +.global Melevator_control +.set Melevator_control, 0x1041BA28 +.global end_Melevator_control +.set end_Melevator_control, 0x1041C402 +.global Mcradle +.set Mcradle, 0x1041C402 +.global end_Mcradle +.set end_Mcradle, 0x1041D162 +.global Mnull1 +.set Mnull1, 0x1041D162 +.global end_Mnull1 +.set end_Mnull1, 0x1041D18C +.global Melevator_wc +.set Melevator_wc, 0x1041D18C +.global end_Melevator_wc +.set end_Melevator_wc, 0x1041D7D2 +.global Megyptian +.set Megyptian, 0x1041D7D2 +.global end_Megyptian +.set end_Megyptian, 0x1041E56C +.global Mfolders +.set Mfolders, 0x1041E56C +.global end_Mfolders +.set end_Mfolders, 0x1041E94E +.global Mwatchmusic +.set Mwatchmusic, 0x1041E94E +.global end_Mwatchmusic +.set end_Mwatchmusic, 0x1041EB40 +.global Maztec +.set Maztec, 0x1041EB40 +.global end_Maztec +.set end_Maztec, 0x1041F7B2 +.global Mwatercaverns +.set Mwatercaverns, 0x1041F7B2 +.global end_Mwatercaverns +.set end_Mwatercaverns, 0x104205DE +.global Mdeathsolo +.set Mdeathsolo, 0x104205DE +.global end_Mdeathsolo +.set end_Mdeathsolo, 0x10420944 +.global Msurface2 +.set Msurface2, 0x10420944 +.global end_Msurface2 +.set end_Msurface2, 0x104216FA +.global Mtrainx +.set Mtrainx, 0x104216FA +.global end_Mtrainx +.set end_Mtrainx, 0x10421F9A +.global Mnull2 +.set Mnull2, 0x10421F9A +.global end_Mnull2 +.set end_Mnull2, 0x10421FC4 +.global Mfacilityx +.set Mfacilityx, 0x10421FC4 +.global end_Mfacilityx +.set end_Mfacilityx, 0x1042291C +.global Mdepotx +.set Mdepotx, 0x1042291C +.global end_Mdepotx +.set end_Mdepotx, 0x104230D8 +.global Mcontrolx +.set Mcontrolx, 0x104230D8 +.global end_Mcontrolx +.set end_Mcontrolx, 0x10423620 +.global Mwatercavernsx +.set Mwatercavernsx, 0x10423620 +.global end_Mwatercavernsx +.set end_Mwatercavernsx, 0x10423D74 +.global Mdamx +.set Mdamx, 0x10423D74 +.global end_Mdamx +.set end_Mdamx, 0x10424294 +.global Mfrigatex +.set Mfrigatex, 0x10424294 +.global end_Mfrigatex +.set end_Mfrigatex, 0x10424856 +.global Marchivesx +.set Marchivesx, 0x10424856 +.global end_Marchivesx +.set end_Marchivesx, 0x10424F7A +.global Msilox +.set Msilox, 0x10424F7A +.global end_Msilox +.set end_Msilox, 0x1042586E +.global Mnull3 +.set Mnull3, 0x1042586E +.global end_Mnull3 +.set end_Mnull3, 0x10425898 +.global Mstreetsx +.set Mstreetsx, 0x10425898 +.global end_Mstreetsx +.set end_Mstreetsx, 0x10425F04 +.global Mbunker1x +.set Mbunker1x, 0x10425F04 +.global end_Mbunker1x +.set end_Mbunker1x, 0x104266AA +.global Mbunker2x +.set Mbunker2x, 0x104266AA +.global end_Mbunker2x +.set end_Mbunker2x, 0x10426CF8 +.global Mjunglex +.set Mjunglex, 0x10426CF8 +.global end_Mjunglex +.set end_Mjunglex, 0x1042750E +.global Mnint_rare_logo +.set Mnint_rare_logo, 0x1042750E +.global end_Mnint_rare_logo +.set end_Mnint_rare_logo, 0x10427940 +.global Mstatuex +.set Mstatuex, 0x10427940 +.global end_Mstatuex +.set end_Mstatuex, 0x10427FF8 +.global Maztecx +.set Maztecx, 0x10427FF8 +.global end_Maztecx +.set end_Maztecx, 0x104288CE +.global Megyptianx +.set Megyptianx, 0x104288CE +.global end_Megyptianx +.set end_Megyptianx, 0x1042917E +.global Mcradlex +.set Mcradlex, 0x1042917E +.global end_Mcradlex +.set end_Mcradlex, 0x10429848 +.global Mcuba +.set Mcuba, 0x10429848 +.global end_Mcuba +.set end_Mcuba, 0x1042A092 +.global Mrunway +.set Mrunway, 0x1042A092 +.global end_Mrunway +.set end_Mrunway, 0x1042ADB0 +.global Mrunway_plane +.set Mrunway_plane, 0x1042ADB0 +.global end_Mrunway_plane +.set end_Mrunway_plane, 0x1042B08A +.global Msurface2x +.set Msurface2x, 0x1042B08A +.global end_Msurface2x +.set end_Msurface2x, 0x1042B7B2 +.global Mwindblowing +.set Mwindblowing, 0x1042B7B2 +.global end_Mwindblowing +.set end_Mwindblowing, 0x1042BCD4 +.global Mmultideath_alt +.set Mmultideath_alt, 0x1042BCD4 +.global end_Mmultideath_alt +.set end_Mmultideath_alt, 0x1042BEE0 +.global Mjungle +.set Mjungle, 0x1042BEE0 +.global end_Mjungle +.set end_Mjungle, 0x1042C668 +.global Mrunwayx +.set Mrunwayx, 0x1042C668 +.global end_Mrunwayx +.set end_Mrunwayx, 0x1042CC8A +.global Msurface1 +.set Msurface1, 0x1042CC8A +.global end_Msurface1 +.set end_Msurface1, 0x1042D9F2 +.global Mmultiplayerdeath +.set Mmultiplayerdeath, 0x1042D9F2 +.global end_Mmultiplayerdeath +.set end_Mmultiplayerdeath, 0x1042DCBA +.global Msurface1x +.set Msurface1x, 0x1042DCBA +.global end_Msurface1x +.set end_Msurface1x, 0x1042E3E2 +.global Msurface2_ending +.set Msurface2_ending, 0x1042E3E2 +.global end_Msurface2_ending +.set end_Msurface2_ending, 0x1042E67E +.global Mstatue_ending +.set Mstatue_ending, 0x1042E67E +.global end_Mstatue_ending +.set end_Mstatue_ending, 0x1042E7E4 +.global Mfrigate_outro +.set Mfrigate_outro, 0x1042E7E4 +.global end_Mfrigate_outro +.set end_Mfrigate_outro, 0x1042EAA0 + +/* --- assets/romfiles2.s -------------------------------------- */ +.global unknown2 +.set unknown2, 0x10291CC0 +.global unknown2_end +.set unknown2_end, 0x102AC240 + +/* --- ge007.ld segment markers ------------------------------------ */ +/* RomStart/RomEnd are exact for asset segments; Start/End mirror them +/* (game code only ever uses End-Start size differences for these). +/* Code segments are approximate (see generator header comment). */ +.global _headerSegmentRomStart +.set _headerSegmentRomStart, 0x10000000 +.global _headerSegmentRomEnd +.set _headerSegmentRomEnd, 0x10000040 +.global _headerSegmentStart +.set _headerSegmentStart, 0x10000000 +.global _headerSegmentEnd +.set _headerSegmentEnd, 0x10000040 /* approximate */ +.global _bootSegmentRomStart +.set _bootSegmentRomStart, 0x10000040 +.global _bootSegmentRomEnd +.set _bootSegmentRomEnd, 0x10001000 +.global _bootSegmentStart +.set _bootSegmentStart, 0x10000040 +.global _bootSegmentEnd +.set _bootSegmentEnd, 0x10001000 /* approximate */ +.global _startSegmentRomStart +.set _startSegmentRomStart, 0x10001000 +.global _startSegmentRomEnd +.set _startSegmentRomEnd, 0x10001050 +.global _startSegmentStart +.set _startSegmentStart, 0x10001000 +.global _startSegmentEnd +.set _startSegmentEnd, 0x10001050 /* approximate */ +.global _codeSegmentRomStart +.set _codeSegmentRomStart, 0x10001050 +.global _codeSegmentRomEnd +.set _codeSegmentRomEnd, 0x10021990 +.global _codeSegmentStart +.set _codeSegmentStart, 0x10001050 +.global _codeSegmentEnd +.set _codeSegmentEnd, 0x10021990 /* approximate */ +.global _cdataSegmentRomStart +.set _cdataSegmentRomStart, 0x10021990 +.global _cdataSegmentRomEnd +.set _cdataSegmentRomEnd, 0x1001F0E2 +.global _cdataSegmentStart +.set _cdataSegmentStart, 0x10021990 +.global _cdataSegmentEnd +.set _cdataSegmentEnd, 0x1001F0E2 /* approximate */ +.global _inflateSegmentRomStart +.set _inflateSegmentRomStart, 0x1001F0E2 +.global _inflateSegmentRomEnd +.set _inflateSegmentRomEnd, 0x10021A9F +.global _inflateSegmentStart +.set _inflateSegmentStart, 0x1001F0E2 +.global _inflateSegmentEnd +.set _inflateSegmentEnd, 0x10021A9F /* approximate */ +.global _gameSegmentRomStart +.set _gameSegmentRomStart, 0x10021A9F +.global _gameSegmentRomEnd +.set _gameSegmentRomEnd, 0x101047F0 +.global _gameSegmentStart +.set _gameSegmentStart, 0x10021A9F +.global _gameSegmentEnd +.set _gameSegmentEnd, 0x101047F0 /* approximate */ +.global _fontdlSegmentRomStart +.set _fontdlSegmentRomStart, 0x101047F0 +.global _fontdlSegmentRomEnd +.set _fontdlSegmentRomEnd, 0x101048B0 +.global _fontdlSegmentStart +.set _fontdlSegmentStart, 0x101047F0 +.global _fontdlSegmentEnd +.set _fontdlSegmentEnd, 0x101048B0 +.global _jfontchardataSegmentRomStart +.set _jfontchardataSegmentRomStart, 0x101048B0 +.global _jfontchardataSegmentRomEnd +.set _jfontchardataSegmentRomEnd, 0x1010FFB0 +.global _jfontchardataSegmentStart +.set _jfontchardataSegmentStart, 0x101048B0 +.global _jfontchardataSegmentEnd +.set _jfontchardataSegmentEnd, 0x1010FFB0 +.global _efontchardataSegmentRomStart +.set _efontchardataSegmentRomStart, 0x1010FFB0 +.global _efontchardataSegmentRomEnd +.set _efontchardataSegmentRomEnd, 0x10111A30 +.global _efontchardataSegmentStart +.set _efontchardataSegmentStart, 0x1010FFB0 +.global _efontchardataSegmentEnd +.set _efontchardataSegmentEnd, 0x10111A30 +.global _animation_entriesSegmentRomStart +.set _animation_entriesSegmentRomStart, 0x10111A30 +.global _animation_entriesSegmentRomEnd +.set _animation_entriesSegmentRomEnd, 0x1027B8F0 +.global _animation_entriesSegmentStart +.set _animation_entriesSegmentStart, 0x10111A30 +.global _animation_entriesSegmentEnd +.set _animation_entriesSegmentEnd, 0x1027B8F0 +.global _animation_dataSegmentRomStart +.set _animation_dataSegmentRomStart, 0x1027B8F0 +.global _animation_dataSegmentRomEnd +.set _animation_dataSegmentRomEnd, 0x1028A0D0 +.global _animation_dataSegmentStart +.set _animation_dataSegmentStart, 0x1027B8F0 +.global _animation_dataSegmentEnd +.set _animation_dataSegmentEnd, 0x1028A0D0 +.global _GlobalimagetableSegmentRomStart +.set _GlobalimagetableSegmentRomStart, 0x1028A0D0 +.global _GlobalimagetableSegmentRomEnd +.set _GlobalimagetableSegmentRomEnd, 0x1028B4C8 +.global _GlobalimagetableSegmentStart +.set _GlobalimagetableSegmentStart, 0x1028A0D0 +.global _GlobalimagetableSegmentEnd +.set _GlobalimagetableSegmentEnd, 0x1028B4C8 +.global _rarewarelogoSegmentRomStart +.set _rarewarelogoSegmentRomStart, 0x1028B4D0 +.global _rarewarelogoSegmentRomEnd +.set _rarewarelogoSegmentRomEnd, 0x10291CC0 +.global _rarewarelogoSegmentStart +.set _rarewarelogoSegmentStart, 0x1028B4D0 +.global _rarewarelogoSegmentEnd +.set _rarewarelogoSegmentEnd, 0x10291CC0 +.global _romfiles2SegmentRomStart +.set _romfiles2SegmentRomStart, 0x10291CC0 +.global _romfiles2SegmentRomEnd +.set _romfiles2SegmentRomEnd, 0x102AC240 +.global _romfiles2SegmentStart +.set _romfiles2SegmentStart, 0x10291CC0 +.global _romfiles2SegmentEnd +.set _romfiles2SegmentEnd, 0x102AC240 +.global _ramromfilesSegmentRomStart +.set _ramromfilesSegmentRomStart, 0x102AC240 +.global _ramromfilesSegmentRomEnd +.set _ramromfilesSegmentRomEnd, 0x102DC830 +.global _ramromfilesSegmentStart +.set _ramromfilesSegmentStart, 0x102AC240 +.global _ramromfilesSegmentEnd +.set _ramromfilesSegmentEnd, 0x102DC830 +.global _fontbankgothicSegmentRomStart +.set _fontbankgothicSegmentRomStart, 0x102DC830 +.global _fontbankgothicSegmentRomEnd +.set _fontbankgothicSegmentRomEnd, 0x102DECE0 +.global _fontbankgothicSegmentStart +.set _fontbankgothicSegmentStart, 0x102DC830 +.global _fontbankgothicSegmentEnd +.set _fontbankgothicSegmentEnd, 0x102DECE0 +.global _fontzurichboldSegmentRomStart +.set _fontzurichboldSegmentRomStart, 0x102DECE0 +.global _fontzurichboldSegmentRomEnd +.set _fontzurichboldSegmentRomEnd, 0x102E2220 +.global _fontzurichboldSegmentStart +.set _fontzurichboldSegmentStart, 0x102DECE0 +.global _fontzurichboldSegmentEnd +.set _fontzurichboldSegmentEnd, 0x102E2220 +.global _musicfilesSegmentRomStart +.set _musicfilesSegmentRomStart, 0x102E2220 +.global _musicfilesSegmentRomEnd +.set _musicfilesSegmentRomEnd, 0x1042EAA0 +.global _musicfilesSegmentStart +.set _musicfilesSegmentStart, 0x102E2220 +.global _musicfilesSegmentEnd +.set _musicfilesSegmentEnd, 0x1042EAA0 +.global _obsegSegmentRomStart +.set _obsegSegmentRomStart, 0x1042EAA0 +.global _obsegSegmentRomEnd +.set _obsegSegmentRomEnd, 0x108F7840 +.global _obsegSegmentStart +.set _obsegSegmentStart, 0x1042EAA0 +.global _obsegSegmentEnd +.set _obsegSegmentEnd, 0x108F7840 +.global _imagesSegmentRomStart +.set _imagesSegmentRomStart, 0x108F7840 +.global _imagesSegmentRomEnd +.set _imagesSegmentRomEnd, 0x108F7840 +.global _imagesSegmentStart +.set _imagesSegmentStart, 0x108F7840 +.global _imagesSegmentEnd +.set _imagesSegmentEnd, 0x108F7840 +.global _alt_startSegmentRomStart +.set _alt_startSegmentRomStart, 0x10101000 +.global _alt_startSegmentStart +.set _alt_startSegmentStart, 0x10101000 diff --git a/port/src/romassets_j.s b/port/src/romassets_j.s new file mode 100644 index 00000000..1318ed41 --- /dev/null +++ b/port/src/romassets_j.s @@ -0,0 +1,3393 @@ +/* + * AUTO-GENERATED by scripts/gen_romassets.py (J) -- do not edit. + * + * Absolute ROM asset symbols for the PC port. Each symbol is the N64 + * cart address (0x10000000 + rom_offset) of the corresponding asset in + * scripts/filelist.j.csv, so `&symbol` / romCopy() work exactly as + * on hardware once romdata.c has mapped the .z64 at 0x10000000. + * Regenerate: python3 scripts/gen_romassets.py j + */ +.section .data + +/* --- assets/obseg (file_resource_table.inc.c order) ------------- */ +.global bg_sev_all_p_seg +.set bg_sev_all_p_seg, 0x10439380 +.global end_bg_sev_all_p_seg +.set end_bg_sev_all_p_seg, 0x1044A170 +.global bg_silo_all_p_seg +.set bg_silo_all_p_seg, 0x1044A170 +.global end_bg_silo_all_p_seg +.set end_bg_silo_all_p_seg, 0x1049B0B0 +.global bg_stat_all_p_seg +.set bg_stat_all_p_seg, 0x1049B0B0 +.global end_bg_stat_all_p_seg +.set end_bg_stat_all_p_seg, 0x104BD180 +.global bg_arec_all_p_seg +.set bg_arec_all_p_seg, 0x104BD180 +.global end_bg_arec_all_p_seg +.set end_bg_arec_all_p_seg, 0x104EB500 +.global bg_arch_all_p_seg +.set bg_arch_all_p_seg, 0x104EB500 +.global end_bg_arch_all_p_seg +.set end_bg_arch_all_p_seg, 0x10510FF0 +.global bg_tra_all_p_seg +.set bg_tra_all_p_seg, 0x10510FF0 +.global end_bg_tra_all_p_seg +.set end_bg_tra_all_p_seg, 0x10531560 +.global bg_dest_all_p_seg +.set bg_dest_all_p_seg, 0x10531560 +.global end_bg_dest_all_p_seg +.set end_bg_dest_all_p_seg, 0x1055EF20 +.global bg_sevb_all_p_seg +.set bg_sevb_all_p_seg, 0x1055EF20 +.global end_bg_sevb_all_p_seg +.set end_bg_sevb_all_p_seg, 0x10579CC0 +.global bg_azt_all_p_seg +.set bg_azt_all_p_seg, 0x10579CC0 +.global end_bg_azt_all_p_seg +.set end_bg_azt_all_p_seg, 0x1059B710 +.global bg_pete_all_p_seg +.set bg_pete_all_p_seg, 0x1059B710 +.global end_bg_pete_all_p_seg +.set end_bg_pete_all_p_seg, 0x105B5340 +.global bg_depo_all_p_seg +.set bg_depo_all_p_seg, 0x105B5340 +.global end_bg_depo_all_p_seg +.set end_bg_depo_all_p_seg, 0x105E1CB0 +.global bg_ref_all_p_seg +.set bg_ref_all_p_seg, 0x105E1CB0 +.global end_bg_ref_all_p_seg +.set end_bg_ref_all_p_seg, 0x105EB2C0 +.global bg_cryp_all_p_seg +.set bg_cryp_all_p_seg, 0x105EB2C0 +.global end_bg_cryp_all_p_seg +.set end_bg_cryp_all_p_seg, 0x10600970 +.global bg_dam_all_p_seg +.set bg_dam_all_p_seg, 0x10600970 +.global end_bg_dam_all_p_seg +.set end_bg_dam_all_p_seg, 0x10630B10 +.global bg_ark_all_p_seg +.set bg_ark_all_p_seg, 0x10630B10 +.global end_bg_ark_all_p_seg +.set end_bg_ark_all_p_seg, 0x10661A90 +.global bg_run_all_p_seg +.set bg_run_all_p_seg, 0x10661A90 +.global end_bg_run_all_p_seg +.set end_bg_run_all_p_seg, 0x1066BE60 +.global bg_sevx_all_p_seg +.set bg_sevx_all_p_seg, 0x1066BE60 +.global end_bg_sevx_all_p_seg +.set end_bg_sevx_all_p_seg, 0x10688430 +.global bg_jun_all_p_seg +.set bg_jun_all_p_seg, 0x10688430 +.global end_bg_jun_all_p_seg +.set end_bg_jun_all_p_seg, 0x1069D580 +.global bg_dish_all_p_seg +.set bg_dish_all_p_seg, 0x1069D580 +.global end_bg_dish_all_p_seg +.set end_bg_dish_all_p_seg, 0x106A1DF0 +.global bg_cave_all_p_seg +.set bg_cave_all_p_seg, 0x106A1DF0 +.global end_bg_cave_all_p_seg +.set end_bg_cave_all_p_seg, 0x106C62E0 +.global bg_cat_all_p_seg +.set bg_cat_all_p_seg, 0x106C62E0 +.global end_bg_cat_all_p_seg +.set end_bg_cat_all_p_seg, 0x106CB810 +.global bg_crad_all_p_seg +.set bg_crad_all_p_seg, 0x106CB810 +.global end_bg_crad_all_p_seg +.set end_bg_crad_all_p_seg, 0x106DBB60 +.global bg_sho_all_p_seg +.set bg_sho_all_p_seg, 0x106DBB60 +.global end_bg_sho_all_p_seg +.set end_bg_sho_all_p_seg, 0x106DBB60 +.global bg_imp_all_p_seg +.set bg_imp_all_p_seg, 0x106DBB60 +.global end_bg_imp_all_p_seg +.set end_bg_imp_all_p_seg, 0x106DBB60 +.global bg_rit_all_p_seg +.set bg_rit_all_p_seg, 0x106E5AC0 +.global end_bg_rit_all_p_seg +.set end_bg_rit_all_p_seg, 0x106E5AC0 +.global bg_oat_all_p_seg +.set bg_oat_all_p_seg, 0x106E5AC0 +.global end_bg_oat_all_p_seg +.set end_bg_oat_all_p_seg, 0x106EC910 +.global bg_ear_all_p_seg +.set bg_ear_all_p_seg, 0x106EC910 +.global end_bg_ear_all_p_seg +.set end_bg_ear_all_p_seg, 0x106EC910 +.global bg_lee_all_p_seg +.set bg_lee_all_p_seg, 0x106EC910 +.global end_bg_lee_all_p_seg +.set end_bg_lee_all_p_seg, 0x106EC910 +.global bg_lip_all_p_seg +.set bg_lip_all_p_seg, 0x106EC910 +.global end_bg_lip_all_p_seg +.set end_bg_lip_all_p_seg, 0x106EC910 +.global bg_len_all_p_seg +.set bg_len_all_p_seg, 0x106EC910 +.global end_bg_len_all_p_seg +.set end_bg_len_all_p_seg, 0x106ED8B0 +.global bg_wax_all_p_seg +.set bg_wax_all_p_seg, 0x106ED8B0 +.global end_bg_wax_all_p_seg +.set end_bg_wax_all_p_seg, 0x106ED8B0 +.global bg_pam_all_p_seg +.set bg_pam_all_p_seg, 0x106ED8B0 +.global end_bg_pam_all_p_seg +.set end_bg_pam_all_p_seg, 0x106ED8B0 +.global CarmourguardZ +.set CarmourguardZ, 0x106ED8B0 +.global end_CarmourguardZ +.set end_CarmourguardZ, 0x106EFD30 +.global CbaronsamediZ +.set CbaronsamediZ, 0x106EFD30 +.global end_CbaronsamediZ +.set end_CbaronsamediZ, 0x106F3420 +.global CbluecamguardZ +.set CbluecamguardZ, 0x106F3420 +.global end_CbluecamguardZ +.set end_CbluecamguardZ, 0x106F5B10 +.global CbluemanZ +.set CbluemanZ, 0x106F5B10 +.global end_CbluemanZ +.set end_CbluemanZ, 0x106F7920 +.global CbluewomanZ +.set CbluewomanZ, 0x106F7920 +.global end_CbluewomanZ +.set end_CbluewomanZ, 0x106F97E0 +.global CboilerbondZ +.set CboilerbondZ, 0x106F97E0 +.global end_CboilerbondZ +.set end_CboilerbondZ, 0x106FC3F0 +.global CboilertrevZ +.set CboilertrevZ, 0x106FC3F0 +.global end_CboilertrevZ +.set end_CboilertrevZ, 0x106FFA70 +.global CborisZ +.set CborisZ, 0x106FFA70 +.global end_CborisZ +.set end_CborisZ, 0x10702B90 +.global CcamguardZ +.set CcamguardZ, 0x10702B90 +.global end_CcamguardZ +.set end_CcamguardZ, 0x10705270 +.global CcardimanZ +.set CcardimanZ, 0x10705270 +.global end_CcardimanZ +.set end_CcardimanZ, 0x10707070 +.global CcheckmanZ +.set CcheckmanZ, 0x10707070 +.global end_CcheckmanZ +.set end_CcheckmanZ, 0x10708EF0 +.global CcommguardZ +.set CcommguardZ, 0x10708EF0 +.global end_CcommguardZ +.set end_CcommguardZ, 0x1070B4F0 +.global CdjbondZ +.set CdjbondZ, 0x1070B4F0 +.global end_CdjbondZ +.set end_CdjbondZ, 0x1070E380 +.global CfattechwomanZ +.set CfattechwomanZ, 0x1070E380 +.global end_CfattechwomanZ +.set end_CfattechwomanZ, 0x107102A0 +.global Cgreatguard2Z +.set Cgreatguard2Z, 0x107102A0 +.global end_Cgreatguard2Z +.set end_Cgreatguard2Z, 0x107129C0 +.global CgreatguardZ +.set CgreatguardZ, 0x107129C0 +.global end_CgreatguardZ +.set end_CgreatguardZ, 0x10715040 +.global CgreyguardZ +.set CgreyguardZ, 0x10715040 +.global end_CgreyguardZ +.set end_CgreyguardZ, 0x10717710 +.global CgreymanZ +.set CgreymanZ, 0x10717710 +.global end_CgreymanZ +.set end_CgreymanZ, 0x107194D0 +.global CheadalanZ +.set CheadalanZ, 0x107194D0 +.global end_CheadalanZ +.set end_CheadalanZ, 0x10719AA0 +.global CheadbZ +.set CheadbZ, 0x10719AA0 +.global end_CheadbZ +.set end_CheadbZ, 0x1071A010 +.global CheadbalaclavaZ +.set CheadbalaclavaZ, 0x1071A010 +.global end_CheadbalaclavaZ +.set end_CheadbalaclavaZ, 0x1071A3E0 +.global CheadbikeZ +.set CheadbikeZ, 0x1071A3E0 +.global end_CheadbikeZ +.set end_CheadbikeZ, 0x1071AA80 +.global CheadbrosnanZ +.set CheadbrosnanZ, 0x1071AA80 +.global end_CheadbrosnanZ +.set end_CheadbrosnanZ, 0x1071B7D0 +.global CheadbrosnanboilerZ +.set CheadbrosnanboilerZ, 0x1071B7D0 +.global end_CheadbrosnanboilerZ +.set end_CheadbrosnanboilerZ, 0x1071C370 +.global CheadbrosnansnowZ +.set CheadbrosnansnowZ, 0x1071C370 +.global end_CheadbrosnansnowZ +.set end_CheadbrosnansnowZ, 0x1071D1F0 +.global CheadbrosnansuitZ +.set CheadbrosnansuitZ, 0x1071D1F0 +.global end_CheadbrosnansuitZ +.set end_CheadbrosnansuitZ, 0x1071DF70 +.global CheadbrosnantimberZ +.set CheadbrosnantimberZ, 0x1071DF70 +.global end_CheadbrosnantimberZ +.set end_CheadbrosnantimberZ, 0x1071EB30 +.global CheadchrisZ +.set CheadchrisZ, 0x1071EB30 +.global end_CheadchrisZ +.set end_CheadchrisZ, 0x1071F070 +.global CheaddaveZ +.set CheaddaveZ, 0x1071F070 +.global end_CheaddaveZ +.set end_CheaddaveZ, 0x1071F5F0 +.global CheaddesZ +.set CheaddesZ, 0x1071F5F0 +.global end_CheaddesZ +.set end_CheaddesZ, 0x1071FB20 +.global CheadduncanZ +.set CheadduncanZ, 0x1071FB20 +.global end_CheadduncanZ +.set end_CheadduncanZ, 0x10720040 +.global CheaddwayneZ +.set CheaddwayneZ, 0x10720040 +.global end_CheaddwayneZ +.set end_CheaddwayneZ, 0x107205C0 +.global CheadgrahamZ +.set CheadgrahamZ, 0x107205C0 +.global end_CheadgrahamZ +.set end_CheadgrahamZ, 0x10720B30 +.global CheadgrantZ +.set CheadgrantZ, 0x10720B30 +.global end_CheadgrantZ +.set end_CheadgrantZ, 0x10721060 +.global CheadjimZ +.set CheadjimZ, 0x10721060 +.global end_CheadjimZ +.set end_CheadjimZ, 0x10721590 +.global Cheadjoe2Z +.set Cheadjoe2Z, 0x10721590 +.global end_Cheadjoe2Z +.set end_Cheadjoe2Z, 0x107219B0 +.global CheadjoeZ +.set CheadjoeZ, 0x107219B0 +.global end_CheadjoeZ +.set end_CheadjoeZ, 0x10721F20 +.global CheadjoelZ +.set CheadjoelZ, 0x10721F20 +.global end_CheadjoelZ +.set end_CheadjoelZ, 0x10722430 +.global CheadkarlZ +.set CheadkarlZ, 0x10722430 +.global end_CheadkarlZ +.set end_CheadkarlZ, 0x10722990 +.global CheadkenZ +.set CheadkenZ, 0x10722990 +.global end_CheadkenZ +.set end_CheadkenZ, 0x10722EE0 +.global CheadleeZ +.set CheadleeZ, 0x10722EE0 +.global end_CheadleeZ +.set end_CheadleeZ, 0x10723460 +.global CheadmandyZ +.set CheadmandyZ, 0x10723460 +.global end_CheadmandyZ +.set end_CheadmandyZ, 0x10723850 +.global CheadmarionZ +.set CheadmarionZ, 0x10723850 +.global end_CheadmarionZ +.set end_CheadmarionZ, 0x10723C60 +.global CheadmarkZ +.set CheadmarkZ, 0x10723C60 +.global end_CheadmarkZ +.set end_CheadmarkZ, 0x10724190 +.global CheadmartinZ +.set CheadmartinZ, 0x10724190 +.global end_CheadmartinZ +.set end_CheadmartinZ, 0x107246F0 +.global CheadmishkinZ +.set CheadmishkinZ, 0x107246F0 +.global end_CheadmishkinZ +.set end_CheadmishkinZ, 0x10724C50 +.global CheadneilZ +.set CheadneilZ, 0x10724C50 +.global end_CheadneilZ +.set end_CheadneilZ, 0x10725170 +.global CheadpeteZ +.set CheadpeteZ, 0x10725170 +.global end_CheadpeteZ +.set end_CheadpeteZ, 0x10725700 +.global CheadrobinZ +.set CheadrobinZ, 0x10725700 +.global end_CheadrobinZ +.set end_CheadrobinZ, 0x10725C10 +.global CheadsallyZ +.set CheadsallyZ, 0x10725C10 +.global end_CheadsallyZ +.set end_CheadsallyZ, 0x10726010 +.global CheadscottZ +.set CheadscottZ, 0x10726010 +.global end_CheadscottZ +.set end_CheadscottZ, 0x10726590 +.global CheadshaunZ +.set CheadshaunZ, 0x10726590 +.global end_CheadshaunZ +.set end_CheadshaunZ, 0x10726B70 +.global CheadsteveeZ +.set CheadsteveeZ, 0x10726B70 +.global end_CheadsteveeZ +.set end_CheadsteveeZ, 0x107270C0 +.global CheadstevehZ +.set CheadstevehZ, 0x107270C0 +.global end_CheadstevehZ +.set end_CheadstevehZ, 0x10727610 +.global CheadvivienZ +.set CheadvivienZ, 0x10727610 +.global end_CheadvivienZ +.set end_CheadvivienZ, 0x10727AA0 +.global CjawsZ +.set CjawsZ, 0x10727AA0 +.global end_CjawsZ +.set end_CjawsZ, 0x1072A6E0 +.global CjeanwomanZ +.set CjeanwomanZ, 0x1072A6E0 +.global end_CjeanwomanZ +.set end_CjeanwomanZ, 0x1072C6F0 +.global CmaydayZ +.set CmaydayZ, 0x1072C6F0 +.global end_CmaydayZ +.set end_CmaydayZ, 0x1072F290 +.global CmoonfemaleZ +.set CmoonfemaleZ, 0x1072F290 +.global end_CmoonfemaleZ +.set end_CmoonfemaleZ, 0x107313E0 +.global CmoonguardZ +.set CmoonguardZ, 0x107313E0 +.global end_CmoonguardZ +.set end_CmoonguardZ, 0x107339D0 +.global CnatalyaZ +.set CnatalyaZ, 0x107339D0 +.global end_CnatalyaZ +.set end_CnatalyaZ, 0x10737290 +.global CnavyguardZ +.set CnavyguardZ, 0x10737290 +.global end_CnavyguardZ +.set end_CnavyguardZ, 0x10739970 +.global CoddjobZ +.set CoddjobZ, 0x10739970 +.global end_CoddjobZ +.set end_CoddjobZ, 0x1073CAA0 +.global ColiveguardZ +.set ColiveguardZ, 0x1073CAA0 +.global end_ColiveguardZ +.set end_ColiveguardZ, 0x1073F0F0 +.global CorumovZ +.set CorumovZ, 0x1073F0F0 +.global end_CorumovZ +.set end_CorumovZ, 0x10742520 +.global CpilotZ +.set CpilotZ, 0x10742520 +.global end_CpilotZ +.set end_CpilotZ, 0x107455A0 +.global CredmanZ +.set CredmanZ, 0x107455A0 +.global end_CredmanZ +.set end_CredmanZ, 0x10747CD0 +.global CrusguardZ +.set CrusguardZ, 0x10747CD0 +.global end_CrusguardZ +.set end_CrusguardZ, 0x10749900 +.global CsnowbondZ +.set CsnowbondZ, 0x10749900 +.global end_CsnowbondZ +.set end_CsnowbondZ, 0x1074CC30 +.global CsnowguardZ +.set CsnowguardZ, 0x1074CC30 +.global end_CsnowguardZ +.set end_CsnowguardZ, 0x1074F8B0 +.global CspicebondZ +.set CspicebondZ, 0x1074F8B0 +.global end_CspicebondZ +.set end_CspicebondZ, 0x107531D0 +.global Csuit_lf_handZ +.set Csuit_lf_handZ, 0x107531D0 +.global end_Csuit_lf_handZ +.set end_Csuit_lf_handZ, 0x107563F0 +.global CsuitbondZ +.set CsuitbondZ, 0x107563F0 +.global end_CsuitbondZ +.set end_CsuitbondZ, 0x10759180 +.global CtechmanZ +.set CtechmanZ, 0x10759180 +.global end_CtechmanZ +.set end_CtechmanZ, 0x1075B830 +.global CtechwomanZ +.set CtechwomanZ, 0x1075B830 +.global end_CtechwomanZ +.set end_CtechwomanZ, 0x1075D820 +.global CtimberbondZ +.set CtimberbondZ, 0x1075D820 +.global end_CtimberbondZ +.set end_CtimberbondZ, 0x10760550 +.global CtrevelyanZ +.set CtrevelyanZ, 0x10760550 +.global end_CtrevelyanZ +.set end_CtrevelyanZ, 0x10763D20 +.global CtrevguardZ +.set CtrevguardZ, 0x10763D20 +.global end_CtrevguardZ +.set end_CtrevguardZ, 0x10766330 +.global CvalentinZ +.set CvalentinZ, 0x10766330 +.global end_CvalentinZ +.set end_CvalentinZ, 0x107692A0 +.global CxeniaZ +.set CxeniaZ, 0x107692A0 +.global end_CxeniaZ +.set end_CxeniaZ, 0x1076CC90 +.global Gak47Z +.set Gak47Z, 0x1076CC90 +.global end_Gak47Z +.set end_Gak47Z, 0x1076D6A0 +.global GaudiotapeZ +.set GaudiotapeZ, 0x1076D6A0 +.global end_GaudiotapeZ +.set end_GaudiotapeZ, 0x1076DA30 +.global GautoshotZ +.set GautoshotZ, 0x1076DA30 +.global end_GautoshotZ +.set end_GautoshotZ, 0x1076F240 +.global GblackboxZ +.set GblackboxZ, 0x1076F240 +.global end_GblackboxZ +.set end_GblackboxZ, 0x1076F840 +.global GblueprintsZ +.set GblueprintsZ, 0x1076F840 +.global end_GblueprintsZ +.set end_GblueprintsZ, 0x1076F940 +.global GbombcaseZ +.set GbombcaseZ, 0x1076F940 +.global end_GbombcaseZ +.set end_GbombcaseZ, 0x107700D0 +.global GbombdefuserZ +.set GbombdefuserZ, 0x107700D0 +.global end_GbombdefuserZ +.set end_GbombdefuserZ, 0x107706C0 +.global GbriefcaseZ +.set GbriefcaseZ, 0x107706C0 +.global end_GbriefcaseZ +.set end_GbriefcaseZ, 0x10770E50 +.global GbugZ +.set GbugZ, 0x10770E50 +.global end_GbugZ +.set end_GbugZ, 0x107717C0 +.global GbugdetectorZ +.set GbugdetectorZ, 0x107717C0 +.global end_GbugdetectorZ +.set end_GbugdetectorZ, 0x10771B10 +.global GbungeeZ +.set GbungeeZ, 0x10771B10 +.global end_GbungeeZ +.set end_GbungeeZ, 0x10771E60 +.global GcameraZ +.set GcameraZ, 0x10771E60 +.global end_GcameraZ +.set end_GcameraZ, 0x107722E0 +.global GcartblueZ +.set GcartblueZ, 0x107722E0 +.global end_GcartblueZ +.set end_GcartblueZ, 0x10772540 +.global GcartridgeZ +.set GcartridgeZ, 0x10772540 +.global end_GcartridgeZ +.set end_GcartridgeZ, 0x10772670 +.global GcartrifleZ +.set GcartrifleZ, 0x10772670 +.global end_GcartrifleZ +.set end_GcartrifleZ, 0x10772880 +.global GcartshellZ +.set GcartshellZ, 0x10772880 +.global end_GcartshellZ +.set end_GcartshellZ, 0x10772A80 +.global GcircuitboardZ +.set GcircuitboardZ, 0x10772A80 +.global end_GcircuitboardZ +.set end_GcircuitboardZ, 0x10772BC0 +.global GclipboardZ +.set GclipboardZ, 0x10772BC0 +.global end_GclipboardZ +.set end_GclipboardZ, 0x10772DB0 +.global GcreditcardZ +.set GcreditcardZ, 0x10772DB0 +.global end_GcreditcardZ +.set end_GcreditcardZ, 0x10773100 +.global GdarkglassesZ +.set GdarkglassesZ, 0x10773100 +.global end_GdarkglassesZ +.set end_GdarkglassesZ, 0x10773450 +.global GdatathiefZ +.set GdatathiefZ, 0x10773450 +.global end_GdatathiefZ +.set end_GdatathiefZ, 0x10773590 +.global GdattapeZ +.set GdattapeZ, 0x10773590 +.global end_GdattapeZ +.set end_GdattapeZ, 0x10773700 +.global GdoordecoderZ +.set GdoordecoderZ, 0x10773700 +.global end_GdoordecoderZ +.set end_GdoordecoderZ, 0x10773C80 +.global GdoorexploderZ +.set GdoorexploderZ, 0x10773C80 +.global end_GdoorexploderZ +.set end_GdoorexploderZ, 0x10773FD0 +.global GdossierredZ +.set GdossierredZ, 0x10773FD0 +.global end_GdossierredZ +.set end_GdossierredZ, 0x10774330 +.global GdynamiteZ +.set GdynamiteZ, 0x10774330 +.global end_GdynamiteZ +.set end_GdynamiteZ, 0x10774680 +.global GexplosivefloppyZ +.set GexplosivefloppyZ, 0x10774680 +.global end_GexplosivefloppyZ +.set end_GexplosivefloppyZ, 0x107748D0 +.global GexplosivepenZ +.set GexplosivepenZ, 0x107748D0 +.global end_GexplosivepenZ +.set end_GexplosivepenZ, 0x10774C20 +.global GextinguisherZ +.set GextinguisherZ, 0x10774C20 +.global end_GextinguisherZ +.set end_GextinguisherZ, 0x10775410 +.global GfingergunZ +.set GfingergunZ, 0x10775410 +.global end_GfingergunZ +.set end_GfingergunZ, 0x10775760 +.global GfistZ +.set GfistZ, 0x10775760 +.global end_GfistZ +.set end_GfistZ, 0x10776E60 +.global GflarepistolZ +.set GflarepistolZ, 0x10776E60 +.global end_GflarepistolZ +.set end_GflarepistolZ, 0x107771B0 +.global Gfnp90Z +.set Gfnp90Z, 0x107771B0 +.global end_Gfnp90Z +.set end_Gfnp90Z, 0x10777E50 +.global GgaskeyringZ +.set GgaskeyringZ, 0x10777E50 +.global end_GgaskeyringZ +.set end_GgaskeyringZ, 0x10778880 +.global GgoldbarZ +.set GgoldbarZ, 0x10778880 +.global end_GgoldbarZ +.set end_GgoldbarZ, 0x10778BD0 +.global GgoldeneyekeyZ +.set GgoldeneyekeyZ, 0x10778BD0 +.global end_GgoldeneyekeyZ +.set end_GgoldeneyekeyZ, 0x10779580 +.global GgoldengunZ +.set GgoldengunZ, 0x10779580 +.global end_GgoldengunZ +.set end_GgoldengunZ, 0x1077AD60 +.global GgoldwppkZ +.set GgoldwppkZ, 0x1077AD60 +.global end_GgoldwppkZ +.set end_GgoldwppkZ, 0x1077C6C0 +.global GgrenadeZ +.set GgrenadeZ, 0x1077C6C0 +.global end_GgrenadeZ +.set end_GgrenadeZ, 0x1077D0F0 +.global GgrenadelaunchZ +.set GgrenadelaunchZ, 0x1077D0F0 +.global end_GgrenadelaunchZ +.set end_GgrenadelaunchZ, 0x1077E170 +.global GheroinZ +.set GheroinZ, 0x1077E170 +.global end_GheroinZ +.set end_GheroinZ, 0x1077E4C0 +.global GjoypadZ +.set GjoypadZ, 0x1077E4C0 +.global end_GjoypadZ +.set end_GjoypadZ, 0x10780370 +.global GkeyanalysercaseZ +.set GkeyanalysercaseZ, 0x10780370 +.global end_GkeyanalysercaseZ +.set end_GkeyanalysercaseZ, 0x10780B00 +.global GkeyboltZ +.set GkeyboltZ, 0x10780B00 +.global end_GkeyboltZ +.set end_GkeyboltZ, 0x107814F0 +.global GkeycardZ +.set GkeycardZ, 0x107814F0 +.global end_GkeycardZ +.set end_GkeycardZ, 0x10781620 +.global GkeyyaleZ +.set GkeyyaleZ, 0x10781620 +.global end_GkeyyaleZ +.set end_GkeyyaleZ, 0x10782370 +.global GknifeZ +.set GknifeZ, 0x10782370 +.global end_GknifeZ +.set end_GknifeZ, 0x10783E40 +.global GlaserZ +.set GlaserZ, 0x10783E40 +.global end_GlaserZ +.set end_GlaserZ, 0x10784C30 +.global GlectreZ +.set GlectreZ, 0x10784C30 +.global end_GlectreZ +.set end_GlectreZ, 0x10784F80 +.global GlockexploderZ +.set GlockexploderZ, 0x10784F80 +.global end_GlockexploderZ +.set end_GlockexploderZ, 0x107852D0 +.global Gm16Z +.set Gm16Z, 0x107852D0 +.global end_Gm16Z +.set end_Gm16Z, 0x10785CF0 +.global GmapZ +.set GmapZ, 0x10785CF0 +.global end_GmapZ +.set end_GmapZ, 0x10785DE0 +.global GmicrocameraZ +.set GmicrocameraZ, 0x10785DE0 +.global end_GmicrocameraZ +.set end_GmicrocameraZ, 0x10786420 +.global GmicrocodeZ +.set GmicrocodeZ, 0x10786420 +.global end_GmicrocodeZ +.set end_GmicrocodeZ, 0x10786770 +.global GmicrofilmZ +.set GmicrofilmZ, 0x10786770 +.global end_GmicrofilmZ +.set end_GmicrofilmZ, 0x10786AC0 +.global GmoneyZ +.set GmoneyZ, 0x10786AC0 +.global end_GmoneyZ +.set end_GmoneyZ, 0x10786E10 +.global Gmp5kZ +.set Gmp5kZ, 0x10786E10 +.global end_Gmp5kZ +.set end_Gmp5kZ, 0x107879F0 +.global Gmp5ksilZ +.set Gmp5ksilZ, 0x107879F0 +.global end_Gmp5ksilZ +.set end_Gmp5ksilZ, 0x107886F0 +.global GpitongunZ +.set GpitongunZ, 0x107886F0 +.global end_GpitongunZ +.set end_GpitongunZ, 0x10788A40 +.global GplansZ +.set GplansZ, 0x10788A40 +.global end_GplansZ +.set end_GplansZ, 0x10788C10 +.global GplastiqueZ +.set GplastiqueZ, 0x10788C10 +.global end_GplastiqueZ +.set end_GplastiqueZ, 0x10788F60 +.global GpolarizedglassesZ +.set GpolarizedglassesZ, 0x10788F60 +.global end_GpolarizedglassesZ +.set end_GpolarizedglassesZ, 0x107894C0 +.global GproximitymineZ +.set GproximitymineZ, 0x107894C0 +.global end_GproximitymineZ +.set end_GproximitymineZ, 0x10789CB0 +.global GremotemineZ +.set GremotemineZ, 0x10789CB0 +.global end_GremotemineZ +.set end_GremotemineZ, 0x1078A670 +.global GrocketlaunchZ +.set GrocketlaunchZ, 0x1078A670 +.global end_GrocketlaunchZ +.set end_GrocketlaunchZ, 0x1078B890 +.global GrugerZ +.set GrugerZ, 0x1078B890 +.global end_GrugerZ +.set end_GrugerZ, 0x1078D620 +.global GsafecrackercaseZ +.set GsafecrackercaseZ, 0x1078D620 +.global end_GsafecrackercaseZ +.set end_GsafecrackercaseZ, 0x1078DDB0 +.global GshotgunZ +.set GshotgunZ, 0x1078DDB0 +.global end_GshotgunZ +.set end_GshotgunZ, 0x1078EC90 +.global GsilverwppkZ +.set GsilverwppkZ, 0x1078EC90 +.global end_GsilverwppkZ +.set end_GsilverwppkZ, 0x107905F0 +.global GskorpionZ +.set GskorpionZ, 0x107905F0 +.global end_GskorpionZ +.set end_GskorpionZ, 0x107917F0 +.global GsniperrifleZ +.set GsniperrifleZ, 0x107917F0 +.global end_GsniperrifleZ +.set end_GsniperrifleZ, 0x10792860 +.global GspectreZ +.set GspectreZ, 0x10792860 +.global end_GspectreZ +.set end_GspectreZ, 0x107934E0 +.global GspooltapeZ +.set GspooltapeZ, 0x107934E0 +.global end_GspooltapeZ +.set end_GspooltapeZ, 0x10793830 +.global GspyfileZ +.set GspyfileZ, 0x10793830 +.global end_GspyfileZ +.set end_GspyfileZ, 0x10793B80 +.global GstafflistZ +.set GstafflistZ, 0x10793B80 +.global end_GstafflistZ +.set end_GstafflistZ, 0x10793D20 +.global GtaserZ +.set GtaserZ, 0x10793D20 +.global end_GtaserZ +.set end_GtaserZ, 0x10795B80 +.global GthrowknifeZ +.set GthrowknifeZ, 0x10795B80 +.global end_GthrowknifeZ +.set end_GthrowknifeZ, 0x10797670 +.global GtimedmineZ +.set GtimedmineZ, 0x10797670 +.global end_GtimedmineZ +.set end_GtimedmineZ, 0x10798130 +.global GtriggerZ +.set GtriggerZ, 0x10798130 +.global end_GtriggerZ +.set end_GtriggerZ, 0x1079B530 +.global Gtt33Z +.set Gtt33Z, 0x1079B530 +.global end_Gtt33Z +.set end_Gtt33Z, 0x1079D050 +.global GuziZ +.set GuziZ, 0x1079D050 +.global end_GuziZ +.set end_GuziZ, 0x1079D960 +.global GvideotapeZ +.set GvideotapeZ, 0x1079D960 +.global end_GvideotapeZ +.set end_GvideotapeZ, 0x1079DB70 +.global GwatchcommunicatorZ +.set GwatchcommunicatorZ, 0x1079DB70 +.global end_GwatchcommunicatorZ +.set end_GwatchcommunicatorZ, 0x1079EFD0 +.global GwatchgeigercounterZ +.set GwatchgeigercounterZ, 0x1079EFD0 +.global end_GwatchgeigercounterZ +.set end_GwatchgeigercounterZ, 0x107A0430 +.global GwatchidentifierZ +.set GwatchidentifierZ, 0x107A0430 +.global end_GwatchidentifierZ +.set end_GwatchidentifierZ, 0x107A1890 +.global GwatchlaserZ +.set GwatchlaserZ, 0x107A1890 +.global end_GwatchlaserZ +.set end_GwatchlaserZ, 0x107A4C90 +.global GwatchmagnetattractZ +.set GwatchmagnetattractZ, 0x107A4C90 +.global end_GwatchmagnetattractZ +.set end_GwatchmagnetattractZ, 0x107A60E0 +.global GwatchmagnetrepelZ +.set GwatchmagnetrepelZ, 0x107A60E0 +.global end_GwatchmagnetrepelZ +.set end_GwatchmagnetrepelZ, 0x107A7540 +.global GweaponcaseZ +.set GweaponcaseZ, 0x107A7540 +.global end_GweaponcaseZ +.set end_GweaponcaseZ, 0x107A7CD0 +.global GwppkZ +.set GwppkZ, 0x107A7CD0 +.global end_GwppkZ +.set end_GwppkZ, 0x107A9960 +.global GwppksilZ +.set GwppksilZ, 0x107A9960 +.global end_GwppksilZ +.set end_GwppksilZ, 0x107AB6A0 +.global GwristdartZ +.set GwristdartZ, 0x107AB6A0 +.global end_GwristdartZ +.set end_GwristdartZ, 0x107AB9F0 +.global PICBMZ +.set PICBMZ, 0x107AB9F0 +.global end_PICBMZ +.set end_PICBMZ, 0x107ADF70 +.global PICBM_noseZ +.set PICBM_noseZ, 0x107ADF70 +.global end_PICBM_noseZ +.set end_PICBM_noseZ, 0x107AE720 +.global Pak47magZ +.set Pak47magZ, 0x107AE720 +.global end_Pak47magZ +.set end_Pak47magZ, 0x107AE900 +.global Palarm1Z +.set Palarm1Z, 0x107AE900 +.global end_Palarm1Z +.set end_Palarm1Z, 0x107AEA60 +.global Palarm2Z +.set Palarm2Z, 0x107AEA60 +.global end_Palarm2Z +.set end_Palarm2Z, 0x107AEC00 +.global Pammo_crate1Z +.set Pammo_crate1Z, 0x107AEC00 +.global end_Pammo_crate1Z +.set end_Pammo_crate1Z, 0x107AEE40 +.global Pammo_crate2Z +.set Pammo_crate2Z, 0x107AEE40 +.global end_Pammo_crate2Z +.set end_Pammo_crate2Z, 0x107AF080 +.global Pammo_crate3Z +.set Pammo_crate3Z, 0x107AF080 +.global end_Pammo_crate3Z +.set end_Pammo_crate3Z, 0x107AF2D0 +.global Pammo_crate4Z +.set Pammo_crate4Z, 0x107AF2D0 +.global end_Pammo_crate4Z +.set end_Pammo_crate4Z, 0x107AF540 +.global Pammo_crate5Z +.set Pammo_crate5Z, 0x107AF540 +.global end_Pammo_crate5Z +.set end_Pammo_crate5Z, 0x107AF800 +.global PapcZ +.set PapcZ, 0x107AF800 +.global end_PapcZ +.set end_PapcZ, 0x107B1460 +.global Parchsecdoor1Z +.set Parchsecdoor1Z, 0x107B1460 +.global end_Parchsecdoor1Z +.set end_Parchsecdoor1Z, 0x107B1640 +.global Parchsecdoor2Z +.set Parchsecdoor2Z, 0x107B1640 +.global end_Parchsecdoor2Z +.set end_Parchsecdoor2Z, 0x107B1810 +.global ParticZ +.set ParticZ, 0x107B1810 +.global end_ParticZ +.set end_ParticZ, 0x107B2610 +.global PartictrailerZ +.set PartictrailerZ, 0x107B2610 +.global end_PartictrailerZ +.set end_PartictrailerZ, 0x107B2F20 +.global PbarricadeZ +.set PbarricadeZ, 0x107B2F20 +.global end_PbarricadeZ +.set end_PbarricadeZ, 0x107B3160 +.global Pbin1Z +.set Pbin1Z, 0x107B3160 +.global end_Pbin1Z +.set end_Pbin1Z, 0x107B34B0 +.global Pblotter1Z +.set Pblotter1Z, 0x107B34B0 +.global end_Pblotter1Z +.set end_Pblotter1Z, 0x107B3590 +.global PbodyarmourZ +.set PbodyarmourZ, 0x107B3590 +.global end_PbodyarmourZ +.set end_PbodyarmourZ, 0x107B3A30 +.global PbodyarmourvestZ +.set PbodyarmourvestZ, 0x107B3A30 +.global end_PbodyarmourvestZ +.set end_PbodyarmourvestZ, 0x107B3E50 +.global PbollardZ +.set PbollardZ, 0x107B3E50 +.global end_PbollardZ +.set end_PbollardZ, 0x107B4050 +.global PbombZ +.set PbombZ, 0x107B4050 +.global end_PbombZ +.set end_PbombZ, 0x107B41C0 +.global Pbook1Z +.set Pbook1Z, 0x107B41C0 +.global end_Pbook1Z +.set end_Pbook1Z, 0x107B4350 +.global Pbookshelf1Z +.set Pbookshelf1Z, 0x107B4350 +.global end_Pbookshelf1Z +.set end_Pbookshelf1Z, 0x107B4A40 +.global Pborg_crateZ +.set Pborg_crateZ, 0x107B4A40 +.global end_Pborg_crateZ +.set end_Pborg_crateZ, 0x107B4BB0 +.global PboxcartridgesZ +.set PboxcartridgesZ, 0x107B4BB0 +.global end_PboxcartridgesZ +.set end_PboxcartridgesZ, 0x107B4DB0 +.global Pboxes2x4Z +.set Pboxes2x4Z, 0x107B4DB0 +.global end_Pboxes2x4Z +.set end_Pboxes2x4Z, 0x107B51E0 +.global Pboxes3x4Z +.set Pboxes3x4Z, 0x107B51E0 +.global end_Pboxes3x4Z +.set end_Pboxes3x4Z, 0x107B5620 +.global Pboxes4x4Z +.set Pboxes4x4Z, 0x107B5620 +.global end_Pboxes4x4Z +.set end_Pboxes4x4Z, 0x107B5C80 +.global PbrakeunitZ +.set PbrakeunitZ, 0x107B5C80 +.global end_PbrakeunitZ +.set end_PbrakeunitZ, 0x107B5FF0 +.global Pbridge_console1aZ +.set Pbridge_console1aZ, 0x107B5FF0 +.global end_Pbridge_console1aZ +.set end_Pbridge_console1aZ, 0x107B6570 +.global Pbridge_console1bZ +.set Pbridge_console1bZ, 0x107B6570 +.global end_Pbridge_console1bZ +.set end_Pbridge_console1bZ, 0x107B6AD0 +.global Pbridge_console2aZ +.set Pbridge_console2aZ, 0x107B6AD0 +.global end_Pbridge_console2aZ +.set end_Pbridge_console2aZ, 0x107B7050 +.global Pbridge_console2bZ +.set Pbridge_console2bZ, 0x107B7050 +.global end_Pbridge_console2bZ +.set end_Pbridge_console2bZ, 0x107B7540 +.global Pbridge_console3aZ +.set Pbridge_console3aZ, 0x107B7540 +.global end_Pbridge_console3aZ +.set end_Pbridge_console3aZ, 0x107B7A90 +.global Pbridge_console3bZ +.set Pbridge_console3bZ, 0x107B7A90 +.global end_Pbridge_console3bZ +.set end_Pbridge_console3bZ, 0x107B8020 +.global PcarbmwZ +.set PcarbmwZ, 0x107B8020 +.global end_PcarbmwZ +.set end_PcarbmwZ, 0x107B8D00 +.global Pcard_box1Z +.set Pcard_box1Z, 0x107B8D00 +.global end_Pcard_box1Z +.set end_Pcard_box1Z, 0x107B8F00 +.global Pcard_box2Z +.set Pcard_box2Z, 0x107B8F00 +.global end_Pcard_box2Z +.set end_Pcard_box2Z, 0x107B9140 +.global Pcard_box3Z +.set Pcard_box3Z, 0x107B9140 +.global end_Pcard_box3Z +.set end_Pcard_box3Z, 0x107B9330 +.global Pcard_box4_lgZ +.set Pcard_box4_lgZ, 0x107B9330 +.global end_Pcard_box4_lgZ +.set end_Pcard_box4_lgZ, 0x107B94E0 +.global Pcard_box5_lgZ +.set Pcard_box5_lgZ, 0x107B94E0 +.global end_Pcard_box5_lgZ +.set end_Pcard_box5_lgZ, 0x107B96E0 +.global Pcard_box6_lgZ +.set Pcard_box6_lgZ, 0x107B96E0 +.global end_Pcard_box6_lgZ +.set end_Pcard_box6_lgZ, 0x107B98D0 +.global PcarescortZ +.set PcarescortZ, 0x107B98D0 +.global end_PcarescortZ +.set end_PcarescortZ, 0x107BA4D0 +.global PcargolfZ +.set PcargolfZ, 0x107BA4D0 +.global end_PcargolfZ +.set end_PcargolfZ, 0x107BB100 +.global PcarweirdZ +.set PcarweirdZ, 0x107BB100 +.global end_PcarweirdZ +.set end_PcarweirdZ, 0x107BC240 +.global PcarzilZ +.set PcarzilZ, 0x107BC240 +.global end_PcarzilZ +.set end_PcarzilZ, 0x107BD840 +.global PcctvZ +.set PcctvZ, 0x107BD840 +.global end_PcctvZ +.set end_PcctvZ, 0x107BDBC0 +.global PchraudiotapeZ +.set PchraudiotapeZ, 0x107BDBC0 +.global end_PchraudiotapeZ +.set end_PchraudiotapeZ, 0x107BE120 +.global PchrautoshotZ +.set PchrautoshotZ, 0x107BE120 +.global end_PchrautoshotZ +.set end_PchrautoshotZ, 0x107BE480 +.global PchrblackboxZ +.set PchrblackboxZ, 0x107BE480 +.global end_PchrblackboxZ +.set end_PchrblackboxZ, 0x107BED00 +.global PchrblueprintsZ +.set PchrblueprintsZ, 0x107BED00 +.global end_PchrblueprintsZ +.set end_PchrblueprintsZ, 0x107BEE50 +.global PchrbombcaseZ +.set PchrbombcaseZ, 0x107BEE50 +.global end_PchrbombcaseZ +.set end_PchrbombcaseZ, 0x107BF040 +.global PchrbombdefuserZ +.set PchrbombdefuserZ, 0x107BF040 +.global end_PchrbombdefuserZ +.set end_PchrbombdefuserZ, 0x107BF920 +.global PchrbriefcaseZ +.set PchrbriefcaseZ, 0x107BF920 +.global end_PchrbriefcaseZ +.set end_PchrbriefcaseZ, 0x107BFAB0 +.global PchrbugZ +.set PchrbugZ, 0x107BFAB0 +.global end_PchrbugZ +.set end_PchrbugZ, 0x107C0860 +.global PchrbugdetectorZ +.set PchrbugdetectorZ, 0x107C0860 +.global end_PchrbugdetectorZ +.set end_PchrbugdetectorZ, 0x107C09D0 +.global PchrbungeeZ +.set PchrbungeeZ, 0x107C09D0 +.global end_PchrbungeeZ +.set end_PchrbungeeZ, 0x107C0B40 +.global PchrcameraZ +.set PchrcameraZ, 0x107C0B40 +.global end_PchrcameraZ +.set end_PchrcameraZ, 0x107C11D0 +.global PchrcircuitboardZ +.set PchrcircuitboardZ, 0x107C11D0 +.global end_PchrcircuitboardZ +.set end_PchrcircuitboardZ, 0x107C1370 +.global PchrclipboardZ +.set PchrclipboardZ, 0x107C1370 +.global end_PchrclipboardZ +.set end_PchrclipboardZ, 0x107C15F0 +.global PchrcreditcardZ +.set PchrcreditcardZ, 0x107C15F0 +.global end_PchrcreditcardZ +.set end_PchrcreditcardZ, 0x107C1760 +.global PchrdarkglassesZ +.set PchrdarkglassesZ, 0x107C1760 +.global end_PchrdarkglassesZ +.set end_PchrdarkglassesZ, 0x107C18D0 +.global PchrdatathiefZ +.set PchrdatathiefZ, 0x107C18D0 +.global end_PchrdatathiefZ +.set end_PchrdatathiefZ, 0x107C1A70 +.global PchrdattapeZ +.set PchrdattapeZ, 0x107C1A70 +.global end_PchrdattapeZ +.set end_PchrdattapeZ, 0x107C1C60 +.global PchrdoordecoderZ +.set PchrdoordecoderZ, 0x107C1C60 +.global end_PchrdoordecoderZ +.set end_PchrdoordecoderZ, 0x107C24C0 +.global PchrdoorexploderZ +.set PchrdoorexploderZ, 0x107C24C0 +.global end_PchrdoorexploderZ +.set end_PchrdoorexploderZ, 0x107C2630 +.global PchrdossierredZ +.set PchrdossierredZ, 0x107C2630 +.global end_PchrdossierredZ +.set end_PchrdossierredZ, 0x107C2B00 +.global PchrdynamiteZ +.set PchrdynamiteZ, 0x107C2B00 +.global end_PchrdynamiteZ +.set end_PchrdynamiteZ, 0x107C2C70 +.global PchrexplosivepenZ +.set PchrexplosivepenZ, 0x107C2C70 +.global end_PchrexplosivepenZ +.set end_PchrexplosivepenZ, 0x107C2DE0 +.global PchrextinguisherZ +.set PchrextinguisherZ, 0x107C2DE0 +.global end_PchrextinguisherZ +.set end_PchrextinguisherZ, 0x107C32E0 +.global PchrfingergunZ +.set PchrfingergunZ, 0x107C32E0 +.global end_PchrfingergunZ +.set end_PchrfingergunZ, 0x107C3450 +.global PchrflarepistolZ +.set PchrflarepistolZ, 0x107C3450 +.global end_PchrflarepistolZ +.set end_PchrflarepistolZ, 0x107C35C0 +.global Pchrfnp90Z +.set Pchrfnp90Z, 0x107C35C0 +.global end_Pchrfnp90Z +.set end_Pchrfnp90Z, 0x107C3A20 +.global PchrgaskeyringZ +.set PchrgaskeyringZ, 0x107C3A20 +.global end_PchrgaskeyringZ +.set end_PchrgaskeyringZ, 0x107C4930 +.global PchrgoldbarZ +.set PchrgoldbarZ, 0x107C4930 +.global end_PchrgoldbarZ +.set end_PchrgoldbarZ, 0x107C4AA0 +.global PchrgoldenZ +.set PchrgoldenZ, 0x107C4AA0 +.global end_PchrgoldenZ +.set end_PchrgoldenZ, 0x107C4D10 +.global PchrgoldeneyekeyZ +.set PchrgoldeneyekeyZ, 0x107C4D10 +.global end_PchrgoldeneyekeyZ +.set end_PchrgoldeneyekeyZ, 0x107C5BB0 +.global PchrgoldwppkZ +.set PchrgoldwppkZ, 0x107C5BB0 +.global end_PchrgoldwppkZ +.set end_PchrgoldwppkZ, 0x107C5D20 +.global PchrgrenadeZ +.set PchrgrenadeZ, 0x107C5D20 +.global end_PchrgrenadeZ +.set end_PchrgrenadeZ, 0x107C6090 +.global PchrgrenadelaunchZ +.set PchrgrenadelaunchZ, 0x107C6090 +.global end_PchrgrenadelaunchZ +.set end_PchrgrenadelaunchZ, 0x107C6420 +.global PchrgrenaderoundZ +.set PchrgrenaderoundZ, 0x107C6420 +.global end_PchrgrenaderoundZ +.set end_PchrgrenaderoundZ, 0x107C6690 +.global PchrheroinZ +.set PchrheroinZ, 0x107C6690 +.global end_PchrheroinZ +.set end_PchrheroinZ, 0x107C6800 +.global PchrkalashZ +.set PchrkalashZ, 0x107C6800 +.global end_PchrkalashZ +.set end_PchrkalashZ, 0x107C6BF0 +.global PchrkeyanalysercaseZ +.set PchrkeyanalysercaseZ, 0x107C6BF0 +.global end_PchrkeyanalysercaseZ +.set end_PchrkeyanalysercaseZ, 0x107C6DE0 +.global PchrkeyboltZ +.set PchrkeyboltZ, 0x107C6DE0 +.global end_PchrkeyboltZ +.set end_PchrkeyboltZ, 0x107C7C80 +.global PchrkeyyaleZ +.set PchrkeyyaleZ, 0x107C7C80 +.global end_PchrkeyyaleZ +.set end_PchrkeyyaleZ, 0x107C90E0 +.global PchrknifeZ +.set PchrknifeZ, 0x107C90E0 +.global end_PchrknifeZ +.set end_PchrknifeZ, 0x107C92E0 +.global PchrlaserZ +.set PchrlaserZ, 0x107C92E0 +.global end_PchrlaserZ +.set end_PchrlaserZ, 0x107C96A0 +.global PchrlectreZ +.set PchrlectreZ, 0x107C96A0 +.global end_PchrlectreZ +.set end_PchrlectreZ, 0x107C9810 +.global PchrlockexploderZ +.set PchrlockexploderZ, 0x107C9810 +.global end_PchrlockexploderZ +.set end_PchrlockexploderZ, 0x107C9980 +.global Pchrm16Z +.set Pchrm16Z, 0x107C9980 +.global end_Pchrm16Z +.set end_Pchrm16Z, 0x107C9D50 +.global PchrmapZ +.set PchrmapZ, 0x107C9D50 +.global end_PchrmapZ +.set end_PchrmapZ, 0x107C9EA0 +.global PchrmicrocameraZ +.set PchrmicrocameraZ, 0x107C9EA0 +.global end_PchrmicrocameraZ +.set end_PchrmicrocameraZ, 0x107CA790 +.global PchrmicrocodeZ +.set PchrmicrocodeZ, 0x107CA790 +.global end_PchrmicrocodeZ +.set end_PchrmicrocodeZ, 0x107CA900 +.global PchrmicrofilmZ +.set PchrmicrofilmZ, 0x107CA900 +.global end_PchrmicrofilmZ +.set end_PchrmicrofilmZ, 0x107CAA70 +.global PchrmoneyZ +.set PchrmoneyZ, 0x107CAA70 +.global end_PchrmoneyZ +.set end_PchrmoneyZ, 0x107CABE0 +.global Pchrmp5kZ +.set Pchrmp5kZ, 0x107CABE0 +.global end_Pchrmp5kZ +.set end_Pchrmp5kZ, 0x107CAF60 +.global Pchrmp5ksilZ +.set Pchrmp5ksilZ, 0x107CAF60 +.global end_Pchrmp5ksilZ +.set end_Pchrmp5ksilZ, 0x107CB370 +.global PchrpitongunZ +.set PchrpitongunZ, 0x107CB370 +.global end_PchrpitongunZ +.set end_PchrpitongunZ, 0x107CB4E0 +.global PchrplansZ +.set PchrplansZ, 0x107CB4E0 +.global end_PchrplansZ +.set end_PchrplansZ, 0x107CB770 +.global PchrplastiqueZ +.set PchrplastiqueZ, 0x107CB770 +.global end_PchrplastiqueZ +.set end_PchrplastiqueZ, 0x107CBBD0 +.global PchrpolarizedglassesZ +.set PchrpolarizedglassesZ, 0x107CBBD0 +.global end_PchrpolarizedglassesZ +.set end_PchrpolarizedglassesZ, 0x107CC490 +.global PchrproximitymineZ +.set PchrproximitymineZ, 0x107CC490 +.global end_PchrproximitymineZ +.set end_PchrproximitymineZ, 0x107CC8F0 +.global PchrremotemineZ +.set PchrremotemineZ, 0x107CC8F0 +.global end_PchrremotemineZ +.set end_PchrremotemineZ, 0x107CCD50 +.global PchrrocketZ +.set PchrrocketZ, 0x107CCD50 +.global end_PchrrocketZ +.set end_PchrrocketZ, 0x107CD300 +.global PchrrocketlaunchZ +.set PchrrocketlaunchZ, 0x107CD300 +.global end_PchrrocketlaunchZ +.set end_PchrrocketlaunchZ, 0x107CD6E0 +.global PchrrugerZ +.set PchrrugerZ, 0x107CD6E0 +.global end_PchrrugerZ +.set end_PchrrugerZ, 0x107CDAC0 +.global PchrsafecrackercaseZ +.set PchrsafecrackercaseZ, 0x107CDAC0 +.global end_PchrsafecrackercaseZ +.set end_PchrsafecrackercaseZ, 0x107CDCB0 +.global PchrshotgunZ +.set PchrshotgunZ, 0x107CDCB0 +.global end_PchrshotgunZ +.set end_PchrshotgunZ, 0x107CE000 +.global PchrsilverwppkZ +.set PchrsilverwppkZ, 0x107CE000 +.global end_PchrsilverwppkZ +.set end_PchrsilverwppkZ, 0x107CE170 +.global PchrskorpionZ +.set PchrskorpionZ, 0x107CE170 +.global end_PchrskorpionZ +.set end_PchrskorpionZ, 0x107CE4F0 +.global PchrsniperrifleZ +.set PchrsniperrifleZ, 0x107CE4F0 +.global end_PchrsniperrifleZ +.set end_PchrsniperrifleZ, 0x107CE880 +.global PchrspectreZ +.set PchrspectreZ, 0x107CE880 +.global end_PchrspectreZ +.set end_PchrspectreZ, 0x107CEBF0 +.global PchrspooltapeZ +.set PchrspooltapeZ, 0x107CEBF0 +.global end_PchrspooltapeZ +.set end_PchrspooltapeZ, 0x107CED60 +.global PchrspyfileZ +.set PchrspyfileZ, 0x107CED60 +.global end_PchrspyfileZ +.set end_PchrspyfileZ, 0x107CEED0 +.global PchrstafflistZ +.set PchrstafflistZ, 0x107CEED0 +.global end_PchrstafflistZ +.set end_PchrstafflistZ, 0x107CF0F0 +.global PchrtesttubeZ +.set PchrtesttubeZ, 0x107CF0F0 +.global end_PchrtesttubeZ +.set end_PchrtesttubeZ, 0x107CF2B0 +.global PchrthrowknifeZ +.set PchrthrowknifeZ, 0x107CF2B0 +.global end_PchrthrowknifeZ +.set end_PchrthrowknifeZ, 0x107CF4D0 +.global PchrtimedmineZ +.set PchrtimedmineZ, 0x107CF4D0 +.global end_PchrtimedmineZ +.set end_PchrtimedmineZ, 0x107CFA00 +.global Pchrtt33Z +.set Pchrtt33Z, 0x107CFA00 +.global end_Pchrtt33Z +.set end_Pchrtt33Z, 0x107CFC90 +.global PchruziZ +.set PchruziZ, 0x107CFC90 +.global end_PchruziZ +.set end_PchruziZ, 0x107CFF60 +.global PchrvideotapeZ +.set PchrvideotapeZ, 0x107CFF60 +.global end_PchrvideotapeZ +.set end_PchrvideotapeZ, 0x107D0230 +.global PchrweaponcaseZ +.set PchrweaponcaseZ, 0x107D0230 +.global end_PchrweaponcaseZ +.set end_PchrweaponcaseZ, 0x107D0430 +.global PchrwppkZ +.set PchrwppkZ, 0x107D0430 +.global end_PchrwppkZ +.set end_PchrwppkZ, 0x107D0670 +.global PchrwppksilZ +.set PchrwppksilZ, 0x107D0670 +.global end_PchrwppksilZ +.set end_PchrwppksilZ, 0x107D0950 +.global PchrwristdartZ +.set PchrwristdartZ, 0x107D0950 +.global end_PchrwristdartZ +.set end_PchrwristdartZ, 0x107D0AC0 +.global Pconsole1Z +.set Pconsole1Z, 0x107D0AC0 +.global end_Pconsole1Z +.set end_Pconsole1Z, 0x107D1140 +.global Pconsole2Z +.set Pconsole2Z, 0x107D1140 +.global end_Pconsole2Z +.set end_Pconsole2Z, 0x107D17C0 +.global Pconsole3Z +.set Pconsole3Z, 0x107D17C0 +.global end_Pconsole3Z +.set end_Pconsole3Z, 0x107D1E50 +.global Pconsole_sev2aZ +.set Pconsole_sev2aZ, 0x107D1E50 +.global end_Pconsole_sev2aZ +.set end_Pconsole_sev2aZ, 0x107D2270 +.global Pconsole_sev2bZ +.set Pconsole_sev2bZ, 0x107D2270 +.global end_Pconsole_sev2bZ +.set end_Pconsole_sev2bZ, 0x107D2730 +.global Pconsole_sev2cZ +.set Pconsole_sev2cZ, 0x107D2730 +.global end_Pconsole_sev2cZ +.set end_Pconsole_sev2cZ, 0x107D2B70 +.global Pconsole_sev2dZ +.set Pconsole_sev2dZ, 0x107D2B70 +.global end_Pconsole_sev2dZ +.set end_Pconsole_sev2dZ, 0x107D2FA0 +.global Pconsole_sev_GEaZ +.set Pconsole_sev_GEaZ, 0x107D2FA0 +.global end_Pconsole_sev_GEaZ +.set end_Pconsole_sev_GEaZ, 0x107D33D0 +.global Pconsole_sev_GEbZ +.set Pconsole_sev_GEbZ, 0x107D33D0 +.global end_Pconsole_sev_GEbZ +.set end_Pconsole_sev_GEbZ, 0x107D3800 +.global Pconsole_sevaZ +.set Pconsole_sevaZ, 0x107D3800 +.global end_Pconsole_sevaZ +.set end_Pconsole_sevaZ, 0x107D3C80 +.global Pconsole_sevbZ +.set Pconsole_sevbZ, 0x107D3C80 +.global end_Pconsole_sevbZ +.set end_Pconsole_sevbZ, 0x107D40F0 +.global Pconsole_sevcZ +.set Pconsole_sevcZ, 0x107D40F0 +.global end_Pconsole_sevcZ +.set end_Pconsole_sevcZ, 0x107D4520 +.global Pconsole_sevdZ +.set Pconsole_sevdZ, 0x107D4520 +.global end_Pconsole_sevdZ +.set end_Pconsole_sevdZ, 0x107D4950 +.global Pcryptdoor1aZ +.set Pcryptdoor1aZ, 0x107D4950 +.global end_Pcryptdoor1aZ +.set end_Pcryptdoor1aZ, 0x107D4AE0 +.global Pcryptdoor1bZ +.set Pcryptdoor1bZ, 0x107D4AE0 +.global end_Pcryptdoor1bZ +.set end_Pcryptdoor1bZ, 0x107D4C70 +.global Pcryptdoor2aZ +.set Pcryptdoor2aZ, 0x107D4C70 +.global end_Pcryptdoor2aZ +.set end_Pcryptdoor2aZ, 0x107D4E00 +.global Pcryptdoor2bZ +.set Pcryptdoor2bZ, 0x107D4E00 +.global end_Pcryptdoor2bZ +.set end_Pcryptdoor2bZ, 0x107D4F90 +.global Pcryptdoor3Z +.set Pcryptdoor3Z, 0x107D4F90 +.global end_Pcryptdoor3Z +.set end_Pcryptdoor3Z, 0x107D5200 +.global Pcryptdoor4Z +.set Pcryptdoor4Z, 0x107D5200 +.global end_Pcryptdoor4Z +.set end_Pcryptdoor4Z, 0x107D5380 +.global PdamchaindoorZ +.set PdamchaindoorZ, 0x107D5380 +.global end_PdamchaindoorZ +.set end_PdamchaindoorZ, 0x107D5600 +.global PdamgatedoorZ +.set PdamgatedoorZ, 0x107D5600 +.global end_PdamgatedoorZ +.set end_PdamgatedoorZ, 0x107D5820 +.global PdamtundoorZ +.set PdamtundoorZ, 0x107D5820 +.global end_PdamtundoorZ +.set end_PdamtundoorZ, 0x107D5B90 +.global Pdepot_door_steelZ +.set Pdepot_door_steelZ, 0x107D5B90 +.global end_Pdepot_door_steelZ +.set end_Pdepot_door_steelZ, 0x107D5D30 +.global Pdepot_gate_entryZ +.set Pdepot_gate_entryZ, 0x107D5D30 +.global end_Pdepot_gate_entryZ +.set end_Pdepot_gate_entryZ, 0x107D5F70 +.global Pdesk1Z +.set Pdesk1Z, 0x107D5F70 +.global end_Pdesk1Z +.set end_Pdesk1Z, 0x107D60F0 +.global Pdesk2Z +.set Pdesk2Z, 0x107D60F0 +.global end_Pdesk2Z +.set end_Pdesk2Z, 0x107D6270 +.global Pdesk_arecibo1Z +.set Pdesk_arecibo1Z, 0x107D6270 +.global end_Pdesk_arecibo1Z +.set end_Pdesk_arecibo1Z, 0x107D64B0 +.global Pdesk_lamp2Z +.set Pdesk_lamp2Z, 0x107D64B0 +.global end_Pdesk_lamp2Z +.set end_Pdesk_lamp2Z, 0x107D67B0 +.global Pdest_engineZ +.set Pdest_engineZ, 0x107D67B0 +.global end_Pdest_engineZ +.set end_Pdest_engineZ, 0x107D80A0 +.global Pdest_exocetZ +.set Pdest_exocetZ, 0x107D80A0 +.global end_Pdest_exocetZ +.set end_Pdest_exocetZ, 0x107D8700 +.global Pdest_gunZ +.set Pdest_gunZ, 0x107D8700 +.global end_Pdest_gunZ +.set end_Pdest_gunZ, 0x107D8D70 +.global Pdest_harpoonZ +.set Pdest_harpoonZ, 0x107D8D70 +.global end_Pdest_harpoonZ +.set end_Pdest_harpoonZ, 0x107D9610 +.global Pdest_seawolfZ +.set Pdest_seawolfZ, 0x107D9610 +.global end_Pdest_seawolfZ +.set end_Pdest_seawolfZ, 0x107DA5C0 +.global Pdisc_readerZ +.set Pdisc_readerZ, 0x107DA5C0 +.global end_Pdisc_readerZ +.set end_Pdisc_readerZ, 0x107DA780 +.global Pdisk_drive1Z +.set Pdisk_drive1Z, 0x107DA780 +.global end_Pdisk_drive1Z +.set end_Pdisk_drive1Z, 0x107DA910 +.global Pdoor_azt_chairZ +.set Pdoor_azt_chairZ, 0x107DA910 +.global end_Pdoor_azt_chairZ +.set end_Pdoor_azt_chairZ, 0x107DAA90 +.global Pdoor_azt_deskZ +.set Pdoor_azt_deskZ, 0x107DAA90 +.global end_Pdoor_azt_deskZ +.set end_Pdoor_azt_deskZ, 0x107DAED0 +.global Pdoor_azt_desk_topZ +.set Pdoor_azt_desk_topZ, 0x107DAED0 +.global end_Pdoor_azt_desk_topZ +.set end_Pdoor_azt_desk_topZ, 0x107DB260 +.global Pdoor_aztecZ +.set Pdoor_aztecZ, 0x107DB260 +.global end_Pdoor_aztecZ +.set end_Pdoor_aztecZ, 0x107DB490 +.global Pdoor_dest1Z +.set Pdoor_dest1Z, 0x107DB490 +.global end_Pdoor_dest1Z +.set end_Pdoor_dest1Z, 0x107DB790 +.global Pdoor_dest2Z +.set Pdoor_dest2Z, 0x107DB790 +.global end_Pdoor_dest2Z +.set end_Pdoor_dest2Z, 0x107DBB50 +.global Pdoor_eyelidZ +.set Pdoor_eyelidZ, 0x107DBB50 +.global end_Pdoor_eyelidZ +.set end_Pdoor_eyelidZ, 0x107DC0B0 +.global Pdoor_irisZ +.set Pdoor_irisZ, 0x107DC0B0 +.global end_Pdoor_irisZ +.set end_Pdoor_irisZ, 0x107DCB00 +.global Pdoor_mfZ +.set Pdoor_mfZ, 0x107DCB00 +.global end_Pdoor_mfZ +.set end_Pdoor_mfZ, 0x107DCDF0 +.global Pdoor_roller1Z +.set Pdoor_roller1Z, 0x107DCDF0 +.global end_Pdoor_roller1Z +.set end_Pdoor_roller1Z, 0x107DD160 +.global Pdoor_roller2Z +.set Pdoor_roller2Z, 0x107DD160 +.global end_Pdoor_roller2Z +.set end_Pdoor_roller2Z, 0x107DD3A0 +.global Pdoor_roller3Z +.set Pdoor_roller3Z, 0x107DD3A0 +.global end_Pdoor_roller3Z +.set end_Pdoor_roller3Z, 0x107DD5E0 +.global Pdoor_roller4Z +.set Pdoor_roller4Z, 0x107DD5E0 +.global end_Pdoor_roller4Z +.set end_Pdoor_roller4Z, 0x107DD840 +.global Pdoor_rollertrainZ +.set Pdoor_rollertrainZ, 0x107DD840 +.global end_Pdoor_rollertrainZ +.set end_Pdoor_rollertrainZ, 0x107DD970 +.global Pdoor_st_arec1Z +.set Pdoor_st_arec1Z, 0x107DD970 +.global end_Pdoor_st_arec1Z +.set end_Pdoor_st_arec1Z, 0x107DDBD0 +.global Pdoor_st_arec2Z +.set Pdoor_st_arec2Z, 0x107DDBD0 +.global end_Pdoor_st_arec2Z +.set end_Pdoor_st_arec2Z, 0x107DDEB0 +.global Pdoor_winZ +.set Pdoor_winZ, 0x107DDEB0 +.global end_Pdoor_winZ +.set end_Pdoor_winZ, 0x107DE050 +.global PdoorconsoleZ +.set PdoorconsoleZ, 0x107DE050 +.global end_PdoorconsoleZ +.set end_PdoorconsoleZ, 0x107DE4C0 +.global PdoorpanelZ +.set PdoorpanelZ, 0x107DE4C0 +.global end_PdoorpanelZ +.set end_PdoorpanelZ, 0x107DE830 +.global Pdoorprison1Z +.set Pdoorprison1Z, 0x107DE830 +.global end_Pdoorprison1Z +.set end_Pdoorprison1Z, 0x107DE980 +.global PdoorstatgateZ +.set PdoorstatgateZ, 0x107DE980 +.global end_PdoorstatgateZ +.set end_PdoorstatgateZ, 0x107DEB80 +.global PexplosionbitZ +.set PexplosionbitZ, 0x107DEB80 +.global end_PexplosionbitZ +.set end_PexplosionbitZ, 0x107DECA0 +.global Pfiling_cabinet1Z +.set Pfiling_cabinet1Z, 0x107DECA0 +.global end_Pfiling_cabinet1Z +.set end_Pfiling_cabinet1Z, 0x107DEE20 +.global PflagZ +.set PflagZ, 0x107DEE20 +.global end_PflagZ +.set end_PflagZ, 0x107DEF50 +.global PfloppyZ +.set PfloppyZ, 0x107DEF50 +.global end_PfloppyZ +.set end_PfloppyZ, 0x107DF270 +.global Pfnp90magZ +.set Pfnp90magZ, 0x107DF270 +.global end_Pfnp90magZ +.set end_Pfnp90magZ, 0x107DF410 +.global Pgas_plant_met1_do1Z +.set Pgas_plant_met1_do1Z, 0x107DF410 +.global end_Pgas_plant_met1_do1Z +.set end_Pgas_plant_met1_do1Z, 0x107DF790 +.global Pgas_plant_sw2_do1Z +.set Pgas_plant_sw2_do1Z, 0x107DF790 +.global end_Pgas_plant_sw2_do1Z +.set end_Pgas_plant_sw2_do1Z, 0x107DF970 +.global Pgas_plant_sw3_do1Z +.set Pgas_plant_sw3_do1Z, 0x107DF970 +.global end_Pgas_plant_sw3_do1Z +.set end_Pgas_plant_sw3_do1Z, 0x107DFB70 +.global Pgas_plant_sw4_do1Z +.set Pgas_plant_sw4_do1Z, 0x107DFB70 +.global end_Pgas_plant_sw4_do1Z +.set end_Pgas_plant_sw4_do1Z, 0x107DFCD0 +.global Pgas_plant_sw_do1Z +.set Pgas_plant_sw_do1Z, 0x107DFCD0 +.global end_Pgas_plant_sw_do1Z +.set end_Pgas_plant_sw_do1Z, 0x107DFF60 +.global Pgas_plant_wc_cub1Z +.set Pgas_plant_wc_cub1Z, 0x107DFF60 +.global end_Pgas_plant_wc_cub1Z +.set end_Pgas_plant_wc_cub1Z, 0x107E0170 +.global PgasbarrelZ +.set PgasbarrelZ, 0x107E0170 +.global end_PgasbarrelZ +.set end_PgasbarrelZ, 0x107E0380 +.global PgasbarrelsZ +.set PgasbarrelsZ, 0x107E0380 +.global end_PgasbarrelsZ +.set end_PgasbarrelsZ, 0x107E08C0 +.global Pgasplant_clear_doorZ +.set Pgasplant_clear_doorZ, 0x107E08C0 +.global end_Pgasplant_clear_doorZ +.set end_Pgasplant_clear_doorZ, 0x107E0E20 +.global PgastankZ +.set PgastankZ, 0x107E0E20 +.global end_PgastankZ +.set end_PgastankZ, 0x107E13D0 +.global Pglassware1Z +.set Pglassware1Z, 0x107E13D0 +.global end_Pglassware1Z +.set end_Pglassware1Z, 0x107E1530 +.global Pglassware2Z +.set Pglassware2Z, 0x107E1530 +.global end_Pglassware2Z +.set end_Pglassware2Z, 0x107E17C0 +.global Pglassware3Z +.set Pglassware3Z, 0x107E17C0 +.global end_Pglassware3Z +.set end_Pglassware3Z, 0x107E19D0 +.global Pglassware4Z +.set Pglassware4Z, 0x107E19D0 +.global end_Pglassware4Z +.set end_Pglassware4Z, 0x107E1F50 +.global PgoldeneyelogoZ +.set PgoldeneyelogoZ, 0x107E1F50 +.global end_PgoldeneyelogoZ +.set end_PgoldeneyelogoZ, 0x107E2E00 +.global PgoldenshellsZ +.set PgoldenshellsZ, 0x107E2E00 +.global end_PgoldenshellsZ +.set end_PgoldenshellsZ, 0x107E3000 +.global PgroundgunZ +.set PgroundgunZ, 0x107E3000 +.global end_PgroundgunZ +.set end_PgroundgunZ, 0x107E37D0 +.global Pgun_runway1Z +.set Pgun_runway1Z, 0x107E37D0 +.global end_Pgun_runway1Z +.set end_Pgun_runway1Z, 0x107E3F10 +.global PhatberetZ +.set PhatberetZ, 0x107E3F10 +.global end_PhatberetZ +.set end_PhatberetZ, 0x107E41B0 +.global PhatberetblueZ +.set PhatberetblueZ, 0x107E41B0 +.global end_PhatberetblueZ +.set end_PhatberetblueZ, 0x107E4480 +.global PhatberetredZ +.set PhatberetredZ, 0x107E4480 +.global end_PhatberetredZ +.set end_PhatberetredZ, 0x107E4760 +.global PhatchboltZ +.set PhatchboltZ, 0x107E4760 +.global end_PhatchboltZ +.set end_PhatchboltZ, 0x107E4830 +.global PhatchdoorZ +.set PhatchdoorZ, 0x107E4830 +.global end_PhatchdoorZ +.set end_PhatchdoorZ, 0x107E4A50 +.global PhatchsevxZ +.set PhatchsevxZ, 0x107E4A50 +.global end_PhatchsevxZ +.set end_PhatchsevxZ, 0x107E4BC0 +.global PhatfurryZ +.set PhatfurryZ, 0x107E4BC0 +.global end_PhatfurryZ +.set end_PhatfurryZ, 0x107E4DF0 +.global PhatfurryblackZ +.set PhatfurryblackZ, 0x107E4DF0 +.global end_PhatfurryblackZ +.set end_PhatfurryblackZ, 0x107E5010 +.global PhatfurrybrownZ +.set PhatfurrybrownZ, 0x107E5010 +.global end_PhatfurrybrownZ +.set end_PhatfurrybrownZ, 0x107E5220 +.global PhathelmetZ +.set PhathelmetZ, 0x107E5220 +.global end_PhathelmetZ +.set end_PhathelmetZ, 0x107E5450 +.global PhathelmetgreyZ +.set PhathelmetgreyZ, 0x107E5450 +.global end_PhathelmetgreyZ +.set end_PhathelmetgreyZ, 0x107E5680 +.global PhatmoonZ +.set PhatmoonZ, 0x107E5680 +.global end_PhatmoonZ +.set end_PhatmoonZ, 0x107E5A60 +.global PhatpeakedZ +.set PhatpeakedZ, 0x107E5A60 +.global end_PhatpeakedZ +.set end_PhatpeakedZ, 0x107E5D70 +.global PhattbirdZ +.set PhattbirdZ, 0x107E5D70 +.global end_PhattbirdZ +.set end_PhattbirdZ, 0x107E5FC0 +.global PhattbirdbrownZ +.set PhattbirdbrownZ, 0x107E5FC0 +.global end_PhattbirdbrownZ +.set end_PhattbirdbrownZ, 0x107E6230 +.global PhelicopterZ +.set PhelicopterZ, 0x107E6230 +.global end_PhelicopterZ +.set end_PhelicopterZ, 0x107EA450 +.global PhindZ +.set PhindZ, 0x107EA450 +.global end_PhindZ +.set end_PhindZ, 0x107EBBC0 +.global PjeepZ +.set PjeepZ, 0x107EBBC0 +.global end_PjeepZ +.set end_PjeepZ, 0x107ECD20 +.global Pjerry_can1Z +.set Pjerry_can1Z, 0x107ECD20 +.global end_Pjerry_can1Z +.set end_Pjerry_can1Z, 0x107ECF80 +.global Pjungle3_treeZ +.set Pjungle3_treeZ, 0x107ECF80 +.global end_Pjungle3_treeZ +.set end_Pjungle3_treeZ, 0x107ED700 +.global Pjungle5_treeZ +.set Pjungle5_treeZ, 0x107ED700 +.global end_Pjungle5_treeZ +.set end_Pjungle5_treeZ, 0x107EDC30 +.global Pkey_holderZ +.set Pkey_holderZ, 0x107EDC30 +.global end_Pkey_holderZ +.set end_Pkey_holderZ, 0x107EDF80 +.global Pkeyboard1Z +.set Pkeyboard1Z, 0x107EDF80 +.global end_Pkeyboard1Z +.set end_Pkeyboard1Z, 0x107EE0F0 +.global Pkit_units1Z +.set Pkit_units1Z, 0x107EE0F0 +.global end_Pkit_units1Z +.set end_Pkit_units1Z, 0x107EE390 +.global PlabbenchZ +.set PlabbenchZ, 0x107EE390 +.global end_PlabbenchZ +.set end_PlabbenchZ, 0x107EE760 +.global PlandmineZ +.set PlandmineZ, 0x107EE760 +.global end_PlandmineZ +.set end_PlandmineZ, 0x107EE9D0 +.global PlegalpageZ +.set PlegalpageZ, 0x107EE9D0 +.global end_PlegalpageZ +.set end_PlegalpageZ, 0x107EF990 +.global Pletter_tray1Z +.set Pletter_tray1Z, 0x107EF990 +.global end_Pletter_tray1Z +.set end_Pletter_tray1Z, 0x107EFAF0 +.global Plocker3Z +.set Plocker3Z, 0x107EFAF0 +.global end_Plocker3Z +.set end_Plocker3Z, 0x107EFC80 +.global Plocker4Z +.set Plocker4Z, 0x107EFC80 +.global end_Plocker4Z +.set end_Plocker4Z, 0x107EFE10 +.global Pm16magZ +.set Pm16magZ, 0x107EFE10 +.global end_Pm16magZ +.set end_Pm16magZ, 0x107EFF50 +.global PmagnumshellsZ +.set PmagnumshellsZ, 0x107EFF50 +.global end_PmagnumshellsZ +.set end_PmagnumshellsZ, 0x107F0150 +.global Pmainframe1Z +.set Pmainframe1Z, 0x107F0150 +.global end_Pmainframe1Z +.set end_Pmainframe1Z, 0x107F0450 +.global Pmainframe2Z +.set Pmainframe2Z, 0x107F0450 +.global end_Pmainframe2Z +.set end_Pmainframe2Z, 0x107F0720 +.global Pmetal_chair1Z +.set Pmetal_chair1Z, 0x107F0720 +.global end_Pmetal_chair1Z +.set end_Pmetal_chair1Z, 0x107F0A60 +.global Pmetal_crate1Z +.set Pmetal_crate1Z, 0x107F0A60 +.global end_Pmetal_crate1Z +.set end_Pmetal_crate1Z, 0x107F0C20 +.global Pmetal_crate2Z +.set Pmetal_crate2Z, 0x107F0C20 +.global end_Pmetal_crate2Z +.set end_Pmetal_crate2Z, 0x107F0DE0 +.global Pmetal_crate3Z +.set Pmetal_crate3Z, 0x107F0DE0 +.global end_Pmetal_crate3Z +.set end_Pmetal_crate3Z, 0x107F0FA0 +.global Pmetal_crate4Z +.set Pmetal_crate4Z, 0x107F0FA0 +.global end_Pmetal_crate4Z +.set end_Pmetal_crate4Z, 0x107F1160 +.global PmilcopterZ +.set PmilcopterZ, 0x107F1160 +.global end_PmilcopterZ +.set end_PmilcopterZ, 0x107F2A40 +.global PmiltruckZ +.set PmiltruckZ, 0x107F2A40 +.global end_PmiltruckZ +.set end_PmiltruckZ, 0x107F4D40 +.global Pmissile_rack2Z +.set Pmissile_rack2Z, 0x107F4D40 +.global end_Pmissile_rack2Z +.set end_Pmissile_rack2Z, 0x107F5750 +.global Pmissile_rackZ +.set Pmissile_rackZ, 0x107F5750 +.global end_Pmissile_rackZ +.set end_Pmissile_rackZ, 0x107F5B30 +.global PmodemboxZ +.set PmodemboxZ, 0x107F5B30 +.global end_PmodemboxZ +.set end_PmodemboxZ, 0x107F5E70 +.global PmotorbikeZ +.set PmotorbikeZ, 0x107F5E70 +.global end_PmotorbikeZ +.set end_PmotorbikeZ, 0x107F6D30 +.global Pmp5kmagZ +.set Pmp5kmagZ, 0x107F6D30 +.global end_Pmp5kmagZ +.set end_Pmp5kmagZ, 0x107F6E80 +.global PnintendologoZ +.set PnintendologoZ, 0x107F6E80 +.global end_PnintendologoZ +.set end_PnintendologoZ, 0x107F9960 +.global Poil_drum1Z +.set Poil_drum1Z, 0x107F9960 +.global end_Poil_drum1Z +.set end_Poil_drum1Z, 0x107F9BD0 +.global Poil_drum2Z +.set Poil_drum2Z, 0x107F9BD0 +.global end_Poil_drum2Z +.set end_Poil_drum2Z, 0x107F9EC0 +.global Poil_drum3Z +.set Poil_drum3Z, 0x107F9EC0 +.global end_Poil_drum3Z +.set end_Poil_drum3Z, 0x107FA1B0 +.global Poil_drum5Z +.set Poil_drum5Z, 0x107FA1B0 +.global end_Poil_drum5Z +.set end_Poil_drum5Z, 0x107FA4A0 +.global Poil_drum6Z +.set Poil_drum6Z, 0x107FA4A0 +.global end_Poil_drum6Z +.set end_Poil_drum6Z, 0x107FA7B0 +.global Poil_drum7Z +.set Poil_drum7Z, 0x107FA7B0 +.global end_Poil_drum7Z +.set end_Poil_drum7Z, 0x107FAAB0 +.global PpadlockZ +.set PpadlockZ, 0x107FAAB0 +.global end_PpadlockZ +.set end_PpadlockZ, 0x107FB500 +.global PpalmZ +.set PpalmZ, 0x107FB500 +.global end_PpalmZ +.set end_PpalmZ, 0x107FB950 +.global PpalmtreeZ +.set PpalmtreeZ, 0x107FB950 +.global end_PpalmtreeZ +.set end_PpalmtreeZ, 0x107FBE20 +.global Pphone1Z +.set Pphone1Z, 0x107FBE20 +.global end_Pphone1Z +.set end_Pphone1Z, 0x107FBF60 +.global PplaneZ +.set PplaneZ, 0x107FBF60 +.global end_PplaneZ +.set end_PplaneZ, 0x107FE540 +.global Pplant11Z +.set Pplant11Z, 0x107FE540 +.global end_Pplant11Z +.set end_Pplant11Z, 0x107FE900 +.global Pplant1Z +.set Pplant1Z, 0x107FE900 +.global end_Pplant1Z +.set end_Pplant1Z, 0x107FEC90 +.global Pplant2Z +.set Pplant2Z, 0x107FEC90 +.global end_Pplant2Z +.set end_Pplant2Z, 0x107FEFF0 +.global Pplant2bZ +.set Pplant2bZ, 0x107FEFF0 +.global end_Pplant2bZ +.set end_Pplant2bZ, 0x107FF400 +.global Pplant3Z +.set Pplant3Z, 0x107FF400 +.global end_Pplant3Z +.set end_Pplant3Z, 0x107FF850 +.global Pradio_unit1Z +.set Pradio_unit1Z, 0x107FF850 +.global end_Pradio_unit1Z +.set end_Pradio_unit1Z, 0x107FFA00 +.global Pradio_unit2Z +.set Pradio_unit2Z, 0x107FFA00 +.global end_Pradio_unit2Z +.set end_Pradio_unit2Z, 0x107FFBC0 +.global Pradio_unit3Z +.set Pradio_unit3Z, 0x107FFBC0 +.global end_Pradio_unit3Z +.set end_Pradio_unit3Z, 0x107FFD80 +.global Pradio_unit4Z +.set Pradio_unit4Z, 0x107FFD80 +.global end_Pradio_unit4Z +.set end_Pradio_unit4Z, 0x107FFF40 +.global ProofgunZ +.set ProofgunZ, 0x107FFF40 +.global end_ProofgunZ +.set end_ProofgunZ, 0x108005A0 +.global PsafeZ +.set PsafeZ, 0x108005A0 +.global end_PsafeZ +.set end_PsafeZ, 0x108008F0 +.global PsafedoorZ +.set PsafedoorZ, 0x108008F0 +.global end_PsafedoorZ +.set end_PsafedoorZ, 0x10800DE0 +.global Psat1_reflectZ +.set Psat1_reflectZ, 0x10800DE0 +.global end_Psat1_reflectZ +.set end_Psat1_reflectZ, 0x10802350 +.global PsatboxZ +.set PsatboxZ, 0x10802350 +.global end_PsatboxZ +.set end_PsatboxZ, 0x10802470 +.global PsatdishZ +.set PsatdishZ, 0x10802470 +.global end_PsatdishZ +.set end_PsatdishZ, 0x108028D0 +.global Psec_panelZ +.set Psec_panelZ, 0x108028D0 +.global end_Psec_panelZ +.set end_Psec_panelZ, 0x10802A70 +.global Psev_door3Z +.set Psev_door3Z, 0x10802A70 +.global end_Psev_door3Z +.set end_Psev_door3Z, 0x10802D00 +.global Psev_door3_windZ +.set Psev_door3_windZ, 0x10802D00 +.global end_Psev_door3_windZ +.set end_Psev_door3_windZ, 0x10803090 +.global Psev_door4_windZ +.set Psev_door4_windZ, 0x10803090 +.global end_Psev_door4_windZ +.set end_Psev_door4_windZ, 0x10803470 +.global Psev_doorZ +.set Psev_doorZ, 0x10803470 +.global end_Psev_doorZ +.set end_Psev_doorZ, 0x108037C0 +.global Psev_door_v1Z +.set Psev_door_v1Z, 0x108037C0 +.global end_Psev_door_v1Z +.set end_Psev_door_v1Z, 0x10803AF0 +.global Psev_trislideZ +.set Psev_trislideZ, 0x10803AF0 +.global end_Psev_trislideZ +.set end_Psev_trislideZ, 0x10803EA0 +.global PsevdishZ +.set PsevdishZ, 0x10803EA0 +.global end_PsevdishZ +.set end_PsevdishZ, 0x10804DC0 +.global PsevdoormetslideZ +.set PsevdoormetslideZ, 0x10804DC0 +.global end_PsevdoormetslideZ +.set end_PsevdoormetslideZ, 0x108050A0 +.global PsevdoornowindZ +.set PsevdoornowindZ, 0x108050A0 +.global end_PsevdoornowindZ +.set end_PsevdoornowindZ, 0x10805210 +.global PsevdoorwindZ +.set PsevdoorwindZ, 0x10805210 +.global end_PsevdoorwindZ +.set end_PsevdoorwindZ, 0x10805640 +.global PsevdoorwoodZ +.set PsevdoorwoodZ, 0x10805640 +.global end_PsevdoorwoodZ +.set end_PsevdoorwoodZ, 0x108059F0 +.global PshuttleZ +.set PshuttleZ, 0x108059F0 +.global end_PshuttleZ +.set end_PshuttleZ, 0x108083F0 +.global Pshuttle_door_lZ +.set Pshuttle_door_lZ, 0x108083F0 +.global end_Pshuttle_door_lZ +.set end_Pshuttle_door_lZ, 0x10809020 +.global Pshuttle_door_rZ +.set Pshuttle_door_rZ, 0x10809020 +.global end_Pshuttle_door_rZ +.set end_Pshuttle_door_rZ, 0x10809D20 +.global PsilencerZ +.set PsilencerZ, 0x10809D20 +.global end_PsilencerZ +.set end_PsilencerZ, 0x10809EC0 +.global Psilo_lift_doorZ +.set Psilo_lift_doorZ, 0x10809EC0 +.global end_Psilo_lift_doorZ +.set end_Psilo_lift_doorZ, 0x1080A100 +.global PsilotopdoorZ +.set PsilotopdoorZ, 0x1080A100 +.global end_PsilotopdoorZ +.set end_PsilotopdoorZ, 0x1080A3F0 +.global PskorpionmagZ +.set PskorpionmagZ, 0x1080A3F0 +.global end_PskorpionmagZ +.set end_PskorpionmagZ, 0x1080A550 +.global PspectremagZ +.set PspectremagZ, 0x1080A550 +.global end_PspectremagZ +.set end_PspectremagZ, 0x1080A6C0 +.global PspeedboatZ +.set PspeedboatZ, 0x1080A6C0 +.global end_PspeedboatZ +.set end_PspeedboatZ, 0x1080B400 +.global Pst_pete_room_1iZ +.set Pst_pete_room_1iZ, 0x1080B400 +.global end_Pst_pete_room_1iZ +.set end_Pst_pete_room_1iZ, 0x1080E540 +.global Pst_pete_room_2iZ +.set Pst_pete_room_2iZ, 0x1080E540 +.global end_Pst_pete_room_2iZ +.set end_Pst_pete_room_2iZ, 0x10811720 +.global Pst_pete_room_3tZ +.set Pst_pete_room_3tZ, 0x10811720 +.global end_Pst_pete_room_3tZ +.set end_Pst_pete_room_3tZ, 0x10814660 +.global Pst_pete_room_5cZ +.set Pst_pete_room_5cZ, 0x10814660 +.global end_Pst_pete_room_5cZ +.set end_Pst_pete_room_5cZ, 0x10817BF0 +.global Pst_pete_room_6cZ +.set Pst_pete_room_6cZ, 0x10817BF0 +.global end_Pst_pete_room_6cZ +.set end_Pst_pete_room_6cZ, 0x1081B000 +.global Psteel_door1Z +.set Psteel_door1Z, 0x1081B000 +.global end_Psteel_door1Z +.set end_Psteel_door1Z, 0x1081B270 +.global Psteel_door2Z +.set Psteel_door2Z, 0x1081B270 +.global end_Psteel_door2Z +.set end_Psteel_door2Z, 0x1081B520 +.global Psteel_door2bZ +.set Psteel_door2bZ, 0x1081B520 +.global end_Psteel_door2bZ +.set end_Psteel_door2bZ, 0x1081B7F0 +.global Psteel_door3Z +.set Psteel_door3Z, 0x1081B7F0 +.global end_Psteel_door3Z +.set end_Psteel_door3Z, 0x1081BAC0 +.global Pstool1Z +.set Pstool1Z, 0x1081BAC0 +.global end_Pstool1Z +.set end_Pstool1Z, 0x1081BD80 +.global Pswipe_card2Z +.set Pswipe_card2Z, 0x1081BD80 +.global end_Pswipe_card2Z +.set end_Pswipe_card2Z, 0x1081BF10 +.global Pswivel_chair1Z +.set Pswivel_chair1Z, 0x1081BF10 +.global end_Pswivel_chair1Z +.set end_Pswivel_chair1Z, 0x1081C1A0 +.global PtankZ +.set PtankZ, 0x1081C1A0 +.global end_PtankZ +.set end_PtankZ, 0x1081DC40 +.global PtigerZ +.set PtigerZ, 0x1081DC40 +.global end_PtigerZ +.set end_PtigerZ, 0x1081FAD0 +.global Ptorpedo_rackZ +.set Ptorpedo_rackZ, 0x1081FAD0 +.global end_Ptorpedo_rackZ +.set end_Ptorpedo_rackZ, 0x10820350 +.global Ptrain_door2Z +.set Ptrain_door2Z, 0x10820350 +.global end_Ptrain_door2Z +.set end_Ptrain_door2Z, 0x10820720 +.global Ptrain_door3Z +.set Ptrain_door3Z, 0x10820720 +.global end_Ptrain_door3Z +.set end_Ptrain_door3Z, 0x10820B40 +.global Ptrain_doorZ +.set Ptrain_doorZ, 0x10820B40 +.global end_Ptrain_doorZ +.set end_Ptrain_doorZ, 0x10820DB0 +.global PtrainextdoorZ +.set PtrainextdoorZ, 0x10820DB0 +.global end_PtrainextdoorZ +.set end_PtrainextdoorZ, 0x108210F0 +.global Ptt33magZ +.set Ptt33magZ, 0x108210F0 +.global end_Ptt33magZ +.set end_Ptt33magZ, 0x10821230 +.global Ptuning_console1Z +.set Ptuning_console1Z, 0x10821230 +.global end_Ptuning_console1Z +.set end_Ptuning_console1Z, 0x10821750 +.global Ptv1Z +.set Ptv1Z, 0x10821750 +.global end_Ptv1Z +.set end_Ptv1Z, 0x10821920 +.global Ptv4screenZ +.set Ptv4screenZ, 0x10821920 +.global end_Ptv4screenZ +.set end_Ptv4screenZ, 0x10821AC0 +.global Ptv_holderZ +.set Ptv_holderZ, 0x10821AC0 +.global end_Ptv_holderZ +.set end_Ptv_holderZ, 0x10822190 +.global PtvscreenZ +.set PtvscreenZ, 0x10822190 +.global end_PtvscreenZ +.set end_PtvscreenZ, 0x10822260 +.global PuzimagZ +.set PuzimagZ, 0x10822260 +.global end_PuzimagZ +.set end_PuzimagZ, 0x108223A0 +.global PvertdoorZ +.set PvertdoorZ, 0x108223A0 +.global end_PvertdoorZ +.set end_PvertdoorZ, 0x108229B0 +.global PwalletbondZ +.set PwalletbondZ, 0x108229B0 +.global end_PwalletbondZ +.set end_PwalletbondZ, 0x10823F60 +.global PwindowZ +.set PwindowZ, 0x10823F60 +.global end_PwindowZ +.set end_PwindowZ, 0x10824050 +.global Pwindow_cor11Z +.set Pwindow_cor11Z, 0x10824050 +.global end_Pwindow_cor11Z +.set end_Pwindow_cor11Z, 0x10824130 +.global Pwindow_lib_lg1Z +.set Pwindow_lib_lg1Z, 0x10824130 +.global end_Pwindow_lib_lg1Z +.set end_Pwindow_lib_lg1Z, 0x10824210 +.global Pwindow_lib_sm1Z +.set Pwindow_lib_sm1Z, 0x10824210 +.global end_Pwindow_lib_sm1Z +.set end_Pwindow_lib_sm1Z, 0x10824300 +.global Pwood_lg_crate1Z +.set Pwood_lg_crate1Z, 0x10824300 +.global end_Pwood_lg_crate1Z +.set end_Pwood_lg_crate1Z, 0x10824580 +.global Pwood_lg_crate2Z +.set Pwood_lg_crate2Z, 0x10824580 +.global end_Pwood_lg_crate2Z +.set end_Pwood_lg_crate2Z, 0x108247A0 +.global Pwood_md_crate3Z +.set Pwood_md_crate3Z, 0x108247A0 +.global end_Pwood_md_crate3Z +.set end_Pwood_md_crate3Z, 0x108249C0 +.global Pwood_sm_crate4Z +.set Pwood_sm_crate4Z, 0x108249C0 +.global end_Pwood_sm_crate4Z +.set end_Pwood_sm_crate4Z, 0x10824C20 +.global Pwood_sm_crate5Z +.set Pwood_sm_crate5Z, 0x10824C20 +.global end_Pwood_sm_crate5Z +.set end_Pwood_sm_crate5Z, 0x10824E80 +.global Pwood_sm_crate6Z +.set Pwood_sm_crate6Z, 0x10824E80 +.global end_Pwood_sm_crate6Z +.set end_Pwood_sm_crate6Z, 0x108250A0 +.global Pwooden_table1Z +.set Pwooden_table1Z, 0x108250A0 +.global end_Pwooden_table1Z +.set end_Pwooden_table1Z, 0x10825410 +.global PwppkmagZ +.set PwppkmagZ, 0x10825410 +.global end_PwppkmagZ +.set end_PwppkmagZ, 0x10825550 +.global Tbg_ame_all_p_stanZ +.set Tbg_ame_all_p_stanZ, 0x10825550 +.global end_Tbg_ame_all_p_stanZ +.set end_Tbg_ame_all_p_stanZ, 0x10826E80 +.global Tbg_arch_all_p_stanZ +.set Tbg_arch_all_p_stanZ, 0x10826E80 +.global end_Tbg_arch_all_p_stanZ +.set end_Tbg_arch_all_p_stanZ, 0x1082CB70 +.global Tbg_arec_all_p_stanZ +.set Tbg_arec_all_p_stanZ, 0x1082CB70 +.global end_Tbg_arec_all_p_stanZ +.set end_Tbg_arec_all_p_stanZ, 0x10834EC0 +.global Tbg_ark_all_p_stanZ +.set Tbg_ark_all_p_stanZ, 0x10834EC0 +.global end_Tbg_ark_all_p_stanZ +.set end_Tbg_ark_all_p_stanZ, 0x1083DE80 +.global Tbg_ash_all_p_stanZ +.set Tbg_ash_all_p_stanZ, 0x1083DE80 +.global end_Tbg_ash_all_p_stanZ +.set end_Tbg_ash_all_p_stanZ, 0x1083F7B0 +.global Tbg_azt_all_p_stanZ +.set Tbg_azt_all_p_stanZ, 0x1083F7B0 +.global end_Tbg_azt_all_p_stanZ +.set end_Tbg_azt_all_p_stanZ, 0x10844D30 +.global Tbg_cat_all_p_stanZ +.set Tbg_cat_all_p_stanZ, 0x10844D30 +.global end_Tbg_cat_all_p_stanZ +.set end_Tbg_cat_all_p_stanZ, 0x10847460 +.global Tbg_cave_all_p_stanZ +.set Tbg_cave_all_p_stanZ, 0x10847460 +.global end_Tbg_cave_all_p_stanZ +.set end_Tbg_cave_all_p_stanZ, 0x1084C350 +.global Tbg_crad_all_p_stanZ +.set Tbg_crad_all_p_stanZ, 0x1084C350 +.global end_Tbg_crad_all_p_stanZ +.set end_Tbg_crad_all_p_stanZ, 0x1084EC60 +.global Tbg_cryp_all_p_stanZ +.set Tbg_cryp_all_p_stanZ, 0x1084EC60 +.global end_Tbg_cryp_all_p_stanZ +.set end_Tbg_cryp_all_p_stanZ, 0x10851CD0 +.global Tbg_dam_all_p_stanZ +.set Tbg_dam_all_p_stanZ, 0x10851CD0 +.global end_Tbg_dam_all_p_stanZ +.set end_Tbg_dam_all_p_stanZ, 0x1085C0B0 +.global Tbg_depo_all_p_stanZ +.set Tbg_depo_all_p_stanZ, 0x1085C0B0 +.global end_Tbg_depo_all_p_stanZ +.set end_Tbg_depo_all_p_stanZ, 0x10862FF0 +.global Tbg_dest_all_p_stanZ +.set Tbg_dest_all_p_stanZ, 0x10862FF0 +.global end_Tbg_dest_all_p_stanZ +.set end_Tbg_dest_all_p_stanZ, 0x108698E0 +.global Tbg_dish_all_p_stanZ +.set Tbg_dish_all_p_stanZ, 0x108698E0 +.global end_Tbg_dish_all_p_stanZ +.set end_Tbg_dish_all_p_stanZ, 0x1086A3F0 +.global Tbg_imp_all_p_stanZ +.set Tbg_imp_all_p_stanZ, 0x1086A3F0 +.global end_Tbg_imp_all_p_stanZ +.set end_Tbg_imp_all_p_stanZ, 0x1086BD20 +.global Tbg_jun_all_p_stanZ +.set Tbg_jun_all_p_stanZ, 0x1086BD20 +.global end_Tbg_jun_all_p_stanZ +.set end_Tbg_jun_all_p_stanZ, 0x10872E70 +.global Tbg_len_all_p_stanZ +.set Tbg_len_all_p_stanZ, 0x10872E70 +.global end_Tbg_len_all_p_stanZ +.set end_Tbg_len_all_p_stanZ, 0x10873930 +.global Tbg_oat_all_p_stanZ +.set Tbg_oat_all_p_stanZ, 0x10873930 +.global end_Tbg_oat_all_p_stanZ +.set end_Tbg_oat_all_p_stanZ, 0x10875230 +.global Tbg_pete_all_p_stanZ +.set Tbg_pete_all_p_stanZ, 0x10875230 +.global end_Tbg_pete_all_p_stanZ +.set end_Tbg_pete_all_p_stanZ, 0x108798C0 +.global Tbg_ref_all_p_stanZ +.set Tbg_ref_all_p_stanZ, 0x108798C0 +.global end_Tbg_ref_all_p_stanZ +.set end_Tbg_ref_all_p_stanZ, 0x1087B690 +.global Tbg_run_all_p_stanZ +.set Tbg_run_all_p_stanZ, 0x1087B690 +.global end_Tbg_run_all_p_stanZ +.set end_Tbg_run_all_p_stanZ, 0x1087D110 +.global Tbg_sev_all_p_stanZ +.set Tbg_sev_all_p_stanZ, 0x1087D110 +.global end_Tbg_sev_all_p_stanZ +.set end_Tbg_sev_all_p_stanZ, 0x10880EE0 +.global Tbg_sevb_all_p_stanZ +.set Tbg_sevb_all_p_stanZ, 0x10880EE0 +.global end_Tbg_sevb_all_p_stanZ +.set end_Tbg_sevb_all_p_stanZ, 0x10885E20 +.global Tbg_sevx_all_p_stanZ +.set Tbg_sevx_all_p_stanZ, 0x10885E20 +.global end_Tbg_sevx_all_p_stanZ +.set end_Tbg_sevx_all_p_stanZ, 0x1088F150 +.global Tbg_silo_all_p_stanZ +.set Tbg_silo_all_p_stanZ, 0x1088F150 +.global end_Tbg_silo_all_p_stanZ +.set end_Tbg_silo_all_p_stanZ, 0x108981F0 +.global Tbg_stat_all_p_stanZ +.set Tbg_stat_all_p_stanZ, 0x108981F0 +.global end_Tbg_stat_all_p_stanZ +.set end_Tbg_stat_all_p_stanZ, 0x1089D0B0 +.global Tbg_tra_all_p_stanZ +.set Tbg_tra_all_p_stanZ, 0x1089D0B0 +.global end_Tbg_tra_all_p_stanZ +.set end_Tbg_tra_all_p_stanZ, 0x1089F480 +.global UbriefarchZ +.set UbriefarchZ, 0x1089F480 +.global end_UbriefarchZ +.set end_UbriefarchZ, 0x1089F4A0 +.global UbriefarkZ +.set UbriefarkZ, 0x1089F4A0 +.global end_UbriefarkZ +.set end_UbriefarkZ, 0x1089F4C0 +.global UbriefaztZ +.set UbriefaztZ, 0x1089F4C0 +.global end_UbriefaztZ +.set end_UbriefaztZ, 0x1089F4E0 +.global UbriefcaveZ +.set UbriefcaveZ, 0x1089F4E0 +.global end_UbriefcaveZ +.set end_UbriefcaveZ, 0x1089F500 +.global UbriefcontrolZ +.set UbriefcontrolZ, 0x1089F500 +.global end_UbriefcontrolZ +.set end_UbriefcontrolZ, 0x1089F520 +.global UbriefcradZ +.set UbriefcradZ, 0x1089F520 +.global end_UbriefcradZ +.set end_UbriefcradZ, 0x1089F540 +.global UbriefcrypZ +.set UbriefcrypZ, 0x1089F540 +.global end_UbriefcrypZ +.set end_UbriefcrypZ, 0x1089F560 +.global UbriefdamZ +.set UbriefdamZ, 0x1089F560 +.global end_UbriefdamZ +.set end_UbriefdamZ, 0x1089F580 +.global UbriefdepoZ +.set UbriefdepoZ, 0x1089F580 +.global end_UbriefdepoZ +.set end_UbriefdepoZ, 0x1089F5A0 +.global UbriefdestZ +.set UbriefdestZ, 0x1089F5A0 +.global end_UbriefdestZ +.set end_UbriefdestZ, 0x1089F5C0 +.global UbriefjunZ +.set UbriefjunZ, 0x1089F5C0 +.global end_UbriefjunZ +.set end_UbriefjunZ, 0x1089F5E0 +.global UbriefpeteZ +.set UbriefpeteZ, 0x1089F5E0 +.global end_UbriefpeteZ +.set end_UbriefpeteZ, 0x1089F600 +.global UbriefrunZ +.set UbriefrunZ, 0x1089F600 +.global end_UbriefrunZ +.set end_UbriefrunZ, 0x1089F620 +.global UbriefsevbZ +.set UbriefsevbZ, 0x1089F620 +.global end_UbriefsevbZ +.set end_UbriefsevbZ, 0x1089F640 +.global UbriefsevbunkerZ +.set UbriefsevbunkerZ, 0x1089F640 +.global end_UbriefsevbunkerZ +.set end_UbriefsevbunkerZ, 0x1089F660 +.global UbriefsevxZ +.set UbriefsevxZ, 0x1089F660 +.global end_UbriefsevxZ +.set end_UbriefsevxZ, 0x1089F680 +.global UbriefsevxbZ +.set UbriefsevxbZ, 0x1089F680 +.global end_UbriefsevxbZ +.set end_UbriefsevxbZ, 0x1089F6A0 +.global UbriefsiloZ +.set UbriefsiloZ, 0x1089F6A0 +.global end_UbriefsiloZ +.set end_UbriefsiloZ, 0x1089F6C0 +.global UbriefstatueZ +.set UbriefstatueZ, 0x1089F6C0 +.global end_UbriefstatueZ +.set end_UbriefstatueZ, 0x1089F6E0 +.global UbrieftraZ +.set UbrieftraZ, 0x1089F6E0 +.global end_UbrieftraZ +.set end_UbrieftraZ, 0x1089F700 +.global Ump_setupameZ +.set Ump_setupameZ, 0x1089F700 +.global end_Ump_setupameZ +.set end_Ump_setupameZ, 0x1089FE20 +.global Ump_setuparchZ +.set Ump_setuparchZ, 0x1089FE20 +.global end_Ump_setuparchZ +.set end_Ump_setuparchZ, 0x108A2BC0 +.global Ump_setuparkZ +.set Ump_setuparkZ, 0x108A2BC0 +.global end_Ump_setuparkZ +.set end_Ump_setuparkZ, 0x108A4900 +.global Ump_setupashZ +.set Ump_setupashZ, 0x108A4900 +.global end_Ump_setupashZ +.set end_Ump_setupashZ, 0x108A4FF0 +.global Ump_setupcaveZ +.set Ump_setupcaveZ, 0x108A4FF0 +.global end_Ump_setupcaveZ +.set end_Ump_setupcaveZ, 0x108A7550 +.global Ump_setupcradZ +.set Ump_setupcradZ, 0x108A7550 +.global end_Ump_setupcradZ +.set end_Ump_setupcradZ, 0x108A7EB0 +.global Ump_setupcrypZ +.set Ump_setupcrypZ, 0x108A7EB0 +.global end_Ump_setupcrypZ +.set end_Ump_setupcrypZ, 0x108A8C10 +.global Ump_setupdishZ +.set Ump_setupdishZ, 0x108A8C10 +.global end_Ump_setupdishZ +.set end_Ump_setupdishZ, 0x108A9000 +.global Ump_setupimpZ +.set Ump_setupimpZ, 0x108A9000 +.global end_Ump_setupimpZ +.set end_Ump_setupimpZ, 0x108A9640 +.global Ump_setupoatZ +.set Ump_setupoatZ, 0x108A9640 +.global end_Ump_setupoatZ +.set end_Ump_setupoatZ, 0x108A9990 +.global Ump_setuprefZ +.set Ump_setuprefZ, 0x108A9990 +.global end_Ump_setuprefZ +.set end_Ump_setuprefZ, 0x108A9DA0 +.global Ump_setupsevbZ +.set Ump_setupsevbZ, 0x108A9DA0 +.global end_Ump_setupsevbZ +.set end_Ump_setupsevbZ, 0x108AB0B0 +.global Ump_setupstatueZ +.set Ump_setupstatueZ, 0x108AB0B0 +.global end_Ump_setupstatueZ +.set end_Ump_setupstatueZ, 0x108ABF30 +.global UsetuparchZ +.set UsetuparchZ, 0x108ABF30 +.global end_UsetuparchZ +.set end_UsetuparchZ, 0x108B0540 +.global UsetuparkZ +.set UsetuparkZ, 0x108B0540 +.global end_UsetuparkZ +.set end_UsetuparkZ, 0x108B40D0 +.global UsetupaztZ +.set UsetupaztZ, 0x108B40D0 +.global end_UsetupaztZ +.set end_UsetupaztZ, 0x108B69D0 +.global UsetupcaveZ +.set UsetupcaveZ, 0x108B69D0 +.global end_UsetupcaveZ +.set end_UsetupcaveZ, 0x108BA830 +.global UsetupcontrolZ +.set UsetupcontrolZ, 0x108BA830 +.global end_UsetupcontrolZ +.set end_UsetupcontrolZ, 0x108BE330 +.global UsetupcradZ +.set UsetupcradZ, 0x108BE330 +.global end_UsetupcradZ +.set end_UsetupcradZ, 0x108BFF60 +.global UsetupcrypZ +.set UsetupcrypZ, 0x108BFF60 +.global end_UsetupcrypZ +.set end_UsetupcrypZ, 0x108C1DF0 +.global UsetupdamZ +.set UsetupdamZ, 0x108C1DF0 +.global end_UsetupdamZ +.set end_UsetupdamZ, 0x108C60C0 +.global UsetupdepoZ +.set UsetupdepoZ, 0x108C60C0 +.global end_UsetupdepoZ +.set end_UsetupdepoZ, 0x108C9050 +.global UsetupdestZ +.set UsetupdestZ, 0x108C9050 +.global end_UsetupdestZ +.set end_UsetupdestZ, 0x108CB3A0 +.global UsetupjunZ +.set UsetupjunZ, 0x108CB3A0 +.global end_UsetupjunZ +.set end_UsetupjunZ, 0x108CEAB0 +.global UsetuplenZ +.set UsetuplenZ, 0x108CEAB0 +.global end_UsetuplenZ +.set end_UsetuplenZ, 0x108CF0A0 +.global UsetuppeteZ +.set UsetuppeteZ, 0x108CF0A0 +.global end_UsetuppeteZ +.set end_UsetuppeteZ, 0x108D2020 +.global UsetuprunZ +.set UsetuprunZ, 0x108D2020 +.global end_UsetuprunZ +.set end_UsetuprunZ, 0x108D3880 +.global UsetupsevbZ +.set UsetupsevbZ, 0x108D3880 +.global end_UsetupsevbZ +.set end_UsetupsevbZ, 0x108D5EE0 +.global UsetupsevbunkerZ +.set UsetupsevbunkerZ, 0x108D5EE0 +.global end_UsetupsevbunkerZ +.set end_UsetupsevbunkerZ, 0x108D7910 +.global UsetupsevxZ +.set UsetupsevxZ, 0x108D7910 +.global end_UsetupsevxZ +.set end_UsetupsevxZ, 0x108DBC20 +.global UsetupsevxbZ +.set UsetupsevxbZ, 0x108DBC20 +.global end_UsetupsevxbZ +.set end_UsetupsevxbZ, 0x108DFD10 +.global UsetupsiloZ +.set UsetupsiloZ, 0x108DFD10 +.global end_UsetupsiloZ +.set end_UsetupsiloZ, 0x108E27D0 +.global UsetupstatueZ +.set UsetupstatueZ, 0x108E27D0 +.global end_UsetupstatueZ +.set end_UsetupstatueZ, 0x108E4FA0 +.global UsetuptraZ +.set UsetuptraZ, 0x108E4FA0 +.global end_UsetuptraZ +.set end_UsetuptraZ, 0x108E81E0 +.global LameE +.set LameE, 0x108E81E0 +.global end_LameE +.set end_LameE, 0x108E81F0 +.global LameJ +.set LameJ, 0x108E81F0 +.global end_LameJ +.set end_LameJ, 0x108E8200 +.global LarchE +.set LarchE, 0x108E8200 +.global end_LarchE +.set end_LarchE, 0x108E8830 +.global LarchJ +.set LarchJ, 0x108E8830 +.global end_LarchJ +.set end_LarchJ, 0x108E8E90 +.global LarecE +.set LarecE, 0x108E8E90 +.global end_LarecE +.set end_LarecE, 0x108E9460 +.global LarecJ +.set LarecJ, 0x108E9460 +.global end_LarecJ +.set end_LarecJ, 0x108E9A00 +.global LarkE +.set LarkE, 0x108E9A00 +.global end_LarkE +.set end_LarkE, 0x108EA0A0 +.global LarkJ +.set LarkJ, 0x108EA0A0 +.global end_LarkJ +.set end_LarkJ, 0x108EA730 +.global LashE +.set LashE, 0x108EA730 +.global end_LashE +.set end_LashE, 0x108EA740 +.global LashJ +.set LashJ, 0x108EA740 +.global end_LashJ +.set end_LashJ, 0x108EA750 +.global LaztE +.set LaztE, 0x108EA750 +.global end_LaztE +.set end_LaztE, 0x108EAB90 +.global LaztJ +.set LaztJ, 0x108EAB90 +.global end_LaztJ +.set end_LaztJ, 0x108EAFE0 +.global LcatE +.set LcatE, 0x108EAFE0 +.global end_LcatE +.set end_LcatE, 0x108EAFF0 +.global LcatJ +.set LcatJ, 0x108EAFF0 +.global end_LcatJ +.set end_LcatJ, 0x108EB000 +.global LcaveE +.set LcaveE, 0x108EB000 +.global end_LcaveE +.set end_LcaveE, 0x108EB400 +.global LcaveJ +.set LcaveJ, 0x108EB400 +.global end_LcaveJ +.set end_LcaveJ, 0x108EB860 +.global LcradE +.set LcradE, 0x108EB860 +.global end_LcradE +.set end_LcradE, 0x108EBD30 +.global LcradJ +.set LcradJ, 0x108EBD30 +.global end_LcradJ +.set end_LcradJ, 0x108EC1D0 +.global LcrypE +.set LcrypE, 0x108EC1D0 +.global end_LcrypE +.set end_LcrypE, 0x108EC420 +.global LcrypJ +.set LcrypJ, 0x108EC420 +.global end_LcrypJ +.set end_LcrypJ, 0x108EC6C0 +.global LdamE +.set LdamE, 0x108EC6C0 +.global end_LdamE +.set end_LdamE, 0x108ECB10 +.global LdamJ +.set LdamJ, 0x108ECB10 +.global end_LdamJ +.set end_LdamJ, 0x108ECF60 +.global LdepoE +.set LdepoE, 0x108ECF60 +.global end_LdepoE +.set end_LdepoE, 0x108ED2D0 +.global LdepoJ +.set LdepoJ, 0x108ED2D0 +.global end_LdepoJ +.set end_LdepoJ, 0x108ED600 +.global LdestE +.set LdestE, 0x108ED600 +.global end_LdestE +.set end_LdestE, 0x108EDA90 +.global LdestJ +.set LdestJ, 0x108EDA90 +.global end_LdestJ +.set end_LdestJ, 0x108EDEF0 +.global LdishE +.set LdishE, 0x108EDEF0 +.global end_LdishE +.set end_LdishE, 0x108EDF00 +.global LdishJ +.set LdishJ, 0x108EDF00 +.global end_LdishJ +.set end_LdishJ, 0x108EDF10 +.global LearE +.set LearE, 0x108EDF10 +.global end_LearE +.set end_LearE, 0x108EDF20 +.global LearJ +.set LearJ, 0x108EDF20 +.global end_LearJ +.set end_LearJ, 0x108EDF30 +.global LeldE +.set LeldE, 0x108EDF30 +.global end_LeldE +.set end_LeldE, 0x108EDF40 +.global LeldJ +.set LeldJ, 0x108EDF40 +.global end_LeldJ +.set end_LeldJ, 0x108EDF50 +.global LgunE +.set LgunE, 0x108EDF50 +.global end_LgunE +.set end_LgunE, 0x108EE670 +.global LgunJ +.set LgunJ, 0x108EE670 +.global end_LgunJ +.set end_LgunJ, 0x108EEDB0 +.global LimpE +.set LimpE, 0x108EEDB0 +.global end_LimpE +.set end_LimpE, 0x108EEDC0 +.global LimpJ +.set LimpJ, 0x108EEDC0 +.global end_LimpJ +.set end_LimpJ, 0x108EEDD0 +.global LjunE +.set LjunE, 0x108EEDD0 +.global end_LjunE +.set end_LjunE, 0x108EF2F0 +.global LjunJ +.set LjunJ, 0x108EF2F0 +.global end_LjunJ +.set end_LjunJ, 0x108EF820 +.global LleeE +.set LleeE, 0x108EF820 +.global end_LleeE +.set end_LleeE, 0x108EF830 +.global LleeJ +.set LleeJ, 0x108EF830 +.global end_LleeJ +.set end_LleeJ, 0x108EF840 +.global LlenE +.set LlenE, 0x108EF840 +.global end_LlenE +.set end_LlenE, 0x108EFEF0 +.global LlenJ +.set LlenJ, 0x108EFEF0 +.global end_LlenJ +.set end_LlenJ, 0x108F0610 +.global LlipE +.set LlipE, 0x108F0610 +.global end_LlipE +.set end_LlipE, 0x108F0620 +.global LlipJ +.set LlipJ, 0x108F0620 +.global end_LlipJ +.set end_LlipJ, 0x108F0630 +.global LlueE +.set LlueE, 0x108F0630 +.global end_LlueE +.set end_LlueE, 0x108F0640 +.global LlueJ +.set LlueJ, 0x108F0640 +.global end_LlueJ +.set end_LlueJ, 0x108F0650 +.global LmiscE +.set LmiscE, 0x108F0650 +.global end_LmiscE +.set end_LmiscE, 0x108F0900 +.global LmiscJ +.set LmiscJ, 0x108F0900 +.global end_LmiscJ +.set end_LmiscJ, 0x108F0BC0 +.global LmpmenuE +.set LmpmenuE, 0x108F0BC0 +.global end_LmpmenuE +.set end_LmpmenuE, 0x108F0D60 +.global LmpmenuJ +.set LmpmenuJ, 0x108F0D60 +.global end_LmpmenuJ +.set end_LmpmenuJ, 0x108F0F00 +.global LmpweaponsE +.set LmpweaponsE, 0x108F0F00 +.global end_LmpweaponsE +.set end_LmpweaponsE, 0x108F0FC0 +.global LmpweaponsJ +.set LmpweaponsJ, 0x108F0FC0 +.global end_LmpweaponsJ +.set end_LmpweaponsJ, 0x108F1090 +.global LoatE +.set LoatE, 0x108F1090 +.global end_LoatE +.set end_LoatE, 0x108F10A0 +.global LoatJ +.set LoatJ, 0x108F10A0 +.global end_LoatJ +.set end_LoatJ, 0x108F10B0 +.global LoptionsE +.set LoptionsE, 0x108F10B0 +.global end_LoptionsE +.set end_LoptionsE, 0x108F12E0 +.global LoptionsJ +.set LoptionsJ, 0x108F12E0 +.global end_LoptionsJ +.set end_LoptionsJ, 0x108F1520 +.global LpamE +.set LpamE, 0x108F1520 +.global end_LpamE +.set end_LpamE, 0x108F1530 +.global LpamJ +.set LpamJ, 0x108F1530 +.global end_LpamJ +.set end_LpamJ, 0x108F1540 +.global LpeteE +.set LpeteE, 0x108F1540 +.global end_LpeteE +.set end_LpeteE, 0x108F19C0 +.global LpeteJ +.set LpeteJ, 0x108F19C0 +.global end_LpeteJ +.set end_LpeteJ, 0x108F1E30 +.global LpropobjE +.set LpropobjE, 0x108F1E30 +.global end_LpropobjE +.set end_LpropobjE, 0x108F20D0 +.global LpropobjJ +.set LpropobjJ, 0x108F20D0 +.global end_LpropobjJ +.set end_LpropobjJ, 0x108F2370 +.global LrefE +.set LrefE, 0x108F2370 +.global end_LrefE +.set end_LrefE, 0x108F2380 +.global LrefJ +.set LrefJ, 0x108F2380 +.global end_LrefJ +.set end_LrefJ, 0x108F2390 +.global LritE +.set LritE, 0x108F2390 +.global end_LritE +.set end_LritE, 0x108F23A0 +.global LritJ +.set LritJ, 0x108F23A0 +.global end_LritJ +.set end_LritJ, 0x108F23B0 +.global LrunE +.set LrunE, 0x108F23B0 +.global end_LrunE +.set end_LrunE, 0x108F2620 +.global LrunJ +.set LrunJ, 0x108F2620 +.global end_LrunJ +.set end_LrunJ, 0x108F28B0 +.global LsevE +.set LsevE, 0x108F28B0 +.global end_LsevE +.set end_LsevE, 0x108F2E10 +.global LsevJ +.set LsevJ, 0x108F2E10 +.global end_LsevJ +.set end_LsevJ, 0x108F3320 +.global LsevbE +.set LsevbE, 0x108F3320 +.global end_LsevbE +.set end_LsevbE, 0x108F3A70 +.global LsevbJ +.set LsevbJ, 0x108F3A70 +.global end_LsevbJ +.set end_LsevbJ, 0x108F4260 +.global LsevxE +.set LsevxE, 0x108F4260 +.global end_LsevxE +.set end_LsevxE, 0x108F46C0 +.global LsevxJ +.set LsevxJ, 0x108F46C0 +.global end_LsevxJ +.set end_LsevxJ, 0x108F4A90 +.global LsevxbE +.set LsevxbE, 0x108F4A90 +.global end_LsevxbE +.set end_LsevxbE, 0x108F4F20 +.global LsevxbJ +.set LsevxbJ, 0x108F4F20 +.global end_LsevxbJ +.set end_LsevxbJ, 0x108F5370 +.global LshoE +.set LshoE, 0x108F5370 +.global end_LshoE +.set end_LshoE, 0x108F5380 +.global LshoJ +.set LshoJ, 0x108F5380 +.global end_LshoJ +.set end_LshoJ, 0x108F5390 +.global LsiloE +.set LsiloE, 0x108F5390 +.global end_LsiloE +.set end_LsiloE, 0x108F5940 +.global LsiloJ +.set LsiloJ, 0x108F5940 +.global end_LsiloJ +.set end_LsiloJ, 0x108F5F30 +.global LstatE +.set LstatE, 0x108F5F30 +.global end_LstatE +.set end_LstatE, 0x108F6850 +.global LstatJ +.set LstatJ, 0x108F6850 +.global end_LstatJ +.set end_LstatJ, 0x108F70A0 +.global LtitleE +.set LtitleE, 0x108F70A0 +.global end_LtitleE +.set end_LtitleE, 0x108F7BB0 +.global LtitleJ +.set LtitleJ, 0x108F7BB0 +.global end_LtitleJ +.set end_LtitleJ, 0x108F87A0 +.global LtraE +.set LtraE, 0x108F87A0 +.global end_LtraE +.set end_LtraE, 0x108F8BD0 +.global LtraJ +.set LtraJ, 0x108F8BD0 +.global end_LtraJ +.set end_LtraJ, 0x108F9020 +.global LwaxE +.set LwaxE, 0x108F9020 +.global end_LwaxE +.set end_LwaxE, 0x108F9030 +.global LwaxJ +.set LwaxJ, 0x108F9030 +.global end_LwaxJ +.set end_LwaxJ, 0x108F9040 +.global ob__ob_end_seg +.set ob__ob_end_seg, 0x108F9040 +.global end_ob__ob_end_seg +.set end_ob__ob_end_seg, 0x108F9050 + +/* --- assets/ramrom (demo replays) ---------------------------- */ +.global ramrom_Dam_1 +.set ramrom_Dam_1, 0x102BFFF0 +.global ramrom_Dam_1_end +.set ramrom_Dam_1_end, 0x102C51F0 +.global ramrom_Dam_2 +.set ramrom_Dam_2, 0x102C51F0 +.global ramrom_Dam_2_end +.set ramrom_Dam_2_end, 0x102C71C0 +.global ramrom_Facility_1 +.set ramrom_Facility_1, 0x102C71C0 +.global ramrom_Facility_1_end +.set ramrom_Facility_1_end, 0x102C8C70 +.global ramrom_Facility_2 +.set ramrom_Facility_2, 0x102C8C70 +.global ramrom_Facility_2_end +.set ramrom_Facility_2_end, 0x102CB050 +.global ramrom_Facility_3 +.set ramrom_Facility_3, 0x102CB050 +.global ramrom_Facility_3_end +.set ramrom_Facility_3_end, 0x102CCCC0 +.global ramrom_Runway_1 +.set ramrom_Runway_1, 0x102CCCC0 +.global ramrom_Runway_1_end +.set ramrom_Runway_1_end, 0x102CF410 +.global ramrom_Runway_2 +.set ramrom_Runway_2, 0x102CF410 +.global ramrom_Runway_2_end +.set ramrom_Runway_2_end, 0x102D1D20 +.global ramrom_BunkerI_1 +.set ramrom_BunkerI_1, 0x102D1D20 +.global ramrom_BunkerI_1_end +.set ramrom_BunkerI_1_end, 0x102D50B0 +.global ramrom_BunkerI_2 +.set ramrom_BunkerI_2, 0x102D50B0 +.global ramrom_BunkerI_2_end +.set ramrom_BunkerI_2_end, 0x102DA330 +.global ramrom_Silo_1 +.set ramrom_Silo_1, 0x102DA330 +.global ramrom_Silo_1_end +.set ramrom_Silo_1_end, 0x102DC4C0 +.global ramrom_Silo_2 +.set ramrom_Silo_2, 0x102DC4C0 +.global ramrom_Silo_2_end +.set ramrom_Silo_2_end, 0x102DE490 +.global ramrom_Frigate_1 +.set ramrom_Frigate_1, 0x102DE490 +.global ramrom_Frigate_1_end +.set ramrom_Frigate_1_end, 0x102DFE40 +.global ramrom_Frigate_2 +.set ramrom_Frigate_2, 0x102DFE40 +.global ramrom_Frigate_2_end +.set ramrom_Frigate_2_end, 0x102E3320 +.global ramrom_Train +.set ramrom_Train, 0x102E3320 +.global ramrom_Train_end +.set ramrom_Train_end, 0x102E7110 +.global _ramromDam1SegmentRomStart +.set _ramromDam1SegmentRomStart, 0x102BFFF0 + +/* --- assets/music ------------------------------------------------ */ +.global _musicsampletblSegmentRomStart +.set _musicsampletblSegmentRomStart, 0x1041A4B0 +.global number_music_samples +.set number_music_samples, 0x1041A4B0 +.global number_music_samples_end +.set number_music_samples_end, 0x1041A4B4 +.global table_music_data +.set table_music_data, 0x1041A4B4 +.global _musicsampletblSegmentRomEnd +.set _musicsampletblSegmentRomEnd, 0x1041A6AC +.global table_music_data_end +.set table_music_data_end, 0x1041A6AC +.global _sfxctlSegmentRomStart +.set _sfxctlSegmentRomStart, 0x102ECB00 +.global _sfxctlSegmentRomEnd +.set _sfxctlSegmentRomEnd, 0x102F26C0 +.global _sfxtblSegmentRomStart +.set _sfxtblSegmentRomStart, 0x102F26C0 +.global _sfxtblSegmentRomEnd +.set _sfxtblSegmentRomEnd, 0x103B5170 +.global _instrumentsctlSegmentRomStart +.set _instrumentsctlSegmentRomStart, 0x103B5170 +.global _instrumentsctlSegmentRomEnd +.set _instrumentsctlSegmentRomEnd, 0x103B9510 +.global _instrumentstblSegmentRomStart +.set _instrumentstblSegmentRomStart, 0x103B9510 +.global _instrumentstblSegmentRomEnd +.set _instrumentstblSegmentRomEnd, 0x1041A4B0 +.global Mno_music +.set Mno_music, 0x1041A6AC +.global end_Mno_music +.set end_Mno_music, 0x1041A6D6 +.global Msolo_death_abrev +.set Msolo_death_abrev, 0x1041A6D6 +.global end_Msolo_death_abrev +.set end_Msolo_death_abrev, 0x1041A8AC +.global Mintro_eye +.set Mintro_eye, 0x1041A8AC +.global end_Mintro_eye +.set end_Mintro_eye, 0x1041B15A +.global Mtrain +.set Mtrain, 0x1041B15A +.global end_Mtrain +.set end_Mtrain, 0x1041BD44 +.global Mdepot +.set Mdepot, 0x1041BD44 +.global end_Mdepot +.set end_Mdepot, 0x1041CAE4 +.global Mjungle_unused +.set Mjungle_unused, 0x1041CAE4 +.global end_Mjungle_unused +.set end_Mjungle_unused, 0x1041D87C +.global Mcitadel +.set Mcitadel, 0x1041D87C +.global end_Mcitadel +.set end_Mcitadel, 0x1041E63C +.global Mfacility +.set Mfacility, 0x1041E63C +.global end_Mfacility +.set end_Mfacility, 0x1041F10A +.global Mcontrol +.set Mcontrol, 0x1041F10A +.global end_Mcontrol +.set end_Mcontrol, 0x1041FC68 +.global Mdam +.set Mdam, 0x1041FC68 +.global end_Mdam +.set end_Mdam, 0x10420A6C +.global Mfrigate +.set Mfrigate, 0x10420A6C +.global end_Mfrigate +.set end_Mfrigate, 0x1042184C +.global Marchives +.set Marchives, 0x1042184C +.global end_Marchives +.set end_Marchives, 0x104221A0 +.global Msilo +.set Msilo, 0x104221A0 +.global end_Msilo +.set end_Msilo, 0x10423010 +.global Mjungle_perimeter_unused +.set Mjungle_perimeter_unused, 0x10423010 +.global end_Mjungle_perimeter_unused +.set end_Mjungle_perimeter_unused, 0x10423F7C +.global Mstreets +.set Mstreets, 0x10423F7C +.global end_Mstreets +.set end_Mstreets, 0x10424C7E +.global Mbunker1 +.set Mbunker1, 0x10424C7E +.global end_Mbunker1 +.set end_Mbunker1, 0x104252F0 +.global Mbunker2 +.set Mbunker2, 0x104252F0 +.global end_Mbunker2 +.set end_Mbunker2, 0x10425970 +.global Mstatue +.set Mstatue, 0x10425970 +.global end_Mstatue +.set end_Mstatue, 0x10426308 +.global Melevator_control +.set Melevator_control, 0x10426308 +.global end_Melevator_control +.set end_Melevator_control, 0x10426CE2 +.global Mcradle +.set Mcradle, 0x10426CE2 +.global end_Mcradle +.set end_Mcradle, 0x10427A42 +.global Mnull1 +.set Mnull1, 0x10427A42 +.global end_Mnull1 +.set end_Mnull1, 0x10427A6C +.global Melevator_wc +.set Melevator_wc, 0x10427A6C +.global end_Melevator_wc +.set end_Melevator_wc, 0x104280B2 +.global Megyptian +.set Megyptian, 0x104280B2 +.global end_Megyptian +.set end_Megyptian, 0x10428E4C +.global Mfolders +.set Mfolders, 0x10428E4C +.global end_Mfolders +.set end_Mfolders, 0x1042922E +.global Mwatchmusic +.set Mwatchmusic, 0x1042922E +.global end_Mwatchmusic +.set end_Mwatchmusic, 0x10429420 +.global Maztec +.set Maztec, 0x10429420 +.global end_Maztec +.set end_Maztec, 0x1042A092 +.global Mwatercaverns +.set Mwatercaverns, 0x1042A092 +.global end_Mwatercaverns +.set end_Mwatercaverns, 0x1042AEBE +.global Mdeathsolo +.set Mdeathsolo, 0x1042AEBE +.global end_Mdeathsolo +.set end_Mdeathsolo, 0x1042B224 +.global Msurface2 +.set Msurface2, 0x1042B224 +.global end_Msurface2 +.set end_Msurface2, 0x1042BFDA +.global Mtrainx +.set Mtrainx, 0x1042BFDA +.global end_Mtrainx +.set end_Mtrainx, 0x1042C87A +.global Mnull2 +.set Mnull2, 0x1042C87A +.global end_Mnull2 +.set end_Mnull2, 0x1042C8A4 +.global Mfacilityx +.set Mfacilityx, 0x1042C8A4 +.global end_Mfacilityx +.set end_Mfacilityx, 0x1042D1FC +.global Mdepotx +.set Mdepotx, 0x1042D1FC +.global end_Mdepotx +.set end_Mdepotx, 0x1042D9B8 +.global Mcontrolx +.set Mcontrolx, 0x1042D9B8 +.global end_Mcontrolx +.set end_Mcontrolx, 0x1042DF00 +.global Mwatercavernsx +.set Mwatercavernsx, 0x1042DF00 +.global end_Mwatercavernsx +.set end_Mwatercavernsx, 0x1042E654 +.global Mdamx +.set Mdamx, 0x1042E654 +.global end_Mdamx +.set end_Mdamx, 0x1042EB74 +.global Mfrigatex +.set Mfrigatex, 0x1042EB74 +.global end_Mfrigatex +.set end_Mfrigatex, 0x1042F136 +.global Marchivesx +.set Marchivesx, 0x1042F136 +.global end_Marchivesx +.set end_Marchivesx, 0x1042F85A +.global Msilox +.set Msilox, 0x1042F85A +.global end_Msilox +.set end_Msilox, 0x1043014E +.global Mnull3 +.set Mnull3, 0x1043014E +.global end_Mnull3 +.set end_Mnull3, 0x10430178 +.global Mstreetsx +.set Mstreetsx, 0x10430178 +.global end_Mstreetsx +.set end_Mstreetsx, 0x104307E4 +.global Mbunker1x +.set Mbunker1x, 0x104307E4 +.global end_Mbunker1x +.set end_Mbunker1x, 0x10430F8A +.global Mbunker2x +.set Mbunker2x, 0x10430F8A +.global end_Mbunker2x +.set end_Mbunker2x, 0x104315D8 +.global Mjunglex +.set Mjunglex, 0x104315D8 +.global end_Mjunglex +.set end_Mjunglex, 0x10431DEE +.global Mnint_rare_logo +.set Mnint_rare_logo, 0x10431DEE +.global end_Mnint_rare_logo +.set end_Mnint_rare_logo, 0x10432220 +.global Mstatuex +.set Mstatuex, 0x10432220 +.global end_Mstatuex +.set end_Mstatuex, 0x104328D8 +.global Maztecx +.set Maztecx, 0x104328D8 +.global end_Maztecx +.set end_Maztecx, 0x104331AE +.global Megyptianx +.set Megyptianx, 0x104331AE +.global end_Megyptianx +.set end_Megyptianx, 0x10433A5E +.global Mcradlex +.set Mcradlex, 0x10433A5E +.global end_Mcradlex +.set end_Mcradlex, 0x10434128 +.global Mcuba +.set Mcuba, 0x10434128 +.global end_Mcuba +.set end_Mcuba, 0x10434972 +.global Mrunway +.set Mrunway, 0x10434972 +.global end_Mrunway +.set end_Mrunway, 0x10435690 +.global Mrunway_plane +.set Mrunway_plane, 0x10435690 +.global end_Mrunway_plane +.set end_Mrunway_plane, 0x1043596A +.global Msurface2x +.set Msurface2x, 0x1043596A +.global end_Msurface2x +.set end_Msurface2x, 0x10436092 +.global Mwindblowing +.set Mwindblowing, 0x10436092 +.global end_Mwindblowing +.set end_Mwindblowing, 0x104365B4 +.global Mmultideath_alt +.set Mmultideath_alt, 0x104365B4 +.global end_Mmultideath_alt +.set end_Mmultideath_alt, 0x104367C0 +.global Mjungle +.set Mjungle, 0x104367C0 +.global end_Mjungle +.set end_Mjungle, 0x10436F48 +.global Mrunwayx +.set Mrunwayx, 0x10436F48 +.global end_Mrunwayx +.set end_Mrunwayx, 0x1043756A +.global Msurface1 +.set Msurface1, 0x1043756A +.global end_Msurface1 +.set end_Msurface1, 0x104382D2 +.global Mmultiplayerdeath +.set Mmultiplayerdeath, 0x104382D2 +.global end_Mmultiplayerdeath +.set end_Mmultiplayerdeath, 0x1043859A +.global Msurface1x +.set Msurface1x, 0x1043859A +.global end_Msurface1x +.set end_Msurface1x, 0x10438CC2 +.global Msurface2_ending +.set Msurface2_ending, 0x10438CC2 +.global end_Msurface2_ending +.set end_Msurface2_ending, 0x10438F5E +.global Mstatue_ending +.set Mstatue_ending, 0x10438F5E +.global end_Mstatue_ending +.set end_Mstatue_ending, 0x104390C4 +.global Mfrigate_outro +.set Mfrigate_outro, 0x104390C4 +.global end_Mfrigate_outro +.set end_Mfrigate_outro, 0x10439380 + +/* --- assets/romfiles2.s -------------------------------------- */ +.global unknown2 +.set unknown2, 0x102A5A70 +.global unknown2_end +.set unknown2_end, 0x102BFFF0 + +/* --- ge007.ld segment markers ------------------------------------ */ +/* RomStart/RomEnd are exact for asset segments; Start/End mirror them +/* (game code only ever uses End-Start size differences for these). +/* Code segments are approximate (see generator header comment). */ +.global _headerSegmentRomStart +.set _headerSegmentRomStart, 0x10000000 +.global _headerSegmentRomEnd +.set _headerSegmentRomEnd, 0x10000040 +.global _headerSegmentStart +.set _headerSegmentStart, 0x10000000 +.global _headerSegmentEnd +.set _headerSegmentEnd, 0x10000040 /* approximate */ +.global _bootSegmentRomStart +.set _bootSegmentRomStart, 0x10000040 +.global _bootSegmentRomEnd +.set _bootSegmentRomEnd, 0x10001000 +.global _bootSegmentStart +.set _bootSegmentStart, 0x10000040 +.global _bootSegmentEnd +.set _bootSegmentEnd, 0x10001000 /* approximate */ +.global _startSegmentRomStart +.set _startSegmentRomStart, 0x10001000 +.global _startSegmentRomEnd +.set _startSegmentRomEnd, 0x10001050 +.global _startSegmentStart +.set _startSegmentStart, 0x10001000 +.global _startSegmentEnd +.set _startSegmentEnd, 0x10001050 /* approximate */ +.global _codeSegmentRomStart +.set _codeSegmentRomStart, 0x10001050 +.global _codeSegmentRomEnd +.set _codeSegmentRomEnd, 0x10021990 +.global _codeSegmentStart +.set _codeSegmentStart, 0x10001050 +.global _codeSegmentEnd +.set _codeSegmentEnd, 0x10021990 /* approximate */ +.global _cdataSegmentRomStart +.set _cdataSegmentRomStart, 0x10021990 +.global _cdataSegmentRomEnd +.set _cdataSegmentRomEnd, 0x10032E92 +.global _cdataSegmentStart +.set _cdataSegmentStart, 0x10021990 +.global _cdataSegmentEnd +.set _cdataSegmentEnd, 0x10032E92 /* approximate */ +.global _inflateSegmentRomStart +.set _inflateSegmentRomStart, 0x10032E92 +.global _inflateSegmentRomEnd +.set _inflateSegmentRomEnd, 0x1003584F +.global _inflateSegmentStart +.set _inflateSegmentStart, 0x10032E92 +.global _inflateSegmentEnd +.set _inflateSegmentEnd, 0x1003584F /* approximate */ +.global _gameSegmentRomStart +.set _gameSegmentRomStart, 0x1003584F +.global _gameSegmentRomEnd +.set _gameSegmentRomEnd, 0x101185A0 +.global _gameSegmentStart +.set _gameSegmentStart, 0x1003584F +.global _gameSegmentEnd +.set _gameSegmentEnd, 0x101185A0 /* approximate */ +.global _fontdlSegmentRomStart +.set _fontdlSegmentRomStart, 0x101185A0 +.global _fontdlSegmentRomEnd +.set _fontdlSegmentRomEnd, 0x10118660 +.global _fontdlSegmentStart +.set _fontdlSegmentStart, 0x101185A0 +.global _fontdlSegmentEnd +.set _fontdlSegmentEnd, 0x10118660 +.global _jfontchardataSegmentRomStart +.set _jfontchardataSegmentRomStart, 0x10118660 +.global _jfontchardataSegmentRomEnd +.set _jfontchardataSegmentRomEnd, 0x10123D60 +.global _jfontchardataSegmentStart +.set _jfontchardataSegmentStart, 0x10118660 +.global _jfontchardataSegmentEnd +.set _jfontchardataSegmentEnd, 0x10123D60 +.global _efontchardataSegmentRomStart +.set _efontchardataSegmentRomStart, 0x10123D60 +.global _efontchardataSegmentRomEnd +.set _efontchardataSegmentRomEnd, 0x101257E0 +.global _efontchardataSegmentStart +.set _efontchardataSegmentStart, 0x10123D60 +.global _efontchardataSegmentEnd +.set _efontchardataSegmentEnd, 0x101257E0 +.global _animation_entriesSegmentRomStart +.set _animation_entriesSegmentRomStart, 0x101257E0 +.global _animation_entriesSegmentRomEnd +.set _animation_entriesSegmentRomEnd, 0x1028F6A0 +.global _animation_entriesSegmentStart +.set _animation_entriesSegmentStart, 0x101257E0 +.global _animation_entriesSegmentEnd +.set _animation_entriesSegmentEnd, 0x1028F6A0 +.global _animation_dataSegmentRomStart +.set _animation_dataSegmentRomStart, 0x1028F6A0 +.global _animation_dataSegmentRomEnd +.set _animation_dataSegmentRomEnd, 0x1029DE80 +.global _animation_dataSegmentStart +.set _animation_dataSegmentStart, 0x1028F6A0 +.global _animation_dataSegmentEnd +.set _animation_dataSegmentEnd, 0x1029DE80 +.global _GlobalimagetableSegmentRomStart +.set _GlobalimagetableSegmentRomStart, 0x1029DE80 +.global _GlobalimagetableSegmentRomEnd +.set _GlobalimagetableSegmentRomEnd, 0x1029F278 +.global _GlobalimagetableSegmentStart +.set _GlobalimagetableSegmentStart, 0x1029DE80 +.global _GlobalimagetableSegmentEnd +.set _GlobalimagetableSegmentEnd, 0x1029F278 +.global _rarewarelogoSegmentRomStart +.set _rarewarelogoSegmentRomStart, 0x1029F280 +.global _rarewarelogoSegmentRomEnd +.set _rarewarelogoSegmentRomEnd, 0x102A5A70 +.global _rarewarelogoSegmentStart +.set _rarewarelogoSegmentStart, 0x1029F280 +.global _rarewarelogoSegmentEnd +.set _rarewarelogoSegmentEnd, 0x102A5A70 +.global _romfiles2SegmentRomStart +.set _romfiles2SegmentRomStart, 0x102A5A70 +.global _romfiles2SegmentRomEnd +.set _romfiles2SegmentRomEnd, 0x102BFFF0 +.global _romfiles2SegmentStart +.set _romfiles2SegmentStart, 0x102A5A70 +.global _romfiles2SegmentEnd +.set _romfiles2SegmentEnd, 0x102BFFF0 +.global _ramromfilesSegmentRomStart +.set _ramromfilesSegmentRomStart, 0x102BFFF0 +.global _ramromfilesSegmentRomEnd +.set _ramromfilesSegmentRomEnd, 0x102E7110 +.global _ramromfilesSegmentStart +.set _ramromfilesSegmentStart, 0x102BFFF0 +.global _ramromfilesSegmentEnd +.set _ramromfilesSegmentEnd, 0x102E7110 +.global _fontbankgothicSegmentRomStart +.set _fontbankgothicSegmentRomStart, 0x102E7110 +.global _fontbankgothicSegmentRomEnd +.set _fontbankgothicSegmentRomEnd, 0x102E95C0 +.global _fontbankgothicSegmentStart +.set _fontbankgothicSegmentStart, 0x102E7110 +.global _fontbankgothicSegmentEnd +.set _fontbankgothicSegmentEnd, 0x102E95C0 +.global _fontzurichboldSegmentRomStart +.set _fontzurichboldSegmentRomStart, 0x102E95C0 +.global _fontzurichboldSegmentRomEnd +.set _fontzurichboldSegmentRomEnd, 0x102ECB00 +.global _fontzurichboldSegmentStart +.set _fontzurichboldSegmentStart, 0x102E95C0 +.global _fontzurichboldSegmentEnd +.set _fontzurichboldSegmentEnd, 0x102ECB00 +.global _musicfilesSegmentRomStart +.set _musicfilesSegmentRomStart, 0x102ECB00 +.global _musicfilesSegmentRomEnd +.set _musicfilesSegmentRomEnd, 0x10439380 +.global _musicfilesSegmentStart +.set _musicfilesSegmentStart, 0x102ECB00 +.global _musicfilesSegmentEnd +.set _musicfilesSegmentEnd, 0x10439380 +.global _obsegSegmentRomStart +.set _obsegSegmentRomStart, 0x10439380 +.global _obsegSegmentRomEnd +.set _obsegSegmentRomEnd, 0x108F9050 +.global _obsegSegmentStart +.set _obsegSegmentStart, 0x10439380 +.global _obsegSegmentEnd +.set _obsegSegmentEnd, 0x108F9050 +.global _imagesSegmentRomStart +.set _imagesSegmentRomStart, 0x108F9050 +.global _imagesSegmentRomEnd +.set _imagesSegmentRomEnd, 0x108F9050 +.global _imagesSegmentStart +.set _imagesSegmentStart, 0x108F9050 +.global _imagesSegmentEnd +.set _imagesSegmentEnd, 0x108F9050 +.global _alt_startSegmentRomStart +.set _alt_startSegmentRomStart, 0x10101000 +.global _alt_startSegmentStart +.set _alt_startSegmentStart, 0x10101000 diff --git a/port/src/romdata.c b/port/src/romdata.c index 67ec742a..4d61a3de 100644 --- a/port/src/romdata.c +++ b/port/src/romdata.c @@ -75,8 +75,10 @@ unsigned char *g_pc_animdata_base = NULL; * data/ takes precedence. */ static const char *romFileCandidates(void) { -#if GE007_IS_PAL +#if defined(VERSION_EU) return "ge007.pal-final.z64|baserom.e.z64"; +#elif defined(VERSION_JP) + return "ge007.jpn-final.z64|baserom.j.z64"; #else return "ge007.ntsc-final.z64|baserom.u.z64"; #endif @@ -85,8 +87,10 @@ static const char *romFileCandidates(void) static int romHeaderValid(const u8 *h, char *err, size_t errsz) { static const u8 magic[4] = { 0x80, 0x37, 0x12, 0x40 }; -#if GE007_IS_PAL +#if defined(VERSION_EU) const char country = 'P'; +#elif defined(VERSION_JP) + const char country = 'J'; #else const char country = 'E'; #endif diff --git a/port/src/video.c b/port/src/video.c index f61766c5..48280e2f 100644 --- a/port/src/video.c +++ b/port/src/video.c @@ -23,6 +23,7 @@ #include #include +#include /* LEVELID_TITLE (D416); MinGW's SDL.h pulled it in by accident, glibc's doesn't */ #include "platform.h" #include "system.h" @@ -37,11 +38,12 @@ #include "../fast3d/gfx_sdl.h" #include "../fast3d/gfx_opengl.h" -/* GE's internal resolution: NTSC LAN1 is 640x480; PAL LAN1 shows a - * 640x400 area. The window opens at the native size (1:1) by default. */ +/* GE's internal resolution before the game's first osViSetMode (which then + * sets the real CFB size): NTSC 640x480; PAL is taller, not shorter -- the EU + * game renders 320x269 at 50 Hz with no borders (TCRF), so 2x = 640x538 (D487). */ #ifdef REFRESH_PAL #define GE_NATIVE_W 640 -#define GE_NATIVE_H 400 +#define GE_NATIVE_H 538 #else #define GE_NATIVE_W 640 #define GE_NATIVE_H 480 @@ -75,6 +77,7 @@ static int cfgSafeAreaCrop = 1; /* crop the N64 TV-overscan safe-area margin static int cfgAspectMode = 0; /* D447: 0 = Window (fill the window), 1 = Original (pillar/letterbox to the console aspect: 4:3, or 16:9 while the game's Ratio option is 16:9) */ static int cfgFullscreen = 0; /* 0 = windowed, 1 = borderless fullscreen */ static int cfgDeckPresetApplied = 0; /* D283: 1 once the Steam Deck preset has been considered */ +static int cfgLowEndConsidered = 0; /* D482: 1 once the low-end GPU defaults have been considered */ /* * [Window] persistence. W/H = 0 -> auto (gfx_sdl2 fits a 4:3 window into ~85% @@ -246,6 +249,11 @@ f32 portNativeAspect(void) f32 portScaleFovY(f32 fovy, s32 isTitleScreen) { + /* D484 (#136): the 20-degree floor below guards the port's own widening, + * but it also raised the game's narrow zoom FOVs (sniper/camera down to + * 7 degrees, the watch zoom) to 20, capping scope magnification at about + * a third of the N64's. Never floor above the game's own value. */ + const f32 floorFovY = fovy < 20.0f ? fovy : 20.0f; if (!isTitleScreen) { /* D334: native widescreen already widens the horizontal FOV through * the projection aspect; the Phase-4 vertical boost below was the @@ -259,8 +267,8 @@ f32 portScaleFovY(f32 fovy, s32 isTitleScreen) fovy *= portFovScale; } } - if (fovy > 160.0f) { fovy = 160.0f; } - if (fovy < 20.0f) { fovy = 20.0f; } + if (fovy > 160.0f) { fovy = 160.0f; } + if (fovy < floorFovY) { fovy = floorFovY; } return fovy; } @@ -503,6 +511,7 @@ PD_CONSTRUCTOR static void videoConfigInit(void) configRegisterInt("Window.Y", &cfgWinY, -1, 16384); configRegisterInt("Window.Maximized", &cfgWinMax, 0, 1); configRegisterInt("Video.DeckPresetApplied", &cfgDeckPresetApplied, 0, 1); /* D283 */ + configRegisterInt("Video.LowEndConsidered", &cfgLowEndConsidered, 0, 1); /* D482 */ } /* D283: Steam Deck preset. Called from main() right AFTER configLoad(), so @@ -592,6 +601,81 @@ void videoApplySteamDeckPreset(void) configSave(); } +/* D482: lighter defaults on Atom/Celeron-class GPUs (#92). + * Measured (Lenovo X220 + the PD port on the same box): fast3d costs no more + * per batch/triangle than PD's; the gap on very weak hardware is workload. + * DrawDistance/LodDistance 250 send 2.5-3x the draw batches of the authored + * distance and MSAA 2x adds ~25-30% GPU time -- PD ships authored distance and + * no MSAA. On Intel HD 400-class GPUs (Bay Trail/Braswell/Apollo Lake/Gemini + * Lake) and software renderers, lower those three to 100/100/1, but only where + * the value is still the port default, and only once per ini + * (Video.LowEndConsidered). Core-series iGPUs (HD 2000-6000, HD 5xx, UHD 6xx + * except 600/605) keep the full defaults; an HD 3000 holds 60 with them. + * The bare "Intel(R) HD Graphics" (no number) counts as low-end on purpose: it + * is what Bay Trail and Celeron/Pentium parts report; no Core-series part + * reports it, and a miss costs one reversible lightening. Don't tighten this + * without measurements. + * Must run after gfx_init (needs GL_RENDERER), so it cannot sit next to + * videoApplySteamDeckPreset in main.c, which runs before any GL context. The + * two touch disjoint keys (Deck: window/fullscreen; this: DD/LOD/MSAA). + * GE_FAKE_LOWEND=1/0 forces the classification for testing. */ +static int videoIsLowEndRenderer(const char *r, const char **why) +{ + static const char *const kTags[] = { + "(BYT)", "(BSW)", "(CHV)", "(APL)", "(GLK)", + "Bay Trail", "Braswell", "Cherryview", "Apollo Lake", "Gemini Lake", + "llvmpipe", "softpipe", "SVGA3D", "Microsoft Basic Render", "GDI Generic", + }; + static const int kModels[] = { 400, 405, 500, 505, 600, 605 }; + const char *p; + + for (int i = 0; i < (int)(sizeof(kTags) / sizeof(kTags[0])); i++) { + if (strstr(r, kTags[i])) { *why = kTags[i]; return 1; } + } + p = strstr(r, "HD Graphics"); + if (p) { + int n = 0, digits = 0; + p += strlen("HD Graphics"); + while (*p == ' ') p++; + while (*p >= '0' && *p <= '9') { n = n * 10 + (*p - '0'); p++; digits++; } + if (!digits) { *why = "numberless HD Graphics"; return 1; } + for (int i = 0; i < (int)(sizeof(kModels) / sizeof(kModels[0])); i++) { + if (n == kModels[i]) { *why = "HD Graphics 400-605 class"; return 1; } + } + } + *why = ""; + return 0; +} + +static void videoApplyLowEndDefaults(void) +{ + const char *r = gfx_opengl_renderer_string(); + const char *why = ""; + const char *fake = getenv("GE_FAKE_LOWEND"); + int low; + + if (cfgLowEndConsidered) return; + if (fake && *fake) { + low = atoi(fake) != 0; + why = "GE_FAKE_LOWEND"; + } else { + low = videoIsLowEndRenderer(r, &why); + } + if (low) { + int changed = 0; + if (cfgDrawDistance == 250) { cfgDrawDistance = 100; changed++; } + if (cfgLodDistance == 250) { cfgLodDistance = 100; changed++; } + if (cfgMSAA == 2) { cfgMSAA = 1; gfx_msaa_level = 1; changed++; } + sysLogPrintf(LOG_INFO, "video: low-end renderer \"%s\" (%s); lowered %d default(s): DrawDistance=%d LodDistance=%d MSAA=%d", + r, why, changed, cfgDrawDistance, cfgLodDistance, cfgMSAA); + } else { + sysLogPrintf(LOG_INFO, "video: renderer \"%s\" (%s); not low-end, defaults kept", + r, why[0] ? why : "no match"); + } + cfgLowEndConsidered = 1; + configSave(); +} + /* D440: "Original N64" preset + its inverse ("Port defaults"). * One row per config key whose port default differs from what the N64 * showed, plus the fidelity-identity keys a user may have moved away from @@ -860,6 +944,7 @@ int videoInit(void) }; gfx_init(&set); + videoApplyLowEndDefaults(); /* D482: needs GL_RENDERER; before the first frame */ /* VSync + optional fps cap; fast3d paces the window itself. */ wmAPI->set_swap_interval(cfgVSync ? 1 : 0); @@ -1016,8 +1101,9 @@ void videoStartFrame(void) videoRenderPark(); } - /* Rendering runs on the game's scheduler thread; the GL context was - * created on the host main thread. */ + /* Rendering runs on the D481 render worker (or the scheduler thread with + * GE_RENDERINLINE/GE_DETERM); the GL context was created on the host + * main thread. */ gfx_sdl_make_context_current(); int dirty = SDL_AtomicSet(&liveCfgDirty, 0); diff --git a/scripts/filelist.e.csv b/scripts/filelist.e.csv index a84caf6d..756937c6 100644 --- a/scripts/filelist.e.csv +++ b/scripts/filelist.e.csv @@ -1,3 +1,99 @@ +1066992,192,assets/ge007.u.117880.jfont_dl.bin,0,0 +1067184,46848,assets/ge007.e.1048B0.jfont_chardata.bin,0,0 +1114032,6784,assets/ge007.u.123040.efont_chardata.bin,0,0 +1120816,1482432,assets/animationtable_entries.bin,0,0 +2603248,59360,assets/animationtable_data.bin,0,0 +2662608,2760,assets/ge007.u.29D160.Globalimagetable.bin,0,0 +2667728,26608,assets/rarewarelogo.bin,0,0 +2694336,107904,assets/ge007.u.2A4D50.usedby7F008DE4.bin,0,1 +2802240,8976,assets/ramrom/ramrom_Dam_1.bin,0,1 +2811216,19888,assets/ramrom/ramrom_Dam_2.bin,0,1 +2831104,12944,assets/ramrom/ramrom_Facility_1.bin,0,1 +2844048,13696,assets/ramrom/ramrom_Facility_2.bin,0,1 +2857744,13632,assets/ramrom/ramrom_Facility_3.bin,0,1 +2871376,9968,assets/ramrom/ramrom_Runway_1.bin,0,1 +2881344,27600,assets/ramrom/ramrom_Runway_2.bin,0,1 +2908944,20688,assets/ramrom/ramrom_BunkerI_1.bin,0,1 +2929632,17440,assets/ramrom/ramrom_BunkerI_2.bin,0,1 +2947072,9472,assets/ramrom/ramrom_Silo_1.bin,0,1 +2956544,13392,assets/ramrom/ramrom_Silo_2.bin,0,1 +2969936,10816,assets/ramrom/ramrom_Frigate_1.bin,0,1 +2980752,8224,assets/ramrom/ramrom_Frigate_2.bin,0,1 +2988976,11392,assets/ramrom/ramrom_Train.bin,0,1 +3000368,676,assets/font/fontBankGothic_kerning.bin,0,0 +3001044,8716,assets/font/fontBankGothic_fontchartable.bin,0,0 +3009760,676,assets/font/fontZurichBold_kerning.bin,0,0 +3010436,12956,assets/font/fontZurichBold_fontchartable.bin,0,0 +3023392,23488,assets/music/sfx.ctl,0,1 +3046880,797360,assets/music/sfx.tbl,0,1 +3844240,17312,assets/music/instruments.ctl,0,1 +3861552,397216,assets/music/instruments.tbl,0,1 +4258768,126667,assets/music/music.sbk,0,1 +4258768,4,assets/music/number_music_samples,0,0 +4258772,504,assets/music/table_music_data.bin,0,0 +4259276,42,assets/music/Mno_music.bin,1,1 +4259318,470,assets/music/Msolo_death_abrev.bin,1,1 +4259788,2222,assets/music/Mintro_eye.bin,1,1 +4262010,3050,assets/music/Mtrain.bin,1,1 +4265060,3488,assets/music/Mdepot.bin,1,1 +4268548,3480,assets/music/Mjungle_unused.bin,1,1 +4272028,3520,assets/music/Mcitadel.bin,1,1 +4275548,2766,assets/music/Mfacility.bin,1,1 +4278314,2910,assets/music/Mcontrol.bin,1,1 +4281224,3588,assets/music/Mdam.bin,1,1 +4284812,3552,assets/music/Mfrigate.bin,1,1 +4288364,2388,assets/music/Marchives.bin,1,1 +4290752,3696,assets/music/Msilo.bin,1,1 +4294448,3948,assets/music/Mjungle_perimeter_unused.bin,1,1 +4298396,3330,assets/music/Mstreets.bin,1,1 +4301726,1650,assets/music/Mbunker1.bin,1,1 +4303376,1664,assets/music/Mbunker2.bin,1,1 +4305040,2456,assets/music/Mstatue.bin,1,1 +4307496,2522,assets/music/Melevator_control.bin,1,1 +4310018,3424,assets/music/Mcradle.bin,1,1 +4313442,42,assets/music/Mnull1.bin,1,1 +4313484,1606,assets/music/Melevator_wc.bin,1,1 +4315090,3482,assets/music/Megyptian.bin,1,1 +4318572,994,assets/music/Mfolders.bin,1,1 +4319566,498,assets/music/Mwatchmusic.bin,1,1 +4320064,3186,assets/music/Maztec.bin,1,1 +4323250,3628,assets/music/Mwatercaverns.bin,1,1 +4326878,870,assets/music/Mdeathsolo.bin,1,1 +4327748,3510,assets/music/Msurface2.bin,1,1 +4331258,2208,assets/music/Mtrainx.bin,1,1 +4333466,42,assets/music/Mnull2.bin,1,1 +4333508,2392,assets/music/Mfacilityx.bin,1,1 +4335900,1980,assets/music/Mdepotx.bin,1,1 +4337880,1352,assets/music/Mcontrolx.bin,1,1 +4339232,1876,assets/music/Mwatercavernsx.bin,1,1 +4341108,1312,assets/music/Mdamx.bin,1,1 +4342420,1474,assets/music/Mfrigatex.bin,1,1 +4343894,1828,assets/music/Marchivesx.bin,1,1 +4345722,2292,assets/music/Msilox.bin,1,1 +4348014,42,assets/music/Mnull3.bin,1,1 +4348056,1644,assets/music/Mstreetsx.bin,1,1 +4349700,1958,assets/music/Mbunker1x.bin,1,1 +4351658,1614,assets/music/Mbunker2x.bin,1,1 +4353272,2070,assets/music/Mjunglex.bin,1,1 +4355342,1074,assets/music/Mnint_rare_logo.bin,1,1 +4356416,1720,assets/music/Mstatuex.bin,1,1 +4358136,2262,assets/music/Maztecx.bin,1,1 +4360398,2224,assets/music/Megyptianx.bin,1,1 +4362622,1738,assets/music/Mcradlex.bin,1,1 +4364360,2122,assets/music/Mcuba.bin,1,1 +4366482,3358,assets/music/Mrunway.bin,1,1 +4369840,730,assets/music/Mrunway_plane.bin,1,1 +4370570,1832,assets/music/Msurface2x.bin,1,1 +4372402,1314,assets/music/Mwindblowing.bin,1,1 +4373716,524,assets/music/Mmultideath_alt.bin,1,1 +4374240,1928,assets/music/Mjungle.bin,1,1 +4376168,1570,assets/music/Mrunwayx.bin,1,1 +4377738,3432,assets/music/Msurface1.bin,1,1 +4381170,712,assets/music/Mmultiplayerdeath.bin,1,1 +4381882,1832,assets/music/Msurface1x.bin,1,1 +4383714,668,assets/music/Msurface2_ending.bin,1,1 +4384382,358,assets/music/Mstatue_ending.bin,1,1 +4384740,700,assets/music/Mfrigate_outro.bin,1,1 4385440,69104,assets/obseg/bg/bg_sev_all_p.bin,0,0 4454544,331584,assets/obseg/bg/bg_silo_all_p.bin,0,0 4786128,139472,assets/obseg/bg/bg_stat_all_p.bin,0,1 @@ -26,12 +122,12 @@ 7148064,0,assets/obseg/bg/bg_ash_all_p.bin,0,1 7148064,0,assets/obseg/bg/bg_lue_all_p.bin,0,1 7148064,40800,assets/obseg/bg/bg_ame_all_p.bin,0,1 -7188864,0,assets/obseg/bg/bg_oat_all_p.bin,0,0 -7188864,28240,assets/obseg/bg/bg_rit_all_p.bin,0,1 +7188864,0,assets/obseg/bg/bg_rit_all_p.bin,0,1 +7188864,28240,assets/obseg/bg/bg_oat_all_p.bin,0,0 7217104,0,assets/obseg/bg/bg_ear_all_p.bin,0,0 7217104,0,assets/obseg/bg/bg_lee_all_p.bin,0,0 -7217104,0,assets/obseg/bg/bg_len_all_p.bin,0,0 -7217104,4000,assets/obseg/bg/bg_lip_all_p.bin,0,1 +7217104,0,assets/obseg/bg/bg_lip_all_p.bin,0,0 +7217104,4000,assets/obseg/bg/bg_len_all_p.bin,0,1 7221104,0,assets/obseg/bg/bg_wax_all_p.bin,0,0 7221104,0,assets/obseg/bg/bg_pam_all_p.bin,0,0 7221104,9344,assets/obseg/chr/CarmourguardZ,1,1 @@ -57,10 +153,10 @@ 7403216,976,assets/obseg/chr/CheadbalaclavaZ,1,1 7404192,1696,assets/obseg/chr/CheadbikeZ,1,1 7405888,3408,assets/obseg/chr/CheadbrosnanZ,1,1 -7409296,2976,assets/obseg/chr/Cheadbrosnanboiler,1,1 -7412272,3712,assets/obseg/chr/Cheadbrosnansnow,1,1 -7415984,3456,assets/obseg/chr/Cheadbrosnansuit,1,1 -7419440,3008,assets/obseg/chr/Cheadbrosnantimber,1,1 +7409296,2976,assets/obseg/chr/CheadbrosnanboilerZ.bin,1,1 +7412272,3712,assets/obseg/chr/CheadbrosnansnowZ.bin,1,1 +7415984,3456,assets/obseg/chr/CheadbrosnansuitZ.bin,1,1 +7419440,3008,assets/obseg/chr/CheadbrosnantimberZ.bin,1,1 7422448,1344,assets/obseg/chr/CheadchrisZ,1,1 7423792,1408,assets/obseg/chr/CheaddaveZ,1,1 7425200,1328,assets/obseg/chr/CheaddesZ,1,1 @@ -140,7 +236,7 @@ 7770944,848,assets/obseg/gun/GdoorexploderZ,1,1 7771792,864,assets/obseg/gun/GdossierredZ,1,1 7772656,848,assets/obseg/gun/GdynamiteZ,1,1 -7773504,592,assets/obseg/gun/Gexplosivefloppy,1,1 +7773504,592,assets/obseg/gun/GexplosivefloppyZ.bin,1,1 7774096,848,assets/obseg/gun/GexplosivepenZ,1,1 7774944,2032,assets/obseg/gun/GextinguisherZ,1,1 7776976,848,assets/obseg/gun/GfingergunZ,1,1 @@ -156,7 +252,7 @@ 7808944,4224,assets/obseg/gun/GgrenadelaunchZ,1,1 7813168,848,assets/obseg/gun/GheroinZ,1,1 7814016,7856,assets/obseg/gun/GjoypadZ,1,1 -7821872,1936,assets/obseg/gun/Gkeyanalysercase,1,1 +7821872,1936,assets/obseg/gun/GkeyanalysercaseZ.bin,1,1 7823808,2544,assets/obseg/gun/GkeyboltZ,1,1 7826352,304,assets/obseg/gun/GkeycardZ,1,1 7826656,3408,assets/obseg/gun/GkeyyaleZ,1,1 @@ -180,7 +276,7 @@ 7861104,2496,assets/obseg/gun/GremotemineZ,1,1 7863600,4640,assets/obseg/gun/GrocketlaunchZ,1,1 7868240,7568,assets/obseg/gun/GrugerZ,1,1 -7875808,1936,assets/obseg/gun/Gsafecrackercase,1,1 +7875808,1936,assets/obseg/gun/GsafecrackercaseZ.bin,1,1 7877744,3808,assets/obseg/gun/GshotgunZ,1,1 7881552,6496,assets/obseg/gun/GsilverwppkZ,1,1 7888048,4608,assets/obseg/gun/GskorpionZ,1,1 @@ -236,12 +332,12 @@ 8038560,1088,assets/obseg/prop/Pboxes3x4Z,1,1 8039648,1632,assets/obseg/prop/Pboxes4x4Z,1,1 8041280,880,assets/obseg/prop/PbrakeunitZ,1,1 -8042160,1408,assets/obseg/prop/Pbridge_console,1,1 -8043568,1376,assets/obseg/prop/Pbridge_console,1,1 -8044944,1408,assets/obseg/prop/Pbridge_console,1,1 -8046352,1264,assets/obseg/prop/Pbridge_console,1,1 -8047616,1360,assets/obseg/prop/Pbridge_console,1,1 -8048976,1424,assets/obseg/prop/Pbridge_console,1,1 +8042160,1408,assets/obseg/prop/Pbridge_console1aZ.bin,1,1 +8043568,1376,assets/obseg/prop/Pbridge_console1bZ.bin,1,1 +8044944,1408,assets/obseg/prop/Pbridge_console2aZ.bin,1,1 +8046352,1264,assets/obseg/prop/Pbridge_console2bZ.bin,1,1 +8047616,1360,assets/obseg/prop/Pbridge_console3aZ.bin,1,1 +8048976,1424,assets/obseg/prop/Pbridge_console3bZ.bin,1,1 8050400,3296,assets/obseg/prop/PcarbmwZ,1,1 8053696,512,assets/obseg/prop/Pcard_box1Z,1,1 8054208,576,assets/obseg/prop/Pcard_box2Z,1,1 @@ -265,38 +361,38 @@ 8085280,368,assets/obseg/prop/PchrbugdetectorZ,1,1 8085648,368,assets/obseg/prop/PchrbungeeZ,1,1 8086016,1680,assets/obseg/prop/PchrcameraZ,1,1 -8087696,416,assets/obseg/prop/Pchrcircuitboard,1,1 +8087696,416,assets/obseg/prop/PchrcircuitboardZ.bin,1,1 8088112,640,assets/obseg/prop/PchrclipboardZ,1,1 8088752,368,assets/obseg/prop/PchrcreditcardZ,1,1 8089120,368,assets/obseg/prop/PchrdarkglassesZ,1,1 8089488,416,assets/obseg/prop/PchrdatathiefZ,1,1 8089904,496,assets/obseg/prop/PchrdattapeZ,1,1 8090400,2144,assets/obseg/prop/PchrdoordecoderZ,1,1 -8092544,368,assets/obseg/prop/Pchrdoorexploder,1,1 +8092544,368,assets/obseg/prop/PchrdoorexploderZ.bin,1,1 8092912,1232,assets/obseg/prop/PchrdossierredZ,1,1 8094144,368,assets/obseg/prop/PchrdynamiteZ,1,1 -8094512,368,assets/obseg/prop/Pchrexplosivepen,1,1 -8094880,1280,assets/obseg/prop/Pchrextinguisher,1,1 +8094512,368,assets/obseg/prop/PchrexplosivepenZ.bin,1,1 +8094880,1280,assets/obseg/prop/PchrextinguisherZ.bin,1,1 8096160,368,assets/obseg/prop/PchrfingergunZ,1,1 8096528,368,assets/obseg/prop/PchrflarepistolZ,1,1 8096896,1120,assets/obseg/prop/Pchrfnp90Z,1,1 8098016,3856,assets/obseg/prop/PchrgaskeyringZ,1,1 8101872,368,assets/obseg/prop/PchrgoldbarZ,1,1 8102240,624,assets/obseg/prop/PchrgoldenZ,1,1 -8102864,3744,assets/obseg/prop/Pchrgoldeneyekey,1,1 +8102864,3744,assets/obseg/prop/PchrgoldeneyekeyZ.bin,1,1 8106608,368,assets/obseg/prop/PchrgoldwppkZ,1,1 8106976,880,assets/obseg/prop/PchrgrenadeZ,1,1 -8107856,912,assets/obseg/prop/Pchrgrenadelauncher,1,1 -8108768,624,assets/obseg/prop/Pchrgrenaderound,1,1 +8107856,912,assets/obseg/prop/PchrgrenadelaunchZ.bin,1,1 +8108768,624,assets/obseg/prop/PchrgrenaderoundZ.bin,1,1 8109392,368,assets/obseg/prop/PchrheroinZ,1,1 8109760,1008,assets/obseg/prop/PchrkalashZ,1,1 -8110768,496,assets/obseg/prop/Pchrkeyanalyser,1,1 +8110768,496,assets/obseg/prop/PchrkeyanalysercaseZ.bin,1,1 8111264,3744,assets/obseg/prop/PchrkeyboltZ,1,1 8115008,5216,assets/obseg/prop/PchrkeyyaleZ,1,1 8120224,512,assets/obseg/prop/PchrknifeZ,1,1 8120736,960,assets/obseg/prop/PchrlaserZ,1,1 8121696,368,assets/obseg/prop/PchrlectreZ,1,1 -8122064,368,assets/obseg/prop/Pchrlockexploder,1,1 +8122064,368,assets/obseg/prop/PchrlockexploderZ.bin,1,1 8122432,976,assets/obseg/prop/Pchrm16Z,1,1 8123408,336,assets/obseg/prop/PchrmapZ,1,1 8123744,2288,assets/obseg/prop/PchrmicrocameraZ,1,1 @@ -308,13 +404,13 @@ 8129072,368,assets/obseg/prop/PchrpitongunZ,1,1 8129440,656,assets/obseg/prop/PchrplansZ,1,1 8130096,1120,assets/obseg/prop/PchrplastiqueZ,1,1 -8131216,2240,assets/obseg/prop/Pchrpolarizedglasses,1,1 -8133456,1120,assets/obseg/prop/Pchrproximitymine,1,1 +8131216,2240,assets/obseg/prop/PchrpolarizedglassesZ.bin,1,1 +8133456,1120,assets/obseg/prop/PchrproximitymineZ.bin,1,1 8134576,1120,assets/obseg/prop/PchrremotemineZ,1,1 8135696,1456,assets/obseg/prop/PchrrocketZ,1,1 -8137152,992,assets/obseg/prop/Pchrrocketlauncher,1,1 +8137152,992,assets/obseg/prop/PchrrocketlaunchZ.bin,1,1 8138144,992,assets/obseg/prop/PchrrugerZ,1,1 -8139136,496,assets/obseg/prop/Pchrsafecracker,1,1 +8139136,496,assets/obseg/prop/PchrsafecrackercaseZ.bin,1,1 8139632,848,assets/obseg/prop/PchrshotgunZ,1,1 8140480,368,assets/obseg/prop/PchrsilverwppkZ,1,1 8140848,896,assets/obseg/prop/PchrskorpionZ,1,1 @@ -340,8 +436,8 @@ 8157488,1216,assets/obseg/prop/Pconsole_sev2bZ,1,1 8158704,1088,assets/obseg/prop/Pconsole_sev2cZ,1,1 8159792,1072,assets/obseg/prop/Pconsole_sev2dZ,1,1 -8160864,1072,assets/obseg/prop/Pconsole_sev_GE,1,1 -8161936,1072,assets/obseg/prop/Pconsole_sev_GE,1,1 +8160864,1072,assets/obseg/prop/Pconsole_sev_GEaZ.bin,1,1 +8161936,1072,assets/obseg/prop/Pconsole_sev_GEbZ.bin,1,1 8163008,1152,assets/obseg/prop/Pconsole_sevaZ,1,1 8164160,1136,assets/obseg/prop/Pconsole_sevbZ,1,1 8165296,1072,assets/obseg/prop/Pconsole_sevcZ,1,1 @@ -355,8 +451,8 @@ 8170048,640,assets/obseg/prop/PdamchaindoorZ,1,1 8170688,544,assets/obseg/prop/PdamgatedoorZ,1,1 8171232,880,assets/obseg/prop/PdamtundoorZ,1,1 -8172112,416,assets/obseg/prop/Pdepot_door_ste,1,1 -8172528,576,assets/obseg/prop/Pdepot_gate_ent,1,1 +8172112,416,assets/obseg/prop/Pdepot_door_steelZ.bin,1,1 +8172528,576,assets/obseg/prop/Pdepot_gate_entryZ.bin,1,1 8173104,384,assets/obseg/prop/Pdesk1Z,1,1 8173488,384,assets/obseg/prop/Pdesk2Z,1,1 8173872,576,assets/obseg/prop/Pdesk_arecibo1Z,1,1 @@ -370,7 +466,7 @@ 8191552,400,assets/obseg/prop/Pdisk_drive1Z,1,1 8191952,384,assets/obseg/prop/Pdoor_azt_chairZ,1,1 8192336,1088,assets/obseg/prop/Pdoor_azt_deskZ,1,1 -8193424,912,assets/obseg/prop/Pdoor_azt_desk_,1,1 +8193424,912,assets/obseg/prop/Pdoor_azt_desk_topZ.bin,1,1 8194336,560,assets/obseg/prop/Pdoor_aztecZ,1,1 8194896,768,assets/obseg/prop/Pdoor_dest1Z,1,1 8195664,960,assets/obseg/prop/Pdoor_dest2Z,1,1 @@ -381,7 +477,7 @@ 8202272,576,assets/obseg/prop/Pdoor_roller2Z,1,1 8202848,576,assets/obseg/prop/Pdoor_roller3Z,1,1 8203424,608,assets/obseg/prop/Pdoor_roller4Z,1,1 -8204032,304,assets/obseg/prop/Pdoor_rollertra,1,1 +8204032,304,assets/obseg/prop/Pdoor_rollertrainZ.bin,1,1 8204336,608,assets/obseg/prop/Pdoor_st_arec1Z,1,1 8204944,736,assets/obseg/prop/Pdoor_st_arec2Z,1,1 8205680,416,assets/obseg/prop/Pdoor_winZ,1,1 @@ -390,19 +486,19 @@ 8208112,336,assets/obseg/prop/Pdoorprison1Z,1,1 8208448,512,assets/obseg/prop/PdoorstatgateZ,1,1 8208960,288,assets/obseg/prop/PexplosionbitZ,1,1 -8209248,384,assets/obseg/prop/Pfiling_cabinet,1,1 +8209248,384,assets/obseg/prop/Pfiling_cabinet1Z.bin,1,1 8209632,304,assets/obseg/prop/PflagZ,1,1 8209936,800,assets/obseg/prop/PfloppyZ,1,1 8210736,416,assets/obseg/prop/Pfnp90magZ,1,1 -8211152,896,assets/obseg/prop/Pgas_plant_met1,1,1 -8212048,480,assets/obseg/prop/Pgas_plant_sw2_,1,1 -8212528,512,assets/obseg/prop/Pgas_plant_sw3_,1,1 -8213040,352,assets/obseg/prop/Pgas_plant_sw4_,1,1 -8213392,656,assets/obseg/prop/Pgas_plant_sw_d,1,1 -8214048,528,assets/obseg/prop/Pgas_plant_wc_c,1,1 +8211152,896,assets/obseg/prop/Pgas_plant_met1_do1Z.bin,1,1 +8212048,480,assets/obseg/prop/Pgas_plant_sw2_do1Z.bin,1,1 +8212528,512,assets/obseg/prop/Pgas_plant_sw3_do1Z.bin,1,1 +8213040,352,assets/obseg/prop/Pgas_plant_sw4_do1Z.bin,1,1 +8213392,656,assets/obseg/prop/Pgas_plant_sw_do1Z.bin,1,1 +8214048,528,assets/obseg/prop/Pgas_plant_wc_cub1Z.bin,1,1 8214576,528,assets/obseg/prop/PgasbarrelZ,1,1 8215104,1344,assets/obseg/prop/PgasbarrelsZ,1,1 -8216448,1376,assets/obseg/prop/Pgasplant_clear,1,1 +8216448,1376,assets/obseg/prop/Pgasplant_clear_doorZ.bin,1,1 8217824,1456,assets/obseg/prop/PgastankZ,1,1 8219280,352,assets/obseg/prop/Pglassware1Z,1,1 8219632,656,assets/obseg/prop/Pglassware2Z,1,1 @@ -493,7 +589,7 @@ 8359552,816,assets/obseg/prop/Psev_door_v1Z,1,1 8360368,944,assets/obseg/prop/Psev_trislideZ,1,1 8361312,3872,assets/obseg/prop/PsevdishZ,1,1 -8365184,736,assets/obseg/prop/Psevdoormetslid,1,1 +8365184,736,assets/obseg/prop/PsevdoormetslideZ.bin,1,1 8365920,368,assets/obseg/prop/PsevdoornowindZ,1,1 8366288,1072,assets/obseg/prop/PsevdoorwindZ,1,1 8367360,944,assets/obseg/prop/PsevdoorwoodZ,1,1 @@ -506,11 +602,11 @@ 8387248,352,assets/obseg/prop/PskorpionmagZ,1,1 8387600,368,assets/obseg/prop/PspectremagZ,1,1 8387968,3392,assets/obseg/prop/PspeedboatZ,1,1 -8391360,12608,assets/obseg/prop/Pst_pete_room_1,1,1 -8403968,12768,assets/obseg/prop/Pst_pete_room_2,1,1 -8416736,12096,assets/obseg/prop/Pst_pete_room_3,1,1 -8428832,13712,assets/obseg/prop/Pst_pete_room_5,1,1 -8442544,13328,assets/obseg/prop/Pst_pete_room_6,1,1 +8391360,12608,assets/obseg/prop/Pst_pete_room_1iZ.bin,1,1 +8403968,12768,assets/obseg/prop/Pst_pete_room_2iZ.bin,1,1 +8416736,12096,assets/obseg/prop/Pst_pete_room_3tZ.bin,1,1 +8428832,13712,assets/obseg/prop/Pst_pete_room_5cZ.bin,1,1 +8442544,13328,assets/obseg/prop/Pst_pete_room_6cZ.bin,1,1 8455872,624,assets/obseg/prop/Psteel_door1Z,1,1 8456496,688,assets/obseg/prop/Psteel_door2Z,1,1 8457184,720,assets/obseg/prop/Psteel_door2bZ,1,1 @@ -526,7 +622,7 @@ 8479232,624,assets/obseg/prop/Ptrain_doorZ,1,1 8479856,832,assets/obseg/prop/PtrainextdoorZ,1,1 8480688,320,assets/obseg/prop/Ptt33magZ,1,1 -8481008,1312,assets/obseg/prop/Ptuning_console,1,1 +8481008,1312,assets/obseg/prop/Ptuning_console1Z.bin,1,1 8482320,464,assets/obseg/prop/Ptv1Z,1,1 8482784,416,assets/obseg/prop/Ptv4screenZ,1,1 8483200,1744,assets/obseg/prop/Ptv_holderZ,1,1 @@ -779,4 +875,5 @@ 9399728,1376,LwaxE,1,1 9401104,1296,LwaxJ,1,1 9402400,16,LwaxP,1,1 +9402416,16,assets/obseg/ob__ob_end.seg,0,1 diff --git a/scripts/filelist.j.csv b/scripts/filelist.j.csv index bdd9cd75..9ef265f4 100644 --- a/scripts/filelist.j.csv +++ b/scripts/filelist.j.csv @@ -21,7 +21,7 @@ 3014208,13536,assets/ramrom/ramrom_Frigate_2.bin,0,1 3027744,15856,assets/ramrom/ramrom_Train.bin,0,1 3043600,676,assets/font/fontBankGothic_kerning.bin,0,0 -3044276,8716,assets/font/fontZurichBold_fontchartable.bin,0,0 +3044276,8716,assets/font/fontBankGothic_fontchartable.bin,0,0 3052992,676,assets/font/fontZurichBold_kerning.bin,0,0 3053668,12956,assets/font/fontZurichBold_fontchartable.bin,0,0 3066624,23488,assets/music/sfx.ctl,0,1 diff --git a/src/boss.c b/src/boss.c index ad78f099..cb766ee0 100644 --- a/src/boss.c +++ b/src/boss.c @@ -146,9 +146,6 @@ struct memallocstring memallocstringtable[] = { }; s32 g_MainStageNum = LEVELID_NONE; -#ifdef PORT -static s32 g_d235ReloadStage = -1, g_d235ReloadWait = 0; /* TEMP D235 verification */ -#endif s32 g_BossIsDebugMenuOpen = FALSE; OSScMsg g_bossGfxDoneMsg = { OS_SC_DONE_MSG }; @@ -524,35 +521,7 @@ void bossMainloop(void) if (ge_d235) osSyncPrintf("D235: stage=%d texcache entries purged at load=%d\n", (s32)g_StageNum, gfx_texture_cache_count()); - if (!getenv("GE_D235_OFF")) /* TEMP: A/B switch for verification */ - videoResetTextureCache(); - - /* TEMP (D235 verification, remove with the probe): - * GE_D235_RELOAD= re-enters the first level once, - * retraces after the title stage loads following it (e.g. after a - * watch Abort) -- so the front end has rendered its own textures - * into the reset stage arena first, like a real death/restart -- - * via the same bossSetLoadedStage() call the front end's mission - * start makes (front.c). Inert when unset. */ - { - static int s_reload = -2, s_firstLevel = -1; - if (s_reload == -2) { - const char *e = getenv("GE_D235_RELOAD"); - s_reload = e ? atoi(e) : -1; - } - if (s_reload >= 0) { - if (g_StageNum != LEVELID_TITLE && s_firstLevel < 0) - s_firstLevel = g_StageNum; - else if (g_StageNum == LEVELID_TITLE && s_firstLevel >= 0 && - g_d235ReloadStage < 0 && g_d235ReloadWait == 0) { - /* GE_D235_NEXT=: load a DIFFERENT stage - * instead (level A -> title -> level B leaks). */ - const char *nx = getenv("GE_D235_NEXT"); - g_d235ReloadStage = (nx && *nx) ? (s32)strtol(nx, NULL, 0) : s_firstLevel; - g_d235ReloadWait = s_reload + 1; - } - } - } + videoResetTextureCache(); } #endif @@ -630,13 +599,6 @@ void bossMainloop(void) { if (g_MainStageNum < 0 && pendingGfx < 2U) { -#ifdef PORT - /* TEMP D235 verification (see GE_D235_RELOAD above) */ - if (g_d235ReloadWait > 0 && --g_d235ReloadWait == 0) { - osSyncPrintf("D235: RELOAD re-entering stage %d\n", g_d235ReloadStage); - bossSetLoadedStage(g_d235ReloadStage); - } -#endif if (get_is_ramrom_flag()) { iterate_ramrom_entries_handle_camera_out(); @@ -671,7 +633,7 @@ void bossMainloop(void) joyButtons = joyGetButtons(0, ANY_BUTTON); g_BossIsDebugMenuOpen = debug_menu_processor(joyStickXPos, joyStickYPos, joyButtons, joyGetButtonsPressedThisFrame(0, ANY_BUTTON)); } -#elif defined(PORT) +#elif defined(PORT) && defined(LEFTOVERDEBUG) /* the debug-menu globals only exist with LEFTOVERDEBUG (not PAL) */ // GE_DEBUGMENU=1 -- diagnostic-only: enable leftover debug-menu open // path (D243). Unset (default) reproduces the #ifndef DEBUGMENU // behavior below exactly -- no behavior change. diff --git a/src/game/explosion.c b/src/game/explosion.c index 5c7fed0b..24904a74 100644 --- a/src/game/explosion.c +++ b/src/game/explosion.c @@ -1,3 +1,6 @@ +#ifdef PORT +#include "porttick.h" /* D486 */ +#endif #include #include #include @@ -434,6 +437,22 @@ void explosionScreenShake(coord3d* source_pos, coord3d* source_mag, coord3d* res } } +#ifdef PORT + /* D486 (RULE-2): the shake counters decayed once per frame; decay at the N64's 2-ticks-per-frame pace */ + if (g_NumSmokeEntries > 0) + { + if (portN64FrameStep()) + { + g_NumSmokeEntries--; + } + explosion_mag++; + } + + if (portN64FrameStep()) + { + g_NumExplosionEntries--; + } +#else if (g_NumSmokeEntries > 0) { g_NumSmokeEntries--; @@ -441,6 +460,7 @@ void explosionScreenShake(coord3d* source_pos, coord3d* source_mag, coord3d* res } g_NumExplosionEntries--; +#endif if (g_NumExplosionEntries & 2) { result->y = explosion_mag; @@ -721,6 +741,13 @@ s32 explosionTick(PropRecord* arg0) } sp9C = (s32) (((f32)explosiontype->propagationrate * (f32)exp->age) / (f32)explosiontype->duration) + 1; +#ifdef PORT + /* D486 (RULE-2): parts spawned once per frame; spawn at the N64's 2-ticks-per-frame pace */ + if (!portN64FrameStep()) + { + sp9C = 0; + } +#endif for (var_s4 = 0; var_s4 < sp9C; var_s4++) { for (j=0; jZoom; } +#ifdef PORT +/* D485 RULE-2-SIGNOFF (maintainer, 2026-10-02: "approve the rule 2 change to + * match the N64 real time speed"). The sniper/camera zoom steps once per game + * FRAME with no tick scaling. The N64 ran these frames at ~2 ticks each + * (30 fps; 20 fps = 3), the port at 1 tick per frame, so the port zoomed 2x + * faster in real time. Scale the per-frame factor to base^(ticks/2): one + * N64 frame at 2 ticks gets exactly the original factor, and the port's + * 1-tick frame gets its square root. Same "N64 frame = 2 ticks" convention as + * the D427 fire gate. g_ClockTimer == 0 (paused/locked) means no step. */ +float sqrtf(float); +static f32 gunZoomStepFactor(f32 zoom) +{ + f32 half = sqrtf(1.0f + (zoom * 0.1f)); + f32 factor = 1.0f; + s32 i; + + for (i = 0; i < g_ClockTimer; i++) { + factor *= half; + } + + return factor; +} +#define GUN_ZOOM_STEP(zoom) gunZoomStepFactor(zoom) +#else +#define GUN_ZOOM_STEP(zoom) (1.0f + ((zoom) * 0.1f)) +#endif + void camera_sniper_zoom_out(f32 zoom) { if (get_item_in_hand_or_watch_menu(GUNRIGHT) == ITEM_SNIPERRIFLE) { - g_CurrentPlayer->sniper_zoom *= (1.0f + (zoom * 0.1f)); + g_CurrentPlayer->sniper_zoom *= GUN_ZOOM_STEP(zoom); if (g_CurrentPlayer->sniper_zoom > 60.0f) { g_CurrentPlayer->sniper_zoom = 60.0f; } @@ -1289,7 +1316,7 @@ void camera_sniper_zoom_out(f32 zoom) else { if (get_item_in_hand_or_watch_menu(GUNRIGHT) == ITEM_CAMERA) { - g_CurrentPlayer->camera_zoom *= (1.0f + (zoom * 0.1f)); + g_CurrentPlayer->camera_zoom *= GUN_ZOOM_STEP(zoom); if (g_CurrentPlayer->camera_zoom > 60.0f) { g_CurrentPlayer->camera_zoom = 60.0f; } @@ -1300,7 +1327,7 @@ void camera_sniper_zoom_out(f32 zoom) void camera_sniper_zoom_in(f32 zoom) { if (get_item_in_hand_or_watch_menu(GUNRIGHT) == ITEM_SNIPERRIFLE) { - g_CurrentPlayer->sniper_zoom /= (1.0f + (zoom * 0.1f)); + g_CurrentPlayer->sniper_zoom /= GUN_ZOOM_STEP(zoom); if (g_CurrentPlayer->sniper_zoom < 7.0f) { g_CurrentPlayer->sniper_zoom = 7.0f; } @@ -1308,7 +1335,7 @@ void camera_sniper_zoom_in(f32 zoom) else { if (get_item_in_hand_or_watch_menu(GUNRIGHT) == ITEM_CAMERA) { - g_CurrentPlayer->camera_zoom /= (1.0f + (zoom * 0.1f)); + g_CurrentPlayer->camera_zoom /= GUN_ZOOM_STEP(zoom); if (g_CurrentPlayer->camera_zoom < 7.0f) { g_CurrentPlayer->camera_zoom = 7.0f; } diff --git a/src/game/lv.c b/src/game/lv.c index b605df96..28ed76e4 100644 --- a/src/game/lv.c +++ b/src/game/lv.c @@ -407,11 +407,18 @@ void lvlStageLoad(s32 stage) extern struct mp_stage_setup multi_stage_setups[]; extern void init_mp_options_for_scenario(s32 numplayers); extern s32 selected_num_players; + extern s32 selected_folder_num; s32 np = (s32)strtol(smp, NULL, 0); const char *comma = strchr(smp, ','); if (np < 2) np = 2; if (np > 4) np = 4; gamemode = GAMEMODE_MULTI; + /* D479: the file-select screen a real MP launch passes through + * sets selected_folder_num = -1 (front.c), so the stage load's + * fileLoadSettingsForFolder applies no Bond file's options. + * Without this the harness applied a blank folder-1 record + * (options 0: ammo counter, sight and auto-aim off). */ + selected_folder_num = -1; init_mp_options_for_scenario(np); if (comma) MP_stage_selected = (s32)strtol(comma + 1, NULL, 0); selected_stage = multi_stage_setups[MP_stage_selected].stage_id; diff --git a/src/game/propobj.c b/src/game/propobj.c index 20aaa82e..1b9d2f55 100644 --- a/src/game/propobj.c +++ b/src/game/propobj.c @@ -6,6 +6,9 @@ ---------------------------------------------------------------------*/ +#ifdef PORT +#include "porttick.h" /* D486 */ +#endif #include #include #ifdef PORT @@ -6338,6 +6341,11 @@ s32 objTick(struct PropRecord *prop) if ((autogun->is_active != 0) && (!(obj->flags & PROPFLAG_IS_DRONE_GUN))) { +#ifdef PORT + /* D486 (RULE-2): the shot counter advanced per frame; step it at the N64's 2-ticks-per-frame pace */ + if (portN64FrameStep()) + { +#endif autogun->unkAC = autogun->unkAC + 1; sp13C = (autogun->unkAC & 1) == 0; @@ -6345,6 +6353,9 @@ s32 objTick(struct PropRecord *prop) { sp138 = (autogun->unkAC & 1) == 1; } +#ifdef PORT + } +#endif if (autogun->unkC0 < g_GlobalTimer) { @@ -6439,7 +6450,12 @@ s32 objTick(struct PropRecord *prop) if ((temp_f20_4 <= (((beam_xdiff * beam_xdiff) + (beam_ydiff * beam_ydiff)) + (beam_collisionTile * beam_collisionTile))) && (bondviewGetIfCurrentPlayerDamageShowTime() == 0)) { temp_f0_35 = sqrtf(temp_f20_4); +#ifdef PORT + /* D486: one shot now spans a 2-tick N64 frame below 2 ticks/frame, so charge that frame's delta (damage per second unchanged) */ + var_f2_7 = (0.16f * (g_ClockTimer >= 2 ? OBJECT_INTERACTION_TIMER_DELTA : 2.0f)) * g_AutogunPendingDamageTick; +#else var_f2_7 = (0.16f * OBJECT_INTERACTION_TIMER_DELTA) * g_AutogunPendingDamageTick; +#endif if (temp_f0_35 > 200.0f) { var_f2_7 *= 200.0f / temp_f0_35; diff --git a/src/game/sky.c b/src/game/sky.c index 61e2912b..33c90c42 100644 --- a/src/game/sky.c +++ b/src/game/sky.c @@ -31,18 +31,8 @@ /* D227 (M-95): forward decls -- the two fan-drawing blocks that call these * (further down this file) come before the static definitions themselves. * See the comment above skyPortBeginFan()'s definition. */ -static void skyPortBeginFan(SkyRelated38 *v, s32 n, bool allowShift); +static void skyPortBeginFan(SkyRelated38 *v, s32 n); static void skyPortEndFan(void); -/* D245 (M-142): same reason -- the water call site (further down) needs to - * override the adaptive shift picked by skyPortBeginFan() before the - * definition itself. */ -static void skyPortForceFanShift(s32 kS, s32 kT); -/* D227 (M-100): same reason -- the texSelect call sites precede the definition. */ -static void skyPortCaptureTile(Gfx *start, Gfx *end); -/* D227 (M-100): relocated up here (was just above skyPortPickShift, further - * down) so the D245 water call site's GE_D245_FIXEDSHIFT clamp can use it -- - * same forward-declare reason as the functions above. */ -#define SKY_TC_MAX_SHIFT 5 #endif // bss @@ -921,67 +911,14 @@ Gfx *skyRender(Gfx *gdl) { gDPPipeSync(gdl++); -#ifdef PORT - /* D227 (M-100): remember the tiles this draw sets up so - * skyPortEmitTileShift() can replay them with a shift. Captured - * AFTER sub_GAME_7F09343C, which re-declares both tiles -- see the - * comment above skyPortCaptureTile(). */ - { - Gfx *skyTileFrom = gdl; - texSelect(&gdl, &skywaterimages[fogGetCurrentEnvironmentp()->WaterImageId], 1, 0, 2); - gdl = sub_GAME_7F09343C(gdl, 0); // ??? - skyPortCaptureTile(skyTileFrom, gdl); - } -#else texSelect(&gdl, &skywaterimages[fogGetCurrentEnvironmentp()->WaterImageId], 1, 0, 2); gdl = sub_GAME_7F09343C(gdl, 0); // ??? -#endif gDPSetRenderMode(gdl++, G_RM_OPA_SURF, G_RM_OPA_SURF2); #ifdef PORT /* D227 (M-95): one shared wScale for every triangle drawn from - * this sp274[] fan -- see skyPortBeginFan() above. D245: allow - * the tc-shift safety valve on the water quad too -- see the - * comment above skyPortBeginFan() for why this doesn't flatten - * the cross-fade. */ - skyPortBeginFan(sp274, s1, TRUE); /* water: see skyPortBeginFan */ - - /* D245 (M-142): opt-in A/B candidate -- see skyPortForceFanShift's - * comment. Off by default (unset env => identical to the current - * allowShift=TRUE behaviour this row is still reopened against). */ - { - const char *fs = GE_ENVSTR("GE_D245_FIXEDSHIFT"); - if (fs) { - s32 kFixed = atoi(fs); - if (kFixed < 0) kFixed = 0; - if (kFixed > SKY_TC_MAX_SHIFT) kFixed = SKY_TC_MAX_SHIFT; - skyPortForceFanShift(kFixed, kFixed); - } - } - - /* D245 (M-142, reopened): dumps the water quad's raw S/T span - * every call, so a scripted multi-frame capture can show whether - * the span crosses skyPortPickShift's ~30719-unit threshold (and - * therefore the tc-shift k) as the camera rotates -- the - * still-open question after allowShift=TRUE didn't fix the live - * symptom. Recomputed locally rather than reading skyPortBeginFan's - * statics (defined later in this TU, not forward-declared). */ - if (GE_ENVFLAG("GE_D245V")) { - static int callN = 0; - f32 minS = sp274[0].unk20, maxS = sp274[0].unk20; - f32 minT = sp274[0].unk24, maxT = sp274[0].unk24; - s32 vi; - for (vi = 1; vi < s1; vi++) { - if (sp274[vi].unk20 < minS) minS = sp274[vi].unk20; - if (sp274[vi].unk20 > maxS) maxS = sp274[vi].unk20; - if (sp274[vi].unk24 < minT) minT = sp274[vi].unk24; - if (sp274[vi].unk24 > maxT) maxT = sp274[vi].unk24; - } - fprintf(stderr, "D245V call=%d s1=%d minS=%.1f maxS=%.1f minT=%.1f maxT=%.1f " - "spanS=%.1f spanT=%.1f\n", callN++, s1, - (double) minS, (double) maxS, (double) minT, (double) maxT, - (double) (maxS - minS), (double) (maxT - minT)); - } + * this sp274[] fan -- see skyPortBeginFan() above. */ + skyPortBeginFan(sp274, s1); #endif if (s1 == 4) { @@ -1401,16 +1338,7 @@ Gfx *skyRender(Gfx *gdl) gDPPipeSync(gdl++); -#ifdef PORT - /* D227 (M-100): see the matching capture in the IsWater block above. */ - { - Gfx *skyTileFrom = gdl; - texSelect(&gdl, &skywaterimages[fogGetCurrentEnvironmentp()->SkyImageId], 1, 0, 2); - skyPortCaptureTile(skyTileFrom, gdl); - } -#else texSelect(&gdl, &skywaterimages[fogGetCurrentEnvironmentp()->SkyImageId], 1, 0, 2); -#endif if (1); @@ -1442,7 +1370,7 @@ Gfx *skyRender(Gfx *gdl) /* D227 (M-95): one shared wScale for every triangle drawn from this * sp94[] fan -- see skyPortBeginFan() above. Computed from unk0c, * which none of the position overrides below touch. */ - skyPortBeginFan(sp94, s1, TRUE); + skyPortBeginFan(sp94, s1); #endif if (s1 == 4) { @@ -1659,129 +1587,18 @@ static bool s_skyFanFoldSet = FALSE; * per-fan consistency is still what keeps shared vertices bit-identical * between the fan's primitives. * - * THE SAFETY VALVE (normally inactive, k == 0). A span can in principle still - * exceed s16. The RDP's own answer to that is the tile descriptor's shift - * field: coordinates shift right by `shift` for shift <= 10 and LEFT by - * (16 - shift) for shift >= 11. So divide tc by 2^k and set the tile shift to - * (16 - k) -- decoded coordinate unchanged, s16 reaches 2^k further. - * port/fast3d implements this exactly (gfx_pc.cpp, gfx_dp_set_tile plus the - * u/v shift block), so it is a native GBI mechanism, not a port-side hack: no - * fast3d change, no tessellation, no extra vertices. - * - * k is chosen per FAN, not per primitive, for the same reason wScale and the - * fold are: the decoded coordinate is identical for any k, but the granularity - * is 2^k units, so two primitives sharing an edge under different k could round - * a shared vertex apart. - * - * k = 5 is the cap, because shift (16 - 5) == 11 is the smallest value fast3d - * still treats as a left shift. Beyond that a span would genuinely need - * Defect-2 tessellation; skyPortPickShift clamps rather than overflowing, so - * the failure mode stays graceful. + * (The tile-shift "safety valve" described here before went with the s16 sky + * vertex path it served: that path was removed 2026-09-30 and its leftover + * capture/shift code on 2026-10-02. The float path has no s16 range limit.) */ /* One tile period expressed in unk20/unk24's units: 64 texels * 32 = 2048. * The fold must be a whole number of these or the rebase shifts the texture. */ #define SKY_TC_WRAP 2048 -static s32 s_skyFanShiftS = 0; -static s32 s_skyFanShiftT = 0; - -/* - * Applying the shift means re-emitting the render tile's G_SETTILE with only - * its two shift fields changed. Rather than rebuild that command -- its format, - * depth, line and mask fields are derived inside texSelect() from the texture - * pool, and duplicating that derivation here would rot the moment a sky image - * had a different format -- capture the exact command texSelect() just emitted - * and replay a patched copy. Exact by construction, and it stays correct if - * texSelect's derivation ever changes. - * - * G_SETTILE word 1 layout (see port/fast3d/gfx_pc.cpp's G_SETTILE dispatch): - * tile = bits 24..26, shiftt = bits 10..13, shifts = bits 0..3. - */ -#define SKY_SETTILE_SHIFTT_SHIFT 10 -#define SKY_SETTILE_FIELD_MASK 0xF - -/* Tiles 0 and 1 are both captured. The IsWater path is a two-texunit draw - * (sub_GAME_7F09343C binds tile 0 and tile 1 to the same TMEM and cross-fades - * TEXEL0/TEXEL1 by an animated PRIM_LOD_FRAC), and both texunits read the same - * vertex tc, so a shift applied to only one of them would desynchronise the - * two layers. Capture must also run AFTER every tile-setup call for the draw, - * not just after texSelect -- sub_GAME_7F09343C re-declares both tiles, so - * capturing earlier would replay a stale declaration and clobber it. */ -#define SKY_NUM_CAPTURED_TILES 2 - -static Gfx s_skyTileCmd[SKY_NUM_CAPTURED_TILES]; -static bool s_skyTileCmdOk[SKY_NUM_CAPTURED_TILES]; - -/* Scan the display list just written for each tile's G_SETTILE. Takes the last - * match per tile: the mipmapped path emits one per level, and a later setup - * call may re-declare a tile the earlier one already set. */ -static void skyPortCaptureTile(Gfx *start, Gfx *end) -{ - Gfx *p; - s32 i; - - for (i = 0; i < SKY_NUM_CAPTURED_TILES; i++) - s_skyTileCmdOk[i] = FALSE; - - for (p = start; p < end; p++) - { - u32 tile; - - if ((u32) (p->words.w0 >> 24) != (u32) (u8) G_SETTILE) - continue; - - tile = (p->words.w1 >> 24) & 7; - if (tile >= (u32) SKY_NUM_CAPTURED_TILES) - continue; - - s_skyTileCmd[tile] = *p; - s_skyTileCmdOk[tile] = TRUE; - } -} - -/* Smallest k in [0, SKY_TC_MAX_SHIFT] for which the whole span still fits an - * s16 once divided by 2^k. `span` is the fan's S or T extent in S10.5 units; - * the +SKY_TC_WRAP covers the fold's rebase to a tile boundary. Normally - * returns 0 -- see the unit note above, the coordinates fit unaided. */ -static s32 skyPortPickShift(f32 span) -{ - s32 k; - for (k = 0; k < SKY_TC_MAX_SHIFT; k++) - { - if ((span + (f32) SKY_TC_WRAP) / (f32) (1 << k) <= 32767.0f) - break; - } - return k; -} - -/* - * `allowShift` gates the safety valve. The IsWater quad used to pass FALSE - * (see D245) on the theory that a matched shift on both texunits would - * flatten the cross-fade; that theory was wrong and D245 corrects it here. - * - * That quad is a two-texunit draw: sub_GAME_7F09343C binds tile 0 and tile 1 - * to the same TMEM and cross-fades TEXEL0/TEXEL1 with an animated - * PRIM_LOD_FRAC (the water shimmer). Both texunits read the SAME vertex tc; - * what makes tile 1 sample a different part of the texture is its own - * SetTileSize uls/ult offset (90,150 in 1/4-texel units -- see - * sub_GAME_7F09343C), applied by the RDP AFTER the tile's shift field - * multiplies the (possibly pre-divided) coordinate back up. skyPortEmitTileShift - * replays BOTH tiles' captured SETTILE commands with the identical k, so both - * texunits' decoded S/T are rescaled by the same 2^k before their own - * (unshifted, tile-native) uls/ult offset is applied -- the offset between - * tile 0 and tile 1's sample points is preserved, not flattened. Confirmed by - * a diagnostic build with allowShift forced TRUE on the water path: the - * cross-fade shimmer still animates, no flattening. D245 (view-tracking - * seam) was this quad's horizon vertex genuinely overflowing an s16 tc with - * no shift applied -- same class of bug as D227 before M-100b's fix, just - * never given the safety valve. - * - * The water on IsWater levels was separately and visibly broken (D229, green - * / pulsating, now FIXED) and that was NOT caused by any of this -- it - * reproduced identically on main with none of the D227 work present. - */ -static void skyPortBeginFan(SkyRelated38 *v, s32 n, bool allowShift) +/* D227 (M-95/M-98): compute the per-fan wScale and S/T fold shared by every + * primitive of one fan (see above). */ +static void skyPortBeginFan(SkyRelated38 *v, s32 n) { f32 maxAbsW = 0.0f; f32 minS, minT, maxS, maxT; @@ -1805,40 +1622,12 @@ static void skyPortBeginFan(SkyRelated38 *v, s32 n, bool allowShift) s_skyFanFoldS = (f32) ((s32) floorf(minS / (f32) SKY_TC_WRAP) * SKY_TC_WRAP); s_skyFanFoldT = (f32) ((s32) floorf(minT / (f32) SKY_TC_WRAP) * SKY_TC_WRAP); s_skyFanFoldSet = TRUE; - - s_skyFanShiftS = allowShift ? skyPortPickShift(maxS - minS) : 0; - s_skyFanShiftT = allowShift ? skyPortPickShift(maxT - minT) : 0; } static void skyPortEndFan(void) { s_skyFanWScale = 0.0f; s_skyFanFoldSet = FALSE; - s_skyFanShiftS = 0; - s_skyFanShiftT = 0; -} - -/* D245 (M-142): overrides the shift skyPortBeginFan() just picked. A GE_D245V - * capture (scripted camera turn, Frigate, headless) proved the water quad's - * raw S/T span sits in the ~290k-390k unit range -- roughly 10x sky's typical - * span -- and, critically, that skyPortPickShift's adaptive k genuinely - * CHANGES during ordinary view rotation (observed kT flipping 4->3 as spanT - * crossed skyPortPickShift's per-k breakpoint mid-turn). That contradicts the - * "normally k==0, this is a rare safety valve" assumption the mechanism was - * verified against (a single static frame, one camera angle) -- every k - * transition re-quantizes the shared vertex tc at a different granularity, - * which is a plausible mechanism for "glitches, goes back and forth... changes - * depending on your view" even with both texunits' relative offset preserved - * (D245's already-verified allowShift=TRUE reasoning). Untested candidate, - * NOT the default: forcing a single fixed k for the whole water draw removes - * the transition, at the cost of coarser (whole-k5-step) tc quantization - * always, which could itself look worse -- needs a live A/B, not another - * blind ship (see the finding's own "don't repeat the same mistake" note). - * GE_D245_FIXEDSHIFT= (0..SKY_TC_MAX_SHIFT) opts in; unset changes nothing. */ -static void skyPortForceFanShift(s32 kS, s32 kT) -{ - s_skyFanShiftS = kS; - s_skyFanShiftT = kT; } /* @@ -1882,7 +1671,7 @@ static Gfx *skyPortRenderPoly(Gfx *gdl, SkyRelated38 **v, s32 nverts) * multiple of that drops magnitudes into s16 range while preserving * inter-vertex deltas (hence the interpolated texture) exactly. With the * units read correctly the spans fit unaided and no Defect-2 tessellation - * is required; skyPortPickShift is the safety valve if one ever doesn't. */ + * is required. */ f32 foldS, foldT; /* D227 (M-98): prefer the whole-fan fold set by skyPortBeginFan() so * every triangle in a multi-call fan bakes its shared vertices against diff --git a/tools_pc/d43_emit.py b/tools_pc/d43_emit.py index 0b20764b..479ff480 100644 --- a/tools_pc/d43_emit.py +++ b/tools_pc/d43_emit.py @@ -44,7 +44,8 @@ if len(sys.argv) > 1: ROM_PATH = f"data/ge007.{REGION}.z64" OUT_DIR = f"data/pcmodels-{REGION}" TABLE = "assets/obseg/file_resource_table.inc.c" -FILELIST = "scripts/filelist.u.csv" +# D258: each region has its own ROM layout; read its own filelist +FILELIST = "scripts/filelist.%s.csv" % {"ntsc-final": "u", "pal-final": "e", "jpn-final": "j"}[REGION] rom = open(ROM_PATH, "rb").read() rows = list(csv.reader(open(FILELIST))) diff --git a/tools_pc/d69_emit.py b/tools_pc/d69_emit.py index 8b40432b..b042f782 100644 --- a/tools_pc/d69_emit.py +++ b/tools_pc/d69_emit.py @@ -53,7 +53,8 @@ if len(sys.argv) > 1 and sys.argv[1] in ("ntsc-final", "pal-final", "jpn-final") ROM_PATH = f"data/ge007.{REGION}.z64" OUT_DIR = f"data/pccg-{REGION}" TABLE = "assets/obseg/file_resource_table.inc.c" -FILELIST = "scripts/filelist.u.csv" +# D258: each region has its own ROM layout; read its own filelist +FILELIST = "scripts/filelist.%s.csv" % {"ntsc-final": "u", "pal-final": "e", "jpn-final": "j"}[REGION] if not os.path.exists(ROM_PATH): print(f"SKIP: {ROM_PATH} not present in this environment", file=sys.stderr) diff --git a/tools_pc/d88_emit.py b/tools_pc/d88_emit.py index 60b5e7c1..f03a2867 100644 --- a/tools_pc/d88_emit.py +++ b/tools_pc/d88_emit.py @@ -94,7 +94,8 @@ for _a in sys.argv[1:]: ROM_PATH = f"data/ge007.{REGION}.z64" OUT_DIR = f"data/pccg-{REGION}" TABLE = "assets/obseg/file_resource_table.inc.c" -FILELIST = "scripts/filelist.u.csv" +# D258: each region has its own ROM layout; read its own filelist +FILELIST = "scripts/filelist.%s.csv" % {"ntsc-final": "u", "pal-final": "e", "jpn-final": "j"}[REGION] if not os.path.exists(ROM_PATH): print(f"SKIP: {ROM_PATH} not present in this environment", file=sys.stderr) diff --git a/tools_pc/gen_env_probes.py b/tools_pc/gen_env_probes.py index 15aa6358..dd64bf17 100644 --- a/tools_pc/gen_env_probes.py +++ b/tools_pc/gen_env_probes.py @@ -26,8 +26,13 @@ DOC = ROOT / "docs" / "dev" / "GE-ENV-PROBES.md" SCAN_DIRS = ["src", "port"] # envflag.h's GE_ENVFLAG/GE_ENVSTR are the cached-env wrappers most port code # uses; matching only bare getenv() reported every wrapper-read var as GONE. +# d466Env (port/src/drawdistgameplay.c) is a local cached wrapper of the same +# shape: d466Env("GE_...", &cache). GETENV_RE = re.compile( - r'(?:getenv|GE_ENVFLAG|GE_ENVSTR)\(\s*"(GE_[A-Z0-9_]+)"\s*\)') + r'(?:getenv|GE_ENVFLAG|GE_ENVSTR)\(\s*"(GE_[A-Z0-9_]+)"\s*\)' + r'|d466Env\(\s*"(GE_[A-Z0-9_]+)"\s*,') +# The wrapper macros' own names appear in the doc's prose; they are not vars. +NOT_VARS = {"GE_ENVFLAG", "GE_ENVSTR"} def live_sites() -> dict[str, list[str]]: @@ -43,7 +48,7 @@ def live_sites() -> dict[str, list[str]]: for n, line in enumerate(lines, 1): for m in GETENV_RE.finditer(line): rel = path.relative_to(ROOT).as_posix() - sites.setdefault(m.group(1), []).append(f"{rel}:{n}") + sites.setdefault(m.group(1) or m.group(2), []).append(f"{rel}:{n}") return sites @@ -60,6 +65,7 @@ def doc_vars() -> tuple[set[str], set[str]]: # names it plainly in the table's first cell, so it is still picked up. vs = [m.group(1) for m in re.finditer(r"(GE_[A-Z0-9_]+)(\[?)", line) if not m.group(2)] + vs = [v for v in vs if v not in NOT_VARS] named.update(vs) if "tombstone" in line.lower(): tombstone.update(vs) diff --git a/tools_pc/golden/README.md b/tools_pc/golden/README.md index e2d71774..842f21ad 100644 --- a/tools_pc/golden/README.md +++ b/tools_pc/golden/README.md @@ -1,23 +1,29 @@ # Golden baseline frames -`frame_NNNNNN.png` — reference `GE_PCDUMP` captures for `framediff.py` -(`-level_09` BUNKER1: settled gameplay after the intro). Compared structurally, not exactly — the port -is not frame-deterministic (see `docs/internals.md` "D117"). +`//frame_NNNNNN.png`: reference `GE_PCDUMP` captures for +`tools_pc/verify.sh`, one folder per solo level (all 21, `cuba` = the ending) +and per platform (`win` today; `linux` to come). -Regenerate after a deliberate visual change: +**Recipe** (2026-10-02 re-base; `verify.sh` applies all of it): +- `data/ge007.ini` pinned to ONLY `[Window] Width = 640, Height = 480` (every + other option at its compiled-in default; verify.sh backs yours up). +- `GE_RSEED=0x0123456789abcdef` (pinned PRNG). +- `GE_INPUTSCRIPT="20:START"` (skips the intro flyby; the scripted pad is + the only input) and `GE_PCDUMP="900-1500:300"`: frames 900/1200/1500 are + settled gameplay on every level. **Cuba** instead: no input + (`1:SNONE`) and `300-900:300` (the ending cutscene; it returns to the boot + screens before frame 1200). +- Every run ends via `GE_QUITFRAME` (orderly quit; never a hard kill, D344). -```sh -# data/ge007.ini must hold ONLY this (back yours up) — every other option at -# its compiled-in default; a personal FovScale/DrawDistance/MSAA fails the gate -printf '[Window] -Width = 640 -Height = 480 -' > data/ge007.ini -GE_PCDUMP="640-1120:240" ./build-pc/ge007.x86_64.exe -level_09 -python tools_pc/framediff.py ppm --update # then git rm any stale stems -``` +**Gate** (two tiers): the structural framediff (cell means, coverage, +phash) catches gross breakage; then a per-pixel `--exact --tol 2` check +with a per-level limit: 1% of pixels, 3% for Jungle and Surface 2, Cuba +structural only. Measured run to run: <= 0.57% on 18 levels, Jungle 1.75%, +Surface 2 2.33%, Cuba 36%; a global texture-filter switch measured 22%. -`tools_pc/verify.sh bunker1` does the ini pin + capture + diff for you. +Regenerate one level after a deliberate visual change: run +`tools_pc/verify.sh ` twice to confirm the new look is stable, then +capture with the recipe above and replace `//*.png`. ## History @@ -39,3 +45,9 @@ python tools_pc/framediff.py ppm --update # then git rm any stale stems its camera is nondeterministic (D117): 1 in ~5 gate runs failed it (dmean 0.7 vs 20.7 run to run). All three frames are now settled gameplay; three independent captures agree (worst dmean ≤ 6.8). +- **2026-10-02:** re-based and extended to all 21 levels (`/win/`), + recipe above. The flat bunker1 set at the folder root was retired. Two + independent 21-level passes agreed; noise per level measured as listed. + `verify.sh` no longer hard-kills (taskkill of every `ge007.x86_64.exe`, + including a maintainer's game); it quits via `GE_QUITFRAME` and only stops + its own PID as a watchdog fallback. diff --git a/tools_pc/golden/archives/win/frame_000900.png b/tools_pc/golden/archives/win/frame_000900.png new file mode 100644 index 00000000..9c2efce6 Binary files /dev/null and b/tools_pc/golden/archives/win/frame_000900.png differ diff --git a/tools_pc/golden/archives/win/frame_001200.png b/tools_pc/golden/archives/win/frame_001200.png new file mode 100644 index 00000000..8429b543 Binary files /dev/null and b/tools_pc/golden/archives/win/frame_001200.png differ diff --git a/tools_pc/golden/archives/win/frame_001500.png b/tools_pc/golden/archives/win/frame_001500.png new file mode 100644 index 00000000..afdf653d Binary files /dev/null and b/tools_pc/golden/archives/win/frame_001500.png differ diff --git a/tools_pc/golden/aztec/win/frame_000900.png b/tools_pc/golden/aztec/win/frame_000900.png new file mode 100644 index 00000000..32029688 Binary files /dev/null and b/tools_pc/golden/aztec/win/frame_000900.png differ diff --git a/tools_pc/golden/aztec/win/frame_001200.png b/tools_pc/golden/aztec/win/frame_001200.png new file mode 100644 index 00000000..6fa328ff Binary files /dev/null and b/tools_pc/golden/aztec/win/frame_001200.png differ diff --git a/tools_pc/golden/aztec/win/frame_001500.png b/tools_pc/golden/aztec/win/frame_001500.png new file mode 100644 index 00000000..17248280 Binary files /dev/null and b/tools_pc/golden/aztec/win/frame_001500.png differ diff --git a/tools_pc/golden/bunker1/win/frame_000900.png b/tools_pc/golden/bunker1/win/frame_000900.png new file mode 100644 index 00000000..6284ce78 Binary files /dev/null and b/tools_pc/golden/bunker1/win/frame_000900.png differ diff --git a/tools_pc/golden/bunker1/win/frame_001200.png b/tools_pc/golden/bunker1/win/frame_001200.png new file mode 100644 index 00000000..4efa6045 Binary files /dev/null and b/tools_pc/golden/bunker1/win/frame_001200.png differ diff --git a/tools_pc/golden/bunker1/win/frame_001500.png b/tools_pc/golden/bunker1/win/frame_001500.png new file mode 100644 index 00000000..68678056 Binary files /dev/null and b/tools_pc/golden/bunker1/win/frame_001500.png differ diff --git a/tools_pc/golden/bunker2/win/frame_000900.png b/tools_pc/golden/bunker2/win/frame_000900.png new file mode 100644 index 00000000..0af5fba3 Binary files /dev/null and b/tools_pc/golden/bunker2/win/frame_000900.png differ diff --git a/tools_pc/golden/bunker2/win/frame_001200.png b/tools_pc/golden/bunker2/win/frame_001200.png new file mode 100644 index 00000000..d90adf77 Binary files /dev/null and b/tools_pc/golden/bunker2/win/frame_001200.png differ diff --git a/tools_pc/golden/bunker2/win/frame_001500.png b/tools_pc/golden/bunker2/win/frame_001500.png new file mode 100644 index 00000000..04d5ae78 Binary files /dev/null and b/tools_pc/golden/bunker2/win/frame_001500.png differ diff --git a/tools_pc/golden/caverns/win/frame_000900.png b/tools_pc/golden/caverns/win/frame_000900.png new file mode 100644 index 00000000..e1ef30d2 Binary files /dev/null and b/tools_pc/golden/caverns/win/frame_000900.png differ diff --git a/tools_pc/golden/caverns/win/frame_001200.png b/tools_pc/golden/caverns/win/frame_001200.png new file mode 100644 index 00000000..b866ff50 Binary files /dev/null and b/tools_pc/golden/caverns/win/frame_001200.png differ diff --git a/tools_pc/golden/caverns/win/frame_001500.png b/tools_pc/golden/caverns/win/frame_001500.png new file mode 100644 index 00000000..751465b6 Binary files /dev/null and b/tools_pc/golden/caverns/win/frame_001500.png differ diff --git a/tools_pc/golden/control/win/frame_000900.png b/tools_pc/golden/control/win/frame_000900.png new file mode 100644 index 00000000..acdba0f7 Binary files /dev/null and b/tools_pc/golden/control/win/frame_000900.png differ diff --git a/tools_pc/golden/control/win/frame_001200.png b/tools_pc/golden/control/win/frame_001200.png new file mode 100644 index 00000000..8fb94c7e Binary files /dev/null and b/tools_pc/golden/control/win/frame_001200.png differ diff --git a/tools_pc/golden/control/win/frame_001500.png b/tools_pc/golden/control/win/frame_001500.png new file mode 100644 index 00000000..92048e45 Binary files /dev/null and b/tools_pc/golden/control/win/frame_001500.png differ diff --git a/tools_pc/golden/cradle/win/frame_000900.png b/tools_pc/golden/cradle/win/frame_000900.png new file mode 100644 index 00000000..e1e7b5d4 Binary files /dev/null and b/tools_pc/golden/cradle/win/frame_000900.png differ diff --git a/tools_pc/golden/cradle/win/frame_001200.png b/tools_pc/golden/cradle/win/frame_001200.png new file mode 100644 index 00000000..c040210e Binary files /dev/null and b/tools_pc/golden/cradle/win/frame_001200.png differ diff --git a/tools_pc/golden/cradle/win/frame_001500.png b/tools_pc/golden/cradle/win/frame_001500.png new file mode 100644 index 00000000..8573c6e7 Binary files /dev/null and b/tools_pc/golden/cradle/win/frame_001500.png differ diff --git a/tools_pc/golden/cuba/win/frame_000300.png b/tools_pc/golden/cuba/win/frame_000300.png new file mode 100644 index 00000000..c261506e Binary files /dev/null and b/tools_pc/golden/cuba/win/frame_000300.png differ diff --git a/tools_pc/golden/cuba/win/frame_000600.png b/tools_pc/golden/cuba/win/frame_000600.png new file mode 100644 index 00000000..a597af21 Binary files /dev/null and b/tools_pc/golden/cuba/win/frame_000600.png differ diff --git a/tools_pc/golden/cuba/win/frame_000900.png b/tools_pc/golden/cuba/win/frame_000900.png new file mode 100644 index 00000000..89976b48 Binary files /dev/null and b/tools_pc/golden/cuba/win/frame_000900.png differ diff --git a/tools_pc/golden/dam/win/frame_000900.png b/tools_pc/golden/dam/win/frame_000900.png new file mode 100644 index 00000000..6087442f Binary files /dev/null and b/tools_pc/golden/dam/win/frame_000900.png differ diff --git a/tools_pc/golden/dam/win/frame_001200.png b/tools_pc/golden/dam/win/frame_001200.png new file mode 100644 index 00000000..f67baba6 Binary files /dev/null and b/tools_pc/golden/dam/win/frame_001200.png differ diff --git a/tools_pc/golden/dam/win/frame_001500.png b/tools_pc/golden/dam/win/frame_001500.png new file mode 100644 index 00000000..7c1ac235 Binary files /dev/null and b/tools_pc/golden/dam/win/frame_001500.png differ diff --git a/tools_pc/golden/depot/win/frame_000900.png b/tools_pc/golden/depot/win/frame_000900.png new file mode 100644 index 00000000..72bc0aa9 Binary files /dev/null and b/tools_pc/golden/depot/win/frame_000900.png differ diff --git a/tools_pc/golden/depot/win/frame_001200.png b/tools_pc/golden/depot/win/frame_001200.png new file mode 100644 index 00000000..ba438665 Binary files /dev/null and b/tools_pc/golden/depot/win/frame_001200.png differ diff --git a/tools_pc/golden/depot/win/frame_001500.png b/tools_pc/golden/depot/win/frame_001500.png new file mode 100644 index 00000000..7e03d1f5 Binary files /dev/null and b/tools_pc/golden/depot/win/frame_001500.png differ diff --git a/tools_pc/golden/egypt/win/frame_000900.png b/tools_pc/golden/egypt/win/frame_000900.png new file mode 100644 index 00000000..92b89958 Binary files /dev/null and b/tools_pc/golden/egypt/win/frame_000900.png differ diff --git a/tools_pc/golden/egypt/win/frame_001200.png b/tools_pc/golden/egypt/win/frame_001200.png new file mode 100644 index 00000000..816ca519 Binary files /dev/null and b/tools_pc/golden/egypt/win/frame_001200.png differ diff --git a/tools_pc/golden/egypt/win/frame_001500.png b/tools_pc/golden/egypt/win/frame_001500.png new file mode 100644 index 00000000..b3d0cb23 Binary files /dev/null and b/tools_pc/golden/egypt/win/frame_001500.png differ diff --git a/tools_pc/golden/facility/win/frame_000900.png b/tools_pc/golden/facility/win/frame_000900.png new file mode 100644 index 00000000..6477e0b7 Binary files /dev/null and b/tools_pc/golden/facility/win/frame_000900.png differ diff --git a/tools_pc/golden/facility/win/frame_001200.png b/tools_pc/golden/facility/win/frame_001200.png new file mode 100644 index 00000000..ea2543e8 Binary files /dev/null and b/tools_pc/golden/facility/win/frame_001200.png differ diff --git a/tools_pc/golden/facility/win/frame_001500.png b/tools_pc/golden/facility/win/frame_001500.png new file mode 100644 index 00000000..746505e4 Binary files /dev/null and b/tools_pc/golden/facility/win/frame_001500.png differ diff --git a/tools_pc/golden/frame_000640.png b/tools_pc/golden/frame_000640.png deleted file mode 100644 index b89243e6..00000000 Binary files a/tools_pc/golden/frame_000640.png and /dev/null differ diff --git a/tools_pc/golden/frame_000880.png b/tools_pc/golden/frame_000880.png deleted file mode 100644 index 9a5dabf4..00000000 Binary files a/tools_pc/golden/frame_000880.png and /dev/null differ diff --git a/tools_pc/golden/frame_001120.png b/tools_pc/golden/frame_001120.png deleted file mode 100644 index 26fadafc..00000000 Binary files a/tools_pc/golden/frame_001120.png and /dev/null differ diff --git a/tools_pc/golden/frigate/win/frame_000900.png b/tools_pc/golden/frigate/win/frame_000900.png new file mode 100644 index 00000000..bbcff1d7 Binary files /dev/null and b/tools_pc/golden/frigate/win/frame_000900.png differ diff --git a/tools_pc/golden/frigate/win/frame_001200.png b/tools_pc/golden/frigate/win/frame_001200.png new file mode 100644 index 00000000..b36ad2f2 Binary files /dev/null and b/tools_pc/golden/frigate/win/frame_001200.png differ diff --git a/tools_pc/golden/frigate/win/frame_001500.png b/tools_pc/golden/frigate/win/frame_001500.png new file mode 100644 index 00000000..1e2a9f9a Binary files /dev/null and b/tools_pc/golden/frigate/win/frame_001500.png differ diff --git a/tools_pc/golden/jungle/win/frame_000900.png b/tools_pc/golden/jungle/win/frame_000900.png new file mode 100644 index 00000000..5c715b04 Binary files /dev/null and b/tools_pc/golden/jungle/win/frame_000900.png differ diff --git a/tools_pc/golden/jungle/win/frame_001200.png b/tools_pc/golden/jungle/win/frame_001200.png new file mode 100644 index 00000000..e9394165 Binary files /dev/null and b/tools_pc/golden/jungle/win/frame_001200.png differ diff --git a/tools_pc/golden/jungle/win/frame_001500.png b/tools_pc/golden/jungle/win/frame_001500.png new file mode 100644 index 00000000..a8a8f678 Binary files /dev/null and b/tools_pc/golden/jungle/win/frame_001500.png differ diff --git a/tools_pc/golden/runway/win/frame_000900.png b/tools_pc/golden/runway/win/frame_000900.png new file mode 100644 index 00000000..92c9e8fe Binary files /dev/null and b/tools_pc/golden/runway/win/frame_000900.png differ diff --git a/tools_pc/golden/runway/win/frame_001200.png b/tools_pc/golden/runway/win/frame_001200.png new file mode 100644 index 00000000..38dafa8f Binary files /dev/null and b/tools_pc/golden/runway/win/frame_001200.png differ diff --git a/tools_pc/golden/runway/win/frame_001500.png b/tools_pc/golden/runway/win/frame_001500.png new file mode 100644 index 00000000..e80a0801 Binary files /dev/null and b/tools_pc/golden/runway/win/frame_001500.png differ diff --git a/tools_pc/golden/silo/win/frame_000900.png b/tools_pc/golden/silo/win/frame_000900.png new file mode 100644 index 00000000..d1864ce6 Binary files /dev/null and b/tools_pc/golden/silo/win/frame_000900.png differ diff --git a/tools_pc/golden/silo/win/frame_001200.png b/tools_pc/golden/silo/win/frame_001200.png new file mode 100644 index 00000000..26909584 Binary files /dev/null and b/tools_pc/golden/silo/win/frame_001200.png differ diff --git a/tools_pc/golden/silo/win/frame_001500.png b/tools_pc/golden/silo/win/frame_001500.png new file mode 100644 index 00000000..7f1817f6 Binary files /dev/null and b/tools_pc/golden/silo/win/frame_001500.png differ diff --git a/tools_pc/golden/statue/win/frame_000900.png b/tools_pc/golden/statue/win/frame_000900.png new file mode 100644 index 00000000..2482cc73 Binary files /dev/null and b/tools_pc/golden/statue/win/frame_000900.png differ diff --git a/tools_pc/golden/statue/win/frame_001200.png b/tools_pc/golden/statue/win/frame_001200.png new file mode 100644 index 00000000..b9f4329f Binary files /dev/null and b/tools_pc/golden/statue/win/frame_001200.png differ diff --git a/tools_pc/golden/statue/win/frame_001500.png b/tools_pc/golden/statue/win/frame_001500.png new file mode 100644 index 00000000..fae13dc5 Binary files /dev/null and b/tools_pc/golden/statue/win/frame_001500.png differ diff --git a/tools_pc/golden/streets/win/frame_000900.png b/tools_pc/golden/streets/win/frame_000900.png new file mode 100644 index 00000000..3708e718 Binary files /dev/null and b/tools_pc/golden/streets/win/frame_000900.png differ diff --git a/tools_pc/golden/streets/win/frame_001200.png b/tools_pc/golden/streets/win/frame_001200.png new file mode 100644 index 00000000..182b04cf Binary files /dev/null and b/tools_pc/golden/streets/win/frame_001200.png differ diff --git a/tools_pc/golden/streets/win/frame_001500.png b/tools_pc/golden/streets/win/frame_001500.png new file mode 100644 index 00000000..e02a0c6a Binary files /dev/null and b/tools_pc/golden/streets/win/frame_001500.png differ diff --git a/tools_pc/golden/surface1/win/frame_000900.png b/tools_pc/golden/surface1/win/frame_000900.png new file mode 100644 index 00000000..29c509ae Binary files /dev/null and b/tools_pc/golden/surface1/win/frame_000900.png differ diff --git a/tools_pc/golden/surface1/win/frame_001200.png b/tools_pc/golden/surface1/win/frame_001200.png new file mode 100644 index 00000000..846ec4c5 Binary files /dev/null and b/tools_pc/golden/surface1/win/frame_001200.png differ diff --git a/tools_pc/golden/surface1/win/frame_001500.png b/tools_pc/golden/surface1/win/frame_001500.png new file mode 100644 index 00000000..41edfedc Binary files /dev/null and b/tools_pc/golden/surface1/win/frame_001500.png differ diff --git a/tools_pc/golden/surface2/win/frame_000900.png b/tools_pc/golden/surface2/win/frame_000900.png new file mode 100644 index 00000000..0ffbd279 Binary files /dev/null and b/tools_pc/golden/surface2/win/frame_000900.png differ diff --git a/tools_pc/golden/surface2/win/frame_001200.png b/tools_pc/golden/surface2/win/frame_001200.png new file mode 100644 index 00000000..e0b1396c Binary files /dev/null and b/tools_pc/golden/surface2/win/frame_001200.png differ diff --git a/tools_pc/golden/surface2/win/frame_001500.png b/tools_pc/golden/surface2/win/frame_001500.png new file mode 100644 index 00000000..704ca894 Binary files /dev/null and b/tools_pc/golden/surface2/win/frame_001500.png differ diff --git a/tools_pc/golden/train/win/frame_000900.png b/tools_pc/golden/train/win/frame_000900.png new file mode 100644 index 00000000..6b70f87e Binary files /dev/null and b/tools_pc/golden/train/win/frame_000900.png differ diff --git a/tools_pc/golden/train/win/frame_001200.png b/tools_pc/golden/train/win/frame_001200.png new file mode 100644 index 00000000..4494b190 Binary files /dev/null and b/tools_pc/golden/train/win/frame_001200.png differ diff --git a/tools_pc/golden/train/win/frame_001500.png b/tools_pc/golden/train/win/frame_001500.png new file mode 100644 index 00000000..03bdc9db Binary files /dev/null and b/tools_pc/golden/train/win/frame_001500.png differ diff --git a/tools_pc/verify.sh b/tools_pc/verify.sh index 71e044ac..53f84e4a 100644 --- a/tools_pc/verify.sh +++ b/tools_pc/verify.sh @@ -18,10 +18,14 @@ # # Options: # --platform win|linux default: autodetect via `uname -s` -# --dump lo-hi:step GE_PCDUMP window (default: 640-1120:240 single level, -# 80-400:40 sweep — matches the existing golden set -# and level_sweep.sh respectively) -# --script "..." GE_INPUTSCRIPT passthrough (scripted input) +# --dump lo-hi:step GE_PCDUMP window (default: 900-1500:300, the golden +# capture window for every level and both modes) +# --script "..." GE_INPUTSCRIPT (default "20:START": skip the intro +# flyby so frame 900+ is settled gameplay) +# +# Golden recipe (2026-10-02 re-base): 640x480 defaults-only ini, GE_RSEED pinned +# (GOLDEN_SEED below), GE_INPUTSCRIPT "20:START", GE_PCDUMP 900-1500:300, +# goldens in tools_pc/golden///. See tools_pc/golden/README.md. # --json also emit one JSON object (or array, for sweep) to # stdout: {level, platform, status, frames, # worst_cell, crash_sym} @@ -41,13 +45,28 @@ cd "$(dirname "$0")/.." ROOT="$(pwd)" # --- arg parsing ------------------------------------------------------------- -MODE=""; LEVEL_ARG=""; PLATFORM=""; DUMP=""; SCRIPT=""; JSON=0; AGAINST="" +MODE=""; LEVEL_ARG=""; PLATFORM=""; DUMP=""; SCRIPT="20:START"; JSON=0; AGAINST="" +GOLDEN_DUMP="900-1500:300" +USER_DUMP=0; USER_SCRIPT=0 +# Per-level golden recipe overrides: Cuba is the ending cutscene + credits (it +# drops back to the boot screens before frame 1200, and START would skip it), +# so it captures the cutscene itself with no input. +golden_dump_for() { case "$1" in cuba) echo "300-900:300" ;; *) echo "$GOLDEN_DUMP" ;; esac; } +# Second tier: per-pixel (framediff --exact) limit, % of pixels over a +# per-channel tolerance of 2. Measured 2026-10-02 run to run (21 levels x 2 +# captures): <= 0.57% everywhere except Jungle 1.75% / Surface 2 2.33% (moving +# foliage/fog) and Cuba 36% (cutscene animation timing; structural tier only). +# A global texture-filter change measured 22% on Dam, so 1% leaves ~2x margin +# over the noise and still catches whole-frame render changes. +golden_tolpct_for() { case "$1" in cuba) echo "" ;; jungle|surface2) echo "3.0" ;; *) echo "1.0" ;; esac; } +golden_script_for() { case "$1" in cuba) echo "1:SNONE" ;; *) echo "20:START" ;; esac; } +GOLDEN_SEED="${GE_RSEED:-0x0123456789abcdef}" POSARGS=() while [ $# -gt 0 ]; do case "$1" in --platform) PLATFORM="$2"; shift 2 ;; - --dump) DUMP="$2"; shift 2 ;; - --script) SCRIPT="$2"; shift 2 ;; + --dump) DUMP="$2"; USER_DUMP=1; shift 2 ;; + --script) SCRIPT="$2"; USER_SCRIPT=1; shift 2 ;; --against) AGAINST="$2"; shift 2 ;; --json) JSON=1; shift ;; -h|--help) sed -n '2,32p' "$0"; exit 0 ;; @@ -74,13 +93,18 @@ if [ "$PLATFORM" = win ]; then BUILD_DIR=build-pc EXE="$ROOT/build-pc/ge007.x86_64.exe" export PATH="/c/msys64/mingw64/bin:$PATH" # addr2line + runtime DLLs - KILL() { taskkill //F //IM ge007.x86_64.exe >/dev/null 2>&1; } else BUILD_DIR=build-linux EXE="$ROOT/build-linux/ge007.x86_64" - KILL() { pkill -f ge007.x86_64 >/dev/null 2>&1; } fi +# Only ever stop the game process THIS script started (never other instances: +# the maintainer may be playing), and only as a watchdog fallback -- every run +# normally ends through GE_QUITFRAME's orderly quit (D344: a hard kill of a +# live GL/audio process has caused a host BSOD). +GAMEPID="" +kill_ours() { [ -n "$GAMEPID" ] && kill "$GAMEPID" >/dev/null 2>&1; GAMEPID=""; } + # name -> -level_XX (mission order; matches playtest.sh / level_sweep.sh) LEVELS=( "dam:33" "facility:34" "runway:35" "surface1:36" "bunker1:09" "silo:20" @@ -129,9 +153,6 @@ golden_dir_for() { local name="$1" local per="$ROOT/tools_pc/golden/$name/$PLATFORM" if [ -d "$per" ] && ls "$per"/*.png >/dev/null 2>&1; then echo "$per"; return; fi - if [ "$name" = "bunker1" ] && ls "$ROOT/tools_pc/golden"/*.png >/dev/null 2>&1; then - echo "$ROOT/tools_pc/golden"; return - fi echo "" } @@ -154,52 +175,49 @@ restore_ini() { if [ -n "$INI_BAK" ]; then cp "$INI_BAK" "$INI" && rm -f "$INI_BAK" elif [ "$INI_CREATED" = 1 ]; then rm -f "$INI"; fi } -trap 'restore_ini; KILL' EXIT INT TERM +trap 'restore_ini; kill_ours' EXIT INT TERM # --- run one level -> sets globals: R_STATUS R_FRAMES R_SYM R_BRIEF ------- run_one() { local name="$1" num="$2" dump="$3" watchdog="${4:-90}" local capdir; capdir=$(mktemp -d) + [ "$USER_DUMP" = 1 ] || dump=$(golden_dump_for "$name") + local script="$SCRIPT" + [ "$USER_SCRIPT" = 1 ] || script=$(golden_script_for "$name") R_STATUS=""; R_FRAMES=0; R_SYM=""; R_BRIEF="" rm -f "$ROOT/ge007.crash.log" - KILL; sleep 0.3 - # Speed-up: a level only needs to render its intro pan + spawn-in once -- - # everything after the last requested GE_PCDUMP frame is wasted wall-clock - # (the process used to always idle out the full watchdog, ~30s/level of - # nothing on top of the ~15s that actually matters -- 21 levels x that - # waste is most of a sweep's runtime). Poll for the last frame's PPM (or a - # crash) and kill the instant it lands; `watchdog` remains the safety net - # for a level that never gets there (hang / load-sensitivity flake). - local lo hi step lastframe target="" + # Quit right after the last requested GE_PCDUMP frame via GE_QUITFRAME (an + # orderly D344 quit), instead of idling out the watchdog; the watchdog stays + # the safety net for a level that never gets there (hang / flake). + local lo hi step lastframe quitframe="" IFS='-:' read -r lo hi step <<< "$dump" if [[ "$lo" =~ ^-?[0-9]+$ && "$hi" =~ ^-?[0-9]+$ ]]; then [[ "$step" =~ ^[0-9]+$ && "$step" -gt 0 ]] || step=1 lastframe=$(( lo + step * ( (hi - lo) / step ) )) - target=$(printf "%s/ppm/frame_%06d.ppm" "$ROOT" "$lastframe") + quitframe=$(( lastframe + 2 )) fi ( cd "$ROOT" && export GE_PCDUMP="$dump" - [ -n "$SCRIPT" ] && export GE_INPUTSCRIPT="$SCRIPT" - if [ -n "$target" ]; then "$EXE" "-level_$num"; else timeout "$watchdog" "$EXE" "-level_$num"; fi ) \ - >"$capdir/run.log" 2>&1 & + [ -n "$quitframe" ] && export GE_QUITFRAME="$quitframe" + [ -n "$script" ] && export GE_INPUTSCRIPT="$script" + export GE_RSEED="$GOLDEN_SEED" + exec "$EXE" "-level_$num" ) >"$capdir/run.log" 2>&1 & local gamepid=$! + GAMEPID=$gamepid - if [ -n "$target" ]; then - local ticks=0 max_ticks=$(( watchdog * 5 )) # 0.2s ticks - while [ "$ticks" -lt "$max_ticks" ]; do - if [ -f "$target" ] || [ -f "$ROOT/ge007.crash.log" ]; then - sleep 0.2 # let the just-written frame's fclose() settle - break - fi - kill -0 "$gamepid" 2>/dev/null || break # exited/crashed on its own - sleep 0.2 - ticks=$((ticks + 1)) - done - KILL + local ticks=0 max_ticks=$(( watchdog * 5 )) # 0.2s ticks + while kill -0 "$gamepid" 2>/dev/null && [ "$ticks" -lt "$max_ticks" ]; do + sleep 0.2 + ticks=$((ticks + 1)) + done + if kill -0 "$gamepid" 2>/dev/null; then + echo " watchdog: $name still running after ${watchdog}s, stopping it" >&2 + kill_ours fi wait "$gamepid" 2>/dev/null + GAMEPID="" mv "$ROOT"/ppm "$capdir/ppm" 2>/dev/null || mkdir -p "$capdir/ppm" R_FRAMES=$(ls "$capdir/ppm"/*.ppm 2>/dev/null | wc -l) @@ -284,13 +302,21 @@ except Exception: # exit 1 = a real per-frame threshold fail (pixel/cell/hash delta). # exit 2 = a structural mismatch (missing/size) -- most commonly the # golden's frame stems don't line up with this run's --dump window - # (today's only golden, level_09, was captured at 640-1120:240; a + # (goldens are captured at GOLDEN_DUMP; a # sweep using a different stride has nothing to compare against # rather than a real regression). Only exit 1 is a verdict fail. case "$fexit" in 1) status=REGRESSION; note="framediff vs $gdir" ;; 2) note="golden frame stems don't match --dump window ($dump) for $gdir" ;; esac + local tolpct; tolpct=$(golden_tolpct_for "$name") + if [ "$fexit" = 0 ] && [ -n "$tolpct" ]; then + local xout; xout=$(python3 "$ROOT/tools_pc/framediff.py" "$CAPDIR/ppm" --golden "$gdir" --exact --tol 2 --tol-pct "$tolpct" 2>&1) + if [ $? -eq 1 ]; then + status=REGRESSION + note="per-pixel: $(echo "$xout" | grep -m1 FAIL | sed 's/^FAIL //') (limit ${tolpct}%)" + fi + fi else note="no golden for $name/$PLATFORM yet (Step 3)" fi @@ -327,7 +353,7 @@ case "$MODE" in name="${resolved%%:*}"; num="${resolved##*:}" [ "${resolved%%:*}" = num ] && name=$(name_for_num "$num") pin_ini_640x480 2>/dev/null || true - verify_level "$name" "$num" "${DUMP:-640-1120:240}" + verify_level "$name" "$num" "${DUMP:-$GOLDEN_DUMP}" ;; sweep) @@ -339,7 +365,7 @@ case "$MODE" in for e in "${entries[@]}"; do n="${e%%:*}"; num="${e##*:}" pin_ini_640x480 2>/dev/null || true - out=$(verify_level "$n" "$num" "${DUMP:-80-400:40}" 45) + out=$(verify_level "$n" "$num" "${DUMP:-$GOLDEN_DUMP}" 60) rc=$? [ "$rc" -ne 0 ] && RC=1 # Pre-existing bug (found alongside D244's diagnostics): `head -1` here @@ -375,7 +401,7 @@ case "$MODE" in [ -z "$resolved" ] && { echo "unknown level '$LEVEL_ARG'" >&2; exit 2; } name="${resolved%%:*}"; num="${resolved##*:}" pin_ini_640x480 2>/dev/null || true - run_one "$name" "$num" "${DUMP:-640-1120:240}" 90 + run_one "$name" "$num" "${DUMP:-$GOLDEN_DUMP}" 90 if [ "$R_STATUS" != PASS ]; then emit_verdict "$name" "$R_STATUS" "$R_FRAMES" "" "$R_SYM" rm -rf "$CAPDIR"; exit 1