1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-07-04 23:36:00 +02:00

Initial checkin

This commit is contained in:
Brian Fiete 2019-08-23 11:56:54 -07:00
parent c74712dad9
commit 078564ac9e
3242 changed files with 1616395 additions and 0 deletions

View 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; \
}\
}

View 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);

File diff suppressed because it is too large Load diff

View 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);
}

View file

@ -0,0 +1,9 @@
#pragma once
#include "../sdl/SdlBFApp.h"
NS_BF_BEGIN;
typedef SdlBFApp PlatformBFApp;
NS_BF_END;

View 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>

View 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

View 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>

View 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"

File diff suppressed because it is too large Load diff

View 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);
}

View file

@ -0,0 +1,9 @@
#pragma once
#include "../../HeadlessApp.h"
NS_BF_BEGIN;
typedef HeadlessApp PlatformBFApp;
NS_BF_END;

View 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);

View 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>

View 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

File diff suppressed because it is too large Load diff

View 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;

View 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;
}

View 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;

View 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"

View 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;
}

View 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

File diff suppressed because it is too large Load diff

View 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;

File diff suppressed because it is too large Load diff

View 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;

File diff suppressed because it is too large Load diff

View 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;