diff --git a/CMakeLists.txt b/CMakeLists.txt index 76dd9c82f..2484d6eb1 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -10,19 +10,22 @@ set(CMAKE_MODULE_PATH ${CMAKE_SOURCE_DIR}/cmake/) set(GAME apps/openmw/main.cpp - apps/openmw/engine.cpp) + apps/openmw/engine.cpp + apps/openmw/world.cpp) set(GAME_HEADER apps/openmw/mwinput/inputmanager.hpp - apps/openmw/engine.hpp) + apps/openmw/engine.hpp + apps/openmw/world.hpp) source_group(game FILES ${GAME} ${GAME_HEADER}) set(GAMEREND apps/openmw/mwrender/mwscene.cpp - apps/openmw/mwrender/cell.cpp + apps/openmw/mwrender/cellimp.cpp apps/openmw/mwrender/interior.cpp apps/openmw/mwrender/sky.cpp) set(GAMEREND_HEADER apps/openmw/mwrender/cell.hpp + apps/openmw/mwrender/cellimp.hpp apps/openmw/mwrender/mwscene.hpp apps/openmw/mwrender/interior.hpp apps/openmw/mwrender/playerpos.hpp diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index f431e51bd..82e1ff58f 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -4,19 +4,14 @@ #include -#include "components/esm_store/cell_store.hpp" -#include "components/bsa/bsa_archive.hpp" -#include "components/engine/ogre/renderer.hpp" #include "components/misc/fileops.hpp" +#include "components/bsa/bsa_archive.hpp" -#include "apps/openmw/mwrender/interior.hpp" #include "mwinput/inputmanager.hpp" -#include "apps/openmw/mwrender/playerpos.hpp" -#include "apps/openmw/mwrender/sky.hpp" + +#include "world.hpp" OMW::Engine::Engine() - : mEnableSky (false) - , mpSkyManager (NULL) { } @@ -76,17 +71,11 @@ void OMW::Engine::addMaster (const std::string& master) } } -// Enables sky rendering -// -void OMW::Engine::enableSky (bool bEnable) -{ - mEnableSky = bEnable; -} - // Initialise and enter main loop. void OMW::Engine::go() { + assert (!mWorld); assert (!mDataDir.empty()); assert (!mCellName.empty()); assert (!mMaster.empty()); @@ -104,55 +93,29 @@ void OMW::Engine::go() addResourcesDirectory (mDataDir / "Meshes"); addResourcesDirectory (mDataDir / "Textures"); - loadBSA(); - - boost::filesystem::path masterPath (mDataDir); - masterPath /= mMaster; - - std::cout << "Loading ESM " << masterPath.string() << "\n"; - ESM::ESMReader esm; - ESMS::ESMStore store; - ESMS::CellStore cell; - - // This parses the ESM file and loads a sample cell - esm.open(masterPath.file_string()); - store.load(esm); - - cell.loadInt(mCellName, store, esm); - // Create the window mOgre.createWindow("OpenMW"); - std::cout << "\nSetting up cell rendering\n"; - - // Sets up camera, scene manager, and viewport. - MWRender::MWScene scene(mOgre); - - // Used to control the player camera and position - MWRender::PlayerPos player(scene.getCamera()); - - // This connects the cell data with the rendering scene. - MWRender::InteriorCellRender rend(cell, scene); - - // Load the cell and insert it into the renderer - rend.show(); - - // Optionally enable the sky - if (mEnableSky) - mpSkyManager = MWRender::SkyManager::create(mOgre.getWindow(), scene.getCamera()); + loadBSA(); + // Create the world + mWorld = new World (mOgre, mDataDir, mMaster, mCellName); + std::cout << "Setting up input system\n"; // Sets up the input system - MWInput::MWInputManager input(mOgre, player); + MWInput::MWInputManager input(mOgre, mWorld->getPlayerPos()); std::cout << "\nStart! Press Q/ESC or close window to exit.\n"; // Start the main rendering loop mOgre.start(); - delete mpSkyManager; - std::cout << "\nThat's all for now!\n"; } +OMW::Engine::~Engine() +{ + delete mWorld; +} + diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index ae69f52b4..ec9fb82d2 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -5,15 +5,12 @@ #include -#include "apps/openmw/mwrender/mwscene.hpp" - -namespace MWRender -{ - class SkyManager; -} +#include "components/engine/ogre/renderer.hpp" namespace OMW { + class World; + /// \brief Main engine class, that brings together all the components of OpenMW class Engine @@ -22,10 +19,8 @@ namespace OMW Render::OgreRenderer mOgre; std::string mCellName; std::string mMaster; + World *mWorld; - bool mEnableSky; - MWRender::SkyManager* mpSkyManager; - // not implemented Engine (const Engine&); Engine& operator= (const Engine&); @@ -41,6 +36,8 @@ namespace OMW Engine(); + ~Engine(); + /// Set data dir void setDataDir (const boost::filesystem::path& dataDir); @@ -52,9 +49,6 @@ namespace OMW /// - Currently OpenMW only supports one master at the same time. void addMaster (const std::string& master); - /// Enables rendering of the sky (off by default). - void enableSky (bool bEnable); - /// Initialise and enter main loop. void go(); }; diff --git a/apps/openmw/main.cpp b/apps/openmw/main.cpp index 635384ad5..cb8b8f58e 100644 --- a/apps/openmw/main.cpp +++ b/apps/openmw/main.cpp @@ -29,7 +29,6 @@ bool parseOptions (int argc, char**argv, OMW::Engine& engine) "set initial cell (only interior cells supported at the moment") ("master", bpo::value()->default_value ("Morrowind"), "master file") - ("enablesky", "enable rendering of the sky") ; bpo::variables_map variables; @@ -48,8 +47,6 @@ bool parseOptions (int argc, char**argv, OMW::Engine& engine) return false; } - engine.enableSky(!!variables.count("enablesky")); - engine.setDataDir (variables["data"].as()); engine.setCell (variables["start"].as()); engine.addMaster (variables["master"].as()); diff --git a/apps/openmw/mwrender/cell.hpp b/apps/openmw/mwrender/cell.hpp index 0ddec0964..756ec1cda 100644 --- a/apps/openmw/mwrender/cell.hpp +++ b/apps/openmw/mwrender/cell.hpp @@ -1,43 +1,22 @@ -#ifndef _GAME_RENDER_CELL_H -#define _GAME_RENDER_CELL_H +#ifndef GAME_RENDER_CELL_H +#define GAME_RENDER_CELL_H -#include - -namespace ESM -{ - class CellRef; -} - -namespace ESMS +namespace MWRender { - class CellStore; -} - -namespace MWRender -{ - /// Base class for cell render, that implements inserting references into a cell in a - /// cell type- and render-engine-independent way. - - class CellRender - { - public: - CellRender() {} - virtual ~CellRender() {} - - /// start inserting a new reference. - virtual void insertBegin (const ESM::CellRef &ref) = 0; - - /// insert a mesh related to the most recent insertBegin call. - virtual void insertMesh(const std::string &mesh) = 0; + class CellRender + { + public: - /// insert a light related to the most recent insertBegin call. - virtual void insertLight(float r, float g, float b, float radius) = 0; + virtual ~CellRender() {}; - /// finish inserting a new reference and return a handle to it. - virtual std::string insertEnd() = 0; - - void insertCell(const ESMS::CellStore &cell); - }; + /// Make the cell visible. Load the cell if necessary. + virtual void show() = 0; + + /// Remove the cell from rendering, but don't remove it from + /// memory. + virtual void hide() = 0; + }; } #endif + diff --git a/apps/openmw/mwrender/cell.cpp b/apps/openmw/mwrender/cellimp.cpp similarity index 87% rename from apps/openmw/mwrender/cell.cpp rename to apps/openmw/mwrender/cellimp.cpp index 912418459..10d647673 100644 --- a/apps/openmw/mwrender/cell.cpp +++ b/apps/openmw/mwrender/cellimp.cpp @@ -1,4 +1,4 @@ -#include "cell.hpp" +#include "cellimp.hpp" #include @@ -7,7 +7,7 @@ using namespace MWRender; template -void insertObj(CellRender& cellRender, const T& liveRef) +void insertObj(CellRenderImp& cellRender, const T& liveRef) { assert (liveRef.base != NULL); const std::string &model = liveRef.base->model; @@ -20,7 +20,7 @@ void insertObj(CellRender& cellRender, const T& liveRef) } template<> -void insertObj(CellRender& cellRender, const ESMS::LiveCellRef& liveRef) +void insertObj(CellRenderImp& cellRender, const ESMS::LiveCellRef& liveRef) { assert (liveRef.base != NULL); const std::string &model = liveRef.base->model; @@ -43,7 +43,7 @@ void insertObj(CellRender& cellRender, const ESMS::LiveCellRef& live } template -void insertCellRefList (CellRender& cellRender, const T& cellRefList) +void insertCellRefList (CellRenderImp& cellRender, const T& cellRefList) { for(typename T::List::const_iterator it = cellRefList.list.begin(); it != cellRefList.list.end(); it++) @@ -52,7 +52,7 @@ void insertCellRefList (CellRender& cellRender, const T& cellRefList) } } -void CellRender::insertCell(const ESMS::CellStore &cell) +void CellRenderImp::insertCell(const ESMS::CellStore &cell) { // Loop through all references in the cell insertCellRefList (*this, cell.activators); diff --git a/apps/openmw/mwrender/cellimp.hpp b/apps/openmw/mwrender/cellimp.hpp new file mode 100644 index 000000000..da598bd82 --- /dev/null +++ b/apps/openmw/mwrender/cellimp.hpp @@ -0,0 +1,44 @@ +#ifndef _GAME_RENDER_CELLIMP_H +#define _GAME_RENDER_CELLIMP_H + +#include + +namespace ESM +{ + class CellRef; +} + +namespace ESMS +{ + class CellStore; +} + +namespace MWRender +{ + /// Base class for cell render, that implements inserting references into a cell in a + /// cell type- and render-engine-independent way. + + class CellRenderImp + { + public: + CellRenderImp() {} + virtual ~CellRenderImp() {} + + /// start inserting a new reference. + virtual void insertBegin (const ESM::CellRef &ref) = 0; + + /// insert a mesh related to the most recent insertBegin call. + virtual void insertMesh(const std::string &mesh) = 0; + + /// insert a light related to the most recent insertBegin call. + virtual void insertLight(float r, float g, float b, float radius) = 0; + + /// finish inserting a new reference and return a handle to it. + virtual std::string insertEnd() = 0; + + void insertCell(const ESMS::CellStore &cell); + + }; +} + +#endif diff --git a/apps/openmw/mwrender/interior.hpp b/apps/openmw/mwrender/interior.hpp index 7657a6751..f4876752a 100644 --- a/apps/openmw/mwrender/interior.hpp +++ b/apps/openmw/mwrender/interior.hpp @@ -2,6 +2,7 @@ #define _GAME_RENDER_INTERIOR_H #include "cell.hpp" +#include "cellimp.hpp" #include "components/esm_store/cell_store.hpp" #include "OgreColourValue.h" @@ -23,7 +24,7 @@ namespace MWRender TODO FIXME: Doesn't do full cleanup yet. */ - class InteriorCellRender : private CellRender + class InteriorCellRender : public CellRender, private CellRenderImp { static bool lightConst; @@ -83,14 +84,14 @@ namespace MWRender virtual ~InteriorCellRender() { destroy(); } /// Make the cell visible. Load the cell if necessary. - void show(); + virtual void show(); /// Remove the cell from rendering, but don't remove it from /// memory. void hide(); /// Destroy all rendering objects connected with this cell. - void destroy(); + void destroy(); // comment by Zini: shouldn't this go into the destructor? /// Switch through lighting modes. void toggleLight(); diff --git a/apps/openmw/world.cpp b/apps/openmw/world.cpp new file mode 100644 index 000000000..3aacfdb29 --- /dev/null +++ b/apps/openmw/world.cpp @@ -0,0 +1,61 @@ + +#include "world.hpp" + +#include "components/bsa/bsa_archive.hpp" +#include "components/engine/ogre/renderer.hpp" + +#include "apps/openmw/mwrender/sky.hpp" +#include "apps/openmw/mwrender/interior.hpp" + +namespace OMW +{ + World::World (Render::OgreRenderer& renderer, const boost::filesystem::path& dataDir, + const std::string& master, const std::string& startCell) + : mSkyManager (0), mScene (renderer), mPlayerPos (mScene.getCamera()) + { + boost::filesystem::path masterPath (dataDir); + masterPath /= master; + + std::cout << "Loading ESM " << masterPath.string() << "\n"; + + // This parses the ESM file and loads a sample cell + mEsm.open (masterPath.file_string()); + mStore.load (mEsm); + + mInteriors[startCell].loadInt (startCell, mStore, mEsm); + + std::cout << "\nSetting up cell rendering\n"; + + // This connects the cell data with the rendering scene. + mActiveCells.insert (std::make_pair (&mInteriors[startCell], + new MWRender::InteriorCellRender (mInteriors[startCell], mScene))); + + // Load the cell and insert it into the renderer + for (CellRenderCollection::iterator iter (mActiveCells.begin()); + iter!=mActiveCells.end(); ++iter) + iter->second->show(); + + // Optionally enable the sky +// if (mEnableSky) +// mpSkyManager = MWRender::SkyManager::create(renderer.getWindow(), mScene.getCamera()); + + } + + World::~World() + { + for (CellRenderCollection::iterator iter (mActiveCells.begin()); + iter!=mActiveCells.end(); ++iter) + delete iter->second; + + for (CellRenderCollection::iterator iter (mBufferedCells.begin()); + iter!=mBufferedCells.end(); ++iter) + delete iter->second; + + delete mSkyManager; + } + + MWRender::PlayerPos& World::getPlayerPos() + { + return mPlayerPos; + } +} diff --git a/apps/openmw/world.hpp b/apps/openmw/world.hpp new file mode 100644 index 000000000..8d7955981 --- /dev/null +++ b/apps/openmw/world.hpp @@ -0,0 +1,59 @@ +#ifndef WORLD_H +#define WORLD_H + +#include +#include + +#include + +#include "components/esm_store/cell_store.hpp" + +#include "apps/openmw/mwrender/playerpos.hpp" +#include "apps/openmw/mwrender/mwscene.hpp" + +namespace Render +{ + class OgreRenderer; +} + +namespace MWRender +{ + class SkyManager; + class CellRender; +} + +namespace OMW +{ + /// \brief The game world and its visual representation + + class World + { + typedef std::map CellRenderCollection; + + MWRender::SkyManager* mSkyManager; + MWRender::MWScene mScene; + MWRender::PlayerPos mPlayerPos; + CellRenderCollection mActiveCells; + CellRenderCollection mBufferedCells; // loaded, but not active (buffering not implementd yet) + ESM::ESMReader mEsm; + ESMS::ESMStore mStore; + std::map mInteriors; + + // not implemented + World (const World&); + World& operator= (const World&); + + public: + + World (Render::OgreRenderer& renderer, const boost::filesystem::path& master, + const std::string& dataDir, const std::string& startCell); + + ~World(); + + MWRender::PlayerPos& getPlayerPos(); + + + }; +} + +#endif diff --git a/components/compiler/parser.hpp b/components/compiler/parser.hpp index 88268eb22..a55f5a024 100644 --- a/components/compiler/parser.hpp +++ b/components/compiler/parser.hpp @@ -6,7 +6,7 @@ namespace Compiler { class Scanner; - class TokenLoc; + struct TokenLoc; class ErrorHandler; class Context;