actorid
Sebastian Wick 12 years ago
commit d364fd8561

@ -14,9 +14,8 @@ before_install:
- sudo apt-get install -qq libboost-all-dev libgtest-dev google-mock libzzip-dev - sudo apt-get install -qq libboost-all-dev libgtest-dev google-mock libzzip-dev
- sudo apt-get install -qq libqt4-dev libxaw7-dev libxrandr-dev libfreeimage-dev libpng-dev - sudo apt-get install -qq libqt4-dev libxaw7-dev libxrandr-dev libfreeimage-dev libpng-dev
- sudo apt-get install -qq libopenal-dev libmpg123-dev libsndfile1-dev - sudo apt-get install -qq libopenal-dev libmpg123-dev libsndfile1-dev
- sudo apt-get install -qq libcg nvidia-cg-toolkit
- sudo apt-get install -qq libavcodec-dev libavformat-dev libavdevice-dev libavutil-dev libswscale-dev libpostproc-dev - sudo apt-get install -qq libavcodec-dev libavformat-dev libavdevice-dev libavutil-dev libswscale-dev libpostproc-dev
- sudo apt-get install -qq libois-dev libbullet-dev libogre-static-dev libmygui-static-dev - sudo apt-get install -qq libbullet-dev libogre-static-dev libmygui-static-dev libsdl2-static-dev
- sudo mkdir /usr/src/gtest/build - sudo mkdir /usr/src/gtest/build
- cd /usr/src/gtest/build - cd /usr/src/gtest/build
- sudo cmake .. -DBUILD_SHARED_LIBS=1 - sudo cmake .. -DBUILD_SHARED_LIBS=1
@ -27,7 +26,7 @@ before_script:
- cd - - cd -
- mkdir build - mkdir build
- cd build - cd build
- cmake .. -DOGRE_STATIC=1 -DMYGUI_STATIC=1 -DBUILD_WITH_CODE_COVERAGE=1 -DBUILD_UNITTESTS=1 - cmake .. -DOGRE_STATIC=1 -DMYGUI_STATIC=1 -DBOOST_STATIC=1 -DSDL2_STATIC=1 -DBUILD_WITH_CODE_COVERAGE=1 -DBUILD_UNITTESTS=1
script: script:
- make -j4 - make -j4
after_script: after_script:

@ -31,6 +31,7 @@ configure_file ("${OpenMW_SOURCE_DIR}/Docs/mainpage.hpp.cmake" "${OpenMW_SOURCE_
option(MYGUI_STATIC "Link static build of Mygui into the binaries" FALSE) option(MYGUI_STATIC "Link static build of Mygui into the binaries" FALSE)
option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binaries" FALSE) option(OGRE_STATIC "Link static build of Ogre and Ogre Plugins into the binaries" FALSE)
option(BOOST_STATIC "Link static build of Boost into the binaries" FALSE) option(BOOST_STATIC "Link static build of Boost into the binaries" FALSE)
option(SDL2_STATIC "Link static build of SDL into the binaries" FALSE)
# Apps and tools # Apps and tools
option(BUILD_BSATOOL "build BSA extractor" OFF) option(BUILD_BSATOOL "build BSA extractor" OFF)

@ -612,8 +612,21 @@ void MainDialog::closeEvent(QCloseEvent *event)
void MainDialog::play() void MainDialog::play()
{ {
if (!writeSettings()) if (!writeSettings()) {
qApp->quit(); qApp->quit();
return;
}
if(!mGameSettings.hasMaster()) {
QMessageBox msgBox;
msgBox.setWindowTitle(tr("No master file selected"));
msgBox.setIcon(QMessageBox::Warning);
msgBox.setStandardButtons(QMessageBox::Ok);
msgBox.setText(tr("<br><b>You do not have any master files selected.</b><br><br> \
OpenMW will not start without a master file selected.<br>"));
msgBox.exec();
return;
}
// Launch the game detached // Launch the game detached
startProgram(QString("openmw"), true); startProgram(QString("openmw"), true);

@ -43,6 +43,7 @@ public:
inline QStringList getDataDirs() { return mDataDirs; } inline QStringList getDataDirs() { return mDataDirs; }
inline void addDataDir(const QString &dir) { if(!dir.isEmpty()) mDataDirs.append(dir); } inline void addDataDir(const QString &dir) { if(!dir.isEmpty()) mDataDirs.append(dir); }
inline QString getDataLocal() {return mDataLocal; } inline QString getDataLocal() {return mDataLocal; }
inline bool hasMaster() { return mSettings.count(QString("master")) > 0; }
QStringList values(const QString &key, const QStringList &defaultValues = QStringList()); QStringList values(const QString &key, const QStringList &defaultValues = QStringList());
bool readFile(QTextStream &stream); bool readFile(QTextStream &stream);

@ -645,7 +645,7 @@ std::string MwIniImporter::numberToString(int n) {
return str.str(); return str.str();
} }
MwIniImporter::multistrmap MwIniImporter::loadIniFile(std::string filename) { MwIniImporter::multistrmap MwIniImporter::loadIniFile(const std::string& filename) const {
std::cout << "load ini file: " << filename << std::endl; std::cout << "load ini file: " << filename << std::endl;
std::string section(""); std::string section("");
@ -701,7 +701,7 @@ MwIniImporter::multistrmap MwIniImporter::loadIniFile(std::string filename) {
return map; return map;
} }
MwIniImporter::multistrmap MwIniImporter::loadCfgFile(std::string filename) { MwIniImporter::multistrmap MwIniImporter::loadCfgFile(const std::string& filename) {
std::cout << "load cfg file: " << filename << std::endl; std::cout << "load cfg file: " << filename << std::endl;
MwIniImporter::multistrmap map; MwIniImporter::multistrmap map;
@ -738,12 +738,11 @@ MwIniImporter::multistrmap MwIniImporter::loadCfgFile(std::string filename) {
return map; return map;
} }
void MwIniImporter::merge(multistrmap &cfg, multistrmap &ini) { void MwIniImporter::merge(multistrmap &cfg, const multistrmap &ini) const {
multistrmap::iterator cfgIt; multistrmap::const_iterator iniIt;
multistrmap::iterator iniIt; for(strmap::const_iterator it=mMergeMap.begin(); it!=mMergeMap.end(); ++it) {
for(strmap::iterator it=mMergeMap.begin(); it!=mMergeMap.end(); ++it) {
if((iniIt = ini.find(it->second)) != ini.end()) { if((iniIt = ini.find(it->second)) != ini.end()) {
for(std::vector<std::string>::iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); ++vc) { for(std::vector<std::string>::const_iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); ++vc) {
cfg.erase(it->first); cfg.erase(it->first);
insertMultistrmap(cfg, it->first, *vc); insertMultistrmap(cfg, it->first, *vc);
} }
@ -751,14 +750,13 @@ void MwIniImporter::merge(multistrmap &cfg, multistrmap &ini) {
} }
} }
void MwIniImporter::mergeFallback(multistrmap &cfg, multistrmap &ini) { void MwIniImporter::mergeFallback(multistrmap &cfg, const multistrmap &ini) const {
cfg.erase("fallback"); cfg.erase("fallback");
multistrmap::iterator cfgIt; multistrmap::const_iterator iniIt;
multistrmap::iterator iniIt; for(std::vector<std::string>::const_iterator it=mMergeFallback.begin(); it!=mMergeFallback.end(); ++it) {
for(std::vector<std::string>::iterator it=mMergeFallback.begin(); it!=mMergeFallback.end(); ++it) {
if((iniIt = ini.find(*it)) != ini.end()) { if((iniIt = ini.find(*it)) != ini.end()) {
for(std::vector<std::string>::iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); ++vc) { for(std::vector<std::string>::const_iterator vc = iniIt->second.begin(); vc != iniIt->second.end(); ++vc) {
std::string value(*it); std::string value(*it);
std::replace( value.begin(), value.end(), ' ', '_' ); std::replace( value.begin(), value.end(), ' ', '_' );
std::replace( value.begin(), value.end(), ':', '_' ); std::replace( value.begin(), value.end(), ':', '_' );
@ -769,21 +767,21 @@ void MwIniImporter::mergeFallback(multistrmap &cfg, multistrmap &ini) {
} }
} }
void MwIniImporter::insertMultistrmap(multistrmap &cfg, std::string key, std::string value) { void MwIniImporter::insertMultistrmap(multistrmap &cfg, const std::string& key, const std::string& value) {
multistrmap::iterator it = cfg.find(key); const multistrmap::const_iterator it = cfg.find(key);
if(it == cfg.end()) { if(it == cfg.end()) {
cfg.insert(std::make_pair (key, std::vector<std::string>() )); cfg.insert(std::make_pair (key, std::vector<std::string>() ));
} }
cfg[key].push_back(value); cfg[key].push_back(value);
} }
void MwIniImporter::importArchives(multistrmap &cfg, multistrmap &ini) { void MwIniImporter::importArchives(multistrmap &cfg, const multistrmap &ini) const {
std::vector<std::string> archives; std::vector<std::string> archives;
std::string baseArchive("Archives:Archive "); std::string baseArchive("Archives:Archive ");
std::string archive; std::string archive;
// Search archives listed in ini file // Search archives listed in ini file
multistrmap::iterator it = ini.begin(); multistrmap::const_iterator it = ini.begin();
for(int i=0; it != ini.end(); i++) { for(int i=0; it != ini.end(); i++) {
archive = baseArchive; archive = baseArchive;
archive.append(this->numberToString(i)); archive.append(this->numberToString(i));
@ -793,7 +791,7 @@ void MwIniImporter::importArchives(multistrmap &cfg, multistrmap &ini) {
break; break;
} }
for(std::vector<std::string>::iterator entry = it->second.begin(); entry!=it->second.end(); ++entry) { for(std::vector<std::string>::const_iterator entry = it->second.begin(); entry!=it->second.end(); ++entry) {
archives.push_back(*entry); archives.push_back(*entry);
} }
} }
@ -805,18 +803,18 @@ void MwIniImporter::importArchives(multistrmap &cfg, multistrmap &ini) {
// does not appears in the ini file // does not appears in the ini file
cfg["fallback-archive"].push_back("Morrowind.bsa"); cfg["fallback-archive"].push_back("Morrowind.bsa");
for(std::vector<std::string>::iterator it=archives.begin(); it!=archives.end(); ++it) { for(std::vector<std::string>::const_iterator it=archives.begin(); it!=archives.end(); ++it) {
cfg["fallback-archive"].push_back(*it); cfg["fallback-archive"].push_back(*it);
} }
} }
void MwIniImporter::importGameFiles(multistrmap &cfg, multistrmap &ini) { void MwIniImporter::importGameFiles(multistrmap &cfg, const multistrmap &ini) const {
std::vector<std::string> esmFiles; std::vector<std::string> esmFiles;
std::vector<std::string> espFiles; std::vector<std::string> espFiles;
std::string baseGameFile("Game Files:GameFile"); std::string baseGameFile("Game Files:GameFile");
std::string gameFile(""); std::string gameFile("");
multistrmap::iterator it = ini.begin(); multistrmap::const_iterator it = ini.begin();
for(int i=0; it != ini.end(); i++) { for(int i=0; it != ini.end(); i++) {
gameFile = baseGameFile; gameFile = baseGameFile;
gameFile.append(this->numberToString(i)); gameFile.append(this->numberToString(i));
@ -826,7 +824,7 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, multistrmap &ini) {
break; break;
} }
for(std::vector<std::string>::iterator entry = it->second.begin(); entry!=it->second.end(); ++entry) { for(std::vector<std::string>::const_iterator entry = it->second.begin(); entry!=it->second.end(); ++entry) {
std::string filetype(entry->substr(entry->length()-3)); std::string filetype(entry->substr(entry->length()-3));
Misc::StringUtils::toLower(filetype); Misc::StringUtils::toLower(filetype);
@ -844,22 +842,22 @@ void MwIniImporter::importGameFiles(multistrmap &cfg, multistrmap &ini) {
cfg.erase("master"); cfg.erase("master");
cfg.insert( std::make_pair<std::string, std::vector<std::string> > ("master", std::vector<std::string>() ) ); cfg.insert( std::make_pair<std::string, std::vector<std::string> > ("master", std::vector<std::string>() ) );
for(std::vector<std::string>::iterator it=esmFiles.begin(); it!=esmFiles.end(); ++it) { for(std::vector<std::string>::const_iterator it=esmFiles.begin(); it!=esmFiles.end(); ++it) {
cfg["master"].push_back(*it); cfg["master"].push_back(*it);
} }
cfg.erase("plugin"); cfg.erase("plugin");
cfg.insert( std::make_pair<std::string, std::vector<std::string> > ("plugin", std::vector<std::string>() ) ); cfg.insert( std::make_pair<std::string, std::vector<std::string> > ("plugin", std::vector<std::string>() ) );
for(std::vector<std::string>::iterator it=espFiles.begin(); it!=espFiles.end(); ++it) { for(std::vector<std::string>::const_iterator it=espFiles.begin(); it!=espFiles.end(); ++it) {
cfg["plugin"].push_back(*it); cfg["plugin"].push_back(*it);
} }
} }
void MwIniImporter::writeToFile(boost::iostreams::stream<boost::iostreams::file_sink> &out, multistrmap &cfg) { void MwIniImporter::writeToFile(boost::iostreams::stream<boost::iostreams::file_sink> &out, const multistrmap &cfg) {
for(multistrmap::iterator it=cfg.begin(); it != cfg.end(); ++it) { for(multistrmap::const_iterator it=cfg.begin(); it != cfg.end(); ++it) {
for(std::vector<std::string>::iterator entry=it->second.begin(); entry != it->second.end(); ++entry) { for(std::vector<std::string>::const_iterator entry=it->second.begin(); entry != it->second.end(); ++entry) {
out << (it->first) << "=" << (*entry) << std::endl; out << (it->first) << "=" << (*entry) << std::endl;
} }
} }

@ -18,18 +18,17 @@ class MwIniImporter {
MwIniImporter(); MwIniImporter();
void setInputEncoding(const ToUTF8::FromType& encoding); void setInputEncoding(const ToUTF8::FromType& encoding);
void setVerbose(bool verbose); void setVerbose(bool verbose);
multistrmap loadIniFile(std::string filename); multistrmap loadIniFile(const std::string& filename) const;
multistrmap loadCfgFile(std::string filename); static multistrmap loadCfgFile(const std::string& filename);
void merge(multistrmap &cfg, multistrmap &ini); void merge(multistrmap &cfg, const multistrmap &ini) const;
void mergeFallback(multistrmap &cfg, multistrmap &ini); void mergeFallback(multistrmap &cfg, const multistrmap &ini) const;
void importGameFiles(multistrmap &cfg, multistrmap &ini); void importGameFiles(multistrmap &cfg, const multistrmap &ini) const;
void importArchives(multistrmap &cfg, multistrmap &ini); void importArchives(multistrmap &cfg, const multistrmap &ini) const;
void writeToFile(boost::iostreams::stream<boost::iostreams::file_sink> &out, multistrmap &cfg); static void writeToFile(boost::iostreams::stream<boost::iostreams::file_sink> &out, const multistrmap &cfg);
private: private:
void insertMultistrmap(multistrmap &cfg, std::string key, std::string value); static void insertMultistrmap(multistrmap &cfg, const std::string& key, const std::string& value);
std::string numberToString(int n); static std::string numberToString(int n);
std::string toUTF8(const std::string &str);
bool mVerbose; bool mVerbose;
strmap mMergeMap; strmap mMergeMap;
std::vector<std::string> mMergeFallback; std::vector<std::string> mMergeFallback;

@ -55,10 +55,8 @@ int main(int argc, char *argv[]) {
std::cerr << "ini file does not exist" << std::endl; std::cerr << "ini file does not exist" << std::endl;
return -3; return -3;
} }
if(!boost::filesystem::exists(cfgFile)) { if(!boost::filesystem::exists(cfgFile))
std::cerr << "cfg file does not exist" << std::endl; std::cerr << "cfg file does not exist" << std::endl;
return -4;
}
MwIniImporter importer; MwIniImporter importer;
importer.setVerbose(vm.count("verbose")); importer.setVerbose(vm.count("verbose"));

@ -133,7 +133,6 @@ bool OMW::Engine::frameRenderingQueued (const Ogre::FrameEvent& evt)
OMW::Engine::Engine(Files::ConfigurationManager& configurationManager) OMW::Engine::Engine(Files::ConfigurationManager& configurationManager)
: mOgre (0) : mOgre (0)
, mFpsLevel(0) , mFpsLevel(0)
, mDebug (false)
, mVerboseScripts (false) , mVerboseScripts (false)
, mNewGame (false) , mNewGame (false)
, mUseSound (true) , mUseSound (true)
@ -283,11 +282,6 @@ void OMW::Engine::addPlugin (const std::string& plugin)
} }
} }
void OMW::Engine::setDebugMode(bool debugMode)
{
mDebug = debugMode;
}
void OMW::Engine::setScriptsVerbosity(bool scriptsVerbosity) void OMW::Engine::setScriptsVerbosity(bool scriptsVerbosity)
{ {
mVerboseScripts = scriptsVerbosity; mVerboseScripts = scriptsVerbosity;
@ -331,7 +325,6 @@ std::string OMW::Engine::loadSettings (Settings::Manager & settings)
nifOverrides.loadTransparencyOverrides(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg"); nifOverrides.loadTransparencyOverrides(mCfgMgr.getGlobalPath().string() + "/transparency-overrides.cfg");
settings.setBool("hardware cursors", "GUI", true); settings.setBool("hardware cursors", "GUI", true);
settings.setBool("debug", "Engine", mDebug);
return settingspath; return settingspath;
} }

@ -71,7 +71,6 @@ namespace OMW
std::vector<std::string> mMaster; std::vector<std::string> mMaster;
std::vector<std::string> mPlugins; std::vector<std::string> mPlugins;
int mFpsLevel; int mFpsLevel;
bool mDebug;
bool mVerboseScripts; bool mVerboseScripts;
bool mNewGame; bool mNewGame;
bool mUseSound; bool mUseSound;
@ -147,10 +146,6 @@ namespace OMW
/// Enable fps counter /// Enable fps counter
void showFPS(int level); void showFPS(int level);
/// Enable debug mode:
/// - non-exclusive input
void setDebugMode(bool debugMode);
/// Enable or disable verbose script output /// Enable or disable verbose script output
void setScriptsVerbosity(bool scriptsVerbosity); void setScriptsVerbosity(bool scriptsVerbosity);

@ -118,9 +118,6 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
("anim-verbose", bpo::value<bool>()->implicit_value(true) ("anim-verbose", bpo::value<bool>()->implicit_value(true)
->default_value(false), "output animation indices files") ->default_value(false), "output animation indices files")
("debug", bpo::value<bool>()->implicit_value(true)
->default_value(false), "debug mode")
("nosound", bpo::value<bool>()->implicit_value(true) ("nosound", bpo::value<bool>()->implicit_value(true)
->default_value(false), "disable all sounds") ->default_value(false), "disable all sounds")
@ -217,8 +214,8 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
StringsVector master = variables["master"].as<StringsVector>(); StringsVector master = variables["master"].as<StringsVector>();
if (master.empty()) if (master.empty())
{ {
std::cout << "No master file given. Assuming Morrowind.esm" << std::endl; std::cout << "No master file given. Aborting...\n";
master.push_back("Morrowind"); return false;
} }
StringsVector plugin = variables["plugin"].as<StringsVector>(); StringsVector plugin = variables["plugin"].as<StringsVector>();
@ -243,7 +240,6 @@ bool parseOptions (int argc, char** argv, OMW::Engine& engine, Files::Configurat
engine.setNewGame(variables["new-game"].as<bool>()); engine.setNewGame(variables["new-game"].as<bool>());
// other settings // other settings
engine.setDebugMode(variables["debug"].as<bool>());
engine.setSoundUsage(!variables["nosound"].as<bool>()); engine.setSoundUsage(!variables["nosound"].as<bool>());
engine.setScriptsVerbosity(variables["script-verbose"].as<bool>()); engine.setScriptsVerbosity(variables["script-verbose"].as<bool>());
engine.setCompileAll(variables["script-all"].as<bool>()); engine.setCompileAll(variables["script-all"].as<bool>());

@ -264,6 +264,8 @@ namespace MWBase
virtual void changePointer (const std::string& name) = 0; virtual void changePointer (const std::string& name) = 0;
virtual const Translation::Storage& getTranslationDataStorage() const = 0; virtual const Translation::Storage& getTranslationDataStorage() const = 0;
virtual void setKeyFocusWidget (MyGUI::Widget* widget) = 0;
}; };
} }

@ -407,7 +407,7 @@ namespace MWGui
getWidget(mEditName, "EditName"); getWidget(mEditName, "EditName");
// Make sure the edit box has focus // Make sure the edit box has focus
MyGUI::InputManager::getInstance().setKeyFocusWidget(mEditName); MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mEditName);
MyGUI::Button* descriptionButton; MyGUI::Button* descriptionButton;
getWidget(descriptionButton, "DescriptionButton"); getWidget(descriptionButton, "DescriptionButton");
@ -866,7 +866,7 @@ namespace MWGui
okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sInputMenu1", "")); okButton->setCaption(MWBase::Environment::get().getWindowManager()->getGameSettingString("sInputMenu1", ""));
// Make sure the edit box has focus // Make sure the edit box has focus
MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit); MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTextEdit);
} }
DescriptionDialog::~DescriptionDialog() DescriptionDialog::~DescriptionDialog()

@ -5,6 +5,7 @@
#include "../mwscript/extensions.hpp" #include "../mwscript/extensions.hpp"
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
namespace MWGui namespace MWGui
{ {
@ -131,16 +132,12 @@ namespace MWGui
// Give keyboard focus to the combo box whenever the console is // Give keyboard focus to the combo box whenever the console is
// turned on // turned on
MyGUI::InputManager::getInstance().setKeyFocusWidget(command); MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(command);
} }
void Console::disable() void Console::disable()
{ {
setVisible(false); setVisible(false);
// Remove keyboard focus from the console input whenever the
// console is turned off
MyGUI::InputManager::getInstance().setKeyFocusWidget(NULL);
} }
void Console::setFont(const std::string &fntName) void Console::setFont(const std::string &fntName)
@ -415,7 +412,7 @@ namespace MWGui
setTitle("#{sConsoleTitle}"); setTitle("#{sConsoleTitle}");
mPtr = MWWorld::Ptr(); mPtr = MWWorld::Ptr();
} }
MyGUI::InputManager::getInstance().setKeyFocusWidget(command); MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(command);
} }
void Console::onReferenceUnavailable() void Console::onReferenceUnavailable()

@ -2,6 +2,9 @@
#include <boost/lexical_cast.hpp> #include <boost/lexical_cast.hpp>
#include "../mwbase/environment.hpp"
#include "../mwbase/windowmanager.hpp"
namespace MWGui namespace MWGui
{ {
CountDialog::CountDialog() : CountDialog::CountDialog() :
@ -40,7 +43,7 @@ namespace MWGui
mMainWidget->getHeight()); mMainWidget->getHeight());
// by default, the text edit field has the focus of the keyboard // by default, the text edit field has the focus of the keyboard
MyGUI::InputManager::getInstance().setKeyFocusWidget(mItemEdit); MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mItemEdit);
mSlider->setScrollPosition(maxCount-1); mSlider->setScrollPosition(maxCount-1);
mItemEdit->setCaption(boost::lexical_cast<std::string>(maxCount)); mItemEdit->setCaption(boost::lexical_cast<std::string>(maxCount));

@ -7,6 +7,7 @@
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/mechanicsmanager.hpp" #include "../mwbase/mechanicsmanager.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/soundmanager.hpp"
#include "../mwmechanics/npcstats.hpp" #include "../mwmechanics/npcstats.hpp"
@ -224,16 +225,22 @@ namespace MWGui
void Choice::activated() void Choice::activated()
{ {
MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.0, 1.0);
MWBase::Environment::get().getDialogueManager()->questionAnswered(mChoiceId); MWBase::Environment::get().getDialogueManager()->questionAnswered(mChoiceId);
} }
void Topic::activated() void Topic::activated()
{ {
MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f);
MWBase::Environment::get().getDialogueManager()->keywordSelected(Misc::StringUtils::lowerCase(mTopicId)); MWBase::Environment::get().getDialogueManager()->keywordSelected(Misc::StringUtils::lowerCase(mTopicId));
} }
void Goodbye::activated() void Goodbye::activated()
{ {
MWBase::Environment::get().getSoundManager()->playSound("Menu Click", 1.f, 1.f);
MWBase::Environment::get().getDialogueManager()->goodbyeSelected(); MWBase::Environment::get().getDialogueManager()->goodbyeSelected();
} }
@ -467,11 +474,12 @@ namespace MWGui
BookTypesetter::Style* body = typesetter->createStyle("", MyGUI::Colour::White); BookTypesetter::Style* body = typesetter->createStyle("", MyGUI::Colour::White);
typesetter->sectionBreak(9);
// choices // choices
const MyGUI::Colour linkHot (223/255.f, 201/255.f, 159/255.f); const MyGUI::Colour linkHot (223/255.f, 201/255.f, 159/255.f);
const MyGUI::Colour linkNormal (150/255.f, 50/255.f, 30/255.f); const MyGUI::Colour linkNormal (150/255.f, 50/255.f, 30/255.f);
const MyGUI::Colour linkActive (243/255.f, 237/255.f, 221/255.f); const MyGUI::Colour linkActive (243/255.f, 237/255.f, 221/255.f);
for (std::map<std::string, int>::iterator it = mChoices.begin(); it != mChoices.end(); ++it) for (std::map<std::string, int>::reverse_iterator it = mChoices.rbegin(); it != mChoices.rend(); ++it)
{ {
Choice* link = new Choice(it->second); Choice* link = new Choice(it->second);
mLinks.push_back(link); mLinks.push_back(link);

@ -10,6 +10,7 @@
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
#include "../mwbase/windowmanager.hpp" #include "../mwbase/windowmanager.hpp"
#include "../mwbase/inputmanager.hpp"
namespace MWGui namespace MWGui
{ {
@ -126,7 +127,7 @@ namespace MWGui
// always update input before rendering something, otherwise mygui goes crazy when something was entered in the frame before // always update input before rendering something, otherwise mygui goes crazy when something was entered in the frame before
// (e.g. when using "coc" console command, it would enter an infinite loop and crash due to overflow) // (e.g. when using "coc" console command, it would enter an infinite loop and crash due to overflow)
//MWBase::Environment::get().getInputManager()->update(0, true); MWBase::Environment::get().getInputManager()->update(0, true);
Ogre::CompositorChain* chain = Ogre::CompositorManager::getSingleton().getCompositorChain(mWindow->getViewport(0)); Ogre::CompositorChain* chain = Ogre::CompositorManager::getSingleton().getCompositorChain(mWindow->getViewport(0));

@ -20,7 +20,7 @@ namespace MWGui
okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TextInputDialog::onOkClicked); okButton->eventMouseButtonClick += MyGUI::newDelegate(this, &TextInputDialog::onOkClicked);
// Make sure the edit box has focus // Make sure the edit box has focus
MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit); MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTextEdit);
} }
void TextInputDialog::setNextButtonShow(bool shown) void TextInputDialog::setNextButtonShow(bool shown)
@ -43,7 +43,7 @@ namespace MWGui
{ {
WindowModal::open(); WindowModal::open();
// Make sure the edit box has focus // Make sure the edit box has focus
MyGUI::InputManager::getInstance().setKeyFocusWidget(mTextEdit); MWBase::Environment::get().getWindowManager()->setKeyFocusWidget(mTextEdit);
} }
// widget controls // widget controls
@ -53,7 +53,7 @@ namespace MWGui
if (mTextEdit->getCaption() == "") if (mTextEdit->getCaption() == "")
{ {
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage37}"); MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage37}");
MyGUI::InputManager::getInstance ().setKeyFocusWidget (mTextEdit); MWBase::Environment::get().getWindowManager()->setKeyFocusWidget (mTextEdit);
} }
else else
eventDone(this); eventDone(this);
@ -64,7 +64,7 @@ namespace MWGui
if (mTextEdit->getCaption() == "") if (mTextEdit->getCaption() == "")
{ {
MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage37}"); MWBase::Environment::get().getWindowManager()->messageBox ("#{sNotifyMessage37}");
MyGUI::InputManager::getInstance ().setKeyFocusWidget (mTextEdit); MWBase::Environment::get().getWindowManager()->setKeyFocusWidget (mTextEdit);
} }
else else
eventDone(this); eventDone(this);

@ -18,7 +18,6 @@ namespace MWGui
ToolTips::ToolTips() : ToolTips::ToolTips() :
Layout("openmw_tooltips.layout") Layout("openmw_tooltips.layout")
, mGameMode(true)
, mFullHelp(false) , mFullHelp(false)
, mEnabled(true) , mEnabled(true)
, mFocusToolTipX(0.0) , mFocusToolTipX(0.0)
@ -73,7 +72,9 @@ namespace MWGui
return; return;
} }
if (!mGameMode) bool gameMode = MWBase::Environment::get().getWindowManager()->isGuiMode();
if (gameMode)
{ {
const MyGUI::IntPoint& mousePos = MyGUI::InputManager::getInstance().getMousePosition(); const MyGUI::IntPoint& mousePos = MyGUI::InputManager::getInstance().getMousePosition();
@ -297,16 +298,6 @@ namespace MWGui
} }
} }
void ToolTips::enterGameMode()
{
mGameMode = true;
}
void ToolTips::enterGuiMode()
{
mGameMode = false;
}
void ToolTips::setFocusObject(const MWWorld::Ptr& focus) void ToolTips::setFocusObject(const MWWorld::Ptr& focus)
{ {
mFocusObject = focus; mFocusObject = focus;

@ -43,9 +43,6 @@ namespace MWGui
void onFrame(float frameDuration); void onFrame(float frameDuration);
void enterGameMode();
void enterGuiMode();
void setEnabled(bool enabled); void setEnabled(bool enabled);
void toggleFullHelp(); ///< show extra info in item tooltips (owner, script) void toggleFullHelp(); ///< show extra info in item tooltips (owner, script)
@ -104,8 +101,6 @@ namespace MWGui
int mLastMouseX; int mLastMouseX;
int mLastMouseY; int mLastMouseY;
bool mGameMode;
bool mEnabled; bool mEnabled;
bool mFullHelp; bool mFullHelp;

@ -221,10 +221,12 @@ namespace MWGui
unsetSelectedWeapon(); unsetSelectedWeapon();
//set up the hardware cursor manager //set up the hardware cursor manager
mCursorManager = new SFO::SDLCursorManager(Settings::Manager::getBool("debug", "Engine")); mCursorManager = new SFO::SDLCursorManager();
MyGUI::PointerManager::getInstance().eventChangeMousePointer += MyGUI::newDelegate(this, &WindowManager::onCursorChange); MyGUI::PointerManager::getInstance().eventChangeMousePointer += MyGUI::newDelegate(this, &WindowManager::onCursorChange);
MyGUI::InputManager::getInstance().eventChangeKeyFocus += MyGUI::newDelegate(this, &WindowManager::onKeyFocusChanged);
setUseHardwareCursors(mUseHardwareCursors); setUseHardwareCursors(mUseHardwareCursors);
onCursorChange(MyGUI::PointerManager::getInstance().getDefaultPointer()); onCursorChange(MyGUI::PointerManager::getInstance().getDefaultPointer());
mCursorManager->cursorVisibilityChange(false); mCursorManager->cursorVisibilityChange(false);
@ -355,12 +357,7 @@ namespace MWGui
setCursorVisible(!gameMode); setCursorVisible(!gameMode);
if (gameMode) if (gameMode)
mToolTips->enterGameMode(); setKeyFocusWidget (NULL);
else
mToolTips->enterGuiMode();
if (gameMode)
MyGUI::InputManager::getInstance ().setKeyFocusWidget (NULL);
setMinimapVisibility((mAllowed & GW_Map) && !mMap->pinned()); setMinimapVisibility((mAllowed & GW_Map) && !mMap->pinned());
setWeaponVisibility((mAllowed & GW_Inventory) && !mInventoryWindow->pinned()); setWeaponVisibility((mAllowed & GW_Inventory) && !mInventoryWindow->pinned());
@ -1299,4 +1296,21 @@ namespace MWGui
mInventoryWindow->updatePlayer(); mInventoryWindow->updatePlayer();
} }
void WindowManager::setKeyFocusWidget(MyGUI::Widget *widget)
{
if (widget == NULL)
MyGUI::InputManager::getInstance().resetKeyFocusWidget();
else
MyGUI::InputManager::getInstance().setKeyFocusWidget(widget);
onKeyFocusChanged(widget);
}
void WindowManager::onKeyFocusChanged(MyGUI::Widget *widget)
{
if (widget && widget->castType<MyGUI::EditBox>(false))
SDL_StartTextInput();
else
SDL_StopTextInput();
}
} }

@ -98,6 +98,8 @@ namespace MWGui
*/ */
virtual void update(); virtual void update();
virtual void setKeyFocusWidget (MyGUI::Widget* widget);
virtual void setNewGame(bool newgame); virtual void setNewGame(bool newgame);
virtual void pushGuiMode(GuiMode mode); virtual void pushGuiMode(GuiMode mode);
@ -353,6 +355,7 @@ namespace MWGui
void onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result); void onRetrieveTag(const MyGUI::UString& _tag, MyGUI::UString& _result);
void onCursorChange(const std::string& name); void onCursorChange(const std::string& name);
void onKeyFocusChanged(MyGUI::Widget* widget);
}; };
} }

@ -23,6 +23,65 @@
using namespace ICS; using namespace ICS;
namespace
{
std::vector<unsigned long> utf8ToUnicode(const std::string& utf8)
{
std::vector<unsigned long> unicode;
size_t i = 0;
while (i < utf8.size())
{
unsigned long uni;
size_t todo;
unsigned char ch = utf8[i++];
if (ch <= 0x7F)
{
uni = ch;
todo = 0;
}
else if (ch <= 0xBF)
{
throw std::logic_error("not a UTF-8 string");
}
else if (ch <= 0xDF)
{
uni = ch&0x1F;
todo = 1;
}
else if (ch <= 0xEF)
{
uni = ch&0x0F;
todo = 2;
}
else if (ch <= 0xF7)
{
uni = ch&0x07;
todo = 3;
}
else
{
throw std::logic_error("not a UTF-8 string");
}
for (size_t j = 0; j < todo; ++j)
{
if (i == utf8.size())
throw std::logic_error("not a UTF-8 string");
unsigned char ch = utf8[i++];
if (ch < 0x80 || ch > 0xBF)
throw std::logic_error("not a UTF-8 string");
uni <<= 6;
uni += ch & 0x3F;
}
if (uni >= 0xD800 && uni <= 0xDFFF)
throw std::logic_error("not a UTF-8 string");
if (uni > 0x10FFFF)
throw std::logic_error("not a UTF-8 string");
unicode.push_back(uni);
}
return unicode;
}
}
namespace MWInput namespace MWInput
{ {
InputManager::InputManager(OEngine::Render::OgreRenderer &ogre, InputManager::InputManager(OEngine::Render::OgreRenderer &ogre,
@ -40,7 +99,6 @@ namespace MWInput
, mMouseWheel(0) , mMouseWheel(0)
, mDragDrop(false) , mDragDrop(false)
, mGuiCursorEnabled(false) , mGuiCursorEnabled(false)
, mDebug(Settings::Manager::getBool("debug", "Engine"))
, mUserFile(userFile) , mUserFile(userFile)
, mUserFileExists(userFileExists) , mUserFileExists(userFileExists)
, mInvertY (Settings::Manager::getBool("invert y axis", "Input")) , mInvertY (Settings::Manager::getBool("invert y axis", "Input"))
@ -213,26 +271,23 @@ namespace MWInput
// event callbacks (which may crash) // event callbacks (which may crash)
mWindows.update(); mWindows.update();
if(!mDebug) bool main_menu = mWindows.containsMode(MWGui::GM_MainMenu);
{
bool main_menu = mWindows.containsMode(MWGui::GM_MainMenu);
bool was_relative = mInputManager->getMouseRelative(); bool was_relative = mInputManager->getMouseRelative();
bool is_relative = !mWindows.isGuiMode(); bool is_relative = !mWindows.isGuiMode();
// don't keep the pointer away from the window edge in gui mode // don't keep the pointer away from the window edge in gui mode
// stop using raw mouse motions and switch to system cursor movements // stop using raw mouse motions and switch to system cursor movements
mInputManager->setMouseRelative(is_relative); mInputManager->setMouseRelative(is_relative);
//we let the mouse escape in the main menu //we let the mouse escape in the main menu
mInputManager->setGrabPointer(!main_menu); mInputManager->setGrabPointer(!main_menu);
//we switched to non-relative mode, move our cursor to where the in-game //we switched to non-relative mode, move our cursor to where the in-game
//cursor is //cursor is
if( !is_relative && was_relative != is_relative ) if( !is_relative && was_relative != is_relative )
{ {
mInputManager->warpMouse(mMouseX, mMouseY); mInputManager->warpMouse(mMouseX, mMouseY);
}
} }
// Disable movement in Gui mode // Disable movement in Gui mode
@ -349,6 +404,7 @@ namespace MWInput
mMouseLookEnabled = !guiMode; mMouseLookEnabled = !guiMode;
if (guiMode) if (guiMode)
mWindows.showCrosshair(false); mWindows.showCrosshair(false);
mWindows.setCursorVisible(guiMode);
// if not in gui mode, the camera decides whether to show crosshair or not. // if not in gui mode, the camera decides whether to show crosshair or not.
} }
@ -411,7 +467,6 @@ namespace MWInput
bool InputManager::keyPressed( const SDL_KeyboardEvent &arg ) bool InputManager::keyPressed( const SDL_KeyboardEvent &arg )
{ {
mInputBinder->keyPressed (arg); mInputBinder->keyPressed (arg);
unsigned int text = arg.keysym.unicode;
if(arg.keysym.sym == SDLK_RETURN if(arg.keysym.sym == SDLK_RETURN
&& MWBase::Environment::get().getWindowManager()->isGuiMode()) && MWBase::Environment::get().getWindowManager()->isGuiMode())
@ -422,11 +477,19 @@ namespace MWInput
OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym); OIS::KeyCode kc = mInputManager->sdl2OISKeyCode(arg.keysym.sym);
MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), text); if (kc != OIS::KC_UNASSIGNED)
MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::Enum(kc), 0);
return true; return true;
} }
void InputManager::textInput(const SDL_TextInputEvent &arg)
{
const char* text = &arg.text[0];
std::vector<unsigned long> unicode = utf8ToUnicode(std::string(text));
for (std::vector<unsigned long>::iterator it = unicode.begin(); it != unicode.end(); ++it)
MyGUI::InputManager::getInstance().injectKeyPress(MyGUI::KeyCode::None, *it);
}
bool InputManager::keyReleased(const SDL_KeyboardEvent &arg ) bool InputManager::keyReleased(const SDL_KeyboardEvent &arg )
{ {
mInputBinder->keyReleased (arg); mInputBinder->keyReleased (arg);
@ -530,19 +593,12 @@ namespace MWInput
bool InputManager::windowFocusChange(bool have_focus) bool InputManager::windowFocusChange(bool have_focus)
{ {
if(!mDebug)
{
}
return true; return true;
} }
bool InputManager::windowVisibilityChange(bool visible) bool InputManager::windowVisibilityChange(bool visible)
{ {
if(!mDebug)
{
//TODO: Pause game? //TODO: Pause game?
}
return true; return true;
} }

@ -88,6 +88,7 @@ namespace MWInput
public: public:
virtual bool keyPressed(const SDL_KeyboardEvent &arg ); virtual bool keyPressed(const SDL_KeyboardEvent &arg );
virtual bool keyReleased( const SDL_KeyboardEvent &arg ); virtual bool keyReleased( const SDL_KeyboardEvent &arg );
virtual void textInput (const SDL_TextInputEvent &arg);
virtual bool mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id ); virtual bool mousePressed( const SDL_MouseButtonEvent &arg, Uint8 id );
virtual bool mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id ); virtual bool mouseReleased( const SDL_MouseButtonEvent &arg, Uint8 id );
@ -146,7 +147,6 @@ namespace MWInput
bool mMouseLookEnabled; bool mMouseLookEnabled;
bool mGuiCursorEnabled; bool mGuiCursorEnabled;
bool mDebug;
float mOverencumberedMessageDelay; float mOverencumberedMessageDelay;

@ -2,6 +2,8 @@
#include <components/nif/niffile.hpp> #include <components/nif/niffile.hpp>
#include <libs/openengine/ogre/fader.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" /// FIXME #include "../mwbase/world.hpp" /// FIXME
#include "../mwbase/soundmanager.hpp" #include "../mwbase/soundmanager.hpp"
@ -353,7 +355,7 @@ namespace MWWorld
void Scene::changeToInteriorCell (const std::string& cellName, const ESM::Position& position) void Scene::changeToInteriorCell (const std::string& cellName, const ESM::Position& position)
{ {
MWBase::Environment::get().getWorld ()->getFader ()->fadeOut(0.5);
const MWWorld::Store<ESM::GameSetting> &gmst = const MWWorld::Store<ESM::GameSetting> &gmst =
MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>(); MWBase::Environment::get().getWorld()->getStore().get<ESM::GameSetting>();
@ -422,6 +424,7 @@ namespace MWWorld
MWBase::Environment::get().getWorld()->adjustSky(); MWBase::Environment::get().getWorld()->adjustSky();
mCellChanged = true; mCellChanged = true;
MWBase::Environment::get().getWorld ()->getFader ()->fadeIn(0.5);
MWBase::Environment::get().getWindowManager ()->loadingDone (); MWBase::Environment::get().getWindowManager ()->loadingDone ();
} }

@ -1,8 +1,5 @@
#include "weather.hpp" #include "weather.hpp"
#include <ctime>
#include <cstdlib>
#include <boost/algorithm/string.hpp> #include <boost/algorithm/string.hpp>
#include "../mwbase/environment.hpp" #include "../mwbase/environment.hpp"
#include "../mwbase/world.hpp" #include "../mwbase/world.hpp"
@ -91,10 +88,11 @@ float WeatherManager::calculateAngleFade (const std::string& moonName, float ang
} }
WeatherManager::WeatherManager(MWRender::RenderingManager* rendering,MWWorld::Fallback* fallback) : WeatherManager::WeatherManager(MWRender::RenderingManager* rendering,MWWorld::Fallback* fallback) :
mHour(14), mCurrentWeather("clear"), mFirstUpdate(true), mWeatherUpdateTime(0), mHour(14), mCurrentWeather("clear"), mNextWeather(""), mFirstUpdate(true),
mThunderFlash(0), mThunderChance(0), mThunderChanceNeeded(50), mThunderSoundDelay(0), mWeatherUpdateTime(0), mThunderFlash(0), mThunderChance(0),
mRemainingTransitionTime(0), mMonth(0), mDay(0), mThunderChanceNeeded(50), mThunderSoundDelay(0), mRemainingTransitionTime(0),
mTimePassed(0), mFallback(fallback), mWindSpeed(0.f), mRendering(rendering) mMonth(0), mDay(0), mTimePassed(0), mFallback(fallback), mWindSpeed(0.f),
mRendering(rendering)
{ {
//Globals //Globals
mThunderSoundID0 = mFallback->getFallbackString("Weather_Thunderstorm_Thunder_Sound_ID_0"); mThunderSoundID0 = mFallback->getFallbackString("Weather_Thunderstorm_Thunder_Sound_ID_0");
@ -197,32 +195,31 @@ void WeatherManager::setWeather(const String& weather, bool instant)
mFirstUpdate = false; mFirstUpdate = false;
} }
WeatherResult WeatherManager::getResult(const String& weather) void WeatherManager::setResult(const String& weatherType)
{ {
const Weather& current = mWeatherSettings[weather]; const Weather& current = mWeatherSettings[weatherType];
WeatherResult result;
mResult.mCloudTexture = current.mCloudTexture;
result.mCloudTexture = current.mCloudTexture; mResult.mCloudBlendFactor = 0;
result.mCloudBlendFactor = 0; mResult.mCloudOpacity = current.mCloudsMaximumPercent;
result.mCloudOpacity = current.mCloudsMaximumPercent; mResult.mWindSpeed = current.mWindSpeed;
result.mWindSpeed = current.mWindSpeed; mResult.mCloudSpeed = current.mCloudSpeed;
result.mCloudSpeed = current.mCloudSpeed; mResult.mGlareView = current.mGlareView;
result.mGlareView = current.mGlareView; mResult.mAmbientLoopSoundID = current.mAmbientLoopSoundID;
result.mAmbientLoopSoundID = current.mAmbientLoopSoundID; mResult.mSunColor = current.mSunDiscSunsetColor;
result.mSunColor = current.mSunDiscSunsetColor;
mResult.mNight = (mHour < mSunriseTime || mHour > mNightStart - 1);
result.mNight = (mHour < mSunriseTime || mHour > mNightStart - 1);
mResult.mFogDepth = mResult.mNight ? current.mLandFogNightDepth : current.mLandFogDayDepth;
result.mFogDepth = result.mNight ? current.mLandFogNightDepth : current.mLandFogDayDepth;
// night // night
if (mHour <= mNightEnd || mHour >= mNightStart + 1) if (mHour <= mNightEnd || mHour >= mNightStart + 1)
{ {
result.mFogColor = current.mFogNightColor; mResult.mFogColor = current.mFogNightColor;
result.mAmbientColor = current.mAmbientNightColor; mResult.mAmbientColor = current.mAmbientNightColor;
result.mSunColor = current.mSunNightColor; mResult.mSunColor = current.mSunNightColor;
result.mSkyColor = current.mSkyNightColor; mResult.mSkyColor = current.mSkyNightColor;
result.mNightFade = 1.f; mResult.mNightFade = 1.f;
} }
// sunrise // sunrise
@ -233,31 +230,31 @@ WeatherResult WeatherManager::getResult(const String& weather)
// fade in // fade in
float advance = mSunriseTime - mHour; float advance = mSunriseTime - mHour;
float factor = advance / 0.5f; float factor = advance / 0.5f;
result.mFogColor = lerp(current.mFogSunriseColor, current.mFogNightColor, factor); mResult.mFogColor = lerp(current.mFogSunriseColor, current.mFogNightColor, factor);
result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientNightColor, factor); mResult.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientNightColor, factor);
result.mSunColor = lerp(current.mSunSunriseColor, current.mSunNightColor, factor); mResult.mSunColor = lerp(current.mSunSunriseColor, current.mSunNightColor, factor);
result.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyNightColor, factor); mResult.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyNightColor, factor);
result.mNightFade = factor; mResult.mNightFade = factor;
} }
else //if (mHour >= 6) else //if (mHour >= 6)
{ {
// fade out // fade out
float advance = mHour - mSunriseTime; float advance = mHour - mSunriseTime;
float factor = advance / 3.f; float factor = advance / 3.f;
result.mFogColor = lerp(current.mFogSunriseColor, current.mFogDayColor, factor); mResult.mFogColor = lerp(current.mFogSunriseColor, current.mFogDayColor, factor);
result.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientDayColor, factor); mResult.mAmbientColor = lerp(current.mAmbientSunriseColor, current.mAmbientDayColor, factor);
result.mSunColor = lerp(current.mSunSunriseColor, current.mSunDayColor, factor); mResult.mSunColor = lerp(current.mSunSunriseColor, current.mSunDayColor, factor);
result.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyDayColor, factor); mResult.mSkyColor = lerp(current.mSkySunriseColor, current.mSkyDayColor, factor);
} }
} }
// day // day
else if (mHour >= mDayStart + 1 && mHour <= mDayEnd - 1) else if (mHour >= mDayStart + 1 && mHour <= mDayEnd - 1)
{ {
result.mFogColor = current.mFogDayColor; mResult.mFogColor = current.mFogDayColor;
result.mAmbientColor = current.mAmbientDayColor; mResult.mAmbientColor = current.mAmbientDayColor;
result.mSunColor = current.mSunDayColor; mResult.mSunColor = current.mSunDayColor;
result.mSkyColor = current.mSkyDayColor; mResult.mSkyColor = current.mSkyDayColor;
} }
// sunset // sunset
@ -268,54 +265,51 @@ WeatherResult WeatherManager::getResult(const String& weather)
// fade in // fade in
float advance = (mDayEnd + 1) - mHour; float advance = (mDayEnd + 1) - mHour;
float factor = (advance / 2); float factor = (advance / 2);
result.mFogColor = lerp(current.mFogSunsetColor, current.mFogDayColor, factor); mResult.mFogColor = lerp(current.mFogSunsetColor, current.mFogDayColor, factor);
result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientDayColor, factor); mResult.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientDayColor, factor);
result.mSunColor = lerp(current.mSunSunsetColor, current.mSunDayColor, factor); mResult.mSunColor = lerp(current.mSunSunsetColor, current.mSunDayColor, factor);
result.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyDayColor, factor); mResult.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyDayColor, factor);
} }
else //if (mHour >= 19) else //if (mHour >= 19)
{ {
// fade out // fade out
float advance = mHour - (mDayEnd + 1); float advance = mHour - (mDayEnd + 1);
float factor = advance / 2.f; float factor = advance / 2.f;
result.mFogColor = lerp(current.mFogSunsetColor, current.mFogNightColor, factor); mResult.mFogColor = lerp(current.mFogSunsetColor, current.mFogNightColor, factor);
result.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientNightColor, factor); mResult.mAmbientColor = lerp(current.mAmbientSunsetColor, current.mAmbientNightColor, factor);
result.mSunColor = lerp(current.mSunSunsetColor, current.mSunNightColor, factor); mResult.mSunColor = lerp(current.mSunSunsetColor, current.mSunNightColor, factor);
result.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyNightColor, factor); mResult.mSkyColor = lerp(current.mSkySunsetColor, current.mSkyNightColor, factor);
result.mNightFade = factor; mResult.mNightFade = factor;
} }
} }
return result;
} }
WeatherResult WeatherManager::transition(float factor) void WeatherManager::transition(float factor)
{ {
const WeatherResult& current = getResult(mCurrentWeather); setResult(mCurrentWeather);
const WeatherResult& other = getResult(mNextWeather); const WeatherResult current = mResult;
WeatherResult result; setResult(mNextWeather);
const WeatherResult other = mResult;
result.mCloudTexture = current.mCloudTexture;
result.mNextCloudTexture = other.mCloudTexture; mResult.mCloudTexture = current.mCloudTexture;
result.mCloudBlendFactor = factor; mResult.mNextCloudTexture = other.mCloudTexture;
mResult.mCloudBlendFactor = factor;
result.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity, factor);
result.mFogColor = lerp(current.mFogColor, other.mFogColor, factor); mResult.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity, factor);
result.mSunColor = lerp(current.mSunColor, other.mSunColor, factor); mResult.mFogColor = lerp(current.mFogColor, other.mFogColor, factor);
result.mSkyColor = lerp(current.mSkyColor, other.mSkyColor, factor); mResult.mSunColor = lerp(current.mSunColor, other.mSunColor, factor);
mResult.mSkyColor = lerp(current.mSkyColor, other.mSkyColor, factor);
result.mAmbientColor = lerp(current.mAmbientColor, other.mAmbientColor, factor);
result.mSunDiscColor = lerp(current.mSunDiscColor, other.mSunDiscColor, factor); mResult.mAmbientColor = lerp(current.mAmbientColor, other.mAmbientColor, factor);
result.mFogDepth = lerp(current.mFogDepth, other.mFogDepth, factor); mResult.mSunDiscColor = lerp(current.mSunDiscColor, other.mSunDiscColor, factor);
result.mWindSpeed = lerp(current.mWindSpeed, other.mWindSpeed, factor); mResult.mFogDepth = lerp(current.mFogDepth, other.mFogDepth, factor);
result.mCloudSpeed = lerp(current.mCloudSpeed, other.mCloudSpeed, factor); mResult.mWindSpeed = lerp(current.mWindSpeed, other.mWindSpeed, factor);
result.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity, factor); mResult.mCloudSpeed = lerp(current.mCloudSpeed, other.mCloudSpeed, factor);
result.mGlareView = lerp(current.mGlareView, other.mGlareView, factor); mResult.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity, factor);
result.mNightFade = lerp(current.mNightFade, other.mNightFade, factor); mResult.mGlareView = lerp(current.mGlareView, other.mGlareView, factor);
mResult.mNightFade = lerp(current.mNightFade, other.mNightFade, factor);
result.mNight = current.mNight;
mResult.mNight = current.mNight;
return result;
} }
void WeatherManager::update(float duration) void WeatherManager::update(float duration)
@ -325,263 +319,227 @@ void WeatherManager::update(float duration)
mWeatherUpdateTime -= timePassed; mWeatherUpdateTime -= timePassed;
bool exterior = (MWBase::Environment::get().getWorld()->isCellExterior() || MWBase::Environment::get().getWorld()->isCellQuasiExterior()); const bool exterior = (MWBase::Environment::get().getWorld()->isCellExterior() || MWBase::Environment::get().getWorld()->isCellQuasiExterior());
if (!exterior)
if (exterior)
{ {
std::string regionstr = Misc::StringUtils::lowerCase(MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->mCell->mRegion); mRendering->sunDisable(false);
mRendering->skyDisable();
mRendering->getSkyManager()->setLightningStrength(0.f);
stopSounds(true);
return;
}
if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion) // Exterior
{ std::string regionstr = Misc::StringUtils::lowerCase(MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->mCell->mRegion);
mCurrentRegion = regionstr;
mWeatherUpdateTime = mHoursBetweenWeatherChanges * 3600;
std::string weather = "clear"; if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion)
{
mCurrentRegion = regionstr;
mWeatherUpdateTime = mHoursBetweenWeatherChanges * 3600;
if (mRegionOverrides.find(regionstr) != mRegionOverrides.end()) std::string weatherType = "clear";
weather = mRegionOverrides[regionstr];
else if (mRegionOverrides.find(regionstr) != mRegionOverrides.end())
{ weatherType = mRegionOverrides[regionstr];
// get weather probabilities for the current region else
const ESM::Region *region = {
// get weather probabilities for the current region
const ESM::Region *region =
MWBase::Environment::get().getWorld()->getStore().get<ESM::Region>().search (regionstr); MWBase::Environment::get().getWorld()->getStore().get<ESM::Region>().search (regionstr);
if (region != 0) if (region != 0)
{ {
float clear = region->mData.mClear/255.f; weatherType = nextWeather(region);
float cloudy = region->mData.mCloudy/255.f;
float foggy = region->mData.mFoggy/255.f;
float overcast = region->mData.mOvercast/255.f;
float rain = region->mData.mRain/255.f;
float thunder = region->mData.mThunder/255.f;
float ash = region->mData.mAsh/255.f;
float blight = region->mData.mBlight/255.f;
float snow = region->mData.mA/255.f;
float blizzard = region->mData.mB/255.f;
// re-scale to 100 percent
const float total = clear+cloudy+foggy+overcast+rain+thunder+ash+blight+snow+blizzard;
float random = ((rand()%100)/100.f) * total;
if (random >= snow+blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
weather = "blizzard";
else if (random >= blight+ash+thunder+rain+overcast+foggy+cloudy+clear)
weather = "snow";
else if (random >= ash+thunder+rain+overcast+foggy+cloudy+clear)
weather = "blight";
else if (random >= thunder+rain+overcast+foggy+cloudy+clear)
weather = "ashstorm";
else if (random >= rain+overcast+foggy+cloudy+clear)
weather = "thunderstorm";
else if (random >= overcast+foggy+cloudy+clear)
weather = "rain";
else if (random >= foggy+cloudy+clear)
weather = "overcast";
else if (random >= cloudy+clear)
weather = "foggy";
else if (random >= clear)
weather = "cloudy";
else
weather = "clear";
}
} }
setWeather(weather, false);
} }
WeatherResult result; setWeather(weatherType, false);
}
if (mNextWeather != "") if (mNextWeather != "")
{
mRemainingTransitionTime -= timePassed;
if (mRemainingTransitionTime < 0)
{ {
mRemainingTransitionTime -= timePassed; mCurrentWeather = mNextWeather;
if (mRemainingTransitionTime < 0) mNextWeather = "";
{
mCurrentWeather = mNextWeather;
mNextWeather = "";
}
} }
}
if (mNextWeather != "") if (mNextWeather != "")
result = transition(1 - (mRemainingTransitionTime / (mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600))); transition(1 - (mRemainingTransitionTime / (mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600)));
else else
result = getResult(mCurrentWeather); setResult(mCurrentWeather);
mWindSpeed = result.mWindSpeed; mWindSpeed = mResult.mWindSpeed;
mRendering->configureFog(result.mFogDepth, result.mFogColor); mRendering->configureFog(mResult.mFogDepth, mResult.mFogColor);
// disable sun during night // disable sun during night
if (mHour >= mNightStart || mHour <= mSunriseTime) if (mHour >= mNightStart || mHour <= mSunriseTime)
mRendering->getSkyManager()->sunDisable(); mRendering->getSkyManager()->sunDisable();
else else
mRendering->getSkyManager()->sunEnable(); mRendering->getSkyManager()->sunEnable();
// sun angle // sun angle
float height; float height;
//Day duration //Day duration
float dayDuration = (mNightStart - 1) - mSunriseTime; float dayDuration = (mNightStart - 1) - mSunriseTime;
// rise at 6, set at 20 // rise at 6, set at 20
if (mHour >= mSunriseTime && mHour <= mNightStart) if (mHour >= mSunriseTime && mHour <= mNightStart)
height = 1 - std::abs(((mHour - dayDuration) / 7.f)); height = 1 - std::abs(((mHour - dayDuration) / 7.f));
else if (mHour > mNightStart) else if (mHour > mNightStart)
height = (mHour - mNightStart) / 4.f; height = (mHour - mNightStart) / 4.f;
else //if (mHour > 0 && mHour < 6) else //if (mHour > 0 && mHour < 6)
height = 1 - (mHour / mSunriseTime); height = 1 - (mHour / mSunriseTime);
int facing = (mHour > 13.f) ? 1 : -1; int facing = (mHour > 13.f) ? 1 : -1;
Vector3 final( Vector3 final(
-(1 - height) * facing, (height - 1) * facing,
-(1 - height) * facing, (height - 1) * facing,
height); height);
mRendering->setSunDirection(final); mRendering->setSunDirection(final);
/*
* TODO: import separated fadeInStart/Finish, fadeOutStart/Finish
* for masser and secunda
*/
float fadeOutFinish=mFallback->getFallbackFloat("Moons_Masser_Fade_Out_Finish");
float fadeInStart=mFallback->getFallbackFloat("Moons_Masser_Fade_In_Start");
//moon calculations
float moonHeight;
if (mHour >= fadeInStart)
moonHeight = mHour - fadeInStart;
else if (mHour <= fadeOutFinish)
moonHeight = mHour + fadeOutFinish;
else
moonHeight = 0;
moonHeight /= (24.f - (fadeInStart - fadeOutFinish)); /*
* TODO: import separated fadeInStart/Finish, fadeOutStart/Finish
* for masser and secunda
*/
if (moonHeight != 0) float fadeOutFinish=mFallback->getFallbackFloat("Moons_Masser_Fade_Out_Finish");
{ float fadeInStart=mFallback->getFallbackFloat("Moons_Masser_Fade_In_Start");
int facing = (moonHeight <= 1) ? 1 : -1;
Vector3 masser( //moon calculations
float moonHeight;
if (mHour >= fadeInStart)
moonHeight = mHour - fadeInStart;
else if (mHour <= fadeOutFinish)
moonHeight = mHour + fadeOutFinish;
else
moonHeight = 0;
moonHeight /= (24.f - (fadeInStart - fadeOutFinish));
if (moonHeight != 0)
{
int facing = (moonHeight <= 1) ? 1 : -1;
Vector3 masser(
(moonHeight - 1) * facing, (moonHeight - 1) * facing,
(1 - moonHeight) * facing, (1 - moonHeight) * facing,
moonHeight); moonHeight);
Vector3 secunda( Vector3 secunda(
(moonHeight - 1) * facing * 1.25, (moonHeight - 1) * facing * 1.25,
(1 - moonHeight) * facing * 0.8, (1 - moonHeight) * facing * 0.8,
moonHeight); moonHeight);
mRendering->getSkyManager()->setMasserDirection(masser); mRendering->getSkyManager()->setMasserDirection(masser);
mRendering->getSkyManager()->setSecundaDirection(secunda); mRendering->getSkyManager()->setSecundaDirection(secunda);
mRendering->getSkyManager()->masserEnable(); mRendering->getSkyManager()->masserEnable();
mRendering->getSkyManager()->secundaEnable(); mRendering->getSkyManager()->secundaEnable();
float angle = (1-moonHeight) * 90.f * facing; float angle = (1-moonHeight) * 90.f * facing;
float masserHourFade = calculateHourFade("Masser"); float masserHourFade = calculateHourFade("Masser");
float secundaHourFade = calculateHourFade("Secunda"); float secundaHourFade = calculateHourFade("Secunda");
float masserAngleFade = calculateAngleFade("Masser", angle); float masserAngleFade = calculateAngleFade("Masser", angle);
float secundaAngleFade = calculateAngleFade("Secunda", angle); float secundaAngleFade = calculateAngleFade("Secunda", angle);
masserAngleFade *= masserHourFade; masserAngleFade *= masserHourFade;
secundaAngleFade *= secundaHourFade; secundaAngleFade *= secundaHourFade;
mRendering->getSkyManager()->setMasserFade(masserAngleFade); mRendering->getSkyManager()->setMasserFade(masserAngleFade);
mRendering->getSkyManager()->setSecundaFade(secundaAngleFade); mRendering->getSkyManager()->setSecundaFade(secundaAngleFade);
} }
else else
{ {
mRendering->getSkyManager()->masserDisable(); mRendering->getSkyManager()->masserDisable();
mRendering->getSkyManager()->secundaDisable(); mRendering->getSkyManager()->secundaDisable();
} }
if (mCurrentWeather == "thunderstorm" && mNextWeather == "" && exterior) if (mCurrentWeather == "thunderstorm" && mNextWeather == "")
{
if (mThunderFlash > 0)
{ {
if (mThunderFlash > 0) // play the sound after a delay
mThunderSoundDelay -= duration;
if (mThunderSoundDelay <= 0)
{ {
// play the sound after a delay // pick a random sound
mThunderSoundDelay -= duration; int sound = rand() % 4;
if (mThunderSoundDelay <= 0) std::string* soundName;
{ if (sound == 0) soundName = &mThunderSoundID0;
// pick a random sound else if (sound == 1) soundName = &mThunderSoundID1;
int sound = rand() % 4; else if (sound == 2) soundName = &mThunderSoundID2;
std::string soundname; else if (sound == 3) soundName = &mThunderSoundID3;
if (sound == 0) soundname = mThunderSoundID0; MWBase::Environment::get().getSoundManager()->playSound(*soundName, 1.0, 1.0);
else if (sound == 1) soundname = mThunderSoundID1; mThunderSoundDelay = 1000;
else if (sound == 2) soundname = mThunderSoundID2;
else if (sound == 3) soundname = mThunderSoundID3;
MWBase::Environment::get().getSoundManager()->playSound(soundname, 1.0, 1.0);
mThunderSoundDelay = 1000;
}
mThunderFlash -= duration;
if (mThunderFlash > 0)
mRendering->getSkyManager()->setLightningStrength( mThunderFlash / mThunderThreshold );
else
{
srand(time(NULL));
mThunderChanceNeeded = rand() % 100;
mThunderChance = 0;
mRendering->getSkyManager()->setLightningStrength( 0.f );
}
} }
mThunderFlash -= duration;
if (mThunderFlash > 0)
mRendering->getSkyManager()->setLightningStrength( mThunderFlash / mThunderThreshold );
else else
{ {
// no thunder active mThunderChanceNeeded = rand() % 100;
mThunderChance += duration*4; // chance increases by 4 percent every second mThunderChance = 0;
if (mThunderChance >= mThunderChanceNeeded) mRendering->getSkyManager()->setLightningStrength( 0.f );
{
mThunderFlash = mThunderThreshold;
mRendering->getSkyManager()->setLightningStrength( mThunderFlash / mThunderThreshold );
mThunderSoundDelay = 0.25;
}
} }
} }
else else
mRendering->getSkyManager()->setLightningStrength(0.f); {
// no thunder active
mThunderChance += duration*4; // chance increases by 4 percent every second
if (mThunderChance >= mThunderChanceNeeded)
{
mThunderFlash = mThunderThreshold;
mRendering->setAmbientColour(result.mAmbientColor); mRendering->getSkyManager()->setLightningStrength( mThunderFlash / mThunderThreshold );
mRendering->sunEnable(false);
mRendering->setSunColour(result.mSunColor);
mRendering->getSkyManager()->setWeather(result); mThunderSoundDelay = 0.25;
}
}
} }
else else
{
mRendering->sunDisable(false);
mRendering->skyDisable();
mRendering->getSkyManager()->setLightningStrength(0.f); mRendering->getSkyManager()->setLightningStrength(0.f);
}
// play sounds mRendering->setAmbientColour(mResult.mAmbientColor);
std::string ambientSnd = (mNextWeather == "" ? mWeatherSettings[mCurrentWeather].mAmbientLoopSoundID : ""); mRendering->sunEnable(false);
if (!exterior) ambientSnd = ""; mRendering->setSunColour(mResult.mSunColor);
if (ambientSnd != "")
mRendering->getSkyManager()->setWeather(mResult);
// Play sounds
if (mNextWeather == "")
{ {
if (std::find(mSoundsPlaying.begin(), mSoundsPlaying.end(), ambientSnd) == mSoundsPlaying.end()) std::string ambientSnd = mWeatherSettings[mCurrentWeather].mAmbientLoopSoundID;
if (!ambientSnd.empty() && std::find(mSoundsPlaying.begin(), mSoundsPlaying.end(), ambientSnd) == mSoundsPlaying.end())
{ {
mSoundsPlaying.push_back(ambientSnd); mSoundsPlaying.push_back(ambientSnd);
MWBase::Environment::get().getSoundManager()->playSound(ambientSnd, 1.0, 1.0, MWBase::SoundManager::Play_Loop); MWBase::Environment::get().getSoundManager()->playSound(ambientSnd, 1.0, 1.0, MWBase::SoundManager::Play_Loop);
} }
}
std::string rainSnd = (mNextWeather == "" ? mWeatherSettings[mCurrentWeather].mRainLoopSoundID : ""); std::string rainSnd = mWeatherSettings[mCurrentWeather].mRainLoopSoundID;
if (!exterior) rainSnd = ""; if (!rainSnd.empty() && std::find(mSoundsPlaying.begin(), mSoundsPlaying.end(), rainSnd) == mSoundsPlaying.end())
if (rainSnd != "")
{
if (std::find(mSoundsPlaying.begin(), mSoundsPlaying.end(), rainSnd) == mSoundsPlaying.end())
{ {
mSoundsPlaying.push_back(rainSnd); mSoundsPlaying.push_back(rainSnd);
MWBase::Environment::get().getSoundManager()->playSound(rainSnd, 1.0, 1.0, MWBase::SoundManager::Play_Loop); MWBase::Environment::get().getSoundManager()->playSound(rainSnd, 1.0, 1.0, MWBase::SoundManager::Play_Loop);
} }
} }
// stop sounds stopSounds(false);
std::vector<std::string>::iterator it=mSoundsPlaying.begin(); }
void WeatherManager::stopSounds(bool stopAll)
{
std::vector<std::string>::iterator it = mSoundsPlaying.begin();
while (it!=mSoundsPlaying.end()) while (it!=mSoundsPlaying.end())
{ {
if ( *it != ambientSnd && *it != rainSnd) if (stopAll || \
!((*it == mWeatherSettings[mCurrentWeather].mAmbientLoopSoundID) || \
(*it == mWeatherSettings[mCurrentWeather].mRainLoopSoundID)))
{ {
MWBase::Environment::get().getSoundManager()->stopSound(*it); MWBase::Environment::get().getSoundManager()->stopSound(*it);
it = mSoundsPlaying.erase(it); it = mSoundsPlaying.erase(it);
@ -591,6 +549,61 @@ void WeatherManager::update(float duration)
} }
} }
Ogre::String WeatherManager::nextWeather(const ESM::Region* region) const
{
/*
* All probabilities must add to 100 (responsibility of the user).
* If chances A and B has values 30 and 70 then by generating
* 100 numbers 1..100, 30% will be lesser or equal 30 and
* 70% will be greater than 30 (in theory).
*/
const int probability[] = {
region->mData.mClear,
region->mData.mCloudy,
region->mData.mFoggy,
region->mData.mOvercast,
region->mData.mRain,
region->mData.mThunder,
region->mData.mAsh,
region->mData.mBlight,
region->mData.mA,
region->mData.mB
}; // 10 elements
int chance = (rand() % 100) + 1; // 1..100
int sum = 0;
for (int i = 0; i < 10; ++i)
{
sum += probability[i];
if (chance < sum)
{
switch (i)
{
case 1:
return "cloudy";
case 2:
return "foggy";
case 3:
return "overcast";
case 4:
return "rain";
case 5:
return "thunderstorm";
case 6:
return "ashstorm";
case 7:
return "blight";
case 8:
return "snow";
case 9:
return "blizzard";
default: // case 0
return "clear";
}
}
}
}
void WeatherManager::setHour(const float hour) void WeatherManager::setHour(const float hour)
{ {
mHour = hour; mHour = hour;

@ -4,6 +4,11 @@
#include <OgreString.h> #include <OgreString.h>
#include <OgreColourValue.h> #include <OgreColourValue.h>
namespace ESM
{
struct Region;
}
namespace MWRender namespace MWRender
{ {
class RenderingManager; class RenderingManager;
@ -129,6 +134,8 @@ namespace MWWorld
*/ */
void update(float duration); void update(float duration);
void stopSounds(bool stopAll);
void setHour(const float hour); void setHour(const float hour);
float getWindSpeed() const; float getWindSpeed() const;
@ -171,13 +178,16 @@ namespace MWWorld
double mTimePassed; // time passed since last update double mTimePassed; // time passed since last update
WeatherResult transition(const float factor); void transition(const float factor);
WeatherResult getResult(const Ogre::String& weather); void setResult(const Ogre::String& weatherType);
float calculateHourFade (const std::string& moonName) const; float calculateHourFade (const std::string& moonName) const;
float calculateAngleFade (const std::string& moonName, float angle) const; float calculateAngleFade (const std::string& moonName, float angle) const;
void setWeather(const Ogre::String& weather, bool instant=false); void setWeather(const Ogre::String& weatherType, bool instant=false);
Ogre::String nextWeather(const ESM::Region* region) const;
WeatherResult mResult;
float mSunriseTime; float mSunriseTime;
float mSunsetTime; float mSunsetTime;
float mSunriseDuration; float mSunriseDuration;

@ -183,3 +183,11 @@ INCLUDE(FindPackageHandleStandardArgs)
FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2 FIND_PACKAGE_HANDLE_STANDARD_ARGS(SDL2
REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR) REQUIRED_VARS SDL2_LIBRARY SDL2_INCLUDE_DIR)
IF(SDL2_STATIC)
if (UNIX AND NOT APPLE)
EXECUTE_PROCESS(COMMAND sdl2-config --static-libs OUTPUT_VARIABLE SDL2_LINK_FLAGS)
STRING(REGEX REPLACE "(\r?\n)+$" "" SDL2_LINK_FLAGS "${SDL2_LINK_FLAGS}")
SET(SDL2_LIBRARY ${SDL2_LINK_FLAGS})
ENDIF()
ENDIF(SDL2_STATIC)

@ -21,6 +21,7 @@ BrotherBrick
Chris Robinson (KittyCat) Chris Robinson (KittyCat)
Cory F. Cohen (cfcohen) Cory F. Cohen (cfcohen)
Cris Mihalache (Mirceam) Cris Mihalache (Mirceam)
darkf
Douglas Diniz (Dgdiniz) Douglas Diniz (Dgdiniz)
Douglas Mencken (dougmencken) Douglas Mencken (dougmencken)
Edmondo Tommasina (edmondo) Edmondo Tommasina (edmondo)

@ -35,6 +35,7 @@ class KeyListener
{ {
public: public:
virtual ~KeyListener() {} virtual ~KeyListener() {}
virtual void textInput (const SDL_TextInputEvent& arg) {}
virtual bool keyPressed(const SDL_KeyboardEvent &arg) = 0; virtual bool keyPressed(const SDL_KeyboardEvent &arg) = 0;
virtual bool keyReleased(const SDL_KeyboardEvent &arg) = 0; virtual bool keyReleased(const SDL_KeyboardEvent &arg) = 0;
}; };

@ -8,8 +8,7 @@
namespace SFO namespace SFO
{ {
SDLCursorManager::SDLCursorManager(bool debug) : SDLCursorManager::SDLCursorManager() :
mDebug(debug),
mEnabled(false), mEnabled(false),
mCursorVisible(false), mCursorVisible(false),
mInitialized(false) mInitialized(false)
@ -45,8 +44,7 @@ namespace SFO
//turn off hardware cursors //turn off hardware cursors
else else
{ {
if(!mDebug) SDL_ShowCursor(SDL_FALSE);
SDL_ShowCursor(SDL_FALSE);
} }
} }
@ -72,7 +70,7 @@ namespace SFO
void SDLCursorManager::_setGUICursor(const std::string &name) void SDLCursorManager::_setGUICursor(const std::string &name)
{ {
if(mEnabled && (mDebug || mCursorVisible)) if(mEnabled && mCursorVisible)
{ {
SDL_SetCursor(mCursorMap.find(name)->second); SDL_SetCursor(mCursorMap.find(name)->second);
_setCursorVisible(mCursorVisible); _setCursorVisible(mCursorVisible);
@ -84,9 +82,6 @@ namespace SFO
if(!mEnabled) if(!mEnabled)
return; return;
if(mDebug)
visible = true;
SDL_ShowCursor(visible ? SDL_TRUE : SDL_FALSE); SDL_ShowCursor(visible ? SDL_TRUE : SDL_FALSE);
} }

@ -12,7 +12,7 @@ namespace SFO
public CursorManager public CursorManager
{ {
public: public:
SDLCursorManager(bool debug=false); SDLCursorManager();
virtual ~SDLCursorManager(); virtual ~SDLCursorManager();
virtual void setEnabled(bool enabled); virtual void setEnabled(bool enabled);
@ -36,8 +36,6 @@ namespace SFO
bool mEnabled; bool mEnabled;
bool mInitialized; bool mInitialized;
bool mCursorVisible; bool mCursorVisible;
bool mDebug;
}; };
} }

@ -26,12 +26,10 @@ namespace SFO
mWrapPointer(false), mWrapPointer(false),
mMouseZ(0), mMouseZ(0),
mMouseY(0), mMouseY(0),
mMouseX(0) mMouseX(0),
mMouseInWindow(true)
{ {
_setupOISKeys(); _setupOISKeys();
// FIXME: text input should only be enabled when a text input widget currently has focus
SDL_StartTextInput();
} }
InputWrapper::~InputWrapper() InputWrapper::~InputWrapper()
@ -39,8 +37,6 @@ namespace SFO
if(mSDLWindow != NULL && mOwnWindow) if(mSDLWindow != NULL && mOwnWindow)
SDL_DestroyWindow(mSDLWindow); SDL_DestroyWindow(mSDLWindow);
mSDLWindow = NULL; mSDLWindow = NULL;
SDL_StopTextInput();
} }
void InputWrapper::capture() void InputWrapper::capture()
@ -71,12 +67,15 @@ namespace SFO
break; break;
case SDL_KEYDOWN: case SDL_KEYDOWN:
if (!evt.key.repeat) if (!evt.key.repeat)
_handleKeyPress(evt.key); mKeyboardListener->keyPressed(evt.key);
break; break;
case SDL_KEYUP: case SDL_KEYUP:
if (!evt.key.repeat) if (!evt.key.repeat)
mKeyboardListener->keyReleased(evt.key); mKeyboardListener->keyReleased(evt.key);
break; break;
case SDL_TEXTINPUT:
mKeyboardListener->textInput(evt.text);
break;
case SDL_WINDOWEVENT: case SDL_WINDOWEVENT:
handleWindowEvent(evt); handleWindowEvent(evt);
break; break;
@ -224,74 +223,6 @@ namespace SFO
return pack_evt; return pack_evt;
} }
void InputWrapper::_handleKeyPress(SDL_KeyboardEvent &evt)
{
//SDL keyboard events are followed by the actual text those keys would generate
//to account for languages that require multiple keystrokes to produce a key.
//Look for an event immediately following ours, assuming each key produces exactly
//one character or none at all.
//TODO: Check if this works properly for multibyte symbols
//do we have to worry about endian-ness?
//for that matter, check if we even need to do any of this.
SDL_Event text_evts[1];
if(SDL_PeepEvents(text_evts, 1, SDL_GETEVENT, SDL_TEXTINPUT, SDL_TEXTINPUT) != 0)
{
if(strlen(text_evts[0].text.text) != 0)
{
const unsigned char* symbol = reinterpret_cast<unsigned char*>(&(text_evts[0].text.text[0]));
evt.keysym.unicode = _UTF8ToUTF32(symbol);
}
}
mKeyboardListener->keyPressed(evt);
}
//Lifted from OIS' LinuxKeyboard.cpp
Uint32 InputWrapper::_UTF8ToUTF32(const unsigned char *buf)
{
unsigned char FirstChar = buf[0];
//it's an ascii char, bail out early.
if(FirstChar < 128)
return FirstChar;
Uint32 val = 0;
Sint32 len = 0;
if((FirstChar & 0xE0) == 0xC0) //2 Chars
{
len = 2;
val = FirstChar & 0x1F;
}
else if((FirstChar & 0xF0) == 0xE0) //3 Chars
{
len = 3;
val = FirstChar & 0x0F;
}
else if((FirstChar & 0xF8) == 0xF0) //4 Chars
{
len = 4;
val = FirstChar & 0x07;
}
else if((FirstChar & 0xFC) == 0xF8) //5 Chars
{
len = 5;
val = FirstChar & 0x03;
}
else // if((FirstChar & 0xFE) == 0xFC) //6 Chars
{
len = 6;
val = FirstChar & 0x01;
}
for(int i = 1; i < len; i++)
val = (val << 6) | (buf[i] & 0x3F);
return val;
}
OIS::KeyCode InputWrapper::sdl2OISKeyCode(SDL_Keycode code) OIS::KeyCode InputWrapper::sdl2OISKeyCode(SDL_Keycode code)
{ {
OIS::KeyCode kc = OIS::KC_UNASSIGNED; OIS::KeyCode kc = OIS::KC_UNASSIGNED;
@ -300,8 +231,6 @@ namespace SFO
if(ois_equiv != mKeyMap.end()) if(ois_equiv != mKeyMap.end())
kc = ois_equiv->second; kc = ois_equiv->second;
else
std::cerr << "Couldn't find OIS key for " << code << std::endl;
return kc; return kc;
} }

@ -42,8 +42,6 @@ namespace SFO
void _wrapMousePointer(const SDL_MouseMotionEvent &evt); void _wrapMousePointer(const SDL_MouseMotionEvent &evt);
MouseMotionEvent _packageMouseMotion(const SDL_Event& evt); MouseMotionEvent _packageMouseMotion(const SDL_Event& evt);
void _handleKeyPress(SDL_KeyboardEvent& evt);
Uint32 _UTF8ToUTF32(const unsigned char *buf);
void _setupOISKeys(); void _setupOISKeys();
SFO::MouseListener* mMouseListener; SFO::MouseListener* mMouseListener;

@ -23,13 +23,29 @@
#include <cstdlib> #include <cstdlib>
#include <stdexcept> #include <stdexcept>
#ifdef __MACOSX__ #if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
#include "osx_utils.h" #include "osx_utils.h"
#endif #endif
using namespace Ogre; using namespace Ogre;
using namespace OEngine::Render; using namespace OEngine::Render;
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
CustomRoot::CustomRoot(const Ogre::String& pluginFileName,
const Ogre::String& configFileName,
const Ogre::String& logFileName)
: Ogre::Root(pluginFileName, configFileName, logFileName)
{}
bool CustomRoot::isQueuedEnd() const
{
return mQueuedEnd;
}
#endif
void OgreRenderer::cleanup() void OgreRenderer::cleanup()
{ {
delete mFader; delete mFader;
@ -52,7 +68,19 @@ void OgreRenderer::cleanup()
void OgreRenderer::start() void OgreRenderer::start()
{ {
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
// we need this custom main loop because otherwise Ogre's Carbon message pump will
// steal input events even from our Cocoa window
// There's no way to disable Ogre's message pump other that comment pump code in Ogre's source
do {
if (!mRoot->renderOneFrame()) {
break;
}
} while (!mRoot->isQueuedEnd());
#else
mRoot->startRendering(); mRoot->startRendering();
#endif
} }
void OgreRenderer::loadPlugins() void OgreRenderer::loadPlugins()
@ -145,7 +173,11 @@ void OgreRenderer::configure(const std::string &logPath,
// Disable logging // Disable logging
log->setDebugOutputEnabled(false); log->setDebugOutputEnabled(false);
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
mRoot = new CustomRoot("", "", "");
#else
mRoot = new Root("", "", ""); mRoot = new Root("", "", "");
#endif
#if defined(ENABLE_PLUGIN_GL) || defined(ENABLE_PLUGIN_Direct3D9) || defined(ENABLE_PLUGIN_CgProgramManager) || defined(ENABLE_PLUGIN_OctreeSceneManager) || defined(ENABLE_PLUGIN_ParticleFX) #if defined(ENABLE_PLUGIN_GL) || defined(ENABLE_PLUGIN_Direct3D9) || defined(ENABLE_PLUGIN_CgProgramManager) || defined(ENABLE_PLUGIN_OctreeSceneManager) || defined(ENABLE_PLUGIN_ParticleFX)
loadPlugins(); loadPlugins();

@ -27,12 +27,18 @@
#include "OgreTexture.h" #include "OgreTexture.h"
#include <OgreWindowEventUtilities.h> #include <OgreWindowEventUtilities.h>
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
#include <OgreRoot.h>
#endif
struct SDL_Window; struct SDL_Window;
struct SDL_Surface; struct SDL_Surface;
namespace Ogre namespace Ogre
{ {
#if OGRE_PLATFORM != OGRE_PLATFORM_APPLE
class Root; class Root;
#endif
class RenderWindow; class RenderWindow;
class SceneManager; class SceneManager;
class Camera; class Camera;
@ -54,11 +60,26 @@ namespace OEngine
std::string icon; std::string icon;
}; };
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
class CustomRoot : public Ogre::Root {
public:
bool isQueuedEnd() const;
CustomRoot(const Ogre::String& pluginFileName = "plugins.cfg",
const Ogre::String& configFileName = "ogre.cfg",
const Ogre::String& logFileName = "Ogre.log");
};
#endif
class Fader; class Fader;
class OgreRenderer class OgreRenderer
{ {
#if OGRE_PLATFORM == OGRE_PLATFORM_APPLE
CustomRoot *mRoot;
#else
Ogre::Root *mRoot; Ogre::Root *mRoot;
#endif
Ogre::RenderWindow *mWindow; Ogre::RenderWindow *mWindow;
SDL_Window *mSDLWindow; SDL_Window *mSDLWindow;
SDL_Surface *mWindowIconSurface; SDL_Surface *mWindowIconSurface;

Loading…
Cancel
Save