mirror of
https://github.com/beefytech/Beef.git
synced 2025-07-04 23:36:00 +02:00
Initial checkin
This commit is contained in:
parent
c74712dad9
commit
078564ac9e
3242 changed files with 1616395 additions and 0 deletions
83
BeefySysLib/platform/PlatformHelper.h
Normal file
83
BeefySysLib/platform/PlatformHelper.h
Normal file
|
@ -0,0 +1,83 @@
|
|||
#pragma once
|
||||
|
||||
#include "../Common.h"
|
||||
|
||||
#define OUTRESULT(res) do { if (outResult != NULL) *outResult = (res); } while (0)
|
||||
|
||||
static bool TryStringOut(const Beefy::String& str, char* outStr, int* inOutSize)
|
||||
{
|
||||
if ((outStr == NULL) || (*inOutSize < str.length() + 1))
|
||||
{
|
||||
if ((outStr != NULL) && (*inOutSize != 0))
|
||||
outStr[0] = 0; // Return empty string
|
||||
*inOutSize = (int)str.length() + 1;
|
||||
return false;
|
||||
}
|
||||
|
||||
*inOutSize = (int)str.length() + 1;
|
||||
memcpy(outStr, str.c_str(), (int)str.length() + 1);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool TryStringOut(const Beefy::String& str, char* outStr, int* inOutSize, BfpResult* outResult)
|
||||
{
|
||||
if (TryStringOut(str, outStr, inOutSize))
|
||||
{
|
||||
OUTRESULT(BfpResult_Ok);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
OUTRESULT(BfpResult_InsufficientBuffer);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
static BfpResult BfpGetStrHelper(Beefy::StringImpl& outStr, std::function<void(char* outStr, int* inOutStrSize, BfpResult* result)> func)
|
||||
{
|
||||
const int initSize = 4096;
|
||||
char localBuf[initSize];
|
||||
|
||||
int strSize = initSize;
|
||||
BfpResult result = BfpResult_Ok;
|
||||
func(localBuf, &strSize, &result);
|
||||
|
||||
if (result == BfpResult_Ok)
|
||||
{
|
||||
outStr.Append(localBuf, strSize - 1);
|
||||
return BfpResult_Ok;
|
||||
}
|
||||
else if (result == BfpResult_InsufficientBuffer)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
char* localBufPtr = (char*)malloc(strSize);
|
||||
func(localBufPtr, &strSize, &result);
|
||||
if (result == BfpResult_InsufficientBuffer)
|
||||
{
|
||||
free(localBufPtr);
|
||||
continue;
|
||||
}
|
||||
outStr.Append(localBuf, strSize - 1);
|
||||
free(localBufPtr);
|
||||
return BfpResult_Ok;
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#define BFP_GETSTR_HELPER(STRNAME, __RESULT, CMD) \
|
||||
{ \
|
||||
int strLen = 0; \
|
||||
int* __STRLEN = &strLen; \
|
||||
char* __STR = NULL; \
|
||||
CMD; \
|
||||
if ((BfpResult)__RESULT == BfpResult_InsufficientBuffer) \
|
||||
{ \
|
||||
STRNAME.Reserve(strLen); \
|
||||
__STR = STRNAME.GetMutablePtr(); \
|
||||
CMD; \
|
||||
STRNAME.mLength = strLen - 1; \
|
||||
}\
|
||||
}
|
432
BeefySysLib/platform/PlatformInterface.h
Normal file
432
BeefySysLib/platform/PlatformInterface.h
Normal file
|
@ -0,0 +1,432 @@
|
|||
#pragma once
|
||||
|
||||
#include "../Common.h"
|
||||
|
||||
#define BFP_VERSION 2
|
||||
|
||||
#ifndef BFP_EXPORT
|
||||
#define BFP_EXPORT BF_EXPORT
|
||||
#endif
|
||||
|
||||
#ifndef BFP_CALLTYPE
|
||||
#define BFP_CALLTYPE BF_CALLTYPE
|
||||
#endif
|
||||
|
||||
// Windows file time (the number of 100-nanosecond intervals that have elapsed since 12:00 A.M. January 1, 1601 Coordinated Universal Time (UTC))
|
||||
typedef uint64 BfpTimeStamp;
|
||||
|
||||
typedef intptr BfpThreadId;
|
||||
struct BfpThread;
|
||||
struct BfpFile;
|
||||
struct BfpSpawn;
|
||||
struct BfpFileWatcher;
|
||||
struct BfpProcess;
|
||||
|
||||
struct BfpGUID
|
||||
{
|
||||
uint32 mData1;
|
||||
uint16 mData2;
|
||||
uint16 mData3;
|
||||
uint8 mData4[8];
|
||||
};
|
||||
|
||||
enum BfpResult
|
||||
{
|
||||
BfpResult_Ok,
|
||||
BfpResult_UnknownError,
|
||||
BfpResult_InsufficientBuffer,
|
||||
BfpResult_NotSupported,
|
||||
BfpResult_NoResults,
|
||||
BfpResult_InvalidParameter,
|
||||
BfpResult_Locked,
|
||||
BfpResult_AlreadyExists,
|
||||
BfpResult_NotFound,
|
||||
BfpResult_ShareError,
|
||||
BfpResult_AccessError,
|
||||
BfpResult_PartialData,
|
||||
BfpResult_TempFileError,
|
||||
BfpResult_Timeout
|
||||
};
|
||||
|
||||
enum BfpSystemResult
|
||||
{
|
||||
BfpSystemResult_Ok = BfpResult_Ok,
|
||||
BfpSystemResult_PartialData = BfpResult_PartialData
|
||||
};
|
||||
|
||||
enum BfpFileResult
|
||||
{
|
||||
BfpFileResult_Ok = BfpResult_Ok,
|
||||
BfpFileResult_NoResults = BfpResult_NoResults,
|
||||
BfpFileResult_UnknownError = BfpResult_UnknownError,
|
||||
BfpFileResult_InvalidParameter = BfpResult_InvalidParameter,
|
||||
BfpFileResult_Locked = BfpResult_Locked,
|
||||
BfpFileResult_AlreadyExists = BfpResult_AlreadyExists,
|
||||
BfpFileResult_NotFound = BfpResult_NotFound,
|
||||
BfpFileResult_ShareError = BfpResult_ShareError,
|
||||
BfpFileResult_AccessError = BfpResult_AccessError,
|
||||
BfpFileResult_PartialData = BfpResult_PartialData,
|
||||
BfpFileResult_InsufficientBuffer = BfpResult_InsufficientBuffer,
|
||||
BfpFileResult_Timeout = BfpResult_Timeout
|
||||
};
|
||||
|
||||
typedef void(*BfpCrashInfoFunc)();
|
||||
|
||||
enum BfpSystemInitFlags
|
||||
{
|
||||
BfpSystemInitFlag_None = 0,
|
||||
BfpSystemInitFlag_InstallCrashCatcher = 1,
|
||||
BfpSystemInitFlag_SilentCrash = 2,
|
||||
};
|
||||
|
||||
enum BfpCrashReportKind
|
||||
{
|
||||
BfpCrashReportKind_Default,
|
||||
BfpCrashReportKind_GUI,
|
||||
BfpCrashReportKind_Console,
|
||||
BfpCrashReportKind_PrintOnly,
|
||||
BfpCrashReportKind_None
|
||||
};
|
||||
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_Init(int version, BfpSystemInitFlags flags);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_SetCommandLine(int argc, char** argv);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_SetCrashReportKind(BfpCrashReportKind crashReportKind);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_AddCrashInfoFunc(BfpCrashInfoFunc crashInfoFunc);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_AddCrashInfo(const char* str); // Can do at any time, or during CrashInfoFunc callbacks
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_Shutdown();
|
||||
BFP_EXPORT uint32 BFP_CALLTYPE BfpSystem_TickCount();
|
||||
BFP_EXPORT BfpTimeStamp BFP_CALLTYPE BfpSystem_GetTimeStamp();
|
||||
BFP_EXPORT uint16 BFP_CALLTYPE BfpSystem_EndianSwap16(uint16 val);
|
||||
BFP_EXPORT uint32 BFP_CALLTYPE BfpSystem_EndianSwap32(uint32 val);
|
||||
BFP_EXPORT uint64 BFP_CALLTYPE BfpSystem_EndianSwap64(uint64 val);
|
||||
BFP_EXPORT uint8 BFP_CALLTYPE BfpSystem_InterlockedExchange8(uint8* ptr, uint8 val);
|
||||
BFP_EXPORT uint16 BFP_CALLTYPE BfpSystem_InterlockedExchange16(uint16* ptr, uint16 val);
|
||||
BFP_EXPORT uint32 BFP_CALLTYPE BfpSystem_InterlockedExchange32(uint32* ptr, uint32 val);
|
||||
BFP_EXPORT uint64 BFP_CALLTYPE BfpSystem_InterlockedExchange64(uint64* ptr, uint64 val);
|
||||
BFP_EXPORT uint32 BFP_CALLTYPE BfpSystem_InterlockedExchangeAdd8(uint8* ptr, uint8 val);
|
||||
BFP_EXPORT uint16 BFP_CALLTYPE BfpSystem_InterlockedExchangeAdd16(uint16* ptr, uint16 val);
|
||||
BFP_EXPORT uint32 BFP_CALLTYPE BfpSystem_InterlockedExchangeAdd32(uint32* ptr, uint32 val); // Returns the initial value in 'ptr'
|
||||
BFP_EXPORT uint64 BFP_CALLTYPE BfpSystem_InterlockedExchangeAdd64(uint64* ptr, uint64 val);
|
||||
BFP_EXPORT uint8 BFP_CALLTYPE BfpSystem_InterlockedCompareExchange8(uint8* ptr, uint8 oldVal, uint8 newVal);
|
||||
BFP_EXPORT uint16 BFP_CALLTYPE BfpSystem_InterlockedCompareExchange16(uint16* ptr, uint16 oldVal, uint16 newVal);
|
||||
BFP_EXPORT uint32 BFP_CALLTYPE BfpSystem_InterlockedCompareExchange32(uint32* ptr, uint32 oldVal, uint32 newVal);
|
||||
BFP_EXPORT uint64 BFP_CALLTYPE BfpSystem_InterlockedCompareExchange64(uint64* ptr, uint64 oldVal, uint64 newVal);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_FatalError(const char* error, const char* title);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_GetCommandLine(char* outStr, int* inOutStrSize, BfpSystemResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_GetExecutablePath(char* outStr, int* inOutStrSize, BfpSystemResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_GetEnvironmentStrings(char* outStr, int* inOutStrSize, BfpSystemResult* outResult);
|
||||
BFP_EXPORT int BFP_CALLTYPE BfpSystem_GetNumLogicalCPUs(BfpSystemResult* outResult);
|
||||
BFP_EXPORT int64 BFP_CALLTYPE BfpSystem_GetCPUTick();
|
||||
BFP_EXPORT int64 BFP_CALLTYPE BfpSystem_GetCPUTickFreq();
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_CreateGUID(BfpGUID* outGuid);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSystem_GetComputerName(char* outStr, int* inOutStrSize, BfpSystemResult* outResult);
|
||||
|
||||
#ifdef BF32
|
||||
#define BfpSystem_InterlockedExchangePtr BfpSystem_InterlockedExchange32
|
||||
#define BfpSystem_InterlockedExchangeAddPtr BfpSystem_InterlockedExchangeAdd32
|
||||
#define BfpSystem_InterlockedCompareExchangePtr BfpSystem_InterlockedCompareExchange32
|
||||
#define BfpSystem_EndianSwapPtr BfpSystem_EndianSwap32
|
||||
#else
|
||||
#define BfpSystem_InterlockedExchangePtr BfpSystem_InterlockedExchange64
|
||||
#define BfpSystem_InterlockedExchangeAddPtr BfpSystem_InterlockedExchangeAdd64
|
||||
#define BfpSystem_InterlockedCompareExchangePtr BfpSystem_InterlockedCompareExchange64
|
||||
#define BfpSystem_EndianSwapPtr BfpSystem_EndianSwap64
|
||||
#endif
|
||||
|
||||
enum BfpProcessResult
|
||||
{
|
||||
BfpProcessResult_Ok = BfpResult_Ok,
|
||||
BfpProcessResult_UnknownError = BfpResult_UnknownError,
|
||||
BfpProcessResult_InsufficientBuffer = BfpResult_InsufficientBuffer,
|
||||
};
|
||||
|
||||
BFP_EXPORT intptr BFP_CALLTYPE BfpProcess_GetCurrentId();
|
||||
BFP_EXPORT bool BFP_CALLTYPE BfpProcess_IsRemoteMachine(const char* machineName);
|
||||
BFP_EXPORT BfpProcess* BFP_CALLTYPE BfpProcess_GetById(const char* machineName, int processId, BfpProcessResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpProcess_Enumerate(const char* machineName, BfpProcess** outProcesses, int* inOutProcessesSize, BfpProcessResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpProcess_Release(BfpProcess* process);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpProcess_GetMainWindowTitle(BfpProcess* process, char* outTitle, int* inOutTitleSize, BfpProcessResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpProcess_GetProcessName(BfpProcess* process, char* outName, int* inOutNameSize, BfpProcessResult* outResult);
|
||||
BFP_EXPORT int BFP_CALLTYPE BfpProcess_GetProcessId(BfpProcess* process);
|
||||
|
||||
enum BfpSpawnFlags
|
||||
{
|
||||
BfpSpawnFlag_None = 0,
|
||||
BfpSpawnFlag_ArgsIncludesTarget = 1, // Otherwise most platforms prepend targetPath to the args
|
||||
BfpSpawnFlag_UseArgsFile = 2,
|
||||
BfpSpawnFlag_UseArgsFile_Native = 4,
|
||||
BfpSpawnFlag_UseArgsFile_UTF8 = 8,
|
||||
BfpSpawnFlag_UseArgsFile_BOM = 0x10,
|
||||
BfpSpawnFlag_UseShellExecute = 0x20, // Allows opening non-executable files by file association (ie: documents)
|
||||
BfpSpawnFlag_RedirectStdInput = 0x40,
|
||||
BfpSpawnFlag_RedirectStdOutput = 0x80,
|
||||
BfpSpawnFlag_RedirectStdError = 0x100,
|
||||
BfpSpawnFlag_NoWindow = 0x200,
|
||||
BfpSpawnFlag_ErrorDialog = 0x400,
|
||||
BfpSpawnFlag_Window_Hide = 0x800,
|
||||
BfpSpawnFlag_Window_Maximized = 0x1000,
|
||||
};
|
||||
|
||||
enum BfpSpawnResult
|
||||
{
|
||||
BfpSpawnResult_Ok = BfpResult_Ok,
|
||||
BfpSpawnResult_UnknownError = BfpResult_UnknownError,
|
||||
BfpSpawnResult_TempFileError = BfpResult_TempFileError
|
||||
};
|
||||
|
||||
enum BfpKillFlags
|
||||
{
|
||||
BfpKillFlag_None = 0,
|
||||
BfpKillFlag_KillChildren = 1
|
||||
};
|
||||
|
||||
BFP_EXPORT BfpSpawn* BFP_CALLTYPE BfpSpawn_Create(const char* targetPath, const char* args, const char* workingDir, const char* env, BfpSpawnFlags flags, BfpSpawnResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSpawn_Release(BfpSpawn* spawn);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSpawn_Kill(BfpSpawn* spawn, int exitCode, BfpKillFlags killFlags, BfpSpawnResult* outResult);
|
||||
BFP_EXPORT bool BFP_CALLTYPE BfpSpawn_WaitFor(BfpSpawn* spawn, int waitMS, int* outExitCode, BfpSpawnResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpSpawn_GetStdHandles(BfpSpawn* spawn, BfpFile** outStdIn, BfpFile** outStdOut, BfpFile** outStdErr); // Caller must release the files
|
||||
|
||||
enum BfpThreadCreateFlags
|
||||
{
|
||||
BfpThreadCreateFlag_None = 0,
|
||||
BfpThreadCreateFlag_Suspended = 1,
|
||||
BfpThreadCreateFlag_StackSizeReserve = 2, // Otherwise is a 'commit'
|
||||
};
|
||||
|
||||
typedef void (BFP_CALLTYPE *BfpThreadStartProc)(void* threadParam);
|
||||
|
||||
enum BfpThreadPriority
|
||||
{
|
||||
BfpThreadPriority_VeryLow = -2,
|
||||
BfpThreadPriority_Low = -1,
|
||||
BfpThreadPriority_Normal = 0,
|
||||
BfpThreadPriority_High = 1,
|
||||
BfpThreadPriority_VeryHigh =2
|
||||
};
|
||||
|
||||
enum BfpThreadResult
|
||||
{
|
||||
BfpThreadResult_Ok = BfpResult_Ok,
|
||||
BfpThreadResult_UnknownError = BfpResult_UnknownError,
|
||||
BfpThreadResult_InsufficientBuffer = BfpResult_InsufficientBuffer,
|
||||
BfpThreadResult_NotSupported = BfpResult_NotSupported
|
||||
};
|
||||
|
||||
BFP_EXPORT BfpThread* BFP_CALLTYPE BfpThread_Create(BfpThreadStartProc startProc, void* threadParam, intptr stackSize = 0, BfpThreadCreateFlags flags = BfpThreadCreateFlag_None, BfpThreadId* outThreadId = NULL);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpThread_Release(BfpThread* thread);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpThread_SetName(BfpThread* thread, const char* name, BfpThreadResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpThread_GetName(BfpThread* thread, char* outName, int* inOutNameSize, BfpThreadResult* outResult);
|
||||
BFP_EXPORT BfpThread* BFP_CALLTYPE BfpThread_GetCurrent();
|
||||
BFP_EXPORT BfpThreadId BFP_CALLTYPE BfpThread_GetCurrentId();
|
||||
BFP_EXPORT bool BFP_CALLTYPE BfpThread_WaitFor(BfpThread* thread, int waitMS);
|
||||
BFP_EXPORT BfpThreadPriority BFP_CALLTYPE BfpThread_GetPriority(BfpThread* thread, BfpThreadResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpThread_SetPriority(BfpThread* thread, BfpThreadPriority threadPriority, BfpThreadResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpThread_Suspend(BfpThread* thread, BfpThreadResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpThread_Resume(BfpThread* thread, BfpThreadResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpThread_GetIntRegisters(BfpThread* thread, intptr* outStackPtr, intptr* outIntRegs, int* inOutIntRegCount, BfpThreadResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpThread_GetStackInfo(BfpThread* thread, intptr* outStackBase, int* outStackLimit, BfpThreadResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpThread_Sleep(int sleepMS);
|
||||
BFP_EXPORT bool BFP_CALLTYPE BfpThread_Yield();
|
||||
|
||||
struct BfpCritSect;
|
||||
BFP_EXPORT BfpCritSect* BFP_CALLTYPE BfpCritSect_Create();
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpCritSect_Release(BfpCritSect* critSect);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpCritSect_Enter(BfpCritSect* critSect);
|
||||
BFP_EXPORT bool BFP_CALLTYPE BfpCritSect_TryEnter(BfpCritSect* critSect, int waitMS);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpCritSect_Leave(BfpCritSect* critSect);
|
||||
|
||||
struct BfpTLS;
|
||||
BFP_EXPORT BfpTLS* BFP_CALLTYPE BfpTLS_Create();
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpTLS_Release(BfpTLS* tls);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpTLS_SetValue(BfpTLS* tls, void* value);
|
||||
BFP_EXPORT void* BFP_CALLTYPE BfpTLS_GetValue(BfpTLS* tls);
|
||||
|
||||
|
||||
enum BfpEventFlags
|
||||
{
|
||||
BfpEventFlag_None = 0,
|
||||
BfpEventFlag_AllowAutoReset = 1,
|
||||
BfpEventFlag_AllowManualReset = 2,
|
||||
BfpEventFlag_InitiallySet_Auto = 4,
|
||||
BfpEventFlag_InitiallySet_Manual = 8
|
||||
};
|
||||
|
||||
enum BfpEventResult
|
||||
{
|
||||
BfpEventResult_Ok = BfpResult_Ok,
|
||||
BfpEventResult_NotSupported = BfpResult_NotSupported
|
||||
};
|
||||
|
||||
struct BfpEvent;
|
||||
BFP_EXPORT BfpEvent* BFP_CALLTYPE BfpEvent_Create(BfpEventFlags flags);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpEvent_Release(BfpEvent* event);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpEvent_Set(BfpEvent* event, bool requireManualReset);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpEvent_Reset(BfpEvent* event, BfpEventResult* outResult);
|
||||
BFP_EXPORT bool BFP_CALLTYPE BfpEvent_WaitFor(BfpEvent* event, int waitMS);
|
||||
|
||||
enum BfpLibResult
|
||||
{
|
||||
BfpLibResult_Ok = BfpResult_Ok,
|
||||
BfpLibResult_UnknownError = BfpResult_UnknownError,
|
||||
BfpLibResult_InsufficientBuffer = BfpResult_InsufficientBuffer
|
||||
};
|
||||
|
||||
struct BfpDynLib;
|
||||
BFP_EXPORT BfpDynLib* BFP_CALLTYPE BfpDynLib_Load(const char* fileName);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpDynLib_Release(BfpDynLib* lib);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpDynLib_GetFilePath(BfpDynLib* lib, char* outPath, int* inOutPathSize, BfpLibResult* outResult);
|
||||
BFP_EXPORT void* BFP_CALLTYPE BfpDynLib_GetProcAddress(BfpDynLib* lib, const char* name);
|
||||
|
||||
enum BfpSysDirectoryKind
|
||||
{
|
||||
BfpSysDirectoryKind_Default, // Home on Linux, Desktop on Windows, etc.
|
||||
BfpSysDirectoryKind_Home,
|
||||
BfpSysDirectoryKind_System,
|
||||
BfpSysDirectoryKind_Desktop,
|
||||
BfpSysDirectoryKind_AppData_Local,
|
||||
BfpSysDirectoryKind_AppData_LocalLow,
|
||||
BfpSysDirectoryKind_AppData_Roaming,
|
||||
};
|
||||
|
||||
struct BfpFindFileData;
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpDirectory_Create(const char* name, BfpFileResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpDirectory_Rename(const char* oldName, const char* newName, BfpFileResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpDirectory_Delete(const char* name, BfpFileResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpDirectory_GetCurrent(char* outPath, int* inOutPathSize, BfpFileResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpDirectory_SetCurrent(const char* path, BfpFileResult* outResult);
|
||||
BFP_EXPORT bool BFP_CALLTYPE BfpDirectory_Exists(const char* path);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpDirectory_GetSysDirectory(BfpSysDirectoryKind sysDirKind, char* outPath, int* inOutPathLen, BfpFileResult* outResult);
|
||||
|
||||
enum BfpFileCreateKind
|
||||
{
|
||||
BfpFileCreateKind_CreateAlways,
|
||||
BfpFileCreateKind_CreateIfNotExists,
|
||||
BfpFileCreateKind_OpenExisting,
|
||||
};
|
||||
|
||||
enum BfpFileCreateFlags
|
||||
{
|
||||
BfpFileCreateFlag_Read = 1,
|
||||
BfpFileCreateFlag_Write = 2,
|
||||
|
||||
BfpFileCreateFlag_ShareRead = 4,
|
||||
BfpFileCreateFlag_ShareWrite = 8,
|
||||
BfpFileCreateFlag_ShareDelete = 0x10,
|
||||
|
||||
BfpFileCreateFlag_Append = 0x20,
|
||||
BfpFileCreateFlag_Truncate = 0x40,
|
||||
|
||||
BfpFileCreateFlag_WriteThrough = 0x80,
|
||||
BfpFileCreateFlag_DeleteOnClose = 0x100,
|
||||
BfpFileCreateFlag_NoBuffering = 0x200,
|
||||
|
||||
BfpFileCreateFlag_NonBlocking = 0x400,
|
||||
BfpFileCreateFlag_AllowTimeouts = 0x800,
|
||||
BfpFileCreateFlag_Pipe = 0x1000,
|
||||
};
|
||||
|
||||
enum BfpFileSeekKind
|
||||
{
|
||||
BfpFileSeekKind_Absolute,
|
||||
BfpFileSeekKind_Relative,
|
||||
BfpFileSeekKind_FromEnd
|
||||
};
|
||||
|
||||
enum BfpFileAttributes
|
||||
{
|
||||
BfpFileAttribute_None = 0,
|
||||
BfpFileAttribute_Normal = 1,
|
||||
BfpFileAttribute_Directory = 2,
|
||||
BfpFileAttribute_SymLink = 4,
|
||||
BfpFileAttribute_Device = 8,
|
||||
BfpFileAttribute_ReadOnly = 0x10,
|
||||
BfpFileAttribute_Hidden = 0x20,
|
||||
BfpFileAttribute_System = 0x40,
|
||||
BfpFileAttribute_Temporary = 0x80,
|
||||
BfpFileAttribute_Offline = 0x100,
|
||||
BfpFileAttribute_Encrypted = 0x200,
|
||||
BfpFileAttribute_Archive = 0x400,
|
||||
};
|
||||
|
||||
enum BfpFileCopyKind
|
||||
{
|
||||
BfpFileCopyKind_Always,
|
||||
BfpFileCopyKind_IfNotExists,
|
||||
BfpFileCopyKind_IfNewer,
|
||||
};
|
||||
|
||||
enum BfpFileWaitFlags
|
||||
{
|
||||
BfpFileWaitFlag_None = 0,
|
||||
BfpFileWaitFlag_Read = 1,
|
||||
BfpFileWaitFlag_Write = 2,
|
||||
};
|
||||
|
||||
enum BfpFileStdKind
|
||||
{
|
||||
BfpFileStdKind_StdOut,
|
||||
BfpFileStdKind_StdError,
|
||||
BfpFileStdKind_StdIn
|
||||
};
|
||||
|
||||
BFP_EXPORT BfpFile* BFP_CALLTYPE BfpFile_Create(const char* name, BfpFileCreateKind createKind, BfpFileCreateFlags createFlags, BfpFileAttributes createdFileAttr, BfpFileResult* outResult);
|
||||
BFP_EXPORT BfpFile* BFP_CALLTYPE BfpFile_GetStd(BfpFileStdKind kind, BfpFileResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpFile_Release(BfpFile* file);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpFile_Close(BfpFile* file, BfpFileResult* outResult);
|
||||
BFP_EXPORT intptr BFP_CALLTYPE BfpFile_Write(BfpFile* file, const void* buffer, intptr size, int timeoutMS, BfpFileResult* outResult);
|
||||
BFP_EXPORT intptr BFP_CALLTYPE BfpFile_Read(BfpFile* file, void* buffer, intptr size, int timeoutMS, BfpFileResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpFile_Flush(BfpFile* file);
|
||||
BFP_EXPORT int64 BFP_CALLTYPE BfpFile_GetFileSize(BfpFile* file);
|
||||
BFP_EXPORT int64 BFP_CALLTYPE BfpFile_Seek(BfpFile* file, int64 offset, BfpFileSeekKind seekKind);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpFile_Truncate(BfpFile* file);
|
||||
BFP_EXPORT BfpTimeStamp BFP_CALLTYPE BfpFile_GetTime_LastWrite(const char* path);
|
||||
BFP_EXPORT BfpFileAttributes BFP_CALLTYPE BfpFile_GetAttributes(const char* path, BfpFileResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpFile_SetAttributes(const char* path, BfpFileAttributes attribs, BfpFileResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpFile_Copy(const char* oldPath, const char* newPath, BfpFileCopyKind copyKind, BfpFileResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpFile_Rename(const char* oldPath, const char* newPath, BfpFileResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpFile_Delete(const char* path, BfpFileResult* outResult);
|
||||
BFP_EXPORT bool BFP_CALLTYPE BfpFile_Exists(const char* path);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpFile_GetTempPath(char* outPath, int* inOutPathSize, BfpFileResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpFile_GetTempFileName(char* outName, int* inOutNameSize, BfpFileResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpFile_GetFullPath(const char* inPath, char* outPath, int* inOutPathSize, BfpFileResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpFile_GetActualPath(const char* inPath, char* outPath, int* inOutPathSize, BfpFileResult* outResult);
|
||||
|
||||
enum BfpFileChangeKind
|
||||
{
|
||||
BfpFileChangeKind_Added,
|
||||
BfpFileChangeKind_Removed,
|
||||
BfpFileChangeKind_Modified,
|
||||
BfpFileChangeKind_Renamed,
|
||||
BfpFileChangeKind_Failed
|
||||
};
|
||||
|
||||
typedef void(*BfpDirectoryChangeFunc)(BfpFileWatcher* watcher, void* userData, BfpFileChangeKind changeKind, const char* directory, const char* fileName, const char* oldName);
|
||||
|
||||
enum BfpFileWatcherFlags
|
||||
{
|
||||
BfpFileWatcherFlag_None = 0,
|
||||
BfpFileWatcherFlag_IncludeSubdirectories = 1
|
||||
};
|
||||
|
||||
BFP_EXPORT BfpFileWatcher* BFP_CALLTYPE BfpFileWatcher_WatchDirectory(const char* path, BfpDirectoryChangeFunc callback, BfpFileWatcherFlags flags, void* userData, BfpFileResult* outResult);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpFileWatcher_Release(BfpFileWatcher* fileWatcher);
|
||||
|
||||
enum BfpFindFileFlags
|
||||
{
|
||||
BfpFindFileFlag_None = 0,
|
||||
BfpFindFileFlag_Files = 1,
|
||||
BfpFindFileFlag_Directories = 2,
|
||||
};
|
||||
|
||||
BFP_EXPORT BfpFindFileData* BFP_CALLTYPE BfpFindFileData_FindFirstFile(const char* path, BfpFindFileFlags flags, BfpFileResult* outResult);
|
||||
BFP_EXPORT bool BFP_CALLTYPE BfpFindFileData_FindNextFile(BfpFindFileData* findData);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpFindFileData_GetFileName(BfpFindFileData* findData, char* outName, int* inOutNameSize, BfpFileResult* outResult);
|
||||
BFP_EXPORT BfpTimeStamp BFP_CALLTYPE BfpFindFileData_GetTime_LastWrite(BfpFindFileData* findData);
|
||||
BFP_EXPORT BfpTimeStamp BFP_CALLTYPE BfpFindFileData_GetTime_Created(BfpFindFileData* findData);
|
||||
BFP_EXPORT BfpTimeStamp BFP_CALLTYPE BfpFindFileData_GetTime_Access(BfpFindFileData* findData);
|
||||
BFP_EXPORT BfpFileAttributes BFP_CALLTYPE BfpFindFileData_GetFileAttributes(BfpFindFileData* findData);
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpFindFileData_Release(BfpFindFileData* findData);
|
||||
|
||||
BFP_EXPORT int BFP_CALLTYPE BfpStack_CaptureBackTrace(int framesToSkip, intptr* outFrames, int wantFrameCount);
|
||||
|
||||
BFP_EXPORT void BFP_CALLTYPE BfpOutput_DebugString(const char* str);
|
1072
BeefySysLib/platform/darwin/DarwinCommon.cpp
Normal file
1072
BeefySysLib/platform/darwin/DarwinCommon.cpp
Normal file
File diff suppressed because it is too large
Load diff
322
BeefySysLib/platform/darwin/DarwinCommon.h
Normal file
322
BeefySysLib/platform/darwin/DarwinCommon.h
Normal file
|
@ -0,0 +1,322 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef __LP64__
|
||||
#define BF64
|
||||
#else
|
||||
#define BF32
|
||||
#endif
|
||||
|
||||
#define BOOST_DETAIL_NO_CONTAINER_FWD
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
#include <sys/time.h>
|
||||
#include <libkern/OSAtomic.h>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
#include <wchar.h>
|
||||
#include <math.h>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#define FFI_BUILDING
|
||||
#include "third_party/libffi/x86_64-apple-darwin12.5.0/include/ffi.h"
|
||||
}
|
||||
|
||||
#define FFI_STDCALL FFI_DEFAULT_ABI
|
||||
#define FFI_THISCALL FFI_DEFAULT_ABI
|
||||
#define FFI_FASTCALL FFI_DEFAULT_ABI
|
||||
|
||||
typedef uint64_t uint64;
|
||||
typedef uint32_t uint32;
|
||||
typedef uint16_t uint16;
|
||||
typedef uint8_t uint8;
|
||||
typedef int64_t int64;
|
||||
typedef int32_t int32;
|
||||
typedef int16_t int16;
|
||||
typedef int8_t int8;
|
||||
typedef unsigned int uint;
|
||||
|
||||
#define BF_PLATFORM_DARWIN
|
||||
#define BF_PLATFORM_SDL
|
||||
|
||||
#define NOP
|
||||
//#define BF_NOTHROW throw ()
|
||||
//#define BF_NOTHROW noexcept
|
||||
#define BF_NOTHROW
|
||||
|
||||
#ifdef BF64
|
||||
typedef int64 intptr;
|
||||
typedef uint64 uintptr;
|
||||
#else
|
||||
typedef int32 intptr;
|
||||
typedef uint32 uintptr;
|
||||
#endif
|
||||
|
||||
typedef wchar_t* BSTR;
|
||||
typedef int HRESULT;
|
||||
typedef uint32 DWORD;
|
||||
typedef int32 LONG;
|
||||
|
||||
typedef pthread_key_t BFTlsKey;
|
||||
typedef pthread_t BF_THREADID;
|
||||
|
||||
int64 abs(int64 val);
|
||||
|
||||
struct IID
|
||||
{
|
||||
unsigned long Data1;
|
||||
unsigned short Data2;
|
||||
unsigned short Data3;
|
||||
unsigned char Data4[ 8 ];
|
||||
};
|
||||
|
||||
typedef void* HANDLE;
|
||||
typedef void* HMODULE;
|
||||
|
||||
#include "../notwin/NotWin.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define _DEBUG
|
||||
#endif
|
||||
|
||||
//ARM
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
#define BF_FULL_MEMORY_FENCE() __asm__ __volatile__("mfence": : :"memory")
|
||||
#define BF_SPINWAIT_NOP() __asm__ volatile ("pause\n" : : : "memory" );
|
||||
#else
|
||||
#define BF_FULL_MEMORY_FENCE() __sync_synchronize()
|
||||
#define BF_SPINWAIT_NOP() ((void) 0)
|
||||
#endif
|
||||
|
||||
#define BF_COMPILER_FENCE() __asm__ __volatile__("": : :"memory")
|
||||
#define BF_THREAD_YIELD() sched_yield()
|
||||
|
||||
#define BF_ASSERT assert
|
||||
#define BF_FATAL(msg) assert(msg == 0)
|
||||
|
||||
#define BF_NOINLINE __attribute__ ((noinline))
|
||||
#define BF_NAKED
|
||||
|
||||
#define _alloca alloca
|
||||
|
||||
namespace Beefy
|
||||
{
|
||||
|
||||
class CritSect
|
||||
{
|
||||
private:
|
||||
pthread_mutex_t mCriticalSection;
|
||||
|
||||
public:
|
||||
CritSect(void)
|
||||
{
|
||||
pthread_mutexattr_t attributes;
|
||||
|
||||
pthread_mutexattr_init(&attributes);
|
||||
pthread_mutexattr_settype(&attributes, PTHREAD_MUTEX_RECURSIVE);
|
||||
pthread_mutex_init(&mCriticalSection, &attributes);
|
||||
pthread_mutexattr_destroy(&attributes);
|
||||
}
|
||||
|
||||
~CritSect(void)
|
||||
{
|
||||
pthread_mutex_destroy(&mCriticalSection);
|
||||
}
|
||||
|
||||
bool TryLock()
|
||||
{
|
||||
return pthread_mutex_trylock( &mCriticalSection ) == 0;
|
||||
}
|
||||
|
||||
void Lock()
|
||||
{
|
||||
pthread_mutex_lock( &mCriticalSection );
|
||||
}
|
||||
|
||||
void Unlock()
|
||||
{
|
||||
pthread_mutex_unlock(&mCriticalSection);
|
||||
}
|
||||
};
|
||||
|
||||
class SyncEvent
|
||||
{
|
||||
private:
|
||||
pthread_mutex_t mMutex;
|
||||
pthread_cond_t mCondition;
|
||||
uint32 mSet;
|
||||
bool mManualReset;
|
||||
|
||||
bool mInitialState;
|
||||
int mSetCount;
|
||||
int mWaitForCountFail;
|
||||
int mWaitForCountSucceed;
|
||||
|
||||
public:
|
||||
SyncEvent(bool manualReset = false, bool initialState = false)
|
||||
{
|
||||
mManualReset = manualReset;
|
||||
mSet = initialState;
|
||||
int result = pthread_mutex_init(&mMutex, NULL);
|
||||
BF_ASSERT(result == 0);
|
||||
result = pthread_cond_init(&mCondition, NULL);
|
||||
BF_ASSERT(result == 0);
|
||||
|
||||
mInitialState = initialState;
|
||||
mSetCount = 0;
|
||||
mWaitForCountFail = 0;
|
||||
mWaitForCountSucceed = 0;
|
||||
}
|
||||
|
||||
~SyncEvent()
|
||||
{
|
||||
pthread_cond_destroy(&mCondition);
|
||||
pthread_mutex_destroy(&mMutex);
|
||||
}
|
||||
|
||||
void Set()
|
||||
{
|
||||
pthread_mutex_lock(&mMutex);
|
||||
mSet = true;
|
||||
pthread_cond_signal(&mCondition);
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
|
||||
mSetCount++;
|
||||
}
|
||||
|
||||
void Reset()
|
||||
{
|
||||
mSet = false;
|
||||
}
|
||||
|
||||
bool WaitFor(uint32 timeout)
|
||||
{
|
||||
int result = pthread_mutex_lock(&mMutex);
|
||||
BF_ASSERT(result == 0);
|
||||
while (!mSet)
|
||||
{
|
||||
struct timespec ts;
|
||||
struct timeval tv;
|
||||
gettimeofday(&tv, NULL);
|
||||
|
||||
uint64 nsec = (uint64)timeout * 1000000;
|
||||
ts.tv_nsec = tv.tv_usec * 1000;
|
||||
ts.tv_sec = tv.tv_sec;
|
||||
|
||||
ts.tv_nsec += nsec % 1000000000;
|
||||
ts.tv_sec += nsec / 1000000000;
|
||||
|
||||
ts.tv_sec += (ts.tv_nsec / 1000000000);
|
||||
ts.tv_nsec %= 1000000000;
|
||||
|
||||
result = pthread_cond_timedwait(&mCondition, &mMutex, &ts);
|
||||
|
||||
if (timeout == (uint32)-1)
|
||||
BF_ASSERT(result == 0);
|
||||
|
||||
if (result != 0)
|
||||
{
|
||||
// Timeout
|
||||
mWaitForCountFail++;
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
if (!mManualReset)
|
||||
mSet = false;
|
||||
mWaitForCountSucceed++;
|
||||
pthread_mutex_unlock(&mMutex);
|
||||
return true;
|
||||
}
|
||||
};
|
||||
|
||||
}
|
||||
|
||||
inline uint32 InterlockedCompareExchange(volatile uint32* dest, uint32 exch, uint32 comp)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (OSAtomicCompareAndSwap32Barrier((int32)comp, (int32)exch, (volatile int32*)dest))
|
||||
return comp;
|
||||
// We don't want to return *dest being equal to 'comp' if the CAS result was false
|
||||
uint32 oldVal = *dest;
|
||||
if (oldVal != comp)
|
||||
return oldVal;
|
||||
}
|
||||
}
|
||||
|
||||
inline uint64 InterlockedCompareExchange64(volatile int64* dest, int64 exch, int64 comp)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (OSAtomicCompareAndSwap64Barrier((int64)comp, (int64)exch, (volatile int64*)dest))
|
||||
return comp;
|
||||
// We don't want to return *dest being equal to 'comp' if the CAS result was false
|
||||
uint64 oldVal = *dest;
|
||||
if (oldVal != comp)
|
||||
return oldVal;
|
||||
}
|
||||
}
|
||||
|
||||
inline void* InterlockedCompareExchangePointer(void* volatile* dest, void* exch, void* comp)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
if (OSAtomicCompareAndSwapPtrBarrier(comp, exch, dest))
|
||||
return comp;
|
||||
// We don't want to return *dest being equal to 'comp' if the CAS result was false
|
||||
void* oldVal = *dest;
|
||||
if (oldVal != comp)
|
||||
return oldVal;
|
||||
}
|
||||
}
|
||||
|
||||
inline uint32 InterlockedExchange(volatile uint32* dest, uint32 val)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
uint32 oldVal = *dest;
|
||||
if (OSAtomicCompareAndSwap32Barrier((int32)oldVal, (int32)val, (volatile int32*)dest))
|
||||
return oldVal;
|
||||
}
|
||||
}
|
||||
|
||||
inline uint64 InterlockedExchange64(volatile int64* dest, int64 val)
|
||||
{
|
||||
while (true)
|
||||
{
|
||||
uint64 oldVal = *dest;
|
||||
if (OSAtomicCompareAndSwap64Barrier((int64)oldVal, (int64)val, (volatile int64*)dest))
|
||||
return oldVal;
|
||||
}
|
||||
}
|
||||
|
||||
inline uint32 InterlockedExchangeAdd(volatile uint32* dest, uint32 val)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
inline int32 InterlockedIncrement(volatile uint32* val)
|
||||
{
|
||||
return OSAtomicIncrement32Barrier((int32*)val);
|
||||
}
|
||||
|
||||
inline int64 InterlockedIncrement64(volatile int64* val)
|
||||
{
|
||||
return OSAtomicIncrement64Barrier(val);
|
||||
}
|
||||
|
||||
inline int32 InterlockedDecrement(volatile uint32* val)
|
||||
{
|
||||
return OSAtomicDecrement32Barrier((int32*)val);
|
||||
}
|
||||
|
||||
inline int64 InterlockedDecrement64(volatile int64* val)
|
||||
{
|
||||
return OSAtomicDecrement64Barrier(val);
|
||||
}
|
9
BeefySysLib/platform/darwin/PlatformApp.h
Normal file
9
BeefySysLib/platform/darwin/PlatformApp.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include "../sdl/SdlBFApp.h"
|
||||
|
||||
NS_BF_BEGIN;
|
||||
|
||||
typedef SdlBFApp PlatformBFApp;
|
||||
|
||||
NS_BF_END;
|
13
BeefySysLib/platform/ios/BFPlatform.cpp
Normal file
13
BeefySysLib/platform/ios/BFPlatform.cpp
Normal file
|
@ -0,0 +1,13 @@
|
|||
#include "Common.h"
|
||||
#include "BFPlatform.h"
|
||||
#include <CoreFoundation/CFByteOrder.h>
|
||||
#include <mach/mach_time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dlfcn.h>
|
||||
#include <wchar.h>
|
||||
#include <fcntl.h>
|
||||
#include <mach/clock.h>
|
||||
#include <mach/mach.h>
|
||||
#include <time.h>
|
||||
#include <dirent.h>
|
||||
|
60
BeefySysLib/platform/ios/BFPlatform.h
Normal file
60
BeefySysLib/platform/ios/BFPlatform.h
Normal file
|
@ -0,0 +1,60 @@
|
|||
#pragma once
|
||||
|
||||
#define BFSTDCALL
|
||||
|
||||
#include "../darwin/DarwinCommon.h"
|
||||
#include "TargetConditionals.h"
|
||||
|
||||
#ifndef __IPHONEOS__
|
||||
#define __IPHONEOS__
|
||||
#endif
|
||||
|
||||
#define BF_PLATFORM_IOS
|
||||
#define BF_PLATFORM_OPENGL_ES2
|
||||
#define BF_PLATFORM_FULLSCREEN
|
||||
|
||||
#if !TARGET_IPHONE_SIMULATOR
|
||||
#ifdef __LP64__
|
||||
#ifdef __I386__
|
||||
#define BF_PLATFORM_X64
|
||||
#else
|
||||
#define BF_PLATFORM_ARM64
|
||||
#endif
|
||||
#define BF64
|
||||
#else ////
|
||||
#ifdef __I386__
|
||||
#define BF_PLATFORM_I386
|
||||
#else
|
||||
#define BF_PLATFORM_ARM32
|
||||
#endif
|
||||
#define BF32
|
||||
#endif
|
||||
|
||||
#else
|
||||
|
||||
#ifdef __LP64__
|
||||
#define BF_PLATFORM_X64
|
||||
#define BF64
|
||||
#else ////
|
||||
#define BF_PLATFORM_I386
|
||||
#define BF32
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
#ifdef BFSYSLIB_DYNAMIC
|
||||
#define BF_EXPORT extern "C" __declspec(dllexport)
|
||||
#define BF_CALLTYPE
|
||||
#else
|
||||
#define BF_EXPORT extern "C"
|
||||
#define BF_CALLTYPE
|
||||
#endif
|
||||
|
||||
#ifdef BF_PLATFORM_ARM32
|
||||
#define BF_REGISTER_COUNT 15
|
||||
#elif defined BF32
|
||||
#define BF_REGISTER_COUNT 7
|
||||
#else
|
||||
#define BF_REGISTER_COUNT 15
|
||||
#endif
|
||||
|
13
BeefySysLib/platform/linux/BFPlatform.cpp
Normal file
13
BeefySysLib/platform/linux/BFPlatform.cpp
Normal file
|
@ -0,0 +1,13 @@
|
|||
#include "Common.h"
|
||||
#include "BFPlatform.h"
|
||||
//#include <CoreFoundation/CFByteOrder.h>
|
||||
//#include <mach/mach_time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dlfcn.h>
|
||||
#include <wchar.h>
|
||||
#include <fcntl.h>
|
||||
//#include <mach/clock.h>
|
||||
//#include <mach/mach.h>
|
||||
#include <time.h>
|
||||
#include <dirent.h>
|
||||
|
22
BeefySysLib/platform/linux/BFPlatform.h
Normal file
22
BeefySysLib/platform/linux/BFPlatform.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#define BFSTDCALL
|
||||
|
||||
#include "LinuxCommon.h"
|
||||
|
||||
#define BF_PLATFORM_LINUX
|
||||
|
||||
#define BF_IMPORT extern "C"
|
||||
|
||||
#ifdef BFSYSLIB_DYNAMIC
|
||||
#define BF_EXPORT extern "C"
|
||||
#define BF_CALLTYPE
|
||||
#else
|
||||
#define BF_EXPORT extern "C"
|
||||
#define BF_CALLTYPE
|
||||
#define BF_RESOURCES_REL_DIR "../Resources"
|
||||
#endif
|
||||
|
||||
#define BF_DEBUG_BREAK()
|
||||
|
||||
#include "../PlatformInterface.h"
|
2093
BeefySysLib/platform/linux/LinuxCommon.cpp
Normal file
2093
BeefySysLib/platform/linux/LinuxCommon.cpp
Normal file
File diff suppressed because it is too large
Load diff
208
BeefySysLib/platform/linux/LinuxCommon.h
Normal file
208
BeefySysLib/platform/linux/LinuxCommon.h
Normal file
|
@ -0,0 +1,208 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef __LP64__
|
||||
#define BF64
|
||||
#else
|
||||
#define BF32
|
||||
#endif
|
||||
|
||||
#define BOOST_DETAIL_NO_CONTAINER_FWD
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <pthread.h>
|
||||
#include <time.h>
|
||||
#include <assert.h>
|
||||
#include <sys/time.h>
|
||||
//#include <libkern/OSAtomic.h>
|
||||
#include <cstdlib>
|
||||
#include <unistd.h>
|
||||
#include <wchar.h>
|
||||
#include <math.h>
|
||||
#include <stdarg.h>
|
||||
#include <string.h>
|
||||
#include <pthread.h>
|
||||
#include <wctype.h>
|
||||
#include <stddef.h>
|
||||
|
||||
//#define offsetof(type, member) __builtin_offsetof (type, member)
|
||||
|
||||
extern "C"
|
||||
{
|
||||
//#define FFI_BUILDING
|
||||
//#include "third_party/libffi/x86_64-apple-darwin12.5.0/include/ffi.h"
|
||||
}
|
||||
|
||||
#define BF_ENDIAN_LITTLE
|
||||
|
||||
#define _NOEXCEPT noexcept
|
||||
#define NTAPI
|
||||
|
||||
#define FFI_STDCALL FFI_DEFAULT_ABI
|
||||
#define FFI_THISCALL FFI_DEFAULT_ABI
|
||||
#define FFI_FASTCALL FFI_DEFAULT_ABI
|
||||
|
||||
#define INVALID_SOCKET -1
|
||||
|
||||
typedef uint64_t uint64;
|
||||
typedef uint32_t uint32;
|
||||
typedef uint16_t uint16;
|
||||
typedef uint8_t uint8;
|
||||
typedef int64_t int64;
|
||||
typedef int32_t int32;
|
||||
typedef int16_t int16;
|
||||
typedef int8_t int8;
|
||||
typedef unsigned int uint;
|
||||
|
||||
#define BF_PLATFORM_LINUX
|
||||
#define BF_PLATFORM_NAME "BF_PLATFORM_LINUX"
|
||||
//#define BF_PLATFORM_SDL
|
||||
|
||||
#define NOP
|
||||
//#define BF_NOTHROW throw ()
|
||||
//#define BF_NOTHROW noexcept
|
||||
#define BF_NOTHROW
|
||||
|
||||
#ifdef BF64
|
||||
typedef int64 intptr;
|
||||
typedef uint64 uintptr;
|
||||
#else
|
||||
typedef int32 intptr;
|
||||
typedef uint32 uintptr;
|
||||
#endif
|
||||
|
||||
typedef wchar_t* BSTR;
|
||||
typedef int HRESULT;
|
||||
typedef uint8 BYTE;
|
||||
typedef uint16 WORD;
|
||||
typedef uint32 DWORD;
|
||||
typedef int32 LONG;
|
||||
|
||||
typedef pthread_key_t BFTlsKey;
|
||||
typedef pthread_t BF_THREADID;
|
||||
typedef pthread_t BF_THREADHANDLE;
|
||||
#define BF_TLS_DECLSPEC thread_local
|
||||
|
||||
//:int64 abs(int64 val);
|
||||
|
||||
#define _stricmp stricmp
|
||||
#define strnicmp strncasecmp
|
||||
|
||||
struct IID
|
||||
{
|
||||
unsigned long Data1;
|
||||
unsigned short Data2;
|
||||
unsigned short Data3;
|
||||
unsigned char Data4[ 8 ];
|
||||
};
|
||||
|
||||
typedef void* HANDLE;
|
||||
typedef void* HMODULE;
|
||||
|
||||
// We only need the stdcall attribute for x32?
|
||||
//#define BFSTDCALL __attribute__((stdcall))
|
||||
|
||||
//#include "../notwin/NotWin.h"
|
||||
|
||||
#ifdef DEBUG
|
||||
#define _DEBUG
|
||||
#endif
|
||||
|
||||
#define NOT_IMPL throw "Unimplemented";
|
||||
|
||||
//ARM
|
||||
|
||||
#if defined(__x86_64__) || defined(__i386__)
|
||||
#define BF_FULL_MEMORY_FENCE() __asm__ __volatile__("mfence": : :"memory")
|
||||
#define BF_SPINWAIT_NOP() __asm__ volatile ("pause\n" : : : "memory" );
|
||||
#else
|
||||
#define BF_FULL_MEMORY_FENCE() __sync_synchronize()
|
||||
#define BF_SPINWAIT_NOP() ((void) 0)
|
||||
#endif
|
||||
|
||||
#define BF_COMPILER_FENCE() __asm__ __volatile__("": : :"memory")
|
||||
#define BF_THREAD_YIELD() sched_yield()
|
||||
|
||||
#if defined _DEBUG || defined BF_DEBUG_ASSERTS
|
||||
#define BF_ASSERT(_Expression) (void)( (!!(_Expression)) || (Beefy::BFFatalError(#_Expression, __FILE__, __LINE__), 0) )
|
||||
#else
|
||||
#define BF_ASSERT(_Expression) (void)(0)
|
||||
#endif
|
||||
|
||||
#define BF_ASSERT_REL(_Expression) (void)( (!!(_Expression)) || (Beefy::BFFatalError(#_Expression, __FILE__, __LINE__), 0) )
|
||||
#define BF_FATAL(msg) (void) ((Beefy::BFFatalError(msg, __FILE__, __LINE__), 0) )
|
||||
|
||||
#if defined _DEBUG || defined BF_DEBUG_ASSERTS
|
||||
#define BF_DBG_FATAL(msg) (void) ((Beefy::BFFatalError(msg, __FILE__, __LINE__), 0) )
|
||||
#else
|
||||
#define BF_DBG_FATAL(msg)
|
||||
#endif
|
||||
|
||||
#define BF_NOINLINE __attribute__ ((noinline))
|
||||
#define BF_NAKED
|
||||
|
||||
#define stricmp strcasecmp
|
||||
#define _alloca alloca
|
||||
|
||||
#define DIR_SEP_CHAR '/'
|
||||
#define DIR_SEP_CHAR_ALT '\\'
|
||||
|
||||
static char* itoa(int value, char* str, int base)
|
||||
{
|
||||
if (base == 16)
|
||||
sprintf(str, "%X", value);
|
||||
else
|
||||
sprintf(str, "%d", value);
|
||||
return str;
|
||||
}
|
||||
|
||||
inline uint32 InterlockedCompareExchange(volatile uint32* dest, uint32 exch, uint32 comp)
|
||||
{
|
||||
return __sync_val_compare_and_swap(dest, comp, exch);
|
||||
}
|
||||
|
||||
inline uint64 InterlockedCompareExchange64(volatile int64* dest, int64 exch, int64 comp)
|
||||
{
|
||||
return __sync_val_compare_and_swap(dest, comp, exch);
|
||||
}
|
||||
|
||||
inline void* InterlockedCompareExchangePointer(void* volatile* dest, void* exch, void* comp)
|
||||
{
|
||||
return __sync_val_compare_and_swap(dest, comp, exch);
|
||||
}
|
||||
|
||||
inline uint32 InterlockedExchange(volatile uint32* dest, uint32 val)
|
||||
{
|
||||
return __sync_lock_test_and_set(dest, val);
|
||||
}
|
||||
|
||||
inline uint64 InterlockedExchange64(volatile int64* dest, int64 val)
|
||||
{
|
||||
return __sync_lock_test_and_set(dest, val);
|
||||
}
|
||||
|
||||
inline uint32 InterlockedExchangeAdd(volatile uint32* dest, uint32 val)
|
||||
{
|
||||
return __sync_add_and_fetch(dest, val);
|
||||
}
|
||||
|
||||
inline int32 InterlockedIncrement(volatile uint32* val)
|
||||
{
|
||||
return __sync_add_and_fetch(val, 1);
|
||||
}
|
||||
|
||||
inline int64 InterlockedIncrement64(volatile int64* val)
|
||||
{
|
||||
return __sync_add_and_fetch(val, 1);
|
||||
}
|
||||
|
||||
inline int32 InterlockedDecrement(volatile uint32* val)
|
||||
{
|
||||
return __sync_add_and_fetch(val, -1);
|
||||
}
|
||||
|
||||
inline int64 InterlockedDecrement64(volatile int64* val)
|
||||
{
|
||||
return __sync_add_and_fetch(val, -1);
|
||||
}
|
9
BeefySysLib/platform/linux/PlatformApp.h
Normal file
9
BeefySysLib/platform/linux/PlatformApp.h
Normal file
|
@ -0,0 +1,9 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../HeadlessApp.h"
|
||||
|
||||
NS_BF_BEGIN;
|
||||
|
||||
typedef HeadlessApp PlatformBFApp;
|
||||
|
||||
NS_BF_END;
|
305
BeefySysLib/platform/notwin/NotWin.h
Normal file
305
BeefySysLib/platform/notwin/NotWin.h
Normal file
|
@ -0,0 +1,305 @@
|
|||
|
||||
void OutputDebugStringA(const char* str);
|
||||
void OutputDebugStringW(const wchar_t* str);
|
||||
|
||||
void* BFTlsGetValue(BFTlsKey tlsKey);
|
||||
bool BFTlsSetValue(BFTlsKey tlsKey, void* tlsValue);
|
||||
BFTlsKey BFTlsAlloc();
|
||||
bool BFTlsFree(BFTlsKey tlsKey);
|
||||
|
||||
enum GET_FILEEX_INFO_LEVELS
|
||||
{
|
||||
GetFileExInfoStandard,
|
||||
GetFileExMaxInfoLevel
|
||||
};
|
||||
|
||||
typedef bool BOOL;
|
||||
|
||||
#define MAX_PATH 4096
|
||||
#define BF_UNUSED __unused
|
||||
#define BF_ENDIAN_LITTLE
|
||||
#define INFINITE -1
|
||||
|
||||
#define CF_TEXT 0
|
||||
|
||||
#define ERROR_SUCCESS 0
|
||||
#define ERROR_FILE_NOT_FOUND 2L
|
||||
#define ERROR_NO_MORE_FILES 18L
|
||||
#define ERROR_SHARING_VIOLATION 32L
|
||||
#define ERROR_INVALID_NAME 123L
|
||||
#define ERROR_ALREADY_EXISTS 183L
|
||||
|
||||
#define INVALID_HANDLE_VALUE ((HANDLE)(intptr)-1)
|
||||
#define INVALID_FILE_ATTRIBUTES (uint32)-1
|
||||
#define INVALID_SET_FILE_POINTER -1
|
||||
#define INVALID_FILE_SIZE -1
|
||||
|
||||
#define NOERROR 0
|
||||
#define E_NOINTERFACE (HRESULT)0x80004002L
|
||||
#define E_FAIL (HRESULT)0x80004005L
|
||||
|
||||
#define FILE_BEGIN 0
|
||||
#define FILE_CURRENT 1
|
||||
#define FILE_END 2
|
||||
|
||||
#define GENERIC_READ (0x80000000L)
|
||||
#define GENERIC_WRITE (0x40000000L)
|
||||
#define GENERIC_EXECUTE (0x20000000L)
|
||||
#define GENERIC_ALL (0x10000000L)
|
||||
|
||||
#define FILE_SHARE_READ 0x00000001
|
||||
#define FILE_SHARE_WRITE 0x00000002
|
||||
#define FILE_SHARE_DELETE 0x00000004
|
||||
|
||||
#define CREATE_NEW 1
|
||||
#define CREATE_ALWAYS 2
|
||||
#define OPEN_EXISTING 3
|
||||
#define OPEN_ALWAYS 4
|
||||
#define TRUNCATE_EXISTING 5
|
||||
|
||||
#define STD_INPUT_HANDLE -10
|
||||
#define STD_OUTPUT_HANDLE -11
|
||||
#define STD_ERROR_HANDLE -12
|
||||
|
||||
#define FILE_ATTRIBUTE_READONLY 0x00000001
|
||||
#define FILE_ATTRIBUTE_HIDDEN 0x00000002
|
||||
#define FILE_ATTRIBUTE_SYSTEM 0x00000004
|
||||
#define FILE_ATTRIBUTE_DIRECTORY 0x00000010
|
||||
#define FILE_ATTRIBUTE_ARCHIVE 0x00000020
|
||||
#define FILE_ATTRIBUTE_DEVICE 0x00000040
|
||||
#define FILE_ATTRIBUTE_NORMAL 0x00000080
|
||||
#define FILE_ATTRIBUTE_TEMPORARY 0x00000100
|
||||
#define FILE_ATTRIBUTE_SPARSE_FILE 0x00000200
|
||||
#define FILE_ATTRIBUTE_REPARSE_POINT 0x00000400
|
||||
#define FILE_ATTRIBUTE_COMPRESSED 0x00000800
|
||||
#define FILE_ATTRIBUTE_OFFLINE 0x00001000
|
||||
#define FILE_ATTRIBUTE_NOT_CONTENT_INDEXED 0x00002000
|
||||
#define FILE_ATTRIBUTE_ENCRYPTED 0x00004000
|
||||
#define FILE_ATTRIBUTE_INTEGRITY_STREAM 0x00008000
|
||||
#define FILE_ATTRIBUTE_VIRTUAL 0x00010000
|
||||
#define FILE_ATTRIBUTE_NO_SCRUB_DATA 0x00020000
|
||||
|
||||
#define FILE_FLAG_WRITE_THROUGH 0x80000000
|
||||
#define FILE_FLAG_OVERLAPPED 0x40000000
|
||||
#define FILE_FLAG_NO_BUFFERING 0x20000000
|
||||
#define FILE_FLAG_RANDOM_ACCESS 0x10000000
|
||||
#define FILE_FLAG_SEQUENTIAL_SCAN 0x08000000
|
||||
#define FILE_FLAG_DELETE_ON_CLOSE 0x04000000
|
||||
#define FILE_FLAG_BACKUP_SEMANTICS 0x02000000
|
||||
#define FILE_FLAG_POSIX_SEMANTICS 0x01000000
|
||||
#define FILE_FLAG_SESSION_AWARE 0x00800000
|
||||
#define FILE_FLAG_OPEN_REPARSE_POINT 0x00200000
|
||||
#define FILE_FLAG_OPEN_NO_RECALL 0x00100000
|
||||
#define FILE_FLAG_FIRST_PIPE_INSTANCE 0x00080000
|
||||
|
||||
#define REPLACEFILE_IGNORE_MERGE_ERRORS 0x00000002
|
||||
|
||||
#define FILE_TYPE_UNKNOWN 0x0000
|
||||
#define FILE_TYPE_DISK 0x0001
|
||||
#define FILE_TYPE_CHAR 0x0002
|
||||
#define FILE_TYPE_PIPE 0x0003
|
||||
#define FILE_TYPE_REMOTE 0x8000
|
||||
|
||||
#define FORMAT_MESSAGE_IGNORE_INSERTS 0x00000200
|
||||
#define FORMAT_MESSAGE_FROM_STRING 0x00000400
|
||||
#define FORMAT_MESSAGE_FROM_HMODULE 0x00000800
|
||||
#define FORMAT_MESSAGE_FROM_SYSTEM 0x00001000
|
||||
#define FORMAT_MESSAGE_ARGUMENT_ARRAY 0x00002000
|
||||
#define FORMAT_MESSAGE_MAX_WIDTH_MASK 0x000000FF
|
||||
|
||||
#define stricmp strcasecmp
|
||||
|
||||
#define TIME_ZONE_ID_UNKNOWN 0
|
||||
#define TIME_ZONE_ID_INVALID -1
|
||||
|
||||
struct SYSTEMTIME
|
||||
{
|
||||
uint16 wYear;
|
||||
uint16 wMonth;
|
||||
uint16 wDayOfWeek;
|
||||
uint16 wDay;
|
||||
uint16 wHour;
|
||||
uint16 wMinute;
|
||||
uint16 wSecond;
|
||||
uint16 wMilliseconds;
|
||||
};
|
||||
|
||||
struct TIME_ZONE_INFORMATION
|
||||
{
|
||||
int32 Bias;
|
||||
wchar_t StandardName[32];
|
||||
SYSTEMTIME StandardDate;
|
||||
int32 StandardBias;
|
||||
wchar_t DaylightName[32];
|
||||
SYSTEMTIME DaylightDate;
|
||||
int32 DaylightBias;
|
||||
};
|
||||
|
||||
extern int gBFPlatformLastError;
|
||||
|
||||
|
||||
typedef intptr (BFSTDCALL *BFLibProcAddr)();
|
||||
|
||||
struct FILETIME
|
||||
{
|
||||
uint32 dwLowDateTime;
|
||||
uint32 dwHighDateTime;
|
||||
};
|
||||
|
||||
struct WIN32_FIND_DATAW
|
||||
{
|
||||
uint32 dwFileAttributes;
|
||||
FILETIME ftCreationTime;
|
||||
FILETIME ftLastAccessTime;
|
||||
FILETIME ftLastWriteTime;
|
||||
uint32 nFileSizeHigh;
|
||||
uint32 nFileSizeLow;
|
||||
uint32 dwReserved0;
|
||||
uint32 dwReserved1;
|
||||
wchar_t cFileName[MAX_PATH];
|
||||
wchar_t cAlternateFileName[14];
|
||||
};
|
||||
|
||||
struct WIN32_FILE_ATTRIBUTE_DATA
|
||||
{
|
||||
uint32 dwFileAttributes;
|
||||
FILETIME ftCreationTime;
|
||||
FILETIME ftLastAccessTime;
|
||||
FILETIME ftLastWriteTime;
|
||||
uint32 nFileSizeHigh;
|
||||
uint32 nFileSizeLow;
|
||||
};
|
||||
|
||||
struct SECURITY_ATTRIBUTES
|
||||
{
|
||||
uint32 nLength;
|
||||
void* lpSecurityDescriptor;
|
||||
bool bInheritHandle;
|
||||
};
|
||||
|
||||
#define WAIT_OBJECT_0 0
|
||||
#define WAIT_TIMEOUT 0x102
|
||||
|
||||
struct OVERLAPPED
|
||||
{
|
||||
|
||||
};
|
||||
|
||||
struct MODULEINFO
|
||||
{
|
||||
void* lpBaseOfDll;
|
||||
DWORD SizeOfImage;
|
||||
void* EntryPoint;
|
||||
};
|
||||
|
||||
struct ULARGE_INTEGER
|
||||
{
|
||||
uint64 QuadPart;
|
||||
};
|
||||
|
||||
struct LARGE_INTEGER
|
||||
{
|
||||
int64 QuadPart;
|
||||
};
|
||||
|
||||
#define DIR_SEP_CHAR '/'
|
||||
#define DIR_SEP_CHAR_ALT '\\'
|
||||
|
||||
#define PROCESS_ALL_ACCESS 0xFFFF
|
||||
#define THREAD_ALL_ACCESS 0xFFFF
|
||||
|
||||
#define THREAD_PRIORITY_BELOW_NORMAL -1
|
||||
#define THREAD_PRIORITY_NORMAL 0
|
||||
#define THREAD_PRIORITY_ABOVE_NORMAL 1
|
||||
|
||||
HANDLE GetModuleHandle(HANDLE h);
|
||||
uint32 GetModuleFileNameW(uint32 hModule, wchar_t* lpFilename, uint32 length);
|
||||
uint32 GetModuleFileNameA(uint32 hModule, char* lpFilename, uint32 length);
|
||||
HMODULE LoadLibraryA(const char* fileName);
|
||||
void FreeLibrary(HMODULE lib);
|
||||
bool CreateDirectoryW(const wchar_t* str, void* securityAttributes);
|
||||
bool RemoveDirectoryW(const wchar_t* str);
|
||||
int GetLastError();
|
||||
BFLibProcAddr GetProcAddress(HMODULE mod, const char* name);
|
||||
int* GetStdHandle(int32 handleId);
|
||||
BF_THREADID GetCurrentThreadId();
|
||||
HANDLE GetCurrentThread();
|
||||
bool SetThreadPriority(HANDLE hThread, int nPriority);
|
||||
int GetThreadPriority(HANDLE hThread);
|
||||
HANDLE OpenThread(int desiredAccess, bool inheritHandle, BF_THREADID threadId);
|
||||
typedef uint32 (BFSTDCALL *LPTHREAD_START_ROUTINE)(void* param);
|
||||
void* CreateThread(void* threadAttributes, int32 stackSize, LPTHREAD_START_ROUTINE threadStartProc, void* param, uint32 flags, BF_THREADID* threadId);
|
||||
uint32 ResumeThread(HANDLE thread);
|
||||
uint32 SuspendThread(HANDLE thread);
|
||||
void Sleep(int32 ms);
|
||||
HANDLE FindFirstFileW(const wchar_t* lpFileName, WIN32_FIND_DATAW* lpFindFileData);
|
||||
bool FindNextFileW(HANDLE hFindFile, WIN32_FIND_DATAW* lpFindFileData);
|
||||
bool FindClose(HANDLE hFindFile);
|
||||
uint32 GetCurrentDirectoryW(uint32 nBufferLength, const wchar_t* lpBuffer);
|
||||
bool SetCurrentDirectoryW(wchar_t* lpBuffer);
|
||||
bool CopyFileW(const wchar_t* lpExistingFileName, const wchar_t* lpNewFileName, bool allowOverwrite);
|
||||
bool MoveFileW(const wchar_t* lpExistingFileName, const wchar_t* lpNewFileName);
|
||||
bool DeleteFileW(const wchar_t* lpFileName);
|
||||
bool ReplaceFileW(const wchar_t* lpReplacedFileName, const wchar_t* lpReplacementFileName, const wchar_t* lpBackupFileName, uint32 dwReplaceFlags, void* lpExclude, void* lpReserved);
|
||||
bool SetFileAttributesW(const wchar_t* lpFileName, uint32 dwFileAttributes);
|
||||
int32 GetFileType(HANDLE fileHandle);
|
||||
bool GetFileAttributesExW(const wchar_t* lpFileName, GET_FILEEX_INFO_LEVELS fInfoLevelId, void* lpFileInformation);
|
||||
HANDLE CreateFileW(const wchar_t* lpFileName, uint32 dwDesiredAccess, uint32 dwShareMode, SECURITY_ATTRIBUTES* lpSecurityAttributes, uint32 dwCreationDisposition, uint32 dwFlagsAndAttributes, HANDLE hTemplateFile);
|
||||
bool CreatePipe(HANDLE* hReadPipe, HANDLE* hWritePipe, SECURITY_ATTRIBUTES* lpPipeAttributes, uint32 nSize);
|
||||
bool WriteFile(HANDLE hFile, void* lpBuffer, uint32 nNumberOfBytesToWrite, uint32* lpNumberOfBytesWritten, OVERLAPPED* lpOverlapped);
|
||||
bool ReadFile(HANDLE hFile, void* lpBuffer, uint32 nNumberOfBytesToRead, uint32* lpNumberOfBytesRead, OVERLAPPED* lpOverlapped);
|
||||
bool CloseHandle_File(HANDLE handle);
|
||||
bool SetEvent(HANDLE handle);
|
||||
bool ResetEvent(HANDLE handle);
|
||||
int WaitForSingleObject(HANDLE obj, int waitMs);
|
||||
int WaitForSingleObject_Thread(HANDLE obj, int waitMs);
|
||||
bool CloseHandle_Event(HANDLE handle);
|
||||
bool FlushFileBuffers(HANDLE handle);
|
||||
int32 SetFilePointer(HANDLE handle, int32 distanceToMove, int32* distanceToMoveHigh, uint32 moveMethod);
|
||||
int32 GetFileSize(HANDLE hFile, uint32* fileSizeHigh);
|
||||
bool GetFileSizeEx(HANDLE hFile, LARGE_INTEGER* lpFileSize);
|
||||
bool SetEndOfFile(HANDLE hFile);
|
||||
bool SetFilePointerEx(HANDLE hFile, LARGE_INTEGER liDistanceToMove, LARGE_INTEGER* lpNewFilePointer, DWORD dwMoveMethod);
|
||||
bool SetFileTime(HANDLE hFile, const FILETIME* lpCreationTime, const FILETIME* lpLastAccessTime, const FILETIME* lpLastWriteTime);
|
||||
bool LockFile(HANDLE hFile, uint32 dwFileOffsetLow, uint32 dwFileOffsetHigh, uint32 nNumberOfBytesToLockLow, uint32 nNumberOfBytesToLockHigh);
|
||||
bool UnlockFile(HANDLE hFile, uint32 dwFileOffsetLow, uint32 dwFileOffsetHigh, uint32 nNumberOfBytesToUnlockLow, uint32 nNumberOfBytesToUnlockHigh);
|
||||
bool DuplicateHandle(HANDLE hSourceProcessHandle, HANDLE hSourceHandle, HANDLE hTargetProcessHandle, HANDLE* lpTargetHandle, uint32 dwDesiredAccess, bool bInheritHandle, uint32 dwOptions);
|
||||
int32 GetTempPath(int32 bufferLen, wchar_t* str);
|
||||
HANDLE CreateEventW(SECURITY_ATTRIBUTES* lpEventAttributes, bool bManualReset, bool bInitialState, wchar_t* lpName);
|
||||
HANDLE OpenEventW(uint32 dwDesiredAccess, bool bInheritHandle, wchar_t* lpName);
|
||||
HANDLE CreateMutexW(SECURITY_ATTRIBUTES* lpMutexAttributes, bool bInitialOwner, wchar_t* lpName);
|
||||
HANDLE OpenMutexW(uint32 dwDesiredAccess, bool bInheritHandle, wchar_t* lpName);
|
||||
bool ReleaseMutex(HANDLE mutex);
|
||||
uint32 FormatMessageW(uint32 dwFlags, void* lpSource, uint32 dwMessageId, uint32 dwLanguageId, wchar_t* lpBuffer, uint32 nSize, va_list* Arguments);
|
||||
int32 WSAGetLastError();
|
||||
bool CloseHandle_Thread(HANDLE handle);
|
||||
bool CloseHandle_Process(HANDLE handle);
|
||||
void GetExitCodeProcess(HANDLE handle, DWORD* code);
|
||||
bool GetProcessTimes(HANDLE handle, FILETIME* createTime, FILETIME* exitTime, FILETIME* kernelTime, FILETIME* userTime);
|
||||
bool GetProcessWorkingSetSize(HANDLE handle, size_t* curMin, size_t* curMax);
|
||||
bool SetProcessWorkingSetSize(HANDLE handle, size_t curMin, size_t curMax);
|
||||
bool EnumProcessModules(HANDLE handle, HMODULE* mods, DWORD cb, DWORD* needed);
|
||||
bool GetModuleBaseNameW(HANDLE handle, HMODULE mod, wchar_t* modname, int maxLen);
|
||||
bool GetModuleFileNameExW(HANDLE handle, HMODULE mod, wchar_t* modname, int maxLen);
|
||||
bool GetModuleInformation(HANDLE handle, HMODULE mod, MODULEINFO* modinfo, int modInfoSize);
|
||||
int GetPriorityClass(HANDLE handle);
|
||||
bool SetPriorityClass(HANDLE handle, int priClass);
|
||||
bool TerminateProcess(HANDLE handle, int termCode);
|
||||
bool WaitForInputIdle(HANDLE handle, int ms);
|
||||
int32 GetCurrentProcessId();
|
||||
HANDLE GetCurrentProcess();
|
||||
HANDLE OpenProcess(DWORD desiredAccess, bool inheritHandle, DWORD pid);
|
||||
bool GetDiskFreeSpaceExW(wchar_t* pathNameStr, ULARGE_INTEGER* wapi_free_bytes_avail, ULARGE_INTEGER* wapi_total_number_of_bytes, ULARGE_INTEGER* wapi_total_number_of_free_bytes);
|
||||
uint32 GetDriveTypeW(wchar_t* driveName);
|
||||
bool GetVolumeInformationW(wchar_t* lpRootPathName, wchar_t* lpVolumeNameBuffer, uint32 nVolumeNameSize, uint32* lpVolumeSerialNumber, uint32* lpMaximumComponentLength, uint32* lpFileSystemFlags, wchar_t* lpFileSystemNameBuffer, uint32 nFileSystemNameSize);
|
||||
uint64 BFClockGetTime();
|
||||
DWORD GetTimeZoneInformation(TIME_ZONE_INFORMATION* lpTimeZoneInformation);
|
||||
bool SystemTimeToFileTime(const SYSTEMTIME* lpSystemTime, FILETIME* lpFileTime);
|
||||
void BFGetThreadRegisters(HANDLE threadHandle, intptr* stackPtr, intptr* dataPtr);
|
||||
void mkdir(const char* path);
|
||||
|
||||
typedef void (*PFLS_CALLBACK_FUNCTION)(void* lpFlsData);
|
||||
DWORD FlsAlloc(PFLS_CALLBACK_FUNCTION lpCallback);
|
||||
void* FlsGetValue(DWORD dwFlsIndex);
|
||||
BOOL FlsSetValue(DWORD dwFlsIndex, void* lpFlsData);
|
||||
BOOL FlsFree(DWORD dwFlsIndex);
|
13
BeefySysLib/platform/osx/BFPlatform.cpp
Normal file
13
BeefySysLib/platform/osx/BFPlatform.cpp
Normal file
|
@ -0,0 +1,13 @@
|
|||
#include "Common.h"
|
||||
#include "BFPlatform.h"
|
||||
#include <CoreFoundation/CFByteOrder.h>
|
||||
#include <mach/mach_time.h>
|
||||
#include <sys/stat.h>
|
||||
#include <dlfcn.h>
|
||||
#include <wchar.h>
|
||||
#include <fcntl.h>
|
||||
#include <mach/clock.h>
|
||||
#include <mach/mach.h>
|
||||
#include <time.h>
|
||||
#include <dirent.h>
|
||||
|
23
BeefySysLib/platform/osx/BFPlatform.h
Normal file
23
BeefySysLib/platform/osx/BFPlatform.h
Normal file
|
@ -0,0 +1,23 @@
|
|||
#pragma once
|
||||
|
||||
#define BFSTDCALL __stdcall
|
||||
|
||||
#include "../darwin/DarwinCommon.h"
|
||||
|
||||
#define BF_PLATFORM_OSX
|
||||
|
||||
#ifdef BFSYSLIB_DYNAMIC
|
||||
#define BF_EXPORT extern "C" __declspec(dllexport)
|
||||
#define BF_CALLTYPE
|
||||
#else
|
||||
#define BF_EXPORT extern "C"
|
||||
#define BF_CALLTYPE
|
||||
#define BF_RESOURCES_REL_DIR "../Resources"
|
||||
#endif
|
||||
|
||||
#ifdef BF32
|
||||
#define BF_REGISTER_COUNT 7
|
||||
#else
|
||||
#define BF_REGISTER_COUNT 15
|
||||
#endif
|
||||
|
1124
BeefySysLib/platform/sdl/GLRenderDevice.cpp
Normal file
1124
BeefySysLib/platform/sdl/GLRenderDevice.cpp
Normal file
File diff suppressed because it is too large
Load diff
171
BeefySysLib/platform/sdl/GLRenderDevice.h
Normal file
171
BeefySysLib/platform/sdl/GLRenderDevice.h
Normal file
|
@ -0,0 +1,171 @@
|
|||
#pragma once
|
||||
|
||||
#include "Common.h"
|
||||
|
||||
#ifdef BF_PLATFORM_OPENGL_ES2
|
||||
#include "SDL_opengles2.h"
|
||||
#else
|
||||
#include "SDL_opengl.h"
|
||||
#endif
|
||||
|
||||
#include "gfx/Shader.h"
|
||||
#include "gfx/Texture.h"
|
||||
#include "gfx/RenderDevice.h"
|
||||
#include "gfx/DrawLayer.h"
|
||||
|
||||
struct SDL_Window;
|
||||
|
||||
NS_BF_BEGIN;
|
||||
|
||||
class BFApp;
|
||||
class GLRenderDevice;
|
||||
|
||||
class GLTexture : public Texture
|
||||
{
|
||||
public:
|
||||
GLRenderDevice* mRenderDevice;
|
||||
GLuint mGLTexture;
|
||||
GLuint mGLTexture2;
|
||||
//IGL10RenderTargetView* mGLRenderTargetView;
|
||||
|
||||
public:
|
||||
GLTexture();
|
||||
~GLTexture();
|
||||
|
||||
virtual void PhysSetAsTarget();
|
||||
};
|
||||
|
||||
class GLShaderParam : public ShaderParam
|
||||
{
|
||||
public:
|
||||
GLint mGLVariable;
|
||||
|
||||
public:
|
||||
GLShaderParam();
|
||||
~GLShaderParam();
|
||||
|
||||
virtual void SetTexture(Texture* texture);
|
||||
virtual void SetFloat4(float x, float y, float z, float w) override;
|
||||
};
|
||||
|
||||
typedef std::map<String, GLShaderParam*> GLShaderParamMap;
|
||||
|
||||
class GLShader : public Shader
|
||||
{
|
||||
public:
|
||||
//IGL10Effect* mGLEffect;
|
||||
|
||||
GLuint mGLVertexShader;
|
||||
GLuint mGLFragmentShader;
|
||||
GLuint mGLProgram;
|
||||
GLint mAttribPosition;
|
||||
GLint mAttribTexCoord0;
|
||||
GLint mAttribColor;
|
||||
GLint mAttribTex0;
|
||||
GLint mAttribTex1;
|
||||
|
||||
GLShaderParamMap mParamsMap;
|
||||
|
||||
public:
|
||||
GLShader();
|
||||
~GLShader();
|
||||
|
||||
virtual ShaderParam* GetShaderParam(const StringImpl& name) override;
|
||||
};
|
||||
|
||||
class GLDrawBatch : public DrawBatch
|
||||
{
|
||||
public:
|
||||
//IGL10Buffer* mGLBuffer;
|
||||
|
||||
public:
|
||||
GLDrawBatch(int minVtxSize = 0, int minIdxSize = 0);
|
||||
~GLDrawBatch();
|
||||
|
||||
virtual void Lock();
|
||||
virtual void Draw();
|
||||
};
|
||||
|
||||
class GLDrawLayer : public DrawLayer
|
||||
{
|
||||
public:
|
||||
virtual DrawBatch* CreateDrawBatch();
|
||||
virtual DrawBatch* AllocateBatch(int minVtxCount, int minIdxCount) override;
|
||||
virtual void FreeBatch(DrawBatch* drawBatch) override;
|
||||
|
||||
public:
|
||||
GLDrawLayer();
|
||||
~GLDrawLayer();
|
||||
};
|
||||
|
||||
class GLRenderWindow : public RenderWindow
|
||||
{
|
||||
public:
|
||||
SDL_Window* mSDLWindow;
|
||||
GLRenderDevice* mRenderDevice;
|
||||
//IGLGISwapChain* mGLSwapChain;
|
||||
//IGL10Texture2D* mGLBackBuffer;
|
||||
//IGL10RenderTargetView* mGLRenderTargetView;
|
||||
bool mResizePending;
|
||||
int mPendingWidth;
|
||||
int mPendingHeight;
|
||||
|
||||
public:
|
||||
virtual void PhysSetAsTarget();
|
||||
|
||||
public:
|
||||
GLRenderWindow(GLRenderDevice* renderDevice, SDL_Window* sdlWindow);
|
||||
~GLRenderWindow();
|
||||
|
||||
void SetAsTarget() override;
|
||||
void Resized() override;
|
||||
virtual void Present() override;
|
||||
|
||||
void CopyBitsTo(uint32* dest, int width, int height);
|
||||
};
|
||||
|
||||
typedef std::vector<GLDrawBatch*> GLDrawBatchVector;
|
||||
|
||||
class GLRenderDevice : public RenderDevice
|
||||
{
|
||||
public:
|
||||
//IGLGIFactory* mGLGIFactory;
|
||||
//IGL10Device* mGLDevice;
|
||||
//IGL10BlendState* mGLNormalBlendState;
|
||||
//IGL10BlendState* mGLAdditiveBlendState;
|
||||
//IGL10RasterizerState* mGLRasterizerStateClipped;
|
||||
//IGL10RasterizerState* mGLRasterizerStateUnclipped;
|
||||
|
||||
GLuint mGLVertexBuffer;
|
||||
GLuint mGLIndexBuffer;
|
||||
GLuint mBlankTexture;
|
||||
|
||||
bool mHasVSync;
|
||||
|
||||
GLDrawBatchVector mDrawBatchPool;
|
||||
GLDrawBatch* mFreeBatchHead;
|
||||
|
||||
public:
|
||||
virtual void PhysSetAdditive(bool additive);
|
||||
virtual void PhysSetShader(Shader* shaderPass);
|
||||
virtual void PhysSetRenderWindow(RenderWindow* renderWindow);
|
||||
virtual void PhysSetRenderTarget(Texture* renderTarget);
|
||||
|
||||
public:
|
||||
GLRenderDevice();
|
||||
virtual ~GLRenderDevice();
|
||||
bool Init(BFApp* app) override;
|
||||
|
||||
void FrameStart() override;
|
||||
void FrameEnd() override;
|
||||
|
||||
Texture* LoadTexture(ImageData* imageData, bool additive) override;
|
||||
Shader* LoadShader(const StringImpl& fileName) override;
|
||||
Texture* CreateRenderTarget(int width, int height, bool destAlpha) override;
|
||||
|
||||
void SetShader(Shader* shader) override;
|
||||
virtual void SetClip(float x, float y, float width, float height) override;
|
||||
virtual void DisableClip() override;
|
||||
};
|
||||
|
||||
NS_BF_END;
|
713
BeefySysLib/platform/sdl/SdlBFApp.cpp
Normal file
713
BeefySysLib/platform/sdl/SdlBFApp.cpp
Normal file
|
@ -0,0 +1,713 @@
|
|||
#include "SdlBFApp.h"
|
||||
#include "GLRenderDevice.h"
|
||||
#include "SDL.h"
|
||||
|
||||
USING_NS_BF;
|
||||
|
||||
///
|
||||
|
||||
#pragma comment(lib, "imm32.lib")
|
||||
#pragma comment(lib, "version.lib")
|
||||
|
||||
SdlBFWindow::SdlBFWindow(BFWindow* parent, const StringImpl& title, int x, int y, int width, int height, int windowFlags)
|
||||
{
|
||||
int sdlWindowFlags = 0;
|
||||
if (windowFlags & BFWINDOW_RESIZABLE)
|
||||
sdlWindowFlags |= SDL_WINDOW_RESIZABLE;
|
||||
sdlWindowFlags |= SDL_WINDOW_OPENGL;
|
||||
|
||||
#ifdef BF_PLATFORM_FULLSCREEN
|
||||
sdlWindowFlags |= SDL_WINDOW_FULLSCREEN;
|
||||
#endif
|
||||
|
||||
mSDLWindow = SDL_CreateWindow(title.c_str(), x, y, width, height, sdlWindowFlags);
|
||||
|
||||
if (!SDL_GL_CreateContext(mSDLWindow))
|
||||
{
|
||||
BF_FATAL(StrFormat("Unable to create OpenGL context: %s", SDL_GetError()).c_str());
|
||||
SDL_Quit();
|
||||
exit(2);
|
||||
}
|
||||
|
||||
glEnable(GL_BLEND);
|
||||
//glBlendFunc(GL_SRC_ALPHA, GL_ONE);
|
||||
glBlendFunc(GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
|
||||
//glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
|
||||
|
||||
#ifndef BF_PLATFORM_OPENGL_ES2
|
||||
glEnableClientState(GL_INDEX_ARRAY);
|
||||
#endif
|
||||
|
||||
//glEnableClientState(GL_VERTEX_ARRAY);
|
||||
//glEnableClientState(GL_TEXTURE_COORD_ARRAY);
|
||||
//glEnableClientState(GL_COLOR_ARRAY);
|
||||
|
||||
mIsMouseInside = false;
|
||||
mRenderWindow = new GLRenderWindow((GLRenderDevice*)gBFApp->mRenderDevice, mSDLWindow);
|
||||
mRenderWindow->mWindow = this;
|
||||
gBFApp->mRenderDevice->AddRenderWindow(mRenderWindow);
|
||||
|
||||
if (parent != NULL)
|
||||
parent->mChildren.push_back(this);
|
||||
}
|
||||
|
||||
SdlBFWindow::~SdlBFWindow()
|
||||
{
|
||||
if (mSDLWindow != NULL)
|
||||
TryClose();
|
||||
}
|
||||
|
||||
bool SdlBFWindow::TryClose()
|
||||
{
|
||||
SdlBFApp* app = (SdlBFApp*)gBFApp;
|
||||
SdlWindowMap::iterator itr = app->mSdlWindowMap.find(SDL_GetWindowID(mSDLWindow));
|
||||
app->mSdlWindowMap.erase(itr);
|
||||
|
||||
SDL_DestroyWindow(mSDLWindow);
|
||||
mSDLWindow = NULL;
|
||||
return true;
|
||||
}
|
||||
|
||||
//LRESULT SdlBFWindow::WindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam)
|
||||
//{
|
||||
// SdlBFApp* app = (SdlBFApp*) gBFApp;
|
||||
//
|
||||
// switch (Msg)
|
||||
// {
|
||||
// case WM_CLOSE:
|
||||
// {
|
||||
// if (mCloseQueryFunc(this) != 0)
|
||||
// gBFApp->RemoveWindow(this);
|
||||
// return 0;
|
||||
// }
|
||||
// break;
|
||||
// case WM_DESTROY:
|
||||
// /*if (mFlags & BFWINDOW_QUIT_ON_CLOSE)
|
||||
// {
|
||||
// gBFApp->mRunning = false;
|
||||
// }*/
|
||||
// mHWnd = NULL;
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// LRESULT result = 0;
|
||||
// bool doResult = false;
|
||||
//
|
||||
// if (!app->mInMsgProc)
|
||||
// {
|
||||
// app->mInMsgProc = true;
|
||||
//
|
||||
// switch (Msg)
|
||||
// {
|
||||
//
|
||||
// case WM_SIZE:
|
||||
// mRenderWindow->Resized();
|
||||
// if (mMovedFunc != NULL)
|
||||
// mMovedFunc(this);
|
||||
// break;
|
||||
// case WM_PAINT:
|
||||
// break;
|
||||
// case WM_LBUTTONDOWN:
|
||||
// case WM_RBUTTONDOWN:
|
||||
// case WM_MBUTTONDOWN:
|
||||
// case WM_LBUTTONDBLCLK:
|
||||
// case WM_RBUTTONDBLCLK:
|
||||
// case WM_LBUTTONUP:
|
||||
// case WM_RBUTTONUP:
|
||||
// case WM_MBUTTONUP:
|
||||
// case WM_MOUSEWHEEL:
|
||||
// case WM_MOUSEMOVE:
|
||||
// {
|
||||
// int x = (short) LOWORD(lParam);
|
||||
// int y = (short) HIWORD(lParam);
|
||||
//
|
||||
// bool releaseCapture = false;
|
||||
//
|
||||
// POINT point = {x, y};
|
||||
// ::ClientToScreen(hWnd, &point);
|
||||
// HWND windowAtPoint = ::WindowFromPoint(point);
|
||||
//
|
||||
// bool isMouseOver = windowAtPoint == hWnd;
|
||||
//
|
||||
// if ((!mIsMouseInside) && (isMouseOver))
|
||||
// {
|
||||
// TRACKMOUSEEVENT tme;
|
||||
// tme.cbSize = sizeof(TRACKMOUSEEVENT);
|
||||
// tme.dwFlags = TME_LEAVE;
|
||||
// tme.hwndTrack = hWnd;
|
||||
// TrackMouseEvent(&tme);
|
||||
// mIsMouseInside = true;
|
||||
// }
|
||||
//
|
||||
// if ((mIsMouseInside) && (!isMouseOver))
|
||||
// {
|
||||
// mIsMouseInside = false;
|
||||
// mMouseLeaveFunc(this);
|
||||
// }
|
||||
//
|
||||
// switch (Msg)
|
||||
// {
|
||||
// case WM_LBUTTONDOWN:
|
||||
// SetCapture(hWnd);
|
||||
// mMouseDownFunc(this, x, y, 0, 1);
|
||||
// break;
|
||||
// case WM_RBUTTONDOWN:
|
||||
// SetCapture(hWnd);
|
||||
// mMouseDownFunc(this, x, y, 1, 1);
|
||||
// break;
|
||||
// case WM_MBUTTONDOWN:
|
||||
// SetCapture(hWnd);
|
||||
// mMouseDownFunc(this, x, y, 2, 1);
|
||||
// break;
|
||||
// case WM_LBUTTONDBLCLK:
|
||||
// SetCapture(hWnd);
|
||||
// mMouseDownFunc(this, x, y, 0, 2);
|
||||
// break;
|
||||
// case WM_RBUTTONDBLCLK:
|
||||
// SetCapture(hWnd);
|
||||
// mMouseDownFunc(this, x, y, 1, 2);
|
||||
// break;
|
||||
// case WM_MBUTTONDBLCLK:
|
||||
// SetCapture(hWnd);
|
||||
// mMouseDownFunc(this, x, y, 2, 2);
|
||||
// break;
|
||||
// case WM_LBUTTONUP:
|
||||
// releaseCapture = true;
|
||||
// mMouseUpFunc(this, x, y, 0);
|
||||
// break;
|
||||
// case WM_RBUTTONUP:
|
||||
// releaseCapture = true;
|
||||
// mMouseUpFunc(this, x, y, 1);
|
||||
// break;
|
||||
// case WM_MBUTTONUP:
|
||||
// releaseCapture = true;
|
||||
// mMouseUpFunc(this, x, y, 2);
|
||||
// break;
|
||||
// case WM_MOUSEWHEEL:
|
||||
// {
|
||||
// POINT pt = {x, y};
|
||||
// ScreenToClient(mHWnd, &pt);
|
||||
//
|
||||
// int delta = ((int16)HIWORD(wParam)) / 120;
|
||||
// mMouseWheelFunc(this, pt.x, pt.y, delta);
|
||||
// }
|
||||
// break;
|
||||
// case WM_MOUSEMOVE:
|
||||
// {
|
||||
// mMouseMoveFunc(this, x, y);
|
||||
//
|
||||
// if ((wParam != 0) && (gBFApp->mWindowList.size() > 1))
|
||||
// {
|
||||
// // See if our mouse is down and has entered into another window's space
|
||||
// POINT point = {x, y};
|
||||
// ::ClientToScreen(hWnd, &point);
|
||||
//
|
||||
// HWND windowAtPoint = ::WindowFromPoint(point);
|
||||
//
|
||||
// BFWindowList::iterator itr = gBFApp->mWindowList.begin();
|
||||
// while (itr != gBFApp->mWindowList.end())
|
||||
// {
|
||||
// SdlBFWindow* aWindow = (SdlBFWindow*) *itr;
|
||||
// if (aWindow != this)
|
||||
// {
|
||||
// if (aWindow->mHWnd == windowAtPoint)
|
||||
// {
|
||||
// POINT clientPt = point;
|
||||
// ::ScreenToClient(aWindow->mHWnd, &clientPt);
|
||||
// aWindow->mMouseProxyMoveFunc(this, clientPt.x, clientPt.y);
|
||||
// aWindow->mIsMouseInside = true;
|
||||
// }
|
||||
// else if (aWindow->mIsMouseInside)
|
||||
// {
|
||||
// aWindow->mMouseLeaveFunc(this);
|
||||
// aWindow->mIsMouseInside = false;
|
||||
// }
|
||||
// }
|
||||
// ++itr;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
// if (releaseCapture)
|
||||
// {
|
||||
// ReleaseCapture();
|
||||
//
|
||||
// BFWindowList::iterator itr = gBFApp->mWindowList.begin();
|
||||
// while (itr != gBFApp->mWindowList.end())
|
||||
// {
|
||||
// SdlBFWindow* aWindow = (SdlBFWindow*) *itr;
|
||||
// if ((aWindow != this) && (aWindow->mIsMouseInside))
|
||||
// {
|
||||
// aWindow->mMouseLeaveFunc(this);
|
||||
// aWindow->mIsMouseInside = false;
|
||||
// }
|
||||
// ++itr;
|
||||
// }
|
||||
// }
|
||||
// }
|
||||
// break;
|
||||
//
|
||||
// case WM_COMMAND:
|
||||
// {
|
||||
// SdlBFMenu* aMenu = mMenuIDMap[(uint32)wParam];
|
||||
// if (aMenu != NULL)
|
||||
// mMenuItemSelectedFunc(this, aMenu);
|
||||
// }
|
||||
// break;
|
||||
// case WM_INITMENUPOPUP:
|
||||
// {
|
||||
// HMENU hMenu = (HMENU) wParam;
|
||||
// SdlBFMenu* aMenu = mHMenuMap[hMenu];
|
||||
// if (aMenu != NULL)
|
||||
// mMenuItemSelectedFunc(this, aMenu);
|
||||
// }
|
||||
// break;
|
||||
//
|
||||
// case WM_MOUSEACTIVATE:
|
||||
// if (mFlags & BFWINDOW_NO_MOUSE_ACTIVATE)
|
||||
// {
|
||||
// doResult = true;
|
||||
// result = MA_NOACTIVATE;
|
||||
// }
|
||||
// break;
|
||||
//
|
||||
// case WM_KILLFOCUS:
|
||||
// mLostFocusFunc(this);
|
||||
// break;
|
||||
// case WM_SETFOCUS:
|
||||
// mGotFocusFunc(this);
|
||||
// break;
|
||||
// case WM_MOUSELEAVE:
|
||||
// mIsMouseInside = false;
|
||||
// mMouseLeaveFunc(this);
|
||||
// break;
|
||||
//
|
||||
// case WM_CHAR:
|
||||
// mKeyCharFunc(this, (WCHAR)wParam);
|
||||
// break;
|
||||
// case WM_SYSKEYDOWN:
|
||||
// case WM_KEYDOWN:
|
||||
// {
|
||||
// int keyCode = (int) wParam;
|
||||
// mIsKeyDown[keyCode] = true;
|
||||
//
|
||||
// WinMenuIDMap::iterator itr = mMenuIDMap.begin();
|
||||
// while (itr != mMenuIDMap.end())
|
||||
// {
|
||||
// SdlBFMenu* aMenu = itr->second;
|
||||
// if ((aMenu->mKeyCode == keyCode) &&
|
||||
// (aMenu->mKeyShift == mIsKeyDown[VK_SHIFT]) &&
|
||||
// (aMenu->mKeyCtrl == mIsKeyDown[VK_CONTROL]) &&
|
||||
// (aMenu->mKeyAlt == mIsKeyDown[VK_MENU]))
|
||||
// {
|
||||
// mMenuItemSelectedFunc(this, aMenu);
|
||||
// doResult = true;
|
||||
// break;
|
||||
// }
|
||||
// ++itr;
|
||||
// }
|
||||
// mKeyDownFunc(this, (int) wParam, (lParam & 0x7FFF) != 0);
|
||||
// }
|
||||
// break;
|
||||
// case WM_SYSCHAR:
|
||||
// {
|
||||
// int keyCode = toupper((int) wParam);
|
||||
//
|
||||
// WinMenuIDMap::iterator itr = mMenuIDMap.begin();
|
||||
// while (itr != mMenuIDMap.end())
|
||||
// {
|
||||
// SdlBFMenu* aMenu = itr->second;
|
||||
// if ((aMenu->mKeyCode == keyCode) &&
|
||||
// (aMenu->mKeyShift == mIsKeyDown[VK_SHIFT]) &&
|
||||
// (aMenu->mKeyCtrl == mIsKeyDown[VK_CONTROL]) &&
|
||||
// (aMenu->mKeyAlt == mIsKeyDown[VK_MENU]))
|
||||
// {
|
||||
// doResult = true;
|
||||
// break;
|
||||
// }
|
||||
// ++itr;
|
||||
// }
|
||||
// }
|
||||
// break;
|
||||
// case WM_SYSKEYUP:
|
||||
// case WM_KEYUP:
|
||||
// {
|
||||
// int keyCode = (int) wParam;
|
||||
// if (mIsKeyDown[keyCode])
|
||||
// {
|
||||
// mKeyUpFunc(this, (int) wParam);
|
||||
// mIsKeyDown[keyCode] = false;
|
||||
// }
|
||||
// }
|
||||
// break;
|
||||
//
|
||||
// case WM_TIMER:
|
||||
// if (gBFApp->mSysDialogCnt == 0)
|
||||
// gBFApp->Process();
|
||||
// break;
|
||||
//
|
||||
// case WM_SETCURSOR:
|
||||
// gBFApp->PhysSetCursor();
|
||||
// break;
|
||||
//
|
||||
// case WM_MOVING:
|
||||
// if (mMovedFunc != NULL)
|
||||
// mMovedFunc(this);
|
||||
// break;
|
||||
// case WM_SIZING:
|
||||
// mRenderWindow->Resized();
|
||||
// if (mMovedFunc != NULL)
|
||||
// mMovedFunc(this);
|
||||
// if (gBFApp->mSysDialogCnt == 0)
|
||||
// gBFApp->Process();
|
||||
// break;
|
||||
// }
|
||||
//
|
||||
//
|
||||
// app->mInMsgProc = false;
|
||||
// }
|
||||
//
|
||||
// if (doResult)
|
||||
// return result;
|
||||
//
|
||||
// return DefWindowProc(hWnd, Msg, wParam, lParam);
|
||||
//}
|
||||
|
||||
static int SDLConvertScanCode(int scanCode)
|
||||
{
|
||||
if ((scanCode >= SDL_SCANCODE_A) && (scanCode <= SDL_SCANCODE_Z))
|
||||
return (scanCode - SDL_SCANCODE_A) + 'A';
|
||||
if ((scanCode >= SDL_SCANCODE_0) && (scanCode <= SDL_SCANCODE_9))
|
||||
return (scanCode - SDL_SCANCODE_0) + '0';
|
||||
|
||||
switch (scanCode)
|
||||
{
|
||||
case SDL_SCANCODE_CANCEL: return 0x03;
|
||||
case SDL_SCANCODE_AC_BACK: return 0x08;
|
||||
case SDL_SCANCODE_TAB: return 0x09;
|
||||
case SDL_SCANCODE_CLEAR: return 0x0C;
|
||||
case SDL_SCANCODE_RETURN: return 0x0D;
|
||||
case SDL_SCANCODE_LSHIFT: return 0x10;
|
||||
case SDL_SCANCODE_RSHIFT: return 0x10;
|
||||
case SDL_SCANCODE_LCTRL: return 0x11;
|
||||
case SDL_SCANCODE_RCTRL: return 0x11;
|
||||
case SDL_SCANCODE_MENU: return 0x12;
|
||||
case SDL_SCANCODE_PAUSE: return 0x13;
|
||||
case SDL_SCANCODE_LANG1: return 0x15;
|
||||
case SDL_SCANCODE_LANG2: return 0x15;
|
||||
case SDL_SCANCODE_LANG3: return 0x17;
|
||||
case SDL_SCANCODE_LANG4: return 0x18;
|
||||
case SDL_SCANCODE_LANG5: return 0x19;
|
||||
case SDL_SCANCODE_LANG6: return 0x19;
|
||||
case SDL_SCANCODE_ESCAPE: return 0x1B;
|
||||
case SDL_SCANCODE_SPACE: return 0x20;
|
||||
case SDL_SCANCODE_PAGEUP: return 0x21;
|
||||
case SDL_SCANCODE_PAGEDOWN: return 0x22;
|
||||
case SDL_SCANCODE_END: return 0x23;
|
||||
case SDL_SCANCODE_HOME: return 0x24;
|
||||
case SDL_SCANCODE_LEFT: return 0x25;
|
||||
case SDL_SCANCODE_UP: return 0x26;
|
||||
case SDL_SCANCODE_RIGHT: return 0x27;
|
||||
case SDL_SCANCODE_DOWN: return 0x28;
|
||||
case SDL_SCANCODE_SELECT: return 0x29;
|
||||
case SDL_SCANCODE_PRINTSCREEN: return 0x2A;
|
||||
case SDL_SCANCODE_EXECUTE: return 0x2B;
|
||||
case SDL_SCANCODE_INSERT: return 0x2D;
|
||||
case SDL_SCANCODE_DELETE: return 0x2E;
|
||||
case SDL_SCANCODE_HELP: return 0x2F;
|
||||
case SDL_SCANCODE_LGUI: return 0x5B;
|
||||
case SDL_SCANCODE_RGUI: return 0x5C;
|
||||
case SDL_SCANCODE_KP_0: return 0x60;
|
||||
case SDL_SCANCODE_KP_1: return 0x61;
|
||||
case SDL_SCANCODE_KP_2: return 0x62;
|
||||
case SDL_SCANCODE_KP_3: return 0x63;
|
||||
case SDL_SCANCODE_KP_4: return 0x64;
|
||||
case SDL_SCANCODE_KP_5: return 0x65;
|
||||
case SDL_SCANCODE_KP_6: return 0x66;
|
||||
case SDL_SCANCODE_KP_7: return 0x67;
|
||||
case SDL_SCANCODE_KP_8: return 0x68;
|
||||
case SDL_SCANCODE_KP_9: return 0x69;
|
||||
case SDL_SCANCODE_KP_MULTIPLY: return 0x6A;
|
||||
case SDL_SCANCODE_KP_PLUS: return 0x6B;
|
||||
case SDL_SCANCODE_SEPARATOR: return 0x6C;
|
||||
case SDL_SCANCODE_KP_MINUS: return 0x6D;
|
||||
case SDL_SCANCODE_KP_PERIOD: return 0x6E;
|
||||
case SDL_SCANCODE_KP_DIVIDE: return 0x6F;
|
||||
case SDL_SCANCODE_F1: return 0x70;
|
||||
case SDL_SCANCODE_F2: return 0x71;
|
||||
case SDL_SCANCODE_F3: return 0x72;
|
||||
case SDL_SCANCODE_F4: return 0x73;
|
||||
case SDL_SCANCODE_F5: return 0x74;
|
||||
case SDL_SCANCODE_F6: return 0x75;
|
||||
case SDL_SCANCODE_F7: return 0x76;
|
||||
case SDL_SCANCODE_F8: return 0x77;
|
||||
case SDL_SCANCODE_F9: return 0x78;
|
||||
case SDL_SCANCODE_F10: return 0x79;
|
||||
case SDL_SCANCODE_F11: return 0x7A;
|
||||
case SDL_SCANCODE_F12: return 0x7B;
|
||||
case SDL_SCANCODE_NUMLOCKCLEAR: return 0x90;
|
||||
case SDL_SCANCODE_SCROLLLOCK: return 0x91;
|
||||
case SDL_SCANCODE_GRAVE: return 0xC0;
|
||||
//case SDL_SCANCODE_COMMAND: return 0xF0;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#ifdef _WIN32
|
||||
extern HINSTANCE gDLLInstance;
|
||||
#endif
|
||||
|
||||
SdlBFApp::SdlBFApp()
|
||||
{
|
||||
|
||||
//_CrtSetReportHook(SdlBFReportHook);
|
||||
|
||||
mRunning = false;
|
||||
mRenderDevice = NULL;
|
||||
|
||||
wchar_t aStr[MAX_PATH];
|
||||
#ifdef _WIN32
|
||||
GetModuleFileNameW(gDLLInstance, aStr, MAX_PATH);
|
||||
#else
|
||||
GetModuleFileNameW(NULL, aStr, MAX_PATH);
|
||||
#endif
|
||||
|
||||
if (aStr[0] == '!')
|
||||
{
|
||||
new SdlBFWindow(NULL, "", 0, 0, 0, 0, 0);
|
||||
}
|
||||
|
||||
mInstallDir = aStr;
|
||||
|
||||
int lastSlash = std::max((int)mInstallDir.rfind('\\'), (int)mInstallDir.rfind('/'));
|
||||
if (lastSlash != -1)
|
||||
mInstallDir = mInstallDir.substr(0, lastSlash);
|
||||
|
||||
//TODO: We're not properly using DataDir vs InstallDir
|
||||
#if (!defined BFSYSLIB_DYNAMIC) && (defined BF_RESOURCES_REL_DIR)
|
||||
mInstallDir += "/" + Beefy::UTF8Decode(BF_RESOURCES_REL_DIR);
|
||||
#endif
|
||||
|
||||
mInstallDir += "/";
|
||||
|
||||
//OutputDebugStrF(L"DataDir: %s\n", mInstallDir.c_str());
|
||||
|
||||
mDataDir = mInstallDir;
|
||||
|
||||
if (SDL_Init(SDL_INIT_VIDEO | SDL_INIT_GAMECONTROLLER) < 0)
|
||||
BF_FATAL(StrFormat("Unable to initialize SDL: %s", SDL_GetError()).c_str());
|
||||
}
|
||||
|
||||
SdlBFApp::~SdlBFApp()
|
||||
{
|
||||
}
|
||||
|
||||
SdlBFWindow* SdlBFApp::GetSdlWindowFromId(uint32 id)
|
||||
{
|
||||
SdlWindowMap::iterator itr = mSdlWindowMap.find(id);
|
||||
if (itr != mSdlWindowMap.end())
|
||||
return itr->second;
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void SdlBFApp::Init()
|
||||
{
|
||||
mRunning = true;
|
||||
mInMsgProc = false;
|
||||
|
||||
mRenderDevice = new GLRenderDevice();
|
||||
mRenderDevice->Init(this);
|
||||
}
|
||||
|
||||
void SdlBFApp::Run()
|
||||
{
|
||||
while (mRunning)
|
||||
{
|
||||
SDL_Event sdlEvent;
|
||||
while (true)
|
||||
{
|
||||
{
|
||||
//Beefy::DebugTimeGuard suspendTimeGuard(30, "BFApp::Run1");
|
||||
if (!SDL_PollEvent(&sdlEvent))
|
||||
break;
|
||||
}
|
||||
|
||||
//Beefy::DebugTimeGuard suspendTimeGuard(30, "BFApp::Run2");
|
||||
|
||||
switch (sdlEvent.type)
|
||||
{
|
||||
case SDL_QUIT:
|
||||
//gBFApp->RemoveWindow(sdlEvent.window);
|
||||
Shutdown();
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
{
|
||||
SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.button.windowID);
|
||||
sdlBFWindow->mMouseUpFunc(sdlBFWindow, sdlEvent.button.x, sdlEvent.button.y, sdlEvent.button.button);
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
{
|
||||
SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.button.windowID);
|
||||
sdlBFWindow->mMouseDownFunc(sdlBFWindow, sdlEvent.button.x, sdlEvent.button.y, sdlEvent.button.button, 1);
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
{
|
||||
SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.button.windowID);
|
||||
sdlBFWindow->mMouseMoveFunc(sdlBFWindow, sdlEvent.button.x, sdlEvent.button.y);
|
||||
}
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
{
|
||||
SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.key.windowID);
|
||||
sdlBFWindow->mKeyDownFunc(sdlBFWindow, SDLConvertScanCode(sdlEvent.key.keysym.scancode), sdlEvent.key.repeat);
|
||||
sdlBFWindow->mKeyCharFunc(sdlBFWindow, sdlEvent.key.keysym.sym);
|
||||
}
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
{
|
||||
SdlBFWindow* sdlBFWindow = GetSdlWindowFromId(sdlEvent.key.windowID);
|
||||
sdlBFWindow->mKeyUpFunc(sdlBFWindow, SDLConvertScanCode(sdlEvent.key.keysym.scancode));
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Process();
|
||||
}
|
||||
}
|
||||
|
||||
extern int gPixelsDrawn;
|
||||
int gFrameCount = 0;
|
||||
int gBFDrawBatchCount = 0;
|
||||
void SdlBFApp::Draw()
|
||||
{
|
||||
//Beefy::DebugTimeGuard suspendTimeGuard(30, "SdlBFApp::Draw");
|
||||
|
||||
glDisable(GL_SCISSOR_TEST);
|
||||
glDisable(GL_CULL_FACE);
|
||||
glDisable(GL_DEPTH_TEST);
|
||||
glClearColor(1.0f, 0.0f, 1.0f, 1.0f);
|
||||
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
|
||||
|
||||
gPixelsDrawn = 0;
|
||||
gBFDrawBatchCount = 0;
|
||||
|
||||
mRenderDevice->FrameStart();
|
||||
BFApp::Draw();
|
||||
mRenderDevice->FrameEnd();
|
||||
|
||||
gFrameCount++;
|
||||
//if (gFrameCount % 60 == 0)
|
||||
//OutputDebugStrF("Pixels: %d Batches: %d\n", gPixelsDrawn / 1000, gBFDrawBatchCount);
|
||||
}
|
||||
|
||||
BFWindow* SdlBFApp::CreateNewWindow(BFWindow* parent, const StringImpl& title, int x, int y, int width, int height, int windowFlags)
|
||||
{
|
||||
SdlBFWindow* aWindow = new SdlBFWindow(parent, title, x, y, width, height, windowFlags);
|
||||
mSdlWindowMap[SDL_GetWindowID(aWindow->mSDLWindow)] = aWindow;
|
||||
mWindowList.push_back(aWindow);
|
||||
return aWindow;
|
||||
}
|
||||
|
||||
void SdlBFWindow::GetPosition(int* x, int* y, int* width, int* height, int* clientX, int* clientY, int* clientWidth, int* clientHeight)
|
||||
{
|
||||
SDL_GetWindowPosition(mSDLWindow, x, y);
|
||||
SDL_GetWindowSize(mSDLWindow, width, height);
|
||||
*clientWidth = *width;
|
||||
*clientHeight = *height;
|
||||
}
|
||||
|
||||
void SdlBFApp::PhysSetCursor()
|
||||
{
|
||||
//
|
||||
//static HCURSOR cursors [] =
|
||||
// {
|
||||
// ::LoadCursor(NULL, IDC_ARROW),
|
||||
//
|
||||
// //TODO: mApp->mHandCursor);
|
||||
// ::LoadCursor(NULL, IDC_ARROW),
|
||||
// //TODO: mApp->mDraggingCursor);
|
||||
// ::LoadCursor(NULL, IDC_ARROW),
|
||||
|
||||
// ::LoadCursor(NULL, IDC_IBEAM),
|
||||
//
|
||||
// ::LoadCursor(NULL, IDC_NO),
|
||||
// ::LoadCursor(NULL, IDC_SIZEALL),
|
||||
// ::LoadCursor(NULL, IDC_SIZENESW),
|
||||
// ::LoadCursor(NULL, IDC_SIZENS),
|
||||
// ::LoadCursor(NULL, IDC_SIZENWSE),
|
||||
// ::LoadCursor(NULL, IDC_SIZEWE),
|
||||
// ::LoadCursor(NULL, IDC_WAIT),
|
||||
// NULL
|
||||
// };
|
||||
|
||||
//::SetCursor(cursors[mCursor]);
|
||||
}
|
||||
|
||||
void SdlBFWindow::SetClientPosition(int x, int y)
|
||||
{
|
||||
SDL_SetWindowPosition(mSDLWindow, x, y);
|
||||
|
||||
if (mMovedFunc != NULL)
|
||||
mMovedFunc(this);
|
||||
}
|
||||
|
||||
void SdlBFWindow::SetAlpha(float alpha, uint32 destAlphaSrcMask, bool isMouseVisible)
|
||||
{
|
||||
// Not supported
|
||||
}
|
||||
|
||||
uint32 SdlBFApp::GetClipboardFormat(const StringImpl& format)
|
||||
{
|
||||
return CF_TEXT;
|
||||
}
|
||||
|
||||
void* SdlBFApp::GetClipboardData(const StringImpl& format, int* size)
|
||||
{
|
||||
return SDL_GetClipboardText();
|
||||
}
|
||||
|
||||
void SdlBFApp::ReleaseClipboardData(void* ptr)
|
||||
{
|
||||
SDL_free(ptr);
|
||||
}
|
||||
|
||||
void SdlBFApp::SetClipboardData(const StringImpl& format, const void* ptr, int size, bool resetClipboard)
|
||||
{
|
||||
SDL_SetClipboardText((const char*)ptr);
|
||||
}
|
||||
|
||||
BFMenu* SdlBFWindow::AddMenuItem(BFMenu* parent, const wchar_t* text, const wchar_t* hotKey, BFSysBitmap* sysBitmap, bool enabled, int checkState, bool radioCheck)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void SdlBFWindow::RemoveMenuItem(BFMenu* item)
|
||||
{
|
||||
}
|
||||
|
||||
BFSysBitmap* SdlBFApp::LoadSysBitmap(const wchar_t* fileName)
|
||||
{
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void SdlBFWindow::ModalsRemoved()
|
||||
{
|
||||
//::EnableWindow(mHWnd, TRUE);
|
||||
//::SetFocus(mHWnd);
|
||||
}
|
||||
|
||||
DrawLayer* SdlBFApp::CreateDrawLayer(BFWindow* window)
|
||||
{
|
||||
GLDrawLayer* drawLayer = new GLDrawLayer();
|
||||
if (window != NULL)
|
||||
{
|
||||
drawLayer->mRenderWindow = window->mRenderWindow;
|
||||
window->mRenderWindow->mDrawLayerList.push_back(drawLayer);
|
||||
}
|
||||
return drawLayer;
|
||||
}
|
68
BeefySysLib/platform/sdl/SdlBFApp.h
Normal file
68
BeefySysLib/platform/sdl/SdlBFApp.h
Normal file
|
@ -0,0 +1,68 @@
|
|||
#pragma once
|
||||
|
||||
#include "BFApp.h"
|
||||
#include "BFWindow.h"
|
||||
|
||||
struct SDL_Window;
|
||||
|
||||
NS_BF_BEGIN;
|
||||
|
||||
class RenderDevice;
|
||||
|
||||
typedef std::map<String, uint32> StringToUIntMap;
|
||||
|
||||
class SdlBFWindow : public BFWindow
|
||||
{
|
||||
public:
|
||||
SDL_Window* mSDLWindow;
|
||||
bool mIsMouseInside;
|
||||
int mModalCount;
|
||||
|
||||
public:
|
||||
SdlBFWindow(BFWindow* parent, const StringImpl& title, int x, int y, int width, int height, int windowFlags);
|
||||
~SdlBFWindow();
|
||||
|
||||
virtual bool TryClose() override;
|
||||
virtual void GetPosition(int* x, int* y, int* width, int* height, int* clientX, int* clientY, int* clientWidth, int* clientHeight) override;
|
||||
virtual void SetClientPosition(int x, int y) override;
|
||||
virtual void SetAlpha(float alpha, uint32 destAlphaSrcMask, bool isMouseVisible) override;
|
||||
virtual BFMenu* AddMenuItem(BFMenu* parent, const wchar_t* text, const wchar_t* hotKey, BFSysBitmap* sysBitmap, bool enabled, int checkState, bool radioCheck);
|
||||
|
||||
virtual void RemoveMenuItem(BFMenu* item) override;
|
||||
virtual void ModalsRemoved() override;
|
||||
};
|
||||
|
||||
typedef std::map<uint32, SdlBFWindow*> SdlWindowMap;
|
||||
|
||||
class SdlBFApp : public BFApp
|
||||
{
|
||||
public:
|
||||
bool mInMsgProc;
|
||||
StringToUIntMap mClipboardFormatMap;
|
||||
SdlWindowMap mSdlWindowMap;
|
||||
|
||||
protected:
|
||||
virtual void Draw() override;
|
||||
virtual void PhysSetCursor() override;
|
||||
|
||||
uint32 GetClipboardFormat(const StringImpl& format);
|
||||
SdlBFWindow* GetSdlWindowFromId(uint32 id);
|
||||
|
||||
public:
|
||||
SdlBFApp();
|
||||
virtual ~SdlBFApp();
|
||||
|
||||
virtual void Init() override;
|
||||
virtual void Run() override;
|
||||
|
||||
virtual BFWindow* CreateNewWindow(BFWindow* parent, const StringImpl& title, int x, int y, int width, int height, int windowFlags) override;
|
||||
virtual DrawLayer* CreateDrawLayer(BFWindow* window);
|
||||
|
||||
virtual void* GetClipboardData(const StringImpl& format, int* size) override;
|
||||
virtual void ReleaseClipboardData(void* ptr) override;
|
||||
virtual void SetClipboardData(const StringImpl& format, const void* ptr, int size, bool resetClipboard) override;
|
||||
|
||||
virtual BFSysBitmap* LoadSysBitmap(const wchar_t* fileName) override;
|
||||
};
|
||||
|
||||
NS_BF_END;
|
198
BeefySysLib/platform/win/BFPlatform.h
Normal file
198
BeefySysLib/platform/win/BFPlatform.h
Normal file
|
@ -0,0 +1,198 @@
|
|||
#pragma once
|
||||
|
||||
#ifndef NOMINMAX
|
||||
#define NOMINMAX
|
||||
#endif
|
||||
|
||||
#if (defined __MINGW32__) && (!defined BF_MINGW)
|
||||
#define BF_MINGW
|
||||
#endif
|
||||
|
||||
#define WIN32_LEAN_AND_MEAN
|
||||
#define BF_PLATFORM_WINDOWS
|
||||
#define BF_PLATFORM_NAME "BF_PLATFORM_WINDOWS"
|
||||
|
||||
#ifdef BF_MINGW
|
||||
#pragma clang diagnostic ignored "-Wunused-variable"
|
||||
#pragma clang diagnostic ignored "-Wunknown-pragmas"
|
||||
#pragma clang diagnostic ignored "-Wunused-function"
|
||||
#pragma clang diagnostic ignored "-Wunknown-attributes"
|
||||
#pragma clang diagnostic ignored "-Wunused-member-function"
|
||||
#pragma clang diagnostic ignored "-Wunused-conversion-function"
|
||||
#pragma clang diagnostic ignored "-Wunused-private-field"
|
||||
#pragma clang diagnostic ignored "-Wdeprecated-declarations"
|
||||
#else
|
||||
#define BF_VC
|
||||
#endif
|
||||
|
||||
#include <windows.h>
|
||||
#include <assert.h>
|
||||
#include <stdint.h>
|
||||
#include <assert.h>
|
||||
#include <wtypes.h>
|
||||
|
||||
#define DIR_SEP_CHAR '\\'
|
||||
#define DIR_SEP_CHAR_ALT '/'
|
||||
|
||||
#ifndef BF_NO_FFI
|
||||
extern "C"
|
||||
{
|
||||
#define FFI_BUILDING
|
||||
#include "libffi/i686-pc-cygwin/include/ffi.h"
|
||||
}
|
||||
#endif
|
||||
|
||||
//#define BF_FORCE_SDL
|
||||
|
||||
#ifdef SDL_FORCE_OPENGL_ES2
|
||||
#define BF_PLATFORM_OPENGL_ES2
|
||||
#endif
|
||||
|
||||
#if (_MSC_VER == 1800) && (!defined BFSYSLIB_STATIC)
|
||||
#define BF_WWISE_ENABLED
|
||||
#endif
|
||||
|
||||
#define CPP11
|
||||
|
||||
#ifdef _DEBUG
|
||||
#define BF_DEBUG
|
||||
//#define DEBUG
|
||||
#endif
|
||||
|
||||
#ifdef BF_MINGW
|
||||
#define NOP asm volatile("nop");
|
||||
extern "C" _CRTIMP int __cdecl __MINGW_NOTHROW _stricmp (const char*, const char*);
|
||||
#elif defined _WIN64
|
||||
#define BF64
|
||||
#define NOP GetTickCount()
|
||||
#else
|
||||
#define BF32
|
||||
#define NOP __asm nop;
|
||||
#endif
|
||||
|
||||
#define BF_HAS_TLS_DECLSPEC
|
||||
#ifdef BF_MINGW
|
||||
#define BF_TLS_DECLSPEC __thread
|
||||
#else
|
||||
#define BF_TLS_DECLSPEC __declspec(thread)
|
||||
#endif
|
||||
|
||||
#if defined _DEBUG || defined BF_DEBUG_ASSERTS
|
||||
#define BF_ASSERT(_Expression) (void)( (!!(_Expression)) || (Beefy::BFFatalError(#_Expression, __FILE__, __LINE__), 0) )
|
||||
#else
|
||||
#define BF_ASSERT(_Expression) (void)(0)
|
||||
#endif
|
||||
|
||||
#define BF_ASSERT_REL(_Expression) (void)( (!!(_Expression)) || (Beefy::BFFatalError(#_Expression, __FILE__, __LINE__), 0) )
|
||||
#define BF_FATAL(msg) (void) ((Beefy::BFFatalError(msg, __FILE__, __LINE__), 0) )
|
||||
|
||||
#if defined _DEBUG || defined BF_DEBUG_ASSERTS
|
||||
#define BF_DBG_FATAL(msg) (void) ((Beefy::BFFatalError(msg, __FILE__, __LINE__), 0) )
|
||||
#else
|
||||
#define BF_DBG_FATAL(msg)
|
||||
#endif
|
||||
|
||||
#define BFSTDCALL __stdcall
|
||||
|
||||
#define BF_IMPORT extern "C" __declspec(dllimport)
|
||||
|
||||
#ifdef BFSYSLIB_DYNAMIC
|
||||
#define BF_EXPORT extern "C" __declspec(dllexport)
|
||||
#define BF_CALLTYPE __stdcall
|
||||
#else
|
||||
#define BF_EXPORT extern "C"
|
||||
#define BF_CALLTYPE __stdcall
|
||||
#endif
|
||||
|
||||
#define BF_NOINLINE __declspec(noinline)
|
||||
#define BF_NAKED __declspec(naked)
|
||||
|
||||
#define BF_PACKED(x) __pragma(pack(push, 1)) x __pragma(pack(pop))
|
||||
#define BF_ALIGNED(x) __declspec(align(x))
|
||||
|
||||
#ifndef BF_MINGW
|
||||
#define strtoull _strtoui64
|
||||
#endif
|
||||
//#define snprintf _snprintf
|
||||
#define __func__ __FUNCTION__
|
||||
|
||||
typedef uint64_t uint64;
|
||||
typedef uint32_t uint32;
|
||||
typedef uint16_t uint16;
|
||||
typedef uint8_t uint8;
|
||||
typedef int64_t int64;
|
||||
typedef int32_t int32;
|
||||
typedef int16_t int16;
|
||||
typedef int8_t int8;
|
||||
typedef unsigned int uint;
|
||||
|
||||
typedef intptr_t intptr;
|
||||
typedef uintptr_t uintptr;
|
||||
|
||||
typedef DWORD BF_THREADID;
|
||||
typedef HANDLE BF_THREADHANDLE;
|
||||
|
||||
#ifdef BF_MINGW
|
||||
#define BF_COMPILER_FENCE() __asm__ __volatile__("mfence" : : : "memory");
|
||||
#define BF_FULL_MEMORY_FENCE() __asm__ __volatile__("mfence" : : : "memory");
|
||||
#define BF_SPINWAIT_NOP() __asm__ __volatile__( "pause;" )
|
||||
#define BF_DEBUG_BREAK() __asm__ __volatile__( "int $0x03;" )
|
||||
#else
|
||||
#define BF_COMPILER_FENCE() _ReadWriteBarrier()
|
||||
//#define BF_FULL_MEMORY_FENCE() __asm { lock add dword ptr [esp],0 }
|
||||
|
||||
#ifdef BF32
|
||||
#define BF_FULL_MEMORY_FENCE() ::MemoryBarrier()
|
||||
#else
|
||||
#define BF_FULL_MEMORY_FENCE() _mm_mfence()
|
||||
#endif
|
||||
|
||||
//#define BF_SPINWAIT_NOP() _asm { pause }
|
||||
#define BF_SPINWAIT_NOP() _mm_pause()
|
||||
#define BF_DEBUG_BREAK() DebugBreak()
|
||||
#endif
|
||||
|
||||
typedef DWORD BfTLSKey;
|
||||
#define BfTLSGetValue ::TlsGetValue
|
||||
#define BfTLSSetValue ::TlsSetValue
|
||||
#define BfTLSAlloc ::TlsAlloc
|
||||
#define BfTLSFree ::TlsFree
|
||||
|
||||
#define BF_THREAD_YIELD() ::SwitchToThread()
|
||||
|
||||
#define BF_UNUSED
|
||||
#define BF_EXPLICIT explicit
|
||||
|
||||
#define BF_ENDIAN_LITTLE
|
||||
|
||||
#define WaitForSingleObject_Thread WaitForSingleObject
|
||||
#define CloseHandle_File CloseHandle
|
||||
#define CloseHandle_Event CloseHandle
|
||||
#define CloseHandle_Thread CloseHandle
|
||||
#define CloseHandle_Process CloseHandle
|
||||
|
||||
#ifdef BF32
|
||||
#define BF_REGISTER_COUNT 7
|
||||
#else
|
||||
#define BF_REGISTER_COUNT 15
|
||||
#endif
|
||||
|
||||
#ifndef BF_MINGW
|
||||
#define __thread __declspec(thread)
|
||||
#endif
|
||||
|
||||
#ifdef BF_MINGW
|
||||
//
|
||||
#else
|
||||
#define strcasecmp stricmp
|
||||
#endif
|
||||
|
||||
struct BfpEvent
|
||||
{
|
||||
CRITICAL_SECTION mCritSect;
|
||||
CONDITION_VARIABLE mCondVariable;
|
||||
bool mSet;
|
||||
bool mManualReset;
|
||||
};
|
||||
|
||||
#include "../PlatformInterface.h"
|
945
BeefySysLib/platform/win/CrashCatcher.cpp
Normal file
945
BeefySysLib/platform/win/CrashCatcher.cpp
Normal file
|
@ -0,0 +1,945 @@
|
|||
#include "CrashCatcher.h"
|
||||
#include "../util/CritSect.h"
|
||||
|
||||
USING_NS_BF;
|
||||
|
||||
#pragma warning(disable:4091)
|
||||
#pragma warning(disable:4996)
|
||||
#include <imagehlp.h>
|
||||
|
||||
#ifdef BF64
|
||||
typedef BOOL(__stdcall * SYMINITIALIZEPROC)(HANDLE, LPSTR, BOOL);
|
||||
typedef DWORD(__stdcall *SYMSETOPTIONSPROC)(DWORD);
|
||||
typedef BOOL(__stdcall *SYMCLEANUPPROC)(HANDLE);
|
||||
typedef LPCSTR(__stdcall *UNDECORATESYMBOLNAMEPROC)(LPCSTR, LPSTR, DWORD, DWORD);
|
||||
typedef BOOL(__stdcall * STACKWALKPROC)
|
||||
(DWORD, HANDLE, HANDLE, LPSTACKFRAME, LPVOID,
|
||||
PREAD_PROCESS_MEMORY_ROUTINE, PFUNCTION_TABLE_ACCESS_ROUTINE,
|
||||
PGET_MODULE_BASE_ROUTINE, PTRANSLATE_ADDRESS_ROUTINE);
|
||||
typedef LPVOID(__stdcall *SYMFUNCTIONTABLEACCESSPROC)(HANDLE, DWORD64);
|
||||
typedef DWORD64 (__stdcall *SYMGETMODULEBASEPROC)(HANDLE, DWORD64);
|
||||
typedef BOOL(__stdcall *SYMGETSYMFROMADDRPROC)(HANDLE, DWORD64, PDWORD64, PIMAGEHLP_SYMBOL64);
|
||||
typedef BOOL(__stdcall *SYMGETLINEFROMADDR)(HANDLE hProcess, DWORD64 qwAddr, PDWORD pdwDisplacement, PIMAGEHLP_LINE64 Line64);
|
||||
#else
|
||||
typedef BOOL(__stdcall * SYMINITIALIZEPROC)(HANDLE, LPSTR, BOOL);
|
||||
typedef DWORD(__stdcall *SYMSETOPTIONSPROC)(DWORD);
|
||||
typedef BOOL(__stdcall *SYMCLEANUPPROC)(HANDLE);
|
||||
typedef LPCSTR(__stdcall *UNDECORATESYMBOLNAMEPROC)(LPCSTR, LPSTR, DWORD, DWORD);
|
||||
typedef BOOL(__stdcall * STACKWALKPROC)
|
||||
(DWORD, HANDLE, HANDLE, LPSTACKFRAME, LPVOID,
|
||||
PREAD_PROCESS_MEMORY_ROUTINE, PFUNCTION_TABLE_ACCESS_ROUTINE,
|
||||
PGET_MODULE_BASE_ROUTINE, PTRANSLATE_ADDRESS_ROUTINE);
|
||||
typedef LPVOID(__stdcall *SYMFUNCTIONTABLEACCESSPROC)(HANDLE, DWORD);
|
||||
typedef DWORD(__stdcall *SYMGETMODULEBASEPROC)(HANDLE, DWORD);
|
||||
typedef BOOL(__stdcall *SYMGETSYMFROMADDRPROC)(HANDLE, DWORD, PDWORD, PIMAGEHLP_SYMBOL);
|
||||
typedef BOOL(__stdcall *SYMGETLINEFROMADDR)(HANDLE hProcess, DWORD qwAddr, PDWORD pdwDisplacement, PIMAGEHLP_LINE Line64);
|
||||
#endif
|
||||
|
||||
static HMODULE gImageHelpLib = NULL;
|
||||
static SYMINITIALIZEPROC gSymInitialize = NULL;
|
||||
static SYMSETOPTIONSPROC gSymSetOptions = NULL;
|
||||
static UNDECORATESYMBOLNAMEPROC gUnDecorateSymbolName = NULL;
|
||||
static SYMCLEANUPPROC gSymCleanup = NULL;
|
||||
static STACKWALKPROC gStackWalk = NULL;
|
||||
static SYMFUNCTIONTABLEACCESSPROC gSymFunctionTableAccess = NULL;
|
||||
static SYMGETMODULEBASEPROC gSymGetModuleBase = NULL;
|
||||
static SYMGETSYMFROMADDRPROC gSymGetSymFromAddr = NULL;
|
||||
static SYMGETLINEFROMADDR gSymGetLineFromAddr = NULL;
|
||||
static Array<CrashInfoFunc> gCrashInfoFuncs;
|
||||
static StringT<0> gCrashInfo;
|
||||
static bool gCrashed = false;
|
||||
extern CritSect gBfpCritSect;
|
||||
|
||||
static LPTOP_LEVEL_EXCEPTION_FILTER gPreviousFilter = NULL;
|
||||
|
||||
static bool gDebugError = false;
|
||||
|
||||
static bool LoadImageHelp()
|
||||
{
|
||||
gImageHelpLib = LoadLibraryA("IMAGEHLP.DLL");
|
||||
if (!gImageHelpLib)
|
||||
return false;
|
||||
|
||||
gSymInitialize = (SYMINITIALIZEPROC)GetProcAddress(gImageHelpLib, "SymInitialize");
|
||||
if (!gSymInitialize)
|
||||
return false;
|
||||
|
||||
gSymSetOptions = (SYMSETOPTIONSPROC)GetProcAddress(gImageHelpLib, "SymSetOptions");
|
||||
if (!gSymSetOptions)
|
||||
return false;
|
||||
|
||||
gSymCleanup = (SYMCLEANUPPROC)GetProcAddress(gImageHelpLib, "SymCleanup");
|
||||
if (!gSymCleanup)
|
||||
return false;
|
||||
|
||||
gUnDecorateSymbolName = (UNDECORATESYMBOLNAMEPROC)GetProcAddress(gImageHelpLib, "UnDecorateSymbolName");
|
||||
if (!gUnDecorateSymbolName)
|
||||
return false;
|
||||
|
||||
gStackWalk = (STACKWALKPROC)GetProcAddress(gImageHelpLib, "StackWalk");
|
||||
if (!gStackWalk)
|
||||
return false;
|
||||
|
||||
gSymFunctionTableAccess = (SYMFUNCTIONTABLEACCESSPROC)GetProcAddress(gImageHelpLib, "SymFunctionTableAccess");
|
||||
if (!gSymFunctionTableAccess)
|
||||
return false;
|
||||
|
||||
gSymGetModuleBase = (SYMGETMODULEBASEPROC)GetProcAddress(gImageHelpLib, "SymGetModuleBase");
|
||||
if (!gSymGetModuleBase)
|
||||
return false;
|
||||
|
||||
gSymGetSymFromAddr = (SYMGETSYMFROMADDRPROC)GetProcAddress(gImageHelpLib, "SymGetSymFromAddr");
|
||||
if (!gSymGetSymFromAddr)
|
||||
return false;
|
||||
|
||||
gSymGetLineFromAddr = (SYMGETLINEFROMADDR)GetProcAddress(gImageHelpLib, "SymGetLineFromAddr64");
|
||||
if (!gSymGetLineFromAddr)
|
||||
return false;
|
||||
|
||||
gSymSetOptions(SYMOPT_DEFERRED_LOADS);
|
||||
|
||||
// Get image filename of the main executable
|
||||
char filepath[MAX_PATH], *lastdir, *pPath;
|
||||
DWORD filepathlen = GetModuleFileNameA(NULL, filepath, sizeof(filepath));
|
||||
|
||||
lastdir = strrchr(filepath, '/');
|
||||
if (lastdir == NULL) lastdir = strrchr(filepath, '\\');
|
||||
if (lastdir != NULL) lastdir[0] = '\0';
|
||||
|
||||
// Initialize the symbol table routines, supplying a pointer to the path
|
||||
pPath = filepath;
|
||||
if (filepath[0] == 0) pPath = NULL;
|
||||
|
||||
if (!gSymInitialize(GetCurrentProcess(), pPath, TRUE))
|
||||
return false;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
struct
|
||||
{
|
||||
DWORD dwExceptionCode;
|
||||
char *szMessage;
|
||||
} gMsgTable[] = {
|
||||
{ STATUS_SEGMENT_NOTIFICATION, "Segment Notification" },
|
||||
{ STATUS_BREAKPOINT, "Breakpoint" },
|
||||
{ STATUS_SINGLE_STEP, "Single step" },
|
||||
{ STATUS_WAIT_0, "Wait 0" },
|
||||
{ STATUS_ABANDONED_WAIT_0, "Abandoned Wait 0" },
|
||||
{ STATUS_USER_APC, "User APC" },
|
||||
{ STATUS_TIMEOUT, "Timeout" },
|
||||
{ STATUS_PENDING, "Pending" },
|
||||
{ STATUS_GUARD_PAGE_VIOLATION, "Guard Page Violation" },
|
||||
{ STATUS_DATATYPE_MISALIGNMENT, "Data Type Misalignment" },
|
||||
{ STATUS_ACCESS_VIOLATION, "Access Violation" },
|
||||
{ STATUS_IN_PAGE_ERROR, "In Page Error" },
|
||||
{ STATUS_NO_MEMORY, "No Memory" },
|
||||
{ STATUS_ILLEGAL_INSTRUCTION, "Illegal Instruction" },
|
||||
{ STATUS_NONCONTINUABLE_EXCEPTION, "Noncontinuable Exception" },
|
||||
{ STATUS_INVALID_DISPOSITION, "Invalid Disposition" },
|
||||
{ STATUS_ARRAY_BOUNDS_EXCEEDED, "Array Bounds Exceeded" },
|
||||
{ STATUS_FLOAT_DENORMAL_OPERAND, "Float Denormal Operand" },
|
||||
{ STATUS_FLOAT_DIVIDE_BY_ZERO, "Divide by Zero" },
|
||||
{ STATUS_FLOAT_INEXACT_RESULT, "Float Inexact Result" },
|
||||
{ STATUS_FLOAT_INVALID_OPERATION, "Float Invalid Operation" },
|
||||
{ STATUS_FLOAT_OVERFLOW, "Float Overflow" },
|
||||
{ STATUS_FLOAT_STACK_CHECK, "Float Stack Check" },
|
||||
{ STATUS_FLOAT_UNDERFLOW, "Float Underflow" },
|
||||
{ STATUS_INTEGER_DIVIDE_BY_ZERO, "Integer Divide by Zero" },
|
||||
{ STATUS_INTEGER_OVERFLOW, "Integer Overflow" },
|
||||
{ STATUS_PRIVILEGED_INSTRUCTION, "Privileged Instruction" },
|
||||
{ STATUS_STACK_OVERFLOW, "Stack Overflow" },
|
||||
{ STATUS_CONTROL_C_EXIT, "Ctrl+C Exit" },
|
||||
{ 0xFFFFFFFF, "" }
|
||||
};
|
||||
|
||||
static bool gUseDefaultFonts;
|
||||
static HFONT gDialogFont;
|
||||
static HFONT gBoldFont;
|
||||
static String gErrorTitle;
|
||||
static String gErrorText;
|
||||
static HWND gDebugButtonWindow = NULL;
|
||||
static HWND gYesButtonWindow = NULL;
|
||||
static HWND gNoButtonWindow = NULL;
|
||||
static bool gExiting = false;
|
||||
static BfpCrashReportKind gCrashReportKind = BfpCrashReportKind_Default;
|
||||
|
||||
static LRESULT CALLBACK SEHWindowProc(HWND hWnd, UINT uMsg, WPARAM wParam, LPARAM lParam)
|
||||
{
|
||||
switch (uMsg)
|
||||
{
|
||||
case WM_COMMAND:
|
||||
{
|
||||
HWND hwndCtl = (HWND)lParam;
|
||||
if (hwndCtl == gYesButtonWindow)
|
||||
{
|
||||
// Hide current window and bring up score submitting stuff
|
||||
ShowWindow(hWnd, SW_HIDE);
|
||||
|
||||
//ShowSubmitInfoDialog();
|
||||
}
|
||||
else if (hwndCtl == gNoButtonWindow)
|
||||
{
|
||||
gExiting = true;
|
||||
}
|
||||
else if (hwndCtl == gDebugButtonWindow)
|
||||
{
|
||||
gDebugError = true;
|
||||
gExiting = true;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case WM_CLOSE:
|
||||
gExiting = true;
|
||||
return 0;
|
||||
}
|
||||
|
||||
return DefWindowProc(hWnd, uMsg, wParam, lParam);
|
||||
}
|
||||
|
||||
static void ShowErrorDialog(const StringImpl& errorTitle, const StringImpl& errorText)
|
||||
{
|
||||
HINSTANCE gHInstance = ::GetModuleHandle(NULL);
|
||||
|
||||
OSVERSIONINFO aVersionInfo;
|
||||
aVersionInfo.dwOSVersionInfoSize = sizeof(aVersionInfo);
|
||||
GetVersionEx(&aVersionInfo);
|
||||
|
||||
// Setting fonts on 98 causes weirdo crash things in GDI upon the second crash.
|
||||
// That's no good.
|
||||
gUseDefaultFonts = aVersionInfo.dwPlatformId != VER_PLATFORM_WIN32_NT;
|
||||
|
||||
int aHeight = -MulDiv(8, 96, 72);
|
||||
gDialogFont = ::CreateFontA(aHeight, 0, 0, 0, FW_NORMAL, FALSE, FALSE,
|
||||
false, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
|
||||
DEFAULT_PITCH | FF_DONTCARE, "Tahoma");
|
||||
|
||||
aHeight = -MulDiv(10, 96, 72);
|
||||
gBoldFont = ::CreateFontA(aHeight, 0, 0, 0, FW_BOLD, FALSE, FALSE,
|
||||
false, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
|
||||
DEFAULT_PITCH | FF_DONTCARE, "Tahoma");
|
||||
|
||||
::SetCursor(::LoadCursor(NULL, IDC_ARROW));
|
||||
|
||||
gErrorTitle = errorTitle;
|
||||
gErrorText = errorText;
|
||||
|
||||
|
||||
WNDCLASSW wc;
|
||||
wc.style = 0;
|
||||
wc.cbClsExtra = 0;
|
||||
wc.cbWndExtra = 0;
|
||||
wc.hbrBackground = ::GetSysColorBrush(COLOR_BTNFACE);
|
||||
wc.hCursor = ::LoadCursor(NULL, IDC_ARROW);
|
||||
wc.hIcon = ::LoadIcon(NULL, IDI_ERROR);
|
||||
wc.hInstance = gHInstance;
|
||||
wc.lpfnWndProc = SEHWindowProc;
|
||||
wc.lpszClassName = L"SEHWindow";
|
||||
wc.lpszMenuName = NULL;
|
||||
RegisterClassW(&wc);
|
||||
|
||||
RECT aRect;
|
||||
aRect.left = 0;
|
||||
aRect.top = 0;
|
||||
aRect.right = 500;
|
||||
aRect.bottom = 400;
|
||||
|
||||
DWORD aWindowStyle = WS_CLIPCHILDREN | WS_POPUP | WS_BORDER | WS_CAPTION | WS_SYSMENU | WS_MINIMIZEBOX;
|
||||
|
||||
RECT windowRect = aRect;
|
||||
BOOL worked = AdjustWindowRect(&windowRect, aWindowStyle, FALSE);
|
||||
|
||||
HWND aHWnd = ::CreateWindowExW(0, L"SEHWindow", L"Fatal Error!",
|
||||
aWindowStyle,
|
||||
64, 64,
|
||||
windowRect.right - windowRect.left,
|
||||
windowRect.bottom - windowRect.top,
|
||||
NULL,
|
||||
NULL,
|
||||
gHInstance,
|
||||
0);
|
||||
|
||||
int textHeight = 30;
|
||||
|
||||
HWND aLabelWindow = ::CreateWindowW(L"EDIT",
|
||||
L"An unexpected error has occured!",
|
||||
WS_VISIBLE | WS_CHILD | ES_MULTILINE | ES_READONLY,
|
||||
8, 8,
|
||||
aRect.right - 8 - 8,
|
||||
textHeight,
|
||||
aHWnd,
|
||||
NULL,
|
||||
gHInstance,
|
||||
0);
|
||||
|
||||
int aFontHeight = -MulDiv(9, 96, 72);
|
||||
HFONT aBoldArialFont = CreateFontA(aFontHeight, 0, 0, 0, FW_BOLD, 0, 0,
|
||||
false, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
|
||||
DEFAULT_PITCH | FF_DONTCARE, "Arial");
|
||||
|
||||
if (!gUseDefaultFonts)
|
||||
SendMessage(aLabelWindow, WM_SETFONT, (WPARAM)aBoldArialFont, 0);
|
||||
|
||||
HWND anEditWindow = CreateWindowA("EDIT", errorText.c_str(),
|
||||
WS_VISIBLE | WS_CHILD | ES_MULTILINE | WS_BORDER | WS_HSCROLL | WS_VSCROLL | ES_READONLY,
|
||||
8, textHeight + 8,
|
||||
aRect.right - 8 - 8,
|
||||
aRect.bottom - textHeight - 24 - 8 - 8 - 8,
|
||||
aHWnd,
|
||||
NULL,
|
||||
gHInstance,
|
||||
0);
|
||||
|
||||
aFontHeight = -MulDiv(8, 96, 72);
|
||||
HFONT aCourierNewFont = CreateFontA(aFontHeight, 0, 0, 0, FW_NORMAL, 0, 0,
|
||||
false, ANSI_CHARSET, OUT_DEFAULT_PRECIS, CLIP_DEFAULT_PRECIS, DEFAULT_QUALITY,
|
||||
DEFAULT_PITCH | FF_DONTCARE, "Courier New");
|
||||
if (!gUseDefaultFonts)
|
||||
SendMessage(anEditWindow, WM_SETFONT, (WPARAM)aCourierNewFont, 0);
|
||||
|
||||
aWindowStyle = WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | BS_PUSHBUTTON;
|
||||
|
||||
//if (mApp == NULL)
|
||||
//aWindowStyle |= WS_DISABLED;
|
||||
|
||||
//#ifdef _DEBUG
|
||||
bool doDebugButton = true;
|
||||
// #else
|
||||
// bool doDebugButton = false;
|
||||
// #endif
|
||||
|
||||
//bool canSubmit = mAllowSubmit && !mSubmitHost.empty();
|
||||
bool canSubmit = false;
|
||||
int aNumButtons = 1 + (doDebugButton ? 1 : 0) + (canSubmit ? 1 : 0);
|
||||
|
||||
int aButtonWidth = (aRect.right - 8 - 8 - (aNumButtons - 1) * 8) / aNumButtons;
|
||||
|
||||
int aCurX = 8;
|
||||
|
||||
if (canSubmit)
|
||||
{
|
||||
gYesButtonWindow = CreateWindowA("BUTTON", "Send Report",
|
||||
aWindowStyle,
|
||||
aCurX, aRect.bottom - 24 - 8,
|
||||
aButtonWidth,
|
||||
24,
|
||||
aHWnd,
|
||||
NULL,
|
||||
gHInstance,
|
||||
0);
|
||||
if (!gUseDefaultFonts)
|
||||
SendMessage(gYesButtonWindow, WM_SETFONT, (WPARAM)aBoldArialFont, 0);
|
||||
|
||||
aCurX += aButtonWidth + 8;
|
||||
}
|
||||
|
||||
if (doDebugButton)
|
||||
{
|
||||
gDebugButtonWindow = CreateWindowA("BUTTON", "Debug",
|
||||
aWindowStyle,
|
||||
aCurX, aRect.bottom - 24 - 8,
|
||||
aButtonWidth,
|
||||
24,
|
||||
aHWnd,
|
||||
NULL,
|
||||
gHInstance,
|
||||
0);
|
||||
if (!gUseDefaultFonts)
|
||||
SendMessage(gDebugButtonWindow, WM_SETFONT, (WPARAM)aBoldArialFont, 0);
|
||||
|
||||
aCurX += aButtonWidth + 8;
|
||||
}
|
||||
|
||||
gNoButtonWindow = CreateWindowA("BUTTON", "Close Now",
|
||||
WS_VISIBLE | WS_CHILD | BS_DEFPUSHBUTTON | BS_PUSHBUTTON,
|
||||
aCurX, aRect.bottom - 24 - 8,
|
||||
aButtonWidth,
|
||||
24,
|
||||
aHWnd,
|
||||
NULL,
|
||||
gHInstance,
|
||||
0);
|
||||
|
||||
if (!gUseDefaultFonts)
|
||||
SendMessage(gNoButtonWindow, WM_SETFONT, (WPARAM)aBoldArialFont, 0);
|
||||
|
||||
ShowWindow(aHWnd, SW_NORMAL);
|
||||
|
||||
MSG msg;
|
||||
while ((GetMessage(&msg, NULL, 0, 0) > 0) && (!gExiting))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
}
|
||||
|
||||
DestroyWindow(aHWnd);
|
||||
|
||||
DeleteObject(gDialogFont);
|
||||
DeleteObject(gBoldFont);
|
||||
DeleteObject(aBoldArialFont);
|
||||
DeleteObject(aCourierNewFont);
|
||||
}
|
||||
|
||||
static bool GetLogicalAddress(void* addr, char* szModule, DWORD len, uintptr& section, uintptr& offset)
|
||||
{
|
||||
MEMORY_BASIC_INFORMATION mbi;
|
||||
|
||||
if (!VirtualQuery(addr, &mbi, sizeof(mbi)))
|
||||
return false;
|
||||
|
||||
uintptr hMod = (uintptr)mbi.AllocationBase;
|
||||
|
||||
if (hMod == NULL)
|
||||
{
|
||||
szModule[0] = 0;
|
||||
section = 0;
|
||||
offset = 0;
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!GetModuleFileNameA((HMODULE)hMod, szModule, len))
|
||||
return false;
|
||||
|
||||
// Point to the DOS header in memory
|
||||
PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMod;
|
||||
|
||||
// From the DOS header, find the NT (PE) header
|
||||
PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)((uint8*)hMod + pDosHdr->e_lfanew);
|
||||
|
||||
PIMAGE_SECTION_HEADER pSection = IMAGE_FIRST_SECTION(pNtHdr);
|
||||
|
||||
uintptr rva = (uintptr)addr - hMod; // RVA is offset from module load address
|
||||
|
||||
// Iterate through the section table, looking for the one that encompasses
|
||||
// the linear address.
|
||||
for (unsigned i = 0; i < pNtHdr->FileHeader.NumberOfSections; i++, pSection++)
|
||||
{
|
||||
uintptr sectionStart = pSection->VirtualAddress;
|
||||
uintptr sectionEnd = sectionStart + BF_MAX(pSection->SizeOfRawData, pSection->Misc.VirtualSize);
|
||||
|
||||
// Is the address in this section???
|
||||
if ((rva >= sectionStart) && (rva <= sectionEnd))
|
||||
{
|
||||
// Yes, address is in the section. Calculate section and offset,
|
||||
// and store in the "section" & "offset" params, which were
|
||||
// passed by reference.
|
||||
section = i + 1;
|
||||
offset = rva - sectionStart;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false; // Should never get here!
|
||||
}
|
||||
|
||||
static BOOL CALLBACK MyMiniDumpCallback(
|
||||
PVOID pParam,
|
||||
const PMINIDUMP_CALLBACK_INPUT pInput,
|
||||
PMINIDUMP_CALLBACK_OUTPUT pOutput
|
||||
)
|
||||
{
|
||||
BOOL bRet = FALSE;
|
||||
|
||||
|
||||
// Check parameters
|
||||
|
||||
if (pInput == 0)
|
||||
return FALSE;
|
||||
|
||||
if (pOutput == 0)
|
||||
return FALSE;
|
||||
|
||||
|
||||
// Process the callbacks
|
||||
|
||||
switch (pInput->CallbackType)
|
||||
{
|
||||
case IncludeModuleCallback:
|
||||
{
|
||||
// Include the module into the dump
|
||||
bRet = TRUE;
|
||||
}
|
||||
break;
|
||||
case IncludeThreadCallback:
|
||||
{
|
||||
// Include the thread into the dump
|
||||
bRet = TRUE;
|
||||
}
|
||||
break;
|
||||
case ModuleCallback:
|
||||
{
|
||||
// Does the module have ModuleReferencedByMemory flag set ?
|
||||
|
||||
if (!(pOutput->ModuleWriteFlags & ModuleReferencedByMemory))
|
||||
{
|
||||
// No, it does not - exclude it
|
||||
|
||||
//wprintf(L"Excluding module: %s \n", pInput->Module.FullPath);
|
||||
|
||||
pOutput->ModuleWriteFlags &= (~ModuleWriteModule);
|
||||
}
|
||||
|
||||
bRet = TRUE;
|
||||
}
|
||||
break;
|
||||
case ThreadCallback:
|
||||
{
|
||||
// Include all thread information into the minidump
|
||||
bRet = TRUE;
|
||||
}
|
||||
break;
|
||||
case ThreadExCallback:
|
||||
{
|
||||
// Include this information
|
||||
bRet = TRUE;
|
||||
}
|
||||
break;
|
||||
case MemoryCallback:
|
||||
{
|
||||
// We do not include any information here -> return FALSE
|
||||
bRet = FALSE;
|
||||
}
|
||||
break;
|
||||
case CancelCallback:
|
||||
break;
|
||||
}
|
||||
|
||||
return bRet;
|
||||
}
|
||||
|
||||
|
||||
void CreateMiniDump(EXCEPTION_POINTERS* pep)
|
||||
{
|
||||
// Open the file
|
||||
typedef BOOL(*PDUMPFN)(
|
||||
HANDLE hProcess,
|
||||
DWORD ProcessId,
|
||||
HANDLE hFile,
|
||||
MINIDUMP_TYPE DumpType,
|
||||
PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam,
|
||||
PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam,
|
||||
PMINIDUMP_CALLBACK_INFORMATION CallbackParam
|
||||
);
|
||||
|
||||
|
||||
HANDLE hFile = CreateFileW(L"D:/temp/CrashDumps/dump.dmp", GENERIC_READ | GENERIC_WRITE,
|
||||
0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL);
|
||||
|
||||
HMODULE h = ::LoadLibrary(L"DbgHelp.dll");
|
||||
PDUMPFN pFn = (PDUMPFN)GetProcAddress(h, "MiniDumpWriteDump");
|
||||
|
||||
if ((hFile != NULL) && (hFile != INVALID_HANDLE_VALUE))
|
||||
{
|
||||
// Create the minidump
|
||||
|
||||
MINIDUMP_EXCEPTION_INFORMATION mdei;
|
||||
|
||||
mdei.ThreadId = GetCurrentThreadId();
|
||||
mdei.ExceptionPointers = pep;
|
||||
mdei.ClientPointers = TRUE;
|
||||
|
||||
MINIDUMP_CALLBACK_INFORMATION mci;
|
||||
mci.CallbackRoutine = (MINIDUMP_CALLBACK_ROUTINE)MyMiniDumpCallback;
|
||||
mci.CallbackParam = 0;
|
||||
|
||||
MINIDUMP_TYPE mdt = (MINIDUMP_TYPE)(MiniDumpWithIndirectlyReferencedMemory | MiniDumpScanMemory);
|
||||
|
||||
BOOL rv = (*pFn)(GetCurrentProcess(), GetCurrentProcessId(),
|
||||
hFile, mdt, (pep != 0) ? &mdei : 0, 0, &mci);
|
||||
|
||||
// Close the file
|
||||
CloseHandle(hFile);
|
||||
}
|
||||
}
|
||||
|
||||
//
|
||||
//LONG WINAPI MyUnhandledExceptionFilter(
|
||||
// struct _EXCEPTION_POINTERS *ExceptionInfo
|
||||
//)
|
||||
//{
|
||||
// CreateMiniDump(ExceptionInfo);
|
||||
// return EXCEPTION_EXECUTE_HANDLER;
|
||||
//}
|
||||
|
||||
static String ImageHelpWalk(PCONTEXT theContext, int theSkipCount)
|
||||
{
|
||||
//char aBuffer[2048];
|
||||
String aDebugDump;
|
||||
|
||||
STACKFRAME sf;
|
||||
memset(&sf, 0, sizeof(sf));
|
||||
|
||||
// Initialize the STACKFRAME structure for the first call. This is only
|
||||
// necessary for Intel CPUs, and isn't mentioned in the documentation.
|
||||
#ifdef BF64
|
||||
sf.AddrPC.Offset = theContext->Rip;
|
||||
sf.AddrPC.Mode = AddrModeFlat;
|
||||
sf.AddrStack.Offset = theContext->Rsp;
|
||||
sf.AddrStack.Mode = AddrModeFlat;
|
||||
sf.AddrFrame.Offset = theContext->Rbp;
|
||||
sf.AddrFrame.Mode = AddrModeFlat;
|
||||
#else
|
||||
sf.AddrPC.Offset = theContext->Eip;
|
||||
sf.AddrPC.Mode = AddrModeFlat;
|
||||
sf.AddrStack.Offset = theContext->Esp;
|
||||
sf.AddrStack.Mode = AddrModeFlat;
|
||||
sf.AddrFrame.Offset = theContext->Ebp;
|
||||
sf.AddrFrame.Mode = AddrModeFlat;
|
||||
#endif
|
||||
|
||||
int aLevelCount = 0;
|
||||
|
||||
CONTEXT ctx = *theContext;
|
||||
|
||||
for (;;)
|
||||
{
|
||||
#ifdef BF64
|
||||
DWORD machineType = IMAGE_FILE_MACHINE_AMD64;
|
||||
PCONTEXT ctxPtr = &ctx;
|
||||
#else
|
||||
DWORD machineType = IMAGE_FILE_MACHINE_I386;
|
||||
PCONTEXT ctxPtr = NULL;
|
||||
#endif
|
||||
|
||||
if (!gStackWalk(machineType, GetCurrentProcess(), GetCurrentThread(),
|
||||
&sf, ctxPtr, NULL, gSymFunctionTableAccess, gSymGetModuleBase, 0))
|
||||
{
|
||||
//DWORD lastErr = GetLastError();
|
||||
//sprintf(aBuffer, "StackWalk failed (error %d)\r\n", lastErr);
|
||||
//aDebugDump += aBuffer;
|
||||
break;
|
||||
}
|
||||
|
||||
if ((aLevelCount > 0) && ((sf.AddrFrame.Offset == 0) || (sf.AddrPC.Offset == 0)))
|
||||
break;
|
||||
|
||||
if (theSkipCount > 0)
|
||||
{
|
||||
theSkipCount--;
|
||||
continue;
|
||||
}
|
||||
|
||||
BYTE symbolBuffer[sizeof(IMAGEHLP_SYMBOL) + 512];
|
||||
PIMAGEHLP_SYMBOL pSymbol = (PIMAGEHLP_SYMBOL)symbolBuffer;
|
||||
pSymbol->SizeOfStruct = sizeof(symbolBuffer);
|
||||
pSymbol->MaxNameLength = 512;
|
||||
|
||||
// Displacement of the input address, relative to the start of the symbol
|
||||
#ifdef BF64
|
||||
DWORD64 symDisplacement = 0;
|
||||
#else
|
||||
DWORD symDisplacement = 0;
|
||||
#endif
|
||||
|
||||
HANDLE hProcess = GetCurrentProcess();
|
||||
|
||||
if (gSymGetSymFromAddr(hProcess, sf.AddrPC.Offset, &symDisplacement, pSymbol))
|
||||
{
|
||||
char aUDName[256];
|
||||
gUnDecorateSymbolName(pSymbol->Name, aUDName, 256,
|
||||
UNDNAME_NO_ALLOCATION_MODEL | UNDNAME_NO_ALLOCATION_LANGUAGE |
|
||||
UNDNAME_NO_MS_THISTYPE | UNDNAME_NO_ACCESS_SPECIFIERS |
|
||||
UNDNAME_NO_THISTYPE | UNDNAME_NO_MEMBER_TYPE |
|
||||
UNDNAME_NO_RETURN_UDT_MODEL | UNDNAME_NO_THROW_SIGNATURES |
|
||||
UNDNAME_NO_SPECIAL_SYMS);
|
||||
|
||||
aDebugDump += StrFormat("%@ %@ %hs+%X\r\n",
|
||||
sf.AddrFrame.Offset, sf.AddrPC.Offset, aUDName, symDisplacement);
|
||||
|
||||
DWORD displacement = 0;
|
||||
#ifdef BF64
|
||||
IMAGEHLP_LINE64 lineInfo = { 0 };
|
||||
lineInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE64);
|
||||
#else
|
||||
IMAGEHLP_LINE lineInfo = { 0 };
|
||||
lineInfo.SizeOfStruct = sizeof(IMAGEHLP_LINE);
|
||||
#endif
|
||||
if (gSymGetLineFromAddr(hProcess, sf.AddrPC.Offset, &displacement, &lineInfo))
|
||||
{
|
||||
aDebugDump += StrFormat(" at %s:%d\r\n", lineInfo.FileName, lineInfo.LineNumber);
|
||||
}
|
||||
}
|
||||
else // No symbol found. Print out the logical address instead.
|
||||
{
|
||||
char szModule[MAX_PATH];
|
||||
szModule[0] = 0;
|
||||
uintptr section = 0, offset = 0;
|
||||
|
||||
GetLogicalAddress((PVOID)sf.AddrPC.Offset, szModule, sizeof(szModule), section, offset);
|
||||
aDebugDump += StrFormat("%@ %@ %04X:%@ %s\r\n", sf.AddrFrame.Offset, sf.AddrPC.Offset, section, offset, GetFileName(szModule).c_str());
|
||||
}
|
||||
|
||||
aDebugDump += StrFormat(" Params: %@ %@ %@ %@\r\n", sf.Params[0], sf.Params[1], sf.Params[2], sf.Params[3]);
|
||||
aDebugDump += "\r\n";
|
||||
|
||||
aLevelCount++;
|
||||
}
|
||||
|
||||
return aDebugDump;
|
||||
}
|
||||
|
||||
static String GetSysInfo()
|
||||
{
|
||||
return "";
|
||||
}
|
||||
|
||||
static void DoHandleDebugEvent(LPEXCEPTION_POINTERS lpEP)
|
||||
{
|
||||
if (gCrashed)
|
||||
return;
|
||||
gCrashed = true;
|
||||
|
||||
HMODULE hMod = GetModuleHandleA(NULL);
|
||||
|
||||
PIMAGE_DOS_HEADER pDosHdr = (PIMAGE_DOS_HEADER)hMod;
|
||||
PIMAGE_NT_HEADERS pNtHdr = (PIMAGE_NT_HEADERS)((uint8*)hMod + pDosHdr->e_lfanew);
|
||||
bool isCLI = pNtHdr->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_CUI;
|
||||
if (gCrashReportKind == BfpCrashReportKind_GUI)
|
||||
isCLI = false;
|
||||
else if ((gCrashReportKind == BfpCrashReportKind_Console) || (gCrashReportKind == BfpCrashReportKind_PrintOnly))
|
||||
isCLI = true;
|
||||
|
||||
bool hasImageHelp = LoadImageHelp();
|
||||
|
||||
String anErrorTitle;
|
||||
String aDebugDump;
|
||||
|
||||
char aBuffer[2048];
|
||||
|
||||
if (isCLI)
|
||||
aDebugDump += "**** FATAL APPLICATION ERROR ****\n";
|
||||
|
||||
for (auto func : gCrashInfoFuncs)
|
||||
func();
|
||||
|
||||
aDebugDump.Append(gCrashInfo);
|
||||
|
||||
for (int i = 0; i < (int)aDebugDump.length(); i++)
|
||||
{
|
||||
char c = aDebugDump[i];
|
||||
if (c == '\n')
|
||||
{
|
||||
aDebugDump.Insert(i, '\r');
|
||||
i++;
|
||||
}
|
||||
else if (c == '\t')
|
||||
{
|
||||
aDebugDump[i] = ' ';
|
||||
aDebugDump.Insert(i, ' ');
|
||||
}
|
||||
}
|
||||
|
||||
// aDebugDump.Replace("\n", "\r\n");
|
||||
// aDebugDump.Replace("\t", " ");
|
||||
|
||||
if (!aDebugDump.IsEmpty())
|
||||
{
|
||||
if (!aDebugDump.EndsWith("\n"))
|
||||
aDebugDump += "\r\n";
|
||||
|
||||
aDebugDump += "\r\n";
|
||||
}
|
||||
|
||||
///////////////////////////
|
||||
// first name the exception
|
||||
char *szName = NULL;
|
||||
for (int i = 0; gMsgTable[i].dwExceptionCode != 0xFFFFFFFF; i++)
|
||||
{
|
||||
if (gMsgTable[i].dwExceptionCode == lpEP->ExceptionRecord->ExceptionCode)
|
||||
{
|
||||
szName = gMsgTable[i].szMessage;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (szName != NULL)
|
||||
{
|
||||
aDebugDump += StrFormat("Exception: %s (code 0x%x) at address %@ in thread %X\r\n",
|
||||
szName, lpEP->ExceptionRecord->ExceptionCode,
|
||||
lpEP->ExceptionRecord->ExceptionAddress, GetCurrentThreadId());
|
||||
}
|
||||
else
|
||||
{
|
||||
aDebugDump += StrFormat("Unknown exception: (code 0x%x) at address %@ in thread %X\r\n",
|
||||
lpEP->ExceptionRecord->ExceptionCode,
|
||||
lpEP->ExceptionRecord->ExceptionAddress, GetCurrentThreadId());
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////
|
||||
// Get logical address of the module where exception occurs
|
||||
uintptr section, offset;
|
||||
GetLogicalAddress(lpEP->ExceptionRecord->ExceptionAddress, aBuffer, sizeof(aBuffer), section, offset);
|
||||
|
||||
CHAR path[MAX_PATH];
|
||||
GetModuleFileNameA(NULL, path, MAX_PATH);
|
||||
aDebugDump += "Executable: ";
|
||||
aDebugDump += path;
|
||||
aDebugDump += "\r\n";
|
||||
|
||||
aDebugDump += "Module: " + GetFileName(aBuffer) + "\r\n";
|
||||
aDebugDump += StrFormat("Logical Address: %04X:%@\r\n", section, offset);
|
||||
|
||||
aDebugDump += "\r\n";
|
||||
|
||||
anErrorTitle = StrFormat("Exception at %04X:%08X", section, offset);
|
||||
|
||||
String aWalkString;
|
||||
|
||||
if (hasImageHelp)
|
||||
aWalkString = ImageHelpWalk(lpEP->ContextRecord, 0);
|
||||
|
||||
/*if (aWalkString.length() == 0)
|
||||
aWalkString = IntelWalk(lpEP->ContextRecord, 0);*/
|
||||
|
||||
aDebugDump += aWalkString;
|
||||
|
||||
aDebugDump += "\r\n";
|
||||
|
||||
#ifdef BF64
|
||||
aDebugDump += StrFormat("RAX:%@ RBX:%@ RCX:%@ RDX:%@ RSI:%@ RDI:%@\r\n",
|
||||
lpEP->ContextRecord->Rax, lpEP->ContextRecord->Rbx, lpEP->ContextRecord->Rcx, lpEP->ContextRecord->Rdx, lpEP->ContextRecord->Rsi, lpEP->ContextRecord->Rdi);
|
||||
aDebugDump += StrFormat("R8:%@ R9:%@ R10:%@ R11:%@\r\nR12:%@ R13:%@ R14:%@ R15:%@\r\n",
|
||||
lpEP->ContextRecord->R8, lpEP->ContextRecord->R9, lpEP->ContextRecord->R10, lpEP->ContextRecord->R11, lpEP->ContextRecord->R12, lpEP->ContextRecord->R13, lpEP->ContextRecord->R14, lpEP->ContextRecord->R15);
|
||||
aDebugDump += StrFormat("EIP:%@ ESP:%@ EBP:%@\r\n", lpEP->ContextRecord->Rip, lpEP->ContextRecord->Rsp, lpEP->ContextRecord->Rbp);
|
||||
aDebugDump += StrFormat("CS:%04X SS:%04X DS:%04X ES:%04X FS:%04X GS:%04X\r\n", lpEP->ContextRecord->SegCs, lpEP->ContextRecord->SegSs, lpEP->ContextRecord->SegDs, lpEP->ContextRecord->SegEs, lpEP->ContextRecord->SegFs, lpEP->ContextRecord->SegGs);
|
||||
aDebugDump += StrFormat("Flags:%@\r\n", lpEP->ContextRecord->EFlags);
|
||||
#else
|
||||
aDebugDump += StrFormat("EAX:%08X EBX:%08X ECX:%08X EDX:%08X ESI:%08X EDI:%08X\r\n",
|
||||
lpEP->ContextRecord->Eax, lpEP->ContextRecord->Ebx, lpEP->ContextRecord->Ecx, lpEP->ContextRecord->Edx, lpEP->ContextRecord->Esi, lpEP->ContextRecord->Edi);
|
||||
aDebugDump += StrFormat("EIP:%08X ESP:%08X EBP:%08X\r\n", lpEP->ContextRecord->Eip, lpEP->ContextRecord->Esp, lpEP->ContextRecord->Ebp);
|
||||
aDebugDump += StrFormat("CS:%04X SS:%04X DS:%04X ES:%04X FS:%04X GS:%04X\r\n", lpEP->ContextRecord->SegCs, lpEP->ContextRecord->SegSs, lpEP->ContextRecord->SegDs, lpEP->ContextRecord->SegEs, lpEP->ContextRecord->SegFs, lpEP->ContextRecord->SegGs);
|
||||
aDebugDump += StrFormat("Flags:%08X\r\n", lpEP->ContextRecord->EFlags);
|
||||
#endif
|
||||
|
||||
aDebugDump += "\r\n";
|
||||
aDebugDump += GetSysInfo();
|
||||
|
||||
/*if (mApp != NULL)
|
||||
{
|
||||
String aGameSEHInfo = mApp->GetGameSEHInfo();
|
||||
if (aGameSEHInfo.length() > 0)
|
||||
{
|
||||
aDebugDump += "\r\n";
|
||||
aDebugDump += aGameSEHInfo;
|
||||
}
|
||||
|
||||
mApp->CopyToClipboard(aDebugDump);
|
||||
}
|
||||
|
||||
if (hasImageHelp)
|
||||
GetSymbolsFromMapFile(aDebugDump);*/
|
||||
|
||||
if (isCLI)
|
||||
{
|
||||
aDebugDump += "\n";
|
||||
//fwrite(aDebugDump.c_str(), 1, aDebugDump.length(), stderr);
|
||||
//fflush(stderr);
|
||||
DWORD bytesWritten;
|
||||
::WriteFile(::GetStdHandle(STD_ERROR_HANDLE), aDebugDump.c_str(), (DWORD)aDebugDump.length(), &bytesWritten, NULL);
|
||||
}
|
||||
else
|
||||
ShowErrorDialog(anErrorTitle, aDebugDump);
|
||||
}
|
||||
|
||||
CrashCatcher::CrashCatcher()
|
||||
{
|
||||
|
||||
}
|
||||
|
||||
static long __stdcall SEHFilter(LPEXCEPTION_POINTERS lpExceptPtr)
|
||||
{
|
||||
//OutputDebugStrF("SEH Filter! CraskReportKind:%d\n", gCrashReportKind);
|
||||
|
||||
if (gCrashReportKind == BfpCrashReportKind_None)
|
||||
{
|
||||
OutputDebugStrF("Silent Exiting\n");
|
||||
::TerminateProcess(GetCurrentProcess(), lpExceptPtr->ExceptionRecord->ExceptionCode);
|
||||
}
|
||||
|
||||
AutoCrit autoCrit(gBfpCritSect);
|
||||
//::ExitProcess();
|
||||
//quick_exit(1);
|
||||
|
||||
if (!gCrashed)
|
||||
{
|
||||
CreateMiniDump(lpExceptPtr);
|
||||
DoHandleDebugEvent(lpExceptPtr);
|
||||
}
|
||||
|
||||
//if (!gDebugError)
|
||||
//SetErrorMode(SEM_NOGPFAULTERRORBOX);
|
||||
|
||||
if (gCrashReportKind == BfpCrashReportKind_PrintOnly)
|
||||
{
|
||||
::TerminateProcess(GetCurrentProcess(), lpExceptPtr->ExceptionRecord->ExceptionCode);
|
||||
}
|
||||
|
||||
return EXCEPTION_CONTINUE_SEARCH;
|
||||
}
|
||||
|
||||
void CrashCatcher::Init()
|
||||
{
|
||||
gPreviousFilter = SetUnhandledExceptionFilter(SEHFilter);
|
||||
|
||||
//__try
|
||||
//{
|
||||
// // all of code normally inside of main or WinMain here...
|
||||
// int a = 123;
|
||||
// int b = 0;
|
||||
// a /= b;
|
||||
//}
|
||||
//__except (SEHFilter(GetExceptionInformation()))
|
||||
//{
|
||||
//
|
||||
//}
|
||||
}
|
||||
|
||||
void CrashCatcher::AddCrashInfoFunc(CrashInfoFunc crashInfoFunc)
|
||||
{
|
||||
AutoCrit autoCrit(gBfpCritSect);
|
||||
gCrashInfoFuncs.Add(crashInfoFunc);
|
||||
}
|
||||
|
||||
void CrashCatcher::AddInfo(const StringImpl& str)
|
||||
{
|
||||
AutoCrit autoCrit(gBfpCritSect);
|
||||
gCrashInfo.Append(str);
|
||||
}
|
||||
|
||||
void CrashCatcher::Crash(const StringImpl& str)
|
||||
{
|
||||
OutputDebugStrF("CrashCatcher::Crash\n");
|
||||
|
||||
gBfpCritSect.Lock();
|
||||
gCrashInfo.Append(str);
|
||||
|
||||
if (gPreviousFilter == NULL)
|
||||
{
|
||||
// A little late, but install handler now so we can catch this crash
|
||||
Init();
|
||||
}
|
||||
|
||||
gBfpCritSect.Unlock();
|
||||
|
||||
|
||||
__debugbreak();
|
||||
|
||||
// When we catch the exception information like this, it displays the dump correctly but
|
||||
// the minidump doesn't contain a valid callstack, so we need to rely on SetUnhandledExceptionFilter
|
||||
/*__try
|
||||
{
|
||||
::MessageBoxA(NULL, "A", "B", MB_ICONERROR);
|
||||
__debugbreak();
|
||||
}
|
||||
__except (SEHFilter(GetExceptionInformation()))
|
||||
{
|
||||
|
||||
}*/
|
||||
|
||||
exit(1);
|
||||
}
|
||||
|
||||
void CrashCatcher::SetCrashReportKind(BfpCrashReportKind crashReportKind)
|
||||
{
|
||||
gCrashReportKind = crashReportKind;
|
||||
}
|
22
BeefySysLib/platform/win/CrashCatcher.h
Normal file
22
BeefySysLib/platform/win/CrashCatcher.h
Normal file
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#include "../../BeefySysLib/Common.h"
|
||||
|
||||
NS_BF_BEGIN
|
||||
|
||||
typedef void(*CrashInfoFunc)();
|
||||
|
||||
class CrashCatcher
|
||||
{
|
||||
public:
|
||||
CrashCatcher();
|
||||
|
||||
void Init();
|
||||
void AddCrashInfoFunc(CrashInfoFunc crashInfoFunc);
|
||||
void AddInfo(const StringImpl& str);
|
||||
|
||||
void Crash(const StringImpl& str);
|
||||
void SetCrashReportKind(BfpCrashReportKind crashReportKind);
|
||||
};
|
||||
|
||||
NS_BF_END
|
1756
BeefySysLib/platform/win/DXRenderDevice.cpp
Normal file
1756
BeefySysLib/platform/win/DXRenderDevice.cpp
Normal file
File diff suppressed because it is too large
Load diff
311
BeefySysLib/platform/win/DXRenderDevice.h
Normal file
311
BeefySysLib/platform/win/DXRenderDevice.h
Normal file
|
@ -0,0 +1,311 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef BF_MINGW
|
||||
#define D3D11_APPEND_ALIGNED_ELEMENT ( 0xffffffff )
|
||||
#ifndef __C89_NAMELESS
|
||||
#define __C89_NAMELESS
|
||||
#define __C89_NAMELESSUNIONNAME
|
||||
#endif
|
||||
#pragma clang diagnostic ignored "-Wunknown-pragmas"
|
||||
#pragma clang diagnostic ignored "-Wunknown-attributes"
|
||||
#pragma clang diagnostic ignored "-Wunused-member-function"
|
||||
#pragma clang diagnostic ignored "-Wunused-conversion-function"
|
||||
#define __in
|
||||
#define __in_opt
|
||||
#define __in_ecount(a)
|
||||
#define __in_ecount_opt(a)
|
||||
#define __in_bcount(a)
|
||||
#define __in_bcount_opt(a)
|
||||
#define __inout
|
||||
#define __inout_opt
|
||||
#define __out
|
||||
#define __out_opt
|
||||
#define __out_bcount(a)
|
||||
#define __out_bcount_opt(a)
|
||||
#define __out_ecount(a)
|
||||
#define __out_ecount_opt(a)
|
||||
#define __out_ecount_part_opt(a, b)
|
||||
#endif
|
||||
|
||||
#pragma warning (push)
|
||||
#pragma warning (disable:4005)
|
||||
#include <d3d11.h>
|
||||
#pragma warning (pop)
|
||||
|
||||
#ifdef BF_MINGW
|
||||
#undef __in
|
||||
#undef __out
|
||||
#endif
|
||||
|
||||
#include "Common.h"
|
||||
#include "gfx/Shader.h"
|
||||
#include "gfx/Texture.h"
|
||||
#include "gfx/RenderDevice.h"
|
||||
#include "gfx/DrawLayer.h"
|
||||
#include "gfx/ModelInstance.h"
|
||||
#include "util/HashSet.h"
|
||||
#include <map>
|
||||
|
||||
NS_BF_BEGIN;
|
||||
|
||||
class BFApp;
|
||||
class DXRenderDevice;
|
||||
|
||||
class DXTexture : public Texture
|
||||
{
|
||||
public:
|
||||
DXRenderDevice* mRenderDevice;
|
||||
ID3D11Texture2D* mD3DTexture;
|
||||
ID3D11ShaderResourceView* mD3DResourceView;
|
||||
ID3D11RenderTargetView* mD3DRenderTargetView;
|
||||
ID3D11Texture2D* mD3DDepthBuffer;
|
||||
ID3D11DepthStencilView* mD3DDepthStencilView;
|
||||
ImageData* mImageData;
|
||||
|
||||
public:
|
||||
DXTexture();
|
||||
~DXTexture();
|
||||
|
||||
void ReleaseNative();
|
||||
void ReinitNative();
|
||||
|
||||
virtual void PhysSetAsTarget() override;
|
||||
virtual void Blt(ImageData* imageData, int x, int y) override;
|
||||
virtual void SetBits(int destX, int destY, int destWidth, int destHeight, int srcPitch, uint32* bits) override;
|
||||
};
|
||||
|
||||
class DXShaderParam : public ShaderParam
|
||||
{
|
||||
public:
|
||||
ID3D10EffectVariable* mD3DVariable;
|
||||
|
||||
public:
|
||||
DXShaderParam();
|
||||
~DXShaderParam();
|
||||
|
||||
virtual void SetTexture(Texture* texture);
|
||||
virtual void SetFloat4(float x, float y, float z, float w) override;
|
||||
};
|
||||
|
||||
typedef std::map<String, DXShaderParam*> DXShaderParamMap;
|
||||
|
||||
class DXShader : public Shader
|
||||
{
|
||||
public:
|
||||
ID3D11InputLayout* mD3DLayout;
|
||||
ID3D11VertexShader* mD3DVertexShader;
|
||||
ID3D11PixelShader* mD3DPixelShader;
|
||||
DXShaderParamMap mParamsMap;
|
||||
ID3D11Buffer* mConstBuffer;
|
||||
bool mHas2DPosition;
|
||||
|
||||
public:
|
||||
DXShader();
|
||||
~DXShader();
|
||||
|
||||
virtual ShaderParam* GetShaderParam(const StringImpl& name) override;
|
||||
};
|
||||
|
||||
class DXDrawBatch : public DrawBatch
|
||||
{
|
||||
public:
|
||||
|
||||
public:
|
||||
DXDrawBatch();
|
||||
~DXDrawBatch();
|
||||
|
||||
virtual void Render(RenderDevice* renderDevice, RenderWindow* renderWindow) override;
|
||||
};
|
||||
|
||||
class DXDrawLayer : public DrawLayer
|
||||
{
|
||||
public:
|
||||
virtual DrawBatch* CreateDrawBatch();
|
||||
virtual RenderCmd* CreateSetTextureCmd(int textureIdx, Texture* texture) override;
|
||||
virtual void SetShaderConstantData(int slotIdx, void* constData, int size) override;
|
||||
virtual void SetShaderConstantDataTyped(int slotIdx, void* constData, int size, int* typeData, int typeCount) override;
|
||||
|
||||
public:
|
||||
DXDrawLayer();
|
||||
~DXDrawLayer();
|
||||
};
|
||||
|
||||
class DXRenderWindow : public RenderWindow
|
||||
{
|
||||
public:
|
||||
HWND mHWnd;
|
||||
DXRenderDevice* mDXRenderDevice;
|
||||
IDXGISwapChain* mDXSwapChain;
|
||||
ID3D11Texture2D* mD3DBackBuffer;
|
||||
ID3D11RenderTargetView* mD3DRenderTargetView;
|
||||
ID3D11Texture2D* mD3DDepthBuffer;
|
||||
ID3D11DepthStencilView* mD3DDepthStencilView;
|
||||
bool mResizePending;
|
||||
bool mWindowed;
|
||||
int mPendingWidth;
|
||||
int mPendingHeight;
|
||||
|
||||
public:
|
||||
virtual void PhysSetAsTarget();
|
||||
|
||||
public:
|
||||
DXRenderWindow(DXRenderDevice* renderDevice, HWND hWnd, bool windowed);
|
||||
~DXRenderWindow();
|
||||
|
||||
void ReleaseNative();
|
||||
void ReinitNative();
|
||||
|
||||
void SetAsTarget() override;
|
||||
void Resized() override;
|
||||
virtual void Present() override;
|
||||
|
||||
void CopyBitsTo(uint32* dest, int width, int height);
|
||||
};
|
||||
|
||||
typedef std::vector<DXDrawBatch*> DXDrawBatchVector;
|
||||
|
||||
#define DX_VTXBUFFER_SIZE 1024*1024
|
||||
#define DX_IDXBUFFER_SIZE 64*1024
|
||||
|
||||
class DXDrawBufferPool
|
||||
{
|
||||
public:
|
||||
std::vector<void*> mPooledIndexBuffers;
|
||||
int mIdxPoolIdx;
|
||||
std::vector<void*> mPooledVertexBuffers;
|
||||
int mVtxPoolIdx;
|
||||
|
||||
void* mIndexBuffer;
|
||||
void* mVertexBuffer;
|
||||
int mIdxByteIdx;
|
||||
int mVtxByteIdx;
|
||||
|
||||
void AllocateIndices(int minIndices);
|
||||
void AllocVertices(int minVertices);
|
||||
};
|
||||
|
||||
class DXRenderState : public RenderState
|
||||
{
|
||||
public:
|
||||
ID3D11RasterizerState* mD3DRasterizerState;
|
||||
ID3D11DepthStencilState* mD3DDepthStencilState;
|
||||
|
||||
public:
|
||||
DXRenderState();
|
||||
~DXRenderState();
|
||||
|
||||
void ReleaseNative();
|
||||
void ReinitNative();
|
||||
|
||||
void InvalidateRasterizerState();
|
||||
void IndalidateDepthStencilState();
|
||||
|
||||
virtual void SetClipped(bool clipped);
|
||||
virtual void SetClipRect(const Rect& rect);
|
||||
virtual void SetWriteDepthBuffer(bool writeDepthBuffer);
|
||||
virtual void SetDepthFunc(DepthFunc depthFunc);
|
||||
};
|
||||
|
||||
class DXModelMesh
|
||||
{
|
||||
public:
|
||||
int mNumIndices;
|
||||
int mNumVertices;
|
||||
DXTexture* mTexture;
|
||||
|
||||
ID3D11Buffer* mD3DIndexBuffer;
|
||||
//TODO: Split the vertex buffer up into static and dynamic buffers
|
||||
ID3D11Buffer* mD3DVertexBuffer;
|
||||
|
||||
public:
|
||||
DXModelMesh();
|
||||
~DXModelMesh();
|
||||
};
|
||||
|
||||
class DXModelInstance : public ModelInstance
|
||||
{
|
||||
public:
|
||||
DXRenderDevice* mD3DRenderDevice;
|
||||
std::vector<DXModelMesh> mDXModelMeshs;
|
||||
|
||||
public:
|
||||
DXModelInstance(ModelDef* modelDef);
|
||||
~DXModelInstance();
|
||||
|
||||
virtual void CommandQueued(DrawLayer* drawLayer) override;
|
||||
virtual void Render(RenderDevice* renderDevice, RenderWindow* renderWindow) override;
|
||||
};
|
||||
|
||||
class DXVertexDefinition : public VertexDefinition
|
||||
{
|
||||
public:
|
||||
~DXVertexDefinition();
|
||||
};
|
||||
|
||||
class DXSetTextureCmd : public RenderCmd
|
||||
{
|
||||
public:
|
||||
int mTextureIdx;
|
||||
Texture* mTexture;
|
||||
|
||||
public:
|
||||
virtual void Render(RenderDevice* renderDevice, RenderWindow* renderWindow) override;
|
||||
};
|
||||
|
||||
class DXSetConstantData : public RenderCmd
|
||||
{
|
||||
public:
|
||||
int mUsageIdx; // 0 = VS, 1 = PS
|
||||
int mSlotIdx;
|
||||
int mSize;
|
||||
uint8 mData[1];
|
||||
|
||||
public:
|
||||
virtual void Render(RenderDevice* renderDevice, RenderWindow* renderWindow) override;
|
||||
};
|
||||
|
||||
class DXRenderDevice : public RenderDevice
|
||||
{
|
||||
public:
|
||||
IDXGIFactory* mDXGIFactory;
|
||||
ID3D11Device* mD3DDevice;
|
||||
ID3D11DeviceContext* mD3DDeviceContext;
|
||||
ID3D11BlendState* mD3DNormalBlendState;
|
||||
ID3D11SamplerState* mD3DDefaultSamplerState;
|
||||
bool mHasVSync;
|
||||
|
||||
ID3D11Buffer* mD3DVertexBuffer;
|
||||
ID3D11Buffer* mD3DIndexBuffer;
|
||||
int mVtxByteIdx;
|
||||
int mIdxByteIdx;
|
||||
|
||||
HashSet<DXRenderState*> mRenderStates;
|
||||
HashSet<DXTexture*> mTextures;
|
||||
|
||||
public:
|
||||
virtual void PhysSetRenderState(RenderState* renderState) override;
|
||||
virtual void PhysSetRenderWindow(RenderWindow* renderWindow);
|
||||
virtual void PhysSetRenderTarget(Texture* renderTarget) override;
|
||||
virtual RenderState* CreateRenderState(RenderState* srcRenderState) override;
|
||||
virtual ModelInstance* CreateModelInstance(ModelDef* modelDef) override;
|
||||
|
||||
public:
|
||||
DXRenderDevice();
|
||||
virtual ~DXRenderDevice();
|
||||
bool Init(BFApp* app) override;
|
||||
|
||||
void ReleaseNative();
|
||||
void ReinitNative();
|
||||
|
||||
void FrameStart() override;
|
||||
void FrameEnd() override;
|
||||
|
||||
Texture* LoadTexture(ImageData* imageData, int flags) override;
|
||||
Texture* CreateDynTexture(int width, int height) override;
|
||||
Shader* LoadShader(const StringImpl& fileName, VertexDefinition* vertexDefinition) override;
|
||||
Texture* CreateRenderTarget(int width, int height, bool destAlpha) override;
|
||||
|
||||
void SetRenderState(RenderState* renderState) override;
|
||||
};
|
||||
|
||||
NS_BF_END;
|
3341
BeefySysLib/platform/win/Platform.cpp
Normal file
3341
BeefySysLib/platform/win/Platform.cpp
Normal file
File diff suppressed because it is too large
Load diff
17
BeefySysLib/platform/win/PlatformApp.h
Normal file
17
BeefySysLib/platform/win/PlatformApp.h
Normal file
|
@ -0,0 +1,17 @@
|
|||
#pragma once
|
||||
|
||||
#ifdef BF_FORCE_SDL
|
||||
#include "SdlBFApp.h"
|
||||
#else
|
||||
#include "WinBFApp.h"
|
||||
#endif
|
||||
|
||||
NS_BF_BEGIN;
|
||||
|
||||
#ifdef BF_FORCE_SDL
|
||||
typedef SdlBFApp PlatformBFApp;
|
||||
#else
|
||||
typedef WinBFApp PlatformBFApp;
|
||||
#endif
|
||||
|
||||
NS_BF_END;
|
1691
BeefySysLib/platform/win/WinBFApp.cpp
Normal file
1691
BeefySysLib/platform/win/WinBFApp.cpp
Normal file
File diff suppressed because it is too large
Load diff
117
BeefySysLib/platform/win/WinBFApp.h
Normal file
117
BeefySysLib/platform/win/WinBFApp.h
Normal file
|
@ -0,0 +1,117 @@
|
|||
#pragma once
|
||||
|
||||
#include "Common.h"
|
||||
#include "BFApp.h"
|
||||
#include "BFWindow.h"
|
||||
#include "util/Dictionary.h"
|
||||
|
||||
|
||||
NS_BF_BEGIN;
|
||||
|
||||
class RenderDevice;
|
||||
|
||||
typedef Dictionary<void*, HGLOBAL> PtrToHGlobalMap;
|
||||
typedef Dictionary<String, uint32> StringToUIntMap;
|
||||
|
||||
class WinBFMenu : public BFMenu
|
||||
{
|
||||
public:
|
||||
HMENU mMenu;
|
||||
uint32 mMenuId;
|
||||
static int mMenuCount;
|
||||
bool mIsPlaceholder;
|
||||
|
||||
public:
|
||||
WinBFMenu();
|
||||
};
|
||||
|
||||
typedef Dictionary<uint32, WinBFMenu*> WinMenuIDMap;
|
||||
typedef Dictionary<HMENU, WinBFMenu*> WinHMenuMap;
|
||||
|
||||
class WinBFWindow : public BFWindow
|
||||
{
|
||||
public:
|
||||
HWND mHWnd;
|
||||
bool mIsMouseInside;
|
||||
WinMenuIDMap mMenuIDMap;
|
||||
WinHMenuMap mHMenuMap;
|
||||
|
||||
int mModalCount;
|
||||
int mAlphaMaskWidth;
|
||||
int mAlphaMaskHeight;
|
||||
HBITMAP mAlphaMaskBitmap;
|
||||
HDC mAlphaMaskDC;
|
||||
uint32* mAlphaMaskPixels;
|
||||
bool mIsMenuKeyHandled;
|
||||
int mMinWidth;
|
||||
int mMinHeight;
|
||||
bool mMouseVisible;
|
||||
bool mHasFocus;
|
||||
bool mSoftHasFocus; // Mostly tracks mHasFocus except for when we get an explicit 'LostFocus' callback
|
||||
|
||||
bool mNeedsStateReset;
|
||||
|
||||
public:
|
||||
virtual LRESULT WindowProc(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
|
||||
static LRESULT CALLBACK WindowProcStub(HWND hWnd, UINT Msg, WPARAM wParam, LPARAM lParam);
|
||||
void RehupMouseOver(bool isMouseOver);
|
||||
|
||||
public:
|
||||
WinBFWindow(BFWindow* parent, const StringImpl& title, int x, int y, int width, int height, int windowFlags);
|
||||
~WinBFWindow();
|
||||
|
||||
virtual void* GetUnderlying() override;
|
||||
virtual void Destroy() override;
|
||||
virtual bool TryClose() override;
|
||||
virtual void SetTitle(const char* title) override;
|
||||
virtual void SetForeground() override;
|
||||
virtual void LostFocus(BFWindow* newFocus) override;
|
||||
virtual void SetMinimumSize(int minWidth, int minHeight, bool clientSized) override;
|
||||
virtual void GetPosition(int* x, int* y, int* width, int* height, int* clientX, int* clientY, int* clientWidth, int* clientHeight) override;
|
||||
virtual void Resize(int x, int y, int width, int height) override;
|
||||
virtual void SetClientPosition(int x, int y) override;
|
||||
virtual void SetMouseVisible(bool isMouseVisible) override;
|
||||
virtual void SetAlpha(float alpha, uint32 destAlphaSrcMask, bool isMouseVisible) override;
|
||||
virtual void CaptureMouse() override;
|
||||
virtual bool IsMouseCaptured() override;
|
||||
|
||||
virtual BFMenu* AddMenuItem(BFMenu* parent, int insertIdx, const char* text, const char* hotKey, BFSysBitmap* bitmap, bool enabled, int checkState, bool radioCheck) override;
|
||||
virtual void ModifyMenuItem(BFMenu* item, const char* text, const char* hotKey, BFSysBitmap* bitmap, bool enabled, int checkState, bool radioCheck) override;
|
||||
virtual void RemoveMenuItem(BFMenu* item) override;
|
||||
virtual void ModalsRemoved() override;
|
||||
};
|
||||
|
||||
class WinBFApp : public BFApp
|
||||
{
|
||||
public:
|
||||
bool mInMsgProc;
|
||||
PtrToHGlobalMap mLockedHGlobalMap;
|
||||
StringToUIntMap mClipboardFormatMap;
|
||||
|
||||
protected:
|
||||
virtual void Draw() override;
|
||||
virtual void PhysSetCursor() override;
|
||||
|
||||
uint32 GetClipboardFormat(const StringImpl& format);
|
||||
|
||||
public:
|
||||
WinBFApp();
|
||||
virtual ~WinBFApp();
|
||||
|
||||
virtual void Init() override;
|
||||
virtual void Run() override;
|
||||
|
||||
virtual void GetDesktopResolution(int& width, int& height);
|
||||
virtual void GetWorkspaceRect(int& x, int& y, int& width, int& height);
|
||||
virtual BFWindow* CreateNewWindow(BFWindow* parent, const StringImpl& title, int x, int y, int width, int height, int windowFlags) override;
|
||||
virtual DrawLayer* CreateDrawLayer(BFWindow* window);
|
||||
|
||||
virtual void* GetClipboardData(const StringImpl& format, int* size) override;
|
||||
virtual void ReleaseClipboardData(void* ptr) override;
|
||||
virtual void SetClipboardData(const StringImpl& format, const void* ptr, int size, bool resetClipboard) override;
|
||||
virtual void RehupMouse() override;
|
||||
|
||||
virtual BFSysBitmap* LoadSysBitmap(const WCHAR* fileName) override;
|
||||
};
|
||||
|
||||
NS_BF_END;
|
Loading…
Add table
Add a link
Reference in a new issue