mirror of
https://gitlab.com/OpenMW/openmw.git
synced 2025-03-19 16:21:08 +00:00
Merge branch 'master' of https://github.com/zinnschlag/openmw
This commit is contained in:
commit
1f4d1d3b57
@ -90,6 +90,7 @@ target_link_libraries(omwlauncher
|
|||||||
${Boost_LIBRARIES}
|
${Boost_LIBRARIES}
|
||||||
${OGRE_LIBRARIES}
|
${OGRE_LIBRARIES}
|
||||||
${OGRE_STATIC_PLUGINS}
|
${OGRE_STATIC_PLUGINS}
|
||||||
|
${SDL2_LIBRARY}
|
||||||
${QT_LIBRARIES}
|
${QT_LIBRARIES}
|
||||||
components
|
components
|
||||||
)
|
)
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
#include <QDesktopWidget>
|
#include <QDesktopWidget>
|
||||||
#include <QMessageBox>
|
#include <QMessageBox>
|
||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
#include <SDL.h>
|
||||||
|
|
||||||
#include <cstdlib>
|
#include <cstdlib>
|
||||||
|
|
||||||
@ -35,13 +36,14 @@ GraphicsPage::GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &g
|
|||||||
setupUi(this);
|
setupUi(this);
|
||||||
|
|
||||||
// Set the maximum res we can set in windowed mode
|
// Set the maximum res we can set in windowed mode
|
||||||
QRect res = QApplication::desktop()->screenGeometry();
|
QRect res = getMaximumResolution();
|
||||||
customWidthSpinBox->setMaximum(res.width());
|
customWidthSpinBox->setMaximum(res.width());
|
||||||
customHeightSpinBox->setMaximum(res.height());
|
customHeightSpinBox->setMaximum(res.height());
|
||||||
|
|
||||||
connect(rendererComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(rendererChanged(const QString&)));
|
connect(rendererComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(rendererChanged(const QString&)));
|
||||||
connect(fullScreenCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotFullScreenChanged(int)));
|
connect(fullScreenCheckBox, SIGNAL(stateChanged(int)), this, SLOT(slotFullScreenChanged(int)));
|
||||||
connect(standardRadioButton, SIGNAL(toggled(bool)), this, SLOT(slotStandardToggled(bool)));
|
connect(standardRadioButton, SIGNAL(toggled(bool)), this, SLOT(slotStandardToggled(bool)));
|
||||||
|
connect(screenComboBox, SIGNAL(currentIndexChanged(const QString&)), this, SLOT(screenChanged(const QString&)));
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -144,17 +146,97 @@ bool GraphicsPage::setupOgre()
|
|||||||
}
|
}
|
||||||
|
|
||||||
antiAliasingComboBox->clear();
|
antiAliasingComboBox->clear();
|
||||||
resolutionComboBox->clear();
|
|
||||||
antiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem));
|
antiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem));
|
||||||
resolutionComboBox->addItems(getAvailableResolutions(mSelectedRenderSystem));
|
|
||||||
|
|
||||||
// Load the rest of the values
|
|
||||||
loadSettings();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsPage::loadSettings()
|
bool GraphicsPage::setupSDL()
|
||||||
{
|
{
|
||||||
|
// FIXME: do setupSDLWordaround here instead.
|
||||||
|
// seems like Qt, SDL and Ogre don't like each other
|
||||||
|
// results in a segfault if SDL is initialized after Qt
|
||||||
|
|
||||||
|
QStringList screens;
|
||||||
|
for (int i = 0; i < mScreenCount; i++)
|
||||||
|
{
|
||||||
|
screens.append(QString("Screen ") + QString::number(i + 1));
|
||||||
|
}
|
||||||
|
screenComboBox->addItems(screens);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
std::vector<VideoMode> GraphicsPage::mVideoModes;
|
||||||
|
int GraphicsPage::mScreenCount;
|
||||||
|
|
||||||
|
bool GraphicsPage::setupSDLWordaround() {
|
||||||
|
if (SDL_Init(SDL_INIT_VIDEO) != 0)
|
||||||
|
{
|
||||||
|
std::cout << "SDL_Init failed: " << SDL_GetError() << std::endl;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_DisplayMode mode;
|
||||||
|
int displayIndex, modeIndex, displays = SDL_GetNumVideoDisplays();
|
||||||
|
mScreenCount = displays;
|
||||||
|
|
||||||
|
if(displays < 0)
|
||||||
|
{
|
||||||
|
std::cout << "SDL_GetNumVideoDisplays failed: " << SDL_GetError() << std::endl;
|
||||||
|
SDL_Quit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (displayIndex = 0; displayIndex < displays; displayIndex++)
|
||||||
|
{
|
||||||
|
int modes = SDL_GetNumDisplayModes(displayIndex);
|
||||||
|
if(modes < 0)
|
||||||
|
{
|
||||||
|
std::cout << "SDL_GetNumDisplayModes failed: " << SDL_GetError() << std::endl;
|
||||||
|
SDL_Quit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
for (modeIndex = 0; modeIndex < modes; modeIndex++)
|
||||||
|
{
|
||||||
|
if (SDL_GetDisplayMode(displayIndex, modeIndex, &mode) < 0)
|
||||||
|
{
|
||||||
|
std::cout << "SDL_GetDisplayMode failed: " << SDL_GetError() << std::endl;
|
||||||
|
SDL_Quit();
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool isDouble = false;
|
||||||
|
for (std::vector<VideoMode>::iterator it = mVideoModes.begin(); it != mVideoModes.end(); it++)
|
||||||
|
{
|
||||||
|
if ((*it).w == mode.w && (*it).h == mode.h && (*it).screen == displayIndex)
|
||||||
|
{
|
||||||
|
isDouble = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (isDouble)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
VideoMode vmode;
|
||||||
|
vmode.w = mode.w;
|
||||||
|
vmode.h = mode.h;
|
||||||
|
vmode.screen = displayIndex;
|
||||||
|
mVideoModes.push_back(vmode);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
SDL_Quit();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool GraphicsPage::loadSettings()
|
||||||
|
{
|
||||||
|
if (!setupSDL())
|
||||||
|
return false;
|
||||||
|
if (!setupOgre())
|
||||||
|
return false;
|
||||||
|
|
||||||
if (mGraphicsSettings.value(QString("Video/vsync")) == QLatin1String("true"))
|
if (mGraphicsSettings.value(QString("Video/vsync")) == QLatin1String("true"))
|
||||||
vSyncCheckBox->setCheckState(Qt::Checked);
|
vSyncCheckBox->setCheckState(Qt::Checked);
|
||||||
|
|
||||||
@ -168,6 +250,11 @@ void GraphicsPage::loadSettings()
|
|||||||
QString width = mGraphicsSettings.value(QString("Video/resolution x"));
|
QString width = mGraphicsSettings.value(QString("Video/resolution x"));
|
||||||
QString height = mGraphicsSettings.value(QString("Video/resolution y"));
|
QString height = mGraphicsSettings.value(QString("Video/resolution y"));
|
||||||
QString resolution = width + QString(" x ") + height;
|
QString resolution = width + QString(" x ") + height;
|
||||||
|
QString screen = mGraphicsSettings.value(QString("Video/screen"));
|
||||||
|
|
||||||
|
int screenIndex = screenComboBox->findText(QString("Screen ") + screen);
|
||||||
|
if (screenIndex != -1)
|
||||||
|
screenComboBox->setCurrentIndex(screenIndex);
|
||||||
|
|
||||||
int resIndex = resolutionComboBox->findText(resolution, Qt::MatchStartsWith);
|
int resIndex = resolutionComboBox->findText(resolution, Qt::MatchStartsWith);
|
||||||
|
|
||||||
@ -180,6 +267,8 @@ void GraphicsPage::loadSettings()
|
|||||||
customHeightSpinBox->setValue(height.toInt());
|
customHeightSpinBox->setValue(height.toInt());
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsPage::saveSettings()
|
void GraphicsPage::saveSettings()
|
||||||
@ -205,6 +294,11 @@ void GraphicsPage::saveSettings()
|
|||||||
mGraphicsSettings.setValue(QString("Video/resolution x"), QString::number(customWidthSpinBox->value()));
|
mGraphicsSettings.setValue(QString("Video/resolution x"), QString::number(customWidthSpinBox->value()));
|
||||||
mGraphicsSettings.setValue(QString("Video/resolution y"), QString::number(customHeightSpinBox->value()));
|
mGraphicsSettings.setValue(QString("Video/resolution y"), QString::number(customHeightSpinBox->value()));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRegExp screenRe(QString(".*(\\d+)"));
|
||||||
|
if(screenRe.exactMatch(screenComboBox->currentText())) {
|
||||||
|
mGraphicsSettings.setValue(QString("Video/screen"), screenRe.cap(1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer)
|
QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer)
|
||||||
@ -240,64 +334,61 @@ QStringList GraphicsPage::getAvailableOptions(const QString &key, Ogre::RenderSy
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
QStringList GraphicsPage::getAvailableResolutions(Ogre::RenderSystem *renderer)
|
QStringList GraphicsPage::getAvailableResolutions(int screen)
|
||||||
{
|
{
|
||||||
QString key("Video Mode");
|
|
||||||
QStringList result;
|
QStringList result;
|
||||||
|
for (std::vector<VideoMode>::iterator it = mVideoModes.begin(); it != mVideoModes.end(); it++)
|
||||||
uint row = 0;
|
|
||||||
Ogre::ConfigOptionMap options = renderer->getConfigOptions();
|
|
||||||
|
|
||||||
for (Ogre::ConfigOptionMap::iterator i = options.begin (); i != options.end (); i++, row++)
|
|
||||||
{
|
{
|
||||||
if (key.toStdString() != i->first)
|
VideoMode mode = *it;
|
||||||
|
if(mode.screen != screen)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
Ogre::StringVector::iterator opt_it;
|
QString aspect = getAspect(mode.w, mode.h);
|
||||||
uint idx = 0;
|
QString resolution = QString::number(mode.w) + QString(" x ") + QString::number(mode.h);
|
||||||
|
|
||||||
for (opt_it = i->second.possibleValues.begin ();
|
if (aspect == QLatin1String("16:9") || aspect == QLatin1String("16:10")) {
|
||||||
opt_it != i->second.possibleValues.end (); opt_it++, idx++)
|
resolution.append(tr("\t(Wide ") + aspect + ")");
|
||||||
{
|
|
||||||
QRegExp resolutionRe(QString("(\\d+) x (\\d+).*"));
|
|
||||||
QString resolution = QString::fromStdString(*opt_it).simplified();
|
|
||||||
|
|
||||||
if (resolutionRe.exactMatch(resolution)) {
|
} else if (aspect == QLatin1String("4:3")) {
|
||||||
|
resolution.append(tr("\t(Standard 4:3)"));
|
||||||
int width = resolutionRe.cap(1).toInt();
|
|
||||||
int height = resolutionRe.cap(2).toInt();
|
|
||||||
|
|
||||||
QString aspect = getAspect(width, height);
|
|
||||||
QString cleanRes = resolutionRe.cap(1) + QString(" x ") + resolutionRe.cap(2);
|
|
||||||
|
|
||||||
if (aspect == QLatin1String("16:9") || aspect == QLatin1String("16:10")) {
|
|
||||||
cleanRes.append(tr("\t(Wide ") + aspect + ")");
|
|
||||||
|
|
||||||
} else if (aspect == QLatin1String("4:3")) {
|
|
||||||
cleanRes.append(tr("\t(Standard 4:3)"));
|
|
||||||
}
|
|
||||||
// do not add duplicate resolutions
|
|
||||||
if (!result.contains(cleanRes))
|
|
||||||
result.append(cleanRes);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
result.append(resolution);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Sort the resolutions in descending order
|
|
||||||
qSort(result.begin(), result.end(), naturalSortGreaterThanCI);
|
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
QRect GraphicsPage::getMaximumResolution()
|
||||||
|
{
|
||||||
|
QRect max;
|
||||||
|
int screens = QApplication::desktop()->screenCount();
|
||||||
|
for (int i = 0; i < screens; ++i)
|
||||||
|
{
|
||||||
|
QRect res = QApplication::desktop()->screenGeometry(i);
|
||||||
|
if (res.width() > max.width())
|
||||||
|
max.setWidth(res.width());
|
||||||
|
if (res.height() > max.height())
|
||||||
|
max.setHeight(res.height());
|
||||||
|
}
|
||||||
|
return max;
|
||||||
|
}
|
||||||
|
|
||||||
void GraphicsPage::rendererChanged(const QString &renderer)
|
void GraphicsPage::rendererChanged(const QString &renderer)
|
||||||
{
|
{
|
||||||
mSelectedRenderSystem = mOgre->getRenderSystemByName(renderer.toStdString());
|
mSelectedRenderSystem = mOgre->getRenderSystemByName(renderer.toStdString());
|
||||||
|
|
||||||
antiAliasingComboBox->clear();
|
antiAliasingComboBox->clear();
|
||||||
resolutionComboBox->clear();
|
|
||||||
|
|
||||||
antiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem));
|
antiAliasingComboBox->addItems(getAvailableOptions(QString("FSAA"), mSelectedRenderSystem));
|
||||||
resolutionComboBox->addItems(getAvailableResolutions(mSelectedRenderSystem));
|
}
|
||||||
|
|
||||||
|
void GraphicsPage::screenChanged(const QString &screen)
|
||||||
|
{
|
||||||
|
QRegExp screenRe(QString(".*(\\d+)"));
|
||||||
|
if(screenRe.exactMatch(screen)) {
|
||||||
|
resolutionComboBox->clear();
|
||||||
|
resolutionComboBox->addItems(getAvailableResolutions(screenRe.cap(1).toInt() - 1));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void GraphicsPage::slotFullScreenChanged(int state)
|
void GraphicsPage::slotFullScreenChanged(int state)
|
||||||
|
@ -18,6 +18,13 @@
|
|||||||
|
|
||||||
#include "ui_graphicspage.h"
|
#include "ui_graphicspage.h"
|
||||||
|
|
||||||
|
struct VideoMode
|
||||||
|
{
|
||||||
|
int w;
|
||||||
|
int h;
|
||||||
|
int screen;
|
||||||
|
};
|
||||||
|
|
||||||
class GraphicsSettings;
|
class GraphicsSettings;
|
||||||
|
|
||||||
namespace Files { struct ConfigurationManager; }
|
namespace Files { struct ConfigurationManager; }
|
||||||
@ -30,10 +37,14 @@ public:
|
|||||||
GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &graphicsSettings, QWidget *parent = 0);
|
GraphicsPage(Files::ConfigurationManager &cfg, GraphicsSettings &graphicsSettings, QWidget *parent = 0);
|
||||||
|
|
||||||
void saveSettings();
|
void saveSettings();
|
||||||
bool setupOgre();
|
bool loadSettings();
|
||||||
|
|
||||||
|
// SDL workaround
|
||||||
|
static bool setupSDLWordaround();
|
||||||
|
|
||||||
public slots:
|
public slots:
|
||||||
void rendererChanged(const QString &renderer);
|
void rendererChanged(const QString &renderer);
|
||||||
|
void screenChanged(const QString &screen);
|
||||||
|
|
||||||
private slots:
|
private slots:
|
||||||
void slotFullScreenChanged(int state);
|
void slotFullScreenChanged(int state);
|
||||||
@ -55,10 +66,14 @@ private:
|
|||||||
GraphicsSettings &mGraphicsSettings;
|
GraphicsSettings &mGraphicsSettings;
|
||||||
|
|
||||||
QStringList getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer);
|
QStringList getAvailableOptions(const QString &key, Ogre::RenderSystem *renderer);
|
||||||
QStringList getAvailableResolutions(Ogre::RenderSystem *renderer);
|
QStringList getAvailableResolutions(int screen);
|
||||||
|
QRect getMaximumResolution();
|
||||||
|
|
||||||
void loadSettings();
|
static std::vector<VideoMode> mVideoModes;
|
||||||
|
static int mScreenCount;
|
||||||
|
|
||||||
|
bool setupOgre();
|
||||||
|
bool setupSDL();
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -3,9 +3,14 @@
|
|||||||
#include <QDir>
|
#include <QDir>
|
||||||
|
|
||||||
#include "maindialog.hpp"
|
#include "maindialog.hpp"
|
||||||
|
// SDL workaround
|
||||||
|
#include "graphicspage.hpp"
|
||||||
|
|
||||||
int main(int argc, char *argv[])
|
int main(int argc, char *argv[])
|
||||||
{
|
{
|
||||||
|
// SDL woraround
|
||||||
|
GraphicsPage::setupSDLWordaround();
|
||||||
|
|
||||||
QApplication app(argc, argv);
|
QApplication app(argc, argv);
|
||||||
|
|
||||||
// Now we make sure the current dir is set to application path
|
// Now we make sure the current dir is set to application path
|
||||||
|
@ -292,8 +292,8 @@ bool MainDialog::setup()
|
|||||||
// Now create the pages as they need the settings
|
// Now create the pages as they need the settings
|
||||||
createPages();
|
createPages();
|
||||||
|
|
||||||
// Call this so we can exit on Ogre errors before mainwindow is shown
|
// Call this so we can exit on Ogre/SDL errors before mainwindow is shown
|
||||||
if (!mGraphicsPage->setupOgre())
|
if (!mGraphicsPage->loadSettings())
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
loadSettings();
|
loadSettings();
|
||||||
|
@ -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();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -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;
|
|
||||||
|
|
||||||
result.mCloudTexture = current.mCloudTexture;
|
mResult.mCloudTexture = current.mCloudTexture;
|
||||||
result.mCloudBlendFactor = 0;
|
mResult.mCloudBlendFactor = 0;
|
||||||
result.mCloudOpacity = current.mCloudsMaximumPercent;
|
mResult.mCloudOpacity = current.mCloudsMaximumPercent;
|
||||||
result.mWindSpeed = current.mWindSpeed;
|
mResult.mWindSpeed = current.mWindSpeed;
|
||||||
result.mCloudSpeed = current.mCloudSpeed;
|
mResult.mCloudSpeed = current.mCloudSpeed;
|
||||||
result.mGlareView = current.mGlareView;
|
mResult.mGlareView = current.mGlareView;
|
||||||
result.mAmbientLoopSoundID = current.mAmbientLoopSoundID;
|
mResult.mAmbientLoopSoundID = current.mAmbientLoopSoundID;
|
||||||
result.mSunColor = current.mSunDiscSunsetColor;
|
mResult.mSunColor = current.mSunDiscSunsetColor;
|
||||||
|
|
||||||
result.mNight = (mHour < mSunriseTime || mHour > mNightStart - 1);
|
|
||||||
|
|
||||||
result.mFogDepth = result.mNight ? current.mLandFogNightDepth : current.mLandFogDayDepth;
|
mResult.mNight = (mHour < mSunriseTime || mHour > mNightStart - 1);
|
||||||
|
|
||||||
|
mResult.mFogDepth = mResult.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;
|
mResult.mCloudTexture = current.mCloudTexture;
|
||||||
result.mNextCloudTexture = other.mCloudTexture;
|
mResult.mNextCloudTexture = other.mCloudTexture;
|
||||||
result.mCloudBlendFactor = factor;
|
mResult.mCloudBlendFactor = factor;
|
||||||
|
|
||||||
result.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity, factor);
|
mResult.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity, factor);
|
||||||
result.mFogColor = lerp(current.mFogColor, other.mFogColor, factor);
|
mResult.mFogColor = lerp(current.mFogColor, other.mFogColor, factor);
|
||||||
result.mSunColor = lerp(current.mSunColor, other.mSunColor, factor);
|
mResult.mSunColor = lerp(current.mSunColor, other.mSunColor, factor);
|
||||||
result.mSkyColor = lerp(current.mSkyColor, other.mSkyColor, factor);
|
mResult.mSkyColor = lerp(current.mSkyColor, other.mSkyColor, factor);
|
||||||
|
|
||||||
result.mAmbientColor = lerp(current.mAmbientColor, other.mAmbientColor, factor);
|
mResult.mAmbientColor = lerp(current.mAmbientColor, other.mAmbientColor, factor);
|
||||||
result.mSunDiscColor = lerp(current.mSunDiscColor, other.mSunDiscColor, factor);
|
mResult.mSunDiscColor = lerp(current.mSunDiscColor, other.mSunDiscColor, factor);
|
||||||
result.mFogDepth = lerp(current.mFogDepth, other.mFogDepth, factor);
|
mResult.mFogDepth = lerp(current.mFogDepth, other.mFogDepth, factor);
|
||||||
result.mWindSpeed = lerp(current.mWindSpeed, other.mWindSpeed, factor);
|
mResult.mWindSpeed = lerp(current.mWindSpeed, other.mWindSpeed, factor);
|
||||||
result.mCloudSpeed = lerp(current.mCloudSpeed, other.mCloudSpeed, factor);
|
mResult.mCloudSpeed = lerp(current.mCloudSpeed, other.mCloudSpeed, factor);
|
||||||
result.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity, factor);
|
mResult.mCloudOpacity = lerp(current.mCloudOpacity, other.mCloudOpacity, factor);
|
||||||
result.mGlareView = lerp(current.mGlareView, other.mGlareView, factor);
|
mResult.mGlareView = lerp(current.mGlareView, other.mGlareView, factor);
|
||||||
result.mNightFade = lerp(current.mNightFade, other.mNightFade, 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);
|
|
||||||
|
|
||||||
if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion)
|
|
||||||
{
|
|
||||||
mCurrentRegion = regionstr;
|
|
||||||
mWeatherUpdateTime = mHoursBetweenWeatherChanges * 3600;
|
|
||||||
|
|
||||||
std::string weather = "clear";
|
|
||||||
|
|
||||||
if (mRegionOverrides.find(regionstr) != mRegionOverrides.end())
|
|
||||||
weather = mRegionOverrides[regionstr];
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// get weather probabilities for the current region
|
|
||||||
const ESM::Region *region =
|
|
||||||
MWBase::Environment::get().getWorld()->getStore().get<ESM::Region>().search (regionstr);
|
|
||||||
|
|
||||||
if (region != 0)
|
|
||||||
{
|
|
||||||
float clear = region->mData.mClear/255.f;
|
|
||||||
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;
|
|
||||||
|
|
||||||
if (mNextWeather != "")
|
|
||||||
{
|
|
||||||
mRemainingTransitionTime -= timePassed;
|
|
||||||
if (mRemainingTransitionTime < 0)
|
|
||||||
{
|
|
||||||
mCurrentWeather = mNextWeather;
|
|
||||||
mNextWeather = "";
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mNextWeather != "")
|
|
||||||
result = transition(1 - (mRemainingTransitionTime / (mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600)));
|
|
||||||
else
|
|
||||||
result = getResult(mCurrentWeather);
|
|
||||||
|
|
||||||
mWindSpeed = result.mWindSpeed;
|
|
||||||
|
|
||||||
mRendering->configureFog(result.mFogDepth, result.mFogColor);
|
|
||||||
|
|
||||||
// disable sun during night
|
|
||||||
if (mHour >= mNightStart || mHour <= mSunriseTime)
|
|
||||||
mRendering->getSkyManager()->sunDisable();
|
|
||||||
else
|
|
||||||
mRendering->getSkyManager()->sunEnable();
|
|
||||||
|
|
||||||
// sun angle
|
|
||||||
float height;
|
|
||||||
|
|
||||||
//Day duration
|
|
||||||
float dayDuration = (mNightStart - 1) - mSunriseTime;
|
|
||||||
|
|
||||||
// rise at 6, set at 20
|
|
||||||
if (mHour >= mSunriseTime && mHour <= mNightStart)
|
|
||||||
height = 1 - std::abs(((mHour - dayDuration) / 7.f));
|
|
||||||
else if (mHour > mNightStart)
|
|
||||||
height = (mHour - mNightStart) / 4.f;
|
|
||||||
else //if (mHour > 0 && mHour < 6)
|
|
||||||
height = 1 - (mHour / mSunriseTime);
|
|
||||||
|
|
||||||
int facing = (mHour > 13.f) ? 1 : -1;
|
|
||||||
|
|
||||||
Vector3 final(
|
|
||||||
-(1 - height) * facing,
|
|
||||||
-(1 - height) * facing,
|
|
||||||
height);
|
|
||||||
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));
|
|
||||||
|
|
||||||
if (moonHeight != 0)
|
|
||||||
{
|
|
||||||
int facing = (moonHeight <= 1) ? 1 : -1;
|
|
||||||
Vector3 masser(
|
|
||||||
(moonHeight - 1) * facing,
|
|
||||||
(1 - moonHeight) * facing,
|
|
||||||
moonHeight);
|
|
||||||
|
|
||||||
Vector3 secunda(
|
|
||||||
(moonHeight - 1) * facing * 1.25,
|
|
||||||
(1 - moonHeight) * facing * 0.8,
|
|
||||||
moonHeight);
|
|
||||||
|
|
||||||
mRendering->getSkyManager()->setMasserDirection(masser);
|
|
||||||
mRendering->getSkyManager()->setSecundaDirection(secunda);
|
|
||||||
mRendering->getSkyManager()->masserEnable();
|
|
||||||
mRendering->getSkyManager()->secundaEnable();
|
|
||||||
|
|
||||||
float angle = (1-moonHeight) * 90.f * facing;
|
|
||||||
float masserHourFade = calculateHourFade("Masser");
|
|
||||||
float secundaHourFade = calculateHourFade("Secunda");
|
|
||||||
float masserAngleFade = calculateAngleFade("Masser", angle);
|
|
||||||
float secundaAngleFade = calculateAngleFade("Secunda", angle);
|
|
||||||
|
|
||||||
masserAngleFade *= masserHourFade;
|
|
||||||
secundaAngleFade *= secundaHourFade;
|
|
||||||
|
|
||||||
mRendering->getSkyManager()->setMasserFade(masserAngleFade);
|
|
||||||
mRendering->getSkyManager()->setSecundaFade(secundaAngleFade);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
mRendering->getSkyManager()->masserDisable();
|
|
||||||
mRendering->getSkyManager()->secundaDisable();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (mCurrentWeather == "thunderstorm" && mNextWeather == "" && exterior)
|
|
||||||
{
|
|
||||||
if (mThunderFlash > 0)
|
|
||||||
{
|
|
||||||
// play the sound after a delay
|
|
||||||
mThunderSoundDelay -= duration;
|
|
||||||
if (mThunderSoundDelay <= 0)
|
|
||||||
{
|
|
||||||
// pick a random sound
|
|
||||||
int sound = rand() % 4;
|
|
||||||
std::string soundname;
|
|
||||||
if (sound == 0) soundname = mThunderSoundID0;
|
|
||||||
else if (sound == 1) soundname = mThunderSoundID1;
|
|
||||||
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 );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// no thunder active
|
|
||||||
mThunderChance += duration*4; // chance increases by 4 percent every second
|
|
||||||
if (mThunderChance >= mThunderChanceNeeded)
|
|
||||||
{
|
|
||||||
mThunderFlash = mThunderThreshold;
|
|
||||||
|
|
||||||
mRendering->getSkyManager()->setLightningStrength( mThunderFlash / mThunderThreshold );
|
|
||||||
|
|
||||||
mThunderSoundDelay = 0.25;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
mRendering->getSkyManager()->setLightningStrength(0.f);
|
|
||||||
|
|
||||||
mRendering->setAmbientColour(result.mAmbientColor);
|
|
||||||
mRendering->sunEnable(false);
|
|
||||||
mRendering->setSunColour(result.mSunColor);
|
|
||||||
|
|
||||||
mRendering->getSkyManager()->setWeather(result);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
{
|
||||||
mRendering->sunDisable(false);
|
mRendering->sunDisable(false);
|
||||||
mRendering->skyDisable();
|
mRendering->skyDisable();
|
||||||
mRendering->getSkyManager()->setLightningStrength(0.f);
|
mRendering->getSkyManager()->setLightningStrength(0.f);
|
||||||
|
stopSounds(true);
|
||||||
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// play sounds
|
// Exterior
|
||||||
std::string ambientSnd = (mNextWeather == "" ? mWeatherSettings[mCurrentWeather].mAmbientLoopSoundID : "");
|
std::string regionstr = Misc::StringUtils::lowerCase(MWBase::Environment::get().getWorld()->getPlayer().getPlayer().getCell()->mCell->mRegion);
|
||||||
if (!exterior) ambientSnd = "";
|
|
||||||
if (ambientSnd != "")
|
if (mWeatherUpdateTime <= 0 || regionstr != mCurrentRegion)
|
||||||
{
|
{
|
||||||
if (std::find(mSoundsPlaying.begin(), mSoundsPlaying.end(), ambientSnd) == mSoundsPlaying.end())
|
mCurrentRegion = regionstr;
|
||||||
|
mWeatherUpdateTime = mHoursBetweenWeatherChanges * 3600;
|
||||||
|
|
||||||
|
std::string weatherType = "clear";
|
||||||
|
|
||||||
|
if (mRegionOverrides.find(regionstr) != mRegionOverrides.end())
|
||||||
|
weatherType = mRegionOverrides[regionstr];
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// get weather probabilities for the current region
|
||||||
|
const ESM::Region *region =
|
||||||
|
MWBase::Environment::get().getWorld()->getStore().get<ESM::Region>().search (regionstr);
|
||||||
|
|
||||||
|
if (region != 0)
|
||||||
|
{
|
||||||
|
weatherType = nextWeather(region);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
setWeather(weatherType, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mNextWeather != "")
|
||||||
|
{
|
||||||
|
mRemainingTransitionTime -= timePassed;
|
||||||
|
if (mRemainingTransitionTime < 0)
|
||||||
|
{
|
||||||
|
mCurrentWeather = mNextWeather;
|
||||||
|
mNextWeather = "";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mNextWeather != "")
|
||||||
|
transition(1 - (mRemainingTransitionTime / (mWeatherSettings[mCurrentWeather].mTransitionDelta * 24.f * 3600)));
|
||||||
|
else
|
||||||
|
setResult(mCurrentWeather);
|
||||||
|
|
||||||
|
mWindSpeed = mResult.mWindSpeed;
|
||||||
|
|
||||||
|
mRendering->configureFog(mResult.mFogDepth, mResult.mFogColor);
|
||||||
|
|
||||||
|
// disable sun during night
|
||||||
|
if (mHour >= mNightStart || mHour <= mSunriseTime)
|
||||||
|
mRendering->getSkyManager()->sunDisable();
|
||||||
|
else
|
||||||
|
mRendering->getSkyManager()->sunEnable();
|
||||||
|
|
||||||
|
// sun angle
|
||||||
|
float height;
|
||||||
|
|
||||||
|
//Day duration
|
||||||
|
float dayDuration = (mNightStart - 1) - mSunriseTime;
|
||||||
|
|
||||||
|
// rise at 6, set at 20
|
||||||
|
if (mHour >= mSunriseTime && mHour <= mNightStart)
|
||||||
|
height = 1 - std::abs(((mHour - dayDuration) / 7.f));
|
||||||
|
else if (mHour > mNightStart)
|
||||||
|
height = (mHour - mNightStart) / 4.f;
|
||||||
|
else //if (mHour > 0 && mHour < 6)
|
||||||
|
height = 1 - (mHour / mSunriseTime);
|
||||||
|
|
||||||
|
int facing = (mHour > 13.f) ? 1 : -1;
|
||||||
|
|
||||||
|
Vector3 final(
|
||||||
|
(height - 1) * facing,
|
||||||
|
(height - 1) * facing,
|
||||||
|
height);
|
||||||
|
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));
|
||||||
|
|
||||||
|
if (moonHeight != 0)
|
||||||
|
{
|
||||||
|
int facing = (moonHeight <= 1) ? 1 : -1;
|
||||||
|
Vector3 masser(
|
||||||
|
(moonHeight - 1) * facing,
|
||||||
|
(1 - moonHeight) * facing,
|
||||||
|
moonHeight);
|
||||||
|
|
||||||
|
Vector3 secunda(
|
||||||
|
(moonHeight - 1) * facing * 1.25,
|
||||||
|
(1 - moonHeight) * facing * 0.8,
|
||||||
|
moonHeight);
|
||||||
|
|
||||||
|
mRendering->getSkyManager()->setMasserDirection(masser);
|
||||||
|
mRendering->getSkyManager()->setSecundaDirection(secunda);
|
||||||
|
mRendering->getSkyManager()->masserEnable();
|
||||||
|
mRendering->getSkyManager()->secundaEnable();
|
||||||
|
|
||||||
|
float angle = (1-moonHeight) * 90.f * facing;
|
||||||
|
float masserHourFade = calculateHourFade("Masser");
|
||||||
|
float secundaHourFade = calculateHourFade("Secunda");
|
||||||
|
float masserAngleFade = calculateAngleFade("Masser", angle);
|
||||||
|
float secundaAngleFade = calculateAngleFade("Secunda", angle);
|
||||||
|
|
||||||
|
masserAngleFade *= masserHourFade;
|
||||||
|
secundaAngleFade *= secundaHourFade;
|
||||||
|
|
||||||
|
mRendering->getSkyManager()->setMasserFade(masserAngleFade);
|
||||||
|
mRendering->getSkyManager()->setSecundaFade(secundaAngleFade);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mRendering->getSkyManager()->masserDisable();
|
||||||
|
mRendering->getSkyManager()->secundaDisable();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mCurrentWeather == "thunderstorm" && mNextWeather == "")
|
||||||
|
{
|
||||||
|
if (mThunderFlash > 0)
|
||||||
|
{
|
||||||
|
// play the sound after a delay
|
||||||
|
mThunderSoundDelay -= duration;
|
||||||
|
if (mThunderSoundDelay <= 0)
|
||||||
|
{
|
||||||
|
// pick a random sound
|
||||||
|
int sound = rand() % 4;
|
||||||
|
std::string* soundName;
|
||||||
|
if (sound == 0) soundName = &mThunderSoundID0;
|
||||||
|
else if (sound == 1) soundName = &mThunderSoundID1;
|
||||||
|
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
|
||||||
|
{
|
||||||
|
mThunderChanceNeeded = rand() % 100;
|
||||||
|
mThunderChance = 0;
|
||||||
|
mRendering->getSkyManager()->setLightningStrength( 0.f );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// no thunder active
|
||||||
|
mThunderChance += duration*4; // chance increases by 4 percent every second
|
||||||
|
if (mThunderChance >= mThunderChanceNeeded)
|
||||||
|
{
|
||||||
|
mThunderFlash = mThunderThreshold;
|
||||||
|
|
||||||
|
mRendering->getSkyManager()->setLightningStrength( mThunderFlash / mThunderThreshold );
|
||||||
|
|
||||||
|
mThunderSoundDelay = 0.25;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
mRendering->getSkyManager()->setLightningStrength(0.f);
|
||||||
|
|
||||||
|
mRendering->setAmbientColour(mResult.mAmbientColor);
|
||||||
|
mRendering->sunEnable(false);
|
||||||
|
mRendering->setSunColour(mResult.mSunColor);
|
||||||
|
|
||||||
|
mRendering->getSkyManager()->setWeather(mResult);
|
||||||
|
|
||||||
|
|
||||||
|
// Play sounds
|
||||||
|
if (mNextWeather == "")
|
||||||
|
{
|
||||||
|
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;
|
||||||
|
@ -58,6 +58,13 @@
|
|||||||
</widget>
|
</widget>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="0">
|
<item row="3" column="0">
|
||||||
|
<widget class="QLabel" name="screenLabel">
|
||||||
|
<property name="text">
|
||||||
|
<string>Screen:</string>
|
||||||
|
</property>
|
||||||
|
</widget>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="0">
|
||||||
<widget class="QLabel" name="resolutionLabel">
|
<widget class="QLabel" name="resolutionLabel">
|
||||||
<property name="text">
|
<property name="text">
|
||||||
<string>Resolution:</string>
|
<string>Resolution:</string>
|
||||||
@ -71,6 +78,9 @@
|
|||||||
<widget class="QComboBox" name="antiAliasingComboBox"/>
|
<widget class="QComboBox" name="antiAliasingComboBox"/>
|
||||||
</item>
|
</item>
|
||||||
<item row="3" column="1">
|
<item row="3" column="1">
|
||||||
|
<widget class="QComboBox" name="screenComboBox"/>
|
||||||
|
</item>
|
||||||
|
<item row="4" column="1">
|
||||||
<layout class="QGridLayout" name="resolutionLayout">
|
<layout class="QGridLayout" name="resolutionLayout">
|
||||||
<item row="1" column="2">
|
<item row="1" column="2">
|
||||||
<layout class="QHBoxLayout" name="customResolutionLayout" stretch="1,0,1">
|
<layout class="QHBoxLayout" name="customResolutionLayout" stretch="1,0,1">
|
||||||
|
Loading…
x
Reference in New Issue
Block a user