1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-07-08 09:16: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

263
BeefySysLib/BFApp.cpp Normal file
View file

@ -0,0 +1,263 @@
#include "BFApp.h"
#include "BFWindow.h"
#include "gfx/RenderDevice.h"
#include "FileStream.h"
#include "util/BSpline.h"
#include "util/PerfTimer.h"
#include "sound/WwiseSound.h"
#include "util/AllocDebug.h"
#pragma warning(disable:4996)
USING_NS_BF;
BFApp* Beefy::gBFApp = NULL;
BFApp::BFApp()
{
mTitle = "Beefy Application";
mRefreshRate = 60;
mLastProcessTick = BFTickCount();
mFrameTimeAcc = 0;
mDrawEnabled = true;
mUpdateFunc = NULL;
mDrawFunc = NULL;
gBFApp = this;
mSysDialogCnt = 0;
mCursor = CURSOR_POINTER;
mInProcess = false;
mUpdateCnt = 0;
mVSynched = true;
mMaxUpdatesPerDraw = 60; // 8?
mUpdateSampleCount = 0;
mUpdateSampleTimes = 0;
if (gPerfManager == NULL)
gPerfManager = new PerfManager();
mRunning = false;
mRenderDevice = NULL;
mVSynched = false;
}
BFApp::~BFApp()
{
gBFApp = NULL;
delete gPerfManager;
for (auto window : mPendingWindowDeleteList)
delete window;
}
void BFApp::Init()
{
}
void BFApp::Run()
{
}
void BFApp::Shutdown()
{
mRunning = false;
}
void BFApp::SetCursor(int cursor)
{
mCursor = cursor;
PhysSetCursor();
}
void BFApp::Update(bool batchStart)
{
//Beefy::DebugTimeGuard suspendTimeGuard(30, "BFApp::Update");
#ifdef BF_WWISE_ENABLED
WWiseUpdate();
#endif
mUpdateCnt++;
gPerfManager->NextFrame();
gPerfManager->ZoneStart("BFApp::Update");
mUpdateFunc(batchStart);
gPerfManager->ZoneEnd();
for (auto window : mPendingWindowDeleteList)
delete window;
mPendingWindowDeleteList.clear();
}
void BFApp::Draw()
{
gPerfManager->ZoneStart("BFApp::Draw");
mDrawFunc();
gPerfManager->ZoneEnd();
}
//#define PERIODIC_PERF_TIMING
void BFApp::Process()
{
//Beefy::DebugTimeGuard suspendTimeGuard(30, "BFApp::Process");
if (mInProcess)
return; // No reentry
mInProcess = true;
int updates;
uint32 tickNow = BFTickCount();
const int vSyncTestingPeriod = 250;
if (mRefreshRate != 0)
{
float ticksPerFrame = 1000.0f / mRefreshRate;
int ticksSinceLastProcess = tickNow - mLastProcessTick;
mUpdateSampleCount++;
mUpdateSampleTimes += ticksSinceLastProcess;
//TODO: Turn off mVSynched based on error calculations - (?)
// Two VSync failures in a row means we set mVSyncFailed and permanently disable it
if (mUpdateSampleTimes >= vSyncTestingPeriod)
{
int expectedFrames = (int)(mUpdateSampleTimes / ticksPerFrame);
if (mUpdateSampleCount > expectedFrames * 1.5)
{
if (!mVSynched)
mVSyncFailed = true;
mVSynched = false;
}
else
if (!mVSyncFailed)
mVSynched = true;
mUpdateSampleCount = 0;
mUpdateSampleTimes = 0;
}
mFrameTimeAcc += tickNow - mLastProcessTick;
bool vSynched = mVSynched;
if (vSynched)
{
// For the startup, try not to go hyper during those first samplings
if (mUpdateSampleTimes <= vSyncTestingPeriod)
{
if (ticksSinceLastProcess < ticksPerFrame / 1.5)
vSynched = false;
}
}
if (vSynched)
{
updates = std::max(1, (int)(mFrameTimeAcc / ticksPerFrame + 0.5f));
mFrameTimeAcc = std::max(0.0f, mFrameTimeAcc - ticksPerFrame * updates);
}
else
{
updates = std::max(0, (int)(mFrameTimeAcc / ticksPerFrame));
mFrameTimeAcc = mFrameTimeAcc - ticksPerFrame * updates;
}
if (updates > mRefreshRate)
{
// If more than 1 second of updates is queued, just re-sync
updates = 1;
mFrameTimeAcc = 0;
}
updates = std::min(updates, mMaxUpdatesPerDraw);
/*if (updates > 2)
OutputDebugStrF("Updates: %d TickDelta: %d\n", updates, tickNow - mLastProcessTick);*/
}
else
updates = 1; // RefreshRate of 0 means to update as fast as possible
if (updates == 0)
{
// Yield
BfpThread_Sleep(1);
}
static uint32 lastUpdate = BFTickCount();
#ifdef PERIODIC_PERF_TIMING
bool perfTime = (tickNow - lastUpdate >= 5000) && (updates > 0);
if (perfTime)
{
updates = 1;
lastUpdate = tickNow;
if (perfTime)
gPerfManager->StartRecording();
}
#endif
for (int updateNum = 0; updateNum < updates; updateNum++)
Update(updateNum == 0);
if ((mRunning) && (updates > 0))
Draw();
#ifdef PERIODIC_PERF_TIMING
if (perfTime)
{
gPerfManager->StopRecording();
gPerfManager->DbgPrint();
}
#endif
mLastProcessTick = tickNow;
mInProcess = false;
}
void BFApp::RemoveWindow(BFWindow* window)
{
auto itr = std::find(mWindowList.begin(), mWindowList.end(), window);
if (itr == mWindowList.end()) // Allow benign failure (double removal)
return;
mWindowList.erase(itr);
while (window->mChildren.size() > 0)
RemoveWindow(window->mChildren.front());
if (window->mParent != NULL)
{
window->mParent->mChildren.erase(std::find(window->mParent->mChildren.begin(), window->mParent->mChildren.end(), window));
if (window->mFlags & BFWINDOW_MODAL)
{
bool hasModal = false;
for (auto childWindow : window->mParent->mChildren)
{
if (childWindow->mFlags & BFWINDOW_MODAL)
hasModal = true;
}
if (!hasModal)
window->mParent->ModalsRemoved();
}
}
window->mClosedFunc(window);
mRenderDevice->RemoveRenderWindow(window->mRenderWindow);
window->Destroy();
mPendingWindowDeleteList.push_back(window);
}
FileStream* BFApp::OpenBinaryFile(const StringImpl& fileName)
{
FILE* fP = fopen(fileName.c_str(), "rb");
if (fP == NULL)
return NULL;
FileStream* fileStream = new FileStream();
fileStream->mFP = fP;
return fileStream;
}

106
BeefySysLib/BFApp.h Normal file
View file

@ -0,0 +1,106 @@
#pragma once
#include "Common.h"
#include <list>
NS_BF_BEGIN;
typedef void (*BFApp_UpdateFunc)(bool batchStart);
typedef void (*BFApp_DrawFunc)();
class BFApp;
class RenderDevice;
class BFWindow;
class FileStream;
class DrawLayer;
typedef std::list<BFWindow*> BFWindowList;
enum
{
CURSOR_POINTER,
CURSOR_HAND,
CURSOR_DRAGGING,
CURSOR_TEXT,
CURSOR_CIRCLE_SLASH,
CURSOR_SIZEALL,
CURSOR_SIZENESW,
CURSOR_SIZENS,
CURSOR_SIZENWSE,
CURSOR_SIZEWE,
CURSOR_WAIT,
CURSOR_NONE,
NUM_CURSORS
};
class BFSysBitmap
{
public:
};
class BFApp
{
public:
String mTitle;
String mInstallDir;
String mDataDir;
bool mDrawEnabled;
float mRefreshRate;
int mMaxUpdatesPerDraw;
bool mInProcess;
bool mRunning;
RenderDevice* mRenderDevice;
int mSysDialogCnt;
int mUpdateCnt;
bool mVSynched;
bool mVSyncFailed;
int mUpdateSampleCount;
int mUpdateSampleTimes;
uint32 mLastProcessTick;
float mFrameTimeAcc;
BFApp_UpdateFunc mUpdateFunc;
BFApp_DrawFunc mDrawFunc;
int mCursor;
BFWindowList mWindowList;
BFWindowList mPendingWindowDeleteList;
public:
virtual void Update(bool batchStart);
virtual void Draw();
virtual void Process();
virtual void PhysSetCursor() = 0;
public:
BFApp();
virtual ~BFApp();
virtual void Init();
virtual void Run();
virtual void Shutdown();
virtual void SetCursor(int cursor);
virtual void GetDesktopResolution(int& width, int& height) = 0;
virtual void GetWorkspaceRect(int& x, int& y, int& width, int& height) = 0;
virtual BFWindow* CreateNewWindow(BFWindow* parent, const StringImpl& title, int x, int y, int width, int height, int windowFlags) = 0;
virtual void RemoveWindow(BFWindow* window);
virtual DrawLayer* CreateDrawLayer(BFWindow* window) = 0;
virtual void* GetClipboardData(const StringImpl& format, int* size) = 0;
virtual void ReleaseClipboardData(void* ptr) = 0;
virtual void SetClipboardData(const StringImpl& format, const void* ptr, int size, bool resetClipboard) = 0;
virtual void RehupMouse() {}
virtual BFSysBitmap* LoadSysBitmap(const wchar_t* fileName) = 0;
virtual FileStream* OpenBinaryFile(const StringImpl& fileName);
};
extern BFApp* gBFApp;
NS_BF_END;

170
BeefySysLib/BFWindow.cpp Normal file
View file

@ -0,0 +1,170 @@
#include "BFWindow.h"
#include "gfx/RenderDevice.h"
USING_NS_BF;
BFMenu::BFMenu()
{
mParent = NULL;
mKeyCode = 0;
mKeyCtrl = 0;
mKeyAlt = 0;
mKeyShift = 0;
}
struct BFNamedVirtKey
{
public:
const char* mName;
int mKeyCode;
};
#define VK_SPACE 0x20
#define VK_PRIOR 0x21
#define VK_NEXT 0x22
#define VK_END 0x23
#define VK_HOME 0x24
#define VK_LEFT 0x25
#define VK_UP 0x26
#define VK_RIGHT 0x27
#define VK_DOWN 0x28
#define VK_SELECT 0x29
#define VK_PRINT 0x2A
#define VK_EXECUTE 0x2B
#define VK_SNAPSHOT 0x2C
#define VK_INSERT 0x2D
#define VK_DELETE 0x2E
#define VK_HELP 0x2F
#define VK_F1 0x70
#define VK_F2 0x71
#define VK_F3 0x72
#define VK_F4 0x73
#define VK_F5 0x74
#define VK_F6 0x75
#define VK_F7 0x76
#define VK_F8 0x77
#define VK_F9 0x78
#define VK_F10 0x79
#define VK_F11 0x7A
#define VK_F12 0x7B
#define VK_SEMICOLON 0xBA
#define VK_EQUALS 0xBB
#define VK_COMMA 0xBC
#define VK_MINUS 0xBD
#define VK_PERIOD 0xBE
#define VK_SLASH 0xBF
#define VK_GRAVE 0xC0
#define VK_LBRACKET 0xDB
#define VK_BACKSLASH 0xDC
#define VK_RBRACKET 0xDD
#define VK_APOSTROPHE 0xDE
#define VK_BACKTICK 0xDF
#define VK_PAUSE 0x13
#define VK_CANCEL 0x03
static BFNamedVirtKey gNamedKeys[] =
{{"F1", VK_F1}, {"F2", VK_F2}, {"F3", VK_F3}, {"F4", VK_F4}, {"F5", VK_F5}, {"F6", VK_F6},
{"F7", VK_F7}, {"F8", VK_F8}, {"F9", VK_F9}, {"F10", VK_F10}, {"F11", VK_F11}, {"F12", VK_F12},
{"INSERT", VK_INSERT}, {"INSERT", VK_INSERT}, {"DE", VK_DELETE}, {"DELETE", VK_DELETE},
{"BREAK", VK_PAUSE},
{"HOME", VK_HOME}, {"END", VK_END}, {"PGUP", VK_PRIOR}, {"PAGEUP", VK_PRIOR}, {"PGDN", VK_NEXT}, {"PAGEDN", VK_NEXT}, {"PAGEDOWN", VK_NEXT},
{"UP", VK_UP}, {"LEFT", VK_LEFT}, {"RIGHT", VK_RIGHT}, {"DOWN", VK_DOWN}
};
bool BFMenu::ParseHotKey(const StringImpl& hotKey)
{
String aHotKey = ToUpper(hotKey);
if (aHotKey.StartsWith("#"))
return false;
while (true)
{
int idx = (int)aHotKey.IndexOf('+');
if (idx == -1)
idx = (int)aHotKey.IndexOf('-');
if (idx == -1)
break;
String aModifier = Trim(aHotKey.Substring(0, idx));
aHotKey = Trim(aHotKey.Substring(idx + 1));
if (aModifier == "SHIFT")
mKeyShift = true;
else if (aModifier == "CTRL")
mKeyCtrl = true;
else if (aModifier == "ALT")
mKeyAlt = true;
else
{
BF_FATAL("Unknown hotkey modifier");
return false;
}
}
if (aHotKey.length() == 1)
{
if (aHotKey == ",")
mKeyCode = /*VK_COMMA*/0xBC;
else
mKeyCode = (int) aHotKey[0];
return true;
}
int count = sizeof(gNamedKeys) / sizeof(BFNamedVirtKey);
for (int i = 0; i < count; i++)
{
if (aHotKey == gNamedKeys[i].mName)
{
mKeyCode = gNamedKeys[i].mKeyCode;
if ((mKeyCode == VK_PAUSE) && (mKeyCtrl))
{
// Ctrl-Pause is really "Cancel"
mKeyCode = VK_CANCEL;
}
return true;
}
}
BF_FATAL("Unknown hotkey key name");
return false;
}
///
BFWindow::BFWindow()
{
mParent = NULL;
mMenu = NULL;
mRenderWindow = NULL;
mNonExclusiveMouseCapture = false;
mParent = NULL;
mMovedFunc = NULL;
mCloseQueryFunc = NULL;
mClosedFunc = NULL;
mGotFocusFunc = NULL;
mLostFocusFunc = NULL;
mKeyCharFunc = NULL;
mKeyDownFunc = NULL;
mKeyUpFunc = NULL;
mMouseMoveFunc = NULL;
mMouseProxyMoveFunc = NULL;
mMouseDownFunc = NULL;
mMouseUpFunc = NULL;
mMouseWheelFunc = NULL;
mMouseLeaveFunc = NULL;
mMenuItemSelectedFunc = NULL;
mHitTestFunc = NULL;
mFlags = 0;
for (int i = 0; i < KEYCODE_MAX; i++)
mIsKeyDown[i] = false;
for (int i = 0; i < MOUSEBUTTON_MAX; i++)
mIsMouseDown[i] = false;
}
BFWindow::~BFWindow()
{
delete mRenderWindow;
delete mMenu;
}

137
BeefySysLib/BFWindow.h Normal file
View file

@ -0,0 +1,137 @@
#pragma once
#include "Common.h"
NS_BF_BEGIN;
class BFMenu;
class BFWindow;
typedef void (*BFWindow_MovedFunc)(BFWindow* window);
typedef int (*BFWindow_CloseQueryFunc)(BFWindow* window);
typedef void (*BFWindow_ClosedFunc)(BFWindow* window);
typedef void (*BFWindow_GotFocusFunc)(BFWindow* window);
typedef void (*BFWindow_LostFocusFunc)(BFWindow* window);
typedef void (*BFWindow_KeyCharFunc)(BFWindow* window, wchar_t theChar);
typedef bool (*BFWindow_KeyDownFunc)(BFWindow* window, int keyCode, int isRepeat);
typedef void (*BFWindow_KeyUpFunc)(BFWindow* window, int keyCode);
typedef int (*BFWindow_HitTestFunc)(BFWindow* window, int x, int y);
typedef void (*BFWindow_MouseMove)(BFWindow* window, int x, int y);
typedef void (*BFWindow_MouseProxyMove)(BFWindow* window, int x, int y);
typedef void (*BFWindow_MouseDown)(BFWindow* window, int x, int y, int btn, int btnCount);
typedef void (*BFWindow_MouseUp)(BFWindow* window, int x, int y, int btn);
typedef void (*BFWindow_MouseWheel)(BFWindow* window, int x, int y, int delta);
typedef void (*BFWindow_MouseLeave)(BFWindow* window);
typedef void (*BFWindow_MenuItemSelectedFunc)(BFWindow* window, BFMenu* menu);
enum
{
BFWINDOW_BORDER = 0x000001,
BFWINDOW_THICKFRAME = 0x000002,
BFWINDOW_RESIZABLE = 0x000004,
BFWINDOW_SYSMENU = 0x000008,
BFWINDOW_CAPTION = 0x000010,
BFWINDOW_MINIMIZE = 0x000020,
BFWINDOW_MAXIMIZE = 0x000040,
BFWINDOW_CLIENT_SIZED = 0x000080,
BFWINDOW_QUIT_ON_CLOSE = 0x000100,
BFWINDOW_VSYNC = 0x000200,
BFWINDOW_POPUP_POSITION = 0x000400,
BFWINDOW_DEST_ALPHA = 0x000800,
BFWINDOW_ALPHA_MASK = 0x0001000,
BFWINDOW_CHILD = 0x002000,
BFWINDOW_TOPMOST = 0x004000,
BFWINDOW_TOOLWINDOW = 0x008000,
BFWINDOW_NO_ACTIVATE = 0x010000,
BFWINDOW_NO_MOUSE_ACTIVATE = 0x020000,
BFWINDOW_MENU = 0x040000,
BFWINDOW_MODAL = 0x080000,
BFWINDOW_SCALE_CONTENT = 0x100000,
BFWINDOW_USE_PARENT_MENU = 0x200000,
BFWINDOW_CAPTURE_MEDIA_KEYS = 0x400000,
BFWINDOW_FULLSCREEN = 0x800000,
BFWINDOW_FAKEFOCUS = 0x1000000
};
class RenderWindow;
class BFMenu
{
public:
BFMenu* mParent;
Array<BFMenu*> mBFMenuList;
uint32 mKeyCode;
bool mKeyCtrl;
bool mKeyAlt;
bool mKeyShift;
public:
BFMenu();
virtual ~BFMenu() { }
virtual bool ParseHotKey(const StringImpl& hotKey);
};
class BFSysBitmap;
#define KEYCODE_MAX 0x100
#define MOUSEBUTTON_MAX 3
class BFWindow;
class BFWindow
{
public:
BFWindow* mParent;
Array<BFWindow*> mChildren;
int mFlags;
bool mIsKeyDown[KEYCODE_MAX];
bool mIsMouseDown[MOUSEBUTTON_MAX];
BFMenu* mMenu;
RenderWindow* mRenderWindow;
bool mNonExclusiveMouseCapture;
BFWindow_MovedFunc mMovedFunc;
BFWindow_CloseQueryFunc mCloseQueryFunc;
BFWindow_ClosedFunc mClosedFunc;
BFWindow_GotFocusFunc mGotFocusFunc;
BFWindow_LostFocusFunc mLostFocusFunc;
BFWindow_KeyCharFunc mKeyCharFunc;
BFWindow_KeyDownFunc mKeyDownFunc;
BFWindow_KeyUpFunc mKeyUpFunc;
BFWindow_HitTestFunc mHitTestFunc;
BFWindow_MouseMove mMouseMoveFunc;
BFWindow_MouseProxyMove mMouseProxyMoveFunc;
BFWindow_MouseDown mMouseDownFunc;
BFWindow_MouseUp mMouseUpFunc;
BFWindow_MouseWheel mMouseWheelFunc;
BFWindow_MouseLeave mMouseLeaveFunc;
BFWindow_MenuItemSelectedFunc mMenuItemSelectedFunc;
public:
BFWindow();
virtual ~BFWindow();
virtual void* GetUnderlying() = 0;
virtual void Destroy() = 0;
virtual bool TryClose() = 0;
virtual void SetTitle(const char* title) = 0;
virtual void SetMinimumSize(int minWidth, int minHeight, bool clientSized) = 0;
virtual void GetPosition(int* x, int* y, int* width, int* height, int* clientX, int* clientY, int* clientWidth, int* clientHeight) = 0;
virtual void Resize(int x, int y, int width, int height) = 0;
virtual void SetClientPosition(int x, int y) = 0;
virtual void SetMouseVisible(bool isMouseVisible) = 0;
virtual void SetAlpha(float alpha, uint32 destAlphaSrcMask, bool isMouseVisible) = 0;
virtual void SetForeground() = 0;
virtual void SetNonExclusiveMouseCapture() { mNonExclusiveMouseCapture = true; }
virtual void CaptureMouse() {}
virtual bool IsMouseCaptured() { return false; }
virtual void LostFocus(BFWindow* newFocus) = 0;
virtual BFMenu* AddMenuItem(BFMenu* parent, int insertIdx, const char* text, const char* hotKey, BFSysBitmap* bitmap, bool enabled, int checkState, bool radioCheck) = 0;
virtual void ModifyMenuItem(BFMenu* item, const char* text, const char* hotKey, BFSysBitmap* bitmap, bool enabled, int checkState, bool radioCheck) = 0;
virtual void RemoveMenuItem(BFMenu* item) = 0;
virtual void ModalsRemoved() { }
};
NS_BF_END;

566
BeefySysLib/BeefProj.toml Normal file
View file

@ -0,0 +1,566 @@
FileVersion = 1
[Project]
Name = "BeefySysLib"
TargetType = "CustomBuild"
[Configs.Debug.Win32]
TargetDirectory = "$(WorkspaceDir)/../IDE/dist"
TargetName = "BeefySysLib32_d.dll"
BuildCommandsOnCompile = "IfFilesChanged"
BuildCommandsOnRun = "IfFilesChanged"
PostBuildCmds = ["$(WorkspaceDir)\\..\\bin\\msbuild.bat $(WorkspaceDir)\\..\\BeefySysLib\\BeefySysLib.vcxproj /p:Configuration=Debug /p:Platform=X86 /p:SolutionDir=$(WorkspaceDir)\\..\\ /v:m"]
[Configs.Debug.Win64]
TargetDirectory = "$(WorkspaceDir)/../IDE/dist"
TargetName = "BeefySysLib64_d.dll"
BuildCommandsOnCompile = "IfFilesChanged"
BuildCommandsOnRun = "IfFilesChanged"
PostBuildCmds = ["$(WorkspaceDir)\\..\\bin\\msbuild.bat $(WorkspaceDir)\\..\\BeefySysLib\\BeefySysLib.vcxproj /p:Configuration=Debug /p:Platform=X64 /p:SolutionDir=$(WorkspaceDir)\\..\\ /v:m"]
[Configs.Release.Win32]
TargetDirectory = "$(WorkspaceDir)/../IDE/dist"
TargetName = "BeefySysLib32.dll"
BuildCommandsOnCompile = "IfFilesChanged"
BuildCommandsOnRun = "IfFilesChanged"
PostBuildCmds = ["$(WorkspaceDir)\\..\\bin\\msbuild.bat $(WorkspaceDir)\\..\\BeefySysLib\\BeefySysLib.vcxproj /p:Configuration=Release /p:Platform=X86 /p:SolutionDir=$(WorkspaceDir)\\..\\ /v:m"]
[Configs.Release.Win64]
TargetDirectory = "$(WorkspaceDir)/../IDE/dist"
TargetName = "BeefySysLib64.dll"
BuildCommandsOnCompile = "IfFilesChanged"
BuildCommandsOnRun = "IfFilesChanged"
PostBuildCmds = ["$(WorkspaceDir)\\..\\bin\\msbuild.bat $(WorkspaceDir)\\..\\BeefySysLib\\BeefySysLib.vcxproj /p:Configuration=Release /p:Platform=X64 /p:SolutionDir=$(WorkspaceDir)\\..\\ /v:m"]
[Configs.Paranoid.Win32]
BuildCommandsOnCompile = "IfFilesChanged"
BuildCommandsOnRun = "IfFilesChanged"
[Configs.Paranoid.Win64]
BuildCommandsOnCompile = "IfFilesChanged"
BuildCommandsOnRun = "IfFilesChanged"
[Configs.Test.Win32]
BuildCommandsOnCompile = "IfFilesChanged"
BuildCommandsOnRun = "IfFilesChanged"
[Configs.Test.Win64]
BuildCommandsOnCompile = "IfFilesChanged"
BuildCommandsOnRun = "IfFilesChanged"
[ProjectFolder]
[[ProjectFolder.Items]]
Type = "Folder"
Name = "fbx"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "FBXReader.cpp"
ImportPath = "fbx/FBXReader.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "FBXReader.h"
ImportPath = "fbx/FBXReader.h"
[[ProjectFolder.Items]]
Type = "Folder"
Name = "gfx"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "DrawLayer.cpp"
ImportPath = "gfx/DrawLayer.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "DrawLayer.h"
ImportPath = "gfx/DrawLayer.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "FTFont.cpp"
ImportPath = "gfx/FTFont.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "FTFont.h"
ImportPath = "gfx/FTFont.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "ModelDef.cpp"
ImportPath = "gfx/ModelDef.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "ModelDef.h"
ImportPath = "gfx/ModelDef.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "ModelInstance.cpp"
ImportPath = "gfx/ModelInstance.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "ModelInstance.h"
ImportPath = "gfx/ModelInstance.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "RenderCmd.cpp"
ImportPath = "gfx/RenderCmd.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "RenderCmd.h"
ImportPath = "gfx/RenderCmd.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "RenderDevice.cpp"
ImportPath = "gfx/RenderDevice.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "RenderDevice.h"
ImportPath = "gfx/RenderDevice.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "RenderTarget.cpp"
ImportPath = "gfx/RenderTarget.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "RenderTarget.h"
ImportPath = "gfx/RenderTarget.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "Shader.cpp"
ImportPath = "gfx/Shader.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "Shader.h"
ImportPath = "gfx/Shader.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "Texture.cpp"
ImportPath = "gfx/Texture.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "Texture.h"
ImportPath = "gfx/Texture.h"
[[ProjectFolder.Items]]
Type = "Folder"
Name = "img"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "BFIData.cpp"
ImportPath = "img/BFIData.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "BFIData.h"
ImportPath = "img/BFIData.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "ImageAdjustments.cpp"
ImportPath = "img/ImageAdjustments.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "ImageAdjustments.h"
ImportPath = "img/ImageAdjustments.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "ImageData.cpp"
ImportPath = "img/ImageData.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "ImageData.h"
ImportPath = "img/ImageData.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "ImageUtils.cpp"
ImportPath = "img/ImageUtils.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "ImageUtils.h"
ImportPath = "img/ImageUtils.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "ImgEffects.cpp"
ImportPath = "img/ImgEffects.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "ImgEffects.h"
ImportPath = "img/ImgEffects.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "JPEGData.cpp"
ImportPath = "img/JPEGData.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "JPEGData.h"
ImportPath = "img/JPEGData.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "PNGData.cpp"
ImportPath = "img/PNGData.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "PNGData.h"
ImportPath = "img/PNGData.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "PSDReader.cpp"
ImportPath = "img/PSDReader.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "PSDReader.h"
ImportPath = "img/PSDReader.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "PVRData.cpp"
ImportPath = "img/PVRData.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "PVRData.h"
ImportPath = "img/PVRData.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "TGAData.cpp"
ImportPath = "img/TGAData.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "TGAData.h"
ImportPath = "img/TGAData.h"
[[ProjectFolder.Items]]
Type = "Folder"
Name = "platform"
[[ProjectFolder.Items.Items]]
Type = "Folder"
Name = "win"
[[ProjectFolder.Items.Items.Items]]
Type = "Source"
Name = "BFPlatform.h"
ImportPath = "platform/win/BFPlatform.h"
[[ProjectFolder.Items.Items.Items]]
Type = "Source"
Name = "DXRenderDevice.cpp"
ImportPath = "platform/win/DXRenderDevice.cpp"
[[ProjectFolder.Items.Items.Items]]
Type = "Source"
Name = "DXRenderDevice.h"
ImportPath = "platform/win/DXRenderDevice.h"
[[ProjectFolder.Items.Items.Items]]
Type = "Source"
Name = "Platform.cpp"
ImportPath = "platform/win/Platform.cpp"
[[ProjectFolder.Items.Items.Items]]
Type = "Source"
Name = "PlatformApp.h"
ImportPath = "platform/win/PlatformApp.h"
[[ProjectFolder.Items.Items.Items]]
Type = "Source"
Name = "WinBFApp.cpp"
ImportPath = "platform/win/WinBFApp.cpp"
[[ProjectFolder.Items.Items.Items]]
Type = "Source"
Name = "WinBFApp.h"
ImportPath = "platform/win/WinBFApp.h"
[[ProjectFolder.Items]]
Type = "Folder"
Name = "sound"
[[ProjectFolder.Items]]
Type = "Folder"
Name = "util"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "AllocDebug.cpp"
ImportPath = "Util/AllocDebug.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "AllocDebug.h"
ImportPath = "Util/AllocDebug.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "BeefPerf.cpp"
ImportPath = "util/BeefPerf.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "BeefPerf.h"
ImportPath = "util/BeefPerf.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "BSpline.cpp"
ImportPath = "Util/BSpline.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "BSpline.h"
ImportPath = "Util/BSpline.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "BumpAllocator.h"
ImportPath = "Util/BumpAllocator.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "CatmullRom.cpp"
ImportPath = "Util/CatmullRom.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "CatmullRom.h"
ImportPath = "Util/CatmullRom.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "CritSect.h"
ImportPath = "Util/CritSect.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "CubicFuncSpline.cpp"
ImportPath = "Util/CubicFuncSpline.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "CubicFuncSpline.h"
ImportPath = "Util/CubicFuncSpline.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "CubicSpline.cpp"
ImportPath = "Util/CubicSpline.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "CubicSpline.h"
ImportPath = "Util/CubicSpline.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "DLIList.h"
ImportPath = "Util/DLIList.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "Hash.cpp"
ImportPath = "Util/Hash.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "Hash.h"
ImportPath = "Util/Hash.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "Json.cpp"
ImportPath = "Util/Json.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "Json.h"
ImportPath = "Util/Json.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "Matrix4.cpp"
ImportPath = "Util/Matrix4.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "Matrix4.h"
ImportPath = "Util/Matrix4.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "PerfTimer.cpp"
ImportPath = "Util/PerfTimer.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "PerfTimer.h"
ImportPath = "Util/PerfTimer.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "Point.cpp"
ImportPath = "Util/Point.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "Point.h"
ImportPath = "Util/Point.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "PolySpline.cpp"
ImportPath = "Util/PolySpline.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "PolySpline.h"
ImportPath = "Util/PolySpline.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "Quaternion.cpp"
ImportPath = "Util/Quaternion.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "Quaternion.h"
ImportPath = "Util/Quaternion.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "Rect.h"
ImportPath = "Util/Rect.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "SLIList.h"
ImportPath = "Util/SLIList.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "TLSingleton.h"
ImportPath = "util/TLSingleton.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "UTF8.cpp"
ImportPath = "Util/UTF8.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "UTF8.h"
ImportPath = "Util/UTF8.h"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "Vector.cpp"
ImportPath = "Util/Vector.cpp"
[[ProjectFolder.Items.Items]]
Type = "Source"
Name = "Vector.h"
ImportPath = "Util/Vector.h"
[[ProjectFolder.Items]]
Type = "Source"
Path = "BeefySysLib.cpp"
[[ProjectFolder.Items]]
Type = "Source"
Path = "BFApp.cpp"
[[ProjectFolder.Items]]
Type = "Source"
Path = "BFApp.h"
[[ProjectFolder.Items]]
Type = "Source"
Path = "BFWindow.cpp"
[[ProjectFolder.Items]]
Type = "Source"
Path = "BFWindow.h"
[[ProjectFolder.Items]]
Type = "Source"
Path = "Common.cpp"
[[ProjectFolder.Items]]
Type = "Source"
Path = "Common.h"
[[ProjectFolder.Items]]
Type = "Source"
Path = "DataStream.cpp"
[[ProjectFolder.Items]]
Type = "Source"
Path = "DataStream.h"
[[ProjectFolder.Items]]
Type = "Source"
Path = "FileHandleStream.cpp"
[[ProjectFolder.Items]]
Type = "Source"
Path = "FileHandleStream.h"
[[ProjectFolder.Items]]
Type = "Source"
Path = "FileStream.cpp"
[[ProjectFolder.Items]]
Type = "Source"
Path = "FileStream.h"
[[ProjectFolder.Items]]
Type = "Source"
Path = "MemStream.cpp"
[[ProjectFolder.Items]]
Type = "Source"
Path = "MemStream.h"
[[ProjectFolder.Items]]
Type = "Source"
Path = "PerfTests.cpp"
[[ProjectFolder.Items]]
Type = "Source"
Path = "ResLib.cpp"
[[ProjectFolder.Items]]
Type = "Source"
Path = "Startup.cpp"

726
BeefySysLib/BeefySysLib.cpp Normal file
View file

@ -0,0 +1,726 @@
#include "Common.h"
#include "PlatformApp.h"
#include "gfx/RenderDevice.h"
#include "gfx/Texture.h"
#include "gfx/Shader.h"
#include "gfx/DrawLayer.h"
#include "gfx/RenderCmd.h"
#include "gfx/FTFont.h"
#include "img/BFIData.h"
#include "util/Vector.h"
#include "util/PerfTimer.h"
#include "util/AllocDebug.h"
//#include "third_party/freetype/include/ft2build.h"
//#include FT_FREETYPE_H
//#include "img/PNGData.h"
#define UTF16DECODE_PTR(strPtr) ((strPtr) == NULL ? NULL : UTF16Decode(strPtr).c_str())
USING_NS_BF;
#pragma warning(disable:4996)
static UTF16String gTempUTF16String;
int gPixelsDrawn = 0;
#ifdef BF_PLATFORM_WINDOWS
static int gLastReqId = 0;
static int BfAllocHook(int nAllocType, void *pvData,
size_t nSize, int nBlockUse, long lRequest,
const unsigned char * szFileName, int nLine)
{
if (gLastReqId == lRequest)
return TRUE;
gLastReqId = lRequest;
if (szFileName == NULL)
return TRUE;
/*char str[1024];
sprintf(str, "Alloc: %d File: %s Line: %d\n", lRequest, szFileName, nLine);
OutputDebugStringA(str);*/
return TRUE;
}
HINSTANCE gDLLInstance = NULL;
BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved)
{
//::MessageBoxA(NULL, "C", "D", MB_OK);
#ifdef BF_VC
//_CrtSetDbgFlag ( _CRTDBG_ALLOC_MEM_DF );
//_CrtSetBreakAlloc(1437);
//_CrtSetAllocHook(BfAllocHook);
#endif
switch (fdwReason)
{
case DLL_PROCESS_ATTACH:
gDLLInstance = hinstDLL;
case DLL_THREAD_ATTACH:
case DLL_THREAD_DETACH:
case DLL_PROCESS_DETACH:
break;
}
return TRUE;
}
#endif
BF_EXPORT void BF_CALLTYPE BFApp_GetDesktopResolution(int& width, int& height)
{
gBFApp->GetDesktopResolution(width, height);
}
BF_EXPORT void BF_CALLTYPE BFApp_GetWorkspaceRect(int& x, int& y, int& width, int& height)
{
gBFApp->GetWorkspaceRect(x, y, width, height);
}
BF_EXPORT void BF_CALLTYPE BFApp_Create()
{
new PlatformBFApp();
}
BF_EXPORT void BF_CALLTYPE BFApp_Delete()
{
delete gBFApp;
gBFApp = NULL;
gTempUTF16String.Dispose();
FTFontManager::ClearCache();
//OutputDebugStrF("Deleting App\n");
#ifdef BF_VC
//_CrtDumpMemoryLeaks();
#endif
}
//void FT_Test()
//{
// FT_Library library; /* handle to library */
// FT_Face face; /* handle to face object */
//
// auto error = FT_Init_FreeType(&library);
// error = FT_New_Face(library, "/temp/SourceCodePro-Regular.ttf", 0, &face);
// if (error == FT_Err_Unknown_File_Format)
// {
//
// }
// else if (error)
// {
//
// }
//
// error = FT_Set_Char_Size(
// face, /* handle to face object */
// 0, /* char_width in 1/64th of points */
// 9 * 64, /* char_height in 1/64th of points */
// 96, /* horizontal device resolution */
// 96); /* vertical device resolution */
//
// String str = ".cHasDebugFlags";
//
// PNGData image;
// image.CreateNew(256, 256);
// for (int i = 0; i < 256 * 256; i++)
// image.mBits[i] = 0xFF000000;
//
// int curX = 0;
// int curY = 0;
//
// for (int i = 0; i < (int)str.length(); i++)
// {
// int glyph_index = FT_Get_Char_Index(face, str[i]);
//
// error = FT_Load_Glyph(
// face, /* handle to face object */
// glyph_index, /* glyph index */
// FT_LOAD_NO_BITMAP); /* load flags, see below */
//
// error = FT_Render_Glyph(face->glyph, /* glyph slot */
// FT_RENDER_MODE_NORMAL); /* render mode */
//
// auto& bitmap = face->glyph->bitmap;
// for (int y = 0; y < (int)bitmap.rows; y++)
// {
// for (int x = 0; x < (int)bitmap.width; x++)
// {
// uint8 val = bitmap.buffer[y * bitmap.pitch + x];
//
// val = (uint8)(pow(val / 255.0f, 0.5556) * 255.0f);
//
// image.mBits[(y + 12 - bitmap.rows) * image.mWidth + x + curX] = 0xFF000000 |
// ((int32)val) | ((int32)val << 8) | ((int32)val << 16);
// }
// }
//
// curX += bitmap.width + 1;
//
// //int w = face->glyph->bitmap.;
//
// //face->glyph->bitmap.buffer
// }
// image.WriteToFile("/temp/fnt.png");
//}
BF_EXPORT void BF_CALLTYPE BFApp_Init()
{
//////////////////////////////////////////////////////////////////////////
//FT_Test();
//////////////////////////////////////////////////////////////////////////
gBFApp->Init();
}
BF_EXPORT void BF_CALLTYPE BFApp_Run()
{
gBFApp->Run();
}
BF_EXPORT void BF_CALLTYPE BFApp_Shutdown()
{
gBFApp->Shutdown();
}
BF_EXPORT void BF_CALLTYPE BFApp_SetDrawEnabled(int enabled)
{
gBFApp->mDrawEnabled = enabled != 0;
}
BF_EXPORT void BF_CALLTYPE BFApp_SetRefreshRate(int rate)
{
gBFApp->mRefreshRate = (float) rate;
}
BF_EXPORT const char* BF_CALLTYPE BFApp_GetInstallDir()
{
return gBFApp->mInstallDir.c_str();
}
BF_EXPORT const char* BF_CALLTYPE BFApp_GetDataDir()
{
return gBFApp->mDataDir.c_str();
}
BF_EXPORT void BF_CALLTYPE BFApp_SetCallbacks(BFApp_UpdateFunc updateFunc, BFApp_DrawFunc drawFunc)
{
gBFApp->mUpdateFunc = updateFunc;
gBFApp->mDrawFunc = drawFunc;
//public delegate void UpdateProc();
}
BF_EXPORT BFWindow* BF_CALLTYPE BFApp_CreateWindow(BFWindow* parent, const char* title, int x, int y, int width, int height, int windowFlags)
{
return gBFApp->CreateNewWindow(parent, title, x, y, width, height, windowFlags);
}
BF_EXPORT void BF_CALLTYPE BFApp_RemoveWindow(BFWindow* window)
{
delete window;
}
BF_EXPORT void BF_CALLTYPE BFApp_SetCursor(int cursor)
{
gBFApp->SetCursor(cursor);
}
BF_EXPORT void* BF_CALLTYPE BFApp_GetClipboardData(const char* format, int* size)
{
return gBFApp->GetClipboardData(format, size);
}
BF_EXPORT void BF_CALLTYPE BFApp_ReleaseClipboardData(void* ptr)
{
return gBFApp->ReleaseClipboardData(ptr);
}
BF_EXPORT void BF_CALLTYPE BFApp_SetClipboardData(const char* format, void* ptr, int size, int resetClipboard)
{
return gBFApp->SetClipboardData(format, ptr, size, resetClipboard != 0);
}
BF_EXPORT void BF_CALLTYPE BFApp_CheckMemory()
{
#ifdef BF_PLATFORM_WINDOWS
_CrtCheckMemory();
#endif
}
BF_EXPORT void BF_CALLTYPE BFApp_RehupMouse()
{
}
///
BF_EXPORT void BF_CALLTYPE BFWindow_SetCallbacks(BFWindow* window, BFWindow_MovedFunc movedFunc, BFWindow_CloseQueryFunc closeQueryFunc, BFWindow_ClosedFunc closedFunc,
BFWindow_GotFocusFunc gotFocusFunc, BFWindow_LostFocusFunc lostFocusFunc,
BFWindow_KeyCharFunc keyCharFunc, BFWindow_KeyDownFunc keyDownFunc, BFWindow_KeyUpFunc keyUpFunc, BFWindow_HitTestFunc hitTestFunc,
BFWindow_MouseMove mouseMoveFunc, BFWindow_MouseProxyMove mouseProxyMoveFunc,
BFWindow_MouseDown mouseDownFunc, BFWindow_MouseUp mouseUpFunc, BFWindow_MouseWheel mouseWheelFunc, BFWindow_MouseLeave mouseLeaveFunc,
BFWindow_MenuItemSelectedFunc menuItemSelectedFunc)
{
window->mMovedFunc = movedFunc;
window->mCloseQueryFunc = closeQueryFunc;
window->mClosedFunc = closedFunc;
window->mGotFocusFunc = gotFocusFunc;
window->mLostFocusFunc = lostFocusFunc;
window->mKeyCharFunc = keyCharFunc;
window->mKeyDownFunc = keyDownFunc;
window->mKeyUpFunc = keyUpFunc;
window->mHitTestFunc = hitTestFunc;
window->mMouseMoveFunc = mouseMoveFunc;
window->mMouseProxyMoveFunc = mouseProxyMoveFunc;
window->mMouseDownFunc = mouseDownFunc;
window->mMouseUpFunc = mouseUpFunc;
window->mMouseWheelFunc = mouseWheelFunc;
window->mMouseLeaveFunc = mouseLeaveFunc;
window->mMenuItemSelectedFunc = menuItemSelectedFunc;
}
BF_EXPORT void* BFWindow_GetNativeUnderlying(BFWindow* window)
{
return window->GetUnderlying();
}
BF_EXPORT void BF_CALLTYPE BFWindow_MovedDelegate(BFWindow* window, BFWindow_MovedFunc movedFunc)
{
window->mMovedFunc = movedFunc;
}
BF_EXPORT void BF_CALLTYPE BFWindow_SetTitle(BFWindow* window, const char* title)
{
window->SetTitle(title);
}
BF_EXPORT void BF_CALLTYPE BFWindow_SetMinimumSize(BFWindow* window, int minWidth, int minHeight, bool clientSized)
{
window->SetMinimumSize(minWidth, minHeight, clientSized);
}
BF_EXPORT void BF_CALLTYPE BFWindow_GetPosition(BFWindow* window, int* x, int* y, int* width, int* height, int* clientX, int* clientY, int* clientWidth, int* clientHeight)
{
window->GetPosition(x, y, width, height, clientX, clientY, clientWidth, clientHeight);
}
BF_EXPORT void BF_CALLTYPE BFWindow_Resize(BFWindow* window, int x, int y, int width, int height)
{
window->Resize(x, y, width, height);
}
BF_EXPORT void BF_CALLTYPE BFWindow_SetForeground(BFWindow* window)
{
window->SetForeground();
}
BF_EXPORT void BF_CALLTYPE BFWindow_SetNonExclusiveMouseCapture(BFWindow* window)
{
window->SetNonExclusiveMouseCapture();
}
BF_EXPORT void BF_CALLTYPE BFWindow_LostFocus(BFWindow* window, BFWindow* newFocus)
{
window->LostFocus(newFocus);
}
BF_EXPORT void BF_CALLTYPE BFWindow_SetAlpha(BFWindow* window, float alpha, uint32 destAlphaSrcMask, int mouseVisible)
{
window->SetAlpha(alpha, destAlphaSrcMask, mouseVisible != 0);
}
BF_EXPORT void BF_CALLTYPE BFWindow_CaptureMouse(BFWindow* window)
{
window->CaptureMouse();
}
BF_EXPORT bool BF_CALLTYPE BFWindow_IsMouseCaptured(BFWindow* window)
{
return window->IsMouseCaptured();
}
BF_EXPORT void BF_CALLTYPE BFWindow_SetMouseVisible(BFWindow* window, bool mouseVisible)
{
window->SetMouseVisible(mouseVisible);
}
BF_EXPORT void BF_CALLTYPE BFWindow_SetClientPosition(BFWindow* window, int x, int y)
{
window->SetClientPosition(x, y);
}
BF_EXPORT BFMenu* BF_CALLTYPE BFWindow_AddMenuItem(BFWindow* window, BFMenu* parent, int insertIdx, const char* text, const char* hotKey, BFSysBitmap* bitmap, int enabled, int checkState, int radioCheck)
{
return window->AddMenuItem(parent, insertIdx, text, hotKey, bitmap, enabled != 0, checkState, radioCheck != 0);
}
BF_EXPORT void BF_CALLTYPE BFWindow_ModifyMenuItem(BFWindow* window, BFMenu* item, const char* text, const char* hotKey, BFSysBitmap* bitmap, int enabled, int checkState, int radioCheck)
{
window->ModifyMenuItem(item, text, hotKey, bitmap, enabled != 0, checkState, radioCheck != 0);
}
BF_EXPORT void BF_CALLTYPE BFWindow_DeleteMenuItem(BFWindow* window, BFMenu* item)
{
window->RemoveMenuItem(item);
delete item;
}
BF_EXPORT void BF_CALLTYPE BFWindow_Close(BFWindow* window, int force)
{
if (force != 0)
gBFApp->RemoveWindow(window);
else
window->TryClose();
}
///
BF_EXPORT TextureSegment* BF_CALLTYPE Gfx_CreateRenderTarget(int width, int height, int destAlpha)
{
Texture* texture = gBFApp->mRenderDevice->CreateRenderTarget(width, height, destAlpha != 0);
TextureSegment* aTextureSegment = new TextureSegment();
aTextureSegment->InitFromTexture(texture);
return aTextureSegment;
}
BF_EXPORT TextureSegment* BF_CALLTYPE Gfx_CreateDynTexture(int width, int height)
{
Texture* texture = gBFApp->mRenderDevice->CreateDynTexture(width, height);
TextureSegment* aTextureSegment = new TextureSegment();
aTextureSegment->InitFromTexture(texture);
return aTextureSegment;
}
BF_EXPORT TextureSegment* BF_CALLTYPE Gfx_LoadTexture(const char* fileName, int flags)
{
Texture* texture = gBFApp->mRenderDevice->LoadTexture(fileName, flags);
if (texture == NULL)
return NULL;
TextureSegment* aTextureSegment = new TextureSegment();
aTextureSegment->InitFromTexture(texture);
return aTextureSegment;
}
BF_EXPORT void BF_CALLTYPE Gfx_Texture_SetBits(TextureSegment* textureSegment, int destX, int destY, int destWidth, int destHeight, int srcPitch, uint32* bits)
{
textureSegment->mTexture->SetBits(destX, destY, destWidth, destHeight, srcPitch, bits);
}
BF_EXPORT void BF_CALLTYPE Gfx_Texture_Delete(TextureSegment* textureSegment)
{
textureSegment->mTexture->Release();
delete textureSegment;
}
BF_EXPORT int BF_CALLTYPE Gfx_Texture_GetWidth(TextureSegment* textureSegment)
{
return (int) textureSegment->mScaleX;
}
BF_EXPORT int BF_CALLTYPE Gfx_Texture_GetHeight(TextureSegment* textureSegment)
{
return (int) textureSegment->mScaleY;
}
BF_EXPORT void BF_CALLTYPE Gfx_ModifyTextureSegment(TextureSegment* destTextureSegment, TextureSegment* srcTextureSegment, int srcX, int srcY, int srcWidth, int srcHeight)
{
if (destTextureSegment->mTexture != srcTextureSegment->mTexture)
{
destTextureSegment->mTexture->Release();
destTextureSegment->mTexture = srcTextureSegment->mTexture;
destTextureSegment->mTexture->AddRef();
}
Texture* texture = srcTextureSegment->mTexture;
destTextureSegment->mU1 = (srcX / (float) texture->mWidth) + srcTextureSegment->mU1;
destTextureSegment->mV1 = (srcY / (float) texture->mHeight) + srcTextureSegment->mV1;
destTextureSegment->mU2 = ((srcX + srcWidth) / (float) texture->mWidth) + srcTextureSegment->mU1;
destTextureSegment->mV2 = ((srcY + srcHeight) / (float) texture->mHeight) + srcTextureSegment->mV1;
destTextureSegment->mScaleX = (float)abs(srcWidth);
destTextureSegment->mScaleY = (float)abs(srcHeight);
}
BF_EXPORT TextureSegment* BF_CALLTYPE Gfx_CreateTextureSegment(TextureSegment* textureSegment, int srcX, int srcY, int srcWidth, int srcHeight)
{
Texture* texture = textureSegment->mTexture;
texture->AddRef();
TextureSegment* aTextureSegment = new TextureSegment();
aTextureSegment->mTexture = texture;
aTextureSegment->mU1 = (srcX / (float) texture->mWidth) + textureSegment->mU1;
aTextureSegment->mV1 = (srcY / (float) texture->mHeight) + textureSegment->mV1;
aTextureSegment->mU2 = ((srcX + srcWidth) / (float) texture->mWidth) + textureSegment->mU1;
aTextureSegment->mV2 = ((srcY + srcHeight) / (float) texture->mHeight) + textureSegment->mV1;
aTextureSegment->mScaleX = (float)abs(srcWidth);
aTextureSegment->mScaleY = (float)abs(srcHeight);
return aTextureSegment;
}
BF_EXPORT void BF_CALLTYPE Gfx_SetDrawSize(TextureSegment* textureSegment, int width, int height)
{
textureSegment->mScaleX = (float)abs(width);
textureSegment->mScaleY = (float)abs(height);
}
BF_EXPORT void BF_CALLTYPE Gfx_DrawTextureSegment(TextureSegment* textureSegment, float a, float b, float c, float d, float tx, float ty, float z, uint32 color, int pixelSnapping)
{
DrawLayer* drawLayer = gBFApp->mRenderDevice->mCurDrawLayer;
drawLayer->SetTexture(0, textureSegment->mTexture);
DefaultVertex3D* v = (DefaultVertex3D*)drawLayer->AllocStrip(4);
if ((pixelSnapping == 1) ||
((pixelSnapping == 2) && (a == 1.0f) && (b == 0) && (c == 0) && (d == 1.0f)))
{
tx = (float) (int) (tx + 100000) - 100000;
ty = (float) (int) (ty + 100000) - 100000;
}
a *= textureSegment->mScaleX;
b *= textureSegment->mScaleX;
c *= textureSegment->mScaleY;
d *= textureSegment->mScaleY;
v[0].Set(tx, ty, z, textureSegment->mU1, textureSegment->mV1, color);
v[1].Set(tx + a, ty + b, z, textureSegment->mU2, textureSegment->mV1, color);
v[2].Set(tx + c, ty + d, z, textureSegment->mU1, textureSegment->mV2, color);
v[3].Set(tx + (a + c), ty + (b + d), z, textureSegment->mU2, textureSegment->mV2, color);
gPixelsDrawn += (int)((a + b) * (c + d));
}
static TextureSegment* gCurTextureSegment = NULL;
static DefaultVertex3D* gCurAllocVertices = NULL;
BF_EXPORT void BF_CALLTYPE Gfx_AllocTris(TextureSegment* textureSegment, int vtxCount)
{
gCurTextureSegment = textureSegment;
DrawLayer* drawLayer = gBFApp->mRenderDevice->mCurDrawLayer;
drawLayer->SetTexture(0, textureSegment->mTexture);
gCurAllocVertices = (DefaultVertex3D*)gBFApp->mRenderDevice->mCurDrawLayer->AllocTris(vtxCount);
}
BF_EXPORT void BF_CALLTYPE Gfx_SetDrawVertex(int idx, float x, float y, float z, float u, float v, uint32 color)
{
gCurAllocVertices[idx].Set(x, y, z,
gCurTextureSegment->mU1 + u * (gCurTextureSegment->mU2 - gCurTextureSegment->mU1),
gCurTextureSegment->mV1 + v * (gCurTextureSegment->mV2 - gCurTextureSegment->mV1), color);
}
BF_EXPORT void BF_CALLTYPE Gfx_CopyDrawVertex(int destIdx, int srcIdx)
{
gCurAllocVertices[destIdx] = gCurAllocVertices[srcIdx];
}
BF_EXPORT void BF_CALLTYPE Gfx_DrawQuads(TextureSegment* textureSegment, DefaultVertex3D* vertices, int vtxCount)
{
/*for (int vtxIdx = 0; vtxIdx < vtxCount; vtxIdx += 4)
{
Vertex3D* v = gBFApp->mRenderDevice->mCurDrawLayer->AllocStrip(textureSegment->mTexture, drawType != 0, 4);
v[0] = vertices[vtxIdx];
v[1] = vertices[vtxIdx + 1];
v[2] = vertices[vtxIdx + 2];
v[3] = vertices[vtxIdx + 3];
}
return;*/
DrawLayer* drawLayer = gBFApp->mRenderDevice->mCurDrawLayer;
drawLayer->SetTexture(0, textureSegment->mTexture);
DefaultVertex3D* vtxInPtr = vertices;
int curIdx = 0;
while (curIdx < vtxCount)
{
//int batchSize = std::min(128, vtxCount - curIdx);
int batchSize = std::min(16*1024, vtxCount - curIdx);
uint16 idxOfs;
DefaultVertex3D* vtxPtr;
uint16* idxPtr;
gBFApp->mRenderDevice->mCurDrawLayer->AllocIndexed(batchSize, batchSize * 6 / 4, (void**)&vtxPtr, &idxPtr, &idxOfs);
for (int vtxIdx = 0; vtxIdx < batchSize; vtxIdx += 4)
{
*(vtxPtr++) = *(vtxInPtr++);
*(vtxPtr++) = *(vtxInPtr++);
*(vtxPtr++) = *(vtxInPtr++);
*(vtxPtr++) = *(vtxInPtr++);
*(idxPtr++) = idxOfs;
*(idxPtr++) = idxOfs + 1;
*(idxPtr++) = idxOfs + 2;
*(idxPtr++) = idxOfs + 1;
*(idxPtr++) = idxOfs + 2;
*(idxPtr++) = idxOfs + 3;
/*int curIdxIdx = idxPtr - gBFApp->mRenderDevice->mCurDrawLayer->mDrawBatchList.mTail->mIndices;
BF_ASSERT(curIdxIdx <= gBFApp->mRenderDevice->mCurDrawLayer->mDrawBatchList.mTail->mAllocatedIndices);
int curVtxIdx = vtxPtr - gBFApp->mRenderDevice->mCurDrawLayer->mDrawBatchList.mTail->mVertices;
BF_ASSERT(curVtxIdx <= gBFApp->mRenderDevice->mCurDrawLayer->mDrawBatchList.mTail->mAllocatedVertices);*/
idxOfs += 4;
}
curIdx += batchSize;
}
}
BF_EXPORT void BF_CALLTYPE Gfx_DrawIndexedVertices2D(int vertexSize, void* vtxData, int vtxCount, uint16* idxData, int idxCount, float a, float b, float c, float d, float tx, float ty, float z)
{
DrawLayer* drawLayer = gBFApp->mRenderDevice->mCurDrawLayer;
uint16 idxOfs;
void* drawBatchVtxPtr;
uint16* drawBatchIdxPtr;
gBFApp->mRenderDevice->mCurDrawLayer->AllocIndexed(vtxCount, idxCount, (void**)&drawBatchVtxPtr, &drawBatchIdxPtr, &idxOfs);
BF_ASSERT(gBFApp->mRenderDevice->mCurDrawLayer->mCurDrawBatch->mVtxSize == vertexSize);
uint16* idxPtr = idxData;
for (int idxIdx = 0; idxIdx < idxCount; idxIdx++)
*(drawBatchIdxPtr++) = *(idxPtr++) + idxOfs;
//memcpy(drawBatchIdxPtr, idxData, sizeof(uint16) * idxCount);
//memcpy(drawBatchVtxPtr, vtxData, vertexSize * vtxCount);
void* vtxPtr = vtxData;
for (int vtxIdx = 0; vtxIdx < vtxCount; vtxIdx++)
{
Vector3* srcPos = (Vector3*)vtxPtr;
Vector3* destPos = (Vector3*)drawBatchVtxPtr;
destPos->mX = srcPos->mX * a + srcPos->mY * c + tx;
destPos->mY = srcPos->mX * b + srcPos->mY * d + ty;
destPos->mZ = srcPos->mZ + z;
memcpy((uint8*)drawBatchVtxPtr + sizeof(Vector3), (uint8*)vtxPtr + sizeof(Vector3), vertexSize - sizeof(Vector3));
drawBatchVtxPtr = (uint8*)drawBatchVtxPtr + vertexSize;
vtxPtr = (uint8*)vtxPtr + vertexSize;
}
}
BF_EXPORT void BF_CALLTYPE Gfx_SetShaderConstantData(int slotIdx, void* constData, int size)
{
gBFApp->mRenderDevice->mCurDrawLayer->SetShaderConstantData(slotIdx, constData, size);
}
BF_EXPORT void BF_CALLTYPE Gfx_SetShaderConstantDataTyped(int slotIdx, void* constData, int size, int* typeData, int typeCount)
{
gBFApp->mRenderDevice->mCurDrawLayer->SetShaderConstantDataTyped(slotIdx, constData, size, typeData, typeCount);
}
BF_EXPORT void BF_CALLTYPE Gfx_QueueRenderCmd(RenderCmd* renderCmd)
{
gBFApp->mRenderDevice->mCurDrawLayer->QueueRenderCmd(renderCmd);
}
BF_EXPORT VertexDefinition* BF_CALLTYPE Gfx_CreateVertexDefinition(VertexDefData* elementData, int numElements)
{
return gBFApp->mRenderDevice->CreateVertexDefinition(elementData, numElements);
}
BF_EXPORT void BF_CALLTYPE Gfx_VertexDefinition_Delete(VertexDefinition* vertexDefinition)
{
delete vertexDefinition;
}
BF_EXPORT void BF_CALLTYPE Gfx_CreateRenderState(RenderState* srcRenderState)
{
gBFApp->mRenderDevice->CreateRenderState(srcRenderState);
}
BF_EXPORT void BF_CALLTYPE RenderState_Delete(RenderState* renderState)
{
delete renderState;
}
BF_EXPORT void BF_CALLTYPE RenderState_SetClip(RenderState* renderState, float x, float y, float width, float height)
{
BF_ASSERT((width >= 0) && (height >= 0));
renderState->mClipRect.mX = x;
renderState->mClipRect.mY = y;
renderState->mClipRect.mWidth = width;
renderState->mClipRect.mHeight = height;
if (!renderState->mClipped)
renderState->SetClipped(true);
}
BF_EXPORT void BF_CALLTYPE RenderState_SetShader(RenderState* renderState, Shader* shader)
{
renderState->SetShader(shader);
}
BF_EXPORT void BF_CALLTYPE RenderState_DisableClip(RenderState* renderState)
{
renderState->SetClipped(false);
}
BF_EXPORT void BF_CALLTYPE Gfx_SetTexture_TextureSegment(int textureIdx, TextureSegment* textureSegment)
{
DrawLayer* drawLayer = gBFApp->mRenderDevice->mCurDrawLayer;
drawLayer->SetTexture(textureIdx, textureSegment->mTexture);
}
BF_EXPORT void BF_CALLTYPE RenderState_SetDepthFunc(RenderState* renderState, int depthFunc)
{
renderState->SetDepthFunc((DepthFunc)depthFunc);
}
BF_EXPORT void BF_CALLTYPE RenderState_SetDepthWrite(RenderState* renderState, int depthWrite)
{
renderState->SetWriteDepthBuffer(depthWrite != 0);
}
BF_EXPORT Shader* BF_CALLTYPE Gfx_LoadShader(const char* fileName, VertexDefinition* vertexDefinition)
{
return gBFApp->mRenderDevice->LoadShader(fileName, vertexDefinition);
}
BF_EXPORT void BF_CALLTYPE Gfx_SetRenderState(RenderState* renderState)
{
BF_ASSERT(renderState->mShader != NULL);
gBFApp->mRenderDevice->SetRenderState(renderState);
}
BF_EXPORT void BF_CALLTYPE Gfx_Shader_Delete(Shader* shader)
{
delete shader;
}
BF_EXPORT ShaderParam* BF_CALLTYPE Gfx_GetShaderParam(Shader* shader, const char* shaderName)
{
return shader->GetShaderParam(shaderName);
}
BF_EXPORT int BF_CALLTYPE BF_TickCount()
{
return (int) BFTickCount();
}
BF_EXPORT int64 BF_CALLTYPE BF_TickCountMicroFast()
{
return (int) BFGetTickCountMicroFast();
}
BF_EXPORT void BF_CALLTYPE BF_Test()
{
BF_ASSERT(false);
int iArr[] = {2, 3, 4};
for (int i = 0; i < 10; i++)
OutputDebugStrF("Hey %d\n", i);
OutputDebugStrF("Break\n");
for (int i : iArr)
OutputDebugStrF("Hey %d\n", i);
}

File diff suppressed because it is too large Load diff

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,12 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="12.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Release|Win32'">
<LocalDebuggerCommand>$(SolutionDir)/dist/$(SolutionName).exe</LocalDebuggerCommand>
<LocalDebuggerWorkingDirectory>$(SolutionDir)/dist</LocalDebuggerWorkingDirectory>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
<PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|Win32'">
<LocalDebuggerCommand>C:\Beef\CycloBuddy\dist\CycloBuddy.exe</LocalDebuggerCommand>
<DebuggerFlavor>WindowsLocalDebugger</DebuggerFlavor>
</PropertyGroup>
</Project>

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,888 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup>
<Filter Include="Resource Files">
<UniqueIdentifier>{67DA6AB6-F800-4c08-8B7A-83BB121AAD01}</UniqueIdentifier>
<Extensions>rc;ico;cur;bmp;dlg;rc2;rct;bin;rgs;gif;jpg;jpeg;jpe;resx;tiff;tif;png;wav;mfcribbon-ms</Extensions>
</Filter>
<Filter Include="src">
<UniqueIdentifier>{93995380-89BD-4b04-88EB-625FBE52EBFB}</UniqueIdentifier>
<Extensions>h;hpp;hxx;hm;inl;inc;xsd</Extensions>
</Filter>
<Filter Include="src\gfx">
<UniqueIdentifier>{43f7e8cc-917a-461b-af5c-961d51c98d65}</UniqueIdentifier>
</Filter>
<Filter Include="src\platform">
<UniqueIdentifier>{5c6ad523-a93e-403b-b358-a15f86078b0f}</UniqueIdentifier>
</Filter>
<Filter Include="src\platform\win">
<UniqueIdentifier>{813c38d5-9d89-4491-bff7-3c25047100d8}</UniqueIdentifier>
</Filter>
<Filter Include="src\img">
<UniqueIdentifier>{2b273590-2487-4e10-acbd-022423c4536c}</UniqueIdentifier>
</Filter>
<Filter Include="src\third_party">
<UniqueIdentifier>{31571ecc-bfdf-44c1-a91d-c1d4b61704c7}</UniqueIdentifier>
</Filter>
<Filter Include="src\third_party\png">
<UniqueIdentifier>{f5ef9398-c086-4951-8614-ceb324d5e029}</UniqueIdentifier>
</Filter>
<Filter Include="src\third_party\zlib">
<UniqueIdentifier>{73a918ba-1f42-4f8e-a7ba-e76494ecdae0}</UniqueIdentifier>
</Filter>
<Filter Include="src\util">
<UniqueIdentifier>{0dfbd92a-e027-49fb-a13f-ffcf0975d4d6}</UniqueIdentifier>
</Filter>
<Filter Include="src\third_party\jpeg">
<UniqueIdentifier>{e7c2dc52-128b-402e-9f94-5c8aeaf27bb3}</UniqueIdentifier>
</Filter>
<Filter Include="src\sound">
<UniqueIdentifier>{5367b1b8-4b9c-437a-9423-7fb1e94b52a0}</UniqueIdentifier>
</Filter>
<Filter Include="src\third_party\ffi">
<UniqueIdentifier>{f7c9966e-5b74-43ba-8a5d-db503ea8aaa6}</UniqueIdentifier>
</Filter>
<Filter Include="src\third_party\libffi">
<UniqueIdentifier>{3ea6b611-924e-4aa1-a5d3-18899c959c9e}</UniqueIdentifier>
</Filter>
<Filter Include="src\third_party\libffi\x86">
<UniqueIdentifier>{e8f4f338-80e8-41ba-ae42-1d03754841ca}</UniqueIdentifier>
</Filter>
<Filter Include="src\platform\sdl">
<UniqueIdentifier>{c2ca20db-b847-4e2f-bc23-57432468dbb1}</UniqueIdentifier>
</Filter>
<Filter Include="src\perf_tests">
<UniqueIdentifier>{e6e45fc1-c3c8-410e-8eca-442b3bfe8f9f}</UniqueIdentifier>
</Filter>
<Filter Include="src\fbx">
<UniqueIdentifier>{befafaa7-a995-4087-ab20-0733b6ae8668}</UniqueIdentifier>
</Filter>
<Filter Include="src\sound\Common">
<UniqueIdentifier>{af42d59a-8e02-4478-b3f1-0bca4eba293e}</UniqueIdentifier>
</Filter>
<Filter Include="src\sound\Win32">
<UniqueIdentifier>{3e364db0-45bf-49fe-8d44-1a2679204c6f}</UniqueIdentifier>
</Filter>
<Filter Include="src\third_party\utf8proc">
<UniqueIdentifier>{1309f90f-4745-4623-ab21-5d7b1450103c}</UniqueIdentifier>
</Filter>
</ItemGroup>
<ItemGroup>
<ClCompile Include="platform\win\DXRenderDevice.cpp">
<Filter>src\platform\win</Filter>
</ClCompile>
<ClCompile Include="platform\win\Platform.cpp">
<Filter>src\platform\win</Filter>
</ClCompile>
<ClCompile Include="gfx\Shader.cpp">
<Filter>src\gfx</Filter>
</ClCompile>
<ClCompile Include="gfx\Texture.cpp">
<Filter>src\gfx</Filter>
</ClCompile>
<ClCompile Include="platform\win\WinBFApp.cpp">
<Filter>src\platform\win</Filter>
</ClCompile>
<ClCompile Include="BFApp.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="BeefySysLib.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="Common.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="BFWindow.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="gfx\RenderDevice.cpp">
<Filter>src\gfx</Filter>
</ClCompile>
<ClCompile Include="third_party\png\png.c">
<Filter>src\third_party\png</Filter>
</ClCompile>
<ClCompile Include="third_party\png\pngerror.c">
<Filter>src\third_party\png</Filter>
</ClCompile>
<ClCompile Include="third_party\png\pngget.c">
<Filter>src\third_party\png</Filter>
</ClCompile>
<ClCompile Include="third_party\png\pngmem.c">
<Filter>src\third_party\png</Filter>
</ClCompile>
<ClCompile Include="third_party\png\pngpread.c">
<Filter>src\third_party\png</Filter>
</ClCompile>
<ClCompile Include="third_party\png\pngread.c">
<Filter>src\third_party\png</Filter>
</ClCompile>
<ClCompile Include="third_party\png\pngrio.c">
<Filter>src\third_party\png</Filter>
</ClCompile>
<ClCompile Include="third_party\png\pngrtran.c">
<Filter>src\third_party\png</Filter>
</ClCompile>
<ClCompile Include="third_party\png\pngrutil.c">
<Filter>src\third_party\png</Filter>
</ClCompile>
<ClCompile Include="third_party\png\pngset.c">
<Filter>src\third_party\png</Filter>
</ClCompile>
<ClCompile Include="third_party\png\pngtrans.c">
<Filter>src\third_party\png</Filter>
</ClCompile>
<ClCompile Include="third_party\png\pngvcrd.c">
<Filter>src\third_party\png</Filter>
</ClCompile>
<ClCompile Include="third_party\png\pngwio.c">
<Filter>src\third_party\png</Filter>
</ClCompile>
<ClCompile Include="third_party\png\pngwrite.c">
<Filter>src\third_party\png</Filter>
</ClCompile>
<ClCompile Include="third_party\png\pngwtran.c">
<Filter>src\third_party\png</Filter>
</ClCompile>
<ClCompile Include="third_party\png\pngwutil.c">
<Filter>src\third_party\png</Filter>
</ClCompile>
<ClCompile Include="third_party\zlib\adler32.c">
<Filter>src\third_party\zlib</Filter>
</ClCompile>
<ClCompile Include="third_party\zlib\compress.c">
<Filter>src\third_party\zlib</Filter>
</ClCompile>
<ClCompile Include="third_party\zlib\crc32.c">
<Filter>src\third_party\zlib</Filter>
</ClCompile>
<ClCompile Include="third_party\zlib\deflate.c">
<Filter>src\third_party\zlib</Filter>
</ClCompile>
<ClCompile Include="third_party\zlib\gzio.c">
<Filter>src\third_party\zlib</Filter>
</ClCompile>
<ClCompile Include="third_party\zlib\infblock.c">
<Filter>src\third_party\zlib</Filter>
</ClCompile>
<ClCompile Include="third_party\zlib\infcodes.c">
<Filter>src\third_party\zlib</Filter>
</ClCompile>
<ClCompile Include="third_party\zlib\inffast.c">
<Filter>src\third_party\zlib</Filter>
</ClCompile>
<ClCompile Include="third_party\zlib\inflate.c">
<Filter>src\third_party\zlib</Filter>
</ClCompile>
<ClCompile Include="third_party\zlib\inftrees.c">
<Filter>src\third_party\zlib</Filter>
</ClCompile>
<ClCompile Include="third_party\zlib\infutil.c">
<Filter>src\third_party\zlib</Filter>
</ClCompile>
<ClCompile Include="third_party\zlib\trees.c">
<Filter>src\third_party\zlib</Filter>
</ClCompile>
<ClCompile Include="third_party\zlib\uncompr.c">
<Filter>src\third_party\zlib</Filter>
</ClCompile>
<ClCompile Include="third_party\zlib\zutil.c">
<Filter>src\third_party\zlib</Filter>
</ClCompile>
<ClCompile Include="img\ImageData.cpp">
<Filter>src\img</Filter>
</ClCompile>
<ClCompile Include="img\PNGData.cpp">
<Filter>src\img</Filter>
</ClCompile>
<ClCompile Include="img\TGAData.cpp">
<Filter>src\img</Filter>
</ClCompile>
<ClCompile Include="ResLib.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="img\PSDReader.cpp">
<Filter>src\img</Filter>
</ClCompile>
<ClCompile Include="FileStream.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="img\ImgEffects.cpp">
<Filter>src\img</Filter>
</ClCompile>
<ClCompile Include="util\BSpline.cpp">
<Filter>src\util</Filter>
</ClCompile>
<ClCompile Include="util\Point.cpp">
<Filter>src\util</Filter>
</ClCompile>
<ClCompile Include="util\CatmullRom.cpp">
<Filter>src\util</Filter>
</ClCompile>
<ClCompile Include="util\CubicSpline.cpp">
<Filter>src\util</Filter>
</ClCompile>
<ClCompile Include="util\PolySpline.cpp">
<Filter>src\util</Filter>
</ClCompile>
<ClCompile Include="util\CubicFuncSpline.cpp">
<Filter>src\util</Filter>
</ClCompile>
<ClCompile Include="img\ImageUtils.cpp">
<Filter>src\img</Filter>
</ClCompile>
<ClCompile Include="util\Vector.cpp">
<Filter>src\util</Filter>
</ClCompile>
<ClCompile Include="img\ImageAdjustments.cpp">
<Filter>src\img</Filter>
</ClCompile>
<ClCompile Include="img\PVRData.cpp">
<Filter>src\img</Filter>
</ClCompile>
<ClCompile Include="img\BFIData.cpp">
<Filter>src\img</Filter>
</ClCompile>
<ClCompile Include="img\JPEGData.cpp">
<Filter>src\img</Filter>
</ClCompile>
<ClCompile Include="MemStream.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="DataStream.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="util\PerfTimer.cpp">
<Filter>src\util</Filter>
</ClCompile>
<ClCompile Include="gfx\DrawLayer.cpp">
<Filter>src\gfx</Filter>
</ClCompile>
<ClCompile Include="gfx\RenderTarget.cpp">
<Filter>src\gfx</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\cdjpeg.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jcapimin.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jcapistd.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jccoefct.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jccolor.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jcdctmgr.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jchuff.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jcinit.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jcmainct.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jcmarker.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jcmaster.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jcomapi.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jcparam.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jcphuff.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jcprepct.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jcsample.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jctrans.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jdapimin.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jdapistd.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jdatadst.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jdatasrc.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jdcoefct.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jdcolor.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jddctmgr.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jdhuff.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jdinput.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jdmainct.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jdmarker.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jdmaster.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jdmerge.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jdphuff.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jdpostct.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jdsample.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jdtrans.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jerror.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jfdctflt.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jfdctfst.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jfdctint.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jidctflt.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jidctfst.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jidctint.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jidctred.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jmemansi.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jmemmgr.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jquant1.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jquant2.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\jutils.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\rdbmp.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\rdcolmap.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\rdgif.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\rdppm.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\rdrle.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\rdswitch.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\rdtarga.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\transupp.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\wrbmp.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\wrgif.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\wrppm.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\wrrle.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="third_party\jpeg\wrtarga.c">
<Filter>src\third_party\jpeg</Filter>
</ClCompile>
<ClCompile Include="sound\WwiseSound.cpp">
<Filter>src\sound</Filter>
</ClCompile>
<ClCompile Include="third_party\libffi\src\x86\ffi.c">
<Filter>src\third_party\libffi\x86</Filter>
</ClCompile>
<ClCompile Include="third_party\libffi\src\x86\ffi64.c">
<Filter>src\third_party\libffi\x86</Filter>
</ClCompile>
<ClCompile Include="third_party\libffi\src\closures.c">
<Filter>src\third_party\libffi</Filter>
</ClCompile>
<ClCompile Include="third_party\libffi\src\debug.c">
<Filter>src\third_party\libffi</Filter>
</ClCompile>
<ClCompile Include="third_party\libffi\src\java_raw_api.c">
<Filter>src\third_party\libffi</Filter>
</ClCompile>
<ClCompile Include="third_party\libffi\src\prep_cif.c">
<Filter>src\third_party\libffi</Filter>
</ClCompile>
<ClCompile Include="third_party\libffi\src\raw_api.c">
<Filter>src\third_party\libffi</Filter>
</ClCompile>
<ClCompile Include="third_party\libffi\src\types.c">
<Filter>src\third_party\libffi</Filter>
</ClCompile>
<ClCompile Include="util\UTF8.cpp">
<Filter>src\util</Filter>
</ClCompile>
<ClCompile Include="platform\sdl\SdlBFApp.cpp">
<Filter>src\platform\sdl</Filter>
</ClCompile>
<ClCompile Include="platform\sdl\GLRenderDevice.cpp">
<Filter>src\platform\sdl</Filter>
</ClCompile>
<ClCompile Include="Startup.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="PerfTests.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="perf_tests\fannkuchredux.cpp">
<Filter>src\perf_tests</Filter>
</ClCompile>
<ClCompile Include="perf_tests\fastaredux.cpp">
<Filter>src\perf_tests</Filter>
</ClCompile>
<ClCompile Include="perf_tests\nbody.cpp">
<Filter>src\perf_tests</Filter>
</ClCompile>
<ClCompile Include="fbx\FBXReader.cpp">
<Filter>src\fbx</Filter>
</ClCompile>
<ClCompile Include="gfx\RenderCmd.cpp">
<Filter>src\gfx</Filter>
</ClCompile>
<ClCompile Include="util\Matrix4.cpp">
<Filter>src\util</Filter>
</ClCompile>
<ClCompile Include="gfx\ModelDef.cpp">
<Filter>src\gfx</Filter>
</ClCompile>
<ClCompile Include="gfx\ModelInstance.cpp">
<Filter>src\gfx</Filter>
</ClCompile>
<ClCompile Include="util\Quaternion.cpp">
<Filter>src\util</Filter>
</ClCompile>
<ClCompile Include="sound\Common\AkDefaultLowLevelIODispatcher.cpp">
<Filter>src\sound\Common</Filter>
</ClCompile>
<ClCompile Include="sound\Common\AkFileLocationBase.cpp">
<Filter>src\sound\Common</Filter>
</ClCompile>
<ClCompile Include="sound\Common\AkFilePackage.cpp">
<Filter>src\sound\Common</Filter>
</ClCompile>
<ClCompile Include="sound\Common\AkFilePackageLUT.cpp">
<Filter>src\sound\Common</Filter>
</ClCompile>
<ClCompile Include="sound\Win32\AkDefaultIOHookBlocking.cpp">
<Filter>src\sound\Win32</Filter>
</ClCompile>
<ClCompile Include="sound\Win32\AkDefaultIOHookDeferred.cpp">
<Filter>src\sound\Win32</Filter>
</ClCompile>
<ClCompile Include="util\Hash.cpp">
<Filter>src\util</Filter>
</ClCompile>
<ClCompile Include="util\AllocDebug.cpp">
<Filter>src\util</Filter>
</ClCompile>
<ClCompile Include="util\Json.cpp">
<Filter>src\util</Filter>
</ClCompile>
<ClCompile Include="FileHandleStream.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="util\ChunkedDataBuffer.cpp">
<Filter>src\util</Filter>
</ClCompile>
<ClCompile Include="util\WorkThread.cpp">
<Filter>src\util</Filter>
</ClCompile>
<ClCompile Include="CachedDataStream.cpp">
<Filter>src</Filter>
</ClCompile>
<ClCompile Include="util\BeefPerf.cpp">
<Filter>src\util</Filter>
</ClCompile>
<ClCompile Include="third_party\utf8proc\utf8proc.c">
<Filter>src\third_party\utf8proc</Filter>
</ClCompile>
<ClCompile Include="util\FileEnumerator.cpp" />
<ClCompile Include="util\String.cpp">
<Filter>src\util</Filter>
</ClCompile>
<ClCompile Include="util\CabUtil.cpp" />
<ClCompile Include="util\MappedFile.cpp">
<Filter>src\util</Filter>
</ClCompile>
<ClCompile Include="platform\win\CrashCatcher.cpp">
<Filter>src\platform\win</Filter>
</ClCompile>
<ClCompile Include="util\StackHelper.cpp">
<Filter>src\util</Filter>
</ClCompile>
<ClCompile Include="util\ThreadPool.cpp" />
</ItemGroup>
<ItemGroup>
<ClInclude Include="Common.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="platform\win\DXRenderDevice.h">
<Filter>src\platform\win</Filter>
</ClInclude>
<ClInclude Include="gfx\Shader.h">
<Filter>src\gfx</Filter>
</ClInclude>
<ClInclude Include="gfx\Texture.h">
<Filter>src\gfx</Filter>
</ClInclude>
<ClInclude Include="gfx\RenderDevice.h">
<Filter>src\gfx</Filter>
</ClInclude>
<ClInclude Include="platform\win\WinBFApp.h">
<Filter>src\platform\win</Filter>
</ClInclude>
<ClInclude Include="BFApp.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="platform\win\PlatformApp.h">
<Filter>src\platform\win</Filter>
</ClInclude>
<ClInclude Include="BFWindow.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="third_party\png\png.h">
<Filter>src\third_party\png</Filter>
</ClInclude>
<ClInclude Include="third_party\png\pngasmrd.h">
<Filter>src\third_party\png</Filter>
</ClInclude>
<ClInclude Include="third_party\png\pngconf.h">
<Filter>src\third_party\png</Filter>
</ClInclude>
<ClInclude Include="third_party\zlib\deflate.h">
<Filter>src\third_party\zlib</Filter>
</ClInclude>
<ClInclude Include="third_party\zlib\infblock.h">
<Filter>src\third_party\zlib</Filter>
</ClInclude>
<ClInclude Include="third_party\zlib\infcodes.h">
<Filter>src\third_party\zlib</Filter>
</ClInclude>
<ClInclude Include="third_party\zlib\inffast.h">
<Filter>src\third_party\zlib</Filter>
</ClInclude>
<ClInclude Include="third_party\zlib\inffixed.h">
<Filter>src\third_party\zlib</Filter>
</ClInclude>
<ClInclude Include="third_party\zlib\inftrees.h">
<Filter>src\third_party\zlib</Filter>
</ClInclude>
<ClInclude Include="third_party\zlib\infutil.h">
<Filter>src\third_party\zlib</Filter>
</ClInclude>
<ClInclude Include="third_party\zlib\trees.h">
<Filter>src\third_party\zlib</Filter>
</ClInclude>
<ClInclude Include="third_party\zlib\zconf.h">
<Filter>src\third_party\zlib</Filter>
</ClInclude>
<ClInclude Include="third_party\zlib\zlib.h">
<Filter>src\third_party\zlib</Filter>
</ClInclude>
<ClInclude Include="third_party\zlib\zutil.h">
<Filter>src\third_party\zlib</Filter>
</ClInclude>
<ClInclude Include="img\ImageData.h">
<Filter>src\img</Filter>
</ClInclude>
<ClInclude Include="img\PNGData.h">
<Filter>src\img</Filter>
</ClInclude>
<ClInclude Include="img\TGAData.h">
<Filter>src\img</Filter>
</ClInclude>
<ClInclude Include="img\PSDReader.h">
<Filter>src\img</Filter>
</ClInclude>
<ClInclude Include="FileStream.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="img\ImgEffects.h">
<Filter>src\img</Filter>
</ClInclude>
<ClInclude Include="util\BSpline.h">
<Filter>src\util</Filter>
</ClInclude>
<ClInclude Include="util\CatmullRom.h">
<Filter>src\util</Filter>
</ClInclude>
<ClInclude Include="util\Point.h">
<Filter>src\util</Filter>
</ClInclude>
<ClInclude Include="util\CubicSpline.h">
<Filter>src\util</Filter>
</ClInclude>
<ClInclude Include="util\PolySpline.h">
<Filter>src\util</Filter>
</ClInclude>
<ClInclude Include="util\CubicFuncSpline.h">
<Filter>src\util</Filter>
</ClInclude>
<ClInclude Include="util\Vector.h">
<Filter>src\util</Filter>
</ClInclude>
<ClInclude Include="img\ImageUtils.h">
<Filter>src\img</Filter>
</ClInclude>
<ClInclude Include="img\ImageAdjustments.h">
<Filter>src\img</Filter>
</ClInclude>
<ClInclude Include="img\PVRData.h">
<Filter>src\img</Filter>
</ClInclude>
<ClInclude Include="img\BFIData.h">
<Filter>src\img</Filter>
</ClInclude>
<ClInclude Include="img\JPEGData.h">
<Filter>src\img</Filter>
</ClInclude>
<ClInclude Include="DataStream.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="MemStream.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="util\PerfTimer.h">
<Filter>src\util</Filter>
</ClInclude>
<ClInclude Include="gfx\RenderTarget.h">
<Filter>src\gfx</Filter>
</ClInclude>
<ClInclude Include="gfx\DrawLayer.h">
<Filter>src\gfx</Filter>
</ClInclude>
<ClInclude Include="third_party\jpeg\cderror.h">
<Filter>src\third_party\jpeg</Filter>
</ClInclude>
<ClInclude Include="third_party\jpeg\cdjpeg.h">
<Filter>src\third_party\jpeg</Filter>
</ClInclude>
<ClInclude Include="third_party\jpeg\jchuff.h">
<Filter>src\third_party\jpeg</Filter>
</ClInclude>
<ClInclude Include="third_party\jpeg\jconfig.h">
<Filter>src\third_party\jpeg</Filter>
</ClInclude>
<ClInclude Include="third_party\jpeg\jdct.h">
<Filter>src\third_party\jpeg</Filter>
</ClInclude>
<ClInclude Include="third_party\jpeg\jdhuff.h">
<Filter>src\third_party\jpeg</Filter>
</ClInclude>
<ClInclude Include="third_party\jpeg\jerror.h">
<Filter>src\third_party\jpeg</Filter>
</ClInclude>
<ClInclude Include="third_party\jpeg\jinclude.h">
<Filter>src\third_party\jpeg</Filter>
</ClInclude>
<ClInclude Include="third_party\jpeg\jmemsys.h">
<Filter>src\third_party\jpeg</Filter>
</ClInclude>
<ClInclude Include="third_party\jpeg\jmorecfg.h">
<Filter>src\third_party\jpeg</Filter>
</ClInclude>
<ClInclude Include="third_party\jpeg\jpegint.h">
<Filter>src\third_party\jpeg</Filter>
</ClInclude>
<ClInclude Include="third_party\jpeg\jpeglib.h">
<Filter>src\third_party\jpeg</Filter>
</ClInclude>
<ClInclude Include="third_party\jpeg\jversion.h">
<Filter>src\third_party\jpeg</Filter>
</ClInclude>
<ClInclude Include="third_party\jpeg\transupp.h">
<Filter>src\third_party\jpeg</Filter>
</ClInclude>
<ClInclude Include="sound\WwiseSound.h">
<Filter>src\sound</Filter>
</ClInclude>
<ClInclude Include="third_party\libffi\i686-pc-cygwin\include\ffi.h">
<Filter>src\third_party\libffi</Filter>
</ClInclude>
<ClInclude Include="third_party\libffi\i686-pc-cygwin\include\ffitarget.h">
<Filter>src\third_party\libffi</Filter>
</ClInclude>
<ClInclude Include="platform\win\BFPlatform.h">
<Filter>src\platform\win</Filter>
</ClInclude>
<ClInclude Include="util\UTF8.h">
<Filter>src\util</Filter>
</ClInclude>
<ClInclude Include="platform\sdl\SdlBFApp.h">
<Filter>src\platform\sdl</Filter>
</ClInclude>
<ClInclude Include="platform\sdl\GLRenderDevice.h">
<Filter>src\platform\sdl</Filter>
</ClInclude>
<ClInclude Include="util\CritSect.h">
<Filter>src\util</Filter>
</ClInclude>
<ClInclude Include="fbx\FBXReader.h">
<Filter>src\fbx</Filter>
</ClInclude>
<ClInclude Include="util\Matrix4.h">
<Filter>src\util</Filter>
</ClInclude>
<ClInclude Include="util\SLIList.h">
<Filter>src\util</Filter>
</ClInclude>
<ClInclude Include="util\Rect.h">
<Filter>src\util</Filter>
</ClInclude>
<ClInclude Include="gfx\ModelInstance.h">
<Filter>src\gfx</Filter>
</ClInclude>
<ClInclude Include="gfx\RenderCmd.h">
<Filter>src\gfx</Filter>
</ClInclude>
<ClInclude Include="util\Quaternion.h">
<Filter>src\util</Filter>
</ClInclude>
<ClInclude Include="gfx\ModelDef.h">
<Filter>src\gfx</Filter>
</ClInclude>
<ClInclude Include="sound\Common\AkDefaultLowLevelIODispatcher.h">
<Filter>src\sound\Common</Filter>
</ClInclude>
<ClInclude Include="sound\Common\AkFileLocationBase.h">
<Filter>src\sound\Common</Filter>
</ClInclude>
<ClInclude Include="sound\Common\AkFilePackage.h">
<Filter>src\sound\Common</Filter>
</ClInclude>
<ClInclude Include="sound\Common\AkFilePackageLowLevelIO.h">
<Filter>src\sound\Common</Filter>
</ClInclude>
<ClInclude Include="sound\Common\AkFilePackageLUT.h">
<Filter>src\sound\Common</Filter>
</ClInclude>
<ClInclude Include="sound\Win32\AkDefaultIOHookBlocking.h">
<Filter>src\sound\Win32</Filter>
</ClInclude>
<ClInclude Include="sound\Win32\AkDefaultIOHookDeferred.h">
<Filter>src\sound\Win32</Filter>
</ClInclude>
<ClInclude Include="sound\Win32\AkFileHelpers.h">
<Filter>src\sound\Win32</Filter>
</ClInclude>
<ClInclude Include="sound\Win32\AkFilePackageLowLevelIOBlocking.h">
<Filter>src\sound\Win32</Filter>
</ClInclude>
<ClInclude Include="sound\Win32\AkFilePackageLowLevelIODeferred.h">
<Filter>src\sound\Win32</Filter>
</ClInclude>
<ClInclude Include="util\Hash.h">
<Filter>src\util</Filter>
</ClInclude>
<ClInclude Include="util\Json.h">
<Filter>src\util</Filter>
</ClInclude>
<ClInclude Include="FileHandleStream.h">
<Filter>src</Filter>
</ClInclude>
<ClInclude Include="util\WorkThread.h">
<Filter>src\util</Filter>
</ClInclude>
<ClInclude Include="util\BeefPerf.h">
<Filter>src\util</Filter>
</ClInclude>
<ClInclude Include="third_party\utf8proc\utf8proc.h">
<Filter>src\third_party\utf8proc</Filter>
</ClInclude>
<ClInclude Include="util\TLSingleton.h">
<Filter>src\util</Filter>
</ClInclude>
<ClInclude Include="util\FileEnumerator.h">
<Filter>src\util</Filter>
</ClInclude>
<ClInclude Include="util\String.h">
<Filter>src\util</Filter>
</ClInclude>
<ClInclude Include="util\CabUtil.h">
<Filter>src\util</Filter>
</ClInclude>
<ClInclude Include="util\MappedFile.h">
<Filter>src\util</Filter>
</ClInclude>
<ClInclude Include="platform\win\CrashCatcher.h">
<Filter>src\platform\win</Filter>
</ClInclude>
<ClInclude Include="util\StackHelper.h">
<Filter>src\util</Filter>
</ClInclude>
<ClInclude Include="util\ThreadPool.h">
<Filter>src\util</Filter>
</ClInclude>
</ItemGroup>
<ItemGroup>
<CustomBuild Include="third_party\libffi\i686-pc-cygwin\src\x86\win32.asm">
<Filter>src\third_party\libffi\x86</Filter>
</CustomBuild>
<CustomBuild Include="third_party\libffi\i686-pc-cygwin\src\x86\win64.asm">
<Filter>src\third_party\libffi\x86</Filter>
</CustomBuild>
</ItemGroup>
<ItemGroup>
<None Include="sound\Common\AkFilePackageLowLevelIO.inl">
<Filter>src\sound\Common</Filter>
</None>
</ItemGroup>
</Project>

295
BeefySysLib/CMakeLists.txt Normal file
View file

@ -0,0 +1,295 @@
cmake_minimum_required(VERSION 3.0.0 FATAL_ERROR)
################### Variables. ####################
# Change if you want modify path or other values. #
###################################################
set(PROJECT_NAME BeefySysLib)
# Output Variables
set(OUTPUT_DEBUG Debug/bin)
set(CMAKE_DEBUG_POSTFIX "_d")
set(OUTPUT_RELEASE Release/bin)
############## CMake Project ################
# The main options of project #
#############################################
project(${PROJECT_NAME} CXX C)
# Define Release by default.
if(NOT CMAKE_BUILD_TYPE)
set(CMAKE_BUILD_TYPE "Debug")
message(STATUS "Build type not specified: Use Debug by default.")
endif(NOT CMAKE_BUILD_TYPE)
# Definition of Macros
add_definitions(
-DIDEHELPER_EXPORTS
-DBFSYSLIB_DYNAMIC
-DUNICODE
-D_UNICODE
-DBF_NO_FBX
-DFT2_BUILD_LIBRARY
-DBFSYSLIB_DYNAMIC
)
include_directories(
.
platform/linux
third_party
third_party/freetype/include
../extern
)
############## Artefacts Output #################
# Defines outputs , depending Debug or Release. #
#################################################
if(CMAKE_BUILD_TYPE STREQUAL "Debug")
add_definitions(
-D_DEBUG
)
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${OUTPUT_DEBUG}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${OUTPUT_DEBUG}")
set(CMAKE_EXECUTABLE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${OUTPUT_DEBUG}")
else()
set(CMAKE_LIBRARY_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${OUTPUT_RELEASE}")
set(CMAKE_ARCHIVE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${OUTPUT_RELEASE}")
set(CMAKE_EXECUTABLE_OUTPUT_DIRECTORY "${CMAKE_BINARY_DIR}/${OUTPUT_RELEASE}")
endif()
################### Dependencies ##################
# Add Dependencies to project. #
###################################################
option(BUILD_DEPENDS
"Build other CMake project."
ON
)
# Dependencies : disable BUILD_DEPENDS to link with lib already build.
if(BUILD_DEPENDS)
else()
endif()
################# Flags ################
# Defines Flags for Windows and Linux. #
########################################
if(MSVC)
set(CMAKE_CXX_FLAGS_DEBUG "${CMAKE_CXX_FLAGS_DEBUG} /W3 /MD /MDd /Od /EHsc")
set(CMAKE_CXX_FLAGS_RELEASE "${CMAKE_CXX_FLAGS_RELEASE} /W3 /GL /Od /Oi /Gy /EHsc")
endif(MSVC)
if(NOT MSVC)
set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11 -Wno-multichar")
if ("${CMAKE_CXX_COMPILER_ID}" STREQUAL "Clang")
set (CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -stdlib=libc++")
endif()
endif(NOT MSVC)
################ Files ################
# -- Add files to project. -- #
#######################################
file(GLOB SRC_FILES
BeefySysLib.cpp
BFApp.cpp
BFWindow.cpp
CachedDataStream.cpp
Common.cpp
DataStream.cpp
FileStream.cpp
HeadlessApp.cpp
MemStream.cpp
ResLib.cpp
Startup.cpp
platform/linux/BFPlatform.cpp
platform/linux/LinuxCommon.cpp
fbx/FBXReader.cpp
gfx/DrawLayer.cpp
gfx/FTFont.cpp
gfx/ModelDef.cpp
gfx/ModelInstance.cpp
gfx/RenderCmd.cpp
gfx/RenderDevice.cpp
gfx/RenderTarget.cpp
gfx/Shader.cpp
gfx/Texture.cpp
img/BFIData.cpp
img/ImageAdjustments.cpp
img/ImageData.cpp
img/ImageUtils.cpp
img/ImgEffects.cpp
img/JPEGData.cpp
img/PNGData.cpp
img/PSDReader.cpp
img/PVRData.cpp
img/TGAData.cpp
third_party/freetype/src/autofit/autofit.c
third_party/freetype/src/base/ftbase.c
third_party/freetype/src/base/ftbbox.c
third_party/freetype/src/base/ftbitmap.c
third_party/freetype/src/base/ftdebug.c
third_party/freetype/src/base/ftfntfmt.c
third_party/freetype/src/base/ftfstype.c
third_party/freetype/src/base/ftgasp.c
third_party/freetype/src/base/ftglyph.c
third_party/freetype/src/base/ftgxval.c
third_party/freetype/src/base/ftinit.c
third_party/freetype/src/base/ftlcdfil.c
third_party/freetype/src/base/ftmm.c
third_party/freetype/src/base/ftotval.c
third_party/freetype/src/base/ftpatent.c
third_party/freetype/src/base/ftstroke.c
third_party/freetype/src/base/ftsynth.c
third_party/freetype/src/base/ftsystem.c
third_party/freetype/src/base/fttype1.c
third_party/freetype/src/base/ftwinfnt.c
third_party/freetype/src/bdf/bdf.c
third_party/freetype/src/cache/ftcache.c
third_party/freetype/src/cff/cff.c
third_party/freetype/src/cid/type1cid.c
third_party/freetype/src/gzip/ftgzip.c
third_party/freetype/src/lzw/ftlzw.c
third_party/freetype/src/pcf/pcf.c
third_party/freetype/src/pfr/pfr.c
third_party/freetype/src/psaux/psaux.c
third_party/freetype/src/pshinter/pshinter.c
third_party/freetype/src/psnames/psmodule.c
third_party/freetype/src/raster/raster.c
third_party/freetype/src/sfnt/sfnt.c
third_party/freetype/src/smooth/smooth.c
third_party/freetype/src/truetype/truetype.c
third_party/freetype/src/type1/type1.c
third_party/freetype/src/type42/type42.c
third_party/freetype/src/winfonts/winfnt.c
third_party/jpeg/cdjpeg.c
third_party/jpeg/jcapimin.c
third_party/jpeg/jcapistd.c
third_party/jpeg/jccoefct.c
third_party/jpeg/jccolor.c
third_party/jpeg/jcdctmgr.c
third_party/jpeg/jchuff.c
third_party/jpeg/jcinit.c
third_party/jpeg/jcmainct.c
third_party/jpeg/jcmarker.c
third_party/jpeg/jcmaster.c
third_party/jpeg/jcomapi.c
third_party/jpeg/jcparam.c
third_party/jpeg/jcphuff.c
third_party/jpeg/jcprepct.c
third_party/jpeg/jcsample.c
third_party/jpeg/jctrans.c
third_party/jpeg/jdapimin.c
third_party/jpeg/jdapistd.c
third_party/jpeg/jdatadst.c
third_party/jpeg/jdatasrc.c
third_party/jpeg/jdcoefct.c
third_party/jpeg/jdcolor.c
third_party/jpeg/jddctmgr.c
third_party/jpeg/jdhuff.c
third_party/jpeg/jdinput.c
third_party/jpeg/jdmainct.c
third_party/jpeg/jdmarker.c
third_party/jpeg/jdmaster.c
third_party/jpeg/jdmerge.c
third_party/jpeg/jdphuff.c
third_party/jpeg/jdpostct.c
third_party/jpeg/jdsample.c
third_party/jpeg/jdtrans.c
third_party/jpeg/jerror.c
third_party/jpeg/jfdctflt.c
third_party/jpeg/jfdctfst.c
third_party/jpeg/jfdctint.c
third_party/jpeg/jidctflt.c
third_party/jpeg/jidctfst.c
third_party/jpeg/jidctint.c
third_party/jpeg/jidctred.c
third_party/jpeg/jmemansi.c
third_party/jpeg/jmemmgr.c
third_party/jpeg/jquant1.c
third_party/jpeg/jquant2.c
third_party/jpeg/jutils.c
third_party/jpeg/rdbmp.c
third_party/jpeg/rdcolmap.c
third_party/jpeg/rdgif.c
third_party/jpeg/rdppm.c
third_party/jpeg/rdrle.c
third_party/jpeg/rdswitch.c
third_party/jpeg/rdtarga.c
third_party/jpeg/transupp.c
third_party/jpeg/wrbmp.c
third_party/jpeg/wrgif.c
third_party/jpeg/wrppm.c
third_party/jpeg/wrrle.c
third_party/jpeg/wrtarga.c
third_party/png/png.c
third_party/png/pngerror.c
third_party/png/pngget.c
third_party/png/pngmem.c
third_party/png/pngpread.c
third_party/png/pngread.c
third_party/png/pngrio.c
third_party/png/pngrtran.c
third_party/png/pngrutil.c
third_party/png/pngset.c
third_party/png/pngtrans.c
third_party/png/pngvcrd.c
third_party/png/pngwio.c
third_party/png/pngwrite.c
third_party/png/pngwtran.c
third_party/png/pngwutil.c
third_party/utf8proc/utf8proc.c
third_party/zlib/adler32.c
third_party/zlib/compress.c
third_party/zlib/crc32.c
third_party/zlib/deflate.c
third_party/zlib/gzio.c
third_party/zlib/infblock.c
third_party/zlib/infcodes.c
third_party/zlib/inffast.c
third_party/zlib/inflate.c
third_party/zlib/inftrees.c
third_party/zlib/infutil.c
third_party/zlib/trees.c
third_party/zlib/uncompr.c
third_party/zlib/zutil.c
util/AllocDebug.cpp
util/BeefPerf.cpp
util/BSpline.cpp
util/CatmullRom.cpp
util/ChunkedDataBuffer.cpp
util/CubicFuncSpline.cpp
util/CubicSpline.cpp
util/FileEnumerator.cpp
util/Hash.cpp
util/Json.cpp
util/MappedFile.cpp
util/Matrix4.cpp
util/PerfTimer.cpp
util/Point.cpp
util/PolySpline.cpp
util/Quaternion.cpp
util/String.cpp
util/StackHelper.cpp
util/ThreadPool.cpp
util/UTF8.cpp
util/WorkThread.cpp
util/Vector.cpp
)
# Add library to build.
add_library(${PROJECT_NAME} SHARED
${SRC_FILES}
)
# Link with other dependencies.
if(MSVC)
target_link_libraries(${PROJECT_NAME} imm32.lib version.lib kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib
)
endif(MSVC)

View file

@ -0,0 +1,79 @@
#include "CachedDataStream.h"
USING_NS_BF;
CachedDataStream::CachedDataStream(DataStream* stream)
{
mStream = stream;
mDataPtr = mChunk;
mDataEnd = mChunk + CHUNK_SIZE;
}
CachedDataStream::~CachedDataStream()
{
Flush();
}
void CachedDataStream::Flush()
{
int cachedBytes = (int)(mDataPtr - mChunk);
if (cachedBytes > 0)
{
mStream->Write(mChunk, cachedBytes);
mDataPtr = mChunk;
}
}
bool CachedDataStream::Eof()
{
Flush();
return mStream->Eof();
}
int CachedDataStream::GetSize()
{
Flush();
return mStream->GetSize();
}
void CachedDataStream::Read(void* ptr, int size)
{
Flush();
mStream->Read(ptr, size);
}
void CachedDataStream::Write(void* ptr, int size)
{
while (size > 0)
{
int cacheLeft = (int)(mDataEnd - mDataPtr);
if (cacheLeft == 0)
{
Flush();
continue;
}
int writeBytes = std::min(cacheLeft, size);
memcpy(mDataPtr, ptr, writeBytes);
ptr = (uint8*)ptr + writeBytes;
size -= writeBytes;
mDataPtr += writeBytes;
}
}
int CachedDataStream::GetPos()
{
return mStream->GetPos() + (int)(mDataPtr - mChunk);
}
void CachedDataStream::Seek(int size)
{
Flush();
mStream->Seek(size);
}
void CachedDataStream::SetPos(int pos)
{
Flush();
mStream->SetPos(pos);
}

View file

@ -0,0 +1,35 @@
#pragma once
#include "DataStream.h"
NS_BF_BEGIN
class CachedDataStream : public DataStream
{
public:
const static int CHUNK_SIZE = 8192;
DataStream* mStream;
uint8 mChunk[CHUNK_SIZE];
uint8* mDataPtr;
uint8* mDataEnd;
public:
void Flush();
public:
CachedDataStream(DataStream* stream);
~CachedDataStream();
virtual bool Eof() override;
virtual int GetSize() override;
virtual void Read(void* ptr, int size) override;
virtual void Write(void* ptr, int size) override;
virtual int GetPos() override;
virtual void Seek(int size) override;
virtual void SetPos(int pos) override;
};
NS_BF_END

1258
BeefySysLib/Common.cpp Normal file

File diff suppressed because it is too large Load diff

297
BeefySysLib/Common.h Normal file
View file

@ -0,0 +1,297 @@
#pragma once
#define __STDC_LIMIT_MACROS
#define __STDC_CONSTANT_MACROS
// #include <string>
// #include <map>
// #include <set>
// #include <vector>
// #include <list>
#include <algorithm>
// #include <functional>
#include <functional>
#include "BFPlatform.h"
inline size_t HashBytes(const uint8* ptr, size_t count) noexcept
{
#ifdef BF64
const size_t _FNV_offset_basis = 14695981039346656037ULL;
const size_t _FNV_prime = 1099511628211ULL;
#else
const size_t _FNV_offset_basis = 2166136261U;
const size_t _FNV_prime = 16777619U;
#endif
size_t val = _FNV_offset_basis;
for (size_t _Next = 0; _Next < count; ++_Next)
{
val ^= (size_t)ptr[_Next];
val *= _FNV_prime;
}
return (val);
}
template <typename T>
struct BeefHash : std::hash<T>
{
};
template<class T>
struct BeefHash<T*>
{
size_t operator()(T* val) const
{
return (size_t)val ^ (size_t)val >> 11;
}
};
template <>
struct BeefHash<int>
{
size_t operator()(int val)
{
return (size_t)val;
}
};
template <>
struct BeefHash<int64>
{
size_t operator()(int64 val)
{
return (size_t)val;
}
};
struct uint128
{
uint64 mLo;
uint64 mHigh;
};
struct int128
{
uint64 mLo;
uint64 mHigh;
};
#define BF_MIN(x, y) (((x) < (y)) ? (x) : (y))
#define BF_MAX(x, y) (((x) > (y)) ? (x ): (y))
#define BF_CLAMP(val, minVal, maxVal) (((val) < (minVal)) ? (minVal) : ((val) > (maxVal)) ? (maxVal) : (val))
#define BF_SWAP(a, b) { auto _a = (a); (a) = (b); (b) = (_a); }
extern int gBFArgC;
extern char** gBFArgV;
#define NS_BF_BEGIN namespace Beefy {
#define NS_BF_END }
#define USING_NS_BF using namespace Beefy
#define BF_ARRAY_COUNT(arr) (sizeof(arr) / sizeof((arr)[0]))
#define BF_CLEAR_VALUE(val) memset(&val, 0, sizeof(val))
#define BF_ALIGN(intVal, alignSize) (((intVal) + ((alignSize) - 1)) & ~((alignSize) - 1))
#define BF_DISALLOW_COPY(name) name(const name& from) = delete;
#define BF_ASSERT_CONCAT_(a, b) a##b
#define BF_ASSERT_CONCAT(a, b) BF_ASSERT_CONCAT_(a, b)
#ifdef __COUNTER__
#define BF_STATIC_ASSERT(e) \
;enum { BF_ASSERT_CONCAT(static_assert_, __COUNTER__) = 1/(int)(!!(e)) }
#else
#define BF_STATIC_ASSERT(e) \
;enum { BF_ASSERT_CONCAT(assert_line_, __LINE__) = 1/(int)(!!(e)) }
#endif
NS_BF_BEGIN;
#ifndef max
template <typename T>
constexpr const T& max(const T& lhs, const T& rhs) noexcept
{
return (lhs < rhs) ? rhs : lhs;
}
template <typename T>
constexpr const T& min(const T& lhs, const T& rhs) noexcept
{
return (lhs < rhs) ? lhs : rhs;
}
#endif
class StringImpl;
template <const int TBufSize>
class StringT;
class UTF16String;
typedef StringT<16> String;
#ifdef BF64
#define V_32_64(v32, v64) v64
#else
#define V_32_64(v32, v64) v32
#endif
#define BF_PI 3.14159265359f
#define BF_PI_D 3.14159265359
//typedef std::vector<int> IntVector;
inline float BFRound(float aVal)
{
if (aVal < 0)
return (float) (int) (aVal - 0.5f);
else
return (float) (int) (aVal + 0.5f);
}
inline float BFClamp(float val, float min, float max)
{
return (val <= min) ? min : (val >= max) ? max : val;
}
inline int BFClamp(int val, int min, int max)
{
return (val <= min) ? min : (val >= max) ? max : val;
}
uint32 BFTickCount();
void BFFatalError(const char* message, const char* file, int line);
void BFFatalError(const StringImpl& message, const StringImpl& file, int line);
int64 EndianSwap(int64 val);
int32 EndianSwap(int32 val);
int16 EndianSwap(int16 val);
#ifdef BF_ENDIAN_LITTLE
static inline int64 FromBigEndian(int64 val) { return Beefy::EndianSwap(val); }
static inline int32 FromBigEndian(int32 val) { return Beefy::EndianSwap(val); }
static inline int16 FromBigEndian(int16 val) { return Beefy::EndianSwap(val); }
static inline uint64 FromBigEndian(uint64 val) { return Beefy::EndianSwap(*((int64*)&val)); }
static inline uint32 FromBigEndian(uint32 val) { return Beefy::EndianSwap(*((int32*)&val)); }
static inline uint16 FromBigEndian(uint16 val) { return Beefy::EndianSwap(*((int16*)&val)); }
static inline int64 ToBigEndian(int64 val) { return Beefy::EndianSwap(val); }
static inline int32 ToBigEndian(int32 val) { return Beefy::EndianSwap(val); }
static inline int16 ToBigEndian(int16 val) { return Beefy::EndianSwap(val); }
static inline uint64 ToBigEndian(uint64 val) { return Beefy::EndianSwap(*((int64*)&val)); }
static inline uint32 ToBigEndian(uint32 val) { return Beefy::EndianSwap(*((int32*)&val)); }
static inline uint16 ToBigEndian(uint16 val) { return Beefy::EndianSwap(*((int16*)&val)); }
static inline int64 FromLittleEndian(int64 val) { return val; }
static inline int32 FromLittleEndian(int32 val) { return val; }
static inline int16 FromLittleEndian(int16 val) { return val; }
static inline int64 FromLittleEndian(uint64 val) { return val; }
static inline int32 FromLittleEndian(uint32 val) { return val; }
static inline int16 FromLittleEndian(uint16 val) { return val; }
#endif
uint64 BFGetTickCountMicro();
uint64 BFGetTickCountMicroFast();
extern String vformat(const char* fmt, va_list argPtr);
extern String StrFormat(const char* fmt ...);
void ExactMinimalFloatToStr(float f, char* str);
void ExactMinimalDoubleToStr(double d, char* str);
String IntPtrDynAddrFormat(intptr addr);
void OutputDebugStr(const StringImpl& theString);
void OutputDebugStrF(const char* fmt ...);
UTF16String ToWString(const StringImpl& theString);
String ToString(const UTF16String& theString);
String ToUpper(const StringImpl& theString);
UTF16String ToUpper(const UTF16String& theString);
UTF16String ToLower(const UTF16String& theString);
String ToLower(const StringImpl& theString);
//UTF16String Trim(const UTF16String& theString);
String Trim(const StringImpl& theString);
bool StrReplace(StringImpl& str, const StringImpl& from, const StringImpl& to);
bool StrStartsWith(const StringImpl& str, const StringImpl& subStr);
bool StrEndsWith(const StringImpl& str, const StringImpl& subStr);
String SlashString(const StringImpl& str, bool utf8decode, bool utf8encode, bool beefString = false);
UTF16String UTF8Decode(const StringImpl& theString);
String UTF8Encode(const UTF16String& theString);
String UTF8Encode(const uint16* theString, int length);
UTF16String UTF16Decode(const uint16* theString);
String FileNameToURI(const StringImpl& fileName);
int64 DecodeULEB32(const char*& p);
void EncodeULEB32(uint64 value, StringImpl& buffer);
int32 Rand();
int32 GetHighestBitSet(int32 n);
uint8* LoadBinaryData(const StringImpl& path, int* size);
char* LoadTextData(const StringImpl& path, int* size);
int64 GetFileTimeWrite(const StringImpl& path);
String GetFileDir(const StringImpl& path);
String GetFileName(const StringImpl& path);
String GetFileExtension(const StringImpl& path);
String GetAbsPath(const StringImpl& relPath, const StringImpl& dir);
String FixPath(const StringImpl& path);
String FixPathAndCase(const StringImpl& path);
String EnsureEndsInSlash(const StringImpl& dir);
String RemoveTrailingSlash(const StringImpl& dir);
bool FileNameEquals(const StringImpl& filePathA, const StringImpl& filePathB);
bool FileExists(const StringImpl& path, String* outActualName = NULL);
bool DirectoryExists(const StringImpl& path, String* outActualName = NULL);
bool RecursiveCreateDirectory(const StringImpl& dirName);
bool RecursiveDeleteDirectory(const StringImpl& dirName);
#define CHARTAG(val) FromBIGEndian(val)
int64 EndianSwap(int64 val);
int32 EndianSwap(int32 val);
int16 EndianSwap(int16 val);
template<typename T>
struct RemoveTypePointer
{
};
template<typename T>
struct RemoveTypePointer<T*>
{
typedef T type;
};
#ifndef BF_SMALL
struct OnScopeExit
{
std::function<void()> mFunc;
OnScopeExit(std::function<void()> func) : mFunc(func)
{
}
~OnScopeExit()
{
mFunc();
}
};
#define CONCAT_INTERNAL(x,y) x##y
#define CONCAT(x,y) CONCAT_INTERNAL(x,y)
template<typename T>
struct ExitScope
{
T lambda;
ExitScope(T lambda) :lambda(lambda) {}
~ExitScope() { lambda(); }
ExitScope(const ExitScope&);
private:
ExitScope & operator =(const ExitScope&);
};
class ExitScopeHelp
{
public:
template<typename T>
ExitScope<T> operator+(T t) { return t; }
};
#define defer const auto& CONCAT(defer__, __LINE__) = ExitScopeHelp() + [&]()
#endif //BF_SMALL
NS_BF_END
#include "util/Array.h"
#include "util/String.h"

281
BeefySysLib/DataStream.cpp Normal file
View file

@ -0,0 +1,281 @@
#include "DataStream.h"
USING_NS_BF;
DataStream::DataStream()
{
mBigEndian = false;
mBitPos = 0;
mReadBitIntPos = -1000;
}
int8 DataStream::ReadInt8()
{
int8 anInt8;
Read(&anInt8, sizeof(int8));
return anInt8;
}
uint8 DataStream::ReadUInt8()
{
return (uint8) ReadInt8();
}
int16 DataStream::ReadInt16()
{
int16 anInt16;
Read(&anInt16, sizeof(int16));
if (mBigEndian)
return FromBigEndian(anInt16);
return anInt16;
}
uint16 DataStream::ReadUInt16()
{
return (uint16) ReadInt16();
}
int32 DataStream::ReadInt32()
{
int32 anInt32;
Read(&anInt32, sizeof(int32));
if (mBigEndian)
return FromBigEndian(anInt32);
return anInt32;
}
int64 Beefy::DataStream::ReadInt64()
{
int64 anInt64;
Read(&anInt64, sizeof(int64));
//if (mBigEndian)
//return FromBigEndian(anInt32);
return anInt64;
}
float DataStream::ReadFloat()
{
if (mBigEndian)
{
int32 anInt32;
Read(&anInt32, sizeof(int32));
anInt32 = FromBigEndian(anInt32);
return *((float*) &anInt32);
}
else
{
float aFloat;
Read(&aFloat, sizeof(float));
return aFloat;
}
}
double DataStream::ReadDouble()
{
if (mBigEndian)
{
int64 anInt64;
Read(&anInt64, sizeof(int64));
anInt64 = FromBigEndian(anInt64);
return *((double*) &anInt64);
}
else
{
double aDouble;
Read(&aDouble, sizeof(double));
return aDouble;
}
}
String DataStream::ReadAscii8SizedString()
{
int size = (int) (uint8) ReadInt8();
String aString;
aString.Append(' ', size);
Read((void*) aString.c_str(), size);
return aString;
}
String DataStream::ReadAscii32SizedString()
{
int size = (int) ReadInt32();
if (size == 0)
return String();
String aString;
aString.Append(' ', size);
Read((void*) aString.c_str(), size);
return aString;
}
String DataStream::ReadUnicode32SizedString()
{
int size = ReadInt32();
UTF16String aString;
aString.ResizeRaw(size + 1);
aString[size] = 0;
Read((void*)aString.c_str(), size * 2);
if (mBigEndian)
for (int i = 0; i < (int) aString.length(); i++)
aString[i] = FromBigEndian((int16) aString[i]);
return UTF8Encode(aString);
}
String DataStream::ReadSZ()
{
String str;
while (true)
{
char c = (char)ReadUInt8();
if (c == 0)
break;
str += c;
}
return str;
}
void DataStream::SyncBitPos()
{
mBitPos = GetPos() * 8;
}
void DataStream::SyncBytePos()
{
SetPos((mBitPos+7) / 8);
}
//int bitMaskR[32] = {
static int LowerBitMask[33] = {0x0000, 0x0001, 0x0003, 0x0007, 0x000F, 0x001F, 0x003F, 0x007F, 0x00FF, 0x01FF, 0x03FF, 0x07FF, 0x0FFF, 0x1FFF, 0x3FFF, 0x7FFF,
0xFFFF, 0x1FFFF, 0x3FFFF, 0x7FFFF, 0xFFFFF, 0x1FFFFF, 0x3FFFFF, 0x7FFFFF, 0xFFFFFF, 0x1FFFFFF, 0x3FFFFFF, 0x7FFFFFF, 0xFFFFFFF, 0x1FFFFFFF, 0x3FFFFFFF,
0x7FFFFFFF, (int)0xFFFFFFFF};
int DataStream::ReadUBits(int bits)
{
int val = 0;
int valBitPos = 0;
while (true)
{
int bitsAvail = (mReadBitIntPos + 32) - mBitPos;
if ((bitsAvail > 0) && (bitsAvail <= 32))
{
int copyBits = std::min(bits - valBitPos, bitsAvail);
val |= ((mCurBitInt >> (32 - bitsAvail)) & LowerBitMask[copyBits]) << valBitPos;
valBitPos += copyBits;
mBitPos += copyBits;
}
if (valBitPos == bits)
break;
mReadBitIntPos = mBitPos & ~7;
SetPos(mReadBitIntPos / 8);
Read(&mCurBitInt, 4);
}
return val;
}
void DataStream::SeekBits(int bits)
{
mBitPos += bits;
}
void Beefy::DataStream::Write(int32 val)
{
Write(&val, sizeof(int32));
}
void Beefy::DataStream::Write(int64 val)
{
Write(&val, sizeof(int64));
}
void Beefy::DataStream::Write(const StringImpl& val)
{
Write((int)val.length());
Write((void*)val.c_str(), (int)val.length());
}
void DataStream::Write(DataStream& refStream)
{
int size = refStream.GetSize();
uint8* data = new uint8[size];
refStream.SetPos(0);
refStream.Read(data, size);
Write(data, size);
delete data;
}
void DataStream::WriteSNZ(const StringImpl& val)
{
Write((void*)val.c_str(), (int)val.length());
}
void DataStream::WriteSZ(const StringImpl& val)
{
Write((void*)val.c_str(), (int)val.length() + 1);
}
void Beefy::DataStream::Write(float val)
{
Write(&val, sizeof(float));
}
void DataStream::Write(uint8 val)
{
Write(&val, 1);
}
void DataStream::Write(int8 val)
{
Write((uint8)val);
}
void DataStream::Write(int16 val)
{
Write(&val, 2);
}
void DataStream::WriteZeros(int size)
{
int sizeLeft = size;
while (sizeLeft > 0)
{
if (sizeLeft >= 8)
{
Write((int64)0);
sizeLeft -= 8;
}
else if (sizeLeft >= 4)
{
Write((int32)0);
sizeLeft -= 4;
}
else if (sizeLeft >= 2)
{
Write((int16)0);
sizeLeft -= 2;
}
else
{
Write((int8)0);
sizeLeft -= 1;
}
}
}
void DataStream::Align(int alignSize)
{
int curPos = GetPos();
int alignBytesLeft = (alignSize - (curPos % alignSize)) % alignSize;
WriteZeros(alignBytesLeft);
}

75
BeefySysLib/DataStream.h Normal file
View file

@ -0,0 +1,75 @@
#pragma once
#include "Common.h"
NS_BF_BEGIN;
class DataStream
{
public:
bool mBigEndian;
int mBitPos;
uint32 mCurBitInt;
int mReadBitIntPos; // in bits
protected:
uint32 GetBitInt(int bitPos);
public:
DataStream();
virtual ~DataStream() {}
virtual bool Eof() = 0;
virtual int GetSize() = 0;
virtual void Read(void* ptr, int size) = 0;
virtual void Write(void* ptr, int size) = 0;
virtual void WriteZeros(int size);
virtual void Align(int size);
virtual int GetPos() = 0;
virtual void Seek(int size) = 0;
virtual void SetPos(int pos) = 0;
virtual int8 ReadInt8();
virtual uint8 ReadUInt8();
virtual int16 ReadInt16();
virtual uint16 ReadUInt16();
virtual int32 ReadInt32();
virtual int64 ReadInt64();
virtual float ReadFloat();
virtual double ReadDouble();
virtual String ReadAscii8SizedString();
virtual String ReadAscii32SizedString();
virtual String ReadUnicode32SizedString();
virtual String ReadSZ();
template <typename T>
void ReadT(const T& val)
{
Read((void*) &val, sizeof(T));
}
virtual void Write(float val);
virtual void Write(uint8 val);
virtual void Write(int8 val);
virtual void Write(int16 val);
virtual void Write(int32 val);
virtual void Write(int64 val);
virtual void Write(const StringImpl& val);
virtual void Write(DataStream& refStream);
virtual void WriteSNZ(const StringImpl& val);
virtual void WriteSZ(const StringImpl& val);
template <typename T>
void WriteT(const T& val)
{
Write((void*)&val, sizeof(T));
}
virtual void SyncBitPos();
virtual void SyncBytePos();
virtual int ReadUBits(int bits);
virtual void SeekBits(int bits);
};
NS_BF_END;

View file

@ -0,0 +1,124 @@
#include "FileHandleStream.h"
USING_NS_BF;
FileHandleStream::FileHandleStream()
{
mFileHandle = NULL;
mCacheBuffer = NULL;
mCacheReadPos = -0x3FFFFFFF;
mCacheSize = 0;
mVFilePos = 0;
}
FileHandleStream::~FileHandleStream()
{
if (mCacheBuffer != NULL)
delete mCacheBuffer;
if (mFileHandle != NULL)
::CloseHandle_File(mFileHandle);
}
void FileHandleStream::SetCacheSize(int size)
{
size = (size + (4096 - 1)) & ~(4096 - 1);
mCacheReadPos = -0x3FFFFFFF;
delete mCacheBuffer;
if (size > 0)
mCacheBuffer = new uint8[size];
else
mCacheBuffer = NULL;
mCacheSize = size;
}
void FileHandleStream::Seek(int pos)
{
if (mCacheBuffer != NULL)
mVFilePos += pos;
else
::SetFilePointer(mFileHandle, pos, 0, FILE_CURRENT);
}
void FileHandleStream::SetPos(int pos)
{
if (mCacheBuffer != NULL)
mVFilePos = pos;
else
::SetFilePointer(mFileHandle, pos, 0, FILE_BEGIN);
}
bool FileHandleStream::Eof()
{
if (mCacheBuffer != NULL)
{
::SetFilePointer(mFileHandle, 0, 0, FILE_END);
return mVFilePos >= (int)::SetFilePointer(mFileHandle, 0, 0, FILE_CURRENT);
}
return ::SetFilePointer(mFileHandle, 0, 0, FILE_CURRENT) != ::GetFileSize(mFileHandle, NULL);
}
int FileHandleStream::GetSize()
{
return ::GetFileSize(mFileHandle, NULL);;
}
void FileHandleStream::Read(void* ptr, int size)
{
if (mCacheBuffer != NULL)
{
while (true)
{
int buffOffset = mVFilePos - mCacheReadPos;
if ((buffOffset >= 0) && (buffOffset + size < mCacheSize))
{
// If inside
memcpy(ptr, mCacheBuffer + buffOffset, size);
mVFilePos += size;
return;
}
else if ((buffOffset >= 0) && (buffOffset < mCacheSize))
{
int subSize = mCacheReadPos + mCacheSize - mVFilePos;
memcpy(ptr, mCacheBuffer + buffOffset, subSize);
mVFilePos += subSize;
ptr = (uint8*)ptr + subSize;
size -= subSize;
}
mCacheReadPos = mVFilePos & ~(4096 - 1);
::SetFilePointer(mFileHandle, mCacheReadPos, 0, FILE_BEGIN);
int aSize = 0;
::ReadFile(mFileHandle, mCacheBuffer, mCacheSize, (DWORD*)&aSize, NULL);
if (aSize != mCacheSize)
{
// Zero out underflow bytes
memset((uint8*)ptr + aSize, 0, mCacheSize - aSize);
}
}
}
else
{
int aSize = 0;
::ReadFile(mFileHandle, ptr, size, (DWORD*)&aSize, NULL);
if (aSize != size)
{
// Zero out underflow bytes
memset((uint8*)ptr + aSize, 0, size - aSize);
}
}
}
void FileHandleStream::Write(void* ptr, int size)
{
::WriteFile(mFileHandle, ptr, size, NULL, NULL);
}
int FileHandleStream::GetPos()
{
if (mCacheBuffer != NULL)
return mVFilePos;
return ::SetFilePointer(mFileHandle, 0, 0, FILE_CURRENT);
}

View file

@ -0,0 +1,35 @@
#pragma once
#include "Common.h"
#include "DataStream.h"
NS_BF_BEGIN;
class FileHandleStream : public DataStream
{
public:
HANDLE mFileHandle;
uint8* mCacheBuffer;
int mCacheReadPos;
int mCacheSize;
int mVFilePos;
public:
FileHandleStream();
~FileHandleStream();
void SetCacheSize(int size);
bool Eof() override;
int GetSize() override;
using DataStream::Read;
void Read(void* ptr, int size) override;
using DataStream::Write;
void Write(void* ptr, int size) override;
int GetPos() override;
void Seek(int size) override;
void SetPos(int pos) override;
};
NS_BF_END;

271
BeefySysLib/FileStream.cpp Normal file
View file

@ -0,0 +1,271 @@
#include "FileStream.h"
#pragma warning(disable:4996)
USING_NS_BF;
FileStream::FileStream()
{
mFP = NULL;
mCacheBuffer = NULL;
mCacheReadPos = -0x3FFFFFFF;
mCacheSize = 0;
mVFilePos = 0;
mReadPastEnd = false;
}
FileStream::~FileStream()
{
if (mCacheBuffer != NULL)
delete mCacheBuffer;
if (mFP != NULL)
fclose(mFP);
}
bool FileStream::Open(const StringImpl& filePath, const char* fopenOptions)
{
#ifdef BF_PLATFORM_WINDOWS
mFP = _wfopen(UTF8Decode(filePath).c_str(), UTF8Decode(fopenOptions).c_str());
#else
mFP = fopen(filePath.c_str(), fopenOptions);
#endif
return mFP != NULL;
}
bool FileStream::IsOpen()
{
return mFP != NULL;
}
void FileStream::Close()
{
if (mFP != NULL)
{
fclose(mFP);
mFP = NULL;
}
}
void FileStream::SetCacheSize(int size)
{
size = (size + (4096-1)) & ~(4096-1);
mCacheReadPos = -0x3FFFFFFF;
delete mCacheBuffer;
if (size > 0)
mCacheBuffer = new uint8[size];
else
mCacheBuffer = NULL;
mCacheSize = size;
}
void FileStream::Seek(int size)
{
if (mCacheBuffer != NULL)
mVFilePos += size;
else
fseek(mFP, size, SEEK_CUR);
}
void FileStream::SetPos(int pos)
{
if (mCacheBuffer != NULL)
mVFilePos = pos;
else
fseek(mFP, pos, SEEK_SET);
}
bool FileStream::Eof()
{
if (mCacheBuffer != NULL)
{
fseek(mFP, 0, SEEK_END);
return mVFilePos >= ftell(mFP);
}
int aPos = (int)ftell(mFP);
fseek(mFP, 0, SEEK_END);
int aSize = (int)ftell(mFP);
fseek(mFP, aPos, SEEK_SET);
return aPos == aSize;
}
int FileStream::GetSize()
{
int aPos = (int)ftell(mFP);
fseek(mFP, 0, SEEK_END);
int aSize = (int)ftell(mFP);
fseek(mFP, aPos, SEEK_SET);
return aSize;
}
void FileStream::Read(void* ptr, int size)
{
if (mCacheBuffer != NULL)
{
while (true)
{
int buffOffset = mVFilePos - mCacheReadPos;
if ((buffOffset >= 0) && (buffOffset + size < mCacheSize))
{
// If inside
memcpy(ptr, mCacheBuffer + buffOffset, size);
mVFilePos += size;
return;
}
else if ((buffOffset >= 0) && (buffOffset < mCacheSize))
{
int subSize = mCacheReadPos + mCacheSize - mVFilePos;
memcpy(ptr, mCacheBuffer + buffOffset, subSize);
mVFilePos += subSize;
ptr = (uint8*) ptr + subSize;
size -= subSize;
}
mCacheReadPos = mVFilePos & ~(4096-1);
fseek(mFP, mCacheReadPos, SEEK_SET);
int aSize = (int)fread(mCacheBuffer, 1, mCacheSize, mFP);
if (aSize != mCacheSize)
{
// Zero out underflow bytes
memset((uint8*) ptr + aSize, 0, mCacheSize - aSize);
}
}
}
else
{
int aSize = (int)fread(ptr, 1, size, mFP);
if (aSize != size)
{
// Zero out underflow bytes
memset((uint8*) ptr + aSize, 0, size - aSize);
mReadPastEnd = true;
}
}
}
void FileStream::Write(void* ptr, int size)
{
fwrite(ptr, 1, size, mFP);
}
int FileStream::GetPos()
{
if (mCacheBuffer != NULL)
return mVFilePos;
return (int)ftell(mFP);
}
//////////////////////////////////////////////////////////////////////////
int FileSubStream::GetSize()
{
return mSize;
}
int FileSubStream::GetPos()
{
return FileStream::GetPos() - mOffset;
}
void FileSubStream::SetPos(int pos)
{
FileStream::SetPos(pos + mOffset);
}
//////////////////////////////////////////////////////////////////////////
SysFileStream::SysFileStream()
{
mFile = NULL;
}
SysFileStream::~SysFileStream()
{
if (mFile != NULL)
BfpFile_Release(mFile);
}
bool SysFileStream::Open(const StringImpl& filePath, BfpFileCreateKind createKind, BfpFileCreateFlags createFlags)
{
mFile = BfpFile_Create(filePath.c_str(), createKind, createFlags, BfpFileAttribute_Normal, NULL);
return mFile != NULL;
//mHandle = ::CreateFileW(UTF8Decode(filePath).c_str(), access, 0, NULL, CREATE_ALWAYS, 0, 0);
//return mHandle != INVALID_HANDLE_VALUE;
}
bool SysFileStream::IsOpen()
{
return mFile != NULL;
}
void SysFileStream::Close()
{
if (mFile != NULL)
{
BfpFile_Release(mFile);
mFile = NULL;
}
}
void SysFileStream::SetSizeFast(int size)
{
int curSize = GetSize();
if (size == curSize)
return;
int curPos = GetPos();
SetPos(size);
BfpFile_Truncate(mFile);
SetPos(curPos);
return;
}
void SysFileStream::Seek(int pos)
{
BfpFile_Seek(mFile, pos, BfpFileSeekKind_Relative);
}
void SysFileStream::SetPos(int pos)
{
BfpFile_Seek(mFile, pos, BfpFileSeekKind_Absolute);
}
bool SysFileStream::Eof()
{
char c;
int readSize = (int)BfpFile_Read(mFile, &c, 1, -1, NULL);
if (readSize == 0)
return true;
BfpFile_Seek(mFile, -1, BfpFileSeekKind_Relative);
return false;
}
int SysFileStream::GetSize()
{
return (int)BfpFile_GetFileSize(mFile);
}
void SysFileStream::Read(void* ptr, int size)
{
int readSize = (int)BfpFile_Read(mFile, ptr, size, -1, NULL);
if (readSize != size)
{
// Zero out underflow bytes
memset((uint8*)ptr + readSize, 0, size - readSize);
}
}
void SysFileStream::Write(void* ptr, int size)
{
BfpFile_Write(mFile, ptr, size, -1, NULL);
}
int SysFileStream::GetPos()
{
return (int)BfpFile_Seek(mFile, 0, BfpFileSeekKind_Relative);
}

79
BeefySysLib/FileStream.h Normal file
View file

@ -0,0 +1,79 @@
#pragma once
#include "Common.h"
#include "DataStream.h"
NS_BF_BEGIN;
class FileStream : public DataStream
{
BF_DISALLOW_COPY(FileStream);
public:
FILE* mFP;
uint8* mCacheBuffer;
int mCacheReadPos;
int mCacheSize;
int mVFilePos;
bool mReadPastEnd;
public:
FileStream();
~FileStream();
bool Open(const StringImpl& filePath, const char* fopenOptions);
bool IsOpen();
void Close();
void SetCacheSize(int size);
bool Eof() override;
int GetSize() override;
using DataStream::Read;
void Read(void* ptr, int size) override;
using DataStream::Write;
void Write(void* ptr, int size) override;
int GetPos() override;
void Seek(int size) override;
void SetPos(int pos) override;
};
class FileSubStream : public FileStream
{
public:
int mOffset;
int mSize;
public:
int GetSize() override;
int GetPos() override;
void SetPos(int pos) override;
};
class SysFileStream : public DataStream
{
BF_DISALLOW_COPY(SysFileStream);
public:
BfpFile* mFile;
public:
SysFileStream();
~SysFileStream();
bool Open(const StringImpl& filePath, BfpFileCreateKind createKind, BfpFileCreateFlags createFlags);
bool IsOpen();
void Close();
void SetSizeFast(int size); // May create uninitialized data
bool Eof() override;
int GetSize() override;
using DataStream::Read;
void Read(void* ptr, int size) override;
using DataStream::Write;
void Write(void* ptr, int size) override;
int GetPos() override;
void Seek(int size) override;
void SetPos(int pos) override;
};
NS_BF_END;

View file

@ -0,0 +1,26 @@
#include "HeadlessApp.h"
#include "platform/PlatformHelper.h"
USING_NS_BF;
void HeadlessApp::Init()
{
mRunning = true;
Beefy::String exePath;
BfpGetStrHelper(exePath, [](char* outStr, int* inOutStrSize, BfpResult* result)
{
BfpSystem_GetExecutablePath(outStr, inOutStrSize, (BfpSystemResult*)result);
});
mInstallDir = GetFileDir(exePath) + "/";
}
void HeadlessApp::Run()
{
while (mRunning)
{
BfpThread_Sleep((uint32)(1000 / mRefreshRate));
Process();
}
}

30
BeefySysLib/HeadlessApp.h Normal file
View file

@ -0,0 +1,30 @@
#pragma once
#include "BFApp.h"
#include "BFWindow.h"
NS_BF_BEGIN;
class HeadlessApp : public BFApp
{
public:
virtual void Init() override;
virtual void Run() override;
virtual void PhysSetCursor() 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) { return NULL; }
virtual DrawLayer* CreateDrawLayer(BFWindow* window) { return NULL; }
virtual void* GetClipboardData(const StringImpl& format, int* size) { return NULL; }
virtual void ReleaseClipboardData(void* ptr) { }
virtual void SetClipboardData(const StringImpl& format, const void* ptr, int size, bool resetClipboard) { }
virtual BFSysBitmap* LoadSysBitmap(const wchar_t* fileName) { return NULL; }
};
NS_BF_END;

155
BeefySysLib/MemStream.cpp Normal file
View file

@ -0,0 +1,155 @@
#include "MemStream.h"
USING_NS_BF;
MemStream* MemStream::CreateWithDuplicate(void* data, int size)
{
uint8* newData = new uint8[size];
memcpy(newData, data, size);
MemStream* memStream = new MemStream(newData, size, true);
return memStream;
}
MemStream* MemStream::CreateWithOwnershipTaken(void* data, int size)
{
return new MemStream(data, size, true);
}
MemStream* MemStream::CreateWithNoCopy(void* data, int size)
{
return new MemStream(data, size, false);
}
MemStream::MemStream(void* data, int size, bool freeMemory)
{
mData = (uint8*) data;
mSize = size;
mPos = 0;
mFreeMemory = freeMemory;
}
MemStream::~MemStream()
{
if (mFreeMemory)
delete mData;
}
bool MemStream::Eof()
{
return mPos >= mSize;
}
int MemStream::GetSize()
{
return mSize;
}
void MemStream::Read(void* ptr, int size)
{
memcpy(ptr, mData + mPos, size);
mPos += size;
}
void Beefy::MemStream::Write(void* ptr, int size)
{
memcpy(mData + mPos, ptr, size);
mPos += size;
}
int MemStream::GetPos()
{
return mPos;
}
void MemStream::Seek(int size)
{
mPos += size;
}
void MemStream::SetPos(int pos)
{
mPos = pos;
}
//////////////////////////////////////////////////////////////////////////
SafeMemStream::SafeMemStream(void* data, int size, bool freeMemory) : MemStream(data, size, freeMemory)
{
mFailed = false;
}
void SafeMemStream::Read(void* ptr, int size)
{
if (mPos + size > mSize)
{
mFailed = true;
memset(ptr, 0, size);
}
else
{
memcpy(ptr, mData + mPos, size);
}
mPos += size;
}
//////////////////////////////////////////////////////////////////////////
DynMemStream::DynMemStream()
{
mPos = 0;
}
bool DynMemStream::Eof()
{
return mPos >= (int)mData.size();
}
int DynMemStream::GetSize()
{
return (int)mData.size();
}
void DynMemStream::Read(void* ptr, int size)
{
memcpy(ptr, (uint8*)&mData.front() + mPos, size);
mPos += size;
}
void DynMemStream::Write(void* ptr, int size)
{
mData.Insert(mPos, (uint8*)ptr, size);
mPos += size;
}
void DynMemStream::Write(uint8 val)
{
mData.push_back(val);
mPos++;
}
int DynMemStream::GetPos()
{
return mPos;
}
void DynMemStream::Seek(int size)
{
mPos += size;
}
void DynMemStream::SetPos(int pos)
{
mPos = pos;
}
void DynMemStream::Clear()
{
mPos = 0;
mData.Clear();
}
void* DynMemStream::GetPtr()
{
return &mData[0];
}

72
BeefySysLib/MemStream.h Normal file
View file

@ -0,0 +1,72 @@
#pragma once
#include "Common.h"
#include "DataStream.h"
NS_BF_BEGIN;
class MemStream : public DataStream
{
public:
uint8* mData;
int mSize;
int mPos;
bool mFreeMemory;
public:
MemStream(void* data, int size, bool freeMemory);
~MemStream();
static MemStream* CreateWithDuplicate(void* data, int size);
static MemStream* CreateWithOwnershipTaken(void* data, int size);
static MemStream* CreateWithNoCopy(void* data, int size);
bool Eof() override;
int GetSize() override;
using DataStream::Read;
void Read(void* ptr, int size) override;
using DataStream::Write;
void Write(void* ptr, int size) override;
int GetPos() override;
void Seek(int size) override;
void SetPos(int pos) override;
};
class SafeMemStream : public MemStream
{
public:
bool mFailed;
SafeMemStream(void* data, int size, bool freeMemory);
using DataStream::Read;
void Read(void* ptr, int size) override;
};
class DynMemStream : public DataStream
{
public:
Array<uint8> mData;
int mPos;
public:
DynMemStream();
bool Eof() override;
int GetSize() override;
using DataStream::Read;
void Read(void* ptr, int size) override;
using DataStream::Write;
void Write(void* ptr, int size) override;
void Write(uint8 val) override;
int GetPos() override;
void Seek(int size) override;
void SetPos(int pos) override;
void Clear();
void* GetPtr();
};
NS_BF_END;

32
BeefySysLib/PerfTests.cpp Normal file
View file

@ -0,0 +1,32 @@
#include "Common.h"
/*int main(int, char** argv)
{
int i, n = atoi(argv[1]);
N_Body_System system;
printf("%.9f\n", system.energy());
for (i = 0; i < n; ++i)
system.advance(0.01);
printf("%.9f\n", system.energy());
return 0;
}*/
void NBody(int n);
void FastaRedux(int n);
void FannkuchRedux(int max_n);
USING_NS_BF;
BF_EXPORT void BF_CALLTYPE BFApp_RunPerfTest(const char* testName, int arg)
{
if (strcmp(testName, "nbody") == 0)
NBody(arg);
if (strcmp(testName, "fastaredux") == 0)
FastaRedux(arg);
if (strcmp(testName, "fannkuchredux") == 0)
FannkuchRedux(arg);
}

90
BeefySysLib/ResLib.cpp Normal file
View file

@ -0,0 +1,90 @@
#include "Common.h"
#include "BFApp.h"
#include "img/PSDReader.h"
#include "gfx/RenderDevice.h"
#include "gfx/Texture.h"
#include "util/PerfTimer.h"
USING_NS_BF;
static UTF16String gTempUTF16String;
BF_EXPORT PSDReader* BF_CALLTYPE Res_OpenPSD(const char* fileName)
{
//gPerfManager->StartRecording();
PSDReader* aPSDReader = new PSDReader();
if (!aPSDReader->Init(fileName))
{
delete aPSDReader;
return NULL;
}
return aPSDReader;
}
BF_EXPORT void BF_CALLTYPE Res_DeletePSDReader(PSDReader* pSDReader)
{
delete pSDReader;
gPerfManager->StopRecording();
gPerfManager->DbgPrint();
}
BF_EXPORT TextureSegment* BF_CALLTYPE Res_PSD_GetLayerTexture(PSDReader* pSDReader, int layerIdx, int* ofsX, int* ofsY)
{
Texture* texture = pSDReader->LoadLayerTexture(layerIdx, ofsX, ofsY);
if (texture == NULL)
return NULL;
TextureSegment* textureSegment = new TextureSegment();
textureSegment->InitFromTexture(texture);
return textureSegment;
}
BF_EXPORT TextureSegment* BF_CALLTYPE Res_PSD_GetMergedLayerTexture(PSDReader* pSDReader, int* layerIndices, int count, int* ofsX, int* ofsY)
{
std::vector<int> aLayerIndices;
aLayerIndices.insert(aLayerIndices.begin(), layerIndices, layerIndices + count);
Texture* texture = pSDReader->LoadMergedLayerTexture(aLayerIndices, ofsX, ofsY);
if (texture == NULL)
return NULL;
TextureSegment* textureSegment = new TextureSegment();
textureSegment->InitFromTexture(texture);
return textureSegment;
}
BF_EXPORT int BF_CALLTYPE Res_PSD_GetLayerCount(PSDReader* pSDReader)
{
return (int) pSDReader->mPSDLayerInfoVector.size();
}
BF_EXPORT PSDLayerInfo* BF_CALLTYPE Res_PSD_GetLayerInfo(PSDReader* pSDReader, int layerIdx)
{
return pSDReader->mPSDLayerInfoVector[layerIdx];
}
BF_EXPORT void BF_CALLTYPE Res_PSDLayer_GetSize(PSDLayerInfo* layerInfo, int* x, int* y, int* width, int* height)
{
*x = layerInfo->mX;
*y = layerInfo->mY;
*width = layerInfo->mWidth;
*height = layerInfo->mHeight;
}
BF_EXPORT int BF_CALLTYPE Res_PSDLayer_GetLayerId(PSDLayerInfo* layerInfo)
{
return layerInfo->mLayerId;
}
BF_EXPORT const char* BF_CALLTYPE Res_PSDLayer_GetName(PSDLayerInfo* layerInfo)
{
return layerInfo->mName.c_str();
}
BF_EXPORT int BF_CALLTYPE Res_PSDLayer_IsVisible(PSDLayerInfo* layerInfo)
{
return layerInfo->mVisible ? 1 : 0;
}

130
BeefySysLib/Span.h Normal file
View file

@ -0,0 +1,130 @@
#pragma once
#include "../Common.h"
NS_BF_BEGIN
template <typename T>
class Span
{
public:
T* mVals;
int mSize;
public:
struct Iterator
{
public:
T* mPtr;
public:
Iterator(T* ptr)
{
mPtr = ptr;
}
Iterator& operator++()
{
mPtr++;
return *this;
}
bool operator!=(const Iterator& itr) const
{
return itr.mPtr != mPtr;
}
bool operator==(const Iterator& itr) const
{
return itr.mPtr == mPtr;
}
T& operator*()
{
return *mPtr;
}
};
Span()
{
}
Span(T* mPtr, int size)
{
mSize = (int)refVec.size();
mVals = NULL;
}
T& operator[](int idx) const
{
return mVals[idx];
}
Iterator begin() const
{
return mVals;
}
Iterator end() const
{
return mVals + mSize;
}
T back() const
{
return mVals[mSize - 1];
}
int size() const
{
return mSize;
}
bool empty() const
{
return mSize == 0;
}
bool IsEmpty() const
{
return mSize == 0;
}
T Get(int idx)
{
if ((idx < 0) || (idx >= mSize))
return (T)0;
return mVals[idx];
}
template <typename T2>
T2 GetAs(int idx)
{
if ((idx < 0) || (idx >= mSize))
return (T2)0;
return (T2)mVals[idx];
}
T GetLast()
{
if (mSize == 0)
return (T)0;
return mVals[mSize - 1];
}
T GetFirst()
{
if (mSize == 0)
return (T)0;
return mVals[0];
}
void SetSize(int size)
{
BF_ASSERT(size <= mSize);
mSize = size;
}
};
NS_BF_END

25
BeefySysLib/Startup.cpp Normal file
View file

@ -0,0 +1,25 @@
#include "Common.h"
USING_NS_BF;
#ifdef BF_PLATFORM_SDL
#include "SDL2-2.0.1/include/SDL_main.h"
#endif
BF_EXPORT void BF_CALLTYPE Lib_Startup(int argc, const char** argv, void (*startupCallback)())
{
gBFArgC = argc;
gBFArgV = (char**)argv;
#ifdef SDL_MAIN_NEEDED
extern SDL_bool SDL_MainIsReady;
if (!SDL_MainIsReady)
{
gSDLStartupCallback = startupCallback;
SDL_entry(gBFArgC, (char**)gBFArgV);
}
else
startupCallback();
#else
startupCallback();
#endif
}

File diff suppressed because it is too large Load diff

228
BeefySysLib/fbx/FBXReader.h Normal file
View file

@ -0,0 +1,228 @@
#pragma once
#ifndef BF_NO_FBX
#define FBXSDK_SHARED
#include "Common.h"
#include "fbxsdk.h"
#include "Util/Vector.h"
#include "Util/Matrix4.h"
#include "Util/Quaternion.h"
NS_BF_BEGIN;
#define BF_MAX_NUM_BONES 256
#define BF_MODEL_VERSION 1
struct FBXBoneWeight
{
public:
int mBoneIdx;
float mBoneWeight;
};
typedef std::vector<FBXBoneWeight> BoneWeightVector;
class FBXVertexData
{
public:
Vector3 mCoords;
uint32 mColor;
std::vector<TexCoords> mTexCoords;
Vector3 mNormal;
std::vector<TexCoords> mBumpTexCoords;
Vector3 mTangent;
BoneWeightVector mBoneWeights;
bool operator==(const FBXVertexData& check) const
{
if (mCoords != check.mCoords)
return false;
if (mNormal != check.mNormal)
return false;
if (mTexCoords.size() != check.mTexCoords.size())
return false;
for (int i = 0; i < (int)mTexCoords.size(); i++)
if ((mTexCoords[i].mU != check.mTexCoords[i].mU) ||
(mTexCoords[i].mV != check.mTexCoords[i].mV))
return false;
return true;
}
};
class FBXMaterial
{
public:
String mTexFileName;
String mBumpFileName;
};
class FBXMesh
{
public:
FBXMaterial mMaterial;
String mName;
std::vector<FBXVertexData> mVertexData;
std::vector<int> mIndexData;
};
struct FBXJoint
{
String name;
int id;
FbxNode *pNode;
FbxAMatrix globalBindPose, localBindPose;
FbxAMatrix bindPose;
Matrix4 mCurMatrix;
float mBoneLength; // Length to parent
int parentIndex;
double posx, posy, posz;
//double angle;
//double axisx,axisy,axisz;
double quatw, quatx, quaty, quatz;
float scalex, scaley, scalez;
bool bInheritScale;
// Used when loading from an Ogre Skeleton.
String parentName;
};
enum FBXTrackType
{
TT_SKELETON,
TT_MORPH,
TT_POSE
};
enum FBXTarget
{
T_MESH,
T_SUBMESH
};
struct FBXVertexPosition
{
float x, y, z;
};
struct FBXVertexPoseRef
{
int poseIndex;
float poseWeight;
};
struct FBXVertexKeyframe
{
float time;
std::vector<FBXVertexPosition> positions;
std::vector<FBXVertexPoseRef> poserefs;
};
struct FBXSkeletonKeyframe
{
float time;
double tx, ty, tz;
double quat_w, quat_x, quat_y, quat_z;
float sx, sy, sz;
};
class FBXTrack
{
public:
FBXTrackType mType;
FBXTarget mTarget;
int mIndex;
String mBone;
std::vector<FBXVertexKeyframe> mVertexKeyframes;
std::vector<FBXSkeletonKeyframe> mSkeletonKeyframes;
public:
FBXTrack()
{
Clear();
}
void Clear()
{
mType = TT_SKELETON;
mTarget = T_MESH;
mIndex = 0;
mBone = "";
mVertexKeyframes.clear();
mSkeletonKeyframes.clear();
}
};
class FBXAnimation
{
public:
//public members
String mName;
float mLength;
std::vector<FBXTrack> mTracks;
};
class ModelDef;
class FBXReader
{
public:
ModelDef* mModelDef;
FbxManager* mFBXManager;
FbxScene* mFBXScene;
std::vector<FBXMesh*> mMeshes;
std::map<String, int> mJointIndexMap;
std::vector<FBXJoint> mFBXJoints;
std::vector<FBXAnimation> mAnimations;
int mParamBindframe;
float mParamLum;
float mFPS;
float mFrameRate;
float mAnimStart;
float mAnimStop;
protected:
FBXMesh* LoadMesh(FbxNode* fbxNode, FbxMesh* fbxMesh);
void TranslateNode(FbxNode* fbxNode);
public:
FBXReader(ModelDef* modelDef);
~FBXReader();
bool WriteBFFile(const StringImpl& fileName, const StringImpl& checkFile, const StringImpl& checkFile2);
bool ReadBFFile(const StringImpl& fileName);
bool ReadFile(const StringImpl& fileName, bool loadAnims = true);
bool FBXLoadJoint(FbxNode* pNode, FbxAMatrix globalBindPose);
int FBXGetJointIndex(FbxNode* pNode);
bool FBXLoadClip(String clipName, float start, float stop, float rate);
bool FBXLoadClipAnim(String clipName, float start, float stop, float rate, FBXAnimation& a);
FBXSkeletonKeyframe FBXLoadKeyframe(FBXJoint& j, float time);
FbxAMatrix CalculateGlobalTransformWithBind(FbxNode* pNode, FbxTime time);
void GetAnimationBounds();
void CalculateLocalTransforms(FbxNode* pRootNode);
void ComputeBindPoseBoundingBox();
void SetParentIndexes();
void SortAndPruneJoints();
void SortJoint(FBXJoint j, std::map<String, int> &sortedJointIndexMap, std::vector<FBXJoint>& sorted_joints);
void AddParentsOfExistingJoints();
void LoadBindPose();
bool GetVertexBoneWeights(FbxNode* pNode, FbxMesh *pMesh, std::vector<BoneWeightVector>& boneWeightsVector);
FbxAMatrix GetBindPose(FbxNode *pNode, FbxMesh *pMesh);
void FindJoints(FbxNode* fbxNode);
};
NS_BF_END;
#endif

View file

@ -0,0 +1,393 @@
#include "BFApp.h"
#include "gfx/DrawLayer.h"
#include "gfx/Texture.h"
#include "gfx/RenderDevice.h"
#include "gfx/Shader.h"
#include "util/PerfTimer.h"
USING_NS_BF;
static int sCurBatchId = 0;
DrawBatch::DrawBatch()
{
mId = ++sCurBatchId;
mVtxIdx = 0;
mIdxIdx = 0;
mAllocatedVertices = 0;
mAllocatedIndices = 0;
mIsIndexBufferHead = false;
mIsVertexBufferHead = false;
mVertices = NULL;
mIndices = NULL;
mRenderState = NULL;
mDrawLayer = NULL;
mNext = NULL;
Clear();
}
DrawBatch::~DrawBatch()
{
}
void DrawBatch::Clear()
{
mVtxIdx = 0;
mIdxIdx = 0;
for (int texIdx = 0; texIdx < MAX_TEXTURES; texIdx++)
mCurTextures[texIdx] = (Texture*)(intptr)-1;
}
void DrawBatch::Free()
{
RenderDevice* renderDevice = mDrawLayer->mRenderDevice;
if (mIsVertexBufferHead)
renderDevice->mPooledVertexBuffers.FreeMemoryBlock(mVertices);
if (mIsIndexBufferHead)
renderDevice->mPooledIndexBuffers.FreeMemoryBlock(mIndices);
mIsVertexBufferHead = false;
mIsIndexBufferHead = false;
Clear();
auto& pool = renderDevice->mDrawBatchPool;
pool.push_back(this);
}
DrawBatch* DrawBatch::AllocateChainedBatch(int minVtxCount, int minIdxCount)
{
mDrawLayer->CloseDrawBatch();
return mDrawLayer->AllocateBatch(minVtxCount, minIdxCount);
}
void* DrawBatch::AllocTris(int vtxCount)
{
int idxCount = vtxCount;
if ((mRenderState != gBFApp->mRenderDevice->mCurRenderState) || (idxCount + mIdxIdx >= mAllocatedIndices))
{
if (mVtxIdx > 0)
{
DrawBatch* nextBatch = AllocateChainedBatch(0, 0);
return nextBatch->AllocTris(vtxCount);
}
mRenderState = gBFApp->mRenderDevice->mCurRenderState;
}
uint16* idxPtr = mIndices + mIdxIdx;
void* vtxPtr = (uint8*)mVertices + (mVtxIdx * mVtxSize);
for (int idxNum = 0; idxNum < idxCount; idxNum++)
{
*idxPtr++ = mVtxIdx++;
mIdxIdx++;
}
return vtxPtr;
}
void* DrawBatch::AllocStrip(int vtxCount)
{
int idxCount = (vtxCount - 2) * 3;
if ((mRenderState != gBFApp->mRenderDevice->mCurRenderState) || (idxCount + mIdxIdx >= mAllocatedIndices))
{
if (mVtxIdx > 0)
{
DrawBatch* nextBatch = AllocateChainedBatch(0, 0);
return nextBatch->AllocStrip(vtxCount);
}
mRenderState = gBFApp->mRenderDevice->mCurRenderState;
}
uint16* idxPtr = mIndices + mIdxIdx;
void* vtxPtr = (uint8*)mVertices + (mVtxIdx * mVtxSize);
mVtxIdx += 2;
for (int idxNum = 0; idxNum < idxCount; idxNum += 3)
{
*idxPtr++ = mVtxIdx - 2;
*idxPtr++ = mVtxIdx - 1;
*idxPtr++ = mVtxIdx;
mVtxIdx++;
mIdxIdx += 3;
}
return vtxPtr;
}
void DrawBatch::AllocIndexed(int vtxCount, int idxCount, void** verticesOut, uint16** indicesOut, uint16* idxOfsOut)
{
if ((mRenderState != gBFApp->mRenderDevice->mCurRenderState) || (idxCount + mIdxIdx > mAllocatedIndices))
{
if (mVtxIdx > 0)
{
DrawBatch* nextBatch = AllocateChainedBatch(vtxCount, idxCount);
return nextBatch->AllocIndexed(vtxCount, idxCount, verticesOut, indicesOut, idxOfsOut);
}
mRenderState = gBFApp->mRenderDevice->mCurRenderState;
}
*verticesOut = (uint8*)mVertices + (mVtxIdx * mVtxSize);
*indicesOut = mIndices + mIdxIdx;
*idxOfsOut = mVtxIdx;
mVtxIdx += vtxCount;
mIdxIdx += idxCount;
}
//
DrawLayer::DrawLayer()
{
mRenderWindow = NULL;
mRenderDevice = NULL;
mIdxBuffer = NULL;
mVtxBuffer = NULL;
mRenderCmdBuffer = NULL;
mIdxByteIdx = 0;
mVtxByteIdx = 0;
mRenderCmdByteIdx = 0;
mCurDrawBatch = NULL;
for (int textureIdx = 0; textureIdx < MAX_TEXTURES; textureIdx++)
mCurTextures[textureIdx] = NULL;
}
DrawLayer::~DrawLayer()
{
NOP;
}
void DrawLayer::CloseDrawBatch()
{
if (mCurDrawBatch == NULL)
return;
mIdxByteIdx += mCurDrawBatch->mIdxIdx * sizeof(uint16);
mVtxByteIdx += mCurDrawBatch->mVtxIdx * mCurDrawBatch->mVtxSize;
BF_ASSERT(mVtxByteIdx <= DRAWBUFFER_VTXBUFFER_SIZE);
mCurDrawBatch = NULL;
}
void DrawLayer::QueueRenderCmd(RenderCmd* renderCmd)
{
CloseDrawBatch();
mRenderCmdList.PushBack(renderCmd);
renderCmd->CommandQueued(this);
}
DrawBatch* DrawLayer::AllocateBatch(int minVtxCount, int minIdxCount)
{
AutoPerf autoPerf("DrawLayer::AllocateBatch");
BF_ASSERT(mRenderDevice->mCurRenderState->mShader != NULL);
int vtxSize = mRenderDevice->mCurRenderState->mShader->mVertexSize;
if (minIdxCount == 0)
{
minIdxCount = 512;
minVtxCount = minIdxCount;
}
BF_ASSERT(minIdxCount * sizeof(uint16) <= DRAWBUFFER_IDXBUFFER_SIZE);
BF_ASSERT(minVtxCount * vtxSize <= DRAWBUFFER_VTXBUFFER_SIZE);
DrawBatch* drawBatch = NULL;
auto& pool = mRenderDevice->mDrawBatchPool;
if (pool.size() == 0)
{
drawBatch = CreateDrawBatch();
}
else
{
drawBatch = pool.back();
pool.pop_back();
}
drawBatch->mDrawLayer = this;
int needIdxBytes = minIdxCount * sizeof(uint16);
int needVtxBytes = minVtxCount * vtxSize;
if (needVtxBytes < DRAWBUFFER_VTXBUFFER_SIZE - mVtxByteIdx)
{
//mVtxByteIdx = ((mVtxByteIdx + vtxSize - 1) / vtxSize) * vtxSize;
drawBatch->mVertices = (Vertex3D*)((uint8*) mVtxBuffer + mVtxByteIdx);
drawBatch->mAllocatedVertices = (int)((DRAWBUFFER_VTXBUFFER_SIZE - mVtxByteIdx) / vtxSize);
drawBatch->mIsVertexBufferHead = false;
}
else
{
mVtxBuffer = mRenderDevice->mPooledVertexBuffers.AllocMemoryBlock();
mVtxByteIdx = 0;
drawBatch->mVertices = (Vertex3D*)mVtxBuffer;
drawBatch->mAllocatedVertices = DRAWBUFFER_VTXBUFFER_SIZE / vtxSize;
drawBatch->mIsVertexBufferHead = true;
}
if (needIdxBytes < DRAWBUFFER_IDXBUFFER_SIZE - mIdxByteIdx)
{
drawBatch->mIndices = (uint16*)((uint8*)mIdxBuffer + mIdxByteIdx);
drawBatch->mAllocatedIndices = (DRAWBUFFER_IDXBUFFER_SIZE - mIdxByteIdx) / sizeof(uint16);
drawBatch->mIsIndexBufferHead = false;
}
else
{
mIdxBuffer = mRenderDevice->mPooledIndexBuffers.AllocMemoryBlock();
mIdxByteIdx = 0;
drawBatch->mIndices = (uint16*)mIdxBuffer;
drawBatch->mAllocatedIndices = DRAWBUFFER_IDXBUFFER_SIZE / sizeof(uint16);
drawBatch->mIsIndexBufferHead = true;
}
drawBatch->mAllocatedIndices = std::min(drawBatch->mAllocatedVertices, drawBatch->mAllocatedIndices);
drawBatch->mVtxSize = vtxSize;
mRenderCmdList.PushBack(drawBatch);
mCurDrawBatch = drawBatch;
return drawBatch;
}
void DrawLayer::Draw()
{
AutoPerf autoPerf("DrawLayer::Draw");
RenderCmd* curRenderCmd = mRenderCmdList.mHead;
while (curRenderCmd != NULL)
{
curRenderCmd->Render(mRenderDevice, mRenderWindow);
curRenderCmd = curRenderCmd->mNext;
}
}
void DrawLayer::Flush()
{
Draw();
Clear();
}
void DrawLayer::Clear()
{
for (int texIdx = 0; texIdx < MAX_TEXTURES; texIdx++)
mCurTextures[texIdx] = (Texture*) (intptr) -1;
RenderCmd* curBatch = mRenderCmdList.mHead;
while (curBatch != NULL)
{
RenderCmd* nextBatch = curBatch->mNext;
curBatch->Free();
curBatch = nextBatch;
}
/*if ((mIdxBuffer == NULL) || (mCurDrawBatch != NULL))
mIdxBuffer = mRenderDevice->mPooledIndexBuffers.AllocMemoryBlock();
if ((mVtxBuffer == NULL) || (mCurDrawBatch != NULL))
mVtxBuffer = mRenderDevice->mPooledVertexBuffers.AllocMemoryBlock();
if ((mRenderCmdBuffer == NULL) || (mRenderCmdByteIdx != 0))
mRenderCmdBuffer = mRenderDevice->mPooledRenderCmdBuffers.AllocMemoryBlock();
mIdxByteIdx = 0;
mVtxByteIdx = 0;
mRenderCmdByteIdx = 0;*/
mIdxBuffer = NULL;
mVtxByteIdx = 0;
mRenderCmdBuffer = NULL;
mIdxByteIdx = DRAWBUFFER_IDXBUFFER_SIZE;
mVtxByteIdx = DRAWBUFFER_VTXBUFFER_SIZE;
mRenderCmdByteIdx = DRAWBUFFER_CMDBUFFER_SIZE;
mRenderCmdList.Clear();
mCurDrawBatch = NULL;
}
void* DrawLayer::AllocTris(int vtxCount)
{
if (mCurDrawBatch == NULL)
AllocateBatch(0, 0);
return mCurDrawBatch->AllocTris(vtxCount);
}
void* DrawLayer::AllocStrip(int vtxCount)
{
if (mCurDrawBatch == NULL)
AllocateBatch(0, 0);
return mCurDrawBatch->AllocStrip(vtxCount);
}
void DrawLayer::AllocIndexed(int vtxCount, int idxCount, void** verticesOut, uint16** indicesOut, uint16* idxOfsOut)
{
if (mCurDrawBatch == NULL)
AllocateBatch(0, 0);
mCurDrawBatch->AllocIndexed(vtxCount, idxCount, verticesOut, indicesOut, idxOfsOut);
}
void DrawLayer::SetTexture(int texIdx, Texture* texture)
{
if (mCurTextures[texIdx] != texture)
{
QueueRenderCmd(CreateSetTextureCmd(texIdx, texture));
mCurTextures[texIdx] = texture;
}
}
void DrawLayer::SetShaderConstantDataTyped(int slotIdx, void* constData, int size, int* typeData, int typeCount)
{
SetShaderConstantData(slotIdx, constData, size);
}
///
BF_EXPORT DrawLayer* BF_CALLTYPE DrawLayer_Create(BFWindow* window)
{
DrawLayer* aDrawLayer = gBFApp->CreateDrawLayer(window);
aDrawLayer->Clear();
return aDrawLayer;
}
BF_EXPORT void BF_CALLTYPE DrawLayer_Delete(DrawLayer* drawLayer)
{
if (drawLayer->mRenderWindow != NULL)
{
drawLayer->mRenderWindow->mDrawLayerList.Remove(drawLayer);
}
delete drawLayer;
}
BF_EXPORT void BF_CALLTYPE DrawLayer_Clear(DrawLayer* drawLayer)
{
drawLayer->Clear();
}
BF_EXPORT void BF_CALLTYPE DrawLayer_Activate(DrawLayer* drawLayer)
{
if (drawLayer->mRenderWindow != NULL)
{
drawLayer->mRenderWindow->SetAsTarget();
}
else
{
gBFApp->mRenderDevice->mCurRenderTarget = NULL;
}
gBFApp->mRenderDevice->mCurDrawLayer = drawLayer;
}
BF_EXPORT void BF_CALLTYPE DrawLayer_DrawToRenderTarget(DrawLayer* drawLayer, TextureSegment* textureSegment)
{
RenderDevice* renderDevice = gBFApp->mRenderDevice;
AutoPerf autoPerf("DrawLayer_DrawToRenderTarget DrawPart");
RenderTarget* prevTarget = renderDevice->mCurRenderTarget;
renderDevice->PhysSetRenderState(renderDevice->mDefaultRenderState);
renderDevice->PhysSetRenderTarget(textureSegment->mTexture);
drawLayer->Draw();
renderDevice->mCurRenderTarget = prevTarget;
}

118
BeefySysLib/gfx/DrawLayer.h Normal file
View file

@ -0,0 +1,118 @@
#pragma once
#include "Common.h"
#include "util/SLIList.h"
#include "fbx/FBXReader.h"
#include "gfx/RenderCmd.h"
#include "gfx/RenderDevice.h"
NS_BF_BEGIN;
class RenderWindow;
class Texture;
class Shader;
class ShaderPass;
class BFApp;
class Vertex3D;
class DrawLayer;
class RenderState;
#define MAX_TEXTURES 4
class DrawBatch : public RenderCmd
{
public:
DrawLayer* mDrawLayer;
int mId;
bool mIsVertexBufferHead;
bool mIsIndexBufferHead;
void* mVertices;
int mVtxSize;
int mVtxIdx;
int mAllocatedVertices;
uint16* mIndices;
int mIdxIdx;
int mAllocatedIndices;
Texture* mCurTextures[MAX_TEXTURES];
public:
DrawBatch();
virtual ~DrawBatch();
virtual void Free() override;
void Clear();
DrawBatch* AllocateChainedBatch(int minVtxCount, int minIdxCount);
virtual void* AllocTris(int vtxCount);
virtual void* AllocStrip(int vtxCount);
virtual void AllocIndexed(int vtxCount, int idxCount, void** verticesOut, uint16** indicesOut, uint16* idxOfsOut);
};
#define DRAWBUFFER_CMDBUFFER_SIZE 64*1024
class DrawLayer
{
public:
SLIList<RenderCmd*> mRenderCmdList;
DrawBatch* mCurDrawBatch;
RenderWindow* mRenderWindow;
RenderDevice* mRenderDevice;
void* mIdxBuffer;
void* mVtxBuffer;
void* mRenderCmdBuffer;
int mIdxByteIdx;
int mVtxByteIdx;
int mRenderCmdByteIdx;
Texture* mCurTextures[MAX_TEXTURES];
public:
template <typename T>
T* AllocRenderCmd(int extraBytes = 0)
{
if (mRenderCmdByteIdx + sizeof(T) + extraBytes >= DRAWBUFFER_CMDBUFFER_SIZE)
{
mRenderCmdBuffer = mRenderDevice->mPooledRenderCmdBuffers.AllocMemoryBlock();
T* cmd = new(mRenderCmdBuffer) T();
cmd->mIsPoolHead = true;
mRenderCmdByteIdx = sizeof(T) + extraBytes;
return cmd;
}
T* cmd = new((uint8*)mRenderCmdBuffer + mRenderCmdByteIdx) T();
cmd->mIsPoolHead = false;
mRenderCmdByteIdx += sizeof(T) + extraBytes;
return cmd;
}
public:
void CloseDrawBatch();
virtual DrawBatch* CreateDrawBatch() = 0;
virtual DrawBatch* AllocateBatch(int minVtxCount, int minIdxCount);
void QueueRenderCmd(RenderCmd* renderCmd);
virtual RenderCmd* CreateSetTextureCmd(int textureIdx, Texture* texture) = 0;
virtual void SetShaderConstantData(int slotIdx, void* constData, int size) = 0;
virtual void SetShaderConstantDataTyped(int slotIdx, void* constData, int size, int* typeData, int typeCount);
public:
DrawLayer();
virtual ~DrawLayer();
virtual void Draw();
virtual void Flush();
virtual void Clear();
virtual void* AllocTris(int vtxCount);
virtual void* AllocStrip(int vtxCount);
virtual void AllocIndexed(int vtxCount, int idxCount, void** verticesOut, uint16** indicesOut, uint16* idxOfsOut);
virtual void SetTexture(int texIdx, Texture* texture);
};
NS_BF_END;

362
BeefySysLib/gfx/FTFont.cpp Normal file
View file

@ -0,0 +1,362 @@
#include "FTFont.h"
#include "gfx/Texture.h"
#include "gfx/RenderDevice.h"
#include "img/ImageData.h"
#include "BFApp.h"
#include "freetype/ftsizes.h"
#include "util/AllocDebug.h"
USING_NS_BF;
const int FT_PAGE_WIDTH = 1024;
const int FT_PAGE_HEIGHT = 1024;
//const int FT_PAGE_WIDTH = 128;
//const int FT_PAGE_HEIGHT = 128;
static FT_Library gFTLibrary = NULL;
static FTFontManager gFTFontManager;
FTFont::FTFont()
{
mFace = NULL;
mFaceSize = NULL;
mHeight = 0;
mAscent = 0;
mDescent = 0;
mMaxAdvance = 0;
}
FTFont::~FTFont()
{
Dispose(false);
}
void FTFont::Dispose(bool cacheRetain)
{
if (mFaceSize != NULL)
{
BF_ASSERT((mFaceSize->mRefCount > 0) && (mFaceSize->mRefCount < 1000000));
mFaceSize->mRefCount--;
if (mFaceSize->mRefCount == 0)
{
mFace->mFaceSizes.Remove(mFaceSize->mPointSize);
delete mFaceSize;
if (!cacheRetain)
{
if (mFace->mFaceSizes.IsEmpty())
{
bool removed = gFTFontManager.mFaces.Remove(mFace->mFileName);
BF_ASSERT(removed);
delete mFace;
}
}
}
mFaceSize = NULL;
}
}
FTFontManager::FaceSize::~FaceSize()
{
if (mFTSize != 0)
FT_Done_Size(mFTSize);
}
FTFontManager::Face::~Face()
{
if (mFTFace != 0)
FT_Done_Face(mFTFace);
}
FTFontManager::FTFontManager()
{
for (int i = 0; i < 256; i++)
{
uint8 whiteVal = (uint8)(pow(i / 255.0f, 0.75) * 255.0f);
uint8 blackVal = (uint8)(pow(i / 255.0f, 0.9) * 255.0f);
mWhiteTab[i] = whiteVal;
mBlackTab[i] = blackVal;
}
}
FTFontManager::~FTFontManager()
{
for (auto page : mPages)
delete page;
mPages.Clear();
for (auto faceKV : mFaces)
delete faceKV.mValue;
mFaces.Clear();
}
void FTFontManager::DoClearCache()
{
for (auto page : mPages)
delete page;
mPages.Clear();
for (auto itr = mFaces.begin(); itr != mFaces.end(); )
{
auto face = itr->mValue;
if (face->mFaceSizes.IsEmpty())
{
delete face;
itr = mFaces.Remove(itr);
}
else
++itr;
}
}
void FTFontManager::ClearCache()
{
gFTFontManager.DoClearCache();
}
FTFontManager::Page::~Page()
{
//delete mTexture;
}
/*FTFontManager::Glyph::~Glyph()
{
//delete mTextureSegment;
}*/
bool FTFont::Load(const StringImpl& fileName, float pointSize)
{
if (gFTLibrary == NULL)
FT_Init_FreeType(&gFTLibrary);
FTFontManager::Face* face = NULL;
FTFontManager::Face** facePtr = NULL;
if (gFTFontManager.mFaces.TryAdd(fileName, NULL, &facePtr))
{
face = new FTFontManager::Face();
*facePtr = face;
face->mFileName = fileName;
FT_Face ftFace;
auto error = FT_New_Face(gFTLibrary, fileName.c_str(), 0, &ftFace);
if (error != FT_Err_Ok)
return false;
face->mFTFace = ftFace;
}
else
{
face = *facePtr;
}
mFace = face;
FTFontManager::FaceSize** faceSizePtr = NULL;
if (face->mFaceSizes.TryAdd(pointSize, NULL, &faceSizePtr))
{
//OutputDebugStrF("Created face %s %f\n", fileName.c_str(), pointSize);
mFaceSize = new FTFontManager::FaceSize();
*faceSizePtr = mFaceSize;
FT_Size ftSize;
FT_New_Size(mFace->mFTFace, &ftSize);
FT_Activate_Size(ftSize);
auto error = FT_Set_Char_Size(mFace->mFTFace, 0, (int)(pointSize * 64), 72, 72);
mFaceSize->mFace = mFace;
mFaceSize->mFTSize = ftSize;
mFaceSize->mPointSize = pointSize;
}
else
{
mFaceSize = *faceSizePtr;
}
mFaceSize->mRefCount++;
mHeight = mFaceSize->mFTSize->metrics.height / 64;
mAscent = mFaceSize->mFTSize->metrics.ascender / 64;
mDescent = mFaceSize->mFTSize->metrics.descender / 64;
mMaxAdvance = mFaceSize->mFTSize->metrics.max_advance / 64;
return true;
}
TextureSegment* BF_CALLTYPE Gfx_CreateTextureSegment(TextureSegment* textureSegment, int srcX, int srcY, int srcWidth, int srcHeight);
FTFontManager::Glyph* FTFont::AllocGlyph(int charCode, bool allowDefault)
{
FT_Activate_Size(mFaceSize->mFTSize);
int glyph_index = FT_Get_Char_Index(mFace->mFTFace, charCode);
if ((glyph_index == 0) && (!allowDefault))
return NULL;
auto error = FT_Load_Glyph(mFace->mFTFace, glyph_index, FT_LOAD_NO_BITMAP);
if (error != FT_Err_Ok)
return NULL;
error = FT_Render_Glyph(mFace->mFTFace->glyph, FT_RENDER_MODE_NORMAL);
if (error != FT_Err_Ok)
return NULL;
auto& bitmap = mFace->mFTFace->glyph->bitmap;
if ((bitmap.rows > FT_PAGE_HEIGHT) || (bitmap.width > FT_PAGE_WIDTH))
{
return NULL;
}
FTFontManager::Page* page = NULL;
if (!gFTFontManager.mPages.empty())
{
page = gFTFontManager.mPages.back();
if (page->mCurX + (int)bitmap.width > page->mTexture->mWidth)
{
// Move down to next row
page->mCurX = 0;
page->mCurY += page->mMaxRowHeight;
page->mMaxRowHeight = 0;
}
if (page->mCurY + (int)bitmap.rows > page->mTexture->mHeight)
{
// Doesn't fit
page = NULL;
}
}
if (page == NULL)
{
page = new FTFontManager::Page();
gFTFontManager.mPages.push_back(page);
}
//auto glyph = new FTFontManager::Glyph();
static FTFontManager::Glyph staticGlyph;
auto glyph = &staticGlyph;
auto ftFace = mFace->mFTFace;
glyph->mXAdvance = ftFace->glyph->advance.x / 64;
glyph->mXOffset = ftFace->glyph->bitmap_left;
glyph->mYOffset = ftFace->size->metrics.ascender / 64 - ftFace->glyph->bitmap_top;
glyph->mPage = page;
glyph->mX = page->mCurX;
glyph->mY = page->mCurY;
glyph->mWidth = bitmap.width;
glyph->mHeight = bitmap.rows;
if (page->mTexture == NULL)
{
ImageData img;
img.CreateNew(FT_PAGE_WIDTH, FT_PAGE_HEIGHT);
for (int i = 0; i < FT_PAGE_HEIGHT * FT_PAGE_WIDTH; i++)
{
if (i % 3 == 0)
img.mBits[i] = 0xFFFF0000;
else if (i % 3 == 1)
img.mBits[i] = 0xFF00FF00;
else
img.mBits[i] = 0xFF0000FF;
}
page->mTexture = gBFApp->mRenderDevice->LoadTexture(&img, TextureFlag_NoPremult);
page->mTexture->mRefCount = 0;
}
if (bitmap.width > 0)
{
ImageData img;
img.CreateNew(bitmap.width, bitmap.rows);
for (int y = 0; y < (int)bitmap.rows; y++)
{
for (int x = 0; x < (int)bitmap.width; x++)
{
uint8 val = bitmap.buffer[y * bitmap.pitch + x];
uint8 whiteVal = gFTFontManager.mWhiteTab[val];
uint8 blackVal = gFTFontManager.mBlackTab[val];
img.mBits[y * img.mWidth + x] = ((int32)whiteVal << 24) |
((int32)blackVal) | ((int32)0xFF << 8) | ((int32)0xFF << 16);
}
}
page->mTexture->Blt(&img, page->mCurX, page->mCurY);
}
page->mCurX += bitmap.width;
page->mMaxRowHeight = std::max(page->mMaxRowHeight, (int)bitmap.rows);
auto texture = page->mTexture;
texture->AddRef();
TextureSegment* textureSegment = new TextureSegment();
textureSegment->mTexture = texture;
textureSegment->mU1 = (glyph->mX / (float)texture->mWidth);
textureSegment->mV1 = (glyph->mY / (float)texture->mHeight);
textureSegment->mU2 = ((glyph->mX + glyph->mWidth) / (float)texture->mWidth);
textureSegment->mV2 = ((glyph->mY + glyph->mHeight) / (float)texture->mHeight);
textureSegment->mScaleX = (float)abs(glyph->mWidth);
textureSegment->mScaleY = (float)abs(glyph->mHeight);
glyph->mTextureSegment = textureSegment;
return glyph;
}
int FTFont::GetKerning(int charA, int charB)
{
FT_Activate_Size(mFaceSize->mFTSize);
FT_Vector kerning;
int glyph_indexA = FT_Get_Char_Index(mFace->mFTFace, charA);
int glyph_indexB = FT_Get_Char_Index(mFace->mFTFace, charB);
FT_Get_Kerning(mFace->mFTFace, glyph_indexA, glyph_indexB, FT_KERNING_DEFAULT, &kerning);
return kerning.x / 64;
}
void FTFont::Release(bool cacheRetain)
{
Dispose(cacheRetain);
delete this;
}
//////////////////////////////////////////////////////////////////////////
BF_EXPORT FTFont* BF_CALLTYPE FTFont_Load(const char* fileName, float pointSize)
{
auto ftFont = new FTFont();
if (!ftFont->Load(fileName, pointSize))
{
delete ftFont;
return NULL;
}
return ftFont;
}
BF_EXPORT void BF_CALLTYPE FTFont_ClearCache()
{
FTFontManager::ClearCache();
}
BF_EXPORT void BF_CALLTYPE FTFont_Delete(FTFont* ftFont, bool cacheRetain)
{
ftFont->Release(cacheRetain);
}
BF_EXPORT FTFontManager::Glyph* BF_CALLTYPE FTFont_AllocGlyph(FTFont* ftFont, int charCode, bool allowDefault)
{
return ftFont->AllocGlyph(charCode, allowDefault);
}
BF_EXPORT int BF_CALLTYPE FTFont_GetKerning(FTFont* ftFont, int charCodeA, int charCodeB)
{
auto kerning = ftFont->GetKerning(charCodeA, charCodeB);
return kerning;
}

140
BeefySysLib/gfx/FTFont.h Normal file
View file

@ -0,0 +1,140 @@
#pragma once
#include "../Common.h"
#include "../util/String.h"
#include "../util/Dictionary.h"
#include "../util/Array.h"
#include <unordered_map>
#include <vector>
#include "third_party/freetype/include/ft2build.h"
#include FT_FREETYPE_H
NS_BF_BEGIN
class Texture;
class TextureSegment;
class FTFontManager
{
public:
class Face;
class FaceSize
{
public:
Face* mFace;
FT_Size mFTSize;
int mRefCount;
float mPointSize;
public:
FaceSize()
{
mFace = NULL;
mRefCount = 0;
mFTSize = NULL;
mPointSize = -1;
}
~FaceSize();
};
class Face
{
public:
String mFileName;
FT_Face mFTFace;
Dictionary<float, FaceSize*> mFaceSizes;
public:
Face()
{
mFTFace = NULL;
}
~Face();
};
class Page
{
public:
Texture* mTexture;
int mCurX;
int mCurY;
int mMaxRowHeight;
public:
Page()
{
mTexture = NULL;
mCurX = 0;
mCurY = 0;
mMaxRowHeight = 0;
}
~Page();
};
class Glyph
{
public:
Page* mPage;
TextureSegment* mTextureSegment;
int mX;
int mY;
int mWidth;
int mHeight;
int mXOffset;
int mYOffset;
int mXAdvance;
public:
Glyph()
{
mPage = NULL;
mTextureSegment = NULL;
}
//~Glyph();
};
public:
Dictionary<String, Face*> mFaces;
Array<Page*> mPages;
uint8 mWhiteTab[256];
uint8 mBlackTab[256];
void DoClearCache();
public:
FTFontManager();
~FTFontManager();
static void ClearCache();
};
class FTFont
{
public:
int mHeight;
int mAscent;
int mDescent;
int mMaxAdvance;
FTFontManager::Face* mFace;
FTFontManager::FaceSize* mFaceSize;
protected:
void Dispose(bool cacheRetain);
public:
FTFont();
~FTFont();
bool Load(const StringImpl& file, float pointSize);
FTFontManager::Glyph* AllocGlyph(int charCode, bool allowDefault);
int GetKerning(int charA, int charB);
void Release(bool cacheRetain = false);
};
NS_BF_END

2
BeefySysLib/gfx/Font.h Normal file
View file

@ -0,0 +1,2 @@
#pragma once

View file

@ -0,0 +1,85 @@
#include "ModelDef.h"
#include "BFApp.h"
#include "gfx/RenderDevice.h"
#include "gfx/ModelInstance.h"
USING_NS_BF;
void Beefy::ModelAnimation::GetJointTranslation(int jointIdx, float frameNum, ModelJointTranslation* outJointTranslation)
{
// Frame 35
BF_ASSERT((int)frameNum < (int)mFrames.size());
int frameNumStart = (int)frameNum;
int frameNumEnd = (frameNumStart + 1) % (int)mFrames.size();
float endAlpha = frameNum - frameNumStart;
float startAlpha = 1.0f - endAlpha;
ModelJointTranslation* jointTransStart = &(mFrames[frameNumStart].mJointTranslations[jointIdx]);
ModelJointTranslation* jointTransEnd = &(mFrames[frameNumEnd].mJointTranslations[jointIdx]);
//if (/*(jointIdx == 37) || (jointIdx == 36) || (jointIdx == 35) ||*/ (jointIdx == 34) /*|| (jointIdx == 12) || (jointIdx == 11) || (jointIdx == 10) || (jointIdx == 0)*/)
{
outJointTranslation->mQuat = Quaternion::Slerp(endAlpha, jointTransStart->mQuat, jointTransEnd->mQuat, true);
outJointTranslation->mScale = (jointTransStart->mScale * startAlpha) + (jointTransEnd->mScale * endAlpha);
outJointTranslation->mTrans = (jointTransStart->mTrans * startAlpha) + (jointTransEnd->mTrans * endAlpha);
}
/*else
{
*outJointTranslation = *jointTransStart;
}*/
//*outJointTranslation = *jointTransStart;
}
//
BF_EXPORT ModelInstance* BF_CALLTYPE ModelDef_CreateModelInstance(ModelDef* modelDef)
{
return gBFApp->mRenderDevice->CreateModelInstance(modelDef);
}
BF_EXPORT float BF_CALLTYPE ModelDef_GetFrameRate(ModelDef* modelDef)
{
return modelDef->mFrameRate;
}
BF_EXPORT int BF_CALLTYPE ModelDef_GetJointCount(ModelDef* modelDef)
{
return (int)modelDef->mJoints.size();
}
BF_EXPORT int BF_CALLTYPE ModelDef_GetAnimCount(ModelDef* modelDef)
{
return (int)modelDef->mAnims.size();
}
BF_EXPORT ModelAnimation* BF_CALLTYPE ModelDef_GetAnimation(ModelDef* modelDef, int animIdx)
{
return &modelDef->mAnims[animIdx];
}
BF_EXPORT void BF_CALLTYPE ModelDefAnimation_GetJointTranslation(ModelAnimation* modelAnimation, int jointIdx, float frame, ModelJointTranslation* outJointTranslation)
{
modelAnimation->GetJointTranslation(jointIdx, frame, outJointTranslation);
}
BF_EXPORT int BF_CALLTYPE ModelDefAnimation_GetFrameCount(ModelAnimation* modelAnimation)
{
return (int)modelAnimation->mFrames.size();
}
BF_EXPORT const char* BF_CALLTYPE ModelDefAnimation_GetName(ModelAnimation* modelAnimation)
{
return modelAnimation->mName.c_str();
}
BF_EXPORT void BF_CALLTYPE ModelDefAnimation_Clip(ModelAnimation* modelAnimation, int startFrame, int numFrames)
{
modelAnimation->mFrames.erase(modelAnimation->mFrames.begin(), modelAnimation->mFrames.begin() + startFrame);
modelAnimation->mFrames.erase(modelAnimation->mFrames.begin() + numFrames, modelAnimation->mFrames.end());
}

View file

@ -0,0 +1,78 @@
#pragma once
#include "Common.h"
#include "util/Quaternion.h"
#include "util/Vector.h"
#include <vector>
NS_BF_BEGIN;
class ModelJointTranslation
{
public:
Quaternion mQuat;
Vector3 mScale;
Vector3 mTrans;
};
class ModelAnimationFrame
{
public:
std::vector<ModelJointTranslation> mJointTranslations;
};
class ModelAnimation
{
public:
String mName;
std::vector<ModelAnimationFrame> mFrames;
public:
void GetJointTranslation(int jointIdx, float frameNum, ModelJointTranslation* outJointTranslation);
};
#define MODEL_MAX_BONE_WEIGHTS 8
class ModelVertex
{
public:
Vector3 mPosition;
uint32 mColor;
TexCoords mTexCoords;
TexCoords mBumpTexCoords;
Vector3 mNormal;
Vector3 mTangent;
int mNumBoneWeights;
int mBoneIndices[MODEL_MAX_BONE_WEIGHTS];
float mBoneWeights[MODEL_MAX_BONE_WEIGHTS];
};
class ModelJoint
{
public:
String mName;
int mParentIdx;
Matrix4 mPoseInvMatrix;
};
class ModelMesh
{
public:
String mName;
std::vector<ModelVertex> mVertices;
std::vector<uint16> mIndices;
String mTexFileName;
String mBumpFileName;
};
class ModelDef
{
public:
String mLoadDir;
float mFrameRate;
std::vector<ModelMesh> mMeshes;
std::vector<ModelJoint> mJoints;
std::vector<ModelAnimation> mAnims;
};
NS_BF_END;

View file

@ -0,0 +1,30 @@
#include "ModelInstance.h"
USING_NS_BF;
ModelInstance::ModelInstance(ModelDef* modelDef)
{
mNext = NULL;
mModelDef = modelDef;
mJointTranslations.resize(mModelDef->mJoints.size());
mMeshesVisible.insert(mMeshesVisible.begin(), mModelDef->mMeshes.size(), true);
}
void Beefy::ModelInstance::SetJointPosition(int jointIdx, const ModelJointTranslation& jointTranslation)
{
mJointTranslations[jointIdx] = jointTranslation;
}
///
BF_EXPORT void BF_CALLTYPE ModelInstance_SetJointTranslation(ModelInstance* modelInstance, int jointIdx, const ModelJointTranslation& jointTranslation)
{
modelInstance->SetJointPosition(jointIdx, jointTranslation);
}
BF_EXPORT void BF_CALLTYPE ModelInstance_SetMeshVisibility(ModelInstance* modelInstance, int meshIdx, int visible)
{
modelInstance->mMeshesVisible[meshIdx] = visible != 0;
}

View file

@ -0,0 +1,24 @@
#pragma once
#include "Common.h"
#include "gfx/ModelDef.h"
#include "gfx/RenderCmd.h"
#include "util/Matrix4.h"
NS_BF_BEGIN;
class ModelInstance : public RenderCmd
{
public:
ModelDef* mModelDef;
std::vector<ModelJointTranslation> mJointTranslations;
std::vector<bool> mMeshesVisible;
public:
ModelInstance(ModelDef* modelDef);
virtual void Free() override {}
virtual void SetJointPosition(int jointIdx, const ModelJointTranslation& jointTranslation);
};
NS_BF_END;

View file

@ -0,0 +1,18 @@
#include "gfx/RenderCmd.h"
#include "gfx/RenderDevice.h"
#include "BFApp.h"
USING_NS_BF;
void RenderCmd::SetRenderState()
{
RenderDevice* renderDevice = gBFApp->mRenderDevice;
if (mRenderState != renderDevice->mPhysRenderState)
renderDevice->PhysSetRenderState(mRenderState);
}
void RenderCmd::Free()
{
if (mIsPoolHead)
gBFApp->mRenderDevice->mPooledRenderCmdBuffers.FreeMemoryBlock(this);
}

View file

@ -0,0 +1,35 @@
#pragma once
#include "Common.h"
NS_BF_BEGIN;
class RenderState;
class RenderDevice;
class RenderWindow;
class DrawLayer;
class RenderCmd
{
public:
RenderCmd* mNext;
RenderState* mRenderState;
bool mIsPoolHead;
int mCmdIdx;
public:
RenderCmd()
{
mNext = NULL;
mRenderState = NULL;
mIsPoolHead = false;
mCmdIdx = -1;
}
void SetRenderState();
virtual void CommandQueued(DrawLayer* drawLayer) {}
virtual void Render(RenderDevice* renderDevice, RenderWindow* renderWindow) = 0;
virtual void Free();
};
NS_BF_END;

View file

@ -0,0 +1,141 @@
#include "RenderDevice.h"
#include "BFApp.h"
#include "Shader.h"
#include "Texture.h"
#include "gfx/DrawLayer.h"
#include "img/TGAData.h"
#include "img/PNGData.h"
#include "img/PVRData.h"
#include "img/BFIData.h"
#include "img/JPEGData.h"
#include "util/PerfTimer.h"
#include "util/AllocDebug.h"
USING_NS_BF;
RenderState::RenderState()
{
mWriteDepthBuffer = false;
mCullMode = CullMode_None;
mDepthFunc = DepthFunc_Always;
mShader = NULL;
mClipped = false;
}
RenderTarget::RenderTarget()
{
mWidth = 0;
mHeight = 0;
mHasBeenDrawnTo = false;
mHasBeenTargeted = false;
mResizeNum = 0;
}
RenderWindow::RenderWindow()
{
mCurDrawLayer = NULL;
mRenderDevice = NULL;
mWindow = NULL;
}
RenderWindow::~RenderWindow()
{
for (auto drawLayer : mDrawLayerList)
delete drawLayer;
}
///
RenderDevice::RenderDevice() :
mPooledIndexBuffers(DRAWBUFFER_IDXBUFFER_SIZE),
mPooledVertexBuffers(DRAWBUFFER_VTXBUFFER_SIZE),
mPooledRenderCmdBuffers(DRAWBUFFER_CMDBUFFER_SIZE)
{
mCurRenderState = NULL;
mDefaultRenderState = NULL;
mPhysRenderState = mDefaultRenderState;
mResizeCount = 0;
mCurRenderTarget = NULL;
mCurDrawLayer = NULL;
mPhysRenderWindow = NULL;
}
RenderDevice::~RenderDevice()
{
for (auto batch : mDrawBatchPool)
delete batch;
}
void RenderDevice::AddRenderWindow(RenderWindow* renderWindow)
{
mRenderWindowList.push_back(renderWindow);
}
void RenderDevice::RemoveRenderWindow(RenderWindow* renderWindow)
{
mRenderWindowList.erase(std::find(mRenderWindowList.begin(), mRenderWindowList.end(), renderWindow));
}
void RenderDevice::FrameEnd()
{
}
RenderState* RenderDevice::CreateRenderState(RenderState* srcRenderState)
{
RenderState* renderState = new RenderState();
if (srcRenderState != NULL)
*renderState = *srcRenderState;
return renderState;
}
VertexDefinition* Beefy::RenderDevice::CreateVertexDefinition(VertexDefData* elementData, int numElements)
{
VertexDefinition* vertexDefinition = new VertexDefinition();
vertexDefinition->mElementData = new VertexDefData[numElements];
vertexDefinition->mNumElements = numElements;
memcpy(vertexDefinition->mElementData, elementData, numElements * sizeof(VertexDefData));
return vertexDefinition;
}
Texture* RenderDevice::LoadTexture(const StringImpl& fileName, int flags)
{
int dotPos = (int)fileName.LastIndexOf('.');
String ext = fileName.Substring(dotPos);
ImageData* imageData = NULL;
if (ext == ".tga")
imageData = new TGAData();
else if (ext == ".png")
imageData = new PNGData();
else if (ext == ".jpg")
imageData = new JPEGData();
else if (ext == ".pvr")
imageData = new PVRData();
else
{
BF_FATAL("Unknown texture format");
return NULL; // Unknown format
}
imageData->mWantsAlphaPremultiplied = (flags & TextureFlag_NoPremult) == 0;
Texture* aTexture = NULL;
if (imageData->LoadFromFile(fileName))
{
// if ((int)fileName.IndexOf("fft") != -1)
// {
// BFIData bFIData;
// bFIData.Compress(imageData);
// }
aTexture = LoadTexture(imageData, flags);
}
else
BF_FATAL("Failed to load image");
delete imageData;
return aTexture;
}

View file

@ -0,0 +1,288 @@
#pragma once
#include "Common.h"
#include "RenderTarget.h"
#include "util/Rect.h"
#include "util/SLIList.h"
NS_BF_BEGIN;
class Texture;
class Shader;
class ShaderPass;
class BFApp;
class DefaultVertex3D
{
public:
float x;
float y;
float z;
float u;
float v;
uint32 color;
public:
DefaultVertex3D()
{
}
DefaultVertex3D(float _x, float _y, float _z, float _u, float _v, uint32 _color)
{
x = _x;
y = _y;
z = _z;
color = _color;
u = _u;
v = _v;
}
void Set(float _x, float _y, float _z, float _u, float _v, uint32 _color)
{
x = _x;
y = _y;
z = _z;
color = _color;
u = _u;
v = _v;
}
};
class RenderWindow;
class DrawBatch;
class DrawLayer;
class BFWindow;
class ImageData;
class DrawLayer;
class ModelInstance;
class FBXReader;
class RenderCmd;
class ModelDef;
class RenderDevice;
class RenderWindow : public RenderTarget
{
public:
RenderDevice* mRenderDevice;
BFWindow* mWindow;
Array<DrawLayer*> mDrawLayerList;
DrawLayer* mCurDrawLayer;
public:
RenderWindow();
virtual ~RenderWindow();
virtual void SetAsTarget() = 0;
virtual void Resized() = 0;
virtual void Present() = 0;
};
const int DRAWBUFFER_IDXBUFFER_SIZE = 8*1024;
const int DRAWBUFFER_VTXBUFFER_SIZE = 64*1024;
enum DepthFunc : int8
{
DepthFunc_Never,
DepthFunc_Less,
DepthFunc_LessEqual,
DepthFunc_Equal,
DepthFunc_Greater,
DepthFunc_NotEqual,
DepthFunc_GreaterEqual,
DepthFunc_Always
};
enum VertexElementFormat : int8
{
VertexElementFormat_Single,
VertexElementFormat_Vector2,
VertexElementFormat_Vector3,
VertexElementFormat_Vector4,
VertexElementFormat_Color,
VertexElementFormat_Byte4,
VertexElementFormat_Short2,
VertexElementFormat_Short4,
VertexElementFormat_NormalizedShort2,
VertexElementFormat_NormalizedShort4,
VertexElementFormat_HalfVector2,
VertexElementFormat_HalfVector4
};
enum VertexElementUsage : int8
{
VertexElementUsage_Position2D,
VertexElementUsage_Position3D,
VertexElementUsage_Color,
VertexElementUsage_TextureCoordinate,
VertexElementUsage_Normal,
VertexElementUsage_Binormal,
VertexElementUsage_Tangent,
VertexElementUsage_BlendIndices,
VertexElementUsage_BlendWeight,
VertexElementUsage_Depth,
VertexElementUsage_Fog,
VertexElementUsage_PointSize,
VertexElementUsage_Sample,
VertexElementUsage_TessellateFactor
};
enum ConstantDataType : int8
{
ConstantDataType_Single,
ConstantDataType_Vector2,
ConstantDataType_Vector3,
ConstantDataType_Vector4,
ConstantDataType_Matrix
};
enum CullMode : int8
{
CullMode_None,
CullMode_Front,
CullMode_Back
};
enum TextureFlag : int8
{
TextureFlag_Additive = 1,
TextureFlag_NoPremult = 2
};
struct VertexDefData
{
VertexElementUsage mUsage;
int mUsageIndex;
VertexElementFormat mFormat;
};
class VertexDefinition
{
public:
VertexDefData* mElementData;
int mNumElements;
public:
VertexDefinition()
{
mElementData = NULL;
mNumElements = 0;
}
virtual ~VertexDefinition()
{
delete [] mElementData;
}
};
class RenderState
{
public:
Shader* mShader;
bool mWriteDepthBuffer;
DepthFunc mDepthFunc;
bool mClipped;
Rect mClipRect;
CullMode mCullMode;
public:
RenderState();
virtual ~RenderState() {}
virtual void SetShader(Shader* shader) { mShader = shader; }
virtual void SetClipped(bool clipped) { mClipped = clipped; }
virtual void SetClipRect(const Rect& rect) { mClipRect = rect; }
virtual void SetWriteDepthBuffer(bool writeDepthBuffer) { mWriteDepthBuffer = writeDepthBuffer; }
virtual void SetDepthFunc(DepthFunc depthFunc) { mDepthFunc = depthFunc; }
};
class PoolData
{
public:
PoolData* mNext;
};
class MemoryPool : protected SLIList<PoolData*>
{
public:
int mSize;
public:
MemoryPool(int size)
{
mSize = size;
}
~MemoryPool()
{
auto cur = mHead;
while (cur != NULL)
{
auto next = cur->mNext;
delete [] cur;
cur = next;
}
}
void* AllocMemoryBlock()
{
if (IsEmpty())
return new uint8[mSize];
return (uint8*)PopFront();
}
void FreeMemoryBlock(void* block)
{
PoolData* poolData = (PoolData*)block;
poolData->mNext = NULL;
PushBack(poolData);
}
};
class RenderDevice
{
public:
Array<DrawBatch*> mDrawBatchPool;
RenderWindow* mPhysRenderWindow;
RenderState* mPhysRenderState;
int mResizeCount;
Array<RenderWindow*> mRenderWindowList;
RenderTarget* mCurRenderTarget;
DrawLayer* mCurDrawLayer;
RenderState* mDefaultRenderState;
RenderState* mCurRenderState;
MemoryPool mPooledIndexBuffers;
MemoryPool mPooledVertexBuffers;
MemoryPool mPooledRenderCmdBuffers;
public:
virtual void PhysSetRenderState(RenderState* renderState) = 0;
virtual void PhysSetRenderTarget(Texture* renderTarget) = 0;
public:
RenderDevice();
virtual ~RenderDevice();
virtual bool Init(BFApp* app) = 0;
virtual void AddRenderWindow(RenderWindow* renderWindow);
virtual void RemoveRenderWindow(RenderWindow* renderWindow);
virtual RenderState* CreateRenderState(RenderState* srcRenderState);
virtual ModelInstance* CreateModelInstance(ModelDef* modelDef) { return NULL; }
virtual VertexDefinition* CreateVertexDefinition(VertexDefData* elementData, int numElements);
virtual void FrameStart() = 0;
virtual void FrameEnd();
virtual Texture* LoadTexture(ImageData* imageData, int flags) = 0;
virtual Texture* CreateDynTexture(int width, int height) = 0;
virtual Texture* LoadTexture(const StringImpl& fileName, int flags);
virtual Texture* CreateRenderTarget(int width, int height, bool destAlpha) = 0;
virtual Shader* LoadShader(const StringImpl& fileName, VertexDefinition* vertexDefinition) = 0;
virtual void SetRenderState(RenderState* renderState) = 0;
};
NS_BF_END;

View file

@ -0,0 +1,2 @@
#include "RenderTarget.h"

View file

@ -0,0 +1,21 @@
#pragma once
#include "Common.h"
NS_BF_BEGIN;
class RenderTarget
{
public:
int mWidth;
int mHeight;
int mResizeNum;
bool mHasBeenTargeted;
bool mHasBeenDrawnTo;
public:
RenderTarget();
};
NS_BF_END;

View file

@ -0,0 +1,18 @@
#include "Shader.h"
USING_NS_BF;
Shader::Shader()
{
mLastResizeCount = -1;
}
Shader::~Shader()
{
mTextureParam = NULL;
}
void Shader::Init()
{
mTextureParam = GetShaderParam("tex2D");
}

38
BeefySysLib/gfx/Shader.h Normal file
View file

@ -0,0 +1,38 @@
#pragma once
#include "Common.h"
NS_BF_BEGIN;
class Texture;
class Shader;
class ShaderParam
{
public:
virtual ~ShaderParam() {}
virtual void SetTexture(Texture* texture) = 0;
virtual void SetFloat2(float x, float y) { SetFloat4(x, y, 0, 1); }
virtual void SetFloat3(float x, float y, float z) { SetFloat4(x, y, z, 1); }
virtual void SetFloat4(float x, float y, float z, float w) = 0;
};
class Shader
{
public:
ShaderParam* mTextureParam;
int mLastResizeCount;
int mVertexSize;
public:
virtual void Init();
public:
Shader();
virtual ~Shader();
virtual ShaderParam* GetShaderParam(const StringImpl& name) = 0;
};
NS_BF_END;

View file

@ -0,0 +1,33 @@
#include "Texture.h"
#include "util/AllocDebug.h"
USING_NS_BF;
Texture::Texture()
{
mRefCount = 0;
}
void Texture::AddRef()
{
mRefCount++;
}
void Texture::Release()
{
mRefCount--;
if (mRefCount == 0)
delete this;
}
void TextureSegment::InitFromTexture(Texture* texture)
{
mTexture = texture;
mU1 = 0;
mV1 = 0;
mU2 = 1.0f;
mV2 = 1.0f;
mScaleX = (float) mTexture->mWidth;
mScaleY = (float) mTexture->mHeight;
}

42
BeefySysLib/gfx/Texture.h Normal file
View file

@ -0,0 +1,42 @@
#pragma once
#include "Common.h"
#include "RenderTarget.h"
NS_BF_BEGIN;
class ImageData;
class Texture : public RenderTarget
{
public:
int mRefCount;
public:
Texture();
virtual ~Texture() {}
virtual void AddRef();
virtual void Release();
virtual void PhysSetAsTarget() = 0;
virtual void Blt(ImageData* imageData, int x, int y) { };
virtual void SetBits(int destX, int destY, int destWidth, int destHeight, int srcPitch, uint32* bits) {}
};
class TextureSegment
{
public:
Texture* mTexture;
float mU1;
float mV1;
float mU2;
float mV2;
float mScaleX;
float mScaleY;
public:
void InitFromTexture(Texture* texture);
};
NS_BF_END;

872
BeefySysLib/img/BFIData.cpp Normal file
View file

@ -0,0 +1,872 @@
#include "BFIData.h"
#include "ImageUtils.h"
USING_NS_BF;
#define IS_ZERO(v) ((fabs(v) < 0.000000001))
#include <complex>
#include <iostream>
#include <valarray>
const double PI = 3.141592653589793238460;
typedef std::complex<double> Complex;
typedef std::valarray<Complex> CArray;
// Cooley<65>Tukey FFT (in-place)
void fft(CArray& x)
{
const size_t N = x.size();
if (N <= 1) return;
// divide
CArray even = x[std::slice(0, N/2, 2)];
CArray odd = x[std::slice(1, N/2, 2)];
// conquer
fft(even);
fft(odd);
// combine
for (size_t k = 0; k < N/2; ++k)
{
Complex t = std::polar(1.0, -2 * PI * k / N) * odd[k];
x[k ] = even[k] + t;
x[k+N/2] = even[k] - t;
}
}
void DFTTest()
{
const Complex test[] = { 1.0, 2.0, 3.0, 4.0 };
CArray data(test, sizeof(test) / sizeof(test[0]));
fft(data);
}
/*-------------------------------------------------------------------------
Perform a 2D FFT inplace given a complex 2D array
The direction dir, 1 for forward, -1 for reverse
The size of the array (nx,ny)
Return false if there are memory problems or
the dimensions are not powers of 2
*/
class COMPLEX
{
public:
double real;
double imag;
};
/*-------------------------------------------------------------------------
This computes an in-place complex-to-complex FFT
x and y are the real and imaginary arrays of 2^m points.
dir = 1 gives forward transform
dir = -1 gives reverse transform
Formula: forward
N-1
---
1 \ - j k 2 pi n / N
X(n) = --- > x(k) e = forward transform
N / n=0..N-1
---
k=0
Formula: reverse
N-1
---
\ j k 2 pi n / N
X(n) = > x(k) e = forward transform
/ n=0..N-1
---
k=0
*/
int FFT(int dir,int m,double *x,double *y)
{
long nn,i,i1,j,k,i2,l,l1,l2;
double c1,c2,tx,ty,t1,t2,u1,u2,z;
/* Calculate the number of points */
nn = 1;
for (i=0;i<m;i++)
nn *= 2;
/* Do the bit reversal */
i2 = nn >> 1;
j = 0;
for (i=0;i<nn-1;i++) {
if (i < j) {
tx = x[i];
ty = y[i];
x[i] = x[j];
y[i] = y[j];
x[j] = tx;
y[j] = ty;
}
k = i2;
while (k <= j) {
j -= k;
k >>= 1;
}
j += k;
}
/* Compute the FFT */
c1 = -1.0;
c2 = 0.0;
l2 = 1;
for (l=0;l<m;l++) {
l1 = l2;
l2 <<= 1;
u1 = 1.0;
u2 = 0.0;
for (j=0;j<l1;j++) {
for (i=j;i<nn;i+=l2) {
i1 = i + l1;
t1 = u1 * x[i1] - u2 * y[i1];
t2 = u1 * y[i1] + u2 * x[i1];
x[i1] = x[i] - t1;
y[i1] = y[i] - t2;
x[i] += t1;
y[i] += t2;
}
z = u1 * c1 - u2 * c2;
u2 = u1 * c2 + u2 * c1;
u1 = z;
}
c2 = sqrt((1.0 - c1) / 2.0);
if (dir == 1)
c2 = -c2;
c1 = sqrt((1.0 + c1) / 2.0);
}
/* Scaling for forward transform */
if (dir == 1) {
for (i=0;i<nn;i++) {
x[i] /= (double)nn;
y[i] /= (double)nn;
}
}
return true;
}
class BFComplex
{
public:
double mR;
double mI;
public:
BFComplex(double r = 0, double i = 0)
{
mR = r;
mI = i;
}
BFComplex operator +(const BFComplex& complex) const
{
return BFComplex(mR + complex.mR, mI + complex.mI);
}
BFComplex& operator +=(const BFComplex& complex)
{
*this = BFComplex(mR + complex.mR, mI + complex.mI);
return *this;
}
BFComplex operator *(const BFComplex& complex) const
{
return BFComplex(mR * complex.mR - mI * complex.mI, mR * complex.mI + mI * complex.mR);
}
BFComplex operator *(double scalar) const
{
return BFComplex(mR * scalar, mI * scalar);
}
double Magnitude()
{
return sqrt(mR * mR + mI * mI);
}
double Phase()
{
return atan2(mI, mR);
}
String ToString()
{
if (fabs(mI) < 0.00000001)
{
if (fabs(mR) < 0.00000001)
return StrFormat("%f", 0.0);
return StrFormat("%f", mR);
}
if (mI > 0)
return StrFormat("%f + %fi", mR, mI);
return StrFormat("%f - %fi", mR, -mI);
}
static BFComplex Polar(double scalar, double angle)
{
return BFComplex(scalar * cos(angle), scalar * sin(angle));
}
};
bool Powerof2(int num, int* power, int* twoPM)
{
*power = 0;
*twoPM = 1;
while (*twoPM < num)
{
*twoPM *= 2;
(*power)++;
}
return *twoPM == num;
}
int FFT2D(BFComplex **c,int nx,int ny,int dir)
{
int i,j;
int m,twopm;
double *real,*imag;
/* Transform the rows */
real = (double *)malloc(nx * sizeof(double));
imag = (double *)malloc(nx * sizeof(double));
if (real == NULL || imag == NULL)
return(false);
if (!Powerof2(nx,&m,&twopm) || twopm != nx)
return(false);
for (j=0;j<ny;j++) {
for (i=0;i<nx;i++) {
real[i] = c[i][j].mR;
imag[i] = c[i][j].mI;
}
FFT(dir,m,real,imag);
for (i=0;i<nx;i++) {
c[i][j].mR = real[i];
c[i][j].mI = imag[i];
}
}
free(real);
free(imag);
/* Transform the columns */
real = (double *)malloc(ny * sizeof(double));
imag = (double *)malloc(ny * sizeof(double));
if (real == NULL || imag == NULL)
return(false);
if (!Powerof2(ny,&m,&twopm) || twopm != ny)
return(false);
for (i=0;i<nx;i++) {
for (j=0;j<ny;j++) {
real[j] = c[i][j].mR;
imag[j] = c[i][j].mI;
}
FFT(dir,m,real,imag);
for (j=0;j<ny;j++) {
c[i][j].mR = real[j];
c[i][j].mI = imag[j];
}
}
free(real);
free(imag);
return(true);
}
void DFTTest_2D()
{
BFComplex** test = new BFComplex*[4];
for (int i = 0; i < 4; i++)
{
test[i] = new BFComplex[4];
for (int j = 0; j < 4; j++)
test[i][j].mR = i*4+j+1;
}
/*std::wstring aString;
for (int i = 0; i < 4; i++)
{
aString += L"(";
for (int j = 0; j < 4; j++)
{
if (j != 0)
aString += L", ";
aString += test[i][j].ToString();
}
aString += L")\n";
}
OutputDebugStringW(aString.c_str());*/
/*[][3] =
{{1.0, 2.0, 3.0},
{4.0, 5.0, 6.0},
{7.0, 8.0, 9.0}};*/
FFT2D(test, 4, 4, -1);
String aString;
for (int i = 0; i < 4; i++)
{
aString += "(";
for (int j = 0; j < 4; j++)
{
if (j != 0)
aString += ", ";
aString += test[i][j].ToString();
}
aString += ")\n";
}
BfpOutput_DebugString(aString.c_str());
}
void PrintComplex2D(BFComplex* ptr, int cols, int rows)
{
String aString = "(\n";
for (int i = 0; i < rows; i++)
{
aString += "\t(";
for (int j = 0; j < cols; j++)
{
if (j != 0)
aString += ", ";
aString += ptr[i*cols+j].ToString();
}
aString += ")\n";
}
aString += ")\n";
BfpOutput_DebugString(aString.c_str());
}
void FFD_1D(BFComplex* array, int size, int pitch, int aDir)
{
BFComplex* prev = new BFComplex[size];
for (int i = 0; i < size; i++)
prev[i] = array[i*pitch];
for (int idxOut = 0; idxOut < size; idxOut++)
{
BFComplex val;
for (int idxIn = 0; idxIn < size; idxIn++)
val += prev[idxIn] * BFComplex::Polar(1.0, aDir * 2 * BF_PI_D * idxIn * idxOut / (double) size);
if (aDir == 1)
val = val * BFComplex(1.0/size);
array[idxOut*pitch] = val;
}
}
void DFTTest_Mine()
{
BFComplex test[] =
{ 1.0, 2.0, 3.0, 4.0,
5.0, 6.0, 7.0, 8.0,
9.0, 10.0, 11.0, 12.0,
13.0, 14.0, 15.0, 16.0};
int aCols = 4;
int aRows = 4;
/*std::vector<BFComplex> outR;
for (int row = 0; row < aRows; row++)
{
for (int colOut = 0; colOut < aCols; colOut++)
{
BFComplex val;
for (int colIn = 0; colIn < aCols; colIn++)
val += test[row*aCols+colIn] * BFComplex::Polar(1.0, - 2 * BF_PI_D * colIn * colOut / (double) aCols);
outR.push_back(val);
}
}
PrintComplex2D(&outR.front(), aCols, aRows);
std::vector<BFComplex> outC;
outC.insert(outC.begin(), aCols*aRows, BFComplex());
for (int col = 0; col < aCols; col++)
{
for (int rowOut = 0; rowOut < aRows; rowOut++)
{
BFComplex val;
for (int rowIn = 0; rowIn < aRows; rowIn++)
val += outR[rowIn*aCols+col] * BFComplex::Polar(1.0, - 2 * BF_PI_D * rowIn * rowOut / (double) aRows);
//outC.push_back(val);
outC[rowOut*aCols+col] = val;
}
}*/
for (int col = 0; col < aCols; col++)
FFD_1D(test + col, aRows, aCols, -1);
PrintComplex2D(test, aRows, aCols);
for (int row = 0; row < aRows; row++)
FFD_1D(test + row*aCols, aCols, 1, -1);
PrintComplex2D(test, aRows, aCols);
/*std::vector<BFComplex> outC;
outC.insert(outC.begin(), aRows*aCols, BFComplex());
for (int col = 0; col < aCols; col++)
{
for (int rowOut = 0; rowOut < aRows; rowOut++)
{
BFComplex val;
for (int rowIn = 0; rowIn < aRows; rowIn++)
val += test[rowIn*aCols+col] * BFComplex::Polar(1.0, - 2 * BF_PI_D * rowIn * rowOut / (double) aRows);
outC[rowOut*aCols+col] = val;
}
}
PrintComplex2D(&outC.front(), aRows, aCols);
std::vector<BFComplex> outR;
outR.insert(outR.begin(), aRows*aCols, BFComplex());
for (int row = 0; row < aRows; row++)
{
for (int colOut = 0; colOut < aCols; colOut++)
{
BFComplex val;
for (int colIn = 0; colIn < aCols; colIn++)
val += outC[row*aCols+colIn] * BFComplex::Polar(1.0, - 2 * BF_PI_D * colIn * colOut / (double) aCols);
//outC.push_back(val);
outR[row*aCols+colOut] = val;
}
}
PrintComplex2D(&outR.front(), aRows, aCols);*/
/*int N = sizeof(test) / sizeof(test[0]);
std::vector<BFComplex> out;
std::vector<BFComplex> invOut;
BFComplex _a = BFComplex::Polar(1.0, 0.5f) * BFComplex::Polar(1.0, 2.01f);
for (int k = 0; k < N; k++)
{
BFComplex val;
for (int n = 0; n < N; n++)
val += test[n] * BFComplex::Polar(1.0, - 2 * BF_PI_D * k * n / (double) N);
out.push_back(val);
}
for (int n = 0; n < N; n++)
{
BFComplex val;
for (int k = 0; k < N; k++)
val += out[k] * BFComplex::Polar(1.0, 2 * BF_PI_D * k * n / (double) N);
invOut.push_back(BFComplex(1.0/N) * val);
}*/
}
void FFTShift1D(BFComplex* array, int size, int pitch, int dir)
{
BFComplex* prev = new BFComplex[size];
for (int i = 0; i < size; i++)
prev[i] = array[i * pitch];
while (dir < 0)
dir += size;
for (int i = 0; i < size; i++)
array[i * pitch] = prev[((i + dir) % size)];
delete prev;
}
static void FFTShift2D(BFComplex* data, int cols, int rows)
{
for (int col = 0; col < cols; col++)
FFTShift1D(data + col, rows, cols, cols / 2);
for (int row = 0; row < rows; row++)
FFTShift1D(data + row*cols, cols, 1, rows / 2);
}
static void FFTConvert(ImageData* source)
{
int aCols = source->mWidth;
int aRows = source->mHeight;
int count = aCols * aRows;
BFComplex* nums = new BFComplex[count];
for (int i = 0; i < count; i++)
{
PackedColor& color = *((PackedColor*) &source->mBits[i]);
nums[i].mR = PackedColorGetGray()(color);
}
//FFT
for (int col = 0; col < aCols; col++)
FFD_1D(nums + col, aRows, aCols, -1);
for (int row = 0; row < aRows; row++)
FFD_1D(nums + row*aCols, aCols, 1, -1);
//INV FFT
/*for (int col = 0; col < aCols; col++)
FFD_1D(nums + col, aRows, aCols, 1);
for (int row = 0; row < aRows; row++)
FFD_1D(nums + row*aCols, aCols, 1, 1);*/
FFTShift2D(nums, aCols, aRows);
double* fFTLog = new double[count];
double maxLog = 0;
for (int i = 0; i < count; i++)
{
double aLog = log(1 + nums[i].Magnitude());
maxLog = std::max(maxLog, aLog);
fFTLog[i] = aLog;
}
for (int i = 0; i < count; i++)
{
//int val = (int) nums[i].Magnitude() / 1;
int val = (int) (fFTLog[i] * 255 / maxLog);
val = std::min(255, std::max(0, val));
source->mBits[i] = 0xFF000000 | val | (val << 8) | (val << 16);
}
delete fFTLog;
delete [] nums;
}
void DCT_1D(double* array, int size, int pitch)
{
double* prev = new double[size];
for (int i = 0; i < size; i++)
prev[i] = array[i*pitch];
for (int idxOut = 0; idxOut < size; idxOut++)
{
double val = 0;
double scale = (idxOut == 0) ? 1/sqrt(2.0) : 1;
for (int idxIn = 0; idxIn < size; idxIn++)
val += prev[idxIn] * cos(idxOut * BF_PI * (2*idxIn + 1)/(2 * size));
array[idxOut*pitch] = 0.5 * scale * val;
}
delete prev;
}
void IDCT_1D(double* array, int size, int pitch)
{
double* prev = new double[size];
for (int i = 0; i < size; i++)
prev[i] = array[i*pitch];
for (int idxOut = 0; idxOut < size; idxOut++)
{
double val = 0;
for (int idxIn = 0; idxIn < size; idxIn++)
{
double scale = (idxIn == 0) ? 1/sqrt(2.0) : 1;
val += scale * prev[idxIn] * cos(idxIn * BF_PI * (2*idxOut + 1)/(2 * size));
}
array[idxOut*pitch] = 0.5 * val;
}
delete prev;
}
const int DCT_1D_I_TABLE[64] =
{
4096, 4096, 4096, 4096, 4096, 4096, 4096, 4096,
4017, 3405, 2275, 799, -799, -2275, -3405, -4017,
3784, 1567, -1567, -3784, -3784, -1567, 1567, 3784,
3405, -799, -4017, -2275, 2275, 4017, 799, -3405,
2896, -2896, -2896, 2896, 2896, -2896, -2896, 2896,
2275, -4017, 799, 3405, -3405, -799, 4017, -2275,
1567, -3784, 3784, -1567, -1567, 3784, -3784, 1567,
799, -2275, 3405, -4017, 4017, -3405, 2275, -799
};
void DCT_1D_I(int* array, int size, int pitch)
{
int* prev = new int[size];
for (int i = 0; i < size; i++)
prev[i] = array[i*pitch];
int multIdx = 0;
for (int idxOut = 0; idxOut < size; idxOut++)
{
int val = 0;
for (int idxIn = 0; idxIn < size; idxIn++)
val += prev[idxIn] * DCT_1D_I_TABLE[multIdx++];
if (idxOut == 0)
array[idxOut*pitch] = val / 0x2d41;
else
array[idxOut*pitch] = val / 0x2000;
}
delete prev;
}
const int IDCT_1D_I_TABLE[64] =
{
2896, 4017, 3784, 3405, 2896, 2275, 1567, 799,
2896, 3405, 1567, -799, -2896, -4017, -3784, -2275,
2896, 2275, -1567, -4017, -2896, 799, 3784, 3405,
2896, 799, -3784, -2275, 2896, 3405, -1567, -4017,
2896, -799, -3784, 2275, 2896, -3405, -1567, 4017,
2896, -2275, -1567, 4017, -2896, -799, 3784, -3405,
2896, -3405, 1567, 799, -2896, 4017, -3784, 2275,
2896, -4017, 3784, -3405, 2896, -2275, 1567, -799
};
void IDCT_1D_I(int* array, int size, int pitch)
{
int prev[64];
for (int i = 0; i < size; i++)
prev[i] = array[i*pitch];
int multIdx = 0;
for (int idxOut = 0; idxOut < size; idxOut++)
{
int val = 0;
for (int idxIn = 0; idxIn < size; idxIn++)
val += prev[idxIn] * IDCT_1D_I_TABLE[multIdx++];
array[idxOut*pitch] = val / 0x2000;
}
}
void BFIData::Compress(ImageData* source)
{
/*DFTTest();
DFTTest_2D();
DFTTest_Mine();*/
//FFTConvert(source);
/*const int rowCount = 3;
const int colCount = 4;
double mat[rowCount][colCount] = {{2, 2, 5, 5}, {4, 4, 10, 11}, {3, 2, 6, 4}};
double rightVals[rowCount] = {1, 2, 3};
int pivotIdx[colCount] = {-1, -1, -1, -1};
int moveIdx = 0;
double pivotVals[colCount] = {0};
for (int pivot = 0; pivot < colCount; pivot++)
{
bool moved = false;
for (int eq = moveIdx; eq < rowCount; eq++)
{
if (!IS_ZERO(mat[eq][pivot]))
{
pivotVals[pivot] = mat[eq][pivot];
for (int swapIdx = 0; swapIdx < colCount; swapIdx++)
std::swap(mat[eq][swapIdx], mat[moveIdx][swapIdx]);
std::swap(rightVals[eq], rightVals[moveIdx]);
pivotIdx[pivot] = moveIdx;
moved = true;
break;
}
}
if (!moved)
continue;
for (int eq = moveIdx + 1; eq < rowCount; eq++)
{
double multFactor = -mat[eq][pivot] / mat[moveIdx][pivot];
bool nonZero = false;
for (int multIdx = pivot; multIdx < colCount; multIdx++)
{
mat[eq][multIdx] += mat[moveIdx][multIdx]*multFactor;
nonZero |= !IS_ZERO(mat[eq][multIdx]);
}
rightVals[eq] += rightVals[moveIdx]*multFactor;
BF_ASSERT(IS_ZERO(rightVals[eq]) || (nonZero));
}
moveIdx++;
}
// Back substitute
double result[colCount];
for (int col = colCount - 1; col >= 0; col--)
{
result[col] = 0;
if (pivotIdx[col] != -1)
{
int eq = pivotIdx[col];
double left = 0;
for (int multCol = col + 1; multCol < colCount; multCol++)
left += mat[eq][multCol] * result[multCol];
double right = rightVals[eq] - left;
right /= mat[eq][col];
result[col] = right;
}
}
///*/
uint8 rawData[64] = {
52, 55, 61, 66, 70, 61, 64, 73,
63, 59, 55, 90,109, 85, 69, 72,
62, 59, 68,113,144,104, 66, 73,
63, 58, 71,122,154,106, 70, 69,
67, 61, 68,104,126, 88, 68, 70,
79, 65, 60, 70, 77, 68, 58, 75,
85, 71, 64, 59, 55, 61, 65, 83,
87, 79, 69, 68, 65, 76, 78, 94};
double dCTIn[64];
for (int i = 0; i < 64; i++)
dCTIn[i] = (int) rawData[i] - 128;
//double dCTOut[64];
/*for (int v = 0; v < 8; v++)
{
for (int u = 0; u < 8; u++)
{
dCTOut[u+v*8] = 0;
for (int y = 0; y < 8; y++)
{
for (int x = 0; x < 8; x++)
{
double au = (u == 0) ? sqrt(1.0/8.0) : sqrt(2.0/8.0);
double av = (v == 0) ? sqrt(1.0/8.0) : sqrt(2.0/8.0);
dCTOut[u+v*8] += au*av*dCTIn[x+y*8]*
cos(BF_PI_D/8 * (x + 0.5)*u) *
cos(BF_PI_D/8 * (y + 0.5)*v);
}
}
}
}*/
double dCT[64];
for (int i = 0; i < 64; i++)
dCT[i] = rawData[i] - 128;
int aCols = 8;
int aRows = 8;
for (int col = 0; col < aCols; col++)
DCT_1D(dCT + col, aRows, aCols);
for (int row = 0; row < aRows; row++)
DCT_1D(dCT + row*aCols, aCols, 1);
for (int col = 0; col < aCols; col++)
IDCT_1D(dCT + col, aRows, aCols);
for (int row = 0; row < aRows; row++)
IDCT_1D(dCT + row*aCols, aCols, 1);
//
int dCT_I[64];
for (int i = 0; i < 64; i++)
dCT_I[i] = (rawData[i] - 128) * 256;
for (int col = 0; col < aCols; col++)
DCT_1D_I(dCT_I + col, aRows, aCols);
for (int row = 0; row < aRows; row++)
DCT_1D_I(dCT_I + row*aCols, aCols, 1);
for (int col = 0; col < aCols; col++)
IDCT_1D_I(dCT_I + col, aRows, aCols);
for (int row = 0; row < aRows; row++)
IDCT_1D_I(dCT_I + row*aCols, aCols, 1);
for (int i = 0; i < 64; i++)
{
int val = dCT_I[i];
if (val < 0)
dCT_I[i] = (val - 128) / 256;
else
dCT_I[i] = (val + 128) / 256;
}
///
int quantTable[] = {16, 11, 11, 16, 23, 27, 31, 30, 11, 12, 12, 15, 20, 23, 23, 30,
11, 12, 13, 16, 23, 26, 35, 47, 16, 15, 16, 23, 26, 37, 47, 64,
23, 20, 23, 26, 39, 51, 64, 64, 27, 23, 26, 37, 51, 64, 64, 64,
31, 23, 35, 47, 64, 64, 64, 64, 30, 30, 47, 64, 64, 64, 64, 64};
int quantDCT[64];
for (int i = 0; i < 64; i++)
quantDCT[i] = (int) BFRound((float) (dCT[i] / quantTable[i]));
int zigZag[64] = {
0, 1, 5, 6, 14, 15, 27, 28,
2, 4, 7, 13, 16, 26, 29, 42,
3, 8, 12, 17, 25, 30, 41, 43,
9, 11, 18, 24, 31, 40, 44, 53,
10, 19, 23, 32, 39, 45, 52, 54,
20, 22, 33, 38, 46, 51, 55, 60,
21, 34, 37, 47, 50, 56, 59, 61,
35, 36, 48, 49, 57, 58, 62, 63
};
int zigZagDCT[64];
for (int i = 0; i < 64; i++)
{
zigZagDCT[i] = quantDCT[zigZag[i]];
}
/*double dCTOutH[64];
double dCTOutV[64];
for (int v = 0; v < 8; v++)
{
for (int u = 0; u < 8; u++)
{
dCTOutV[u+v*8] = 0;
for (int y = 0; y < 8; y++)
{
double av = (v == 0) ? sqrt(1.0/8.0) : sqrt(2.0/8.0);
dCTOutV[u+v*8] += av*dCTIn[u+y*8]*
cos(BF_PI_D/8 * (y + 0.5)*v);
}
}
}
for (int v = 0; v < 8; v++)
{
for (int u = 0; u < 8; u++)
{
dCTOutH[u+v*8] = 0;
for (int x = 0; x < 8; x++)
{
double au = (u == 0) ? sqrt(1.0/8.0) : sqrt(2.0/8.0);
dCTOutH[u+v*8] += au*dCTOutV[x+v*8]*
cos(BF_PI_D/8 * (x + 0.5)*u);
}
//dCTOut[u+v*8] = val;
}
}*/
}

14
BeefySysLib/img/BFIData.h Normal file
View file

@ -0,0 +1,14 @@
#pragma once
#include "Common.h"
#include "ImageData.h"
NS_BF_BEGIN;
class BFIData : ImageData
{
public:
void Compress(ImageData* source);
};
NS_BF_END;

View file

@ -0,0 +1,76 @@
#include "ImageAdjustments.h"
#include "ImageData.h"
#include "PSDReader.h"
#include "ImageUtils.h"
#include "ImgEffects.h"
USING_NS_BF;
ImageAdjustment::~ImageAdjustment()
{
}
void ImageAdjustment::ApplyImageAdjustment(PSDLayerInfo* layerInfo, ImageData* image)
{
}
ImageData* ImageAdjustment::CreateAdjustedImage(PSDLayerInfo* layerInfo, ImageData* destImage)
{
ImageData* newImage = destImage->Duplicate();
ApplyImageAdjustment(layerInfo, newImage);
CrossfadeImage(destImage, newImage, layerInfo->mFillOpacity / 255.0f);
return newImage;
}
void InvertImageAdjustement::ApplyImageAdjustment(PSDLayerInfo* layerInfo, ImageData* image)
{
int size = image->mWidth*image->mHeight;
for (int i = 0; i < size; i++)
{
image->mBits[i] =
(image->mBits[i] & 0xFF000000) |
((0xFFFFFFFF - image->mBits[i]) & 0x00FFFFFF);
}
}
void SolidColorImageAdjustement::ApplyImageAdjustment(PSDLayerInfo* layerInfo, ImageData* image)
{
int size = image->mWidth*image->mHeight;
for (int i = 0; i < size; i++)
image->mBits[i] = mColor;
}
GradientImageAdjustement::~GradientImageAdjustement()
{
delete mFill;
}
void GradientImageAdjustement::ApplyImageAdjustment(PSDLayerInfo* layerInfo, ImageData* image)
{
mFill->Apply(layerInfo, image, image);
}
PatternImageAdjustement::~PatternImageAdjustement()
{
delete mFill;
}
void PatternImageAdjustement::ApplyImageAdjustment(PSDLayerInfo* layerInfo, ImageData* image)
{
mFill->Apply(layerInfo, image, image);
}
void BrightnessContrastImageAdjustment::ApplyImageAdjustment(PSDLayerInfo* layerInfo, ImageData* image)
{
int size = image->mWidth*image->mHeight;
for (int i = 0; i < size; i++)
{
PackedColor* color = (PackedColor*) (&image->mBits[i]);
//int effect = 256 - (int) (pow(abs(color->r - mMeanValue)/127.0, 2.0)*127);
//color->r = BFClamp(color->r + effect*mBrightness/256, 0, 255);
color->r = (int) (pow(color->r / 255.0f, 1.0f - mBrightness/200.0f) * 255);
image->mBits[i] = *((uint32*) color);
}
}

View file

@ -0,0 +1,70 @@
#pragma once
#include "Common.h"
NS_BF_BEGIN;
class ImageData;
class PSDLayerInfo;
class ImageGradientFill;
class ImagePatternFill;
class ImageAdjustment
{
public:
~ImageAdjustment();
virtual ImageData* CreateAdjustedImage(PSDLayerInfo* layerInfo, ImageData* destImage);
virtual void ApplyImageAdjustment(PSDLayerInfo* layerInfo, ImageData* image);
};
class InvertImageAdjustement : public ImageAdjustment
{
public:
virtual void ApplyImageAdjustment(PSDLayerInfo* layerInfo, ImageData* image);
};
class SolidColorImageAdjustement : public ImageAdjustment
{
public:
uint32 mColor;
public:
virtual void ApplyImageAdjustment(PSDLayerInfo* layerInfo, ImageData* image);
};
class GradientImageAdjustement : public ImageAdjustment
{
public:
ImageGradientFill* mFill;
public:
~GradientImageAdjustement();
virtual void ApplyImageAdjustment(PSDLayerInfo* layerInfo, ImageData* image);
};
class PatternImageAdjustement : public ImageAdjustment
{
public:
ImagePatternFill* mFill;
public:
~PatternImageAdjustement();
virtual void ApplyImageAdjustment(PSDLayerInfo* layerInfo, ImageData* image);
};
class BrightnessContrastImageAdjustment : public ImageAdjustment
{
public:
int mBrightness;
int mContrast;
int mMeanValue;
bool mLabColorOnly;
public:
virtual void ApplyImageAdjustment(PSDLayerInfo* layerInfo, ImageData* image);
};
NS_BF_END;

View file

@ -0,0 +1,129 @@
#include "ImageData.h"
#include "ImageUtils.h"
USING_NS_BF;
ImageData::ImageData()
{
mSrcData = NULL;
mOwnsSrcData = false;
mKeepSrcDataValid = false;
mBits = NULL;
mHWBitsType = 0;
mHWBitsLength = 0;
mHWBits = NULL;
mX = 0;
mY = 0;
mWidth = 0;
mHeight = 0;
mWantsAlphaPremultiplied = true;
mAlphaPremultiplied = false;
mIsAdditive = false;
mSrcDataLen = 0;
}
ImageData::~ImageData()
{
delete [] mBits;
delete [] mSrcData;
}
void ImageData::SwapRAndB()
{
int aSize = mWidth*mHeight;
uint32* aPtr = mBits;
for (int i = 0; i < aSize; i++)
{
uint32 aColor = *aPtr;
int a = (aColor & 0xFF000000) >> 24;
int r = (aColor & 0x00FF0000) >> 16;
int g = (aColor & 0x0000FF00) >> 8;
int b = (aColor & 0x000000FF);
*(aPtr++) = (a << 24) | (b << 16) | (g << 8) | r;
}
}
void ImageData::CreateNew(int x, int y, int width, int height, bool clear)
{
CreateNew(width, height, clear);
mX = x;
mY = y;
}
void ImageData::CreateNew(int width, int height, bool clear)
{
mWidth = width;
mHeight = height;
mBits = new uint32[mWidth*mHeight];
if (clear)
memset(mBits, 0, mWidth*mHeight*sizeof(uint32));
}
void ImageData::Fill(uint32 color)
{
int size = mWidth*mHeight;
for (int i = 0; i < size; i++)
mBits[i] = color;
}
ImageData* ImageData::Duplicate()
{
ImageData* copy = new ImageData();
copy->CreateNew(mWidth, mHeight);
copy->mX = mX;
copy->mY = mY;
copy->mAlphaPremultiplied = mAlphaPremultiplied;
copy->mIsAdditive = mIsAdditive;
memcpy(copy->mBits, mBits, mWidth*mHeight*sizeof(uint32));
return copy;
}
bool ImageData::LoadFromFile(const StringImpl& path)
{
int size = 0;
uint8* aData = LoadBinaryData(path, &size);
if (aData == NULL)
return NULL;
SetSrcData(aData, size);
bool result = ReadData();
if (mKeepSrcDataValid)
{
mOwnsSrcData = true;
}
else
{
delete [] mSrcData;
mSrcData = NULL;
}
return result;
}
void ImageData::SetSrcData(uint8* data, int dataLen)
{
mSrcData = data;
mSrcDataLen = dataLen;
}
void ImageData::PremultiplyAlpha()
{
if (mBits == NULL)
return;
if (!mAlphaPremultiplied)
{
mAlphaPremultiplied = true;
int size = mWidth*mHeight;
for (int i = 0; i < size; i++)
{
PackedColor* packedColor = (PackedColor*) (mBits + i);
packedColor->r = (packedColor->r * packedColor->a) / 255;
packedColor->g = (packedColor->g * packedColor->a) / 255;
packedColor->b = (packedColor->b * packedColor->a) / 255;
if (mIsAdditive)
packedColor->a = 0;
}
}
}

View file

@ -0,0 +1,50 @@
#pragma once
#include "../Common.h"
NS_BF_BEGIN;
enum
{
HWBITS_UNKNOWN,
HWBITS_PVRTC_2BPPV1,
HWBITS_PVRTC_4BPPV1,
HWBITS_PVRTC_2X4BPPV1
};
class ImageData
{
public:
int mX;
int mY;
int mWidth;
int mHeight;
void* mHWBits;
int mHWBitsLength;
int mHWBitsType;
uint32* mBits;
uint8* mSrcData;
int mSrcDataLen;
bool mKeepSrcDataValid;
bool mOwnsSrcData;
bool mWantsAlphaPremultiplied;
bool mAlphaPremultiplied;
bool mIsAdditive;
public:
ImageData();
virtual ~ImageData();
void SwapRAndB();
void CreateNew(int x, int y, int width, int height, bool clear = true);
void CreateNew(int width, int height, bool clear = true);
void Fill(uint32 color);
virtual ImageData* Duplicate();
void SetSrcData(uint8* data, int dataLen);
virtual bool LoadFromFile(const StringImpl& path);
virtual bool ReadData() { return false; }
virtual void PremultiplyAlpha();
};
NS_BF_END;

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,51 @@
#pragma once
#include "Common.h"
NS_BF_BEGIN;
class ImageData;
struct PackedColor
{
uint8 r;
uint8 g;
uint8 b;
uint8 a;
};
class PackedColorGetR
{
public:
int operator()(PackedColor color) { return color.r; }
};
class PackedColorGetG
{
public:
int operator()(PackedColor color) { return color.g; }
};
class PackedColorGetB
{
public:
int operator()(PackedColor color) { return color.b; }
};
class PackedColorGetGray
{
public:
int operator()(PackedColor color) { return ((color.r * 300) + (color.g * 586) + (color.b * 113)) / 1000; }
};
ImageData* CreateResizedImageUnion(ImageData* src, int x, int y, int width, int height);
ImageData* CreateEmptyResizedImageUnion(ImageData* src, int x, int y, int width, int height);
void CrossfadeImage(ImageData* origImage, ImageData* newImage, float opacity);
void BlendImage(ImageData* dest, ImageData* src, int destX, int destY, float alpha = 1.0f, int mixType = 'Nrml', bool fullAlpha = false);
void BlendImagesTogether(ImageData* bottomImage, ImageData* topImage, ImageData* alphaImage);
void SetImageAlpha(ImageData* image, ImageData* alphaImage);
void MultiplyImageAlpha(ImageData* image, ImageData* alphaImage);
void SetImageAlpha(ImageData* image, int alpha);
void CopyImageBits(ImageData* dest, ImageData* src);
NS_BF_END;

File diff suppressed because it is too large Load diff

View file

@ -0,0 +1,376 @@
#pragma once
#include "Common.h"
#include "util/Point.h"
#include "util/CubicFuncSpline.h"
#include "ImageUtils.h"
NS_BF_BEGIN;
class ImageData;
class ImageEffectCtx;
enum MixType
{
IMAGEMIX_INNER,
IMAGEMIX_OUTER,
IMAGEMIX_OVER
};
class ImageCurvePoint
{
public:
float mX;
float mY;
CubicFuncSpline* mSpline;
bool mIsSplineOwner;
bool mIsCorner;
public:
ImageCurvePoint();
~ImageCurvePoint();
};
typedef std::vector<ImageCurvePoint> ImageCurvePointVector;
class ImageCurve
{
public:
String mInterpType;
ImageCurvePointVector mPoints;
bool mInitialized;
public:
void Init();
float GetVal(float x);
bool IsDefault();
};
class ImageGradientPoint
{
public:
float mX;
int mValue;
};
typedef std::vector<ImageGradientPoint> ImageGradientPointVector;
class ImageGradient
{
public:
String mInterpType;
ImageGradientPointVector mPoints;
CubicUnitFuncSpline mSpline;
float mSmoothness; // 0.0 - 1.0
int mXSize;
public:
int GetVal(float x);
};
///
const int CONTOUR_DATA_SIZE = 4096;
const int GRADIENT_DATA_SIZE = 4096;
class PSDLayerInfo;
class ImageStrokeEffect;
class ImageEffects;
class BaseImageEffect
{
public:
double mOpacity;
int32 mBlendMode;
uint16* mContourData;
uint32* mGradientData;
bool mInitialized;
public:
BaseImageEffect();
virtual ~BaseImageEffect();
virtual void Init();
virtual void Apply(PSDLayerInfo* layerInfo, ImageData* imageData, ImageData* destImageData) = 0;
virtual void Apply(ImageEffectCtx* ctx);
virtual int GetMixType(); // Default:Interior
virtual int GetNeededBorderSize();
virtual bool NeedsOrigBits(ImageEffects* effects);
};
class ImageShadowEffect :public BaseImageEffect
{
public:
uint32 mColor;
bool mUseGlobalLight;
double mLocalAngle;
double mDistance;
double mSpread; // Also 'Choke'
double mSize;
ImageCurve mContour;
bool mAntiAliased;
double mNoise;
public:
virtual void Init();
virtual void Apply(PSDLayerInfo* layerInfo, ImageData* imageData, ImageData* destImageData);
virtual int GetNeededBorderSize();
};
class ImageDropShadowEffect : public ImageShadowEffect
{
public:
bool mLayerKnocksOut;
public:
virtual int GetMixType() override;
};
class ImageInnerShadowEffect : public ImageShadowEffect
{
public:
bool mLayerKnocksOut;
};
class ImageGlowEffect : public BaseImageEffect
{
public:
ImageGradient mColorGradient[4];
bool mHasGradient;
double mNoise;
int32 mTechnique; // 'SfBL' or 'PrBL'
double mSize;
ImageCurve mContour;
double mRange;
double mJitter;
bool mAntiAliased;
public:
virtual void Init() override;
virtual void CreateContourAndGradientData();
virtual int GetNeededBorderSize();
};
class ImageOuterGlowEffect : public ImageGlowEffect
{
public:
double mSpread;
public:
void Apply(PSDLayerInfo* layerInfo, ImageData* imageData, ImageData* destImageData) override;
virtual int GetMixType() override;
};
class ImageInnerGlowEffect : public ImageGlowEffect
{
public:
double mChoke;
bool mIsCenter; // Otherwise 'Edge'
public:
void Apply(PSDLayerInfo* layerInfo, ImageData* imageData, ImageData* destImageData) override;
};
class ImageFill
{
public:
virtual ~ImageFill() {}
virtual void Apply(PSDLayerInfo* layerInfo, ImageData* imageData, ImageData* destImageData) = 0;
};
class ImageColorFill : public ImageFill
{
public:
uint32 mColor;
public:
virtual void Apply(PSDLayerInfo* layerInfo, ImageData* imageData, ImageData* destImageData);
};
class ImagePatternFill : public ImageFill
{
public:
double mPhaseX;
double mPhaseY;
bool mLinkWithLayer;
double mScale;
String mPatternName;
public:
void Apply(PSDLayerInfo* layerInfo, ImageData* imageData, ImageData* destImageData);
};
class ImageGradientFill : public ImageFill
{
public:
ImageGradient mColorGradient[4];
uint32* mGradientData;
int mStyle; // 'Lnr ',
bool mReverse;
bool mAlignWithLayer;
double mOffsetX;
double mOffsetY;
double mAngle;
double mScale;
public:
ImageGradientFill();
~ImageGradientFill();
void Apply(PSDLayerInfo* layerInfo, ImageData* imageData, ImageData* destImageData);
};
class ImageBevelEffect : public BaseImageEffect
{
public:
int32 mStyle; // 'InrB'=Inner Bevel, 'OtrB'=Outer Bevel
int32 mTechnique; // 'SfBL'=Smooth, 'PrBL'=Chisel Hard, 'Slmt'=Chisel Soft
double mDepth;
bool mDirectionUp;
double mSize;
double mSoften;
double mLocalAngle;
bool mUseGlobalLight;
double mLocalAltitude;
ImageCurve mGlossContour;
bool mAntiAliased;
int32 mHiliteMode;
uint32 mHiliteColor;
double mHiliteOpacity;
int32 mShadowMode;
uint32 mShadowColor;
double mShadowOpacity;
bool mUseContour;
ImageCurve mBevelContour;
int32* mBevelContourData;
double mBevelContourRange;
bool mUseTexture;
ImagePatternFill mTexture;
double mTextureDepth;
bool mTextureInvert;
uint16* mGlossContourData;
public:
ImageBevelEffect();
~ImageBevelEffect();
void Init() override;
void Apply(PSDLayerInfo* layerInfo, ImageData* imageData, ImageData* destImageData) override;
virtual void Apply(ImageEffectCtx* ctx) override;
virtual int GetMixType();
void Apply(int pass, int style, PSDLayerInfo* layerInfo, ImageData* imageData, ImageData* hiliteImage, ImageData* shadowImage);
virtual int GetNeededBorderSize();
};
typedef std::vector<BaseImageEffect*> ImageEffectVector;
class ImageSatinEffect : public BaseImageEffect
{
public:
uint32 mColor;
double mAngle;
double mDistance;
double mSize;
ImageCurve mContour;
bool mAntiAliased;
bool mInvert;
public:
virtual void Init();
virtual void Apply(PSDLayerInfo* layerInfo, ImageData* imageData, ImageData* destImageData) override;
virtual int GetMixType(); // Default:Interior
virtual int GetNeededBorderSize();
};
class ImageColorOverlayEffect : public BaseImageEffect
{
public:
ImageColorFill mColorFill;
public:
virtual void Apply(PSDLayerInfo* layerInfo, ImageData* imageData, ImageData* destImageData) override;
};
class ImageGradientOverlayEffect : public BaseImageEffect
{
public:
ImageGradientFill mGradientFill;
public:
virtual void Apply(PSDLayerInfo* layerInfo, ImageData* imageData, ImageData* destImageData) override;
};
class ImagePatternOverlayEffect : public BaseImageEffect
{
public:
ImagePatternFill mPattern;
public:
virtual void Apply(PSDLayerInfo* layerInfo, ImageData* imageData, ImageData* destImageData) override;
};
class ImageStrokeEffect : public BaseImageEffect
{
public:
double mSize;
int mPosition;
int32 mFillType;
ImageGradientFill mGradientFill;
ImageColorFill mColorFill;
ImagePatternFill mPatternFill;
public:
virtual void Apply(PSDLayerInfo* layerInfo, ImageData* imageData, ImageData* destImageData) override;
virtual void Apply(ImageEffectCtx* ctx) override;
virtual int GetMixType(); // Default:Interior
virtual int GetNeededBorderSize();
virtual bool NeedsOrigBits(ImageEffects* effects) override;
};
///
class ImageEffectCtx
{
public:
int mBlendX;
int mBlendY;
int mBlendWidth;
int mBlendHeight;
PSDLayerInfo* mLayerInfo;
ImageData* mLayerImage;
ImageData* mInnerImage;
ImageData* mOuterImage;
ImageData* mOrigImage;
};
class ImageEffects
{
public:
ImageEffectVector mImageEffectVector;
ImageData* mSwapImages[2];
public:
ImageData* GetDestImage(ImageData* usingImage);
public:
ImageEffects();
~ImageEffects();
ImageData* FlattenInto(ImageData* dest, PSDLayerInfo* srcLayer, ImageData* srcImage, ImageData* knockoutBottom, ImageData* insideImage);
void AddEffect(BaseImageEffect* effect);
};
NS_BF_END;

View file

@ -0,0 +1,208 @@
#define XMD_H
#include "JPEGData.h"
#include "MemStream.h"
#include "ImageUtils.h"
#include <setjmp.h>
extern "C"
{
#include "jpeg/jpeglib.h"
#include "jpeg/jerror.h"
#include "jpeg/jpegint.h"
}
USING_NS_BF;
// -----------------------------------------------------------------------
// JPEG error handling
// Will "longjmp" on error_exit.
// -----------------------------------------------------------------------
struct ErrorHandler
{
/** "subclass" of jpeg_error_mgr */
struct jpeg_error_mgr errorMgr;
jmp_buf setjmpBuffer;
ErrorHandler( j_decompress_ptr cinfo )
{
Init( (j_common_ptr)cinfo );
}
ErrorHandler( j_compress_ptr cinfo )
{
Init( (j_common_ptr)cinfo );
}
void Init( j_common_ptr cinfo )
{
// setup the standard error handling.
cinfo->err = jpeg_std_error( &errorMgr );
// then hook up our error_exit function.
errorMgr.error_exit = &ErrorHandler::OnErrorExit;
}
static void OnErrorExit( j_common_ptr cinfo )
{
// recover the pointer to "derived class" instance
ErrorHandler* errorHandler = (ErrorHandler*)cinfo->err;
// use the default error message output.
(*cinfo->err->output_message)( cinfo );
// return control to the setjmp point.
longjmp( errorHandler->setjmpBuffer, 1 );
}
};
struct JpegMemSource
{
JpegMemSource(JPEGData* buffer, j_decompress_ptr cinfo )
{
struct jpeg_source_mgr * src;
if ( cinfo->src == NULL )
{
// Have the jpeg library allocate the source manager object so
// that it is automatically deallocated by the decompressor.
cinfo->src = (struct jpeg_source_mgr *)(*cinfo->mem->alloc_small)( (j_common_ptr)cinfo, JPOOL_PERMANENT, sizeof(struct jpeg_source_mgr) );
}
src = cinfo->src;
src->init_source = &JpegMemSource::InitSource;
src->fill_input_buffer = &JpegMemSource::FillInputBuffer;
src->skip_input_data = &JpegMemSource::SkipInputData;
src->resync_to_restart = jpeg_resync_to_restart; /* use default method */
src->term_source = &JpegMemSource::TermSource;
src->bytes_in_buffer = (size_t) buffer->mSrcDataLen;
src->next_input_byte = (JOCTET *) buffer->mSrcData;
}
~JpegMemSource()
{
// The setjmp/longjmp action in ErrorHandler can actually
// completely skip the destruction of this C++ data source wrapper,
// but that is OK so long as there is no actual cleanup to do.
}
static void InitSource( j_decompress_ptr cinfo )
{
/* no work necessary here */
}
static boolean FillInputBuffer( j_decompress_ptr cinfo )
{
static JOCTET mybuffer[4];
/* The whole JPEG data is expected to reside in the supplied memory
* buffer, so any request for more data beyond the given buffer size
* is treated as an error.
*/
WARNMS(cinfo, JWRN_JPEG_EOF);
/* Insert a fake EOI marker */
mybuffer[0] = (JOCTET) 0xFF;
mybuffer[1] = (JOCTET) JPEG_EOI;
cinfo->src->next_input_byte = mybuffer;
cinfo->src->bytes_in_buffer = 2;
return TRUE;
}
static void SkipInputData( j_decompress_ptr cinfo, long num_bytes )
{
struct jpeg_source_mgr * src = cinfo->src;
/* Just a dumb implementation for now. Could use fseek() except
* it doesn't work on pipes. Not clear that being smart is worth
* any trouble anyway --- large skips are infrequent.
*/
if (num_bytes > 0) {
while (num_bytes > (long) src->bytes_in_buffer) {
num_bytes -= (long) src->bytes_in_buffer;
(void) (*src->fill_input_buffer) (cinfo);
/* note we assume that fill_input_buffer will never return FALSE,
* so suspension need not be handled.
*/
}
src->next_input_byte += (size_t) num_bytes;
src->bytes_in_buffer -= (size_t) num_bytes;
}
}
static void TermSource( j_decompress_ptr cinfo )
{
/* no work necessary here */
}
};
bool JPEGData::ReadData()
{
jpeg_decompress_struct cinfo;
ErrorHandler err( &cinfo );
if ( setjmp( err.setjmpBuffer ) )
{
// ErrorHandler::OnErrorExit will longjmp back to here from
// within the ReadImage call below.
jpeg_destroy_decompress( &cinfo );
return false;
}
jpeg_create_decompress( &cinfo );
JpegMemSource(this, &cinfo );
jpeg_read_header( &cinfo, TRUE );
jpeg_start_decompress( &cinfo );
mWidth = cinfo.output_width;
mHeight = cinfo.output_height;
mBits = new uint32[ mWidth * mHeight ];
uint32* destPtr = mBits;
// Have the jpeg library allocate a scan-line buffer as a
// per-image resource so that it will be automatically deallocated
// by jpeg_finish_decompress.
int row_stride = cinfo.output_width * cinfo.output_components;
unsigned char** scanline = (*cinfo.mem->alloc_sarray)( (j_common_ptr)&cinfo, JPOOL_IMAGE, row_stride, 1 );
if ( cinfo.output_components == 1 )
{
while ( cinfo.output_scanline < cinfo.output_height )
{
jpeg_read_scanlines( &cinfo, scanline, 1 );
uint8* p = *scanline;
for ( JDIMENSION i = 0; i < cinfo.output_width; ++i )
{
int r = *p++;
*destPtr++ = 0xFF000000 | (r << 16) | (r << 8) | (r);
}
}
}
else
{
while ( cinfo.output_scanline < cinfo.output_height )
{
jpeg_read_scanlines(&cinfo, scanline, 1 );
uint8* p = *scanline;
for ( JDIMENSION i = 0; i < cinfo.output_width; ++i )
{
int r = *p++;
int g = *p++;
int b = *p++;
*destPtr++ = 0xFF000000 | (r << 16) | (g << 8) | (b);
}
}
}
jpeg_finish_decompress( &cinfo );
jpeg_destroy_decompress( &cinfo );
return true;
}

View file

@ -0,0 +1,18 @@
#pragma once
#include "Common.h"
#include "ImageData.h"
NS_BF_BEGIN;
class JPEGHuffmanTable;
class JPEGComponentInfo;
class JPEGDataStream;
class JPEGData : public ImageData
{
public:
bool ReadData();
};
NS_BF_END;

263
BeefySysLib/img/PNGData.cpp Normal file
View file

@ -0,0 +1,263 @@
#include "PNGData.h"
#include "third_party/png/png.h"
USING_NS_BF;
#pragma warning(disable:4996)
static void PNGError(png_structp ptr, png_const_charp err)
{
OutputDebugStrF("PNG ERROR: %s\r\n", err);
}
static void png_buffer_read_data(png_structp png_ptr, png_bytep data, png_size_t length)
{
PNGData* aData = (PNGData*)png_ptr->io_ptr;
png_size_t bytesAvailable = aData->mSrcDataLen - aData->mReadPos;
png_size_t bytesToRead = std::min( length, bytesAvailable );
memcpy(data, aData->mSrcData + aData->mReadPos, length);
aData->mReadPos += (int)length;
if ( bytesToRead != length )
{
png_error( png_ptr, "Read Error" );
}
}
PNGData::PNGData()
{
mReadPos = 0;
}
bool PNGData::ReadData()
{
mReadPos = 0;
png_uint_32 width, height;
int bit_depth, color_type, interlace_type;
png_structp png_ptr;
png_infop info_ptr;
png_ptr = png_create_read_struct( PNG_LIBPNG_VER_STRING, NULL, NULL, NULL );
if (png_ptr == NULL)
{
return false;
}
png_set_read_fn( png_ptr, (png_voidp)this, &png_buffer_read_data );
png_ptr->error_fn = PNGError;
/* Allocate/initialize the memory for image information. REQUIRED. */
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL)
{
png_destroy_read_struct(&png_ptr, (png_infopp)NULL, (png_infopp)NULL);
return false;
}
/* Set error handling if you are using the setjmp/longjmp method (this is
* the normal method of doing things with libpng). REQUIRED unless you
* set up your own error handlers in the png_create_read_struct() earlier.
*/
if (setjmp(png_ptr->jmpbuf))
{
/* Free all of the memory associated with the png_ptr and info_ptr */
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
/* If we get here, we had a problem reading the file */
return false;
}
png_read_info(png_ptr, info_ptr);
png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type,
&interlace_type, NULL, NULL);
/* Add filler (or alpha) byte (before/after each RGB triplet) */
png_set_expand(png_ptr);
#ifdef BF_PLATFORM_BIG_ENDIAN
png_set_filler(png_ptr, 0xff, PNG_FILLER_BEFORE);
png_set_swap_alpha(png_ptr);
#else
png_set_filler(png_ptr, 0xff, PNG_FILLER_AFTER);
#endif
//png_set_gray_1_2_4_to_8(png_ptr);
png_set_palette_to_rgb(png_ptr);
png_set_gray_to_rgb(png_ptr);
#ifndef PLATFORM_BIG_ENDIAN
png_set_bgr(png_ptr);
#endif
// int numBytes = png_get_rowbytes(png_ptr, info_ptr) * height / 4;
uint32* bits = new uint32[width*height];
uint32* addr = bits;
//if (info_ptr->interlace_type == PNG_INTERLACE_ADAM7)
//{
// uint32* rowData = new uint32[width + 1];
// memset(rowData, 0xBF, (width + 1) * sizeof(uint32));
// static const int passOffsets[7][3] = /* startOfs, colOfs, rowOfs */
// {
// {0, 8, 8}, // 1
// {4, 8, 8}, // 2
// {4 * width, 4, 8}, // 3
// {2, 4, 4}, // 4
// {2 * width, 2, 4}, // 5
// {1, 2, 2}, // 6
// {width, 1, 2}, // 7
// };
// for (int pass = 0; pass < 7; pass++)
// {
// uint32* bitsWriteRow = bits + passOffsets[pass][0];
// int colOfs = passOffsets[pass][1];
// int rowOfs = passOffsets[pass][2];
// int virtWidth = (width + 7) & ~7;
// int virtHeight = (height + 7) & ~7;
// int colCount = (width - (passOffsets[pass][0] % width)) / colOfs;
// int rowCount = (width * height - passOffsets[pass][0]) / (rowOfs * width);
// int skipRow = passOffsets[pass][0] / width;
// int virtRowCount = (virtHeight - skipRow) / rowOfs;
//
// for (int row = 0; row < rowCount; row++)
// {
// memset(rowData, 0xBF, (width + 1) * sizeof(uint32));
// png_read_rows(png_ptr, (png_bytepp)&rowData, NULL, 1);
// uint32* bitsRead = rowData;
// uint32* bitsWrite = bitsWriteRow;
// for (int col = 0; col < colCount; col++)
// {
// BF_ASSERT((bitsWrite < bits + width * height) && (bitsWrite >= bits));
// *bitsWrite = *(bitsRead++);
// bitsWrite += colOfs;
// }
// //BF_ASSERT(*(bitsRead - 1) != 0xCDCDCDCD);
// //BF_ASSERT(*bitsRead == 0xCDCDCDCD);
// bitsWriteRow += rowOfs * width;
// }
// /*for (int row = rowCount; row < virtRowCount; row++)
// {
// // Extra rows to ignore
// png_read_rows(png_ptr, (png_bytepp)&rowData, NULL, 1);
// }*/
// }
// delete rowData;
//}
//else
//{
// for (png_uint_32 i = 0; i < height; i++)
// {
// png_read_rows(png_ptr, (png_bytepp) &addr, NULL, 1);
// addr += width;
// }
//}
BF_ASSERT(height < 16 * 1024);
uint32* rowPtrs[16 * 1024];
for (int row = 0; row < (int)height; row++)
rowPtrs[row] = &bits[row * width];
png_read_image(png_ptr, (png_bytepp)rowPtrs);
/* read rest of file, and get additional chunks in info_ptr - REQUIRED */
png_read_end(png_ptr, info_ptr);
/* clean up after the read, and free any memory allocated - REQUIRED */
png_destroy_read_struct(&png_ptr, &info_ptr, (png_infopp)NULL);
mWidth = width;
mHeight = height;
mBits = bits;
SwapRAndB();
return true;
}
bool PNGData::WriteToFile(const StringImpl& path)
{
png_structp png_ptr;
png_infop info_ptr;
FILE *fp;
if ((fp = fopen(path.c_str(), "wb")) == NULL)
return false;
png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,
NULL, NULL, NULL);
if (png_ptr == NULL)
{
fclose(fp);
return false;
}
// Allocate/initialize the memory for image information. REQUIRED.
info_ptr = png_create_info_struct(png_ptr);
if (info_ptr == NULL)
{
fclose(fp);
png_destroy_write_struct(&png_ptr, (png_infopp) NULL);
return false;
}
// Set error handling if you are using the setjmp/longjmp method (this is
// the normal method of doing things with libpng). REQUIRED unless you
// set up your own error handlers in the png_create_write_struct() earlier.
if (setjmp(png_ptr->jmpbuf))
{
// Free all of the memory associated with the png_ptr and info_ptr
png_destroy_write_struct(&png_ptr, &info_ptr);
fclose(fp);
// If we get here, we had a problem writing the file
return false;
}
png_init_io(png_ptr, fp);
png_color_8 sig_bit;
sig_bit.red = 8;
sig_bit.green = 8;
sig_bit.blue = 8;
/* if the image has an alpha channel then */
sig_bit.alpha = 8;
png_set_sBIT(png_ptr, info_ptr, &sig_bit);
png_set_bgr(png_ptr);
png_set_IHDR(png_ptr, info_ptr, mWidth, mHeight, 8, PNG_COLOR_TYPE_RGB_ALPHA,
PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE);
png_write_info(png_ptr, info_ptr);
SwapRAndB();
for (int i = 0; i < mHeight; i++)
{
png_bytep aRowPtr = (png_bytep) (mBits + i*mWidth);
png_write_rows(png_ptr, &aRowPtr, 1);
}
SwapRAndB();
// write rest of file, and get additional chunks in info_ptr - REQUIRED
png_write_end(png_ptr, info_ptr);
// clean up after the write, and free any memory allocated - REQUIRED
png_destroy_write_struct(&png_ptr, &info_ptr);
// close the file
fclose(fp);
return true;
}

19
BeefySysLib/img/PNGData.h Normal file
View file

@ -0,0 +1,19 @@
#pragma once
#include "ImageData.h"
NS_BF_BEGIN;
class PNGData : public ImageData
{
public:
int mReadPos;
public:
PNGData();
bool ReadData();
bool WriteToFile(const StringImpl& path);
};
NS_BF_END;

File diff suppressed because it is too large Load diff

224
BeefySysLib/img/PSDReader.h Normal file
View file

@ -0,0 +1,224 @@
#pragma once
#include "../Common.h"
#include "ImageData.h"
#include <vector>
#include <map>
NS_BF_BEGIN;
class FileStream;
class ImageData;
class ImageAdjustment;
class PSDChannelInfo
{
public:
int mId;
int mLength;
};
typedef std::vector<PSDChannelInfo> PSDChannelInfoVector;
class PSDReader;
class ImageEffects;
enum
{
PSDVal_None, // 0
PSDVal_Descriptor, // 1
PSDVal_KeyedString, // 2
PSDVal_String, // 3
PSDVal_Double, // 4
PSDVal_Integer, // 5
PSDVal_UnitFloat, // 6
PSDVal_List // 7
};
class PSDDescriptor;
class PSDPathPoint
{
public:
double mCtlEnterX;
double mCtlEnterY;
double mAnchorX;
double mAnchorY;
double mCtlLeaveX;
double mCtlLeaveY;
};
typedef std::vector<PSDPathPoint> PSDPathPointVector;
class PSDPath
{
public:
bool mClosed;
PSDPathPointVector mPoints;
};
class PSDValue
{
public:
int mType;
String mKey;
String mString;
double mDouble;
int mInteger;
PSDDescriptor* mDescriptor;
PSDValue* mList;
public:
PSDValue();
~PSDValue();
int32 GetMulticharInt();
};
typedef std::map<String, PSDValue> PSDValueMap;
class PSDDescriptor
{
public:
PSDValueMap mPSDValueMap;
public:
bool IsEmpty();
bool Contains(const StringImpl& value);
PSDValue* Get(const StringImpl& value);
PSDDescriptor* GetDescriptor(const StringImpl& value);
};
enum
{
PSDDIVIDER_NONE,
PSDDIVIDER_OPEN_FOLDER,
PSDDIVIDER_CLOSED_FOLDER,
PSDDIVIDER_SECTION_END
};
class PSDLayerInfo : public ImageData
{
public:
PSDReader* mPSDReader;
PSDLayerInfo* mParent;
String mName;
int mIdx;
uint32 mLayerId;
int mSectionDividerType;
int32 mSectionBlendMode;
uint8 mOpacity;
uint8 mFillOpacity;
int32 mBlendMode;
bool mBaseClipping;
bool mVisible;
bool mLayerMaskEnabled;
bool mLayerMaskInverted;
uint8 mLayerMaskDefault;
uint8* mLayerMask;
int mLayerMaskX;
int mLayerMaskY;
int mLayerMaskWidth;
int mLayerMaskHeight;
ImageEffects* mImageEffects;
PSDDescriptor* mPSDDescriptor;
PSDPath* mVectorMask;
double mRefX;
double mRefY;
int mKnockout; // 1 = Shallow, 2 = Deep
bool mBlendInteriorEffectsAsGroup;
bool mBlendClippedElementsAsGroup;
bool mTransparencyShapesLayer;
bool mLayerMaskHidesEffects;
bool mVectorMaskHidesEffects;
uint32 mBlendingRangeSourceStart;
uint32 mBlendingRangeSourceEnd;
uint32 mBlendingRangeDestStart;
uint32 mBlendingRangeDestEnd;
ImageAdjustment* mImageAdjustment;
int mImageDataStart;
PSDChannelInfoVector mChannels;
int mChannelMask;
public:
PSDLayerInfo();
~PSDLayerInfo();
virtual bool ReadData();
void ApplyVectorMask(ImageData* imageData);
void ApplyMask(ImageData* imageData);
};
typedef std::vector<PSDLayerInfo*> PSDLayerInfoVector;
class PSDPattern : public ImageData
{
public:
int mTop;
int mLeft;
int mBottom;
int mRight;
uint8* mIntensityBits;
PSDPattern* mNextMipLevel;
public:
PSDPattern();
~PSDPattern();
PSDPattern* GetNextMipLevel();
};
typedef std::map<String, PSDPattern*> PSDPatternMap;
class Texture;
class ImageGradient;
class ImageCurve;
class ImageGradientFill;
class ImagePatternFill;
class PSDReader
{
public:
FileStream* mFS;
int mVersion;
int mWidth;
int mHeight;
int mBitDepthPerChannel;
int mMode;
int mGlobalAngle;
int mGlobalAltitude;
int mChannels;
PSDLayerInfoVector mPSDLayerInfoVector;
PSDPatternMap mPSDPatternMap;
public:
String ReadIdString();
void ReadPSDValue(PSDValue* value);
void ReadPSDDescriptor(PSDDescriptor* descriptor);
void ReadEffectColor(PSDDescriptor* colorDesc, uint32* color);
bool ReadEffectGradient(PSDDescriptor* descriptor, ImageGradient* colorGradient);
void ReadEffectContour(PSDDescriptor* descriptor, ImageCurve* curve);
int32 ReadBlendMode(PSDValue* value);
void ReadExtraInfo(int endPos);
void ReadEffectSection(ImageEffects* imageEffects, PSDDescriptor* desc);
void ReadGradientFill(PSDDescriptor* descriptor, ImageGradientFill* gradientFill);
void ReadPatternFill(PSDDescriptor* descriptor, ImagePatternFill* patternFill);
public:
PSDReader();
~PSDReader();
bool Init(const StringImpl& fileName);
Texture* LoadLayerTexture(int layerIdx, int* ofsX, int* ofsY); // -1 = composited image
ImageData* MergeLayers(PSDLayerInfo* group, const std::vector<int>& layerIndices, ImageData* bottomImage);
Texture* LoadMergedLayerTexture(const std::vector<int>& layerIndices, int* ofsX, int* ofsY);
};
NS_BF_END;

166
BeefySysLib/img/PVRData.cpp Normal file
View file

@ -0,0 +1,166 @@
#include "PVRData.h"
USING_NS_BF;
struct PVRTextureHeader
{
unsigned int dwHeaderSize;
unsigned int dwHeight;
unsigned int dwWidth;
unsigned int dwMipMapCount;
unsigned int dwpfFlags;
unsigned int dwTextureDataSize;
unsigned int dwBitCount;
unsigned int dwRBitMask;
unsigned int dwGBitMask;
unsigned int dwBBitMask;
unsigned int dwAlphaBitMask;
unsigned int dwPVR;
unsigned int dwNumSurfs;
};
typedef struct TextureMIPLevelData_TAG
{
unsigned char* pData;
unsigned int dwDataSize;
unsigned int dwMIPLevel;
unsigned int dwSizeX;
unsigned int dwSizeY;
} TextureMIPLevelData;
typedef struct TextureImageData_TAG
{
TextureMIPLevelData* pLevels;
int textureFormat;
int textureType;
bool isCompressed;
unsigned int dwMipLevels;
unsigned int dwWidth;
unsigned int dwHeight;
} TextureImageData;
static int DisableTwiddlingRoutine = 0;
static unsigned long TwiddleUV(unsigned long YSize, unsigned long XSize, unsigned long YPos, unsigned long XPos)
{
unsigned long Twiddled;
unsigned long MinDimension;
unsigned long MaxValue;
unsigned long SrcBitPos;
unsigned long DstBitPos;
int ShiftCount;
if(YSize < XSize)
{
MinDimension = YSize;
MaxValue = XPos;
}
else
{
MinDimension = XSize;
MaxValue = YPos;
}
/*
// Nasty hack to disable twiddling
*/
if(DisableTwiddlingRoutine)
{
return (YPos* XSize + XPos);
}
/*
// Step through all the bits in the "minimum" dimension
*/
SrcBitPos = 1;
DstBitPos = 1;
Twiddled = 0;
ShiftCount = 0;
while(SrcBitPos < MinDimension)
{
if(YPos & SrcBitPos)
{
Twiddled |= DstBitPos;
}
if(XPos & SrcBitPos)
{
Twiddled |= (DstBitPos << 1);
}
SrcBitPos <<= 1;
DstBitPos <<= 2;
ShiftCount += 1;
}/*end while*/
/*
// prepend any unused bits
*/
MaxValue >>= ShiftCount;
Twiddled |= (MaxValue << (2*ShiftCount));
return Twiddled;
}
#define PVR_TEXTURE_FLAG_TYPE_MASK 0xFF
#define PVR_TEXTURE_FLAG_TYPE_PVRTC_2 24
#define PVR_TEXTURE_FLAG_TYPE_PVRTC_4 25
bool PVRData::ReadData()
{
PVRTextureHeader* aHeader = (PVRTextureHeader*) (mSrcData);
if (aHeader->dwHeaderSize != 52)
return false;
if ((aHeader->dwpfFlags & PVR_TEXTURE_FLAG_TYPE_MASK) == PVR_TEXTURE_FLAG_TYPE_PVRTC_2)
mHWBitsType = HWBITS_PVRTC_2BPPV1;
else if ((aHeader->dwpfFlags & PVR_TEXTURE_FLAG_TYPE_MASK) == PVR_TEXTURE_FLAG_TYPE_PVRTC_4)
{
if (aHeader->dwNumSurfs > 1)
mHWBitsType = HWBITS_PVRTC_2X4BPPV1;
else
mHWBitsType = HWBITS_PVRTC_4BPPV1;
}
mHWBits = (uint8*)mSrcData + aHeader->dwHeaderSize;
mHWBitsLength = mSrcDataLen - aHeader->dwHeaderSize;
mWidth = aHeader->dwWidth;
mHeight = aHeader->dwHeight;
mKeepSrcDataValid = true;
/*mWidth = aHeader->dwWidth / 4;
mHeight = aHeader->dwHeight / 4;
mBits = new uint32[mWidth*mHeight];
int blockW = aHeader->dwWidth / 4;
int blockH = aHeader->dwHeight / 4;
int numBlocks = blockW * blockH;
for (int blockNum = 0; blockNum < numBlocks; blockNum++)
{
int blockX = (blockNum % blockW);
int blockY = blockH - (blockNum / blockW) - 1;
uint8* srcData = mSrcData + aHeader->dwHeaderSize + TwiddleUV(blockH, blockW, blockY, blockX)*8 + 4;
uint16 baseColorB = *((uint16*) (srcData));
uint32 color = 0xFF000000 |
(((uint32) baseColorB & 0x7C00) >> 7) |
(((uint32) baseColorB & 0x03E0) << 6) |
(((uint32) baseColorB & 0x001F) << 19);
mBits[blockNum] = color;
}*/
return true;
}

14
BeefySysLib/img/PVRData.h Normal file
View file

@ -0,0 +1,14 @@
#pragma once
#include "Common.h"
#include "ImageData.h"
NS_BF_BEGIN;
class PVRData : public ImageData
{
public:
bool ReadData();
};
NS_BF_END;

265
BeefySysLib/img/TGAData.cpp Normal file
View file

@ -0,0 +1,265 @@
#include "TGAData.h"
USING_NS_BF;
///
bool TGAData::ReadData()
{
size_t step = sizeof(unsigned char) * 2;
//CC_BREAK_IF((step + sizeof(unsigned char)) > bufSize);
#pragma pack(push, 1)
struct Header
{
char mIdLength;
char mColourMapType;
char mDataTypeCode;
short int mColourMapOrigin;
short int mColourMapLength;
char mColourMapDepth;
short int mXOrigin;
short int mYOrigin;
short mWidth;
short mHeight;
char mBitsPerPixel;
char mImageDescriptor;
};
#pragma pack(pop)
Header* hdr = (Header*)mSrcData;
/*memcpy(&aType, mSrcData, sizeof(unsigned char));
step += sizeof(unsigned char) * 2;
step += sizeof(signed short) * 4;
//CC_BREAK_IF((step + sizeof(signed short) * 2 + sizeof(unsigned char)) > bufSize);
memcpy(&width, mSrcData + step, sizeof(signed short));
memcpy(&height, mSrcData + step + sizeof(signed short), sizeof(signed short));
memcpy(&pixelDepth, mSrcData + step + sizeof(signed short) * 2, sizeof(unsigned char));
step += sizeof(unsigned char);
step += sizeof(signed short) * 2;
//CC_BREAK_IF((step + sizeof(unsigned char)) > bufSize);
unsigned char cGarbage;
memcpy(&cGarbage, mSrcData + step, sizeof(unsigned char));
bool flipped = (cGarbage & 0x20) != 0;*/
bool flipped = (hdr->mImageDescriptor & 0x20) != 0;
mWidth = hdr->mWidth;
mHeight = hdr->mWidth;
mBits = new uint32[mWidth * mHeight];
if (hdr->mDataTypeCode == 10) // RLE
{
int total;
size_t step = (sizeof(unsigned char) + sizeof(signed short)) * 6;
// mode equal the number of components for each pixel
int aMode = hdr->mBitsPerPixel / 8;
// total is the number of unsigned chars we'll have to read
total = mHeight * mWidth * aMode;
size_t dataSize = sizeof(unsigned char) * total;
//CC_BREAK_IF((step + dataSize) > bufSize);
uint8* srcPtr = mSrcData + step;
uint32* destPtr = mBits;
int destAdd = 0;
if (!flipped)
{
destPtr = mBits + mWidth*(mHeight - 1);
destAdd = -mWidth * 2;
}
if (aMode == 4)
{
int y = 0;
int x = 0;
readSpanHeader:
int spanLen = 0;
uint32 spanColor = 0;
uint8 spanHeader = *(srcPtr++);
spanLen = (spanHeader & 0x7F) + 1;
if ((spanHeader & 0x80) != 0)
{
// Repeat color
int b = *(srcPtr++);
int g = *(srcPtr++);
int r = *(srcPtr++);
int a = *(srcPtr++);
if (mWantsAlphaPremultiplied)
{
r = (r * a) / 255;
g = (g * a) / 255;
b = (b * a) / 255;
}
spanColor = (a << 24) | (b << 16) | (g << 8) | r;
for (; y < mHeight; y++)
{
for (; x < mWidth; x++)
{
if (spanLen == 0)
goto readSpanHeader;
*(destPtr++) = spanColor;
spanLen--;
}
x = 0;
destPtr += destAdd;
}
}
else
{
for (; y < mHeight; y++)
{
for (; x < mWidth; x++)
{
if (spanLen == 0)
goto readSpanHeader;
int b = *(srcPtr++);
int g = *(srcPtr++);
int r = *(srcPtr++);
int a = *(srcPtr++);
if (mWantsAlphaPremultiplied)
{
r = (r * a) / 255;
g = (g * a) / 255;
b = (b * a) / 255;
}
*(destPtr++) = (a << 24) | (b << 16) | (g << 8) | r;
spanLen--;
}
x = 0;
destPtr += destAdd;
}
}
NOP;
}
}
else
{
int total;
size_t step = (sizeof(unsigned char) + sizeof(signed short)) * 6;
// mode equal the number of components for each pixel
int aMode = hdr->mBitsPerPixel / 8;
// total is the number of unsigned chars we'll have to read
total = mHeight * mWidth * aMode;
size_t dataSize = sizeof(unsigned char) * total;
//CC_BREAK_IF((step + dataSize) > bufSize);
uint8* srcPtr = mSrcData + step;
uint32* destPtr = mBits;
int destAdd = 0;
if (!flipped)
{
destPtr = mBits + mWidth*(mHeight - 1);
destAdd = -mWidth*2;
}
if (aMode == 4)
{
for (int y = 0; y < mHeight; y++)
{
for (int x = 0; x < mWidth; x++)
{
int b = *(srcPtr++);
int g = *(srcPtr++);
int r = *(srcPtr++);
int a = *(srcPtr++);
if (mWantsAlphaPremultiplied)
{
r = (r * a) / 255;
g = (g * a) / 255;
b = (b * a) / 255;
}
*(destPtr++) = (a << 24) | (b << 16) | (g << 8) | r;
}
destPtr += destAdd;
}
}
else if (aMode == 3)
{
for (int y = 0; y < mHeight; y++)
{
for (int x = 0; x < mWidth; x++)
{
int b = *(srcPtr++);
int g = *(srcPtr++);
int r = *(srcPtr++);
int a = 255;
*(destPtr++) = (a << 24) | (b << 16) | (g << 8) | r;
}
destPtr += destAdd;
}
}
else if (aMode == 1)
{
for (int y = 0; y < mHeight; y++)
{
for (int x = 0; x < mWidth; x++)
{
int a = *(srcPtr++);
#ifdef BF_PLATFORM_WINDOWS
// Only windows has alpha correction for colored fonts (ATM)
//int r = (int) (pow(a / 255.0f, 0.7f) * 255.0f);
int r = (int)(pow(a / 255.0f, 1.2f) * 255.0f);
//int r = a;
int g = 255;
int b = 255;
#else
int r = a;
int g = a;
int b = a;
#endif
*(destPtr++) = (a << 24) | (b << 16) | (g << 8) | r;
}
destPtr += destAdd;
}
}
//memcpy(psInfo->imageData, Buffer + step, dataSize);
// mode=3 or 4 implies that the image is RGB(A). However TGA
// stores it as BGR(A) so we'll have to swap R and B.
/*if (mode >= 3)
{
for (i=0; i < total; i+= mode)
{
aux = psInfo->imageData[i];
psInfo->imageData[i] = psInfo->imageData[i+2];
psInfo->imageData[i+2] = aux;
}
}*/
}
mAlphaPremultiplied = mWantsAlphaPremultiplied;
return true;
}

14
BeefySysLib/img/TGAData.h Normal file
View file

@ -0,0 +1,14 @@
#pragma once
#include "ImageData.h"
NS_BF_BEGIN;
class TGAData : public ImageData
{
public:
public:
bool ReadData();
};
NS_BF_END;

View file

@ -0,0 +1,81 @@
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#include "Common.h"
static void fannkuch(int n, int& sumOut, int& maxflipsOut)
{
int sum = 0;
int maxflips = 0;
/*int* p = (int*)alloca(sizeof(int)*n);
int* q = (int*)alloca(sizeof(int)*n);
int* s = (int*)alloca(sizeof(int)*n);*/
int* p = new int[n];
int* q = new int[n];
int* s = new int[n];
int sign = 1, m = n - 1;
for (int i = 0; i < n; i++) { p[i] = i; q[i] = i; s[i] = i; }
do
{
// Copy and flip.
int q0 = p[0]; // Cache 0th element.
if (q0 != 0)
{
for (int i = 1; i < n; i++) q[i] = p[i]; // Work on a copy.
int flips = 1;
do
{
int qq = q[q0];
if (qq == 0)
{ // ... until 0th element is 0.
sum += sign * flips;
if (flips > maxflips) maxflips = flips; // New maximum?
break;
}
q[q0] = q0;
if (q0 >= 3)
{
int i = 1, j = q0 - 1, t;
do { t = q[i]; q[i] = q[j]; q[j] = t; i++; j--; } while (i < j);
}
q0 = qq; flips++;
} while (true);
}
// Permute.
if (sign == 1)
{
int t = p[1]; p[1] = p[0]; p[0] = t; sign = -1; // Rotate 0<-1.
}
else
{
int t = p[1]; p[1] = p[2]; p[2] = t; sign = 1; // Rotate 0<-1 and 0<-1<-2.
for (int i = 2; i < n; i++)
{
int sx = s[i];
if (sx != 0) { s[i] = sx - 1; break; }
if (i == m)
{
sumOut = sum;
maxflipsOut = maxflips;
return; // Out of permutations.
}
s[i] = i;
// Rotate 0<-...<-i+1.
t = p[0]; for (int j = 0; j <= i; j++) { p[j] = p[j + 1]; } p[i + 1] = t;
}
}
} while (true);
}
void FannkuchRedux(int n)
{
int sum;
int maxflips;
fannkuch(n, sum, maxflips);
Beefy::OutputDebugStrF("%d\nPfannkuchenC(%d) = %d\n", sum, n, maxflips);
}

View file

@ -0,0 +1,140 @@
#pragma warning(disable:4838)
#pragma warning(disable:4305)
#define _GNU_SOURCE
#include <stdlib.h>
#include <stdio.h>
#include <string.h>
#include <assert.h>
#define MIN(x, y) ((x < y) ? x : y)
#define LINELEN 60
#define SLOTS 4095
struct aminoacid {
char c;
float p;
};
static struct aminoacid *lu[SLOTS + 1];
static void repeat_fasta(const char *alu, size_t n)
{
const size_t alulen = strlen(alu);
assert(alulen < 1024);
char buf[1024 + LINELEN];
size_t pos = 0, bytes;
memcpy(buf, alu, alulen);
memcpy(buf + alulen, alu, LINELEN);
while (n) {
bytes = MIN(LINELEN, n);
//fwrite_unlocked(buf + pos, bytes, 1, stdout);
//putchar_unlocked('\n');
pos += bytes;
if (pos > alulen)
pos -= alulen;
n -= bytes;
}
}
static void acc_probs(struct aminoacid *table)
{
struct aminoacid *iter = table;
while ((++iter)->c) {
iter->p += (iter - 1)->p;
}
for (int i = 0; i <= SLOTS; ++i) {
while (i > (table->p * SLOTS))
++table;
lu[i] = table;
}
}
static float rng(float max)
{
const unsigned int IM = 139968, IA = 3877, IC = 29573;
static unsigned int seed = 42;
seed = (seed * IA + IC) % IM;
return max * seed / IM;
}
static char nextc()
{
float r;
struct aminoacid *iter;
r = rng(1.0f);
iter = lu[(int) (r * SLOTS)];
while (iter->p < r)
++iter;
return iter->c;
}
static void random_fasta(struct aminoacid *table, size_t n)
{
size_t i, lines = n / LINELEN;
const size_t chars_left = n % LINELEN;
char buf[LINELEN + 1];
while (lines--) {
for (i = 0; i < LINELEN; ++i) {
buf[i] = nextc();
}
buf[i] = '\n';
//fwrite_unlocked(buf, i + 1, 1, stdout);
}
for (i = 0; i < chars_left; ++i)
buf[i] = nextc();
//fwrite_unlocked(buf, i, 1, stdout);
}
void FastaRedux(int n)
{
//const size_t n = (argc > 1) ? atoi(argv[1]) : 1000;
const char alu [] =
"GGCCGGGCGCGGTGGCTCACGCCTGTAATCCCAGCACTTTG"
"GGAGGCCGAGGCGGGCGGATCACCTGAGGTCAGGAGTTCGA"
"GACCAGCCTGGCCAACATGGTGAAACCCCGTCTCTACTAAA"
"AATACAAAAATTAGCCGGGCGTGGTGGCGCGCGCCTGTAAT"
"CCCAGCTACTCGGGAGGCTGAGGCAGGAGAATCGCTTGAAC"
"CCGGGAGGCGGAGGTTGCAGTGAGCCGAGATCGCGCCACTG"
"CACTCCAGCCTGGGCGACAGAGCGAGACTCCGTCTCAAAAA";
struct aminoacid iub [] = {
{ 'a', 0.27 },
{ 'c', 0.12 },
{ 'g', 0.12 },
{ 't', 0.27 },
{ 'B', 0.02 },
{ 'D', 0.02 },
{ 'H', 0.02 },
{ 'K', 0.02 },
{ 'M', 0.02 },
{ 'N', 0.02 },
{ 'R', 0.02 },
{ 'S', 0.02 },
{ 'V', 0.02 },
{ 'W', 0.02 },
{ 'Y', 0.02 },
{ 0, 0 }
};
struct aminoacid homosapiens [] = {
{ 'a', 0.3029549426680 },
{ 'c', 0.1979883004921 },
{ 'g', 0.1975473066391 },
{ 't', 0.3015094502008 },
{ 0, 0 }
};
//fputs_unlocked(">ONE Homo sapiens alu\n", stdout);
repeat_fasta(alu, n * 2);
//fputs_unlocked(">TWO IUB ambiguity codes\n", stdout);
acc_probs(iub);
random_fasta(iub, n * 3);
//fputs_unlocked(">THREE Homo sapiens frequency\n", stdout);
acc_probs(homosapiens);
random_fasta(homosapiens, n * 5);
//putchar_unlocked('\n');
}

View file

@ -0,0 +1,136 @@
#include <math.h>
#include <stdio.h>
#include <stdlib.h>
#include "Common.h"
#define pi 3.141592653589793
#define solar_mass (4 * pi * pi)
#define days_per_year 365.24
struct planet {
double x, y, z;
double vx, vy, vz;
double mass;
};
void advance(int nbodies, struct planet * bodies, double dt)
{
int i, j;
for (i = 0; i < nbodies; i++) {
struct planet * b = &(bodies[i]);
for (j = i + 1; j < nbodies; j++) {
struct planet * b2 = &(bodies[j]);
double dx = b->x - b2->x;
double dy = b->y - b2->y;
double dz = b->z - b2->z;
double distance = sqrt(dx * dx + dy * dy + dz * dz);
double mag = dt / (distance * distance * distance);
b->vx -= dx * b2->mass * mag;
b->vy -= dy * b2->mass * mag;
b->vz -= dz * b2->mass * mag;
b2->vx += dx * b->mass * mag;
b2->vy += dy * b->mass * mag;
b2->vz += dz * b->mass * mag;
}
}
for (i = 0; i < nbodies; i++) {
struct planet * b = &(bodies[i]);
b->x += dt * b->vx;
b->y += dt * b->vy;
b->z += dt * b->vz;
}
}
double energy(int nbodies, struct planet * bodies)
{
double e;
int i, j;
e = 0.0;
for (i = 0; i < nbodies; i++) {
struct planet * b = &(bodies[i]);
e += 0.5 * b->mass * (b->vx * b->vx + b->vy * b->vy + b->vz * b->vz);
for (j = i + 1; j < nbodies; j++) {
struct planet * b2 = &(bodies[j]);
double dx = b->x - b2->x;
double dy = b->y - b2->y;
double dz = b->z - b2->z;
double distance = sqrt(dx * dx + dy * dy + dz * dz);
e -= (b->mass * b2->mass) / distance;
}
}
return e;
}
void offset_momentum(int nbodies, struct planet * bodies)
{
double px = 0.0, py = 0.0, pz = 0.0;
int i;
for (i = 0; i < nbodies; i++) {
px += bodies[i].vx * bodies[i].mass;
py += bodies[i].vy * bodies[i].mass;
pz += bodies[i].vz * bodies[i].mass;
}
bodies[0].vx = -px / solar_mass;
bodies[0].vy = -py / solar_mass;
bodies[0].vz = -pz / solar_mass;
}
#define NBODIES 5
struct planet orig_bodies[NBODIES] = {
{ /* sun */
0, 0, 0, 0, 0, 0, solar_mass
},
{ /* jupiter */
4.84143144246472090e+00,
-1.16032004402742839e+00,
-1.03622044471123109e-01,
1.66007664274403694e-03 * days_per_year,
7.69901118419740425e-03 * days_per_year,
-6.90460016972063023e-05 * days_per_year,
9.54791938424326609e-04 * solar_mass
},
{ /* saturn */
8.34336671824457987e+00,
4.12479856412430479e+00,
-4.03523417114321381e-01,
-2.76742510726862411e-03 * days_per_year,
4.99852801234917238e-03 * days_per_year,
2.30417297573763929e-05 * days_per_year,
2.85885980666130812e-04 * solar_mass
},
{ /* uranus */
1.28943695621391310e+01,
-1.51111514016986312e+01,
-2.23307578892655734e-01,
2.96460137564761618e-03 * days_per_year,
2.37847173959480950e-03 * days_per_year,
-2.96589568540237556e-05 * days_per_year,
4.36624404335156298e-05 * solar_mass
},
{ /* neptune */
1.53796971148509165e+01,
-2.59193146099879641e+01,
1.79258772950371181e-01,
2.68067772490389322e-03 * days_per_year,
1.62824170038242295e-03 * days_per_year,
-9.51592254519715870e-05 * days_per_year,
5.15138902046611451e-05 * solar_mass
}
};
struct planet bodies[NBODIES];
void NBody(int n)
{
int i;
memcpy(bodies, orig_bodies, sizeof(orig_bodies));
offset_momentum(NBODIES, bodies);
printf("%.9f\n", energy(NBODIES, bodies));
for (i = 1; i <= n; i++)
advance(NBODIES, bodies, 0.01);
printf("%.9f\n", energy(NBODIES, bodies));
}

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;

Some files were not shown because too many files have changed in this diff Show more