From cf37e9cbe6166534a8e733d79aec887fe0b9b85c Mon Sep 17 00:00:00 2001 From: Ykkrosh Date: Mon, 27 Jun 2005 23:04:34 +0000 Subject: [PATCH] Atlas: Added a button. Reorganised game<->UI communication system. main.cpp: Allowed correct operation when not calling Init/Shutdown. Game.cpp: Stopped complaint when starting game with no GUI. This was SVN commit r2446. --- source/main.cpp | 11 +- source/ps/Game.cpp | 12 +- source/tests/Tests.cpp | 20 ++- source/tools/atlas/Atlas.sln | 19 +++ source/tools/atlas/AtlasUI/AtlasUI.vcproj | 48 ++++++- .../CustomControls/Buttons/ActionButton.cpp | 7 + .../CustomControls/Buttons/ActionButton.h | 25 ++++ .../SnapSplitterWindow/SnapSplitterWindow.cpp | 37 +++++ .../SnapSplitterWindow/SnapSplitterWindow.h | 17 +++ .../tools/atlas/AtlasUI/Misc/DLLInterface.cpp | 8 +- source/tools/atlas/AtlasUI/Misc/stdafx.h | 1 + .../AtlasUI/ScenarioEditor/ScenarioEditor.cpp | 49 +++++-- source/tools/atlas/GameInterface/GameLoop.cpp | 136 ++++++++---------- source/tools/atlas/GameInterface/GameLoop.h | 11 +- .../GameInterface/Handlers/GraphicsSetup.cpp | 95 ++++++++++++ .../atlas/GameInterface/Handlers/Map.cpp | 29 ++++ .../GameInterface/Handlers/MessageHandler.cpp | 16 +++ .../GameInterface/Handlers/MessageHandler.h | 18 +++ .../{MessageHandler.h => MessagePasser.h} | 11 +- ...eHandlerImpl.cpp => MessagePasserImpl.cpp} | 12 +- ...ssageHandlerImpl.h => MessagePasserImpl.h} | 4 +- source/tools/atlas/GameInterface/Messages.h | 54 ++++--- 22 files changed, 498 insertions(+), 142 deletions(-) create mode 100644 source/tools/atlas/AtlasUI/CustomControls/Buttons/ActionButton.cpp create mode 100644 source/tools/atlas/AtlasUI/CustomControls/Buttons/ActionButton.h create mode 100644 source/tools/atlas/AtlasUI/CustomControls/SnapSplitterWindow/SnapSplitterWindow.cpp create mode 100644 source/tools/atlas/AtlasUI/CustomControls/SnapSplitterWindow/SnapSplitterWindow.h create mode 100644 source/tools/atlas/GameInterface/Handlers/GraphicsSetup.cpp create mode 100644 source/tools/atlas/GameInterface/Handlers/Map.cpp create mode 100644 source/tools/atlas/GameInterface/Handlers/MessageHandler.cpp create mode 100644 source/tools/atlas/GameInterface/Handlers/MessageHandler.h rename source/tools/atlas/GameInterface/{MessageHandler.h => MessagePasser.h} (57%) rename source/tools/atlas/GameInterface/{MessageHandlerImpl.cpp => MessagePasserImpl.cpp} (50%) rename source/tools/atlas/GameInterface/{MessageHandlerImpl.h => MessagePasserImpl.h} (73%) diff --git a/source/main.cpp b/source/main.cpp index 2cccd9c654..9d7a737d85 100755 --- a/source/main.cpp +++ b/source/main.cpp @@ -1,7 +1,5 @@ #include "precompiled.h" -//#define ATLAS - #ifdef SCED # include "ui/StdAfx.h" # undef ERROR @@ -132,7 +130,7 @@ extern size_t frameCount; static bool quit = false; // break out of main loop #ifdef ATLAS -static bool g_Atlas = true; // allows startup in Atlas vs non-Atlas (game) modes +static bool g_Atlas = true; // allows optional startup in Atlas vs non-Atlas (game) modes #endif @@ -923,6 +921,9 @@ static void InitPs() } // Temporary hack until revised GUI structure is completed. +#ifdef ATLAS + if (! g_Atlas) +#endif { // TIMER(ps_gui_hack) @@ -1136,6 +1137,8 @@ static void Shutdown() mem_shutdown(); delete &g_Logger; + + delete &g_Profiler; } @@ -1514,8 +1517,6 @@ int main(int argc, char* argv[]) Shutdown(); } - delete &g_Profiler; - exit(0); } diff --git a/source/ps/Game.cpp b/source/ps/Game.cpp index f3e1962978..bf06b7cfbc 100755 --- a/source/ps/Game.cpp +++ b/source/ps/Game.cpp @@ -65,12 +65,16 @@ PSRETURN CGame::RegisterInit(CGameAttributes* pAttribs) PSRETURN CGame::ReallyStartGame() { #ifndef NO_GUI - jsval rval; - - JSBool ok = JS_CallFunctionName(g_ScriptingHost.getContext(), - g_GUI.GetScriptObject(), "reallyStartGame", 0, NULL, &rval); + // Call the reallyStartGame function, but only if it exists + jsval fval, rval; + JSBool ok = JS_GetProperty(g_ScriptingHost.getContext(), g_GUI.GetScriptObject(), "reallyStartGame", &fval); assert(ok); + if (ok && !JSVAL_IS_VOID(fval)) + { + ok = JS_CallFunctionValue(g_ScriptingHost.getContext(), g_GUI.GetScriptObject(), fval, 0, NULL, &rval); + assert(ok); + } #endif debug_printf("GAME STARTED, ALL INIT COMPLETE\n"); diff --git a/source/tests/Tests.cpp b/source/tests/Tests.cpp index 0653f4bd5d..46255aad51 100755 --- a/source/tests/Tests.cpp +++ b/source/tests/Tests.cpp @@ -3,6 +3,7 @@ #include "ps/CLogger.h" #include "ps/Parser.h" #include "ps/XMLWriter.h" +#include "maths/Matrix3D.h" #define ensure(x) if (!(x)) { ++err_count; LOG(ERROR, "", "%s:%d - test failed! (%s)", __FILE__, __LINE__, #x); } @@ -157,4 +158,21 @@ void PerformTests() ensure(memcmp(str_utf8.data(), chr_utf8, sizeof(chr_utf8)) == 0); ensure(str_utf8.FromUTF8() == str_utf16); } -} \ No newline at end of file + + { + CMatrix3D m; + srand(0); + for (int i = 0; i < 4; ++i) + { + for (int j = 0; j < 16; ++j) + m._data[j] = -1.0f + 2.0f*(rand()/(float)RAND_MAX); + CMatrix3D n; + m.GetInverse(n); + m *= n; + for (int x = 0; x < 4; ++x) + for (int y = 0; y < 4; ++y) + ensure(abs(m(x,y) - (x==y ? 1.0f : 0.0f)) < 0.0001f); + } + + } +} diff --git a/source/tools/atlas/Atlas.sln b/source/tools/atlas/Atlas.sln index 4676956056..2b9f5ed63d 100644 --- a/source/tools/atlas/Atlas.sln +++ b/source/tools/atlas/Atlas.sln @@ -18,28 +18,47 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ColourTester", "AtlasFronte {E99BA969-D540-4F23-822E-37C499E8F704} = {E99BA969-D540-4F23-822E-37C499E8F704} EndProjectSection EndProject +Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pyrogenesis", "..\..\..\build\workspaces\vc2003\pyrogenesis.vcproj", "{CDA14ADB-57CA-DB49-A474-E7605D7922BD}" + ProjectSection(ProjectDependencies) = postProject + EndProjectSection +EndProject Global GlobalSection(SolutionConfiguration) = preSolution Debug = Debug Release = Release + Testing = Testing EndGlobalSection GlobalSection(ProjectConfiguration) = postSolution {E99BA969-D540-4F23-822E-37C499E8F704}.Debug.ActiveCfg = Debug|Win32 {E99BA969-D540-4F23-822E-37C499E8F704}.Debug.Build.0 = Debug|Win32 {E99BA969-D540-4F23-822E-37C499E8F704}.Release.ActiveCfg = Release|Win32 {E99BA969-D540-4F23-822E-37C499E8F704}.Release.Build.0 = Release|Win32 + {E99BA969-D540-4F23-822E-37C499E8F704}.Testing.ActiveCfg = Release|Win32 + {E99BA969-D540-4F23-822E-37C499E8F704}.Testing.Build.0 = Release|Win32 {228B468D-3C2E-45BF-9833-C626E1A35B04}.Debug.ActiveCfg = Debug|Win32 {228B468D-3C2E-45BF-9833-C626E1A35B04}.Debug.Build.0 = Debug|Win32 {228B468D-3C2E-45BF-9833-C626E1A35B04}.Release.ActiveCfg = Release|Win32 {228B468D-3C2E-45BF-9833-C626E1A35B04}.Release.Build.0 = Release|Win32 + {228B468D-3C2E-45BF-9833-C626E1A35B04}.Testing.ActiveCfg = Release|Win32 + {228B468D-3C2E-45BF-9833-C626E1A35B04}.Testing.Build.0 = Release|Win32 {E859DDC0-224A-41F6-B09F-E320EC8DDA35}.Debug.ActiveCfg = Debug|Win32 {E859DDC0-224A-41F6-B09F-E320EC8DDA35}.Debug.Build.0 = Debug|Win32 {E859DDC0-224A-41F6-B09F-E320EC8DDA35}.Release.ActiveCfg = Release|Win32 {E859DDC0-224A-41F6-B09F-E320EC8DDA35}.Release.Build.0 = Release|Win32 + {E859DDC0-224A-41F6-B09F-E320EC8DDA35}.Testing.ActiveCfg = Debug|Win32 + {E859DDC0-224A-41F6-B09F-E320EC8DDA35}.Testing.Build.0 = Debug|Win32 {C018BE85-EBFE-428E-8626-3CCB77052715}.Debug.ActiveCfg = Debug|Win32 {C018BE85-EBFE-428E-8626-3CCB77052715}.Debug.Build.0 = Debug|Win32 {C018BE85-EBFE-428E-8626-3CCB77052715}.Release.ActiveCfg = Release|Win32 {C018BE85-EBFE-428E-8626-3CCB77052715}.Release.Build.0 = Release|Win32 + {C018BE85-EBFE-428E-8626-3CCB77052715}.Testing.ActiveCfg = Debug|Win32 + {C018BE85-EBFE-428E-8626-3CCB77052715}.Testing.Build.0 = Debug|Win32 + {CDA14ADB-57CA-DB49-A474-E7605D7922BD}.Debug.ActiveCfg = Debug|Win32 + {CDA14ADB-57CA-DB49-A474-E7605D7922BD}.Debug.Build.0 = Debug|Win32 + {CDA14ADB-57CA-DB49-A474-E7605D7922BD}.Release.ActiveCfg = Release|Win32 + {CDA14ADB-57CA-DB49-A474-E7605D7922BD}.Release.Build.0 = Release|Win32 + {CDA14ADB-57CA-DB49-A474-E7605D7922BD}.Testing.ActiveCfg = Testing|Win32 + {CDA14ADB-57CA-DB49-A474-E7605D7922BD}.Testing.Build.0 = Testing|Win32 EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution EndGlobalSection diff --git a/source/tools/atlas/AtlasUI/AtlasUI.vcproj b/source/tools/atlas/AtlasUI/AtlasUI.vcproj index 8f29f3e77b..1c8b2809e1 100644 --- a/source/tools/atlas/AtlasUI/AtlasUI.vcproj +++ b/source/tools/atlas/AtlasUI/AtlasUI.vcproj @@ -19,7 +19,7 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + = m_DefaultSashPosition-m_SnapTolerance && + evt.GetSashPosition() <= m_DefaultSashPosition+m_SnapTolerance) + { + evt.SetSashPosition(m_DefaultSashPosition); + } +} diff --git a/source/tools/atlas/AtlasUI/CustomControls/SnapSplitterWindow/SnapSplitterWindow.h b/source/tools/atlas/AtlasUI/CustomControls/SnapSplitterWindow/SnapSplitterWindow.h new file mode 100644 index 0000000000..5552a437df --- /dev/null +++ b/source/tools/atlas/AtlasUI/CustomControls/SnapSplitterWindow/SnapSplitterWindow.h @@ -0,0 +1,17 @@ +#include "wx/splitter.h" + +class SnapSplitterWindow : public wxSplitterWindow +{ +public: + SnapSplitterWindow(wxWindow* parent); + virtual bool SplitVertically(wxWindow *window1, wxWindow *window2, int sashPosition); + virtual bool SplitHorizontally(wxWindow *window1, wxWindow *window2, int sashPosition); + +private: + void OnSashPosChanging(wxSplitterEvent& evt); + + int m_DefaultSashPosition; + int m_SnapTolerance; + + DECLARE_EVENT_TABLE(); +}; diff --git a/source/tools/atlas/AtlasUI/Misc/DLLInterface.cpp b/source/tools/atlas/AtlasUI/Misc/DLLInterface.cpp index 81d91a1d29..2ab2ec399d 100644 --- a/source/tools/atlas/AtlasUI/Misc/DLLInterface.cpp +++ b/source/tools/atlas/AtlasUI/Misc/DLLInterface.cpp @@ -7,7 +7,7 @@ #include "ColourTester/ColourTester.h" #include "ScenarioEditor/ScenarioEditor.h" -#include "GameInterface/MessageHandler.h" +#include "GameInterface/MessagePasser.h" #include "wx/config.h" @@ -37,11 +37,11 @@ BOOL APIENTRY DllMain(HINSTANCE hModule, DWORD fdwReason, LPVOID WXUNUSED(lpRese return TRUE; } -AtlasMessage::MessageHandler* AtlasMessage::g_MessageHandler = NULL; +AtlasMessage::MessagePasser* AtlasMessage::g_MessagePasser = NULL; -ATLASDLLIMPEXP void Atlas_SetMessageHandler(AtlasMessage::MessageHandler* handler) +ATLASDLLIMPEXP void Atlas_SetMessagePasser(AtlasMessage::MessagePasser* handler) { - AtlasMessage::g_MessageHandler = handler; + AtlasMessage::g_MessagePasser = handler; } ATLASDLLIMPEXP void Atlas_StartWindow(wchar_t* type) diff --git a/source/tools/atlas/AtlasUI/Misc/stdafx.h b/source/tools/atlas/AtlasUI/Misc/stdafx.h index c2c2763f2b..11c2a56a19 100644 --- a/source/tools/atlas/AtlasUI/Misc/stdafx.h +++ b/source/tools/atlas/AtlasUI/Misc/stdafx.h @@ -22,6 +22,7 @@ #include "wx/colordlg.h" #include "wx/regex.h" #include "wx/image.h" +#include "wx/splitter.h" #include #include diff --git a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp index d0d4038ef4..4ab19d45a1 100644 --- a/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp +++ b/source/tools/atlas/AtlasUI/ScenarioEditor/ScenarioEditor.cpp @@ -3,10 +3,15 @@ #include "ScenarioEditor.h" #include "wx/glcanvas.h" +#include "CustomControls/SnapSplitterWindow/SnapSplitterWindow.h" -#include "GameInterface/MessageHandler.h" +#include "GameInterface/MessagePasser.h" #include "GameInterface/Messages.h" +#include "Sections/Map/Map.h" + +//#define UI_ONLY + ////////////////////////////////////////////////////////////////////////// class Canvas : public wxGLCanvas @@ -20,8 +25,10 @@ public: void OnResize(wxSizeEvent&) { + // Be careful not to send 'resize' messages to the game before we've + // told it that this canvas exists if (! m_SuppressResize) - AtlasMessage::g_MessageHandler->Add(new AtlasMessage::mResizeScreen(GetSize().GetWidth(), GetSize().GetHeight())); + AtlasMessage::g_MessagePasser->Add(new AtlasMessage::mResizeScreen(GetSize().GetWidth(), GetSize().GetHeight())); } void InitSize() @@ -41,44 +48,56 @@ END_EVENT_TABLE() ////////////////////////////////////////////////////////////////////////// BEGIN_EVENT_TABLE(ScenarioEditor, wxFrame) -EVT_CLOSE(ScenarioEditor::OnClose) + EVT_CLOSE(ScenarioEditor::OnClose) END_EVENT_TABLE() ScenarioEditor::ScenarioEditor() -: wxFrame(NULL, wxID_ANY, _("Atlas - Scenario Editor")) +: wxFrame(NULL, wxID_ANY, _("Atlas - Scenario Editor"), wxDefaultPosition, wxSize(1024, 768)) { - wxPanel* panel = new wxPanel(this); - wxBoxSizer* sizer = new wxBoxSizer(wxVERTICAL); - panel->SetSizer(sizer); + SnapSplitterWindow* splitter = new SnapSplitterWindow(this); + + // Set up GL canvas: int glAttribList[] = { WX_GL_RGBA, WX_GL_DOUBLEBUFFER, - WX_GL_DEPTH_SIZE, 24, + WX_GL_DEPTH_SIZE, 24, // TODO: wx documentation doesn't say this is valid 0 }; - Canvas* canvas = new Canvas(panel, glAttribList); + Canvas* canvas = new Canvas(splitter, glAttribList); // The canvas' context gets made current on creation; but it can only be // current for one thread at a time, and it needs to be current for the // thread that is doing the draw calls, so disable it for this one. wglMakeCurrent(NULL, NULL); - sizer->Add(canvas, wxSizerFlags().Proportion(1).Expand()); + // Set up sidebars: - AtlasMessage::g_MessageHandler->Add(new AtlasMessage::mSetContext(canvas->GetHDC(), canvas->GetContext()->GetGLRC())); + Sidebar* sidebar = new MapSidebar(splitter); - AtlasMessage::g_MessageHandler->Add(new AtlasMessage::mCommandString("init")); + // Build layout: + + splitter->SplitVertically(sidebar, canvas, 200); + + // Send setup messages to game engine: + +#ifndef UI_ONLY + ADD_MESSAGE(SetContext(canvas->GetHDC(), canvas->GetContext()->GetGLRC())); + + ADD_MESSAGE(CommandString("init")); canvas->InitSize(); - AtlasMessage::g_MessageHandler->Add(new AtlasMessage::mCommandString("render_enable")); + ADD_MESSAGE(CommandString("render_enable")); +#endif } void ScenarioEditor::OnClose(wxCloseEvent&) { - AtlasMessage::g_MessageHandler->Add(new AtlasMessage::mCommandString("shutdown")); - AtlasMessage::g_MessageHandler->Add(new AtlasMessage::mCommandString("exit")); +#ifndef UI_ONLY + ADD_MESSAGE(CommandString("shutdown")); +#endif + ADD_MESSAGE(CommandString("exit")); // TODO: What if it's still rendering while we're destroying the canvas? Destroy(); diff --git a/source/tools/atlas/GameInterface/GameLoop.cpp b/source/tools/atlas/GameInterface/GameLoop.cpp index c7c2ccbf09..3876287fd8 100644 --- a/source/tools/atlas/GameInterface/GameLoop.cpp +++ b/source/tools/atlas/GameInterface/GameLoop.cpp @@ -1,20 +1,31 @@ #include "precompiled.h" -#include "MessageHandlerImpl.h" +#include "GameLoop.h" + +#include "MessagePasserImpl.h" #include "Messages.h" +#include "handlers/MessageHandler.h" #include "lib/sdl.h" #include "lib/ogl.h" #include "ps/CLogger.h" -#include "gui/GUI.h" -#include "renderer/Renderer.h" +//#include "gui/GUI.h" +//#include "renderer/Renderer.h" +//#include "ps/Game.h" +//#include "ps/Loader.h" + +#ifdef NDEBUG +#pragma comment(lib, "AtlasUI") +#else +#pragma comment(lib, "AtlasUI_d") +#endif using namespace AtlasMessage; extern __declspec(dllimport) void Atlas_StartWindow(wchar_t* type); -extern __declspec(dllimport) void Atlas_SetMessageHandler(MessageHandler*); +extern __declspec(dllimport) void Atlas_SetMessagePasser(MessagePasser*); -static MessageHandlerImpl msgHandler; +static MessagePasserImpl msgPasser; static void* LaunchWindow(void*) { @@ -22,111 +33,78 @@ static void* LaunchWindow(void*) return NULL; } -extern void Init_(int argc, char** argv, bool setup_gfx); -extern void Shutdown_(); extern void Render_(); -extern int g_xres, g_yres; +//extern int g_xres, g_yres; extern "C" { __declspec(dllimport) int __stdcall SwapBuffers(void*); } // HACK (and not exactly portable) // // (Er, actually that's what most of this file is. Oh well.) +static GameLoopState state; +GameLoopState* g_GameLoop = &state; + void BeginAtlas(int argc, char** argv) { - Atlas_SetMessageHandler(&msgHandler); + // Pass our message handler to Atlas + Atlas_SetMessagePasser(&msgPasser); + // Create a new thread, and launch the Atlas window inside that thread pthread_t gameThread; pthread_create(&gameThread, NULL, LaunchWindow, NULL); - bool running = true; - bool rendering = false; - HDC currentDC = NULL; + state.argc = argc; + state.argv = argv; + state.running = true; + state.rendering = false; + state.currentDC = NULL; - while (running) + while (state.running) { IMessage* msg; - while (msg = msgHandler.Retrieve()) + while (msg = msgPasser.Retrieve()) { - switch (msg->GetType()) + std::string name (msg->GetType()); + + if (name == "CommandString") { - case CommandString: - { - mCommandString* cmd = static_cast(msg); - - if (cmd->name == "init") - { - oglInit(); - Init_(argc, argv, false); - } - else if (cmd->name == "render_enable") - { - rendering = true; - } - else if (cmd->name == "render_disable") - { - rendering = false; - } - else if (cmd->name == "shutdown") - { - Shutdown_(); - } - else if (cmd->name == "exit") - { - running = false; - } - else - { - LOG(ERROR, "atlas", "Unrecognised command string (%s)", cmd->name.c_str()); - } - } - break; - - case SetContext: - { - mSetContext* cmd = static_cast(msg); - // TODO: portability - wglMakeCurrent(cmd->hdc, cmd->hglrc); - currentDC = cmd->hdc; - } - break; - - case ResizeScreen: - { - mResizeScreen* cmd = static_cast(msg); - g_xres = cmd->width; - g_yres = cmd->height; - if (g_xres == 0) g_xres = 160; - if (g_yres == 0) g_yres = 120; - SViewPort vp; - vp.m_X = vp.m_Y = 0; - vp.m_Width = g_xres; - vp.m_Height = g_yres; - g_Renderer.SetViewport(vp); - g_GUI.UpdateResolution(); - } - break; - - default: - LOG(ERROR, "atlas", "Unrecognised message (%d)", msg->GetType()); - break; + // Allow some laziness: For commands that don't need any data other + // than their name, we just use CommandString (and then need to + // construct a reference to the appropriate handler for the + // given string) + name += "_"; + name += static_cast(msg)->name; + // use 'static_cast' when casting messages, to make it clear + // that it's slightly dangerous - we have to just assume that + // GetType is correct, since we can't use proper RTTI + } + handlers::const_iterator it = GetHandlers().find(name); + if (it != GetHandlers().end()) + { + it->second(msg); + } + else + { + debug_warn("Unrecognised message"); + // TODO: CLogger might not be initialised + LOG(ERROR, "atlas", "Unrecognised message (%s)", name.c_str()); } delete msg; } - if (! running) + if (! state.running) break; - if (rendering) + if (state.rendering) { Render_(); - SwapBuffers(currentDC); + SwapBuffers(state.currentDC); } - SDL_Delay(100); + SDL_Delay(50); } pthread_join(gameThread, NULL); diff --git a/source/tools/atlas/GameInterface/GameLoop.h b/source/tools/atlas/GameInterface/GameLoop.h index 0519ecba6e..9251b3b19a 100644 --- a/source/tools/atlas/GameInterface/GameLoop.h +++ b/source/tools/atlas/GameInterface/GameLoop.h @@ -1 +1,10 @@ - \ No newline at end of file +struct GameLoopState +{ + int argc; + char** argv; + bool running; + bool rendering; + void* currentDC; +}; + +extern GameLoopState* g_GameLoop; \ No newline at end of file diff --git a/source/tools/atlas/GameInterface/Handlers/GraphicsSetup.cpp b/source/tools/atlas/GameInterface/Handlers/GraphicsSetup.cpp new file mode 100644 index 0000000000..35d9668a0d --- /dev/null +++ b/source/tools/atlas/GameInterface/Handlers/GraphicsSetup.cpp @@ -0,0 +1,95 @@ +#include "precompiled.h" + +#include "MessageHandler.h" +#include "../GameLoop.h" + +#include "renderer/Renderer.h" +#include "gui/GUI.h" +#include "ps/Game.h" +#include "ps/Loader.h" + +extern int g_xres, g_yres; + +extern void Init_(int argc, char** argv, bool setup_gfx); +extern void Shutdown_(); + + +namespace AtlasMessage { + + +void fCommandString_init(IMessage*) +{ + oglInit(); + Init_(g_GameLoop->argc, g_GameLoop->argv, false); + + // Set attributes for the game: + g_GameAttributes.m_MapFile = L""; // start without a map + for (int i=1; i<8; ++i) + g_GameAttributes.GetSlot(i)->AssignLocal(); + + g_Game = new CGame(); + PSRETURN ret = g_Game->StartGame(&g_GameAttributes); + assert(ret == PSRETURN_OK); + LDR_NonprogressiveLoad(); + ret = g_Game->ReallyStartGame(); + assert(ret == PSRETURN_OK); +} +REGISTER(CommandString_init); + + +void fCommandString_shutdown(IMessage*) +{ + Shutdown_(); +} +REGISTER(CommandString_shutdown); + + +void fCommandString_exit(IMessage*) +{ + g_GameLoop->running = false; +} +REGISTER(CommandString_exit); + + +void fCommandString_render_enable(IMessage*) +{ + g_GameLoop->rendering = true; +} +REGISTER(CommandString_render_enable); + + +void fCommandString_render_disable(IMessage*) +{ + g_GameLoop->rendering = false; +} +REGISTER(CommandString_render_disable); + +////////////////////////////////////////////////////////////////////////// + +void fSetContext(IMessage* msg) +{ + mSetContext* cmd = static_cast(msg); + // TODO: portability + wglMakeCurrent(cmd->hdc, cmd->hglrc); + g_GameLoop->currentDC = cmd->hdc; +} +REGISTER(SetContext); + + +void fResizeScreen(IMessage* msg) +{ + mResizeScreen* cmd = static_cast(msg); + g_xres = cmd->width; + g_yres = cmd->height; + if (g_xres == 0) g_xres = 1; // avoid GL errors caused by invalid sizes + if (g_yres == 0) g_yres = 1; + SViewPort vp; + vp.m_X = vp.m_Y = 0; + vp.m_Width = g_xres; + vp.m_Height = g_yres; + g_Renderer.SetViewport(vp); + g_GUI.UpdateResolution(); +} +REGISTER(ResizeScreen); + +} diff --git a/source/tools/atlas/GameInterface/Handlers/Map.cpp b/source/tools/atlas/GameInterface/Handlers/Map.cpp new file mode 100644 index 0000000000..9308221e39 --- /dev/null +++ b/source/tools/atlas/GameInterface/Handlers/Map.cpp @@ -0,0 +1,29 @@ +#include "precompiled.h" + +#include "MessageHandler.h" + +#include "graphics/Patch.h" +#include "ps/Game.h" + +namespace AtlasMessage { + + +void fGenerateMap(IMessage* msg) +{ + mGenerateMap* cmd = static_cast(msg); + + int tiles = cmd->size * PATCH_SIZE + 1; + + u16* heightmap = new u16[tiles*tiles]; + for (int y = 0; y < tiles; ++y) + for (int x = 0; x < tiles; ++x) + heightmap[x + y*tiles] = 32768; + + g_Game->GetWorld()->GetTerrain()->Resize(cmd->size); + g_Game->GetWorld()->GetTerrain()->SetHeightMap(heightmap); + + delete[] heightmap; +} +REGISTER(GenerateMap); + +} diff --git a/source/tools/atlas/GameInterface/Handlers/MessageHandler.cpp b/source/tools/atlas/GameInterface/Handlers/MessageHandler.cpp new file mode 100644 index 0000000000..bae2f32ee6 --- /dev/null +++ b/source/tools/atlas/GameInterface/Handlers/MessageHandler.cpp @@ -0,0 +1,16 @@ +#include "precompiled.h" + +#include "MessageHandler.h" + +namespace AtlasMessage +{ + +handlers& GetHandlers() +{ + // Make sure this is initialised when it's first required, rather than + // hoping to be lucky with static initialisation order + static handlers h; + return h; +} + +} \ No newline at end of file diff --git a/source/tools/atlas/GameInterface/Handlers/MessageHandler.h b/source/tools/atlas/GameInterface/Handlers/MessageHandler.h new file mode 100644 index 0000000000..22aa9fbbf0 --- /dev/null +++ b/source/tools/atlas/GameInterface/Handlers/MessageHandler.h @@ -0,0 +1,18 @@ +#include "../Messages.h" + +namespace AtlasMessage +{ + +typedef void (*handler)(IMessage*); +typedef std::map handlers; +extern handlers& GetHandlers(); + +#define CAT1(a,b) a##b +#define CAT2(a,b) CAT1(a,b) + +#define REGISTER(t) namespace CAT2(hndlr_, __LINE__) { struct init { init() { \ + bool notAlreadyRegisted = GetHandlers().insert(std::pair(#t, &f##t)).second; \ + assert(notAlreadyRegisted); \ + } } init; }; + +} \ No newline at end of file diff --git a/source/tools/atlas/GameInterface/MessageHandler.h b/source/tools/atlas/GameInterface/MessagePasser.h similarity index 57% rename from source/tools/atlas/GameInterface/MessageHandler.h rename to source/tools/atlas/GameInterface/MessagePasser.h index d7ec29078b..6e24501f65 100644 --- a/source/tools/atlas/GameInterface/MessageHandler.h +++ b/source/tools/atlas/GameInterface/MessagePasser.h @@ -1,8 +1,11 @@ +#ifndef MESSAGEPASSER_H__ +#define MESSAGEPASSER_H__ + namespace AtlasMessage { struct IMessage; -class MessageHandler +class MessagePasser { public: virtual void Add(IMessage*)=0; @@ -12,7 +15,9 @@ public: virtual void QueryDone()=0; }; -extern MessageHandler* g_MessageHandler; +extern MessagePasser* g_MessagePasser; + +#define ADD_MESSAGE(type) AtlasMessage::g_MessagePasser->Add(new AtlasMessage::m##type) } @@ -24,3 +29,5 @@ atlas->game->atlas query ("what is at position (x,y)?") game->atlas notification ("game ended") ?? */ + +#endif // MESSAGEPASSER_H__ diff --git a/source/tools/atlas/GameInterface/MessageHandlerImpl.cpp b/source/tools/atlas/GameInterface/MessagePasserImpl.cpp similarity index 50% rename from source/tools/atlas/GameInterface/MessageHandlerImpl.cpp rename to source/tools/atlas/GameInterface/MessagePasserImpl.cpp index 9a9839a99a..c8e78ca636 100644 --- a/source/tools/atlas/GameInterface/MessageHandlerImpl.cpp +++ b/source/tools/atlas/GameInterface/MessagePasserImpl.cpp @@ -1,10 +1,10 @@ #include "precompiled.h" -#include "MessageHandlerImpl.h" +#include "MessagePasserImpl.h" using namespace AtlasMessage; -void MessageHandlerImpl::Add(IMessage* msg) +void MessagePasserImpl::Add(IMessage* msg) { m_Mutex.Lock(); @@ -13,7 +13,7 @@ void MessageHandlerImpl::Add(IMessage* msg) m_Mutex.Unlock(); } -IMessage* MessageHandlerImpl::Retrieve() +IMessage* MessagePasserImpl::Retrieve() { m_Mutex.Lock(); @@ -29,12 +29,12 @@ IMessage* MessageHandlerImpl::Retrieve() return msg; } -void MessageHandlerImpl::Query(IMessage&) +void MessagePasserImpl::Query(IMessage&) { } -void MessageHandlerImpl::QueryDone() +void MessagePasserImpl::QueryDone() { } -MessageHandler* g_MessageHandler = NULL; +MessagePasser* g_MessagePasser = NULL; diff --git a/source/tools/atlas/GameInterface/MessageHandlerImpl.h b/source/tools/atlas/GameInterface/MessagePasserImpl.h similarity index 73% rename from source/tools/atlas/GameInterface/MessageHandlerImpl.h rename to source/tools/atlas/GameInterface/MessagePasserImpl.h index 5865c668f2..8eaa09a8ff 100644 --- a/source/tools/atlas/GameInterface/MessageHandlerImpl.h +++ b/source/tools/atlas/GameInterface/MessagePasserImpl.h @@ -1,9 +1,9 @@ -#include "MessageHandler.h" +#include "MessagePasser.h" #include "ps/ThreadUtil.h" #include -class MessageHandlerImpl : public AtlasMessage::MessageHandler +class MessagePasserImpl : public AtlasMessage::MessagePasser { public: virtual void Add(AtlasMessage::IMessage* msg); diff --git a/source/tools/atlas/GameInterface/Messages.h b/source/tools/atlas/GameInterface/Messages.h index f999d0caed..8d71db1411 100644 --- a/source/tools/atlas/GameInterface/Messages.h +++ b/source/tools/atlas/GameInterface/Messages.h @@ -1,38 +1,50 @@ +#ifndef MESSAGES_H__ +#define MESSAGES_H__ + +#include "MessagePasser.h" + namespace AtlasMessage { struct IMessage { - virtual int GetType() = 0; + virtual const char* GetType() const = 0; virtual ~IMessage() {} }; -enum { - CommandString, - SetContext, - ResizeScreen, +#define DEFINE(t) struct m##t : public IMessage { const char* GetType() const { return #t; } + +////////////////////////////////////////////////////////////////////////// + +DEFINE(CommandString) +mCommandString(const std::string& name_) : name(name_) {} +const std::string name; }; -struct mCommandString : public IMessage -{ - mCommandString(const std::string& n) : name(n) {}; - const std::string name; - virtual int GetType() { return CommandString; } +////////////////////////////////////////////////////////////////////////// + +DEFINE(SetContext) +mSetContext(void* /* HDC */ hdc_, void* /* HGLRC */ hglrc_) : hdc(hdc_), hglrc(hglrc_) {}; +void* hdc; +void* hglrc; }; -struct mSetContext : public IMessage -{ - mSetContext(void* /* HDC */ dc, void* /* HGLRC */ cx) : hdc(dc), hglrc(cx) {}; - void* hdc; - void* hglrc; - virtual int GetType() { return SetContext; } +DEFINE(ResizeScreen) +mResizeScreen(int width_, int height_) : width(width_), height(height_) {} +int width, height; }; -struct mResizeScreen : public IMessage -{ - mResizeScreen(int w, int h) : width(w), height(h) {} - int width, height; - virtual int GetType() { return ResizeScreen; } +////////////////////////////////////////////////////////////////////////// + +DEFINE(GenerateMap) +mGenerateMap(int size_) : size(size_) {} +int size; // size in number of patches }; +////////////////////////////////////////////////////////////////////////// + +#undef DEFINE + } + +#endif // MESSAGES_H__ \ No newline at end of file