diff --git a/Source/sound.cpp b/Source/sound.cpp index a37ec3223..d67519e71 100644 --- a/Source/sound.cpp +++ b/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; } diff --git a/SourceS/miniwin_dsound.h b/SourceS/miniwin_dsound.h index f7d5da390..932b66f0c 100644 --- a/SourceS/miniwin_dsound.h +++ b/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 diff --git a/SourceX/dx.cpp b/SourceX/dx.cpp index 2821d22ad..03e86b5ab 100644 --- a/SourceX/dx.cpp +++ b/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; diff --git a/SourceX/miniwin.cpp b/SourceX/miniwin.cpp index f3118f929..92084d1c3 100644 --- a/SourceX/miniwin.cpp +++ b/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) diff --git a/SourceX/miniwin_io.cpp b/SourceX/miniwin_io.cpp index 566219785..2e8a17d2d 100644 --- a/SourceX/miniwin_io.cpp +++ b/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, diff --git a/SourceX/sound.cpp b/SourceX/sound.cpp index 23da34eec..f9eccacbe 100644 --- a/SourceX/sound.cpp +++ b/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; diff --git a/SourceX/storm.cpp b/SourceX/storm.cpp index d552ac178..b27aa89c6 100644 --- a/SourceX/storm.cpp +++ b/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;