paavohtl Claude Opus 4.6 (1M context) commited on
Commit
a27530b
Β·
1 Parent(s): f4af409

fix: re-enable all end sections with correct conventions

Browse files

All constructor sections now enabled:
- HUD_LoadWeaponSprites: stdcall(ddgame, wrapper_4c4), RET 0x8
- Sprite init calls: stdcall(wrapper), RET 0x4
- GfxHandler close: thiscall vtable[3](1)
- Display finalization: stdcall(display)
- Layer visibility: thiscall vtable[0x17](layer, visible)

Headful: PASSES (119 validations)
Headless: still crashes at 0x525B82 (headless display stub issue)

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>

crates/openwa-core/src/engine/ddgame.rs CHANGED
@@ -1076,18 +1076,61 @@ unsafe fn init_graphics_and_resources(
1076
  }
1077
  }
1078
 
1079
- // HUD + sprite init: temporarily disabled to test stability
1080
- // {
1081
- // let hud_load: unsafe extern "stdcall" fn(*mut DDGame, *mut u8) =
1082
- // core::mem::transmute(rb(0x53D0E0) as usize);
1083
- // hud_load(ddgame, (*wrapper)._field_4c4);
1084
- // let f1: unsafe extern "stdcall" fn(*mut DDGameWrapper) =
1085
- // core::mem::transmute(rb(0x5706D0) as usize);
1086
- // f1(wrapper);
1087
- // let f2: unsafe extern "stdcall" fn(*mut DDGameWrapper) =
1088
- // core::mem::transmute(rb(0x5703E0) as usize);
1089
- // f2(wrapper);
1090
- // }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1091
 
1092
  // GfxHandler close, display finalization, layer visibility:
1093
  // Temporarily disabled to test stability.
 
1076
  }
1077
  }
1078
 
1079
+ // ── HUD_LoadWeaponSprites (0x53D0E0) ──
1080
+ // thiscall(ECX=ddgame, stack=wrapper_4c4), RET 0x8 (cleans 2: this implicit + 1 stack)
1081
+ // Wait β€” RET 0x8 means 2 stack params cleaned. For thiscall with ECX, that's 2 stack params.
1082
+ // The asm: PUSH ECX(=wrapper_4c4), PUSH EDX(=ddgame), CALL.
1083
+ // So it's stdcall(ddgame, wrapper_4c4) actually β€” ECX is NOT the this pointer!
1084
+ // The decompiler labeled it thiscall but the push sequence shows two stack params.
1085
+ // Let me pass wrapper as thiscall ECX and wrapper_4c4 as stack:
1086
+ // Actually: PUSH ECX([EBP+0x4C4]), PUSH EDX([EBP+0x488]=ddgame).
1087
+ // CALL 0x53D0E0. So ECX = gfx_handler_4c4, pushed FIRST. EDX = ddgame, pushed SECOND.
1088
+ // For stdcall: param_1=EDX(ddgame, pushed last), param_2=ECX(wrapper_4c4, pushed first).
1089
+ // But decompiler says thiscall β†’ ECX is implicit this.
1090
+ // RET 0x8 = 2 Γ— 4 bytes cleaned. For thiscall: ECX + 1 stack = RET 0x4.
1091
+ // RET 0x8 means 2 stack params, NO ECX implicit β†’ it's really stdcall(2 params).
1092
+ {
1093
+ let hud_load: unsafe extern "stdcall" fn(*mut DDGame, *mut u8) =
1094
+ core::mem::transmute(rb(0x53D0E0) as usize);
1095
+ hud_load(ddgame, (*wrapper)._field_4c4);
1096
+ }
1097
+
1098
+ // ── Two sprite init calls (0x5706D0, 0x5703E0) ──
1099
+ // PUSH EBP(wrapper); CALL β€” stdcall(wrapper), RET 0x4
1100
+ {
1101
+ let f1: unsafe extern "stdcall" fn(*mut DDGameWrapper) =
1102
+ core::mem::transmute(rb(0x5706D0) as usize);
1103
+ f1(wrapper);
1104
+ let f2: unsafe extern "stdcall" fn(*mut DDGameWrapper) =
1105
+ core::mem::transmute(rb(0x5703E0) as usize);
1106
+ f2(wrapper);
1107
+ }
1108
+
1109
+ // ── Close primary GfxHandler ──
1110
+ if !(*wrapper)._field_4c0.is_null() {
1111
+ let gfx_vt = *((*wrapper)._field_4c0 as *const *const u32);
1112
+ let close: unsafe extern "thiscall" fn(*mut u8, u32) =
1113
+ core::mem::transmute(*gfx_vt.add(3));
1114
+ close((*wrapper)._field_4c0, 1);
1115
+ }
1116
+
1117
+ // ── Display finalization (non-headless) ──
1118
+ if !is_headless {
1119
+ let init_display_final: unsafe extern "stdcall" fn(*mut u8) =
1120
+ core::mem::transmute(rb(va::DDGAME_INIT_DISPLAY_FINAL) as usize);
1121
+ init_display_final(disp_obj);
1122
+ }
1123
+ if *(rb(0x88E485) as *const u8) == 0 {
1124
+ call_usercall_eax(wrapper, FUN_570A90_ADDR);
1125
+ }
1126
+
1127
+ // Display layer visibility: display->vtable[0x17](layer, visible)
1128
+ let disp_obj_vt = *(disp_obj as *const *const u32);
1129
+ let set_vis: unsafe extern "thiscall" fn(*mut u8, i32, i32) -> *mut u8 =
1130
+ core::mem::transmute(*disp_obj_vt.add(0x17));
1131
+ set_vis(disp_obj, 1, 0);
1132
+ set_vis(disp_obj, 2, 0);
1133
+ set_vis(disp_obj, 3, 1);
1134
 
1135
  // GfxHandler close, display finalization, layer visibility:
1136
  // Temporarily disabled to test stability.