aboutsummaryrefslogtreecommitdiff
path: root/sword2
diff options
context:
space:
mode:
authorPaweł Kołodziejski2003-08-30 18:06:08 +0000
committerPaweł Kołodziejski2003-08-30 18:06:08 +0000
commita2dad74da12f4d4bd63f79e86d0226c07e16dcc9 (patch)
tree4e3cecef76dcac2467755f8b4e92889a44420988 /sword2
parent890c5cde042ce1fa1cce0c55e6ef7976dc2bbb9a (diff)
downloadscummvm-rg350-a2dad74da12f4d4bd63f79e86d0226c07e16dcc9.tar.gz
scummvm-rg350-a2dad74da12f4d4bd63f79e86d0226c07e16dcc9.tar.bz2
scummvm-rg350-a2dad74da12f4d4bd63f79e86d0226c07e16dcc9.zip
added sfx support, increased speech support, and music code(streaming works fine but you don't hear anything) newStream, and appendStream doesn't work but playRaw works for music
svn-id: r9923
Diffstat (limited to 'sword2')
-rw-r--r--sword2/credits.h2
-rw-r--r--sword2/driver/d_sound.cpp2464
-rw-r--r--sword2/driver/d_sound.h26
-rw-r--r--sword2/driver/driver96.h44
-rw-r--r--sword2/driver/rdwin.cpp6
-rw-r--r--sword2/sound.cpp2
-rw-r--r--sword2/sword2.cpp6
7 files changed, 782 insertions, 1768 deletions
diff --git a/sword2/credits.h b/sword2/credits.h
index 26337c81c6..efb7a27095 100644
--- a/sword2/credits.h
+++ b/sword2/credits.h
@@ -23,6 +23,6 @@
#include "driver/driver96.h"
// int32 __declspec( dllexport ) Credits(_drvDrawStatus *pDrawStatus, _drvSoundStatus *pSoundStatus, const char *cdPath, BOOL smoke, BOOL *pAppFocus, _drvKeyStatus *pKeyStatus);
-int32 Credits(_drvDrawStatus *pDrawStatus, _drvSoundStatus *pSoundStatus, const char *cdPath, BOOL smoke, BOOL *pAppFocus, _drvKeyStatus *pKeyStatus);
+//int32 Credits(_drvDrawStatus *pDrawStatus, _drvSoundStatus *pSoundStatus, const char *cdPath, BOOL smoke, BOOL *pAppFocus, _drvKeyStatus *pKeyStatus);
#endif
diff --git a/sword2/driver/d_sound.cpp b/sword2/driver/d_sound.cpp
index 15c8744704..2b9b8ab99f 100644
--- a/sword2/driver/d_sound.cpp
+++ b/sword2/driver/d_sound.cpp
@@ -25,170 +25,6 @@
//
// Summary : This module holds the driver interface to direct sound.
//
-// Version Date By Description
-// ------- --------- --- -----------------------------------------------
-// 1.0 03-Dec-96 PRP The sound buffer can be created, with the
-// format defined by the game engine, and speech
-// can be played.
-//
-// 1.1 05-Dec-96 PRP Sound effects now done.
-//
-// 1.2 19-Dec-96 PRP Added volume and pan to speech and sound
-// effects. Also, added type to sound effects
-// so that they can be looped. Implemented
-// a CloseAllFx function which will clear out
-// all sound effects.
-//
-// 1.3 20-Dec-96 PRP Fixed a bug in the function which clears
-// spot effects when they have finished playing.
-//
-// 1.4 02-Jan-97 PRP Fixed a bug in ClearAllFx which was trying
-// to close the speech.
-//
-// 1.5 08-Apr-97 PRP Added ... to the
-// InitialiseSound function.
-//
-// 1.6 09-Apr-97 PRP Added functions to steam music from CD.
-//
-// 1.7 29-May-97 PSJ Added functions to save and restore the state
-// of the sound drivers.
-//
-// 1.8 04-Jun-97 PRP Added bodge to PlayFx routine which registers
-// a sound effect to remove itself from the list
-// if it is the tune to leave a sequence.
-//
-// 1.9 06-Jun-97 PSJ Expanded volTable from 17 to 241 entries.
-// Added an fx and a speech master volume level.
-// Added SetFxVolume and GetFxVolume for fx master
-// volume. Added SetSpeechVolume and GetSpeechVolume
-// for speech master volume.
-//
-// 1.10 09-Jun-97 PSJ Added SetMusicVolume and GetMusicVolume.
-//
-// 1.11 09-Jun-97 PSJ Fixed bug in SetSpeechVolume.
-//
-// 1.12 10-Jun-97 PSJ Added MuteMusic, MuteSpeech, MuteFx, IsMusicMute,
-// IsFxMute and IsSpeechMute.
-//
-// 1.13 12-Jun-97 PSJ Added PlayCompSpeech to play compressed speech
-// from a speech cluster.
-//
-// 1.14 19-Jun-97 PSJ Added StreamCompMusic and UpdateCompSampleStreaming
-// to play compressed music from a music cluster.
-// Added StopMusic to fade out any music playing.
-//
-// 1.15 24-Jun-97 PSJ Changed PlayCompSpeech to physically check for
-// playing samples rather than using the assuming the
-// speechStatus flag is correct.
-//
-// 1.16 24-Jun-97 PSJ Fixed bug it SetSpeechVolume.
-//
-// 1.17 26-Jun-97 PSJ Added AmISpeaking() for lip syncing.
-//
-// 1.18 26-Jun-97 PSJ Tweaked the nose of the dread, killer AmISpeaking
-// function.
-//
-// 1.19 26-Jun-97 PSJ Added PauseSpeech and UnpauseSpeech.
-//
-// 1.20 26-Jun-97 PSJ Fixed a bug in the muteSpeech routine.
-//
-// 1.21 26-Jun-97 PSJ Fixed a bug in the AmISpeaking routine.
-//
-// 1.22 26-Jun-97 PSJ PlayCompSpeech loads and pauses the speech
-// ready to be played by UnpauseSpeech.
-//
-// 1.23 01-Jul-97 PSJ Fixed GetSpeechStatus to work when speech is paused
-//
-// 1.24 03-Jul-97 PSJ Stopped PlayCompSpeech clicking at the end of samples.
-//
-// 1.25 10-Jul-97 PSJ Reduced music volume by 1/4 when playing speech
-//
-// 1.26 10-Jul-97 PSJ GetMusicVolume return safeMusicVol if it is set.
-//
-// 1.27 15-Jul-97 PRP Added functions to pause and unpause the sound effects.
-//
-// 1.28 15-Jul-97 PRP Fixed PauseFx
-//
-// 1.29 16-Jul-97 PSJ Added GetCompSpeechSize and PreFetchCompSpeech
-//
-// 1.30 16-Jul-97 PRP Fixed setting of sound fx volume.
-//
-// 1.31 18-Jul-97 PRP Added speech expansion to get samples to sound the same.
-//
-// 1.32 18-Jul-97 PRP Hopefully fixed expansion algorithm.
-//
-// 1.33 18-Jul-97 JEL Fixed UnpauseFx()
-//
-// 1.34 18-Jul-97 JEL Fixed PlayCompSpeech()
-//
-// 1.35 18-Jul-97 JEL Removed speech volume enhancing (now to be done in speech compressor)
-//
-// 1.36 21-Jul-97 PRP Added new type of sound effect which is the music lead in.
-// Also, added function to pause the sound effects
-// just for sequences.
-//
-// 1.37 21-Jul-97 PRP Modified ClearAllFx so that it doesn't kick out
-// lead in and lead out music for smacker sequences.
-//
-// 1.38 21-Jul-97 PRP Tried to fix the bug where the second lead in
-// music will not play due to a duplicate id.
-//
-// 1.39 21-Jul-97 PRP Finally fixed the bug to kick out lead in music
-// fx when they have finished.
-//
-// 1.40 25-Jul-97 JEL Fixed crashing when music paused & unpaused repeatedly
-//
-// 1.41 28-Jul-97 PRP Checked to see if fx are looping as well as playing!
-//
-// 1.42 30-Jul-97 PSJ Added Music dipping.
-//
-// 1.43 30-Jul-97 PSJ Added MusicTimeRemaining.
-//
-// 1.44 31-Jul-97 PSJ Adjusted MusicTimeRemaining to include music left in buffer.
-//
-// 1.45 06-Aug-97 PSJ Updated Get and Set scroll SoundStatus.
-//
-// 1.46 12-Aug-97 PSJ Added ReverseStereo(void)
-//
-// 1.47 13-Aug-97 PSJ Updated DipMusic so it fades up after speech has finished.
-//
-// 1.48 13-Aug-97 PRP Added IsFxOpen().
-//
-// 1.49 15-Aug-97 PRP Added SetFxVolumePan().
-//
-// 1.50 15-Aug-97 PRP Added SetFxIdVolume()
-//
-// 1.51 15-Aug-97 PSJ Fixed bug in PlayCompMusic();
-//
-// 1.52 19-Aug-97 JEL Fixed bug in MusicTimeRemaining()
-//
-// WE'VE SCREWED UP THE NUMBERING!
-//
-// 1.59 19-Aug-97 JEL Fixed bug in MusicTimeRemaining(), ;)
-//
-// 1.60 19-Aug-97 PSJ Updated DipMusic so it fades music a bit more.
-//
-// 1.61 21-Aug-97 PSJ Updated StreamCompMusic so if both streams are in use,
-// the fading stream is stopped and the new tune started.
-//
-// 1.62 21-Aug-97 PSJ Updated StreamCompMusic so if the music is unmuted,
-// the last tune is restarted if it was looping.
-//
-// 1.63 22-Aug-97 PSJ Update PlayFx to handle smacker leadouts.
-//
-// 1.64 27-Aug-97 PSJ Update PlayFx to record an fx's local volume,
-// So SetFxVolume can update playing fx's with the
-// correct volume.
-//
-// 1.65 27-Aug-97 PSJ Stopped CloseFX from closing invalid fx's.
-//
-// 1.66 01-Sep-97 PRP Cleared the fxPaused flag when closing fx.
-//
-// 1.67 01-Sep-97 PRP Fixed the fact that SetFxVolume was still
-// being done even if the fx were muted.
-//
-// 1.68 01-Sep-97 PRP Set zero sound to -10000
-//
// Functions
// ---------
//
@@ -205,15 +41,6 @@
//
// --------------------------------------------------------------------------
//
-// int32 PlaySpeech(uint8 *data, uint8 vol, int8 pan)
-//
-// This function plays the wav file passed into it as speech. An error occurs
-// if speech is already playing, or directSound comes accross problems. The
-// volume is 0 for zero volume and 16 for maximum volume. The pan position
-// is -16 for full left, 0 for central and 16 for full right.
-//
-// --------------------------------------------------------------------------
-//
// int32 PlayCompSpeech(const char *filename, uint32 id, uint8 vol, int8 pan)
//
// This function loads, decompresses and plays the wav 'id' from the cluster
@@ -296,15 +123,6 @@
//
// --------------------------------------------------------------------------
//
-// int32 StreamMusic(uint8 *filename, int32 loopFlag)
-//
-// Streams music from the file defined by filename. The loopFlag should
-// be set to RDSE_FXLOOP if the music is to loop back to the start.
-// Otherwise, it should be RDSE_FXSPOT.
-// The return value must be checked for any problems.
-//
-// --------------------------------------------------------------------------
-//
// int32 StreamCompMusic(uint8 *filename, uint32 id, int32 loopFlag)
//
// Streams music 'id' from the cluster file 'filename'. The loopFlag should
@@ -312,8 +130,6 @@
// Otherwise, it should be RDSE_FXSPOT.
// The return value must be checked for any problems.
//
-// StreamCompMusic should not be used inconjunction with StreamMusic.
-//
// --------------------------------------------------------------------------
//
// void StopMusic(void)
@@ -346,34 +162,21 @@
//
//=============================================================================
-
-
-
#define WIN32_LEAN_AND_MEAN
-//#include <windows.h>
-//#include <windowsx.h>
-#include <stdio.h>
-
#include "stdafx.h"
#include "driver96.h"
#include "rdwin.h" // for hwnd.
#include "d_sound.h"
#include "../sword2.h"
+#include "sound/mixer.h"
// Decompression macros
-#define MakeCompressedByte(shift,sign,amplitude) (((shift)<<4) + ((sign)<<3) + (amplitude))
-#define GetCompressedShift(byte) ((byte)>>4)
-#define GetCompressedSign(byte) (((byte)>>3) & 1)
-#define GetCompressedAmplitude(byte) ((byte) & 7)
-#define GetdAPower(dA,power) for (power = 15;power>0 && !((dA) & (1<<power)); power--)
-
-/*
-LPDIRECTSOUND lpDS;
-LPDIRECTSOUNDBUFFER dsbPrimary;
-LPDIRECTSOUNDBUFFER dsbSpeech;
-LPDIRECTSOUNDBUFFER dsbFx[MAXFX];
-*/
+#define MakeCompressedByte(shift, sign, amplitude) (((shift) << 4) + ((sign) << 3) + (amplitude))
+#define GetCompressedShift(byte) ((byte) >> 4)
+#define GetCompressedSign(byte) (((byte) >> 3) & 1)
+#define GetCompressedAmplitude(byte) ((byte) & 7)
+#define GetdAPower(dA, power) for (power = 15; power > 0 && !((dA) & (1 << power)); power--)
int32 panTable[33] = {
-10000,
@@ -388,12 +191,10 @@ int32 panTable[33] = {
};
int32 volTable[241] = {
-
-10000, -3925, -3852, -3781, -3710, -3642, -3574, -3508, -3443, -3379, -3316, -3255, -3194, -3135, -3077, -3020, -2964, -2909, -2855, -2802, -2750, -2699, -2649, -2600, -2551, -2504, -2458, -2412, -2367, -2323, -2280, -2238, -2197, -2156, -2116, -2077, -2038, -2000, -1963, -1927, -1891, -1856, -1821, -1788, -1755, -1722, -1690, -1659, -1628, -1598, -1568, -1539, -1510, -1482, -1455, -1428, -1401, -1375, -1350, -1325,
-1300, -1290, -1279, -1269, -1259, -1249, -1239, -1229, -1219, -1209, -1199, -1190, -1180, -1171, -1161, -1152, -1142, -1133, -1124, -1115, -1106, -1097, -1088, -1080, -1071, -1062, -1054, -1045, -1037, -1028, -1020, -1012, -1004, -996, -988, -980, -972, -964, -956, -949, -941, -933, -926, -918, -911, -904, -896, -889, -882, -875, -868, -861, -854, -847, -840, -833, -827, -820, -813, -807,
-800, -791, -782, -773, -764, -755, -747, -738, -730, -721, -713, -705, -697, -689, -681, -673, -665, -658, -650, -643, -635, -628, -621, -613, -606, -599, -593, -586, -579, -572, -566, -559, -553, -546, -540, -534, -528, -522, -516, -510, -504, -498, -492, -487, -481, -476, -470, -465, -459, -454, -449, -444, -439, -434, -429, -424, -419, -414, -409, -404,
-400, -362, -328, -297, -269, -244, -221, -200, -181, -164, -148, -134, -122, -110, -100, -90, -82, -74, -67, -61, -55, -50, -45, -41, -37, -33, -30, -27, -25, -22, -20, -18, -16, -15, -13, -12, -11, -10, -9, -8, -7, -6, -6, -5, -5, -4, -4, -3, -3, -3, -2, -2, -2, -2, -1, -1, -1, -1, -1, 0
-
};
int32 musicVolTable[17] = {
@@ -404,10 +205,11 @@ int32 musicVolTable[17] = {
-200, -100, -50, 0
};
-
+void sword2_sound_handler (void *engine) {
+ g_sword2->_sound->FxServer();
+}
Sword2Sound::Sword2Sound(SoundMixer *mixer) {
-
soundOn = 0;
speechStatus = 0;
fxPaused = 0;
@@ -421,92 +223,44 @@ Sword2Sound::Sword2Sound(SoundMixer *mixer) {
volMusic[0] = 16;
volMusic[1] = 16;
musicMuted = 0;
-
+ bufferSizeMusic = 44100;
_mixer = mixer;
}
-/* not used seemingly - khalek
-
-#define SPEECH_EXPANSION
-
-#ifdef SPEECH_EXPANSION
-
-int16 ExpandSpeech(int16 sample)
-// This code is executed to expand the speech samples to make them sound
-// louder, without losing the quality of the sample
-{
- double x, xsquared, result;
- double expansionFactor = 2.5;
-
- x = (double) sample;
- xsquared = sample * sample;
-
- if (x < 0.0)
- {
- result = expansionFactor * x + (expansionFactor - 1.0) * xsquared / 32768.0;
- if (result < -32767.0)
- result = -32767.0;
- }
- else
- {
- result = expansionFactor * x + (1.0 - expansionFactor) * xsquared / 32768.0;
- if (result > 32767.0)
- result = 32767.0;
- }
-
- return (int16) result;
-
-}
-#endif
-*/
-
// --------------------------------------------------------------------------
// This function reverse the pan table, thus reversing the stereo.
// --------------------------------------------------------------------------
-int32 Sword2Sound::ReverseStereo(void)
-{
- int32 i,j;
+int32 Sword2Sound::ReverseStereo(void) {
+ int i,j;
- for (i = 0; i<16; i++)
- {
+ for (i = 0; i < 16; i++) {
j = panTable[i];
- panTable[i] = panTable[32-i];
- panTable[32-i] = j;
+ panTable[i] = panTable[32 - i];
+ panTable[32 - i] = j;
}
return (RD_OK);
}
-
-
// --------------------------------------------------------------------------
// This function returns the index of the sound effect with the ID passed in.
// --------------------------------------------------------------------------
-int32 Sword2Sound::GetFxIndex(int32 id)
-
-{
-
+int32 Sword2Sound::GetFxIndex(int32 id) {
int32 i = 0;
- while (i < MAXFX)
- {
+ while (i < MAXFX) {
if (fxId[i] == id)
break;
i++;
}
return(i);
-
}
-
-int32 Sword2Sound::IsFxOpen(int32 id)
-{
-
+int32 Sword2Sound::IsFxOpen(int32 id) {
int32 i = 0;
- while (i < MAXFX)
- {
+ while (i < MAXFX) {
if (fxId[i] == id)
break;
i++;
@@ -516,83 +270,59 @@ int32 Sword2Sound::IsFxOpen(int32 id)
return 1;
else
return 0;
-
}
-
// --------------------------------------------------------------------------
// This function checks the status of all current sound effects, and clears
// out the ones which are no longer required in a buffer. It is called on
// a slow timer from rdwin.c
// --------------------------------------------------------------------------
-void Sword2Sound::FxServer(void)
-
-{
- warning("stub FxServer");
-/*
- int32 i;
- int32 status;
-
+void Sword2Sound::FxServer(void) {
+ int i;
if (!soundOn)
return;
- if (musicPaused[0] + musicPaused[1] == 0)
- {
+ if (musicPaused[0] + musicPaused[1] == 0) {
if (compressedMusic == 1)
UpdateCompSampleStreaming();
- else if (compressedMusic == 2)
- UpdateSampleStreaming();
}
- if (fxPaused)
- {
- for (i=0; i<MAXFX; i++)
- {
- if ((fxId[i] == 0xfffffffe) || (fxId[i] == 0xffffffff))
- {
- IDirectSoundBuffer_GetStatus(dsbFx[i], &status);
- if (!(status & (DSBSTATUS_PLAYING + DSBSTATUS_LOOPING)))
- {
- if (fxCached[i] == RDSE_FXTOCLEAR)
- {
- IDirectSoundBuffer_Release(dsbFx[i]);
- fxId[i] = 0;
+ if (fxPaused) {
+ for (i = 0; i < MAXFX; i++) {
+ if ((fxId[i] == 0xfffffffe) || (fxId[i] == 0xffffffff)) {
+ if (!g_engine->_mixer->isChannelActive(soundHandleFx[i])) {
+ fxId[i] = 0;
+ if (bufferFx[i] != NULL) {
+ free(bufferFx[i]);
+ bufferFx[i] = NULL;
}
+ bufferSizeFx[i] = 0;
+ flagsFx[i] = 0;
}
}
}
return;
- }
-
+ }
- for (i=0; i<MAXFX; i++)
- {
- if (fxId[i])
- {
- IDirectSoundBuffer_GetStatus(dsbFx[i], &status);
- if (!(status & (DSBSTATUS_PLAYING + DSBSTATUS_LOOPING)))
- {
- if (fxCached[i] == RDSE_FXTOCLEAR)
- {
- IDirectSoundBuffer_Release(dsbFx[i]);
- fxId[i] = 0;
+ for (i = 0; i < MAXFX; i++) {
+ if (fxId[i]) {
+ if (!g_engine->_mixer->isChannelActive(soundHandleFx[i])) {
+ fxId[i] = 0;
+ if (bufferFx[i] != NULL) {
+ free(bufferFx[i]);
+ bufferFx[i] = NULL;
}
+ bufferSizeFx[i] = 0;
+ flagsFx[i] = 0;
}
}
}
-*/
}
-
-
-
-
-int32 Sword2Sound::InitialiseSound(uint16 freq, uint16 channels, uint16 bitDepth)
-
-{
- warning("stub InitaliseSound( %d, %d, %d )", freq, channels, bitDepth);
-
+int32 Sword2Sound::InitialiseSound(uint16 freq, uint16 channels, uint16 bitDepth) {
+ soundOn = 1;
+
memset(fxId, 0, sizeof(fxId));
memset(fxCached, 0, sizeof(fxCached));
memset(fxiPaused, 0, sizeof(fxiPaused));
@@ -605,310 +335,79 @@ int32 Sword2Sound::InitialiseSound(uint16 freq, uint16 channels, uint16 bitDepth
memset(musLooping, 0, sizeof(musLooping));
- memset(streamCursor, 0, sizeof(streamCursor));
memset(musFilePos, 0, sizeof(musFilePos));
memset(musEnd, 0, sizeof(musEnd));
memset(musLastSample, 0, sizeof(musLastSample));
memset(musId, 0, sizeof(musId));
+ memset(soundHandleMusic, -1, sizeof(soundHandleMusic));
+ memset(soundHandleFx, -1, sizeof(soundHandleFx));
+ soundHandleSpeech = -1;
+ memset(bufferFx, 0, sizeof(bufferFx));
+ memset(flagsFx, 0, sizeof(flagsFx));
+ memset(bufferSizeFx, 0, sizeof(bufferSizeFx));
-/*
- int32 i;
- HRESULT hrz;
- DSBUFFERDESC dsbd;
- WAVEFORMATEX pf;
-
-
- hrz = DirectSoundCreate(NULL, &lpDS, NULL);
- if (hrz != DS_OK)
- return(RDERR_DSOUNDCREATE);
-
- hrz = IDirectSound_SetCooperativeLevel(lpDS, hwnd, DSSCL_EXCLUSIVE);
- if (hrz != DS_OK)
- {
- IDirectSound_Release(lpDS);
- return(RDERR_DSOUNDCOOPERATE);
- }
-
-
- memset(&dsbd, 0, sizeof(DSBUFFERDESC));
- dsbd.dwSize = sizeof(DSBUFFERDESC);
- dsbd.dwFlags = DSBCAPS_PRIMARYBUFFER;
- dsbd.lpwfxFormat = NULL;
- hrz = IDirectSound_CreateSoundBuffer(lpDS, &dsbd, &dsbPrimary, NULL);
- if (hrz != DS_OK)
- {
- IDirectSound_Release(lpDS);
- return(RDERR_DSOUNDPBUFFER);
- }
-
- memset(&pf, 0, sizeof(WAVEFORMATEX));
-
- pf.wFormatTag = WAVE_FORMAT_PCM;
-
- pf.nSamplesPerSec = freq;
-
- pf.nChannels = channels;
-
- pf.wBitsPerSample = bitDepth;
- pf.nBlockAlign = pf.wBitsPerSample * pf.nChannels >> 3;
- pf.nAvgBytesPerSec = pf.nBlockAlign * pf.nSamplesPerSec;
- pf.cbSize = 0;
- hrz = IDirectSoundBuffer_SetFormat(dsbPrimary, (LPWAVEFORMATEX) &pf);
- if (hrz != DS_OK)
- {
- // We have not been able to set the primary format to the format requested!!!
- // But carry on anyway, the mixer will just have to work harder :)
- }
-
- // Clear the fx id's
- for (i=0; i<MAXFX; i++)
- fxId[i] = 0;
- */
-
- soundOn = 1;
-
- /*
- //----------------------------------
- // New initialisers (James19aug97)
-
- memset (fxId, 0, MAXFX*sizeof(int32));
- memset (fxCached, 0, MAXFX*sizeof(uint8));
- memset (fxiPaused, 0, MAXFX*sizeof(uint8));
- memset (fxLooped, 0, MAXFX*sizeof(uint8));
-
- memset (musStreaming, 0, MAXFX*sizeof(int16));
- memset (musicPaused, 0, MAXFX*sizeof(int16));
- memset (musCounter, 0, MAXFX*sizeof(int16));
- memset (musFading, 0, MAXFX*sizeof(int16));
-
- memset (musLooping, 0, MAXFX*sizeof(int16));
- memset (fpMus, 0, MAXFX*sizeof(FILE*));
-
- memset (streamCursor, 0, MAXFX*sizeof(int32));
- memset (musFilePos, 0, MAXFX*sizeof(int32));
- memset (musEnd, 0, MAXFX*sizeof(int32));
- memset (musLastSample, 0, MAXFX*sizeof(int16));
- memset (musId, 0, MAXFX*sizeof(uint32));
-*/
return(RD_OK);
-
}
-
-int32 Sword2Sound::PlaySpeech(uint8 *data, uint8 vol, int8 pan)
-
-{
- warning("stub PlaySpeech");
-/*
- uint32 dwBytes1, dwBytes2;
- int32 i;
- uint32 *data32;
- void *lpv1, *lpv2;
- _wavHeader *wav;
- HRESULT hr;
- DSBUFFERDESC dsbd;
- PCMWAVEFORMAT wf;
-
-
- wav = (_wavHeader *) data;
-
- if (soundOn)
- {
- if (speechStatus)
- return(RDERR_SPEECHPLAYING);
-
- memset(&wf, 0, sizeof(PCMWAVEFORMAT));
- wf.wf.wFormatTag = WAVE_FORMAT_PCM;
- wf.wf.nChannels = wav->channels;
- wf.wf.nSamplesPerSec = wav->samplesPerSec;
- wf.wBitsPerSample = 8 * wav->blockAlign / (wav->samplesPerSec * wav->channels);
- wf.wf.nBlockAlign = wf.wf.nChannels * wf.wBitsPerSample / 8;
- wf.wf.nAvgBytesPerSec = wf.wf.nSamplesPerSec * wf.wf.nBlockAlign;
-
- memset(&dsbd, 0, sizeof(DSBUFFERDESC));
- dsbd.dwSize = sizeof(DSBUFFERDESC);
- // dsbd.dwFlags = DSBCAPS_CTRLDEFAULT;
- dsbd.lpwfxFormat = (LPWAVEFORMATEX) &wf;
-
- // Set the sample size - search for the size of the data.
- i = 0;
- while (i<100)
- {
- if (*data == 'd')
- {
- data32 = (int32 *) data;
- if (*data32 == 'atad')
- break;
- }
- i += 1;
- data++;
- }
- if (i == 100)
- return(RDERR_INVALIDWAV);
-
- dsbd.dwBufferBytes = *(data32 + 1);
-
- // Create the speech sample buffer
- hr = IDirectSound_CreateSoundBuffer(lpDS, &dsbd, &dsbSpeech, NULL);
- if (hr != DS_OK)
- return(RDERR_CREATESOUNDBUFFER);
-
- // Lock the speech buffer, ready to fill it with data
- hr = IDirectSoundBuffer_Lock(dsbSpeech, 0, dsbd.dwBufferBytes, &lpv1, &dwBytes1, &lpv2, &dwBytes2, 0);
- if (hr == DSERR_BUFFERLOST)
- {
- IDirectSoundBuffer_Restore(dsbSpeech);
- hr = IDirectSoundBuffer_Lock(dsbSpeech, 0, dsbd.dwBufferBytes, &lpv1, &dwBytes1, &lpv2, &dwBytes2, 0);
- }
-
- if (hr == DS_OK)
- {
- // Fill the speech buffer with data
- memcpy((uint8 *) lpv1, (uint8 *) (data32 + 2), dwBytes1);
-
- if (dwBytes1 != dsbd.dwBufferBytes)
- {
- memcpy((uint8 *) lpv1 + dwBytes1, (uint8 *) (data32 + 2) + dwBytes1, dwBytes2);
- }
-
- // Unlock the buffer now that we've filled it
- IDirectSoundBuffer_Unlock(dsbSpeech, lpv1, dwBytes1, lpv2, dwBytes2);
-
- // Modify the volume according to the master volume
- if (speechMuted)
- IDirectSoundBuffer_SetVolume(dsbSpeech, volTable[0]);
- else
- IDirectSoundBuffer_SetVolume(dsbSpeech, volTable[vol*speechVol]);
-
- IDirectSoundBuffer_SetPan(dsbSpeech, panTable[pan+16]);
-
- // Start the speech playing
- IDirectSoundBuffer_Play(dsbSpeech, 0, 0, 0);
- speechStatus = 1;
-
- }
- else
- {
- IDirectSoundBuffer_Release(dsbSpeech);
- return(RDERR_LOCKSPEECHBUFFER);
- }
- }
-*/
- return(RD_OK);
-
-}
-
-
-int32 Sword2Sound::AmISpeaking()
-{
- warning("stub AmISpeaking");
-/*
- int32 len;
-// int32 status;
- int32 readCursor, writeCursor;
- int32 dwBytes1, dwBytes2;
- int16 *sample;
- int32 count = 0;
- LPVOID lpv1, lpv2;
- HRESULT hr;
-
-#define POSITIVE_THRESHOLD 350
-#define NEGATIVE_THRESHOLD -350
- if ((!speechMuted) && (!speechPaused) && (dsbSpeech))
- {
- if (IDirectSoundBuffer_GetCurrentPosition(dsbSpeech, &readCursor, &writeCursor) != DS_OK)
- {
+int32 Sword2Sound::AmISpeaking() {
+ if ((!speechMuted) && (!speechPaused) && (soundHandleSpeech != -1)) {
+ if (g_engine->_mixer->isChannelActive(soundHandleSpeech))
return (RDSE_SPEAKING);
- }
-
- len = 44100 / 12;
-
- hr = IDirectSoundBuffer_Lock(dsbSpeech, readCursor, len, &lpv1, &dwBytes1, &lpv2, &dwBytes2, 0);
- if (hr == DS_OK)
- {
- for (sample = (int16*)lpv1; sample<(int16*)((int8*)lpv1+dwBytes1); sample+= 90) // 20 samples
- if (*sample>POSITIVE_THRESHOLD || *sample<NEGATIVE_THRESHOLD)
- count++;
-
- IDirectSoundBuffer_Unlock(dsbSpeech,lpv1,dwBytes1,lpv2,dwBytes2);
-
- if (count>5) // 25% of the samples
- return (RDSE_SPEAKING);
- }
- return (RDSE_QUIET);
}
- return (RDSE_SPEAKING);
-*/
- return RDSE_QUIET;
+ return (RDSE_QUIET);
}
-
-int32 Sword2Sound::GetCompSpeechSize(const char *filename, uint32 speechid)
-{
- int32 i;
+int32 Sword2Sound::GetCompSpeechSize(const char *filename, uint32 speechid) {
+ int32 i;
uint32 speechIndex[2];
- FILE *fp;
+ File fp;
- // Open the speech cluster and find the data offset & size
- fp = fopen(filename, "rb");
- if (fp == NULL)
+ // Open the speech cluster and find the data offset & size
+ fp.open(filename, g_engine->getGameDataPath());
+ if (fp.isOpen() == false)
return(0);
- if (fseek(fp, (++speechid)*8, SEEK_SET))
- {
- fclose(fp);
- return (0);
- }
+ fp.seek((++speechid) * 8, SEEK_SET);
- if (fread(speechIndex, sizeof(uint32), 2, fp) != 2)
- {
- fclose(fp);
+ if (fp.read(speechIndex, sizeof(uint32) * 2) != (sizeof(uint32) * 2)) {
+ fp.close();
return (0);
}
- if (!speechIndex[0] || !speechIndex[1])
- {
- fclose(fp);
+ if (!speechIndex[0] || !speechIndex[1]) {
+ fp.close();
return (0);
}
- fclose(fp);
+ fp.close();
- i = (speechIndex[1]-1)*2 + sizeof(_wavHeader) + 8;
+ i = (speechIndex[1] - 1) * 2 + sizeof(_wavHeader) + 8;
return(i);
}
-
-int32 Sword2Sound::PreFetchCompSpeech(const char *filename, uint32 speechid, uint8 *waveMem)
-{
- uint32 i;
+int32 Sword2Sound::PreFetchCompSpeech(const char *filename, uint32 speechid, uint8 *waveMem) {
+ uint32 i;
uint16 *data16;
uint8 *data8;
uint32 speechIndex[2];
_wavHeader *pwf = (_wavHeader *) waveMem;
- FILE *fp;
+ File fp;
// Open the speech cluster and find the data offset & size
- fp = fopen(filename, "rb");
- if (fp == NULL)
+ fp.open(filename, g_engine->getGameDataPath());
+ if (fp.isOpen() == false)
return(RDERR_INVALIDFILENAME);
- if (fseek(fp, (++speechid)*8, SEEK_SET))
- {
- fclose(fp);
- return (RDERR_READERROR);
- }
+ fp.seek((++speechid) * 8, SEEK_SET);
- if (fread(speechIndex, sizeof(uint32), 2, fp) != 2)
- {
- fclose(fp);
+ if (fp.read(speechIndex, sizeof(uint32) * 2) != (sizeof(uint32) * 2)) {
+ fp.close();
return (RDERR_READERROR);
}
- if (!speechIndex[0] || !speechIndex[1])
- {
- fclose(fp);
+ if (!speechIndex[0] || !speechIndex[1]) {
+ fp.close();
return (RDERR_INVALIDID);
}
@@ -934,83 +433,64 @@ int32 Sword2Sound::PreFetchCompSpeech(const char *filename, uint32 speechid, uin
data16 += 2;
- *((uint32*)data16) = (speechIndex[1]-1)*2;
+ *((uint32*)data16) = (speechIndex[1] - 1) * 2;
data16 += 2;
- pwf->fileLength = (speechIndex[1]-1)*2 + sizeof(_wavHeader) + 8;
-
+ pwf->fileLength = (speechIndex[1] - 1) * 2 + sizeof(_wavHeader) + 8;
// Calculate position in buffer to load compressed sound into
data8 = (uint8*)data16 + (speechIndex[1]-1);
- if (fseek(fp, speechIndex[0], SEEK_SET))
- {
- fclose(fp);
- return (RDERR_INVALIDID);
- }
+ fp.seek(speechIndex[0], SEEK_SET);
- if (fread(data8, sizeof(uint8), speechIndex[1], fp) != speechIndex[1])
- {
- fclose(fp);
+ if (fp.read(data8, speechIndex[1]) != speechIndex[1]) {
+ fp.close();
return (RDERR_INVALIDID);
}
- fclose(fp);
+ fp.close();
data16[0] = *((int16*)data8); // Starting Value
- i=1;
+ i = 1;
- while (i<(speechIndex[1]-1))
- {
- if (GetCompressedSign(data8[i+1]))
- data16[i] = data16[i-1] - (GetCompressedAmplitude(data8[i+1])<<GetCompressedShift(data8[i+1]));
+ while (i < (speechIndex[1] - 1)) {
+ if (GetCompressedSign(data8[i + 1]))
+ data16[i] = data16[i - 1] - (GetCompressedAmplitude(data8[i + 1]) << GetCompressedShift(data8[i + 1]));
else
- data16[i] = data16[i-1] + (GetCompressedAmplitude(data8[i+1])<<GetCompressedShift(data8[i+1]));
+ data16[i] = data16[i - 1] + (GetCompressedAmplitude(data8[i + 1])<<GetCompressedShift(data8[i + 1]));
i++;
}
return(RD_OK);
}
-
-int32 Sword2Sound::PlayCompSpeech(const char *filename, uint32 speechid, uint8 vol, int8 pan)
-{
-
- uint32 dwBytes1, dwBytes2;
- uint32 i;
+int32 Sword2Sound::PlayCompSpeech(const char *filename, uint32 speechid, uint8 vol, int8 pan) {
+ uint32 i;
uint16 *data16;
- uint8 *data8;
+ uint8 *data8;
uint32 speechIndex[2];
- void *lpv1;
- File fp;
+ void *lpv1;
+ File fp;
uint32 bufferSize;
- if (!speechMuted)
- {
+ if (!speechMuted) {
if (GetSpeechStatus() == RDERR_SPEECHPLAYING)
return RDERR_SPEECHPLAYING;
- // Open the speech cluster and find the data offset & size
- if (fp.open(filename, g_sword2->getGameDataPath()) == false)
+ // Open the speech cluster and find the data offset & size
+ fp.open(filename, g_engine->getGameDataPath());
+ if (fp.isOpen() == false)
return(RDERR_INVALIDFILENAME);
- /* FIXME ? our fseek returns void not int
- if (fp.seek((++speechid) * 8, SEEK_SET))
- {
- fp.close();
- return (RDERR_READERROR);
- }
- */
- fp.seek((++speechid) * 8, SEEK_SET);
- if (fp.read(speechIndex, sizeof(uint32) * 2) != (2 * sizeof(uint32)))
- {
+ fp.seek((++speechid) * 8, SEEK_SET);
+
+ if (fp.read(speechIndex, sizeof(uint32) * 2) != (sizeof(uint32) * 2)) {
fp.close();
return (RDERR_READERROR);
}
- if (speechIndex[0] == 0 || speechIndex[1] == 0)
- {
+ if (speechIndex[0] == 0 || speechIndex[1] == 0) {
fp.close();
return (RDERR_INVALIDID);
}
@@ -1018,23 +498,14 @@ int32 Sword2Sound::PlayCompSpeech(const char *filename, uint32 speechid, uint8 v
bufferSize = (speechIndex[1] - 1) * 2;
// Create tempory buffer for compressed speech
- if ((data8 = (uint8 *)malloc(speechIndex[1])) == NULL)
- {
+ if ((data8 = (uint8 *)malloc(speechIndex[1])) == NULL) {
fp.close();
return(RDERR_OUTOFMEMORY);
}
- /* FIXME ? see above
- if (fp.seek(speechIndex[0], SEEK_SET))
- {
- fp.close();
- free(data8);
- return (RDERR_INVALIDID);
- }
- */
+
fp.seek(speechIndex[0], SEEK_SET);
- if (fp.read(data8, sizeof(uint8) * speechIndex[1]) != (speechIndex[1] * sizeof(uint8)))
- {
+ if (fp.read(data8, speechIndex[1]) != speechIndex[1]) {
fp.close();
free(data8);
return (RDERR_INVALIDID);
@@ -1042,240 +513,187 @@ int32 Sword2Sound::PlayCompSpeech(const char *filename, uint32 speechid, uint8 v
fp.close();
- // Create the speech sample buffer
- /*
- hr = IDirectSound_CreateSoundBuffer(lpDS, &dsbd, &dsbSpeech, NULL);
- if (hr != DS_OK)
- {
- free(data8);
- return(RDERR_CREATESOUNDBUFFER);
- }
-
- // Lock the speech buffer, ready to fill it with data
- hr = IDirectSoundBuffer_Lock(dsbSpeech, 0, dsbd.dwBufferBytes, &lpv1, &dwBytes1, &lpv2, &dwBytes2, 0);
- if (hr == DSERR_BUFFERLOST)
- {
- IDirectSoundBuffer_Restore(dsbSpeech);
- hr = IDirectSoundBuffer_Lock(dsbSpeech, 0, dsbd.dwBufferBytes, &lpv1, &dwBytes1, &lpv2, &dwBytes2, 0);
- }
- */
-
lpv1 = malloc(bufferSize);
- dwBytes1 = dwBytes2 = bufferSize;
- if (1 /*hr == DS_OK*/)
- {
- // decompress data into speech buffer.
- data16 = (uint16*)lpv1;
+ // decompress data into speech buffer.
+ data16 = (uint16*)lpv1;
- data16[0] = *((int16*)data8); // Starting Value
- i=1;
-
- while (i<dwBytes1/2)
- {
- if (GetCompressedSign(data8[i+1]))
- data16[i] = data16[i-1] - (GetCompressedAmplitude(data8[i+1])<<GetCompressedShift(data8[i+1]));
- else
- data16[i] = data16[i-1] + (GetCompressedAmplitude(data8[i+1])<<GetCompressedShift(data8[i+1]));
-
-
- i++;
- }
-
- if (dwBytes1 != bufferSize)
- {
- while (i<(dwBytes1+dwBytes2)/2)
- {
- if (GetCompressedSign(data8[i+1]))
- data16[i] = data16[i-1] - (GetCompressedAmplitude(data8[i+1])<<GetCompressedShift(data8[i+1]));
- else
- data16[i] = data16[i-1] + (GetCompressedAmplitude(data8[i+1])<<GetCompressedShift(data8[i+1]));
-
-
- i++;
- }
- }
-
- free(data8);
-
- // Unlock the buffer now that we've filled it
- //IDirectSoundBuffer_Unlock(dsbSpeech, lpv1, dwBytes1, lpv2, dwBytes2);
+ data16[0] = *((int16*)data8); // Starting Value
+ i = 1;
- // Modify the volume according to the master volume
- /*
- if (speechMuted)
- IDirectSoundBuffer_SetVolume(dsbSpeech, volTable[0]);
+ while (i < bufferSize / 2) {
+ if (GetCompressedSign(data8[i + 1]))
+ data16[i] = data16[i - 1] - (GetCompressedAmplitude(data8[i + 1]) << GetCompressedShift(data8[i + 1]));
else
- IDirectSoundBuffer_SetVolume(dsbSpeech, volTable[vol*speechVol]);
+ data16[i] = data16[i - 1] + (GetCompressedAmplitude(data8[i + 1]) << GetCompressedShift(data8[i + 1]));
+ i++;
+ }
- IDirectSoundBuffer_SetPan(dsbSpeech, panTable[pan+16]);
- */
+ free(data8);
- //TODO: Implement volume change + panning
-
- // Start the speech playing
- speechPaused = 1;
-// IDirectSoundBuffer_Play(dsbSpeech, 0, 0, 0);
+ // Modify the volume according to the master volume
+ if (speechMuted) {
+// IDirectSoundBuffer_SetVolume(dsbSpeech, volTable[0]);
+ } else {
+// IDirectSoundBuffer_SetVolume(dsbSpeech, volTable[vol*speechVol]);
+ }
+// IDirectSoundBuffer_SetPan(dsbSpeech, panTable[pan+16]);
+
+ // Start the speech playing
+ speechPaused = 1;
- uint32 flags = SoundMixer::FLAG_16BITS;
- flags |= SoundMixer::FLAG_AUTOFREE;
+ uint32 flags = SoundMixer::FLAG_16BITS;
+ flags |= SoundMixer::FLAG_AUTOFREE;
- //Until the mixer supports LE samples natively, we need to convert our LE ones to BE
- for (uint j = 0; j < (bufferSize / 2); j++)
- data16[j] = TO_BE_16(data16[j]);
+ //Until the mixer supports LE samples natively, we need to convert our LE ones to BE
+ for (uint j = 0; j < (bufferSize / 2); j++)
+ data16[j] = TO_BE_16(data16[j]);
- PlayingSoundHandle speechHandle = 0;
- _mixer->playRaw(&speechHandle, data16, bufferSize, 22050, flags);
+ soundHandleSpeech = -1;
+ _mixer->playRaw(&soundHandleSpeech, data16, bufferSize, 22050, flags);
- speechStatus = 1;
- }
- else
- {
- //IDirectSoundBuffer_Release(dsbSpeech);
- free(data8);
- return(RDERR_LOCKSPEECHBUFFER);
- }
+ speechStatus = 1;
}
DipMusic();
-
- // return read error for now so we get subtitles
- return (RDERR_READERROR);
+ return (RD_OK);
}
-int32 Sword2Sound::StopSpeechSword2(void)
-
-{
- warning("stub StopSpeechSword2");
-/*
- int32 status;
-
-
+int32 Sword2Sound::StopSpeechSword2(void) {
if (!soundOn)
return(RD_OK);
- if (speechStatus)
- {
- IDirectSoundBuffer_GetStatus(dsbSpeech, &status);
- if (status & DSBSTATUS_PLAYING)
- {
- IDirectSoundBuffer_Stop(dsbSpeech);
-// SetMusicVolume(GetMusicVolume());
- }
-
- IDirectSoundBuffer_Release(dsbSpeech);
- dsbSpeech = 0;
+ if (speechStatus) {
+ g_engine->_mixer->stopHandle(soundHandleSpeech);
+ soundHandleSpeech = -1;
speechStatus = 0;
return(RD_OK);
}
-*/
return(RDERR_SPEECHNOTPLAYING);
-
}
-
-
-int32 Sword2Sound::GetSpeechStatus(void)
-{
- warning("stub GetSpeechStatus");
-/*
- int32 status;
-
-
+int32 Sword2Sound::GetSpeechStatus(void) {
if ((!soundOn) || (!speechStatus))
return(RDSE_SAMPLEFINISHED);
if (speechPaused)
return(RDSE_SAMPLEPLAYING);
- IDirectSoundBuffer_GetStatus(dsbSpeech, &status);
- if (!(status & DSBSTATUS_PLAYING))
- {
+ if (g_engine->_mixer->isChannelActive(soundHandleSpeech) == false) {
speechStatus = 0;
- IDirectSoundBuffer_Release(dsbSpeech);
- dsbSpeech = 0;
-// SetMusicVolume(GetMusicVolume());
+ soundHandleSpeech = -1;
return(RDSE_SAMPLEFINISHED);
}
return(RDSE_SAMPLEPLAYING);
-*/
- return RDSE_SAMPLEFINISHED;
-
}
-
-void Sword2Sound::SetSpeechVolume(uint8 volume)
-{
- warning("stub SetSpeechVolume");
-/*
+void Sword2Sound::SetSpeechVolume(uint8 volume) {
speechVol = volume;
- if (dsbSpeech && !speechMuted && GetSpeechStatus() == RDSE_SAMPLEPLAYING)
- IDirectSoundBuffer_SetVolume(dsbSpeech, volTable[16*speechVol]);
-*/
+ if ((soundHandleSpeech != -1) && !speechMuted && GetSpeechStatus() == RDSE_SAMPLEPLAYING) {
+// IDirectSoundBuffer_SetVolume(dsbSpeech, volTable[16*speechVol]);
+ }
}
-
-uint8 Sword2Sound::GetSpeechVolume()
-{
+uint8 Sword2Sound::GetSpeechVolume() {
return speechVol;
}
-
-void Sword2Sound::MuteSpeech(uint8 mute)
-{
- warning("stub MuteSpeech( %d )", mute);
-/*
+void Sword2Sound::MuteSpeech(uint8 mute) {
speechMuted = mute;
- if (GetSpeechStatus() == RDSE_SAMPLEPLAYING)
- {
- if (mute)
- IDirectSoundBuffer_SetVolume(dsbSpeech, volTable[0]);
- else
- IDirectSoundBuffer_SetVolume(dsbSpeech, volTable[16*speechVol]);
+ if (GetSpeechStatus() == RDSE_SAMPLEPLAYING) {
+ if (mute) {
+// IDirectSoundBuffer_SetVolume(dsbSpeech, volTable[0]);
+ } else {
+// IDirectSoundBuffer_SetVolume(dsbSpeech, volTable[16*speechVol]);
+ }
}
-*/
}
-
-uint8 Sword2Sound::IsSpeechMute(void)
-{
+uint8 Sword2Sound::IsSpeechMute(void) {
return (speechMuted);
}
-
-int32 Sword2Sound::PauseSpeech(void)
-{
- warning("PauseSpeech");
-/*
- if (GetSpeechStatus() == RDSE_SAMPLEPLAYING)
- {
+int32 Sword2Sound::PauseSpeech(void) {
+ if (GetSpeechStatus() == RDSE_SAMPLEPLAYING) {
speechPaused = 1;
- return (IDirectSoundBuffer_Stop(dsbSpeech));
+ g_engine->_mixer->pauseChannels(true);
}
-*/
return(RD_OK);
}
-int32 Sword2Sound::UnpauseSpeech(void)
-{
- warning("UnpauseSpeech");
-/*
- if (speechPaused)
- {
+int32 Sword2Sound::UnpauseSpeech(void) {
+ if (speechPaused) {
speechPaused = 0;
- return (IDirectSoundBuffer_Play(dsbSpeech, 0, 0, 0));
+ g_engine->_mixer->pauseChannels(false);
}
-*/
return(RD_OK);
}
+int32 Sword2Sound::OpenFx(int32 id, uint8 *data) {
+ int32 i, fxi;
+ uint32 *data32;
+ _wavHeader *wav;
+
+ wav = (_wavHeader *) data;
+
+ if (soundOn) {
+ // Check for a valid id.
+ if (id == 0)
+ return(RDERR_INVALIDID);
+
+ // Check that the fx is not already open
+ for (i = 0; i < MAXFX; i++) {
+ if (fxId[i] == id)
+ return(RDERR_FXALREADYOPEN);
+ }
+
+ // Now choose a free slot for the fx
+ fxi = 0;
+ while (fxi < MAXFX) {
+ if (fxId[fxi] == 0)
+ break;
+ fxi++;
+ }
+
+ if (fxi == MAXFX)
+ return(RDERR_NOFREEBUFFERS);
+
+ // Set the sample size - search for the size of the data.
+ i = 0;
+ while (i < 100) {
+ if (*data == 'd') {
+ data32 = (uint32*)data;
+ if (*data32 == 'atad')
+ break;
+ }
+ i += 1;
+ data++;
+ }
+ if (i == 100)
+ return(RDERR_INVALIDWAV);
+
+ bufferSizeFx[fxi] = *(data32 + 1);
+
+ // Fill the speech buffer with data
+ if (bufferFx[fxi] != NULL)
+ free(bufferFx[fxi]);
+ bufferFx[fxi] = (uint16*)malloc(bufferSizeFx[fxi]);
+ memcpy(bufferFx[fxi], (uint8 *)(data32 + 2), bufferSizeFx[fxi]);
+ flagsFx[fxi] = SoundMixer::FLAG_16BITS;
+ if (wav->channels == 2)
+ flagsFx[fxi] |= SoundMixer::FLAG_STEREO;
+
+ //Until the mixer supports LE samples natively, we need to convert our LE ones to BE
+ for (int32 j = 0; j < (bufferSizeFx[fxi] / 2); j++)
+ bufferFx[fxi][j] = TO_BE_16(bufferFx[fxi][j]);
-int32 Sword2Sound::OpenFx(int32 id, uint8 *data)
+ fxId[fxi] = id;
+ fxCached[fxi] = RDSE_FXCACHED;
+ }
+ return(RD_OK);
-{
- warning("stub OpenFx( %d )", id);
/*
uint32 dwBytes1, dwBytes2;
int32 i, fxi;
@@ -1381,16 +799,116 @@ int32 Sword2Sound::OpenFx(int32 id, uint8 *data)
fxCached[fxi] = RDSE_FXCACHED;
}
-*/
return(RD_OK);
-
+*/
}
+int32 Sword2Sound::PlayFx(int32 id, uint8 *data, uint8 vol, int8 pan, uint8 type) {
+ int32 i, loop;
+ HRESULT hr;
+return RD_OK;
+ if (type == RDSE_FXLOOP)
+ loop = 1;
+ else
+ loop = 0;
-int32 Sword2Sound::PlayFx(int32 id, uint8 *data, uint8 vol, int8 pan, uint8 type)
+ if (soundOn) {
+ if (data == NULL) {
+ if (type == RDSE_FXLEADOUT) {
+ id = 0xffffffff;
+ i = GetFxIndex(id);
+ if (i == MAXFX) {
+ return(RDERR_FXNOTOPEN);
+ }
+ fxLooped[i] = 0;
+ flagsFx[i] &= ~SoundMixer::FLAG_LOOP;
+
+ // Start the sound effect playing
+ if (musicMuted) {
+// IDirectSoundBuffer_SetVolume(dsbFx[i], volTable[0]);
+ } else {
+// IDirectSoundBuffer_SetVolume(dsbFx[i], musicVolTable[volMusic[0]]);
+ }
+// IDirectSoundBuffer_SetPan(dsbFx[i], 0);
+ g_engine->_mixer->playRaw(&soundHandleFx[i], bufferFx[i], bufferSizeFx[i], 22050, flagsFx[i]);
+
+ fxCached[i] = RDSE_FXTOCLEAR;
+ } else {
+ i = GetFxIndex(id);
+ if (i == MAXFX) {
+ return(RDERR_FXNOTOPEN);
+ }
+ fxLooped[i] = loop;
+ if (loop == 1)
+ flagsFx[i] |= SoundMixer::FLAG_LOOP;
+ else
+ flagsFx[i] &= ~SoundMixer::FLAG_LOOP;
+
+ fxVolume[i] = vol;
+
+ // Start the sound effect playing
+ if (fxMuted) {
+// IDirectSoundBuffer_SetVolume(dsbFx[i], volTable[0]);
+ } else {
+// IDirectSoundBuffer_SetVolume(dsbFx[i], volTable[vol*fxVol]);
+ }
+// IDirectSoundBuffer_SetPan(dsbFx[i], panTable[pan+16]);
+
+ g_engine->_mixer->playRaw(&soundHandleFx[i], bufferFx[i], bufferSizeFx[i], 22050, flagsFx[i]);
+ if (id == 0xffffffff) {
+ fxCached[i] = RDSE_FXTOCLEAR;
+ }
+ }
+ } else {
+ if (type == RDSE_FXLEADIN) {
+ id = 0xfffffffe;
+ hr = OpenFx(id, data);
+ if (hr != RD_OK) {
+ return hr;
+ }
+ i = GetFxIndex(id);
+ if (i == MAXFX) {
+ return RDERR_FXFUCKED;
+ }
+ fxCached[i] = RDSE_FXTOCLEAR;
+ if (musicMuted) {
+// IDirectSoundBuffer_SetVolume(dsbFx[i], volTable[0]);
+ } else {
+// IDirectSoundBuffer_SetVolume(dsbFx[i], musicVolTable[volMusic[0]]);
+ }
+// IDirectSoundBuffer_SetPan(dsbFx[i], 0);
+ g_engine->_mixer->playRaw(&soundHandleFx[i], bufferFx[i], bufferSizeFx[i], 22050, flagsFx[i]);
+ } else {
+ hr = OpenFx(id, data);
+ if (hr != RD_OK) {
+ return(hr);
+ }
+
+ i = GetFxIndex(id);
+ if (i == MAXFX) {
+ return(RDERR_FXFUCKED);
+ }
+ fxCached[i] = RDSE_FXTOCLEAR;
+ fxLooped[i] = loop;
+ if (loop == 1)
+ flagsFx[i] |= SoundMixer::FLAG_LOOP;
+ else
+ flagsFx[i] &= ~SoundMixer::FLAG_LOOP;
+ fxVolume[i] = vol;
+
+ // Start the sound effect playing
+ if (fxMuted) {
+// IDirectSoundBuffer_SetVolume(dsbFx[i], volTable[0]);
+ } else {
+// IDirectSoundBuffer_SetVolume(dsbFx[i], volTable[vol*fxVol]);
+ }
+// IDirectSoundBuffer_SetPan(dsbFx[i], panTable[pan+16]);
+ g_engine->_mixer->playRaw(&soundHandleFx[i], bufferFx[i], bufferSizeFx[i], 22050, flagsFx[i]);
+ }
+ }
+ }
+ return(RD_OK);
-{
- warning("stub PlayFx( %d, %d, %d, %d )", id, vol, pan, type);
/*
int32 i, loop;
HRESULT hr;
@@ -1487,839 +1005,414 @@ int32 Sword2Sound::PlayFx(int32 id, uint8 *data, uint8 vol, int8 pan, uint8 type
}
}
}
-*/
return(RD_OK);
-
+*/
}
-
-int32 Sword2Sound::SetFxVolumePan(int32 id, uint8 vol, int8 pan)
-{
- warning("stub SetFxVolumePan( %d, %d, %d )", id, vol, pan);
-/*
+int32 Sword2Sound::SetFxVolumePan(int32 id, uint8 vol, int8 pan) {
int32 i = GetFxIndex(id);
if (i == MAXFX)
return RDERR_FXNOTOPEN;
fxVolume[i] = vol;
- if (!fxMuted)
- IDirectSoundBuffer_SetVolume(dsbFx[i], volTable[vol*fxVol]);
- IDirectSoundBuffer_SetPan(dsbFx[i], panTable[pan+16]);
-*/
+ if (!fxMuted) {
+// IDirectSoundBuffer_SetVolume(dsbFx[i], volTable[vol*fxVol]);
+// IDirectSoundBuffer_SetPan(dsbFx[i], panTable[pan+16]);
+ }
return RD_OK;
}
-int32 Sword2Sound::SetFxIdVolume(int32 id, uint8 vol)
-{
- warning("stub SetFxIdVolume( %d, %d )", id, vol);
-/*
+int32 Sword2Sound::SetFxIdVolume(int32 id, uint8 vol) {
int32 i = GetFxIndex(id);
if (i == MAXFX)
return RDERR_FXNOTOPEN;
fxVolume[i] = vol;
- if (!fxMuted)
- IDirectSoundBuffer_SetVolume(dsbFx[i], volTable[vol*fxVol]);
-*/
+ if (!fxMuted) {
+// IDirectSoundBuffer_SetVolume(dsbFx[i], volTable[vol*fxVol]);
+ }
return RD_OK;
}
-
-
-int32 Sword2Sound::ClearAllFx(void)
-
-{
- warning("stub ClearAllFx");
-/*
- int32 status;
- int32 i;
-
+int32 Sword2Sound::ClearAllFx(void) {
+ int i;
if (!soundOn)
return(RD_OK);
i = 0;
- while (i < MAXFX)
- {
- if ((fxId[i]) && (fxId[i] != 0xfffffffe) && (fxId[i] != 0xffffffff))
- {
- IDirectSoundBuffer_GetStatus(dsbFx[i], &status);
- if (status & (DSBSTATUS_PLAYING + DSBSTATUS_LOOPING))
- {
- IDirectSoundBuffer_Stop(dsbFx[i]);
- }
- IDirectSoundBuffer_Release(dsbFx[i]);
+ while (i < MAXFX) {
+ if ((fxId[i]) && (fxId[i] != 0xfffffffe) && (fxId[i] != 0xffffffff)) {
+ g_engine->_mixer->stopHandle(soundHandleFx[i]);
fxId[i] = 0;
fxiPaused[i] = 0;
+ if (bufferFx[i] != NULL) {
+ free(bufferFx[i]);
+ bufferFx[i] = NULL;
+ }
+ bufferSizeFx[i] = 0;
+ flagsFx[i] = 0;
}
i++;
}
-
-*/
return(RD_OK);
-
}
-
-int32 Sword2Sound::CloseFx(int32 id)
-
-{
- warning("stub CloseFx( %d )", id);
-/*
- int32 i;
- int32 status;
-
+int32 Sword2Sound::CloseFx(int32 id) {
+ int i;
if (!soundOn)
return(RD_OK);
i = GetFxIndex(id);
- if (i<MAXFX)
- {
- IDirectSoundBuffer_GetStatus(dsbFx[i], &status);
- if (status & (DSBSTATUS_PLAYING + DSBSTATUS_LOOPING))
- {
- IDirectSoundBuffer_Stop(dsbFx[i]);
- }
-
- IDirectSoundBuffer_Release(dsbFx[i]);
+ if (i < MAXFX) {
+ g_engine->_mixer->stopHandle(soundHandleFx[i]);
fxId[i] = 0;
fxiPaused[i] = 0;
+ if (bufferFx[i] != NULL) {
+ free(bufferFx[i]);
+ bufferFx[i] = NULL;
+ }
+ bufferSizeFx[i] = 0;
+ flagsFx[i] = 0;
}
-*/
return(RD_OK);
-
}
+int32 Sword2Sound::PauseFx(void) {
+ int i;
-int32 Sword2Sound::PauseFx(void)
-
-{
- warning("stub PauseFx");
-/*
- int32 i;
- int32 status;
-
- if (!fxPaused)
- {
- for (i=0; i<MAXFX; i++)
- {
- if (fxId[i])
- {
- IDirectSoundBuffer_GetStatus(dsbFx[i], &status);
- if (status & (DSBSTATUS_PLAYING + DSBSTATUS_LOOPING))
- {
- fxiPaused[i] = 1;
- if (IDirectSoundBuffer_Stop(dsbFx[i]) != RD_OK)
- return(RDERR_FXFUCKED);
- }
- }
- else
- {
+ if (!fxPaused) {
+ for (i = 0; i < MAXFX; i++) {
+ if (fxId[i]) {
+ g_engine->_mixer->pauseChannels(true);
+ fxiPaused[i] = 1;
+ } else {
fxiPaused[i] = 0;
}
}
fxPaused = 1;
}
-*/
return (RD_OK);
-
}
+int32 Sword2Sound::PauseFxForSequence(void) {
+ int i;
-int32 Sword2Sound::PauseFxForSequence(void)
-
-{
- warning("stub PauseFxForSequence");
-/*
- int32 i;
- int32 status;
-
- if (!fxPaused)
- {
- for (i=0; i<MAXFX; i++)
- {
- if ((fxId[i]) && (fxId[i] != 0xfffffffe))
- {
- IDirectSoundBuffer_GetStatus(dsbFx[i], &status);
- if (status & (DSBSTATUS_PLAYING + DSBSTATUS_LOOPING))
- {
- fxiPaused[i] = 1;
- IDirectSoundBuffer_Stop(dsbFx[i]);
- }
- }
- else
- {
+ if (!fxPaused) {
+ for (i = 0; i<MAXFX; i++) {
+ if ((fxId[i]) && (fxId[i] != 0xfffffffe)) {
+ g_engine->_mixer->stopHandle(soundHandleFx[i]);
+ fxiPaused[i] = 1;
+ } else {
fxiPaused[i] = 0;
}
}
fxPaused = 1;
}
-*/
return (RD_OK);
-
}
+int32 Sword2Sound::UnpauseFx(void) {
+ int i;
-
-int32 Sword2Sound::UnpauseFx(void)
-
-{
- warning("stub UnpauseFx");
-/*
- int32 i;
-
- if (fxPaused)
- {
- for (i=0; i<MAXFX; i++)
- {
- if (fxiPaused[i] && fxId[i])
- {
- if (IDirectSoundBuffer_Play(dsbFx[i], 0, 0, fxLooped[i]) != RD_OK)
- return(RDERR_FXFUCKED);
+ if (fxPaused) {
+ for (i = 0; i < MAXFX; i++) {
+ if (fxiPaused[i] && fxId[i]) {
+ g_engine->_mixer->pauseChannels(false);
}
}
fxPaused = 0;
}
-*/
return (RD_OK);
}
-
-
-uint8 Sword2Sound::GetFxVolume()
-{
+uint8 Sword2Sound::GetFxVolume() {
return fxVol;
}
-
-void Sword2Sound::SetFxVolume(uint8 volume)
-{
- warning("stub SetFxVolume( %d )", volume);
-/*
+void Sword2Sound::SetFxVolume(uint8 volume) {
int32 fxi;
fxVol = volume;
// Now update the volume of any fxs playing
- for (fxi = 0; fxi<MAXFX; fxi++)
- {
- if (fxId[fxi] && !fxMuted)
- IDirectSoundBuffer_SetVolume(dsbFx[fxi], volTable[fxVolume[fxi]*fxVol]);
+ for (fxi = 0; fxi < MAXFX; fxi++) {
+ if (fxId[fxi] && !fxMuted) {
+// IDirectSoundBuffer_SetVolume(dsbFx[fxi], volTable[fxVolume[fxi]*fxVol]);
+ }
}
-*/
}
-
-void Sword2Sound::MuteFx(uint8 mute)
-{
- warning("stub MuteFx( %d )", mute);
-/*
+void Sword2Sound::MuteFx(uint8 mute) {
int32 fxi;
fxMuted = mute;
// Now update the volume of any fxs playing
- for (fxi = 0; fxi<MAXFX; fxi++)
- {
- if (fxId[fxi])
- {
- if (mute)
- IDirectSoundBuffer_SetVolume(dsbFx[fxi], volTable[0]);
- else
- IDirectSoundBuffer_SetVolume(dsbFx[fxi], volTable[fxVolume[fxi]*fxVol]);
+ for (fxi = 0; fxi < MAXFX; fxi++) {
+ if (fxId[fxi]) {
+ if (mute) {
+// IDirectSoundBuffer_SetVolume(dsbFx[fxi], volTable[0]);
+ } else {
+// IDirectSoundBuffer_SetVolume(dsbFx[fxi], volTable[fxVolume[fxi]*fxVol]);
+ }
}
}
-*/
}
-uint8 Sword2Sound::IsFxMute(void)
-{
+uint8 Sword2Sound::IsFxMute(void) {
return (fxMuted);
}
-
-
-
-void Sword2Sound::StartMusicFadeDown(int i)
-
-{
-
-// IDirectSoundBuffer_Stop(lpDsbMus[i]);
-// IDirectSoundBuffer_Release(lpDsbMus[i]);
+void Sword2Sound::StartMusicFadeDown(int i) {
+ g_engine->_mixer->endStream(soundHandleMusic[i]);
musFading[i] = -16;
-// musStreaming[i] = 0;
- fpMus[i].close();
-
+ musStreaming[i] = 0;
+ fpMus.close();
}
-
-int32 Sword2Sound::StreamMusic(uint8 *filename, int32 looping)
-
-{
- warning("stub StreamMusic( %s, %d )", filename, looping);
-/*
-
- HRESULT hr;
- LPVOID lpv1, lpv2;
- DWORD dwBytes1, dwBytes2;
- int32 i;
+int32 Sword2Sound::StreamCompMusic(const char *filename, uint32 musicId, int32 looping) {
+ int32 i, j;
int32 v0, v1;
- int32 bytes;
- _wavHeader head;
-
- // Do not allow compressed and uncompressed music to be streamed at the same time.
- if (compressedMusic == 1)
- return (RDERR_FXFUCKED);
-
- compressedMusic = 2;
-
+ uint16 *data16;
+ uint8 *data8;
- if (musStreaming[0] + musStreaming[1] == 0)
- {
+ compressedMusic = 1;
+ if (musStreaming[0] + musStreaming[1] == 0) {
i = 0;
- fpMus[i] = fopen(filename, "rb");
- if (fpMus[i] == NULL)
- return(RDERR_INVALIDFILENAME);
-
- fread(&head, sizeof(_wavHeader), 1, fpMus[i]);
- streamCursor[i] = 0;
- musLooping[i] = looping;
-
-
- memset(&wfMus[i], 0, sizeof(PCMWAVEFORMAT));
- wfMus[i].wf.wFormatTag = WAVE_FORMAT_PCM;
- wfMus[i].wf.nChannels = head.channels;
- wfMus[i].wf.nSamplesPerSec = head.samplesPerSec;
- wfMus[i].wBitsPerSample = 8 * head.blockAlign / (head.samplesPerSec * head.channels);
- wfMus[i].wf.nBlockAlign = wfMus[i].wf.nChannels * wfMus[i].wBitsPerSample / 8;
- wfMus[i].wf.nAvgBytesPerSec = wfMus[i].wf.nSamplesPerSec * wfMus[i].wf.nBlockAlign;
-
-
- // Reset the sample format and size
- memset(&dsbdMus[i], 0, sizeof(DSBUFFERDESC));
- dsbdMus[i].dwSize = sizeof(DSBUFFERDESC);
-// dsbdMus[i].dwFlags = DSBCAPS_CTRLDEFAULT;
- dsbdMus[i].dwBufferBytes = 3 * wfMus[i].wf.nAvgBytesPerSec; // 3 seconds
- dsbdMus[i].lpwfxFormat = (LPWAVEFORMATEX) &wfMus[i];
-
- // Create the sound effect sample buffer
- hr = IDirectSound_CreateSoundBuffer(lpDS, &dsbdMus[i], &lpDsbMus[i], NULL);
- if (hr == DS_OK)
- {
- hr = IDirectSoundBuffer_Lock(lpDsbMus[i], 0, dsbdMus[i].dwBufferBytes, &lpv1, &dwBytes1, &lpv2, &dwBytes2, 0);
-
- if (hr == DSERR_BUFFERLOST)
- {
- IDirectSoundBuffer_Restore(lpDsbMus[i]);
- hr = IDirectSoundBuffer_Lock(lpDsbMus[i], 0, dsbdMus[i].dwBufferBytes, &lpv1, &dwBytes1, &lpv2, &dwBytes2, 0);
- }
-
- if (hr == DS_OK)
- {
-
- // Fill the speech buffer with data
- bytes = fread(lpv1, 1, dwBytes1, fpMus[i]);
-// memcpy((uint8 *) lpv1, (uint8 *) wavData + sizeof(wavHeader), dwBytes1);
-
- // Unlock the buffer now that we've filled it
- IDirectSoundBuffer_Unlock(lpDsbMus[i], lpv1, dwBytes1, lpv2, dwBytes2);
-
- // Modify the volume according to the master volume and music mute state
- if (musicMuted)
- v0 = v1 = 0;
- else
- {
- v0 = volMusic[0];
- v1 = volMusic[1];
- }
-
- if (v0 > v1)
- {
- IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v0]);
- IDirectSoundBuffer_SetPan(lpDsbMus[i], musicVolTable[v1*16/v0]);
- }
- else
- {
- if (v1 > v0)
- {
- IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v1]);
- IDirectSoundBuffer_SetPan(lpDsbMus[i], -musicVolTable[v0*16/v1]);
- }
- else
- {
- IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v1]);
- IDirectSoundBuffer_SetPan(lpDsbMus[i], 0);
- }
- }
-
-
- // Start the sound effect playing
- IDirectSoundBuffer_Play(lpDsbMus[i], 0, 0, DSBPLAY_LOOPING);
-
- musStreaming[i] = 1;
- musCounter[i] = 250;
- strcpy(musFilename[i], filename);
-
- // and exit the function.
- }
- else
- {
-// Pdebug("Failed to lock sound buffer upon creation - (%d)", hr & 0x0000ffff);
-// DirectSoundDebug("Error - ", hr);
- fclose(fpMus[i]);
- return(RDERR_LOCKFAILED);
- }
- }
- else
- {
-// Pdebug("Failed to create sound buffer - (%d)", hr & 0x0000ffff);
-// Pdebug("Error - ", hr);
- fclose(fpMus[i]);
- return(RDERR_CREATESOUNDBUFFER);
- }
- }
- else if (musStreaming[0] + musStreaming[1] == 1)
- {
-
- i = musStreaming[0];
- musLooping[i] = looping;
+ musLooping[i] = looping; // Save looping info
+ strcpy(musFilename[i], filename); // And tune id's
+ musId[i] = musicId;
- if (!musFading[1-i])
- StartMusicFadeDown(1 - i);
+ if (IsMusicMute()) // Don't start streaming if the volume is off.
+ return (RD_OK);
- fpMus[i] = fopen(filename, "rb");
- if (fpMus[i] == NULL)
+ fpMus.open(filename, g_engine->getGameDataPath()); // Always use fpMus[0] (all music in one cluster) musFilePos[i] for different pieces of music.
+ if (fpMus.isOpen() == false)
return(RDERR_INVALIDFILENAME);
- fread(&head, sizeof(_wavHeader), 1, fpMus[i]);
- streamCursor[i] = 0;
-
-
- memset(&wfMus[i], 0, sizeof(PCMWAVEFORMAT));
- wfMus[i].wf.wFormatTag = WAVE_FORMAT_PCM;
- wfMus[i].wf.nChannels = head.channels;
- wfMus[i].wf.nSamplesPerSec = head.samplesPerSec;
- wfMus[i].wBitsPerSample = 8 * head.blockAlign / (head.samplesPerSec * head.channels);
- wfMus[i].wf.nBlockAlign = wfMus[i].wf.nChannels * wfMus[i].wBitsPerSample / 8;
- wfMus[i].wf.nAvgBytesPerSec = wfMus[i].wf.nSamplesPerSec * wfMus[i].wf.nBlockAlign;
-
-
- // Reset the sample format and size
- memset(&dsbdMus[i], 0, sizeof(DSBUFFERDESC));
- dsbdMus[i].dwSize = sizeof(DSBUFFERDESC);
-// dsbdMus[i].dwFlags = DSBCAPS_CTRLDEFAULT;
- dsbdMus[i].dwBufferBytes = 6 * wfMus[i].wf.nAvgBytesPerSec; // 3 seconds
- dsbdMus[i].lpwfxFormat = (LPWAVEFORMATEX) &wfMus[i];
-
- // Create the sound effect sample buffer
- hr = IDirectSound_CreateSoundBuffer(lpDS, &dsbdMus[i], &lpDsbMus[i], NULL);
- if (hr == DS_OK)
- {
- hr = IDirectSoundBuffer_Lock(lpDsbMus[i], 0, dsbdMus[i].dwBufferBytes, &lpv1, &dwBytes1, &lpv2, &dwBytes2, 0);
-
- if (hr == DSERR_BUFFERLOST)
- {
- IDirectSoundBuffer_Restore(lpDsbMus[i]);
- hr = IDirectSoundBuffer_Lock(lpDsbMus[i], 0, dsbdMus[i].dwBufferBytes, &lpv1, &dwBytes1, &lpv2, &dwBytes2, 0);
- }
-
- if (hr == DS_OK)
- {
-
- // Fill the speech buffer with data
- bytes = fread(lpv1, 1, dwBytes1, fpMus[i]);
-// Pdebug("Read %d bytes\n", bytes);
-// memcpy((uint8 *) lpv1, (uint8 *) wavData + sizeof(_wavHeader), dwBytes1);
-
- // Unlock the buffer now that we've filled it
- IDirectSoundBuffer_Unlock(lpDsbMus[i], lpv1, dwBytes1, lpv2, dwBytes2);
-
- // Modify the volume according to the master volume and music mute state
- if (musicMuted)
- v0 = v1 = 0;
- else
- {
- v0 = volMusic[0];
- v1 = volMusic[1];
- }
+ fpMus.seek((musicId + 1) * 8, SEEK_SET);
+ if (fpMus.read(&musFilePos[i], sizeof(uint32)) != sizeof(uint32)) {
+ fpMus.close();
+ return (RDERR_READERROR);
+ }
- if (v0 > v1)
- {
- IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v0]);
- IDirectSoundBuffer_SetPan(lpDsbMus[i], musicVolTable[v1*16/v0]);
- }
- else
- {
- if (v1 > v0)
- {
- IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v1]);
- IDirectSoundBuffer_SetPan(lpDsbMus[i], -musicVolTable[v0*16/v1]);
- }
- else
- {
- IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v1]);
- IDirectSoundBuffer_SetPan(lpDsbMus[i], 0);
- }
- }
-
-
- // Start the sound effect playing
- IDirectSoundBuffer_Play(lpDsbMus[i], 0, 0, DSBPLAY_LOOPING);
-
- musStreaming[i] = 1;
- musCounter[i] = 250;
- strcpy(musFilename[i], filename);
-
- }
- else
- {
-// Pdebug("Failed to lock sound buffer upon creation - (%d)", hr & 0x0000ffff);
-// DirectSoundDebug("Error - ", hr);
- fclose(fpMus[i]);
- return(RDERR_LOCKFAILED);
- }
- }
- else
- {
-// Pdebug("Failed to create sound buffer - (%d)", hr & 0x0000ffff);
-// Pdebug("Error - ", hr);
- fclose(fpMus[i]);
- return(RDERR_CREATESOUNDBUFFER);
+ if (fpMus.read(&musEnd[i], sizeof(uint32)) != sizeof(uint32)) {
+ fpMus.close();
+ return (RDERR_READERROR);
}
- }
-*/
- return(RD_OK);
-}
+ if (!musEnd[i] || !musFilePos[i]) {
+ fpMus.close();
+ return (RDERR_INVALIDID);
+ }
+ musEnd[i] += musFilePos[i]; // Calculate the file position of the end of the music
-void Sword2Sound::UpdateSampleStreaming(void)
+ // Create a temporary buffer
+ data8 = (uint8*)malloc(bufferSizeMusic / 2);
+ if (data8 == NULL) {
+ fpMus.close();
+ return(RDERR_OUTOFMEMORY);
+ }
-{
- warning("stub UpdateSampleStreaming");
-/*
+ // Seek to start of the compressed music
+ fpMus.seek(musFilePos[i], SEEK_SET);
- int32 i;
- int32 v0, v1;
- int32 readLen;
- int32 len;
- int32 readCursor, writeCursor;
- int32 dwBytes1, dwBytes2;
- LPVOID lpv1, lpv2;
- HRESULT hr;
+ // Read the compressed data in to the buffer
+ if (fpMus.read(data8, bufferSizeMusic / 2) != bufferSizeMusic / 2) {
+ fpMus.close();
+ free(data8);
+ return (RDERR_INVALIDID);
+ }
+ // Store the current position in the file for future streaming
+ musFilePos[i] = fpMus.pos();
- for (i=0; i<MAXMUS; i++)
- {
- if (musStreaming[i])
- {
- if (musFading[i])
- {
- if (musFading[i] < 0)
- {
- if (++musFading[i] == 0)
- {
- IDirectSoundBuffer_Stop(lpDsbMus[i]);
- IDirectSoundBuffer_Release(lpDsbMus[i]);
- musStreaming[i] = 0;
- }
- else
- {
- // Modify the volume according to the master volume and music mute state
- if (musicMuted)
- v0 = v1 = 0;
- else
- {
- v0 = (volMusic[0] * (0 - musFading[i]) / 16);
- v1 = (volMusic[1] * (0 - musFading[i]) / 16);
- }
+ // decompress the music into the music buffer.
+ data16 = (uint16 *)malloc(bufferSizeMusic);
+
+ data16[0] = *((int16 *)data8); // First sample value
+ j = 1;
- if (v0 > v1)
- {
- IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v0]);
- IDirectSoundBuffer_SetPan(lpDsbMus[i], musicVolTable[v1*16/v0]);
- }
- else
- {
- if (v1 > v0)
- {
- IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v1]);
- IDirectSoundBuffer_SetPan(lpDsbMus[i], -musicVolTable[v0*16/v1]);
- }
- else
- {
- IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v1]);
- IDirectSoundBuffer_SetPan(lpDsbMus[i], 0);
- }
- }
- }
- }
- }
+ while (j < (bufferSizeMusic / 2) - 1) {
+ if (GetCompressedSign(data8[j + 1]))
+ data16[j] = data16[j - 1] - (GetCompressedAmplitude(data8[j + 1]) << GetCompressedShift(data8[j + 1]));
else
- {
-
- if (IDirectSoundBuffer_GetCurrentPosition(lpDsbMus[i], &readCursor, &writeCursor) != DS_OK)
- {
-// Pdebug ("Stopping sample %d cos cant get position", i);
- IDirectSoundBuffer_Stop(lpDsbMus[i]);
- }
+ data16[j] = data16[j - 1] + (GetCompressedAmplitude(data8[j + 1]) << GetCompressedShift(data8[j + 1]));
+ j++;
+ }
+ // Store the value of the last sample ready for next batch of decompression
+ musLastSample[i] = data16[j - 1];
- len = readCursor - streamCursor[i];
- if (len < 0)
- {
- len += dsbdMus[i].dwBufferBytes;
- }
- if (len > 0)
- {
- hr = IDirectSoundBuffer_Lock(lpDsbMus[i], streamCursor[i], len, &lpv1, &dwBytes1, &lpv2, &dwBytes2, 0);
- if (hr == DSERR_BUFFERLOST)
- {
- IDirectSoundBuffer_Restore(lpDsbMus[i]);
- hr = IDirectSoundBuffer_Lock(lpDsbMus[i], streamCursor[i], len, &lpv1, &dwBytes1, &lpv2, &dwBytes2, 0);
- }
+ // Free the decompression buffer and unlock the buffer now that we've filled it
+ free(data8);
- if (hr == DS_OK)
- {
- streamCursor[i] += len;
- if (streamCursor[i] >= (int32) dsbdMus[i].dwBufferBytes)
- streamCursor[i] -= dsbdMus[i].dwBufferBytes;
+ // Modify the volume according to the master volume and music mute state
+ if (musicMuted)
+ v0 = v1 = 0;
+ else {
+ v0 = volMusic[0];
+ v1 = volMusic[1];
+ }
- if (len > dwBytes1)
- {
- readLen = fread(lpv1, 1, dwBytes1, fpMus[i]);
- if (readLen == dwBytes1)
- {
- readLen = fread(lpv2, 1, dwBytes2, fpMus[i]);
- if (readLen != dwBytes2)
- {
- IDirectSoundBuffer_Unlock(lpDsbMus[i], lpv1, dwBytes1, lpv2, dwBytes2);
- StartMusicFadeDown(i);
- if (musLooping[i])
- {
- StreamMusic(musFilename[i], musLooping[i]);
- }
- }
- else
- {
- IDirectSoundBuffer_Unlock(lpDsbMus[i], lpv1, dwBytes1, lpv2, dwBytes2);
- }
- }
- else
- {
- IDirectSoundBuffer_Unlock(lpDsbMus[i], lpv1, dwBytes1, lpv2, dwBytes2);
- StartMusicFadeDown(i);
- if (musLooping[i])
- {
- StreamMusic(musFilename[i], musLooping[i]);
- }
- }
- }
- else
- {
- readLen = fread(lpv1, 1, len, fpMus[i]);
- if (readLen != len)
- {
- IDirectSoundBuffer_Unlock(lpDsbMus[i], lpv1, dwBytes1, lpv2, dwBytes2);
- StartMusicFadeDown(i);
- if (musLooping[i])
- {
- StreamMusic(musFilename[i], musLooping[i]);
- }
- }
- else
- {
- IDirectSoundBuffer_Unlock(lpDsbMus[i], lpv1, dwBytes1, lpv2, dwBytes2);
- }
- }
- }
-// else
-// {
-// DirectSoundDebug("Failed to lock sound buffer to write bytes", hr);
-// Pdebug("Stream cursor %d", streamCursor[i]);
-// Pdebug("len %d", len);
-// }
- }
- //}
+ if (v0 > v1) {
+// IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v0]);
+// IDirectSoundBuffer_SetPan(lpDsbMus[i], musicVolTable[v1*16/v0]);
+ } else {
+ if (v1 > v0) {
+// IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v1]);
+// IDirectSoundBuffer_SetPan(lpDsbMus[i], -musicVolTable[v0*16/v1]);
+ } else {
+// IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v1]);
+// IDirectSoundBuffer_SetPan(lpDsbMus[i], 0);
}
}
- }
-*/
-}
+ //Until the mixer supports LE samples natively, we need to convert our LE ones to BE
+ for (int32 j = 0; j < (bufferSizeMusic / 2); j++) {
+ data16[j] = TO_BE_16(data16[j]);
+ }
+ if (soundHandleMusic[i] == -1) {
+ soundHandleMusic[i] = g_engine->_mixer->newStream(data16, bufferSizeMusic, 22050, SoundMixer::FLAG_16BITS, 100000);
+ } else {
+ g_engine->_mixer->appendStream(soundHandleMusic[i], data16, bufferSizeMusic);
+ }
-int32 Sword2Sound::StreamCompMusic(const char *filename, const char *directory, uint32 musicId, int32 looping) {
- // FIXME: Find a good buffer size. The original code mentions three
- // seconds.
- uint32 buffer_size = 32768;
- uint32 i, j;
- int32 v0, v1;
- uint16 *data16;
- uint8 *data8;
-
- warning("stub StreamCompMusic( %s, %d, %d )", filename, musicId, looping);
-
- // Do not allow compressed and uncompressed music to be streamed at
- // the same time.
- if (compressedMusic == 2)
- return RDERR_FXFUCKED;
-
- compressedMusic = 1;
+ free(data16);
- if (musStreaming[0] + musStreaming[1] == 2) {
- // Both streams in use, try to find a fading stream
+ // Recorder some last variables
+ musStreaming[i] = 1;
+ musCounter[i] = 250;
+ } else if (musStreaming[0] + musStreaming[1] == 2) {
if (musFading[0])
i = 0;
else
i = 1;
-
+
musFading[i] = 0;
- _mixer->stop(musicChannels[i]);
+ g_engine->_mixer->endStream(soundHandleMusic[i]);
musStreaming[i] = 0;
- }
+ } else if (musStreaming[0] + musStreaming[1] == 1) {
+ i = musStreaming[0]; // Set i to the free channel
- if (musStreaming[0] + musStreaming[1] == 1) {
- // Set i to the free channel
- i = musStreaming[0];
- } else {
- // No music streaming at present
- i = 0;
- }
+ musLooping[i] = looping; // Save looping info
+ strcpy(musFilename[i], filename); // And tune id's
+ musId[i] = musicId;
- musLooping[i] = looping; // Save looping info
- strcpy(musFilename[i], filename); // And tune id's
- musId[i] = musicId;
+ if (IsMusicMute()) // Don't start streaming if the volume is off.
+ return (RD_OK);
- // Don't start streaming if the volume is off.
- if (IsMusicMute())
- return RD_OK;
+ if (fpMus.isOpen() == false)
+ fpMus.open(filename, g_engine->getGameDataPath()); // Always use fpMus[0] (all music in one cluster) musFilePos[i] for different pieces of music.
+ if (fpMus.isOpen() == false)
+ return(RDERR_INVALIDFILENAME);
- // Always use fpMus[0] (all music in one cluster)
- // musFilePos[i] for different pieces of music.
- if (!fpMus[0].isOpen()) {
- if (!fpMus[0].open(filename, directory))
- return RDERR_INVALIDFILENAME;
- }
+ if (!musFading[1 - i]) // Start other music stream fading out
+ musFading[1 - i] = -16;
- if (musStreaming[0] + musStreaming[1] == 1) {
- // Start other music stream fading out
- if (!musFading[i - 1])
- musFading[i - 1] = -16;
+ fpMus.seek((musicId + 1) * 8, SEEK_SET);
- // Restart the streaming cursor for this sample
- streamCursor[i] = 0;
- }
+ if (fpMus.read(&musFilePos[i], sizeof(uint32)) != sizeof(uint32)) {
+ fpMus.close();
+ return (RDERR_READERROR);
+ }
- // Seek to music index
- fpMus[0].seek((musicId + 1) * 8);
+ if (fpMus.read(&musEnd[i], sizeof(uint32)) != sizeof(uint32)) {
+ fpMus.close();
+ return (RDERR_READERROR);
+ }
- musFilePos[i] = fpMus[0].readUint32LE();
- musEnd[i] = fpMus[0].readUint32LE();
+ if (!musEnd[i] || !musFilePos[i]) {
+ fpMus.close();
+ return (RDERR_INVALIDID);
+ }
- // Check that music is valid (has length & offset)
- if (!musEnd[i] || !musFilePos[i]) {
- fpMus[0].close();
- return RDERR_INVALIDID;
- }
+ musEnd[i] += musFilePos[i]; // Calculate the file position of the end of the music
- // Calculate the file position of the end of the music
- musEnd[i] += musFilePos[i];
+ // Allocate a compressed data buffer
+ data8 = (uint8*)malloc(bufferSizeMusic);
+ if (data8 == NULL) {
+ fpMus.close();
+ return(RDERR_OUTOFMEMORY);
+ }
- // Reset streaming cursor and store looping flag
- streamCursor[i] = 0;
+ // Seek to start of the compressed music
+ fpMus.seek(musFilePos[i], SEEK_SET);
- // Allocate a temporary buffer for compressed data
- data8 = (uint8 *) malloc(buffer_size / 2);
- if (!data8) {
- fpMus[0].close();
- return RDERR_OUTOFMEMORY;
- }
+ // Read the compressed data in to the buffer
+ if (fpMus.read(data8, bufferSizeMusic / 2) != bufferSizeMusic / 2) {
+ fpMus.close();
+ free(data8);
+ return (RDERR_INVALIDID);
+ }
+
+ // Store the current position in the file for future streaming
+ musFilePos[i] = fpMus.pos();
- // Allocate a buffer for the decoded sound
- data16 = (uint16 *) malloc(buffer_size);
- if (!data16) {
- fpMus[0].close();
- free(data8);
- return RDERR_OUTOFMEMORY;
- }
+ // decompress the music into the music buffer.
+ data16 = (uint16 *)malloc(bufferSizeMusic);
+
+ data16[0] = *((int16 *)data8); // First sample value
+ j = 1;
- lpDsbMus[i] = data16;
+ while (j < (bufferSizeMusic / 2) - 1) {
+ if (GetCompressedSign(data8[j + 1]))
+ data16[j] = data16[j - 1] - (GetCompressedAmplitude(data8[j + 1]) << GetCompressedShift(data8[j + 1]));
+ else
+ data16[j] = data16[j - 1] + (GetCompressedAmplitude(data8[j + 1]) << GetCompressedShift(data8[j + 1]));
+ j++;
+ }
- // Seek to start of the compressed music
- fpMus[0].seek(musFilePos[i]);
+ // Store the value of the last sample ready for next batch of decompression
+ musLastSample[i] = data16[j - 1];
- // Read the compressed data in to the buffer
- if (fpMus[0].read(data8, buffer_size / 2) != buffer_size / 2) {
- fpMus[0].close();
+ // Free the compressiong buffer and unlock the buffer now that we've filled it
free(data8);
- free(data16);
- return RDERR_INVALIDID;
- }
-
- // Store the current position in the file for future streaming
- musFilePos[i] = fpMus[0].pos();
-
- // Decompress the sound into the buffer
- // First sample value
- data16[0] = READ_LE_UINT16(data8);
- j = 1;
+ // Modify the volume according to the master volume and music mute state
+ if (musicMuted)
+ v0 = v1 = 0;
+ else {
+ v0 = volMusic[0];
+ v1 = volMusic[1];
+ }
- while (j < (buffer_size / 2) - 1) {
- if (GetCompressedSign(data8[j + 1]))
- data16[j] = data16[j - 1] - (GetCompressedAmplitude(data8[j + 1]) << GetCompressedShift(data8[j + 1]));
- else
- data16[j] = data16[j - 1] + (GetCompressedAmplitude(data8[j + 1]) << GetCompressedShift(data8[j + 1]));
- j++;
- }
+ if (v0 > v1) {
+// IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v0]);
+// IDirectSoundBuffer_SetPan(lpDsbMus[i], musicVolTable[v1*16/v0]);
+ } else {
+ if (v1 > v0) {
+// IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v1]);
+// IDirectSoundBuffer_SetPan(lpDsbMus[i], -musicVolTable[v0*16/v1]);
+ } else {
+// IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v1]);
+// IDirectSoundBuffer_SetPan(lpDsbMus[i], 0);
+ }
+ }
- // Store the value of the last sample ready for next batch of
- // decompression
- musLastSample[i] = data16[j - 1];
+ //Until the mixer supports LE samples natively, we need to convert our LE ones to BE
+ for (int32 j = 0; j < (bufferSizeMusic / 2); j++)
+ data16[j] = TO_BE_16(data16[j]);
- // Free the decompression buffer
- free(data8);
+ if (soundHandleMusic[i] == -1) {
+ soundHandleMusic[i] = g_engine->_mixer->newStream(data16, bufferSizeMusic, 22050, SoundMixer::FLAG_16BITS, 100000);
+ } else {
+ g_engine->_mixer->appendStream(soundHandleMusic[i], data16, bufferSizeMusic);
+ }
- // Modify the volume according to the master volume and music
- // mute state
- if (musicMuted)
- v0 = v1 = 0;
- else {
- v0 = volMusic[0];
- v1 = volMusic[1];
- }
+ free(data16);
-#if 0
- if (v0 > v1) {
- IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v0]);
- IDirectSoundBuffer_SetPan(lpDsbMus[i], musicVolTable[v1*16/v0]);
- } else if (v1 > v0) {
- IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v1]);
- IDirectSoundBuffer_SetPan(lpDsbMus[i], -musicVolTable[v0*16/v1]);
- } else {
- IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v1]);
- IDirectSoundBuffer_SetPan(lpDsbMus[i], 0);
+ // Record the last variables for streaming and looping
+ musStreaming[i] = 1;
+ musCounter[i] = 250;
}
-#else
- warning("FIXME: Implement volume and panning");
-#endif
-
- // Start the sound effect playing
-#if 0
- // FIXME: This does not work. It sounds like white noise to me.
- musicChannels[i] = _mixer->playRaw(&musicHandle[i], lpDsbMus[i], buffer_size, 22050, SoundMixer::FLAG_16BITS | SoundMixer::FLAG_AUTOFREE);
-#else
- warning("FIXME: Play the sound");
- free(lpDsbMus[i]);
-#endif
-
- // Record the last variables for streaming and looping
- musStreaming[i] = 1;
- musCounter[i] = 250;
+ return (RD_OK);
/*
HRESULT hr;
@@ -2435,6 +1528,7 @@ int32 Sword2Sound::StreamCompMusic(const char *filename, const char *directory,
hr = IDirectSoundBuffer_Lock(lpDsbMus[i], 0, dsbdMus[i].dwBufferBytes, &lpv1, &dwBytes1, &lpv2, &dwBytes2, 0);
if (hr == DSERR_BUFFERLOST)
+
{
IDirectSoundBuffer_Restore(lpDsbMus[i]);
hr = IDirectSoundBuffer_Lock(lpDsbMus[i], 0, dsbdMus[i].dwBufferBytes, &lpv1, &dwBytes1, &lpv2, &dwBytes2, 0);
@@ -2725,13 +1819,137 @@ int32 Sword2Sound::StreamCompMusic(const char *filename, const char *directory,
}
}
*/
- return(RD_OK);
}
+void Sword2Sound::UpdateCompSampleStreaming(void) {
+ uint32 i,j;
+ int32 v0, v1;
+ int32 len;
+ uint16 *data16;
+ uint8 *data8;
+ int fade;
+
+ for (i = 0; i < MAXMUS; i++) {
+ if (musStreaming[i]) {
+ if (musFading[i]) {
+ if (musFading[i] < 0) {
+ if (++musFading[i] == 0) {
+ g_engine->_mixer->endStream(soundHandleMusic[i]);
+ musStreaming[i] = 0;
+ musLooping[i] = 0;
+ } else {
+ // Modify the volume according to the master volume and music mute state
+ if (musicMuted)
+ v0 = v1 = 0;
+ else {
+ v0 = (volMusic[0] * (0 - musFading[i]) / 16);
+ v1 = (volMusic[1] * (0 - musFading[i]) / 16);
+ }
+
+ if (v0 > v1) {
+// IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v0]);
+// IDirectSoundBuffer_SetPan(lpDsbMus[i], musicVolTable[v1*16/v0]);
+ } else {
+ if (v1 > v0) {
+// IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v1]);
+// IDirectSoundBuffer_SetPan(lpDsbMus[i], -musicVolTable[v0*16/v1]);
+ } else {
+// IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[v1]);
+// IDirectSoundBuffer_SetPan(lpDsbMus[i], 0);
+ }
+ }
+ }
+ }
+ } else {
+ len = bufferSizeMusic;
+
+ // Reduce length if it requires reading past the end of the music
+ if (musFilePos[i] + len >= musEnd[i]) {
+ len = musEnd[i] - musFilePos[i];
+ fade = 1; // End of music reaced so we'll need to fade and repeat
+ } else
+ fade = 0;
+
+ if (len > 0) {
+ data8 = (uint8*)malloc(len / 2);
+ // Allocate a compressed data buffer
+ if (data8 == NULL) {
+ fpMus.close();
+ musFading[i] = -16;
+ }
+
+ // Seek to update position of compressed music when neccassary (probably never occurs)
+ if (fpMus.pos() != musFilePos[i]) {
+ fpMus.seek(musFilePos[i], SEEK_SET);
+ }
+ // Read the compressed data in to the buffer
+ if (fpMus.read(data8, len / 2) != (len / 2)) {
+ fpMus.close();
+ free(data8);
+ musFading[i] = -16;
+ return;
+ }
+
+ // Update the current position in the file for future streaming
+ musFilePos[i] = fpMus.pos();
+
+ // decompress the music into the music buffer.
+ data16 = (uint16*)malloc(len);
+
+ // Decompress the first byte using the last decompressed sample
+ if (GetCompressedSign(data8[0]))
+ data16[0] = musLastSample[i] - (GetCompressedAmplitude(data8[0]) << GetCompressedShift(data8[0]));
+ else
+ data16[0] = musLastSample[i] + (GetCompressedAmplitude(data8[0]) << GetCompressedShift(data8[0]));
+
+ j = 1;
+
+ while (j < (uint32)len / 2) {
+ if (GetCompressedSign(data8[j]))
+ data16[j] = data16[j - 1] - (GetCompressedAmplitude(data8[j]) << GetCompressedShift(data8[j]));
+ else
+ data16[j] = data16[j - 1] + (GetCompressedAmplitude(data8[j]) << GetCompressedShift(data8[j]));
+ j++;
+ }
+
+ musLastSample[i] = data16[j - 1];
+
+ //Until the mixer supports LE samples natively, we need to convert our LE ones to BE
+ for (int32 j = 0; j < (len / 2); j++) {
+ data16[j] = TO_BE_16(data16[j]);
+ }
+
+ if (soundHandleMusic[i] == -1) {
+ soundHandleMusic[i] = g_engine->_mixer->newStream(data16, bufferSizeMusic, 22050, SoundMixer::FLAG_16BITS, 100000);
+ } else {
+ g_engine->_mixer->appendStream(soundHandleMusic[i], data16, len);
+ }
+
+ free(data16);
+
+ // Free the compressed data buffer and unlock the sound buffer.
+ free(data8);
+
+ // End of the music so we need to start fading and start the music again
+ if (fade) {
+ musFading[i] = -16; // Fade the old music
+
+ // Close the music cluster if it's open
+ if (fpMus.isOpen()) {
+ fpMus.close();
+ }
+
+ // Loop if neccassary
+ if (musLooping[i]) {
+ StreamCompMusic(musFilename[i], musId[i], musLooping[i]);
+ }
+ }
+ }
+ }
+ }
+ }
+ DipMusic();
-void Sword2Sound::UpdateCompSampleStreaming(void)
-{
- warning("stub UpdateCompSampleStreaming");
/*
uint32 i,j,k;
@@ -2939,9 +2157,11 @@ void Sword2Sound::UpdateCompSampleStreaming(void)
*/
}
-int32 Sword2Sound::DipMusic()
-{
- warning("stub DipMusic");
+int32 Sword2Sound::DipMusic() {
+ // TODO: implement this func
+ // disable this func for now
+ return RD_OK;
+
/*
int32 len;
int32 readCursor, writeCursor;
@@ -3011,262 +2231,104 @@ int32 Sword2Sound::DipMusic()
return (hr);
*/
- return RD_OK;
}
-int32 Sword2Sound::MusicTimeRemaining()
-{
- warning("stub MusicTimeRemaaining");
-/*
- int32 writeCursor;
- int32 i;
- int32 readCursor;
+int32 Sword2Sound::MusicTimeRemaining() {
+ int i;
+// int32 readCursor;
- for (i=0; i<MAXMUS && !musStreaming[i]; i++)
- {
+ for (i = 0; i < MAXMUS && !musStreaming[i]; i++) {
// this is meant to be empty! (James19aug97)
}
if (i == MAXMUS)
return 0;
-
- if ((IDirectSoundBuffer_GetCurrentPosition(lpDsbMus[i], &readCursor, &writeCursor)) != DS_OK)
- return 0;
-
- return (((132300-readCursor)/2 + (musEnd[i] - musFilePos[i])) / 22050);
-*/
- return 0;
+ return (musEnd[i] - musFilePos[i]) / 22050;
+ // TODO: plus channel offset
+ // return (((132300 - readCursor) / 2 + (musEnd[i] - musFilePos[i])) / 22050);
}
+void Sword2Sound::StopMusic(void) {
+ int i;
+ for (i = 0; i < MAXMUS; i++) {
+ if (musStreaming[i])
+ musFading[i] = -16;
+ else
+ musLooping[i] = 0;
+ }
-void Sword2Sound::StopMusic(void)
-{
- int32 i;
-
- switch (compressedMusic)
- {
- case 1: // compressed music streaming
- for (i = 0; i<MAXMUS; i++)
- {
- if (musStreaming[i])
- musFading[i] = -16;
- else
- // If the music is muted, make sure the tune doesn't restart.
- musLooping[i] = 0;
- }
-
- if (fpMus[0].isOpen())
- fpMus[0].close();
- break;
- case 2:
- for (i = 0; i<MAXMUS; i++)
- {
- if (musStreaming[i])
- StartMusicFadeDown(i);
- }
- break;
- default:
- break;
+ if (fpMus.isOpen()) {
+ fpMus.close();
}
}
+int32 Sword2Sound::PauseMusic(void) {
+ int i;
-int32 Sword2Sound::PauseMusic(void)
-{
- warning("stub PauseMusic");
-/*
- int32 i;
-
- if (soundOn)
- {
- for (i=0; i<2; i++)
- {
- if (musStreaming[i])
- {
+ if (soundOn) {
+ for (i = 0; i < 2; i++) {
+ if (musStreaming[i]) {
musicPaused[i] = TRUE;
-
- if (IDirectSoundBuffer_Stop(lpDsbMus[i]) != RD_OK)
- return(RDERR_FXFUCKED);
- }
- else
- {
+ g_engine->_mixer->pauseChannels(true);
+ } else {
musicPaused[i] = FALSE;
}
}
}
-*/
return(RD_OK);
}
-int32 Sword2Sound::UnpauseMusic(void)
-{
- warning("stub UnpauseMusic");
-/*
-
- int32 i;
-
- if (soundOn)
- {
- for (i=0; i<2; i++)
- {
- if (musicPaused[i])
- {
- if (IDirectSoundBuffer_Play(lpDsbMus[i], 0, 0, DSBPLAY_LOOPING) != RD_OK)
- return(RDERR_FXFUCKED);
+int32 Sword2Sound::UnpauseMusic(void) {
+ int i;
+ if (soundOn) {
+ for (i = 0; i < 2; i++) {
+ if (musicPaused[i]) {
+ g_engine->_mixer->pauseChannels(false);
musicPaused[i] = FALSE;
}
}
}
-*/
return(RD_OK);
}
-
-void Sword2Sound::SetMusicVolume(uint8 volume)
-{
- warning("stub SetMusicVolume( %d )", volume);
-/*
- int32 i;
- for (i = 0; i<MAXMUS; i++)
- {
+void Sword2Sound::SetMusicVolume(uint8 volume) {
+ int i;
+ for (i = 0; i < MAXMUS; i++) {
volMusic[i] = volume;
- if (musStreaming[i] && !musFading[i] && !musicMuted)
- IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[volume]);
+ if (musStreaming[i] && !musFading[i] && !musicMuted) {
+// IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[volume]);
+ }
}
-*/
}
-
-uint8 Sword2Sound::GetMusicVolume()
-{
- return (uint8) volMusic[0];
+uint8 Sword2Sound::GetMusicVolume() {
+ return (uint8) volMusic[0];
}
-
-void Sword2Sound::MuteMusic(uint8 mute)
-{
- warning("stub MuteMusic( %d )", mute);
-/*
- int32 i;
+void Sword2Sound::MuteMusic(uint8 mute) {
+ int i;
musicMuted = mute;
- for (i = 0; i<MAXMUS; i++)
- {
- if (!mute)
- {
+ for (i = 0; i < MAXMUS; i++) {
+ if (!mute) {
if (!musStreaming[i] && musLooping[i])
StreamCompMusic(musFilename[i], musId[i], musLooping[i]);
}
- if (musStreaming[i] && !musFading[i])
- {
- if (mute)
- IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[0]);
- else
- IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[volMusic[i]]);
+ if (musStreaming[i] && !musFading[i]) {
+ if (mute) {
+// IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[0]);
+ } else {
+// IDirectSoundBuffer_SetVolume(lpDsbMus[i], musicVolTable[volMusic[i]]);
+ }
}
}
-*/
}
-
-uint8 Sword2Sound::IsMusicMute(void)
-{
+uint8 Sword2Sound::IsMusicMute(void) {
return (musicMuted);
}
-
-
-
-void Sword2Sound::GetSoundStatus(_drvSoundStatus *s)
-{
- int i;
-
-// s->hwnd = hwnd;
-// s->lpDS = lpDS;
-// s->dsbPrimary = dsbPrimary;
-// s->dsbSpeech = dsbSpeech;
- s->soundOn = soundOn;
- s->speechStatus = speechStatus;
- s->fxPaused = fxPaused;
- s->speechPaused = speechPaused;
- s->speechVol = speechVol;
- s->fxVol = fxVol;
- s->speechMuted = speechMuted;
- s->fxMuted = fxMuted;
- s->compressedMusic = compressedMusic;
- s->musicMuted = musicMuted;
-
- memcpy(s->fxId, fxId, sizeof(int32) * MAXFX);
- memcpy(s->fxCached, fxCached, sizeof(uint8) * MAXFX);
-// memcpy(s->dsbFx, dsbFx, sizeof(LPDIRECTSOUNDBUFFER) * MAXFX);
- memcpy(s->fxiPaused, fxiPaused, sizeof(uint8) * MAXFX);
- memcpy(s->fxLooped, fxLooped, sizeof(uint8) * MAXFX);
- memcpy(s->musStreaming, musStreaming, sizeof(int16) * MAXMUS);
- memcpy(s->musicPaused, musicPaused, sizeof(int16) * MAXMUS);
- memcpy(s->musCounter, musCounter, sizeof(int16) * MAXMUS);
- memcpy(s->musFading, musFading, sizeof(int16) * MAXMUS);
- memcpy(s->musLooping, musLooping, sizeof(int16) * MAXMUS);
- memcpy(s->musLastSample,musLastSample, sizeof(int16) * MAXMUS);
- memcpy(s->streamCursor, streamCursor, sizeof(int32) * MAXMUS);
- memcpy(s->musFilePos, musFilePos, sizeof(int32) * MAXMUS);
- memcpy(s->musEnd, musEnd, sizeof(int32) * MAXMUS);
- memcpy(s->musId, musId, sizeof(uint32) * MAXMUS);
- memcpy(s->volMusic, volMusic, sizeof(uint32) * 2);
-// memcpy(s->dsbdMus, dsbdMus, sizeof(DSBUFFERDESC) * MAXMUS);
-// memcpy(s->lpDsbMus, lpDsbMus, sizeof(LPDIRECTSOUNDBUFFER) * MAXMUS);
- memcpy(s->fpMus, fpMus, sizeof(FILE*) * MAXMUS);
-// memcpy(s->wfMus, wfMus, sizeof(PCMWAVEFORMAT) * MAXMUS);
-
- for (i = 0; i<MAXMUS; i++)
- memcpy(s->musFilename[i], musFilename[i], sizeof(char) * 256);
-}
-
-
-void Sword2Sound::SetSoundStatus(_drvSoundStatus *s)
-{
- int i;
-
-// hwnd = s->hwnd;
-// lpDS = s->lpDS;
-// dsbPrimary = s->dsbPrimary;
-// dsbSpeech = s->dsbSpeech;
- soundOn = s->soundOn;
- speechStatus = s->speechStatus;
- fxPaused = s->fxPaused;
- speechPaused = s->speechPaused;
- speechVol = s->speechVol;
- fxVol = s->fxVol;
- speechMuted = s->speechMuted;
- fxMuted = s->fxMuted;
- compressedMusic = s->compressedMusic;
- musicMuted = s->musicMuted;
-
- memcpy(fxId, s->fxId, sizeof(int32) * MAXFX);
- memcpy(fxCached, s->fxCached, sizeof(uint8) * MAXFX);
-// memcpy(dsbFx, s->dsbFx, sizeof(LPDIRECTSOUNDBUFFER) * MAXFX);
- memcpy(fxiPaused, s->fxiPaused, sizeof(uint8) * MAXFX);
- memcpy(fxLooped, s->fxLooped, sizeof(uint8) * MAXFX);
- memcpy(musStreaming, s->musStreaming, sizeof(int16) * MAXMUS);
- memcpy(musicPaused, s->musicPaused, sizeof(int16) * MAXMUS);
- memcpy(musCounter, s->musCounter, sizeof(int16) * MAXMUS);
- memcpy(musFading, s->musFading, sizeof(int16) * MAXMUS);
- memcpy(musLooping, s->musLooping, sizeof(int16) * MAXMUS);
- memcpy(musLastSample,s->musLastSample, sizeof(int16) * MAXMUS);
- memcpy(streamCursor, s->streamCursor, sizeof(int32) * MAXMUS);
- memcpy(musFilePos, s->musFilePos, sizeof(int32) * MAXMUS);
- memcpy(musEnd, s->musEnd, sizeof(int32) * MAXMUS);
- memcpy(musId, s->musId, sizeof(uint32) * MAXMUS);
- memcpy(volMusic, s->volMusic, sizeof(uint32) * 2);
-// memcpy(dsbdMus, s->dsbdMus, sizeof(DSBUFFERDESC) * MAXMUS);
-// memcpy(lpDsbMus, s->lpDsbMus, sizeof(LPDIRECTSOUNDBUFFER) * MAXMUS);
-// memcpy(fpMus, s->fpMus, sizeof(FILE*) * MAXMUS);
-// memcpy(wfMus, s->wfMus, sizeof(PCMWAVEFORMAT) * MAXMUS);
-
- for (i = 0; i<MAXMUS; i++)
- memcpy(musFilename[i], s->musFilename[i], sizeof(char) * 256);
-}
-
diff --git a/sword2/driver/d_sound.h b/sword2/driver/d_sound.h
index def3eaf268..7fb4af60fa 100644
--- a/sword2/driver/d_sound.h
+++ b/sword2/driver/d_sound.h
@@ -41,6 +41,8 @@
#include "sound/mixer.h"
#include "common/file.h"
+void sword2_sound_handler (void *engine);
+
class Sword2Sound {
public:
Sword2Sound(SoundMixer *mixer);
@@ -65,7 +67,7 @@ class Sword2Sound {
int32 PauseMusic(void);
int32 UnpauseMusic(void);
int32 StreamMusic(uint8 *filename, int32 looping);
- int32 StreamCompMusic(const char *filename, const char *directory, uint32 musicId, int32 looping);
+ int32 StreamCompMusic(const char *filename, uint32 musicId, int32 looping);
int32 MusicTimeRemaining();
int32 ReverseStereo(void);
uint8 GetFxVolume(void);
@@ -75,8 +77,6 @@ class Sword2Sound {
uint8 IsFxMute(void);
uint8 IsSpeechMute(void);
void StopMusic(void);
- void GetSoundStatus(_drvSoundStatus *s);
- void SetSoundStatus(_drvSoundStatus *s);
void SetFxVolume(uint8 vol);
void SetSpeechVolume(uint8 vol);
void SetMusicVolume(uint8 vol);
@@ -92,14 +92,16 @@ class Sword2Sound {
int32 GetFxIndex(int32 id);
void StartMusicFadeDown(int i);
int32 DipMusic();
- void UpdateSampleStreaming(void);
int32 fxId[MAXFX];
uint8 fxCached[MAXFX];
uint8 fxiPaused[MAXFX];
uint8 fxLooped[MAXFX];
uint8 fxVolume[MAXFX];
-
+ uint32 flagsFx[MAXFX];
+ uint16 *bufferFx[MAXFX];
+ int32 bufferSizeFx[MAXFX];
+
uint8 soundOn;
uint8 speechStatus;
uint8 fxPaused;
@@ -116,14 +118,13 @@ class Sword2Sound {
int16 musFading[MAXMUS];
int16 musLooping[MAXMUS];
- //DSBUFFERDESC dsbdMus[MAXMUS];
- //LPDIRECTSOUNDBUFFER lpDsbMus[MAXMUS];
- PlayingSoundHandle musicHandle[MAXMUS];
+ PlayingSoundHandle soundHandleFx[MAXFX];
+ PlayingSoundHandle soundHandleMusic[MAXMUS];
+ PlayingSoundHandle soundHandleSpeech;
+ File fpMus;
+ int bufferSizeMusic;
+ int musicIndexChannel[MAXMUS];
int musicChannels[MAXMUS];
- uint16 *lpDsbMus[MAXMUS];
- File fpMus[MAXMUS];
- //FILE *fpMus[MAXMUS];
- //PCMWAVEFORMAT wfMus[MAXMUS];
int32 streamCursor[MAXMUS];
char musFilename[MAXMUS][256];
int32 musFilePos[MAXMUS];
@@ -132,7 +133,6 @@ class Sword2Sound {
uint32 musId[MAXMUS];
uint32 volMusic[2];
uint8 musicMuted;
-
};
diff --git a/sword2/driver/driver96.h b/sword2/driver/driver96.h
index 5c30de2f29..78588aed85 100644
--- a/sword2/driver/driver96.h
+++ b/sword2/driver/driver96.h
@@ -1365,50 +1365,6 @@ typedef struct
// DDCOLORKEY blackColorKey;
} _drvDrawStatus;
-
-
-// This is the structure which is used to set and
-// retrieve the direct sound drivers global variables.
-
-typedef struct
-{
-// HWND hwnd;
-// LPDIRECTSOUND lpDS;
-// LPDIRECTSOUNDBUFFER dsbPrimary;
-// LPDIRECTSOUNDBUFFER dsbSpeech;
-// LPDIRECTSOUNDBUFFER dsbFx[MAXFX];
- int32 fxId[MAXFX];
- uint8 fxCached[MAXFX];
- uint8 soundOn;
- uint8 speechStatus;
- uint8 fxPaused;
- char musFilename[MAXMUS][256];
- uint8 speechPaused;
- uint8 speechVol;
- uint8 fxVol;
- uint8 speechMuted;
- uint8 fxMuted;
- uint8 musicMuted;
- uint8 compressedMusic;
- uint8 fxiPaused[MAXFX];
- uint8 fxLooped[MAXFX];
- int16 musStreaming[MAXMUS];
- int16 musicPaused[MAXMUS];
- int16 musCounter[MAXMUS];
- int16 musFading[MAXMUS];
- int16 musLooping[MAXMUS];
- int16 musLastSample[MAXMUS];
- int32 streamCursor[MAXMUS];
- int32 musFilePos[MAXMUS];
- int32 musEnd[MAXMUS];
- uint32 musId[MAXMUS];
-// DSBUFFERDESC dsbdMus[MAXMUS];
-// LPDIRECTSOUNDBUFFER lpDsbMus[MAXMUS];
- FILE *fpMus[MAXMUS];
-// PCMWAVEFORMAT wfMus[MAXMUS];
- uint32 volMusic[2];
-} _drvSoundStatus;
-
// This is the structure which is used to retrieve
// the keyboard driver bits.
diff --git a/sword2/driver/rdwin.cpp b/sword2/driver/rdwin.cpp
index 299721c9ce..4a4a1ac812 100644
--- a/sword2/driver/rdwin.cpp
+++ b/sword2/driver/rdwin.cpp
@@ -19,12 +19,9 @@
#define WIN32_LEAN_AND_MEAN
-//#include <windows.h>
-//#include <windowsx.h>
-#include <stdio.h>
-
#include "common/stdafx.h"
#include "common/engine.h"
+#include "common/timer.h"
#include "driver96.h"
@@ -532,6 +529,7 @@ int32 CloseAppWindow(void)
DestroyWindow(hwnd);
*/
// just quit for now
+ g_engine->_timer->releaseProcedure(sword2_sound_handler);
g_system->quit();
return(RD_OK);
diff --git a/sword2/sound.cpp b/sword2/sound.cpp
index e16c51b8ce..fae889a483 100644
--- a/sword2/sound.cpp
+++ b/sword2/sound.cpp
@@ -412,7 +412,7 @@ int32 FN_play_music(int32 *params) // updated by James on 10apr97
sprintf(filename,"Music.clu");
- rv = g_sword2->_sound->StreamCompMusic(filename, g_sword2->getGameDataPath(), params[0], loopFlag);
+ rv = g_sword2->_sound->StreamCompMusic(filename, params[0], loopFlag);
#ifdef _SWORD2_DEBUG
if (rv)
diff --git a/sword2/sword2.cpp b/sword2/sword2.cpp
index 6a7d05b951..c7828840d4 100644
--- a/sword2/sword2.cpp
+++ b/sword2/sword2.cpp
@@ -18,15 +18,12 @@
*/
//------------------------------------------------------------------------------------
-#include <ctype.h>
-#include <stdio.h>
-//#include <windows.h>
-
#include "stdafx.h"
#include "driver/driver96.h"
#include "driver/palette.h"
#include "common/gameDetector.h"
#include "common/config-file.h"
+#include "common/timer.h"
#include "build_display.h"
#include "console.h"
#include "controls.h"
@@ -318,6 +315,7 @@ void Sword2State::go()
}
*/
+ g_engine->_timer->installProcedure(sword2_sound_handler, 1000000);
Zdebug("CALLING: InitialiseGame");
if (InitialiseGame())
{