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

feat: replace DSSound slot 5 (set_pan) with Rust

Browse files

Pan uses the same VOLUME_DB_TABLE read backwards β€” index 0 from the end
gives near-0 dB (no attenuation), larger indices give more attenuation.
Positive pan negates the dB value for right-channel bias.

20/24 DSSound vtable slots now Rust.

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

crates/openwa-core/src/audio/dssound.rs CHANGED
@@ -287,6 +287,42 @@ pub unsafe extern "thiscall" fn set_master_volume(
287
  1
288
  }
289
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
290
  /// Slot 8: set_channel_volume β€” sets volume on a specific channel.
291
  /// `pool_id` is 1-based (1..64). `volume` is Fixed 16.16 (0..0x10000).
292
  pub unsafe extern "thiscall" fn set_channel_volume(
 
287
  1
288
  }
289
 
290
+ /// Slot 5: set_pan β€” sets stereo panning on a specific channel.
291
+ /// `pool_id` is 1-based (1..64). `pan` is Fixed 16.16 (-0x10000..0x10000).
292
+ /// Negative = left, positive = right.
293
+ pub unsafe extern "thiscall" fn set_pan(
294
+ this: *mut DSSound, pool_id: i32, pan: i32,
295
+ ) -> u32 {
296
+ let idx = (pool_id - 1) as usize;
297
+ if idx >= 64 {
298
+ return 0;
299
+ }
300
+ let snd = &*this;
301
+ let desc_idx = snd.buffer_pool_shadow[idx];
302
+ if desc_idx < 0 || desc_idx as usize >= 8 {
303
+ return 0;
304
+ }
305
+
306
+ // Clamp pan to [-0x10000, 0x10000].
307
+ let pan = pan.max(-0x10000).min(0x10000);
308
+
309
+ // Index into table backwards: abs(pan) >> 10 gives 0..63.
310
+ // Table is read from the END (index 63 = near silence, index 0 = full).
311
+ let table_idx = ((pan.unsigned_abs() >> 10) as usize).min(63);
312
+ let mut db = VOLUME_DB_TABLE[63 - table_idx] as i32;
313
+
314
+ // Positive pan β†’ negate (right channel louder = negative pan dB for left).
315
+ if pan > 0 {
316
+ db = -db;
317
+ }
318
+
319
+ if let Some(buf) = snd.channel_descs[desc_idx as usize].buffer() {
320
+ let _ = buf.SetPan(db);
321
+ }
322
+
323
+ 1
324
+ }
325
+
326
  /// Slot 8: set_channel_volume β€” sets volume on a specific channel.
327
  /// `pool_id` is 1-based (1..64). `volume` is Fixed 16.16 (0..0x10000).
328
  pub unsafe extern "thiscall" fn set_channel_volume(
crates/openwa-core/src/audio/mod.rs CHANGED
@@ -10,7 +10,7 @@ pub use dssound::{DSSound, DSSoundVtable, ChannelDescriptor};
10
  pub use dssound::{
11
  update_channels, release_finished,
12
  is_slot_loaded, is_channel_finished, stop_channel,
13
- set_master_volume, set_channel_volume,
14
  sub_destructor as dssound_sub_destructor, load_wav,
15
  noop as dssound_noop, returns_0 as dssound_returns_0, returns_1 as dssound_returns_1,
16
  };
 
10
  pub use dssound::{
11
  update_channels, release_finished,
12
  is_slot_loaded, is_channel_finished, stop_channel,
13
+ set_master_volume, set_channel_volume, set_pan,
14
  sub_destructor as dssound_sub_destructor, load_wav,
15
  noop as dssound_noop, returns_0 as dssound_returns_0, returns_1 as dssound_returns_1,
16
  };
crates/openwa-wormkit/src/replacements/sound.rs CHANGED
@@ -170,7 +170,7 @@ unsafe fn patch_dssound_vtable() -> Result<(), String> {
170
  use openwa_core::audio::{
171
  update_channels, release_finished,
172
  is_slot_loaded, is_channel_finished, stop_channel,
173
- set_master_volume, set_channel_volume, dssound_sub_destructor,
174
  load_wav, dssound_noop, dssound_returns_0, dssound_returns_1,
175
  };
176
 
@@ -192,6 +192,9 @@ unsafe fn patch_dssound_vtable() -> Result<(), String> {
192
  // Slot 11: release_finished β€” like update_channels, returns count
193
  *vt.add(11) = release_finished as *const () as u32;
194
 
 
 
 
195
  // Slot 9: is_channel_finished β€” returns 0 if playing, 1 if stopped/free
196
  *vt.add(9) = is_channel_finished as *const () as u32;
197
 
@@ -216,6 +219,6 @@ unsafe fn patch_dssound_vtable() -> Result<(), String> {
216
  // Trivial returns-1 (slot 23)
217
  *vt.add(23) = dssound_returns_1 as *const () as u32;
218
 
219
- let _ = log_line("[Sound] DSSound vtable: patched 19/24 slots with Rust");
220
  }).map_err(|e| e.to_string())
221
  }
 
170
  use openwa_core::audio::{
171
  update_channels, release_finished,
172
  is_slot_loaded, is_channel_finished, stop_channel,
173
+ set_master_volume, set_channel_volume, set_pan, dssound_sub_destructor,
174
  load_wav, dssound_noop, dssound_returns_0, dssound_returns_1,
175
  };
176
 
 
192
  // Slot 11: release_finished β€” like update_channels, returns count
193
  *vt.add(11) = release_finished as *const () as u32;
194
 
195
+ // Slot 5: set_pan β€” stereo panning with dB lookup
196
+ *vt.add(5) = set_pan as *const () as u32;
197
+
198
  // Slot 9: is_channel_finished β€” returns 0 if playing, 1 if stopped/free
199
  *vt.add(9) = is_channel_finished as *const () as u32;
200
 
 
219
  // Trivial returns-1 (slot 23)
220
  *vt.add(23) = dssound_returns_1 as *const () as u32;
221
 
222
+ let _ = log_line("[Sound] DSSound vtable: patched 20/24 slots with Rust");
223
  }).map_err(|e| e.to_string())
224
  }