Introducing: The Pre-Game State. The game instance is not created on program load as before, but can be started by JS functions.

This was SVN commit r912.
This commit is contained in:
Simon Brenner 2004-08-05 13:07:51 +00:00
parent aa1c08f6be
commit b2afef529c
17 changed files with 205 additions and 79 deletions

View File

@ -24,8 +24,6 @@
extern int g_xres, g_yres;
extern bool g_active;
extern CLightEnv g_LightEnv;
CVector3D cameraBookmarks[10];
bool bookmarkInUse[10] = { false, false, false, false, false, false, false, false, false, false };
i8 currentBookmark = -1;
@ -78,23 +76,19 @@ void CGameView::Initialize(CGameAttributes *pAttribs)
#undef getViewParameter
// setup default lighting environment
g_LightEnv.m_SunColor=RGBColor(1,1,1);
g_LightEnv.m_Rotation=DEGTORAD(270);
g_LightEnv.m_Elevation=DEGTORAD(45);
g_LightEnv.m_TerrainAmbientColor=RGBColor(0,0,0);
g_LightEnv.m_UnitsAmbientColor=RGBColor(0.4f,0.4f,0.4f);
g_Renderer.SetLightEnv(&g_LightEnv);
// If we start storing initial camera in the Map/World, change this code to
// init from the CWorld member instead of filling in defaults
m_Camera.SetProjection (1, 5000, DEGTORAD(20));
m_Camera.m_Orientation.SetXRotation(DEGTORAD(30));
m_Camera.m_Orientation.RotateY(DEGTORAD(-45));
m_Camera.m_Orientation.Translate (100, 150, -100);
g_Renderer.SetCamera(m_Camera);
}
void CGameView::Render()
{
g_Renderer.SetCamera(m_Camera);
MICROLOG(L"render terrain");
RenderTerrain(m_pWorld->GetTerrain());
MICROLOG(L"render models");
@ -506,12 +500,13 @@ void CGameView::PopCameraTarget()
int game_view_handler(const SDL_Event* ev)
{
CGameView *pView=g_Game->GetView();
// put any events that must be processed even if inactive here
if(!g_active)
if(!g_active || !g_Game)
return EV_PASS;
CGameView *pView=g_Game->GetView();
switch(ev->type)
{

View File

@ -106,7 +106,7 @@ static inline Handle handle(const u32 _idx, const u32 tag)
// determines maximum number of references to a resource.
static const uint REF_BITS = 8;
static const u32 REF_MAX = 1ul << REF_BITS;
static const u32 REF_MAX = (1ul << REF_BITS)-1;
static const uint TYPE_BITS = 8;

View File

@ -26,4 +26,4 @@ extern int debug_write_crashlog(const char* file, wchar_t* header, void* context
extern void debug_check_heap();
extern void debug_break();
extern void debug_break();

View File

@ -30,6 +30,7 @@
#include "ObjectManager.h"
#include "SkeletonAnimManager.h"
#include "Renderer.h"
#include "LightEnv.h"
#include "Model.h"
#include "UnitManager.h"
@ -89,6 +90,8 @@ static bool g_NoPBuffer=true;
static bool g_FixedFrameTiming=false;
static bool g_VSync = false;
extern CLightEnv g_LightEnv;
static bool g_EntGraph = false;
static float g_Gamma = 1.0f;
@ -362,6 +365,20 @@ static int handler(const SDL_Event* ev)
return EV_PASS;
}
extern void StartGame();
void RenderNoCull();
void StartGame()
{
g_Game=new CGame();
g_Game->Initialize(&g_GameAttributes);
}
void EndGame()
{
delete g_Game;
g_Game=NULL;
}
/////////////////////////////////////////////////////////////////////////////////////////////
// RenderNoCull: render absolutely everything to a blank frame to force renderer
// to load required assets
@ -369,7 +386,8 @@ void RenderNoCull()
{
g_Renderer.BeginFrame();
g_Game->GetView()->RenderNoCull();
if (g_Game)
g_Game->GetView()->RenderNoCull();
g_Renderer.FlushFrame();
glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);
@ -387,28 +405,33 @@ static void Render()
// switch on wireframe for terrain if we want it
//g_Renderer.SetTerrainRenderMode( SOLID ); // (PT: If this is done here, the W key doesn't work)
g_Game->GetView()->Render();
MICROLOG(L"flush frame");
g_Renderer.FlushFrame();
glPushAttrib( GL_ENABLE_BIT );
glDisable( GL_LIGHTING );
glDisable( GL_TEXTURE_2D );
glDisable( GL_DEPTH_TEST );
if( g_EntGraph )
if (g_Game)
{
glColor3f( 1.0f, 0.0f, 1.0f );
g_Game->GetView()->Render();
MICROLOG(L"render entities");
g_EntityManager.renderAll(); // <-- collision outlines, pathing routes
MICROLOG(L"flush frame");
g_Renderer.FlushFrame();
glPushAttrib( GL_ENABLE_BIT );
glDisable( GL_LIGHTING );
glDisable( GL_TEXTURE_2D );
glDisable( GL_DEPTH_TEST );
if( g_EntGraph )
{
glColor3f( 1.0f, 0.0f, 1.0f );
MICROLOG(L"render entities");
g_EntityManager.renderAll(); // <-- collision outlines, pathing routes
}
g_Mouseover.renderSelectionOutlines();
g_Selection.renderSelectionOutlines();
glPopAttrib();
}
g_Mouseover.renderSelectionOutlines();
g_Selection.renderSelectionOutlines();
glPopAttrib();
else
g_Renderer.FlushFrame();
MICROLOG(L"render fonts");
// overlay mode
@ -458,8 +481,11 @@ static void Render()
MICROLOG(L"render console");
g_Console->Render();
g_Mouseover.renderOverlays();
g_Selection.renderOverlays();
if (g_Game)
{
g_Mouseover.renderOverlays();
g_Selection.renderOverlays();
}
// Draw the cursor (or set the Windows cursor, on Windows)
cursor_draw(g_CursorName);
@ -475,6 +501,10 @@ static void Render()
g_Renderer.EndFrame();
}
static void InitDefaultGameAttributes()
{
g_GameAttributes.m_MapFile="test01.pmp";
}
static void ParseArgs(int argc, char* argv[])
{
@ -659,8 +689,9 @@ static void Shutdown()
{
psShutdown(); // Must delete g_GUI before g_ScriptingHost
delete g_Game;
if (g_Game)
delete g_Game;
delete &g_Scheduler;
delete &g_Mouseover;
@ -668,7 +699,8 @@ static void Shutdown()
delete &g_ScriptingHost;
delete &g_Pathfinder;
delete &g_EntityManager;
// Managed by CWorld
// delete &g_EntityManager;
delete &g_EntityTemplateCollection;
// destroy actor related stuff
@ -753,6 +785,8 @@ PREVTSC=TSC;
// the profile dir is VFS mounted (or we will do a new SetConfigFile with
// a generated profile path)
// We init the defaults here; command line options might want to override
InitDefaultGameAttributes();
ParseArgs(argc, argv);
//g_xres = 800;
@ -827,23 +861,33 @@ PREVTSC=CURTSC;
MICROLOG(L"init renderer");
g_Renderer.Open(g_xres,g_yres,g_bpp);
// Setup default lighting environment. Since the Renderer accesses the
// lighting environment through a pointer, this has to be done before
// the first Frame.
g_LightEnv.m_SunColor=RGBColor(1,1,1);
g_LightEnv.m_Rotation=DEGTORAD(270);
g_LightEnv.m_Elevation=DEGTORAD(45);
g_LightEnv.m_TerrainAmbientColor=RGBColor(0,0,0);
g_LightEnv.m_UnitsAmbientColor=RGBColor(0.4f,0.4f,0.4f);
g_Renderer.SetLightEnv(&g_LightEnv);
// I haven't seen the camera affecting GUI rendering and such, but the
// viewport has to be updated according to the video mode
SViewPort vp;
vp.m_X=0;
vp.m_Y=0;
vp.m_Width=g_xres;
vp.m_Height=g_yres;
g_Renderer.SetViewport(vp);
// This needs to be done after the renderer has loaded all its actors...
new CBaseEntityCollection;
new CEntityManager;
// CEntityManager is managed by CWorld
//new CEntityManager;
new CPathfindEngine;
new CSelectedEntities;
new CMouseoverEntities;
// if no map name specified, load test01.pmp (for convenience during
// development. that means loading no map at all is currently impossible.
// is that a problem?
if(!g_GameAttributes.m_MapFile)
g_GameAttributes.m_MapFile = "test01.pmp";
MICROLOG(L"start game");
g_Game=new CGame();
g_Game->Initialize(&g_GameAttributes);
// Check for heap corruption after every allocation. Very, very slowly.
// (And it highlights the allocation just after the one you care about,
// so you need to run it again and tell it to break on the one before.)
@ -988,14 +1032,17 @@ static void Frame()
in_get_events();
g_Game->Update(TimeSinceLastFrame);
if (!g_FixedFrameTiming)
g_Game->GetView()->Update(float(TimeSinceLastFrame));
if (g_Game)
{
g_Game->Update(TimeSinceLastFrame);
if (!g_FixedFrameTiming)
g_Game->GetView()->Update(float(TimeSinceLastFrame));
// TODO Where does GameView end and other things begin?
g_Mouseover.update( TimeSinceLastFrame );
g_Selection.update();
// TODO Where does GameView end and other things begin?
g_Mouseover.update( TimeSinceLastFrame );
g_Selection.update();
}
g_Console->Update(TimeSinceLastFrame);

View File

@ -28,4 +28,4 @@ private:
Handle m_Handle;
void* m_Buffer;
size_t m_BufferSize;
};
};

View File

@ -1,9 +1,36 @@
#include "precompiled.h"
#include "Game.h"
#include "CLogger.h"
CGame *g_Game=NULL;
JSBool CGameAttributes::FillFromJS(JSContext *cx, JSObject *obj)
{
#define GETVAL(_name) jsval _name=g_ScriptingHost.GetObjectProperty(obj, #_name)
GETVAL(mapFile);
#define TOSTRING(_jsval) g_ScriptingHost.ValueToString(_jsval)
if (JSVAL_IS_STRING(mapFile))
m_MapFile=TOSTRING(mapFile);
return JS_TRUE;
}
CGame::CGame():
m_World(this),
m_Simulation(this),
m_GameView(this),
m_pLocalPlayer(NULL)
{
debug_out("CGame::CGame(): Game object CREATED");
}
CGame::~CGame()
{
debug_out("CGame::~CGame(): Game object DESTROYED");
}
PSRETURN CGame::Initialize(CGameAttributes *pAttribs)
{
try

View File

@ -10,19 +10,22 @@ ERROR_GROUP(Game);
#include "Simulation.h"
#include "Player.h"
#include "GameView.h"
#include "scripting/ScriptingHost.h"
#define PS_MAX_PLAYERS 6
#include <vector>
class CGameAttributes
{
public:
inline CGameAttributes():
m_MapFile(NULL)
m_MapFile()
{}
JSBool FillFromJS(JSContext *cx, JSObject *obj);
// The VFS path of the mapfile to load or NULL for no map (and to use
// default terrain)
const char *m_MapFile;
CStr m_MapFile;
};
class CGame
@ -31,18 +34,12 @@ class CGame
CSimulation m_Simulation;
CGameView m_GameView;
CPlayer *m_Players[PS_MAX_PLAYERS];
std::vector<CPlayer *> m_Players;
CPlayer *m_pLocalPlayer;
public:
inline CGame():
m_World(this),
m_Simulation(this),
m_GameView(this)
{
// TODO When are players created?
// TODO Probably should at least reset in here though
}
CGame();
~CGame();
/*
Initialize all local state and members for playing a game described by

View File

@ -102,4 +102,4 @@ void initKeyNameMap();
CStr getKeyName( int keycode );
int getKeyCode( CStr keyname );
extern bool hotkeys[HOTKEY_LAST];
extern bool hotkeys[HOTKEY_LAST];

View File

@ -12,6 +12,7 @@ extern CGame *g_Game;
extern CConsole* g_Console;
extern int mouse_x, mouse_y;
extern bool keys[SDLK_LAST];
extern bool g_active;
static const float SELECT_DBLCLICK_RATE = 0.5f;
static const int ORDER_DELAY = 5;
@ -721,6 +722,9 @@ void CMouseoverEntities::stopBandbox()
int interactInputHandler( const SDL_Event* ev )
{
if (!g_active || !g_Game)
return EV_PASS;
CGameView *pView=g_Game->GetView();
CCamera *pCamera=pView->GetCamera();
CTerrain *pTerrain=g_Game->GetWorld()->GetTerrain();

View File

@ -10,6 +10,7 @@
#include "Terrain.h"
#include "LightEnv.h"
#include "BaseEntityCollection.h"
#include "EntityManager.h"
extern CLightEnv g_LightEnv;
@ -27,3 +28,13 @@ void CWorld::Initialize(CGameAttributes *pAttribs)
throw PSERROR_Game_World_MapLoadFailed();
}
}
CWorld::~CWorld()
{
// The Entity Manager should perhaps be converted into a CWorld member..
// But for now, we'll just create and delete the global singleton instance
// following the creation and deletion of CWorld.
// The reason for not keeping the instance around is that we require a
// clean slate for each game start.
delete &m_EntityManager;
}

View File

@ -3,6 +3,7 @@
#include "Terrain.h"
#include "UnitManager.h"
#include "EntityManager.h"
class CGame;
class CGameAttributes;
@ -11,18 +12,22 @@ class CWorld
{
CGame *m_pGame;
CTerrain m_Terrain;
// These both point to the respective g_* globals - the plan is to remove
// the globals and move them into CWorld members as soon as all code has
// been converted
CTerrain m_Terrain;
CUnitManager &m_UnitManager;
CEntityManager &m_EntityManager;
public:
inline CWorld(CGame *pGame):
m_pGame(pGame),
m_Terrain(),
m_UnitManager(g_UnitMan)
m_UnitManager(g_UnitMan),
m_EntityManager(*new CEntityManager())
{}
~CWorld();
/*
Initialize the World - load the map and all objects
*/

View File

@ -151,9 +151,11 @@ JSBool JSI_Selection::toString( JSContext* cx, JSObject* obj, uintN argc, jsval*
std::vector<HEntity>* set = (std::vector<HEntity>*)JS_GetPrivate( cx, obj );
wchar_t buffer[256];
_snwprintf( buffer, 256, L"[object EntityCollection: %d entities]", set->size() );
int len=swprintf( buffer, 256, L"[object EntityCollection: %d entities]", set->size() );
buffer[255] = 0;
*rval = STRING_TO_JSVAL( JS_NewUCStringCopyZ( cx, buffer ) );
if (len < 0 || len > 255) len=255;
utf16string u16str(buffer, buffer+len);
*rval = STRING_TO_JSVAL( JS_NewUCStringCopyZ( cx, u16str.c_str() ) );
return( JS_TRUE );
}
@ -312,4 +314,4 @@ JSBool JSI_Selection::setContextOrder( JSContext* context, JSObject* obj, jsval
}
g_Selection.setContext( orderCode );
return( JS_TRUE );
}
}

View File

@ -32,4 +32,4 @@ namespace JSI_Selection
JSBool setContextOrder( JSContext* context, JSObject* obj, jsval id, jsval* vp );
};
#endif
#endif

View File

@ -940,12 +940,16 @@ void CRenderer::SetCamera(CCamera& camera)
glMatrixMode(GL_MODELVIEW);
glLoadMatrixf(&view._11);
const SViewPort& vp=camera.GetViewPort();
glViewport(vp.m_X,vp.m_Y,vp.m_Width,vp.m_Height);
SetViewport(camera.GetViewPort());
m_Camera=camera;
}
void CRenderer::SetViewport(const SViewPort &vp)
{
glViewport(vp.m_X,vp.m_Y,vp.m_Width,vp.m_Height);
}
void CRenderer::Submit(CPatch* patch)
{
CPatchRData::Submit(patch);

View File

@ -153,6 +153,9 @@ public:
// set camera used for subsequent rendering operations; includes viewport, projection and modelview matrices
void SetCamera(CCamera& camera);
// set the viewport
void SetViewport(const SViewPort &);
// submission of objects for rendering; the passed matrix indicating the transform must be scoped such that it is valid beyond
// the call to frame end, as must the object itself
void Submit(CPatch* patch);

View File

@ -9,6 +9,7 @@
#include "EntityManager.h"
#include "BaseEntityCollection.h"
#include "Scheduler.h"
#include "Game.h"
#include "scripting/JSInterface_Entity.h"
#include "scripting/JSInterface_BaseEntity.h"
#include "scripting/JSInterface_Vector3D.h"
@ -40,6 +41,8 @@ JSFunctionSpec ScriptFunctionTable[] =
{"getGlobal", getGlobal, 0, 0, 0 },
{"getGUIGlobal", getGUIGlobal, 0, 0, 0 },
{"setCursor", setCursor, 0, 0, 0 },
{"startGame", startGame, 0, 0, 0 },
{"endGame", endGame, 0, 0, 0 },
{"exit", exitProgram, 0, 0, 0 },
{"crash", crash, 1, 0, 0 },
{0, 0, 0, 0, 0},
@ -253,6 +256,31 @@ JSBool setCursor(JSContext* UNUSEDPARAM(context), JSObject* UNUSEDPARAM(globalOb
return JS_TRUE;
}
// From main.cpp
extern void StartGame();
extern CGameAttributes g_GameAttributes;
JSBool startGame(JSContext* cx, JSObject* UNUSEDPARAM(globalObject), unsigned int argc, jsval* argv, jsval* rval)
{
if (argc == 1)
{
JSObject *obj;
if (JS_ConvertArguments(cx, 1, argv, "o", &obj))
{
g_GameAttributes.FillFromJS(cx, obj);
}
}
StartGame();
*rval=BOOLEAN_TO_JSVAL(JS_TRUE);
return JS_TRUE;
}
extern void EndGame();
JSBool endGame(JSContext* UNUSEDPARAM(context), JSObject* UNUSEDPARAM(globalObject), unsigned int UNUSEDPARAM(argc), jsval* UNUSEDPARAM(argv), jsval* UNUSEDPARAM(rval))
{
EndGame();
return JS_TRUE;
}
extern void kill_mainloop(); // from main.cpp

View File

@ -22,6 +22,9 @@ JSBool getGlobal(JSContext* context, JSObject* globalObject, unsigned int argc,
JSBool setCursor(JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval);
JSBool startGame(JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval);
JSBool endGame(JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval);
// Tells the main loop to stop looping
JSBool exitProgram(JSContext* context, JSObject* globalObject, unsigned int argc, jsval* argv, jsval* rval);