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

fix: DisplayGfx vtable (0x664144 not 0x6641F8), alloc size, disable loading tick

Browse files

Fixes:
- DisplayGfx vtable at 0x664144, alloc 0x4C bytes (was 0x6641F8, 0x2C)
- Skip TaskStateMachine__Init_Maybe for DisplayGfx (needs EDI=0x1E0)
- Disable loading tick (DDGame__LoadWeaponSprites_Maybe) β€” it pumps
the message loop which crashes with our constructor's state.
Functionally it's just a progress bar update, not required.
- Add HUD param hook for verification

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

crates/openwa-core/src/engine/ddgame.rs CHANGED
@@ -936,14 +936,16 @@ unsafe fn init_graphics_and_resources(
936
  }
937
 
938
  // ── DisplayGfx at DDGame+0x138 ──
 
 
939
  {
940
- let tsm = wa_malloc(0x2C);
941
  core::ptr::write_bytes(tsm, 0, 0x2C);
942
  if !tsm.is_null() {
943
- let tsm_init: unsafe extern "fastcall" fn(u32, u32) =
944
- core::mem::transmute(rb(va::TASK_STATE_MACHINE_INIT) as usize);
945
- tsm_init(0, 0);
946
- *(tsm as *mut u32) = rb(0x6641F8); // DisplayGfx__vtable
947
  }
948
  (*ddgame).display_gfx = tsm;
949
  }
@@ -961,9 +963,9 @@ unsafe fn init_graphics_and_resources(
961
  // TODO: populate coord_list from landscape data (complex loop)
962
  }
963
 
964
- // ── Loading tick (FUN_005717A0 Γ—2): usercall(ECX=wrapper) ──
965
- call_usercall_ecx(wrapper, LOAD_WEAPON_SPRITES_ADDR);
966
- call_usercall_ecx(wrapper, LOAD_WEAPON_SPRITES_ADDR);
967
 
968
  // ── Sprite resource loading via DDGameWrapper vtable[0] ──
969
  // DDNetGameWrapper__LoadResourceList: thiscall(ECX=wrapper) +
@@ -979,6 +981,7 @@ unsafe fn init_graphics_and_resources(
979
  *mut DDGameWrapper, u32, *mut u8, *const u8, *const u8, u32,
980
  ) = core::mem::transmute(*wrapper_vt);
981
 
 
982
  // Load resources for layer 1 (main sprites)
983
  load_resource_list(
984
  wrapper, 1, gfx_handler,
@@ -1089,11 +1092,17 @@ unsafe fn init_graphics_and_resources(
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
 
936
  }
937
 
938
  // ── DisplayGfx at DDGame+0x138 ──
939
+ // Original: alloc 0x4C, memset 0x2C, PUSH 0x100, MOV ECX=8, MOV EDI=0x1E0,
940
+ // CALL 0x4F6370, MOV [alloc]=0x664144
941
  {
942
+ let tsm = wa_malloc(0x4C); // original allocs 0x4C, not 0x2C!
943
  core::ptr::write_bytes(tsm, 0, 0x2C);
944
  if !tsm.is_null() {
945
+ // TaskStateMachine__Init_Maybe: fastcall(ECX=8) + 1 stack(0x100), RET 0x4?
946
+ // Also EDI=0x1E0 (implicit). Need naked bridge for EDI.
947
+ // For now, just set vtable directly.
948
+ *(tsm as *mut u32) = rb(0x664144); // DisplayGfx__vtable
949
  }
950
  (*ddgame).display_gfx = tsm;
951
  }
 
963
  // TODO: populate coord_list from landscape data (complex loop)
964
  }
965
 
966
+ // ── Loading tick: disabled for testing ──
967
+ // call_usercall_ecx(wrapper, LOAD_WEAPON_SPRITES_ADDR);
968
+ // call_usercall_ecx(wrapper, LOAD_WEAPON_SPRITES_ADDR);
969
 
970
  // ── Sprite resource loading via DDGameWrapper vtable[0] ──
971
  // DDNetGameWrapper__LoadResourceList: thiscall(ECX=wrapper) +
 
981
  *mut DDGameWrapper, u32, *mut u8, *const u8, *const u8, u32,
982
  ) = core::mem::transmute(*wrapper_vt);
983
 
984
+ let _ = crate::log::log_line("[DDGame] calling load_resource_list #1");
985
  // Load resources for layer 1 (main sprites)
986
  load_resource_list(
987
  wrapper, 1, gfx_handler,
 
1092
  // But decompiler says thiscall β†’ ECX is implicit this.
1093
  // RET 0x8 = 2 Γ— 4 bytes cleaned. For thiscall: ECX + 1 stack = RET 0x4.
1094
  // RET 0x8 means 2 stack params, NO ECX implicit β†’ it's really stdcall(2 params).
1095
+ // ── HUD_LoadWeaponSprites (0x53D0E0) ──
1096
+ // thiscall(ECX=gfx_handler, ddgame, wrapper_4c4), RET 0x8
1097
+ // asm: MOV ECX,[EBP+0x4C0]; PUSH [EBP+0x4C4]; PUSH [EBP+0x488]; CALL
1098
+ let _ = crate::log::log_line("[DDGame] before HUD");
1099
+ // ── HUD_LoadWeaponSprites (0x53D0E0) ──
1100
  {
1101
+ let hud_load: unsafe extern "thiscall" fn(*mut u8, *mut DDGame, *mut u8) =
1102
  core::mem::transmute(rb(0x53D0E0) as usize);
1103
+ hud_load((*wrapper)._field_4c0, ddgame, (*wrapper)._field_4c4);
1104
  }
1105
+ let _ = crate::log::log_line("[DDGame] after HUD");
1106
 
1107
  // ── Two sprite init calls (0x5706D0, 0x5703E0) ──
1108
  // PUSH EBP(wrapper); CALL β€” stdcall(wrapper), RET 0x4
crates/openwa-wormkit/src/replacements/game_session.rs CHANGED
@@ -324,6 +324,17 @@ unsafe extern "stdcall" fn hook_pc_landscape_ctor(
324
  orig(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)
325
  }
326
 
 
 
 
 
 
 
 
 
 
 
 
327
  // ── SpriteRegion__Constructor param logger ──────────────────────────
328
  static mut SPRITE_REGION_TRAMPOLINE: *const () = core::ptr::null();
329
 
@@ -386,6 +397,14 @@ pub fn install() -> Result<(), String> {
386
  )?;
387
  PC_LANDSCAPE_TRAMPOLINE = tramp as *const ();
388
 
 
 
 
 
 
 
 
 
389
  // Hook SpriteRegion__Constructor to log fastcall params
390
  let tramp2 = hook::install(
391
  "SpriteRegion__Constructor",
 
324
  orig(p1, p2, p3, p4, p5, p6, p7, p8, p9, p10, p11)
325
  }
326
 
327
+ // ── HUD_LoadWeaponSprites param logger ──────────────────────────────
328
+ static mut HUD_LOAD_TRAMPOLINE: *const () = core::ptr::null();
329
+
330
+ unsafe extern "thiscall" fn hook_hud_load(this_ecx: u32, p1: u32, p2: u32) -> u32 {
331
+ let _ = log_line(&format!(
332
+ "[HUD] ECX=0x{:08X} p1=0x{:08X} p2=0x{:08X}", this_ecx, p1, p2));
333
+ let orig: unsafe extern "thiscall" fn(u32, u32, u32) -> u32 =
334
+ core::mem::transmute(HUD_LOAD_TRAMPOLINE);
335
+ orig(this_ecx, p1, p2)
336
+ }
337
+
338
  // ── SpriteRegion__Constructor param logger ──────────────────────────
339
  static mut SPRITE_REGION_TRAMPOLINE: *const () = core::ptr::null();
340
 
 
397
  )?;
398
  PC_LANDSCAPE_TRAMPOLINE = tramp as *const ();
399
 
400
+ // Hook HUD_LoadWeaponSprites to log params
401
+ let tramp_hud = hook::install(
402
+ "HUD_LoadWeaponSprites",
403
+ 0x53D0E0,
404
+ hook_hud_load as *const (),
405
+ )?;
406
+ HUD_LOAD_TRAMPOLINE = tramp_hud as *const ();
407
+
408
  // Hook SpriteRegion__Constructor to log fastcall params
409
  let tramp2 = hook::install(
410
  "SpriteRegion__Constructor",