diff --git a/3rdParty/Storm/Source/storm.h b/3rdParty/Storm/Source/storm.h index 6713924a7..b3c03db49 100644 --- a/3rdParty/Storm/Source/storm.h +++ b/3rdParty/Storm/Source/storm.h @@ -14,26 +14,31 @@ extern std::string basePath; #endif #ifdef __cplusplus -//static float infinity = std::numeric_limits::infinity(); - struct CCritSect { - CRITICAL_SECTION m_critsect; + SDL_mutex *m_critsect; CCritSect() { - InitializeCriticalSection(&m_critsect); + m_critsect = SDL_CreateMutex(); + if (m_critsect == NULL) { + ErrSdl(); + } } ~CCritSect() { - DeleteCriticalSection(&m_critsect); + SDL_DestroyMutex(m_critsect); } void Enter() { - EnterCriticalSection(&m_critsect); + if (SDL_LockMutex(m_critsect) < 0) { + ErrSdl(); + } } void Leave() { - LeaveCriticalSection(&m_critsect); + if (SDL_UnlockMutex(m_critsect) < 0) { + ErrSdl(); + } } }; #endif diff --git a/CMakeLists.txt b/CMakeLists.txt index 1f813d413..2327ff570 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -257,7 +257,7 @@ set(devilutionx_SRCS SourceX/controls/touch.cpp SourceX/display.cpp SourceX/miniwin/misc_msg.cpp - SourceX/miniwin/thread.cpp + SourceX/thread.cpp SourceX/sound.cpp SourceX/soundsample.cpp SourceX/storm/storm.cpp diff --git a/Source/appfat.cpp b/Source/appfat.cpp index fc01b3286..4b7702cf6 100644 --- a/Source/appfat.cpp +++ b/Source/appfat.cpp @@ -34,11 +34,11 @@ void MsgBox(const char *pszFmt, va_list va) void FreeDlg() { - if (terminating && cleanup_thread_id != GetCurrentThreadId()) + if (terminating && cleanup_thread_id != SDL_GetThreadID(NULL)) SDL_Delay(20000); terminating = TRUE; - cleanup_thread_id = GetCurrentThreadId(); + cleanup_thread_id = SDL_GetThreadID(NULL); if (gbMaxPlayers > 1) { if (SNetLeaveGame(3)) diff --git a/Source/diablo.cpp b/Source/diablo.cpp index a847e4331..5a75a4e9e 100644 --- a/Source/diablo.cpp +++ b/Source/diablo.cpp @@ -460,6 +460,12 @@ BOOL PressEscKey() return rv; } +static void GetMousePos(LPARAM lParam) +{ + MouseX = (short)(lParam & 0xffff); + MouseY = (short)((lParam >> 16) & 0xffff); +} + LRESULT DisableInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) { switch (uMsg) { @@ -469,8 +475,7 @@ LRESULT DisableInputWndProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) case WM_SYSKEYDOWN: case WM_SYSCOMMAND: case WM_MOUSEMOVE: - MouseX = (short)LOWORD(lParam); - MouseY = (short)HIWORD(lParam); + GetMousePos(lParam); return 0; case WM_LBUTTONDOWN: if (sgbMouseDown != 0) @@ -526,21 +531,18 @@ LRESULT GM_Game(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } break; case WM_MOUSEMOVE: - MouseX = (short)LOWORD(lParam); - MouseY = (short)HIWORD(lParam); + GetMousePos(lParam); gmenu_on_mouse_move(); return 0; case WM_LBUTTONDOWN: - MouseX = (short)LOWORD(lParam); - MouseY = (short)HIWORD(lParam); + GetMousePos(lParam); if (sgbMouseDown == 0) { sgbMouseDown = 1; track_repeat_walk(LeftMouseDown(wParam)); } return 0; case WM_LBUTTONUP: - MouseX = (short)LOWORD(lParam); - MouseY = (short)HIWORD(lParam); + GetMousePos(lParam); if (sgbMouseDown == 1) { sgbMouseDown = 0; LeftMouseUp(); @@ -548,16 +550,14 @@ LRESULT GM_Game(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam) } return 0; case WM_RBUTTONDOWN: - MouseX = (short)LOWORD(lParam); - MouseY = (short)HIWORD(lParam); + GetMousePos(lParam); if (sgbMouseDown == 0) { sgbMouseDown = 2; RightMouseDown(); } return 0; case WM_RBUTTONUP: - MouseX = (short)LOWORD(lParam); - MouseY = (short)HIWORD(lParam); + GetMousePos(lParam); if (sgbMouseDown == 2) { sgbMouseDown = 0; } diff --git a/Source/dthread.cpp b/Source/dthread.cpp index dca7a917b..8a2fd70a1 100644 --- a/Source/dthread.cpp +++ b/Source/dthread.cpp @@ -4,13 +4,13 @@ DEVILUTION_BEGIN_NAMESPACE static CCritSect sgMemCrit; -unsigned int glpDThreadId; +SDL_threadID glpDThreadId; TMegaPkt *sgpInfoHead; /* may not be right struct */ BOOLEAN dthread_running; -HANDLE sghWorkToDoEvent; +event_emul *sghWorkToDoEvent; /* rdata */ -static HANDLE sghThread = INVALID_HANDLE_VALUE; +static SDL_Thread *sghThread = NULL; void dthread_remove_player(int pnum) { @@ -58,7 +58,7 @@ void dthread_start() return; } - sghWorkToDoEvent = CreateEvent(); + sghWorkToDoEvent = StartEvent(); if (!sghWorkToDoEvent) { error_buf = TraceLastError(); app_fatal("dthread:1\n%s", error_buf); @@ -66,8 +66,8 @@ void dthread_start() dthread_running = TRUE; - sghThread = (HANDLE)_beginthreadex(NULL, 0, dthread_handler, NULL, 0, &glpDThreadId); - if (sghThread == INVALID_HANDLE_VALUE) { + sghThread = CreateThread(dthread_handler, &glpDThreadId); + if (sghThread == NULL) { error_buf = TraceLastError(); app_fatal("dthread2:\n%s", error_buf); } @@ -80,7 +80,7 @@ unsigned int dthread_handler(void *) DWORD dwMilliseconds; while (dthread_running) { - if (!sgpInfoHead && WaitForSingleObject(sghWorkToDoEvent, 0xFFFFFFFF) == -1) { + if (!sgpInfoHead && WaitForEvent(sghWorkToDoEvent) == -1) { error_buf = TraceLastError(); app_fatal("dthread4:\n%s", error_buf); } @@ -122,15 +122,11 @@ void dthread_cleanup() dthread_running = FALSE; SetEvent(sghWorkToDoEvent); - if (sghThread != INVALID_HANDLE_VALUE && glpDThreadId != GetCurrentThreadId()) { - if (WaitForSingleObject(sghThread, 0xFFFFFFFF) == -1) { - error_buf = TraceLastError(); - app_fatal("dthread3:\n(%s)", error_buf); - } - CloseEvent(sghThread); - sghThread = INVALID_HANDLE_VALUE; + if (sghThread != NULL && glpDThreadId != SDL_GetThreadID(NULL)) { + SDL_WaitThread(sghThread, NULL); + sghThread = NULL; } - CloseEvent(sghWorkToDoEvent); + EndEvent(sghWorkToDoEvent); sghWorkToDoEvent = NULL; while (sgpInfoHead) { diff --git a/Source/dthread.h b/Source/dthread.h index 74c2f416b..f0a9800e0 100644 --- a/Source/dthread.h +++ b/Source/dthread.h @@ -2,7 +2,7 @@ #ifndef __DTHREAD_H__ #define __DTHREAD_H__ -extern unsigned int glpDThreadId; +extern SDL_threadID glpDThreadId; extern BOOLEAN dthread_running; void dthread_remove_player(int pnum); diff --git a/Source/effects.cpp b/Source/effects.cpp index c6346cfb1..88674ea91 100644 --- a/Source/effects.cpp +++ b/Source/effects.cpp @@ -1242,7 +1242,7 @@ void effects_play_sound(char *snd_file) } for (i = 0; i < sizeof(sgSFX) / sizeof(TSFX); i++) { - if (!_strcmpi(sgSFX[i].pszName, snd_file) && sgSFX[i].pSnd) { + if (!strcasecmp(sgSFX[i].pszName, snd_file) && sgSFX[i].pSnd) { if (!snd_playing(sgSFX[i].pSnd)) snd_play_snd(sgSFX[i].pSnd, 0, 0); diff --git a/Source/nthread.cpp b/Source/nthread.cpp index eed0115ed..9b2c5c858 100644 --- a/Source/nthread.cpp +++ b/Source/nthread.cpp @@ -10,7 +10,7 @@ DWORD gdwDeltaBytesSec; BOOLEAN nthread_should_run; DWORD gdwTurnsInTransit; uintptr_t glpMsgTbl[MAX_PLRS]; -unsigned int glpNThreadId; +SDL_threadID glpNThreadId; char sgbSyncCountdown; int turn_upper_bit; BOOLEAN sgbTicsOutOfSync; @@ -21,7 +21,7 @@ DWORD gdwNormalMsgSize; int last_tick; /* data */ -static HANDLE sghThread = INVALID_HANDLE_VALUE; +static SDL_Thread *sghThread = NULL; void nthread_terminate_game(const char *pszFcn) { @@ -157,12 +157,11 @@ void nthread_start(BOOL set_turn_upper_bit) sgbThreadIsRunning = FALSE; sgMemCrit.Enter(); nthread_should_run = TRUE; - sghThread = (HANDLE)_beginthreadex(NULL, 0, nthread_handler, NULL, 0, &glpNThreadId); - if (sghThread == INVALID_HANDLE_VALUE) { + sghThread = CreateThread(nthread_handler, &glpNThreadId); + if (sghThread == NULL) { err2 = TraceLastError(); app_fatal("nthread2:\n%s", err2); } - SetThreadPriority(sghThread, THREAD_PRIORITY_HIGHEST); } } @@ -198,20 +197,17 @@ void nthread_cleanup() gdwTurnsInTransit = 0; gdwNormalMsgSize = 0; gdwLargestMsgSize = 0; - if (sghThread != INVALID_HANDLE_VALUE && glpNThreadId != GetCurrentThreadId()) { + if (sghThread != NULL && glpNThreadId != SDL_GetThreadID(NULL)) { if (!sgbThreadIsRunning) sgMemCrit.Leave(); - if (WaitForSingleObject(sghThread, 0xFFFFFFFF) == -1) { - app_fatal("nthread3:\n(%s)", TraceLastError()); - } - CloseEvent(sghThread); - sghThread = INVALID_HANDLE_VALUE; + SDL_WaitThread(sghThread, NULL); + sghThread = NULL; } } void nthread_ignore_mutex(BOOL bStart) { - if (sghThread != INVALID_HANDLE_VALUE) { + if (sghThread != NULL) { if (bStart) sgMemCrit.Leave(); else diff --git a/Source/nthread.h b/Source/nthread.h index 331ae0f89..b44393f38 100644 --- a/Source/nthread.h +++ b/Source/nthread.h @@ -8,7 +8,7 @@ extern DWORD gdwDeltaBytesSec; extern BOOLEAN nthread_should_run; extern DWORD gdwTurnsInTransit; extern uintptr_t glpMsgTbl[MAX_PLRS]; -extern unsigned int glpNThreadId; +extern SDL_threadID glpNThreadId; extern int turn_upper_bit; extern BOOLEAN sgbThreadIsRunning; extern DWORD gdwLargestMsgSize; diff --git a/Source/pfile.cpp b/Source/pfile.cpp index ca490ecc8..994f19fdf 100644 --- a/Source/pfile.cpp +++ b/Source/pfile.cpp @@ -34,7 +34,7 @@ DWORD pfile_get_save_num_from_name(const char *name) DWORD i; for (i = 0; i < MAX_CHARACTERS; i++) { - if (!_strcmpi(hero_names[i], name)) + if (!strcasecmp(hero_names[i], name)) break; } @@ -124,7 +124,7 @@ BOOL pfile_rename_hero(const char *name_1, const char *name_2) if (pfile_get_save_num_from_name(name_2) == MAX_CHARACTERS) { for (i = 0; i != MAX_PLRS; i++) { - if (!_strcmpi(name_1, plr[i]._pName)) { + if (!strcasecmp(name_1, plr[i]._pName)) { found = TRUE; break; } @@ -139,7 +139,7 @@ BOOL pfile_rename_hero(const char *name_1, const char *name_2) SStrCopy(hero_names[save_num], name_2, PLR_NAME_LEN); SStrCopy(plr[i]._pName, name_2, PLR_NAME_LEN); - if (!_strcmpi(gszHero, name_1)) + if (!strcasecmp(gszHero, name_1)) SStrCopy(gszHero, name_2, sizeof(gszHero)); game_2_ui_player(plr, &uihero, gbValidSaveFile); UiSetupPlayerInfo(gszHero, &uihero, GAME_ID); diff --git a/SourceS/miniwin.h b/SourceS/miniwin.h index 4619e0962..f62dc93e2 100644 --- a/SourceS/miniwin.h +++ b/SourceS/miniwin.h @@ -22,7 +22,6 @@ #endif #include "miniwin/misc.h" -#include "miniwin/thread.h" #include "storm_full.h" #ifndef MAX_PATH diff --git a/SourceS/miniwin/misc.h b/SourceS/miniwin/misc.h index 5760e43a8..792765465 100644 --- a/SourceS/miniwin/misc.h +++ b/SourceS/miniwin/misc.h @@ -20,8 +20,6 @@ typedef void *PVOID; typedef unsigned int UINT; -typedef uintptr_t DWORD_PTR, *PDWORD_PTR; - typedef uintptr_t WPARAM; typedef uintptr_t LPARAM; typedef uintptr_t LRESULT; @@ -50,12 +48,6 @@ typedef struct tagMSG { // Everything else // -HANDLE CreateEventA(); -BOOL CloseEvent(HANDLE event); -void SetEvent(HANDLE hEvent); -void ResetEvent(HANDLE hEvent); -int WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds); - void SetCursorPos(int X, int Y); void FocusOnCharInfo(); @@ -67,11 +59,6 @@ bool TranslateMessage(const MSG *lpMsg); LRESULT DispatchMessageA(const MSG *lpMsg); bool PostMessageA(UINT Msg, WPARAM wParam, LPARAM lParam); -uintptr_t DVL_beginthreadex(void *_Security, unsigned _StackSize, unsigned(*_StartAddress)(void *), - void *_ArgList, unsigned _InitFlag, unsigned *_ThrdAddr); -DWORD GetCurrentThreadId(); -bool SetThreadPriority(HANDLE hThread, int nPriority); - // // MSCVRT emulation // @@ -79,7 +66,6 @@ bool SetThreadPriority(HANDLE hThread, int nPriority); constexpr auto DVL_FILE_CURRENT = 1; constexpr auto DVL_WM_QUIT = 0x0012; -constexpr auto DVL_INFINITE = 0xFFFFFFFF; // // Events diff --git a/SourceS/miniwin/misc_macro.h b/SourceS/miniwin/misc_macro.h index 1b0912d4c..f607e7fdb 100644 --- a/SourceS/miniwin/misc_macro.h +++ b/SourceS/miniwin/misc_macro.h @@ -3,44 +3,21 @@ #define TRUE true #define FALSE false -#define INVALID_HANDLE_VALUE ((HANDLE)-1) -#define INVALID_HANDLE ((HANDLE)-1) - -// -// Intrinsics -// -#define LOWORD(l) ((WORD)(((DWORD_PTR)(l)) & 0xffff)) -#define HIWORD(l) ((WORD)((((DWORD_PTR)(l)) >> 16) & 0xffff)) - -#define CreateEvent CreateEventA - -#define WM_QUIT DVL_WM_QUIT - #define PeekMessage PeekMessageA #define DispatchMessage DispatchMessageA #define PostMessage PostMessageA -#define _strcmpi(a, b) strcasecmp(a, b) - -#define THREAD_PRIORITY_HIGHEST 2 - // // File I/O // #define FILE_CURRENT DVL_FILE_CURRENT -// -// Calculate the byte offset of a field in a structure of type type. -// - -#define DeleteFile DeleteFileA - // // Events // -#define _beginthreadex DVL_beginthreadex +#define WM_QUIT DVL_WM_QUIT #define WM_MOUSEMOVE DVL_WM_MOUSEMOVE #define WM_LBUTTONDOWN DVL_WM_LBUTTONDOWN diff --git a/SourceS/miniwin/thread.h b/SourceS/miniwin/thread.h deleted file mode 100644 index fa8e5bbbc..000000000 --- a/SourceS/miniwin/thread.h +++ /dev/null @@ -1,11 +0,0 @@ -#pragma once - -namespace dvl { - -typedef void *CRITICAL_SECTION, **LPCRITICAL_SECTION; -void InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection); -void EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection); -void LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection); -void DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection); - -} // namespace dvl diff --git a/SourceS/sdl2_to_1_2_backports.h b/SourceS/sdl2_to_1_2_backports.h index 249f200d0..5a8b59f3c 100644 --- a/SourceS/sdl2_to_1_2_backports.h +++ b/SourceS/sdl2_to_1_2_backports.h @@ -21,6 +21,8 @@ //== Events handling +#define SDL_threadID Uint32 + #define SDL_Keysym SDL_keysym #define SDL_Keycode SDLKey diff --git a/SourceS/thread.h b/SourceS/thread.h new file mode 100644 index 000000000..413d6831a --- /dev/null +++ b/SourceS/thread.h @@ -0,0 +1,17 @@ +#pragma once + +namespace dvl { + +typedef struct event_emul { + SDL_mutex *mutex; + SDL_cond *cond; +} event_emul; + +event_emul *StartEvent(); +void EndEvent(event_emul *event); +void SetEvent(event_emul *e); +void ResetEvent(event_emul *e); +int WaitForEvent(event_emul *e); +SDL_Thread *CreateThread(unsigned int (*handler)(void *), SDL_threadID *ThreadID); + +} // namespace dvl diff --git a/SourceX/miniwin/thread.cpp b/SourceX/miniwin/thread.cpp deleted file mode 100644 index 8b5f6bdd6..000000000 --- a/SourceX/miniwin/thread.cpp +++ /dev/null @@ -1,176 +0,0 @@ -#include "devilution.h" -#include "stubs.h" -#include -#include - -namespace dvl { - -static std::set threads; -static std::set events; - -struct event_emul { - SDL_mutex *mutex; - SDL_cond *cond; -}; - -struct func_translate { - unsigned int (*func)(void *); - void *arg; -}; - -static int SDLCALL thread_translate(void *ptr) -{ - func_translate *ftptr = static_cast(ptr); - auto ret = ftptr->func(ftptr->arg); - delete ftptr; - return ret; -} - -uintptr_t DVL_beginthreadex(void *_Security, unsigned _StackSize, unsigned (*_StartAddress)(void *), - void *_ArgList, unsigned _InitFlag, unsigned *_ThrdAddr) -{ - if (_Security != NULL) - UNIMPLEMENTED(); - if (_StackSize != 0) - UNIMPLEMENTED(); - if (_InitFlag != 0) - UNIMPLEMENTED(); - func_translate *ft = new func_translate; - ft->func = _StartAddress; - ft->arg = _ArgList; -#ifdef USE_SDL1 - SDL_Thread *ret = SDL_CreateThread(thread_translate, ft); -#else - SDL_Thread *ret = SDL_CreateThread(thread_translate, NULL, ft); -#endif - if (ret == NULL) { - ErrSdl(); - } - *_ThrdAddr = SDL_GetThreadID(ret); - threads.insert((uintptr_t)ret); - return (uintptr_t)ret; -} - -DWORD GetCurrentThreadId() -{ - // DWORD is compatible with SDL_threadID - return SDL_GetThreadID(NULL); -} - -bool SetThreadPriority(HANDLE hThread, int nPriority) -{ - // SDL cannot set the priority of the non-current thread - // (and e.g. unprivileged processes on Linux cannot increase it) - return true; -} - -void InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection) -{ - SDL_mutex *m = SDL_CreateMutex(); - if (m == NULL) { - ErrSdl(); - } - *lpCriticalSection = m; -} - -void EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection) -{ - if (SDL_LockMutex(*((SDL_mutex **)lpCriticalSection)) <= -1) { - ErrSdl(); - } -} - -void LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection) -{ - if (SDL_UnlockMutex(*((SDL_mutex **)lpCriticalSection)) <= -1) { - ErrSdl(); - } -} - -void DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection) -{ - SDL_DestroyMutex(*((SDL_mutex **)lpCriticalSection)); -} - -HANDLE CreateEventA() -{ - struct event_emul *ret; - ret = (struct event_emul *)malloc(sizeof(struct event_emul)); - ret->mutex = SDL_CreateMutex(); - if (ret->mutex == NULL) { - ErrSdl(); - } - ret->cond = SDL_CreateCond(); - if (ret->cond == NULL) { - ErrSdl(); - } - events.insert((uintptr_t)ret); - return ret; -} - -BOOL CloseEvent(HANDLE hObject) -{ - struct event_emul *event = static_cast(hObject); - if (events.find((uintptr_t)event) == events.end()) - return false; - SDL_DestroyCond(event->cond); - SDL_DestroyMutex(event->mutex); - events.erase((uintptr_t)event); - free(event); - return true; -} - -void SetEvent(HANDLE hEvent) -{ - struct event_emul *e = (struct event_emul *)hEvent; - if (SDL_LockMutex(e->mutex) <= -1 || SDL_CondSignal(e->cond) <= -1 || SDL_UnlockMutex(e->mutex) <= -1) { - ErrSdl(); - } -} - -void ResetEvent(HANDLE hEvent) -{ - struct event_emul *e = (struct event_emul *)hEvent; - if (SDL_LockMutex(e->mutex) <= -1 || SDL_CondWaitTimeout(e->cond, e->mutex, 0) <= -1 || SDL_UnlockMutex(e->mutex) <= -1) { - ErrSdl(); - } -} - -static int wait_for_sdl_cond(HANDLE hHandle, DWORD dwMilliseconds) -{ - struct event_emul *e = (struct event_emul *)hHandle; - if (SDL_LockMutex(e->mutex) <= -1) { - ErrSdl(); - } - int ret; - if (dwMilliseconds == DVL_INFINITE) - ret = SDL_CondWait(e->cond, e->mutex); - else - ret = SDL_CondWaitTimeout(e->cond, e->mutex, dwMilliseconds); - if (ret <= -1 || SDL_CondSignal(e->cond) <= -1 || SDL_UnlockMutex(e->mutex) <= -1) { - SDL_Log(SDL_GetError()); - return -1; - } - return ret; -} - -static int wait_for_sdl_thread(HANDLE hHandle, DWORD dwMilliseconds) -{ - if (dwMilliseconds != DVL_INFINITE) - UNIMPLEMENTED(); - SDL_Thread *t = (SDL_Thread *)hHandle; - SDL_WaitThread(t, NULL); - return 0; -} - -int WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds) -{ - // return value different from WinAPI - if (threads.find((uintptr_t)hHandle) != threads.end()) - return wait_for_sdl_thread(hHandle, dwMilliseconds); - if (events.find((uintptr_t)hHandle) != events.end()) - return wait_for_sdl_cond(hHandle, dwMilliseconds); - UNIMPLEMENTED(); -} - -} diff --git a/SourceX/thread.cpp b/SourceX/thread.cpp new file mode 100644 index 000000000..f2918e5b9 --- /dev/null +++ b/SourceX/thread.cpp @@ -0,0 +1,78 @@ +#include "devilution.h" +#include "stubs.h" +#include +#include + +namespace dvl { + +static int SDLCALL thread_translate(void *ptr) +{ + unsigned int (*handler)(void *) = (unsigned int (*)(void *))ptr; + + return handler(NULL); +} + +SDL_Thread *CreateThread(unsigned int (*handler)(void *), SDL_threadID *ThreadID) +{ +#ifdef USE_SDL1 + SDL_Thread *ret = SDL_CreateThread(thread_translate, (void *)handler); +#else + SDL_Thread *ret = SDL_CreateThread(thread_translate, NULL, (void *)handler); +#endif + if (ret == NULL) { + ErrSdl(); + } + *ThreadID = SDL_GetThreadID(ret); + return ret; +} + +event_emul *StartEvent() +{ + event_emul *ret; + ret = (event_emul *)malloc(sizeof(event_emul)); + ret->mutex = SDL_CreateMutex(); + if (ret->mutex == NULL) { + ErrSdl(); + } + ret->cond = SDL_CreateCond(); + if (ret->cond == NULL) { + ErrSdl(); + } + return ret; +} + +void EndEvent(event_emul *event) +{ + SDL_DestroyCond(event->cond); + SDL_DestroyMutex(event->mutex); + free(event); +} + +void SetEvent(event_emul *e) +{ + if (SDL_LockMutex(e->mutex) <= -1 || SDL_CondSignal(e->cond) <= -1 || SDL_UnlockMutex(e->mutex) <= -1) { + ErrSdl(); + } +} + +void ResetEvent(event_emul *e) +{ + if (SDL_LockMutex(e->mutex) <= -1 || SDL_CondWaitTimeout(e->cond, e->mutex, 0) <= -1 || SDL_UnlockMutex(e->mutex) <= -1) { + ErrSdl(); + } +} + +int WaitForEvent(event_emul *e) +{ + if (SDL_LockMutex(e->mutex) <= -1) { + ErrSdl(); + } + int ret = SDL_CondWait(e->cond, e->mutex); + if (ret <= -1 || SDL_CondSignal(e->cond) <= -1 || SDL_UnlockMutex(e->mutex) <= -1) { + SDL_Log(SDL_GetError()); + return -1; + } + return ret; +} + +} diff --git a/types.h b/types.h index 7e593bac0..1bcbe7fc0 100644 --- a/types.h +++ b/types.h @@ -10,6 +10,7 @@ #include "miniwin.h" #include "soundsample.h" +#include "thread.h" #include "ui_fwd.h" DEVILUTION_BEGIN_NAMESPACE