paavohtl Claude Opus 4.6 (1M context) commited on
Commit
5d8928f
·
1 Parent(s): 2d732a2

refactor: extract task_state_machine_init to task/state_machine.rs

Browse files

ddgame.rs: 1965 → 1924 lines (-41)
New: task/state_machine.rs (50 lines)
Re-exported via pub use for backward compatibility.

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

crates/openwa-core/src/engine/ddgame.rs CHANGED
@@ -485,51 +485,8 @@ pub unsafe fn ddgame_init_render_indices(base: *mut u8) {
485
  *(base.add(0x460) as *mut u16) = 0x10;
486
  }
487
 
488
- /// Pure Rust implementation of TaskStateMachine__Init (0x4F6370).
489
- ///
490
- /// Convention: usercall(ESI=object, ECX=param1, EDI=height) + 1 stack(width), RET 0x4.
491
- ///
492
- /// Allocates a bit-per-cell grid buffer. `param1` is typically 1 (cells per unit).
493
- /// `width` and `height` are pixel dimensions. The buffer is a row-major bitfield
494
- /// with rows aligned to 4 bytes.
495
- ///
496
- /// # Safety
497
- /// `object` must point to a zero-filled allocation of at least 0x2C bytes.
498
- pub unsafe fn task_state_machine_init(object: *mut u8, param1: u32, width: u32, height: u32) {
499
- // Row stride: bits-to-bytes rounded up, then aligned to 4
500
- let bits = param1.wrapping_mul(width).wrapping_add(7) as i32;
501
- let row_stride = ((bits >> 3) + 3) & !3;
502
- let total_size = row_stride as u32 * height;
503
-
504
- // Allocate data buffer with 0x20-byte header
505
- let alloc_size = ((total_size + 3) & !3) + 0x20;
506
- let buffer = wa_malloc(alloc_size);
507
-
508
- if buffer.is_null() {
509
- return;
510
- }
511
- // Guard against integer overflow producing tiny alloc_size with huge total_size
512
- if total_size as usize > alloc_size as usize {
513
- return;
514
- }
515
-
516
- // Memset twice (matches original — likely redundant but exact match)
517
- core::ptr::write_bytes(buffer, 0, total_size as usize);
518
- core::ptr::write_bytes(buffer, 0, total_size as usize);
519
-
520
- let obj = object as *mut u32;
521
- *obj.add(0) = rb(0x6640EC); // vtable
522
- *obj.add(1) = 0; // unused
523
- *obj.add(2) = buffer as u32; // data pointer
524
- *obj.add(3) = param1; // param1
525
- *obj.add(4) = row_stride as u32; // row stride
526
- *obj.add(5) = width; // width
527
- *obj.add(6) = height; // height
528
- *obj.add(7) = 0; // unused
529
- *obj.add(8) = 0; // unused
530
- *obj.add(9) = width; // width (duplicate)
531
- *obj.add(10) = height; // height (duplicate)
532
- }
533
 
534
  /// Pure Rust implementation of FUN_570E20 (display layer color init).
535
  ///
 
485
  *(base.add(0x460) as *mut u16) = 0x10;
486
  }
487
 
488
+ // TaskStateMachine__Init moved to crate::task::state_machine
489
+ pub use crate::task::state_machine::task_state_machine_init;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
490
 
491
  /// Pure Rust implementation of FUN_570E20 (display layer color init).
492
  ///
crates/openwa-core/src/task/mod.rs CHANGED
@@ -6,6 +6,7 @@ mod game_task;
6
  mod mine_oil_drum;
7
  mod missile;
8
  mod overlays;
 
9
  mod supply_crate;
10
  mod team;
11
  mod turn_game;
 
6
  mod mine_oil_drum;
7
  mod missile;
8
  mod overlays;
9
+ pub mod state_machine;
10
  mod supply_crate;
11
  mod team;
12
  mod turn_game;
crates/openwa-core/src/task/state_machine.rs ADDED
@@ -0,0 +1,50 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ //! TaskStateMachine initialization — bitfield grid buffer for spatial queries.
2
+
3
+ use crate::rebase::rb;
4
+ use crate::wa_alloc::wa_malloc;
5
+
6
+ /// Pure Rust implementation of TaskStateMachine__Init (0x4F6370).
7
+ ///
8
+ /// Convention: usercall(ESI=object, ECX=param1, EDI=height) + 1 stack(width), RET 0x4.
9
+ ///
10
+ /// Allocates a bit-per-cell grid buffer. `param1` is typically 1 (cells per unit).
11
+ /// `width` and `height` are pixel dimensions. The buffer is a row-major bitfield
12
+ /// with rows aligned to 4 bytes.
13
+ ///
14
+ /// # Safety
15
+ /// `object` must point to a zero-filled allocation of at least 0x2C bytes.
16
+ pub unsafe fn task_state_machine_init(object: *mut u8, param1: u32, width: u32, height: u32) {
17
+ // Row stride: bits-to-bytes rounded up, then aligned to 4
18
+ let bits = param1.wrapping_mul(width).wrapping_add(7) as i32;
19
+ let row_stride = ((bits >> 3) + 3) & !3;
20
+ let total_size = row_stride as u32 * height;
21
+
22
+ // Allocate data buffer with 0x20-byte header
23
+ let alloc_size = ((total_size + 3) & !3) + 0x20;
24
+ let buffer = wa_malloc(alloc_size);
25
+
26
+ if buffer.is_null() {
27
+ return;
28
+ }
29
+ // Guard against integer overflow producing tiny alloc_size with huge total_size
30
+ if total_size as usize > alloc_size as usize {
31
+ return;
32
+ }
33
+
34
+ // Memset twice (matches original — likely redundant but exact match)
35
+ core::ptr::write_bytes(buffer, 0, total_size as usize);
36
+ core::ptr::write_bytes(buffer, 0, total_size as usize);
37
+
38
+ let obj = object as *mut u32;
39
+ *obj.add(0) = rb(0x6640EC); // vtable
40
+ *obj.add(1) = 0;
41
+ *obj.add(2) = buffer as u32; // data pointer
42
+ *obj.add(3) = param1;
43
+ *obj.add(4) = row_stride as u32;
44
+ *obj.add(5) = width;
45
+ *obj.add(6) = height;
46
+ *obj.add(7) = 0;
47
+ *obj.add(8) = 0;
48
+ *obj.add(9) = width; // duplicate
49
+ *obj.add(10) = height; // duplicate
50
+ }