merge app's main files for different platforms
This commit is contained in:
parent
bc7362d6d7
commit
a4fb50813f
14 changed files with 196 additions and 1884 deletions
|
@ -116,7 +116,6 @@ newoption {
|
|||
value = "GCC",
|
||||
description = "Choose GCC flavor",
|
||||
allowed = {
|
||||
{ "asmjs", "Emscripten/asm.js" },
|
||||
{ "android-x86", "Android - x86" },
|
||||
{ "linux-gcc", "Linux (GCC compiler)" },
|
||||
{ "linux-gcc-5", "Linux (GCC-5 compiler)" },
|
||||
|
@ -163,20 +162,7 @@ newaction {
|
|||
|
||||
|
||||
function strip()
|
||||
configuration { "asmjs" }
|
||||
postbuildcommands {
|
||||
"$(SILENT) echo Running asmjs finalize.",
|
||||
"$(SILENT) \"$(EMSCRIPTEN)/emcc\" -O2 "
|
||||
-- .. "-s EMTERPRETIFY=1 "
|
||||
-- .. "-s EMTERPRETIFY_ASYNC=1 "
|
||||
.. "-s TOTAL_MEMORY=268435456 "
|
||||
-- .. "-s ALLOW_MEMORY_GROWTH=1 "
|
||||
-- .. "-s USE_WEBGL2=1 "
|
||||
.. "--memory-init-file 1 "
|
||||
.. "\"$(TARGET)\" -o \"$(TARGET)\".html "
|
||||
-- .. "--preload-file ../../../examples/runtime@/"
|
||||
}
|
||||
|
||||
|
||||
configuration { "android-x86", "Release" }
|
||||
postbuildcommands {
|
||||
"$(SILENT) echo Stripping symbols.",
|
||||
|
@ -208,9 +194,6 @@ function defaultConfigurations()
|
|||
defines { "_GLIBCXX_USE_CXX11_ABI=0" }
|
||||
links { "pthread" }
|
||||
|
||||
configuration { "asmjs" }
|
||||
buildoptions { "-std=c++14" }
|
||||
|
||||
configuration { "vs20*"}
|
||||
buildoptions { "/wd4503"}
|
||||
|
||||
|
@ -240,7 +223,7 @@ function useLua()
|
|||
if _OPTIONS["static-plugins"] then
|
||||
linkLib("lua")
|
||||
else
|
||||
configuration { "windows", "not asmjs" }
|
||||
configuration { "windows" }
|
||||
defines { "LUA_BUILD_AS_DLL" }
|
||||
configuration {}
|
||||
end
|
||||
|
@ -378,18 +361,8 @@ solution "LumixEngine"
|
|||
|
||||
configuration {}
|
||||
|
||||
if "asmjs" == _OPTIONS["gcc"] then
|
||||
if not os.getenv("EMSCRIPTEN") then
|
||||
print("Set EMSCRIPTEN enviroment variable.")
|
||||
end
|
||||
premake.gcc.cc = "\"$(EMSCRIPTEN)/emcc\""
|
||||
premake.gcc.cxx = "\"$(EMSCRIPTEN)/em++\""
|
||||
premake.gcc.ar = "\"$(EMSCRIPTEN)/emar\""
|
||||
_G["premake"].gcc.llvm = true
|
||||
premake.gcc.llvm = true
|
||||
LOCATION = "tmp/emscripten_gmake"
|
||||
|
||||
elseif "android-x86" == _OPTIONS["gcc"] then
|
||||
if "android-x86" == _OPTIONS["gcc"] then
|
||||
if not os.getenv("ANDROID_NDK_X86") or not os.getenv("ANDROID_NDK_ROOT") then
|
||||
print("Set ANDROID_NDK_X86 and ANDROID_NDK_ROOT envrionment variables.")
|
||||
end
|
||||
|
@ -476,9 +449,6 @@ solution "LumixEngine"
|
|||
configuration "not windows"
|
||||
removefiles { "../src/**/win/*"}
|
||||
|
||||
configuration "asmjs"
|
||||
removefiles { "../src/**/win/*"}
|
||||
|
||||
configuration "android-*"
|
||||
removefiles { "../src/**/win/*"}
|
||||
|
||||
|
@ -555,7 +525,7 @@ project "renderer"
|
|||
configuration {}
|
||||
useLua()
|
||||
|
||||
configuration { "windows", "not asmjs" }
|
||||
configuration { "windows" }
|
||||
links { "psapi" }
|
||||
|
||||
defaultConfigurations()
|
||||
|
@ -772,19 +742,12 @@ if build_app then
|
|||
linkLib "bgfx"
|
||||
linkLib "lua"
|
||||
linkLib "recast"
|
||||
|
||||
configuration { "asmjs" }
|
||||
targetextension ".bc"
|
||||
files { "../src/app/main_asmjs.cpp" }
|
||||
files { "../src/app/main.cpp" }
|
||||
|
||||
configuration { "windows", "not android-*" }
|
||||
configuration { "windows" }
|
||||
kind "WindowedApp"
|
||||
|
||||
configuration { "windows", "not asmjs", "not android-*" }
|
||||
files { "../src/app/main_win.cpp" }
|
||||
|
||||
configuration { "linux-*" }
|
||||
files { "../src/app/main_linux.cpp" }
|
||||
links { "GL", "X11", "dl", "rt" }
|
||||
|
||||
configuration {}
|
||||
|
@ -831,7 +794,7 @@ if build_studio then
|
|||
defines { "LUMIXENGINE_PLUGINS=" .. def }
|
||||
end
|
||||
|
||||
configuration { "windows", "not asmjs" }
|
||||
configuration { "windows" }
|
||||
links { "winmm" }
|
||||
|
||||
configuration {}
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
genie.exe --static-plugins --gcc=asmjs gmake
|
|
@ -25,7 +25,9 @@
|
|||
#include "renderer/renderer.h"
|
||||
#include "renderer/texture.h"
|
||||
#include <cstdio>
|
||||
#ifdef _MSC_VER
|
||||
#include <SDL.h>
|
||||
#include <SDL_syswm.h>
|
||||
#ifdef _WIN32
|
||||
#include <windows.h>
|
||||
#endif
|
||||
|
||||
|
@ -45,14 +47,8 @@ struct GUIInterface : GUISystem::Interface
|
|||
|
||||
void enableCursor(bool enable) override
|
||||
{
|
||||
if (enable)
|
||||
{
|
||||
while (ShowCursor(true) < 0);
|
||||
}
|
||||
else
|
||||
{
|
||||
while (ShowCursor(false) >= 0);
|
||||
}
|
||||
SDL_ShowCursor(enable);
|
||||
SDL_SetRelativeMouseMode(!enable ? SDL_TRUE : SDL_FALSE);
|
||||
}
|
||||
|
||||
|
||||
|
@ -85,109 +81,13 @@ public:
|
|||
}
|
||||
|
||||
|
||||
LRESULT onMessage(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
auto& input_system = m_engine->getInputSystem();
|
||||
switch (msg)
|
||||
{
|
||||
case WM_KILLFOCUS: m_engine->getInputSystem().enable(false); break;
|
||||
case WM_SETFOCUS: m_engine->getInputSystem().enable(true); break;
|
||||
case WM_CLOSE: PostQuitMessage(0); break;
|
||||
case WM_MOVE:
|
||||
case WM_SIZE: onResize(); break;
|
||||
case WM_QUIT: m_finished = true; break;
|
||||
case WM_INPUT: handleRawInput(lparam); break;
|
||||
}
|
||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
|
||||
static LRESULT CALLBACK msgProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
if (!s_instance || !s_instance->m_pipeline) return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
|
||||
return s_instance->onMessage(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
|
||||
void onResize()
|
||||
{
|
||||
RECT rect;
|
||||
RECT screen_rect;
|
||||
GetClientRect(m_hwnd, &rect);
|
||||
GetWindowRect(m_hwnd, &screen_rect);
|
||||
int w = rect.right - rect.left;
|
||||
int h = rect.bottom - rect.top;
|
||||
if (w > 0)
|
||||
{
|
||||
ClipCursor(&screen_rect);
|
||||
m_pipeline->resize(w, h);
|
||||
Renderer* renderer =
|
||||
static_cast<Renderer*>(m_engine->getPluginManager().getPlugin("renderer"));
|
||||
renderer->resize(w, h);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void createWindow()
|
||||
{
|
||||
HINSTANCE hInst = GetModuleHandle(NULL);
|
||||
WNDCLASSEX wnd;
|
||||
wnd = {};
|
||||
wnd.cbSize = sizeof(wnd);
|
||||
wnd.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wnd.lpfnWndProc = msgProc;
|
||||
wnd.hInstance = hInst;
|
||||
wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||
wnd.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wnd.lpszClassName = "App";
|
||||
wnd.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
|
||||
RegisterClassExA(&wnd);
|
||||
|
||||
RECT rect = { 0, 0, 600, 400 };
|
||||
AdjustWindowRect(&rect, WS_OVERLAPPEDWINDOW | WS_VISIBLE, FALSE);
|
||||
|
||||
m_hwnd = CreateWindowA("App",
|
||||
"App",
|
||||
WS_OVERLAPPEDWINDOW | WS_VISIBLE,
|
||||
0,
|
||||
0,
|
||||
rect.right - rect.left,
|
||||
rect.bottom - rect.top,
|
||||
NULL,
|
||||
NULL,
|
||||
hInst,
|
||||
0);
|
||||
|
||||
if(!m_window_mode) setFullscreenBorderless();
|
||||
|
||||
RAWINPUTDEVICE Rid;
|
||||
Rid.usUsagePage = 0x01;
|
||||
Rid.usUsage = 0x02;
|
||||
Rid.dwFlags = 0;
|
||||
Rid.hwndTarget = 0;
|
||||
RegisterRawInputDevices(&Rid, 1, sizeof(Rid));
|
||||
}
|
||||
|
||||
|
||||
void setFullscreenBorderless()
|
||||
{
|
||||
HMONITOR hmon = MonitorFromWindow(m_hwnd, MONITOR_DEFAULTTONEAREST);
|
||||
MONITORINFO mi = {sizeof(mi)};
|
||||
if (!GetMonitorInfo(hmon, &mi)) return;
|
||||
|
||||
SetWindowLong(m_hwnd, GWL_STYLE, GetWindowLong(m_hwnd, GWL_STYLE) & ~(WS_CAPTION | WS_THICKFRAME));
|
||||
SetWindowLong(m_hwnd,
|
||||
GWL_EXSTYLE,
|
||||
GetWindowLong(m_hwnd, GWL_EXSTYLE) &
|
||||
~(WS_EX_DLGMODALFRAME | WS_EX_WINDOWEDGE | WS_EX_CLIENTEDGE | WS_EX_STATICEDGE));
|
||||
SetWindowPos(m_hwnd,
|
||||
NULL,
|
||||
mi.rcMonitor.left,
|
||||
mi.rcMonitor.top,
|
||||
mi.rcMonitor.right - mi.rcMonitor.left,
|
||||
mi.rcMonitor.bottom - mi.rcMonitor.top,
|
||||
SWP_NOZORDER | SWP_NOACTIVATE | SWP_FRAMECHANGED);
|
||||
int w, h;
|
||||
SDL_GetWindowSize(m_window, &w, &h);
|
||||
m_pipeline->resize(w, h);
|
||||
Renderer* renderer = (Renderer*)m_engine->getPluginManager().getPlugin("renderer");
|
||||
renderer->resize(w, h);
|
||||
}
|
||||
|
||||
|
||||
|
@ -218,7 +118,8 @@ public:
|
|||
}
|
||||
}
|
||||
|
||||
createWindow();
|
||||
u32 flags = SDL_WINDOW_SHOWN | SDL_WINDOW_RESIZABLE;
|
||||
if (!m_window_mode) flags |= SDL_WINDOW_FULLSCREEN_DESKTOP;
|
||||
|
||||
g_log_info.getCallback().bind<outputToVS>();
|
||||
g_log_warning.getCallback().bind<outputToVS>();
|
||||
|
@ -234,7 +135,11 @@ public:
|
|||
|
||||
m_mem_file_device = LUMIX_NEW(m_allocator, FS::MemoryFileDevice)(m_allocator);
|
||||
char current_dir[MAX_PATH_LENGTH];
|
||||
GetCurrentDirectory(sizeof(current_dir), current_dir);
|
||||
#ifdef _WIN32
|
||||
GetCurrentDirectory(sizeof(current_dir), current_dir);
|
||||
#else
|
||||
current_dir[0] = '\0';
|
||||
#endif
|
||||
m_disk_file_device = LUMIX_NEW(m_allocator, FS::DiskFileDevice)("disk", current_dir, m_allocator);
|
||||
m_pack_file_device = LUMIX_NEW(m_allocator, FS::PackFileDevice)(m_allocator);
|
||||
|
||||
|
@ -246,8 +151,20 @@ public:
|
|||
m_file_system->setSaveGameDevice("memory:disk");
|
||||
|
||||
m_engine = Engine::create(current_dir, "", m_file_system, m_allocator);
|
||||
Engine::PlatformData platform_data;
|
||||
platform_data.window_handle = m_hwnd;
|
||||
m_window = SDL_CreateWindow("Lumix App", 0, 0, 600, 400, flags);
|
||||
if (!m_window_mode) SDL_SetWindowFullscreen(m_window, SDL_WINDOW_FULLSCREEN_DESKTOP);
|
||||
SDL_SysWMinfo window_info;
|
||||
SDL_VERSION(&window_info.version);
|
||||
SDL_GetWindowWMInfo(m_window, &window_info);
|
||||
Engine::PlatformData platform_data = {};
|
||||
#ifdef _WIN32
|
||||
platform_data.window_handle = window_info.info.win.window;
|
||||
#elif defined(__linux__)
|
||||
platform_data.window_handle = (void*)(uintptr_t)window_info.info.x11.window;
|
||||
platform_data.display = window_info.info.x11.display;
|
||||
#else
|
||||
#error PLATFORM_NOT_SUPPORTED
|
||||
#endif
|
||||
m_engine->setPlatformData(platform_data);
|
||||
|
||||
m_engine->getPluginManager().load("renderer");
|
||||
|
@ -289,7 +206,8 @@ public:
|
|||
|
||||
gui_system->setInterface(m_gui_interface);
|
||||
|
||||
while (ShowCursor(false) >= 0);
|
||||
SDL_ShowCursor(false);
|
||||
SDL_SetRelativeMouseMode(true ? SDL_TRUE : SDL_FALSE);
|
||||
onResize();
|
||||
|
||||
runStartupScript();
|
||||
|
@ -303,8 +221,8 @@ public:
|
|||
if (file)
|
||||
{
|
||||
m_engine->runScript((const char*)file->getBuffer(), (int)file->size(), m_startup_script_path);
|
||||
fs.close(*file);
|
||||
}
|
||||
fs.close(*file);
|
||||
}
|
||||
|
||||
|
||||
|
@ -414,54 +332,147 @@ public:
|
|||
int getExitCode() const { return m_exit_code; }
|
||||
|
||||
|
||||
void handleRawInput(LPARAM lParam)
|
||||
{
|
||||
UINT dwSize;
|
||||
char data[sizeof(RAWINPUT) * 10];
|
||||
|
||||
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));
|
||||
if (dwSize > sizeof(data)) return;
|
||||
|
||||
if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, data, &dwSize, sizeof(RAWINPUTHEADER)) !=
|
||||
dwSize) return;
|
||||
|
||||
RAWINPUT* raw = (RAWINPUT*)data;
|
||||
if (raw->header.dwType == RIM_TYPEMOUSE &&
|
||||
raw->data.mouse.usFlags == MOUSE_MOVE_RELATIVE)
|
||||
{
|
||||
POINT p;
|
||||
GetCursorPos(&p);
|
||||
ScreenToClient(m_hwnd, &p);
|
||||
auto& input_system = m_engine->getInputSystem();
|
||||
/*input_system.injectMouseXMove(float(raw->data.mouse.lLastX), (float)p.x);
|
||||
input_system.injectMouseYMove(float(raw->data.mouse.lLastY), (float)p.y);*/
|
||||
// TODO
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#if 1
|
||||
void handleEvents()
|
||||
{
|
||||
MSG msg;
|
||||
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
|
||||
SDL_Event event;
|
||||
InputSystem& input = m_engine->getInputSystem();
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
|
||||
onMessage(msg.hwnd, msg.message, msg.wParam, msg.lParam);
|
||||
switch (event.type)
|
||||
{
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
{
|
||||
Vec2 rel_mp = {(float)event.button.x, (float)event.button.y};
|
||||
InputSystem::Event input_event;
|
||||
input_event.type = InputSystem::Event::BUTTON;
|
||||
input_event.device = input.getMouseDevice();
|
||||
input_event.data.button.key_id = event.button.button;
|
||||
input_event.data.button.state = InputSystem::ButtonEvent::DOWN;
|
||||
input_event.data.button.x_abs = rel_mp.x;
|
||||
input_event.data.button.y_abs = rel_mp.y;
|
||||
input.injectEvent(input_event);
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
{
|
||||
Vec2 rel_mp = { (float)event.button.x, (float)event.button.y };
|
||||
InputSystem::Event input_event;
|
||||
input_event.type = InputSystem::Event::BUTTON;
|
||||
input_event.device = input.getMouseDevice();
|
||||
input_event.data.button.key_id = event.button.button;
|
||||
input_event.data.button.state = InputSystem::ButtonEvent::UP;
|
||||
input_event.data.button.x_abs = rel_mp.x;
|
||||
input_event.data.button.y_abs = rel_mp.y;
|
||||
input.injectEvent(input_event);
|
||||
}
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
{
|
||||
Vec2 rel_mp = { (float)event.motion.x, (float)event.motion.y };
|
||||
InputSystem::Event input_event;
|
||||
input_event.type = InputSystem::Event::AXIS;
|
||||
input_event.device = input.getMouseDevice();
|
||||
input_event.data.axis.x_abs = rel_mp.x;
|
||||
input_event.data.axis.y_abs = rel_mp.y;
|
||||
input_event.data.axis.x = (float)event.motion.xrel;
|
||||
input_event.data.axis.y = (float)event.motion.yrel;
|
||||
input.injectEvent(input_event);
|
||||
}
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
{
|
||||
InputSystem::Event input_event;
|
||||
input_event.type = InputSystem::Event::BUTTON;
|
||||
input_event.device = input.getKeyboardDevice();
|
||||
input_event.data.button.state = InputSystem::ButtonEvent::DOWN;
|
||||
input_event.data.button.key_id = event.key.keysym.sym;
|
||||
input.injectEvent(input_event);
|
||||
}
|
||||
break;
|
||||
case SDL_KEYUP:
|
||||
{
|
||||
InputSystem::Event input_event;
|
||||
input_event.type = InputSystem::Event::BUTTON;
|
||||
input_event.device = input.getKeyboardDevice();
|
||||
input_event.data.button.state = InputSystem::ButtonEvent::UP;
|
||||
input_event.data.button.key_id = event.key.keysym.sym;
|
||||
input.injectEvent(input_event);
|
||||
}
|
||||
break;
|
||||
case SDL_WINDOWEVENT:
|
||||
switch (event.window.event)
|
||||
{
|
||||
case SDL_WINDOWEVENT_CLOSE:
|
||||
m_finished = true;
|
||||
break;
|
||||
case SDL_WINDOWEVENT_RESIZED:
|
||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||
case SDL_WINDOWEVENT_MOVED:
|
||||
onResize();
|
||||
break;
|
||||
}
|
||||
break;
|
||||
case SDL_QUIT: m_finished = true; break;
|
||||
case SDL_WINDOWEVENT_FOCUS_GAINED: m_engine->getInputSystem().enable(true); break;
|
||||
case SDL_WINDOWEVENT_FOCUS_LOST: m_engine->getInputSystem().enable(false); break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#else
|
||||
void handleEvents()
|
||||
{
|
||||
SDL_Event event;
|
||||
while (SDL_PollEvent(&event))
|
||||
{
|
||||
switch (event.type)
|
||||
{
|
||||
case SDL_WINDOWEVENT:
|
||||
switch (event.window.event)
|
||||
{
|
||||
case SDL_WINDOWEVENT_MOVED:
|
||||
case SDL_WINDOWEVENT_SIZE_CHANGED:
|
||||
{
|
||||
int x, y, w, h;
|
||||
SDL_GetWindowSize(m_window, &w, &h);
|
||||
SDL_GetWindowPosition(m_window, &x, &y);
|
||||
onResize();
|
||||
}
|
||||
break;
|
||||
case SDL_WINDOWEVENT_CLOSE: m_finished = true; break;
|
||||
}
|
||||
break;
|
||||
case SDL_QUIT: m_finished = true; break;
|
||||
case SDL_MOUSEBUTTONDOWN:
|
||||
break;
|
||||
case SDL_MOUSEBUTTONUP:
|
||||
break;
|
||||
case SDL_MOUSEMOTION:
|
||||
break;
|
||||
case SDL_TEXTINPUT:
|
||||
break;
|
||||
case SDL_KEYDOWN:
|
||||
case SDL_KEYUP:
|
||||
break;
|
||||
case SDL_MOUSEWHEEL:
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
|
||||
static void outputToVS(const char* system, const char* message)
|
||||
{
|
||||
char tmp[2048];
|
||||
copyString(tmp, system);
|
||||
catString(tmp, " : ");
|
||||
catString(tmp, message);
|
||||
catString(tmp, "\r");
|
||||
#ifdef _MSC_VER
|
||||
char tmp[2048];
|
||||
copyString(tmp, system);
|
||||
catString(tmp, " : ");
|
||||
catString(tmp, message);
|
||||
catString(tmp, "\r");
|
||||
|
||||
OutputDebugString(tmp);
|
||||
OutputDebugString(tmp);
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
|
@ -525,7 +536,7 @@ private:
|
|||
int m_exit_code;
|
||||
char m_startup_script_path[MAX_PATH_LENGTH];
|
||||
char m_pipeline_path[MAX_PATH_LENGTH];
|
||||
HWND m_hwnd;
|
||||
SDL_Window* m_window;
|
||||
|
||||
static App* s_instance;
|
||||
};
|
||||
|
@ -536,8 +547,11 @@ App* App::s_instance = nullptr;
|
|||
|
||||
}
|
||||
|
||||
|
||||
#ifdef _WIN32
|
||||
INT WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, INT)
|
||||
#else
|
||||
int main(int args, char* argv[])
|
||||
#endif
|
||||
{
|
||||
Lumix::App app;
|
||||
app.init();
|
||||
|
@ -545,4 +559,3 @@ INT WINAPI WinMain(HINSTANCE, HINSTANCE, LPSTR, INT)
|
|||
app.shutdown();
|
||||
return app.getExitCode();
|
||||
}
|
||||
|
|
@ -1,399 +0,0 @@
|
|||
#include "engine/core/blob.h"
|
||||
#include "engine/core/command_line_parser.h"
|
||||
#include "engine/core/crc32.h"
|
||||
#include "engine/core/fs/disk_file_device.h"
|
||||
#include "engine/core/fs/file_system.h"
|
||||
#include "engine/core/fs/file_system.h"
|
||||
#include "engine/core/fs/memory_file_device.h"
|
||||
#include "engine/core/fs/pack_file_device.h"
|
||||
#include "engine/core/input_system.h"
|
||||
#include "engine/core/log.h"
|
||||
#include "engine/core/lua_wrapper.h"
|
||||
#include "engine/core/mt/thread.h"
|
||||
#include "engine/core/path_utils.h"
|
||||
#include "engine/core/profiler.h"
|
||||
#include "engine/core/resource_manager.h"
|
||||
#include "engine/core/resource_manager_base.h"
|
||||
#include "engine/core/system.h"
|
||||
#include "engine/core/timer.h"
|
||||
#include "engine/debug/debug.h"
|
||||
#include "editor/gizmo.h"
|
||||
#include "editor/world_editor.h"
|
||||
#include "engine/engine.h"
|
||||
#include "engine/plugin_manager.h"
|
||||
#include "renderer/pipeline.h"
|
||||
#include "renderer/renderer.h"
|
||||
#include "renderer/texture.h"
|
||||
#include "engine/universe/universe.h"
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
struct App
|
||||
{
|
||||
App()
|
||||
{
|
||||
m_universe = nullptr;
|
||||
m_exit_code = 0;
|
||||
m_frame_timer = Lumix::Timer::create(m_allocator);
|
||||
ASSERT(!s_instance);
|
||||
s_instance = this;
|
||||
m_pipeline = nullptr;
|
||||
}
|
||||
|
||||
|
||||
~App()
|
||||
{
|
||||
Lumix::Timer::destroy(m_frame_timer);
|
||||
ASSERT(!m_universe);
|
||||
s_instance = nullptr;
|
||||
}
|
||||
|
||||
/*
|
||||
LRESULT onMessage(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case WM_CLOSE: PostQuitMessage(0); break;
|
||||
case WM_MOVE:
|
||||
case WM_SIZE: onResize(); break;
|
||||
case WM_QUIT: m_finished = true; break;
|
||||
case WM_INPUT: handleRawInput(lparam); break;
|
||||
}
|
||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
|
||||
static LRESULT CALLBACK msgProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
if (!s_instance || !s_instance->m_pipeline) return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
|
||||
return s_instance->onMessage(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
|
||||
void onResize()
|
||||
{
|
||||
RECT rect;
|
||||
RECT screen_rect;
|
||||
GetClientRect(m_hwnd, &rect);
|
||||
GetWindowRect(m_hwnd, &screen_rect);
|
||||
int w = rect.right - rect.left;
|
||||
int h = rect.bottom - rect.top;
|
||||
if (w > 0)
|
||||
{
|
||||
ClipCursor(&screen_rect);
|
||||
m_pipeline->setViewport(0, 0, w, h);
|
||||
Lumix::Renderer* renderer =
|
||||
static_cast<Lumix::Renderer*>(m_engine->getPluginManager().getPlugin("renderer"));
|
||||
renderer->resize(w, h);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void createWindow()
|
||||
{
|
||||
HINSTANCE hInst = GetModuleHandle(NULL);
|
||||
WNDCLASSEX wnd;
|
||||
wnd = {};
|
||||
wnd.cbSize = sizeof(wnd);
|
||||
wnd.style = CS_HREDRAW | CS_VREDRAW;
|
||||
wnd.lpfnWndProc = msgProc;
|
||||
wnd.hInstance = hInst;
|
||||
wnd.hIcon = LoadIcon(NULL, IDI_APPLICATION);
|
||||
wnd.hCursor = LoadCursor(NULL, IDC_ARROW);
|
||||
wnd.lpszClassName = "App";
|
||||
wnd.hIconSm = LoadIcon(NULL, IDI_APPLICATION);
|
||||
RegisterClassExA(&wnd);
|
||||
m_hwnd = CreateWindowA("App", "App", WS_OVERLAPPEDWINDOW | WS_VISIBLE, 0, 0, 800, 600, NULL, NULL, hInst, 0);
|
||||
|
||||
RAWINPUTDEVICE Rid;
|
||||
Rid.usUsagePage = 0x01;
|
||||
Rid.usUsage = 0x02;
|
||||
Rid.dwFlags = 0;
|
||||
Rid.hwndTarget = 0;
|
||||
RegisterRawInputDevices(&Rid, 1, sizeof(Rid));
|
||||
}
|
||||
*/
|
||||
|
||||
void init()
|
||||
{
|
||||
Lumix::copyString(m_pipeline_path, "pipelines/app.lua");
|
||||
Lumix::copyString(m_startup_script_path, "startup.lua");
|
||||
char cmd_line[1024];
|
||||
Lumix::getCommandLine(cmd_line, Lumix::lengthOf(cmd_line));
|
||||
Lumix::CommandLineParser parser(cmd_line);
|
||||
while (parser.next())
|
||||
{
|
||||
if (parser.currentEquals("-pipeline"))
|
||||
{
|
||||
if (!parser.next()) break;
|
||||
|
||||
parser.getCurrent(m_pipeline_path, Lumix::lengthOf(m_pipeline_path));
|
||||
}
|
||||
else if(parser.currentEquals("-script"))
|
||||
{
|
||||
if (!parser.next()) break;
|
||||
|
||||
parser.getCurrent(m_startup_script_path, Lumix::lengthOf(m_startup_script_path));
|
||||
}
|
||||
}
|
||||
|
||||
// createWindow(); // TODO
|
||||
|
||||
Lumix::g_log_info.getCallback().bind<outputToConsole>();
|
||||
Lumix::g_log_warning.getCallback().bind<outputToConsole>();
|
||||
Lumix::g_log_error.getCallback().bind<outputToConsole>();
|
||||
|
||||
Lumix::enableCrashReporting(false);
|
||||
|
||||
m_file_system = Lumix::FS::FileSystem::create(m_allocator);
|
||||
|
||||
m_mem_file_device = LUMIX_NEW(m_allocator, Lumix::FS::MemoryFileDevice)(m_allocator);
|
||||
m_disk_file_device = LUMIX_NEW(m_allocator, Lumix::FS::DiskFileDevice)("disk", "", m_allocator);
|
||||
m_pack_file_device = LUMIX_NEW(m_allocator, Lumix::FS::PackFileDevice)(m_allocator);
|
||||
|
||||
m_file_system->mount(m_mem_file_device);
|
||||
m_file_system->mount(m_disk_file_device);
|
||||
m_file_system->mount(m_pack_file_device);
|
||||
m_pack_file_device->mount("data.pak");
|
||||
m_file_system->setDefaultDevice("memory:disk:pack");
|
||||
m_file_system->setSaveGameDevice("memory:disk");
|
||||
|
||||
m_engine = Lumix::Engine::create("", "", m_file_system, m_allocator);
|
||||
Lumix::Engine::PlatformData platform_data;
|
||||
// platform_data.window_handle = m_hwnd; // TODO
|
||||
m_engine->setPlatformData(platform_data);
|
||||
|
||||
m_engine->getPluginManager().load("renderer");
|
||||
m_engine->getPluginManager().load("animation");
|
||||
m_engine->getPluginManager().load("audio");
|
||||
m_engine->getPluginManager().load("lua_script");
|
||||
m_engine->getPluginManager().load("physics");
|
||||
m_engine->getInputSystem().enable(true);
|
||||
Lumix::Renderer* renderer = static_cast<Lumix::Renderer*>(m_engine->getPluginManager().getPlugin("renderer"));
|
||||
m_pipeline = Lumix::Pipeline::create(*renderer, Lumix::Path(m_pipeline_path), m_engine->getAllocator());
|
||||
m_pipeline->load();
|
||||
|
||||
while (m_engine->getFileSystem().hasWork())
|
||||
{
|
||||
Lumix::MT::sleep(100);
|
||||
m_engine->getFileSystem().updateAsyncTransactions();
|
||||
}
|
||||
|
||||
m_universe = &m_engine->createUniverse();
|
||||
m_pipeline->setScene((Lumix::RenderScene*)m_universe->getScene(Lumix::crc32("renderer")));
|
||||
m_pipeline->setViewport(0, 0, 600, 400);
|
||||
renderer->resize(600, 400);
|
||||
|
||||
registerLuaAPI();
|
||||
|
||||
//while (ShowCursor(false) >= 0); // TODO
|
||||
// onResize(); // TODO
|
||||
}
|
||||
|
||||
|
||||
void startupScriptLoaded(Lumix::FS::IFile& file, bool success)
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
Lumix::g_log_error.log("App") << "Could not open " << m_startup_script_path;
|
||||
return;
|
||||
}
|
||||
|
||||
m_engine->runScript((const char*)file.getBuffer(), (int)file.size(), m_startup_script_path);
|
||||
}
|
||||
|
||||
|
||||
void registerLuaAPI()
|
||||
{
|
||||
lua_State* L = m_engine->getState();
|
||||
|
||||
#define REGISTER_FUNCTION(F, name) \
|
||||
do { \
|
||||
auto* f = &Lumix::LuaWrapper::wrapMethod<App, decltype(&App::F), &App::F>; \
|
||||
Lumix::LuaWrapper::createSystemFunction(L, "App", name, f); \
|
||||
} while(false) \
|
||||
|
||||
REGISTER_FUNCTION(loadUniverse, "loadUniverse");
|
||||
REGISTER_FUNCTION(frame, "frame");
|
||||
REGISTER_FUNCTION(exit, "exit");
|
||||
|
||||
#undef REGISTER_FUNCTION
|
||||
|
||||
Lumix::LuaWrapper::createSystemVariable(L, "App", "instance", this);
|
||||
Lumix::LuaWrapper::createSystemVariable(L, "App", "universe", m_universe);
|
||||
|
||||
auto& fs = m_engine->getFileSystem();
|
||||
Lumix::FS::ReadCallback cb;
|
||||
cb.bind<App, &App::startupScriptLoaded>(this);
|
||||
fs.openAsync(fs.getDefaultDevice(), Lumix::Path(m_startup_script_path), Lumix::FS::Mode::OPEN_AND_READ, cb);
|
||||
}
|
||||
|
||||
|
||||
void universeFileLoaded(Lumix::FS::IFile& file, bool success)
|
||||
{
|
||||
ASSERT(success);
|
||||
if (!success) return;
|
||||
|
||||
ASSERT(file.getBuffer());
|
||||
Lumix::InputBlob blob(file.getBuffer(), (int)file.size());
|
||||
#pragma pack(1)
|
||||
struct Header
|
||||
{
|
||||
Lumix::u32 magic;
|
||||
int version;
|
||||
Lumix::u32 hash;
|
||||
Lumix::u32 engine_hash;
|
||||
};
|
||||
#pragma pack()
|
||||
Header header;
|
||||
blob.read(header);
|
||||
if (Lumix::crc32((const u8*)blob.getData() + sizeof(header), blob.getSize() - sizeof(header)) !=
|
||||
header.hash)
|
||||
{
|
||||
Lumix::g_log_error.log("App") << "Universe corrupted";
|
||||
return;
|
||||
}
|
||||
bool deserialize_succeeded = m_engine->deserialize(*m_universe, blob);
|
||||
if (!deserialize_succeeded)
|
||||
{
|
||||
Lumix::g_log_error.log("App") << "Failed to deserialize universe";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void loadUniverse(const char* path)
|
||||
{
|
||||
auto& fs = m_engine->getFileSystem();
|
||||
Lumix::FS::ReadCallback file_read_cb;
|
||||
file_read_cb.bind<App, &App::universeFileLoaded>(this);
|
||||
fs.openAsync(fs.getDefaultDevice(), Lumix::Path(path), Lumix::FS::Mode::OPEN_AND_READ, file_read_cb);
|
||||
}
|
||||
|
||||
|
||||
void shutdown()
|
||||
{
|
||||
m_engine->destroyUniverse(*m_universe);
|
||||
Lumix::FS::FileSystem::destroy(m_file_system);
|
||||
LUMIX_DELETE(m_allocator, m_disk_file_device);
|
||||
LUMIX_DELETE(m_allocator, m_mem_file_device);
|
||||
LUMIX_DELETE(m_allocator, m_pack_file_device);
|
||||
Lumix::Pipeline::destroy(m_pipeline);
|
||||
Lumix::Engine::destroy(m_engine, m_allocator);
|
||||
m_engine = nullptr;
|
||||
m_pipeline = nullptr;
|
||||
m_universe = nullptr;
|
||||
}
|
||||
|
||||
|
||||
int getExitCode() const { return m_exit_code; }
|
||||
|
||||
/*
|
||||
void handleRawInput(LPARAM lParam)
|
||||
{
|
||||
UINT dwSize;
|
||||
char data[sizeof(RAWINPUT) * 10];
|
||||
|
||||
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));
|
||||
if (dwSize > sizeof(data)) return;
|
||||
|
||||
if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, data, &dwSize, sizeof(RAWINPUTHEADER)) !=
|
||||
dwSize) return;
|
||||
|
||||
RAWINPUT* raw = (RAWINPUT*)data;
|
||||
if (raw->header.dwType == RIM_TYPEMOUSE &&
|
||||
raw->data.mouse.usFlags == MOUSE_MOVE_RELATIVE)
|
||||
{
|
||||
POINT p;
|
||||
GetCursorPos(&p);
|
||||
ScreenToClient(m_hwnd, &p);
|
||||
auto& input_system = m_engine->getInputSystem();
|
||||
input_system.injectMouseXMove(float(raw->data.mouse.lLastX));
|
||||
input_system.injectMouseYMove(float(raw->data.mouse.lLastY));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void handleEvents()
|
||||
{
|
||||
MSG msg;
|
||||
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
|
||||
{
|
||||
TranslateMessage(&msg);
|
||||
DispatchMessage(&msg);
|
||||
|
||||
onMessage(msg.hwnd, msg.message, msg.wParam, msg.lParam);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
static void outputToConsole(const char* system, const char* message)
|
||||
{
|
||||
printf("%s: %s\n", system, message);
|
||||
}
|
||||
|
||||
|
||||
void exit(int exit_code)
|
||||
{
|
||||
m_finished = true;
|
||||
m_exit_code = exit_code;
|
||||
}
|
||||
|
||||
|
||||
void frame()
|
||||
{
|
||||
float frame_time = m_frame_timer->tick();
|
||||
m_engine->update(*m_universe);
|
||||
m_pipeline->render();
|
||||
auto* renderer = m_engine->getPluginManager().getPlugin("renderer");
|
||||
static_cast<Lumix::Renderer*>(renderer)->frame();
|
||||
m_engine->getFileSystem().updateAsyncTransactions();
|
||||
if (frame_time < 1 / 60.0f)
|
||||
{
|
||||
PROFILE_BLOCK("sleep");
|
||||
Lumix::MT::sleep(Lumix::u32(1000 / 60.0f - frame_time * 1000));
|
||||
}
|
||||
// handleEvents(); // TODO
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
m_finished = false;
|
||||
while (!m_finished)
|
||||
{
|
||||
frame();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
Lumix::DefaultAllocator m_allocator;
|
||||
Lumix::Engine* m_engine;
|
||||
Lumix::Universe* m_universe;
|
||||
Lumix::Pipeline* m_pipeline;
|
||||
Lumix::FS::FileSystem* m_file_system;
|
||||
Lumix::FS::MemoryFileDevice* m_mem_file_device;
|
||||
Lumix::FS::DiskFileDevice* m_disk_file_device;
|
||||
Lumix::FS::PackFileDevice* m_pack_file_device;
|
||||
Lumix::Timer* m_frame_timer;
|
||||
bool m_finished;
|
||||
int m_exit_code;
|
||||
char m_startup_script_path[Lumix::MAX_PATH_LENGTH];
|
||||
char m_pipeline_path[Lumix::MAX_PATH_LENGTH];
|
||||
//HWND m_hwnd;
|
||||
|
||||
static App* s_instance;
|
||||
};
|
||||
|
||||
|
||||
App* App::s_instance = nullptr;
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
App app;
|
||||
app.init();
|
||||
app.run();
|
||||
app.shutdown();
|
||||
return app.getExitCode();
|
||||
}
|
|
@ -1,400 +0,0 @@
|
|||
#include "engine/blob.h"
|
||||
#include "engine/command_line_parser.h"
|
||||
#include "engine/crc32.h"
|
||||
#include "engine/fs/disk_file_device.h"
|
||||
#include "engine/fs/file_system.h"
|
||||
#include "engine/fs/file_system.h"
|
||||
#include "engine/fs/memory_file_device.h"
|
||||
#include "engine/fs/pack_file_device.h"
|
||||
#include "engine/input_system.h"
|
||||
#include "engine/log.h"
|
||||
#include "engine/lua_wrapper.h"
|
||||
#include "engine/mt/thread.h"
|
||||
#include "engine/path_utils.h"
|
||||
#include "engine/profiler.h"
|
||||
#include "engine/resource_manager.h"
|
||||
#include "engine/resource_manager_base.h"
|
||||
#include "engine/system.h"
|
||||
#include "engine/timer.h"
|
||||
#include "engine/debug/debug.h"
|
||||
#include "editor/gizmo.h"
|
||||
#include "editor/world_editor.h"
|
||||
#include "engine/engine.h"
|
||||
#include "engine/plugin_manager.h"
|
||||
#include "renderer/pipeline.h"
|
||||
#include "renderer/renderer.h"
|
||||
#include "renderer/texture.h"
|
||||
#include "engine/universe/universe.h"
|
||||
#include <cstdio>
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
|
||||
namespace Lumix
|
||||
{
|
||||
|
||||
|
||||
struct App
|
||||
{
|
||||
App()
|
||||
{
|
||||
m_universe = nullptr;
|
||||
m_exit_code = 0;
|
||||
m_frame_timer = Timer::create(m_allocator);
|
||||
ASSERT(!s_instance);
|
||||
s_instance = this;
|
||||
m_pipeline = nullptr;
|
||||
}
|
||||
|
||||
|
||||
~App()
|
||||
{
|
||||
Timer::destroy(m_frame_timer);
|
||||
ASSERT(!m_universe);
|
||||
s_instance = nullptr;
|
||||
}
|
||||
|
||||
/*
|
||||
LRESULT onMessage(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
switch (msg)
|
||||
{
|
||||
case WM_CLOSE: PostQuitMessage(0); break;
|
||||
case WM_MOVE:
|
||||
case WM_SIZE: onResize(); break;
|
||||
case WM_QUIT: m_finished = true; break;
|
||||
case WM_INPUT: handleRawInput(lparam); break;
|
||||
}
|
||||
return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
|
||||
static LRESULT CALLBACK msgProc(HWND hwnd, UINT msg, WPARAM wparam, LPARAM lparam)
|
||||
{
|
||||
if (!s_instance || !s_instance->m_pipeline) return DefWindowProc(hwnd, msg, wparam, lparam);
|
||||
|
||||
return s_instance->onMessage(hwnd, msg, wparam, lparam);
|
||||
}
|
||||
|
||||
|
||||
void onResize()
|
||||
{
|
||||
RECT rect;
|
||||
RECT screen_rect;
|
||||
GetClientRect(m_hwnd, &rect);
|
||||
GetWindowRect(m_hwnd, &screen_rect);
|
||||
int w = rect.right - rect.left;
|
||||
int h = rect.bottom - rect.top;
|
||||
if (w > 0)
|
||||
{
|
||||
ClipCursor(&screen_rect);
|
||||
m_pipeline->setViewport(0, 0, w, h);
|
||||
Renderer* renderer =
|
||||
static_cast<Renderer*>(m_engine->getPluginManager().getPlugin("renderer"));
|
||||
renderer->resize(w, h);
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
bool createWindow()
|
||||
{
|
||||
m_display = XOpenDisplay(nullptr);
|
||||
if (!m_display) return false;
|
||||
|
||||
int s = DefaultScreen(m_display);
|
||||
m_window = XCreateSimpleWindow(m_display, RootWindow(m_display, s), 10, 10, 100, 100, 1
|
||||
, BlackPixel(m_display, s), WhitePixel(m_display, s));
|
||||
XSelectInput(m_display, m_window, ExposureMask | KeyPressMask);
|
||||
XMapWindow(m_display, m_window);
|
||||
return true;
|
||||
}
|
||||
|
||||
void init()
|
||||
{
|
||||
copyString(m_pipeline_path, "pipelines/app.lua");
|
||||
copyString(m_startup_script_path, "startup.lua");
|
||||
char cmd_line[1024];
|
||||
getCommandLine(cmd_line, lengthOf(cmd_line));
|
||||
CommandLineParser parser(cmd_line);
|
||||
while (parser.next())
|
||||
{
|
||||
if (parser.currentEquals("-pipeline"))
|
||||
{
|
||||
if (!parser.next()) break;
|
||||
|
||||
parser.getCurrent(m_pipeline_path, lengthOf(m_pipeline_path));
|
||||
}
|
||||
else if(parser.currentEquals("-script"))
|
||||
{
|
||||
if (!parser.next()) break;
|
||||
|
||||
parser.getCurrent(m_startup_script_path, lengthOf(m_startup_script_path));
|
||||
}
|
||||
}
|
||||
|
||||
createWindow();
|
||||
|
||||
g_log_info.getCallback().bind<outputToConsole>();
|
||||
g_log_warning.getCallback().bind<outputToConsole>();
|
||||
g_log_error.getCallback().bind<outputToConsole>();
|
||||
|
||||
enableCrashReporting(false);
|
||||
|
||||
m_file_system = FS::FileSystem::create(m_allocator);
|
||||
|
||||
m_mem_file_device = LUMIX_NEW(m_allocator, FS::MemoryFileDevice)(m_allocator);
|
||||
m_disk_file_device = LUMIX_NEW(m_allocator, FS::DiskFileDevice)("disk", "", m_allocator);
|
||||
m_pack_file_device = LUMIX_NEW(m_allocator, FS::PackFileDevice)(m_allocator);
|
||||
|
||||
m_file_system->mount(m_mem_file_device);
|
||||
m_file_system->mount(m_disk_file_device);
|
||||
m_file_system->mount(m_pack_file_device);
|
||||
m_pack_file_device->mount("data.pak");
|
||||
m_file_system->setDefaultDevice("memory:disk:pack");
|
||||
m_file_system->setSaveGameDevice("memory:disk");
|
||||
|
||||
m_engine = Engine::create("", "", m_file_system, m_allocator);
|
||||
Engine::PlatformData platform_data;
|
||||
platform_data.window_handle = (void*)(uintptr_t)m_window;
|
||||
platform_data.display = m_display;
|
||||
m_engine->setPlatformData(platform_data);
|
||||
|
||||
m_engine->getPluginManager().load("renderer");
|
||||
m_engine->getPluginManager().load("animation");
|
||||
m_engine->getPluginManager().load("audio");
|
||||
m_engine->getPluginManager().load("lua_script");
|
||||
m_engine->getPluginManager().load("physics");
|
||||
m_engine->getInputSystem().enable(true);
|
||||
Renderer* renderer = static_cast<Renderer*>(m_engine->getPluginManager().getPlugin("renderer"));
|
||||
m_pipeline = Pipeline::create(*renderer, Path(m_pipeline_path), "APP", m_engine->getAllocator());
|
||||
m_pipeline->load();
|
||||
|
||||
while (m_engine->getFileSystem().hasWork())
|
||||
{
|
||||
MT::sleep(100);
|
||||
m_engine->getFileSystem().updateAsyncTransactions();
|
||||
}
|
||||
|
||||
m_universe = &m_engine->createUniverse(true);
|
||||
m_pipeline->setScene((RenderScene*)m_universe->getScene(crc32("renderer")));
|
||||
m_pipeline->resize(600, 400);
|
||||
renderer->resize(600, 400);
|
||||
|
||||
registerLuaAPI();
|
||||
|
||||
//while (ShowCursor(false) >= 0); // TODO
|
||||
// onResize(); // TODO
|
||||
}
|
||||
|
||||
|
||||
void startupScriptLoaded(FS::IFile& file, bool success)
|
||||
{
|
||||
if (!success)
|
||||
{
|
||||
g_log_error.log("App") << "Could not open " << m_startup_script_path;
|
||||
return;
|
||||
}
|
||||
|
||||
m_engine->runScript((const char*)file.getBuffer(), (int)file.size(), m_startup_script_path);
|
||||
}
|
||||
|
||||
|
||||
void registerLuaAPI()
|
||||
{
|
||||
lua_State* L = m_engine->getState();
|
||||
|
||||
#define REGISTER_FUNCTION(F, name) \
|
||||
do { \
|
||||
auto* f = &LuaWrapper::wrapMethod<App, decltype(&App::F), &App::F>; \
|
||||
LuaWrapper::createSystemFunction(L, "App", name, f); \
|
||||
} while(false) \
|
||||
|
||||
REGISTER_FUNCTION(loadUniverse, "loadUniverse");
|
||||
REGISTER_FUNCTION(frame, "frame");
|
||||
REGISTER_FUNCTION(exit, "exit");
|
||||
|
||||
#undef REGISTER_FUNCTION
|
||||
|
||||
LuaWrapper::createSystemVariable(L, "App", "instance", this);
|
||||
LuaWrapper::createSystemVariable(L, "App", "universe", m_universe);
|
||||
|
||||
auto& fs = m_engine->getFileSystem();
|
||||
FS::ReadCallback cb;
|
||||
cb.bind<App, &App::startupScriptLoaded>(this);
|
||||
fs.openAsync(fs.getDefaultDevice(), Path(m_startup_script_path), FS::Mode::OPEN_AND_READ, cb);
|
||||
}
|
||||
|
||||
|
||||
void universeFileLoaded(FS::IFile& file, bool success)
|
||||
{
|
||||
ASSERT(success);
|
||||
if (!success) return;
|
||||
|
||||
ASSERT(file.getBuffer());
|
||||
InputBlob blob(file.getBuffer(), (int)file.size());
|
||||
#pragma pack(1)
|
||||
struct Header
|
||||
{
|
||||
u32 magic;
|
||||
int version;
|
||||
u32 hash;
|
||||
u32 engine_hash;
|
||||
};
|
||||
#pragma pack()
|
||||
Header header;
|
||||
blob.read(header);
|
||||
if (crc32((const u8*)blob.getData() + sizeof(header), blob.getSize() - sizeof(header)) !=
|
||||
header.hash)
|
||||
{
|
||||
g_log_error.log("App") << "Universe corrupted";
|
||||
return;
|
||||
}
|
||||
bool deserialize_succeeded = m_engine->deserialize(*m_universe, blob);
|
||||
if (!deserialize_succeeded)
|
||||
{
|
||||
g_log_error.log("App") << "Failed to deserialize universe";
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void loadUniverse(const char* path)
|
||||
{
|
||||
auto& fs = m_engine->getFileSystem();
|
||||
FS::ReadCallback file_read_cb;
|
||||
file_read_cb.bind<App, &App::universeFileLoaded>(this);
|
||||
fs.openAsync(fs.getDefaultDevice(), Path(path), FS::Mode::OPEN_AND_READ, file_read_cb);
|
||||
}
|
||||
|
||||
|
||||
void shutdown()
|
||||
{
|
||||
m_engine->destroyUniverse(*m_universe);
|
||||
FS::FileSystem::destroy(m_file_system);
|
||||
LUMIX_DELETE(m_allocator, m_disk_file_device);
|
||||
LUMIX_DELETE(m_allocator, m_mem_file_device);
|
||||
LUMIX_DELETE(m_allocator, m_pack_file_device);
|
||||
Pipeline::destroy(m_pipeline);
|
||||
Engine::destroy(m_engine, m_allocator);
|
||||
m_engine = nullptr;
|
||||
m_pipeline = nullptr;
|
||||
m_universe = nullptr;
|
||||
|
||||
XCloseDisplay(m_display);
|
||||
}
|
||||
|
||||
|
||||
int getExitCode() const { return m_exit_code; }
|
||||
|
||||
/*
|
||||
void handleRawInput(LPARAM lParam)
|
||||
{
|
||||
UINT dwSize;
|
||||
char data[sizeof(RAWINPUT) * 10];
|
||||
|
||||
GetRawInputData((HRAWINPUT)lParam, RID_INPUT, NULL, &dwSize, sizeof(RAWINPUTHEADER));
|
||||
if (dwSize > sizeof(data)) return;
|
||||
|
||||
if (GetRawInputData((HRAWINPUT)lParam, RID_INPUT, data, &dwSize, sizeof(RAWINPUTHEADER)) !=
|
||||
dwSize) return;
|
||||
|
||||
RAWINPUT* raw = (RAWINPUT*)data;
|
||||
if (raw->header.dwType == RIM_TYPEMOUSE &&
|
||||
raw->data.mouse.usFlags == MOUSE_MOVE_RELATIVE)
|
||||
{
|
||||
POINT p;
|
||||
GetCursorPos(&p);
|
||||
ScreenToClient(m_hwnd, &p);
|
||||
auto& input_system = m_engine->getInputSystem();
|
||||
input_system.injectMouseXMove(float(raw->data.mouse.lLastX));
|
||||
input_system.injectMouseYMove(float(raw->data.mouse.lLastY));
|
||||
}
|
||||
}
|
||||
*/
|
||||
|
||||
void handleEvents()
|
||||
{
|
||||
XEvent e;
|
||||
while (XPending(m_display) > 0)
|
||||
{
|
||||
XNextEvent(m_display, &e);
|
||||
if (e.type == KeyPress) break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void outputToConsole(const char* system, const char* message)
|
||||
{
|
||||
printf("%s: %s\n", system, message);
|
||||
}
|
||||
|
||||
|
||||
void exit(int exit_code)
|
||||
{
|
||||
m_finished = true;
|
||||
m_exit_code = exit_code;
|
||||
}
|
||||
|
||||
|
||||
void frame()
|
||||
{
|
||||
float frame_time = m_frame_timer->tick();
|
||||
m_engine->update(*m_universe);
|
||||
m_pipeline->render();
|
||||
auto* renderer = m_engine->getPluginManager().getPlugin("renderer");
|
||||
static_cast<Renderer*>(renderer)->frame(false);
|
||||
m_engine->getFileSystem().updateAsyncTransactions();
|
||||
if (frame_time < 1 / 60.0f)
|
||||
{
|
||||
PROFILE_BLOCK("sleep");
|
||||
MT::sleep(u32(1000 / 60.0f - frame_time * 1000));
|
||||
}
|
||||
handleEvents();
|
||||
}
|
||||
|
||||
void run()
|
||||
{
|
||||
m_finished = false;
|
||||
while (!m_finished)
|
||||
{
|
||||
frame();
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
private:
|
||||
DefaultAllocator m_allocator;
|
||||
Engine* m_engine;
|
||||
Universe* m_universe;
|
||||
Pipeline* m_pipeline;
|
||||
FS::FileSystem* m_file_system;
|
||||
FS::MemoryFileDevice* m_mem_file_device;
|
||||
FS::DiskFileDevice* m_disk_file_device;
|
||||
FS::PackFileDevice* m_pack_file_device;
|
||||
Timer* m_frame_timer;
|
||||
bool m_finished;
|
||||
int m_exit_code;
|
||||
char m_startup_script_path[MAX_PATH_LENGTH];
|
||||
char m_pipeline_path[MAX_PATH_LENGTH];
|
||||
Display* m_display;
|
||||
Window m_window;
|
||||
|
||||
static App* s_instance;
|
||||
};
|
||||
|
||||
|
||||
App* App::s_instance = nullptr;
|
||||
|
||||
|
||||
}
|
||||
|
||||
|
||||
int main(int argc, char* argv[])
|
||||
{
|
||||
Lumix::setCommandLine(argc, argv);
|
||||
Lumix::App app;
|
||||
app.init();
|
||||
app.run();
|
||||
app.shutdown();
|
||||
return app.getExitCode();
|
||||
}
|
||||
|
||||
|
|
@ -1,362 +0,0 @@
|
|||
#include "engine/debug/debug.h"
|
||||
#include "engine/mt/atomic.h"
|
||||
#include "engine/string.h"
|
||||
#include "engine/system.h"
|
||||
#include <cstdlib>
|
||||
#include <cstdio>
|
||||
|
||||
|
||||
static bool g_is_crash_reporting_enabled = false;
|
||||
|
||||
|
||||
namespace Lumix
|
||||
{
|
||||
|
||||
|
||||
namespace Debug
|
||||
{
|
||||
|
||||
|
||||
void debugOutput(const char* message)
|
||||
{
|
||||
puts(message);
|
||||
}
|
||||
|
||||
|
||||
void debugBreak()
|
||||
{
|
||||
abort();
|
||||
}
|
||||
|
||||
|
||||
int StackTree::s_instances = 0;
|
||||
|
||||
|
||||
class StackNode
|
||||
{
|
||||
public:
|
||||
~StackNode()
|
||||
{
|
||||
delete m_next;
|
||||
delete m_first_child;
|
||||
}
|
||||
|
||||
void* m_instruction;
|
||||
StackNode* m_next;
|
||||
StackNode* m_first_child;
|
||||
StackNode* m_parent;
|
||||
};
|
||||
|
||||
|
||||
StackTree::StackTree()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
StackTree::~StackTree()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
void StackTree::refreshModuleList()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
int StackTree::getPath(StackNode* node, StackNode** output, int max_size)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
StackNode* StackTree::getParent(StackNode* node)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
bool StackTree::getFunction(StackNode* node, char* out, int max_size, int* line)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
void StackTree::printCallstack(StackNode* node)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
StackNode* StackTree::insertChildren(StackNode* root_node, void** instruction, void** stack)
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
StackNode* StackTree::record()
|
||||
{
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
static const u32 UNINITIALIZED_MEMORY_PATTERN = 0xCD;
|
||||
static const u32 FREED_MEMORY_PATTERN = 0xDD;
|
||||
static const u32 ALLOCATION_GUARD = 0xFDFDFDFD;
|
||||
|
||||
|
||||
Allocator::Allocator(IAllocator& source)
|
||||
: m_source(source)
|
||||
, m_root(nullptr)
|
||||
, m_mutex(false)
|
||||
, m_stack_tree(LUMIX_NEW(m_source, Debug::StackTree))
|
||||
, m_total_size(0)
|
||||
, m_is_fill_enabled(true)
|
||||
, m_are_guards_enabled(true)
|
||||
{
|
||||
m_sentinels[0].m_next = &m_sentinels[1];
|
||||
m_sentinels[0].m_previous = nullptr;
|
||||
m_sentinels[0].m_stack_leaf = nullptr;
|
||||
m_sentinels[0].m_size = 0;
|
||||
|
||||
m_sentinels[1].m_next = nullptr;
|
||||
m_sentinels[1].m_previous = &m_sentinels[0];
|
||||
m_sentinels[1].m_stack_leaf = nullptr;
|
||||
m_sentinels[1].m_size = 0;
|
||||
|
||||
m_root = &m_sentinels[1];
|
||||
}
|
||||
|
||||
|
||||
Allocator::~Allocator()
|
||||
{
|
||||
AllocationInfo* last_sentinel = &m_sentinels[1];
|
||||
if (m_root != last_sentinel)
|
||||
{
|
||||
debugOutput("Memory leaks detected!\n");
|
||||
AllocationInfo* info = m_root;
|
||||
while (info != last_sentinel)
|
||||
{
|
||||
char tmp[2048];
|
||||
sprintf(tmp, "\nAllocation size : %zu, memory %p\n", info->m_size, info + sizeof(info));
|
||||
debugOutput(tmp);
|
||||
m_stack_tree->printCallstack(info->m_stack_leaf);
|
||||
info = info->m_next;
|
||||
}
|
||||
ASSERT(false);
|
||||
}
|
||||
LUMIX_DELETE(m_source, m_stack_tree);
|
||||
}
|
||||
|
||||
|
||||
void Allocator::lock()
|
||||
{
|
||||
m_mutex.lock();
|
||||
}
|
||||
|
||||
|
||||
void Allocator::unlock()
|
||||
{
|
||||
m_mutex.unlock();
|
||||
}
|
||||
|
||||
|
||||
void Allocator::checkGuards()
|
||||
{
|
||||
if (m_are_guards_enabled) return;
|
||||
|
||||
auto* info = m_root;
|
||||
while (info)
|
||||
{
|
||||
auto user_ptr = getUserPtrFromAllocationInfo(info);
|
||||
void* system_ptr = getSystemFromUser(user_ptr);
|
||||
ASSERT(*(u32*)system_ptr == ALLOCATION_GUARD);
|
||||
ASSERT(*(u32*)((u8*)user_ptr + info->m_size) == ALLOCATION_GUARD);
|
||||
|
||||
info = info->m_next;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
size_t Allocator::getAllocationOffset()
|
||||
{
|
||||
return sizeof(AllocationInfo) + (m_are_guards_enabled ? sizeof(ALLOCATION_GUARD) : 0);
|
||||
}
|
||||
|
||||
|
||||
size_t Allocator::getNeededMemory(size_t size)
|
||||
{
|
||||
return size + sizeof(AllocationInfo) +
|
||||
(m_are_guards_enabled ? sizeof(ALLOCATION_GUARD) << 1 : 0);
|
||||
}
|
||||
|
||||
|
||||
Allocator::AllocationInfo* Allocator::getAllocationInfoFromSystem(void* system_ptr)
|
||||
{
|
||||
return (AllocationInfo*)(m_are_guards_enabled ? (u8*)system_ptr + sizeof(ALLOCATION_GUARD)
|
||||
: system_ptr);
|
||||
}
|
||||
|
||||
|
||||
void* Allocator::getUserPtrFromAllocationInfo(AllocationInfo* info)
|
||||
{
|
||||
return ((u8*)info + sizeof(AllocationInfo));
|
||||
}
|
||||
|
||||
|
||||
Allocator::AllocationInfo* Allocator::getAllocationInfoFromUser(void* user_ptr)
|
||||
{
|
||||
return (AllocationInfo*)((u8*)user_ptr - sizeof(AllocationInfo));
|
||||
}
|
||||
|
||||
|
||||
void* Allocator::getUserFromSystem(void* system_ptr)
|
||||
{
|
||||
return (u8*)system_ptr + (m_are_guards_enabled ? sizeof(ALLOCATION_GUARD) : 0) +
|
||||
sizeof(AllocationInfo);
|
||||
}
|
||||
|
||||
|
||||
void* Allocator::getSystemFromUser(void* user_ptr)
|
||||
{
|
||||
return (u8*)user_ptr - (m_are_guards_enabled ? sizeof(ALLOCATION_GUARD) : 0) -
|
||||
sizeof(AllocationInfo);
|
||||
}
|
||||
|
||||
|
||||
void* Allocator::reallocate(void* user_ptr, size_t size)
|
||||
{
|
||||
#ifndef _DEBUG
|
||||
return m_source.reallocate(user_ptr, size);
|
||||
#else
|
||||
if (user_ptr == nullptr) return allocate(size);
|
||||
if (size == 0) return nullptr;
|
||||
|
||||
void* new_data = allocate(size);
|
||||
if (!new_data) return nullptr;
|
||||
|
||||
AllocationInfo* info = getAllocationInfoFromUser(user_ptr);
|
||||
copyMemory(new_data, user_ptr, info->m_size < size ? info->m_size : size);
|
||||
|
||||
deallocate(user_ptr);
|
||||
|
||||
return new_data;
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
void* Allocator::allocate_aligned(size_t size, size_t align)
|
||||
{
|
||||
return m_source.allocate_aligned(size, align);
|
||||
}
|
||||
|
||||
|
||||
void Allocator::deallocate_aligned(void* ptr)
|
||||
{
|
||||
m_source.deallocate_aligned(ptr);
|
||||
}
|
||||
|
||||
|
||||
void* Allocator::reallocate_aligned(void* ptr, size_t size, size_t align)
|
||||
{
|
||||
return m_source.reallocate_aligned(ptr, size, align);
|
||||
}
|
||||
|
||||
|
||||
void* Allocator::allocate(size_t size)
|
||||
{
|
||||
#ifndef _DEBUG
|
||||
return m_source.allocate(size);
|
||||
#else
|
||||
void* system_ptr;
|
||||
AllocationInfo* info;
|
||||
size_t system_size = getNeededMemory(size);
|
||||
{
|
||||
MT::SpinLock lock(m_mutex);
|
||||
system_ptr = m_source.allocate(system_size);
|
||||
info = new (NewPlaceholder(), getAllocationInfoFromSystem(system_ptr)) AllocationInfo();
|
||||
|
||||
info->m_previous = m_root->m_previous;
|
||||
m_root->m_previous->m_next = info;
|
||||
|
||||
info->m_next = m_root;
|
||||
m_root->m_previous = info;
|
||||
|
||||
m_root = info;
|
||||
|
||||
m_total_size += size;
|
||||
} // because of the SpinLock
|
||||
|
||||
void* user_ptr = getUserFromSystem(system_ptr);
|
||||
info->m_stack_leaf = m_stack_tree->record();
|
||||
info->m_size = size;
|
||||
if (m_is_fill_enabled)
|
||||
{
|
||||
memset(user_ptr, UNINITIALIZED_MEMORY_PATTERN, size);
|
||||
}
|
||||
|
||||
if (m_are_guards_enabled)
|
||||
{
|
||||
*(u32*)system_ptr = ALLOCATION_GUARD;
|
||||
*(u32*)((u8*)system_ptr + system_size - sizeof(ALLOCATION_GUARD)) = ALLOCATION_GUARD;
|
||||
}
|
||||
|
||||
return user_ptr;
|
||||
#endif
|
||||
}
|
||||
|
||||
void Allocator::deallocate(void* user_ptr)
|
||||
{
|
||||
#ifndef _DEBUG
|
||||
m_source.deallocate(user_ptr);
|
||||
#else
|
||||
if (user_ptr)
|
||||
{
|
||||
AllocationInfo* info = getAllocationInfoFromUser(user_ptr);
|
||||
void* system_ptr = getSystemFromUser(user_ptr);
|
||||
if (m_is_fill_enabled)
|
||||
{
|
||||
memset(user_ptr, FREED_MEMORY_PATTERN, info->m_size);
|
||||
}
|
||||
|
||||
if (m_are_guards_enabled)
|
||||
{
|
||||
ASSERT(*(u32*)system_ptr == ALLOCATION_GUARD);
|
||||
ASSERT(*(u32*)((u8*)user_ptr + info->m_size) == ALLOCATION_GUARD);
|
||||
}
|
||||
|
||||
{
|
||||
MT::SpinLock lock(m_mutex);
|
||||
if (info == m_root)
|
||||
{
|
||||
m_root = info->m_next;
|
||||
}
|
||||
info->m_previous->m_next = info->m_next;
|
||||
info->m_next->m_previous = info->m_previous;
|
||||
|
||||
m_total_size -= info->m_size;
|
||||
} // because of the SpinLock
|
||||
|
||||
info->~AllocationInfo();
|
||||
|
||||
m_source.deallocate((void*)system_ptr);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
|
||||
} // namespace Debug
|
||||
|
||||
|
||||
|
||||
void enableCrashReporting(bool enable)
|
||||
{
|
||||
ASSERT(!enable); // not supported on asmjs
|
||||
g_is_crash_reporting_enabled = false;
|
||||
}
|
||||
|
||||
|
||||
void installUnhandledExceptionHandler()
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
} // namespace Lumix
|
|
@ -1,14 +0,0 @@
|
|||
#include "engine/debug/floating_points.h"
|
||||
#include <float.h>
|
||||
|
||||
namespace Lumix
|
||||
{
|
||||
|
||||
|
||||
void enableFloatingPointTraps(bool enable)
|
||||
{
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
|
||||
} // namespace Lumix
|
|
@ -786,6 +786,7 @@ public:
|
|||
{
|
||||
Universe* univ = LuaWrapper::checkArg<Universe*>(L, 1);
|
||||
int entity_index = LuaWrapper::checkArg<int>(L, 2);
|
||||
if (entity_index < 0) return 0;
|
||||
|
||||
if (lua_gettop(L) > 3)
|
||||
{
|
||||
|
|
|
@ -1,171 +0,0 @@
|
|||
#include "engine/fs/os_file.h"
|
||||
#include "engine/iallocator.h"
|
||||
#include "engine/string.h"
|
||||
#include "engine/lumix.h"
|
||||
#include <cstdio>
|
||||
#include <unistd.h>
|
||||
|
||||
|
||||
namespace Lumix
|
||||
{
|
||||
namespace FS
|
||||
{
|
||||
struct OsFileImpl
|
||||
{
|
||||
explicit OsFileImpl(IAllocator& allocator)
|
||||
: m_allocator(allocator)
|
||||
{
|
||||
}
|
||||
|
||||
IAllocator& m_allocator;
|
||||
FILE* m_file;
|
||||
};
|
||||
|
||||
OsFile::OsFile()
|
||||
{
|
||||
m_impl = nullptr;
|
||||
}
|
||||
|
||||
OsFile::~OsFile()
|
||||
{
|
||||
ASSERT(!m_impl);
|
||||
}
|
||||
|
||||
bool OsFile::open(const char* path, Mode mode, IAllocator& allocator)
|
||||
{
|
||||
FILE* fp = fopen(path, Mode::WRITE & mode ? "wb" : "rb");
|
||||
if (fp)
|
||||
{
|
||||
OsFileImpl* impl = LUMIX_NEW(allocator, OsFileImpl)(allocator);
|
||||
impl->m_file = fp;
|
||||
m_impl = impl;
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void OsFile::flush()
|
||||
{
|
||||
ASSERT(nullptr != m_impl);
|
||||
fflush(m_impl->m_file);
|
||||
}
|
||||
|
||||
void OsFile::close()
|
||||
{
|
||||
if (nullptr != m_impl)
|
||||
{
|
||||
fclose(m_impl->m_file);
|
||||
LUMIX_DELETE(m_impl->m_allocator, m_impl);
|
||||
m_impl = nullptr;
|
||||
}
|
||||
}
|
||||
|
||||
bool OsFile::writeText(const char* text)
|
||||
{
|
||||
int len = stringLength(text);
|
||||
return write(text, len);
|
||||
}
|
||||
|
||||
bool OsFile::write(const void* data, size_t size)
|
||||
{
|
||||
ASSERT(nullptr != m_impl);
|
||||
size_t written = fwrite(data, size, 1, m_impl->m_file);
|
||||
return written == 1;
|
||||
}
|
||||
|
||||
bool OsFile::read(void* data, size_t size)
|
||||
{
|
||||
ASSERT(nullptr != m_impl);
|
||||
size_t read = fread(data, size, 1, m_impl->m_file);
|
||||
return read == 1;
|
||||
}
|
||||
|
||||
size_t OsFile::size()
|
||||
{
|
||||
ASSERT(nullptr != m_impl);
|
||||
long pos = ftell(m_impl->m_file);
|
||||
fseek(m_impl->m_file, 0, SEEK_END);
|
||||
size_t size = (size_t)ftell(m_impl->m_file);
|
||||
fseek(m_impl->m_file, pos, SEEK_SET);
|
||||
return size;
|
||||
}
|
||||
|
||||
bool OsFile::fileExists(const char* path)
|
||||
{
|
||||
return access(path, F_OK) != -1;
|
||||
}
|
||||
|
||||
size_t OsFile::pos()
|
||||
{
|
||||
ASSERT(nullptr != m_impl);
|
||||
long pos = ftell(m_impl->m_file);
|
||||
return (size_t)pos;
|
||||
}
|
||||
|
||||
bool OsFile::seek(SeekMode base, size_t pos)
|
||||
{
|
||||
ASSERT(nullptr != m_impl);
|
||||
int dir = 0;
|
||||
switch (base)
|
||||
{
|
||||
case SeekMode::BEGIN:
|
||||
dir = SEEK_SET;
|
||||
break;
|
||||
case SeekMode::END:
|
||||
dir = SEEK_END;
|
||||
break;
|
||||
case SeekMode::CURRENT:
|
||||
dir = SEEK_CUR;
|
||||
break;
|
||||
}
|
||||
|
||||
return fseek(m_impl->m_file, pos, dir) == 0;
|
||||
}
|
||||
|
||||
|
||||
OsFile& OsFile::operator <<(const char* text)
|
||||
{
|
||||
write(text, stringLength(text));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
OsFile& OsFile::operator <<(i32 value)
|
||||
{
|
||||
char buf[20];
|
||||
toCString(value, buf, lengthOf(buf));
|
||||
write(buf, stringLength(buf));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
OsFile& OsFile::operator <<(u32 value)
|
||||
{
|
||||
char buf[20];
|
||||
toCString(value, buf, lengthOf(buf));
|
||||
write(buf, stringLength(buf));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
OsFile& OsFile::operator <<(u64 value)
|
||||
{
|
||||
char buf[30];
|
||||
toCString(value, buf, lengthOf(buf));
|
||||
write(buf, stringLength(buf));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
OsFile& OsFile::operator <<(float value)
|
||||
{
|
||||
char buf[30];
|
||||
toCString(value, buf, lengthOf(buf), 1);
|
||||
write(buf, stringLength(buf));
|
||||
return *this;
|
||||
}
|
||||
|
||||
|
||||
} // namespace FS
|
||||
} // namespace Lumix
|
|
@ -1,62 +0,0 @@
|
|||
#include "engine/mt/atomic.h"
|
||||
#include <SDL_atomic.h>
|
||||
|
||||
|
||||
namespace Lumix
|
||||
{
|
||||
namespace MT
|
||||
{
|
||||
|
||||
i32 atomicIncrement(i32 volatile* value)
|
||||
{
|
||||
ASSERT(false);
|
||||
return *value++;
|
||||
}
|
||||
|
||||
i32 atomicDecrement(i32 volatile* value)
|
||||
{
|
||||
ASSERT(false);
|
||||
return *value--;
|
||||
}
|
||||
|
||||
i32 atomicAdd(i32 volatile* addend, i32 value)
|
||||
{
|
||||
ASSERT(false);
|
||||
int tmp = *addend;
|
||||
*addend += value;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
i32 atomicSubtract(i32 volatile* addend, i32 value)
|
||||
{
|
||||
ASSERT(false);
|
||||
int tmp = *addend;
|
||||
*addend -= value;
|
||||
return tmp;
|
||||
}
|
||||
|
||||
bool compareAndExchange(i32 volatile* dest, i32 exchange, i32 comperand)
|
||||
{
|
||||
ASSERT(false);
|
||||
if (*dest != comperand) return false;
|
||||
*dest = exchange;
|
||||
return true;
|
||||
}
|
||||
|
||||
bool compareAndExchange64(i64 volatile* dest, i64 exchange, i64 comperand)
|
||||
{
|
||||
ASSERT(false);
|
||||
if (*dest != comperand) return false;
|
||||
*dest = exchange;
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
LUMIX_ENGINE_API void memoryBarrier()
|
||||
{
|
||||
SDL_CompilerBarrier();
|
||||
}
|
||||
|
||||
|
||||
} // ~namespace MT
|
||||
} // ~namespace Lumix
|
|
@ -1,138 +0,0 @@
|
|||
#include "engine/mt/sync.h"
|
||||
#include "engine/mt/atomic.h"
|
||||
#include "engine/mt/thread.h"
|
||||
|
||||
|
||||
namespace Lumix
|
||||
{
|
||||
namespace MT
|
||||
{
|
||||
|
||||
|
||||
Semaphore::Semaphore(int init_count, int /*max_count*/)
|
||||
{
|
||||
m_id = nullptr;
|
||||
}
|
||||
|
||||
Semaphore::~Semaphore()
|
||||
{
|
||||
}
|
||||
|
||||
void Semaphore::signal()
|
||||
{
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
void Semaphore::wait()
|
||||
{
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
bool Semaphore::poll()
|
||||
{
|
||||
ASSERT(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
Mutex::Mutex(bool locked)
|
||||
{
|
||||
m_id = nullptr;
|
||||
}
|
||||
|
||||
Mutex::~Mutex()
|
||||
{
|
||||
}
|
||||
|
||||
void Mutex::lock()
|
||||
{
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
|
||||
void Mutex::unlock()
|
||||
{
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
|
||||
Event::Event()
|
||||
{
|
||||
m_id = nullptr;
|
||||
}
|
||||
|
||||
Event::~Event()
|
||||
{
|
||||
}
|
||||
|
||||
void Event::reset()
|
||||
{
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
void Event::trigger()
|
||||
{
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
void Event::wait()
|
||||
{
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
bool Event::poll()
|
||||
{
|
||||
ASSERT(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
SpinMutex::SpinMutex(bool locked)
|
||||
: m_id(0)
|
||||
{
|
||||
if (locked)
|
||||
{
|
||||
lock();
|
||||
}
|
||||
}
|
||||
|
||||
SpinMutex::~SpinMutex()
|
||||
{
|
||||
}
|
||||
|
||||
void SpinMutex::lock()
|
||||
{
|
||||
for (;;)
|
||||
{
|
||||
if (compareAndExchange(&m_id, 1, 0))
|
||||
{
|
||||
memoryBarrier();
|
||||
return;
|
||||
}
|
||||
|
||||
while (m_id)
|
||||
{
|
||||
yield();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool SpinMutex::poll()
|
||||
{
|
||||
if (compareAndExchange(&m_id, 1, 0))
|
||||
{
|
||||
memoryBarrier();
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void SpinMutex::unlock()
|
||||
{
|
||||
memoryBarrier();
|
||||
m_id = 0;
|
||||
}
|
||||
|
||||
|
||||
} // namespace MT
|
||||
} // namespace Lumix
|
|
@ -1,77 +0,0 @@
|
|||
#include "engine/lumix.h"
|
||||
#include "engine/iallocator.h"
|
||||
#include "engine/mt/task.h"
|
||||
#include "engine/mt/thread.h"
|
||||
#include "engine/profiler.h"
|
||||
|
||||
|
||||
namespace Lumix
|
||||
{
|
||||
namespace MT
|
||||
{
|
||||
|
||||
struct TaskImpl
|
||||
{
|
||||
IAllocator& allocator;
|
||||
};
|
||||
|
||||
Task::Task(IAllocator& allocator)
|
||||
{
|
||||
m_implementation = LUMIX_NEW(allocator, TaskImpl) {allocator};
|
||||
}
|
||||
|
||||
Task::~Task()
|
||||
{
|
||||
LUMIX_DELETE(m_implementation->allocator, m_implementation);
|
||||
}
|
||||
|
||||
bool Task::create(const char* name)
|
||||
{
|
||||
ASSERT(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Task::destroy()
|
||||
{
|
||||
ASSERT(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
void Task::setAffinityMask(u32 affinity_mask)
|
||||
{
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
u32 Task::getAffinityMask() const
|
||||
{
|
||||
ASSERT(false);
|
||||
return 0;
|
||||
}
|
||||
|
||||
bool Task::isRunning() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Task::isFinished() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
bool Task::isForceExit() const
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
IAllocator& Task::getAllocator()
|
||||
{
|
||||
return m_implementation->allocator;
|
||||
}
|
||||
|
||||
void Task::forceExit(bool wait)
|
||||
{
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
} // namespace MT
|
||||
} // namespace Lumix
|
|
@ -1,41 +0,0 @@
|
|||
#include "engine/lumix.h"
|
||||
#include "engine/mt/thread.h"
|
||||
#include <SDL_cpuinfo.h>
|
||||
#include <SDL_timer.h>
|
||||
|
||||
|
||||
namespace Lumix
|
||||
{
|
||||
namespace MT
|
||||
{
|
||||
|
||||
|
||||
void sleep(u32 milliseconds)
|
||||
{
|
||||
SDL_Delay(milliseconds);
|
||||
}
|
||||
|
||||
u32 getCPUsCount()
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
u32 getCurrentThreadID()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
u32 getProccessAffinityMask()
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
void setThreadName(u32 /*thread_id*/, const char* /*thread_name*/)
|
||||
{
|
||||
ASSERT(false);
|
||||
}
|
||||
|
||||
|
||||
} //! namespace MT
|
||||
} //! namespace Lumix
|
|
@ -466,7 +466,7 @@ struct CommonProperty : Property<T>
|
|||
};
|
||||
|
||||
|
||||
template <typename Counter, typename Adder, typename Remover, typename... Properties>
|
||||
template <typename Counter, typename Adder, typename Remover, typename... Props>
|
||||
struct ArrayProperty : IArrayProperty
|
||||
{
|
||||
ArrayProperty() {}
|
||||
|
@ -571,14 +571,14 @@ struct ArrayProperty : IArrayProperty
|
|||
void visit(IAttributeVisitor& visitor) const override {}
|
||||
|
||||
|
||||
Tuple<Properties...> properties;
|
||||
Tuple<Props...> properties;
|
||||
Counter counter;
|
||||
Adder adder;
|
||||
Remover remover;
|
||||
};
|
||||
|
||||
|
||||
template <typename Counter, typename... Properties>
|
||||
template <typename Counter, typename... Props>
|
||||
struct ConstArrayProperty : IArrayProperty
|
||||
{
|
||||
ConstArrayProperty() {}
|
||||
|
@ -667,7 +667,7 @@ struct ConstArrayProperty : IArrayProperty
|
|||
}
|
||||
|
||||
|
||||
Tuple<Properties...> properties;
|
||||
Tuple<Props...> properties;
|
||||
Counter counter;
|
||||
};
|
||||
|
||||
|
@ -677,7 +677,7 @@ struct Scene
|
|||
{
|
||||
void registerScene()
|
||||
{
|
||||
apply([&](auto& cmp) { Properties::registerComponent(&cmp); }, components);
|
||||
apply([&](auto& cmp) { registerComponent(&cmp); }, components);
|
||||
}
|
||||
|
||||
|
||||
|
@ -686,10 +686,10 @@ struct Scene
|
|||
};
|
||||
|
||||
|
||||
template <typename... Properties>
|
||||
template <typename... Props>
|
||||
struct Component : ComponentBase
|
||||
{
|
||||
int getPropertyCount() const override { return sizeof...(Properties); }
|
||||
int getPropertyCount() const override { return sizeof...(Props); }
|
||||
|
||||
|
||||
void visit(IComponentVisitor& visitor) const override
|
||||
|
@ -700,7 +700,7 @@ struct Component : ComponentBase
|
|||
}
|
||||
|
||||
|
||||
Tuple<Properties...> properties;
|
||||
Tuple<Props...> properties;
|
||||
};
|
||||
|
||||
|
||||
|
@ -714,13 +714,13 @@ auto scene(const char* name, Components... components)
|
|||
}
|
||||
|
||||
|
||||
template <typename... Properties>
|
||||
auto component(const char* name, Properties... props)
|
||||
template <typename... Props>
|
||||
auto component(const char* name, Props... props)
|
||||
{
|
||||
Component<Properties...> cmp;
|
||||
Component<Props...> cmp;
|
||||
cmp.name = name;
|
||||
cmp.properties = makeTuple(props...);
|
||||
cmp.component_type = Properties::getComponentType(name);
|
||||
cmp.component_type = getComponentType(name);
|
||||
return cmp;
|
||||
}
|
||||
|
||||
|
@ -790,10 +790,10 @@ auto dyn_enum_property(const char* name, Getter getter, Setter setter, Counter c
|
|||
}
|
||||
|
||||
|
||||
template <typename Counter, typename Adder, typename Remover, typename... Properties>
|
||||
auto array(const char* name, Counter counter, Adder adder, Remover remover, Properties... properties)
|
||||
template <typename Counter, typename Adder, typename Remover, typename... Props>
|
||||
auto array(const char* name, Counter counter, Adder adder, Remover remover, Props... properties)
|
||||
{
|
||||
ArrayProperty<Counter, Adder, Remover, Properties...> p;
|
||||
ArrayProperty<Counter, Adder, Remover, Props...> p;
|
||||
p.name = name;
|
||||
p.counter = counter;
|
||||
p.adder = adder;
|
||||
|
@ -803,10 +803,10 @@ auto array(const char* name, Counter counter, Adder adder, Remover remover, Prop
|
|||
}
|
||||
|
||||
|
||||
template <typename Counter, typename... Properties>
|
||||
auto const_array(const char* name, Counter counter, Properties... properties)
|
||||
template <typename Counter, typename... Props>
|
||||
auto const_array(const char* name, Counter counter, Props... properties)
|
||||
{
|
||||
ConstArrayProperty<Counter, Properties...> p;
|
||||
ConstArrayProperty<Counter, Props...> p;
|
||||
p.name = name;
|
||||
p.counter = counter;
|
||||
p.properties = makeTuple(properties...);
|
||||
|
|
Loading…
Reference in a new issue