1
0
forked from 0ad/0ad

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.
This commit is contained in:
Ykkrosh 2005-06-27 23:04:34 +00:00
parent 22a9ccb00a
commit cf37e9cbe6
22 changed files with 498 additions and 142 deletions

View File

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

View File

@ -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");

View File

@ -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);
}
}
{
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);
}
}
}

View File

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

View File

@ -19,7 +19,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="0"
AdditionalIncludeDirectories=".;..;.\General;.\CustomControls\EditableListCtrl;.\CustomControls\DraggableListCtrl;.\CustomControls\Windows;.\Misc;E:\wx\wxWidgets\include;E:\wx\wxWidgets\include\msvc;..\..\..\..\libraries\devil\src\include"
AdditionalIncludeDirectories=".;..;.\General;.\CustomControls\Buttons;.\CustomControls\DraggableListCtrl;.\CustomControls\EditableListCtrl;.\CustomControls\Windows;.\Misc;E:\wx\wxWidgets\include;E:\wx\wxWidgets\include\msvc;..\..\..\..\libraries\devil\src\include"
PreprocessorDefinitions="WIN32;_DEBUG;_WINDOWS"
MinimalRebuild="TRUE"
BasicRuntimeChecks="3"
@ -71,7 +71,7 @@
<Tool
Name="VCCLCompilerTool"
Optimization="1"
AdditionalIncludeDirectories=".;..;.\General;.\CustomControls\EditableListCtrl;.\CustomControls\DraggableListCtrl;.\CustomControls\Windows;.\Misc;E:\wx\wxWidgets\include;E:\wx\wxWidgets\include\msvc;..\..\..\..\libraries\devil\src\include"
AdditionalIncludeDirectories=".;..;.\General;.\CustomControls\Buttons;.\CustomControls\DraggableListCtrl;.\CustomControls\EditableListCtrl;.\CustomControls\Windows;.\Misc;E:\wx\wxWidgets\include;E:\wx\wxWidgets\include\msvc;..\..\..\..\libraries\devil\src\include"
PreprocessorDefinitions="WIN32;NDEBUG;_WINDOWS"
StringPooling="TRUE"
RuntimeLibrary="2"
@ -245,6 +245,26 @@
RelativePath=".\CustomControls\VirtualDirTreeCtrl\virtualdirtreectrl.h">
</File>
</Filter>
<Filter
Name="SnapSplitterWindow"
Filter="">
<File
RelativePath=".\CustomControls\SnapSplitterWindow\SnapSplitterWindow.cpp">
</File>
<File
RelativePath=".\CustomControls\SnapSplitterWindow\SnapSplitterWindow.h">
</File>
</Filter>
<Filter
Name="Buttons"
Filter="">
<File
RelativePath=".\CustomControls\Buttons\ActionButton.cpp">
</File>
<File
RelativePath=".\CustomControls\Buttons\ActionButton.h">
</File>
</Filter>
</Filter>
<Filter
Name="ActorEditor"
@ -342,6 +362,30 @@
<File
RelativePath=".\ScenarioEditor\ScenarioEditor.h">
</File>
<Filter
Name="Sections"
Filter="">
<Filter
Name="Map"
Filter="">
<File
RelativePath=".\ScenarioEditor\Sections\Map\Map.cpp">
</File>
<File
RelativePath=".\ScenarioEditor\Sections\Map\Map.h">
</File>
</Filter>
<Filter
Name="Common"
Filter="">
<File
RelativePath=".\ScenarioEditor\Sections\Common\Sidebar.cpp">
</File>
<File
RelativePath=".\ScenarioEditor\Sections\Common\Sidebar.h">
</File>
</Filter>
</Filter>
</Filter>
</Filter>
<File

View File

@ -0,0 +1,7 @@
#include "stdafx.h"
#include "ActionButton.h"
BEGIN_EVENT_TABLE(ActionButton, wxButton)
EVT_BUTTON(wxID_ANY, ActionButton::OnClick)
END_EVENT_TABLE()

View File

@ -0,0 +1,25 @@
class ActionButton : public wxButton
{
typedef void (*actionFun)();
public:
ActionButton(wxWindow *parent,
const wxString& label,
actionFun fun,
const wxSize& size = wxDefaultSize,
long style = 0)
: wxButton(parent, wxID_ANY, label, wxDefaultPosition, size, style),
m_Fun(fun)
{
}
protected:
virtual void OnClick(wxCommandEvent&)
{
m_Fun();
}
private:
actionFun m_Fun;
DECLARE_EVENT_TABLE();
};

View File

@ -0,0 +1,37 @@
#include "stdafx.h"
#include "SnapSplitterWindow.h"
BEGIN_EVENT_TABLE(SnapSplitterWindow, wxSplitterWindow)
EVT_SPLITTER_SASH_POS_CHANGING(wxID_ANY, SnapSplitterWindow::OnSashPosChanging)
END_EVENT_TABLE()
SnapSplitterWindow::SnapSplitterWindow(wxWindow* parent)
: wxSplitterWindow(parent, wxID_ANY, wxDefaultPosition, wxDefaultSize,
wxSP_3D | wxSP_LIVE_UPDATE),
m_SnapTolerance(16)
{
// Set min size, to disable unsplitting
SetMinimumPaneSize(32);
}
bool SnapSplitterWindow::SplitVertically(wxWindow *window1, wxWindow *window2, int sashPosition)
{
m_DefaultSashPosition = sashPosition;
return DoSplit(wxSPLIT_VERTICAL, window1, window2, sashPosition);
}
bool SnapSplitterWindow::SplitHorizontally(wxWindow *window1, wxWindow *window2, int sashPosition)
{
m_DefaultSashPosition = sashPosition;
return DoSplit(wxSPLIT_HORIZONTAL, window1, window2, sashPosition);
}
void SnapSplitterWindow::OnSashPosChanging(wxSplitterEvent& evt)
{
if (evt.GetSashPosition() >= m_DefaultSashPosition-m_SnapTolerance &&
evt.GetSashPosition() <= m_DefaultSashPosition+m_SnapTolerance)
{
evt.SetSashPosition(m_DefaultSashPosition);
}
}

View File

@ -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();
};

View File

@ -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)

View File

@ -22,6 +22,7 @@
#include "wx/colordlg.h"
#include "wx/regex.h"
#include "wx/image.h"
#include "wx/splitter.h"
#include <vector>
#include <string>

View File

@ -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();

View File

@ -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<mCommandString*>(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<mSetContext*>(msg);
// TODO: portability
wglMakeCurrent(cmd->hdc, cmd->hglrc);
currentDC = cmd->hdc;
}
break;
case ResizeScreen:
{
mResizeScreen* cmd = static_cast<mResizeScreen*>(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<mCommandString*>(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);

View File

@ -1 +1,10 @@
struct GameLoopState
{
int argc;
char** argv;
bool running;
bool rendering;
void* currentDC;
};
extern GameLoopState* g_GameLoop;

View File

@ -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<mSetContext*>(msg);
// TODO: portability
wglMakeCurrent(cmd->hdc, cmd->hglrc);
g_GameLoop->currentDC = cmd->hdc;
}
REGISTER(SetContext);
void fResizeScreen(IMessage* msg)
{
mResizeScreen* cmd = static_cast<mResizeScreen*>(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);
}

View File

@ -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<mGenerateMap*>(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);
}

View File

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

View File

@ -0,0 +1,18 @@
#include "../Messages.h"
namespace AtlasMessage
{
typedef void (*handler)(IMessage*);
typedef std::map<std::string, handler> 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<std::string, handler>(#t, &f##t)).second; \
assert(notAlreadyRegisted); \
} } init; };
}

View File

@ -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__

View File

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

View File

@ -1,9 +1,9 @@
#include "MessageHandler.h"
#include "MessagePasser.h"
#include "ps/ThreadUtil.h"
#include <queue>
class MessageHandlerImpl : public AtlasMessage::MessageHandler
class MessagePasserImpl : public AtlasMessage::MessagePasser
{
public:
virtual void Add(AtlasMessage::IMessage* msg);

View File

@ -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__