diff --git a/sndlib/ds3dgeometry.cpp b/sndlib/ds3dgeometry.cpp
deleted file mode 100644
index 57098f86..00000000
--- a/sndlib/ds3dgeometry.cpp
+++ /dev/null
@@ -1,244 +0,0 @@
-/*
-* Descent 3
-* Copyright (C) 2024 Parallax Software
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see .
-
---- HISTORICAL COMMENTS FOLLOW ---
-
- * $Source: $
- * $Revision: 8 $
- * $Author: Jeff $
- * $Date: 10/21/99 9:28p $
- *
- * Hardware occlusion and reflection sound support
- *
- * $Log: /DescentIII/Main/dd_sndlib/geometry.cpp $
- *
- * 8 10/21/99 9:28p Jeff
- * B.A. Macintosh code merge
- *
- * 7 8/13/99 2:00p Samir
- * more aureal and geometry fixes.
- *
- * 6 8/11/99 3:12p Samir
- * fixes for aureal support.
- *
- * 5 4/13/99 4:09p Samir
- * more priority stuff.
- *
- * 4 4/06/99 8:30p Samir
- * added reflection support.
- *
- * 3 3/30/99 5:36p Matt
- * Fixed compile warnings
- *
- * 2 3/29/99 10:52a Samir
- * occlusion support almost complete.
- *
- */
-
-#include "ds3dlib_internal.h"
-#include "auddev.h"
-#include "pserror.h"
-
-//////////////////////////////////////////////////////////////////////////////
-
-//////////////////////////////////////////////////////////////////////////////
-llsGeometry::llsGeometry() {
- m_snd_system = NULL;
- m_snd_mixer = SOUND_MIXER_NONE;
- m_lib_init = false;
-}
-
-// specify a sound library to associate geometry with
-bool llsGeometry::Init(llsSystem *snd_sys) {
- int i;
-
- if (m_lib_init) {
- Int3(); // really, this shouldn't happen.
- return true;
- }
- if (!snd_sys) {
- Int3();
- return false;
- }
-
- if (!m_lib_init) {
- mprintf(0, "DDSNDGEO: Failed to initialize geometry interface.\n");
- return false;
- }
-
- m_snd_mixer = snd_sys->GetSoundMixer();
-
- m_snd_system = snd_sys;
- m_lib_init = true;
-
- // create material list.
- for (i = 0; i < SNDGEO_MATERIAL_COUNT; i++) {
- m_snd_materials[i] = NULL;
- }
-
- CreateMaterial(SNDGEO_MATERIAL_ROCK, 0.2f, 0.5f, 0.9f, 0.8f);
- CreateMaterial(SNDGEO_MATERIAL_WATER, 1.0f, 0.3f, 0.8f, 0.7f);
- CreateMaterial(SNDGEO_MATERIAL_METAL, 0.1f, 0.1f, 0.95f, 0.85f);
-
- mprintf(0, "DDSNDGEO: Initialized.\n");
- return true;
-}
-
-// closes low level geometry system.
-void llsGeometry::Shutdown() {
- int i;
-
- if (!m_lib_init) { // damn this shouldn't happen.
- Int3();
- return;
- }
-
- // destroy materials list
- for (i = 0; i < SNDGEO_MATERIAL_COUNT; i++) {
- DestroyMaterial(i);
- }
-
- m_snd_mixer = SOUND_MIXER_NONE;
- m_snd_system = NULL;
- m_lib_init = false;
-
- mprintf(0, "DDSNDGEO: Shutdown.\n");
-}
-
-void llsGeometry::StartFrame() {
- n_primatives_used = 0;
- n_reflections_used = 0;
- n_materials_used = 0;
-}
-
-void llsGeometry::EndFrame() {
- mprintf_at(3, 4, 20, "sndpoly=%04d", n_primatives_used);
- mprintf_at(3, 4, 38, "sndmat=%04d", n_materials_used);
- mprintf_at(3, 5, 20, "sndref=%04d", n_reflections_used);
-}
-
-// polygon lists
-
-// marks beginning of a list of polygons to render
-// -1 group if non cached (user doesn't want to reuse this.
-void llsGeometry::StartPolygonGroup(int group) {
- ASSERT(m_lib_init);
-}
-
-// ends a list of polygons to render.
-void llsGeometry::EndPolygonGroup(int group) {
- ASSERT(m_lib_init);
-}
-
-// renders a group.
-void llsGeometry::RenderGroup(int group) {
- ASSERT(m_lib_init);
-}
-
-void llsGeometry::Clear() {
- ASSERT(m_lib_init);
-}
-
-// primatives
-// 4 verts here.
-void llsGeometry::AddQuad(unsigned tag, vector **verts) {
- n_primatives_used++;
-}
-
-// 3 verts here.
-void llsGeometry::AddTriangle(unsigned tag, vector **verts) {
- n_primatives_used++;
-}
-
-void llsGeometry::AddPoly(int nv, vector **verts, unsigned tag, tSoundMaterial material) {
- int i, saved_primatives_used; //,p;
- void *matp = NULL;
-
- if (nv < 3) {
- Int3();
- return;
- }
-
- if (material >= 0 && material < SNDGEO_MATERIAL_COUNT) {
- matp = m_snd_materials[material];
- }
-
- if (matp) {
- n_materials_used++;
- }
- saved_primatives_used = n_primatives_used;
-
- // add polygons or split.
- switch (nv) {
- case 3:
- AddTriangle(tag, verts);
- break;
- case 4:
- AddQuad(tag, verts);
- break;
- default:
- Int3();
- }
-
- if (matp) {
- n_reflections_used += (n_primatives_used - saved_primatives_used);
- }
-}
-
-// values MUST be from 0 to 1 for gain and highfreq.
-void llsGeometry::CreateMaterial(tSoundMaterial material, float transmit_gain, float transmit_highfreq,
- float reflect_gain, float reflect_highfreq) {
- if (m_snd_materials[material] || material < 0 || material >= SNDGEO_MATERIAL_COUNT) {
- Int3(); // get samir, trying to intiialize a material in an existing slot.
- return;
- }
-
- // check values.
- if (transmit_gain < 0) {
- transmit_gain = 0;
- } else if (transmit_gain > 1) {
- transmit_gain = 1;
- }
- if (transmit_highfreq < 0) {
- transmit_highfreq = 0;
- } else if (transmit_highfreq > 1) {
- transmit_highfreq = 1;
- }
- if (reflect_gain < 0) {
- reflect_gain = 0;
- } else if (reflect_gain > 1) {
- reflect_gain = 1;
- }
- if (reflect_highfreq < 0) {
- reflect_highfreq = 0;
- } else if (reflect_highfreq > 1) {
- reflect_highfreq = 1;
- }
-}
-
-void llsGeometry::DestroyMaterial(tSoundMaterial material) {
- if (!m_snd_materials[material]) {
- if (material < 0 || material >= SNDGEO_MATERIAL_COUNT) {
- Int3(); // get samir, trying to destroy a material in an nonexisting slot.
- }
- return;
- }
-
- if (m_snd_materials[material]) {
- m_snd_materials[material] = NULL;
- }
-}
diff --git a/sndlib/ds3dlib.cpp b/sndlib/ds3dlib.cpp
deleted file mode 100644
index 7f8e9776..00000000
--- a/sndlib/ds3dlib.cpp
+++ /dev/null
@@ -1,3312 +0,0 @@
-/*
-* Descent 3
-* Copyright (C) 2024 Parallax Software
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see .
-
---- HISTORICAL COMMENTS FOLLOW ---
-
- * $Logfile: /DescentIII/Main/dd_sndlib/Ds3dlib.cpp $
- * $Revision: 149 $
- * $Date: 9/27/99 5:38p $
- * $Author: Samir $
- *
- * DirectSound(2d and 3d) implementation of the Descent III low-level sound interface
- *
- * $Log: /DescentIII/Main/dd_sndlib/Ds3dlib.cpp $
- *
- * 149 9/27/99 5:38p Samir
- * EAX 2.0->1.0 compatibility checkin.
- *
- * 148 8/23/99 5:29p Samir
- * incremental EAX 2.0 checkin
- *
- * 147 8/13/99 2:00p Samir
- * more aureal and geometry fixes.
- *
- * 146 5/23/99 12:48a Samir
- * decreased rolloff factor of 3d sounds under 3d sound mixers from 0.75
- * to 0.5
- *
- * 145 5/20/99 6:23p Kevin
- * minor speed up of software mixer and fix for memory debugging
- *
- * 144 5/20/99 1:00a Samir
- * changes in ordering of EAX and NONE mixers.
- *
- * 143 5/09/99 7:09p Samir
- * fixed sound card selection (enumeration) problems.
- *
- * 142 5/07/99 5:39p Samir
- * better error checking for CheckAndForceDataAlloc for PageInSound.
- *
- * 141 5/03/99 3:12a Samir
- * fixed up aureal so it works (a little slow though...)
- *
- * 140 5/01/99 10:25p Jeff
- * (samir) fixed crash bug when alt-tabbing,inserting cds,etc
- *
- * 139 4/29/99 4:36p Kevin
- * fixed a problem with low quality sounds & the optimizd software mixer
- *
- * 138 4/29/99 3:01p Samir
- * added code for direct sound mixers only (and function for Aureal
- * really) that will use direct sound looping for simple loops.
- *
- * 137 4/27/99 7:08p Kevin
- * optimized software mixer!
- *
- * 136 4/27/99 6:21p Samir
- * if callback gets a NULL guid, just return, assume that the sound device
- * is the default?
- *
- * 135 4/27/99 5:19p Samir
- * mprintf change.
- *
- * 134 4/27/99 2:10p Samir
- * added code to set the desired sound card given the descriptive name of
- * a sound card.
- *
- * 133 4/25/99 9:52p Samir
- * fixed looping sequencing bug with thread for direct sound mixers.
- * SSF_PLAY_LOOPING must be set before any buffer filling occurs,
- * otherwise bad things happen with very small loops....
- *
- * 132 4/23/99 7:51p Samir
- * looping fixes for directsound
- *
- * 131 4/22/99 10:33p Samir
- * modifications so that DirectSound mixers use one thread for all looping
- * and streaming sounds. It worked without crashing for about twenty
- * minutes of playing from level 1 to level 2 of D3. We'll see.
- *
- * 130 4/18/99 5:37p Kevin
- * Very simple optimization for the software mixer
- *
- * 129 4/13/99 4:15p Jason
- * took out register keyword because it was hurting performance
- *
- * 128 4/13/99 4:09p Samir
- * more priority stuff.
- *
- *
- * 126 4/12/99 7:14p Samir
- * prioritization code added.
- *
- * 125 4/10/99 5:08p Samir
- * took out obsolete data from play_information structure that should save
- * around 70 bytes per instance.
- *
- * 124 4/09/99 5:00p Kevin
- * put the memset in -- memset should be doing at least 32 bit copies,
- * which is FAR better than a for loop.
- *
- * 123 4/09/99 12:03p Samir
- * took out windows.h again, this time made HWND a void pointer, and
- * checked under both editor and main projects.
- *
- * 122 4/06/99 8:29p Samir
- * added error check system.
- *
- * 121 3/29/99 11:00a Samir
- * added system to support different 3d sound options.
- *
- * 120 3/17/99 4:20p Samir
- * added functions to pause and resume individual sounds.
- *
- * 119 3/04/99 1:23p Kevin
- * Fixed Poping sound!!!
- *
- * 118 3/03/99 6:53p Matt
- * Fixed compile warning
- *
- * 117 3/03/99 3:12p Chris
- * Fixed volume problems
- *
- * 116 3/01/99 8:12p Samir
- * pause sounds when switching sound quality!
- *
- * 115 2/25/99 4:50p Kevin
- * Semi-hack to fix the problem with music looping and stuttering in DS
- *
- * 114 2/24/99 3:15p Kevin
- * OEM menu changes, and bug fixes for the save/load system
- *
- * 113 2/22/99 6:28p Kevin
- * Fixed a bug that was introduced (?) when the thread problem was fixed.
- *
- * 112 2/20/99 1:14a Kevin
- * Fixed another bug
- *
- * 111 2/19/99 10:45p Kevin
- * Fixed bug I just introduced...
- *
- * 110 2/19/99 5:21p Kevin
- * Fixed some connection DLLs and a Direct Sound bug with threads.
- *
- * 109 2/11/99 3:30p Doug
- * error checking in PlaySoundBuffer.
- *
- * 108 2/04/99 9:46a Kevin
- * OEM version changes
- *
- * 107 1/14/99 6:10p Samir
- * added DirectSound buffer duplication code.
- *
- * 106 1/11/99 5:51p Samir
- * reverb on the buffer level.
- *
- * 105 1/08/99 6:31p Samir
- * added reverb
- *
- * 104 1/08/99 11:36a Samir
- * implemented basic Aureal 2.0 support.
- *
- * 103 1/08/99 10:32a Chris
- *
- * 102 12/23/98 11:49a Samir
- * reorganized code so it works with different APIs.
- *
- * 101 12/11/98 5:21p Samir
- * (chris) fixed problem with software streaming audio.
- *
- * 100 12/10/98 3:16p Chris
- * added mprintfs for later use
- *
- * 99 12/10/98 2:18p Chris
- * Added more asserts to the streaming code
- *
- * 98 11/13/98 4:55p Nate
- * don't do dedicated server check in lowlevel.
- *
- * 97 11/13/98 12:17p Chris
- *
- * 96 11/12/98 12:15p Chris
- * Fixed a bug with streaming mixers
- *
- * 95 10/30/98 1:20p Chris
- * Fixed a m_unique_id bug where it was being used before it was being
- * assigned
- *
- *
- * $NoKeywords: $
- */
-
-#include "ds3dlib_internal.h"
-
-#include
-#include
-#include
-#include "cfile.h"
-#include "pserror.h"
-#include "mono.h"
-#include "soundload.h"
-#include "mem.h"
-#include "application.h"
-#include "auddev.h"
-#include "Macros.h"
-#include "ddio.h"
-
-// Hacked window handle -- chrishack
-static oeWin32Application *SoundApp = NULL;
-static void *GameWindowHandle;
-#define MIN_SOUND_MIX_VOLUME 0.0
-#define MAX_WRITE_AHEAD .04 // Seconds to write ahead of the play position (in seconds)
-
-// write position
-
-#define IS_3D_MIXER(_type) ((_type) >= SOUND_MIXER_DS3D_16 && (_type) != SOUND_MIXER_NONE)
-
-win_llsSystem *ll_sound_ptr;
-emulated_listener *g_emulated_listener = NULL; // silly hack (Samir)
-int16_t Global_DS_alloced_sounds = 0;
-
-int *Fast_mixer = NULL;
-int Fast_mixer_len = 0;
-
-#define VOLUME_FIX_BITS 1024
-
-// Streaming primary buffer information
-DSSTREAM m_sb_info;
-char m_sound_device_name[256] = ""; // set by set sound card
-
-// Loads a sound buffer with data
-HRESULT LoadSoundData(LPDIRECTSOUNDBUFFER lp_dsb, char *sound_data_ptr, DWORD total_bytes);
-
-///////////////////////////////////////////////////////////////////////////////
-
-static t3dEnvironmentValues Env3dValues;
-static t3dEnvironmentToggles Env3dToggles;
-
-#define ENV3DTOG_DOPPLER true
-#define ENV3DTOG_GEOMETRY true
-
-#define ENV3DVAL_DOPPLER_DEFAULT 0.5f
-#define ENV3DVAL_ROLLOFF_DEFAULT 0.5f
-
-///////////////////////////////////////////////////////////////////////////////
-
-win_llsSystem::win_llsSystem(void) : llsSystem() {
- m_lp_ds = NULL;
- m_f_sound_lib_init = 0;
- m_hwnd_main = NULL;
- m_mixer_type = -1;
- m_sound_quality = SQT_NORMAL;
- m_cache_stress_timer = 0.0f;
- ll_sound_ptr = NULL;
- m_timer_last_frametime = -1;
- memset(&Env3dValues, 0, sizeof(Env3dValues));
- memset(&Env3dToggles, 0, sizeof(Env3dToggles));
- SetError(SSL_OK);
-}
-
-win_llsSystem::~win_llsSystem(void) {
- DestroySoundLib();
- SetSoundCard(NULL);
-}
-
-inline void opti_8m_mix(uint8_t *cur_sample_8bit, const int num_write, int &samples_played, int *mixer_buffer16,
- const float l_volume, const float r_volume) {
- int i;
- int *mb = mixer_buffer16;
-
- const int fix_rvol = r_volume * VOLUME_FIX_BITS;
- const int fix_lvol = l_volume * VOLUME_FIX_BITS;
-
- for (i = 0; i < (num_write << 1); i += 2) {
- int sample;
- int l_sample;
- int r_sample;
-
- sample = (((*cur_sample_8bit)) - 128) << 8;
- cur_sample_8bit++;
-
- l_sample = *mb + (sample * fix_lvol);
- r_sample = *(mb + 1) + (sample * fix_rvol);
-
- *mb = l_sample;
- mb++;
- *mb = r_sample;
- mb++;
- }
- samples_played += (i / 2);
-}
-
-inline void opti_8s_mix(uint8_t *cur_sample_8bit, const int num_write, int &samples_played, int *mixer_buffer16,
- const float l_volume, const float r_volume) {
- int i;
- int *mb = mixer_buffer16;
-
- const int fix_rvol = r_volume * VOLUME_FIX_BITS;
- const int fix_lvol = l_volume * VOLUME_FIX_BITS;
-
- for (i = 0; i < (num_write << 1); i += 2) {
- int lsample;
- int rsample;
- int l_sample;
- int r_sample;
-
- lsample = (((*cur_sample_8bit)) - 128) << 8;
- cur_sample_8bit++;
- rsample = (((*cur_sample_8bit)) - 128) << 8;
- cur_sample_8bit++;
-
- l_sample = *mb + (lsample * fix_lvol);
- r_sample = *(mb + 1) + (rsample * fix_rvol);
-
- *mb = l_sample;
- mb++;
- *mb = r_sample;
- mb++;
- }
- samples_played += (i / 2);
-}
-
-inline void opti_16m_mix(int16_t *cur_sample_16bit, const int num_write, int &samples_played, int *mixer_buffer16,
- const float l_volume, const float r_volume) {
- int i;
- int *mb = mixer_buffer16;
-
- const int fix_rvol = r_volume * VOLUME_FIX_BITS;
- const int fix_lvol = l_volume * VOLUME_FIX_BITS;
-
- for (i = 0; i < (num_write << 1); i += 2) {
- int sample;
- int l_sample;
- int r_sample;
-
- sample = *cur_sample_16bit;
- cur_sample_16bit++;
-
- l_sample = *mb + (sample * fix_lvol);
- r_sample = *(mb + 1) + (sample * fix_rvol);
-
- *mb = l_sample;
- mb++;
- *mb = r_sample;
- mb++;
- }
- samples_played += (i / 2);
-}
-
-inline void opti_16s_mix(int16_t *cur_sample_16bit, const int num_write, int &samples_played, int *mixer_buffer16,
- const float l_volume, const float r_volume) {
- int i;
- int *mb = mixer_buffer16;
-
- const int fix_rvol = r_volume * VOLUME_FIX_BITS;
- const int fix_lvol = l_volume * VOLUME_FIX_BITS;
-
- for (i = 0; i < (num_write << 1); i += 2) {
- int lsample;
- int rsample;
- int l_sample;
- int r_sample;
-
- lsample = *cur_sample_16bit;
- cur_sample_16bit++;
- rsample = *cur_sample_16bit;
- cur_sample_16bit++;
-
- l_sample = *mb + (lsample * fix_lvol);
- r_sample = *(mb + 1) + (rsample * fix_rvol);
-
- *mb = l_sample;
- mb++;
- *mb = r_sample;
- *mb++;
- }
- samples_played += (i / 2);
-}
-
-////////////////////////////////////////////////////////////////////////////////////
-
-#define MAX_DS_PAN 1000.0f
-
-int GamePanToDsPan(float pan) {
- int ds_pan;
- ds_pan = (int)(pan * MAX_DS_PAN);
-
- if (ds_pan > MAX_DS_PAN)
- ds_pan = MAX_DS_PAN;
- if (ds_pan < -MAX_DS_PAN)
- ds_pan = -MAX_DS_PAN;
-
- // mprintf(0, "P %f %d\n", pan, ds_pan);
- return ds_pan;
-}
-
-int GameVolumeToDsAttenuation(float volume) {
- float fvol;
-
- if (volume <= 0.0f) {
- fvol = 2000.0f;
- } else {
- fvol = logf(volume) / logf(10.0f);
- fvol *= 2000.0;
- }
-
- if (volume <= 0.01f) {
- fvol = DSBVOLUME_MIN;
- }
-
- // mprintf(0, "V %f %f\n", volume, fvol);
- return (int)fvol;
-}
-
-////////////////////////////////////////////////////////////////////////////////////
-
-inline char *get_sound_info(sound_buffer_info *sb, int *length, bool *f16bit) {
- if (sb->m_sound_index < 0) {
- if (sb->s) {
- *f16bit = sb->s->f_sample_16bit;
- }
- return NULL;
- }
- if (SoundFiles[Sounds[sb->m_sound_index].sample_index].sample_8bit) {
- *length = SoundFiles[Sounds[sb->m_sound_index].sample_index].np_sample_length;
- *f16bit = false;
- return (char *)SoundFiles[Sounds[sb->m_sound_index].sample_index].sample_8bit;
- } else {
- ASSERT(SoundFiles[Sounds[sb->m_sound_index].sample_index].sample_16bit);
- *f16bit = true;
- *length = SoundFiles[Sounds[sb->m_sound_index].sample_index].np_sample_length * 2;
- return (char *)SoundFiles[Sounds[sb->m_sound_index].sample_index].sample_16bit;
- }
-}
-
-//////////////////////////////////////////////////////////////////////////////////
-#define SB_STATUS_PLAYING 0x1
-#define SB_STATUS_INVALID 0x2
-
-inline int sb_get_status(sound_buffer_info *sb) {
- int retflags = 0;
-
- if (sb->m_mixer_type != SOUND_MIXER_SOFTWARE_16) {
- LPDIRECTSOUNDBUFFER sound_ptr = sb->m_sound_buffer;
- unsigned long status;
-
- if (sound_ptr) {
- sound_ptr->GetStatus(&status);
- if (status & DSBSTATUS_PLAYING)
- retflags |= SB_STATUS_PLAYING;
- } else {
- retflags |= SB_STATUS_INVALID;
- }
- }
-
- return retflags;
-}
-
-inline void sb_adjust_properties_3d(sound_buffer_info *sb, float f_volume, pos_state *pos, float reverb) {
- if (!ll_sound_ptr->m_in_sound_frame)
- ll_sound_ptr->m_pending_actions = true;
-
- sb->m_volume = f_volume;
-
- if (IS_3D_MIXER(sb->m_mixer_type)) {
- LPDIRECTSOUNDBUFFER lp_dsb = sb->m_sound_buffer;
- LPDIRECTSOUND3DBUFFER lpDSB3D = sb->m_sound_buffer_3d;
-
- lp_dsb->SetVolume(GameVolumeToDsAttenuation(f_volume));
-
- ASSERT(lpDSB3D != NULL);
-
- if (sb->m_mixer_type == SOUND_MIXER_CREATIVE_EAX) {
- lpDSB3D->SetMinDistance(30.0f, DS3D_IMMEDIATE);
- } else {
- lpDSB3D->SetMinDistance(Sounds[sb->m_sound_index].min_distance, DS3D_IMMEDIATE);
- }
- lpDSB3D->SetMaxDistance(Sounds[sb->m_sound_index].max_distance, DS3D_IMMEDIATE);
- lpDSB3D->SetConeOrientation(pos->orient->fvec.x, pos->orient->fvec.y, pos->orient->fvec.z, DS3D_IMMEDIATE);
- lpDSB3D->SetPosition(pos->position->x, pos->position->y, pos->position->z, DS3D_IMMEDIATE);
- lpDSB3D->SetVelocity(pos->velocity->x, pos->velocity->y, pos->velocity->z, DS3D_IMMEDIATE);
-
- // if (sb->m_mixer_type == SOUND_MIXER_CREATIVE_EAX) {
- // EAX_SetBufferReverbMix(lpDSB3D, reverb);
- // }
- } else {
- mprintf(0, "m_mixer_type = %d\n", sb->m_mixer_type);
- Int3();
- }
-}
-
-inline void sb_adjust_properties_2d(sound_buffer_info *sb, float f_volume, float f_pan, uint16_t frequency) {
- if (!ll_sound_ptr->m_in_sound_frame)
- ll_sound_ptr->m_pending_actions = true;
-
- sb->m_volume = f_volume;
-
- if (sb->m_mixer_type != SOUND_MIXER_SOFTWARE_16) {
- LPDIRECTSOUNDBUFFER lpdsb;
-
- ASSERT(f_pan >= -1.0f && f_pan <= 1.0f);
- ASSERT(f_volume >= 0.0f && f_volume <= 1.0f);
-
- lpdsb = sb->m_sound_buffer;
- if (lpdsb == NULL)
- return;
-
- // mprintf(0, "Sound UID %d is now at %d volume,%d pan\n", sound_uid, volume, pan);
-
- lpdsb->SetVolume(GameVolumeToDsAttenuation(f_volume));
- lpdsb->SetPan(GamePanToDsPan(f_pan)); // chrishack pan is off
- lpdsb->SetFrequency(frequency);
- }
-}
-
-// functions for different APIs
-int sb_get_current_position(sound_buffer_info *sb, uint32_t *writep) {
- DWORD playp, wp;
-
- if (sb->m_mixer_type != SOUND_MIXER_SOFTWARE_16) {
- if (sb->m_sound_buffer && sb->m_sound_buffer->GetCurrentPosition(&playp, &wp) == DS_OK) {
- *writep = (uint32_t)wp;
- } else {
- playp = (DWORD)(-1);
- *writep = (uint32_t)(-1);
- }
- }
-
- return (uint32_t)playp;
-}
-
-inline void sb_set_current_position(sound_buffer_info *sb, uint32_t pos) {
- if (!ll_sound_ptr->m_in_sound_frame)
- ll_sound_ptr->m_pending_actions = true;
-
- if (sb->m_mixer_type != SOUND_MIXER_SOFTWARE_16) {
- sb->m_sound_buffer->SetCurrentPosition((DWORD)pos);
- }
-}
-
-void sb_free_buffer(sound_buffer_info *sb) {
- if (!ll_sound_ptr->m_in_sound_frame)
- ll_sound_ptr->m_pending_actions = true;
- if (!sb->m_sound_buffer)
- return;
-
- if (sb->m_mixer_type != SOUND_MIXER_SOFTWARE_16) {
- if (sb->m_mixer_type == SOUND_MIXER_CREATIVE_EAX) {
- EAX_FreeSource(sb->m_lpksps);
- }
-
- if (sb->m_sound_buffer) {
- sb->m_sound_buffer->Release();
- sb->m_sound_buffer = NULL;
- }
- if (sb->m_sound_buffer_3d) {
- sb->m_sound_buffer_3d->Release();
- sb->m_sound_buffer_3d = NULL;
- }
- }
-}
-
-void sb_stop_buffer(sound_buffer_info *sb) {
- if (!ll_sound_ptr->m_in_sound_frame)
- ll_sound_ptr->m_pending_actions = true;
-
- if (sb->m_mixer_type != SOUND_MIXER_SOFTWARE_16) {
- sb->m_sound_buffer->Stop();
- }
-}
-
-bool sb_lock_buffer(sound_buffer_info *sb, uint32_t dwWriteCursor, uint32_t dwWriteBytes, void **lplpvAudioPtr1,
- uint32_t *lpdwAudioBytes1, void **lplpvAudioPtr2, uint32_t *lpdwAudioBytes2) {
- DWORD len1, len2;
-
- if (sb->m_mixer_type != SOUND_MIXER_SOFTWARE_16) {
- TryLockAgainLabel:
- switch (sb->m_sound_buffer->Lock(dwWriteCursor, dwWriteBytes, lplpvAudioPtr1, &len1, lplpvAudioPtr2, &len2, 0)) {
- case DS_OK:
- *lpdwAudioBytes1 = len1;
- *lpdwAudioBytes2 = len2;
- return true;
-
- case DSERR_BUFFERLOST:
- if (sb->m_sound_buffer->Restore() == DS_OK)
- goto TryLockAgainLabel;
- }
-
- return false;
- }
-
- return false;
-}
-
-bool sb_unlock_buffer(sound_buffer_info *sb, void *ptr1, uint32_t len1, void *ptr2, uint32_t len2) {
- if (sb->m_mixer_type != SOUND_MIXER_SOFTWARE_16) {
- sb->m_sound_buffer->Unlock(ptr1, len1, ptr2, len2);
- return true;
- }
-
- return false;
-}
-
-bool sb_load_buffer(sound_buffer_info *sb, void *sample_data, int length) {
- if (!ll_sound_ptr->m_in_sound_frame)
- ll_sound_ptr->m_pending_actions = true;
-
- if (LoadSoundData(sb->m_sound_buffer, (char *)sample_data, length) != DS_OK) {
- Int3();
- sb->m_status = SSF_UNUSED;
- return false;
- }
- return true;
-}
-
-///////////////////////////////////////////////////////////////////////////////
-
-// The actual mixer code that sum's the sounds on each channel and does all the actual
-// mixing and effects (writes data to the locked primary buffer)
-void StreamMixer(char *ptr, int len) {
- int i;
- int16_t *mixer_buffer16 = (int16_t *)ptr;
- int current_slot = 0;
- bool f_loop;
- bool f_mono;
-
- const int buff_len = len / ll_sound_ptr->m_primary_alignment;
-
- // this code will assure that this function will not be called when sound system is in error mode.
- if (ll_sound_ptr->m_lib_error_code != SSL_OK) {
- return;
- }
-
- ASSERT(len <= m_sb_info.BufferSize);
- ASSERT(ptr && len >= 0);
-
- ASSERT((len % ll_sound_ptr->m_primary_alignment) == 0);
-
- // memset((char *)ptr, 0, len);
-
- // This memset is hopefully temporary
- memset(Fast_mixer, 0, Fast_mixer_len * sizeof(int));
- int *fast_mix_ptr = Fast_mixer;
-
- // Mix the sound slots
- while (current_slot < ll_sound_ptr->m_sound_mixer.m_max_sounds_played) {
- sound_buffer_info *cur_buf = &ll_sound_ptr->m_sound_mixer.m_sound_cache[current_slot];
- int num_samples = buff_len;
- // mixer_buffer16 = (int16_t *) ptr;
- fast_mix_ptr = Fast_mixer;
- f_mono = true;
-
- // Find slots with sounds in them
- if ((cur_buf->m_status != SSF_UNUSED) && !(cur_buf->m_status & SSF_PAUSED)) {
- float l_volume = cur_buf->play_info->left_volume;
- float r_volume = cur_buf->play_info->right_volume;
- int skip_interval = cur_buf->play_info->sample_skip_interval;
- int samples_played = cur_buf->play_info->m_samples_played;
- int16_t *sample_16bit;
- uint8_t *sample_8bit;
- int np_sample_length;
- int sample_length;
- int loop_start;
- int loop_end;
-
- if (cur_buf->m_status & SSF_PLAY_STREAMING) {
- switch (cur_buf->play_info->m_stream_format) {
- case SIF_STREAMING_16_M:
- sample_16bit = (int16_t *)cur_buf->play_info->m_stream_data;
- sample_8bit = NULL;
- np_sample_length = sample_length = cur_buf->play_info->m_stream_size / 2;
- break;
- case SIF_STREAMING_8_M:
- sample_16bit = NULL;
- sample_8bit = (uint8_t *)cur_buf->play_info->m_stream_data;
- np_sample_length = sample_length = cur_buf->play_info->m_stream_size;
- break;
- case SIF_STREAMING_16_S:
- sample_16bit = (int16_t *)cur_buf->play_info->m_stream_data;
- sample_8bit = NULL;
- np_sample_length = sample_length = cur_buf->play_info->m_stream_size / 4;
- f_mono = false;
- break;
- case SIF_STREAMING_8_S:
- sample_16bit = NULL;
- sample_8bit = (uint8_t *)cur_buf->play_info->m_stream_data;
- np_sample_length = sample_length = cur_buf->play_info->m_stream_size / 2;
- f_mono = false;
- break;
- default:
- Int3();
- break;
- }
- loop_start = 0;
- loop_end = np_sample_length - 1;
- } else {
- int sound_index = cur_buf->m_sound_index;
- int sample_index = Sounds[sound_index].sample_index;
- sound_file_info *snd_file = &SoundFiles[sample_index];
- sample_16bit = snd_file->sample_16bit;
- sample_8bit = snd_file->sample_8bit;
- np_sample_length = snd_file->np_sample_length;
- sample_length = snd_file->sample_length;
- loop_start = Sounds[sound_index].loop_start;
- loop_end = Sounds[sound_index].loop_end;
- if (!sample_16bit && !sample_8bit) {
- mprintf(0, "sound file %s didn't have data for samples.\n", snd_file->name);
- }
- }
-
- // cleanly continue if this happens, and inform a logfile, if it does. error handling
- // ASSERT(sample_16bit || sample_8bit);
- if (!sample_16bit && !sample_8bit) {
- sound_file_info *snd_file = &SoundFiles[Sounds[cur_buf->m_sound_index].sample_index];
- ll_sound_ptr->SetError(SSL_ERROR_SAMPLE_NODATA);
- ll_sound_ptr->ErrorText("ASSERT(sample_16bit || sample_8bit)\nNo data found for sound file: %s",
- snd_file->name);
- cur_buf->m_status = SSF_UNUSED;
- goto error_bail;
- }
-
- ASSERT(np_sample_length <= sample_length);
- ASSERT(samples_played >= 0 || samples_played <= sample_length);
-
- int num_write;
-
- error_trap:
-
- // We have not looped -- yet
- f_loop = false;
-
- // Verify the volume levels are o.k.
- ASSERT(l_volume >= 0.0 && l_volume <= 1.0);
- ASSERT(r_volume >= 0.0 && r_volume <= 1.0);
-
- looping: // Will go to this label to do the next iteration of a looping sample
-
- if (cur_buf->m_status &
- (SSF_PLAY_LOOPING | SSF_PLAY_STREAMING)) // Looping sample's process is broken up into linear pieces
- {
- if (f_loop) {
- ASSERT(num_write >= 0);
-
- num_samples -= num_write;
- ASSERT(num_samples > 0);
-
- fast_mix_ptr += (num_write * 2);
- // mixer_buffer16 += num_write << 1; // update to the new start position
- // (2x because of left and right channels)
-
- samples_played = loop_start;
- }
-
- if (cur_buf->m_status & SSF_PLAY_LOOPING) // Looping sample's process is broken up into linear pieces
- {
- ASSERT(loop_end < sample_length);
- if (loop_end < samples_played) {
- // CHRISHACK -- Fuck milestone. Fix later. Code below is a major hack (but it works). :)
-
- if (loop_end != loop_start) {
- while (loop_end < samples_played) {
- // Int3();
- samples_played -= loop_end - loop_start;
- }
-
- ASSERT(samples_played >= 0);
- } else {
- cur_buf->m_status &= ~SSF_PLAY_LOOPING;
- cur_buf->m_status |= SSF_PLAY_NORMAL;
- }
-
- goto error_trap;
- }
- }
- // The number of samples to write to the primary buffer
- num_write = ((num_samples) < (loop_end - samples_played + 1)) ? (num_samples) : (loop_end - samples_played + 1);
- ASSERT(num_write >= 0 && num_write <= num_samples);
-
- if (num_write < num_samples)
- f_loop = true;
- else
- f_loop = false;
-
- if (num_write <= 0) {
- num_write = 0;
- mprintf(0, "d");
- goto stream_done;
- }
- } else {
- // The number of samples to write to the primary buffer
- num_write =
- ((num_samples) < (np_sample_length - samples_played)) ? (num_samples) : (np_sample_length - samples_played);
- if (!(num_write > 0 && num_write <= num_samples)) {
- num_write = 0;
- goto done;
- }
-
- // Optimization for silent sounds
- if (l_volume <= MIN_SOUND_MIX_VOLUME && r_volume <= MIN_SOUND_MIX_VOLUME) {
- cur_buf->play_info->m_samples_played += num_write;
- goto done;
- }
- }
-
- if (!(num_write > 0 && num_write <= num_samples)) // this was an assert
- {
- num_write = 0;
- mprintf(0, "D");
- goto done;
- }
-
- // Mix at 16 bits per sample
- if (skip_interval == 0) {
- int16_t *cur_sample_16bit = sample_16bit;
- uint8_t *cur_sample_8bit = sample_8bit;
-
- if (f_mono) {
- if (sample_8bit) {
- cur_sample_8bit += samples_played;
- opti_8m_mix(cur_sample_8bit, num_write, samples_played, fast_mix_ptr, l_volume, r_volume);
- } else {
- cur_sample_16bit += samples_played;
- opti_16m_mix(cur_sample_16bit, num_write, samples_played, fast_mix_ptr, l_volume, r_volume);
- }
- } else {
- if (sample_8bit) {
- cur_sample_8bit += (samples_played << 1);
- opti_8s_mix(cur_sample_8bit, num_write, samples_played, fast_mix_ptr, l_volume, r_volume);
- } else {
- cur_sample_16bit += (samples_played << 1);
- opti_16s_mix(cur_sample_16bit, num_write, samples_played, fast_mix_ptr, l_volume, r_volume);
- }
- }
- } else
- // Account for lower-sampling rate
- {
- if (skip_interval == 1) {
- const int fix_rvol = r_volume * VOLUME_FIX_BITS;
- const int fix_lvol = l_volume * VOLUME_FIX_BITS;
-
- for (i = 0; i < (num_write << 1); i += 2) {
- int sample;
-
- if (sample_16bit) {
- if (samples_played & 0x0001) {
- sample = ((int)sample_16bit[samples_played ^ 0x0001] + (int)sample_16bit[samples_played + 1]) >> 1;
- } else
- sample = sample_16bit[samples_played];
- } else {
- if (samples_played & 0x0001) {
- // Notes: (<<7) is from a (<<8) - (>>1)
- // Notes: (-256) is from (-128) + (-128)
- sample = ((int)sample_8bit[samples_played ^ 0x0001] + (int)sample_8bit[samples_played + 1] - 256) << 7;
- } else
- sample = (((int)sample_8bit[samples_played]) - (int)128) << 8;
- }
-
- samples_played++;
-
- ASSERT(i >= 0 && (i + 1 < num_samples * 2));
-
- int l_sample = fast_mix_ptr[i] + (sample * fix_lvol);
- int r_sample = fast_mix_ptr[i + 1] + (sample * fix_rvol);
-
- fast_mix_ptr[i] = l_sample;
- fast_mix_ptr[i + 1] = r_sample;
- }
- } else {
- const int fix_rvol = r_volume * VOLUME_FIX_BITS;
- const int fix_lvol = l_volume * VOLUME_FIX_BITS;
- for (i = 0; i < (num_write << 1); i += 2) {
- int sample;
- const int mod_pos = samples_played % 4;
-
- if (sample_16bit) {
- switch (mod_pos) {
- case 0:
- sample = sample_16bit[samples_played];
- break;
- case 1:
- sample = (sample_16bit[samples_played - 1] * 3 + sample_16bit[samples_played + 3]) >> 2;
- break;
- case 2:
- sample = (sample_16bit[samples_played - 2] + sample_16bit[samples_played + 2]) >> 1;
- break;
- case 3:
- sample = (sample_16bit[samples_played - 3] + sample_16bit[samples_played + 1] * 3) >> 2;
- break;
- }
- } else {
- switch (mod_pos) {
- case 0:
- sample = ((((int)sample_8bit[samples_played]) - 128) << 8);
- break;
- case 1:
- sample = (((((int)sample_8bit[samples_played - 1]) - 128) << 8) * 3 +
- ((((int)sample_8bit[samples_played + 3]) - 128) << 8)) >>
- 2;
- break;
- case 2:
- sample = (((((int)sample_8bit[samples_played - 2]) - 128) << 8) +
- ((((int)sample_8bit[samples_played + 2]) - 128) << 8)) >>
- 1;
- break;
- case 3:
- sample = (((((int)sample_8bit[samples_played - 3]) - 128) << 8) +
- ((((int)sample_8bit[samples_played + 1]) - 128) << 8) * 3) >>
- 2;
- break;
- }
- }
-
- samples_played++;
-
- ASSERT(i >= 0 && (i + 1 < num_samples * 2));
-
- int l_sample = fast_mix_ptr[i] + (sample * fix_lvol);
- int r_sample = fast_mix_ptr[i + 1] + (sample * fix_rvol);
-
- fast_mix_ptr[i] = l_sample;
- fast_mix_ptr[i + 1] = r_sample;
- }
- }
- }
-
- stream_done:
-
- cur_buf->play_info->m_samples_played = samples_played;
-
- if (cur_buf->m_status & SSF_PLAY_STREAMING) {
- if (f_loop) {
- if (cur_buf->play_info->m_stream_cback && cur_buf->play_info->m_stream_data) {
- cur_buf->play_info->m_stream_data = (*cur_buf->play_info->m_stream_cback)(
- cur_buf->play_info->user_data, cur_buf->play_info->m_stream_handle, &cur_buf->play_info->m_stream_size);
-// cur_buf->s->current_position = (char*)cur_buf->play_info->m_stream_data;
-// mprintf(0, "%x %d\n", cur_buf->play_info->m_stream_data, cur_buf->play_info->m_stream_size));
- ASSERT(!(cur_buf->play_info->m_stream_data && cur_buf->play_info->m_stream_size <= 0));
-/*
- mprintf(0, "Data %X, length %d\n",
- cur_buf->play_info->m_stream_data,
- cur_buf->play_info->m_stream_size);
-*/
-
- if (cur_buf->play_info->m_stream_data) {
- switch (cur_buf->play_info->m_stream_format) {
- case SIF_STREAMING_16_M:
- sample_16bit = (int16_t *)cur_buf->play_info->m_stream_data;
- loop_end = sample_length = np_sample_length = cur_buf->play_info->m_stream_size / 2;
- break;
- case SIF_STREAMING_8_M:
- sample_8bit = (uint8_t *)cur_buf->play_info->m_stream_data;
- loop_end = sample_length = np_sample_length = cur_buf->play_info->m_stream_size;
- break;
- case SIF_STREAMING_16_S:
- sample_16bit = (int16_t *)cur_buf->play_info->m_stream_data;
- loop_end = sample_length = np_sample_length = cur_buf->play_info->m_stream_size / 4;
- break;
- case SIF_STREAMING_8_S:
- sample_8bit = (uint8_t *)cur_buf->play_info->m_stream_data;
- loop_end = sample_length = np_sample_length = cur_buf->play_info->m_stream_size / 2;
- break;
- default:
- Int3();
- break;
- }
- loop_end -= 1;
- } else {
- mprintf(0, "SE: Data is NULL\n");
- cur_buf->m_status &= ~SSF_PLAY_STREAMING;
- f_loop = false;
- }
- } else {
- mprintf(0, "SE: Callback/data is NULL\n");
- cur_buf->m_status &= ~SSF_PLAY_STREAMING;
- f_loop = false;
- }
- }
- }
-
- if (f_loop)
- goto looping;
-
- done:
-
- if (cur_buf->play_info->m_samples_played >= (np_sample_length) &&
- !(cur_buf->m_status & (SSF_PLAY_LOOPING | SSF_PLAY_STREAMING))) {
- ll_sound_ptr->StopSound(cur_buf->m_unique_id);
- }
- }
-
- error_bail:
- current_slot++;
- }
-
- for (int a = 0; a < (buff_len * 2); a++) {
- Fast_mixer[a] = Fast_mixer[a] / VOLUME_FIX_BITS;
-
- if (Fast_mixer[a] > 32767)
- Fast_mixer[a] = 32767;
- if (Fast_mixer[a] < -32767)
- Fast_mixer[a] = -32767;
-
- mixer_buffer16[a] = Fast_mixer[a];
-
- Fast_mixer[a + 1] = Fast_mixer[a + 1] / VOLUME_FIX_BITS;
-
- if (Fast_mixer[a + 1] > 32767)
- Fast_mixer[a + 1] = 32767;
- if (Fast_mixer[a + 1] < -32767)
- Fast_mixer[a + 1] = -32767;
-
- mixer_buffer16[a + 1] = Fast_mixer[a + 1];
-
- a++;
- }
- // mprintf(0," -%d- ",a);
-}
-
-// Locks the primary buffer and fills in the new data
-void StreamFill(int start_byte, int num_bytes) {
- char *ptr1;
- char *ptr2;
- int len1, len2;
-
- if ((num_bytes % ll_sound_ptr->m_primary_alignment) != 0) {
- ll_sound_ptr->SetError(SSL_ERROR_STREAMMIXER);
- ll_sound_ptr->ErrorText("ASSERT((len % ll_sound_ptr->m_primary_alignment) == 0)\nLen:%d PrA:%d", num_bytes,
- ll_sound_ptr->m_primary_alignment);
- return;
- }
- ASSERT((num_bytes % ll_sound_ptr->m_primary_alignment) == 0);
- ASSERT((start_byte % ll_sound_ptr->m_primary_alignment) == 0);
-
- start_byte = (start_byte % m_sb_info.BufferSize);
-
-TryLockAgainLabel:
-
- switch (m_sb_info.m_lp_looping_buffer->Lock(start_byte, num_bytes, (void **)&ptr1, (DWORD *)&len1, (void **)&ptr2,
- (DWORD *)&len2, 0)) {
- ASSERT((len1 % ll_sound_ptr->m_primary_alignment) == 0);
- ASSERT((len2 % ll_sound_ptr->m_primary_alignment) == 0);
-
- // The pointers are to the lock areas of the primary buffer. There are two because locked region
- // might be a discontinuous chunk (wrapped around the end of the buffer i.e. 'LLLLBBBBBBLLLLL'
- // L is for Locked and B is unlocked buffer.
- case DS_OK:
- StreamMixer(ptr1, len1);
- if (ptr2)
- StreamMixer(ptr2, len2);
-
- m_sb_info.m_lp_looping_buffer->Unlock(ptr1, len1, ptr2, len2);
-
- m_sb_info.NextWritePos = (start_byte + num_bytes) % m_sb_info.BufferSize;
- break;
-
- case DSERR_BUFFERLOST:
- if (m_sb_info.m_lp_primary_buffer->Restore() == DS_OK && m_sb_info.m_lp_looping_buffer->Restore() == DS_OK)
- goto TryLockAgainLabel;
- break;
- }
-}
-
-// A peroidic mixer that uses the primary buffer as a stream buffer
-void __cdecl StreamTimer(void *user_ptr) {
- int playp, writep;
- int try_count = 0;
- DSSTREAM *sb_info = (DSSTREAM *)user_ptr;
- DWORD result;
-
- m_sb_info.m_lp_primary_buffer->Restore();
- m_sb_info.m_lp_primary_buffer->Play(0, 0, DSBPLAY_LOOPING);
-
- while (!sb_info->thread_request_kill) {
- try_count = 0;
-
- TryAgain:
- try_count++;
-
- // hresult = m_sb_info.m_lp_primary_buffer->GetStatus(&stat_result);
- //
- // if(hresult != DS_OK || !(stat_result & DSBSTATUS_LOOPING))
- // {
- // m_sb_info.m_lp_primary_buffer->Restore();
- m_sb_info.m_lp_primary_buffer->Restore();
- m_sb_info.m_lp_primary_buffer->Play(0, 0, DSBPLAY_LOOPING);
- // }
-
- result = sb_info->m_lp_looping_buffer->GetCurrentPosition((DWORD *)&playp, (DWORD *)&writep);
-
- // mprintf(0, "(%d,%d)\n", playp, writep);
-
- // If primary buffer was stopped from playing
- if (writep == playp) {
- sb_info->NextWritePos = -1;
-
- if ((try_count == 1) &&
- (m_sb_info.m_lp_primary_buffer->Restore() == DS_OK && m_sb_info.m_lp_looping_buffer->Restore() == DS_OK)) {
- if ((try_count == 1) && (m_sb_info.m_lp_looping_buffer->Play(0, 0, DSBPLAY_LOOPING) == DS_OK)) {
- goto TryAgain;
- }
- }
-
- goto done;
- }
-
- // Insert mixer code
- {
- int num_write_bytes;
-
- if (sb_info->NextWritePos < 0)
- sb_info->NextWritePos = writep;
-
- // Debugging code (not sure what would happen if we hit these without an Int3()) -- Skipping noise
- if (sb_info->LastPlayPos < sb_info->NextWritePos) {
-
- if (playp >= sb_info->NextWritePos || playp < sb_info->LastPlayPos) {
- if (!sb_info->m_f_secondary_looping)
- goto done;
- playp = sb_info->NextWritePos - 4;
- num_write_bytes = 4 * (int)(22050 * DSPB_TICK_INTERVAL);
- } else {
- // Determine how much we can write out.
- num_write_bytes = (sb_info->MaxWriteBytes + playp) - sb_info->NextWritePos;
- }
- } else {
- if (playp >= sb_info->NextWritePos && playp < sb_info->LastPlayPos) {
- if (!sb_info->m_f_secondary_looping)
- goto done;
-
- playp = sb_info->NextWritePos - 4;
- num_write_bytes = 4 * (int)(22050 * DSPB_TICK_INTERVAL);
- } else {
- // Determine how much we can write out.
- if (playp < sb_info->NextWritePos)
- num_write_bytes = (sb_info->MaxWriteBytes + playp) - sb_info->NextWritePos;
- else
- num_write_bytes = sb_info->MaxWriteBytes - (sb_info->NextWritePos + (sb_info->BufferSize - playp));
- }
- }
-
- num_write_bytes &= (0xFFFFFFFF & (~(ll_sound_ptr->m_primary_alignment)));
-
- if (num_write_bytes > 0) {
- // ASSERT(num_write_bytes < sb_info->BufferSize);
- if (num_write_bytes >= sb_info->BufferSize) {
- num_write_bytes = sb_info->BufferSize / 2;
- }
-
- StreamFill(sb_info->NextWritePos, num_write_bytes);
- }
- }
-
- sb_info->LastPlayPos = playp;
-
- done:
- Sleep(DSPB_TICK_MILLISECONDS);
- }
-
- sb_info->thread_alive = false;
-}
-
-// Begins the whole streaming process
-bool win_llsSystem::StartStreaming(void) {
- DSBCAPS dsbcaps;
-
- dsbcaps.dwSize = sizeof(DSBCAPS);
- m_sb_info.m_lp_looping_buffer->GetCaps(&dsbcaps);
-
- m_sb_info.m_f_secondary_looping = (m_sb_info.m_lp_looping_buffer != m_sb_info.m_lp_primary_buffer);
-
- m_sb_info.BufferSize = dsbcaps.dwBufferBytes;
-
- m_sb_info.MaxWriteSamples = m_primary_frequency * MAX_WRITE_AHEAD;
- m_sb_info.MaxWriteBytes = m_sb_info.MaxWriteSamples * m_primary_alignment;
-
- m_sb_info.NextWritePos = -1;
- m_sb_info.LastPlayPos = 0;
-
- StreamFill(0, dsbcaps.dwBufferBytes);
-
- m_sb_info.thread_request_kill = false;
- m_sb_info.thread_alive = true;
-
- // Start mixing thread.
- m_sb_info.thread_handle = _beginthread(StreamTimer, 16384, (void *)&m_sb_info);
- if (m_sb_info.thread_handle == -1) {
- m_sb_info.thread_alive = false;
- mprintf(0, "Thread failed\n");
- Int3();
- return false;
- }
-
- if (m_sb_info.m_f_secondary_looping) {
- if (!SetThreadPriority((HANDLE)m_sb_info.thread_handle, THREAD_PRIORITY_HIGHEST))
- Int3();
- } else {
- if (!SetThreadPriority((HANDLE)m_sb_info.thread_handle, THREAD_PRIORITY_TIME_CRITICAL))
- Int3();
- }
-
- return true;
-}
-
-// Creates a 2d, 3d, or Primary direct sound buffer
-HRESULT win_llsSystem::CreateDSBuffer(int buffer_type, LPDIRECTSOUNDBUFFER *lp_lp_dsb, LPDIRECTSOUND3DBUFFER *lp_lp_dsb_3d,
- DWORD sound_bytes, DWORD frequency, bool f_is_stereo, bool f_is_16_bit) {
- DSBUFFERDESC dsbd;
- tWAVEFORMATEX fmt;
- HRESULT result = DS_OK;
-
- ASSERT(m_lp_ds != NULL && sound_bytes >= 0);
- ASSERT(frequency == 44100 || frequency == 22050 || frequency == 11025);
- if (!m_f_sound_lib_init)
- return 0;
-
- if (lp_lp_dsb) {
- *lp_lp_dsb = NULL;
- }
- if (lp_lp_dsb_3d) {
- *lp_lp_dsb_3d = NULL;
- }
-
- // Setup the wave format
- fmt.nChannels = (f_is_stereo) ? 2 : 1;
- fmt.wBitsPerSample = (f_is_16_bit) ? 16 : 8;
- fmt.nSamplesPerSec = ((DWORD)frequency);
- fmt.nBlockAlign = fmt.nChannels * (fmt.wBitsPerSample >> 3);
- fmt.nAvgBytesPerSec = ((DWORD)fmt.nSamplesPerSec) * ((DWORD)fmt.nBlockAlign);
- fmt.wFormatTag = WAVE_FORMAT_PCM;
-
- // Setup the secondary direct sound buffer
- memset(&dsbd, 0, sizeof(dsbd));
- dsbd.lpwfxFormat = (LPWAVEFORMATEX)&fmt;
- dsbd.dwSize = sizeof(DSBUFFERDESC);
- dsbd.dwBufferBytes = sound_bytes;
-
- if (m_mixer_type == SOUND_MIXER_SOFTWARE_16) {
- dsbd.dwFlags = DSBCAPS_GETCURRENTPOSITION2;
-
- ASSERT(buffer_type == SBT_PRIMARY);
-
- m_primary_frequency = m_current_frequency = frequency;
- m_primary_bit_depth = fmt.wBitsPerSample;
- m_primary_alignment = fmt.nBlockAlign;
-
- dsbd.lpwfxFormat = NULL;
- dsbd.dwBufferBytes = 0;
- dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_GETCURRENTPOSITION2;
- } else if (m_mixer_type == SOUND_MIXER_DS_16 || m_mixer_type == SOUND_MIXER_DS_8) {
- // There are three buffer types that we should consider.
- switch (buffer_type) {
- case SBT_2D:
- dsbd.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN;
- break;
- case SBT_PRIMARY:
- dsbd.lpwfxFormat = NULL;
- dsbd.dwBufferBytes = 0;
- dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;
- break;
- default:
- ASSERT(0); // Invalid type of buffer
- }
- } else if (IS_3D_MIXER(m_mixer_type)) {
- // There are three buffer types that we should consider.
- switch (buffer_type) {
- case SBT_2D:
- dsbd.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN;
- break;
- case SBT_3D:
- dsbd.dwFlags = DSBCAPS_GETCURRENTPOSITION2 | DSBCAPS_CTRL3D | DSBCAPS_CTRLVOLUME;
- break;
- case SBT_PRIMARY:
- dsbd.lpwfxFormat = NULL;
- dsbd.dwBufferBytes = 0;
- dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER | DSBCAPS_CTRL3D | DSBCAPS_CTRLVOLUME;
- break;
- default:
- ASSERT(0); // Invalid type of buffer
- }
- } else {
- mprintf(0, "DS3DLIB: Unsupported function for mixer specfied in CreateDSBuffer (%d,%d)\n", m_mixer_type, buffer_type);
- Int3(); // Get Samir!!!
- return DSERR_UNSUPPORTED;
- }
-
- // Create the buffer
- result = m_lp_ds->CreateSoundBuffer(&dsbd, lp_lp_dsb, 0);
- /// ASSERT(result == DS_OK);
-
- if (result == DS_OK && buffer_type == SBT_PRIMARY) {
- // Creative EAX Init
- if (m_mixer_type == SOUND_MIXER_CREATIVE_EAX) {
- if (!EAX_SetPrimaryBuffer()) {
- mprintf(0, "CreateDSBuffer: EAX Init failed.\n");
- result = DSERR_UNSUPPORTED;
- goto ds_error;
- }
- }
-
- // Succeeded. Set primary buffer to desired format.
- result = (*lp_lp_dsb)->SetFormat(&fmt);
- }
-
- if (result != DS_OK) {
- mprintf(0, "DS3DLIB: Failed to init sound buffer of type %d for mixer %d.\n", buffer_type, m_mixer_type);
- goto ds_error;
- }
-
- // call get format to make sure we're okay.
- if (buffer_type == SBT_PRIMARY) {
- }
-
- // do 3d sound support stuff.
- if (IS_3D_MIXER(m_mixer_type)) {
- // a 3d buffer needs a 3d interface pointer
- if (buffer_type == SBT_3D) {
- ASSERT(lp_lp_dsb_3d != NULL);
- result = (*lp_lp_dsb)->QueryInterface(IID_IDirectSound3DBuffer, (void **)lp_lp_dsb_3d);
- if (result != DS_OK) {
- goto ds_error;
- }
-
- // ASSERT(result == DS_OK);
- } else if (buffer_type == SBT_PRIMARY) {
- if ((result = (*lp_lp_dsb)->QueryInterface(IID_IDirectSound3DListener, (void **)&m_lp_listener)) == S_OK) {
- m_lp_listener->SetRolloffFactor(ENV3DVAL_ROLLOFF_DEFAULT, DS3D_IMMEDIATE);
- }
- }
- }
-
-ds_error:
- if (result != DS_OK) {
- mprintf(0, "DS3DLIB:result=%x\n", result);
- if (lp_lp_dsb_3d && (*lp_lp_dsb_3d)) {
- (*lp_lp_dsb_3d)->Release();
- *lp_lp_dsb_3d = NULL;
- }
-
- if (lp_lp_dsb && (*lp_lp_dsb)) {
- (*lp_lp_dsb)->Release();
- *lp_lp_dsb = NULL;
- }
- }
-
- return (long)result;
-}
-
-// Internal function to enumerate sound devices
-BOOL CALLBACK LLEnumCallback(LPGUID lp_guid, LPCSTR lpstr_description, LPCSTR lpstr_module, LPVOID lp_Context) {
- GUID FAR *lp_ret_guid = (GUID FAR *)lp_Context;
-
- if (m_sound_device_name[0]) {
- if (strcmp(lpstr_description, m_sound_device_name) == 0) {
- mprintf(0, "Using sound card:%s-%s\n", lpstr_description, lpstr_module);
- if (lp_guid) {
- memmove(lp_ret_guid, lp_guid, sizeof(GUID));
- }
- return FALSE;
- }
- }
-
- return TRUE;
-}
-
-void win_llsSystem::SetSoundCard(const char *name) {
- if (name) {
- strcpy(m_sound_device_name, name);
- } else {
- m_sound_device_name[0] = 0;
- }
-}
-
-// Initializes the sound library
-int win_llsSystem::InitSoundLib(char mixer_type, oeApplication *sos, uint8_t MaxSoundsPlayed) // add playlist info
-{
- GUID card_guid, zero_card_guid;
- GUID *pguid = NULL;
- DSCAPS dscaps;
- HRESULT hresult;
- bool f16bit;
- bool retval = true;
-
- // reset error system.
- SetError(SSL_OK);
- SoundApp = (oeWin32Application *)sos;
-
- if (sos) {
- oeWin32Application *obj = (oeWin32Application *)sos;
-
- // If the the library if already init'ed, then return o.k.
- if (m_f_sound_lib_init)
- return 1;
-
- GameWindowHandle = (void *)obj->m_hWnd;
- } else {
- ASSERT(GameWindowHandle);
- }
-
- ll_sound_ptr = this;
- m_timer_last_frametime = -1;
- m_cache_stress_timer = 0.0f;
- m_in_sound_frame = false;
- m_pending_actions = false;
-
- //////////////////////////////////////////////////////////////////////////////
- // chrishack -- Need to enumerate sound devices for now
- // Attempt to enumerate the sound device
- // if(DirectSoundEnumerate(&LLEnumCallback, NULL) != DS_OK) return 0;
-
- // Setup the game handle
- m_hwnd_main = GameWindowHandle;
-
- // Check for invalid values and NULL pointers
- ASSERT(m_hwnd_main != NULL);
- ASSERT(Sounds != NULL);
- ASSERT(SoundFiles != NULL);
- ASSERT(MaxSoundsPlayed > 0);
-
- memset(&m_sb_info, 0, sizeof(DSSTREAM));
-
- // Currently restart total sounds played count (for unique ids and stats)
- m_total_sounds_played = 0;
-
- // Setup the sound mixer object
- m_sound_mixer.m_cur_sounds_played = 0;
- m_sound_mixer.m_max_sounds_played = MaxSoundsPlayed;
- m_sound_mixer.m_sound_cache = new sound_buffer_info[MaxSoundsPlayed];
- m_mixer_type = SOUND_MIXER_NONE;
-
- if (m_sound_mixer.m_sound_cache == NULL) {
- Int3();
- goto error_sub;
- }
-
- // Create the Direct Sound Interface
- // determine GUID for sound card which was chosen in the launcher...
- ZeroMemory(&card_guid, sizeof(GUID));
- ZeroMemory(&zero_card_guid, sizeof(GUID));
- hresult = DirectSoundEnumerate(LLEnumCallback, &card_guid);
- if (hresult == DS_OK) {
- if (memcmp(&card_guid, &zero_card_guid, sizeof(GUID)) != 0) {
- pguid = &card_guid;
- }
- }
-
- if (mixer_type != SOUND_MIXER_NONE) {
- if (mixer_type == SOUND_MIXER_CREATIVE_EAX) {
- if (!EAX_Create(pguid, &m_lp_ds)) {
- mprintf(0, "Sound NT: Error EAX\n");
- retval = false;
- goto error_sub;
- }
- } else {
- hresult = DirectSoundCreate(pguid, &m_lp_ds, NULL);
- if (hresult != DS_OK) {
- retval = false;
- goto error_sub;
- }
- }
-
- ASSERT(m_lp_ds != NULL);
-
- // determine if we're using a crappy card
- dscaps.dwSize = sizeof(DSCAPS);
- m_lp_ds->GetCaps(&dscaps);
- if (dscaps.dwFlags & DSCAPS_EMULDRIVER) {
- mixer_type = SOUND_MIXER_DS_8;
- mprintf(0, "SOUND INIT(1): We are in NT or have a crappy sound card\n");
- }
-
- m_sound_mixer.m_loop_method = DSLOOP_STREAM_METHOD;
- }
-
- if (mixer_type != SOUND_MIXER_NONE) {
- m_f_sound_lib_init = 1;
- }
-
-// This section initializes the primary buffer
-// software mixer try.
-retry_mixer_init:
- if (mixer_type == SOUND_MIXER_SOFTWARE_16) {
- // test different conditions to see if we really can play sound in software
- hresult = m_lp_ds->SetCooperativeLevel((HWND)m_hwnd_main, DSSCL_WRITEPRIMARY);
- if (hresult != DS_OK) {
- mprintf(0, "SOUND INIT(2): SCL: WritePrimary failed. Attempting DS 8 init.\n");
- mixer_type = SOUND_MIXER_DS_8;
- goto retry_mixer_init;
- }
-
- // Creates a primary buffer and makes sure we are at the specified frequency, bit depth, and that we
- // can to 3d stuff too :)
- m_mixer_type = SOUND_MIXER_SOFTWARE_16;
- f16bit = true;
- hresult = CreateDSBuffer(SBT_PRIMARY, &m_sb_info.m_lp_primary_buffer, NULL, 0,
- 22050, // frequency
- true, // stereo
- f16bit); // 16-bit
- if (hresult != DS_OK) {
- if (m_sb_info.m_lp_primary_buffer) {
- m_sb_info.m_lp_primary_buffer->Release();
- m_sb_info.m_lp_primary_buffer = NULL;
- }
- mprintf(0, "SOUND INIT(3): Cannot create primary buffer.\n");
- mixer_type = SOUND_MIXER_DS_8;
- goto retry_mixer_init;
- } else {
- // Determine if we are running NT or have a shitty Win95 sound card
- DSBCAPS dsbcaps;
-
- ASSERT(m_sb_info.m_lp_primary_buffer);
-
- dsbcaps.dwSize = sizeof(DSBCAPS);
- m_sb_info.m_lp_primary_buffer->GetCaps(&dsbcaps);
-
- // Let's allocate our array of ints for our optimized software mixer!
- if (!Fast_mixer) {
- Fast_mixer = (int *)mem_malloc(dsbcaps.dwBufferBytes * sizeof(int));
- Fast_mixer_len = dsbcaps.dwBufferBytes;
- mprintf(0, "Using %d ints for fast software mixer\n", dsbcaps.dwBufferBytes);
- }
-
- // Is you want to see the caps, here is where -- mprintf all you want
- if (!(dsbcaps.dwFlags & DSBCAPS_LOCHARDWARE)) {
- mprintf(0, "SOUND INIT(4): Primary is not in hardware\n");
- m_sb_info.m_lp_primary_buffer->Release();
- m_sb_info.m_lp_primary_buffer = NULL;
- mixer_type = SOUND_MIXER_DS_8;
- goto retry_mixer_init;
- }
- }
-
- // looping buffer is the same as the primary buffer for software mixers.
- m_sb_info.m_lp_looping_buffer = m_sb_info.m_lp_primary_buffer;
-
- // Start the primary and have it always play.
- m_f_sound_lib_init = StartStreaming();
- if (!m_f_sound_lib_init) {
- mprintf(0, "SOUND INIT(5): Something went wrong in StartStreaming\n");
- m_sb_info.m_lp_primary_buffer->Release();
- m_sb_info.m_lp_primary_buffer = NULL;
- mixer_type = SOUND_MIXER_DS_8;
- goto retry_mixer_init;
- }
-
- } else if (mixer_type == SOUND_MIXER_NONE) {
- m_mixer_type = mixer_type;
- m_f_sound_lib_init = 0;
- } else {
- // This is for DirectSound Internal Mixers. We let DirectSound do its magic.
- m_mixer_type = mixer_type;
- hresult = m_lp_ds->SetCooperativeLevel((HWND)m_hwnd_main, DSSCL_PRIORITY);
- if (hresult != DS_OK) {
- mprintf(0, "Sound NT: Error 1\n");
- retval = false;
- goto error_sub;
- }
-
- // start primary buffer
- f16bit = (mixer_type == SOUND_MIXER_DS_16 || mixer_type == SOUND_MIXER_DS3D_16 ||
- mixer_type == SOUND_MIXER_CREATIVE_EAX);
- hresult = CreateDSBuffer(SBT_PRIMARY, &m_sb_info.m_lp_primary_buffer, NULL, 0,
- 22050, // frequency
- true, // stereo
- f16bit); // 8 or 16 bit
- if (hresult != DS_OK) {
- mprintf(0, "Sound NT: Error 2\n");
- if (m_sb_info.m_lp_primary_buffer) {
- m_sb_info.m_lp_primary_buffer->Release();
- m_sb_info.m_lp_primary_buffer = NULL;
- }
- retval = false;
- goto error_sub;
- }
-
- m_sb_info.m_lp_primary_buffer->Play(0, 0, DSBPLAY_LOOPING);
- }
-
- // buffered method doesn't use threads at all.
- if (m_mixer_type != SOUND_MIXER_SOFTWARE_16 && m_mixer_type != SOUND_MIXER_NONE &&
- m_sound_mixer.m_loop_method != DSLOOP_BUFFER_METHOD) {
- // start looping thread, failure results in a 'clean exit'
- if (!sb_loop_thread_init(this)) {
- retval = false;
- if (m_sb_info.m_lp_primary_buffer) {
- m_sb_info.m_lp_primary_buffer->Release();
- m_sb_info.m_lp_primary_buffer = NULL;
- }
- goto error_sub;
- }
- }
-
- mprintf(0, "Sound mixer: ");
- retval = true;
-
- switch (m_mixer_type) {
- case SOUND_MIXER_SOFTWARE_16:
- mprintf(0, "Software 16\n");
- break;
- case SOUND_MIXER_DS_8:
- mprintf(0, "DS 8\n");
- break;
- case SOUND_MIXER_DS_16:
- mprintf(0, "DS 16\n");
- break;
- case SOUND_MIXER_DS3D_16:
- mprintf(0, "DS3D 16\n");
- break;
- case SOUND_MIXER_CREATIVE_EAX:
- mprintf(0, "Creative EAX\n");
- break;
- case SOUND_MIXER_NONE:
- mprintf(0, "None\n");
- break;
- default:
- mprintf(0, "LLSound ERROR: Unsupported mixer");
- Int3();
- retval = false;
- break;
- }
-
- // set 3d environment settings
- t3dEnvironmentToggles env_toggles;
- t3dEnvironmentValues env_values;
-
- memset(&Env3dValues, 0, sizeof(Env3dValues));
- memset(&Env3dToggles, 0, sizeof(Env3dToggles));
-
- env_toggles.flags = 0; // get supported features
- GetEnvironmentToggles(&env_toggles);
-
- env_values.flags = 0; // set up values and toggles to be set
- env_toggles.flags = env_toggles.supported;
-
- // we may want to check this with configured options later -- samir
- if (CHECK_FLAG(env_toggles.supported, ENV3DVALF_DOPPLER) && ENV3DTOG_DOPPLER) {
- env_values.flags |= ENV3DVALF_DOPPLER;
- env_values.doppler_scalar = ENV3DVAL_DOPPLER_DEFAULT;
- env_toggles.doppler = true;
- }
- if (CHECK_FLAG(env_toggles.supported, ENV3DVALF_GEOMETRY) && ENV3DTOG_GEOMETRY) {
- env_toggles.geometry = true;
- }
- SetEnvironmentToggles(&env_toggles);
- SetEnvironmentValues(&env_values);
-
- /////////////////////////////////////////////////////////////////////////////
- g_emulated_listener = &m_emulated_listener;
-
-error_sub:
- if (retval == false) {
- // Only gets here if there was an error
- if (m_mixer_type == SOUND_MIXER_CREATIVE_EAX) {
- EAX_Destroy();
- } else if (m_lp_ds) {
- m_lp_ds->Release();
- }
- m_lp_ds = NULL;
- mprintf(0, "Sound Warning: Didn't initialize sound library.\n");
- if (m_sound_mixer.m_sound_cache != NULL)
- delete[] m_sound_mixer.m_sound_cache;
- m_f_sound_lib_init = 0;
- m_mixer_type = SOUND_MIXER_NONE;
- }
-
- Global_DS_alloced_sounds = 0;
-
- return (m_f_sound_lib_init);
-}
-
-// Cleans up after the sound library is done being used
-void win_llsSystem::DestroySoundLib(void) {
- bool f_all_done = false;
-
- if (!m_f_sound_lib_init)
- return;
-
- mprintf(0, "Start of sound system close\n");
-
- // kill sound geometry object if any.
- if (m_geometry) {
- m_geometry->Shutdown();
- m_geometry = NULL;
- }
-
- StopAllSounds();
-
- // Wait till they are all done
- mprintf(0, "Waiting for sounds to stop\n");
- if (m_mixer_type != SOUND_MIXER_SOFTWARE_16) {
- while (!f_all_done) {
- f_all_done = true;
- int i;
-
- for (i = 0; i < m_sound_mixer.m_max_sounds_played; i++) {
- sound_buffer_info *sb = &m_sound_mixer.m_sound_cache[i];
- if (sb->s && sb->s->kill_me && !(sb->m_status & (SSF_BUFFERED_LOOP + SSF_BUFFERED_STRM))) {
- cleanup_directsound_looping_sb(&m_sound_mixer.m_sound_cache[i]);
- } else if (sb->m_status & (SSF_PLAY_LOOPING | SSF_PLAY_STREAMING)) {
- // this should block until the sound is truly free, so we don't need to do a 'all done'
- StopSound(m_sound_mixer.m_sound_cache[i].m_unique_id, SKT_HOLD_UNTIL_STOP);
- // f_all_done = false;
- }
- }
- }
-
- // buffered method doesn't use threads at all.
- if (m_sound_mixer.m_loop_method != DSLOOP_BUFFER_METHOD) {
- sb_loop_thread_kill();
- }
- }
- mprintf(0, "All sounds stopped\n");
-
- if (m_mixer_type == SOUND_MIXER_SOFTWARE_16) {
- // Kill thread goes here
- if (m_sb_info.thread_handle) {
- m_sb_info.thread_request_kill = true;
- while (m_sb_info.thread_alive) {
- }
- }
-
- if (m_mixer_type == SOUND_MIXER_SOFTWARE_16) {
- m_sb_info.m_lp_looping_buffer->Stop();
- m_sb_info.m_lp_looping_buffer->Release();
- }
- }
-
- // free audio device;
- if (m_mixer_type == SOUND_MIXER_CREATIVE_EAX) {
- EAX_Destroy();
- } else if (m_lp_ds) {
- m_lp_ds->Release();
- }
-
- m_lp_ds = NULL;
- m_sb_info.m_lp_looping_buffer = NULL;
-
- mprintf(0, "End of sound system close\n");
-
- if (m_sound_mixer.m_sound_cache != NULL)
- delete[] m_sound_mixer.m_sound_cache;
-
- m_f_sound_lib_init = false;
- g_emulated_listener = NULL;
- m_mixer_type = -1;
- ll_sound_ptr = NULL;
- if (Fast_mixer) {
- mem_free(Fast_mixer);
- Fast_mixer = NULL;
- Fast_mixer_len = 0;
- }
-}
-
-// used to clean up direct sound buffer stuff
-void win_llsSystem::cleanup_directsound_looping_sb(sound_buffer_info *sb) {
- if (!sb->s)
- return;
- if (!sb->s->kill_me)
- return;
-
- // should occur when kill_me set, sb_stop_buffer(&ll_sound_ptr->m_sound_mixer.m_sound_cache[i]);
- sb_free_buffer(sb);
-
- sb->m_sound_buffer = NULL;
- sb->s->playing = 0;
-
- void *p = (void *)sb->s;
- sb->s = NULL;
- sb->m_status = SSF_UNUSED;
- mem_free(p);
-}
-
-// cleans up a sound -replaces a lot of repeated code whenever we cleanup sounds.
-void win_llsSystem::update_directsound_sb(sound_buffer_info *sb, bool update_looping) {
- if (m_mixer_type == SOUND_MIXER_SOFTWARE_16 || m_mixer_type == SOUND_MIXER_NONE) {
- return;
- }
-
- // take care of any streamed threaded method looping sounds that are done.
- // orphan streaming structure, clean it up! (sound buffer is NULL yet sb->s is valid
- if (sb->s && (((sb->m_status & (SSF_BUFFERED_LOOP + SSF_BUFFERED_STRM)) && !sb->m_sound_buffer) || sb->s->kill_me)) {
- cleanup_directsound_looping_sb(sb);
- } else if (sb->m_status && !(sb->m_status & SSF_PAUSED)) {
- // non playing sounds should be stopped always
- int status = sb_get_status(sb);
-
- if (update_looping) {
- if (status & SB_STATUS_PLAYING) {
- if ((sb->m_status & (SSF_PLAY_STREAMING + SSF_BUFFERED_STRM)) == (SSF_PLAY_STREAMING + SSF_BUFFERED_STRM)) {
- sb_stream_buffered_update(sb);
- }
- } else {
- if ((sb->m_status & (SSF_PLAY_LOOPING + SSF_BUFFERED_LOOP)) == (SSF_PLAY_LOOPING + SSF_BUFFERED_LOOP)) {
- sb_buffered_loop_step(this, sb);
- status = sb_get_status(sb); // get new status for following checks.
- }
- }
- }
- if (!(status & SB_STATUS_PLAYING)) {
- StopSound(sb->m_unique_id);
- } else if (status & SB_STATUS_INVALID) {
- StopSound(sb->m_unique_id);
- }
- }
-}
-
-// Stops the sound from playing -- f_immediately is used for looping samples -- i.e. so we can
-// play the end of loop snipit
-void win_llsSystem::StopSound(int sound_uid, uint8_t f_immediately) {
- int current_slot;
- sound_buffer_info *sb;
-
- if (!m_f_sound_lib_init)
- return;
-
- if ((current_slot = ValidateUniqueId(sound_uid)) == -1)
- return;
-
- sb = &m_sound_mixer.m_sound_cache[current_slot];
-
- if (sb->m_status == SSF_UNUSED)
- return;
-
- // update sound count.
- m_sound_mixer.m_cur_sounds_played--;
-
- if (f_immediately == SKT_STOP_AFTER_LOOP) {
- sb->m_status &= ~SSF_PLAY_LOOPING;
- sb->m_status |= SSF_PLAY_NORMAL;
- if (m_mixer_type != SOUND_MIXER_SOFTWARE_16 && (sb->m_status & SSF_BUFFERED_LOOP)) {
- sb_buffered_loop_step(this, sb, DSBUFLOOP_FINISH_STEP);
- }
- return;
- }
-
- if (m_mixer_type != SOUND_MIXER_SOFTWARE_16) {
- if (sb->s && !(sb->m_status & (SSF_BUFFERED_LOOP + SSF_BUFFERED_STRM))) {
- sb_loop_element_kill(sb);
- if (f_immediately == SKT_HOLD_UNTIL_STOP) {
- sb_loop_element_wait_until_dead(sb);
- cleanup_directsound_looping_sb(sb);
- }
- return;
- } else if (sb->m_sound_buffer) // this works for buffered loops too.
- {
- if (sb->m_status & (SSF_BUFFERED_LOOP + SSF_BUFFERED_STRM)) {
- if (sb->m_status & SSF_PLAY_STREAMING) {
- sb_stream_element_kill(sb);
- }
-
- void *p = (void *)sb->s;
- if (p) {
- mem_free(p);
- sb->s = NULL;
- }
- }
- GetSoundPos(sb->m_unique_id);
- sb_stop_buffer(sb);
- sb_free_buffer(sb);
-
- if (SoundFiles[Sounds[sb->m_sound_index].sample_index].use_count > 0) {
- SoundFiles[Sounds[sb->m_sound_index].sample_index].use_count--;
- // DUPSND if (SoundFiles[Sounds[sb->m_sound_index].sample_index].use_count == 0) {
- // DUPSND Global_DS_alloced_sounds--;
- // DUPSND }
- }
- Global_DS_alloced_sounds--;
- }
- m_sound_mixer.m_sound_cache[current_slot].m_sound_buffer = NULL;
- }
-
- // mprintf(0, "SL cleaning slot %d\n", current_slot);
- m_sound_mixer.m_sound_cache[current_slot].m_status = SSF_UNUSED;
-}
-
-// Copies sound data from the external sound data block to an individual sound buffer
-HRESULT LoadSoundData(LPDIRECTSOUNDBUFFER lp_dsb, char *sound_data_ptr, DWORD total_bytes) {
- LPVOID ptr1, ptr2;
- DWORD len1, len2;
- HRESULT result;
-
- ASSERT(lp_dsb != NULL && sound_data_ptr != NULL && total_bytes > 0);
-
-TryLockAgainLabel:
- result = lp_dsb->Lock(0, total_bytes, &ptr1, &len1, &ptr2, &len2, 0);
-
- switch (result) {
- case DS_OK:
- memcpy(ptr1, sound_data_ptr, len1);
- if (ptr2)
- memcpy(ptr2, sound_data_ptr + len1, len2);
- lp_dsb->Unlock(ptr1, len1, ptr2, len2);
- break;
- case DSERR_BUFFERLOST:
- result = lp_dsb->Restore();
- if (result == DS_OK)
- goto TryLockAgainLabel;
- break;
- }
-
- return (long)result;
-}
-
-// Determines if a sound will play. Takes into account maximum allowable
-// sounds.
-// Also put prioritization code in here
-// ignore reserved slots
-
-#ifdef _DEBUG
-int16_t win_llsSystem::FindFreeSoundSlot(int sound_index, float volume, int priority)
-#else
-int16_t win_llsSystem::FindFreeSoundSlot(float volume, int priority)
-#endif
-{
- int current_slot;
- sound_buffer_info *sb;
-
- // stop any left over sounds for Direct Sound.
- if (m_mixer_type != SOUND_MIXER_SOFTWARE_16) {
- for (current_slot = 0; current_slot < m_sound_mixer.m_max_sounds_played; current_slot++) {
- sb = &m_sound_mixer.m_sound_cache[current_slot];
- update_directsound_sb(sb);
- }
- }
-
- for (current_slot = 0; current_slot < m_sound_mixer.m_max_sounds_played; current_slot++) {
- sb = &m_sound_mixer.m_sound_cache[current_slot];
- if (sb->m_status == SSF_UNUSED) {
- if (!((m_mixer_type == SOUND_MIXER_DS_8 || m_mixer_type == SOUND_MIXER_DS_16 ||
- m_mixer_type == SOUND_MIXER_DS3D_16 ||
- m_mixer_type == SOUND_MIXER_CREATIVE_EAX) &&
- sb->s))
- return current_slot;
- }
- }
-
- // no more slots? take priority into account.
- // throw out lowest priority sound slot (must be lower than or equal to new sound priority)
- float weighted_priority = (priority * 2.0f) * volume;
- if (current_slot == m_sound_mixer.m_max_sounds_played) {
- int throw_out_slot = -1, equiv_priority_slot = -1;
- float weighted_priorityA, weighted_priorityB;
- for (current_slot = 0; current_slot < m_sound_mixer.m_max_sounds_played; current_slot++) {
- sb = &m_sound_mixer.m_sound_cache[current_slot];
- if (!(sb->m_status & (SSF_PLAY_LOOPING + SSF_PLAY_STREAMING))) {
- weighted_priorityA = sb->play_info->priority * 2.0f * sb->m_volume;
- if (weighted_priorityA < weighted_priority) {
- if (throw_out_slot == -1) {
- throw_out_slot = current_slot;
- } else {
- play_information *play_info2 = m_sound_mixer.m_sound_cache[throw_out_slot].play_info;
- weighted_priorityB = play_info2->priority * 2.0f * sb->m_volume;
- if (weighted_priorityB > weighted_priorityA) {
- throw_out_slot = current_slot;
- }
- }
- }
-
- else if (equiv_priority_slot == -1 && weighted_priorityA == weighted_priority) {
- equiv_priority_slot = current_slot;
- }
- }
- }
-
- // if no slot found to stop, look for a slot with priority == new priority
- if (throw_out_slot == -1) {
- throw_out_slot = equiv_priority_slot;
- }
- if (throw_out_slot > -1) {
- sb = &m_sound_mixer.m_sound_cache[throw_out_slot];
- win_llsSystem::StopSound(sb->m_unique_id, SKT_HOLD_UNTIL_STOP);
-/*
- mprintf(0, "DDSNDLIB: Replace sound (p:%d) with sound (p:%d) in slot %d\n",
- sb->play_info->priority,
- priority,
- throw_out_slot));
-*/
- return throw_out_slot;
- }
- }
-
-#ifdef _DEBUG
- if (sound_index > -1) {
- mprintf(0, "DDSNDLIB: Sound %s with priority (%d) too low.\n", Sounds[sound_index].name, priority);
- } else {
- mprintf(0, "DDSNDLIB: Sound unknown with priority (%d) too low.\n", priority);
- }
-#endif
-
- return -1;
-}
-
-int win_llsSystem::PlaySound2d(play_information *play_info, int sound_index, float f_volume, float f_pan,
- bool f_looped) {
- sound_buffer_info *sb = NULL;
- int16_t sound_slot;
-
- if (!m_f_sound_lib_init) {
- return -1;
- }
-
- // calculate volume and pan
- f_volume = (f_volume < 0.0f) ? 0.0f : (f_volume > 1.0f) ? 1.0f : f_volume;
- play_info->left_volume = play_info->right_volume = f_volume;
-
- f_pan = (f_pan < -1.0f) ? -1.0f : (f_pan > 1.0f) ? 1.0f : f_pan;
- if (f_pan < 0.0) {
- play_info->right_volume += f_volume * f_pan;
- } else {
- play_info->left_volume -= f_volume * f_pan;
- }
-
- // do common processing.
- if (SoundFiles[Sounds[sound_index].sample_index].used == 0) {
- mprintf(0, "Tryed to play %d sound, it DNE.\n", sound_index);
- return -1;
- }
-#ifdef _DEBUG
- sound_slot = FindFreeSoundSlot(sound_index, f_volume, play_info->priority);
-#else
- sound_slot = FindFreeSoundSlot(f_volume, play_info->priority);
-#endif
- if (sound_slot < 0) {
- // do prioritization code here.
- return -1;
- }
- sb = &m_sound_mixer.m_sound_cache[sound_slot];
- m_total_sounds_played++;
- sb->play_info = play_info;
- sb->m_unique_id = MakeUniqueId(sound_slot);
- sb->m_buffer_type = SBT_2D;
- sb->m_sound_index = sound_index;
- sb->m_status = SSF_UNUSED;
-
- ASSERT(sb->m_unique_id != -1);
-
- // play 2d sound
- if (m_mixer_type == SOUND_MIXER_SOFTWARE_16) {
- sb->m_status = (f_looped) ? SSF_PLAY_LOOPING : SSF_PLAY_NORMAL;
- return sb->m_unique_id;
- }
-
- if (f_looped) {
- LoopStartStreaming(sb, SBT_2D, f_volume, f_pan, NULL);
- if (sb->m_snd_obj == NULL) {
- sb->m_status = SSF_UNUSED;
- Int3();
- return -1;
- }
- } else {
- tPSBInfo psb;
-
- if (SoundFiles[Sounds[sound_index].sample_index].use_count > 0) {
- if (DuplicateSoundBuffer(sb)) {
- goto play_sound;
- }
- }
- if (!CreateSoundBuffer(sb, false)) {
- return -1;
- }
- if (!LoadSoundBuffer(sb)) {
- sb_free_buffer(sb);
- return -1;
- }
-
- play_sound:
- sb->m_status = SSF_PLAY_NORMAL;
-
- psb.volume = f_volume;
- psb.pan = f_pan;
- psb.freq = 22050;
- psb.looping = false;
- if (!PlaySoundBuffer(sb, &psb)) {
- sb_free_buffer(sb);
- return -1;
- }
- }
-
- m_sound_mixer.m_cur_sounds_played++;
-
- return sb->m_unique_id;
-}
-
-void win_llsSystem::LoopStartStreaming(sound_buffer_info *sb, int buffer_type, float volume, float pan,
- pos_state *cur_pos) {
- // unsigned long thread_handle;
- int sound_length, buffer_size;
- int determined_method;
- bool f_sample_16bit;
- char *sample_ptr;
- tPSBInfo psb;
- DSLOOPSTREAM *s;
-
- // setup looping buffer. must clear out before assigning to sound buffer for thread security.
- s = (DSLOOPSTREAM *)mem_malloc(sizeof(DSLOOPSTREAM));
- if (s == NULL) {
- sb->s = NULL;
- return;
- }
- memset((void *)s, 0, sizeof(DSLOOPSTREAM));
- sb->s = s;
-
- sample_ptr = get_sound_info(sb, &sound_length, &f_sample_16bit);
- sb->s->f_sample_16bit = f_sample_16bit;
- sb->m_buffer_type = buffer_type;
-
- if (m_sound_mixer.m_loop_method == DSLOOP_SMART_METHOD) {
- int loop_startb, loop_endb;
- bool b;
- if (sb_get_loop_info(sb, &loop_startb, &loop_endb, &b)) {
- if (SoundFiles[Sounds[sb->m_sound_index].sample_index].np_sample_length == (loop_endb - loop_startb + 1)) {
- determined_method = DSLOOP_BUFFER_METHOD;
- } else {
- determined_method = DSLOOP_STREAM_METHOD;
- }
- } else { // wtf?
- return;
- }
- } else {
- determined_method = m_sound_mixer.m_loop_method;
- }
-
- switch (determined_method) {
- case DSLOOP_BUFFER_METHOD:
- sound_length = 0;
- sb->s->loop_step = -1;
- while (!sound_length && sb->s->loop_step < 2) {
- sample_ptr = sb_get_loop_step_info(sb, sb->s->loop_step, f_sample_16bit, &sound_length);
- sb->s->loop_step++;
- }
- if (!sound_length && sb->s->loop_step == 2) {
- // hmm, weird loop. no sample?
- return;
- }
- sb->s->loop_step--; // return to proper step.
- sb->s->loop_timer = 0.0f;
- sb->s->bytes_left = sound_length;
- buffer_size = sound_length;
- sb->m_status = SSF_PLAY_LOOPING | SSF_BUFFERED_LOOP;
- // mprintf(0, "DDSNDLIB: Starting buffered loop %d (step %d).\n", sb->m_unique_id, sb->s->loop_step);
- break;
- default:
- buffer_size = STREAM_BUFFER_SIZE;
- sb->m_status = SSF_PLAY_LOOPING; // must go before buffer is initialized!!!!!!
- }
-
- sb->sample_data = sample_ptr;
-
- // allocate buffer for playback
- if (!CreateSoundBuffer(sb, false, buffer_size, (sb->m_status & SSF_BUFFERED_LOOP) ? false : true)) {
- return;
- }
-
- // remind sb system and play.
- if (determined_method == DSLOOP_BUFFER_METHOD) {
- psb.looping = (sb->s->loop_step == 0) ? true : false;
- if (!sb_load_buffer(sb, sb->sample_data, sound_length))
- return;
- } else if (sb_loop_element_init(sb, sample_ptr, sound_length, STREAM_BUFFER_SIZE)) {
- psb.looping = true;
- } else {
- sb->s->playing = 0;
- return;
- }
-
- if (buffer_type == SBT_3D) {
- psb.cur_pos = cur_pos;
- } else {
- ASSERT(buffer_type == SBT_2D);
- psb.pan = pan;
- }
- psb.volume = volume;
- psb.freq = 22050;
-
- PlaySoundBuffer(sb, &psb);
-
- // must be at end to initiate thread management.
- sb->s->playing = 1;
-}
-
-void win_llsSystem::DSStartStreaming(sound_buffer_info *sb, float volume, float pan) {
- tPSBInfo psb;
- int sound_length;
- int stream_buflength;
- int determined_method;
- char *sample_ptr;
- bool f_stereo;
-
- sb->s = (DSLOOPSTREAM *)mem_malloc(sizeof(DSLOOPSTREAM));
- ASSERT(sb->s);
- if (sb->s == NULL)
- return;
-
- memset((void *)sb->s, 0, sizeof(DSLOOPSTREAM));
-
- sample_ptr = (char *)sb->play_info->m_stream_data;
- sound_length = sb->play_info->m_stream_size;
- stream_buflength = sb->play_info->m_stream_bufsize;
-
- switch (sb->play_info->m_stream_format) {
- case SIF_STREAMING_16_M:
- sb->s->f_sample_16bit = true;
- f_stereo = false;
- break;
-
- case SIF_STREAMING_8_M:
- sb->s->f_sample_16bit = false;
- f_stereo = false;
- break;
-
- case SIF_STREAMING_16_S:
- sb->s->f_sample_16bit = true;
- f_stereo = true;
- break;
-
- case SIF_STREAMING_8_S:
- sb->s->f_sample_16bit = false;
- f_stereo = true;
- break;
-
- default:
- ASSERT(0);
- break;
- }
-
- ASSERT(sb->m_buffer_type == SBT_2D);
- sb->m_sound_index = -1;
-
- // determine how we will stream this data
- determined_method = m_sound_mixer.m_loop_method;
- switch (determined_method) {
- case DSLOOP_BUFFER_METHOD:
- sb->m_status = SSF_PLAY_STREAMING | SSF_BUFFERED_STRM;
- break;
- default:
- sb->m_status = SSF_PLAY_STREAMING; // must go before buffer is initialized!!!!!!
- break;
- }
-
- if (!CreateSoundBuffer(sb, f_stereo, stream_buflength, true)) {
- mem_free((void *)sb->s);
- sb->s = NULL;
- return;
- }
-
- // set wave event or do thread streamed method
- if (sb_stream_element_init(sb, sample_ptr, sound_length, stream_buflength)) {
- psb.pan = pan;
- psb.volume = volume;
- psb.freq = 22050;
- psb.looping = true;
-
- PlaySoundBuffer(sb, &psb);
-
- // must be at end to initiate thread management.
- sb->s->playing = 1;
- }
-}
-
-int win_llsSystem::PlayStream(play_information *play_info) {
- int16_t sound_slot;
- DWORD ds_flags = 0;
-
- ASSERT(play_info != NULL);
-
- float volume = (play_info->left_volume > play_info->right_volume) ? play_info->left_volume : play_info->right_volume;
-
- if (!m_f_sound_lib_init)
- return -1;
-
-#ifdef _DEBUG
- sound_slot = FindFreeSoundSlot(-1, volume, play_info->priority);
-#else
- sound_slot = FindFreeSoundSlot(volume, play_info->priority);
-#endif
- // Out of sound slots
- if (sound_slot < 0) {
- return -1;
- }
-
- // mprintf(0, "TS(%d)Playing sound index %d at %d volume,%d pan\n", TotalSoundsPlayed, sound_index, volume, pan);
-
- m_total_sounds_played++;
- m_sound_mixer.m_sound_cache[sound_slot].play_info = play_info;
-
- m_sound_mixer.m_sound_cache[sound_slot].m_unique_id = MakeUniqueId(sound_slot);
- ASSERT(m_sound_mixer.m_sound_cache[sound_slot].m_unique_id != -1);
-
- m_sound_mixer.m_sound_cache[sound_slot].m_buffer_type = SBT_2D;
-
- if (m_mixer_type != SOUND_MIXER_SOFTWARE_16) {
- float volume;
- float pan;
- LPDIRECTSOUNDBUFFER sound_ptr;
-
- if (play_info->left_volume > play_info->right_volume) {
- volume = play_info->left_volume;
- pan = -1.0f + (play_info->right_volume / play_info->left_volume);
- } else {
- volume = play_info->right_volume;
- pan = 1.0f - (play_info->left_volume / play_info->right_volume);
- }
-
- DSStartStreaming(&m_sound_mixer.m_sound_cache[sound_slot], volume, pan);
- sound_ptr = m_sound_mixer.m_sound_cache[sound_slot].m_sound_buffer;
- if (sound_ptr == NULL) {
- m_sound_mixer.m_sound_cache[sound_slot].m_sound_buffer = NULL;
- return -1;
- }
- } else {
- m_sound_mixer.m_sound_cache[sound_slot].m_status = SSF_PLAY_STREAMING;
- }
-
- m_sound_mixer.m_cur_sounds_played++;
-
- return (m_sound_mixer.m_sound_cache[sound_slot].m_unique_id);
-}
-
-// Checks a Unique Sound ID and determines if that sound is still playing
-bool win_llsSystem::IsSoundInstancePlaying(int sound_uid) {
- int current_slot;
-
- if (!m_f_sound_lib_init)
- return false;
-
- if ((current_slot = ValidateUniqueId(sound_uid)) == -1)
- return false;
-
- // mprintf(0, "Checking slot %d of UID %d\n", current_slot, sound_uid);
-
- if (m_sound_mixer.m_sound_cache[current_slot].m_status != SSF_UNUSED) {
- return true;
- }
-
- return false;
-}
-
-// Is this sound placing on any "channel"
-int win_llsSystem::IsSoundPlaying(int sound_index) {
- int current_slot;
-
- if (!m_f_sound_lib_init)
- return -1;
-
- for (current_slot = 0; current_slot < m_sound_mixer.m_max_sounds_played; current_slot++) {
- if ((m_sound_mixer.m_sound_cache[current_slot].m_status != SSF_UNUSED) &&
- (m_sound_mixer.m_sound_cache[current_slot].m_sound_index == sound_index)) {
- return m_sound_mixer.m_sound_cache[current_slot].m_unique_id;
- }
- }
-
- return -1;
-}
-
-// This function limits the number of sounds cached to 255(8bits) and 256 bit is for invalid channel
-// The purpose is to create unique signatures for each sound played (and allow for
-// the slot_number to be quickly determined)
-inline int win_llsSystem::MakeUniqueId(int sound_slot) { return ((((int)m_total_sounds_played) << 8) + sound_slot); }
-
-inline int win_llsSystem::ValidateUniqueId(int sound_uid) {
- if (sound_uid == m_sound_mixer.m_sound_cache[sound_uid & 0x00FF].m_unique_id) {
- return sound_uid & 0x00FF;
- } else {
- return -1;
- }
-}
-
-void win_llsSystem::PauseSounds() {
- int current_slot;
-
- if (m_mixer_type != SOUND_MIXER_SOFTWARE_16) {
-
- for (current_slot = 0; current_slot < m_sound_mixer.m_max_sounds_played; current_slot++) {
- sound_buffer_info *sb = &m_sound_mixer.m_sound_cache[current_slot];
- update_directsound_sb(sb);
-
- /* if((sb->m_status != SSF_UNUSED) &&
- ((sb->m_status & SSF_PAUSED) == 0))
- {
- int status = sb_get_status(sb);
-
- if(!(status & SB_STATUS_PLAYING)) {
- ll_sound_ptr->StopSound(sb->m_unique_id);
- }
- else if (status & SB_STATUS_INVALID) {
- ll_sound_ptr->StopSound(sb->m_unique_id);
- }
- }
- */
- }
- }
-
- for (current_slot = 0; current_slot < m_sound_mixer.m_max_sounds_played; current_slot++) {
- sound_buffer_info *sb = &m_sound_mixer.m_sound_cache[current_slot];
- if (sb->m_status != SSF_UNUSED && !(sb->m_status & SSF_PAUSED)) {
- sb->m_status |= SSF_PAUSED;
- if (m_mixer_type != SOUND_MIXER_SOFTWARE_16 && (sb->m_sound_buffer)) {
- sb_stop_buffer(sb);
- }
- }
- }
-}
-
-void win_llsSystem::ResumeSounds() {
- int current_slot;
-
- for (current_slot = 0; current_slot < m_sound_mixer.m_max_sounds_played; current_slot++) {
- sound_buffer_info *sb = &m_sound_mixer.m_sound_cache[current_slot];
-
- if (sb->m_status != SSF_UNUSED && (sb->m_status & SSF_PAUSED)) {
- if (m_mixer_type != SOUND_MIXER_SOFTWARE_16) {
- PlaySoundBuffer(sb, NULL);
- }
-
- m_sound_mixer.m_sound_cache[current_slot].m_status &= (~SSF_PAUSED);
- }
- }
-}
-
-void win_llsSystem::PauseSound(int sound_uid) {
- int current_slot;
-
- if (m_mixer_type != SOUND_MIXER_SOFTWARE_16) {
-
- for (current_slot = 0; current_slot < m_sound_mixer.m_max_sounds_played; current_slot++) {
- sound_buffer_info *sb = &m_sound_mixer.m_sound_cache[current_slot];
-
- if (sb->m_unique_id == sound_uid) {
- update_directsound_sb(sb);
-
- /* if((sb->m_status != SSF_UNUSED) && ((sb->m_status & SSF_PAUSED) == 0))
- {
- int status = sb_get_status(sb);
-
- if(!(status & SB_STATUS_PLAYING)) {
- ll_sound_ptr->StopSound(sb->m_unique_id);
- }
- else if (status & SB_STATUS_INVALID) {
- ll_sound_ptr->StopSound(sb->m_unique_id);
- }
- }
- */
- break;
- }
- }
- }
-
- for (current_slot = 0; current_slot < m_sound_mixer.m_max_sounds_played; current_slot++) {
- sound_buffer_info *sb = &m_sound_mixer.m_sound_cache[current_slot];
- if (sb->m_unique_id == sound_uid) {
- if (sb->m_status != SSF_UNUSED && !(sb->m_status & SSF_PAUSED)) {
- sb->m_status |= SSF_PAUSED;
- if (m_mixer_type != SOUND_MIXER_SOFTWARE_16 && (sb->m_sound_buffer)) {
- sb_stop_buffer(sb);
- }
- }
- break;
- }
- }
-}
-
-void win_llsSystem::ResumeSound(int sound_uid) {
- int current_slot;
-
- for (current_slot = 0; current_slot < m_sound_mixer.m_max_sounds_played; current_slot++) {
- if (sound_uid == m_sound_mixer.m_sound_cache[current_slot].m_unique_id) {
- if (m_sound_mixer.m_sound_cache[current_slot].m_status != SSF_UNUSED &&
- (m_sound_mixer.m_sound_cache[current_slot].m_status & SSF_PAUSED)) {
- if (m_mixer_type != SOUND_MIXER_SOFTWARE_16) {
- PlaySoundBuffer(&m_sound_mixer.m_sound_cache[current_slot], NULL);
- }
-
- m_sound_mixer.m_sound_cache[current_slot].m_status &= (~SSF_PAUSED);
- break;
- }
- }
- }
-}
-
-void win_llsSystem::StopAllSounds() {
- int current_slot;
-
- for (current_slot = 0; current_slot < m_sound_mixer.m_max_sounds_played; current_slot++) {
- if (m_sound_mixer.m_sound_cache[current_slot].m_status != SSF_UNUSED) {
- StopSound(m_sound_mixer.m_sound_cache[current_slot].m_unique_id);
- }
- }
-}
-
-// Begin sound frame
-void win_llsSystem::SoundStartFrame(void) {
- float frame_time;
- int current_slot;
- int i;
-
- if (m_timer_last_frametime == -1) {
- frame_time = 0.0f;
- } else {
- frame_time = (timer_GetMSTime() - m_timer_last_frametime) / 1000.0f;
- }
- m_timer_last_frametime = timer_GetMSTime();
-
- // perform necessary functions if sound events are pending for frame, this doesn't have to do anything
- // if the mixer doesn't require such actions. Aureal does though.
- if (m_pending_actions) {
- mprintf(0, "pending actions\n");
- }
-
- // start mixer dependant frame
- m_in_sound_frame = true;
- m_pending_actions = false;
-
- // cleanup sound cache.
- // mprintf(0, "StartCleanup\n");
- if (m_mixer_type != SOUND_MIXER_SOFTWARE_16) {
- for (i = 0; i < m_sound_mixer.m_max_sounds_played; i++) {
- sound_buffer_info *sb = &m_sound_mixer.m_sound_cache[i];
- update_directsound_sb(sb, true);
- }
- }
- // mprintf(0, "EndCleanup\n");
-
- int counter = 0, loop_counter = 0, stream_counter = 0, buf_loop_counter = 0;
-
-#ifdef _DEBUG
- int n_p5 = 0, n_p4 = 0, n_p3 = 0, n_p2 = 0, n_p1 = 0, n_p0 = 0;
-#endif
-
- for (current_slot = 0; current_slot < m_sound_mixer.m_max_sounds_played; current_slot++) {
- sound_buffer_info *sb = &m_sound_mixer.m_sound_cache[current_slot];
- if (sb->m_status != SSF_UNUSED) {
- counter++;
- if (sb->m_status & SSF_PLAY_LOOPING) {
- if (sb->m_status & SSF_BUFFERED_LOOP)
- buf_loop_counter++;
- loop_counter++;
- }
- if (sb->m_status & SSF_PLAY_STREAMING)
- stream_counter++;
-
-#ifdef _DEBUG
- if (sb->play_info->priority == SND_PRIORITY_CRITICAL)
- n_p5++;
- else if (sb->play_info->priority == SND_PRIORITY_HIGHEST)
- n_p4++;
- else if (sb->play_info->priority == SND_PRIORITY_HIGH)
- n_p3++;
- else if (sb->play_info->priority == SND_PRIORITY_NORMAL)
- n_p2++;
- else if (sb->play_info->priority == SND_PRIORITY_LOW)
- n_p1++;
- else if (sb->play_info->priority == SND_PRIORITY_LOWEST)
- n_p0++;
-#endif
- }
- }
-
- // update cache stress timer.
- if (counter < (m_sound_mixer.m_max_sounds_played * 3 / 4)) {
- m_cache_stress_timer += frame_time;
- } else {
- m_cache_stress_timer = 0.0f;
- }
-
-#ifdef _DEBUG
- mprintf_at(3, 2, 0, "LNS: %02d/%02d", counter, m_sound_mixer.m_max_sounds_played);
- mprintf_at(3, 3, 1, "Lp: %02d", loop_counter);
- mprintf_at(3, 4, 1, "St: %02d", stream_counter);
- mprintf_at(3, 5, 0, " Ot: %02d", counter - loop_counter - stream_counter);
-
- if (m_sound_mixer.m_loop_method != DSLOOP_STREAM_METHOD && m_mixer_type != SOUND_MIXER_SOFTWARE_16) {
- mprintf_at(3, 3, 10, "Bf: %02d", buf_loop_counter);
- }
-
- mprintf_at(3, 2, 20, "P5:%02d P4:%02d P3:%02d", n_p5, n_p4, n_p3);
- mprintf_at(3, 3, 20, "P2:%02d P1:%02d P0:%02d", n_p2, n_p1, n_p0);
-#endif
-}
-
-// End sound frame
-void win_llsSystem::SoundEndFrame(void) {
- CheckForErrors(); // handles errors.
-
- m_in_sound_frame = false;
-}
-
-bool win_llsSystem::LockSound(int sound_uid) { return false; }
-
-bool win_llsSystem::UnlockSound(int sound_uid) { return false; }
-
-// True means it was already loaded, false means that it was not
-bool win_llsSystem::CheckAndForceSoundDataAlloc(int sound_index) {
- int result;
- int sound_file_index = Sounds[sound_index].sample_index;
-
- ASSERT(sound_file_index >= 0 && sound_file_index < MAX_SOUND_FILES);
-
- if (sound_file_index < 0 || sound_file_index >= MAX_SOUND_FILES) {
- return false;
- }
-
- // Check if the sample data is already loaded
- if (SoundFiles[sound_file_index].sample_16bit != NULL || SoundFiles[sound_file_index].sample_8bit != NULL)
- return true;
-
- // If not, get the sound data
- result = SoundLoadWaveFile(SoundFiles[sound_file_index].name, Sounds[sound_index].import_volume, sound_file_index,
- (m_sound_quality == SQT_HIGH), true);
-
- // Why would it load once (table load time) and not now?
- if (!result)
- return false;
-
- mprintf(0, "Sound %s loaded.\n", SoundFiles[sound_file_index].name);
-
- return true;
-}
-
-bool win_llsSystem::SetSoundQuality(char quality) {
- int i;
-
- if (quality == m_sound_quality)
- return true;
-
- // pause any sounds that may be playing
- win_llsSystem::PauseSounds();
-
- if (quality == SQT_NORMAL) {
- m_sound_quality = SQT_NORMAL;
- } else {
- m_sound_quality = SQT_HIGH;
- }
-
- for (i = 0; i < MAX_SOUNDS; i++) {
- if (Sounds[i].used != 0) {
- int j = Sounds[i].sample_index;
-
- if (SoundFiles[j].sample_8bit && m_sound_quality == SQT_HIGH) {
- mem_free(SoundFiles[j].sample_8bit);
- SoundFiles[j].sample_8bit = NULL;
-
- CheckAndForceSoundDataAlloc(i);
- }
- if (SoundFiles[j].sample_16bit && m_sound_quality == SQT_NORMAL) {
- int count;
-
- ASSERT(SoundFiles[j].sample_8bit == NULL);
- SoundFiles[j].sample_8bit = (uint8_t *)mem_malloc(SoundFiles[j].sample_length);
-
- // NOTE: Interesting note on sound conversion: 16 bit sounds are signed (0 biase). 8 bit sounds are unsigned
- // (+128 biase).
- for (count = 0; count < (int)SoundFiles[j].sample_length; count++) {
- SoundFiles[j].sample_8bit[count] = (uint8_t)((((int)SoundFiles[j].sample_16bit[count]) + 32767) >> 8);
- }
-
- mem_free(SoundFiles[j].sample_16bit);
- SoundFiles[j].sample_16bit = NULL;
- }
- }
- }
-
- win_llsSystem::ResumeSounds();
-
- return true;
-}
-
-char win_llsSystem::GetSoundQuality(void) { return m_sound_quality; }
-
-bool win_llsSystem::SetSoundMixer(char mixer_type) {
- if (mixer_type == m_mixer_type)
- return true;
- else {
- // Chris note: This is not the best way to do this. All the currently playing
- // sounds are lost. This shouldn't happen. A real solutions has to take in account
- // for three things: Normal sounds, looping sounds, and streaming audio.
- DestroySoundLib();
- InitSoundLib(mixer_type, SoundApp, m_sound_mixer.m_max_sounds_played);
- SetSoundQuality(m_sound_quality);
- }
- return true;
-}
-
-char win_llsSystem::GetSoundMixer(void) { return m_mixer_type; }
-
-void win_llsSystem::SetListener(pos_state *cur_pos) {
- if (!m_f_sound_lib_init)
- return;
-
- m_emulated_listener.orient = *cur_pos->orient;
- m_emulated_listener.position = *cur_pos->position;
- m_emulated_listener.velocity = *cur_pos->velocity;
-
- if (IS_3D_MIXER(m_mixer_type)) {
- m_lp_listener->SetOrientation(cur_pos->orient->fvec.x, cur_pos->orient->fvec.y, cur_pos->orient->fvec.z,
- cur_pos->orient->uvec.x, cur_pos->orient->uvec.y, cur_pos->orient->uvec.z,
- DS3D_DEFERRED);
- m_lp_listener->SetPosition(cur_pos->position->x, cur_pos->position->y, cur_pos->position->z, DS3D_DEFERRED);
- m_lp_listener->SetVelocity(cur_pos->velocity->x, cur_pos->velocity->y, cur_pos->velocity->z, DS3D_DEFERRED);
- m_lp_listener->CommitDeferredSettings();
- }
-}
-
-// AdjustSound2d -- adjusts the volume, pan, and freq. of a sound
-void win_llsSystem::AdjustSound(int sound_uid, float f_volume, float f_pan, uint16_t frequency) {
- int current_slot;
-
- if (!m_f_sound_lib_init)
- return;
-
- if ((current_slot = ValidateUniqueId(sound_uid)) == -1)
- return;
- if (m_sound_mixer.m_sound_cache[current_slot].m_status == SSF_UNUSED)
- return;
-
- sound_buffer_info *sb = &m_sound_mixer.m_sound_cache[current_slot];
- play_information *play_info = sb->play_info;
-
- play_info->left_volume = play_info->right_volume = f_volume;
- if (f_pan < 0.0)
- play_info->right_volume += f_volume * f_pan;
- else
- play_info->left_volume -= f_volume * f_pan;
-
- sb_adjust_properties_2d(&m_sound_mixer.m_sound_cache[current_slot], f_volume, f_pan, frequency);
-
- return;
-}
-
-void win_llsSystem::AdjustSound(int sound_uid, pos_state *cur_pos, float adjusted_volume, float reverb) {
- if (!m_f_sound_lib_init)
- return;
-
- LPDIRECTSOUNDBUFFER lp_dsb;
- // LPDIRECTSOUND3DBUFFER lpDSB3D;
- int current_slot;
-
- if (!m_f_sound_lib_init)
- return;
-
- if ((current_slot = ValidateUniqueId(sound_uid)) == -1)
- return;
- if (m_sound_mixer.m_sound_cache[current_slot].m_status == SSF_UNUSED)
- return;
-
- // sound_buffer_info *sb = &m_sound_mixer.m_sound_cache[current_slot];
-
- if (IS_3D_MIXER(m_mixer_type)) {
- int sound_index = m_sound_mixer.m_sound_cache[current_slot].m_sound_index;
- lp_dsb = m_sound_mixer.m_sound_cache[current_slot].m_sound_buffer;
- if (lp_dsb == NULL)
- return;
-
- sb_adjust_properties_3d(&m_sound_mixer.m_sound_cache[current_slot], adjusted_volume, cur_pos, reverb);
- } else {
- // We need to determine the pan and volume
- float volume;
-
- volume = adjusted_volume;
-
- float dist;
- vector dir_to_sound = *cur_pos->position - m_emulated_listener.position;
- float pan;
-
- dist = vm_NormalizeVector(&dir_to_sound);
- if (dist < .1f) {
- dir_to_sound = m_emulated_listener.orient.fvec;
- }
-
- if (dist >= Sounds[m_sound_mixer.m_sound_cache[current_slot].m_sound_index].max_distance) {
- volume = 0.0f;
- } else if (dist > Sounds[m_sound_mixer.m_sound_cache[current_slot].m_sound_index].min_distance) {
- volume *= (1.0 - ((dist - Sounds[m_sound_mixer.m_sound_cache[current_slot].m_sound_index].min_distance) /
- (Sounds[m_sound_mixer.m_sound_cache[current_slot].m_sound_index].max_distance -
- Sounds[m_sound_mixer.m_sound_cache[current_slot].m_sound_index].min_distance)));
- }
-
- pan = (dir_to_sound * m_emulated_listener.orient.rvec);
-
- if (volume < 0.0f)
- volume = 0.0f;
- else if (volume > 1.0f)
- volume = 1.0f;
-
- if (pan < -1.0f)
- pan = -1.0f;
- else if (pan > 1.0f)
- pan = 1.0f;
-
- AdjustSound(m_sound_mixer.m_sound_cache[current_slot].m_unique_id, volume, pan, 22050);
- }
-
- return;
-}
-
-int win_llsSystem::PlaySound3d(play_information *play_info, int sound_index, pos_state *cur_pos, float adjusted_volume,
- bool f_looped, float reverb) {
- int16_t sound_slot;
- DWORD ds_flags = 0;
- float volume;
-
- volume = adjusted_volume; // Adjust base volume by sent volume, let 3d stuff do the rest
-
- if (!m_f_sound_lib_init)
- return -1;
-
- ASSERT(Sounds[sound_index].used != 0);
- if (Sounds[sound_index].used == 0)
- return -1;
-
- if (!IS_3D_MIXER(m_mixer_type)) {
- float dist;
- vector dir_to_sound = *cur_pos->position - m_emulated_listener.position;
- float pan;
-
- dist = vm_NormalizeVector(&dir_to_sound);
- if (dist < .1f) {
- dir_to_sound = m_emulated_listener.orient.fvec;
- }
-
- if (dist >= Sounds[sound_index].max_distance) {
- return -1;
- } else if (dist > Sounds[sound_index].min_distance) {
- volume *= (1.0 - ((dist - Sounds[sound_index].min_distance) /
- (Sounds[sound_index].max_distance - Sounds[sound_index].min_distance)));
- }
-
- pan = (dir_to_sound * m_emulated_listener.orient.rvec);
-
- if (volume < 0.0f)
- volume = 0.0f;
- else if (volume > 1.0f)
- volume = 1.0f;
-
- if (pan < -1.0f)
- pan = -1.0f;
- else if (pan > 1.0f)
- pan = 1.0f;
-
- return PlaySound2d(play_info, sound_index, volume, pan, f_looped);
- }
-
-// Out of sound slots
-#ifdef _DEBUG
- sound_slot = FindFreeSoundSlot(sound_index, volume, play_info->priority);
-#else
- sound_slot = FindFreeSoundSlot(volume, play_info->priority);
-#endif
-
- if (sound_slot < 0) {
- return -1;
- }
-
- m_sound_mixer.m_sound_cache[sound_slot].play_info = play_info;
- m_total_sounds_played++;
- m_sound_mixer.m_sound_cache[sound_slot].m_unique_id = MakeUniqueId(sound_slot);
- ASSERT(m_sound_mixer.m_sound_cache[sound_slot].m_unique_id != -1);
-
- // 3-D!!
- sound_buffer_info *sb = &m_sound_mixer.m_sound_cache[sound_slot];
-
- sb->m_buffer_type = SBT_3D;
- sb->m_sound_index = sound_index;
-
- if (f_looped) {
- LoopStartStreaming(sb, SBT_3D, adjusted_volume, 0.0, cur_pos);
- if (sb->m_snd_obj == NULL) {
- sb->m_sound_buffer = NULL;
- Int3();
- return -1;
- }
- } else {
- tPSBInfo psb;
-
- if (SoundFiles[Sounds[sound_index].sample_index].use_count > 0) {
- if (DuplicateSoundBuffer(sb)) {
- goto play_sound;
- }
- }
- if (!CreateSoundBuffer(sb, false)) {
- return -1;
- }
- if (!LoadSoundBuffer(sb)) {
- sb_free_buffer(sb);
- return -1;
- }
-
- play_sound:
- sb->m_status = SSF_PLAY_NORMAL;
-
- psb.cur_pos = cur_pos;
- psb.volume = volume;
- psb.freq = 22050;
- psb.reverb = reverb;
- psb.looping = false;
- if (!PlaySoundBuffer(sb, &psb)) {
- sb_free_buffer(sb);
- return -1;
- }
-/*
- mprintf(0, "SL Play sound on slot %d, TP = %d UI = %X\n",
- sound_slot,
- TotalSoundsPlayed,
- m_sound_mixer.m_sound_cache[sound_slot].m_unique_id);
-*/
- }
-
- m_sound_mixer.m_cur_sounds_played++;
-
- return (sb->m_unique_id);
-}
-
-// These work in samples to make things easier in the long run
-int win_llsSystem::SetSoundPos(int sound_uid, int pos) {
- int current_slot;
-
- if (pos <= 0)
- return 1;
-
- if (!m_f_sound_lib_init)
- return -1;
- if ((current_slot = ValidateUniqueId(sound_uid)) == -1)
- return -1;
- if (m_sound_mixer.m_sound_cache[current_slot].m_status == SSF_UNUSED)
- return -1;
-
- m_sound_mixer.m_sound_cache[current_slot].play_info->m_samples_played = pos;
-
- if (m_mixer_type != SOUND_MIXER_SOFTWARE_16) {
- sound_buffer_info *sb = &m_sound_mixer.m_sound_cache[current_slot];
-
- if (sb->stereo) {
- pos *= 2;
- }
-
- if (sb->bps == 16) {
- pos *= 2;
- }
-
- sb_set_current_position(sb, pos);
- }
-
- return 1;
-}
-
-// These work in samples to make things easier in the long run
-int win_llsSystem::GetSoundPos(int sound_uid) {
- int current_slot;
- uint32_t temp, pos;
-
- if (!m_f_sound_lib_init)
- return -1;
- if ((current_slot = ValidateUniqueId(sound_uid)) == -1)
- return -1;
- if (m_sound_mixer.m_sound_cache[current_slot].m_status == SSF_UNUSED)
- return -1;
-
- if (m_mixer_type != SOUND_MIXER_SOFTWARE_16) {
- sound_buffer_info *sb = &m_sound_mixer.m_sound_cache[current_slot];
-
- temp = sb_get_current_position(sb, &pos);
-
- if (sb->stereo) {
- pos /= 2;
- }
- if (sb->bps == 16) {
- pos /= 2;
- }
-
- // Updates the readable data
- m_sound_mixer.m_sound_cache[current_slot].play_info->m_samples_played = pos;
-
- return pos;
- } else {
- return m_sound_mixer.m_sound_cache[current_slot].play_info->m_samples_played;
- }
-
- return -1;
-}
-
-////////////////////////////////////////////////////////////////////////////////
-bool win_llsSystem::CreateSoundBuffer(sound_buffer_info *sb, bool f_is_stereo, int size, bool dynamic) {
- // do buffer creation
- int buftype = sb->m_buffer_type;
- bool f_sample_16bit;
- int sound_length;
-
- get_sound_info(sb, &sound_length, &f_sample_16bit);
-
- if (size != -1) {
- sound_length = size;
- }
-
- switch (m_mixer_type) {
- case SOUND_MIXER_SOFTWARE_16:
- Int3();
- break;
- default:
- CreateDSBuffer(buftype, &sb->m_sound_buffer, &sb->m_sound_buffer_3d, sound_length, 22050, f_is_stereo,
- f_sample_16bit);
-
- sb->m_lpksps = NULL;
- if (m_mixer_type == SOUND_MIXER_CREATIVE_EAX) {
- EAX_InitSource(sb->m_sound_buffer_3d, &sb->m_lpksps);
- }
-
- if (!sb->m_sound_buffer) {
- Int3();
- sb->m_status = SSF_UNUSED;
- return false;
- }
- }
-
- sb->m_mixer_type = m_mixer_type;
- sb->bps = f_sample_16bit ? 16 : 8;
- sb->stereo = f_is_stereo;
-
- if (sb->m_sound_index > -1) {
- SoundFiles[Sounds[sb->m_sound_index].sample_index].use_count++;
- // Global_DS_alloced_sounds++;
- }
-
- return true;
-}
-
-bool win_llsSystem::LoadSoundBuffer(sound_buffer_info *sb) {
- // play 2d sound
- int buftype = sb->m_buffer_type;
- bool f_sample_16bit;
- char *sample_ptr;
- int sound_length;
-
- // get pointer
- sample_ptr = get_sound_info(sb, &sound_length, &f_sample_16bit);
- sb->sample_data = sample_ptr;
- sb->sample_length = (int)sound_length;
-
- // do buffer creation
- switch (m_mixer_type) {
- case SOUND_MIXER_SOFTWARE_16:
- Int3();
- break;
- default:
- if (LoadSoundData(sb->m_sound_buffer, sample_ptr, sound_length) != DS_OK) {
- Int3();
- sb->m_status = SSF_UNUSED;
- return false;
- }
- }
-
- return true;
-}
-
-bool win_llsSystem::PlaySoundBuffer(sound_buffer_info *sb, tPSBInfo *psb) {
- bool f_looping;
-
- if (!m_f_sound_lib_init)
- return false;
- if (!m_in_sound_frame)
- m_pending_actions = true;
-
-TryPlayAgainLabel:
- if (psb) {
- if (sb->m_buffer_type == SBT_2D) {
- AdjustSound(sb->m_unique_id, psb->volume, psb->pan, psb->freq);
- } else if (sb->m_buffer_type == SBT_3D) {
- AdjustSound(sb->m_unique_id, psb->cur_pos, psb->volume, psb->reverb);
- }
-
- SetSoundPos(sb->m_unique_id, sb->play_info->m_samples_played);
-
- f_looping = psb->looping;
- } else {
- f_looping = ((sb->m_status & SSF_PLAY_LOOPING) || sb->s) ? true : false;
- if (f_looping && m_sound_mixer.m_loop_method == DSLOOP_BUFFER_METHOD && sb->s->loop_step != 0 &&
- (sb->m_status & SSF_BUFFERED_LOOP)) {
- f_looping = false;
- }
- }
-
- switch (m_mixer_type) {
- case SOUND_MIXER_SOFTWARE_16:
- Int3();
- break;
-
- default: {
- LPDIRECTSOUNDBUFFER sound_ptr = sb->m_sound_buffer;
- DWORD ds_flags = f_looping ? DSBPLAY_LOOPING : 0;
-
- ASSERT(sound_ptr);
-
- if (sound_ptr->Play(0, 0, ds_flags) == DSERR_BUFFERLOST) {
- if (LoadSoundData(sound_ptr, sb->sample_data, sb->sample_length) == DS_OK) {
- goto TryPlayAgainLabel;
- }
-
- sb->m_status = SSF_UNUSED;
-
- // Some type of error -- we cannot play the sound? -- get chris
- Int3();
- return false;
- }
- }
- }
-
- return true;
-}
-
-bool win_llsSystem::DuplicateSoundBuffer(sound_buffer_info *sb) {
- return false; // for now, let's not do this.
-/*
- sound_buffer_info *source_sb = m_sound_mixer.FindSoundBuffer(sb->m_sound_index);
-
- ASSERT(m_mixer_type != SOUND_MIXER_SOFTWARE_16);
-
- if (!source_sb) {
- Int3();
- return false;
- }
-
- // we have a source sound buffer. let's use it.
- if (m_mixer_type == SOUND_MIXER_AUREAL) {
- sb->m_snd_obj = A3D_DuplicateSource(source_sb->m_snd_obj);
- if (!sb->m_snd_obj) {
- return false;
- }
- } else {
- HRESULT hr;
- hr = m_lp_ds->DuplicateSoundBuffer(source_sb->m_sound_buffer, &sb->m_sound_buffer);
- if (FAILED(hr)) {
- mprintf(0, "DDSNDLIB: Failed to duplicate sound buffer (%x)\n", hr);
- return false;
- }
-
- if (IS_3D_MIXER(m_mixer_type)) {
- // a 3d buffer needs a 3d interface pointer
- if (sb->m_buffer_type == SBT_3D) {
- hr = sb->m_sound_buffer->QueryInterface(IID_IDirectSound3DBuffer, (void **)&sb->m_sound_buffer_3d);
- if (FAILED(hr)) {
- mprintf(0, "DDSNDLIB: Failed to acquire 3d interface from duplicate buffer (%x)\n", hr);
- return false;
- }
- }
- }
- }
-
- sb->m_mixer_type = source_sb->m_mixer_type;
- sb->bps = source_sb->bps;
- sb->stereo = source_sb->stereo;
- sb->sample_data = source_sb->sample_data;
- sb->sample_length = source_sb->sample_length;
-
- // mprintf(0, "Duplicated!!\n");
- SoundFiles[Sounds[sb->m_sound_index].sample_index].use_count++;
-
- return true;
- */
-}
-
-// environmental sound interface
-// volume modifier (0-1), damping(0-1), 1 = complete, 0 = none
-// decay 0.1 to 100 seconds, how long it takes for a sound to die.
-bool win_llsSystem::SetGlobalReverbProperties(float volume, float damping, float decay) {
- if (m_mixer_type == SOUND_MIXER_CREATIVE_EAX) {
- return EAX_SetEnvironmentalReverb(volume, damping, decay);
- }
-
- return false;
-}
-
-sound_buffer_info *sound_buffer_cache::FindSoundBuffer(int sound_index) {
- int i;
-
- // is there's no use count for this soudn, then there should be no available buffer.
- if (SoundFiles[Sounds[sound_index].sample_index].use_count == 0) {
- return NULL;
- }
-
- // returns a sound buffer with the 'sound_index' if it is still active.
- // we can use the sound buffer to create duplicates.
- for (i = 0; i < m_max_sounds_played; i++) {
- sound_buffer_info *sb = &m_sound_cache[i];
-
- if (sb->m_status != SSF_UNUSED) {
- if (sb->m_sound_index == sound_index) {
- return sb;
- }
- }
- }
-
- return NULL;
-}
-
-// set special parameters for the 3d environment.
-// of strcuture passed, you must set the appropriate 'flags' value for values you wish to modify
-void win_llsSystem::SetEnvironmentValues(const t3dEnvironmentValues *env) {
- if (CHECK_FLAG(env->flags, ENV3DVALF_DOPPLER)) {
- Env3dValues.doppler_scalar = env->doppler_scalar;
- }
-}
-
-// get special parameters for the 3d environment.
-// of strcuture passed, you must set the appropriate 'flags' value for values you wish to modify
-void win_llsSystem::GetEnvironmentValues(t3dEnvironmentValues *env) {
- if (CHECK_FLAG(env->flags, ENV3DVALF_DOPPLER)) {
- env->doppler_scalar = Env3dValues.doppler_scalar;
- }
-}
-
-// enable special parameters for the 3d environment.
-// of strcuture passed, you must set the appropriate 'flags' value for values you wish to modify
-void win_llsSystem::SetEnvironmentToggles(const t3dEnvironmentToggles *env) {
- t3dEnvironmentValues values;
-
- if (CHECK_FLAG(env->flags, ENV3DVALF_DOPPLER)) {
- // set toggle then set doppler again.
- Env3dToggles.doppler = env->doppler;
- values.flags = ENV3DVALF_DOPPLER;
- values.doppler_scalar = Env3dValues.doppler_scalar;
- SetEnvironmentValues(&Env3dValues);
- }
- if (CHECK_FLAG(env->flags, ENV3DVALF_GEOMETRY)) {
- // initialize geometry object if available and true.
- if (m_geometry) {
- delete m_geometry;
- }
- m_geometry = NULL;
- Env3dToggles.geometry = m_geometry ? true : false;
- }
-}
-
-// get states of special parameters for the 3d environment.
-// of strcuture passed, you must set the appropriate 'flags' value for values you wish to modify
-void win_llsSystem::GetEnvironmentToggles(t3dEnvironmentToggles *env) {
- if (CHECK_FLAG(env->flags, ENV3DVALF_DOPPLER)) {
- env->doppler = Env3dToggles.doppler;
- }
-
- env->supported = 0;
-}
-
-// Sound System Error Handler.
-void win_llsSystem::CheckForErrors() {
- // if a fatal error occurred, quit and display an error
- // non fatal errors should be put inside a logfile, or just mprinted out.
- switch (m_lib_error_code) {
- case SSL_ERROR_SAMPLE_NODATA:
- Error("%s\nSample had no data.", m_error_text);
- break;
-
- case SSL_ERROR_STREAMMIXER:
- Error("%s\nMixer alignment check failed.", m_error_text);
- break;
-
- case SSL_ERROR_GENERIC:
- Error("%s\nGeneric error.", m_error_text);
- break;
- }
-
- // must call!
- llsSystem::CheckForErrors();
-
- // add our default error string.
- char buf[8];
- sprintf(buf, "mix:%d\n", m_mixer_type);
- strcat(m_error_text, buf);
-}
-
-/////////////////////////////////////////////////////////////////////////////////////
-// set auxillary 3d sound properties
-bool win_llsSystem::SoundPropertySupport() const {
- switch (m_mixer_type) {
- case SOUND_MIXER_CREATIVE_EAX:
- if (EAX_Caps() & EAXF_SOURCE_OBSTRUCTION) {
- return true;
- }
- break;
- }
-
- return false;
-}
-
-// sound obstruction from 0 to 1.0 (1.0 = fully obstructed)
-void win_llsSystem::SetSoundProperties(int sound_uid, float obstruction) {
- sound_buffer_info *sb;
- int current_slot;
-
- if (!m_f_sound_lib_init)
- return;
-
- if ((current_slot = ValidateUniqueId(sound_uid)) == -1)
- return;
-
- sb = &m_sound_mixer.m_sound_cache[current_slot];
-
- switch (m_mixer_type) {
- case SOUND_MIXER_CREATIVE_EAX:
- EAX_SetSourceProperties(sb->m_lpksps, obstruction);
- break;
- }
-}
diff --git a/sndlib/dsound3d.cpp b/sndlib/dsound3d.cpp
deleted file mode 100644
index 4af8c3b4..00000000
--- a/sndlib/dsound3d.cpp
+++ /dev/null
@@ -1,616 +0,0 @@
-/*
-* Descent 3
-* Copyright (C) 2024 Parallax Software
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see .
-
---- HISTORICAL COMMENTS FOLLOW ---
-
- * $Source: $
- * $Revision: 6 $
- * $Author: Samir $
- * $Date: 5/03/99 3:12a $
- *
- * Direct Sound subsystem.
- *
- * $Log: /DescentIII/Main/dd_sndlib/dsound3d.cpp $
- *
- * 6 5/03/99 3:12a Samir
- * fixed up aureal so it works (a little slow though...)
- *
- * 5 4/29/99 3:01p Samir
- * added code for direct sound mixers only (and function for Aureal
- * really) that will use direct sound looping for simple loops.
- *
- * 4 4/25/99 9:53p Samir
- * added debugging.
- *
- * 3 4/23/99 7:51p Samir
- * looping fixes for directsound.
- *
- * 2 4/22/99 10:33p Samir
- * modifications so that DirectSound mixers use one thread for all looping
- * and streaming sounds. It worked without crashing for about twenty
- * minutes of playing from level 1 to level 2 of D3. We'll see.
- *
- * 1 4/22/99 10:30p Samir
- * initial revision ( a bit messy)
- *
- */
-
-#include "ds3dlib_internal.h"
-#include "auddev.h"
-
-#include "pserror.h"
-
-#include
-
-static struct t_sb_loop_thread_data {
- win_llsSystem *m_ll_sndsys;
- uintptr_t thread_handle;
- int16_t no_callbacks;
- bool request_kill;
- bool thread_alive;
-} m_ds;
-
-static uint8_t m_sb_cur_timeslice;
-
-////////////////////////////////////////////////////////////////////////////////
-// DSLOOP_STREAM_METHOD
-
-inline void sb_loop_thread_clean_buffer(sound_buffer_info *sb) {
- m_ds.m_ll_sndsys->GetSoundPos(sb->m_unique_id);
- sb_stop_buffer(sb);
- sb->s->playing = 0;
- sb->s->kill_me = true;
-
- // TODO: investigate why this is -1 sometimes, 32bit builds seem to work by
- // chance while 64bit builds crash without this ckeck
- if (sb->m_sound_index < 0) {
- return;
- }
-
- if (SoundFiles[Sounds[sb->m_sound_index].sample_index].use_count > 0) {
- SoundFiles[Sounds[sb->m_sound_index].sample_index].use_count--;
- // DUPSND if (SoundFiles[Sounds[sb->m_sound_index].sample_index].use_count == 0) {
- // Global_DS_alloced_sounds--;
- // DUPSND }
- }
-}
-
-// helper functions for loop streaming.
-void sb_loop_stream_copy(sound_buffer_info *sb, char *ptr, DWORD len) {
- DWORD amt;
- bool f_looping = (sb->m_status & SSF_PLAY_LOOPING) != 0;
- char *sample_ptr;
-
- if (f_looping) {
- const int sound_index = sb->m_sound_index;
- int loop_start = Sounds[sound_index].loop_start;
- int loop_end = Sounds[sound_index].loop_end;
- if (sb->s->f_sample_16bit) {
- loop_start = loop_start << 1;
- loop_end = loop_end << 1;
- sample_ptr = (char *)SoundFiles[Sounds[sound_index].sample_index].sample_16bit;
- } else {
- sample_ptr = (char *)SoundFiles[Sounds[sound_index].sample_index].sample_8bit;
- }
-
- while (sb->s->num_written + (int)len >= loop_end) {
- int num_till_loop_end = loop_end - sb->s->num_written;
- int num_to_loop_start = sb->s->num_written - loop_start;
-
- if (num_till_loop_end > 0) {
- memcpy(ptr, sb->s->current_position, num_till_loop_end);
- len -= num_till_loop_end;
- }
- ptr += num_till_loop_end;
-
- sb->s->current_position = sample_ptr + loop_start;
- // ASSERT(sb->s->current_position >= sample_ptr && sample_ptr == sb->sample_data);
-
- sb->s->num_written -= num_to_loop_start;
- sb->s->bytes_left += num_to_loop_start;
-
- // ASSERT(sb->s->num_written == loop_start);
- }
- }
-
- amt = (len > sb->s->bytes_left) ? sb->s->bytes_left : len;
-
- // int i_amt = (int)amt;
-
- // ASSERT(i_amt >= 0);
-
- if (amt) {
- memcpy(ptr, sb->s->current_position, amt);
- sb->s->current_position += amt;
- sb->s->bytes_left -= amt;
- sb->s->num_written += amt;
- // ASSERT(sb->s->current_position >= sb->sample_data);
- }
-
- len -= amt;
-
- if (len) {
- memset(ptr + amt, sb->s->silence_byte, len);
- sb->s->close_on_next = 1;
- }
-}
-
-// helper functions for loop streaming.
-void sb_loop_stream_fillhalf(sound_buffer_info *sb, DWORD half) {
- char *ptr1 = NULL;
- char *ptr2 = NULL;
- uint32_t len1, len2;
-
- if (sb_lock_buffer(sb, half, sb->s->half_buffer_point, (void **)&ptr1, &len1, (void **)&ptr2, &len2)) {
- // memset(ptr1, sb->s->silence_byte, len1);
- sb_loop_stream_copy(sb, ptr1, len1);
- if (ptr2) {
- sb_loop_stream_copy(sb, ptr2, len2);
- }
- sb_unlock_buffer(sb, ptr1, len1, ptr2, len2);
- }
-}
-
-// helper functions for streaming
-void sb_stream_copy(sound_buffer_info *sb, char *ptr, DWORD len) {
- DWORD amt;
-
-new_data:
-
- amt = (len > sb->s->bytes_left) ? sb->s->bytes_left : len;
-
- ASSERT(amt >= 0);
-
- if (amt) {
- ASSERT(sb->s->current_position);
-
- memcpy(ptr, sb->s->current_position, amt);
- sb->s->current_position += amt;
- sb->s->bytes_left -= amt;
- }
-
- len -= amt;
-
- if (len) {
- if (sb->play_info->m_stream_cback && sb->s->current_position) {
- memset(ptr + amt, sb->s->silence_byte, len);
- int new_len = sb->play_info->m_stream_size;
- sb->s->current_position =
- (char *)(*sb->play_info->m_stream_cback)(sb->play_info->user_data, sb->play_info->m_stream_handle, &new_len);
- sb->play_info->m_stream_data = sb->s->current_position;
- ASSERT(!(sb->play_info->m_stream_data && sb->play_info->m_stream_size <= 0));
-
- sb->s->bytes_left = sb->play_info->m_stream_size;
-
- if (sb->s->current_position == NULL) {
- sb->s->bytes_left = sb->play_info->m_stream_size = 0;
- }
-
- goto new_data;
- }
-
- memset(ptr + amt, sb->s->silence_byte, len);
- sb->s->close_on_next = 1;
- }
-}
-
-void sb_stream_fillhalf(sound_buffer_info *sb, DWORD half) {
- char *ptr1 = NULL;
- char *ptr2 = NULL;
- uint32_t len1, len2;
-
- if (sb_lock_buffer(sb, half, sb->s->half_buffer_point, (void **)&ptr1, &len1, (void **)&ptr2, &len2)) {
- sb_stream_copy(sb, ptr1, len1);
- if (ptr2) {
- sb_stream_copy(sb, ptr2, len2);
- }
- sb_unlock_buffer(sb, ptr1, len1, ptr2, len2);
- }
-}
-
-// main looping thread.
-void __cdecl sb_loop_thread(void *user_ptr) {
- sound_buffer_cache *sndcache;
- DWORD playp, writep, whichhalf;
- int i;
- uint8_t iteration;
-
- // validate thread
- m_ds.m_ll_sndsys = (win_llsSystem *)user_ptr;
- m_ds.thread_alive = true;
- sndcache = &m_ds.m_ll_sndsys->m_sound_mixer;
- iteration = 0;
-
- mprintf(0, "DS3DLIB: Looping thread begins.\n");
-
- // main thread body
- while (!m_ds.request_kill) {
- if (m_ds.no_callbacks++ == 0) {
- for (i = 0; i < sndcache->m_max_sounds_played; i++) {
- sound_buffer_info *sb = &sndcache->m_sound_cache[i];
-
- // skip unused slots and only handle looping (maybe streaming) slots.
- if ((sb->m_status == SSF_UNUSED) || (sb->m_status & SSF_BUFFERED_LOOP) || !sb->s) {
- continue;
- }
- if (!sb->s->playing) { // loops before calling play do have SSF_PLAY_LOOPING set, and MUST!!
- continue;
- }
-
- // at this point it's definitely either a streaming buffer or loop streaming buffer
- if (sb->m_status & SSF_PLAY_STREAMING) {
- // streams will stop at the request of the application always, unlike looping buffers (see below)
- if (sb->s->please_close) {
- sb_loop_thread_clean_buffer(sb);
- // mprintf(0, "ds thread pleas_close request processed.\n");
- } else if (sb->m_status & SSF_PAUSED) {
- continue; // just continue
- } else if ((iteration % 4) == (sb->s->time_slice % 4)) {
- // update streamed buffer only when allowed
- playp = sb_get_current_position(sb, (uint32_t *)&writep);
- whichhalf = (playp < sb->s->half_buffer_point) ? 0 : sb->s->half_buffer_point;
-
- if (whichhalf != sb->s->last_half) {
- if (sb->s->close_on_next) {
- sb_loop_thread_clean_buffer(sb);
- } else {
- sb_stream_fillhalf(sb, sb->s->last_half);
- sb->s->last_half = whichhalf;
- }
- }
- // mprintf(0, "ds thread stream update.\n");
- }
- } else if (!(sb->m_status & SSF_BUFFERED_LOOP)) {
- // this slot is a looping slot. check to see if app requested closing this loop.
- // also we don't check the looping flag because we could be playing the end part of a loop
- // and the stream filling code below will set close_on_next when done itself.
- if (sb->s->please_close) {
- sb_loop_thread_clean_buffer(sb);
- } else if (sb->m_status & SSF_PAUSED) {
- continue; // just continue
- } else if ((iteration % 4) == (sb->s->time_slice % 4)) {
- // update looped buffer only when allowed
- playp = sb_get_current_position(sb, (uint32_t *)&writep);
- whichhalf = (playp < sb->s->half_buffer_point) ? 0 : sb->s->half_buffer_point;
-
- if (whichhalf != sb->s->last_half) {
- if (sb->s->close_on_next) {
- sb_loop_thread_clean_buffer(sb);
- } else {
- sb_loop_stream_fillhalf(sb, sb->s->last_half);
- sb->s->last_half = whichhalf;
- }
- }
- }
- }
- }
- iteration++;
- }
- m_ds.no_callbacks--;
- Sleep(DSPB_TICK_MILLISECONDS); // defer to OS
- }
-
- // invalidate thread
- m_ds.thread_alive = false;
- m_ds.m_ll_sndsys = NULL;
- mprintf(0, "DS3DLIB: Looping thread done.\n");
-}
-
-///////////////////////////////////////////////////////////////////////////////
-// this will initialize the looping thread
-
-bool sb_loop_thread_init(win_llsSystem *lls) {
- // start looping thread
- m_sb_cur_timeslice = 0;
-
- m_ds.request_kill = false;
- m_ds.thread_alive = false;
- m_ds.no_callbacks = 1;
-
- m_ds.thread_handle = _beginthread(sb_loop_thread, 16384, (void *)lls);
- if (m_ds.thread_handle == -1) {
- return false;
- }
- if (!SetThreadPriority((HANDLE)m_ds.thread_handle, THREAD_PRIORITY_TIME_CRITICAL)) {
- return false;
- }
-
- m_ds.no_callbacks = 0;
-
- return true;
-}
-
-void sb_loop_thread_kill() {
- if (m_ds.thread_alive) {
- mprintf(0, "DS3DLIB: Killing looping thread.\n");
- m_ds.request_kill = true;
- while (m_ds.thread_alive) {
- Sleep(DSPB_TICK_MILLISECONDS);
- }
- }
-}
-
-// a lot of looping info will be initialized here, including copying data, etc.
-bool sb_loop_element_init(sound_buffer_info *sb, char *sample_ptr, int sound_length, int buffer_size) {
- // finish initting loop
- if (!sb->s) {
- Int3();
- return false;
- }
-
- sb->s->time_slice = m_sb_cur_timeslice; // allocate timeslice for updating.
- sb->s->half_buffer_point = buffer_size / 2;
- sb->s->current_position = sample_ptr;
- sb->s->bytes_left = sound_length;
- sb->s->silence_byte = (sb->s->f_sample_16bit) ? 0 : 128;
- sb_loop_stream_fillhalf(sb, 0);
- sb_loop_stream_fillhalf(sb, sb->s->half_buffer_point);
-
- sb->s->close_on_next = 0;
- sb->s->kill_me = false;
- m_ds.m_ll_sndsys->SetSoundPos(sb->m_unique_id, sb->play_info->m_samples_played);
-
- m_sb_cur_timeslice++;
-
- return true;
-}
-
-void sb_loop_element_kill(sound_buffer_info *sb) { sb->s->please_close = 1; }
-
-void sb_loop_element_wait_until_dead(sound_buffer_info *sb) {
- if (!sb->s)
- return;
-
- while (!sb->s->kill_me) {
- }
-}
-
-// initialize streaming audio.
-bool sb_stream_element_init(sound_buffer_info *sb, char *sample_ptr, int sound_length, int buffer_size) {
- // finish initting loop
- if (!sb->s) {
- Int3();
- return false;
- }
-
- sb->s->time_slice = m_sb_cur_timeslice; // allocate timeslice for updating.
-
- sb->s->half_buffer_point = buffer_size / 2;
- sb->s->current_position = sample_ptr;
- sb->s->bytes_left = sound_length;
- sb->s->silence_byte = (sb->s->f_sample_16bit) ? 0 : 128;
- sb_stream_fillhalf(sb, 0);
- sb_stream_fillhalf(sb, sb->s->half_buffer_point);
- sb->s->close_on_next = 0;
- sb->s->kill_me = false;
-
- if (sb->m_status & SSF_BUFFERED_STRM) {
- sb->s->hEvent = NULL;
- /* sb->s->hEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
- if (sb->m_mixer_type == SOUND_MIXER_AUREAL) {
- if (!A3D_SetSourceWaveEvent(sb->m_snd_obj, sb->s->half_buffer_point, sb->s->hEvent)) {
- CloseHandle(sb->s->hEvent);
- sb->s->hEvent = NULL;
- return false;
- }
- }
- else {
- Int3();
- // unimplemented for normal DirectSound CloseHandle(sb->s->hEvent); sb->s->hEvent = NULL;
- }
- */
- }
-
- m_sb_cur_timeslice++;
-
- return true;
-}
-
-// these work on buffered streams only
-void sb_stream_element_kill(sound_buffer_info *sb) {
- if (sb->m_status & SSF_BUFFERED_STRM) {
- if (sb->s->hEvent) {
- CloseHandle(sb->s->hEvent);
- sb->s->hEvent = NULL;
- }
- }
-}
-
-void sb_stream_buffered_update(sound_buffer_info *sb) {
- DWORD playp, writep, whichhalf;
- ASSERT((sb->m_status & SSF_BUFFERED_STRM));
-
- playp = sb_get_current_position(sb, (uint32_t *)&writep);
- whichhalf = (playp < sb->s->half_buffer_point) ? 0 : sb->s->half_buffer_point;
-
- if (whichhalf != sb->s->last_half) {
- // mprintf(0, "DSOUND3D: event triggered. Updating stream half %d.\n", sb->s->last_half);
- if (sb->s->close_on_next) {
- extern win_llsSystem *ll_sound_ptr;
- ll_sound_ptr->StopSound(sb->m_unique_id);
- } else {
- sb_stream_fillhalf(sb, sb->s->last_half);
- sb->s->last_half = whichhalf;
- }
- }
-
- /* if (WaitForSingleObject(sb->s->hEvent, 0) == WAIT_OBJECT_0) {
- // event was signaled by DirectSound/Aureal. do appropriate stream fill.
- if (sb->s->close_on_next) {
- extern win_llsSystem *ll_sound_ptr;
- ll_sound_ptr->StopSound(sb->m_unique_id);
- }
- else {
- mprintf(0, "DSOUND3D: event triggered. Updating stream half %d.\n", sb->s->last_half);
- A3D_ClearSourceWaveEvents(sb->m_snd_obj);
- sb_stream_fillhalf(sb, sb->s->last_half);
- sb->s->last_half = (sb->s->last_half) ? 0 : sb->s->half_buffer_point;
- ResetEvent(sb->s->hEvent);
- if (sb->m_mixer_type == SOUND_MIXER_AUREAL) {
- A3D_SetSourceWaveEvent(sb->m_snd_obj, sb->s->last_half, sb->s->hEvent);
- }
- else {
- Int3();
- }
- }
- }
- */
-}
-
-////////////////////////////////////////////////////////////////////////////////
-// DSLOOP_BUFFER_METHOD
-
-char *sb_get_loop_info(const sound_buffer_info *sb, int *loop_start, int *loop_end, bool *is_16_bit) {
- int sound_index = sb->m_sound_index;
-
- if (sound_index > -1) {
- *loop_start = Sounds[sound_index].loop_start;
- *loop_end = Sounds[sound_index].loop_end;
-
- if (SoundFiles[Sounds[sound_index].sample_index].sample_16bit) {
- *is_16_bit = true;
- return (char *)SoundFiles[Sounds[sound_index].sample_index].sample_16bit;
- }
- if (SoundFiles[Sounds[sound_index].sample_index].sample_8bit) {
- *is_16_bit = false;
- return (char *)SoundFiles[Sounds[sound_index].sample_index].sample_8bit;
- }
- }
- Int3();
- return NULL;
-}
-
-char *sb_get_loop_step_info(const sound_buffer_info *sb, int step, bool is16bit, int *length) {
- sound_file_info *sf;
- char *sample_ptr;
-
- if (sb->m_sound_index < 0) {
- Int3();
- return NULL;
- }
-
- int loop_start_byte = Sounds[sb->m_sound_index].loop_start;
- int loop_end_byte = Sounds[sb->m_sound_index].loop_end;
-
- if (is16bit) {
- loop_start_byte = loop_start_byte << 1;
- loop_end_byte = loop_end_byte << 1;
- }
-
- sf = &SoundFiles[Sounds[sb->m_sound_index].sample_index];
- sample_ptr = is16bit ? (char *)sf->sample_16bit : (char *)sf->sample_8bit;
-
- if (step == DSBUFLOOP_INIT_STEP) {
- *length = loop_start_byte;
- return sample_ptr;
- }
- if (step == DSBUFLOOP_LOOP_STEP) {
- *length = (loop_end_byte - loop_start_byte);
- return (sample_ptr + loop_start_byte);
- }
- if (step == DSBUFLOOP_FINISH_STEP) {
- int sample_length_byte = is16bit ? (sf->np_sample_length * 2) : sf->np_sample_length;
- *length = (sample_length_byte - loop_end_byte);
- return (sample_ptr + loop_end_byte);
- }
-
- Int3(); // illegal step!!
- *length = 0;
-
- return NULL;
-}
-
-// steps to next state of buffered loop.
-// force_next_step = -2, do it automatically, otherwise set 'next_step' using passed value.
-// this will stop and free the current ds object
-// advance to next valid step (may skip a step)
-// if new step is > 1, then we're done.
-// else create and play the new one if we can.
-
-// before destroying old object, we must get the current sound properties depending on buffer type.
-// and set them for the new sound object.
-// we will call either direct sound or custom mixer functions.
-// yuck.
-
-void sb_buffered_loop_step(win_llsSystem *lls, sound_buffer_info *sb, int force_next_step) {
- if (!sb->s)
- return;
- if (!(sb->m_status & SSF_BUFFERED_LOOP))
- return;
-
- tPSBInfo psb;
- char *sample_ptr;
- int sound_length;
-
- pos_state old_pos_state;
- float old_pan;
- float old_volume = 0.0f;
-
- ASSERT(lls->m_mixer_type != SOUND_MIXER_SOFTWARE_16 && lls->m_mixer_type != SOUND_MIXER_NONE);
-
- // get current properties.
- old_pan = 0;
-
- // advance to next step.
- sound_length = 0;
- sb->s->loop_step = (force_next_step == -2) ? (sb->s->loop_step + 1) : force_next_step;
- while (!sound_length && sb->s->loop_step < 2) {
- sample_ptr = sb_get_loop_step_info(sb, sb->s->loop_step, sb->s->f_sample_16bit, &sound_length);
- sb->s->loop_step++;
- }
- if (!sound_length && sb->s->loop_step == 2) {
- // mprintf(0, "DS3DLIB: Buffered loop %d advancing to post-end step (done)\n", sb->m_unique_id);
- lls->StopSound(sb->m_unique_id);
- return;
- } else {
- sb_stop_buffer(sb);
- sb_free_buffer(sb);
- }
-
- sb->s->loop_step--; // return to proper step.
- sb->s->loop_timer = 0.0f;
- sb->s->bytes_left = sound_length;
- sb->m_status = SSF_PLAY_LOOPING | SSF_BUFFERED_LOOP;
- sb->sample_data = sample_ptr;
-
- // allocate buffer for playback
- if (!lls->CreateSoundBuffer(sb, false, sb->s->bytes_left, true)) {
- return;
- }
-
- if (!sb_load_buffer(sb, sb->sample_data, sound_length)) {
- return;
- }
-
- // using old sound properties, play the next buffer with those qualities!
- psb.looping = (sb->s->loop_step == 0) ? true : false;
-
- if (sb->m_buffer_type == SBT_3D) {
- psb.cur_pos = &old_pos_state;
- } else {
- psb.pan = old_pan;
- }
-
- psb.volume = old_volume;
- psb.freq = 22050;
- lls->PlaySoundBuffer(sb, &psb);
-
- // must be at end to initiate thread management.
- sb->s->playing = 1;
-
- // mprintf(0, "DDSNDLIB: Buffered loop %d advancing to step %d.\n", sb->m_unique_id, sb->s->loop_step);
-}
diff --git a/sndlib/eax.cpp b/sndlib/eax.cpp
deleted file mode 100644
index 823c7739..00000000
--- a/sndlib/eax.cpp
+++ /dev/null
@@ -1,335 +0,0 @@
-/*
-* Descent 3
-* Copyright (C) 2024 Parallax Software
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see .
-
---- HISTORICAL COMMENTS FOLLOW ---
-
- * $Source: $
- * $Revision: 10 $
- * $Author: Samir $
- * $Date: 9/27/99 5:38p $
- *
- *
- *
- * $Log: /DescentIII/Main/dd_sndlib/eax.cpp $
- *
- * 10 9/27/99 5:38p Samir
- * EAX 2.0->1.0 compatibility checkin.
- *
- * 9 8/24/99 3:42p Samir
- * load EAX dynamically
- *
- * 8 8/24/99 1:47p Samir
- * updated header file.
- *
- * 7 8/23/99 5:29p Samir
- * incremental EAX 2.0 checkin
- *
- * 6 1/11/99 5:54p Samir
- * made environment a hangar.
- *
- * 5 1/11/99 5:52p Samir
- * updated EAX support.
- *
- * 4 1/08/99 6:31p Samir
- * added reverb
- *
- * 3 12/23/98 11:50a Samir
- *
- * 2 12/23/98 11:48a Samir
- * basic functionality.
- *
- * 1 12/21/98 7:06p Samir
- * Creative Labs EAX
- *
- */
-
-#include "auddev.h"
-
-#include
-#include
-
-#include "eax.h"
-#include "eax2.h"
-#include "pserror.h"
-
-// DATA
-#define EAX_ENVIRONMENTS_AVAILABLE (1 << 0)
-#define VOICE_MANAGMENT_AVAILABLE (1 << 1)
-
-struct {
- HINSTANCE m_dll;
- LPDIRECTSOUND m_lpds;
- LPDIRECTSOUNDBUFFER m_lpdsb;
- LPKSPROPERTYSET m_lpksps;
- DWORD m_dwSoundProperties;
- VmMode m_vmode;
- EAX_REVERBPROPERTIES m_preset;
-} EAX = {NULL, NULL, 0, 0, 0};
-
-const EAX_REVERBPROPERTIES EAX_Environments[EAX_ENVIRONMENT_COUNT] = {
- {EAX_PRESET_GENERIC}, {EAX_PRESET_PADDEDCELL}, {EAX_PRESET_ROOM}, {EAX_PRESET_BATHROOM},
- {EAX_PRESET_LIVINGROOM}, {EAX_PRESET_STONEROOM}, {EAX_PRESET_AUDITORIUM}, {EAX_PRESET_CONCERTHALL},
- {EAX_PRESET_CAVE}, {EAX_PRESET_ARENA}, {EAX_PRESET_HANGAR}, {EAX_PRESET_CARPETEDHALLWAY},
- {EAX_PRESET_HALLWAY}, {EAX_PRESET_STONECORRIDOR}, {EAX_PRESET_ALLEY}, {EAX_PRESET_FOREST},
- {EAX_PRESET_CITY}, {EAX_PRESET_MOUNTAINS}, {EAX_PRESET_QUARRY}, {EAX_PRESET_PLAIN},
- {EAX_PRESET_PARKINGLOT}, {EAX_PRESET_SEWERPIPE}, {EAX_PRESET_UNDERWATER}, {EAX_PRESET_DRUGGED},
- {EAX_PRESET_DIZZY}, {EAX_PRESET_PSYCHOTIC}};
-
-// FUNCTIONS
-
-HRESULT(FAR PASCAL *DLLEAXDirectSoundCreate)(GUID *, LPDIRECTSOUND *, IUnknown FAR *) = NULL;
-
-// EAX 1.0 support.
-bool EAX_SetEnvironmentPreset(unsigned environment);
-bool EAX_SetEnvironmentalReverb(float volume, float damping, float decay);
-
-// CODE
-bool EAX_Create(GUID *pGuid, LPDIRECTSOUND *lpds) {
- HRESULT hr;
-
- EAX.m_dll = LoadLibrary("eax.dll");
- if (EAX.m_dll) {
- DLLEAXDirectSoundCreate = (LPEAXDIRECTSOUNDCREATE)GetProcAddress(EAX.m_dll, "EAXDirectSoundCreate");
- if (!DLLEAXDirectSoundCreate) {
- Error("EAX DLL doesn't contain latest code for 2.0 functionality.");
- return false;
- }
-
- mprintf(0, "EAX 2.0 support detected.\n");
- hr = (*DLLEAXDirectSoundCreate)(pGuid, &EAX.m_lpds, NULL);
- } else {
- mprintf(0, "EAX 1.0 support detected.\n");
- hr = DirectSoundCreate(pGuid, &EAX.m_lpds, NULL);
- }
-
- if (hr != DS_OK) {
- *lpds = NULL;
- return false;
- }
- EAX.m_lpdsb = NULL;
- EAX.m_dwSoundProperties = 0;
-
- *lpds = EAX.m_lpds;
-
- return true;
-}
-
-void EAX_Destroy() {
- if (EAX.m_lpds) {
- if (EAX.m_lpksps != NULL) {
- EAX.m_lpksps->Release();
- EAX.m_lpksps = NULL;
- }
- if (EAX.m_lpdsb) {
- EAX.m_lpdsb->Release();
- EAX.m_lpdsb = NULL;
- }
- EAX.m_lpds->Release();
- EAX.m_lpds = NULL;
- }
- if (EAX.m_dll) {
- FreeLibrary(EAX.m_dll);
- EAX.m_dll = NULL;
- DLLEAXDirectSoundCreate = NULL;
- }
- EAX.m_dwSoundProperties = 0;
-}
-
-// returns EAX caps
-int EAX_Caps() { return EAX.m_dwSoundProperties; }
-
-// initializes EAX specific interfaces.
-bool EAX_SetPrimaryBuffer() {
- HRESULT hr;
- DWORD support;
- bool retval = true;
- WAVEFORMATEX wave;
- DSBUFFERDESC dsbdesc;
- EAX_REVERBPROPERTIES props = {EAX_PRESET_HANGAR};
-
- ASSERT(EAX.m_lpds);
-
- memset(&wave, 0, sizeof(WAVEFORMATEX));
- wave.wFormatTag = WAVE_FORMAT_PCM;
- wave.nChannels = 2;
- wave.nSamplesPerSec = 22050;
- wave.wBitsPerSample = 16;
- wave.nBlockAlign = wave.wBitsPerSample / 8 * wave.nChannels;
- wave.nAvgBytesPerSec = wave.nSamplesPerSec * wave.nBlockAlign;
-
- memset(&dsbdesc, 0, sizeof(DSBUFFERDESC));
- dsbdesc.dwSize = sizeof(DSBUFFERDESC);
- dsbdesc.dwFlags = DSBCAPS_STATIC | DSBCAPS_CTRL3D;
- dsbdesc.dwBufferBytes = DSBSIZE_MIN * 2;
- dsbdesc.lpwfxFormat = &wave;
-
- if (FAILED(EAX.m_lpds->CreateSoundBuffer(&dsbdesc, &EAX.m_lpdsb, NULL))) {
- return false;
- }
-
- if (EAX.m_lpksps == NULL) {
- if (FAILED(EAX.m_lpdsb->QueryInterface(IID_IKsPropertySet, (LPVOID *)&EAX.m_lpksps))) {
- mprintf(0, "EAX: Error failed to query property set interface.\n");
- Int3();
- retval = false;
- goto error_sub;
- }
- }
-
- // now, query support depending on EAX 2.0 availability
- if (EAX.m_dll) {
- hr = EAX.m_lpksps->QuerySupport(DSPROPSETID_EAX_ListenerProperties, DSPROPERTY_EAXLISTENER_ENVIRONMENT, &support);
- if (SUCCEEDED(hr)) {
- if ((support & (KSPROPERTY_SUPPORT_SET | KSPROPERTY_SUPPORT_GET)) ==
- (KSPROPERTY_SUPPORT_SET | KSPROPERTY_SUPPORT_GET)) {
- EAX.m_dwSoundProperties |= EAX_ENVIRONMENTS_AVAILABLE;
- }
- }
-
- hr = EAX.m_lpksps->QuerySupport(DSPROPSETID_EAX_BufferProperties, DSPROPERTY_EAXBUFFER_OBSTRUCTION, &support);
- if (SUCCEEDED(hr)) {
- if ((support & (KSPROPERTY_SUPPORT_SET | KSPROPERTY_SUPPORT_GET)) ==
- (KSPROPERTY_SUPPORT_SET | KSPROPERTY_SUPPORT_GET)) {
- EAX.m_dwSoundProperties |= EAXF_SOURCE_OBSTRUCTION;
- }
- }
- } else {
- hr = EAX.m_lpksps->QuerySupport(DSPROPSETID_EAX_ReverbProperties, DSPROPERTY_EAX_ALL, &support);
- if (SUCCEEDED(hr)) {
- if ((support & KSPROPERTY_SUPPORT_SET | KSPROPERTY_SUPPORT_GET) ==
- (KSPROPERTY_SUPPORT_SET | KSPROPERTY_SUPPORT_GET)) {
- EAX.m_dwSoundProperties |= EAX_ENVIRONMENTS_AVAILABLE;
- /*
- Here the reverb environment is initialized to off.
- */
- EAX_SetEnvironmentPreset(EAX_ENVIRONMENT_HANGAR);
- }
- }
- }
-
- retval = (EAX.m_dwSoundProperties & EAX_ENVIRONMENTS_AVAILABLE) ? true : false;
- EAX_SetEnvironmentalReverb(props.fVolume, props.fDamping, props.fDecayTime_sec);
-
-error_sub:
- if (retval == false) {
- mprintf(0, "EAX: Error failed to query environmental support.\n");
- Int3();
- if (EAX.m_lpksps) {
- EAX.m_lpksps->Release();
- EAX.m_lpksps = NULL;
- }
- }
-
- return retval;
-}
-
-/*
-
- This routine can be used to change the current EAX preset environment. The environment applies
- to all 3D buffers.
-
-*/
-// sets up current global environment reverb
-bool EAX_SetEnvironmentalReverb(float volume, float damping, float decay) {
- if (EAX.m_dwSoundProperties & EAX_ENVIRONMENTS_AVAILABLE) {
- int i;
-
- EAX.m_preset.environment = EAX_ENVIRONMENT_GENERIC;
- EAX.m_preset.fVolume = volume;
- EAX.m_preset.fDecayTime_sec = decay;
- EAX.m_preset.fDamping = damping;
-
- if (EAX.m_dll) {
- for (i = 0; i < EAX_ENVIRONMENT_COUNT; i++) {
- if (volume == EAX_Environments[i].fVolume && damping == EAX_Environments[i].fDamping &&
- decay == EAX_Environments[i].fDecayTime_sec) {
- EAX.m_preset.environment = (uint32_t)i;
- break;
- }
- }
- if (FAILED(EAX.m_lpksps->Set(DSPROPSETID_EAX_ListenerProperties, DSPROPERTY_EAXLISTENER_ENVIRONMENT, NULL, 0,
- &EAX.m_preset.environment, sizeof(uint32_t)))) {
- return false;
- }
- } else {
- if (FAILED(EAX.m_lpksps->Set(DSPROPSETID_EAX_ReverbProperties, DSPROPERTY_EAX_VOLUME, NULL, 0,
- &EAX.m_preset.fVolume, sizeof(float)))) {
- return false;
- }
- if (FAILED(EAX.m_lpksps->Set(DSPROPSETID_EAX_ReverbProperties, DSPROPERTY_EAX_DECAYTIME, NULL, 0,
- &EAX.m_preset.fDecayTime_sec, sizeof(float)))) {
- return false;
- }
- if (FAILED(EAX.m_lpksps->Set(DSPROPSETID_EAX_ReverbProperties, DSPROPERTY_EAX_DAMPING, NULL, 0,
- &EAX.m_preset.fDamping, sizeof(float)))) {
- return false;
- }
- }
-
- return true;
- }
-
- return false;
-}
-
-// intializes a sound source for EAX
-bool EAX_InitSource(LPDIRECTSOUND3DBUFFER lpBuffer3D, LPKSPROPERTYSET *plpksp) {
- if (!lpBuffer3D)
- return true;
-
- if (SUCCEEDED(lpBuffer3D->QueryInterface(IID_IKsPropertySet, (void **)plpksp))) {
- return true;
- }
-
- return false;
-}
-
-// frees an eax sound source
-void EAX_FreeSource(LPKSPROPERTYSET lpksp) {
- if (lpksp) {
- lpksp->Release();
- }
-}
-
-// sets source properties
-void EAX_SetSourceProperties(LPKSPROPERTYSET lpksp, float obstruction) {
- if (!lpksp)
- return;
-
- if (EAX.m_dwSoundProperties & EAXF_SOURCE_OBSTRUCTION) {
- LONG lValue = (DWORD)(-10000 * obstruction);
- lpksp->Set(DSPROPSETID_EAX_BufferProperties, DSPROPERTY_EAXBUFFER_OBSTRUCTION, NULL, 0, &lValue, sizeof(LONG));
- }
-}
-
-/*
-
- This routine can be used to change the current EAX preset environment. The environment applies
- to all 3D buffers.
-
-*/
-// sets up current global environment reverb
-bool EAX_SetEnvironmentPreset(unsigned environment) {
- EAX.m_preset.environment = environment;
-
- if (FAILED(EAX.m_lpksps->Set(DSPROPSETID_EAX_ReverbProperties, DSPROPERTY_EAX_ENVIRONMENT, NULL, 0,
- &EAX.m_preset.environment, sizeof(float)))) {
- return false;
- }
-
- return true;
-}
diff --git a/sndlib/eax.h b/sndlib/eax.h
deleted file mode 100644
index f11b928c..00000000
--- a/sndlib/eax.h
+++ /dev/null
@@ -1,105 +0,0 @@
-/*
-* Descent 3
-* Copyright (C) 2024 Parallax Software
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see .
-*/
-
-
-// EAX.H -- DirectSound Environmental Audio Extensions
-
-#ifndef EAX_H_INCLUDED
-#define EAX_H_INCLUDED
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-
-// EAX (listener) reverb property set {4a4e6fc1-c341-11d1-b73a-444553540000}
-DEFINE_GUID(DSPROPSETID_EAX_ReverbProperties, 0x4a4e6fc1, 0xc341, 0x11d1, 0xb7, 0x3a, 0x44, 0x45, 0x53, 0x54, 0x00,
- 0x00);
-
-enum DSPROPERTY_EAX_REVERBPROPERTY {
- DSPROPERTY_EAX_ALL, // all reverb properties
- DSPROPERTY_EAX_ENVIRONMENT, // standard environment no.
- DSPROPERTY_EAX_VOLUME, // loudness of the reverb
- DSPROPERTY_EAX_DECAYTIME, // how long the reverb lasts
- DSPROPERTY_EAX_DAMPING // the high frequencies decay faster
-};
-
-#define EAX_NUM_STANDARD_PROPERTIES (DSPROPERTY_EAX_DAMPING + 1)
-
-// use this structure for get/set all properties...
-struct EAX_REVERBPROPERTIES {
- uint32_t environment; // 0 to EAX_ENVIRONMENT_COUNT-1
- float fVolume; // 0 to 1
- float fDecayTime_sec; // seconds, 0.1 to 100
- float fDamping; // 0 to 1
-};
-
-// #define EAX_MAX_ENVIRONMENT (EAX_ENVIRONMENT_COUNT - 1)
-
-// presets
-#define EAX_PRESET_GENERIC EAX_ENVIRONMENT_GENERIC, 0.5F, 1.493F, 0.5F
-#define EAX_PRESET_PADDEDCELL EAX_ENVIRONMENT_PADDEDCELL, 0.25F, 0.1F, 0.0F
-#define EAX_PRESET_ROOM EAX_ENVIRONMENT_ROOM, 0.417F, 0.4F, 0.666F
-#define EAX_PRESET_BATHROOM EAX_ENVIRONMENT_BATHROOM, 0.653F, 1.499F, 0.166F
-#define EAX_PRESET_LIVINGROOM EAX_ENVIRONMENT_LIVINGROOM, 0.208F, 0.478F, 0.0F
-#define EAX_PRESET_STONEROOM EAX_ENVIRONMENT_STONEROOM, 0.5F, 2.309F, 0.888F
-#define EAX_PRESET_AUDITORIUM EAX_ENVIRONMENT_AUDITORIUM, 0.403F, 4.279F, 0.5F
-#define EAX_PRESET_CONCERTHALL EAX_ENVIRONMENT_CONCERTHALL, 0.5F, 3.961F, 0.5F
-#define EAX_PRESET_CAVE EAX_ENVIRONMENT_CAVE, 0.5F, 2.886F, 1.304F
-#define EAX_PRESET_ARENA EAX_ENVIRONMENT_ARENA, 0.361F, 7.284F, 0.332F
-#define EAX_PRESET_HANGAR EAX_ENVIRONMENT_HANGAR, 0.5F, 10.0F, 0.3F
-#define EAX_PRESET_CARPETEDHALLWAY EAX_ENVIRONMENT_CARPETEDHALLWAY, 0.153F, 0.259F, 2.0F
-#define EAX_PRESET_HALLWAY EAX_ENVIRONMENT_HALLWAY, 0.361F, 1.493F, 0.0F
-#define EAX_PRESET_STONECORRIDOR EAX_ENVIRONMENT_STONECORRIDOR, 0.444F, 2.697F, 0.638F
-#define EAX_PRESET_ALLEY EAX_ENVIRONMENT_ALLEY, 0.25F, 1.752F, 0.776F
-#define EAX_PRESET_FOREST EAX_ENVIRONMENT_FOREST, 0.111F, 3.145F, 0.472F
-#define EAX_PRESET_CITY EAX_ENVIRONMENT_CITY, 0.111F, 2.767F, 0.224F
-#define EAX_PRESET_MOUNTAINS EAX_ENVIRONMENT_MOUNTAINS, 0.194F, 7.841F, 0.472F
-#define EAX_PRESET_QUARRY EAX_ENVIRONMENT_QUARRY, 1.0F, 1.499F, 0.5F
-#define EAX_PRESET_PLAIN EAX_ENVIRONMENT_PLAIN, 0.097F, 2.767F, 0.224F
-#define EAX_PRESET_PARKINGLOT EAX_ENVIRONMENT_PARKINGLOT, 0.208F, 1.652F, 1.5F
-#define EAX_PRESET_SEWERPIPE EAX_ENVIRONMENT_SEWERPIPE, 0.652F, 2.886F, 0.25F
-#define EAX_PRESET_UNDERWATER EAX_ENVIRONMENT_UNDERWATER, 1.0F, 1.499F, 0.0F
-#define EAX_PRESET_DRUGGED EAX_ENVIRONMENT_DRUGGED, 0.875F, 8.392F, 1.388F
-#define EAX_PRESET_DIZZY EAX_ENVIRONMENT_DIZZY, 0.139F, 17.234F, 0.666F
-#define EAX_PRESET_PSYCHOTIC EAX_ENVIRONMENT_PSYCHOTIC, 0.486F, 7.563F, 0.806F
-
-// EAX buffer reverb property set {4a4e6fc0-c341-11d1-b73a-444553540000}
-DEFINE_GUID(DSPROPSETID_EAXBUFFER_ReverbProperties, 0x4a4e6fc0, 0xc341, 0x11d1, 0xb7, 0x3a, 0x44, 0x45, 0x53, 0x54,
- 0x00, 0x00);
-
-enum DSPROPERTY_EAXBUFFER_REVERBPROPERTY {
- DSPROPERTY_EAXBUFFER_ALL, // all reverb buffer properties
- DSPROPERTY_EAXBUFFER_REVERBMIX // the wet source amount
-};
-
-// use this structure for get/set all properties...
-struct EAXBUFFER_REVERBPROPERTIES {
- float fMix; // linear factor, 0.0F to 1.0F
-};
-
-#define EAX_REVERBMIX_USEDISTANCE \
- -1.0F // out of normal range
- // signifies the reverb engine should
- // calculate it's own reverb mix value
- // based on distance
-
-#ifdef __cplusplus
-}
-#endif // __cplusplus
-
-#endif
diff --git a/sndlib/eax2.h b/sndlib/eax2.h
deleted file mode 100644
index 35b02f33..00000000
--- a/sndlib/eax2.h
+++ /dev/null
@@ -1,404 +0,0 @@
-/*
-* Descent 3
-* Copyright (C) 2024 Parallax Software
-*
-* This program is free software: you can redistribute it and/or modify
-* it under the terms of the GNU General Public License as published by
-* the Free Software Foundation, either version 3 of the License, or
-* (at your option) any later version.
-*
-* This program is distributed in the hope that it will be useful,
-* but WITHOUT ANY WARRANTY; without even the implied warranty of
-* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
-* GNU General Public License for more details.
-*
-* You should have received a copy of the GNU General Public License
-* along with this program. If not, see .
-*/
-
-/******************************************************************
- *
- * EAX.H - DirectSound3D Environmental Audio Extensions version 2.0
- * Updated June 18, 1999
- *
- *******************************************************************
- */
-
-#ifndef EAX2_H_INCLUDED
-#define EAX2_H_INCLUDED
-
-#include
-
-#ifdef __cplusplus
-extern "C" {
-#endif // __cplusplus
-
-#pragma pack(push, 4)
-
-/*
- EAX Wrapper Interface
-*/
-// {4FF53B81-1CE0-11d3-AAB8-00A0C95949D5}
-DEFINE_GUID(CLSID_EAXDirectSound, 0x4ff53b81, 0x1ce0, 0x11d3, 0xaa, 0xb8, 0x0, 0xa0, 0xc9, 0x59, 0x49, 0xd5);
-
-__declspec(dllimport) HRESULT WINAPI EAXDirectSoundCreate(GUID *, LPDIRECTSOUND *, IUnknown FAR *);
-
-typedef HRESULT(FAR PASCAL *LPEAXDIRECTSOUNDCREATE)(GUID *, LPDIRECTSOUND *, IUnknown FAR *);
-
-/*
- * EAX 2.0 listener property set {0306A6A8-B224-11d2-99E5-0000E8D8C722}
- */
-DEFINE_GUID(DSPROPSETID_EAX20_ListenerProperties, 0x306a6a8, 0xb224, 0x11d2, 0x99, 0xe5, 0x0, 0x0, 0xe8, 0xd8, 0xc7,
- 0x22);
-
-// For compatibility with future EAX versions:
-#define DSPROPSETID_EAX_ListenerProperties DSPROPSETID_EAX20_ListenerProperties
-
-enum DSPROPERTY_EAX_LISTENERPROPERTY {
- DSPROPERTY_EAXLISTENER_NONE,
- DSPROPERTY_EAXLISTENER_ALLPARAMETERS,
- DSPROPERTY_EAXLISTENER_ROOM,
- DSPROPERTY_EAXLISTENER_ROOMHF,
- DSPROPERTY_EAXLISTENER_ROOMROLLOFFFACTOR,
- DSPROPERTY_EAXLISTENER_DECAYTIME,
- DSPROPERTY_EAXLISTENER_DECAYHFRATIO,
- DSPROPERTY_EAXLISTENER_REFLECTIONS,
- DSPROPERTY_EAXLISTENER_REFLECTIONSDELAY,
- DSPROPERTY_EAXLISTENER_REVERB,
- DSPROPERTY_EAXLISTENER_REVERBDELAY,
- DSPROPERTY_EAXLISTENER_ENVIRONMENT,
- DSPROPERTY_EAXLISTENER_ENVIRONMENTSIZE,
- DSPROPERTY_EAXLISTENER_ENVIRONMENTDIFFUSION,
- DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF,
- DSPROPERTY_EAXLISTENER_FLAGS
-};
-
-// OR these flags with property id
-#define DSPROPERTY_EAXLISTENER_IMMEDIATE 0x00000000 // changes take effect immediately
-#define DSPROPERTY_EAXLISTENER_DEFERRED 0x80000000 // changes take effect later
-#define DSPROPERTY_EAXLISTENER_COMMITDEFERREDSETTINGS (DSPROPERTY_EAXLISTENER_NONE | DSPROPERTY_EAXLISTENER_IMMEDIATE)
-
-// Use this structure for DSPROPERTY_EAXLISTENER_ALLPARAMETERS
-// - all levels are hundredths of decibels
-// - all times are in seconds
-// - the reference for high frequency controls is 5 kHz
-//
-// NOTE: This structure may change in future EAX versions.
-// It is recommended to initialize fields by name:
-// myListener.lRoom = -1000;
-// myListener.lRoomHF = -100;
-// ...
-// myListener.dwFlags = myFlags /* see EAXLISTENERFLAGS below */ ;
-// instead of:
-// myListener = { -1000, -100, ... , 0x00000009 };
-// If you want to save and load presets in binary form, you
-// should define your own structure to insure future compatibility.
-//
-struct EAXLISTENERPROPERTIES {
- LONG lRoom; // room effect level at low frequencies
- LONG lRoomHF; // room effect high-frequency level re. low frequency level
- FLOAT flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect
- FLOAT flDecayTime; // reverberation decay time at low frequencies
- FLOAT flDecayHFRatio; // high-frequency to low-frequency decay time ratio
- LONG lReflections; // early reflections level relative to room effect
- FLOAT flReflectionsDelay; // initial reflection delay time
- LONG lReverb; // late reverberation level relative to room effect
- FLOAT flReverbDelay; // late reverberation delay time relative to initial reflection
- DWORD dwEnvironment; // sets all listener properties
- FLOAT flEnvironmentSize; // environment size in meters
- FLOAT flEnvironmentDiffusion; // environment diffusion
- FLOAT flAirAbsorptionHF; // change in level per meter at 5 kHz
- DWORD dwFlags; // modifies the behavior of properties
-};
-
-// used by DSPROPERTY_EAXLISTENER_ENVIRONMENT
-enum {
- EAX_ENVIRONMENT_GENERIC,
- EAX_ENVIRONMENT_PADDEDCELL,
- EAX_ENVIRONMENT_ROOM,
- EAX_ENVIRONMENT_BATHROOM,
- EAX_ENVIRONMENT_LIVINGROOM,
- EAX_ENVIRONMENT_STONEROOM,
- EAX_ENVIRONMENT_AUDITORIUM,
- EAX_ENVIRONMENT_CONCERTHALL,
- EAX_ENVIRONMENT_CAVE,
- EAX_ENVIRONMENT_ARENA,
- EAX_ENVIRONMENT_HANGAR,
- EAX_ENVIRONMENT_CARPETEDHALLWAY,
- EAX_ENVIRONMENT_HALLWAY,
- EAX_ENVIRONMENT_STONECORRIDOR,
- EAX_ENVIRONMENT_ALLEY,
- EAX_ENVIRONMENT_FOREST,
- EAX_ENVIRONMENT_CITY,
- EAX_ENVIRONMENT_MOUNTAINS,
- EAX_ENVIRONMENT_QUARRY,
- EAX_ENVIRONMENT_PLAIN,
- EAX_ENVIRONMENT_PARKINGLOT,
- EAX_ENVIRONMENT_SEWERPIPE,
- EAX_ENVIRONMENT_UNDERWATER,
- EAX_ENVIRONMENT_DRUGGED,
- EAX_ENVIRONMENT_DIZZY,
- EAX_ENVIRONMENT_PSYCHOTIC,
-
- EAX_ENVIRONMENT_COUNT
-};
-
-// Used by DSPROPERTY_EAXLISTENER_FLAGS
-//
-// Note: The number and order of flags may change in future EAX versions.
-// It is recommended to use the flag defines as follows:
-// myFlags = EAXLISTENERFLAGS_DECAYTIMESCALE | EAXLISTENERFLAGS_REVERBSCALE;
-// instead of:
-// myFlags = 0x00000009;
-//
-// These flags determine what properties are affected by environment size.
-#define EAXLISTENERFLAGS_DECAYTIMESCALE 0x00000001 // reverberation decay time
-#define EAXLISTENERFLAGS_REFLECTIONSSCALE 0x00000002 // reflection level
-#define EAXLISTENERFLAGS_REFLECTIONSDELAYSCALE 0x00000004 // initial reflection delay time
-#define EAXLISTENERFLAGS_REVERBSCALE 0x00000008 // reflections level
-#define EAXLISTENERFLAGS_REVERBDELAYSCALE 0x00000010 // late reverberation delay time
-
-// This flag limits high-frequency decay time according to air absorption.
-#define EAXLISTENERFLAGS_DECAYHFLIMIT 0x00000020
-
-#define EAXLISTENERFLAGS_RESERVED 0xFFFFFFC0 // reserved future use
-
-// property ranges and defaults:
-
-#define EAXLISTENER_MINROOM -10000
-#define EAXLISTENER_MAXROOM 0
-#define EAXLISTENER_DEFAULTROOM -1000
-
-#define EAXLISTENER_MINROOMHF -10000
-#define EAXLISTENER_MAXROOMHF 0
-#define EAXLISTENER_DEFAULTROOMHF -100
-
-#define EAXLISTENER_MINROOMROLLOFFFACTOR 0.0f
-#define EAXLISTENER_MAXROOMROLLOFFFACTOR 10.0f
-#define EAXLISTENER_DEFAULTROOMROLLOFFFACTOR 0.0f
-
-#define EAXLISTENER_MINDECAYTIME 0.1f
-#define EAXLISTENER_MAXDECAYTIME 20.0f
-#define EAXLISTENER_DEFAULTDECAYTIME 1.49f
-
-#define EAXLISTENER_MINDECAYHFRATIO 0.1f
-#define EAXLISTENER_MAXDECAYHFRATIO 2.0f
-#define EAXLISTENER_DEFAULTDECAYHFRATIO 0.83f
-
-#define EAXLISTENER_MINREFLECTIONS -10000
-#define EAXLISTENER_MAXREFLECTIONS 1000
-#define EAXLISTENER_DEFAULTREFLECTIONS -2602
-
-#define EAXLISTENER_MINREFLECTIONSDELAY 0.0f
-#define EAXLISTENER_MAXREFLECTIONSDELAY 0.3f
-#define EAXLISTENER_DEFAULTREFLECTIONSDELAY 0.007f
-
-#define EAXLISTENER_MINREVERB -10000
-#define EAXLISTENER_MAXREVERB 2000
-#define EAXLISTENER_DEFAULTREVERB 200
-
-#define EAXLISTENER_MINREVERBDELAY 0.0f
-#define EAXLISTENER_MAXREVERBDELAY 0.1f
-#define EAXLISTENER_DEFAULTREVERBDELAY 0.011f
-
-#define EAXLISTENER_MINENVIRONMENT 0
-#define EAXLISTENER_MAXENVIRONMENT (EAX_ENVIRONMENT_COUNT - 1)
-#define EAXLISTENER_DEFAULTENVIRONMENT EAX_ENVIRONMENT_GENERIC
-
-#define EAXLISTENER_MINENVIRONMENTSIZE 1.0f
-#define EAXLISTENER_MAXENVIRONMENTSIZE 100.0f
-#define EAXLISTENER_DEFAULTENVIRONMENTSIZE 7.5f
-
-#define EAXLISTENER_MINENVIRONMENTDIFFUSION 0.0f
-#define EAXLISTENER_MAXENVIRONMENTDIFFUSION 1.0f
-#define EAXLISTENER_DEFAULTENVIRONMENTDIFFUSION 1.0f
-
-#define EAXLISTENER_MINAIRABSORPTIONHF -100.0f
-#define EAXLISTENER_MAXAIRABSORPTIONHF 0.0f
-#define EAXLISTENER_DEFAULTAIRABSORPTIONHF -5.0f
-
-#define EAXLISTENER_DEFAULTFLAGS \
- (EAXLISTENERFLAGS_DECAYTIMESCALE | EAXLISTENERFLAGS_REFLECTIONSSCALE | EAXLISTENERFLAGS_REFLECTIONSDELAYSCALE | \
- EAXLISTENERFLAGS_REVERBSCALE | EAXLISTENERFLAGS_REVERBDELAYSCALE | EAXLISTENERFLAGS_DECAYHFLIMIT)
-
-/*
- * EAX 2.0 buffer property set {0306A6A7-B224-11d2-99E5-0000E8D8C722}
- */
-DEFINE_GUID(DSPROPSETID_EAX20_BufferProperties, 0x306a6a7, 0xb224, 0x11d2, 0x99, 0xe5, 0x0, 0x0, 0xe8, 0xd8, 0xc7,
- 0x22);
-
-// For compatibility with future EAX versions:
-#define DSPROPSETID_EAX_BufferProperties DSPROPSETID_EAX20_BufferProperties
-
-enum DSPROPERTY_EAX_BUFFERPROPERTY {
- DSPROPERTY_EAXBUFFER_NONE,
- DSPROPERTY_EAXBUFFER_ALLPARAMETERS,
- DSPROPERTY_EAXBUFFER_DIRECT,
- DSPROPERTY_EAXBUFFER_DIRECTHF,
- DSPROPERTY_EAXBUFFER_ROOM,
- DSPROPERTY_EAXBUFFER_ROOMHF,
- DSPROPERTY_EAXBUFFER_ROOMROLLOFFFACTOR,
- DSPROPERTY_EAXBUFFER_OBSTRUCTION,
- DSPROPERTY_EAXBUFFER_OBSTRUCTIONLFRATIO,
- DSPROPERTY_EAXBUFFER_OCCLUSION,
- DSPROPERTY_EAXBUFFER_OCCLUSIONLFRATIO,
- DSPROPERTY_EAXBUFFER_OCCLUSIONROOMRATIO,
- DSPROPERTY_EAXBUFFER_OUTSIDEVOLUMEHF,
- DSPROPERTY_EAXBUFFER_AIRABSORPTIONFACTOR,
- DSPROPERTY_EAXBUFFER_FLAGS
-};
-
-// OR these flags with property id
-#define DSPROPERTY_EAXBUFFER_IMMEDIATE 0x00000000 // changes take effect immediately
-#define DSPROPERTY_EAXBUFFER_DEFERRED 0x80000000 // changes take effect later
-#define DSPROPERTY_EAXBUFFER_COMMITDEFERREDSETTINGS (DSPROPERTY_EAXBUFFER_NONE | DSPROPERTY_EAXBUFFER_IMMEDIATE)
-
-// Use this structure for DSPROPERTY_EAXBUFFER_ALLPARAMETERS
-// - all levels are hundredths of decibels
-//
-// NOTE: This structure may change in future EAX versions.
-// It is recommended to initialize fields by name:
-// myBuffer.lDirect = 0;
-// myBuffer.lDirectHF = -200;
-// ...
-// myBuffer.dwFlags = myFlags /* see EAXBUFFERFLAGS below */ ;
-// instead of:
-// myBuffer = { 0, -200, ... , 0x00000003 };
-//
-struct EAXBUFFERPROPERTIES {
- LONG lDirect; // direct path level
- LONG lDirectHF; // direct path level at high frequencies
- LONG lRoom; // room effect level
- LONG lRoomHF; // room effect level at high frequencies
- FLOAT flRoomRolloffFactor; // like DS3D flRolloffFactor but for room effect
- LONG lObstruction; // main obstruction control (attenuation at high frequencies)
- FLOAT flObstructionLFRatio; // obstruction low-frequency level re. main control
- LONG lOcclusion; // main occlusion control (attenuation at high frequencies)
- FLOAT flOcclusionLFRatio; // occlusion low-frequency level re. main control
- FLOAT flOcclusionRoomRatio; // occlusion room effect level re. main control
- LONG lOutsideVolumeHF; // outside sound cone level at high frequencies
- FLOAT flAirAbsorptionFactor; // multiplies DSPROPERTY_EAXLISTENER_AIRABSORPTIONHF
- DWORD dwFlags; // modifies the behavior of properties
-};
-
-// Used by DSPROPERTY_EAXBUFFER_FLAGS
-// TRUE: value is computed automatically - property is an offset
-// FALSE: value is used directly
-//
-// Note: The number and order of flags may change in future EAX versions.
-// To insure future compatibility, use flag defines as follows:
-// myFlags = EAXBUFFERFLAGS_DIRECTHFAUTO | EAXBUFFERFLAGS_ROOMAUTO;
-// instead of:
-// myFlags = 0x00000003;
-//
-#define EAXBUFFERFLAGS_DIRECTHFAUTO 0x00000001 // affects DSPROPERTY_EAXBUFFER_DIRECTHF
-#define EAXBUFFERFLAGS_ROOMAUTO 0x00000002 // affects DSPROPERTY_EAXBUFFER_ROOM
-#define EAXBUFFERFLAGS_ROOMHFAUTO 0x00000004 // affects DSPROPERTY_EAXBUFFER_ROOMHF
-
-#define EAXBUFFERFLAGS_RESERVED 0xFFFFFFF8 // reserved future use
-
-// property ranges and defaults:
-
-#define EAXBUFFER_MINDIRECT -10000
-#define EAXBUFFER_MAXDIRECT 1000
-#define EAXBUFFER_DEFAULTDIRECT 0
-
-#define EAXBUFFER_MINDIRECTHF -10000
-#define EAXBUFFER_MAXDIRECTHF 0
-#define EAXBUFFER_DEFAULTDIRECTHF 0
-
-#define EAXBUFFER_MINROOM -10000
-#define EAXBUFFER_MAXROOM 1000
-#define EAXBUFFER_DEFAULTROOM 0
-
-#define EAXBUFFER_MINROOMHF -10000
-#define EAXBUFFER_MAXROOMHF 0
-#define EAXBUFFER_DEFAULTROOMHF 0
-
-#define EAXBUFFER_MINROOMROLLOFFFACTOR 0.0f
-#define EAXBUFFER_MAXROOMROLLOFFFACTOR 10.f
-#define EAXBUFFER_DEFAULTROOMROLLOFFFACTOR 0.0f
-
-#define EAXBUFFER_MINOBSTRUCTION -10000
-#define EAXBUFFER_MAXOBSTRUCTION 0
-#define EAXBUFFER_DEFAULTOBSTRUCTION 0
-
-#define EAXBUFFER_MINOBSTRUCTIONLFRATIO 0.0f
-#define EAXBUFFER_MAXOBSTRUCTIONLFRATIO 1.0f
-#define EAXBUFFER_DEFAULTOBSTRUCTIONLFRATIO 0.0f
-
-#define EAXBUFFER_MINOCCLUSION -10000
-#define EAXBUFFER_MAXOCCLUSION 0
-#define EAXBUFFER_DEFAULTOCCLUSION 0
-
-#define EAXBUFFER_MINOCCLUSIONLFRATIO 0.0f
-#define EAXBUFFER_MAXOCCLUSIONLFRATIO 1.0f
-#define EAXBUFFER_DEFAULTOCCLUSIONLFRATIO 0.25f
-
-#define EAXBUFFER_MINOCCLUSIONROOMRATIO 0.0f
-#define EAXBUFFER_MAXOCCLUSIONROOMRATIO 10.0f
-#define EAXBUFFER_DEFAULTOCCLUSIONROOMRATIO 0.5f
-
-#define EAXBUFFER_MINOUTSIDEVOLUMEHF -10000
-#define EAXBUFFER_MAXOUTSIDEVOLUMEHF 0
-#define EAXBUFFER_DEFAULTOUTSIDEVOLUMEHF 0
-
-#define EAXBUFFER_MINAIRABSORPTIONFACTOR 0.0f
-#define EAXBUFFER_MAXAIRABSORPTIONFACTOR 10.0f
-#define EAXBUFFER_DEFAULTAIRABSORPTIONFACTOR 1.0f
-
-#define EAXBUFFER_DEFAULTFLAGS (EAXBUFFERFLAGS_DIRECTHFAUTO | EAXBUFFERFLAGS_ROOMAUTO | EAXBUFFERFLAGS_ROOMHFAUTO)
-
-// Material transmission presets
-// 3 values in this order:
-// 1: occlusion (or obstruction)
-// 2: occlusion LF Ratio (or obstruction LF Ratio)
-// 3: occlusion Room Ratio
-
-// Single window material preset
-#define EAX_MATERIAL_SINGLEWINDOW -2800
-#define EAX_MATERIAL_SINGLEWINDOWLF 0.71
-#define EAX_MATERIAL_SINGLEWINDOWROOMRATIO 0.43
-
-// Double window material preset
-#define EAX_MATERIAL_DOUBLEWINDOW -5000
-#define EAX_MATERIAL_DOUBLEWINDOWHF 0.40
-#define EAX_MATERIAL_DOUBLEWINDOWROOMRATIO 0.24
-
-// Thin door material preset
-#define EAX_MATERIAL_THINDOOR -1800
-#define EAX_MATERIAL_THINDOORLF 0.66
-#define EAX_MATERIAL_THINDOORROOMRATIO 0.66
-
-// Thick door material preset
-#define EAX_MATERIAL_THICKDOOR -4400
-#define EAX_MATERIAL_THICKDOORLF 0.64
-#define EAX_MATERIAL_THICKDOORROOMRTATION 0.27
-
-// Wood wall material preset
-#define EAX_MATERIAL_WOODWALL -4000
-#define EAX_MATERIAL_WOODWALLLF 0.50
-#define EAX_MATERIAL_WOODWALLROOMRATIO 0.30
-
-// Brick wall material preset
-#define EAX_MATERIAL_BRICKWALL -5000
-#define EAX_MATERIAL_BRICKWALLLF 0.60
-#define EAX_MATERIAL_BRICKWALLROOMRATIO 0.24
-
-// Stone wall material preset
-#define EAX_MATERIAL_STONEWALL -6000
-#define EAX_MATERIAL_STONEWALLLF 0.68
-#define EAX_MATERIAL_STONEWALLROOMRATIO 0.20
-
-// Curtain material preset
-#define EAX_MATERIAL_CURTAIN -1200
-#define EAX_MATERIAL_CURTAINLF 0.15
-#define EAX_MATERIAL_CURTAINROOMRATIO 1.00
-
-#pragma pack(pop)
-
-#ifdef __cplusplus
-}
-#endif // __cplusplus
-
-#endif