From c84672a560f568c6dfa0be059055ae7b136a459d Mon Sep 17 00:00:00 2001 From: Nicolay Korslund Date: Sat, 17 Jul 2010 14:01:47 +0200 Subject: [PATCH] Added MyGUI to OpenMW, fully working (with events and script hooks) --- CMakeLists.txt | 6 +- apps/mygui_dev/CMakeLists.txt | 1 + apps/mygui_dev/main.cpp | 17 +-- apps/openmw/engine.cpp | 31 ++--- apps/openmw/engine.hpp | 14 +++ apps/openmw/mwinput/inputmanager.hpp | 85 +++++++++++++- apps/openmw/mwscript/guiextensions.cpp | 79 ++++--------- apps/openmw/mwscript/interpretercontext.cpp | 8 +- apps/openmw/mwscript/interpretercontext.hpp | 2 +- apps/openmw/mwworld/environment.hpp | 6 +- apps/openmw/mwworld/world.cpp | 2 - components/esm_store/store.cpp | 6 + components/mwgui/guimanager.cpp | 34 ------ components/mwgui/guimanager.hpp | 52 --------- components/mwgui/window_manager.cpp | 74 ++++++++++++ components/mwgui/window_manager.hpp | 121 ++++++++++++++++++++ libs/openengine | 2 +- testall.sh | 16 --- 18 files changed, 354 insertions(+), 202 deletions(-) delete mode 100644 components/mwgui/guimanager.cpp delete mode 100644 components/mwgui/guimanager.hpp create mode 100644 components/mwgui/window_manager.cpp create mode 100644 components/mwgui/window_manager.hpp delete mode 100755 testall.sh diff --git a/CMakeLists.txt b/CMakeLists.txt index 4d900978fd..2af57c7eae 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -53,9 +53,11 @@ source_group(components\\esm FILES ${ESM_HEADER}) # components/mw_gui set(MWGUI_HEADER ${COMP_DIR}/mwgui/mw_layouts.hpp - ${COMP_DIR}/mwgui/guimanager.hpp) + ${COMP_DIR}/mwgui/window_manager.hpp +) set(MWGUI - ${COMP_DIR}/mwgui/guimanager.cpp) + ${COMP_DIR}/mwgui/window_manager.cpp +) source_group(components\\mwgui FILES ${MWGUI_HEADER} ${MWGUI}) set(COMMANDSERVER diff --git a/apps/mygui_dev/CMakeLists.txt b/apps/mygui_dev/CMakeLists.txt index 82facd0674..9265279e51 100644 --- a/apps/mygui_dev/CMakeLists.txt +++ b/apps/mygui_dev/CMakeLists.txt @@ -1,6 +1,7 @@ add_executable(mygui_test main.cpp ${BSA} ${BSA_HEADER} + ${MWGUI} ${MWGUI_HEADER} ${OENGINE_OGRE} ${OENGINE_GUI} ${MANGLE_INPUT} diff --git a/apps/mygui_dev/main.cpp b/apps/mygui_dev/main.cpp index da39335ee4..2e589ddd68 100644 --- a/apps/mygui_dev/main.cpp +++ b/apps/mygui_dev/main.cpp @@ -7,7 +7,7 @@ using namespace std; #include -#include +#include #include #include @@ -66,23 +66,14 @@ int main() cout << "Setting up MyGUI\n"; OEngine::GUI::MyGUIManager gui(ogre.getWindow(), ogre.getScene()); - int w = ogre.getWindow()->getWidth(); - int h = ogre.getWindow()->getHeight(); - cout << "Connecting to input\n"; OEngine::GUI::EventInjector *evt = new OEngine::GUI::EventInjector(gui.getGui()); input.setEvent(Mangle::Input::EventPtr(evt)); - cout << "Setting up the window layouts\n"; - MWGui::HUD hud(w,h); - MWGui::MapWindow map; - MWGui::MainMenu menu(w,h); - MWGui::StatsWindow stats; + cout << "Setting up the window manager\n"; + MWGui::WindowManager gm(gui.getGui()); - hud.setVisible(true); - map.setVisible(true); - menu.setVisible(false); - stats.setVisible(true); + gm.setMode(MWGui::GM_Inventory); cout << "Starting rendering loop\n"; cout << "PRESS ESCAPE TO EXIT\n"; diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 7918c0cf88..e46e58d94c 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -7,7 +7,8 @@ #include #include -#include +#include +#include #include "mwinput/inputmanager.hpp" @@ -81,8 +82,8 @@ OMW::Engine::~Engine() if (mspCommandServer.get()) mspCommandServer->stop(); + delete mGuiManager; delete mEnvironment.mWorld; - delete mEnvironment.mGuiManager; delete mEnvironment.mSoundManager; delete mEnvironment.mGlobalScripts; delete mScriptManager; @@ -174,11 +175,7 @@ void OMW::Engine::go() assert (!mCellName.empty()); assert (!mMaster.empty()); - std::cout << "Hello, fellow traveler!\n"; - - std::cout << "Your data directory for today is: " << mDataDir << "\n"; - - std::cout << "Initializing OGRE\n"; + std::cout << "Data directory: " << mDataDir << "\n"; const char* plugCfg = "plugins.cfg"; @@ -187,6 +184,10 @@ void OMW::Engine::go() addResourcesDirectory (mDataDir / "Meshes"); addResourcesDirectory (mDataDir / "Textures"); + // This has to be added BEFORE MyGUI is initialized, as it needs + // to find core.xml here. + addResourcesDirectory("resources/mygui/"); + // Create the window mOgre.createWindow("OpenMW"); @@ -195,7 +196,12 @@ void OMW::Engine::go() // Create the world mEnvironment.mWorld = new MWWorld::World (mOgre, mDataDir, mMaster, mCellName, mNewGame); - mEnvironment.mGuiManager = new MWGui::GuiManager; + // Set up the GUI system + mGuiManager = new OEngine::GUI::MyGUIManager(mOgre.getWindow(), + mOgre.getScene()); + + // Create window manager - this manages all the MW-specific GUI windows + mEnvironment.mWindowManager = new MWGui::WindowManager(mGuiManager->getGui()); mEnvironment.mSoundManager = new MWSound::SoundManager; @@ -211,10 +217,9 @@ void OMW::Engine::go() mEnvironment.mGlobalScripts = new MWScript::GlobalScripts (mEnvironment.mWorld->getStore(), *mScriptManager); - std::cout << "Setting up input system\n"; - // Sets up the input system - MWInput::MWInputManager input(mOgre, mEnvironment.mWorld->getPlayerPos(), mDebug); + MWInput::MWInputManager input(mOgre, mEnvironment.mWorld->getPlayerPos(), + *mEnvironment.mWindowManager, mDebug); // Launch the console server if (mEnableCommandServer) @@ -226,14 +231,14 @@ void OMW::Engine::go() else std::cout << "Command server disabled" << std::endl; - std::cout << "\nStart! Press Q/ESC or close window to exit.\n"; + std::cout << "\nPress Q/ESC or close window to exit.\n"; mOgre.getRoot()->addFrameListener (this); // Start the main rendering loop mOgre.start(); - std::cout << "\nThat's all for now!\n"; + std::cout << "Quitting peacefully.\n"; } diff --git a/apps/openmw/engine.hpp b/apps/openmw/engine.hpp index e4b6073cf2..a0d6a16e3d 100644 --- a/apps/openmw/engine.hpp +++ b/apps/openmw/engine.hpp @@ -35,6 +35,19 @@ namespace MWWorld class World; } +namespace MWGui +{ + class WindowManager; +} + +namespace OEngine +{ + namespace GUI + { + class MyGUIManager; + } +} + namespace OMW { /// \brief Main engine class, that brings together all the components of OpenMW @@ -59,6 +72,7 @@ namespace OMW MWScript::ScriptManager *mScriptManager; Compiler::Extensions mExtensions; Compiler::Context *mScriptContext; + OEngine::GUI::MyGUIManager *mGuiManager; // not implemented Engine (const Engine&); diff --git a/apps/openmw/mwinput/inputmanager.hpp b/apps/openmw/mwinput/inputmanager.hpp index b1cd82749e..59b5ad5005 100644 --- a/apps/openmw/mwinput/inputmanager.hpp +++ b/apps/openmw/mwinput/inputmanager.hpp @@ -4,10 +4,14 @@ #include #include +#include + #include #include #include +#include + #include #include @@ -27,6 +31,8 @@ namespace MWInput A_Screenshot, // Take a screenshot + A_Inventory, // Toggle inventory screen + A_MoveLeft, // Move player left / right A_MoveRight, A_MoveUp, // Move up / down @@ -46,10 +52,11 @@ namespace MWInput Mangle::Input::OISDriver input; OEngine::Input::Poller poller; OEngine::Render::MouseLookEventPtr mouse; + OEngine::GUI::EventInjectorPtr guiEvents; MWRender::PlayerPos &player; + MWGui::WindowManager &windows; - // Count screenshots. TODO: We should move this functionality to - // OgreRender or somewhere else. + // Count screenshots. int shotCount; // Write screenshot to file. @@ -66,18 +73,67 @@ namespace MWInput ogre.screenshot(buf); } + // Switch between gui modes. Besides controlling the Gui windows + // this also makes sure input is directed to the right place + void setGuiMode(MWGui::GuiMode mode) + { + // Tell the GUI what to show (this also takes care of the mouse + // pointer) + windows.setMode(mode); + + // Are we in GUI mode now? + if(windows.isGuiMode()) + { + // Disable mouse look + mouse->setCamera(NULL); + + // Enable GUI events + guiEvents->enabled = true; + } + else + { + // Start mouse-looking again. TODO: This should also allow + // for other ways to disable mouselook, like paralyzation. + mouse->setCamera(player.getCamera()); + + // Disable GUI events + guiEvents->enabled = false; + } + } + + // Called when the user presses the button to toggle the inventory + // screen. + void toggleInventory() + { + using namespace MWGui; + + GuiMode mode = windows.getMode(); + + // Toggle between game mode and inventory mode + if(mode == GM_Game) + setGuiMode(GM_Inventory); + else if(mode == GM_Inventory) + setGuiMode(GM_Game); + + // .. but don't touch any other mode. + } + public: MWInputManager(OEngine::Render::OgreRenderer &_ogre, - MWRender::PlayerPos &_player, bool debug) + MWRender::PlayerPos &_player, + MWGui::WindowManager &_windows, + bool debug) : ogre(_ogre), exit(ogre.getWindow()), input(ogre.getWindow(), !debug), poller(input), player(_player), + windows(_windows), shotCount(0) { using namespace OEngine::Input; using namespace OEngine::Render; + using namespace OEngine::GUI; using namespace Mangle::Input; using namespace OIS; @@ -88,6 +144,8 @@ namespace MWInput "Quit program"); disp->funcs.bind(A_Screenshot, boost::bind(&MWInputManager::screenshot, this), "Screenshot"); + disp->funcs.bind(A_Inventory, boost::bind(&MWInputManager::toggleInventory, this), + "Toggle inventory screen"); // Add the exit listener @@ -98,6 +156,9 @@ namespace MWInput // Set up the mouse handler and tell it about the player camera mouse = MouseLookEventPtr(new MouseLookEvent(player.getCamera())); + // This event handler pumps events into MyGUI + guiEvents = EventInjectorPtr(new EventInjector(windows.getGui())); + // Hook 'mouse' and 'disp' up as event handlers into 'input' // (the OIS driver and event source.) We do this through an // EventList which dispatches the event to multiple handlers for @@ -107,12 +168,25 @@ namespace MWInput input.setEvent(EventPtr(lst)); lst->add(mouse,Event::EV_MouseMove); lst->add(disp,Event::EV_KeyDown); + lst->add(guiEvents,Event::EV_ALL); } - // Key bindings + // Start out in game mode + setGuiMode(MWGui::GM_Game); + + /********************************** + Key binding section + + The rest of this function has hard coded key bindings, and is + intended to be replaced by user defined bindings later. + **********************************/ + + // Key bindings for keypress events + disp->bind(A_Quit, KC_Q); disp->bind(A_Quit, KC_ESCAPE); disp->bind(A_Screenshot, KC_SYSRQ); + disp->bind(A_Inventory, KC_I); // Key bindings for polled keys @@ -139,6 +213,9 @@ namespace MWInput // Tell OIS to handle all input events input.capture(); + // Disable movement in Gui mode + if(windows.isGuiMode()) return true; + float speed = 300 * evt.timeSinceLastFrame; float moveX = 0, moveY = 0, moveZ = 0; diff --git a/apps/openmw/mwscript/guiextensions.cpp b/apps/openmw/mwscript/guiextensions.cpp index 11a268cfb7..d3558b9864 100644 --- a/apps/openmw/mwscript/guiextensions.cpp +++ b/apps/openmw/mwscript/guiextensions.cpp @@ -7,58 +7,38 @@ #include #include -#include +#include #include "interpretercontext.hpp" - namespace MWScript { namespace Gui { class OpEnableWindow : public Interpreter::Opcode0 { - MWGui::GuiManager::GuiWindow mWindow; + MWGui::GuiWindow mWindow; public: - OpEnableWindow (MWGui::GuiManager::GuiWindow window) : mWindow (window) {} + OpEnableWindow (MWGui::GuiWindow window) : mWindow (window) {} virtual void execute (Interpreter::Runtime& runtime) { InterpreterContext& context = static_cast (runtime.getContext()); - context.getGuiManager().enableWindow (mWindow); + context.getWindowManager().allow (mWindow); } }; - class OpShowOneTimeDialogue : public Interpreter::Opcode0 - { - MWGui::GuiManager::GuiOneTimeDialogue mOneTimeDialogue; - - public: - - OpShowOneTimeDialogue (MWGui::GuiManager::GuiOneTimeDialogue OneTimeDialogue) - : mOneTimeDialogue (OneTimeDialogue) - {} - - virtual void execute (Interpreter::Runtime& runtime) - { - InterpreterContext& context = - static_cast (runtime.getContext()); - - context.getGuiManager().showOneTimeDialogue (mOneTimeDialogue); - } - }; - class OpShowDialogue : public Interpreter::Opcode0 { - MWGui::GuiManager::GuiDialogue mDialogue; + MWGui::GuiMode mDialogue; public: - OpShowDialogue (MWGui::GuiManager::GuiDialogue dialogue) + OpShowDialogue (MWGui::GuiMode dialogue) : mDialogue (dialogue) {} @@ -67,29 +47,10 @@ namespace MWScript InterpreterContext& context = static_cast (runtime.getContext()); - context.getGuiManager().enableDialogue (mDialogue); + context.getWindowManager().setMode(mDialogue); } }; - class OpEnableDialogue : public Interpreter::Opcode0 - { - MWGui::GuiManager::GuiDialogue mDialogue; - - public: - - OpEnableDialogue (MWGui::GuiManager::GuiDialogue dialogue) - : mDialogue (dialogue) - {} - - virtual void execute (Interpreter::Runtime& runtime) - { - InterpreterContext& context = - static_cast (runtime.getContext()); - - context.getGuiManager().showDialogue (mDialogue); - } - }; - const int opcodeEnableBirthMenu = 0x200000e; const int opcodeEnableClassMenu = 0x200000f; const int opcodeEnableNameMenu = 0x2000010; @@ -125,30 +86,34 @@ namespace MWScript void installOpcodes (Interpreter::Interpreter& interpreter) { interpreter.installSegment5 (opcodeEnableBirthMenu, - new OpShowOneTimeDialogue (MWGui::GuiManager::Gui_Birth)); + new OpShowDialogue (MWGui::GM_Birth)); interpreter.installSegment5 (opcodeEnableClassMenu, - new OpShowOneTimeDialogue (MWGui::GuiManager::Gui_Class)); + new OpShowDialogue (MWGui::GM_Class)); interpreter.installSegment5 (opcodeEnableNameMenu, - new OpShowOneTimeDialogue (MWGui::GuiManager::Gui_Name)); + new OpShowDialogue (MWGui::GM_Name)); interpreter.installSegment5 (opcodeEnableRaceMenu, - new OpShowOneTimeDialogue (MWGui::GuiManager::Gui_Race)); + new OpShowDialogue (MWGui::GM_Race)); interpreter.installSegment5 (opcodeEnableStatsReviewMenu, - new OpShowOneTimeDialogue (MWGui::GuiManager::Gui_Review)); + new OpShowDialogue (MWGui::GM_Review)); interpreter.installSegment5 (opcodeEnableInventoryMenu, - new OpEnableWindow (MWGui::GuiManager::Gui_Inventory)); + new OpEnableWindow (MWGui::GW_Inventory)); interpreter.installSegment5 (opcodeEnableMagicMenu, - new OpEnableWindow (MWGui::GuiManager:: Gui_Magic)); + new OpEnableWindow (MWGui::GW_Magic)); interpreter.installSegment5 (opcodeEnableMapMenu, - new OpEnableWindow (MWGui::GuiManager::Gui_Map)); + new OpEnableWindow (MWGui::GW_Map)); interpreter.installSegment5 (opcodeEnableStatsMenu, - new OpEnableWindow (MWGui::GuiManager::Gui_Status)); + new OpEnableWindow (MWGui::GW_Stats)); + + /* Not done yet. Enabling rest mode is not really a gui + issue, it's a gameplay issue. interpreter.installSegment5 (opcodeEnableRest, - new OpEnableDialogue (MWGui::GuiManager::Gui_Rest)); + new OpEnableDialogue (MWGui::GM_Rest)); + */ interpreter.installSegment5 (opcodeShowRestMenu, - new OpShowDialogue (MWGui::GuiManager::Gui_Rest)); + new OpShowDialogue (MWGui::GM_Rest)); } } } diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index cfa9acc570..c5cf436e59 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -9,7 +9,7 @@ #include "../mwworld/world.hpp" -#include +#include #include "locals.hpp" #include "globalscripts.hpp" @@ -112,7 +112,7 @@ namespace MWScript bool InterpreterContext::menuMode() { - return mEnvironment.mGuiManager->isGuiActive(); + return mEnvironment.mWindowManager->isGuiMode(); } int InterpreterContext::getGlobalShort (const std::string& name) const @@ -215,9 +215,9 @@ namespace MWScript mEnvironment.mWorld->disable (ref); } - MWGui::GuiManager& InterpreterContext::getGuiManager() + MWGui::WindowManager& InterpreterContext::getWindowManager() { - return *mEnvironment.mGuiManager; + return *mEnvironment.mWindowManager; } MWWorld::World& InterpreterContext::getWorld() diff --git a/apps/openmw/mwscript/interpretercontext.hpp b/apps/openmw/mwscript/interpretercontext.hpp index ac719f1518..ee35964b80 100644 --- a/apps/openmw/mwscript/interpretercontext.hpp +++ b/apps/openmw/mwscript/interpretercontext.hpp @@ -84,7 +84,7 @@ namespace MWScript MWSound::SoundManager& getSoundManager(); - MWGui::GuiManager& getGuiManager(); + MWGui::WindowManager& getWindowManager(); MWWorld::Ptr getReference(); ///< Reference, that the script is running from (can be empty) diff --git a/apps/openmw/mwworld/environment.hpp b/apps/openmw/mwworld/environment.hpp index cfcd7d6bdc..ab0989d497 100644 --- a/apps/openmw/mwworld/environment.hpp +++ b/apps/openmw/mwworld/environment.hpp @@ -13,7 +13,7 @@ namespace MWScript namespace MWGui { - class GuiManager; + class WindowManager; } namespace MWWorld @@ -25,13 +25,13 @@ namespace MWWorld { public: Environment() - : mWorld (0), mSoundManager (0), mGlobalScripts (0), mGuiManager (0), mFrameDuration (0) + : mWorld (0), mSoundManager (0), mGlobalScripts (0), mWindowManager (0), mFrameDuration (0) {} World *mWorld; MWSound::SoundManager *mSoundManager; MWScript::GlobalScripts *mGlobalScripts; - MWGui::GuiManager *mGuiManager; + MWGui::WindowManager *mWindowManager; float mFrameDuration; }; } diff --git a/apps/openmw/mwworld/world.cpp b/apps/openmw/mwworld/world.cpp index a4c95fbf4d..6a3318250d 100644 --- a/apps/openmw/mwworld/world.cpp +++ b/apps/openmw/mwworld/world.cpp @@ -175,8 +175,6 @@ namespace MWWorld *reinterpret_cast (&newGameState); } - 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))); diff --git a/components/esm_store/store.cpp b/components/esm_store/store.cpp index b5a24f5322..2016272e0e 100644 --- a/components/esm_store/store.cpp +++ b/components/esm_store/store.cpp @@ -6,6 +6,7 @@ using namespace std; using namespace ESM; using namespace ESMS; +/* static string toStr(int i) { char name[5]; @@ -13,6 +14,7 @@ static string toStr(int i) name[4] = 0; return std::string(name); } +*/ void ESMStore::load(ESMReader &esm) { @@ -44,6 +46,9 @@ void ESMStore::load(ESMReader &esm) all[id] = n.val; } + /* This information isn't needed on screen. But keep the code around + for debugging purposes later. + cout << "\n" << recLists.size() << " record types:\n"; for(RecListList::iterator it = recLists.begin(); it != recLists.end(); it++) cout << " " << toStr(it->first) << ": " << it->second->getSize() << endl; @@ -52,4 +57,5 @@ void ESMStore::load(ESMReader &esm) it != missing.end(); it++ ) cout << *it << " "; cout << endl; + */ } diff --git a/components/mwgui/guimanager.cpp b/components/mwgui/guimanager.cpp deleted file mode 100644 index 2ac98300a9..0000000000 --- a/components/mwgui/guimanager.cpp +++ /dev/null @@ -1,34 +0,0 @@ - -#include "guimanager.hpp" - -#include - -#include "mw_layouts.hpp" - -namespace MWGui -{ - void GuiManager::enableWindow (GuiWindow window) - { - std::cout << "enable window: " << window << std::endl; - } - - void GuiManager::showOneTimeDialogue (GuiOneTimeDialogue dialogue) - { - std::cout << "show one time dialogue: " << dialogue << std::endl; - } - - void GuiManager::enableDialogue (GuiDialogue dialogue) - { - std::cout << "enable dialogue: " << dialogue << std::endl; - } - - void GuiManager::showDialogue (GuiDialogue dialogue) - { - std::cout << "show dialogue: " << dialogue << std::endl; - } - - bool GuiManager::isGuiActive() const - { - return false; - } -} diff --git a/components/mwgui/guimanager.hpp b/components/mwgui/guimanager.hpp deleted file mode 100644 index 5e5d1cfddf..0000000000 --- a/components/mwgui/guimanager.hpp +++ /dev/null @@ -1,52 +0,0 @@ -#ifndef GAME_SOUND_GUIMANAGER_H -#define GAME_SOUND_GUIMANAGER_H - -namespace MWGui -{ - // Predeclarations, these are defined in mw_layouts.hpp - class HUD; - class MapWindow; - class MainMenu; - class StatsWindow; - - class GuiManager - { - HUD *hud; - MapWindow *map; - MainMenu *menu; - StatsWindow *stats; - - public: - - enum GuiWindow - { - Gui_Inventory, Gui_Magic, Gui_Map, Gui_Status - }; - - enum GuiOneTimeDialogue // used only once - { - // character generation - Gui_Birth, Gui_Class, Gui_Name, Gui_Race, Gui_Review - }; - - enum GuiDialogue - { - Gui_Rest - }; - - void enableWindow (GuiWindow window); - ///< diabled by default. - - void showOneTimeDialogue (GuiOneTimeDialogue dialogue); - - void enableDialogue (GuiDialogue dialogue); - ///< disabled by default. - - void showDialogue (GuiDialogue dialogue); - - bool isGuiActive() const; - ///< Any non-HUD GUI element active (dialogues and windows)? - }; -} - -#endif diff --git a/components/mwgui/window_manager.cpp b/components/mwgui/window_manager.cpp new file mode 100644 index 0000000000..38757fb6de --- /dev/null +++ b/components/mwgui/window_manager.cpp @@ -0,0 +1,74 @@ +#include "window_manager.hpp" +#include "mw_layouts.hpp" + +#include + +using namespace MWGui; + +WindowManager::WindowManager(MyGUI::Gui *_gui) + : gui(_gui), mode(GM_Game), shown(GW_ALL), allowed(GW_ALL) +{ + // Get size info from the Gui object + assert(gui); + int w = gui->getViewWidth(); + int h = gui->getViewHeight(); + + hud = new HUD(w,h); + menu = new MainMenu(w,h); + map = new MapWindow(); + stats = new StatsWindow(); + + // The HUD is always on + hud->setVisible(true); + + // Set up visibility + updateVisible(); +} + +WindowManager::~WindowManager() +{ + delete hud; + delete map; + delete menu; + delete stats; +} + +void WindowManager::updateVisible() +{ + // Start out by hiding everything except the HUD + map->setVisible(false); + menu->setVisible(false); + stats->setVisible(false); + + // Mouse is visible whenever we're not in game mode + gui->setVisiblePointer(isGuiMode()); + + // If in game mode, don't show anything. + if(mode == GM_Game) + { + return; + } + + if(mode == GM_MainMenu) + { + // Enable the main menu + menu->setVisible(true); + return; + } + + if(mode == GM_Inventory) + { + // Ah, inventory mode. First, compute the effective set of + // windows to show. This is controlled both by what windows the + // user has opened/closed (the 'shown' variable) and by what + // windows we are allowed to show (the 'allowed' var.) + int eff = shown & allowed; + + // Show the windows we want + map -> setVisible( eff & GW_Map ); + stats -> setVisible( eff & GW_Stats ); + return; + } + + // All other modes are ignored +} diff --git a/components/mwgui/window_manager.hpp b/components/mwgui/window_manager.hpp new file mode 100644 index 0000000000..89e08aa69f --- /dev/null +++ b/components/mwgui/window_manager.hpp @@ -0,0 +1,121 @@ +#ifndef MWGUI_WINDOWMANAGER_H +#define MWGUI_WINDOWMANAGER_H + +/** + This class owns and controls all the MW specific windows in the + GUI. It can enable/disable Gui mode, and is responsible for sending + and retrieving information from the Gui. + + MyGUI should be initialized separately before creating instances of + this class. + */ + +namespace MyGUI +{ + class Gui; +} + +namespace MWGui +{ + class HUD; + class MapWindow; + class MainMenu; + class StatsWindow; + + enum GuiMode + { + GM_Game, // Game mode, only HUD + GM_Inventory, // Inventory mode + GM_MainMenu, // Main menu mode + + // None of the following are implemented yet + + GM_Dialogue, // NPC interaction + GM_Barter, + GM_Rest, + // .. more here .. + + // Startup character creation dialogs + GM_Name, + GM_Race, + GM_Birth, + GM_Class, + GM_Review + }; + + // Windows shown in inventory mode + enum GuiWindow + { + GW_None = 0, + + GW_Map = 0x01, + GW_Inventory = 0x02, + GW_Magic = 0x04, + GW_Stats = 0x08, + + GW_ALL = 0xFF + }; + + class WindowManager + { + HUD *hud; + MapWindow *map; + MainMenu *menu; + StatsWindow *stats; + + MyGUI::Gui *gui; + + // Current gui mode + GuiMode mode; + + // Currently shown windows in inventory mode + GuiWindow shown; + + /* Currently ALLOWED windows in inventory mode. This is used at + the start of the game, when windows are enabled one by one + through script commands. You can manipulate this through using + allow() and disableAll(). + + The setting should also affect visibility of certain HUD + elements, but this is not done yet. + */ + GuiWindow allowed; + + // Update visibility of all windows based on mode, shown and + // allowed settings. + void updateVisible(); + + public: + /// The constructor needs the main Gui object + WindowManager(MyGUI::Gui *_gui); + virtual ~WindowManager(); + + void setMode(GuiMode newMode) + { + mode = newMode; + updateVisible(); + } + + GuiMode getMode() const { return mode; } + + // Everything that is not game mode is considered "gui mode" + bool isGuiMode() const { return getMode() != GM_Game; } + + // Disallow all inventory mode windows + void disallowAll() + { + allowed = GW_None; + updateVisible(); + } + + // Allow one or more windows + void allow(GuiWindow wnd) + { + allowed = (GuiWindow)(allowed | wnd); + updateVisible(); + } + + MyGUI::Gui* getGui() const { return gui; } + }; +} +#endif diff --git a/libs/openengine b/libs/openengine index fedb1a8025..82a3c071e5 160000 --- a/libs/openengine +++ b/libs/openengine @@ -1 +1 @@ -Subproject commit fedb1a80256a093511075aeb88408c7c56a136ce +Subproject commit 82a3c071e56f2df451618e1371424c39aa299690 diff --git a/testall.sh b/testall.sh deleted file mode 100755 index 9e9bd55b59..0000000000 --- a/testall.sh +++ /dev/null @@ -1,16 +0,0 @@ -#!/bin/bash - -function run() -{ - echo - echo "$1/tests/:" - cd "$1/tests/" - ./test.sh - cd ../../ -} - -run tools -run input -run bsa -run nif -run nifogre