diff --git a/.gitignore b/.gitignore index 216620640..99ff960d5 100644 --- a/.gitignore +++ b/.gitignore @@ -3,6 +3,7 @@ #ignore cmake cache /build/ +/build32/ .vscode/tasks.json # ELF object file. diff --git a/SourceS/miniwin.h b/SourceS/miniwin.h index 7545a542a..bb3c9eb89 100644 --- a/SourceS/miniwin.h +++ b/SourceS/miniwin.h @@ -286,7 +286,7 @@ VOID WINAPI SetLastError(DWORD dwErrCode); WINBOOL WINAPI CloseHandle(HANDLE hObject); HANDLE WINAPI CreateEventA(LPSECURITY_ATTRIBUTES lpEventAttributes, WINBOOL bManualReset, WINBOOL bInitialState, - LPCSTR lpName); + LPCSTR lpName); #define CreateEvent CreateEventA BOOL WINAPI SetEvent(HANDLE hEvent); BOOL WINAPI ResetEvent(HANDLE hEvent); @@ -326,7 +326,7 @@ HWND WINAPI FindWindowA(LPCSTR lpClassName, LPCSTR lpWindowName); #define THREAD_PRIORITY_ABOVE_NORMAL (THREAD_PRIORITY_HIGHEST - 1) uintptr_t __cdecl _beginthreadex(void *_Security, unsigned _StackSize, unsigned(__stdcall *_StartAddress)(void *), - void *_ArgList, unsigned _InitFlag, unsigned *_ThrdAddr); + void *_ArgList, unsigned _InitFlag, unsigned *_ThrdAddr); HANDLE WINAPI GetCurrentThread(VOID); DWORD WINAPI GetCurrentThreadId(VOID); WINBOOL WINAPI SetThreadPriority(HANDLE hThread, int nPriority); @@ -418,18 +418,18 @@ typedef struct _PROCESS_INFORMATION { typedef void *LPSTARTUPINFOA; WINBOOL WINAPI CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, - LPSECURITY_ATTRIBUTES lpThreadAttributes, WINBOOL bInheritHandles, DWORD dwCreationFlags, - LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation); + LPSECURITY_ATTRIBUTES lpThreadAttributes, WINBOOL bInheritHandles, DWORD dwCreationFlags, + LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation); #define CreateProcess CreateProcessA VOID WINAPI ExitProcess(UINT uExitCode); DWORD WINAPI GetCurrentProcessId(VOID); HANDLE WINAPI CreateFileMappingA(HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, DWORD flProtect, - DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCSTR lpName); + DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCSTR lpName); #define CreateFileMapping CreateFileMappingA LPVOID WINAPI MapViewOfFile(HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, - DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap); + DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap); WINBOOL WINAPI UnmapViewOfFile(LPCVOID lpBaseAddress); DWORD WINAPI WaitForInputIdle(HANDLE hProcess, DWORD dwMilliseconds); @@ -438,13 +438,33 @@ HWND WINAPI GetWindow(HWND hWnd, UINT uCmd); DWORD WINAPI GetWindowThreadProcessId(HWND hWnd, LPDWORD lpdwProcessId); DWORD WINAPI GetPrivateProfileStringA(LPCSTR lpAppName, LPCSTR lpKeyName, LPCSTR lpDefault, LPSTR lpReturnedString, - DWORD nSize, LPCSTR lpFileName); + DWORD nSize, LPCSTR lpFileName); #define GetPrivateProfileString GetPrivateProfileStringA int MessageBoxA(HWND hWnd, const char *Text, const char *Title, UINT Flags); #define MessageBox MessageBoxA +typedef LONG LSTATUS, HKEY, REGSAM, PHKEY; +#define HKEY_CURRENT_USER 1 +#define KEY_READ 0x20019 +#define KEY_WRITE 0x20006 +#define REG_SZ 1 +LSTATUS RegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult); +#define RegOpenKeyEx RegOpenKeyExA +LSTATUS RegQueryValueExA(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, BYTE *lpData, LPDWORD lpcbData); +#define RegQueryValueEx RegQueryValueExA +LSTATUS RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, const BYTE *lpData, DWORD cbData); +#define RegSetValueEx RegSetValueExA +LSTATUS RegCloseKeyA(HKEY hKey); +#define RegCloseKey RegCloseKeyA +void PostQuitMessage(int nExitCode); +LRESULT DefWindowProcA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam); +#define DefWindowProc DefWindowProcA +LONG GetWindowLongA(HWND hWnd, int nIndex); +#define GetWindowLong GetWindowLongA +LONG SetWindowLongA(HWND hWnd, int nIndex, LONG dwNewLong); +#define SetWindowLong SetWindowLongA WINBOOL WINAPI WriteFile(HANDLE hFile, LPCVOID lpBuffer, DWORD nNumberOfBytesToWrite, LPDWORD lpNumberOfBytesWritten, - LPOVERLAPPED lpOverlapped); + LPOVERLAPPED lpOverlapped); DWORD WINAPI SetFilePointer(HANDLE hFile, LONG lDistanceToMove, PLONG lpDistanceToMoveHigh, DWORD dwMoveMethod); WINBOOL WINAPI SetEndOfFile(HANDLE hFile); DWORD WINAPI GetFileAttributesA(LPCSTR lpFileName); @@ -455,16 +475,16 @@ HANDLE WINAPI FindFirstFileA(LPCSTR lpFileName, LPWIN32_FIND_DATAA lpFindFileDat #define FindFirstFile FindFirstFileA WINBOOL WINAPI FindClose(HANDLE hFindFile); HANDLE WINAPI CreateFileA(LPCSTR lpFileName, DWORD dwDesiredAccess, DWORD dwShareMode, - LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, - DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); + LPSECURITY_ATTRIBUTES lpSecurityAttributes, DWORD dwCreationDisposition, + DWORD dwFlagsAndAttributes, HANDLE hTemplateFile); #define CreateFile CreateFileA WINBOOL WINAPI ReadFile(HANDLE hFile, LPVOID lpBuffer, DWORD nNumberOfBytesToRead, LPDWORD lpNumberOfBytesRead, - LPOVERLAPPED lpOverlapped); + LPOVERLAPPED lpOverlapped); DWORD WINAPI GetFileSize(HANDLE hFile, LPDWORD lpFileSizeHigh); UINT WINAPI GetWindowsDirectoryA(LPSTR lpBuffer, UINT uSize); #define GetWindowsDirectory GetWindowsDirectoryA WINBOOL WINAPI GetDiskFreeSpaceA(LPCSTR lpRootPathName, LPDWORD lpSectorsPerCluster, LPDWORD lpBytesPerSector, - LPDWORD lpNumberOfFreeClusters, LPDWORD lpTotalNumberOfClusters); + LPDWORD lpNumberOfFreeClusters, LPDWORD lpTotalNumberOfClusters); #define GetDiskFreeSpace GetDiskFreeSpaceA DWORD WINAPI GetModuleFileNameA(HMODULE hModule, LPSTR lpFilename, DWORD nSize); #define GetModuleFileName GetModuleFileNameA @@ -476,6 +496,10 @@ WINBOOL WINAPI CopyFileA(LPCSTR lpExistingFileName, LPCSTR lpNewFileName, WINBOO #define CopyFile CopyFileA HFILE WINAPI OpenFile(LPCSTR lpFileName, LPOFSTRUCT lpReOpenBuff, UINT uStyle); +#define GWL_STYLE (-16) + +#define WS_SYSMENU 0x00080000L + // // Events // @@ -498,6 +522,15 @@ HFILE WINAPI OpenFile(LPCSTR lpFileName, LPOFSTRUCT lpReOpenBuff, UINT uStyle); #define WM_CHAR 0x0102 #define WM_CAPTURECHANGED 0x0215 +#define WM_CREATE 0x0001 +#define WM_DESTROY 0x0002 +#define WM_PAINT 0x000F +#define WM_CLOSE 0x0010 +#define WM_ERASEBKGND 0x0014 +#define WM_ACTIVATEAPP 0x001C +#define WM_QUERYNEWPALETTE 0x030F +#define WM_PALETTECHANGED 0x0311 + #define SC_CLOSE 0xF060 #define VK_RETURN 0x0D diff --git a/SourceS/miniwin_dsound.h b/SourceS/miniwin_dsound.h index 1dbd9968b..f7d5da390 100644 --- a/SourceS/miniwin_dsound.h +++ b/SourceS/miniwin_dsound.h @@ -30,7 +30,8 @@ DECLARE_INTERFACE_(IDirectSoundBuffer, IUnknown) // clang-format on }; -typedef void *LPDIRECTSOUNDBUFFER, *LPDSCAPS, *LPUNKNOWN, *LPCGUID; +typedef IDirectSoundBuffer *LPDIRECTSOUNDBUFFER; +typedef void *LPDSCAPS, *LPUNKNOWN, *LPCGUID; DECLARE_INTERFACE_(IDirectSound, IUnknown) { diff --git a/SourceX/dvlnet/tcp_client.cpp b/SourceX/dvlnet/tcp_client.cpp index 82fc802e0..3f9881698 100644 --- a/SourceX/dvlnet/tcp_client.cpp +++ b/SourceX/dvlnet/tcp_client.cpp @@ -1,4 +1,5 @@ #include "dvlnet/tcp_client.h" +#include using namespace dvlnet; diff --git a/SourceX/init.cpp b/SourceX/init.cpp index 83d1d33e8..8945ddf26 100644 --- a/SourceX/init.cpp +++ b/SourceX/init.cpp @@ -20,6 +20,8 @@ char gszProductName[260] = "Diablo v1.09"; void __fastcall init_cleanup(BOOL show_cursor) { pfile_flush_W(); + init_disable_screensaver(0); + init_run_office_from_start_menu(); if (diabdat_mpq) { SFileCloseArchive(diabdat_mpq); @@ -36,16 +38,52 @@ void __fastcall init_cleanup(BOOL show_cursor) UiDestroy(); effects_cleanup_sfx(); - //sound_cleanup(); + sound_cleanup(); NetClose(); dx_cleanup(); MI_Dummy(show_cursor); - //StormDestroy(); + StormDestroy(); if (show_cursor) ShowCursor(TRUE); } +void __cdecl init_run_office_from_start_menu() +{ + DUMMY(); +} +// 634CA0: using guessed type int killed_mom_parent; + +// SDL_DisableScreenSaver +void __fastcall init_disable_screensaver(BOOLEAN disable) +{ + BOOLEAN v1; // al + char Data[16]; // [esp+4h] [ebp-20h] + DWORD Type; // [esp+14h] [ebp-10h] + DWORD cbData; // [esp+18h] [ebp-Ch] + HKEY phkResult; // [esp+1Ch] [ebp-8h] + BOOLEAN v6; // [esp+20h] [ebp-4h] + + // BUGFIX: this is probably the worst possible way to do this. Alternatives: ExtEscape() with SETPOWERMANAGEMENT, + // SystemParametersInfo() with SPI_SETSCREENSAVEACTIVE/SPI_SETPOWEROFFACTIVE/SPI_SETLOWPOWERACTIVE + + v6 = disable; + if (!RegOpenKeyEx(HKEY_CURRENT_USER, "Control Panel\\Desktop", 0, KEY_READ | KEY_WRITE, &phkResult)) { + if (v6) { + cbData = 16; + if (!RegQueryValueEx(phkResult, "ScreenSaveActive", 0, &Type, (LPBYTE)Data, &cbData)) + screensaver_enabled_prev = Data[0] != '0'; + v1 = 0; + } else { + v1 = screensaver_enabled_prev; + } + Data[1] = 0; + Data[0] = (v1 != 0) + '0'; + RegSetValueEx(phkResult, "ScreenSaveActive", 0, REG_SZ, (const BYTE *)Data, 2u); + RegCloseKey(phkResult); + } +} + /** * Case insensitive search for a file name in a directory. * @return Empty string when not found. @@ -84,6 +122,11 @@ static std::string find_file_in_std_directories(const char *file) TermMsg("Required file %s not found", file); } +void FakeWMDestroy() +{ + MainWndProc(NULL, WM_DESTROY, NULL, NULL); +} + void __fastcall init_create_window(int nCmdShow) { DUMMY(); @@ -120,11 +163,76 @@ void __fastcall init_create_window(int nCmdShow) init_archives(); gmenu_init_menu(); + atexit(FakeWMDestroy); } LRESULT __stdcall MainWndProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) { - UNIMPLEMENTED(); + if (Msg > WM_ERASEBKGND) { + if (Msg == WM_ACTIVATEAPP) { + init_activate_window(hWnd, wParam); + } else { + if (Msg == WM_QUERYNEWPALETTE) { + SDrawRealizePalette(); + return 1; + } + if (Msg == WM_PALETTECHANGED && (HWND)wParam != hWnd) + SDrawRealizePalette(); + } + } else { + switch (Msg) { + case WM_ERASEBKGND: + return 0; + case WM_CREATE: + ghMainWnd = hWnd; + break; + case WM_DESTROY: + init_cleanup(1); + ghMainWnd = 0; + PostQuitMessage(0); + break; + case WM_PAINT: + drawpanflag = 255; + break; + case WM_CLOSE: + return 0; + } + } + return DefWindowProc(hWnd, Msg, wParam, lParam); +} + +void __fastcall init_activate_window(HWND hWnd, BOOLEAN bActive) +{ + LONG dwNewLong; // eax + + gbActive = bActive; + UiAppActivate(bActive); + dwNewLong = GetWindowLong(hWnd, GWL_STYLE); + + if (gbActive && fullscreen) + dwNewLong &= ~WS_SYSMENU; + else + dwNewLong |= WS_SYSMENU; + + SetWindowLong(hWnd, GWL_STYLE, dwNewLong); + + if (gbActive) { + drawpanflag = 255; + ResetPal(); + } +} +// 52571C: using guessed type int drawpanflag; +// 634980: using guessed type int gbActive; + +LRESULT __stdcall WindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + LRESULT result; // eax + + if (CurrentProc) + result = CurrentProc(hWnd, Msg, wParam, lParam); + else + result = MainWndProc(hWnd, Msg, wParam, lParam); + return result; } WNDPROC __fastcall SetWindowProc(WNDPROC NewProc) diff --git a/SourceX/miniwin.cpp b/SourceX/miniwin.cpp index 05be5b4b5..4520ccea4 100644 --- a/SourceX/miniwin.cpp +++ b/SourceX/miniwin.cpp @@ -79,7 +79,7 @@ UINT WINAPI GetWindowsDirectoryA(LPSTR lpBuffer, UINT uSize) } WINBOOL WINAPI GetDiskFreeSpaceA(LPCSTR lpRootPathName, LPDWORD lpSectorsPerCluster, LPDWORD lpBytesPerSector, - LPDWORD lpNumberOfFreeClusters, LPDWORD lpTotalNumberOfClusters) + LPDWORD lpNumberOfFreeClusters, LPDWORD lpTotalNumberOfClusters) { struct statvfs fiData; int success = statvfs("/", &fiData); @@ -231,9 +231,9 @@ UINT WINAPI GetSystemPaletteEntries(HDC hdc, UINT iStart, UINT cEntries, LPPALET } WINBOOL WINAPI CreateProcessA(LPCSTR lpApplicationName, LPSTR lpCommandLine, LPSECURITY_ATTRIBUTES lpProcessAttributes, - LPSECURITY_ATTRIBUTES lpThreadAttributes, WINBOOL bInheritHandles, DWORD dwCreationFlags, - LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, - LPPROCESS_INFORMATION lpProcessInformation) + LPSECURITY_ATTRIBUTES lpThreadAttributes, WINBOOL bInheritHandles, DWORD dwCreationFlags, + LPVOID lpEnvironment, LPCSTR lpCurrentDirectory, LPSTARTUPINFOA lpStartupInfo, + LPPROCESS_INFORMATION lpProcessInformation) { UNIMPLEMENTED(); } @@ -249,7 +249,7 @@ DWORD WINAPI GetCurrentProcessId(VOID) } HANDLE WINAPI CreateFileMappingA(HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappingAttributes, DWORD flProtect, - DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCSTR lpName) + DWORD dwMaximumSizeHigh, DWORD dwMaximumSizeLow, LPCSTR lpName) { DUMMY(); assert(hFile == (HANDLE)-1); @@ -257,7 +257,7 @@ HANDLE WINAPI CreateFileMappingA(HANDLE hFile, LPSECURITY_ATTRIBUTES lpFileMappi } LPVOID WINAPI MapViewOfFile(HANDLE hFileMappingObject, DWORD dwDesiredAccess, DWORD dwFileOffsetHigh, - DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap) + DWORD dwFileOffsetLow, SIZE_T dwNumberOfBytesToMap) { UNIMPLEMENTED(); } @@ -288,7 +288,7 @@ DWORD WINAPI GetWindowThreadProcessId(HWND hWnd, LPDWORD lpdwProcessId) } DWORD WINAPI GetPrivateProfileStringA(LPCSTR lpAppName, LPCSTR lpKeyName, LPCSTR lpDefault, LPSTR lpReturnedString, - DWORD nSize, LPCSTR lpFileName) + DWORD nSize, LPCSTR lpFileName) { if (!SRegLoadString(lpAppName, lpKeyName, 0, lpReturnedString, nSize)) { strncpy(lpReturnedString, lpDefault, nSize); @@ -307,3 +307,62 @@ int MessageBoxA(HWND hWnd, const char *Text, const char *Title, UINT Flags) SDL_ShowSimpleMessageBox(SDLFlags, Title, Text, window) < 0 ? -1 : 0; } + +LSTATUS RegOpenKeyExA(HKEY hKey, LPCSTR lpSubKey, DWORD ulOptions, REGSAM samDesired, PHKEY phkResult) +{ + return 1; +}; + +/** + * @brief This is only ever used to enable or disable the screen saver in a hackish way + * For all other settings operation SReg* from Storm is used instead. + */ +LSTATUS RegQueryValueExA(HKEY hKey, LPCSTR lpValueName, LPDWORD lpReserved, LPDWORD lpType, BYTE *lpData, LPDWORD lpcbData) +{ + if (SDL_IsScreenSaverEnabled()) { + lpData[0] = '0'; + lpData[1] = '\0'; + } + + return 1; +}; + +/** + * @brief This is only ever used to enable or disable the screen saver in a hackish way + * For all other settings operation SReg* from Storm is used instead. + */ +LSTATUS RegSetValueExA(HKEY hKey, LPCSTR lpValueName, DWORD Reserved, DWORD dwType, const BYTE *lpData, DWORD cbData) +{ + if (lpData[0] == '0') { + SDL_DisableScreenSaver(); + } else { + SDL_EnableScreenSaver(); + } + + return 1; +}; + +LSTATUS RegCloseKeyA(HKEY hKey) +{ + return 1; +}; + +void PostQuitMessage(int nExitCode) +{ + DUMMY(); // Possibly use SDL_PumpEvents +} + +LRESULT DefWindowProcA(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam) +{ + DUMMY(); +} + +LONG GetWindowLongA(HWND hWnd, int nIndex) +{ + DUMMY(); +} + +LONG SetWindowLongA(HWND hWnd, int nIndex, LONG dwNewLong) +{ + DUMMY(); +} diff --git a/SourceX/movie.cpp b/SourceX/movie.cpp index e767dd234..ddfe1b883 100644 --- a/SourceX/movie.cpp +++ b/SourceX/movie.cpp @@ -8,13 +8,10 @@ void __fastcall play_movie(char *pszMovie, BOOL user_can_close) { DUMMY_PRINT("%s", pszMovie); - SDL_DestroyTexture(texture); - texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, 320, 156); - SDL_RenderSetLogicalSize(renderer, 320, 156); void *video_stream; movie_playing = TRUE; - //sound_disable_music(TRUE); + sound_disable_music(TRUE); sfx_stop(); effects_play_sound("Sfx\\Misc\\blank.wav"); @@ -26,9 +23,6 @@ void __fastcall play_movie(char *pszMovie, BOOL user_can_close) int bytestoread = SFileGetFileSize(directsound, 0); fileBuffer = DiabloAllocPtr(bytestoread); SFileReadFile(directsound, fileBuffer, bytestoread, NULL, 0); - if (Mix_OpenAudio(22050, AUDIO_S16LSB, 1, 512) < 0) { - printf("SDL_mixer could not initialize! SDL_mixer Error: %s\n", Mix_GetError()); - } /* file meta-info */ unsigned long width, height, nFrames; @@ -48,9 +42,16 @@ void __fastcall play_movie(char *pszMovie, BOOL user_can_close) smk_enable_all(smacker, -1); smk_info_all(smacker, NULL, &nFrames, &usPerFrame); smk_info_video(smacker, &width, &height, NULL); + smk_info_audio(smacker, &a_trackmask, a_channels, a_depth, a_rate); - printf("Audio info for track 0: bit-depth %u, channels %u, rate %u\n", a_depth[0], a_channels[0], a_rate[0]); + if (a_depth[0] && Mix_OpenAudio(a_rate[0], a_depth[0] == 16 ? AUDIO_S16LSB : AUDIO_U8, a_channels[0], 512) < 0) { + printf("SDL_mixer could not initialize! SDL_mixer Error: %s\n", Mix_GetError()); + } + + SDL_DestroyTexture(texture); + texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, width, height); + SDL_RenderSetLogicalSize(renderer, width, height); smk_first(smacker); @@ -61,7 +62,9 @@ void __fastcall play_movie(char *pszMovie, BOOL user_can_close) switch (event.type) { case SDL_KEYDOWN: case SDL_MOUSEBUTTONDOWN: - movie_playing = false; + if (user_can_close) { + movie_playing = false; + } break; case SDL_QUIT: exit(0); @@ -110,13 +113,13 @@ void __fastcall play_movie(char *pszMovie, BOOL user_can_close) } smk_close(smacker); - } - Mix_CloseAudio(); - if (Mix_OpenAudio(44100, AUDIO_S16LSB, 2, 1024) < 0) { - printf("SDL_mixer could not initialize! SDL_mixer Error: %s\n", Mix_GetError()); + SDL_DestroyTexture(texture); + texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, SCREEN_WIDTH, SCREEN_HEIGHT); + SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH, SCREEN_HEIGHT); + + if (a_depth[0] && Mix_OpenAudio(44100, AUDIO_S16LSB, 2, 1024) < 0) { + printf("SDL_mixer could not initialize! SDL_mixer Error: %s\n", Mix_GetError()); + } } - SDL_DestroyTexture(texture); - texture = SDL_CreateTexture(renderer, SDL_PIXELFORMAT_RGBA8888, SDL_TEXTUREACCESS_STREAMING, SCREEN_WIDTH, SCREEN_HEIGHT); - SDL_RenderSetLogicalSize(renderer, SCREEN_WIDTH, SCREEN_HEIGHT); } diff --git a/SourceX/sound.cpp b/SourceX/sound.cpp index a1411c937..6ccbaa3cb 100644 --- a/SourceX/sound.cpp +++ b/SourceX/sound.cpp @@ -1,116 +1,47 @@ +//HEADER_GOES_HERE + +#include "../types.h" #include "pch.h" -bool SoundInited; +LPDIRECTSOUNDBUFFER DSBs[8]; +LPDIRECTSOUND sglpDS; char gbSndInited; -BYTE gbDupSounds; -unsigned char channels = 8; // defines how many channels, respectively how many *.wav files can be played at the same time -UCHAR gbMusicOn; -UCHAR gbSoundOn; - -char *sgszMusicTracks[6] = { "Music\\DTowne.wav", "Music\\DLvlA.wav", "Music\\DLvlB.wav", - "Music\\DLvlC.wav", "Music\\DLvlD.wav", "Music\\Dintro.wav" }; - -void __fastcall snd_init(HWND hWnd) -{ - DUMMY(); - printf("\nSND INIT\n"); - - /* following function Mix_AllocateChannels allocates the number of channels of simultaneously played sounds.*/ - printf("Opened %i sound channels\n\n", Mix_AllocateChannels(channels)); - /* for example following possible channels: - 1. music is playing - 2. walking at the same time (walking sound) - 3. reading a quest book at the same time - 4. perform a magic spell at the same time - 5. hitting an enemy at the same time - 5. enemy is dieing - 6. enemy is losing an object an so on - So it is possible that the channels value has to be modified to adjust an amount of simultaneously played sounds in the future. - At this time 8 channels seem to be sufficient */ - - if (Mix_OpenAudio(44100 /*sampling frequency*/, AUDIO_S16LSB /*Signed 16-bit samples, in little-endian byte order*/, 2 /*2 for stereo sound*/, 1024 /*size of each mixed sample*/) < 0) { - printf("SDL_mixer could not initialize! SDL_mixer Error: %s\n", Mix_GetError()); - } - - gbSndInited = 1; - gbSoundOn = 1; - SoundInited = 1; -} - -void *sgpMusicTrack; -void *buffer; -// int bytestoread; -int channel = 2; - -SDL_AudioSpec wanted; -static Uint8 *audio_chunk; -static Uint32 audio_len; -static Uint8 *audio_pos; +int sglMusicVolume; +int sglSoundVolume; +HMODULE hDsound_dll; +HANDLE sgpMusicTrack; +LPDIRECTSOUNDBUFFER sglpDSB; + +/* data */ + +BYTE gbMusicOn = TRUE; +BYTE gbSoundOn = TRUE; +BYTE gbDupSounds = TRUE; +int sgnMusicTrack = 6; +char *sgszMusicTracks[NUM_MUSIC] = { + "Music\\DTowne.wav", + "Music\\DLvlA.wav", + "Music\\DLvlB.wav", + "Music\\DLvlC.wav", + "Music\\DLvlD.wav", + "Music\\Dintro.wav" +}; +char unk_volume[4][2] = { + { 15, -16 }, + { 15, -16 }, + { 30, -31 }, + { 30, -31 } +}; -void fill_audio(void *udata, Uint8 *stream, int len) +void __fastcall snd_update(BOOL bStopAll) { - /* Only play if we have data left */ - if (audio_len == 0) - return; - - /* Mix as much data as possible */ - len = (len > audio_len ? audio_len : len); - SDL_MixAudio(stream, audio_pos, len, SDL_MIX_MAXVOLUME); - audio_pos += len; - audio_len -= len; + DUMMY_PRINT("snd_update: %d", bStopAll); } -void __fastcall music_start(int nTrack) -{ - //DUMMY(); - //wanted.freq = 44100; //seems not to be used at this time - //wanted.format = AUDIO_S16LSB; //seems not to be used at this time - //wanted.channels = 2; /* 1 = mono, 2 = stereo */ //seems not to be used at this time - //wanted.samples = 1024; /* Good low-latency value for callback */ //seems not to be used at this time - //wanted.callback = fill_audio; //seems not to be used at this time - //wanted.userdata = NULL; //seems not to be used at this time - - gbSoundOn = true; - gbMusicOn = true; - int bytestoread; - int nread; - void *file; - int v6; - - if (buffer != NULL) { - music_stop(); - } - - if (SoundInited) { - /// I know this needs clean up... I haven't the time to do this. - SFileOpenFile(sgszMusicTracks[nTrack], &sgpMusicTrack); - - // This is a hack.... I don't like it . - // If you know this better than I , please help clean it up. - - //Mix_OpenAudio(44100, AUDIO_S16LSB, 1, 1024); //No need to Mix_OpenAudio. Already done in the function __fastcall snd_init - - //Mix_OpenAudio(44100, AUDIO_S16LSB, 2, 1024); - - file = sgpMusicTrack; - bytestoread = (int)SFileGetFileSize((HANDLE)file, 0); - buffer = DiabloAllocPtr(bytestoread); - SFileReadFile(file, (char *)buffer, bytestoread, (LPDWORD)&nread, 0); - - SDL_RWops *rw = SDL_RWFromMem(buffer, bytestoread); - - Mix_Music *Song = Mix_LoadMUS_RW(rw, 1); - - Mix_PlayMusic(Song, -1); - // Mix_PlayChannel(2, Music, 0); - } -} - -void __cdecl music_stop() +void __fastcall snd_stop_snd(TSnd *pSnd) { - DUMMY(); + DUMMY_ONCE(); Mix_HaltMusic(); - Mix_HaltChannel(-1); } BOOL __fastcall snd_playing(TSnd *pSnd) @@ -124,13 +55,6 @@ void __fastcall snd_play_snd(TSnd *pSnd, int lVolume, int lPan) Mix_PlayChannel(-1, pSnd->chunk, 0); } -void __fastcall snd_stop_snd(TSnd *pSnd) -{ - DUMMY(); - Mix_HaltMusic(); -} - -void *MSFXBuffer; TSnd *__fastcall sound_file_load(char *path) { int bytestoread; @@ -142,8 +66,8 @@ TSnd *__fastcall sound_file_load(char *path) SFileOpenFile(path, &file); bytestoread = (int)SFileGetFileSize((HANDLE)file, 0); - MSFXBuffer = DiabloAllocPtr(bytestoread); - SFileReadFile(file, (char *)MSFXBuffer, bytestoread, (LPDWORD)&nrread, 0); + char * MSFXBuffer = DiabloAllocPtr(bytestoread); + SFileReadFile(file, MSFXBuffer, bytestoread, (LPDWORD)&nrread, 0); SDL_RWops *rw = SDL_RWFromMem(MSFXBuffer, bytestoread); Mix_Chunk *SoundFX = Mix_LoadWAV_RW(rw, 1); @@ -153,9 +77,6 @@ TSnd *__fastcall sound_file_load(char *path) fx->sound_path = NULL; return fx; - - // printf("Sound_File_Load %s\n", path); - // UNIMPLEMENTED(); } void __fastcall sound_file_cleanup(TSnd *sound_file) @@ -163,20 +84,170 @@ void __fastcall sound_file_cleanup(TSnd *sound_file) DUMMY(); } -int __fastcall sound_get_or_set_sound_volume(int volume) +void __fastcall snd_init(HWND hWnd) +{ + DUMMY(); + printf("\nSND INIT\n"); + + /* following function Mix_AllocateChannels allocates the number of channels of simultaneously played sounds.*/ + printf("Opened %i sound channels\n\n", Mix_AllocateChannels(8)); + + 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; + } + + gbSndInited = 1; +} + +void __fastcall sound_load_volume(char *value_name, int *value) +{ + int v = *value; + if (!SRegLoadValue("Diablo", value_name, 0, &v)) { + v = VOLUME_MAX; + } + *value = v; + + if (*value < VOLUME_MIN) { + *value = VOLUME_MIN; + } else if (*value > VOLUME_MAX) { + *value = VOLUME_MAX; + } + *value -= *value % 100; +} + +void __fastcall sound_create_primary_buffer(HANDLE music_track) +{ + DUMMY(); +} + +void __cdecl sound_cleanup() +{ + snd_update(TRUE); + //SVidDestroy(); + SFileDdaDestroy(); + + if (sglpDS) { +#ifdef __cplusplus + sglpDS->Release(); +#else + sglpDS->lpVtbl->Release(sglpDS); +#endif + sglpDS = NULL; + } + + if (gbSndInited) { + gbSndInited = FALSE; + sound_store_volume("Sound Volume", sglSoundVolume); + sound_store_volume("Music Volume", sglMusicVolume); + } +} + +void __fastcall sound_store_volume(char *key, int value) +{ + SRegSaveValue("Diablo", key, 0, value); +} + +void __cdecl music_stop() { - DUMMY_PRINT("volume: %d", volume); - return volume; + DUMMY(); + Mix_HaltMusic(); + Mix_HaltChannel(-1); +} + +void *buffer; +void __fastcall music_start(int nTrack) +{ + BOOL success; + + /// ASSERT: assert((DWORD) nTrack < NUM_MUSIC); + music_stop(); + if (gbSndInited && gbMusicOn) { +#ifdef _DEBUG + SFileEnableDirectAccess(FALSE); +#endif + success = SFileOpenFile(sgszMusicTracks[nTrack], &sgpMusicTrack); +#ifdef _DEBUG + SFileEnableDirectAccess(TRUE); +#endif + sound_create_primary_buffer(sgpMusicTrack); + if (!success) { + sgpMusicTrack = 0; + } else { + int bytestoread = (int)SFileGetFileSize((HANDLE)sgpMusicTrack, 0); + char *buffer = DiabloAllocPtr(bytestoread); + SFileReadFile(sgpMusicTrack, buffer, bytestoread, NULL, 0); + + SDL_RWops *rw = SDL_RWFromMem(buffer, bytestoread); + Mix_Music *Song = Mix_LoadMUS_RW(rw, 1); + Mix_PlayMusic(Song, -1); + + sgnMusicTrack = nTrack; + } + } +} + +void __fastcall sound_disable_music(BOOL disable) +{ + if (disable) { + music_stop(); + } else if (sgnMusicTrack != 6) { + music_start(sgnMusicTrack); + } } int __fastcall sound_get_or_set_music_volume(int volume) { - DUMMY_PRINT("volume: %d", volume); - return volume; + if (volume == 1) + return sglMusicVolume; + + sglMusicVolume = volume; + + if (sgpMusicTrack) + SFileDdaSetVolume(sgpMusicTrack, volume, 0); + + return sglMusicVolume; } -void __fastcall snd_update(BOOL bStopAll) +int __fastcall sound_get_or_set_sound_volume(int volume) { + if (volume == 1) + return sglSoundVolume; + + sglSoundVolume = volume; - // DUMMY_PRINT("stopall: %d", bStopAll); + return sglSoundVolume; +} + +/* +SDL_AudioSpec wanted; +static Uint32 audio_len; +static Uint8 *audio_pos; + +void fill_audio(void *udata, Uint8 *stream, int len) +{ + //DUMMY(); + //wanted.freq = 44100; //seems not to be used at this time + //wanted.format = AUDIO_S16LSB; //seems not to be used at this time + //wanted.channels = 2; // 1 = mono, 2 = stereo, seems not to be used at this time + //wanted.samples = 1024; // Good low-latency value for callback, seems not to be used at this time + //wanted.callback = fill_audio; //seems not to be used at this time + //wanted.userdata = NULL; //seems not to be used at this time + + // Only play if we have data left + if (audio_len == 0) + return; + + // Mix as much data as possible + len = (len > audio_len ? audio_len : len); + SDL_MixAudio(stream, audio_pos, len, SDL_MIX_MAXVOLUME); + audio_pos += len; + audio_len -= len; } +*/ diff --git a/SourceX/storm.cpp b/SourceX/storm.cpp index 78aa92f49..133c8da09 100644 --- a/SourceX/storm.cpp +++ b/SourceX/storm.cpp @@ -439,12 +439,12 @@ void __stdcall SDrawMessageBox(char *Text, char *Title, int Flags) //{ // UNIMPLEMENTED(); //} -// -// bool __cdecl StormDestroy(void) -//{ -// UNIMPLEMENTED(); -//} -// + +BOOLEAN __cdecl StormDestroy(void) +{ + DUMMY(); +} + // bool __stdcall SFileSetBasePath(char *) //{ // UNIMPLEMENTED();