12 KiB
F7 Debug Overlays In Retail CRUSADER.EXE
This note documents the three cheat-gated F7-family overlays in the live NE CRUSADER.EXE database and what each one represents on screen.
The practical keyboard side is already summarized in docs/ne-segment1.md. This file focuses on the overlay consumers themselves, the recovered geometry math, and what the map viewer can safely reproduce from static scene data.
Toggle points
Inside World_HandleKeyboardInput_13e8_14b4, the three overlay hotkeys toggle three different globals before forcing a camera refresh through the active camera process:
13e8:1a7ctoggles1478:2bcafor plainF713e8:1a50toggles1478:2bc9forAlt+F713e8:1a20toggles1478:0ee0forCtrl+F7
All three are still gated by the broader cheat/debug latch at 1478:0844, so they are part of the Laurie/debug family rather than always-on retail UI features.
The live database and exported evidence agree on the three consumers:
Camera_1180_15efhandles the plainF7grid and theCtrl+F7egg-hatcher overlaySnap_1058_0814handles theAlt+F7snap overlayEggHatcher_1090_0921handles theCtrl+F7diamond outlines through the shared helper at1180:1ce5
Palette colors and flash timing
The overlay colors are not hardcoded RGB values inside the overlay consumers. They are palette-indexed line draws that ride the shared CycleProcess palette animator in segment 1438.
Recovered retail evidence now closes the important pieces:
CycleProcess_InitColorTables(1438:0480) seeds the runtime color-cycle tables at1478:6848..1478:6871CycleProcess_Update(1438:011b) advances those rows by+2intensity units per update tick and writes them into palette entries8..14Snap_1058_0814pushes color index0x09EggHatcher_1090_0921pushes color index0x0dCamera_1180_15efstores and uses color index0x0efor the plainF7grid lines
So the current overlay-to-palette mapping is:
- plain
F7grid = palette color14 Alt+F7snap overlay = palette color9Ctrl+F7egg-hatcher overlay = palette color13
The recovered cycle rows explain the visible behavior:
- color
9is a blue ramp that rises0 -> 63in steps of2and wraps - color
13is a white ramp that rises0 -> 63in all three channels in steps of2and wraps - color
14is primarily a green ramp, but its row is flagged through the specialword-flag == 1path, so each wrap injects an additional small random-looking RGB offset before the next ramp cycle
For the viewer that means the correct match is not one static CSS color per overlay. The viewer should simulate the same discrete palette-cycle phase and then derive the on-screen RGB from the live palette index assigned to each overlay.
The retail game is updating those colors in its normal engine/palette lane, not in a browser-style wall-clock timer. For the viewer it is acceptable to run the same phase logic at a slower cadence if that produces a closer visual impression on a modern display.
Plain F7: coarse world-cell grid
What it represents
Plain F7 is the simple debug background grid. It is not an object-family overlay and it is not tied to egg processes.
Current best read from the live camera path is:
- the grid is aligned to the world coordinate lattice
- each coarse cell is
0x200world units wide in both world axes - the visible shape is an isometric diamond because the game projects the world lattice into screen space
That means the overlay is best understood as a coarse world-cell coordinate grid useful for orientation and spatial debugging.
Viewer reproduction rule
The viewer should not anchor this grid to the middle of the screen. The right model is:
- use the world origin-aligned
0x200 x 0x200lattice - project every visible coarse cell that intersects the current viewport
- let the lattice continue indefinitely across the visible world instead of only drawing a fixed
3 x 3patch around the viewport center
That is closer to the game-space meaning of the overlay than a screen-centered approximation.
Ctrl+F7: egg-hatcher trigger diamonds
What it represents
Ctrl+F7 is not a third generic grid. It visualizes the trigger footprint used by live EggHatcherProcess objects.
The live control flow is:
13e8:1a20toggles1478:0ee0Camera_1180_15efchecks1478:0ee0- eligible live
EggHatcherProcessobjects are routed throughEggHatcher_1090_0921 EggHatcher_1090_0921calls the shared diamond helper at1180:1ce5
The process/runtime note in docs/ne-segment1.md already closes the gameplay meaning: for non-monster egg families, these processes watch an avatar footprint against egg-centered X/Y/Z trigger windows and fire hatch or unhatch behavior on boundary crossings.
Geometry source
The recovered runtime uses the same egg range values that the process runner tests:
Egg_GetXRange(itemno)returns the high nibble of the egg-range byteEgg_GetYRange(itemno)returns the low nibble of the same byte- each nibble expands in steps of
0x40world units in the current viewer-side evidence model - the vertical window is about
+/- 0x30Z units
For authored family-4 usecode-trigger eggs in the viewer, the packed range byte already exists in the decoded map item payload, so the static reproduction is defensible.
Why it can appear blank in game
This overlay walks live EggHatcherProcess objects, not all possible egg-family map items. A blank Ctrl+F7 result only means there is no currently eligible live egg-hatcher outline being drawn at that moment.
Alt+F7: SnapProcess rectangles, not generic egg coverage
The important correction
The first viewer approximation treated Alt+F7 as a broad snap-oriented egg-family overlay. The recovered runtime is narrower than that.
The key proof comes from the object-entry path that feeds the snap process:
- the live/extracted logic only calls
Snap_AddSnapEggwheng_snapProcess != 0 - and when the entering item's shape number is exactly
0x04fe
The exported live note at 10a0:2c82 summarizes the same behavior directly: when shape 0x4fe enters, we trigger the snap process.
So Alt+F7 is not a generic "all eggs" overlay. Its runtime source is the SnapProcess egg list, and the recovered producer for that list is currently tied to shape 0x04FE items.
Geometry source
The geometry is recovered more tightly now too, and the important detail is that the helper is not drawing a symmetric world-centered diamond from item_x,item_y alone.
The Snap_1058_0814 consumer does this per active SnapProcess entry:
qHiHiNibble = (Item_GetQHi(itemno) >> 4) & 0x0fqHiLoNibble = Item_GetQHi(itemno) & 0x0fmapSigned = sign_extend_8(Item_GetMapArray(itemno))npcSigned = sign_extend_8(Item_GetNPCNum(itemno))
Then it builds the helper inputs as:
x_{helper} = item_x + qHiHiNibble \cdot 0x20 + mapSigned \cdot 0x20
y_{helper} = item_y + qHiLoNibble \cdot 0x20 + npcSigned \cdot 0x20
xRange_{helper} = qHiHiNibble \cdot 2
yRange_{helper} = qHiLoNibble \cdot 2
and finally calls the shared overlay primitive with color 0x09:
FUN_1180_1ce5(x_helper, y_helper, item_z, xRange_helper, yRange_helper, 9)
That helper works in projected screen space. Starting from the projected helper center, it emits a four-segment polygon with these deltas:
- point
A= center+ ( yRange * 0x10, -yRange * 0x08 ) - point
B= pointA + ( -xRange * 0x10, -xRange * 0x08 ) - point
C= pointB + ( -yRange * 0x10, yRange * 0x08 ) - close back to center
So the game is not drawing a simple min/max world rectangle and then projecting it. It is feeding an offset center and doubled nibble step counts into a dedicated screen-space overlay helper. That is why the earlier viewer reconstruction read too small.
In practical terms for the viewer:
- use the
BRO_BOOT/0x04feitem as the authored source row - offset the helper center by the packed signed bytes and nibble terms exactly as above
- use doubled nibble counts as helper step counts
- reproduce the helper polygon itself rather than a centered approximation
This is materially different from the Ctrl+F7 egg-hatcher path:
Ctrl+F7is tied to liveEggHatcherProcesstrigger windowsAlt+F7is tied to the SnapProcess list and the explicitSnap_GetSnapEggRangerectangle math for shape0x04fe
What the overlay represents
Current safest read is:
Alt+F7visualizes snap-process coverage regions associated with the subset of runtime objects that are inserted into the SnapProcess egg list- those regions are authored through the
0x04feitem's ownQHi,mapNum, andnpcNumbytes rather than the generic family-4 egg-hatcher nibble layout - this is related to, but not identical with, the family-4 egg trigger overlay shown by
Ctrl+F7
Is this related to camera snapping?
Probably related to the game's broader snap subsystem, but not proven as a pure camera-only feature.
What is directly supported by the recovered retail evidence is:
- the overlay consumer is
Snap_1058_0814, not a camera helper - the producer path adds only shape
0x04fe(BRO_BOOT) items into the SnapProcess list - an inline live note at
10a0:2c82says that when shape0x04feenters, it triggers the snap process - another recovered note inside the SnapProcess body marks one related branch as
snap to this egg
So the defensible statement is:
- yes, it is related to the engine's snap behavior
- no, the currently recovered evidence does not justify calling it only a camera-snap overlay
The best present label is still SnapProcess coverage or snap-region overlay, not camera snap grid. The subsystem may influence camera behavior, controlled-NPC placement, or both, but the proven path is the SnapProcess path itself.
Why BRO_BOOT appears to own it
The viewer-side tie to BRO_BOOT is not arbitrary. That shape tie is exactly what the retail producer currently shows.
Recovered producer behavior:
- when
g_snapProcess != 0 - and a newly entering item has shape
0x04fe - the game calls
Snap_AddSnapEgg
That is why the static viewer reproduction binds Alt+F7 to BRO_BOOT items. It is not because BRO_BOOT is being used as a loose guess for a nearby effect; it is because the current live evidence says those are the items that seed the SnapProcess overlay list.
Viewer guidance
The map viewer can reproduce these overlays with different confidence levels:
- plain
F7: strong static reproduction, because it is just a world-aligned coarse grid Ctrl+F7: strong static reproduction for authored family-4 trigger eggs, because the packed X/Y range bytes are already decoded in scene dataAlt+F7: narrower static reproduction using only shape0x04feitems and the exact recovered SnapProcess helper inputs and helper polygon; broader egg-family approximations should be avoided
Current viewer policy after the latest correction:
- keep the palette colors matched to the recovered cycle-color indices
- allow the viewer-side animation cadence to be slower than retail if the result reads more like the in-game flash on modern displays
- prefer reproducing the helper polygon exactly over re-expressing it as a simplified centered world diamond
Evidence anchors
13e8:1a20,13e8:1a50,13e8:1a7c: hotkey toggles inWorld_HandleKeyboardInput_13e8_14b41058:0137:Snap_GetSnapEggRange1058:021b:Snap_AddSnapEgg1058:0814:Alt+F7overlay consumer1090:0921:Ctrl+F7overlay consumer1180:15ef: camera-side overlay helper1180:1ce5: shared diamond helper10a0:2c82: live note that shape0x04feentering triggers the snap process
Cross-reference evidence also lives in: