You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

142 lines
3.5 KiB

#include "pch.h"
static std::set<HANDLE> threads;
static std::set<HANDLE> events;
struct event_emul {
SDL_mutex *mutex;
SDL_cond *cond;
};
uintptr_t __cdecl _beginthreadex(void *_Security, unsigned _StackSize, unsigned(__stdcall *_StartAddress)(void *),
7 years ago
void *_ArgList, unsigned _InitFlag, unsigned *_ThrdAddr)
{
7 years ago
if (_Security != NULL)
UNIMPLEMENTED();
7 years ago
if (_StackSize != 0)
UNIMPLEMENTED();
7 years ago
if (_InitFlag != 0)
UNIMPLEMENTED();
// WARNING: wrong return type of _StartAddress
SDL_Thread *ret = SDL_CreateThread((SDL_ThreadFunction)_StartAddress, NULL, _ArgList);
*_ThrdAddr = SDL_GetThreadID(ret);
threads.insert((HANDLE)ret);
return (uintptr_t)ret;
}
DWORD WINAPI GetCurrentThreadId(VOID)
{
// DWORD is compatible with SDL_threadID
return SDL_GetThreadID(NULL);
}
HANDLE WINAPI GetCurrentThread(VOID)
{
// Only used for SetThreadPriority, which is unimplemented
return NULL;
}
WINBOOL WINAPI 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 WINAPI InitializeCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
{
SDL_mutex *m = SDL_CreateMutex();
*lpCriticalSection = m;
}
VOID WINAPI EnterCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
{
SDL_LockMutex(*lpCriticalSection);
}
VOID WINAPI LeaveCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
{
SDL_UnlockMutex(*lpCriticalSection);
}
VOID WINAPI DeleteCriticalSection(LPCRITICAL_SECTION lpCriticalSection)
{
SDL_DestroyMutex(*lpCriticalSection);
}
HANDLE WINAPI CreateEventA(LPSECURITY_ATTRIBUTES lpEventAttributes, WINBOOL bManualReset, WINBOOL bInitialState,
7 years ago
LPCSTR lpName)
{
7 years ago
if (lpName != NULL && !strcmp(lpName, "DiabloEvent")) {
// This is used by diablo.cpp to check whether
// the game is already running
// (we do not want to replicate this behaviour anyway)
return NULL;
}
7 years ago
if (lpEventAttributes != NULL)
UNIMPLEMENTED();
7 years ago
if (bManualReset != TRUE)
UNIMPLEMENTED();
7 years ago
if (bInitialState != FALSE)
UNIMPLEMENTED();
7 years ago
if (lpName != NULL)
UNIMPLEMENTED();
struct event_emul *ret;
7 years ago
ret = (struct event_emul *)malloc(sizeof(struct event_emul));
ret->mutex = SDL_CreateMutex();
ret->cond = SDL_CreateCond();
7 years ago
events.insert((HANDLE *)ret);
return ret;
}
BOOL WINAPI SetEvent(HANDLE hEvent)
{
7 years ago
struct event_emul *e = (struct event_emul *)hEvent;
SDL_LockMutex(e->mutex);
SDL_CondSignal(e->cond);
SDL_UnlockMutex(e->mutex);
return 1;
}
BOOL WINAPI ResetEvent(HANDLE hEvent)
{
7 years ago
struct event_emul *e = (struct event_emul *)hEvent;
SDL_LockMutex(e->mutex);
SDL_CondWaitTimeout(e->cond, e->mutex, 0);
SDL_UnlockMutex(e->mutex);
return 1;
}
static DWORD wait_for_sdl_cond(HANDLE hHandle, DWORD dwMilliseconds)
{
7 years ago
struct event_emul *e = (struct event_emul *)hHandle;
SDL_LockMutex(e->mutex);
DWORD ret;
7 years ago
if (dwMilliseconds == INFINITE)
ret = SDL_CondWait(e->cond, e->mutex);
else
ret = SDL_CondWaitTimeout(e->cond, e->mutex, dwMilliseconds);
SDL_CondSignal(e->cond);
SDL_UnlockMutex(e->mutex);
return ret;
}
static DWORD wait_for_sdl_thread(HANDLE hHandle, DWORD dwMilliseconds)
{
7 years ago
if (dwMilliseconds != INFINITE)
UNIMPLEMENTED();
7 years ago
SDL_Thread *t = (SDL_Thread *)hHandle;
SDL_WaitThread(t, NULL);
return 0;
}
DWORD WINAPI WaitForSingleObject(HANDLE hHandle, DWORD dwMilliseconds)
{
// return value different from WinAPI
7 years ago
if (threads.find(hHandle) != threads.end())
return wait_for_sdl_thread(hHandle, dwMilliseconds);
7 years ago
if (events.find(hHandle) != threads.end())
return wait_for_sdl_cond(hHandle, dwMilliseconds);
UNIMPLEMENTED();
}