developer switch (strat property 258): 101 reads, a+s dev warp points, aux bits for hearts, fruit, coins, idols and flying, river log invincible noclip, flipped and tested in game

This commit is contained in:
MineTec committed 2026-11-08 17:33:05 +01:00
1 parent b5b6e22957
commit db08cf8bf3
4 files changed
+59 -1

No files matched your search

Binary file not shown.

After

Width:  |  Height:  |  Size: 33 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 39 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 87 KiB

+59 -1
View File
@@ -63,7 +63,7 @@ diagnostics) → `jmp 0x41C050`. The cave writes only game globals, so it needs
| F4 in game | requests state 0x0C (world map) – the normal "back to map" | no |
| F7 in game | toggles 0x584708 → start row of the strat debug print (0x6D9DB8 = 0x20 / 0x48); nothing visible in retail strats | no |
| F6 | screenshot `capture%d.tga` | no |
| `CheatTeleport`, `CheatCharge` strats | present in most level WADs; strat-only logic, not decoded | no |
| `CheatTeleport`, `CheatCharge` strats | present in most level WADs; gated by property 258, see "Developer switch (property 258)" | no |
Level select / unlock-all is the save editor's job (`--unlock`), not duplicated here.
@@ -115,3 +115,61 @@ the bit makes it fall back. Same write as the llama: normal jump, no effect (pro
To enable on PC a patch is required, e.g. make the pad poll map a key to padAux bit 0x800. Which PS
button of pad 2 feeds bit 0x800 is not known (no PS binary analysed) – hypothesis only.
## Developer switch (property 258)
Strat property 258 (0x102) is a hard-wired developer flag: getter FUN_00550e60, jump table
0x552684[0x102] → 0x55231B `mov eax,[esp+14h]; push 0; push eax; call 0x54BBD0` (the `push 0` byte is
at **0x552320**; the same handler also serves the unread ids 0x75, 0x9E, 0xC1, 0xEE). It is read
101× in the 34 level WADs (all units disassembled; `pushProp` only, no player/parent/... variants).
Every use is a logical test (`and`, `not`, `jz`), so any non-zero value enables it.
Keys (in-game `padHeld` 0x5FCF20, measured with gdb while holding the key): A 0x400, S 0x800
(camera left/right), Return 0x1000, Z 0x2000 (action), X 0x4000 (jump), Space 0x8000 (power),
P 0x08 (pause). No keyboard key gives 0x100/0x200. `padAux` (prop 88, 0x5FCF58) and
`padAuxPressed` (prop 90, 0x5FCF60 = edge of padAux, computed every frame at 0x425C1E) are never
set on PC (see above). Strat constants are 20.12: `0.25` = 0x400, `0.5` = 0x800, `0.75` = 0xC00,
`10.0` = 0xA000, `256r` = raw 0x100.
| Reader strat | Levels | Gate | Bits / keys | Effect | Status |
|---|---|---|---|---|---|
| CheatTeleport (+CheatCharge, same unit) | placed in 22 levels: 1-1..1-4, 2-1, 2-2, 4-1..4-3, 5-1..5-3, 6-1..6-3, 7-2, 7-4, 8-1..8-5 (code also in 3-1..3-4, not placed) | entry `if (!prop258) remove` at level start | hold **A+S** (padHeld 0xC00) | teleports the llama to the next node of the strat's own path (hand-placed warp list, 1–18 nodes per level, often next to checkpoints, doors, puzzles; wraps around); sets `g0 = 14` | verified 1-1 (4 nodes, cycled twice) |
| CheatTeleport | same | prop258 | padAuxPressed 0x400 | +1 heart (if alive), +5 purple fruit, hudDigit = charge | verified (fruit 0 → 5, HUD shows it) |
| CheatTeleport | same | prop258 (+ prop 0 == 0) | padAux 0x100 held | +1 coin per frame (prop 190, coins of this level) | verified (HUD 307 coins after 0.5 s) |
| CheatTeleport | same | prop258 (+ prop 0 == 0) | padAux 0x200 held | +1 pink idol per frame, max 99 (prop 250) | verified (0 → 65 → 99) |
| CheatTeleport | same | prop258 | hold Space+Z (0xA000) | only `print` debug lists (player/camera state dump: "gFreezePlayer", "gCamAng", "teleported to location (" …) that the PC VM skips → nothing visible | static |
| CheatTeleport | same | prop258 **and prop 0 ≠ 0** | padAux 0x100 held = debug menu; then padPressed Space/Z = previous/next music track (spawns unit 48 = track display, `musicPlay`), X = lose heart, Return = +1 idol, A = +1 coin (+10 charge every 5), S = full charge, 0x100 = **`endLevel(g101,g102,g103)`** (finish level), 0x200 = +1 counterC; combo becomes 0xF00 | unreachable even with prop258 = 1 (prop 0 is also hard-wired 0, handler 0x552192) | static |
| Llama | 23 levels (all with a llama) | prop258 | padAux 0x800 held | moonjump/fly: starts a jump on the ground without pressing X (no cooldown check) and sets vertical speed 0.0698/frame every frame in the air → rises until released | verified 1-1: y 8.25 → 20.6 in ~2 s without touching a key |
| LlamaChase | 2-3 (night chase) | prop258 | padAux 0x800 | same moonjump; also allows jumping anywhere (normally only on floor material 11) | static (chase intro did not start under load) |
| KuscoBunny | 7-4, 8-1, 8-2 (potion) | prop258 | padAux 0x800 | rabbit jumps/rises with speed 0.045 while held | static |
| KuscoFrog | 4-3, 8-3 (potion) | prop258 only for take-off | padAux 0x800 | air rise has **no** gate (moonjump agent, verified); with prop258 the bit also starts the jump | static |
| KuscoAndPachaTogetherOnATree (river log) | 3-1..3-4 | prop258 | hold **Space** (0x8000) | damage handling skipped (invincible), +1 heart every frame, collision flag 0x40000 off (passes through banks), horizontal movement ×8, no current/steering term | verified 3-1: with Space the log shot through the river bank out of the level |
| RiverWhirlpool | 3-2 (36×) | prop258 | hold Space | whirlpool does not pull the log | static |
| CondorManDoor | 5-2 | prop258 | padHeld 0x100 (no PC key) | a hit always takes the "straight hit" branch (`v16 = 1`, later `otherPiece()` on impact; hypothesis: the door breaks) instead of needing the angle within 96 | static |
| EndGameTriggerBox | 8-6 (finale, 15×) | prop258 | hold Space+Z during the box's wait time | `endLevel(1,1,1)` at once (hypothesis: skips the rest of the finale) | static |
How it was verified (apptest `devflag-a`, :25, German exe): `set {char}0x552320 = 1` via the winedbg
gdb proxy at the main menu (CheatTeleport removes itself at level start, so the patch must be in
before the level loads), then `set {int}0x5FCF58 = 0x100/0x200/0x400/0x800` one at a time.
`img/mods/devflag_teleport.jpg` (1-1 start → three A+S warps), `devflag_aux_moonjump.jpg` (before /
after padAux 0x400+0x100: fruit 5 and 307 coins on the HUD / bit 0x800: llama flying above the
village), `devflag_river.jpg` (3-1 log normal / after Space boost in the bank / outside the level).
Note: the exe run by LlamaMod relocates the per-level array 0x584F1C to 0x6DB940 (seen at 0x550BC2),
so `levelRecord`/coins are not at the address of `re/groove.exe`.
Property 0 is a second hard-wired 0 read by strats (131×: Camera, CameraSide, CheatTeleport, birds,
butterflies, ladybirds, moths, Bunny, Panther, Yzma…). Ambient critters with a parameter set remove
themselves when it is non-zero, the camera uses alternative heights/distances when it is 0, and
CheatTeleport switches its combo to 0xF00 – **hypothesis**: a platform/hardware flag (PS button
layout or low-memory mode), not a debug flag. Other constant getter cases: 0x5E/0x60 = 84,
0x5F/0x61 = 123, 0x82/0x83 = 42 (stick thresholds), and 0, 0x13, 0x15, 0x47, 0x75, 0x76, 0x77,
0x98, 0x9E, 0xC1, 0xD8, 0xED, 0xEE, 0x102 = 0; of the zero ids only 0 and 0x102 are read by any strat.
No exe code writes padAux, and no other dev key handler was found beyond the table above (F4, F6, F7).
Suggested "Developer mode" option for the cheats mod (not implemented): patch byte 0x552320 to 1
(or point jump-table entry 0x552A8C at a cave that pushes 0x1000, leaving the shared handler alone),
and map keys to padAux in the pad poll: at the end of FUN_004256C0 (0x425B88, where padAux is only
cleared when >1 pad) jump to a cave that builds padAux from the DIK state array 0x58226C + 4·DIK,
e.g. F1 → 0x800 (moonjump), F2 → 0x400 (heart + fruit), F3 → 0x200 (idols), F5 → 0x100 (coins).
A+S teleport and Space (river) work with the normal keys once prop 258 is 1. Note that F4/F6/F7
are taken; the frog's ungated moonjump would also react to the 0x800 key.