From 09f47d68201e5dceec379971815bb834a0cc013f Mon Sep 17 00:00:00 2001 From: olsner Date: Sat, 31 Jul 2004 15:57:18 +0000 Subject: [PATCH] Core Classes Reorganization: - g_Terrain and g_Camera totally eradicated as globals, is now m_Terrain of CWorld and m_Camera of CGameView - terrainMain.cpp is almost completely empty with functionality moved into the relevant core classes - Miscellaneous global functions moved into Core Classes (mostly GameView) This was SVN commit r865. --- source/graphics/GameView.cpp | 470 +++++++++++++++++++- source/graphics/GameView.h | 49 +- source/graphics/HFTracer.cpp | 19 +- source/graphics/HFTracer.h | 5 +- source/graphics/MapReader.cpp | 22 +- source/graphics/MapReader.h | 7 +- source/graphics/MapWriter.cpp | 53 ++- source/graphics/MapWriter.h | 20 +- source/graphics/Terrain.h | 5 - source/main.cpp | 33 +- source/ps/Game.cpp | 21 +- source/ps/Game.h | 11 +- source/ps/Interact.cpp | 114 +++-- source/ps/Interact.h | 10 - source/ps/World.cpp | 25 +- source/ps/World.h | 21 +- source/scripting/ScriptingHost.h | 2 + source/simulation/Entity.cpp | 32 +- source/simulation/EntityStateProcessing.cpp | 4 +- source/simulation/PathfindSparse.cpp | 7 +- source/simulation/Simulation.cpp | 5 +- source/terrain/terrainMain.cpp | 420 +---------------- 22 files changed, 705 insertions(+), 650 deletions(-) diff --git a/source/graphics/GameView.cpp b/source/graphics/GameView.cpp index 65efbba29f..5709b180b7 100755 --- a/source/graphics/GameView.cpp +++ b/source/graphics/GameView.cpp @@ -6,29 +6,100 @@ #include "Game.h" #include "Camera.h" -extern CCamera g_Camera; +#include "Matrix3D.h" +#include "Renderer.h" +#include "Terrain.h" +#include "LightEnv.h" +#include "HFTracer.h" +#include "TextureManager.h" +#include "ObjectManager.h" +#include "Prometheus.h" +#include "Hotkey.h" +#include "ConfigDB.h" + +#include "sdl.h" +#include "input.h" +#include "lib.h" + +extern int g_xres, g_yres; +extern bool g_active; + +extern CLightEnv g_LightEnv; CGameView::CGameView(CGame *pGame): m_pGame(pGame), m_pWorld(pGame->GetWorld()), - m_pCamera(&g_Camera) -{} + m_Camera(), + m_ViewScrollSpeed(60), + m_ViewRotateSensitivity(0.002f), + m_ViewRotateAboutTargetSensitivity(0.010f), + m_ViewDragSensitivity(0.5f), + m_ViewZoomSensitivityWheel(16.0f), + m_ViewZoomSensitivity(256.0f), + m_ViewZoomSmoothness(0.02f), + m_ViewSnapSmoothness(0.02f), + m_CameraPivot(), + m_CameraDelta()//, +// m_CameraZoom(10) +{ + InitResources(); +} void CGameView::Initialize(CGameAttributes *pAttribs) -{} +{ + SViewPort vp; + vp.m_X=0; + vp.m_Y=0; + vp.m_Width=g_xres; + vp.m_Height=g_yres; + m_Camera.SetViewPort(&vp); + + CConfigValue* cfg; + +#define getViewParameter( name, value ) STMT( \ + cfg = g_ConfigDB.GetValue( CFG_SYSTEM, name );\ + if( cfg ) cfg->GetFloat( value ); ) + + getViewParameter( "view.scroll.speed", m_ViewScrollSpeed ); + getViewParameter( "view.rotate.speed", m_ViewRotateSensitivity ); + getViewParameter( "view.rotate.abouttarget.speed", m_ViewRotateAboutTargetSensitivity ); + getViewParameter( "view.drag.speed", m_ViewDragSensitivity ); + getViewParameter( "view.zoom.speed", m_ViewZoomSensitivity ); + getViewParameter( "view.zoom.wheel.speed", m_ViewZoomSensitivityWheel ); + getViewParameter( "view.zoom.smoothness", m_ViewZoomSmoothness ); + getViewParameter( "view.snap.smoothness", m_ViewSnapSmoothness ); + + if( ( m_ViewZoomSmoothness < 0.0f ) || ( m_ViewZoomSmoothness > 1.0f ) ) m_ViewZoomSmoothness = 0.02f; + if( ( m_ViewSnapSmoothness < 0.0f ) || ( m_ViewSnapSmoothness > 1.0f ) ) m_ViewSnapSmoothness = 0.02f; + +#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); + + 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); +} void CGameView::Render() { + g_Renderer.SetCamera(m_Camera); MICROLOG(L"render terrain"); RenderTerrain(m_pWorld->GetTerrain()); MICROLOG(L"render models"); RenderModels(m_pWorld->GetUnitManager()); - MICROLOG(L"flush frame"); } void CGameView::RenderTerrain(CTerrain *pTerrain) { - CFrustum frustum=m_pCamera->GetFrustum(); + CFrustum frustum=m_Camera.GetFrustum(); u32 patchesPerSide=pTerrain->GetPatchesPerSide(); for (uint j=0; jGetFrustum(); + CFrustum frustum=m_Camera.GetFrustum(); const std::vector& units=pUnitMan->GetUnits(); for (uint i=0;iGetUnitManager(); CTerrain *pTerrain=m_pWorld->GetTerrain(); + g_Renderer.SetCamera(m_Camera); + uint i,j; const std::vector& units=pUnitMan->GetUnits(); for (i=0;iGetTerrain(); + + int x, z; + CHFTracer tracer( pTerrain ); + CVector3D origin, dir; + origin = m_Camera.m_Orientation.GetTranslation(); + dir = m_Camera.m_Orientation.GetIn(); + m_Camera.BuildCameraRay( origin, dir ); + + if( !tracer.RayIntersect( origin, dir, x, z, m_CameraPivot ) ) + m_CameraPivot = origin - dir * ( origin.Y / dir.Y ); +} + +void CGameView::Update(float DeltaTime) +{ + if (!g_active) + return; + + float delta = powf( m_ViewSnapSmoothness, DeltaTime ); + m_Camera.m_Orientation.Translate( m_CameraDelta * ( 1.0f - delta ) ); + m_CameraDelta *= delta; + +#define CAMERASTYLE 2 // 0 = old style, 1 = relatively new style, 2 = newest style + +#if CAMERASTYLE == 2 + + // This could be rewritten much more reliably, so it doesn't e.g. accidentally tilt + // the camera, assuming we know exactly what limits the camera should have. + + + // Calculate mouse movement + static int mouse_last_x = 0; + static int mouse_last_y = 0; + int mouse_dx = mouse_x - mouse_last_x; + int mouse_dy = mouse_y - mouse_last_y; + mouse_last_x = mouse_x; + mouse_last_y = mouse_y; + + // Miscellaneous vectors + CVector3D forwards = m_Camera.m_Orientation.GetIn(); + CVector3D rightwards = m_Camera.m_Orientation.GetLeft() * -1.0f; // upwards.Cross(forwards); + CVector3D upwards( 0.0f, 1.0f, 0.0f ); + // rightwards.Normalize(); + + CVector3D forwards_horizontal = forwards; + forwards_horizontal.Y = 0.0f; + forwards_horizontal.Normalize(); + + /* + if ((mouseButtons[SDL_BUTTON_MIDDLE] && (keys[SDLK_LCTRL] || keys[SDLK_RCTRL])) + || (mouseButtons[SDL_BUTTON_LEFT] && mouseButtons[SDL_BUTTON_RIGHT]) ) + */ + if( hotkeys[HOTKEY_CAMERA_ROTATE] ) + { + // Ctrl + middle-drag or left-and-right-drag to rotate view + + // Untranslate the camera, so it rotates around the correct point + CVector3D position = m_Camera.m_Orientation.GetTranslation(); + m_Camera.m_Orientation.Translate(position*-1); + + // Sideways rotation + m_Camera.m_Orientation.RotateY(m_ViewRotateSensitivity * (float)(mouse_dx)); + + // Up/down rotation + CQuaternion temp; + temp.FromAxisAngle(rightwards, m_ViewRotateSensitivity * (float)(mouse_dy)); + m_Camera.m_Orientation.Rotate(temp); + + // Retranslate back to the right position + m_Camera.m_Orientation.Translate(position); + + } + else if( hotkeys[HOTKEY_CAMERA_ROTATE_ABOUT_TARGET] ) + { + CVector3D origin = m_Camera.m_Orientation.GetTranslation(); + CVector3D delta = origin - m_CameraPivot; + + CQuaternion rotateH, rotateV; CMatrix3D rotateM; + + // Side-to-side rotation + rotateH.FromAxisAngle( upwards, m_ViewRotateAboutTargetSensitivity * (float)mouse_dx ); + + // Up-down rotation + rotateV.FromAxisAngle( rightwards, m_ViewRotateAboutTargetSensitivity * (float)mouse_dy ); + + rotateH *= rotateV; + rotateH.ToMatrix( rotateM ); + + delta = rotateM.Rotate( delta ); + + // Lock the inclination to a rather arbitrary values (for the sake of graphical decency) + + float scan = sqrt( delta.X * delta.X + delta.Z * delta.Z ) / delta.Y; + if( ( scan >= 0.5f ) ) + { + // Move the camera to the origin (in preparation for rotation ) + m_Camera.m_Orientation.Translate( origin * -1.0f ); + + m_Camera.m_Orientation.Rotate( rotateH ); + + // Move the camera back to where it belongs + m_Camera.m_Orientation.Translate( m_CameraPivot + delta ); + } + + } + else if( hotkeys[HOTKEY_CAMERA_PAN] ) + { + // Middle-drag to pan + m_Camera.m_Orientation.Translate(rightwards * (m_ViewDragSensitivity * mouse_dx)); + m_Camera.m_Orientation.Translate(forwards_horizontal * (-m_ViewDragSensitivity * mouse_dy)); + } + + // Mouse movement + + if( !hotkeys[HOTKEY_CAMERA_ROTATE] && !hotkeys[HOTKEY_CAMERA_ROTATE_ABOUT_TARGET] ) + { + if (mouse_x >= g_xres-2) + m_Camera.m_Orientation.Translate(rightwards * (m_ViewScrollSpeed * DeltaTime)); + else if (mouse_x <= 3) + m_Camera.m_Orientation.Translate(-rightwards * (m_ViewScrollSpeed * DeltaTime)); + + if (mouse_y >= g_yres-2) + m_Camera.m_Orientation.Translate(-forwards_horizontal * (m_ViewScrollSpeed * DeltaTime)); + else if (mouse_y <= 3) + m_Camera.m_Orientation.Translate(forwards_horizontal * (m_ViewScrollSpeed * DeltaTime)); + } + + + // Keyboard movement (added to mouse movement, so you can go faster if you want) + + if( hotkeys[HOTKEY_CAMERA_PAN_RIGHT] ) + m_Camera.m_Orientation.Translate(rightwards * (m_ViewScrollSpeed * DeltaTime)); + if( hotkeys[HOTKEY_CAMERA_PAN_LEFT] ) + m_Camera.m_Orientation.Translate(-rightwards * (m_ViewScrollSpeed * DeltaTime)); + + if( hotkeys[HOTKEY_CAMERA_PAN_BACKWARD] ) + m_Camera.m_Orientation.Translate(-forwards_horizontal * (m_ViewScrollSpeed * DeltaTime)); + if( hotkeys[HOTKEY_CAMERA_PAN_FORWARD] ) + m_Camera.m_Orientation.Translate(forwards_horizontal * (m_ViewScrollSpeed * DeltaTime)); + + // Smoothed zooming (move a certain percentage towards the desired zoom distance every frame) + + static float zoom_delta = 0.0f; + + if( hotkeys[HOTKEY_CAMERA_ZOOM_WHEEL_IN] ) + zoom_delta += m_ViewZoomSensitivityWheel; + else if( hotkeys[HOTKEY_CAMERA_ZOOM_WHEEL_OUT] ) + zoom_delta -= m_ViewZoomSensitivityWheel; + + if( hotkeys[HOTKEY_CAMERA_ZOOM_IN] ) + zoom_delta += m_ViewZoomSensitivity*DeltaTime; + else if( hotkeys[HOTKEY_CAMERA_ZOOM_OUT] ) + zoom_delta -= m_ViewZoomSensitivity*DeltaTime; + + if (zoom_delta) + { + float zoom_proportion = powf(m_ViewZoomSmoothness, DeltaTime); + m_Camera.m_Orientation.Translate(forwards * (zoom_delta * (1.0f-zoom_proportion))); + zoom_delta *= zoom_proportion; + } + + +#elif CAMERASTYLE == 1 + + // Remember previous mouse position, to calculate changes + static mouse_last_x = 0; + static mouse_last_y = 0; + + // Miscellaneous vectors + CVector3D forwards = m_Camera.m_Orientation.GetIn(); + CVector3D upwards (0.0f, 1.0f, 0.0f); + CVector3D rightwards = upwards.Cross(forwards); + + // Click and drag to look around + if (mouseButtons[0]) + { + // Untranslate the camera, so it rotates around the correct point + CVector3D position = m_Camera.m_Orientation.GetTranslation(); + m_Camera.m_Orientation.Translate(position*-1); + + // Sideways rotation + m_Camera.m_Orientation.RotateY(m_ViewRotateSpeed*(float)(mouse_x-mouse_last_x)); + + // Up/down rotation + CQuaternion temp; + temp.FromAxisAngle(rightwards, m_ViewRotateSpeed*(float)(mouse_y-mouse_last_y)); + m_Camera.m_Orientation.Rotate(temp); + + // Retranslate back to the right position + m_Camera.m_Orientation.Translate(position); + } + mouse_last_x = mouse_x; + mouse_last_y = mouse_y; + + // Calculate the necessary vectors for movement + + rightwards.Normalize(); + CVector3D forwards_horizontal = upwards.Cross(rightwards); + forwards_horizontal.Normalize(); + + // Move when desirable + + if (mouse_x >= g_xres-2) + m_Camera.m_Orientation.Translate(rightwards); + else if (mouse_x <= 3) + m_Camera.m_Orientation.Translate(-rightwards); + + if (mouse_y >= g_yres-2) + m_Camera.m_Orientation.Translate(forwards_horizontal); + else if (mouse_y <= 3) + m_Camera.m_Orientation.Translate(-forwards_horizontal); + + // Smoothed height-changing (move a certain percentage towards the desired height every frame) + + static float height_delta = 0.0f; + + if (mouseButtons[SDL_BUTTON_WHEELUP]) + height_delta -= 4.0f; + else if (mouseButtons[SDL_BUTTON_WHEELDOWN]) + height_delta += 4.0f; + + const float height_speed = 0.2f; + m_Camera.m_Orientation.Translate(0.0f, height_delta*height_speed, 0.0f); + height_delta *= (1.0f - height_speed); + +#else // CAMERASTYLE == 0 + + const float dx = m_ViewScrollSpeed * DeltaTime; + const CVector3D Right(dx,0, dx); + const CVector3D Up (dx,0,-dx); + + if (mouse_x >= g_xres-2) + m_Camera.m_Orientation.Translate(Right); + if (mouse_x <= 3) + m_Camera.m_Orientation.Translate(Right*-1); + + if (mouse_y >= g_yres-2) + m_Camera.m_Orientation.Translate(Up); + if (mouse_y <= 3) + m_Camera.m_Orientation.Translate(Up*-1); + + /* + janwas: grr, plotted the zoom vector on paper twice, but it appears + to be completely wrong. sticking with the FOV hack for now. + if anyone sees what's wrong, or knows how to correctly implement zoom, + please put this code out of its misery :) + */ + // RC - added ScEd style zoom in and out (actually moving camera, rather than fudging fov) + + float dir=0; + if (mouseButtons[SDL_BUTTON_WHEELUP]) dir=-1; + else if (mouseButtons[SDL_BUTTON_WHEELDOWN]) dir=1; + + float factor=dir*dir; + if (factor) { + if (dir<0) factor=-factor; + CVector3D forward=m_Camera.m_Orientation.GetIn(); + + // check we're not going to zoom into the terrain, or too far out into space + float h=m_Camera.m_Orientation.GetTranslation().Y+forward.Y*factor*m_Camera.Zoom; + float minh=65536*HEIGHT_SCALE*1.05f; + + if (h1500) { + // yup, we will; don't move anywhere (do clamped move instead, at some point) + } else { + // do a full move + m_Camera.Zoom-=(factor)*0.1f; + if (m_Camera.Zoom<0.01f) m_Camera.Zoom=0.01f; + m_Camera.m_Orientation.Translate(forward*(factor*m_Camera.Zoom)); + } + } +#endif // CAMERASTYLE + + m_Camera.UpdateFrustum (); +} + +void CGameView::PushCameraTarget( const CVector3D& target ) +{ + // Save the current position + m_CameraTargets.push_back( m_Camera.m_Orientation.GetTranslation() ); + // And set the camera + SetCameraTarget( target ); +} + +void CGameView::SetCameraTarget( const CVector3D& target ) +{ + // Maintain the same orientation and level of zoom, if we can + // (do this by working out the point the camera is looking at, saving + // the difference beteen that position and the camera point, and restoring + // that difference to our new target) + + CHFTracer tracer( m_pWorld->GetTerrain() ); + int x, z; + CVector3D origin, dir, currentTarget; + origin = m_Camera.m_Orientation.GetTranslation(); + dir = m_Camera.m_Orientation.GetIn(); + if( tracer.RayIntersect( origin, dir, x, z, currentTarget ) ) + { + m_CameraDelta = target - currentTarget; + } + else + m_CameraDelta = ( target - dir * 160.0f ) - origin; +} + +void CGameView::PopCameraTarget() +{ + m_CameraDelta = m_CameraTargets.back() - m_Camera.m_Orientation.GetTranslation(); + m_CameraTargets.pop_back(); +} + +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) + return EV_PASS; + + switch(ev->type) + { + + case SDL_HOTKEYDOWN: + switch(ev->user.code) + { + case HOTKEY_WIREFRAME: + if (g_Renderer.GetTerrainRenderMode()==WIREFRAME) { + g_Renderer.SetTerrainRenderMode(SOLID); + } else { + g_Renderer.SetTerrainRenderMode(WIREFRAME); + } + return( EV_HANDLED ); + + case HOTKEY_CAMERA_RESET: + pView->ResetCamera(); + return( EV_HANDLED ); + + case HOTKEY_CAMERA_ROTATE_ABOUT_TARGET: + pView->RotateAboutTarget(); + return( EV_HANDLED ); + + } + + } + + return EV_PASS; +} diff --git a/source/graphics/GameView.h b/source/graphics/GameView.h index aad92c65e4..7c3c0ff69c 100755 --- a/source/graphics/GameView.h +++ b/source/graphics/GameView.h @@ -1,22 +1,40 @@ #ifndef _GameView_H #define _GameView_H +#include "Camera.h" +#include "Vector3D.h" + class CGame; class CGameAttributes; class CWorld; class CTerrain; class CUnitManager; class CModel; -class CCamera; - -extern CCamera g_Camera; class CGameView { CGame *m_pGame; CWorld *m_pWorld; - CCamera *m_pCamera; + CCamera m_Camera; + //////////////////////////////////////// + // Settings + float m_ViewScrollSpeed; + float m_ViewRotateSensitivity; + float m_ViewRotateAboutTargetSensitivity; + float m_ViewDragSensitivity; + float m_ViewZoomSensitivityWheel; + float m_ViewZoomSensitivity; + float m_ViewZoomSmoothness; // 0.0 = instantaneous zooming, 1.0 = so slow it never moves + float m_ViewSnapSmoothness; // Just the same. + + //////////////////////////////////////// + // Camera Controls State + CVector3D m_CameraDelta; + CVector3D m_CameraPivot; + //float m_CameraZoom; + std::vector m_CameraTargets; + // RenderTerrain: iterate through all terrain patches and submit all patches // in viewing frustum to the renderer void RenderTerrain(CTerrain *pTerrain); @@ -28,22 +46,37 @@ class CGameView // SubmitModelRecursive: recurse down given model, submitting it and all its // descendents to the renderer void SubmitModelRecursive(CModel *pModel); + + // InitResources(): Load all graphics resources (textures, actor objects and + // alpha maps) required by the game + void InitResources(); public: CGameView(CGame *pGame); void Initialize(CGameAttributes *pGameAttributes); - /* - Render the World - */ + // Update: Update all the view information (i.e. rotate camera, scroll, + // whatever). This will *not* change any World information - only the + // *presentation* + void Update(float DeltaTime); + + // Render: Render the World void Render(); // RenderNoCull: render absolutely everything to a blank frame to force // renderer to load required assets void RenderNoCull(); + // Camera Control Functions (used by input handler) + void ResetCamera(); + void RotateAboutTarget(); + + void PushCameraTarget( const CVector3D& target ); + void SetCameraTarget( const CVector3D& target ); + void PopCameraTarget(); + inline CCamera *GetCamera() - { return m_pCamera; } + { return &m_Camera; } }; #endif diff --git a/source/graphics/HFTracer.cpp b/source/graphics/HFTracer.cpp index 27ab6a32c1..196c9f8e4e 100755 --- a/source/graphics/HFTracer.cpp +++ b/source/graphics/HFTracer.cpp @@ -13,13 +13,14 @@ #include "Bound.h" #include "Vector3D.h" -extern CTerrain g_Terrain; - /////////////////////////////////////////////////////////////////////////////// // CHFTracer constructor -CHFTracer::CHFTracer(const u16* hf,u32 mapsize,float cellsize,float heightscale) - : m_Heightfield(hf), m_MapSize(mapsize), m_CellSize(cellsize), - m_HeightScale(heightscale) +CHFTracer::CHFTracer(CTerrain *pTerrain): + m_pTerrain(pTerrain), + m_Heightfield(m_pTerrain->GetHeightMap()), + m_MapSize(m_pTerrain->GetVerticesPerSide()), + m_CellSize(CELL_SIZE), + m_HeightScale(HEIGHT_SCALE) { } @@ -82,10 +83,10 @@ bool CHFTracer::CellIntersect(int cx,int cz,CVector3D& origin,CVector3D& dir,flo // get vertices for this cell CVector3D vpos[4]; - g_Terrain.CalcPosition(cx,cz,vpos[0]); - g_Terrain.CalcPosition(cx+1,cz,vpos[1]); - g_Terrain.CalcPosition(cx+1,cz+1,vpos[2]); - g_Terrain.CalcPosition(cx,cz+1,vpos[3]); + m_pTerrain->CalcPosition(cx,cz,vpos[0]); + m_pTerrain->CalcPosition(cx+1,cz,vpos[1]); + m_pTerrain->CalcPosition(cx+1,cz+1,vpos[2]); + m_pTerrain->CalcPosition(cx,cz+1,vpos[3]); dist=1.0e30f; if (RayTriIntersect(vpos[0],vpos[1],vpos[2],origin,dir,dist)) { diff --git a/source/graphics/HFTracer.h b/source/graphics/HFTracer.h index e2d9c88c85..81581713de 100755 --- a/source/graphics/HFTracer.h +++ b/source/graphics/HFTracer.h @@ -10,6 +10,7 @@ #define _HFTRACER_H class CVector3D; +class CTerrain; #include "res/res.h" @@ -19,7 +20,7 @@ class CHFTracer { public: // constructor; setup data - CHFTracer(const u16* hf,u32 mapsize,float cellsize,float heightscale); + CHFTracer(CTerrain *pTerrain); // intersect ray with this heightfield; return true if intersection // occurs (and fill in grid coordinates and point of intersection), or false otherwise @@ -35,6 +36,8 @@ private: // test if ray intersects either of the triangles in the given bool CellIntersect(int cx,int cz,CVector3D& origin,CVector3D& dir,float& dist) const; + // The terrain we're operating on + CTerrain *m_pTerrain; // the heightfield were tracing const u16* m_Heightfield; // size of the heightfield diff --git a/source/graphics/MapReader.cpp b/source/graphics/MapReader.cpp index 5b20d15687..4f6469f207 100755 --- a/source/graphics/MapReader.cpp +++ b/source/graphics/MapReader.cpp @@ -12,18 +12,13 @@ #include "Terrain.h" #include "TextureManager.h" -extern CTerrain g_Terrain; -extern CLightEnv g_LightEnv; - - - // CMapReader constructor: nothing to do at the minute CMapReader::CMapReader() { } // LoadMap: try to load the map from given file; reinitialise the scene to new data if successful -void CMapReader::LoadMap(const char* filename) +void CMapReader::LoadMap(const char* filename, CTerrain *pTerrain, CUnitManager *pUnitMan, CLightEnv *pLightEnv) { CFileUnpacker unpacker; unpacker.Read(filename,"PSMP"); @@ -37,7 +32,7 @@ void CMapReader::LoadMap(const char* filename) UnpackMap(unpacker); // finally, apply data to the world - ApplyData(unpacker); + ApplyData(unpacker, pTerrain, pUnitMan, pLightEnv); } // UnpackMap: unpack the given data from the raw data stream into local variables @@ -122,10 +117,10 @@ void CMapReader::UnpackTerrain(CFileUnpacker& unpacker) } // ApplyData: take all the input data, and rebuild the scene from it -void CMapReader::ApplyData(CFileUnpacker& unpacker) +void CMapReader::ApplyData(CFileUnpacker& unpacker, CTerrain *pTerrain, CUnitManager *pUnitMan, CLightEnv *pLightEnv) { // initialise the terrain - g_Terrain.Initialize(m_MapSize,&m_Heightmap[0]); + pTerrain->Initialize(m_MapSize,&m_Heightmap[0]); // setup the textures on the minipatches STileDesc* tileptr=&m_Tiles[0]; @@ -133,7 +128,7 @@ void CMapReader::ApplyData(CFileUnpacker& unpacker) for (u32 i=0;im_MiniPatches[m][k]; + CMiniPatch& mp=pTerrain->GetPatch(i,j)->m_MiniPatches[m][k]; mp.Tex1=m_TerrainTextures[tileptr->m_Tex1Index]; mp.Tex1Priority=tileptr->m_Priority; @@ -145,7 +140,7 @@ void CMapReader::ApplyData(CFileUnpacker& unpacker) } // empty out existing units - g_UnitMan.DeleteAll(); + pUnitMan->DeleteAll(); // add new objects for (u32 i=0;iGetIn(); @@ -171,13 +167,13 @@ void CMapReader::ApplyData(CFileUnpacker& unpacker) unit->GetModel()->SetTransform(transform); // add this unit to list of units stored in unit manager - g_UnitMan.AddUnit(unit); + pUnitMan->AddUnit(unit); } } } if (unpacker.GetVersion()>=2) { // copy over the lighting parameters - g_LightEnv=m_LightEnv; + *pLightEnv=m_LightEnv; } } diff --git a/source/graphics/MapReader.h b/source/graphics/MapReader.h index fc0b5b1db3..90dcd2e666 100755 --- a/source/graphics/MapReader.h +++ b/source/graphics/MapReader.h @@ -7,6 +7,9 @@ #include "FileUnpacker.h" class CObjectEntry; +class CTerrain; +class CUnitManager; +class CLightEnv; class CMapReader : public CMapIO { @@ -14,7 +17,7 @@ public: // constructor CMapReader(); // LoadMap: try to load the map from given file; reinitialise the scene to new data if successful - void LoadMap(const char* filename); + void LoadMap(const char* filename, CTerrain *pTerrain, CUnitManager *pUnitMan, CLightEnv *pLightEnv); private: // UnpackMap: unpack the given data from the raw data stream into local variables @@ -27,7 +30,7 @@ private: void UnpackLightEnv(CFileUnpacker& unpacker); // ApplyData: take all the input data, and rebuild the scene from it - void ApplyData(CFileUnpacker& unpacker); + void ApplyData(CFileUnpacker& unpacker, CTerrain *pTerrain, CUnitManager *pUnitMan, CLightEnv *pLightEnv); // size of map u32 m_MapSize; diff --git a/source/graphics/MapWriter.cpp b/source/graphics/MapWriter.cpp index 6328223c07..e2f538fa54 100755 --- a/source/graphics/MapWriter.cpp +++ b/source/graphics/MapWriter.cpp @@ -9,9 +9,6 @@ #include "LightEnv.h" #include "TextureManager.h" -extern CTerrain g_Terrain; -extern CLightEnv g_LightEnv; - /////////////////////////////////////////////////////////////////////////////////////////////////// // CMapWriter constructor: nothing to do at the minute CMapWriter::CMapWriter() @@ -20,12 +17,12 @@ CMapWriter::CMapWriter() /////////////////////////////////////////////////////////////////////////////////////////////////// // SaveMap: try to save the current map to the given file -void CMapWriter::SaveMap(const char* filename) +void CMapWriter::SaveMap(const char* filename, CTerrain *pTerrain, CLightEnv *pLightEnv, CUnitManager *pUnitMan) { CFilePacker packer; // build necessary data - PackMap(packer); + PackMap(packer, pTerrain, pLightEnv, pUnitMan); // write it out packer.Write(filename,FILE_VERSION,"PSMP"); @@ -62,23 +59,24 @@ static u16 GetObjectIndex(const CObjectEntry* object,const std::vector& textures, +void CMapWriter::EnumTerrainTextures(CTerrain *pTerrain, + std::vector& textures, std::vector& tiles) { // the list of all handles in use std::vector handles; // resize tile array to required size - tiles.resize(SQR(g_Terrain.GetVerticesPerSide()-1)); + tiles.resize(SQR(pTerrain->GetVerticesPerSide()-1)); STileDesc* tileptr=&tiles[0]; // now iterate through all the tiles - u32 mapsize=g_Terrain.GetPatchesPerSide(); + u32 mapsize=pTerrain->GetPatchesPerSide(); for (u32 j=0;jm_MiniPatches[m][k]; + CMiniPatch& mp=pTerrain->GetPatch(i,j)->m_MiniPatches[m][k]; u16 index=u16(GetHandleIndex(mp.Tex1,handles)); if (index==0xffff) { index=(u16)handles.size(); @@ -111,13 +109,14 @@ void CMapWriter::EnumTerrainTextures(std::vector& textures, /////////////////////////////////////////////////////////////////////////////////////////////////// // EnumObjects: build lists of object types used by map, and object descriptions for // each object in the world -void CMapWriter::EnumObjects(std::vector& objectTypes,std::vector& objects) +void CMapWriter::EnumObjects(CUnitManager *pUnitMan, + std::vector& objectTypes, std::vector& objects) { // the list of all object entries in use std::vector objectsInUse; // resize object array to required size - const std::vector& units=g_UnitMan.GetUnits(); + const std::vector& units=pUnitMan->GetUnits(); objects.resize(units.size()); SObjectDesc* objptr=&objects[0]; @@ -144,29 +143,29 @@ void CMapWriter::EnumObjects(std::vector& objectTypes,std::vectorm_SunColor,sizeof(pLightEnv->m_SunColor)); + packer.PackRaw(&pLightEnv->m_Elevation,sizeof(pLightEnv->m_Elevation)); + packer.PackRaw(&pLightEnv->m_Rotation,sizeof(pLightEnv->m_Rotation)); + packer.PackRaw(&pLightEnv->m_TerrainAmbientColor,sizeof(pLightEnv->m_TerrainAmbientColor)); + packer.PackRaw(&pLightEnv->m_UnitsAmbientColor,sizeof(pLightEnv->m_UnitsAmbientColor)); } /////////////////////////////////////////////////////////////////////////////////////////////////// // PackObjects: pack world objects onto the end of the output data stream // - data: list of objects types used by map, list of object descriptions -void CMapWriter::PackObjects(CFilePacker& packer) +void CMapWriter::PackObjects(CFilePacker& packer, CUnitManager *pUnitMan) { // the list of object types used by map std::vector objectTypes; @@ -174,7 +173,7 @@ void CMapWriter::PackObjects(CFilePacker& packer) std::vector objects; // build lists by scanning through the world - EnumObjects(objectTypes,objects); + EnumObjects(pUnitMan, objectTypes, objects); // pack object types u32 numObjTypes=(u32)objectTypes.size(); @@ -192,14 +191,14 @@ void CMapWriter::PackObjects(CFilePacker& packer) /////////////////////////////////////////////////////////////////////////////////////////////////// // PackTerrain: pack the terrain onto the end of the output data stream // - data: map size, heightmap, list of textures used by map, texture tile assignments -void CMapWriter::PackTerrain(CFilePacker& packer) +void CMapWriter::PackTerrain(CFilePacker& packer, CTerrain *pTerrain) { // pack map size - u32 mapsize=g_Terrain.GetPatchesPerSide(); + u32 mapsize=pTerrain->GetPatchesPerSide(); packer.PackRaw(&mapsize,sizeof(mapsize)); // pack heightmap - packer.PackRaw(g_Terrain.GetHeightMap(),sizeof(u16)*SQR(g_Terrain.GetVerticesPerSide())); + packer.PackRaw(pTerrain->GetHeightMap(),sizeof(u16)*SQR(pTerrain->GetVerticesPerSide())); // the list of textures used by map std::vector terrainTextures; @@ -207,7 +206,7 @@ void CMapWriter::PackTerrain(CFilePacker& packer) std::vector tiles; // build lists by scanning through the terrain - EnumTerrainTextures(terrainTextures,tiles); + EnumTerrainTextures(pTerrain, terrainTextures, tiles); // pack texture names u32 numTextures=(u32)terrainTextures.size(); diff --git a/source/graphics/MapWriter.h b/source/graphics/MapWriter.h index b7bb2475e1..042d6bc3db 100755 --- a/source/graphics/MapWriter.h +++ b/source/graphics/MapWriter.h @@ -6,31 +6,37 @@ #include "CStr.h" #include "FilePacker.h" +class CLightEnv; +class CTerrain; +class CUnitManager; + class CMapWriter : public CMapIO { public: // constructor CMapWriter(); // SaveMap: try to save the current map to the given file - void SaveMap(const char* filename); + void SaveMap(const char* filename, CTerrain *pTerr, CLightEnv *pLightEnv, CUnitManager *pUnitMan); private: // PackMap: pack the current world into a raw data stream - void PackMap(CFilePacker& packer); + void PackMap(CFilePacker& packer, CTerrain *pTerr, CLightEnv *pLightEnv, CUnitManager *pUnitMan); // PackTerrain: pack the terrain onto the end of the data stream - void PackTerrain(CFilePacker& packer); + void PackTerrain(CFilePacker& packer, CTerrain *pTerrain); // PackObjects: pack world objects onto the end of the output data stream - void PackObjects(CFilePacker& packer); + void PackObjects(CFilePacker& packer, CUnitManager *pUnitMan); // PackLightEnv: pack lighting parameters onto the end of the output data stream - void PackLightEnv(CFilePacker& packer); + void PackLightEnv(CFilePacker& packer, CLightEnv *pLightEnv); // EnumTerrainTextures: build lists of textures used by map, and indices into this list // for each tile on the terrain - void EnumTerrainTextures(std::vector& textures,std::vector& tileIndices); + void EnumTerrainTextures(CTerrain *pTerrain, std::vector& textures, + std::vector& tileIndices); // EnumObjects: build lists of object types used by map, and object descriptions for // each object in the world - void EnumObjects(std::vector& objectTypes,std::vector& objects); + void EnumObjects(CUnitManager *pUnitMan, std::vector& objectTypes, + std::vector& objects); }; #endif diff --git a/source/graphics/Terrain.h b/source/graphics/Terrain.h index abf1fdcbc2..58e10a5d43 100755 --- a/source/graphics/Terrain.h +++ b/source/graphics/Terrain.h @@ -77,9 +77,4 @@ private: u16* m_Heightmap; }; -extern CTerrain* g_Terrain_ptr; -#ifndef g_Terrain -#define g_Terrain (*g_Terrain_ptr) -#endif - #endif diff --git a/source/main.cpp b/source/main.cpp index 3dcdd3328e..4008923fef 100755 --- a/source/main.cpp +++ b/source/main.cpp @@ -91,21 +91,15 @@ static bool g_EntGraph = false; static float g_Gamma = 1.0f; CGameAttributes g_GameAttributes; -CGame *g_Game=NULL; +extern int game_view_handler(const SDL_Event* ev); static Handle g_Font_Console; // for the console static Handle g_Font_Misc; // random font for miscellaneous things -extern CCamera g_Camera; - static CMusicPlayer MusicPlayer; CStr g_CursorName = "test"; -extern void terr_init(); -extern void terr_update(float time); -extern int terr_handler(const SDL_Event* ev); - extern int allow_reload(); extern int dir_add_watch(const char* const dir, bool watch_subdirs); @@ -371,8 +365,7 @@ static int handler(const SDL_Event* ev) void RenderNoCull() { g_Renderer.BeginFrame(); - g_Renderer.SetCamera(g_Camera); - + g_Game->GetView()->RenderNoCull(); g_Renderer.FlushFrame(); @@ -387,13 +380,13 @@ static void Render() // start new frame g_Renderer.BeginFrame(); - g_Renderer.SetCamera(g_Camera); // 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->Render(); + g_Game->GetView()->Render(); + MICROLOG(L"flush frame"); g_Renderer.FlushFrame(); glPushAttrib( GL_ENABLE_BIT ); @@ -681,7 +674,6 @@ static void Shutdown() // destroy terrain related stuff delete &g_TexMan; - delete &g_Terrain; // destroy renderer delete &g_Renderer; @@ -831,12 +823,6 @@ PREVTSC=CURTSC; MICROLOG(L"init renderer"); g_Renderer.Open(g_xres,g_yres,g_bpp); - g_Terrain_ptr = new CTerrain; - - // terr_init loads a bunch of resources as well as setting up the terrain - terr_init(); - - // This needs to be done after the renderer has loaded all its actors... new CBaseEntityCollection; new CEntityManager; @@ -844,8 +830,6 @@ PREVTSC=CURTSC; new CSelectedEntities; new CMouseoverEntities; - g_EntityTemplateCollection.loadTemplates(); - // 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? @@ -867,11 +851,8 @@ PREVTSC=CURTSC; // Initialize entities - CMessage init_msg (CMessage::EMSG_INIT); - g_EntityManager.dispatchAll(&init_msg); - in_add_handler(handler); - in_add_handler(terr_handler); + in_add_handler(game_view_handler); in_add_handler(interactInputHandler); @@ -888,6 +869,7 @@ PREVTSC=CURTSC; RenderNoCull(); if (g_FixedFrameTiming) { + CCamera &g_Camera=*g_Game->GetView()->GetCamera(); #if 0 // TOPDOWN g_Camera.SetProjection(1.0f,10000.0f,DEGTORAD(90)); g_Camera.m_Orientation.SetIdentity(); @@ -1005,8 +987,9 @@ static void Frame() g_Game->Update(TimeSinceLastFrame); if (!g_FixedFrameTiming) - terr_update(float(TimeSinceLastFrame)); + g_Game->GetView()->Update(float(TimeSinceLastFrame)); + // TODO Where does GameView end and other things begin? g_Mouseover.update( TimeSinceLastFrame ); g_Selection.update(); diff --git a/source/ps/Game.cpp b/source/ps/Game.cpp index 36b864843e..62918c315b 100755 --- a/source/ps/Game.cpp +++ b/source/ps/Game.cpp @@ -2,16 +2,21 @@ #include "Game.h" -void CGame::Initialize(CGameAttributes *pAttribs) -{ - m_World.Initialize(pAttribs); - m_Simulation.Initialize(pAttribs); - m_GameView.Initialize(pAttribs); -} +CGame *g_Game=NULL; -void CGame::Render() +PSRETURN CGame::Initialize(CGameAttributes *pAttribs) { - m_GameView.Render(); + try + { + m_World.Initialize(pAttribs); + m_Simulation.Initialize(pAttribs); + m_GameView.Initialize(pAttribs); + } + catch (PSERROR_Game e) + { + return e.code; + } + return 0; } void CGame::Update(double deltaTime) diff --git a/source/ps/Game.h b/source/ps/Game.h index 70d0d26c20..a1b5f27719 100755 --- a/source/ps/Game.h +++ b/source/ps/Game.h @@ -47,23 +47,22 @@ public: /* Initialize all local state and members for playing a game described by the attribute class. + + Return: 0 on OK - a PSRETURN code otherwise */ - void Initialize(CGameAttributes *pGameAttributes); + PSRETURN Initialize(CGameAttributes *pGameAttributes); /* Perform all per-frame updates */ void Update(double deltaTime); - /* - Render the game - */ - void Render(); - inline CWorld *GetWorld() { return &m_World; } inline CGameView *GetView() { return &m_GameView; } }; +extern CGame *g_Game; + #endif diff --git a/source/ps/Interact.cpp b/source/ps/Interact.cpp index e40e6f41b9..6203e84afc 100755 --- a/source/ps/Interact.cpp +++ b/source/ps/Interact.cpp @@ -6,8 +6,9 @@ #include "HFTracer.h" #include "Hotkey.h" #include "timer.h" +#include "Game.h" -extern CCamera g_Camera; +extern CGame *g_Game; extern CConsole* g_Console; extern int mouse_x, mouse_y; extern bool keys[SDLK_LAST]; @@ -15,6 +16,10 @@ extern bool keys[SDLK_LAST]; static const float SELECT_DBLCLICK_RATE = 0.5f; static const int ORDER_DELAY = 5; +CVector3D cameraBookmarks[10]; +bool bookmarkInUse[10] = { false, false, false, false, false, false, false, false, false, false }; +u8 currentBookmark = 255; + void CSelectedEntities::addSelection( CEntity* entity ) { m_group = 255; @@ -60,6 +65,9 @@ void CSelectedEntities::renderSelectionOutlines() void CSelectedEntities::renderOverlays() { + CTerrain *pTerrain=g_Game->GetWorld()->GetTerrain(); + CCamera *pCamera=g_Game->GetView()->GetCamera(); + glPushMatrix(); glEnable( GL_TEXTURE_2D ); std::vector::iterator it; @@ -71,11 +79,11 @@ void CSelectedEntities::renderOverlays() glLoadIdentity(); float x, y; - CVector3D labelpos = (*it)->m_graphics_position - g_Camera.m_Orientation.GetLeft() * (*it)->m_bounds->m_radius; + CVector3D labelpos = (*it)->m_graphics_position - pCamera->m_Orientation.GetLeft() * (*it)->m_bounds->m_radius; #ifdef SELECTION_TERRAIN_CONFORMANCE - labelpos.Y = g_Terrain.getExactGroundLevel( labelpos.X, labelpos.Z ); + labelpos.Y = pTerrain->getExactGroundLevel( labelpos.X, labelpos.Z ); #endif - g_Camera.GetScreenCoordinates( labelpos, x, y ); + pCamera->GetScreenCoordinates( labelpos, x, y ); glColor4f( 1.0f, 1.0f, 1.0f, 1.0f ); glTranslatef( x, g_Renderer.GetHeight() - y, 0.0f ); glScalef( 1.0f, -1.0f, 1.0f ); @@ -95,11 +103,11 @@ void CSelectedEntities::renderOverlays() glLoadIdentity(); float x, y; - CVector3D labelpos = (*it)->m_graphics_position - g_Camera.m_Orientation.GetLeft() * (*it)->m_bounds->m_radius; + CVector3D labelpos = (*it)->m_graphics_position - pCamera->m_Orientation.GetLeft() * (*it)->m_bounds->m_radius; #ifdef SELECTION_TERRAIN_CONFORMANCE - labelpos.Y = g_Terrain.getExactGroundLevel( labelpos.X, labelpos.Z ); + labelpos.Y = pTerrain->getExactGroundLevel( labelpos.X, labelpos.Z ); #endif - g_Camera.GetScreenCoordinates( labelpos, x, y ); + pCamera->GetScreenCoordinates( labelpos, x, y ); glColor4f( 1.0f, 1.0f, 1.0f, 0.5f ); glTranslatef( x, g_Renderer.GetHeight() - y, 0.0f ); glScalef( 1.0f, -1.0f, 1.0f ); @@ -275,13 +283,13 @@ void CSelectedEntities::highlightGroup( u8 groupid ) if( !getGroupCount( groupid ) ) return; m_group_highlight = groupid; - pushCameraTarget( getGroupPosition( groupid ) ); + g_Game->GetView()->PushCameraTarget( getGroupPosition( groupid ) ); } void CSelectedEntities::highlightNone() { if( m_group_highlight != 255 ) - popCameraTarget(); + g_Game->GetView()->PopCameraTarget(); m_group_highlight = 255; } @@ -312,7 +320,7 @@ void CSelectedEntities::update() m_contextOrder = -1; } if( ( m_group_highlight != 255 ) && getGroupCount( m_group_highlight ) ) - setCameraTarget( getGroupPosition( m_group_highlight ) ); + g_Game->GetView()->SetCameraTarget( getGroupPosition( m_group_highlight ) ); } void CSelectedEntities::setContext( int contextOrder ) @@ -369,18 +377,21 @@ bool CSelectedEntities::isContextValid( int contextOrder ) void CSelectedEntities::contextOrder( bool pushQueue ) { + CCamera *pCamera=g_Game->GetView()->GetCamera(); + CTerrain *pTerrain=g_Game->GetWorld()->GetTerrain(); + std::vector::iterator it; CEntityOrder context, contextRandomized; (int&)context.m_type = m_contextOrder; CVector3D origin, dir; - g_Camera.BuildCameraRay( origin, dir ); + pCamera->BuildCameraRay( origin, dir ); switch( m_contextOrder ) { case CEntityOrder::ORDER_GOTO: case CEntityOrder::ORDER_PATROL: { - CHFTracer maptracer( g_Terrain.GetHeightMap(), g_Terrain.GetVerticesPerSide(), (float)CELL_SIZE, HEIGHT_SCALE ); + CHFTracer maptracer( pTerrain ); int x, y; CVector3D ipt; maptracer.RayIntersect( origin, dir, x, y, ipt ); context.m_data[0].location.x = ipt.X; @@ -423,8 +434,11 @@ void CSelectedEntities::contextOrder( bool pushQueue ) void CMouseoverEntities::update( float timestep ) { + CCamera *pCamera=g_Game->GetView()->GetCamera(); + CTerrain *pTerrain=g_Game->GetWorld()->GetTerrain(); + CVector3D origin, dir; - g_Camera.BuildCameraRay( origin, dir ); + pCamera->BuildCameraRay( origin, dir ); CUnit* hit = g_UnitMan.PickUnit( origin, dir ); @@ -473,7 +487,7 @@ void CMouseoverEntities::update( float timestep ) float x, y; - g_Camera.GetScreenCoordinates( worldspace, x, y ); + pCamera->GetScreenCoordinates( worldspace, x, y ); bool inBox; if( m_x1 < m_x2 ) @@ -616,6 +630,9 @@ void CMouseoverEntities::renderSelectionOutlines() void CMouseoverEntities::renderOverlays() { + CCamera *pCamera=g_Game->GetView()->GetCamera(); + CTerrain *pTerrain=g_Game->GetWorld()->GetTerrain(); + glLoadIdentity(); glDisable( GL_TEXTURE_2D ); if( m_bandbox ) @@ -642,11 +659,11 @@ void CMouseoverEntities::renderOverlays() glEnable( GL_TEXTURE_2D ); glLoadIdentity(); float x, y; - CVector3D labelpos = it->entity->m_graphics_position - g_Camera.m_Orientation.GetLeft() * it->entity->m_bounds->m_radius; + CVector3D labelpos = it->entity->m_graphics_position - pCamera->m_Orientation.GetLeft() * it->entity->m_bounds->m_radius; #ifdef SELECTION_TERRAIN_CONFORMANCE - labelpos.Y = g_Terrain.getExactGroundLevel( labelpos.X, labelpos.Z ); + labelpos.Y = pTerrain->getExactGroundLevel( labelpos.X, labelpos.Z ); #endif - g_Camera.GetScreenCoordinates( labelpos, x, y ); + pCamera->GetScreenCoordinates( labelpos, x, y ); glColor4f( 1.0f, 1.0f, 1.0f, it->fade ); glTranslatef( x, g_Renderer.GetHeight() - y, 0.0f ); glScalef( 1.0f, -1.0f, 1.0f ); @@ -670,7 +687,10 @@ void CMouseoverEntities::stopBandbox() int interactInputHandler( const SDL_Event* ev ) { - + CGameView *pView=g_Game->GetView(); + CCamera *pCamera=pView->GetCamera(); + CTerrain *pTerrain=g_Game->GetWorld()->GetTerrain(); + static float lastclicktime = 0.0f; static CEntity* lastclickobject = NULL; static u8 clicks = 0; @@ -688,7 +708,7 @@ int interactInputHandler( const SDL_Event* ev ) break; case HOTKEY_SELECTION_SNAP: if( g_Selection.m_selected.size() ) - setCameraTarget( g_Selection.getSelectionPosition() ); + pView->SetCameraTarget( g_Selection.getSelectionPosition() ); break; case HOTKEY_CONTEXTORDER_NEXT: g_Selection.nextContext(); @@ -697,7 +717,7 @@ int interactInputHandler( const SDL_Event* ev ) g_Selection.previousContext(); break; default: - if( ( ev->user.code >= HOTKEY_SELECTION_GROUP_0 ) && ( ev->key.keysym.sym <= HOTKEY_SELECTION_GROUP_19 ) ) + if( ( ev->user.code >= HOTKEY_SELECTION_GROUP_0 ) && ( ev->user.code <= HOTKEY_SELECTION_GROUP_19 ) ) { // The above test limits it to 20 groups, so don't worry about overflowing u8 id = (u8)( ev->user.code - HOTKEY_SELECTION_GROUP_0 ); @@ -718,7 +738,7 @@ int interactInputHandler( const SDL_Event* ev ) { if( ( g_Selection.m_group == id ) && g_Selection.getGroupCount( id ) ) { - setCameraTarget( g_Selection.getGroupPosition( id ) ); + pView->SetCameraTarget( g_Selection.getGroupPosition( id ) ); } else g_Selection.loadGroup( id ); @@ -732,10 +752,11 @@ int interactInputHandler( const SDL_Event* ev ) if( hotkeys[HOTKEY_CAMERA_BOOKMARK_SAVE] ) { // Attempt to track the ground we're looking at - CHFTracer tracer( g_Terrain.GetHeightMap(), g_Terrain.GetVerticesPerSide(), (float)CELL_SIZE, (float)HEIGHT_SCALE ); int x, z; + CHFTracer tracer( pTerrain ); + int x, z; CVector3D origin, dir, delta, currentTarget; - origin = g_Camera.m_Orientation.GetTranslation(); - dir = g_Camera.m_Orientation.GetIn(); + origin = pCamera->m_Orientation.GetTranslation(); + dir = pCamera->m_Orientation.GetIn(); if( tracer.RayIntersect( origin, dir, x, z, currentTarget ) ) { cameraBookmarks[id] = currentTarget; @@ -743,7 +764,7 @@ int interactInputHandler( const SDL_Event* ev ) else { // Placing a bookmark off the map? If you say so, guv'nor. - cameraBookmarks[id] = g_Camera.m_Orientation.GetTranslation() + g_Camera.m_Orientation.GetIn() * 160.0f; + cameraBookmarks[id] = pCamera->m_Orientation.GetTranslation() + pCamera->m_Orientation.GetIn() * 160.0f; } bookmarkInUse[id] = true; } @@ -751,14 +772,14 @@ int interactInputHandler( const SDL_Event* ev ) { if( bookmarkInUse[id] && ( currentBookmark == 255 ) ) { - pushCameraTarget( cameraBookmarks[id] ); + pView->PushCameraTarget( cameraBookmarks[id] ); currentBookmark = id; } } else { if( bookmarkInUse[id] ) - setCameraTarget( cameraBookmarks[id] ); + pView->SetCameraTarget( cameraBookmarks[id] ); } return( EV_HANDLED ); } @@ -774,7 +795,7 @@ int interactInputHandler( const SDL_Event* ev ) break; case HOTKEY_CAMERA_BOOKMARK_SNAP: if( currentBookmark != 255 ) - popCameraTarget(); + pView->PopCameraTarget(); currentBookmark = 255; break; case HOTKEY_HIGHLIGHTALL: @@ -855,7 +876,9 @@ int interactInputHandler( const SDL_Event* ev ) bool isOnScreen( CEntity* ev ) { - CFrustum frustum = g_Camera.GetFrustum(); + CCamera *pCamera=g_Game->GetView()->GetCamera(); + + CFrustum frustum = pCamera->GetFrustum(); return( frustum.IsBoxVisible( CVector3D(), ev->m_actor->GetModel()->GetBounds() ) ); } @@ -869,36 +892,3 @@ bool isMouseoverType( CEntity* ev ) } return( false ); } - -void pushCameraTarget( const CVector3D& target ) -{ - // Save the current position - cameraTargets.push_back( g_Camera.m_Orientation.GetTranslation() ); - // And set the camera - setCameraTarget( target ); -} - -void setCameraTarget( const CVector3D& target ) -{ - // Maintain the same orientation and level of zoom, if we can - // (do this by working out the point the camera is looking at, saving - // the difference beteen that position and the camera point, and restoring - // that difference to our new target) - - CHFTracer tracer( g_Terrain.GetHeightMap(), g_Terrain.GetVerticesPerSide(), (float)CELL_SIZE, (float)HEIGHT_SCALE ); int x, z; - CVector3D origin, dir, currentTarget; - origin = g_Camera.m_Orientation.GetTranslation(); - dir = g_Camera.m_Orientation.GetIn(); - if( tracer.RayIntersect( origin, dir, x, z, currentTarget ) ) - { - cameraDelta = target - currentTarget; - } - else - cameraDelta = ( target - dir * 160.0f ) - origin; -} - -void popCameraTarget() -{ - cameraDelta = cameraTargets.back() - g_Camera.m_Orientation.GetTranslation(); - cameraTargets.pop_back(); -} diff --git a/source/ps/Interact.h b/source/ps/Interact.h index a9b5922385..9a34b9e314 100755 --- a/source/ps/Interact.h +++ b/source/ps/Interact.h @@ -103,18 +103,8 @@ struct CMouseoverEntities : public Singleton bool isMouseoverType( CEntity* ev ); bool isOnScreen( CEntity* ev ); -void pushCameraTarget( const CVector3D& target ); -void setCameraTarget( const CVector3D& target ); -void popCameraTarget(); - int interactInputHandler( const SDL_Event* ev ); -extern std::vector cameraTargets; -extern CVector3D cameraBookmarks[10]; -extern bool bookmarkInUse[10]; -extern u8 currentBookmark; -extern CVector3D cameraDelta; - #define g_Selection CSelectedEntities::GetSingleton() #define g_Mouseover CMouseoverEntities::GetSingleton() diff --git a/source/ps/World.cpp b/source/ps/World.cpp index bdb552fa0b..6048808202 100755 --- a/source/ps/World.cpp +++ b/source/ps/World.cpp @@ -8,21 +8,22 @@ #include "MapReader.h" #include "Game.h" #include "Terrain.h" +#include "LightEnv.h" +#include "BaseEntityCollection.h" -CTerrain* g_Terrain_ptr = NULL; +extern CLightEnv g_LightEnv; void CWorld::Initialize(CGameAttributes *pAttribs) { - // load a map if we were given one - if (pAttribs->m_MapFile) { - CStr mapfilename("mods/official/maps/scenarios/"); - mapfilename+=pAttribs->m_MapFile; - try { - CMapReader reader; - reader.LoadMap(mapfilename); - } catch (...) { - LOG(ERROR, "Failed to load map %s", mapfilename.c_str()); - throw PSERROR_Game_World_MapLoadFailed(); - } + g_EntityTemplateCollection.loadTemplates(); + + CStr mapfilename("mods/official/maps/scenarios/"); + mapfilename+=pAttribs->m_MapFile; + try { + CMapReader reader; + reader.LoadMap(mapfilename, &m_Terrain, &m_UnitManager, &g_LightEnv); + } catch (...) { + LOG(ERROR, "Failed to load map %s", mapfilename.c_str()); + throw PSERROR_Game_World_MapLoadFailed(); } } diff --git a/source/ps/World.h b/source/ps/World.h index 83faa72a9d..c9b4707da8 100755 --- a/source/ps/World.h +++ b/source/ps/World.h @@ -1,15 +1,12 @@ #ifndef _ps_World_H #define _ps_World_H +#include "Terrain.h" +#include "UnitManager.h" + class CGame; class CGameAttributes; -class CTerrain; -extern CTerrain* g_Terrain_ptr; -#define g_Terrain (*g_Terrain_ptr) - -#include "UnitManager.h" - class CWorld { CGame *m_pGame; @@ -17,13 +14,13 @@ class CWorld // 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_pTerrain; - CUnitManager *m_pUnitManager; + CTerrain m_Terrain; + CUnitManager &m_UnitManager; public: inline CWorld(CGame *pGame): m_pGame(pGame), - m_pTerrain(&g_Terrain), - m_pUnitManager(&g_UnitMan) + m_Terrain(), + m_UnitManager(g_UnitMan) {} /* @@ -32,9 +29,9 @@ public: void Initialize(CGameAttributes *pGameAttributes); inline CTerrain *GetTerrain() - { return m_pTerrain; } + { return &m_Terrain; } inline CUnitManager *GetUnitManager() - { return m_pUnitManager; } + { return &m_UnitManager; } }; #include "Game.h" diff --git a/source/scripting/ScriptingHost.h b/source/scripting/ScriptingHost.h index 5b3c8bc138..3a58c96675 100755 --- a/source/scripting/ScriptingHost.h +++ b/source/scripting/ScriptingHost.h @@ -12,6 +12,8 @@ # endif #endif +#include "Errors.h" + ERROR_GROUP(Scripting); ERROR_TYPE(Scripting, RuntimeCreationFailed); ERROR_TYPE(Scripting, ContextCreationFailed); diff --git a/source/simulation/Entity.cpp b/source/simulation/Entity.cpp index 4327c48f5b..4c41f51fda 100755 --- a/source/simulation/Entity.cpp +++ b/source/simulation/Entity.cpp @@ -14,7 +14,7 @@ #include "Collision.h" #include "PathfindEngine.h" -extern CCamera g_Camera; +#include "Game.h" CEntity::CEntity( CBaseEntity* base, CVector3D position, float orientation ) { @@ -155,7 +155,9 @@ void CEntity::updateActorTransforms() void CEntity::snapToGround() { - m_graphics_position.Y = g_Terrain.getExactGroundLevel( m_graphics_position.X, m_graphics_position.Z ); + CTerrain *pTerrain = g_Game->GetWorld()->GetTerrain(); + + m_graphics_position.Y = pTerrain->getExactGroundLevel( m_graphics_position.X, m_graphics_position.Z ); } void CEntity::update( size_t timestep ) @@ -340,6 +342,8 @@ void CEntity::interpolate( float relativeoffset ) void CEntity::render() { + CTerrain *pTerrain = g_Game->GetWorld()->GetTerrain(); + if( !m_orderQueue.empty() ) { std::deque::iterator it; @@ -384,11 +388,11 @@ void CEntity::render() glEnd(); glBegin( GL_LINES ); glColor3f( 1.0f, 0.0f, 0.0f ); - glVertex3f( x0 + fwd.x * r.distance, g_Terrain.getExactGroundLevel( x0 + fwd.x * r.distance, y0 + fwd.y * r.distance ) + 0.25f, y0 + fwd.y * r.distance ); - glVertex3f( r.position.x, g_Terrain.getExactGroundLevel( r.position.x, r.position.y ) + 0.25f, r.position.y ); + glVertex3f( x0 + fwd.x * r.distance, pTerrain->getExactGroundLevel( x0 + fwd.x * r.distance, y0 + fwd.y * r.distance ) + 0.25f, y0 + fwd.y * r.distance ); + glVertex3f( r.position.x, pTerrain->getExactGroundLevel( r.position.x, r.position.y ) + 0.25f, r.position.y ); glEnd(); glBegin( GL_LINE_STRIP ); - glVertex3f( x0, g_Terrain.getExactGroundLevel( x0, y0 ), y0 ); + glVertex3f( x0, pTerrain->getExactGroundLevel( x0, y0 ), y0 ); } switch( it->m_type ) { @@ -405,7 +409,7 @@ void CEntity::render() continue; } - glVertex3f( x, g_Terrain.getExactGroundLevel( x, y ) + 0.25f, y ); + glVertex3f( x, pTerrain->getExactGroundLevel( x, y ) + 0.25f, y ); } glEnd(); @@ -414,11 +418,13 @@ void CEntity::render() glColor3f( 1.0f, 1.0f, 1.0f ); if( getCollisionObject( this ) ) glColor3f( 0.5f, 0.5f, 1.0f ); - m_bounds->render( g_Terrain.getExactGroundLevel( m_position.X, m_position.Z ) + 0.25f ); //m_position.Y + 0.25f ); + m_bounds->render( pTerrain->getExactGroundLevel( m_position.X, m_position.Z ) + 0.25f ); //m_position.Y + 0.25f ); } void CEntity::renderSelectionOutline( float alpha ) { + CTerrain *pTerrain = g_Game->GetWorld()->GetTerrain(); + if( !m_bounds ) return; glColor4f( 1.0f, 1.0f, 1.0f, alpha ); @@ -439,7 +445,7 @@ void CEntity::renderSelectionOutline( float alpha ) float x = pos.X + radius * sin( ang ); float y = pos.Z + radius * cos( ang ); #ifdef SELECTION_TERRAIN_CONFORMANCE - glVertex3f( x, g_Terrain.getExactGroundLevel( x, y ) + 0.25f, y ); + glVertex3f( x, pTerrain->getExactGroundLevel( x, y ) + 0.25f, y ); #else glVertex3f( x, pos.Y + 0.25f, y ); #endif @@ -463,29 +469,29 @@ void CEntity::renderSelectionOutline( float alpha ) for( int i = SELECTION_BOX_POINTS; i > -SELECTION_BOX_POINTS; i-- ) { p = q + u * h + v * ( w * (float)i / (float)SELECTION_BOX_POINTS ); - glVertex3f( p.x, g_Terrain.getExactGroundLevel( p.x, p.y ) + 0.25f, p.y ); + glVertex3f( p.x, pTerrain->getExactGroundLevel( p.x, p.y ) + 0.25f, p.y ); } for( int i = SELECTION_BOX_POINTS; i > -SELECTION_BOX_POINTS; i-- ) { p = q + u * ( h * (float)i / (float)SELECTION_BOX_POINTS ) - v * w; - glVertex3f( p.x, g_Terrain.getExactGroundLevel( p.x, p.y ) + 0.25f, p.y ); + glVertex3f( p.x, pTerrain->getExactGroundLevel( p.x, p.y ) + 0.25f, p.y ); } for( int i = -SELECTION_BOX_POINTS; i < SELECTION_BOX_POINTS; i++ ) { p = q - u * h + v * ( w * (float)i / (float)SELECTION_BOX_POINTS ); - glVertex3f( p.x, g_Terrain.getExactGroundLevel( p.x, p.y ) + 0.25f, p.y ); + glVertex3f( p.x, pTerrain->getExactGroundLevel( p.x, p.y ) + 0.25f, p.y ); } for( int i = -SELECTION_BOX_POINTS; i < SELECTION_BOX_POINTS; i++ ) { p = q + u * ( h * (float)i / (float)SELECTION_BOX_POINTS ) + v * w; - glVertex3f( p.x, g_Terrain.getExactGroundLevel( p.x, p.y ) + 0.25f, p.y ); + glVertex3f( p.x, pTerrain->getExactGroundLevel( p.x, p.y ) + 0.25f, p.y ); } #else p = q + u * h + v * w; - glVertex3f( p.x, g_Terrain.getExactGroundLevel( p.x, p.y ) + 0.25f, p.y ); + glVertex3f( p.x, pTerrain->getExactGroundLevel( p.x, p.y ) + 0.25f, p.y ); p = q + u * h - v * w; glVertex3f( p.x, getExactGroundLevel( p.x, p.y ) + 0.25f, p.y ); diff --git a/source/simulation/EntityStateProcessing.cpp b/source/simulation/EntityStateProcessing.cpp index b06a34073d..eecaea200b 100755 --- a/source/simulation/EntityStateProcessing.cpp +++ b/source/simulation/EntityStateProcessing.cpp @@ -9,7 +9,7 @@ #include "PathfindEngine.h" #include "Terrain.h" -extern CTerrain g_Terrain; +#include "Game.h" bool CEntity::processGotoNoPathing( CEntityOrder* current, size_t timestep_millis ) { @@ -192,7 +192,7 @@ bool CEntity::processGotoNoPathing( CEntityOrder* current, size_t timestep_milli } // Will we step off the map? - if( !g_Terrain.isOnMap( m_position.X, m_position.Z ) ) + if( !g_Game->GetWorld()->GetTerrain()->isOnMap( m_position.X, m_position.Z ) ) { // Yes. That's not a particularly good idea, either. diff --git a/source/simulation/PathfindSparse.cpp b/source/simulation/PathfindSparse.cpp index e1a80c51f3..cdb90a11c1 100755 --- a/source/simulation/PathfindSparse.cpp +++ b/source/simulation/PathfindSparse.cpp @@ -2,6 +2,7 @@ #include "PathfindSparse.h" #include "Terrain.h" +#include "Game.h" int SPF_RECURSION_DEPTH = 10; @@ -28,6 +29,8 @@ sparsePathTree::~sparsePathTree() bool sparsePathTree::slice() { + CTerrain *pTerrain = g_Game->GetWorld()->GetTerrain(); + if( type == SPF_OPEN_UNVISITED ) { if( !recursionDepth ) @@ -104,14 +107,14 @@ bool sparsePathTree::slice() // Let me know. // Check that the subwaypoints are on the map... - if( !g_Terrain.isOnMap( left ) ) + if( !pTerrain->isOnMap( left ) ) { // Shut that path down leftPre->type = SPF_IMPOSSIBLE; leftPost->type = SPF_IMPOSSIBLE; } - if( !g_Terrain.isOnMap( right ) ) + if( !pTerrain->isOnMap( right ) ) { // Shut that path down rightPre->type = SPF_IMPOSSIBLE; diff --git a/source/simulation/Simulation.cpp b/source/simulation/Simulation.cpp index c12e2ce8f3..1aa6408978 100755 --- a/source/simulation/Simulation.cpp +++ b/source/simulation/Simulation.cpp @@ -16,7 +16,10 @@ CSimulation::CSimulation(CGame *pGame): {} void CSimulation::Initialize(CGameAttributes *pAttribs) -{} +{ + CMessage init_msg (CMessage::EMSG_INIT); + g_EntityManager.dispatchAll(&init_msg); +} void CSimulation::Update(double frameTime) { diff --git a/source/terrain/terrainMain.cpp b/source/terrain/terrainMain.cpp index fa87273ebe..ca03359303 100755 --- a/source/terrain/terrainMain.cpp +++ b/source/terrain/terrainMain.cpp @@ -27,398 +27,11 @@ extern bool g_active; CMatrix3D g_WorldMat; -CCamera g_Camera; CLightEnv g_LightEnv; -float g_CameraZoom = 10; - -std::vector cameraTargets; -CVector3D cameraBookmarks[10]; -bool bookmarkInUse[10] = { false, false, false, false, false, false, false, false, false, false }; -u8 currentBookmark = 255; -CVector3D cameraDelta; -CVector3D cameraPivot; - -// These were 'const'; loaded from config now. - -float ViewScrollSpeed = 60; -float ViewRotateSensitivity = 0.002f; -float ViewRotateAboutTargetSensitivity = 0.010f; -float ViewDragSensitivity = 0.5f; -float ViewZoomSensitivityWheel = 16.0f; -float ViewZoomSensitivity = 256.0f; -float ViewZoomSmoothness = 0.02f; // 0.0 = instantaneous zooming, 1.0 = so slow it never moves -float ViewSnapSmoothness = 0.02f; // Just the same. - -float ViewFOV; - -extern int g_xres, g_yres; - -void terr_init() +/*void InitScene () { - SViewPort vp; - vp.m_X=0; - vp.m_Y=0; - vp.m_Width=g_xres; - vp.m_Height=g_yres; - g_Camera.SetViewPort(&vp); - - CConfigValue* cfg; - -#define getViewParameter( name, value ) STMT( \ - cfg = g_ConfigDB.GetValue( CFG_SYSTEM, name );\ - if( cfg ) cfg->GetFloat( value ); ) - - getViewParameter( "view.scroll.speed", ViewScrollSpeed ); - getViewParameter( "view.rotate.speed", ViewRotateSensitivity ); - getViewParameter( "view.rotate.abouttarget.speed", ViewRotateAboutTargetSensitivity ); - getViewParameter( "view.drag.speed", ViewDragSensitivity ); - getViewParameter( "view.zoom.speed", ViewZoomSensitivity ); - getViewParameter( "view.zoom.wheel.speed", ViewZoomSensitivityWheel ); - getViewParameter( "view.zoom.smoothness", ViewZoomSmoothness ); - getViewParameter( "view.snap.smoothness", ViewSnapSmoothness ); - - if( ( ViewZoomSmoothness < 0.0f ) || ( ViewZoomSmoothness > 1.0f ) ) ViewZoomSmoothness = 0.02f; - if( ( ViewSnapSmoothness < 0.0f ) || ( ViewSnapSmoothness > 1.0f ) ) ViewSnapSmoothness = 0.02f; - -#undef getViewParameter - - InitResources (); - InitScene (); -} - - -static void move_camera(float DeltaTime) -{ - float delta = powf( ViewSnapSmoothness, DeltaTime ); - g_Camera.m_Orientation.Translate( cameraDelta * ( 1.0f - delta ) ); - cameraDelta *= delta; - -#define CAMERASTYLE 2 // 0 = old style, 1 = relatively new style, 2 = newest style - -#if CAMERASTYLE == 2 - - // This could be rewritten much more reliably, so it doesn't e.g. accidentally tilt - // the camera, assuming we know exactly what limits the camera should have. - - - // Calculate mouse movement - static int mouse_last_x = 0; - static int mouse_last_y = 0; - int mouse_dx = mouse_x - mouse_last_x; - int mouse_dy = mouse_y - mouse_last_y; - mouse_last_x = mouse_x; - mouse_last_y = mouse_y; - - // Miscellaneous vectors - CVector3D forwards = g_Camera.m_Orientation.GetIn(); - CVector3D rightwards = g_Camera.m_Orientation.GetLeft() * -1.0f; // upwards.Cross(forwards); - CVector3D upwards( 0.0f, 1.0f, 0.0f ); - // rightwards.Normalize(); - - CVector3D forwards_horizontal = forwards; - forwards_horizontal.Y = 0.0f; - forwards_horizontal.Normalize(); - - /* - if ((mouseButtons[SDL_BUTTON_MIDDLE] && (keys[SDLK_LCTRL] || keys[SDLK_RCTRL])) - || (mouseButtons[SDL_BUTTON_LEFT] && mouseButtons[SDL_BUTTON_RIGHT]) ) - */ - if( hotkeys[HOTKEY_CAMERA_ROTATE] ) - { - // Ctrl + middle-drag or left-and-right-drag to rotate view - - // Untranslate the camera, so it rotates around the correct point - CVector3D position = g_Camera.m_Orientation.GetTranslation(); - g_Camera.m_Orientation.Translate(position*-1); - - // Sideways rotation - g_Camera.m_Orientation.RotateY(ViewRotateSensitivity * (float)(mouse_dx)); - - // Up/down rotation - CQuaternion temp; - temp.FromAxisAngle(rightwards, ViewRotateSensitivity * (float)(mouse_dy)); - g_Camera.m_Orientation.Rotate(temp); - - // Retranslate back to the right position - g_Camera.m_Orientation.Translate(position); - - } - else if( hotkeys[HOTKEY_CAMERA_ROTATE_ABOUT_TARGET] ) - { - CVector3D origin = g_Camera.m_Orientation.GetTranslation(); - CVector3D delta = origin - cameraPivot; - - CQuaternion rotateH, rotateV; CMatrix3D rotateM; - - // Side-to-side rotation - rotateH.FromAxisAngle( upwards, ViewRotateAboutTargetSensitivity * (float)mouse_dx ); - - // Up-down rotation - rotateV.FromAxisAngle( rightwards, ViewRotateAboutTargetSensitivity * (float)mouse_dy ); - - rotateH *= rotateV; - rotateH.ToMatrix( rotateM ); - - delta = rotateM.Rotate( delta ); - - // Lock the inclination to a rather arbitrary values (for the sake of graphical decency) - - float scan = sqrt( delta.X * delta.X + delta.Z * delta.Z ) / delta.Y; - if( ( scan >= 0.5f ) ) - { - // Move the camera to the origin (in preparation for rotation ) - g_Camera.m_Orientation.Translate( origin * -1.0f ); - - g_Camera.m_Orientation.Rotate( rotateH ); - - // Move the camera back to where it belongs - g_Camera.m_Orientation.Translate( cameraPivot + delta ); - } - - } - else if( hotkeys[HOTKEY_CAMERA_PAN] ) - { - // Middle-drag to pan - g_Camera.m_Orientation.Translate(rightwards * (ViewDragSensitivity * mouse_dx)); - g_Camera.m_Orientation.Translate(forwards_horizontal * (-ViewDragSensitivity * mouse_dy)); - } - - // Mouse movement - - if( !hotkeys[HOTKEY_CAMERA_ROTATE] && !hotkeys[HOTKEY_CAMERA_ROTATE_ABOUT_TARGET] ) - { - if (mouse_x >= g_xres-2) - g_Camera.m_Orientation.Translate(rightwards * (ViewScrollSpeed * DeltaTime)); - else if (mouse_x <= 3) - g_Camera.m_Orientation.Translate(-rightwards * (ViewScrollSpeed * DeltaTime)); - - if (mouse_y >= g_yres-2) - g_Camera.m_Orientation.Translate(-forwards_horizontal * (ViewScrollSpeed * DeltaTime)); - else if (mouse_y <= 3) - g_Camera.m_Orientation.Translate(forwards_horizontal * (ViewScrollSpeed * DeltaTime)); - } - - - // Keyboard movement (added to mouse movement, so you can go faster if you want) - - if( hotkeys[HOTKEY_CAMERA_PAN_RIGHT] ) - g_Camera.m_Orientation.Translate(rightwards * (ViewScrollSpeed * DeltaTime)); - if( hotkeys[HOTKEY_CAMERA_PAN_LEFT] ) - g_Camera.m_Orientation.Translate(-rightwards * (ViewScrollSpeed * DeltaTime)); - - if( hotkeys[HOTKEY_CAMERA_PAN_BACKWARD] ) - g_Camera.m_Orientation.Translate(-forwards_horizontal * (ViewScrollSpeed * DeltaTime)); - if( hotkeys[HOTKEY_CAMERA_PAN_FORWARD] ) - g_Camera.m_Orientation.Translate(forwards_horizontal * (ViewScrollSpeed * DeltaTime)); - - // Smoothed zooming (move a certain percentage towards the desired zoom distance every frame) - - static float zoom_delta = 0.0f; - - if( hotkeys[HOTKEY_CAMERA_ZOOM_WHEEL_IN] ) - zoom_delta += ViewZoomSensitivityWheel; - else if( hotkeys[HOTKEY_CAMERA_ZOOM_WHEEL_OUT] ) - zoom_delta -= ViewZoomSensitivityWheel; - - if( hotkeys[HOTKEY_CAMERA_ZOOM_IN] ) - zoom_delta += ViewZoomSensitivity*DeltaTime; - else if( hotkeys[HOTKEY_CAMERA_ZOOM_OUT] ) - zoom_delta -= ViewZoomSensitivity*DeltaTime; - - if (zoom_delta) - { - float zoom_proportion = powf(ViewZoomSmoothness, DeltaTime); - g_Camera.m_Orientation.Translate(forwards * (zoom_delta * (1.0f-zoom_proportion))); - zoom_delta *= zoom_proportion; - } - - -#elif CAMERASTYLE == 1 - - // Remember previous mouse position, to calculate changes - static mouse_last_x = 0; - static mouse_last_y = 0; - - // Miscellaneous vectors - CVector3D forwards = g_Camera.m_Orientation.GetIn(); - CVector3D upwards (0.0f, 1.0f, 0.0f); - CVector3D rightwards = upwards.Cross(forwards); - - // Click and drag to look around - if (mouseButtons[0]) - { - // Untranslate the camera, so it rotates around the correct point - CVector3D position = g_Camera.m_Orientation.GetTranslation(); - g_Camera.m_Orientation.Translate(position*-1); - - // Sideways rotation - g_Camera.m_Orientation.RotateY(ViewRotateSpeed*(float)(mouse_x-mouse_last_x)); - - // Up/down rotation - CQuaternion temp; - temp.FromAxisAngle(rightwards, ViewRotateSpeed*(float)(mouse_y-mouse_last_y)); - g_Camera.m_Orientation.Rotate(temp); - - // Retranslate back to the right position - g_Camera.m_Orientation.Translate(position); - } - mouse_last_x = mouse_x; - mouse_last_y = mouse_y; - - // Calculate the necessary vectors for movement - - rightwards.Normalize(); - CVector3D forwards_horizontal = upwards.Cross(rightwards); - forwards_horizontal.Normalize(); - - // Move when desirable - - if (mouse_x >= g_xres-2) - g_Camera.m_Orientation.Translate(rightwards); - else if (mouse_x <= 3) - g_Camera.m_Orientation.Translate(-rightwards); - - if (mouse_y >= g_yres-2) - g_Camera.m_Orientation.Translate(forwards_horizontal); - else if (mouse_y <= 3) - g_Camera.m_Orientation.Translate(-forwards_horizontal); - - // Smoothed height-changing (move a certain percentage towards the desired height every frame) - - static float height_delta = 0.0f; - - if (mouseButtons[SDL_BUTTON_WHEELUP]) - height_delta -= 4.0f; - else if (mouseButtons[SDL_BUTTON_WHEELDOWN]) - height_delta += 4.0f; - - const float height_speed = 0.2f; - g_Camera.m_Orientation.Translate(0.0f, height_delta*height_speed, 0.0f); - height_delta *= (1.0f - height_speed); - -#else // CAMERASTYLE == 0 - - const float dx = ViewScrollSpeed * DeltaTime; - const CVector3D Right(dx,0, dx); - const CVector3D Up (dx,0,-dx); - - if (mouse_x >= g_xres-2) - g_Camera.m_Orientation.Translate(Right); - if (mouse_x <= 3) - g_Camera.m_Orientation.Translate(Right*-1); - - if (mouse_y >= g_yres-2) - g_Camera.m_Orientation.Translate(Up); - if (mouse_y <= 3) - g_Camera.m_Orientation.Translate(Up*-1); - - /* - janwas: grr, plotted the zoom vector on paper twice, but it appears - to be completely wrong. sticking with the FOV hack for now. - if anyone sees what's wrong, or knows how to correctly implement zoom, - please put this code out of its misery :) - */ - // RC - added ScEd style zoom in and out (actually moving camera, rather than fudging fov) - - float dir=0; - if (mouseButtons[SDL_BUTTON_WHEELUP]) dir=-1; - else if (mouseButtons[SDL_BUTTON_WHEELDOWN]) dir=1; - - float factor=dir*dir; - if (factor) { - if (dir<0) factor=-factor; - CVector3D forward=g_Camera.m_Orientation.GetIn(); - - // check we're not going to zoom into the terrain, or too far out into space - float h=g_Camera.m_Orientation.GetTranslation().Y+forward.Y*factor*g_CameraZoom; - float minh=65536*HEIGHT_SCALE*1.05f; - - if (h1500) { - // yup, we will; don't move anywhere (do clamped move instead, at some point) - } else { - // do a full move - g_CameraZoom-=(factor)*0.1f; - if (g_CameraZoom<0.01f) g_CameraZoom=0.01f; - g_Camera.m_Orientation.Translate(forward*(factor*g_CameraZoom)); - } - } -#endif // CAMERASTYLE - - g_Camera.UpdateFrustum (); -} - - -void terr_update(const float DeltaTime) -{ - if(g_active) - move_camera(DeltaTime); -} - -int terr_handler(const SDL_Event* ev) -{ - // put any events that must be processed even if inactive here - - if(!g_active) - return EV_PASS; - - switch(ev->type) - { - - case SDL_HOTKEYDOWN: - switch(ev->user.code) - { - case HOTKEY_WIREFRAME: - if (g_Renderer.GetTerrainRenderMode()==WIREFRAME) { - g_Renderer.SetTerrainRenderMode(SOLID); - } else { - g_Renderer.SetTerrainRenderMode(WIREFRAME); - } - return( EV_HANDLED ); - - case HOTKEY_CAMERA_RESET: - // quick hack to return camera home, for screenshots (after alt+tabbing) - g_Camera.SetProjection (1, 5000, DEGTORAD(20)); - g_Camera.m_Orientation.SetXRotation(DEGTORAD(30)); - g_Camera.m_Orientation.RotateY(DEGTORAD(-45)); - g_Camera.m_Orientation.Translate (100, 150, -100); - return( EV_HANDLED ); - - case HOTKEY_CAMERA_ROTATE_ABOUT_TARGET: - { - int x, z; - CHFTracer tracer( g_Terrain.GetHeightMap(), g_Terrain.GetVerticesPerSide(), (float)CELL_SIZE, HEIGHT_SCALE ); - CVector3D origin, dir; - origin = g_Camera.m_Orientation.GetTranslation(); - dir = g_Camera.m_Orientation.GetIn(); - g_Camera.BuildCameraRay( origin, dir ); - - if( !tracer.RayIntersect( origin, dir, x, z, cameraPivot ) ) - cameraPivot = origin - dir * ( origin.Y / dir.Y ); - } - return( EV_HANDLED ); - - } - - } - - return EV_PASS; -} - - - - -void InitScene () -{ - // 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); - // load terrain TexInfo ti; int err = tex_load("terrain.raw", &ti); @@ -466,35 +79,6 @@ void InitScene () } } - g_Camera.SetProjection (1, 5000, DEGTORAD(20)); - g_Camera.m_Orientation.SetXRotation(DEGTORAD(30)); - g_Camera.m_Orientation.RotateY(DEGTORAD(-45)); - - g_Camera.m_Orientation.Translate (100, 150, -100); -} - -void InitResources() -{ - g_TexMan.LoadTerrainTextures(); - g_ObjMan.LoadObjects(); - - const char* fns[CRenderer::NumAlphaMaps] = { - "art/textures/terrain/alphamaps/special/blendcircle.png", - "art/textures/terrain/alphamaps/special/blendlshape.png", - "art/textures/terrain/alphamaps/special/blendedge.png", - "art/textures/terrain/alphamaps/special/blendedgecorner.png", - "art/textures/terrain/alphamaps/special/blendedgetwocorners.png", - "art/textures/terrain/alphamaps/special/blendfourcorners.png", - "art/textures/terrain/alphamaps/special/blendtwooppositecorners.png", - "art/textures/terrain/alphamaps/special/blendlshapecorner.png", - "art/textures/terrain/alphamaps/special/blendtwocorners.png", - "art/textures/terrain/alphamaps/special/blendcorner.png", - "art/textures/terrain/alphamaps/special/blendtwoedges.png", - "art/textures/terrain/alphamaps/special/blendthreecorners.png", - "art/textures/terrain/alphamaps/special/blendushape.png", - "art/textures/terrain/alphamaps/special/blendbad.png" - }; - - g_Renderer.LoadAlphaMaps(fns); } +*/