diff --git a/CMakeLists.txt b/CMakeLists.txt index ea0c41fe2..543d9cb98 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -37,6 +37,9 @@ option(USE_FFMPEG "use ffmpeg for sound" OFF) option(USE_AUDIERE "use audiere for sound" OFF) option(USE_MPG123 "use mpg123 + libsndfile for sound" ON) +# OS X deployment +option(OPENMW_OSX_DEPLOYMENT OFF) + find_program(DPKG_PROGRAM dpkg DOC "dpkg program of Debian-based systems") # Location of morrowind data files @@ -230,22 +233,46 @@ if (APPLE) ${OGRE_Plugin_OctreeSceneManager_LIBRARY_REL} ${OGRE_Plugin_CgProgramManager_LIBRARY_REL} ${OGRE_Plugin_ParticleFX_LIBRARY_REL}) + + if (${OGRE_PLUGIN_DIR_REL}}) + set(OGRE_PLUGINS_REL_FOUND TRUE) + endif () + + if (${OGRE_PLUGIN_DIR_DBG}) + set(OGRE_PLUGINS_DBG_FOUND TRUE) + endif () + + if (${OGRE_PLUGINS_REL_FOUND}) + set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_REL}) + else () + set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_DBG}) + endif () + + #set(OGRE_PLUGIN_DIR "${OGRE_PLUGIN_DIR}/") + + configure_file(${OpenMW_SOURCE_DIR}/files/mac/Info.plist + "${APP_BUNDLE_DIR}/Contents/Info.plist") + + configure_file(${OpenMW_SOURCE_DIR}/files/mac/openmw.icns + "${APP_BUNDLE_DIR}/Contents/Resources/OpenMW.icns" COPYONLY) endif (APPLE) # Set up Ogre plugin folder & debug suffix -set(DEBUG_SUFFIX "") -if (DEFINED CMAKE_BUILD_TYPE) - if (CMAKE_BUILD_TYPE STREQUAL "Debug") - set(DEBUG_SUFFIX "_d") - add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="_d") - else() - add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="") - endif() +# Ogre on OS X doesn't use "_d" suffix (see Ogre's CMakeLists.txt) +if (DEFINED CMAKE_BUILD_TYPE AND CMAKE_BUILD_TYPE STREQUAL "Debug" AND NOT APPLE) + add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="_d") +else() + add_definitions(-DOGRE_PLUGIN_DEBUG_SUFFIX="") endif() + add_definitions(-DOGRE_PLUGIN_DIR_REL="${OGRE_PLUGIN_DIR_REL}") add_definitions(-DOGRE_PLUGIN_DIR_DBG="${OGRE_PLUGIN_DIR_DBG}") -add_definitions(-DOGRE_PLUGIN_DIR="${OGRE_PLUGIN_DIR}") +if (APPLE AND OPENMW_OSX_DEPLOYMENT) + add_definitions(-DOGRE_PLUGIN_DIR="${APP_BUNDLE_NAME}/Contents/Plugins") +else() + add_definitions(-DOGRE_PLUGIN_DIR="${OGRE_PLUGIN_DIR}") +endif() add_subdirectory(files/) @@ -278,35 +305,6 @@ if (${CMAKE_SYSTEM_NAME} MATCHES "Linux") "${OpenMW_BINARY_DIR}/openmw.desktop") endif() -if (APPLE) - if (${OGRE_PLUGIN_DIR_REL}}) - set(OGRE_PLUGINS_REL_FOUND TRUE) - endif () - - if (${OGRE_PLUGIN_DIR_DBG}) - set(OGRE_PLUGINS_DBG_FOUND TRUE) - endif () - - if (${OGRE_PLUGINS_REL_FOUND}) - set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_REL}) - else () - set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_DBG}) - endif () - - set(OGRE_PLUGIN_DIR "${OGRE_PLUGIN_DIR}/") - - set(OGRE_PLUGIN_DIR_2 ${OGRE_PLUGIN_DIR}) - set(OGRE_PLUGIN_DIR "") - set(OGRE_PLUGIN_DIR ${OGRE_PLUGIN_DIR_2}) - - configure_file(${OpenMW_SOURCE_DIR}/files/mac/Info.plist - "${APP_BUNDLE_DIR}/Contents/Info.plist") - - configure_file(${OpenMW_SOURCE_DIR}/files/mac/openmw.icns - "${APP_BUNDLE_DIR}/Contents/Resources/OpenMW.icns" COPYONLY) -endif (APPLE) - - # Compiler settings if (CMAKE_COMPILER_IS_GNUCC) add_definitions (-Wall -Wextra -Wno-unused-parameter -Wno-reorder) diff --git a/apps/launcher/graphicspage.cpp b/apps/launcher/graphicspage.cpp index 3c1d76f3d..c3c39cffc 100644 --- a/apps/launcher/graphicspage.cpp +++ b/apps/launcher/graphicspage.cpp @@ -6,6 +6,7 @@ #include #include +#include #include #include "graphicspage.hpp" @@ -115,13 +116,12 @@ bool GraphicsPage::setupOgre() #endif } - std::string glPlugin = std::string(pluginDir) + "/RenderSystem_GL" + OGRE_PLUGIN_DEBUG_SUFFIX; - if (boost::filesystem::exists(glPlugin + ".so") || boost::filesystem::exists(glPlugin + ".dll")) - mOgre->loadPlugin (glPlugin); + boost::filesystem::path absPluginPath = boost::filesystem::absolute(boost::filesystem::path(pluginDir)); - std::string dxPlugin = std::string(pluginDir) + "/RenderSystem_Direct3D9" + OGRE_PLUGIN_DEBUG_SUFFIX; - if (boost::filesystem::exists(dxPlugin + ".so") || boost::filesystem::exists(dxPlugin + ".dll")) - mOgre->loadPlugin (dxPlugin); + pluginDir = absPluginPath.string(); + + Files::loadOgrePlugin(pluginDir, "RenderSystem_GL", *mOgre); + Files::loadOgrePlugin(pluginDir, "RenderSystem_Direct3D9", *mOgre); #ifdef ENABLE_PLUGIN_GL mGLPlugin = new Ogre::GLPlugin(); diff --git a/apps/openmw/CMakeLists.txt b/apps/openmw/CMakeLists.txt index 556b9a1ba..05aa161e6 100644 --- a/apps/openmw/CMakeLists.txt +++ b/apps/openmw/CMakeLists.txt @@ -21,6 +21,7 @@ add_openmw_dir (mwrender add_openmw_dir (mwinput inputmanager + mouselookevent ) add_openmw_dir (mwgui @@ -32,18 +33,18 @@ add_openmw_dir (mwgui ) add_openmw_dir (mwdialogue - dialoguemanager journal journalentry quest topic + dialoguemanagerimp journalimp journalentry quest topic ) add_openmw_dir (mwscript - locals scriptmanager compilercontext interpretercontext cellextensions miscextensions + locals scriptmanagerimp compilercontext interpretercontext cellextensions miscextensions guiextensions soundextensions skyextensions statsextensions containerextensions aiextensions controlextensions extensions globalscripts ref dialogueextensions animationextensions transformationextensions consoleextensions userextensions ) add_openmw_dir (mwsound - soundmanager openal_output audiere_decoder mpgsnd_decoder ffmpeg_decoder + soundmanagerimp openal_output audiere_decoder mpgsnd_decoder ffmpeg_decoder ) add_openmw_dir (mwworld @@ -64,7 +65,7 @@ add_openmw_dir (mwmechanics ) add_openmw_dir (mwbase - environment world + environment world scriptmanager dialoguemanager journal soundmanager ) # Main executable diff --git a/apps/openmw/engine.cpp b/apps/openmw/engine.cpp index 5e9aedf66..2467f91d1 100644 --- a/apps/openmw/engine.cpp +++ b/apps/openmw/engine.cpp @@ -18,10 +18,10 @@ #include "mwgui/window_manager.hpp" #include "mwgui/cursorreplace.hpp" -#include "mwscript/scriptmanager.hpp" +#include "mwscript/scriptmanagerimp.hpp" #include "mwscript/extensions.hpp" -#include "mwsound/soundmanager.hpp" +#include "mwsound/soundmanagerimp.hpp" #include "mwworld/class.hpp" #include "mwworld/player.hpp" @@ -29,8 +29,8 @@ #include "mwclass/classes.hpp" -#include "mwdialogue/dialoguemanager.hpp" -#include "mwdialogue/journal.hpp" +#include "mwdialogue/dialoguemanagerimp.hpp" +#include "mwdialogue/journalimp.hpp" #include "mwmechanics/mechanicsmanager.hpp" diff --git a/apps/openmw/mwbase/dialoguemanager.hpp b/apps/openmw/mwbase/dialoguemanager.hpp new file mode 100644 index 000000000..ccffc6b21 --- /dev/null +++ b/apps/openmw/mwbase/dialoguemanager.hpp @@ -0,0 +1,46 @@ +#ifndef GAME_MWBASE_DIALOGUEMANAGER_H +#define GAME_MWBASE_DIALOGUEMANAGER_H + +#include + +namespace MWWorld +{ + class Ptr; +} + +namespace MWBase +{ + /// \brief Interface for dialogue manager (implemented in MWDialogue) + class DialogueManager + { + DialogueManager (const DialogueManager&); + ///< not implemented + + DialogueManager& operator= (const DialogueManager&); + ///< not implemented + + public: + + DialogueManager() {} + + virtual ~DialogueManager() {} + + virtual void startDialogue (const MWWorld::Ptr& actor) = 0; + + virtual void addTopic (const std::string& topic) = 0; + + virtual void askQuestion (const std::string& question,int choice) = 0; + + virtual void goodbye() = 0; + + ///get the faction of the actor you are talking with + virtual std::string getFaction() const = 0; + + //calbacks for the GUI + virtual void keywordSelected (const std::string& keyword) = 0; + virtual void goodbyeSelected() = 0; + virtual void questionAnswered (const std::string& answer) = 0; + }; +} + +#endif diff --git a/apps/openmw/mwbase/environment.cpp b/apps/openmw/mwbase/environment.cpp index 7218f22eb..7d109b000 100644 --- a/apps/openmw/mwbase/environment.cpp +++ b/apps/openmw/mwbase/environment.cpp @@ -5,16 +5,13 @@ #include "../mwinput/inputmanager.hpp" -#include "../mwscript/scriptmanager.hpp" - -#include "../mwsound/soundmanager.hpp" - -#include "../mwdialogue/dialoguemanager.hpp" -#include "../mwdialogue/journal.hpp" - #include "../mwmechanics/mechanicsmanager.hpp" #include "world.hpp" +#include "scriptmanager.hpp" +#include "dialoguemanager.hpp" +#include "journal.hpp" +#include "soundmanager.hpp" MWBase::Environment *MWBase::Environment::sThis = 0; @@ -37,12 +34,12 @@ void MWBase::Environment::setWorld (World *world) mWorld = world; } -void MWBase::Environment::setSoundManager (MWSound::SoundManager *soundManager) +void MWBase::Environment::setSoundManager (SoundManager *soundManager) { mSoundManager = soundManager; } -void MWBase::Environment::setScriptManager (MWScript::ScriptManager *scriptManager) +void MWBase::Environment::setScriptManager (ScriptManager *scriptManager) { mScriptManager = scriptManager; } @@ -57,12 +54,12 @@ void MWBase::Environment::setMechanicsManager (MWMechanics::MechanicsManager *me mMechanicsManager = mechanicsManager; } -void MWBase::Environment::setDialogueManager (MWDialogue::DialogueManager *dialogueManager) +void MWBase::Environment::setDialogueManager (DialogueManager *dialogueManager) { mDialogueManager = dialogueManager; } -void MWBase::Environment::setJournal (MWDialogue::Journal *journal) +void MWBase::Environment::setJournal (Journal *journal) { mJournal = journal; } @@ -83,13 +80,13 @@ MWBase::World *MWBase::Environment::getWorld() const return mWorld; } -MWSound::SoundManager *MWBase::Environment::getSoundManager() const +MWBase::SoundManager *MWBase::Environment::getSoundManager() const { assert (mSoundManager); return mSoundManager; } -MWScript::ScriptManager *MWBase::Environment::getScriptManager() const +MWBase::ScriptManager *MWBase::Environment::getScriptManager() const { assert (mScriptManager); return mScriptManager; @@ -107,13 +104,13 @@ MWMechanics::MechanicsManager *MWBase::Environment::getMechanicsManager() const return mMechanicsManager; } -MWDialogue::DialogueManager *MWBase::Environment::getDialogueManager() const +MWBase::DialogueManager *MWBase::Environment::getDialogueManager() const { assert (mDialogueManager); return mDialogueManager; } -MWDialogue::Journal *MWBase::Environment::getJournal() const +MWBase::Journal *MWBase::Environment::getJournal() const { assert (mJournal); return mJournal; diff --git a/apps/openmw/mwbase/environment.hpp b/apps/openmw/mwbase/environment.hpp index ad5a6f655..d03267c25 100644 --- a/apps/openmw/mwbase/environment.hpp +++ b/apps/openmw/mwbase/environment.hpp @@ -1,16 +1,6 @@ #ifndef GAME_BASE_INVIRONMENT_H #define GAME_BASE_INVIRONMENT_H -namespace MWSound -{ - class SoundManager; -} - -namespace MWScript -{ - class ScriptManager; -} - namespace MWGui { class WindowManager; @@ -21,12 +11,6 @@ namespace MWMechanics class MechanicsManager; } -namespace MWDialogue -{ - class DialogueManager; - class Journal; -} - namespace MWInput { struct MWInputManager; @@ -35,6 +19,10 @@ namespace MWInput namespace MWBase { class World; + class ScriptManager; + class DialogueManager; + class Journal; + class SoundManager; /// \brief Central hub for mw-subsystems /// @@ -47,12 +35,12 @@ namespace MWBase static Environment *sThis; World *mWorld; - MWSound::SoundManager *mSoundManager; - MWScript::ScriptManager *mScriptManager; + SoundManager *mSoundManager; + ScriptManager *mScriptManager; MWGui::WindowManager *mWindowManager; MWMechanics::MechanicsManager *mMechanicsManager; - MWDialogue::DialogueManager *mDialogueManager; - MWDialogue::Journal *mJournal; + DialogueManager *mDialogueManager; + Journal *mJournal; MWInput::MWInputManager *mInputManager; float mFrameDuration; @@ -70,17 +58,17 @@ namespace MWBase void setWorld (World *world); - void setSoundManager (MWSound::SoundManager *soundManager); + void setSoundManager (SoundManager *soundManager); - void setScriptManager (MWScript::ScriptManager *scriptManager); + void setScriptManager (MWBase::ScriptManager *scriptManager); void setWindowManager (MWGui::WindowManager *windowManager); void setMechanicsManager (MWMechanics::MechanicsManager *mechanicsManager); - void setDialogueManager (MWDialogue::DialogueManager *dialogueManager); + void setDialogueManager (DialogueManager *dialogueManager); - void setJournal (MWDialogue::Journal *journal); + void setJournal (Journal *journal); void setInputManager (MWInput::MWInputManager *inputManager); @@ -89,17 +77,17 @@ namespace MWBase World *getWorld() const; - MWSound::SoundManager *getSoundManager() const; + SoundManager *getSoundManager() const; - MWScript::ScriptManager *getScriptManager() const; + MWBase::ScriptManager *getScriptManager() const; MWGui::WindowManager *getWindowManager() const; MWMechanics::MechanicsManager *getMechanicsManager() const; - MWDialogue::DialogueManager *getDialogueManager() const; + DialogueManager *getDialogueManager() const; - MWDialogue::Journal *getJournal() const; + Journal *getJournal() const; MWInput::MWInputManager *getInputManager() const; diff --git a/apps/openmw/mwbase/journal.hpp b/apps/openmw/mwbase/journal.hpp new file mode 100644 index 000000000..99f6996cf --- /dev/null +++ b/apps/openmw/mwbase/journal.hpp @@ -0,0 +1,76 @@ +#ifndef GAME_MWBASE_JOURNAL_H +#define GAME_MWBASE_JOURNAL_H + +#include +#include +#include + +namespace MWDialogue +{ + class Quest; + class Topic; + struct StampedJournalEntry; +} + +namespace MWBase +{ + /// \brief Interface for the player's journal (implemented in MWDialogue) + class Journal + { + Journal (const Journal&); + ///< not implemented + + Journal& operator= (const Journal&); + ///< not implemented + + public: + + typedef std::deque TEntryContainer; + typedef TEntryContainer::const_iterator TEntryIter; + typedef std::map TQuestContainer; // topc, quest + typedef TQuestContainer::const_iterator TQuestIter; + typedef std::map TTopicContainer; // topic-id, topic-content + typedef TTopicContainer::const_iterator TTopicIter; + + public: + + Journal() {} + + virtual ~Journal() {} + + virtual void addEntry (const std::string& id, int index) = 0; + ///< Add a journal entry. + + virtual void setJournalIndex (const std::string& id, int index) = 0; + ///< Set the journal index without adding an entry. + + virtual int getJournalIndex (const std::string& id) const = 0; + ///< Get the journal index. + + virtual void addTopic (const std::string& topicId, const std::string& infoId) = 0; + + virtual TEntryIter begin() const = 0; + ///< Iterator pointing to the begin of the main journal. + /// + /// \note Iterators to main journal entries will never become invalid. + + virtual TEntryIter end() const = 0; + ///< Iterator pointing past the end of the main journal. + + virtual TQuestIter questBegin() const = 0; + ///< Iterator pointing to the first quest (sorted by topic ID) + + virtual TQuestIter questEnd() const = 0; + ///< Iterator pointing past the last quest. + + virtual TTopicIter topicBegin() const = 0; + ///< Iterator pointing to the first topic (sorted by topic ID) + /// + /// \note The topic ID is identical with the user-visible topic string. + + virtual TTopicIter topicEnd() const = 0; + ///< Iterator pointing past the last topic. + }; +} + +#endif diff --git a/apps/openmw/mwbase/scriptmanager.hpp b/apps/openmw/mwbase/scriptmanager.hpp new file mode 100644 index 000000000..ae146e064 --- /dev/null +++ b/apps/openmw/mwbase/scriptmanager.hpp @@ -0,0 +1,62 @@ +#ifndef GAME_MWBASE_SCRIPTMANAGER_H +#define GAME_MWBASE_SCRIPTMANAGER_H + +#include + +namespace Interpreter +{ + class Context; +} + +namespace Compiler +{ + class Locals; +} + +namespace MWScript +{ + class GlobalScripts; +} + +namespace MWBase +{ + /// \brief Interface for script manager (implemented in MWScript) + class ScriptManager + { + ScriptManager (const ScriptManager&); + ///< not implemented + + ScriptManager& operator= (const ScriptManager&); + ///< not implemented + + public: + + ScriptManager() {} + + virtual ~ScriptManager() {} + + virtual void run (const std::string& name, Interpreter::Context& interpreterContext) = 0; + ///< Run the script with the given name (compile first, if not compiled yet) + + virtual bool compile (const std::string& name) = 0; + ///< Compile script with the given namen + /// \return Success? + + virtual std::pair compileAll() = 0; + ///< Compile all scripts + /// \return count, success + + virtual Compiler::Locals& getLocals (const std::string& name) = 0; + ///< Return locals for script \a name. + + virtual MWScript::GlobalScripts& getGlobalScripts() = 0; + + virtual int getLocalIndex (const std::string& scriptId, const std::string& variable, + char type) = 0; + ///< Return index of the variable of the given name and type in the given script. Will + /// throw an exception, if there is no such script or variable or the type does not match. + + }; +} + +#endif diff --git a/apps/openmw/mwbase/soundmanager.hpp b/apps/openmw/mwbase/soundmanager.hpp new file mode 100644 index 000000000..dfc619bf9 --- /dev/null +++ b/apps/openmw/mwbase/soundmanager.hpp @@ -0,0 +1,129 @@ +#ifndef GAME_MWBASE_SOUNDMANAGER_H +#define GAME_MWBASE_SOUNDMANAGER_H + +#include + +#include + +#include + +#include "../mwworld/ptr.hpp" + +namespace Ogre +{ + class Vector3; +} + +namespace MWWorld +{ + class CellStore; +} + +namespace MWSound +{ + class Sound; +} + +namespace MWBase +{ + typedef boost::shared_ptr SoundPtr; + + /// \brief Interface for sound manager (implemented in MWSound) + class SoundManager + { + public: + + enum PlayMode { + Play_Normal = 0, /* tracked, non-looping, multi-instance, environment */ + Play_Loop = 1<<0, /* Sound will continually loop until explicitly stopped */ + Play_NoEnv = 1<<1, /* Do not apply environment effects (eg, underwater filters) */ + Play_NoTrack = 1<<2, /* (3D only) Play the sound at the given object's position + * but do not keep it updated (the sound will not move with + * the object and will not stop when the object is deleted. */ + }; + + private: + + SoundManager (const SoundManager&); + ///< not implemented + + SoundManager& operator= (const SoundManager&); + ///< not implemented + + public: + + SoundManager() {} + + virtual ~SoundManager() {} + + virtual void processChangedSettings(const Settings::CategorySettingVector& settings) = 0; + + virtual void stopMusic() = 0; + ///< Stops music if it's playing + + virtual void streamMusic(const std::string& filename) = 0; + ///< Play a soundifle + /// \param filename name of a sound file in "Music/" in the data directory. + + virtual void startRandomTitle() = 0; + ///< Starts a random track from the current playlist + + virtual bool isMusicPlaying() = 0; + ///< Returns true if music is playing + + virtual void playPlaylist(const std::string &playlist) = 0; + ///< Start playing music from the selected folder + /// \param name of the folder that contains the playlist + + virtual void say(MWWorld::Ptr reference, const std::string& filename) = 0; + ///< Make an actor say some text. + /// \param filename name of a sound file in "Sound/" in the data directory. + + virtual void say(const std::string& filename) = 0; + ///< Say some text, without an actor ref + /// \param filename name of a sound file in "Sound/" in the data directory. + + virtual bool sayDone(MWWorld::Ptr reference=MWWorld::Ptr()) const = 0; + ///< Is actor not speaking? + + virtual void stopSay(MWWorld::Ptr reference=MWWorld::Ptr()) = 0; + ///< Stop an actor speaking + + virtual SoundPtr playSound(const std::string& soundId, float volume, float pitch, + int mode=Play_Normal) = 0; + ///< Play a sound, independently of 3D-position + + virtual SoundPtr playSound3D(MWWorld::Ptr reference, const std::string& soundId, + float volume, float pitch, int mode=Play_Normal) = 0; + ///< Play a sound from an object + + virtual void stopSound3D(MWWorld::Ptr reference, const std::string& soundId) = 0; + ///< Stop the given object from playing the given sound, + + virtual void stopSound3D(MWWorld::Ptr reference) = 0; + ///< Stop the given object from playing all sounds. + + virtual void stopSound(const MWWorld::CellStore *cell) = 0; + ///< Stop all sounds for the given cell. + + virtual void stopSound(const std::string& soundId) = 0; + ///< Stop a non-3d looping sound + + virtual bool getSoundPlaying(MWWorld::Ptr reference, const std::string& soundId) const = 0; + ///< Is the given sound currently playing on the given object? + + virtual void updateObject(MWWorld::Ptr reference) = 0; + ///< Update the position of all sounds connected to the given object. + + virtual void update(float duration) = 0; + + virtual void setListenerPosDir(const Ogre::Vector3 &pos, const Ogre::Vector3 &dir) = 0; + }; + + inline int operator|(SoundManager::PlayMode a, SoundManager::PlayMode b) + { return static_cast (a) | static_cast (b); } + inline int operator&(SoundManager::PlayMode a, SoundManager::PlayMode b) + { return static_cast (a) & static_cast (b); } +} + +#endif diff --git a/apps/openmw/mwbase/world.hpp b/apps/openmw/mwbase/world.hpp index f257b723e..8b809d399 100644 --- a/apps/openmw/mwbase/world.hpp +++ b/apps/openmw/mwbase/world.hpp @@ -46,6 +46,7 @@ namespace MWWorld namespace MWBase { + /// \brief Interface for the World (implemented in MWWorld) class World { World (const World&); @@ -54,14 +55,6 @@ namespace MWBase World& operator= (const World&); ///< not implemented - protected: - - virtual void - placeObject( - const MWWorld::Ptr &ptr, - MWWorld::CellStore &cell, - const ESM::Position &pos) = 0; - public: enum RenderMode @@ -184,9 +177,12 @@ namespace MWBase virtual void moveObject (const MWWorld::Ptr& ptr, float x, float y, float z) = 0; + virtual void + moveObject(const MWWorld::Ptr &ptr, MWWorld::CellStore &newCell, float x, float y, float z) = 0; + virtual void scaleObject (const MWWorld::Ptr& ptr, float scale) = 0; - virtual void rotateObject(const MWWorld::Ptr& ptr,float x,float y,float z) = 0; + virtual void rotateObject(const MWWorld::Ptr& ptr,float x,float y,float z, bool adjust = false) = 0; virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false) const = 0; @@ -249,6 +245,9 @@ namespace MWBase ///< @return true if it is possible to place on object at specified cursor location virtual void processChangedSettings (const Settings::CategorySettingVector& settings) = 0; + + virtual bool isSwimming(const MWWorld::Ptr &object) = 0; + virtual bool isUnderwater(const ESM::Cell &cell, const Ogre::Vector3 &pos) = 0; }; } diff --git a/apps/openmw/mwclass/apparatus.cpp b/apps/openmw/mwclass/apparatus.cpp index 9814b140c..3c22cc5fb 100644 --- a/apps/openmw/mwclass/apparatus.cpp +++ b/apps/openmw/mwclass/apparatus.cpp @@ -5,6 +5,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" @@ -18,8 +19,6 @@ #include "../mwgui/window_manager.hpp" #include "../mwgui/tooltips.hpp" -#include "../mwsound/soundmanager.hpp" - namespace MWClass { void Apparatus::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const @@ -39,7 +38,7 @@ namespace MWClass physics.insertObjectPhysics(ptr, model); } } - + std::string Apparatus::getModel(const MWWorld::Ptr &ptr) const { MWWorld::LiveCellRef *ref = @@ -64,7 +63,7 @@ namespace MWClass boost::shared_ptr Apparatus::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { - MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWBase::SoundManager::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); diff --git a/apps/openmw/mwclass/armor.cpp b/apps/openmw/mwclass/armor.cpp index 4624b94d9..43c1e0a43 100644 --- a/apps/openmw/mwclass/armor.cpp +++ b/apps/openmw/mwclass/armor.cpp @@ -7,6 +7,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" @@ -21,8 +22,6 @@ #include "../mwgui/window_manager.hpp" #include "../mwgui/tooltips.hpp" -#include "../mwsound/soundmanager.hpp" - namespace MWClass { void Armor::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const @@ -42,7 +41,7 @@ namespace MWClass physics.insertObjectPhysics(ptr, model); } } - + std::string Armor::getModel(const MWWorld::Ptr &ptr) const { MWWorld::LiveCellRef *ref = @@ -67,7 +66,7 @@ namespace MWClass boost::shared_ptr Armor::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { - MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWBase::SoundManager::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); diff --git a/apps/openmw/mwclass/book.cpp b/apps/openmw/mwclass/book.cpp index d8166347e..29a53140a 100644 --- a/apps/openmw/mwclass/book.cpp +++ b/apps/openmw/mwclass/book.cpp @@ -5,6 +5,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/actionread.hpp" @@ -17,8 +18,6 @@ #include "../mwgui/window_manager.hpp" #include "../mwgui/tooltips.hpp" -#include "../mwsound/soundmanager.hpp" - namespace MWClass { void Book::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const @@ -38,7 +37,7 @@ namespace MWClass physics.insertObjectPhysics(ptr, model); } } - + std::string Book::getModel(const MWWorld::Ptr &ptr) const { MWWorld::LiveCellRef *ref = diff --git a/apps/openmw/mwclass/clothing.cpp b/apps/openmw/mwclass/clothing.cpp index f55d6ed88..ef91b0fac 100644 --- a/apps/openmw/mwclass/clothing.cpp +++ b/apps/openmw/mwclass/clothing.cpp @@ -5,6 +5,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" @@ -19,8 +20,6 @@ #include "../mwrender/objects.hpp" #include "../mwrender/renderinginterface.hpp" -#include "../mwsound/soundmanager.hpp" - namespace MWClass { void Clothing::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const @@ -40,7 +39,7 @@ namespace MWClass physics.insertObjectPhysics(ptr, model); } } - + std::string Clothing::getModel(const MWWorld::Ptr &ptr) const { MWWorld::LiveCellRef *ref = @@ -65,7 +64,7 @@ namespace MWClass boost::shared_ptr Clothing::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { - MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWBase::SoundManager::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); diff --git a/apps/openmw/mwclass/container.cpp b/apps/openmw/mwclass/container.cpp index c6d22b3a5..7d31b945d 100644 --- a/apps/openmw/mwclass/container.cpp +++ b/apps/openmw/mwclass/container.cpp @@ -5,6 +5,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/nullaction.hpp" @@ -20,8 +21,6 @@ #include "../mwrender/objects.hpp" #include "../mwrender/renderinginterface.hpp" -#include "../mwsound/soundmanager.hpp" - namespace { struct CustomData : public MWWorld::CustomData @@ -69,7 +68,7 @@ namespace MWClass physics.insertObjectPhysics(ptr, model); } } - + std::string Container::getModel(const MWWorld::Ptr &ptr) const { MWWorld::LiveCellRef *ref = diff --git a/apps/openmw/mwclass/door.cpp b/apps/openmw/mwclass/door.cpp index 6939c356e..19eda16ef 100644 --- a/apps/openmw/mwclass/door.cpp +++ b/apps/openmw/mwclass/door.cpp @@ -5,6 +5,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwworld/player.hpp" #include "../mwworld/ptr.hpp" @@ -19,8 +20,6 @@ #include "../mwrender/objects.hpp" #include "../mwrender/renderinginterface.hpp" -#include "../mwsound/soundmanager.hpp" - namespace MWClass { void Door::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const diff --git a/apps/openmw/mwclass/ingredient.cpp b/apps/openmw/mwclass/ingredient.cpp index d8c8b4b3b..eb92accb6 100644 --- a/apps/openmw/mwclass/ingredient.cpp +++ b/apps/openmw/mwclass/ingredient.cpp @@ -5,6 +5,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" @@ -17,8 +18,6 @@ #include "../mwrender/objects.hpp" #include "../mwrender/renderinginterface.hpp" -#include "../mwsound/soundmanager.hpp" - namespace MWClass { void Ingredient::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const @@ -38,7 +37,7 @@ namespace MWClass physics.insertObjectPhysics(ptr, model); } } - + std::string Ingredient::getModel(const MWWorld::Ptr &ptr) const { MWWorld::LiveCellRef *ref = @@ -63,7 +62,7 @@ namespace MWClass boost::shared_ptr Ingredient::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { - MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWBase::SoundManager::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); diff --git a/apps/openmw/mwclass/light.cpp b/apps/openmw/mwclass/light.cpp index f09d3ce36..ed8fd1de6 100644 --- a/apps/openmw/mwclass/light.cpp +++ b/apps/openmw/mwclass/light.cpp @@ -5,6 +5,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" @@ -17,8 +18,6 @@ #include "../mwgui/window_manager.hpp" #include "../mwgui/tooltips.hpp" -#include "../mwsound/soundmanager.hpp" - #include "../mwrender/objects.hpp" #include "../mwrender/renderinginterface.hpp" @@ -58,7 +57,7 @@ namespace MWClass physics.insertObjectPhysics(ptr, "meshes\\" + model); } if (!ref->base->sound.empty()) { - MWBase::Environment::get().getSoundManager()->playSound3D(ptr, ref->base->sound, 1.0, 1.0, MWSound::Play_Loop); + MWBase::Environment::get().getSoundManager()->playSound3D(ptr, ref->base->sound, 1.0, 1.0, MWBase::SoundManager::Play_Loop); } } @@ -95,7 +94,7 @@ namespace MWClass if (!(ref->base->data.flags & ESM::Light::Carry)) return boost::shared_ptr (new MWWorld::NullAction); - MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWBase::SoundManager::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); diff --git a/apps/openmw/mwclass/lockpick.cpp b/apps/openmw/mwclass/lockpick.cpp index 20441b520..1472b7e8b 100644 --- a/apps/openmw/mwclass/lockpick.cpp +++ b/apps/openmw/mwclass/lockpick.cpp @@ -5,6 +5,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" @@ -19,8 +20,6 @@ #include "../mwrender/objects.hpp" #include "../mwrender/renderinginterface.hpp" -#include "../mwsound/soundmanager.hpp" - namespace MWClass { void Lockpick::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const @@ -40,7 +39,7 @@ namespace MWClass physics.insertObjectPhysics(ptr, model); } } - + std::string Lockpick::getModel(const MWWorld::Ptr &ptr) const { MWWorld::LiveCellRef *ref = @@ -65,7 +64,7 @@ namespace MWClass boost::shared_ptr Lockpick::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { - MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWBase::SoundManager::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); diff --git a/apps/openmw/mwclass/misc.cpp b/apps/openmw/mwclass/misc.cpp index cb6d40c43..8b5b41495 100644 --- a/apps/openmw/mwclass/misc.cpp +++ b/apps/openmw/mwclass/misc.cpp @@ -7,6 +7,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" @@ -20,8 +21,6 @@ #include "../mwrender/objects.hpp" #include "../mwrender/renderinginterface.hpp" -#include "../mwsound/soundmanager.hpp" - #include namespace MWClass @@ -43,7 +42,7 @@ namespace MWClass physics.insertObjectPhysics(ptr, model); } } - + std::string Miscellaneous::getModel(const MWWorld::Ptr &ptr) const { MWWorld::LiveCellRef *ref = @@ -68,7 +67,7 @@ namespace MWClass boost::shared_ptr Miscellaneous::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { - MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWBase::SoundManager::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -189,7 +188,7 @@ namespace MWClass Miscellaneous::copyToCellImpl(const MWWorld::Ptr &ptr, MWWorld::CellStore &cell) const { MWWorld::Ptr newPtr; - + const ESMS::ESMStore &store = MWBase::Environment::get().getWorld()->getStore(); diff --git a/apps/openmw/mwclass/potion.cpp b/apps/openmw/mwclass/potion.cpp index d3f2912ea..27903fdf7 100644 --- a/apps/openmw/mwclass/potion.cpp +++ b/apps/openmw/mwclass/potion.cpp @@ -5,6 +5,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" @@ -19,8 +20,6 @@ #include "../mwrender/objects.hpp" #include "../mwrender/renderinginterface.hpp" -#include "../mwsound/soundmanager.hpp" - namespace MWClass { void Potion::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const @@ -65,7 +64,7 @@ namespace MWClass boost::shared_ptr Potion::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { - MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWBase::SoundManager::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); diff --git a/apps/openmw/mwclass/probe.cpp b/apps/openmw/mwclass/probe.cpp index 450016209..8a563865d 100644 --- a/apps/openmw/mwclass/probe.cpp +++ b/apps/openmw/mwclass/probe.cpp @@ -5,6 +5,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" @@ -19,8 +20,6 @@ #include "../mwrender/objects.hpp" #include "../mwrender/renderinginterface.hpp" -#include "../mwsound/soundmanager.hpp" - namespace MWClass { void Probe::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const @@ -40,7 +39,7 @@ namespace MWClass physics.insertObjectPhysics(ptr, model); } } - + std::string Probe::getModel(const MWWorld::Ptr &ptr) const { MWWorld::LiveCellRef *ref = @@ -64,7 +63,7 @@ namespace MWClass boost::shared_ptr Probe::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { - MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWBase::SoundManager::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); @@ -174,4 +173,3 @@ namespace MWClass return MWWorld::Ptr(&cell.probes.insert(*ref), &cell); } } - diff --git a/apps/openmw/mwclass/repair.cpp b/apps/openmw/mwclass/repair.cpp index 829fe311a..096d3d0ee 100644 --- a/apps/openmw/mwclass/repair.cpp +++ b/apps/openmw/mwclass/repair.cpp @@ -5,6 +5,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" @@ -17,8 +18,6 @@ #include "../mwrender/objects.hpp" #include "../mwrender/renderinginterface.hpp" -#include "../mwsound/soundmanager.hpp" - namespace MWClass { void Repair::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const @@ -38,7 +37,7 @@ namespace MWClass physics.insertObjectPhysics(ptr, model); } } - + std::string Repair::getModel(const MWWorld::Ptr &ptr) const { MWWorld::LiveCellRef *ref = @@ -63,7 +62,7 @@ namespace MWClass boost::shared_ptr Repair::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { - MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWBase::SoundManager::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); diff --git a/apps/openmw/mwclass/weapon.cpp b/apps/openmw/mwclass/weapon.cpp index b45953130..bc8e3e648 100644 --- a/apps/openmw/mwclass/weapon.cpp +++ b/apps/openmw/mwclass/weapon.cpp @@ -5,6 +5,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/actiontake.hpp" @@ -19,8 +20,6 @@ #include "../mwrender/objects.hpp" #include "../mwrender/renderinginterface.hpp" -#include "../mwsound/soundmanager.hpp" - namespace MWClass { void Weapon::insertObjectRendering (const MWWorld::Ptr& ptr, MWRender::RenderingInterface& renderingInterface) const @@ -40,7 +39,7 @@ namespace MWClass physics.insertObjectPhysics(ptr, model); } } - + std::string Weapon::getModel(const MWWorld::Ptr &ptr) const { MWWorld::LiveCellRef *ref = @@ -65,7 +64,7 @@ namespace MWClass boost::shared_ptr Weapon::activate (const MWWorld::Ptr& ptr, const MWWorld::Ptr& actor) const { - MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWSound::Play_NoTrack); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, getUpSoundId(ptr), 1.0, 1.0, MWBase::SoundManager::Play_NoTrack); return boost::shared_ptr ( new MWWorld::ActionTake (ptr)); diff --git a/apps/openmw/mwdialogue/dialoguemanager.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp similarity index 97% rename from apps/openmw/mwdialogue/dialoguemanager.cpp rename to apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 6f3f0c901..644da49e2 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -1,5 +1,5 @@ -#include "dialoguemanager.hpp" +#include "dialoguemanagerimp.hpp" #include #include @@ -11,6 +11,8 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/scriptmanager.hpp" +#include "../mwbase/journal.hpp" #include "../mwworld/class.hpp" #include "../mwworld/refdata.hpp" @@ -21,12 +23,9 @@ #include "../mwgui/dialogue.hpp" #include "../mwgui/window_manager.hpp" -#include "journal.hpp" - #include #include "../mwscript/extensions.hpp" -#include "../mwscript/scriptmanager.hpp" #include #include @@ -599,12 +598,12 @@ namespace MWDialogue } } - void DialogueManager::addTopic(std::string topic) + void DialogueManager::addTopic (const std::string& topic) { mKnownTopics[toLower(topic)] = true; } - void DialogueManager::parseText(std::string text) + void DialogueManager::parseText (std::string text) { std::list::iterator it; for(it = mActorKnownTopics.begin();it != mActorKnownTopics.end();++it) @@ -804,7 +803,7 @@ namespace MWDialogue mChoice = choice; } - void DialogueManager::keywordSelected(std::string keyword) + void DialogueManager::keywordSelected (const std::string& keyword) { if(!mIsInChoice) { @@ -846,11 +845,11 @@ namespace MWDialogue MWBase::Environment::get().getWindowManager()->removeGuiMode(MWGui::GM_Dialogue); } - void DialogueManager::questionAnswered(std::string answere) + void DialogueManager::questionAnswered (const std::string& answer) { - if(mChoiceMap.find(answere) != mChoiceMap.end()) + if(mChoiceMap.find(answer) != mChoiceMap.end()) { - mChoice = mChoiceMap[answere]; + mChoice = mChoiceMap[answer]; std::vector::const_iterator iter; if(mDialogueMap.find(mLastTopic) != mDialogueMap.end()) @@ -882,13 +881,13 @@ namespace MWDialogue } } - void DialogueManager::printError(std::string error) + void DialogueManager::printError (std::string error) { MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); win->addText(error); } - void DialogueManager::askQuestion(std::string question, int choice) + void DialogueManager::askQuestion (const std::string& question, int choice) { MWGui::DialogueWindow* win = MWBase::Environment::get().getWindowManager()->getDialogueWindow(); win->askQuestion(question); @@ -896,7 +895,7 @@ namespace MWDialogue mIsInChoice = true; } - std::string DialogueManager::getFaction() + std::string DialogueManager::getFaction() const { if (mActor.getTypeName() != typeid(ESM::NPC).name()) return ""; diff --git a/apps/openmw/mwdialogue/dialoguemanager.hpp b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp similarity index 71% rename from apps/openmw/mwdialogue/dialoguemanager.hpp rename to apps/openmw/mwdialogue/dialoguemanagerimp.hpp index d139ddc01..69cc88f25 100644 --- a/apps/openmw/mwdialogue/dialoguemanager.hpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.hpp @@ -1,5 +1,5 @@ -#ifndef GAME_MMDIALOG_DIALOGUEMANAGER_H -#define GAME_MWDIALOG_DIALOGUEMANAGER_H +#ifndef GAME_MMDIALOG_DIALOGUEMANAGERIMP_H +#define GAME_MWDIALOG_DIALOGUEMANAGERIMP_H #include @@ -8,12 +8,15 @@ #include "../mwscript/interpretercontext.hpp" #include +#include "../mwbase/dialoguemanager.hpp" + #include "../mwworld/ptr.hpp" + #include namespace MWDialogue { - class DialogueManager + class DialogueManager : public MWBase::DialogueManager { bool isMatching (const MWWorld::Ptr& actor, const ESM::DialInfo::SelectStruct& select) const; @@ -50,21 +53,21 @@ namespace MWDialogue DialogueManager (const Compiler::Extensions& extensions); - void startDialogue (const MWWorld::Ptr& actor); + virtual void startDialogue (const MWWorld::Ptr& actor); - void addTopic(std::string topic); + virtual void addTopic (const std::string& topic); - void askQuestion(std::string question,int choice); + virtual void askQuestion (const std::string& question,int choice); - void goodbye(); + virtual void goodbye(); ///get the faction of the actor you are talking with - std::string getFaction(); + virtual std::string getFaction() const; //calbacks for the GUI - void keywordSelected(std::string keyword); - void goodbyeSelected(); - void questionAnswered(std::string answere); + virtual void keywordSelected (const std::string& keyword); + virtual void goodbyeSelected(); + virtual void questionAnswered (const std::string& answer); }; } diff --git a/apps/openmw/mwdialogue/journal.cpp b/apps/openmw/mwdialogue/journalimp.cpp similarity index 98% rename from apps/openmw/mwdialogue/journal.cpp rename to apps/openmw/mwdialogue/journalimp.cpp index ad10be3aa..052b92194 100644 --- a/apps/openmw/mwdialogue/journal.cpp +++ b/apps/openmw/mwdialogue/journalimp.cpp @@ -1,5 +1,5 @@ -#include "journal.hpp" +#include "journalimp.hpp" #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" diff --git a/apps/openmw/mwdialogue/journal.hpp b/apps/openmw/mwdialogue/journalimp.hpp similarity index 52% rename from apps/openmw/mwdialogue/journal.hpp rename to apps/openmw/mwdialogue/journalimp.hpp index 62b9f4bed..5fafc265a 100644 --- a/apps/openmw/mwdialogue/journal.hpp +++ b/apps/openmw/mwdialogue/journalimp.hpp @@ -1,9 +1,7 @@ #ifndef GAME_MMDIALOG_JOURNAL_H #define GAME_MWDIALOG_JOURNAL_H -#include -#include -#include +#include "../mwbase/journal.hpp" #include "journalentry.hpp" #include "quest.hpp" @@ -11,19 +9,8 @@ namespace MWDialogue { /// \brief The player's journal - class Journal + class Journal : public MWBase::Journal { - public: - - typedef std::deque TEntryContainer; - typedef TEntryContainer::const_iterator TEntryIter; - typedef std::map TQuestContainer; // topc, quest - typedef TQuestContainer::const_iterator TQuestIter; - typedef std::map TTopicContainer; // topic-id, topic-content - typedef TTopicContainer::const_iterator TTopicIter; - - private: - TEntryContainer mJournal; TQuestContainer mQuests; TTopicContainer mTopics; @@ -34,37 +21,37 @@ namespace MWDialogue Journal(); - void addEntry (const std::string& id, int index); + virtual void addEntry (const std::string& id, int index); ///< Add a journal entry. - void setJournalIndex (const std::string& id, int index); + virtual void setJournalIndex (const std::string& id, int index); ///< Set the journal index without adding an entry. - int getJournalIndex (const std::string& id) const; + virtual int getJournalIndex (const std::string& id) const; ///< Get the journal index. - void addTopic (const std::string& topicId, const std::string& infoId); + virtual void addTopic (const std::string& topicId, const std::string& infoId); - TEntryIter begin() const; + virtual TEntryIter begin() const; ///< Iterator pointing to the begin of the main journal. /// /// \note Iterators to main journal entries will never become invalid. - TEntryIter end() const; + virtual TEntryIter end() const; ///< Iterator pointing past the end of the main journal. - TQuestIter questBegin() const; + virtual TQuestIter questBegin() const; ///< Iterator pointing to the first quest (sorted by topic ID) - TQuestIter questEnd() const; + virtual TQuestIter questEnd() const; ///< Iterator pointing past the last quest. - TTopicIter topicBegin() const; + virtual TTopicIter topicBegin() const; ///< Iterator pointing to the first topic (sorted by topic ID) /// /// \note The topic ID is identical with the user-visible topic string. - TTopicIter topicEnd() const; + virtual TTopicIter topicEnd() const; ///< Iterator pointing past the last topic. }; } diff --git a/apps/openmw/mwgui/alchemywindow.cpp b/apps/openmw/mwgui/alchemywindow.cpp index 9d691d371..81e5640d4 100644 --- a/apps/openmw/mwgui/alchemywindow.cpp +++ b/apps/openmw/mwgui/alchemywindow.cpp @@ -4,13 +4,12 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwworld/player.hpp" #include "../mwworld/manualref.hpp" #include "../mwworld/containerstore.hpp" -#include "../mwsound/soundmanager.hpp" - #include "window_manager.hpp" namespace diff --git a/apps/openmw/mwgui/bookwindow.cpp b/apps/openmw/mwgui/bookwindow.cpp index 1e0301d8e..19a5e9398 100644 --- a/apps/openmw/mwgui/bookwindow.cpp +++ b/apps/openmw/mwgui/bookwindow.cpp @@ -4,8 +4,10 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" + #include "../mwinput/inputmanager.hpp" -#include "../mwsound/soundmanager.hpp" + #include "../mwworld/actiontake.hpp" #include "../mwworld/player.hpp" @@ -98,7 +100,7 @@ void BookWindow::onCloseButtonClicked (MyGUI::Widget* _sender) void BookWindow::onTakeButtonClicked (MyGUI::Widget* _sender) { - MWBase::Environment::get().getSoundManager()->playSound ("Item Book Up", 1.0, 1.0, MWSound::Play_NoTrack); + MWBase::Environment::get().getSoundManager()->playSound ("Item Book Up", 1.0, 1.0, MWBase::SoundManager::Play_NoTrack); MWWorld::ActionTake take(mBook); take.execute (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); diff --git a/apps/openmw/mwgui/charactercreation.cpp b/apps/openmw/mwgui/charactercreation.cpp index c39e305dc..c0081544b 100644 --- a/apps/openmw/mwgui/charactercreation.cpp +++ b/apps/openmw/mwgui/charactercreation.cpp @@ -9,7 +9,7 @@ #include "mode.hpp" #include "../mwbase/environment.hpp" -#include "../mwsound/soundmanager.hpp" +#include "../mwbase/soundmanager.hpp" namespace { diff --git a/apps/openmw/mwgui/container.cpp b/apps/openmw/mwgui/container.cpp index 44cb12d2d..66dea0849 100644 --- a/apps/openmw/mwgui/container.cpp +++ b/apps/openmw/mwgui/container.cpp @@ -10,6 +10,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwworld/manualref.hpp" #include "../mwworld/containerstore.hpp" @@ -20,8 +21,6 @@ #include "../mwinput/inputmanager.hpp" -#include "../mwsound/soundmanager.hpp" - #include "window_manager.hpp" #include "widgets.hpp" #include "countdialog.hpp" diff --git a/apps/openmw/mwgui/dialogue.cpp b/apps/openmw/mwgui/dialogue.cpp index 760c89f49..30089dd46 100644 --- a/apps/openmw/mwgui/dialogue.cpp +++ b/apps/openmw/mwgui/dialogue.cpp @@ -9,7 +9,8 @@ #include #include "../mwbase/environment.hpp" -#include "../mwdialogue/dialoguemanager.hpp" +#include "../mwbase/dialoguemanager.hpp" +#include "../mwbase/world.hpp" #include "dialogue_history.hpp" #include "window_manager.hpp" diff --git a/apps/openmw/mwgui/hud.cpp b/apps/openmw/mwgui/hud.cpp index d2eef26ac..1c7943386 100644 --- a/apps/openmw/mwgui/hud.cpp +++ b/apps/openmw/mwgui/hud.cpp @@ -8,12 +8,11 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwworld/class.hpp" #include "../mwworld/player.hpp" -#include "../mwsound/soundmanager.hpp" - #include "../mwgui/widgets.hpp" #include "inventorywindow.hpp" diff --git a/apps/openmw/mwgui/inventorywindow.cpp b/apps/openmw/mwgui/inventorywindow.cpp index 926c35172..090b7dd6e 100644 --- a/apps/openmw/mwgui/inventorywindow.cpp +++ b/apps/openmw/mwgui/inventorywindow.cpp @@ -9,6 +9,7 @@ #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwworld/containerstore.hpp" #include "../mwworld/class.hpp" @@ -17,10 +18,6 @@ #include "../mwworld/actiontake.hpp" #include "../mwworld/inventorystore.hpp" -#include "../mwsound/soundmanager.hpp" - -#include "../mwclass/container.hpp" - #include "window_manager.hpp" #include "widgets.hpp" #include "bookwindow.hpp" diff --git a/apps/openmw/mwgui/journalwindow.cpp b/apps/openmw/mwgui/journalwindow.cpp index 8b50c9ef1..475a70631 100644 --- a/apps/openmw/mwgui/journalwindow.cpp +++ b/apps/openmw/mwgui/journalwindow.cpp @@ -2,10 +2,10 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/journal.hpp" +#include "../mwbase/soundmanager.hpp" -#include "../mwdialogue/journal.hpp" - -#include "../mwsound/soundmanager.hpp" +#include "../mwdialogue/journalentry.hpp" #include "window_manager.hpp" diff --git a/apps/openmw/mwgui/scrollwindow.cpp b/apps/openmw/mwgui/scrollwindow.cpp index 00e5a01dc..67a02e53b 100644 --- a/apps/openmw/mwgui/scrollwindow.cpp +++ b/apps/openmw/mwgui/scrollwindow.cpp @@ -2,10 +2,12 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" + #include "../mwinput/inputmanager.hpp" + #include "../mwworld/actiontake.hpp" #include "../mwworld/player.hpp" -#include "../mwsound/soundmanager.hpp" #include "formatting.hpp" #include "window_manager.hpp" @@ -62,7 +64,7 @@ void ScrollWindow::onCloseButtonClicked (MyGUI::Widget* _sender) void ScrollWindow::onTakeButtonClicked (MyGUI::Widget* _sender) { - MWBase::Environment::get().getSoundManager()->playSound ("Item Book Up", 1.0, 1.0, MWSound::Play_NoTrack); + MWBase::Environment::get().getSoundManager()->playSound ("Item Book Up", 1.0, 1.0, MWBase::SoundManager::Play_NoTrack); MWWorld::ActionTake take(mScroll); take.execute (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); diff --git a/apps/openmw/mwgui/settingswindow.cpp b/apps/openmw/mwgui/settingswindow.cpp index d8b0c96d7..9629c7cca 100644 --- a/apps/openmw/mwgui/settingswindow.cpp +++ b/apps/openmw/mwgui/settingswindow.cpp @@ -12,11 +12,10 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwrender/renderingmanager.hpp" -#include "../mwsound/soundmanager.hpp" - #include "../mwinput/inputmanager.hpp" #include "window_manager.hpp" @@ -75,9 +74,9 @@ namespace return boost::lexical_cast(xaspect) + " : " + boost::lexical_cast(yaspect); } - bool hasGLSL () + std::string hlslGlsl () { - return (Ogre::Root::getSingleton ().getRenderSystem ()->getName ().find("OpenGL") != std::string::npos); + return (Ogre::Root::getSingleton ().getRenderSystem ()->getName ().find("OpenGL") != std::string::npos) ? "glsl" : "hlsl"; } } @@ -393,12 +392,9 @@ namespace MWGui std::string val = static_cast(_sender)->getCaption(); if (val == "off") { - if (hasGLSL ()) - val = "glsl"; - else - val = "cg"; + val = hlslGlsl(); } - else if (val == "glsl") + else if (val == hlslGlsl()) val = "cg"; else val = "off"; @@ -411,6 +407,7 @@ namespace MWGui // water shader not supported with object shaders off mWaterShaderButton->setCaptionWithReplacing("#{sOff}"); + mUnderwaterButton->setCaptionWithReplacing("#{sOff}"); mWaterShaderButton->setEnabled(false); mReflectObjectsButton->setEnabled(false); mReflectActorsButton->setEnabled(false); diff --git a/apps/openmw/mwgui/spellwindow.cpp b/apps/openmw/mwgui/spellwindow.cpp index 8f81a1761..b528eecc2 100644 --- a/apps/openmw/mwgui/spellwindow.cpp +++ b/apps/openmw/mwgui/spellwindow.cpp @@ -8,6 +8,7 @@ #include "../mwbase/world.hpp" #include "../mwbase/environment.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwworld/player.hpp" #include "../mwworld/inventorystore.hpp" @@ -16,8 +17,6 @@ #include "../mwmechanics/creaturestats.hpp" #include "../mwmechanics/spellsuccess.hpp" -#include "../mwsound/soundmanager.hpp" - #include "window_manager.hpp" #include "inventorywindow.hpp" #include "confirmationdialog.hpp" diff --git a/apps/openmw/mwgui/tradewindow.cpp b/apps/openmw/mwgui/tradewindow.cpp index d9f9692ff..75e39fd87 100644 --- a/apps/openmw/mwgui/tradewindow.cpp +++ b/apps/openmw/mwgui/tradewindow.cpp @@ -4,10 +4,10 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwworld/inventorystore.hpp" #include "../mwworld/manualref.hpp" -#include "../mwsound/soundmanager.hpp" #include "window_manager.hpp" #include "inventorywindow.hpp" diff --git a/apps/openmw/mwinput/inputmanager.cpp b/apps/openmw/mwinput/inputmanager.cpp index 3a8315b71..35aafa446 100644 --- a/apps/openmw/mwinput/inputmanager.cpp +++ b/apps/openmw/mwinput/inputmanager.cpp @@ -6,7 +6,6 @@ #include #include -#include #include #include "../mwgui/window_manager.hpp" @@ -16,12 +15,12 @@ #include +#include "mouselookevent.hpp" + #include "../engine.hpp" #include "../mwworld/player.hpp" -#include "../mwrender/player.hpp" - #include #include #include @@ -82,7 +81,7 @@ namespace MWInput OEngine::Render::ExitListener exit; Mangle::Input::OISDriver input; OEngine::Input::Poller poller; - OEngine::Render::MouseLookEventPtr mouse; + MouseLookEventPtr mouse; OEngine::GUI::EventInjectorPtr guiEvents; MWWorld::Player &player; MWGui::WindowManager &windows; @@ -90,6 +89,7 @@ namespace MWInput bool mDragDrop; + std::map mControlSwitch; /* InputImpl Methods */ public: @@ -278,8 +278,7 @@ private: // Add the exit listener ogre.getRoot()->addFrameListener(&exit); - // Set up the mouse handler and tell it about the player camera - mouse = MouseLookEventPtr(new MouseLookEvent(player.getRenderer()->getCamera())); + mouse = MouseLookEventPtr(new MouseLookEvent()); // This event handler pumps events into MyGUI guiEvents = EventInjectorPtr(new EventInjector(windows.getGui())); @@ -296,6 +295,14 @@ private: lst->add(guiEvents,Event::EV_ALL); } + mControlSwitch["playercontrols"] = true; + mControlSwitch["playerfighting"] = true; + mControlSwitch["playerjumping"] = true; + mControlSwitch["playerlooking"] = true; + mControlSwitch["playermagic"] = true; + mControlSwitch["playerviewswitch"] = true; + mControlSwitch["vanitymode"] = true; + changeInputMode(false); /********************************** @@ -366,38 +373,40 @@ private: // Configure player movement according to keyboard input. Actual movement will // be done in the physics system. - if (poller.isDown(A_MoveLeft)) - { - player.setAutoMove (false); - player.setLeftRight (1); - } - else if (poller.isDown(A_MoveRight)) - { - player.setAutoMove (false); - player.setLeftRight (-1); - } - else - player.setLeftRight (0); + if (mControlSwitch["playercontrols"]) { + if (poller.isDown(A_MoveLeft)) + { + player.setAutoMove (false); + player.setLeftRight (1); + } + else if (poller.isDown(A_MoveRight)) + { + player.setAutoMove (false); + player.setLeftRight (-1); + } + else + player.setLeftRight (0); - if (poller.isDown(A_MoveForward)) - { - player.setAutoMove (false); - player.setForwardBackward (1); - } - else if (poller.isDown(A_MoveBackward)) - { - player.setAutoMove (false); - player.setForwardBackward (-1); - } - else - player.setForwardBackward (0); + if (poller.isDown(A_MoveForward)) + { + player.setAutoMove (false); + player.setForwardBackward (1); + } + else if (poller.isDown(A_MoveBackward)) + { + player.setAutoMove (false); + player.setForwardBackward (-1); + } + else + player.setForwardBackward (0); - if (poller.isDown(A_Jump)) - player.setUpDown (1); - else if (poller.isDown(A_Crouch)) - player.setUpDown (-1); - else - player.setUpDown (0); + if (poller.isDown(A_Jump) && mControlSwitch["playerjumping"]) + player.setUpDown (1); + else if (poller.isDown(A_Crouch)) + player.setUpDown (-1); + else + player.setUpDown (0); + } } // Switch between gui modes. Besides controlling the Gui windows @@ -408,21 +417,47 @@ private: if(guiMode) { // Disable mouse look - mouse->setCamera(NULL); + mouse->disable(); // 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.getRenderer()->getCamera()); + // Start mouse-looking again if allowed. + if (mControlSwitch["playerlooking"]) { + mouse->enable(); + } // Disable GUI events guiEvents->enabled = false; } } + + void toggleControlSwitch(std::string sw, bool value) + { + if (mControlSwitch[sw] == value) { + return; + } + /// \note 7 switches at all, if-else is relevant + if (sw == "playercontrols" && !value) { + player.setLeftRight(0); + player.setForwardBackward(0); + player.setAutoMove(false); + player.setUpDown(0); + } else if (sw == "playerjumping" && !value) { + /// \fixme maybe crouching at this time + player.setUpDown(0); + } else if (sw == "playerlooking") { + if (value) { + mouse->enable(); + } else { + mouse->disable(); + } + } + mControlSwitch[sw] = value; + } + }; /***CONSTRUCTOR***/ @@ -471,4 +506,9 @@ private: if (changeRes) impl->adjustMouseRegion(Settings::Manager::getInt("resolution x", "Video"), Settings::Manager::getInt("resolution y", "Video")); } + + void MWInputManager::toggleControlSwitch(std::string sw, bool value) + { + impl->toggleControlSwitch(sw, value); + } } diff --git a/apps/openmw/mwinput/inputmanager.hpp b/apps/openmw/mwinput/inputmanager.hpp index 4ef3df137..2486f82d6 100644 --- a/apps/openmw/mwinput/inputmanager.hpp +++ b/apps/openmw/mwinput/inputmanager.hpp @@ -57,6 +57,8 @@ namespace MWInput void processChangedSettings(const Settings::CategorySettingVector& changed); void setDragDrop(bool dragDrop); + + void toggleControlSwitch(std::string sw, bool value); }; } #endif diff --git a/apps/openmw/mwinput/mouselookevent.cpp b/apps/openmw/mwinput/mouselookevent.cpp new file mode 100644 index 000000000..f318ce666 --- /dev/null +++ b/apps/openmw/mwinput/mouselookevent.cpp @@ -0,0 +1,28 @@ +#include "mouselookevent.hpp" + +#include "../mwbase/environment.hpp" +#include "../mwbase/world.hpp" + +#include "../mwworld/player.hpp" + +#include +#include +#include + +using namespace OIS; +using namespace MWInput; + +void MouseLookEvent::event(Type type, int index, const void *p) +{ + if (type != EV_MouseMove || mDisabled) { + return; + } + + MouseEvent *arg = (MouseEvent*)(p); + + float x = arg->state.X.rel * sensX; + float y = arg->state.Y.rel * sensY; + + MWBase::World *world = MWBase::Environment::get().getWorld(); + world->rotateObject(world->getPlayer().getPlayer(), -y, 0.f, x, true); +} diff --git a/apps/openmw/mwinput/mouselookevent.hpp b/apps/openmw/mwinput/mouselookevent.hpp new file mode 100644 index 000000000..af996643f --- /dev/null +++ b/apps/openmw/mwinput/mouselookevent.hpp @@ -0,0 +1,57 @@ +#ifndef _MWINPUT_MOUSELOOKEVENT_H +#define _MWINPUT_MOUSELOOKEVENT_H + +/* + A mouse-look class for Ogre. Accepts input events from Mangle::Input + and translates them. + + You can adjust the mouse sensibility and switch to a different + camera. The mouselook class also has an optional wrap protection + that keeps the camera from flipping upside down. + + You can disable the mouse looker at any time by calling + setCamera(NULL), and reenable it by setting the camera back. + + NOTE: The current implementation will ONLY work for native OIS + events. + */ + +#include + +namespace MWInput +{ + class MouseLookEvent : public Mangle::Input::Event + { + float sensX, sensY; // Mouse sensibility + bool flipProt; // Flip protection + bool mDisabled; + + public: + MouseLookEvent(float sX = 0.2, float sY = 0.2, bool prot=true) + : sensX(sX), sensY(sY), flipProt(prot) + {} + + void setSens(float sX, float sY) { + sensX = sX; + sensY = sY; + } + + void setProt(bool p) { + flipProt = p; + } + + void disable() { + mDisabled = true; + } + + void enable() { + mDisabled = false; + } + + void event(Type type, int index, const void *p); + }; + + typedef boost::shared_ptr MouseLookEventPtr; +} + +#endif diff --git a/apps/openmw/mwrender/actors.cpp b/apps/openmw/mwrender/actors.cpp index a73244305..415d17241 100644 --- a/apps/openmw/mwrender/actors.cpp +++ b/apps/openmw/mwrender/actors.cpp @@ -146,9 +146,10 @@ Actors::updateObjectCell(const MWWorld::Ptr &ptr) node = mCellSceneNodes[newCell]; } node->addChild(ptr.getRefData().getBaseNode()); - if (Animation *anim = mAllActors[ptr]) { + if (mAllActors.find(ptr) != mAllActors.end()) { /// \note Update key (Ptr's are compared only with refdata so mCell /// on key is outdated), maybe redundant + Animation *anim = mAllActors[ptr]; mAllActors.erase(ptr); mAllActors[ptr] = anim; } diff --git a/apps/openmw/mwrender/player.cpp b/apps/openmw/mwrender/player.cpp index 27ae28e14..8b27adbe3 100644 --- a/apps/openmw/mwrender/player.cpp +++ b/apps/openmw/mwrender/player.cpp @@ -1,34 +1,101 @@ - #include "player.hpp" #include +#include + +#include "../mwbase/environment.hpp" +#include "../mwbase/soundmanager.hpp" + +#include "../mwworld/ptr.hpp" +#include "../mwworld/refdata.hpp" namespace MWRender { Player::Player (Ogre::Camera *camera, Ogre::SceneNode* node) - : mCamera (camera), mNode (node) + : mCamera (camera), + mNode (node), + mFirstPersonView(true), + mVanityModeEnabled(false) {} - void Player::setRot(float x, float y, float z) + bool Player::setRotation(const Ogre::Vector3 &rot) { - Ogre::SceneNode *sceneNode = mNode; - Ogre::Node* yawNode = sceneNode->getChildIterator().getNext(); - Ogre::Node* pitchNode = yawNode->getChildIterator().getNext(); + Ogre::SceneNode *sceneNode = mNode; + Ogre::Node* yawNode = sceneNode->getChildIterator().getNext(); + Ogre::Node* pitchNode = yawNode->getChildIterator().getNext(); - // we are only interested in X and Y rotation + // we are only interested in X and Y rotation - // Rotate around X axis - Ogre::Quaternion xr(Ogre::Radian(x), Ogre::Vector3::UNIT_X); + // Rotate around X axis + Ogre::Quaternion xr(Ogre::Degree(rot.x), Ogre::Vector3::UNIT_X); - // Rotate around Y axis - Ogre::Quaternion yr(Ogre::Radian(-z), Ogre::Vector3::UNIT_Y); + // Rotate around Y axis + Ogre::Quaternion yr(Ogre::Degree(-rot.z), Ogre::Vector3::UNIT_Y); - pitchNode->setOrientation(xr); - yawNode->setOrientation(yr); + pitchNode->setOrientation(xr); + yawNode->setOrientation(yr); + + controlFlip(); + updateListener(); + + return !mVanityModeEnabled; } std::string Player::getHandle() const { return mNode->getName(); } + + void Player::attachTo(const MWWorld::Ptr &ptr) + { + ptr.getRefData().setBaseNode(mNode); + } + + bool Player::adjustRotation(const Ogre::Vector3 &rot) + { + Ogre::SceneNode *pitchNode = mCamera->getParentSceneNode(); + Ogre::SceneNode *yawNode = pitchNode->getParentSceneNode(); + + pitchNode->pitch(Ogre::Degree(rot.x)); + yawNode->yaw(Ogre::Degree(-rot.z)); + + controlFlip(); + updateListener(); + + return !mVanityModeEnabled; + } + + void Player::controlFlip() + { + Ogre::SceneNode *pitchNode = mCamera->getParentSceneNode(); + Ogre::Quaternion orient = pitchNode->getOrientation(); + + float pitchAngle = + (2 * Ogre::Degree(Ogre::Math::ACos(orient.w)).valueDegrees()); + + // Limit the pitch between -90 degress and +90 degrees, Quake3-style. + if (pitchAngle > 90.0f) + { + Ogre::Real sqrt = Ogre::Math::Sqrt(0.5f); + if (orient.x > 0) { + // Set orientation to 90 degrees on X-axis. + pitchNode->setOrientation(Ogre::Quaternion(sqrt, sqrt, 0, 0)); + } else if (orient.x < 0) { + // Sets orientation to -90 degrees on X-axis. + pitchNode->setOrientation(Ogre::Quaternion(sqrt, -sqrt, 0, 0)); + } + } + } + + void Player::updateListener() + { + Ogre::Vector3 pos = mCamera->getRealPosition(); + Ogre::Vector3 dir = mCamera->getRealDirection(); + + Ogre::Real xch; + xch = pos.y, pos.y = -pos.z, pos.z = xch; + xch = dir.y, dir.y = -dir.z, dir.z = xch; + + MWBase::Environment::get().getSoundManager()->setListenerPosDir(pos, dir); + } } diff --git a/apps/openmw/mwrender/player.hpp b/apps/openmw/mwrender/player.hpp index 0ba936f6f..b1160435d 100644 --- a/apps/openmw/mwrender/player.hpp +++ b/apps/openmw/mwrender/player.hpp @@ -3,12 +3,19 @@ #include + namespace Ogre -{ +{ + class Vector3; class Camera; class SceneNode; } +namespace MWWorld +{ + class Ptr; +} + namespace MWRender { /// \brief Player character rendering and camera control @@ -17,17 +24,31 @@ namespace MWRender Ogre::Camera *mCamera; Ogre::SceneNode* mNode; - public: + bool mFirstPersonView; + bool mVanityModeEnabled; - Player (Ogre::Camera *camera, Ogre::SceneNode* mNode); + void controlFlip(); + void updateListener(); - Ogre::Camera *getCamera() { return mCamera; } + public: - /// Set where the player is looking at. Uses Morrowind (euler) angles - void setRot(float x, float y, float z); + Player (Ogre::Camera *camera, Ogre::SceneNode* mNode); - std::string getHandle() const; - Ogre::SceneNode* getNode() {return mNode;} + /// Set where the player is looking at. Uses Morrowind (euler) angles + bool setRotation(const Ogre::Vector3 &rot); + bool adjustRotation(const Ogre::Vector3 &rot); + + std::string getHandle() const; + + void attachTo(const MWWorld::Ptr &); + + void toggleViewMode() { + mFirstPersonView = !mFirstPersonView; + } + + void toggleVanityMode() { + mVanityModeEnabled = !mVanityModeEnabled; + } }; } diff --git a/apps/openmw/mwrender/renderinginterface.hpp b/apps/openmw/mwrender/renderinginterface.hpp index 03935bef6..8ae2c0f8f 100644 --- a/apps/openmw/mwrender/renderinginterface.hpp +++ b/apps/openmw/mwrender/renderinginterface.hpp @@ -1,16 +1,17 @@ #ifndef _GAME_RENDERING_INTERFACE_H #define _GAME_RENDERING_INTERFACE_H -namespace MWRender{ - class Objects; - class Actors; - class Player; + +namespace MWRender +{ + class Objects; + class Actors; -class RenderingInterface{ + class RenderingInterface + { public: virtual MWRender::Objects& getObjects() = 0; - virtual MWRender::Player& getPlayer() = 0; virtual MWRender::Actors& getActors() = 0; virtual ~RenderingInterface(){}; }; } -#endif \ No newline at end of file +#endif diff --git a/apps/openmw/mwrender/renderingmanager.cpp b/apps/openmw/mwrender/renderingmanager.cpp index cec5569c8..8719557ca 100644 --- a/apps/openmw/mwrender/renderingmanager.cpp +++ b/apps/openmw/mwrender/renderingmanager.cpp @@ -43,12 +43,14 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const :mRendering(_rend), mObjects(mRendering), mActors(mRendering), mAmbientMode(0), mSunEnabled(0) { // select best shader mode - if (Settings::Manager::getString("shader mode", "General") == "") + bool openGL = (Ogre::Root::getSingleton ().getRenderSystem ()->getName().find("OpenGL") != std::string::npos); + + // glsl is only supported in opengl mode and hlsl only in direct3d mode. + if (Settings::Manager::getString("shader mode", "General") == "" + || (openGL && Settings::Manager::getString("shader mode", "General") == "hlsl") + || (!openGL && Settings::Manager::getString("shader mode", "General") == "glsl")) { - if (Ogre::Root::getSingleton ().getRenderSystem ()->getName().find("OpenGL") == std::string::npos) - Settings::Manager::setString("shader mode", "General", "cg"); - else - Settings::Manager::setString("shader mode", "General", "glsl"); + Settings::Manager::setString("shader mode", "General", openGL ? "glsl" : "hlsl"); } mRendering.createScene("PlayerCam", Settings::Manager::getFloat("field of view", "General"), 5); @@ -74,10 +76,6 @@ RenderingManager::RenderingManager (OEngine::Render::OgreRenderer& _rend, const mFactory->setCurrentLanguage (lang); mFactory->loadAllFiles(); - //The fog type must be set before any terrain objects are created as if the - //fog type is set to FOG_NONE then the initially created terrain won't have any fog - configureFog(1, ColourValue(1,1,1)); - // Set default mipmap level (NB some APIs ignore this) TextureManager::getSingleton().setDefaultNumMipmaps(Settings::Manager::getInt("num mipmaps", "General")); @@ -185,10 +183,6 @@ MWRender::Actors& RenderingManager::getActors(){ return mActors; } -MWRender::Player& RenderingManager::getPlayer(){ - return (*mPlayer); -} - OEngine::Render::Fader* RenderingManager::getFader() { return mRendering.getFader(); @@ -253,8 +247,34 @@ void RenderingManager::moveObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& void RenderingManager::scaleObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& scale){ } -void RenderingManager::rotateObject (const MWWorld::Ptr& ptr, const::Ogre::Quaternion& orientation){ +bool +RenderingManager::rotateObject( + const MWWorld::Ptr &ptr, + Ogre::Vector3 &rot, + bool adjust) +{ + if (ptr.getRefData().getHandle() == "player") { + if (adjust) { + return mPlayer->adjustRotation(rot); + } else { + return mPlayer->setRotation(rot); + } + } + MWWorld::Class::get(ptr).adjustRotation(ptr, rot.x, rot.y, rot.z); + + if (adjust) { + float *f = ptr.getRefData().getPosition().rot; + rot.x += f[0], rot.y += f[1], rot.z += f[2]; + } + + Ogre::Quaternion xr(Ogre::Degree(rot.x), Ogre::Vector3::UNIT_X); + Ogre::Quaternion yr(Ogre::Degree(rot.y), Ogre::Vector3::UNIT_Y); + Ogre::Quaternion zr(Ogre::Degree(rot.z), Ogre::Vector3::UNIT_Z); + + ptr.getRefData().getBaseNode()->setOrientation(xr * yr * zr); + + return true; } void @@ -292,11 +312,20 @@ void RenderingManager::update (float duration){ mLocalMap->updatePlayer( mRendering.getCamera()->getRealPosition(), mRendering.getCamera()->getRealOrientation() ); - checkUnderwater(); + if (mWater) { + Ogre::Vector3 cam = mRendering.getCamera()->getRealPosition(); - if (mWater) + MWBase::World *world = MWBase::Environment::get().getWorld(); + + mWater->updateUnderwater( + world->isUnderwater( + *world->getPlayer().getPlayer().getCell()->cell, + Ogre::Vector3(cam.x, -cam.z, cam.y)) + ); mWater->update(duration); + } } + void RenderingManager::waterAdded (MWWorld::Ptr::CellStore *store){ if(store->cell->data.flags & store->cell->HasWater || ((!(store->cell->data.flags & ESM::Cell::Interior)) @@ -476,13 +505,6 @@ void RenderingManager::toggleLight() setAmbientMode(); } -void RenderingManager::checkUnderwater() -{ - if(mWater) - { - mWater->checkUnderwater( mRendering.getCamera()->getRealPosition().y ); - } -} void RenderingManager::playAnimationGroup (const MWWorld::Ptr& ptr, const std::string& groupName, int mode, int number) @@ -787,4 +809,9 @@ void RenderingManager::getTriangleBatchCount(unsigned int &triangles, unsigned i } } +void RenderingManager::attachCameraTo(const MWWorld::Ptr &ptr) +{ + mPlayer->attachTo(ptr); +} + } // namespace diff --git a/apps/openmw/mwrender/renderingmanager.hpp b/apps/openmw/mwrender/renderingmanager.hpp index e618908c1..197c1fda0 100644 --- a/apps/openmw/mwrender/renderingmanager.hpp +++ b/apps/openmw/mwrender/renderingmanager.hpp @@ -56,11 +56,7 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList RenderingManager(OEngine::Render::OgreRenderer& _rend, const boost::filesystem::path& resDir, OEngine::Physic::PhysicEngine* engine); virtual ~RenderingManager(); - - - virtual MWRender::Player& getPlayer(); /// \todo move this to private again as soon as - /// MWWorld::Player has been rewritten to not need access - /// to internal details of the rendering system anymore + void attachCameraTo(const MWWorld::Ptr &ptr); SkyManager* getSkyManager(); Compositors* getCompositors(); @@ -89,9 +85,8 @@ class RenderingManager: private RenderingInterface, public Ogre::WindowEventList void moveObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& position); void scaleObject (const MWWorld::Ptr& ptr, const Ogre::Vector3& scale); - void rotateObject (const MWWorld::Ptr& ptr, const::Ogre::Quaternion& orientation); + bool rotateObject (const MWWorld::Ptr& ptr, Ogre::Vector3 &rot, bool adjust = false); - void checkUnderwater(); void setWaterHeight(const float height); void toggleWater(); diff --git a/apps/openmw/mwrender/terrainmaterial.cpp b/apps/openmw/mwrender/terrainmaterial.cpp index 1a2d96a14..5ef9fe58f 100644 --- a/apps/openmw/mwrender/terrainmaterial.cpp +++ b/apps/openmw/mwrender/terrainmaterial.cpp @@ -2,6 +2,8 @@ #include +#include + #include namespace @@ -86,15 +88,15 @@ namespace MWRender normalMap->setProperty ("direct_texture", sh::makeProperty (new sh::StringValue(terrain->getTerrainNormalMap ()->getName()))); normalMap->setProperty ("tex_address_mode", sh::makeProperty (new sh::StringValue("clamp"))); - uint maxLayers = getMaxLayers(terrain); - uint numBlendTextures = std::min(terrain->getBlendTextureCount(maxLayers), terrain->getBlendTextureCount()); - uint numLayers = std::min(maxLayers, static_cast(terrain->getLayerCount())); + Ogre::uint maxLayers = getMaxLayers(terrain); + Ogre::uint numBlendTextures = std::min(terrain->getBlendTextureCount(maxLayers), terrain->getBlendTextureCount()); + Ogre::uint numLayers = std::min(maxLayers, static_cast(terrain->getLayerCount())); p->mShaderProperties.setProperty ("num_layers", sh::makeProperty(new sh::StringValue(Ogre::StringConverter::toString(numLayers)))); p->mShaderProperties.setProperty ("num_blendmaps", sh::makeProperty(new sh::StringValue(Ogre::StringConverter::toString(numBlendTextures)))); // blend maps - for (uint i = 0; i < numBlendTextures; ++i) + for (Ogre::uint i = 0; i < numBlendTextures; ++i) { sh::MaterialInstanceTextureUnit* blendTex = p->createTextureUnit ("blendMap" + Ogre::StringConverter::toString(i)); blendTex->setProperty ("direct_texture", sh::makeProperty (new sh::StringValue(terrain->getBlendTextureName(i)))); @@ -102,7 +104,7 @@ namespace MWRender } // layer maps - for (uint i = 0; i < numLayers; ++i) + for (Ogre::uint i = 0; i < numLayers; ++i) { sh::MaterialInstanceTextureUnit* diffuseTex = p->createTextureUnit ("diffuseMap" + Ogre::StringConverter::toString(i)); diffuseTex->setProperty ("direct_texture", sh::makeProperty (new sh::StringValue(terrain->getLayerTextureName(i, 0)))); @@ -111,7 +113,7 @@ namespace MWRender } // shadow - for (uint i = 0; i < 3; ++i) + for (Ogre::uint i = 0; i < 3; ++i) { sh::MaterialInstanceTextureUnit* shadowTex = p->createTextureUnit ("shadowMap" + Ogre::StringConverter::toString(i)); shadowTex->setProperty ("content_type", sh::makeProperty (new sh::StringValue("shadow"))); diff --git a/apps/openmw/mwrender/water.cpp b/apps/openmw/mwrender/water.cpp index 92fc97b3b..d5b93b7cb 100644 --- a/apps/openmw/mwrender/water.cpp +++ b/apps/openmw/mwrender/water.cpp @@ -184,22 +184,16 @@ void Water::toggle() updateVisible(); } -void Water::checkUnderwater(float y) +void +Water::updateUnderwater(bool underwater) { - if (!mActive) - { + if (!mActive) { return; } - - if ((mIsUnderwater && y > mTop) || !mWater->isVisible() || mCamera->getPolygonMode() != Ogre::PM_SOLID) - { - mIsUnderwater = false; - } - - if (!mIsUnderwater && y < mTop && mWater->isVisible() && mCamera->getPolygonMode() == Ogre::PM_SOLID) - { - mIsUnderwater = true; - } + mIsUnderwater = + underwater && + mWater->isVisible() && + mCamera->getPolygonMode() == Ogre::PM_SOLID; updateVisible(); } diff --git a/apps/openmw/mwrender/water.hpp b/apps/openmw/mwrender/water.hpp index d0a5a4352..f56ba7410 100644 --- a/apps/openmw/mwrender/water.hpp +++ b/apps/openmw/mwrender/water.hpp @@ -101,7 +101,8 @@ namespace MWRender { void processChangedSettings(const Settings::CategorySettingVector& settings); - void checkUnderwater(float y); + /// Updates underwater state accordingly + void updateUnderwater(bool underwater); void changeCell(const ESM::Cell* cell); void setHeight(const float height); diff --git a/apps/openmw/mwscript/compilercontext.cpp b/apps/openmw/mwscript/compilercontext.cpp index 57e786b11..139a5cc6c 100644 --- a/apps/openmw/mwscript/compilercontext.cpp +++ b/apps/openmw/mwscript/compilercontext.cpp @@ -3,14 +3,15 @@ #include +#include + #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/scriptmanager.hpp" #include "../mwworld/ptr.hpp" #include "../mwworld/class.hpp" -#include "scriptmanager.hpp" - namespace MWScript { CompilerContext::CompilerContext (Type type) diff --git a/apps/openmw/mwscript/controlextensions.cpp b/apps/openmw/mwscript/controlextensions.cpp index 24d8bcf1e..084698c5b 100644 --- a/apps/openmw/mwscript/controlextensions.cpp +++ b/apps/openmw/mwscript/controlextensions.cpp @@ -14,6 +14,8 @@ #include "../mwmechanics/npcstats.hpp" +#include "../mwinput/inputmanager.hpp" + #include "interpretercontext.hpp" #include "ref.hpp" @@ -36,6 +38,10 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime) { + MWBase::Environment::get() + .getInputManager() + ->toggleControlSwitch(mControl, mEnable); + if (mEnable) std::cout << "enable: " << mControl << std::endl; else diff --git a/apps/openmw/mwscript/dialogueextensions.cpp b/apps/openmw/mwscript/dialogueextensions.cpp index ec8ab59b4..21c21acf0 100644 --- a/apps/openmw/mwscript/dialogueextensions.cpp +++ b/apps/openmw/mwscript/dialogueextensions.cpp @@ -7,8 +7,9 @@ #include #include -#include "../mwdialogue/journal.hpp" -#include "../mwdialogue/dialoguemanager.hpp" +#include "../mwbase/environment.hpp" +#include "../mwbase/dialoguemanager.hpp" +#include "../mwbase/journal.hpp" #include "interpretercontext.hpp" #include "ref.hpp" @@ -84,7 +85,7 @@ namespace MWScript virtual void execute (Interpreter::Runtime& runtime, unsigned int arg0) { - MWDialogue::DialogueManager* dialogue = MWBase::Environment::get().getDialogueManager(); + MWBase::DialogueManager* dialogue = MWBase::Environment::get().getDialogueManager(); while(arg0>0) { std::string question = runtime.getStringLiteral (runtime[0].mInteger); diff --git a/apps/openmw/mwscript/docs/vmformat.txt b/apps/openmw/mwscript/docs/vmformat.txt index 3ca93d4b2..1ea5f8e3e 100644 --- a/apps/openmw/mwscript/docs/vmformat.txt +++ b/apps/openmw/mwscript/docs/vmformat.txt @@ -179,4 +179,6 @@ op 0x200016e: user3, explicit reference (console only, requires --script-console op 0x200016f: user3 (implicit reference, console only, requires --script-console switch) op 0x2000170: user4, explicit reference (console only, requires --script-console switch) op 0x2000171: user4 (implicit reference, console only, requires --script-console switch) -opcodes 0x2000172-0x3ffffff unused +op 0x2000172: GetStartingAngle +op 0x2000173: GetStartingAngle, explicit reference +opcodes 0x2000174-0x3ffffff unused diff --git a/apps/openmw/mwscript/globalscripts.cpp b/apps/openmw/mwscript/globalscripts.cpp index 3f4cec723..6407bf0cb 100644 --- a/apps/openmw/mwscript/globalscripts.cpp +++ b/apps/openmw/mwscript/globalscripts.cpp @@ -6,13 +6,15 @@ #include #include +#include "../mwbase/environment.hpp" +#include "../mwbase/scriptmanager.hpp" + #include "interpretercontext.hpp" -#include "scriptmanager.hpp" namespace MWScript { - GlobalScripts::GlobalScripts (const ESMS::ESMStore& store, ScriptManager& scriptManager) - : mStore (store), mScriptManager (scriptManager) + GlobalScripts::GlobalScripts (const ESMS::ESMStore& store) + : mStore (store) { addScript ("Main"); @@ -63,9 +65,8 @@ namespace MWScript { MWScript::InterpreterContext interpreterContext ( &iter->second.second, MWWorld::Ptr()); - mScriptManager.run (iter->first, interpreterContext); + MWBase::Environment::get().getScriptManager()->run (iter->first, interpreterContext); } } - } } diff --git a/apps/openmw/mwscript/globalscripts.hpp b/apps/openmw/mwscript/globalscripts.hpp index 3d62e4d7a..cc2f7ffdd 100644 --- a/apps/openmw/mwscript/globalscripts.hpp +++ b/apps/openmw/mwscript/globalscripts.hpp @@ -13,17 +13,14 @@ namespace ESMS namespace MWScript { - class ScriptManager; - class GlobalScripts { const ESMS::ESMStore& mStore; - ScriptManager& mScriptManager; std::map > mScripts; // running, local variables public: - GlobalScripts (const ESMS::ESMStore& store, ScriptManager& scriptManager); + GlobalScripts (const ESMS::ESMStore& store); void addScript (const std::string& name); diff --git a/apps/openmw/mwscript/interpretercontext.cpp b/apps/openmw/mwscript/interpretercontext.cpp index 3a824473e..327eed913 100644 --- a/apps/openmw/mwscript/interpretercontext.cpp +++ b/apps/openmw/mwscript/interpretercontext.cpp @@ -8,6 +8,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/scriptmanager.hpp" #include "../mwworld/class.hpp" #include "../mwworld/player.hpp" @@ -18,7 +19,6 @@ #include "locals.hpp" #include "globalscripts.hpp" -#include "scriptmanager.hpp" namespace MWScript { diff --git a/apps/openmw/mwscript/scriptmanager.cpp b/apps/openmw/mwscript/scriptmanagerimp.cpp similarity index 98% rename from apps/openmw/mwscript/scriptmanager.cpp rename to apps/openmw/mwscript/scriptmanagerimp.cpp index d8bd269c6..0b33d43fa 100644 --- a/apps/openmw/mwscript/scriptmanager.cpp +++ b/apps/openmw/mwscript/scriptmanagerimp.cpp @@ -1,5 +1,5 @@ -#include "scriptmanager.hpp" +#include "scriptmanagerimp.hpp" #include #include @@ -21,7 +21,7 @@ namespace MWScript Compiler::Context& compilerContext) : mErrorHandler (std::cerr), mStore (store), mVerbose (verbose), mCompilerContext (compilerContext), mParser (mErrorHandler, mCompilerContext), - mOpcodesInstalled (false), mGlobalScripts (store, *this) + mOpcodesInstalled (false), mGlobalScripts (store) {} bool ScriptManager::compile (const std::string& name) diff --git a/apps/openmw/mwscript/scriptmanager.hpp b/apps/openmw/mwscript/scriptmanagerimp.hpp similarity index 75% rename from apps/openmw/mwscript/scriptmanager.hpp rename to apps/openmw/mwscript/scriptmanagerimp.hpp index a466f903d..bacc232b2 100644 --- a/apps/openmw/mwscript/scriptmanager.hpp +++ b/apps/openmw/mwscript/scriptmanagerimp.hpp @@ -10,6 +10,8 @@ #include #include +#include "../mwbase/scriptmanager.hpp" + #include "globalscripts.hpp" namespace ESMS @@ -30,7 +32,7 @@ namespace Interpreter namespace MWScript { - class ScriptManager + class ScriptManager : public MWBase::ScriptManager { Compiler::StreamErrorHandler mErrorHandler; const ESMS::ESMStore& mStore; @@ -51,23 +53,24 @@ namespace MWScript ScriptManager (const ESMS::ESMStore& store, bool verbose, Compiler::Context& compilerContext); - void run (const std::string& name, Interpreter::Context& interpreterContext); + virtual void run (const std::string& name, Interpreter::Context& interpreterContext); ///< Run the script with the given name (compile first, if not compiled yet) - bool compile (const std::string& name); + virtual bool compile (const std::string& name); ///< Compile script with the given namen /// \return Success? - std::pair compileAll(); + virtual std::pair compileAll(); ///< Compile all scripts /// \return count, success - Compiler::Locals& getLocals (const std::string& name); + virtual Compiler::Locals& getLocals (const std::string& name); ///< Return locals for script \a name. - GlobalScripts& getGlobalScripts(); + virtual GlobalScripts& getGlobalScripts(); - int getLocalIndex (const std::string& scriptId, const std::string& variable, char type); + virtual int getLocalIndex (const std::string& scriptId, const std::string& variable, + char type); ///< Return index of the variable of the given name and type in the given script. Will /// throw an exception, if there is no such script or variable or the type does not match. }; diff --git a/apps/openmw/mwscript/soundextensions.cpp b/apps/openmw/mwscript/soundextensions.cpp index 3e05d72d3..6dc8f3919 100644 --- a/apps/openmw/mwscript/soundextensions.cpp +++ b/apps/openmw/mwscript/soundextensions.cpp @@ -9,8 +9,7 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" - -#include "../mwsound/soundmanager.hpp" +#include "../mwbase/soundmanager.hpp" #include "interpretercontext.hpp" #include "ref.hpp" @@ -116,7 +115,7 @@ namespace MWScript std::string sound = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - MWBase::Environment::get().getSoundManager()->playSound3D (ptr, sound, 1.0, 1.0, mLoop ? MWSound::Play_Loop : 0); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, sound, 1.0, 1.0, mLoop ? MWBase::SoundManager::Play_Loop : 0); } }; @@ -142,7 +141,7 @@ namespace MWScript Interpreter::Type_Float pitch = runtime[0].mFloat; runtime.pop(); - MWBase::Environment::get().getSoundManager()->playSound3D (ptr, sound, volume, pitch, mLoop ? MWSound::Play_Loop : 0); + MWBase::Environment::get().getSoundManager()->playSound3D (ptr, sound, volume, pitch, mLoop ? MWBase::SoundManager::Play_Loop : 0); } }; diff --git a/apps/openmw/mwscript/statsextensions.cpp b/apps/openmw/mwscript/statsextensions.cpp index 0cbbe8398..5113c9dbf 100644 --- a/apps/openmw/mwscript/statsextensions.cpp +++ b/apps/openmw/mwscript/statsextensions.cpp @@ -16,6 +16,7 @@ #include #include "../mwbase/environment.hpp" +#include "../mwbase/dialoguemanager.hpp" #include "../mwworld/class.hpp" #include "../mwworld/player.hpp" @@ -26,7 +27,6 @@ #include "interpretercontext.hpp" #include "ref.hpp" -#include "../mwdialogue/dialoguemanager.hpp" namespace MWScript { diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index f47a1829a..50897278f 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -66,18 +66,49 @@ namespace MWScript float ay = Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees(); float az = Ogre::Radian(ptr.getRefData().getPosition().rot[2]).valueDegrees(); - if(axis == "x") + if (axis == "x") { MWBase::Environment::get().getWorld()->rotateObject(ptr,angle,ay,az); } - if(axis == "y") + else if (axis == "y") { MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,angle,az); } - if(axis == "z") + else if (axis == "z") { MWBase::Environment::get().getWorld()->rotateObject(ptr,ax,ay,angle); } + else + throw std::runtime_error ("invalid ration axis: " + axis); + } + }; + + template + class OpGetStartingAngle : public Interpreter::Opcode0 + { + public: + + virtual void execute (Interpreter::Runtime& runtime) + { + MWWorld::Ptr ptr = R()(runtime); + + std::string axis = runtime.getStringLiteral (runtime[0].mInteger); + runtime.pop(); + + if (axis == "x") + { + runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees()); + } + else if (axis == "y") + { + runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees()); + } + else if (axis == "z") + { + runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[2]).valueDegrees()); + } + else + throw std::runtime_error ("invalid ration axis: " + axis); } }; @@ -93,18 +124,20 @@ namespace MWScript std::string axis = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); - if(axis == "x") + if (axis=="x") { - runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[0]).valueDegrees()); + runtime.push(Ogre::Radian(ptr.getCellRef().pos.rot[0]).valueDegrees()); } - if(axis == "y") + else if (axis=="y") { - runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[1]).valueDegrees()); + runtime.push(Ogre::Radian(ptr.getCellRef().pos.rot[1]).valueDegrees()); } - if(axis == "z") + else if (axis=="z") { - runtime.push(Ogre::Radian(ptr.getRefData().getPosition().rot[2]).valueDegrees()); + runtime.push(Ogre::Radian(ptr.getCellRef().pos.rot[2]).valueDegrees()); } + else + throw std::runtime_error ("invalid ration axis: " + axis); } }; @@ -124,11 +157,11 @@ namespace MWScript { runtime.push(ptr.getRefData().getPosition().pos[0]); } - if(axis == "y") + else if(axis == "y") { runtime.push(ptr.getRefData().getPosition().pos[1]); } - if(axis == "z") + else if(axis == "z") { runtime.push(ptr.getRefData().getPosition().pos[2]); } @@ -158,11 +191,11 @@ namespace MWScript { MWBase::Environment::get().getWorld()->moveObject(ptr,pos,ay,az); } - if(axis == "y") + else if(axis == "y") { MWBase::Environment::get().getWorld()->moveObject(ptr,ax,pos,az); } - if(axis == "z") + else if(axis == "z") { MWBase::Environment::get().getWorld()->moveObject(ptr,ax,ay,pos); } @@ -185,11 +218,11 @@ namespace MWScript { runtime.push(ptr.getCellRef().pos.pos[0]); } - if(axis == "y") + else if(axis == "y") { runtime.push(ptr.getCellRef().pos.pos[1]); } - if(axis == "z") + else if(axis == "z") { runtime.push(ptr.getCellRef().pos.pos[2]); } diff --git a/apps/openmw/mwsound/openal_output.cpp b/apps/openmw/mwsound/openal_output.cpp index ac4baa8b2..e5169d878 100644 --- a/apps/openmw/mwsound/openal_output.cpp +++ b/apps/openmw/mwsound/openal_output.cpp @@ -8,7 +8,7 @@ #include "openal_output.hpp" #include "sound_decoder.hpp" #include "sound.hpp" -#include "soundmanager.hpp" +#include "soundmanagerimp.hpp" #ifndef ALC_ALL_DEVICES_SPECIFIER #define ALC_ALL_DEVICES_SPECIFIER 0x1013 @@ -263,7 +263,7 @@ void OpenAL_SoundStream::update() { ALfloat gain = mVolume*mBaseVolume; ALfloat pitch = mPitch; - if(!(mFlags&Play_NoEnv) && mOutput.mLastEnvironment == Env_Underwater) + if(!(mFlags&MWBase::SoundManager::Play_NoEnv) && mOutput.mLastEnvironment == Env_Underwater) { gain *= 0.9f; pitch *= 0.7f; @@ -400,7 +400,7 @@ void OpenAL_Sound::update() { ALfloat gain = mVolume*mBaseVolume; ALfloat pitch = mPitch; - if(!(mFlags&Play_NoEnv) && mOutput.mLastEnvironment == Env_Underwater) + if(!(mFlags&MWBase::SoundManager::Play_NoEnv) && mOutput.mLastEnvironment == Env_Underwater) { gain *= 0.9f; pitch *= 0.7f; @@ -420,7 +420,7 @@ void OpenAL_Sound3D::update() ALfloat pitch = mPitch; if(mPos.squaredDistance(mOutput.mPos) > mMaxDistance*mMaxDistance) gain = 0.0f; - else if(!(mFlags&Play_NoEnv) && mOutput.mLastEnvironment == Env_Underwater) + else if(!(mFlags&MWBase::SoundManager::Play_NoEnv) && mOutput.mLastEnvironment == Env_Underwater) { gain *= 0.9f; pitch *= 0.7f; @@ -642,7 +642,7 @@ void OpenAL_Output::bufferFinished(ALuint buf) } -SoundPtr OpenAL_Output::playSound(const std::string &fname, float volume, float pitch, int flags) +MWBase::SoundPtr OpenAL_Output::playSound(const std::string &fname, float volume, float pitch, int flags) { boost::shared_ptr sound; ALuint src=0, buf=0; @@ -674,7 +674,7 @@ SoundPtr OpenAL_Output::playSound(const std::string &fname, float volume, float alSourcef(src, AL_MAX_DISTANCE, 1000.0f); alSourcef(src, AL_ROLLOFF_FACTOR, 0.0f); - if(!(flags&Play_NoEnv) && mLastEnvironment == Env_Underwater) + if(!(flags&MWBase::SoundManager::Play_NoEnv) && mLastEnvironment == Env_Underwater) { volume *= 0.9f; pitch *= 0.7f; @@ -683,7 +683,7 @@ SoundPtr OpenAL_Output::playSound(const std::string &fname, float volume, float alSourcef(src, AL_PITCH, pitch); alSourcei(src, AL_SOURCE_RELATIVE, AL_TRUE); - alSourcei(src, AL_LOOPING, (flags&Play_Loop) ? AL_TRUE : AL_FALSE); + alSourcei(src, AL_LOOPING, (flags&MWBase::SoundManager::Play_Loop) ? AL_TRUE : AL_FALSE); throwALerror(); alSourcei(src, AL_BUFFER, buf); @@ -693,7 +693,7 @@ SoundPtr OpenAL_Output::playSound(const std::string &fname, float volume, float return sound; } -SoundPtr OpenAL_Output::playSound3D(const std::string &fname, const Ogre::Vector3 &pos, float volume, float pitch, +MWBase::SoundPtr OpenAL_Output::playSound3D(const std::string &fname, const Ogre::Vector3 &pos, float volume, float pitch, float min, float max, int flags) { boost::shared_ptr sound; @@ -726,7 +726,7 @@ SoundPtr OpenAL_Output::playSound3D(const std::string &fname, const Ogre::Vector alSourcef(src, AL_MAX_DISTANCE, max); alSourcef(src, AL_ROLLOFF_FACTOR, 1.0f); - if(!(flags&Play_NoEnv) && mLastEnvironment == Env_Underwater) + if(!(flags&MWBase::SoundManager::Play_NoEnv) && mLastEnvironment == Env_Underwater) { volume *= 0.9f; pitch *= 0.7f; @@ -736,7 +736,7 @@ SoundPtr OpenAL_Output::playSound3D(const std::string &fname, const Ogre::Vector alSourcef(src, AL_PITCH, pitch); alSourcei(src, AL_SOURCE_RELATIVE, AL_FALSE); - alSourcei(src, AL_LOOPING, (flags&Play_Loop) ? AL_TRUE : AL_FALSE); + alSourcei(src, AL_LOOPING, (flags&MWBase::SoundManager::Play_Loop) ? AL_TRUE : AL_FALSE); throwALerror(); alSourcei(src, AL_BUFFER, buf); @@ -747,7 +747,7 @@ SoundPtr OpenAL_Output::playSound3D(const std::string &fname, const Ogre::Vector } -SoundPtr OpenAL_Output::streamSound(const std::string &fname, float volume, float pitch, int flags) +MWBase::SoundPtr OpenAL_Output::streamSound(const std::string &fname, float volume, float pitch, int flags) { boost::shared_ptr sound; ALuint src; @@ -759,7 +759,7 @@ SoundPtr OpenAL_Output::streamSound(const std::string &fname, float volume, floa try { - if((flags&Play_Loop)) + if((flags&MWBase::SoundManager::Play_Loop)) std::cout <<"Warning: cannot loop stream "<open(fname); @@ -779,7 +779,7 @@ SoundPtr OpenAL_Output::streamSound(const std::string &fname, float volume, floa alSourcef(src, AL_MAX_DISTANCE, 1000.0f); alSourcef(src, AL_ROLLOFF_FACTOR, 0.0f); - if(!(flags&Play_NoEnv) && mLastEnvironment == Env_Underwater) + if(!(flags&MWBase::SoundManager::Play_NoEnv) && mLastEnvironment == Env_Underwater) { volume *= 0.9f; pitch *= 0.7f; diff --git a/apps/openmw/mwsound/openal_output.hpp b/apps/openmw/mwsound/openal_output.hpp index d62d20286..90917c53c 100644 --- a/apps/openmw/mwsound/openal_output.hpp +++ b/apps/openmw/mwsound/openal_output.hpp @@ -42,10 +42,10 @@ namespace MWSound virtual void init(const std::string &devname=""); virtual void deinit(); - virtual SoundPtr playSound(const std::string &fname, float volume, float pitch, int flags); - virtual SoundPtr playSound3D(const std::string &fname, const Ogre::Vector3 &pos, + virtual MWBase::SoundPtr playSound(const std::string &fname, float volume, float pitch, int flags); + virtual MWBase::SoundPtr playSound3D(const std::string &fname, const Ogre::Vector3 &pos, float volume, float pitch, float min, float max, int flags); - virtual SoundPtr streamSound(const std::string &fname, float volume, float pitch, int flags); + virtual MWBase::SoundPtr streamSound(const std::string &fname, float volume, float pitch, int flags); virtual void updateListener(const Ogre::Vector3 &pos, const Ogre::Vector3 &atdir, const Ogre::Vector3 &updir, Environment env); diff --git a/apps/openmw/mwsound/sound.hpp b/apps/openmw/mwsound/sound.hpp index 0cba6abca..729147f75 100644 --- a/apps/openmw/mwsound/sound.hpp +++ b/apps/openmw/mwsound/sound.hpp @@ -3,7 +3,7 @@ #include -#include "soundmanager.hpp" +#include "soundmanagerimp.hpp" namespace MWSound { @@ -35,7 +35,7 @@ namespace MWSound , mPitch(1.0f) , mMinDistance(20.0f) /* 1 * min_range_scale */ , mMaxDistance(12750.0f) /* 255 * max_range_scale */ - , mFlags(Play_Normal) + , mFlags(MWBase::SoundManager::Play_Normal) { } virtual ~Sound() { } diff --git a/apps/openmw/mwsound/sound_output.hpp b/apps/openmw/mwsound/sound_output.hpp index 100b2208c..2680ec1db 100644 --- a/apps/openmw/mwsound/sound_output.hpp +++ b/apps/openmw/mwsound/sound_output.hpp @@ -6,7 +6,7 @@ #include -#include "soundmanager.hpp" +#include "soundmanagerimp.hpp" #include "../mwworld/ptr.hpp" @@ -24,10 +24,10 @@ namespace MWSound virtual void init(const std::string &devname="") = 0; virtual void deinit() = 0; - virtual SoundPtr playSound(const std::string &fname, float volume, float pitch, int flags) = 0; - virtual SoundPtr playSound3D(const std::string &fname, const Ogre::Vector3 &pos, + virtual MWBase::SoundPtr playSound(const std::string &fname, float volume, float pitch, int flags) = 0; + virtual MWBase::SoundPtr playSound3D(const std::string &fname, const Ogre::Vector3 &pos, float volume, float pitch, float min, float max, int flags) = 0; - virtual SoundPtr streamSound(const std::string &fname, float volume, float pitch, int flags) = 0; + virtual MWBase::SoundPtr streamSound(const std::string &fname, float volume, float pitch, int flags) = 0; virtual void updateListener(const Ogre::Vector3 &pos, const Ogre::Vector3 &atdir, const Ogre::Vector3 &updir, Environment env) = 0; diff --git a/apps/openmw/mwsound/soundmanager.cpp b/apps/openmw/mwsound/soundmanagerimp.cpp similarity index 92% rename from apps/openmw/mwsound/soundmanager.cpp rename to apps/openmw/mwsound/soundmanagerimp.cpp index c6332d9f3..e1720453b 100644 --- a/apps/openmw/mwsound/soundmanager.cpp +++ b/apps/openmw/mwsound/soundmanagerimp.cpp @@ -1,11 +1,9 @@ -#include "soundmanager.hpp" +#include "soundmanagerimp.hpp" #include #include #include -#include - #include #include "../mwbase/environment.hpp" @@ -13,8 +11,6 @@ #include "../mwworld/player.hpp" -#include "../mwrender/player.hpp" - #include "sound_output.hpp" #include "sound_decoder.hpp" #include "sound.hpp" @@ -222,7 +218,7 @@ namespace MWSound const ESM::Position &pos = ptr.getCellRef().pos; const Ogre::Vector3 objpos(pos.pos[0], pos.pos[1], pos.pos[2]); - SoundPtr sound = mOutput->playSound3D(filePath, objpos, basevol, 1.0f, + MWBase::SoundPtr sound = mOutput->playSound3D(filePath, objpos, basevol, 1.0f, 20.0f, 12750.0f, Play_Normal); sound->mPos = objpos; sound->mBaseVolume = basevol; @@ -244,7 +240,7 @@ namespace MWSound float basevol = mMasterVolume * mVoiceVolume; std::string filePath = "Sound/"+filename; - SoundPtr sound = mOutput->playSound(filePath, basevol, 1.0f, Play_Normal); + MWBase::SoundPtr sound = mOutput->playSound(filePath, basevol, 1.0f, Play_Normal); sound->mBaseVolume = basevol; mActiveSounds[sound] = std::make_pair(MWWorld::Ptr(), std::string("_say_sound")); @@ -277,9 +273,9 @@ namespace MWSound - SoundPtr SoundManager::playSound(const std::string& soundId, float volume, float pitch, int mode) + MWBase::SoundPtr SoundManager::playSound(const std::string& soundId, float volume, float pitch, int mode) { - SoundPtr sound; + MWBase::SoundPtr sound; if(!mOutput->isInitialized()) return sound; try @@ -305,10 +301,10 @@ namespace MWSound return sound; } - SoundPtr SoundManager::playSound3D(MWWorld::Ptr ptr, const std::string& soundId, + MWBase::SoundPtr SoundManager::playSound3D(MWWorld::Ptr ptr, const std::string& soundId, float volume, float pitch, int mode) { - SoundPtr sound; + MWBase::SoundPtr sound; if(!mOutput->isInitialized()) return sound; try @@ -491,25 +487,20 @@ namespace MWSound if(!isMusicPlaying()) startRandomTitle(); - const ESM::Cell *cell = MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->cell; - Ogre::Camera *cam = MWBase::Environment::get().getWorld()->getPlayer().getRenderer()->getCamera(); - Ogre::Vector3 nPos, nDir, nUp; - nPos = cam->getRealPosition(); - nDir = cam->getRealDirection(); - nUp = cam->getRealUp(); + MWWorld::Ptr player = + MWBase::Environment::get().getWorld()->getPlayer().getPlayer(); + const ESM::Cell *cell = player.getCell()->cell; Environment env = Env_Normal; - if((cell->data.flags&cell->HasWater) && nPos.y < cell->water) + if((cell->data.flags&cell->HasWater) && mListenerPos.z < cell->water) env = Env_Underwater; - // The output handler is expecting vectors oriented like the game - // (that is, -Z goes down, +Y goes forward), but that's not what we - // get from Ogre's camera, so we have to convert. - const Ogre::Vector3 pos(nPos[0], -nPos[2], nPos[1]); - const Ogre::Vector3 at(nDir[0], -nDir[2], nDir[1]); - const Ogre::Vector3 up(nUp[0], -nUp[2], nUp[1]); - - mOutput->updateListener(pos, at, up, env); + mOutput->updateListener( + mListenerPos, + mListenerDir, + Ogre::Vector3::UNIT_Z, + env + ); // Check if any sounds are finished playing, and trash them SoundMap::iterator snditer = mActiveSounds.begin(); @@ -567,6 +558,12 @@ namespace MWSound } } + void SoundManager::setListenerPosDir(const Ogre::Vector3 &pos, const Ogre::Vector3 &dir) + { + mListenerPos = pos; + mListenerDir = dir; + } + // Default readAll implementation, for decoders that can't do anything // better void Sound_Decoder::readAll(std::vector &output) diff --git a/apps/openmw/mwsound/soundmanager.hpp b/apps/openmw/mwsound/soundmanagerimp.hpp similarity index 57% rename from apps/openmw/mwsound/soundmanager.hpp rename to apps/openmw/mwsound/soundmanagerimp.hpp index 83195390c..956ad5712 100644 --- a/apps/openmw/mwsound/soundmanager.hpp +++ b/apps/openmw/mwsound/soundmanagerimp.hpp @@ -7,19 +7,15 @@ #include +#include #include #include +#include "../mwbase/soundmanager.hpp" + #include "../mwworld/ptr.hpp" - -namespace Ogre -{ - class Root; - class Camera; -} - namespace MWSound { class Sound_Output; @@ -27,27 +23,13 @@ namespace MWSound class Sound; typedef boost::shared_ptr DecoderPtr; - typedef boost::shared_ptr SoundPtr; - - enum PlayMode { - Play_Normal = 0, /* tracked, non-looping, multi-instance, environment */ - Play_Loop = 1<<0, /* Sound will continually loop until explicitly stopped */ - Play_NoEnv = 1<<1, /* Do not apply environment effects (eg, underwater filters) */ - Play_NoTrack = 1<<2, /* (3D only) Play the sound at the given object's position - * but do not keep it updated (the sound will not move with - * the object and will not stop when the object is deleted. */ - }; - static inline int operator|(const PlayMode &a, const PlayMode &b) - { return (int)a | (int)b; } - static inline int operator&(const PlayMode &a, const PlayMode &b) - { return (int)a & (int)b; } enum Environment { Env_Normal, Env_Underwater, }; - class SoundManager + class SoundManager : public MWBase::SoundManager { Ogre::ResourceGroupManager& mResourceMgr; @@ -65,9 +47,12 @@ namespace MWSound std::string mCurrentPlaylist; typedef std::pair PtrIDPair; - typedef std::map SoundMap; + typedef std::map SoundMap; SoundMap mActiveSounds; + Ogre::Vector3 mListenerPos; + Ogre::Vector3 mListenerDir; + std::string lookup(const std::string &soundId, float &volume, float &min, float &max); void streamMusicFull(const std::string& filename); @@ -84,67 +69,69 @@ namespace MWSound public: SoundManager(bool useSound); - ~SoundManager(); + virtual ~SoundManager(); - void processChangedSettings(const Settings::CategorySettingVector& settings); + virtual void processChangedSettings(const Settings::CategorySettingVector& settings); - void stopMusic(); + virtual void stopMusic(); ///< Stops music if it's playing - void streamMusic(const std::string& filename); + virtual void streamMusic(const std::string& filename); ///< Play a soundifle /// \param filename name of a sound file in "Music/" in the data directory. - void startRandomTitle(); + virtual void startRandomTitle(); ///< Starts a random track from the current playlist - bool isMusicPlaying(); + virtual bool isMusicPlaying(); ///< Returns true if music is playing - void playPlaylist(const std::string &playlist); + virtual void playPlaylist(const std::string &playlist); ///< Start playing music from the selected folder /// \param name of the folder that contains the playlist - void say(MWWorld::Ptr reference, const std::string& filename); + virtual void say(MWWorld::Ptr reference, const std::string& filename); ///< Make an actor say some text. /// \param filename name of a sound file in "Sound/" in the data directory. - void say(const std::string& filename); + virtual void say(const std::string& filename); ///< Say some text, without an actor ref /// \param filename name of a sound file in "Sound/" in the data directory. - bool sayDone(MWWorld::Ptr reference=MWWorld::Ptr()) const; + virtual bool sayDone(MWWorld::Ptr reference=MWWorld::Ptr()) const; ///< Is actor not speaking? - void stopSay(MWWorld::Ptr reference=MWWorld::Ptr()); + virtual void stopSay(MWWorld::Ptr reference=MWWorld::Ptr()); ///< Stop an actor speaking - SoundPtr playSound(const std::string& soundId, float volume, float pitch, int mode=Play_Normal); + virtual MWBase::SoundPtr playSound(const std::string& soundId, float volume, float pitch, int mode=Play_Normal); ///< Play a sound, independently of 3D-position - SoundPtr playSound3D(MWWorld::Ptr reference, const std::string& soundId, + virtual MWBase::SoundPtr playSound3D(MWWorld::Ptr reference, const std::string& soundId, float volume, float pitch, int mode=Play_Normal); ///< Play a sound from an object - void stopSound3D(MWWorld::Ptr reference, const std::string& soundId); + virtual void stopSound3D(MWWorld::Ptr reference, const std::string& soundId); ///< Stop the given object from playing the given sound, - void stopSound3D(MWWorld::Ptr reference); + virtual void stopSound3D(MWWorld::Ptr reference); ///< Stop the given object from playing all sounds. - void stopSound(const MWWorld::CellStore *cell); + virtual void stopSound(const MWWorld::CellStore *cell); ///< Stop all sounds for the given cell. - void stopSound(const std::string& soundId); + virtual void stopSound(const std::string& soundId); ///< Stop a non-3d looping sound - bool getSoundPlaying(MWWorld::Ptr reference, const std::string& soundId) const; + virtual bool getSoundPlaying(MWWorld::Ptr reference, const std::string& soundId) const; ///< Is the given sound currently playing on the given object? - void updateObject(MWWorld::Ptr reference); + virtual void updateObject(MWWorld::Ptr reference); ///< Update the position of all sounds connected to the given object. - void update(float duration); + virtual void update(float duration); + + virtual void setListenerPosDir(const Ogre::Vector3 &pos, const Ogre::Vector3 &dir); }; } diff --git a/apps/openmw/mwworld/action.cpp b/apps/openmw/mwworld/action.cpp index 0a57d5f67..c142294bb 100644 --- a/apps/openmw/mwworld/action.cpp +++ b/apps/openmw/mwworld/action.cpp @@ -2,8 +2,7 @@ #include "action.hpp" #include "../mwbase/environment.hpp" - -#include "../mwsound/soundmanager.hpp" +#include "../mwbase/soundmanager.hpp" MWWorld::Action::Action() {} @@ -13,7 +12,7 @@ void MWWorld::Action::execute (const Ptr& actor) { if (!mSoundId.empty()) MWBase::Environment::get().getSoundManager()->playSound3D (actor, mSoundId, 1.0, 1.0, - MWSound::Play_NoTrack); + MWBase::SoundManager::Play_NoTrack); executeImp (actor); } diff --git a/apps/openmw/mwworld/actiontalk.cpp b/apps/openmw/mwworld/actiontalk.cpp index 78171bbe5..d94cb67f4 100644 --- a/apps/openmw/mwworld/actiontalk.cpp +++ b/apps/openmw/mwworld/actiontalk.cpp @@ -2,8 +2,7 @@ #include "actiontalk.hpp" #include "../mwbase/environment.hpp" -#include "../mwgui/window_manager.hpp" -#include "../mwdialogue/dialoguemanager.hpp" +#include "../mwbase/dialoguemanager.hpp" namespace MWWorld { diff --git a/apps/openmw/mwworld/cells.cpp b/apps/openmw/mwworld/cells.cpp index cffaf70ea..822aa78d6 100644 --- a/apps/openmw/mwworld/cells.cpp +++ b/apps/openmw/mwworld/cells.cpp @@ -167,67 +167,71 @@ MWWorld::Ptr MWWorld::Cells::getPtr (const std::string& name, Ptr::CellStore& ce else return Ptr(); } + MWWorld::Ptr ptr; if (MWWorld::LiveCellRef *ref = cell.activators.find (name)) - return Ptr (ref, &cell); + ptr = Ptr (ref, &cell); if (MWWorld::LiveCellRef *ref = cell.potions.find (name)) - return Ptr (ref, &cell); + ptr = Ptr (ref, &cell); if (MWWorld::LiveCellRef *ref = cell.appas.find (name)) - return Ptr (ref, &cell); + ptr = Ptr (ref, &cell); if (MWWorld::LiveCellRef *ref = cell.armors.find (name)) - return Ptr (ref, &cell); + ptr = Ptr (ref, &cell); if (MWWorld::LiveCellRef *ref = cell.books.find (name)) - return Ptr (ref, &cell); + ptr = Ptr (ref, &cell); if (MWWorld::LiveCellRef *ref = cell.clothes.find (name)) - return Ptr (ref, &cell); + ptr = Ptr (ref, &cell); if (MWWorld::LiveCellRef *ref = cell.containers.find (name)) - return Ptr (ref, &cell); + ptr = Ptr (ref, &cell); if (MWWorld::LiveCellRef *ref = cell.creatures.find (name)) - return Ptr (ref, &cell); + ptr = Ptr (ref, &cell); if (MWWorld::LiveCellRef *ref = cell.doors.find (name)) - return Ptr (ref, &cell); + ptr = Ptr (ref, &cell); if (MWWorld::LiveCellRef *ref = cell.ingreds.find (name)) - return Ptr (ref, &cell); + ptr = Ptr (ref, &cell); if (MWWorld::LiveCellRef *ref = cell.creatureLists.find (name)) - return Ptr (ref, &cell); + ptr = Ptr (ref, &cell); if (MWWorld::LiveCellRef *ref = cell.itemLists.find (name)) - return Ptr (ref, &cell); + ptr = Ptr (ref, &cell); if (MWWorld::LiveCellRef *ref = cell.lights.find (name)) - return Ptr (ref, &cell); + ptr = Ptr (ref, &cell); if (MWWorld::LiveCellRef *ref = cell.lockpicks.find (name)) - return Ptr (ref, &cell); + ptr = Ptr (ref, &cell); if (MWWorld::LiveCellRef *ref = cell.miscItems.find (name)) - return Ptr (ref, &cell); + ptr = Ptr (ref, &cell); if (MWWorld::LiveCellRef *ref = cell.npcs.find (name)) - return Ptr (ref, &cell); + ptr = Ptr (ref, &cell); if (MWWorld::LiveCellRef *ref = cell.probes.find (name)) - return Ptr (ref, &cell); + ptr = Ptr (ref, &cell); if (MWWorld::LiveCellRef *ref = cell.repairs.find (name)) - return Ptr (ref, &cell); + ptr = Ptr (ref, &cell); if (MWWorld::LiveCellRef *ref = cell.statics.find (name)) - return Ptr (ref, &cell); + ptr = Ptr (ref, &cell); if (MWWorld::LiveCellRef *ref = cell.weapons.find (name)) - return Ptr (ref, &cell); + ptr = Ptr (ref, &cell); + if (!ptr.isEmpty() && ptr.getRefData().getCount() > 0) { + return ptr; + } return Ptr(); } diff --git a/apps/openmw/mwworld/cellstore.hpp b/apps/openmw/mwworld/cellstore.hpp index 0be0ef651..3ec4a2e78 100644 --- a/apps/openmw/mwworld/cellstore.hpp +++ b/apps/openmw/mwworld/cellstore.hpp @@ -69,7 +69,7 @@ namespace MWWorld { for (typename std::list::iterator iter (list.begin()); iter!=list.end(); ++iter) { - if (iter->ref.refID==name) + if (iter->mData.getCount() > 0 && iter->ref.refID == name) return &*iter; } @@ -155,6 +155,20 @@ namespace MWWorld forEachImp (functor, weapons); } + bool operator==(const CellStore &cell) { + return this->cell->name == cell.cell->name && + this->cell->data.gridX == cell.cell->data.gridX && + this->cell->data.gridY == cell.cell->data.gridY; + } + + bool operator!=(const CellStore &cell) { + return !(*this == cell); + } + + bool isExterior() const { + return cell->isExterior(); + } + private: template diff --git a/apps/openmw/mwworld/player.cpp b/apps/openmw/mwworld/player.cpp index 4d508c3e9..0f05ae24d 100644 --- a/apps/openmw/mwworld/player.cpp +++ b/apps/openmw/mwworld/player.cpp @@ -6,8 +6,6 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" -#include "../mwrender/player.hpp" - #include "../mwmechanics/movement.hpp" #include "../mwmechanics/npcstats.hpp" @@ -15,8 +13,8 @@ namespace MWWorld { - Player::Player (MWRender::Player *renderer, const ESM::NPC *player, const MWBase::World& world) : - mCellStore (0), mRenderer (renderer), mClass (0), + Player::Player (const ESM::NPC *player, const MWBase::World& world) : + mCellStore (0), mClass (0), mAutoMove (false), mForwardBackward (0) { mPlayer.base = player; @@ -28,7 +26,6 @@ namespace MWWorld float* playerPos = mPlayer.mData.getPosition().pos; playerPos[0] = playerPos[1] = playerPos[2] = 0; - mPlayer.mData.setBaseNode(renderer->getNode()); /// \todo Do not make a copy of classes defined in esm/p records. mClass = new ESM::Class (*world.getStore().classes.find (player->cls)); } @@ -38,17 +35,6 @@ namespace MWWorld delete mClass; } - void Player::setPos(float x, float y, float z) - { - /// \todo This fcuntion should be removed during the mwrender-refactoring. - MWBase::Environment::get().getWorld()->moveObject (getPlayer(), x, y, z); - } - - void Player::setRot(float x, float y, float z) - { - mRenderer->setRot(x, y, z); - } - void Player::setClass (const ESM::Class& class_) { ESM::Class *new_class = new ESM::Class (class_); diff --git a/apps/openmw/mwworld/player.hpp b/apps/openmw/mwworld/player.hpp index ee7c030a5..68df2ec6d 100644 --- a/apps/openmw/mwworld/player.hpp +++ b/apps/openmw/mwworld/player.hpp @@ -14,11 +14,6 @@ namespace MWBase class World; } -namespace MWRender -{ - class Player; -} - namespace MWWorld { class CellStore; @@ -28,7 +23,6 @@ namespace MWWorld { LiveCellRef mPlayer; MWWorld::CellStore *mCellStore; - MWRender::Player *mRenderer; std::string mName; bool mMale; std::string mRace; @@ -38,16 +32,10 @@ namespace MWWorld int mForwardBackward; public: - Player(MWRender::Player *renderer, const ESM::NPC *player, const MWBase::World& world); + Player(const ESM::NPC *player, const MWBase::World& world); ~Player(); - /// Set the player position. Uses Morrowind coordinates. - void setPos(float x, float y, float z); - - /// Set where the player is looking at. Uses Morrowind (euler) angles - void setRot(float x, float y, float z); - void setCell (MWWorld::CellStore *cellStore) { mCellStore = cellStore; @@ -59,8 +47,6 @@ namespace MWWorld return ptr; } - MWRender::Player *getRenderer() { return mRenderer; } - void setName (const std::string& name) { mName = name; diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 13e5ecb85..ec557e35c 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -2,11 +2,10 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" /// FIXME +#include "../mwbase/soundmanager.hpp" #include "../mwmechanics/mechanicsmanager.hpp" -#include "../mwsound/soundmanager.hpp" - #include "../mwgui/window_manager.hpp" #include "player.hpp" @@ -135,23 +134,33 @@ namespace MWWorld } - void Scene::playerCellChange (Ptr::CellStore *cell, const ESM::Position& position, + void + Scene::playerCellChange( + MWWorld::CellStore *cell, + const ESM::Position& pos, bool adjustPlayerPos) { - bool hasWater = cell->cell->data.flags & cell->cell->HasWater; - mPhysics->setCurrentWater(hasWater, cell->cell->water); - if (adjustPlayerPos) - { - MWBase::Environment::get().getWorld()->getPlayer().setPos (position.pos[0], position.pos[1], position.pos[2]); - MWBase::Environment::get().getWorld()->getPlayer().setRot (position.rot[0], position.rot[1], position.rot[2]); - } - MWBase::Environment::get().getWorld()->getPlayer().setCell (cell); - MWBase::Environment::get().getMechanicsManager()->addActor (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); - MWBase::Environment::get().getMechanicsManager()->watchActor (MWBase::Environment::get().getWorld()->getPlayer().getPlayer()); + bool hasWater = cell->cell->data.flags & cell->cell->HasWater; + mPhysics->setCurrentWater(hasWater, cell->cell->water); - MWBase::Environment::get().getWindowManager()->changeCell( mCurrentCell ); + MWBase::World *world = MWBase::Environment::get().getWorld(); + MWWorld::Ptr player = world->getPlayer().getPlayer(); + + if (adjustPlayerPos) { + world->moveObject(player, pos.pos[0], pos.pos[1], pos.pos[2]); + world->rotateObject(player, pos.rot[0], pos.rot[1], pos.rot[2]); + } + world->getPlayer().setCell(cell); + + MWMechanics::MechanicsManager *mechMgr = + MWBase::Environment::get().getMechanicsManager(); + + mechMgr->addActor(player); + mechMgr->watchActor(player); + + MWBase::Environment::get().getWindowManager()->changeCell(mCurrentCell); } void Scene::changeCell (int X, int Y, const ESM::Position& position, bool adjustPlayerPos) @@ -224,7 +233,7 @@ namespace MWWorld // adjust player - playerCellChange (MWBase::Environment::get().getWorld()->getExterior(X, Y), position, adjustPlayerPos); + playerCellChange (mCurrentCell, position, adjustPlayerPos); // Sky system MWBase::Environment::get().getWorld()->adjustSky(); @@ -337,7 +346,7 @@ namespace MWWorld mRendering.addObject(ptr); MWWorld::Class::get(ptr).insertObject(ptr, *mPhysics); } - + void Scene::removeObjectFromScene (const Ptr& ptr) { MWBase::Environment::get().getMechanicsManager()->removeActor (ptr); @@ -350,10 +359,7 @@ namespace MWWorld { CellStoreCollection::iterator active = mActiveCells.begin(); while (active != mActiveCells.end()) { - if ((*active)->cell->name == cell.cell->name && - (*active)->cell->data.gridX == cell.cell->data.gridX && - (*active)->cell->data.gridY == cell.cell->data.gridY) - { + if (**active == cell) { return true; } ++active; diff --git a/apps/openmw/mwworld/weather.cpp b/apps/openmw/mwworld/weather.cpp index b5f2e3a57..0adf87dae 100644 --- a/apps/openmw/mwworld/weather.cpp +++ b/apps/openmw/mwworld/weather.cpp @@ -9,11 +9,10 @@ #include "../mwbase/environment.hpp" #include "../mwbase/world.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwrender/renderingmanager.hpp" -#include "../mwsound/soundmanager.hpp" - #include "player.hpp" using namespace Ogre; diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 215fbb30e..cf2d21014 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -4,14 +4,13 @@ #include #include "../mwbase/environment.hpp" +#include "../mwbase/soundmanager.hpp" #include "../mwrender/sky.hpp" #include "../mwrender/player.hpp" #include "../mwmechanics/mechanicsmanager.hpp" -#include "../mwsound/soundmanager.hpp" - #include "../mwgui/window_manager.hpp" #include "player.hpp" @@ -51,7 +50,7 @@ namespace for (iterator iter (refList.list.begin()); iter!=refList.list.end(); ++iter) { - if(iter->mData.getBaseNode()){ + if(iter->mData.getCount() > 0 && iter->mData.getBaseNode()){ if (iter->mData.getHandle()==handle) { return &*iter; @@ -189,8 +188,9 @@ namespace MWWorld mEsm.open (masterPath.string()); mStore.load (mEsm); - MWRender::Player* play = &(mRendering->getPlayer()); - mPlayer = new MWWorld::Player (play, mStore.npcs.find ("player"), *this); + mPlayer = new MWWorld::Player (mStore.npcs.find ("player"), *this); + mRendering->attachCameraTo(mPlayer->getPlayer()); + mPhysics->addActor (mPlayer->getPlayer().getRefData().getHandle(), "", Ogre::Vector3 (0, 0, 0)); // global variables @@ -543,80 +543,73 @@ namespace MWWorld } } - bool World::moveObjectImp (const Ptr& ptr, float x, float y, float z) + void World::moveObject(const Ptr &ptr, CellStore &newCell, float x, float y, float z) { - bool cellChanged = false, haveToMove = true; - ESM::Position &pos = ptr.getRefData().getPosition(); pos.pos[0] = x, pos.pos[1] = y, pos.pos[2] = z; Ogre::Vector3 vec(x, y, z); - CellStore *currCell; - /// \todo fix assertion fail on player ptr.getCell() on start - if (ptr == mPlayer->getPlayer()) { - currCell = mWorldScene->getCurrentCell(); - } else { - currCell = ptr.getCell(); - } + CellStore *currCell = ptr.getCell(); + bool isPlayer = ptr == mPlayer->getPlayer(); + bool haveToMove = mWorldScene->isCellActive(*currCell) || isPlayer; - if (currCell) { - if (!(currCell->cell->data.flags & ESM::Cell::Interior)) { - // exterior -> adjust loaded cells - int cellX = 0, cellY = 0; - positionToIndex (x, y, cellX, cellY); - - if (currCell->cell->data.gridX != cellX || - currCell->cell->data.gridY != cellY) - { - if (ptr == mPlayer->getPlayer()) { - mWorldScene->changeCell(cellX, cellY, pos, false); - } else { - CellStore *newCell = - MWBase::Environment::get().getWorld()->getExterior(cellX, cellY); - - // placeObject() handles both target cell states - // with active current cell - if (!mWorldScene->isCellActive(*currCell)) { - placeObject(ptr, *newCell, pos); - haveToMove = false; - } else if (!mWorldScene->isCellActive(*newCell)) { - MWWorld::Class::get(ptr).copyToCell(ptr, *newCell); - mWorldScene->removeObjectFromScene(ptr); - mLocalScripts.remove(ptr); - - haveToMove = false; - } else { - MWWorld::Ptr copy = - MWWorld::Class::get(ptr).copyToCell(ptr, *newCell); - - mRendering->moveObjectToCell(copy, vec, currCell); - - if (MWWorld::Class::get(ptr).isActor()) { - MWMechanics::MechanicsManager *mechMgr = - MWBase::Environment::get().getMechanicsManager(); - - mechMgr->removeActor(ptr); - mechMgr->addActor(copy); - } else { - std::string script = - MWWorld::Class::get(ptr).getScript(ptr); - if (!script.empty()) { - mLocalScripts.remove(ptr); - mLocalScripts.add(script, copy); - } - } - } - ptr.getRefData().setCount(0); - } - cellChanged = true; + if (*currCell != newCell) { + if (isPlayer) { + if (!newCell.isExterior()) { + changeToInteriorCell(newCell.cell->name, pos); + } else { + changeToExteriorCell(pos); } + } else { + if (!mWorldScene->isCellActive(newCell)) { + copyObjectToCell(ptr, newCell, pos); + } else if (!mWorldScene->isCellActive(*currCell)) { + MWWorld::Class::get(ptr).copyToCell(ptr, newCell); + mWorldScene->removeObjectFromScene(ptr); + mLocalScripts.remove(ptr); + haveToMove = false; + } else { + MWWorld::Ptr copy = + MWWorld::Class::get(ptr).copyToCell(ptr, newCell); + + mRendering->moveObjectToCell(copy, vec, currCell); + + if (MWWorld::Class::get(ptr).isActor()) { + MWMechanics::MechanicsManager *mechMgr = + MWBase::Environment::get().getMechanicsManager(); + + mechMgr->removeActor(ptr); + mechMgr->addActor(copy); + } else { + std::string script = + MWWorld::Class::get(ptr).getScript(ptr); + if (!script.empty()) { + mLocalScripts.remove(ptr); + mLocalScripts.add(script, copy); + } + } + } + ptr.getRefData().setCount(0); } } if (haveToMove) { mRendering->moveObject(ptr, vec); mPhysics->moveObject(ptr.getRefData().getHandle(), vec); } - return cellChanged; + } + + bool World::moveObjectImp(const Ptr& ptr, float x, float y, float z) + { + CellStore *cell = ptr.getCell(); + if (cell->isExterior()) { + int cellX, cellY; + positionToIndex(x, y, cellX, cellY); + + cell = getExterior(cellX, cellY); + } + moveObject(ptr, *cell, x, y, z); + + return cell != ptr.getCell(); } void World::moveObject (const Ptr& ptr, float x, float y, float z) @@ -634,19 +627,20 @@ namespace MWWorld mPhysics->scaleObject( ptr.getRefData().getHandle(), scale ); } - void World::rotateObject (const Ptr& ptr,float x,float y,float z) + void World::rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust) { - MWWorld::Class::get(ptr).adjustRotation(ptr,x,y,z); + Ogre::Vector3 rot(x, y, z); + if (mRendering->rotateObject(ptr, rot, adjust)) { + float *objRot = ptr.getRefData().getPosition().rot; + objRot[0] = Ogre::Degree(rot.x).valueRadians(); + objRot[1] = Ogre::Degree(rot.y).valueRadians(); + objRot[2] = Ogre::Degree(rot.z).valueRadians(); - ptr.getRefData().getPosition().rot[0] = Ogre::Degree(x).valueRadians(); - ptr.getRefData().getPosition().rot[1] = Ogre::Degree(y).valueRadians(); - ptr.getRefData().getPosition().rot[2] = Ogre::Degree(z).valueRadians(); - - Ogre::Quaternion rotx(Ogre::Degree(x),Ogre::Vector3::UNIT_X); - Ogre::Quaternion roty(Ogre::Degree(y),Ogre::Vector3::UNIT_Y); - Ogre::Quaternion rotz(Ogre::Degree(z),Ogre::Vector3::UNIT_Z); - ptr.getRefData().getBaseNode()->setOrientation(rotz*roty*rotx); - mPhysics->rotateObject(ptr.getRefData().getHandle(),ptr.getRefData().getBaseNode()->getOrientation()); + mPhysics->rotateObject( + ptr.getRefData().getHandle(), + ptr.getRefData().getBaseNode()->getOrientation() + ); + } } void World::indexToPosition (int cellX, int cellY, float &x, float &y, bool centre) const @@ -1057,7 +1051,7 @@ namespace MWWorld pos.pos[1] = -result.second[2]; pos.pos[2] = result.second[1]; - placeObject(object, *cell, pos); + copyObjectToCell(object, *cell, pos); object.getRefData().setCount(0); return true; @@ -1075,7 +1069,7 @@ namespace MWWorld } void - World::placeObject(const Ptr &object, CellStore &cell, const ESM::Position &pos) + World::copyObjectToCell(const Ptr &object, CellStore &cell, const ESM::Position &pos) { /// \todo add searching correct cell for position specified MWWorld::Ptr dropped = @@ -1110,7 +1104,7 @@ namespace MWWorld Ogre::Vector3 orig = Ogre::Vector3(pos.pos[0], pos.pos[1], pos.pos[2]); Ogre::Vector3 dir = Ogre::Vector3(0, 0, -1); - + float len = (pos.pos[2] >= 0) ? pos.pos[2] : -pos.pos[2]; len += 100.0; @@ -1118,7 +1112,7 @@ namespace MWWorld mPhysics->castRay(orig, dir, len); pos.pos[2] = hit.second.z; - placeObject(object, *cell, pos); + copyObjectToCell(object, *cell, pos); object.getRefData().setCount(0); } @@ -1131,4 +1125,26 @@ namespace MWWorld { mRendering->getTriangleBatchCount(triangles, batches); } + + bool + World::isSwimming(const MWWorld::Ptr &object) + { + /// \todo add check ifActor() - only actors can swim + float *fpos = object.getRefData().getPosition().pos; + Ogre::Vector3 pos(fpos[0], fpos[1], fpos[2]); + + /// \fixme should rely on object height + pos.z += 30; + + return isUnderwater(*object.getCell()->cell, pos); + } + + bool + World::isUnderwater(const ESM::Cell &cell, const Ogre::Vector3 &pos) + { + if (!(cell.data.flags & ESM::Cell::HasWater)) { + return false; + } + return pos.z < cell.water; + } } diff --git a/apps/openmw/mwworld/worldimp.hpp b/apps/openmw/mwworld/worldimp.hpp index d39871c21..24645cb8e 100644 --- a/apps/openmw/mwworld/worldimp.hpp +++ b/apps/openmw/mwworld/worldimp.hpp @@ -90,7 +90,7 @@ namespace MWWorld ///< @return true if the active cell (cell player is in) changed virtual void - placeObject(const Ptr &ptr, CellStore &cell, const ESM::Position &pos); + copyObjectToCell(const Ptr &ptr, CellStore &cell, const ESM::Position &pos); public: @@ -206,10 +206,11 @@ namespace MWWorld virtual void deleteObject (const Ptr& ptr); virtual void moveObject (const Ptr& ptr, float x, float y, float z); + virtual void moveObject (const Ptr& ptr, CellStore &newCell, float x, float y, float z); virtual void scaleObject (const Ptr& ptr, float scale); - virtual void rotateObject (const Ptr& ptr,float x,float y,float z); + virtual void rotateObject (const Ptr& ptr,float x,float y,float z, bool adjust = false); virtual void indexToPosition (int cellX, int cellY, float &x, float &y, bool centre = false) const; @@ -270,6 +271,9 @@ namespace MWWorld ///< @return true if it is possible to place on object at specified cursor location virtual void processChangedSettings(const Settings::CategorySettingVector& settings); + + virtual bool isSwimming(const MWWorld::Ptr &object); + virtual bool isUnderwater(const ESM::Cell &cell, const Ogre::Vector3 &pos); }; } diff --git a/cmake/FindMyGUI.cmake b/cmake/FindMyGUI.cmake index 7278fe200..e2fefac7d 100644 --- a/cmake/FindMyGUI.cmake +++ b/cmake/FindMyGUI.cmake @@ -128,9 +128,11 @@ ELSE (WIN32) #Unix ENDIF (WIN32) #Do some preparation -SEPARATE_ARGUMENTS(MYGUI_INCLUDE_DIRS) -SEPARATE_ARGUMENTS(MYGUI_LIBRARIES) -SEPARATE_ARGUMENTS(MYGUI_PLATFORM_LIBRARIES) +IF (NOT WIN32) # This does not work on Windows for paths with spaces in them + SEPARATE_ARGUMENTS(MYGUI_INCLUDE_DIRS) + SEPARATE_ARGUMENTS(MYGUI_LIBRARIES) + SEPARATE_ARGUMENTS(MYGUI_PLATFORM_LIBRARIES) +ENDIF (NOT WIN32) SET(MYGUI_LIBRARIES ${MYGUI_LIBRARIES} ${FREETYPE_LIBRARIES}) diff --git a/components/CMakeLists.txt b/components/CMakeLists.txt index efeb69cae..c0585d5ee 100644 --- a/components/CMakeLists.txt +++ b/components/CMakeLists.txt @@ -52,7 +52,7 @@ add_component_dir (misc add_component_dir (files linuxpath windowspath macospath fixedpath multidircollection collections fileops configurationmanager - filelibrary + filelibrary ogreplugin ) add_component_dir (compiler diff --git a/components/bsa/bsa_file.cpp b/components/bsa/bsa_file.cpp index 053191c9b..1700e1aab 100644 --- a/components/bsa/bsa_file.cpp +++ b/components/bsa/bsa_file.cpp @@ -200,7 +200,7 @@ void BSAFile::readHeader() input.read(&stringBuf[0], stringBuf.size()); // Check our position - assert(input.tellg() == static_cast (12+dirsize)); + assert(input.tellg() == std::streampos(12+dirsize)); // Calculate the offset of the data buffer. All file offsets are // relative to this. 12 header bytes + directory + hash table diff --git a/components/esm/esm_reader.cpp b/components/esm/esm_reader.cpp index a2cf69ddc..95ef46e81 100644 --- a/components/esm/esm_reader.cpp +++ b/components/esm/esm_reader.cpp @@ -1,4 +1,5 @@ #include "esm_reader.hpp" +#include namespace ESM { diff --git a/components/files/ogreplugin.cpp b/components/files/ogreplugin.cpp new file mode 100644 index 000000000..c434114b3 --- /dev/null +++ b/components/files/ogreplugin.cpp @@ -0,0 +1,37 @@ +#include "ogreplugin.hpp" + +#include +#include + +namespace Files { + +bool loadOgrePlugin(const std::string &pluginDir, std::string pluginName, Ogre::Root &ogreRoot) { + pluginName = pluginName + OGRE_PLUGIN_DEBUG_SUFFIX; +#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE + std::ostringstream verStream; + verStream << "." << OGRE_VERSION_MAJOR << "." << OGRE_VERSION_MINOR << "." << OGRE_VERSION_PATCH; + pluginName = pluginName + verStream.str(); +#endif + + std::string pluginExt; +#if OGRE_PLATFORM == OGRE_PLATFORM_WIN32 + pluginExt = ".dll"; +#endif +#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE + pluginExt = ".dylib"; +#endif +#if OGRE_PLATFORM == OGRE_PLATFORM_LINUX + pluginExt = ".so"; +#endif + + std::string pluginPath = pluginDir + "/" + pluginName + pluginExt; + if (boost::filesystem::exists(pluginPath)) { + ogreRoot.loadPlugin(pluginPath); + return true; + } + else { + return false; + } +} + +} \ No newline at end of file diff --git a/components/files/ogreplugin.hpp b/components/files/ogreplugin.hpp new file mode 100644 index 000000000..2d56bfb47 --- /dev/null +++ b/components/files/ogreplugin.hpp @@ -0,0 +1,64 @@ +/** + * Open Morrowind - an opensource Elder Scrolls III: Morrowind + * engine implementation. + * + * Copyright (C) 2011 Open Morrowind Team + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +/** \file components/files/ogreplugin.hpp */ + +#ifndef COMPONENTS_FILES_OGREPLUGIN_H +#define COMPONENTS_FILES_OGREPLUGIN_H + +#include + +#include +#include + +namespace Ogre { + class Root; +} + +#if (BOOST_VERSION <= 104500) +namespace boost { +namespace filesystem { +inline path absolute(const path& p, const path& base=current_path()) { + // call obsolete version of this function on older boost + return complete(p, base); +} +} +} +#endif /* (BOOST_VERSION <= 104300) */ + +/** + * \namespace Files + */ +namespace Files { + +/** + * \brief Loads Ogre plugin with given name. + * + * \param pluginDir absolute path to plugins + * \param pluginName plugin name, for example "RenderSystem_GL" + * \param ogreRoot Ogre::Root instance + * + * \return whether plugin was located or not + */ +bool loadOgrePlugin(const std::string &pluginDir, std::string pluginName, Ogre::Root &ogreRoot); + +} + +#endif /* COMPONENTS_FILES_OGREPLUGIN_H */ diff --git a/components/nif/nif_file.hpp b/components/nif/nif_file.hpp index 624066317..a4eaa8990 100644 --- a/components/nif/nif_file.hpp +++ b/components/nif/nif_file.hpp @@ -37,6 +37,8 @@ #include #include +#include + #include "record.hpp" #include "nif_types.hpp" diff --git a/credits.txt b/credits.txt index 3a942bfd8..5b8ede117 100644 --- a/credits.txt +++ b/credits.txt @@ -14,6 +14,7 @@ Jason “jhooks” Hooks Karl-Felix “k1ll” Glatzer Lukasz “lgro” Gromanowski Marc “Zini” Zinnschlag +Michael Mc Donnell Michael “werdanith” Papageorgiou Nikolay “corristo” Kasyanov Pieter “pvdk” van der Kloet diff --git a/files/materials/core.h b/files/materials/core.h index 6e27d349c..cba716777 100644 --- a/files/materials/core.h +++ b/files/materials/core.h @@ -1,20 +1,20 @@ -#if SH_HLSL == 1 - #error "HLSL is unsupported" -#endif - -#if SH_CG == 1 +#if SH_HLSL == 1 || SH_CG == 1 #define shTexture2D sampler2D #define shSample(tex, coord) tex2D(tex, coord) + #define shCubicSample(tex, coord) texCUBE(tex, coord) #define shLerp(a, b, t) lerp(a, b, t) #define shSaturate(a) saturate(a) #define shSampler2D(name) , uniform sampler2D name : register(s@shCounter(0)) @shUseSampler(name) + + #define shSamplerCube(name) , uniform samplerCUBE name : register(s@shCounter(0)) @shUseSampler(name) #define shMatrixMult(m, v) mul(m, v) #define shUniform(type, name) , uniform type name + #define shTangentInput(type) , in type tangent : TANGENT #define shVertexInput(type, name) , in type name : TEXCOORD@shCounter(1) #define shInput(type, name) , in type name : TEXCOORD@shCounter(1) #define shOutput(type, name) , out type name : TEXCOORD@shCounter(2) @@ -65,9 +65,10 @@ #define float4 vec4 #define int2 ivec2 #define int3 ivec3 - #define int4 ivec4/ + #define int4 ivec4 #define shTexture2D sampler2D #define shSample(tex, coord) texture2D(tex, coord) + #define shCubicSample(tex, coord) textureCube(tex, coord) #define shLerp(a, b, t) mix(a, b, t) #define shSaturate(a) clamp(a, 0.0, 1.0) @@ -75,11 +76,14 @@ #define shSampler2D(name) uniform sampler2D name; @shUseSampler(name) + #define shSamplerCube(name) uniform samplerCube name; @shUseSampler(name) + #define shMatrixMult(m, v) (m * v) #define shOutputPosition gl_Position #define float4x4 mat4 + #define float3x3 mat3 // GLSL 1.3 #if 0 @@ -89,8 +93,8 @@ #define shOutputColour(num) oColor##num - - + #define shTangentInput(type) in type tangent; + #define shVertexInput(type, name) in type name; #define shInput(type, name) in type name; #define shOutput(type, name) out type name; @@ -101,7 +105,7 @@ #ifdef SH_VERTEX_SHADER #define SH_BEGIN_PROGRAM \ - in float4 shInputPosition; + in float4 vertex; #define SH_START_PROGRAM \ void main(void) @@ -126,10 +130,11 @@ #if 1 // automatically recognized by ogre when the input name equals this - #define shInputPosition gl_Vertex + #define shInputPosition vertex #define shOutputColour(num) gl_FragData[num] + #define shTangentInput(type) attribute type tangent; #define shVertexInput(type, name) attribute type name; #define shInput(type, name) varying type name; #define shOutput(type, name) varying type name; @@ -140,8 +145,8 @@ #ifdef SH_VERTEX_SHADER - #define SH_BEGIN_PROGRAM - + #define SH_BEGIN_PROGRAM \ + attribute vec4 vertex; #define SH_START_PROGRAM \ void main(void) diff --git a/files/materials/objects.shaderset b/files/materials/objects.shaderset index ccb975fe9..028c15ce8 100644 --- a/files/materials/objects.shaderset +++ b/files/materials/objects.shaderset @@ -3,7 +3,7 @@ shader_set openmw_objects_vertex source objects.shader type vertex profiles_cg vs_2_0 vp40 arbvp1 - profiles_hlsl vs_2_0 + profiles_hlsl vs_3_0 vs_2_0 } shader_set openmw_objects_fragment @@ -11,5 +11,5 @@ shader_set openmw_objects_fragment source objects.shader type fragment profiles_cg ps_3_0 ps_2_x ps_2_0 fp40 arbfp1 - profiles_hlsl ps_2_0 + profiles_hlsl ps_3_0 ps_2_0 } diff --git a/files/materials/terrain.shaderset b/files/materials/terrain.shaderset index be8ecd7d8..a72f2358f 100644 --- a/files/materials/terrain.shaderset +++ b/files/materials/terrain.shaderset @@ -3,7 +3,7 @@ shader_set terrain_vertex source terrain.shader type vertex profiles_cg vs_2_0 vp40 arbvp1 - profiles_hlsl vs_2_0 + profiles_hlsl vs_3_0 vs_2_0 } shader_set terrain_fragment @@ -11,5 +11,5 @@ shader_set terrain_fragment source terrain.shader type fragment profiles_cg ps_3_0 ps_2_x ps_2_0 fp40 arbfp1 - profiles_hlsl ps_2_0 + profiles_hlsl ps_3_0 ps_2_0 } diff --git a/files/materials/underwater.h b/files/materials/underwater.h index fe19ff93b..18052a98d 100644 --- a/files/materials/underwater.h +++ b/files/materials/underwater.h @@ -28,7 +28,7 @@ float3 intercept(float3 lineP, float3 perturb1(shTexture2D tex, float2 coords, float bend, float2 windDir, float windSpeed, float timer) { - float2 nCoord = float2(0.0); + float2 nCoord = float2(0,0); bend *= WAVE_CHOPPYNESS; nCoord = coords * (WAVE_SCALE * 0.05) + windDir * timer * (windSpeed*0.04); float3 normal0 = 2.0 * shSample(tex, nCoord + float2(-timer*0.015,-timer*0.05)).rgb - 1.0; @@ -55,8 +55,8 @@ float3 perturb1(shTexture2D tex, float2 coords, float bend, float2 windDir, floa float3 perturb(shTexture2D tex, float2 coords, float bend, float2 windDir, float windSpeed, float timer) { bend *= WAVE_CHOPPYNESS; - float3 col = float3(0.0); - float2 nCoord = float2(0.0); //normal coords + float3 col = float3(0,0,0); + float2 nCoord = float2(0,0); //normal coords nCoord = coords * (WAVE_SCALE * 0.025) + windDir * timer * (windSpeed*0.03); col += shSample(tex,nCoord + float2(-timer*0.005,-timer*0.01)).rgb*0.20; @@ -102,11 +102,11 @@ float3 getCaustics (shTexture2D causticMap, float3 worldPos, float3 waterEyePos, /// \todo sunFade // float3 caustics = clamp(pow(float3(causticR)*5.5,float3(5.5*causticdepth)),0.0,1.0)*NdotL*sunFade*causticdepth; - float3 caustics = clamp(pow(float3(causticR)*5.5,float3(5.5*causticdepth)),0.0,1.0)*NdotL*causticdepth; + float3 caustics = clamp(pow(float3(causticR,causticR,causticR)*5.5,float3(5.5*causticdepth,5.5*causticdepth,5.5*causticdepth)),0.0,1.0)*NdotL*causticdepth; float causticG = 1.0-perturb(causticMap,causticPos.xz+(1.0-causticdepth)*ABBERATION, causticdepth, windDir_windSpeed.xy, windDir_windSpeed.z, waterTimer).z; float causticB = 1.0-perturb(causticMap,causticPos.xz+(1.0-causticdepth)*ABBERATION*2.0, causticdepth, windDir_windSpeed.xy, windDir_windSpeed.z, waterTimer).z; //caustics = shSaturate(pow(float3(causticR,causticG,causticB)*5.5,float3(5.5*causticdepth)))*NdotL*sunFade*causticdepth; - caustics = shSaturate(pow(float3(causticR,causticG,causticB)*5.5,float3(5.5*causticdepth)))*NdotL*causticdepth; + caustics = shSaturate(pow(float3(causticR,causticG,causticB)*5.5,float3(5.5*causticdepth,5.5*causticdepth,5.5*causticdepth)))*NdotL*causticdepth; caustics *= 3; diff --git a/files/materials/water.shader b/files/materials/water.shader index 2145919b0..08a19ace9 100644 --- a/files/materials/water.shader +++ b/files/materials/water.shader @@ -198,7 +198,7 @@ float depth = shSample(depthMap, screenCoords).x * far - depthPassthrough; float shoreFade = shSaturate(depth / 50.0); - float2 nCoord = float2(0.0); + float2 nCoord = float2(0,0); nCoord = UV * (WAVE_SCALE * 0.05) + WIND_DIR * waterTimer * (WIND_SPEED*0.04); float3 normal0 = 2.0 * shSample(normalMap, nCoord + float2(-waterTimer*0.015,-waterTimer*0.005)).rgb - 1.0; @@ -238,12 +238,12 @@ // sunlight scattering float3 pNormal = float3(0,1,0); - vec3 lR = reflect(lVec, lNormal); - vec3 llR = reflect(lVec, pNormal); + float3 lR = reflect(lVec, lNormal); + float3 llR = reflect(lVec, pNormal); float s = shSaturate(dot(lR, vVec)*2.0-1.2); float lightScatter = shSaturate(dot(-lVec,lNormal)*0.7+0.3) * s * SCATTER_AMOUNT * waterSunFade_sunHeight.x * shSaturate(1.0-exp(-waterSunFade_sunHeight.y)); - float3 scatterColour = shLerp(vec3(SCATTER_COLOUR)*vec3(1.0,0.4,0.0), SCATTER_COLOUR, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT))); + float3 scatterColour = shLerp(float3(SCATTER_COLOUR)*float3(1.0,0.4,0.0), SCATTER_COLOUR, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT))); // fresnel float ior = (cameraPos.y>0)?(1.333/1.0):(1.0/1.333); //air to water; water to air @@ -284,7 +284,7 @@ waterGradient = clamp((waterGradient*0.5+0.5),0.2,1.0); float3 watercolour = (float3(0.0078, 0.5176, 0.700)+waterSunColour)*waterGradient*2.0; float3 waterext = float3(0.6, 0.9, 1.0);//water extinction - watercolour = mix(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT))); + watercolour = shLerp(watercolour*0.3*waterSunFade_sunHeight.x, watercolour, shSaturate(1.0-exp(-waterSunFade_sunHeight.y*SUN_EXT))); float darkness = VISIBILITY*2.0; darkness = clamp((cameraPos.y+darkness)/darkness,0.2,1.0); @@ -299,6 +299,7 @@ shOutputColour(0).xyz = shLerp (shOutputColour(0).xyz, fogColor, fogValue); } + shOutputColour(0).w = 1; } #endif diff --git a/files/materials/water.shaderset b/files/materials/water.shaderset index 754ac8e49..5e070a45a 100644 --- a/files/materials/water.shaderset +++ b/files/materials/water.shaderset @@ -3,7 +3,7 @@ shader_set water_vertex source water.shader type vertex profiles_cg vs_2_0 vp40 arbvp1 - profiles_hlsl vs_2_0 + profiles_hlsl vs_3_0 vs_2_0 } shader_set water_fragment @@ -11,5 +11,5 @@ shader_set water_fragment source water.shader type fragment profiles_cg ps_2_x ps_2_0 ps fp40 arbfp1 - profiles_hlsl ps_2_0 + profiles_hlsl ps_3_0 ps_2_0 } diff --git a/libs/openengine/ogre/renderer.cpp b/libs/openengine/ogre/renderer.cpp index e40bdf708..70bbf7940 100644 --- a/libs/openengine/ogre/renderer.cpp +++ b/libs/openengine/ogre/renderer.cpp @@ -11,6 +11,8 @@ #include +#include + #include #include #include @@ -111,17 +113,13 @@ void OgreRenderer::configure(const std::string &logPath, #endif } - std::string glPlugin = std::string(pluginDir) + "/RenderSystem_GL" + OGRE_PLUGIN_DEBUG_SUFFIX; - if (boost::filesystem::exists(glPlugin + ".so") || boost::filesystem::exists(glPlugin + ".dll")) - mRoot->loadPlugin (glPlugin); + boost::filesystem::path absPluginPath = boost::filesystem::absolute(boost::filesystem::path(pluginDir)); - std::string dxPlugin = std::string(pluginDir) + "/RenderSystem_Direct3D9" + OGRE_PLUGIN_DEBUG_SUFFIX; - if (boost::filesystem::exists(dxPlugin + ".so") || boost::filesystem::exists(dxPlugin + ".dll")) - mRoot->loadPlugin (dxPlugin); + pluginDir = absPluginPath.string(); - std::string cgPlugin = std::string(pluginDir) + "/Plugin_CgProgramManager" + OGRE_PLUGIN_DEBUG_SUFFIX; - if (boost::filesystem::exists(cgPlugin + ".so") || boost::filesystem::exists(cgPlugin + ".dll")) - mRoot->loadPlugin (cgPlugin); + Files::loadOgrePlugin(pluginDir, "RenderSystem_GL", *mRoot); + Files::loadOgrePlugin(pluginDir, "RenderSystem_Direct3D9", *mRoot); + Files::loadOgrePlugin(pluginDir, "Plugin_CgProgramManager", *mRoot); RenderSystem* rs = mRoot->getRenderSystemByName(renderSystem); if (rs == 0) @@ -143,7 +141,7 @@ void OgreRenderer::createWindow(const std::string &title, const WindowSettings& // create the semi-transparent black background texture used by the GUI. // has to be created in code with TU_DYNAMIC_WRITE_ONLY_DISCARDABLE param - // so that it can be modified at runtime. + // so that it can be modified at runtime. Ogre::TextureManager::getSingleton().createManual( "transparent.png", Ogre::ResourceGroupManager::DEFAULT_RESOURCE_GROUP_NAME,