paavohtl Claude Opus 4.6 (1M context) commited on
Commit
89937ca
·
1 Parent(s): afaf5de

refactor: type CoordEntry fields as Fixed and eliminate pointer arithmetic in level_bounds

Browse files

Retype CoordEntry fields from raw i32 to named Fixed center_x/y and
center_x_target/y_target. Extend viewport_coords array to 5 entries to
cover the init spill. Retype init_game_state_level_bounds param from
*mut u8 to *mut DDGame, removing all raw pointer arithmetic.

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

crates/openwa-core/src/engine/coord.rs CHANGED
@@ -2,16 +2,22 @@
2
  // Coordinate types — DDGame sub-structs for screen and terrain coords
3
  // ============================================================
4
 
5
- /// Coordinate entry used in DDGame screen coordinate tables (stride 0x10).
6
  ///
7
- /// InitFields zeroes x and y; at runtime they contain fixed-point screen
8
- /// coordinates used for camera tracking and rendering regions.
 
9
  #[repr(C)]
10
  #[derive(Clone, Copy)]
11
  pub struct CoordEntry {
12
- pub x: i32,
13
- pub y: i32,
14
- pub _unknown: [u8; 8],
 
 
 
 
 
15
  }
16
 
17
  const _: () = assert!(core::mem::size_of::<CoordEntry>() == 0x10);
 
2
  // Coordinate types — DDGame sub-structs for screen and terrain coords
3
  // ============================================================
4
 
5
+ /// Coordinate entry used in DDGame viewport/camera tables (stride 0x10).
6
  ///
7
+ /// Each entry tracks a camera center position as two pairs of Fixed16.16
8
+ /// coordinates (current and target). InitGameState initializes all four
9
+ /// fields to the level center.
10
  #[repr(C)]
11
  #[derive(Clone, Copy)]
12
  pub struct CoordEntry {
13
+ /// +0x00: Camera center X (Fixed16.16).
14
+ pub center_x: crate::fixed::Fixed,
15
+ /// +0x04: Camera center Y (Fixed16.16).
16
+ pub center_y: crate::fixed::Fixed,
17
+ /// +0x08: Camera center X target (Fixed16.16).
18
+ pub center_x_target: crate::fixed::Fixed,
19
+ /// +0x0C: Camera center Y target (Fixed16.16).
20
+ pub center_y_target: crate::fixed::Fixed,
21
  }
22
 
23
  const _: () = assert!(core::mem::size_of::<CoordEntry>() == 0x10);
crates/openwa-core/src/engine/ddgame.rs CHANGED
@@ -499,13 +499,13 @@ pub struct DDGame {
499
  /// - 0x8174: value 0x3FC (1020) at runtime
500
  pub _unknown_81cc: [u8; 0x8CBC - 0x81CC],
501
 
502
- /// 0x8CBC-0x8CFB: 4 coordinate entries (0x10-byte stride).
503
- /// InitFields zeroes x and y of each. At runtime contains fixed-point
504
- /// screen coordinates (e.g. 393.0, 532.0, 960.0, 348.0).
505
- pub screen_coords: [CoordEntry; 4],
506
 
507
- /// 0x8CFC-0x984F: Unknown
508
- pub _unknown_8cfc: [u8; 0x9850 - 0x8CFC],
509
 
510
  /// 0x9850-0x988F: 4 coordinate entries (0x10-byte stride, zeroed by InitFields).
511
  pub screen_coords_2: [CoordEntry; 4],
@@ -618,12 +618,15 @@ impl DDGame {
618
  }
619
  }
620
 
621
- /// Listener position for 3D audio — stored at DDGame+0x8CEC (screen_coords[3]).
622
  ///
623
  /// Returns `(x, y)` as raw i32 values (fixed-point 16.16).
624
  /// Used by ComputeDistanceParams / Distance3D_Attenuation.
625
  pub fn listener_pos(&self) -> (i32, i32) {
626
- (self.screen_coords[3].x, self.screen_coords[3].y)
 
 
 
627
  }
628
  }
629
 
 
499
  /// - 0x8174: value 0x3FC (1020) at runtime
500
  pub _unknown_81cc: [u8; 0x8CBC - 0x81CC],
501
 
502
+ /// 0x8CBC-0x8D0B: 5 viewport coordinate entries (0x10-byte stride).
503
+ /// InitGameState writes camera center to entries 1..5 (indexed from base 0..4).
504
+ /// Entry 0 is not written by init (used for other purposes).
505
+ pub viewport_coords: [CoordEntry; 5],
506
 
507
+ /// 0x8D0C-0x984F: Unknown
508
+ pub _unknown_8d0c: [u8; 0x9850 - 0x8D0C],
509
 
510
  /// 0x9850-0x988F: 4 coordinate entries (0x10-byte stride, zeroed by InitFields).
511
  pub screen_coords_2: [CoordEntry; 4],
 
618
  }
619
  }
620
 
621
+ /// Listener position for 3D audio — stored at DDGame+0x8CEC (viewport_coords[3]).
622
  ///
623
  /// Returns `(x, y)` as raw i32 values (fixed-point 16.16).
624
  /// Used by ComputeDistanceParams / Distance3D_Attenuation.
625
  pub fn listener_pos(&self) -> (i32, i32) {
626
+ (
627
+ self.viewport_coords[3].center_x.0,
628
+ self.viewport_coords[3].center_y.0,
629
+ )
630
  }
631
  }
632
 
crates/openwa-core/src/engine/ddgame_constructor.rs CHANGED
@@ -17,6 +17,7 @@ use crate::engine::coord::{CoordList, CoordListEntry};
17
  use crate::engine::ddgame_wrapper::DDGameWrapper;
18
  use crate::engine::game_info::GameInfo;
19
  use crate::engine::net_bridge::NetBridge;
 
20
  use crate::input::keyboard::DDKeyboard;
21
  use crate::rebase::rb;
22
  use crate::render::display::gfx::DisplayGfx;
@@ -72,13 +73,13 @@ pub unsafe fn ddgame_init_fields(ddgame: *mut DDGame) {
72
  ddgame_init_render_indices(ddgame);
73
 
74
  // Zero x and y of each screen coordinate entry (4 entries each)
75
- for entry in &mut (*ddgame).screen_coords {
76
- entry.x = 0;
77
- entry.y = 0;
78
  }
79
  for entry in &mut (*ddgame).screen_coords_2 {
80
- entry.x = 0;
81
- entry.y = 0;
82
  }
83
  }
84
 
 
17
  use crate::engine::ddgame_wrapper::DDGameWrapper;
18
  use crate::engine::game_info::GameInfo;
19
  use crate::engine::net_bridge::NetBridge;
20
+ use crate::fixed::Fixed;
21
  use crate::input::keyboard::DDKeyboard;
22
  use crate::rebase::rb;
23
  use crate::render::display::gfx::DisplayGfx;
 
73
  ddgame_init_render_indices(ddgame);
74
 
75
  // Zero x and y of each screen coordinate entry (4 entries each)
76
+ for entry in &mut (*ddgame).viewport_coords {
77
+ entry.center_x = Fixed(0);
78
+ entry.center_y = Fixed(0);
79
  }
80
  for entry in &mut (*ddgame).screen_coords_2 {
81
+ entry.center_x = Fixed(0);
82
+ entry.center_y = Fixed(0);
83
  }
84
  }
85
 
crates/openwa-core/src/engine/game_state_init.rs CHANGED
@@ -938,7 +938,7 @@ pub unsafe fn init_game_state(wrapper: *mut DDGameWrapper) {
938
  init_landscape_flags(wrapper as *mut u8);
939
 
940
  // ===== Level bounds and camera initialization =====
941
- init_game_state_level_bounds(ddgame_raw, game_info);
942
 
943
  // ===== Display objects for HUD (headful only) =====
944
  if is_headful {
@@ -1526,9 +1526,7 @@ unsafe fn create_camera_object(
1526
  }
1527
 
1528
  /// Initialize level bounds and camera center positions.
1529
- unsafe fn init_game_state_level_bounds(ddgame_raw: *mut u8, game_info: *const GameInfo) {
1530
- let ddgame = ddgame_raw as *mut DDGame;
1531
-
1532
  (*ddgame)._field_7794 = 0;
1533
  (*ddgame)._field_7798 = 0;
1534
 
@@ -1551,15 +1549,17 @@ unsafe fn init_game_state_level_bounds(ddgame_raw: *mut u8, game_info: *const Ga
1551
  }
1552
 
1553
  // Camera center initialization (4 viewports)
1554
- for viewport_offset in [0x8CBCu32, 0x8CCCu32, 0x8CDCu32, 0x8CECu32] {
1555
- let level_w = (*ddgame).level_width as i32;
1556
- let level_h = (*ddgame).level_height as i32;
1557
- let cx = (level_w << 16) / 2;
1558
- let cy = (level_h * 0x10000) / 2;
1559
- *(ddgame_raw.add(viewport_offset as usize + 0x18) as *mut i32) = cx;
1560
- *(ddgame_raw.add(viewport_offset as usize + 0x10) as *mut i32) = cx;
1561
- *(ddgame_raw.add(viewport_offset as usize + 0x1C) as *mut i32) = cy;
1562
- *(ddgame_raw.add(viewport_offset as usize + 0x14) as *mut i32) = cy;
 
 
1563
  }
1564
 
1565
  // Map dimension fields
 
938
  init_landscape_flags(wrapper as *mut u8);
939
 
940
  // ===== Level bounds and camera initialization =====
941
+ init_game_state_level_bounds(ddgame, game_info);
942
 
943
  // ===== Display objects for HUD (headful only) =====
944
  if is_headful {
 
1526
  }
1527
 
1528
  /// Initialize level bounds and camera center positions.
1529
+ unsafe fn init_game_state_level_bounds(ddgame: *mut DDGame, game_info: *const GameInfo) {
 
 
1530
  (*ddgame)._field_7794 = 0;
1531
  (*ddgame)._field_7798 = 0;
1532
 
 
1549
  }
1550
 
1551
  // Camera center initialization (4 viewports)
1552
+ // Each iteration writes to viewport_coords[i+1] (entries 1..5).
1553
+ let level_w = (*ddgame).level_width as i32;
1554
+ let level_h = (*ddgame).level_height as i32;
1555
+ let cx = Fixed((level_w << 16) / 2);
1556
+ let cy = Fixed((level_h << 16) / 2);
1557
+ for i in 0..4 {
1558
+ let entry = &mut (*ddgame).viewport_coords[i + 1];
1559
+ entry.center_x = cx;
1560
+ entry.center_y = cy;
1561
+ entry.center_x_target = cx;
1562
+ entry.center_y_target = cy;
1563
  }
1564
 
1565
  // Map dimension fields