diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 05aa161e6..172c6a494 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -29,7 +29,7 @@ add_openmw_dir (mwgui dialogue_history window_base stats_window messagebox journalwindow charactercreation map_window window_pinnable_base cursorreplace tooltips scrollwindow bookwindow list formatting inventorywindow container hud countdialog tradewindow settingswindow - confirmationdialog alchemywindow referenceinterface spellwindow + confirmationdialog alchemywindow referenceinterface spellwindow mainmenu ) add_openmw_dir (mwdialogue diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 2467f91d1..5fc9774d1 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -116,7 +116,7 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt) std::cerr << "Error in framelistener: " << e.what() << std::endl; } - return true; + return !MWBase::Environment::get().getWorld()->getExitNow(); } OMW::Engine::Engine(Files::ConfigurationManager& configurationManager) diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index 8b809d399..f08617d4c 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -248,6 +248,9 @@ namespace MWBase virtual bool isSwimming(const MWWorld::Ptr &object) = 0; virtual bool isUnderwater(const ESM::Cell &cell, const Ogre::Vector3 &pos) = 0; + + virtual void exitNow() = 0; ///< exit after this frame has ended + virtual bool getExitNow() = 0; ///< @return true if the application should exit }; } diff --git a/apps/openmw/mwgui/cursorreplace.cpp b/apps/openmw/mwgui/cursorreplace.cpp index e66f54326..a4b6a100b 100644 --- a/apps/openmw/mwgui/cursorreplace.cpp +++ b/apps/openmw/mwgui/cursorreplace.cpp @@ -16,4 +16,5 @@ CursorReplace::CursorReplace() OEngine::Render::ImageRotate::rotate("textures\\tx_cursormove.dds", "mwpointer_dresize2.png", 45); OEngine::Render::Atlas::createFromFile("atlas1.cfg", "mwgui1", "textures\\"); + OEngine::Render::Atlas::createFromFile("mainmenu.cfg", "mwgui2", "textures\\"); } diff --git a/apps/openmw/mwgui/mainmenu.cpp b/apps/openmw/mwgui/mainmenu.cpp new file mode 100644 index 000000000..ca9ebbc4a --- /dev/null +++ b/apps/openmw/mwgui/mainmenu.cpp @@ -0,0 +1,75 @@ +#include "mainmenu.hpp" + +#include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" + +#include "window_manager.hpp" + +namespace MWGui +{ + + MainMenu::MainMenu(int w, int h) + : OEngine::GUI::Layout("openmw_mainmenu.layout") + { + setCoord(0,0,w,h); + + int height = 64 * 3; + + mButtonBox = mMainWidget->createWidget("", MyGUI::IntCoord(w/2 - 64, h/2 - height/2, 128, height), MyGUI::Align::Default); + int curH = 0; + + mReturn = mButtonBox->createWidget ("ButtonImage", MyGUI::IntCoord(0, curH, 128, 64), MyGUI::Align::Default); + mReturn->setImageResource ("Menu_Return"); + mReturn->eventMouseButtonClick += MyGUI::newDelegate(this, &MainMenu::returnToGame); + curH += 64; + + + /* + mNewGame = mButtonBox->createWidget ("ButtonImage", MyGUI::IntCoord(0, curH, 128, 64), MyGUI::Align::Default); + mNewGame->setImageResource ("Menu_NewGame"); + curH += 64; + + mLoadGame = mButtonBox->createWidget ("ButtonImage", MyGUI::IntCoord(0, curH, 128, 64), MyGUI::Align::Default); + mLoadGame->setImageResource ("Menu_LoadGame"); + curH += 64; + + + mSaveGame = mButtonBox->createWidget ("ButtonImage", MyGUI::IntCoord(0, curH, 128, 64), MyGUI::Align::Default); + mSaveGame->setImageResource ("Menu_SaveGame"); + curH += 64; + */ + + mOptions = mButtonBox->createWidget ("ButtonImage", MyGUI::IntCoord(0, curH, 128, 64), MyGUI::Align::Default); + mOptions->setImageResource ("Menu_Options"); + mOptions->eventMouseButtonClick += MyGUI::newDelegate(this, &MainMenu::showOptions); + curH += 64; + + /* + mCredits = mButtonBox->createWidget ("ButtonImage", MyGUI::IntCoord(0, curH, 128, 64), MyGUI::Align::Default); + mCredits->setImageResource ("Menu_Credits"); + curH += 64; + */ + + mExitGame = mButtonBox->createWidget ("ButtonImage", MyGUI::IntCoord(0, curH, 128, 64), MyGUI::Align::Default); + mExitGame->setImageResource ("Menu_ExitGame"); + mExitGame->eventMouseButtonClick += MyGUI::newDelegate(this, &MainMenu::exitGame); + curH += 64; + + } + + void MainMenu::returnToGame(MyGUI::Widget* sender) + { + MWBase::Environment::get().getWindowManager ()->removeGuiMode (GM_MainMenu); + } + + void MainMenu::showOptions(MyGUI::Widget* sender) + { + MWBase::Environment::get().getWindowManager ()->pushGuiMode (GM_Settings); + } + + void MainMenu::exitGame(MyGUI::Widget* sender) + { + MWBase::Environment::get().getWorld ()->exitNow(); + } + +} diff --git a/apps/openmw/mwgui/mainmenu.hpp b/apps/openmw/mwgui/mainmenu.hpp index 06c59396f..5fa2f6943 100644 --- a/apps/openmw/mwgui/mainmenu.hpp +++ b/apps/openmw/mwgui/mainmenu.hpp @@ -6,11 +6,22 @@ namespace MWGui class MainMenu : public OEngine::GUI::Layout { public: - MainMenu(int w, int h) - : Layout("openmw_mainmenu.layout") - { - setCoord(0,0,w,h); - } + MainMenu(int w, int h); + + private: + MyGUI::Button* mReturn; + MyGUI::Button* mNewGame; + MyGUI::Button* mLoadGame; + MyGUI::Button* mSaveGame; + MyGUI::Button* mOptions; + MyGUI::Button* mCredits; + MyGUI::Button* mExitGame; + + MyGUI::Widget* mButtonBox; + + void returnToGame(MyGUI::Widget* sender); + void showOptions(MyGUI::Widget* sender); + void exitGame(MyGUI::Widget* sender); }; } diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index 9629c7cca..d1e1f7095 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -263,6 +263,7 @@ namespace MWGui dialog->eventOkClicked.clear(); dialog->eventOkClicked += MyGUI::newDelegate(this, &SettingsWindow::onResolutionAccept); dialog->eventCancelClicked.clear(); + dialog->eventCancelClicked += MyGUI::newDelegate(this, &SettingsWindow::onResolutionCancel); } void SettingsWindow::onResolutionAccept() diff --git a/apps/openmw/mwinput/inputmanager.cpp b/apps/openmw/mwinput/inputmanager.cpp index 35aafa446..5a4718ccf 100644 --- a/apps/openmw/mwinput/inputmanager.cpp +++ b/apps/openmw/mwinput/inputmanager.cpp @@ -5,7 +5,6 @@ #include -#include #include #include "../mwgui/window_manager.hpp" @@ -20,6 +19,7 @@ #include "../engine.hpp" #include "../mwworld/player.hpp" +#include "../mwbase/world.hpp" #include #include @@ -68,8 +68,6 @@ namespace MWInput A_ToggleWeapon, A_ToggleSpell, - A_Settings, // Temporary hotkey - A_LAST // Marker for the last item }; @@ -78,7 +76,6 @@ namespace MWInput { OEngine::Input::DispatcherPtr disp; OEngine::Render::OgreRenderer &ogre; - OEngine::Render::ExitListener exit; Mangle::Input::OISDriver input; OEngine::Input::Poller poller; MouseLookEventPtr mouse; @@ -140,15 +137,6 @@ private: windows.messageBox ("Screenshot saved", empty); } - void showSettings() - { - if (mDragDrop) - return; - - if (!windows.isGuiMode() || windows.getMode() != MWGui::GM_Settings) - windows.pushGuiMode(MWGui::GM_Settings); - } - /* toggleInventory() is called when the user presses the button to toggle the inventory screen. */ void toggleInventory() { @@ -222,11 +210,19 @@ private: player.toggleRunning(); } + void toggleMainMenu() + { + if (windows.isGuiMode () && windows.getMode () == MWGui::GM_MainMenu) + windows.removeGuiMode (MWGui::GM_MainMenu); + else + windows.pushGuiMode (MWGui::GM_MainMenu); + } + // Exit program now button (which is disabled in GUI mode) void exitNow() { if(!windows.isGuiMode()) - exit.exitNow(); + MWBase::Environment::get().getWorld()->exitNow(); } public: @@ -236,7 +232,6 @@ private: bool debug, OMW::Engine& engine) : ogre(_ogre), - exit(ogre.getWindow()), input(ogre.getWindow(), !debug), poller(input), player(_player), @@ -273,10 +268,8 @@ private: "Draw Weapon"); disp->funcs.bind(A_ToggleSpell,boost::bind(&InputImpl::toggleSpell,this), "Ready hands"); - disp->funcs.bind(A_Settings, boost::bind(&InputImpl::showSettings, this), - "Show settings window"); - // Add the exit listener - ogre.getRoot()->addFrameListener(&exit); + disp->funcs.bind(A_GameMenu, boost::bind(&InputImpl::toggleMainMenu, this), + "Toggle main menu"); mouse = MouseLookEventPtr(new MouseLookEvent()); @@ -316,7 +309,7 @@ private: // NOTE: These keys do not require constant polling - use in conjuction with variables in loops. disp->bind(A_Quit, KC_Q); - disp->bind(A_Quit, KC_ESCAPE); + disp->bind(A_GameMenu, KC_ESCAPE); disp->bind(A_Screenshot, KC_SYSRQ); disp->bind(A_Inventory, KC_I); disp->bind(A_Console, KC_F1); @@ -327,7 +320,6 @@ private: disp->bind(A_ToggleWalk, KC_C); disp->bind(A_ToggleWeapon,KC_F); disp->bind(A_ToggleSpell,KC_R); - disp->bind(A_Settings, KC_F2); // Key bindings for polled keys // NOTE: These keys are constantly being polled. Only add keys that must be checked each frame. diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index cf2d21014..cb33b40f2 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -170,7 +170,7 @@ namespace MWWorld const std::string& encoding, std::map fallbackMap) : mPlayer (0), mLocalScripts (mStore), mGlobalVariables (0), mSky (true), mNextDynamicRecord (0), mCells (mStore, mEsm), - mNumFacing(0) + mNumFacing(0), mExit(false) { mPhysics = new PhysicsSystem(renderer); mPhysEngine = mPhysics->getEngine(); @@ -1147,4 +1147,15 @@ namespace MWWorld } return pos.z < cell.water; } + + void World::exitNow() + { + mExit = true; + } + + bool World::getExitNow() + { + return mExit; + } + } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index 24645cb8e..7af71d349 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -84,6 +84,8 @@ namespace MWWorld unsigned long lastTick; Ogre::Timer mTimer; + bool mExit; + int getDaysPerMonth (int month) const; bool moveObjectImp (const Ptr& ptr, float x, float y, float z); @@ -274,6 +276,10 @@ namespace MWWorld virtual bool isSwimming(const MWWorld::Ptr &object); virtual bool isUnderwater(const ESM::Cell &cell, const Ogre::Vector3 &pos); + + virtual void exitNow(); ///< exit after this frame has ended + virtual bool getExitNow(); ///< @return true if the application should exit + }; } diff --git a/files/mygui/CMakeLists.txt b/files/mygui/CMakeLists.txt index ae007f023..3a5430c6f 100644 --- a/files/mygui/CMakeLists.txt +++ b/files/mygui/CMakeLists.txt @@ -5,6 +5,7 @@ set(DDIR ${OpenMW_BINARY_DIR}/resources/mygui) set(MYGUI_FILES atlas1.cfg + mainmenu.cfg bigbars.png black.png core.skin diff --git a/files/mygui/mainmenu.cfg b/files/mygui/mainmenu.cfg new file mode 100644 index 000000000..7aaf8c1c7 --- /dev/null +++ b/files/mygui/mainmenu.cfg @@ -0,0 +1,95 @@ +[settings] + size_x = 512 + size_y = 512 + + +[menu_newgame.dds] + x = 0 + y = 0 + +[menu_newgame_pressed.dds] + x = 128 + y = 0 + +[menu_newgame_over.dds] + x = 256 + y = 0 + + +[menu_loadgame.dds] + x = 384 + y = 0 + +[menu_loadgame_pressed.dds] + x = 0 + y = 64 + +[menu_loadgame_over.dds] + x = 128 + y = 64 + + +[menu_options.dds] + x = 256 + y = 64 + +[menu_options_pressed.dds] + x = 384 + y = 64 + +[menu_options_over.dds] + x = 0 + y = 128 + + +[menu_credits.dds] + x = 128 + y = 128 + +[menu_credits_pressed.dds] + x = 256 + y = 128 + +[menu_credits_over.dds] + x = 384 + y = 128 + + +[menu_exitgame.dds] + x = 0 + y = 192 + +[menu_exitgame_pressed.dds] + x = 128 + y = 192 + +[menu_exitgame_over.dds] + x = 256 + y = 192 + + +[menu_savegame.dds] + x = 384 + y = 192 + +[menu_savegame_pressed.dds] + x = 0 + y = 256 + +[menu_savegame_over.dds] + x = 128 + y = 256 + + +[menu_return.dds] + x = 256 + y = 256 + +[menu_return_pressed.dds] + x = 384 + y = 256 + +[menu_return_over.dds] + x = 0 + y = 320 + diff --git a/files/mygui/openmw_layers.xml b/files/mygui/openmw_layers.xml index 56f800ea3..7a8d586d2 100644 --- a/files/mygui/openmw_layers.xml +++ b/files/mygui/openmw_layers.xml @@ -4,8 +4,6 @@ - - diff --git a/files/mygui/openmw_mainmenu.layout b/files/mygui/openmw_mainmenu.layout index bf17be7f7..4479a121f 100644 --- a/files/mygui/openmw_mainmenu.layout +++ b/files/mygui/openmw_mainmenu.layout @@ -2,16 +2,5 @@ - - - - - - - - - - - - + diff --git a/files/mygui/openmw_resources.xml b/files/mygui/openmw_resources.xml index f1a8b0dfc..83461bbe8 100644 --- a/files/mygui/openmw_resources.xml +++ b/files/mygui/openmw_resources.xml @@ -1,6 +1,8 @@ + + @@ -44,6 +46,10 @@ + + + + @@ -113,6 +119,124 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/libs/openengine/ogre/exitlistener.hpp b/libs/openengine/ogre/exitlistener.hpp deleted file mode 100644 index 5a9d1ff68..000000000 --- a/libs/openengine/ogre/exitlistener.hpp +++ /dev/null @@ -1,37 +0,0 @@ -#ifndef OENGINE_OGRE_EXITLISTEN_H -#define OENGINE_OGRE_EXITLISTEN_H - -/* - This FrameListener simply exits the rendering loop when the window - is closed. You can also tell it to exit manually by setting the exit - member to true; - */ - -#include -#include - -namespace OEngine { -namespace Render -{ - struct ExitListener : Ogre::FrameListener - { - Ogre::RenderWindow *window; - bool exit; - - ExitListener(Ogre::RenderWindow *wnd) - : window(wnd), exit(false) {} - - bool frameStarted(const Ogre::FrameEvent &evt) - { - if(window->isClosed()) - exit = true; - - return !exit; - } - - // Function equivalent of setting exit=true. Handy when you need a - // delegate to bind to an event. - void exitNow() { exit = true; } - }; -}} -#endif diff --git a/libs/openengine/ogre/fader.hpp b/libs/openengine/ogre/fader.hpp index f76ac51ef..efb12a5d2 100644 --- a/libs/openengine/ogre/fader.hpp +++ b/libs/openengine/ogre/fader.hpp @@ -9,8 +9,6 @@ inspired by http://www.ogre3d.org/tikiwiki/FadeEffectOverlay (heavily adjusted) */ -#include - namespace Ogre { class TextureUnitState;