Crusader_Decomp/.github/instructions/ghidra.instructions.md
2026-03-19 16:39:57 +01:00

69 lines
3.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

---
applyTo: "**"
---
# Crusader Ghidra Workflow
- Active target is the raw full-EXE Ghidra program `CRUSADER-RAW.EXE` unless explicitly stated otherwise.
- Use Ghidra MCP tools for analysis, decompilation, renaming, comments, and xref work.
- Keep analysis batches small: prefer 1-5 functions, labels, or comments at a time.
- Avoid speculative renames. Prefer names that are supported by one of these:
- verified raw mapping from standalone segment work
- direct string evidence
- clear call/field behavior in decompiler or disassembly
- xref relationships to already-named functions
- When porting names from standalone segment extracts into `CRUSADER-RAW.EXE`, use only verified base mappings.
# Verified Raw Mapping Rules
- `seg001` raw base = `0x6E570`
- `seg021` raw base = `0x87170`
- Porting formula: `raw_full_exe_flat = verified_segment_base + standalone_segment_relative_offset`
- `seg001` and `seg021` both contain a keyboard handler; keep the seg001 name as `seg001_input_keyboard_handler` to avoid collision.
# Working Method
- Prefer a single decompile call first.
- If the decompiler collapses to thunk-heavy output, use one disassembly lookup to confirm the wrapper or parameter setup.
- Add a short decompiler comment when a rename is mapped from verified notes so the provenance stays visible in Ghidra.
- Keep `crusader_decompilation_notes.md` updated after each verified batch.
- Record raw-import addresses alongside original segment-relative offsets when porting names.
# Current Verified Raw-Import Ports
- `0006:e5d0` = `cursor_update_hover` from seg001 `0x0060`
- `0008:7377` = `entity_count_by_type_a` from seg021 `0x0207`
- `0007:28ce` = `shot_entity_alloc` from seg001 `0x435e`
- `0007:2a19` = `shot_entity_free` from seg001 `0x44a9`
- `0007:2bc9` = `projectile_init_vector` from seg001 `0x4659`
- `0007:3001` = `entity_fire_weapon` from seg001 `0x4a91`
- `0007:3088` = `fire_weapon_from_cursor` from seg001 `0x4b18`
- `0007:30e8` = `projectile_check_hit` from seg001 `0x4b78`
- `0007:319e` = `projectile_step_update` from seg001 `0x4c2e`
- `0007:3298` = `projectile_trace_ray` from seg001 `0x4d28`
- `0007:371d` = `projectile_update_tick` from seg001 `0x51ad`
- `0007:4009` = `projectile_apply_hit` from seg001 `0x5a99`
# Named 000e: Functions (direct analysis — not segment-ported)
## Parser Cluster (`000e:34xx38xx`)
- `000e:345e` = `record_table_init`
- `000e:34cc` = `record_table_destroy`
- `000e:35c6` = `record_table_release_buffer`
- `000e:35ef` = `record_table_next_slot`
- `000e:3639` = `record_table_parse_buffer`
- `000e:3798` = `record_parser_read_line`
- `000e:38f8` = `record_parser_find_marker`
## RIFF/Animation Cluster (`000e:03xx2xxx`)
- `000e:2a28` = `riff_find_chunk_by_type` (RIFF LIST/RIFF walker; FourCC match at chunk+8)
- `000e:2104` = `animation_start` (finds "movi" chunk, inits timing ring buffer, kicks advance)
- `000e:12f4` = `animation_advance_frame` (fixed-point 0x1000 timer stepper, ring buffer update)
- `000e:103f` = `animation_tick` (guard wrapper — checks +0xd4 != -1, calls advance_frame)
- `000e:06f7` = `anim_load_audio_frame` (checks "01wb" chunk tag 0x62773130, copies audio into ring buffer)
## Constructor/Assert Helpers (`000e:22xx29xx`)
- `000e:223d` = `assert_alive_sentinel` (expects +0xd4 == -1; traps on mismatch)
- `000e:2777` = `animation_ctor_variant_a` (alloc + init flags + chained init/assert/finalize)
- `000e:2860` = `animation_ctor_variant_b` (variant A with extra +0x109 init)
- `000e:2969` = `animation_ctor_variant_c` (default static flag profile +0x4c=0xd)