488 lines
11 KiB
C++
488 lines
11 KiB
C++
/********************************************************************************
|
|
Copyright (C) 2001-2012 Hugh Bailey <obs.jim@gmail.com>
|
|
|
|
This program is free software; you can redistribute it and/or modify
|
|
it under the terms of the GNU General Public License as published by
|
|
the Free Software Foundation; either version 2 of the License, or
|
|
(at your option) any later version.
|
|
|
|
This program is distributed in the hope that it will be useful,
|
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
GNU General Public License for more details.
|
|
|
|
You should have received a copy of the GNU General Public License
|
|
along with this program; if not, write to the Free Software
|
|
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307, USA.
|
|
********************************************************************************/
|
|
|
|
|
|
#ifdef WIN32
|
|
|
|
#define WINVER 0x0600
|
|
#define _WIN32_WINDOWS 0x0600
|
|
#define _WIN32_WINNT 0x0600
|
|
#define WIN32_LEAN_AND_MEAN
|
|
#define ISOLATION_AWARE_ENABLED 1
|
|
#include <windows.h>
|
|
#include <MMSystem.h>
|
|
|
|
#include "XT.h"
|
|
|
|
|
|
|
|
|
|
|
|
LARGE_INTEGER clockFreq, startTime;
|
|
LONGLONG prevElapsedTime;
|
|
DWORD startTick;
|
|
|
|
void STDCALL InputProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
|
|
void STDCALL ResetCursorClip();
|
|
|
|
SYSTEM_INFO si;
|
|
|
|
BOOL bHidingCursor = 0;
|
|
|
|
HWND hwndMainAppWindow = NULL;
|
|
|
|
|
|
void STDCALL OSInit()
|
|
{
|
|
timeBeginPeriod(1);
|
|
|
|
GetSystemInfo(&si);
|
|
|
|
QueryPerformanceFrequency(&clockFreq);
|
|
QueryPerformanceCounter(&startTime);
|
|
startTick = GetTickCount();
|
|
prevElapsedTime = 0;
|
|
}
|
|
|
|
void STDCALL OSExit()
|
|
{
|
|
timeEndPeriod(1);
|
|
}
|
|
|
|
|
|
|
|
void STDCALL OSSetMainAppWindow(HANDLE window)
|
|
{
|
|
hwndMainAppWindow = (HWND)window;
|
|
}
|
|
|
|
void __cdecl OSMessageBoxva(const TCHAR *format, va_list argptr)
|
|
{
|
|
TCHAR blah[4096];
|
|
vtsprintf_s(blah, 4095, format, argptr);
|
|
|
|
MessageBox(hwndMainAppWindow, blah, NULL, MB_ICONWARNING);
|
|
}
|
|
|
|
void __cdecl OSMessageBox(const TCHAR *format, ...)
|
|
{
|
|
va_list arglist;
|
|
|
|
va_start(arglist, format);
|
|
|
|
OSMessageBoxva(format, arglist);
|
|
}
|
|
|
|
|
|
HANDLE STDCALL OSFindFirstFile(CTSTR lpFileName, OSFindData &findData)
|
|
{
|
|
WIN32_FIND_DATA wfd;
|
|
HANDLE hFind = FindFirstFile(lpFileName, &wfd);
|
|
|
|
if(hFind == INVALID_HANDLE_VALUE)
|
|
hFind = NULL;
|
|
else
|
|
{
|
|
BOOL bFoundDumbDir;
|
|
do
|
|
{
|
|
bFoundDumbDir = FALSE;
|
|
if( (scmp(wfd.cFileName, TEXT("..")) == 0) ||
|
|
(scmp(wfd.cFileName, TEXT(".")) == 0) )
|
|
{
|
|
if(!FindNextFile(hFind, &wfd))
|
|
{
|
|
FindClose(hFind);
|
|
return NULL;
|
|
}
|
|
bFoundDumbDir = TRUE;
|
|
}
|
|
}while(bFoundDumbDir);
|
|
|
|
scpy(findData.fileName, wfd.cFileName);
|
|
findData.bDirectory = (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
|
findData.bHidden = (wfd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0;
|
|
}
|
|
|
|
return hFind;
|
|
}
|
|
|
|
BOOL STDCALL OSFindNextFile(HANDLE hFind, OSFindData &findData)
|
|
{
|
|
WIN32_FIND_DATA wfd;
|
|
BOOL bSuccess = FindNextFile(hFind, &wfd);
|
|
|
|
BOOL bFoundDumbDir;
|
|
do
|
|
{
|
|
bFoundDumbDir = FALSE;
|
|
if( (scmp(wfd.cFileName, TEXT("..")) == 0) ||
|
|
(scmp(wfd.cFileName, TEXT(".")) == 0) )
|
|
{
|
|
if(!FindNextFile(hFind, &wfd))
|
|
{
|
|
bSuccess = FALSE;
|
|
break;
|
|
}
|
|
bFoundDumbDir = TRUE;
|
|
}
|
|
}while(bFoundDumbDir);
|
|
|
|
if(bSuccess)
|
|
{
|
|
scpy(findData.fileName, wfd.cFileName);
|
|
findData.bDirectory = (wfd.dwFileAttributes & FILE_ATTRIBUTE_DIRECTORY) != 0;
|
|
findData.bHidden = (wfd.dwFileAttributes & FILE_ATTRIBUTE_HIDDEN) != 0;
|
|
}
|
|
else
|
|
*findData.fileName = 0;
|
|
|
|
return bSuccess;
|
|
}
|
|
|
|
void STDCALL OSFindClose(HANDLE hFind)
|
|
{
|
|
FindClose(hFind);
|
|
}
|
|
|
|
|
|
DWORD STDCALL OSGetSysPageSize()
|
|
{
|
|
return si.dwPageSize;
|
|
}
|
|
|
|
LPVOID STDCALL OSVirtualAlloc(size_t dwSize)
|
|
{
|
|
return VirtualAlloc(NULL, dwSize, MEM_RESERVE|MEM_COMMIT, PAGE_READWRITE);
|
|
}
|
|
|
|
void STDCALL OSVirtualFree(LPVOID lpData)
|
|
{
|
|
VirtualFree(lpData, 0, MEM_RELEASE);
|
|
}
|
|
|
|
void STDCALL OSExitProgram()
|
|
{
|
|
PostQuitMessage(0);
|
|
}
|
|
|
|
void STDCALL OSCriticalExit()
|
|
{
|
|
SystemParametersInfo(SPI_SETSCREENSAVEACTIVE, 1, 0, 0);
|
|
TerminateProcess(GetCurrentProcess(), INVALID);
|
|
}
|
|
|
|
|
|
BOOL STDCALL OSDeleteFile(CTSTR lpFile)
|
|
{
|
|
return DeleteFile(lpFile);
|
|
}
|
|
|
|
BOOL STDCALL OSCopyFile(CTSTR lpFileDest, CTSTR lpFileSrc)
|
|
{
|
|
return CopyFile(lpFileSrc, lpFileDest, TRUE);
|
|
}
|
|
|
|
BOOL STDCALL OSCreateDirectory(CTSTR lpDirectory)
|
|
{
|
|
return CreateDirectory(lpDirectory, NULL);
|
|
}
|
|
|
|
BOOL STDCALL OSSetCurrentDirectory(CTSTR lpDirectory)
|
|
{
|
|
return SetCurrentDirectory(lpDirectory);
|
|
}
|
|
|
|
BOOL STDCALL OSFileExists(CTSTR lpFile)
|
|
{
|
|
OSFindData ofd;
|
|
HANDLE hFind = OSFindFirstFile(lpFile, ofd);
|
|
if(hFind)
|
|
{
|
|
OSFindClose(hFind);
|
|
return TRUE;
|
|
}
|
|
|
|
return FALSE;
|
|
}
|
|
|
|
int STDCALL OSProcessEvent()
|
|
{
|
|
MSG msg;
|
|
|
|
if (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE))
|
|
{
|
|
if (msg.message == WM_QUIT)
|
|
return 0;
|
|
else
|
|
{
|
|
TranslateMessage(&msg);
|
|
DispatchMessage(&msg);
|
|
return 2;
|
|
}
|
|
}
|
|
else
|
|
return 1;
|
|
}
|
|
|
|
|
|
void STDCALL OSShowCursor(BOOL bShow)
|
|
{
|
|
/*HCURSOR hCursor = bShow ? LoadCursor(NULL, IDC_ARROW) : NULL;
|
|
bHidingCursor = !bShow;
|
|
SetCursor(hCursor);
|
|
|
|
ResetCursorClip(hwndMain);*/
|
|
|
|
if(bShow)
|
|
{
|
|
int displayCount = ShowCursor(TRUE);
|
|
while(displayCount > 0)
|
|
displayCount = ShowCursor(FALSE);
|
|
}
|
|
else
|
|
{
|
|
int displayCount = ShowCursor(FALSE);
|
|
while(displayCount > -1)
|
|
displayCount = ShowCursor(FALSE);
|
|
}
|
|
}
|
|
|
|
void STDCALL OSSetCursorPos(int x, int y)
|
|
{
|
|
POINT point;
|
|
point.x = x;
|
|
point.y = y;
|
|
SetCursorPos(point.x, point.y);
|
|
}
|
|
|
|
void STDCALL OSGetCursorPos(int &x, int &y)
|
|
{
|
|
POINT point;
|
|
|
|
GetCursorPos(&point);
|
|
x = point.x;
|
|
y = point.y;
|
|
}
|
|
|
|
|
|
BOOL STDCALL OSDebuggerPresent()
|
|
{
|
|
return IsDebuggerPresent();
|
|
}
|
|
|
|
void __cdecl OSDebugOutva(const TCHAR *format, va_list argptr)
|
|
{
|
|
/*TCHAR blah[4096];
|
|
vtsprintf_s(blah, 4095, format, argptr);*/
|
|
|
|
String strDebug = FormattedStringva(format, argptr);
|
|
|
|
OutputDebugString(strDebug);
|
|
}
|
|
|
|
void __cdecl OSDebugOut(const TCHAR *format, ...)
|
|
{
|
|
va_list arglist;
|
|
|
|
va_start(arglist, format);
|
|
|
|
OSDebugOutva(format, arglist);
|
|
}
|
|
|
|
|
|
|
|
HANDLE STDCALL OSLoadLibrary(CTSTR lpFile)
|
|
{
|
|
TCHAR FullFileName[250];
|
|
|
|
scpy(FullFileName, lpFile);
|
|
scat(FullFileName, TEXT(".dll"));
|
|
return (HANDLE)LoadLibrary(FullFileName);
|
|
}
|
|
|
|
DEFPROC STDCALL OSGetProcAddress(HANDLE hLibrary, LPCSTR lpProcedure)
|
|
{
|
|
return (DEFPROC)GetProcAddress((HMODULE)hLibrary, lpProcedure);
|
|
}
|
|
|
|
void STDCALL OSFreeLibrary(HANDLE hLibrary)
|
|
{
|
|
FreeLibrary((HMODULE)hLibrary);
|
|
}
|
|
|
|
|
|
HANDLE STDCALL OSCreateMutex()
|
|
{
|
|
CRITICAL_SECTION *pSection = (CRITICAL_SECTION*)malloc(sizeof(CRITICAL_SECTION));
|
|
InitializeCriticalSection(pSection);
|
|
|
|
return (HANDLE)pSection;
|
|
}
|
|
|
|
void STDCALL OSEnterMutex(HANDLE hMutex)
|
|
{
|
|
assert(hMutex);
|
|
EnterCriticalSection((CRITICAL_SECTION*)hMutex);
|
|
}
|
|
|
|
BOOL STDCALL OSTryEnterMutex(HANDLE hMutex)
|
|
{
|
|
assert(hMutex);
|
|
return TryEnterCriticalSection((CRITICAL_SECTION*)hMutex);
|
|
}
|
|
|
|
void STDCALL OSLeaveMutex(HANDLE hMutex)
|
|
{
|
|
assert(hMutex);
|
|
LeaveCriticalSection((CRITICAL_SECTION*)hMutex);
|
|
}
|
|
|
|
void STDCALL OSCloseMutex(HANDLE hMutex)
|
|
{
|
|
assert(hMutex);
|
|
DeleteCriticalSection((CRITICAL_SECTION*)hMutex);
|
|
free(hMutex);
|
|
}
|
|
|
|
|
|
|
|
void STDCALL OSSleep(DWORD dwMSeconds)
|
|
{
|
|
Sleep(dwMSeconds);
|
|
}
|
|
|
|
|
|
DWORD STDCALL OSGetTime()
|
|
{
|
|
//NOTE: Credit goes to the amazingly awesome bullet physics library for this time code fix,
|
|
//though I think this was basically copied out of the KB274323
|
|
|
|
/*LARGE_INTEGER currentTime;
|
|
QueryPerformanceCounter(¤tTime);
|
|
LONGLONG elapsedTime = currentTime.QuadPart -
|
|
startTime.QuadPart;
|
|
|
|
// Compute the number of millisecond ticks elapsed.
|
|
unsigned long msecTicks = (unsigned long)(1000 * elapsedTime /
|
|
clockFreq.QuadPart);
|
|
|
|
// Check for unexpected leaps in the Win32 performance counter.
|
|
// (This is caused by unexpected data across the PCI to ISA
|
|
// bridge, aka south bridge. See Microsoft KB274323.)
|
|
unsigned long elapsedTicks = GetTickCount() - startTick;
|
|
signed long msecOff = (signed long)(msecTicks - elapsedTicks);
|
|
if (msecOff < -100 || msecOff > 100)
|
|
{
|
|
// Adjust the starting time forwards.
|
|
LONGLONG msecAdjustment = MIN(msecOff *
|
|
clockFreq.QuadPart / 1000, elapsedTime -
|
|
prevElapsedTime);
|
|
startTime.QuadPart += msecAdjustment;
|
|
elapsedTime -= msecAdjustment;
|
|
|
|
// Recompute the number of millisecond ticks elapsed.
|
|
msecTicks = (unsigned long)(1000 * elapsedTime /
|
|
clockFreq.QuadPart);
|
|
}
|
|
|
|
// Store the current elapsed time for adjustments next time.
|
|
prevElapsedTime = elapsedTime;
|
|
|
|
return msecTicks;*/
|
|
|
|
return timeGetTime();
|
|
}
|
|
|
|
QWORD STDCALL OSGetTimeMicroseconds()
|
|
{
|
|
LARGE_INTEGER currentTime;
|
|
QueryPerformanceCounter(¤tTime);
|
|
LONGLONG elapsedTime = currentTime.QuadPart -
|
|
startTime.QuadPart;
|
|
|
|
// Compute the number of millisecond ticks elapsed.
|
|
unsigned long msecTicks = (unsigned long)(1000 * elapsedTime /
|
|
clockFreq.QuadPart);
|
|
|
|
// Check for unexpected leaps in the Win32 performance counter.
|
|
// (This is caused by unexpected data across the PCI to ISA
|
|
// bridge, aka south bridge. See Microsoft KB274323.)
|
|
unsigned long elapsedTicks = GetTickCount() - startTick;
|
|
signed long msecOff = (signed long)(msecTicks - elapsedTicks);
|
|
if (msecOff < -100 || msecOff > 100)
|
|
{
|
|
// Adjust the starting time forwards.
|
|
LONGLONG msecAdjustment = MIN(msecOff *
|
|
clockFreq.QuadPart / 1000, elapsedTime -
|
|
prevElapsedTime);
|
|
startTime.QuadPart += msecAdjustment;
|
|
elapsedTime -= msecAdjustment;
|
|
}
|
|
|
|
// Store the current elapsed time for adjustments next time.
|
|
prevElapsedTime = elapsedTime;
|
|
|
|
// Convert to microseconds.
|
|
unsigned long usecTicks = (unsigned long)(1000000 * elapsedTime /
|
|
clockFreq.QuadPart);
|
|
|
|
return usecTicks;
|
|
}
|
|
|
|
|
|
UINT STDCALL OSGetProcessorCount()
|
|
{
|
|
return si.dwNumberOfProcessors;
|
|
}
|
|
|
|
HANDLE STDCALL OSCreateThread(XTHREAD lpThreadFunc, LPVOID param)
|
|
{
|
|
DWORD dummy;
|
|
return CreateThread(NULL, 0, (LPTHREAD_START_ROUTINE)lpThreadFunc, param, 0, &dummy);
|
|
}
|
|
|
|
BOOL STDCALL OSWaitForThread(HANDLE hThread, LPDWORD ret)
|
|
{
|
|
BOOL bRet = (WaitForSingleObjectEx(hThread, INFINITE, 0) == WAIT_OBJECT_0);
|
|
|
|
if(ret)
|
|
GetExitCodeThread(hThread, ret);
|
|
|
|
return bRet;
|
|
}
|
|
|
|
BOOL STDCALL OSCloseThread(HANDLE hThread)
|
|
{
|
|
CloseHandle(hThread);
|
|
return 1;
|
|
}
|
|
|
|
BOOL STDCALL OSTerminateThread(HANDLE hThread, DWORD waitMS)
|
|
{
|
|
if(WaitForSingleObjectEx(hThread, waitMS, 0) == WAIT_TIMEOUT)
|
|
TerminateThread(hThread, 0);
|
|
|
|
CloseHandle(hThread);
|
|
return 1;
|
|
}
|
|
|
|
|
|
|
|
#endif
|