refactor: type CoordEntry fields as Fixed and eliminate pointer arithmetic in level_bounds
Browse filesRetype 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
|
| 6 |
///
|
| 7 |
-
///
|
| 8 |
-
/// coordinates
|
|
|
|
| 9 |
#[repr(C)]
|
| 10 |
#[derive(Clone, Copy)]
|
| 11 |
pub struct CoordEntry {
|
| 12 |
-
|
| 13 |
-
pub
|
| 14 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 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-
|
| 503 |
-
///
|
| 504 |
-
///
|
| 505 |
-
pub
|
| 506 |
|
| 507 |
-
///
|
| 508 |
-
pub
|
| 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 (
|
| 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 |
}
|
| 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).
|
| 76 |
-
entry.
|
| 77 |
-
entry.
|
| 78 |
}
|
| 79 |
for entry in &mut (*ddgame).screen_coords_2 {
|
| 80 |
-
entry.
|
| 81 |
-
entry.
|
| 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(
|
| 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(
|
| 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 |
-
|
| 1555 |
-
|
| 1556 |
-
|
| 1557 |
-
|
| 1558 |
-
|
| 1559 |
-
|
| 1560 |
-
|
| 1561 |
-
|
| 1562 |
-
|
|
|
|
|
|
|
| 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
|