Browse Source

Implement most of sound.cpp (#34)

* Implement most of sound.cpp

This fixes
- Menu sounds being cut short
- Spartial sound in game
- Memory leaks
- Sound volume

* Some minor bugfixes
pull/36/head
Anders Jenbo 7 years ago committed by GitHub
parent
commit
4223512c72
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 1
      Source/sound.cpp
  2. 48
      SourceS/miniwin_dsound.h
  3. 2
      SourceX/dx.cpp
  4. 39
      SourceX/miniwin.cpp
  5. 6
      SourceX/miniwin_io.cpp
  6. 265
      SourceX/sound.cpp
  7. 18
      SourceX/storm.cpp

1
Source/sound.cpp

@ -83,7 +83,6 @@ BOOL __fastcall snd_playing(TSnd *pSnd)
#else
if (pSnd->DSB->lpVtbl->GetStatus(pSnd->DSB, &error_code))
#endif
return FALSE;
return error_code == DSBSTATUS_PLAYING;
}

48
SourceS/miniwin_dsound.h

@ -5,6 +5,14 @@ typedef void *LPDSBCAPS, *LPCDSBUFFERDESC;
struct IDirectSound;
typedef IDirectSound *LPDIRECTSOUND;
typedef struct _DSBUFFERDESC {
DWORD dwSize;
DWORD dwFlags;
DWORD dwBufferBytes;
DWORD dwReserved;
LPWAVEFORMATEX lpwfxFormat;
} DSBUFFERDESC, *LPDSBUFFERDESC;
DECLARE_INTERFACE_(IDirectSoundBuffer, IUnknown)
{
// clang-format off
@ -30,8 +38,44 @@ DECLARE_INTERFACE_(IDirectSoundBuffer, IUnknown)
// clang-format on
};
#define DSBCAPS_PRIMARYBUFFER 0x00000001
#define DSBCAPS_STATIC 0x00000002
#define DSBCAPS_CTRLPAN 0x00000040
#define DSBCAPS_CTRLVOLUME 0x00000080
#define WAVE_FORMAT_PCM 1
#define ERROR_SUCCESS 0L
typedef IDirectSoundBuffer *LPDIRECTSOUNDBUFFER;
typedef void *LPDSCAPS, *LPUNKNOWN, *LPCGUID;
typedef void *LPUNKNOWN, *LPCGUID;
typedef struct _DSCAPS {
DWORD dwSize;
DWORD dwFlags;
DWORD dwMinSecondarySampleRate;
DWORD dwMaxSecondarySampleRate;
DWORD dwPrimaryBuffers;
DWORD dwMaxHwMixingAllBuffers;
DWORD dwMaxHwMixingStaticBuffers;
DWORD dwMaxHwMixingStreamingBuffers;
DWORD dwFreeHwMixingAllBuffers;
DWORD dwFreeHwMixingStaticBuffers;
DWORD dwFreeHwMixingStreamingBuffers;
DWORD dwMaxHw3DAllBuffers;
DWORD dwMaxHw3DStaticBuffers;
DWORD dwMaxHw3DStreamingBuffers;
DWORD dwFreeHw3DAllBuffers;
DWORD dwFreeHw3DStaticBuffers;
DWORD dwFreeHw3DStreamingBuffers;
DWORD dwTotalHwMemBytes;
DWORD dwFreeHwMemBytes;
DWORD dwMaxContigFreeHwMemBytes;
DWORD dwUnlockTransferRateHwBuffers;
DWORD dwPlayCpuOverheadSwBuffers;
DWORD dwReserved1;
DWORD dwReserved2;
} DSCAPS, *LPDSCAPS;
DECLARE_INTERFACE_(IDirectSound, IUnknown)
{
@ -47,7 +91,7 @@ DECLARE_INTERFACE_(IDirectSound, IUnknown)
// clang-format on
};
#define _FACDS 0x878
#define _FACDS 0x878
#define MAKE_DSHRESULT(code) MAKE_HRESULT(1, _FACDS, code)
#define E_NOINTERFACE 0x80004002

2
SourceX/dx.cpp

@ -478,7 +478,7 @@ BOOL STORMAPI SDrawUpdatePalette(unsigned int firstentry, unsigned int numentrie
assert(numentries == 256);
SDL_Color colors[256];
for (int i = firstentry; i < numentries; i++) {
for (unsigned int i = firstentry; i < numentries; i++) {
SDL_Color *c = &colors[i];
PALETTEENTRY *p = &pPalEntries[i];
c->r = p->peRed;

39
SourceX/miniwin.cpp

@ -56,6 +56,8 @@ char *__cdecl _itoa(int _Value, char *_Dest, int _Radix)
UNIMPLEMENTED();
break;
}
return _Dest;
}
DWORD WINAPI GetTickCount(VOID)
@ -98,25 +100,25 @@ UINT WINAPI GetWindowsDirectoryA(LPSTR lpBuffer, UINT uSize)
WINBOOL WINAPI GetDiskFreeSpaceA(LPCSTR lpRootPathName, LPDWORD lpSectorsPerCluster, LPDWORD lpBytesPerSector,
LPDWORD lpNumberOfFreeClusters, LPDWORD lpTotalNumberOfClusters)
{
#ifndef _WIN32
#ifndef _WIN32
struct statvfs fiData;
int success = statvfs("/", &fiData);
*lpBytesPerSector = fiData.f_frsize;
*lpSectorsPerCluster = 1;
*lpNumberOfFreeClusters = fiData.f_bavail;
*lpTotalNumberOfClusters = fiData.f_blocks;
return success >= 0;
#else
// Todo give windows the real GetDiskFreeSpace
DUMMY();
*lpBytesPerSector = 1;
*lpSectorsPerCluster = 1;
*lpNumberOfFreeClusters = 10 << 20;
*lpTotalNumberOfClusters = 10 << 20;
return true;
#endif
*lpTotalNumberOfClusters = fiData.f_blocks;
return success >= 0;
#else
// Todo give windows the real GetDiskFreeSpace
DUMMY();
*lpBytesPerSector = 1;
*lpSectorsPerCluster = 1;
*lpNumberOfFreeClusters = 10 << 20;
*lpTotalNumberOfClusters = 10 << 20;
return true;
#endif
}
/**
@ -466,7 +468,7 @@ int GetClassName(HWND hWnd, LPTSTR lpClassName, int nMaxCount)
*/
HRESULT SHGetSpecialFolderLocation(HWND hwnd, int csidl, PIDLIST_ABSOLUTE *ppidl)
{
return NULL;
return 0;
}
/**
@ -531,8 +533,9 @@ int WINAPI GetDeviceCaps(HDC hdc, int index)
if (index == HORZRES) {
return current.w;
} else if (index == VERTRES) {
current.h;
}
if (index == VERTRES) {
return current.h;
}
return 0;
@ -643,7 +646,7 @@ int MessageBoxA(HWND hWnd, const char *Text, const char *Title, UINT Flags)
SDLFlags |= SDL_MESSAGEBOX_WARNING;
}
SDL_ShowSimpleMessageBox(SDLFlags, Title, Text, window) < 0 ? -1 : 0;
return SDL_ShowSimpleMessageBox(SDLFlags, Title, Text, window) < 0 ? -1 : 0;
}
LSTATUS RegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult)

6
SourceX/miniwin_io.cpp

@ -33,10 +33,10 @@ HANDLE WINAPI CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShar
} else {
UNIMPLEMENTED();
}
int fd = open(name, flags, mode);
HANDLE fd = (HANDLE)open(name, flags, mode);
files.insert((HANDLE)fd);
return (HANDLE)fd;
files.insert(fd);
return fd;
}
WINBOOL WINAPI ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead,

265
SourceX/sound.cpp

@ -35,76 +35,201 @@ char unk_volume[4][2] = {
void __fastcall snd_update(BOOL bStopAll)
{
DUMMY_ONCE();
DWORD error_code, i;
if (!bStopAll)
return;
Mix_HaltChannel(-1);
}
void __fastcall snd_stop_snd(TSnd *pSnd)
{
DUMMY_ONCE();
Mix_HaltChannel(-1);
if (pSnd && pSnd->DSB)
Mix_HaltChannel(-1);
}
BOOL __fastcall snd_playing(TSnd *pSnd)
{
DUMMY();
return false;
DWORD error_code; // TODO should probably be HRESULT
if (!pSnd)
return FALSE;
if (pSnd->DSB == NULL)
return FALSE;
DUMMY_ONCE();
return FALSE;
}
void __fastcall snd_play_snd(TSnd *pSnd, int lVolume, int lPan)
{
Mix_PlayChannel(-1, (Mix_Chunk *)(pSnd->DSB), 0);
LPDIRECTSOUNDBUFFER DSB;
DWORD tc;
HRESULT error_code;
if (!pSnd || !gbSoundOn) {
return;
}
DSB = pSnd->DSB;
if (!DSB) {
return;
}
tc = GetTickCount();
if (tc - pSnd->start_tc < 80) {
pSnd->start_tc = GetTickCount();
return;
}
lVolume += sglSoundVolume;
if (lVolume < VOLUME_MIN) {
lVolume = VOLUME_MIN;
} else if (lVolume > VOLUME_MAX) {
lVolume = VOLUME_MAX;
}
Mix_VolumeChunk((Mix_Chunk *)(pSnd->DSB), MIX_MAX_VOLUME - MIX_MAX_VOLUME * lVolume / VOLUME_MIN);
int channel = Mix_PlayChannel(-1, (Mix_Chunk *)(pSnd->DSB), 0);
if (channel != -1) {
int panned = 255 * abs(lPan) / 10000;
Mix_SetPanning(channel, lPan <= 0 ? 255 : panned, lPan >= 0 ? 255 : panned);
}
if (channel == -1) {
SDL_Log("Mix_PlayChannel: %s\n", SDL_GetError());
} else if (sound_file_reload(pSnd, DSB)) {
UNIMPLEMENTED();
}
pSnd->start_tc = tc;
}
LPDIRECTSOUNDBUFFER __fastcall sound_dup_channel(LPDIRECTSOUNDBUFFER DSB)
{
DWORD i;
if (!gbDupSounds) {
return NULL;
}
for (i = 0; i < 8; i++) {
UNIMPLEMENTED();
}
return NULL;
}
BOOL __fastcall sound_file_reload(TSnd *sound_file, LPDIRECTSOUNDBUFFER DSB)
{
HANDLE file;
LPVOID buf1, buf2;
DWORD size1, size2;
BOOL rv;
DUMMY_ONCE();
rv = FALSE;
WOpenFile(sound_file->sound_path, &file, FALSE);
WSetFilePointer(file, sound_file->chunk.dwOffset, NULL, 0);
WCloseFile(file);
return rv;
}
TSnd *__fastcall sound_file_load(char *path)
{
int bytestoread;
int nrread;
HANDLE file;
BYTE *wave_file;
TSnd *pSnd;
LPVOID buf1, buf2;
DWORD size1, size2;
HRESULT error_code;
if (!gbSndInited)
return NULL;
WOpenFile(path, &file, FALSE);
pSnd = (TSnd *)DiabloAllocPtr(sizeof(TSnd));
memset(pSnd, 0, sizeof(TSnd));
pSnd->sound_path = path;
pSnd->start_tc = GetTickCount() - 81;
//This opens the file and reads it, makes Mix_chunk pointer to it.
//Once this is done the pointer is stored TSnd Struct
SFileOpenFile(path, &file);
bytestoread = (int)SFileGetFileSize((HANDLE)file, 0);
unsigned char *MSFXBuffer = DiabloAllocPtr(bytestoread);
SFileReadFile(file, MSFXBuffer, bytestoread, (LPDWORD)&nrread, 0);
SDL_RWops *rw = SDL_RWFromMem(MSFXBuffer, bytestoread);
size1 = (int)SFileGetFileSize((HANDLE)file, 0);
wave_file = DiabloAllocPtr(size1);
SFileReadFile(file, (void *)wave_file, size1, (LPDWORD)&size2, 0);
SDL_RWops *rw = SDL_RWFromConstMem((void *)wave_file, size1);
Mix_Chunk *SoundFX = Mix_LoadWAV_RW(rw, 1);
pSnd->DSB = (LPDIRECTSOUNDBUFFER)SoundFX;
if (!pSnd->DSB)
TermMsg("Invalid sound format on file %s", pSnd->sound_path);
TSnd *fx = (TSnd *)malloc(sizeof(TSnd));
memset(fx, 0, sizeof(TSnd));
fx->DSB = (LPDIRECTSOUNDBUFFER)SoundFX;
fx->start_tc = 0;
fx->sound_path = NULL;
sound_CreateSoundBuffer(pSnd);
return fx;
mem_free_dbg((void *)wave_file);
WCloseFile(file);
return pSnd;
}
// 456F07: could not find valid save-restore pair for esi
void __fastcall sound_file_cleanup(TSnd *sound_file)
void __fastcall sound_CreateSoundBuffer(TSnd *sound_file)
{
DUMMY_ONCE();
DSBUFFERDESC DSB;
HRESULT error_code;
memset(&DSB, 0, sizeof(DSBUFFERDESC));
DSB.dwBufferBytes = sound_file->chunk.dwSize;
DSB.lpwfxFormat = &sound_file->fmt;
DSB.dwSize = sizeof(DSBUFFERDESC);
DSB.dwFlags = DSBCAPS_CTRLVOLUME | DSBCAPS_CTRLPAN | DSBCAPS_STATIC;
if (error_code != ERROR_SUCCESS)
DSErrMsg(error_code, 282, "C:\\Src\\Diablo\\Source\\SOUND.CPP");
}
void __fastcall snd_init(HWND hWnd)
void __fastcall sound_file_cleanup(TSnd *sound_file)
{
DUMMY();
printf("\nSND INIT\n");
if (sound_file) {
if (sound_file->DSB) {
DUMMY_ONCE();
Mix_FreeChunk((Mix_Chunk *)sound_file->DSB);
sound_file->DSB = NULL;
}
/* following function Mix_AllocateChannels allocates the number of channels of simultaneously played sounds.*/
printf("Opened %i sound channels\n\n", Mix_AllocateChannels(8));
mem_free_dbg(sound_file);
}
}
void __fastcall snd_init(HWND hWnd)
{
DUMMY();
sound_load_volume("Sound Volume", &sglSoundVolume);
gbSoundOn = sglSoundVolume > VOLUME_MIN;
sound_load_volume("Music Volume", &sglMusicVolume);
gbMusicOn = sglMusicVolume > VOLUME_MIN;
if (Mix_OpenAudio(44100, AUDIO_S16LSB, 2, 1024) < 0) {
printf("SDL_mixer could not initialize! SDL_mixer Error: %s\n", Mix_GetError());
return;
if (Mix_OpenAudio(44100, AUDIO_S16LSB, 2, 1024) != 0) {
sglpDS = NULL;
sound_create_primary_buffer(NULL);
}
gbSndInited = 1;
SVidInitialize(sglpDS);
SFileDdaInitialize(sglpDS);
gbSndInited = true;
}
void __fastcall sound_load_volume(char *value_name, int *value)
@ -126,6 +251,73 @@ void __fastcall sound_load_volume(char *value_name, int *value)
void __fastcall sound_create_primary_buffer(HANDLE music_track)
{
DUMMY();
HRESULT error_code;
DSBUFFERDESC dsbuf;
WAVEFORMATEX format;
if (!music_track) {
memset(&dsbuf, 0, sizeof(DSBUFFERDESC));
dsbuf.dwSize = sizeof(DSBUFFERDESC);
dsbuf.dwFlags = DSBCAPS_PRIMARYBUFFER;
#ifdef __cplusplus
error_code = sglpDS->CreateSoundBuffer(&dsbuf, &sglpDSB, NULL);
#else
error_code = sglpDS->lpVtbl->CreateSoundBuffer(sglpDS, &dsbuf, &sglpDSB, NULL);
#endif
if (error_code != DS_OK)
DSErrMsg(error_code, 375, "C:\\Src\\Diablo\\Source\\SOUND.CPP");
}
if (sglpDSB) {
DSCAPS dsbcaps;
dsbcaps.dwSize = sizeof(DSCAPS);
#ifdef __cplusplus
error_code = sglpDS->GetCaps(&dsbcaps);
#else
error_code = sglpDS->lpVtbl->GetCaps(sglpDS, &dsbcaps);
#endif
if (error_code != DS_OK)
DSErrMsg(error_code, 383, "C:\\Src\\Diablo\\Source\\SOUND.CPP");
if (!music_track || !LoadWaveFormat(music_track, &format)) {
memset(&format, 0, sizeof(WAVEFORMATEX));
format.wFormatTag = WAVE_FORMAT_PCM;
format.nSamplesPerSec = 22050;
format.wBitsPerSample = 16;
format.cbSize = 0;
}
format.nChannels = 2;
format.nBlockAlign = format.nChannels * format.wBitsPerSample / 8;
format.nAvgBytesPerSec = format.nSamplesPerSec * format.nBlockAlign;
#ifdef __cplusplus
sglpDSB->SetFormat(&format);
#else
sglpDSB->lpVtbl->SetFormat(sglpDSB, &format);
#endif
}
}
// 69F100: using guessed type int sglpDSB;
HRESULT __fastcall sound_DirectSoundCreate(LPGUID lpGuid, LPDIRECTSOUND *ppDS, LPUNKNOWN pUnkOuter)
{
UNIMPLEMENTED();
HRESULT(WINAPI * DirectSoundCreate)
(LPGUID lpGuid, LPDIRECTSOUND * ppDS, LPUNKNOWN pUnkOuter);
if (hDsound_dll == NULL) {
if (hDsound_dll == NULL) {
}
}
DirectSoundCreate = NULL;
if (DirectSoundCreate == NULL) {
ErrDlg(IDD_DIALOG5, GetLastError(), "C:\\Src\\Diablo\\Source\\SOUND.CPP", 427);
}
return DirectSoundCreate(lpGuid, ppDS, pUnkOuter);
}
void __cdecl sound_cleanup()
@ -134,12 +326,8 @@ void __cdecl sound_cleanup()
SVidDestroy();
SFileDdaDestroy();
if (sglpDS) {
#ifdef __cplusplus
sglpDS->Release();
#else
sglpDS->lpVtbl->Release(sglpDS);
#endif
if (gbSndInited) {
DUMMY();
sglpDS = NULL;
}
@ -160,12 +348,11 @@ void __cdecl music_stop()
if (sgpMusicTrack) {
Mix_HaltMusic();
SFileCloseFile(sgpMusicTrack);
sgpMusicTrack = 0;
sgpMusicTrack = NULL;
sgnMusicTrack = 6;
}
}
void *buffer;
void __fastcall music_start(int nTrack)
{
BOOL success;
@ -182,15 +369,15 @@ void __fastcall music_start(int nTrack)
#endif
sound_create_primary_buffer(sgpMusicTrack);
if (!success) {
sgpMusicTrack = 0;
sgpMusicTrack = NULL;
} else {
int bytestoread = (int)SFileGetFileSize((HANDLE)sgpMusicTrack, 0);
char *buffer = (char *)DiabloAllocPtr(bytestoread);
SFileReadFile(sgpMusicTrack, buffer, bytestoread, NULL, 0);
SDL_RWops *rw = SDL_RWFromMem(buffer, bytestoread);
SDL_RWops *rw = SDL_RWFromConstMem(buffer, bytestoread);
Mix_Music *Song = Mix_LoadMUS_RW(rw, 1);
Mix_VolumeMusic(128 - 128 * sglMusicVolume / -1600);
Mix_VolumeMusic(MIX_MAX_VOLUME - MIX_MAX_VOLUME * sglMusicVolume / VOLUME_MIN);
Mix_PlayMusic(Song, -1);
sgnMusicTrack = nTrack;

18
SourceX/storm.cpp

@ -38,7 +38,7 @@ BOOL STORMAPI SFileDdaBeginEx(HANDLE directsound, DWORD flags, DWORD mask, unsig
SFXbuffer = DiabloAllocPtr(bytestoread);
SFileReadFile(directsound, (char *)SFXbuffer, bytestoread, (LPDWORD)&nrread, 0);
SDL_RWops *rw = SDL_RWFromMem(SFXbuffer, bytestoread);
SDL_RWops *rw = SDL_RWFromConstMem(SFXbuffer, bytestoread);
Mix_Chunk *SoundFX = Mix_LoadWAV_RW(rw, 1);
Mix_PlayChannel(-1, SoundFX, 0);
@ -72,7 +72,7 @@ BOOL STORMAPI SFileDdaInitialize(HANDLE directsound)
BOOL STORMAPI SFileDdaSetVolume(HANDLE directsound, signed int bigvolume, signed int volume)
{
Mix_VolumeMusic(128 - 128 * bigvolume / -1600);
Mix_VolumeMusic(MIX_MAX_VOLUME - MIX_MAX_VOLUME * bigvolume / VOLUME_MIN);
return TRUE;
}
@ -251,7 +251,7 @@ HWND STORMAPI SDrawGetFrameWindow(HWND *sdraw_framewindow)
void *STORMAPI SMemAlloc(unsigned int amount, char *logfilename, int logline, char defaultValue)
{
// fprintf(stderr, "%s: %d (%s:%d)\n", __FUNCTION__, amount, logfilename, logline);
assert(amount != -1);
assert(amount != -1u);
return malloc(amount);
}
@ -352,15 +352,17 @@ BOOL STORMAPI SRegSaveValue(const char *keyname, const char *valuename, BYTE fla
return TRUE;
}
BOOL STORMAPI SVidDestroy()
BOOL STORMAPI SVidInitialize(HANDLE video)
{
DUMMY();
return TRUE;
}
// BOOL STORMAPI SVidInitialize(HANDLE video)
//{
// UNIMPLEMENTED();
//}
BOOL STORMAPI SVidDestroy()
{
DUMMY();
return TRUE;
}
double SVidFrameEnd;
double SVidFrameLength;

Loading…
Cancel
Save