paavohtl Claude Opus 4.6 commited on
Commit
ba3ea2d
·
1 Parent(s): b3cb49f

feat: add Debug formatter for GameInfo known fields

Browse files

Prints all named options fields, data paths as strings, and unknown
config DWORDs in hex. Skips the large unknown padding regions.

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>

crates/openwa-types/src/game_info.rs CHANGED
@@ -81,3 +81,59 @@ pub struct GameInfo {
81
  }
82
 
83
  const _: () = assert!(core::mem::size_of::<GameInfo>() == 0xF500);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
81
  }
82
 
83
  const _: () = assert!(core::mem::size_of::<GameInfo>() == 0xF500);
84
+
85
+ struct HexU32s<'a>(&'a [u32]);
86
+
87
+ impl core::fmt::Debug for HexU32s<'_> {
88
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
89
+ write!(f, "[")?;
90
+ for (i, v) in self.0.iter().enumerate() {
91
+ if i > 0 { write!(f, ", ")?; }
92
+ write!(f, "0x{v:08X}")?;
93
+ }
94
+ write!(f, "]")
95
+ }
96
+ }
97
+
98
+ impl core::fmt::Debug for GameInfo {
99
+ fn fmt(&self, f: &mut core::fmt::Formatter<'_>) -> core::fmt::Result {
100
+ // Extract land_dat_path as a string (null-terminated)
101
+ let land_str = self.land_dat_path.iter()
102
+ .position(|&b| b == 0)
103
+ .map(|end| core::str::from_utf8(&self.land_dat_path[..end]).unwrap_or("<invalid utf8>"))
104
+ .unwrap_or(core::str::from_utf8(&self.land_dat_path).unwrap_or("<invalid utf8>"));
105
+
106
+ // Extract speech_path as a string (null-terminated)
107
+ let speech_str = self.speech_path.iter()
108
+ .position(|&b| b == 0)
109
+ .map(|end| core::str::from_utf8(&self.speech_path[..end]).unwrap_or("<invalid utf8>"))
110
+ .unwrap_or(core::str::from_utf8(&self.speech_path).unwrap_or("<invalid utf8>"));
111
+
112
+ f.debug_struct("GameInfo")
113
+ // Cluster 1: data paths
114
+ .field("_config_dword_dae8", &format_args!("0x{:08X}", self._config_dword_dae8))
115
+ .field("land_dat_path", &land_str)
116
+ // Cluster 2: game options
117
+ .field("_config_byte_f3a0", &self._config_byte_f3a0)
118
+ .field("detail_level", &self.detail_level)
119
+ .field("energy_bar", &self.energy_bar)
120
+ .field("info_transparency", &self.info_transparency)
121
+ .field("info_spy", &self.info_spy)
122
+ .field("chat_pinned", &self.chat_pinned)
123
+ .field("chat_lines", &self.chat_lines)
124
+ .field("pinned_chat_lines", &format_args!("0x{:08X}", self.pinned_chat_lines))
125
+ .field("home_lock", &self.home_lock)
126
+ .field("_config_block_f3b4", &HexU32s(&self._config_block_f3b4))
127
+ .field("_config_dword_f3d4", &format_args!("0x{:08X}", self._config_dword_f3d4))
128
+ .field("_config_dword_f3d8", &format_args!("0x{:08X}", self._config_dword_f3d8))
129
+ .field("capture_transparent_pngs", &self.capture_transparent_pngs)
130
+ .field("camera_unlock_mouse_speed", &self.camera_unlock_mouse_speed)
131
+ .field("_config_dword_f3e4", &format_args!("0x{:08X}", self._config_dword_f3e4))
132
+ .field("background_debris_parallax", &format_args!("0x{:08X}", self.background_debris_parallax))
133
+ .field("topmost_explosion_onomatopoeia", &self.topmost_explosion_onomatopoeia)
134
+ .field("_zeroed_f3f0", &self._zeroed_f3f0)
135
+ .field("_conditional_config_f3f4", &HexU32s(&self._conditional_config_f3f4))
136
+ .field("speech_path", &speech_str)
137
+ .finish()
138
+ }
139
+ }