From 441420225f47fb7af3555c45fcf19f614b6c8d8f Mon Sep 17 00:00:00 2001 From: scrawl <720642+scrawl@users.noreply.github.com> Date: Mon, 4 Dec 2017 17:00:02 +0000 Subject: [PATCH 01/31] Contributing.md: referencing issues in commit messages --- CONTRIBUTING.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index b5a7423d2..6c82d1dfd 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -33,6 +33,7 @@ Furthermore, we advise to: * Feel free to submit incomplete pull requests. Even if the work can not be merged yet, pull requests are a great place to collect early feedback. Just make sure to mark it as *[Incomplete]* or *[Do not merge yet]* in the title. * If you plan on contributing often, please read the [Developer Reference](https://wiki.openmw.org/index.php?title=Developer_Reference) on our wiki, especially the [Policies and Standards](https://wiki.openmw.org/index.php?title=Policies_and_Standards). * Make sure each of your changes has a clear objective. Unnecessary changes may lead to merge conflicts, clutter the commit history and slow down review. Code formatting 'fixes' should be avoided, unless you were already changing that particular line anyway. +* Reference the bug / feature ticket(s) in your commit message (e.g. 'Bug #123') to make it easier to keep track of what we changed for what reason. Our bugtracker will show those commits next to the ticket. If your commit message includes 'Fixes #123', that bug/feature will automatically be set to 'Closed' when your commit is merged. Guidelines for original engine "fixes" ================================= From b6ae7f3cc8106fb9b1c1b7791ad243e36fd06ddd Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Mon, 4 Dec 2017 22:01:57 +0400 Subject: [PATCH 02/31] Do not add greetings to the journal index (bug #4342) --- apps/openmw/mwdialogue/dialoguemanagerimp.cpp | 20 ++++++++++--------- 1 file changed, 11 insertions(+), 9 deletions(-) diff --git a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp index 1f6de04e5..de9ca83ca 100644 --- a/apps/openmw/mwdialogue/dialoguemanagerimp.cpp +++ b/apps/openmw/mwdialogue/dialoguemanagerimp.cpp @@ -146,7 +146,6 @@ namespace MWDialogue // TODO play sound } - MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor); callback->addResponse("", Interpreter::fixDefinesDialog(info->mResponse, interpreterContext)); executeScript (info->mResultScript, mActor); @@ -387,7 +386,7 @@ namespace MWDialogue { Filter filter (mActor, mChoice, mTalkedTo); - if (dialogue->mType == ESM::Dialogue::Topic || dialogue->mType == ESM::Dialogue::Greeting) + if (dialogue->mType == ESM::Dialogue::Topic || dialogue->mType == ESM::Dialogue::Greeting) { if (const ESM::DialInfo *info = filter.search (*dialogue, true)) { @@ -401,15 +400,18 @@ namespace MWDialogue MWScript::InterpreterContext interpreterContext(&mActor.getRefData().getLocals(),mActor); callback->addResponse("", Interpreter::fixDefinesDialog(text, interpreterContext)); - // Make sure the returned DialInfo is from the Dialogue we supplied. If could also be from the Info refusal group, - // in which case it should not be added to the journal. - for (ESM::Dialogue::InfoContainer::const_iterator iter = dialogue->mInfo.begin(); - iter!=dialogue->mInfo.end(); ++iter) + if (dialogue->mType == ESM::Dialogue::Topic) { - if (iter->mId == info->mId) + // Make sure the returned DialInfo is from the Dialogue we supplied. If could also be from the Info refusal group, + // in which case it should not be added to the journal + for (ESM::Dialogue::InfoContainer::const_iterator iter = dialogue->mInfo.begin(); + iter!=dialogue->mInfo.end(); ++iter) { - MWBase::Environment::get().getJournal()->addTopic (Misc::StringUtils::lowerCase(mLastTopic), info->mId, mActor); - break; + if (iter->mId == info->mId) + { + MWBase::Environment::get().getJournal()->addTopic (Misc::StringUtils::lowerCase(mLastTopic), info->mId, mActor); + break; + } } } From 29b2308b2c64510e787a526793abe65065624bb6 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Mon, 4 Dec 2017 22:10:22 +0400 Subject: [PATCH 03/31] Do not display cyrillic soft/hard signs in the journal index --- apps/openmw/mwgui/journalbooks.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwgui/journalbooks.cpp b/apps/openmw/mwgui/journalbooks.cpp index f3ee8162e..e8aa23158 100644 --- a/apps/openmw/mwgui/journalbooks.cpp +++ b/apps/openmw/mwgui/journalbooks.cpp @@ -281,6 +281,8 @@ BookTypesetter::Ptr JournalBooks::createCyrillicJournalIndex () textColours.journalTopicOver, textColours.journalTopicPressed, first); + ch[1]++; + // Words can not be started with these characters if (i == 26 || i == 28) continue; @@ -290,8 +292,6 @@ BookTypesetter::Ptr JournalBooks::createCyrillicJournalIndex () typesetter->write (style, to_utf8_span (buffer)); typesetter->lineBreak (); - - ch[1]++; } return typesetter; From a28cc37501c729930bb935cc305696e413a75c4e Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Tue, 5 Dec 2017 10:24:58 +0400 Subject: [PATCH 04/31] Do not sell ingredients from organic containers --- apps/openmw/mwworld/worldimp.cpp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 9c7fba9fa..2d38f1518 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2446,6 +2446,11 @@ namespace MWWorld if (ptr.getRefData().isDeleted()) return true; + // we should not sell ingrediends from owned organic containers + MWWorld::LiveCellRef* ref = ptr.get(); + if (ref && (ref->mBase->mFlags & ESM::Container::Organic)) + return true; + if (Misc::StringUtils::ciEqual(ptr.getCellRef().getOwner(), mOwner.getCellRef().getRefId())) mOut.push_back(ptr); From e0c54b3f396d53c13cd83bf3f9806cc4104fa47e Mon Sep 17 00:00:00 2001 From: Allofich Date: Tue, 5 Dec 2017 23:41:08 +0900 Subject: [PATCH 05/31] Stop guards trying to arrest player when calm (Fixes #3863) --- apps/openmw/mwmechanics/actors.cpp | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/apps/openmw/mwmechanics/actors.cpp b/apps/openmw/mwmechanics/actors.cpp index 20955f22a..d685967da 100644 --- a/apps/openmw/mwmechanics/actors.cpp +++ b/apps/openmw/mwmechanics/actors.cpp @@ -1009,7 +1009,8 @@ namespace MWMechanics if (player.getClass().getNpcStats(player).isWerewolf()) return; - if (ptr.getClass().isClass(ptr, "Guard") && creatureStats.getAiSequence().getTypeId() != AiPackage::TypeIdPursue && !creatureStats.getAiSequence().isInCombat()) + if (ptr.getClass().isClass(ptr, "Guard") && creatureStats.getAiSequence().getTypeId() != AiPackage::TypeIdPursue && !creatureStats.getAiSequence().isInCombat() + && creatureStats.getMagicEffects().get(ESM::MagicEffect::CalmHumanoid).getMagnitude() == 0) { const MWWorld::ESMStore& esmStore = MWBase::Environment::get().getWorld()->getStore(); static const int cutoff = esmStore.get().find("iCrimeThreshold")->getInt(); From 7e87ce878760022c2c875336b7802aac0b18dc9c Mon Sep 17 00:00:00 2001 From: Allofich Date: Wed, 6 Dec 2017 00:31:48 +0900 Subject: [PATCH 06/31] Prevent combat on/off cycling for calmed actors --- apps/openmw/mwmechanics/mechanicsmanagerimp.cpp | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp index 2b6236ecb..b51b55421 100644 --- a/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp +++ b/apps/openmw/mwmechanics/mechanicsmanagerimp.cpp @@ -1653,6 +1653,12 @@ namespace MWMechanics bool MechanicsManager::isAggressive(const MWWorld::Ptr &ptr, const MWWorld::Ptr &target) { + // Don't become aggressive if a calm effect is active, since it would cause combat to cycle on/off as + // combat is activated here and then canceled by the calm effect + if ((ptr.getClass().isNpc() && ptr.getClass().getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::CalmHumanoid).getMagnitude() > 0) + || (!ptr.getClass().isNpc() && ptr.getClass().getCreatureStats(ptr).getMagicEffects().get(ESM::MagicEffect::CalmCreature).getMagnitude() > 0)) + return false; + int disposition = 50; if (ptr.getClass().isNpc()) disposition = getDerivedDisposition(ptr, true); From 744859f32715a1244930f049b9d4933e27f2b34f Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Thu, 7 Dec 2017 22:43:32 +0400 Subject: [PATCH 07/31] Take in account armor condition in the armor rating calculation (bug #4246) --- apps/openmw/mwclass/npc.cpp | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/apps/openmw/mwclass/npc.cpp b/apps/openmw/mwclass/npc.cpp index e7085bfbc..134bbf943 100644 --- a/apps/openmw/mwclass/npc.cpp +++ b/apps/openmw/mwclass/npc.cpp @@ -1129,6 +1129,15 @@ namespace MWClass else { ratings[i] = it->getClass().getEffectiveArmorRating(*it, ptr); + + // Take in account armor condition + const bool hasHealth = it->getClass().hasItemHealth(*it); + if (hasHealth) + { + int armorHealth = it->getClass().getItemHealth(*it); + int armorMaxHealth = it->getClass().getItemMaxHealth(*it); + ratings[i] *= (float(armorHealth) / armorMaxHealth); + } } } From 360d786ff2a203c7363675d432697ff42e39374a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Thu, 7 Dec 2017 23:48:34 +0100 Subject: [PATCH 08/31] CS: Add rendering prefs and camera FOV --- apps/opencs/model/prefs/state.cpp | 3 +++ apps/opencs/view/prefs/dialogue.cpp | 1 - apps/opencs/view/render/scenewidget.cpp | 6 +++++- 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index 1f84c5a87..be6534089 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -192,6 +192,9 @@ void CSMPrefs::State::declare() setRange (0.001, 100.0); declareDouble ("rotate-factor", "Free rotation factor", 0.007).setPrecision(4).setRange(0.0001, 0.1); + declareCategory ("Rendering"); + declareDouble ("camera-fov", "Camera FOV", 90.).setPrecision(5).setRange(10.0, 160.0); + declareCategory ("Tooltips"); declareBool ("scene", "Show Tooltips in 3D scenes", true); declareBool ("scene-hide-basic", "Hide basic 3D scenes tooltips", false); diff --git a/apps/opencs/view/prefs/dialogue.cpp b/apps/opencs/view/prefs/dialogue.cpp index 960ca74bc..1f5772f18 100644 --- a/apps/opencs/view/prefs/dialogue.cpp +++ b/apps/opencs/view/prefs/dialogue.cpp @@ -84,7 +84,6 @@ CSVPrefs::Dialogue::~Dialogue() void CSVPrefs::Dialogue::closeEvent (QCloseEvent *event) { QMainWindow::closeEvent (event); - CSMPrefs::State::get().save(); } diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 11c7f5926..46bbb29dd 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -66,7 +66,11 @@ RenderWidget::RenderWidget(QWidget *parent, Qt::WindowFlags f) mView->getCamera()->setGraphicsContext(window); mView->getCamera()->setClearColor( osg::Vec4(0.2, 0.2, 0.6, 1.0) ); mView->getCamera()->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) ); - mView->getCamera()->setProjectionMatrixAsPerspective(30.0f, static_cast(traits->width)/static_cast(traits->height), 1.0f, 10000.0f ); + + mView->getCamera()->setProjectionMatrixAsPerspective( + CSMPrefs::get()["Rendering"]["camera-fov"].toDouble(), + static_cast(traits->width)/static_cast(traits->height), + 1.0f, 10000.0f); SceneUtil::LightManager* lightMgr = new SceneUtil::LightManager; lightMgr->setStartLight(1); From 7d36dd68dcc4e3b245a119a948959b9f91f37752 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Thu, 7 Dec 2017 23:52:05 +0100 Subject: [PATCH 09/31] CS: Make orbit camera not change roll --- apps/opencs/view/render/cameracontroller.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index 7b802b0ef..cb1278805 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -673,6 +673,7 @@ namespace CSVRender { osg::Vec3d eye, center, up; getCamera()->getViewMatrixAsLookAt(eye, center, up); + up = osg::Vec3(0,0,1); osg::Quat rotation = osg::Quat(value, up); osg::Vec3d oldOffset = eye - mCenter; @@ -685,6 +686,7 @@ namespace CSVRender { osg::Vec3d eye, center, up; getCamera()->getViewMatrixAsLookAt(eye, center, up); + up = osg::Vec3(0,0,1); osg::Vec3d forward = center - eye; osg::Quat rotation = osg::Quat(value, up ^ forward); From cfdc6c788ed33d9a5dc5f3b7c2a2b687769f3f94 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Fri, 8 Dec 2017 00:05:50 +0100 Subject: [PATCH 10/31] CS: Make camera FOV change dynamically --- apps/opencs/view/render/scenewidget.cpp | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 46bbb29dd..7d3ac3f1c 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -374,6 +374,13 @@ void SceneWidget::settingChanged (const CSMPrefs::Setting *setting) { mOrbitCamControl->setOrbitSpeedMultiplier(setting->toDouble()); } + else if (*setting=="Rendering/camera-fov") + { + mView->getCamera()->setProjectionMatrixAsPerspective( + setting->toDouble(), + static_cast(width())/static_cast(height()), + 1.0f, 10000.0f); + } } void SceneWidget::selectNavigationMode (const std::string& mode) From 5e076ee01519cf06f79cc59a717a8acd3298a9d3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Fri, 8 Dec 2017 00:19:05 +0100 Subject: [PATCH 11/31] CS: Fix camera orbit with arbitrary roll --- apps/opencs/view/render/cameracontroller.cpp | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index cb1278805..f0158fe28 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -673,12 +673,13 @@ namespace CSVRender { osg::Vec3d eye, center, up; getCamera()->getViewMatrixAsLookAt(eye, center, up); - up = osg::Vec3(0,0,1); + osg::Vec3 absoluteUp = osg::Vec3(0,0,1); - osg::Quat rotation = osg::Quat(value, up); + osg::Quat rotation = osg::Quat(value, absoluteUp); osg::Vec3d oldOffset = eye - mCenter; osg::Vec3d newOffset = rotation * oldOffset; + up = rotation * up; getCamera()->setViewMatrixAsLookAt(mCenter + newOffset, mCenter, up); } @@ -686,13 +687,14 @@ namespace CSVRender { osg::Vec3d eye, center, up; getCamera()->getViewMatrixAsLookAt(eye, center, up); - up = osg::Vec3(0,0,1); + osg::Vec3 absoluteUp = osg::Vec3(0,0,1); osg::Vec3d forward = center - eye; - osg::Quat rotation = osg::Quat(value, up ^ forward); + osg::Quat rotation = osg::Quat(value, absoluteUp ^ forward); osg::Vec3d oldOffset = eye - mCenter; osg::Vec3d newOffset = rotation * oldOffset; + up = rotation * up; getCamera()->setViewMatrixAsLookAt(mCenter + newOffset, mCenter, up); } From aecf74e7bbeca9dae1d19444535b511f3df7f473 Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 8 Dec 2017 07:00:04 -0800 Subject: [PATCH 12/31] Don't throw exceptions from the audio decoder --- apps/openmw/mwsound/ffmpeg_decoder.cpp | 190 ++++++++++++---------- apps/openmw/mwsound/ffmpeg_decoder.hpp | 18 +- apps/openmw/mwsound/movieaudiofactory.cpp | 32 ++-- apps/openmw/mwsound/openal_output.cpp | 14 +- apps/openmw/mwsound/sound_decoder.hpp | 4 +- 5 files changed, 146 insertions(+), 112 deletions(-) diff --git a/apps/openmw/mwsound/ffmpeg_decoder.cpp b/apps/openmw/mwsound/ffmpeg_decoder.cpp index 1f1834761..12ea84a42 100644 --- a/apps/openmw/mwsound/ffmpeg_decoder.cpp +++ b/apps/openmw/mwsound/ffmpeg_decoder.cpp @@ -3,7 +3,7 @@ #include #include -#include +#include #include #include @@ -11,11 +11,6 @@ namespace MWSound { -void FFmpeg_Decoder::fail(const std::string &msg) -{ - throw std::runtime_error("FFmpeg exception: "+msg); -} - int FFmpeg_Decoder::readPacket(void *user_data, uint8_t *buf, int buf_size) { try @@ -33,7 +28,8 @@ int FFmpeg_Decoder::readPacket(void *user_data, uint8_t *buf, int buf_size) int FFmpeg_Decoder::writePacket(void *, uint8_t *, int) { - throw std::runtime_error("can't write to read-only stream"); + std::cerr<< "can't write to read-only stream" <get(fname); + try + { + mDataStream = mResourceMgr->get(fname); - if((mFormatCtx=avformat_alloc_context()) == NULL) - fail("Failed to allocate context"); + if((mFormatCtx=avformat_alloc_context()) == NULL) + throw std::runtime_error("Failed to allocate context"); - mFormatCtx->pb = avio_alloc_context(NULL, 0, 0, this, readPacket, writePacket, seek); - if(!mFormatCtx->pb || avformat_open_input(&mFormatCtx, fname.c_str(), NULL, NULL) != 0) - { - // "Note that a user-supplied AVFormatContext will be freed on failure". - if (mFormatCtx) + mFormatCtx->pb = avio_alloc_context(NULL, 0, 0, this, readPacket, writePacket, seek); + if(!mFormatCtx->pb || avformat_open_input(&mFormatCtx, fname.c_str(), NULL, NULL) != 0) { - if (mFormatCtx->pb != NULL) + // "Note that a user-supplied AVFormatContext will be freed on failure". + if (mFormatCtx) { - if (mFormatCtx->pb->buffer != NULL) + if (mFormatCtx->pb != NULL) { - av_free(mFormatCtx->pb->buffer); - mFormatCtx->pb->buffer = NULL; + if (mFormatCtx->pb->buffer != NULL) + { + av_free(mFormatCtx->pb->buffer); + mFormatCtx->pb->buffer = NULL; + } + av_free(mFormatCtx->pb); + mFormatCtx->pb = NULL; } - av_free(mFormatCtx->pb); - mFormatCtx->pb = NULL; + avformat_free_context(mFormatCtx); } - avformat_free_context(mFormatCtx); + mFormatCtx = NULL; + throw std::runtime_error("Failed to allocate input stream"); } - mFormatCtx = NULL; - fail("Failed to allocate input stream"); - } - try - { if(avformat_find_stream_info(mFormatCtx, NULL) < 0) - fail("Failed to find stream info in "+fname); + throw std::runtime_error("Failed to find stream info in "+fname); for(size_t j = 0;j < mFormatCtx->nb_streams;j++) { @@ -224,23 +220,45 @@ void FFmpeg_Decoder::open(const std::string &fname) } } if(!mStream) - fail("No audio streams in "+fname); + throw std::runtime_error("No audio streams in "+fname); (*mStream)->codec->request_sample_fmt = (*mStream)->codec->sample_fmt; AVCodec *codec = avcodec_find_decoder((*mStream)->codec->codec_id); if(!codec) { - std::stringstream ss("No codec found for id "); - ss << (*mStream)->codec->codec_id; - fail(ss.str()); + std::string ss = "No codec found for id " + + std::to_string((*mStream)->codec->codec_id); + throw std::runtime_error(ss); } if(avcodec_open2((*mStream)->codec, codec, NULL) < 0) - fail("Failed to open audio codec " + std::string(codec->long_name)); + throw std::runtime_error(std::string("Failed to open audio codec ") + + codec->long_name); mFrame = av_frame_alloc(); + + if((*mStream)->codec->sample_fmt == AV_SAMPLE_FMT_FLT || + (*mStream)->codec->sample_fmt == AV_SAMPLE_FMT_FLTP) + mOutputSampleFormat = AV_SAMPLE_FMT_S16; // FIXME: Check for AL_EXT_FLOAT32 support + else if((*mStream)->codec->sample_fmt == AV_SAMPLE_FMT_U8P) + mOutputSampleFormat = AV_SAMPLE_FMT_U8; + else if((*mStream)->codec->sample_fmt == AV_SAMPLE_FMT_S16P) + mOutputSampleFormat = AV_SAMPLE_FMT_S16; + else + mOutputSampleFormat = AV_SAMPLE_FMT_S16; + + mOutputChannelLayout = (*mStream)->codec->channel_layout; + if(mOutputChannelLayout == 0) + mOutputChannelLayout = av_get_default_channel_layout((*mStream)->codec->channels); + + return true; } - catch(std::exception&) + catch(std::exception &e) + { + std::cerr<< "Could not open audio file: "<codec); @@ -248,15 +266,15 @@ void FFmpeg_Decoder::open(const std::string &fname) if (mFormatCtx->pb->buffer != NULL) { - av_free(mFormatCtx->pb->buffer); - mFormatCtx->pb->buffer = NULL; + av_free(mFormatCtx->pb->buffer); + mFormatCtx->pb->buffer = NULL; } av_free(mFormatCtx->pb); mFormatCtx->pb = NULL; avformat_close_input(&mFormatCtx); - throw; } + return false; } void FFmpeg_Decoder::close() @@ -274,18 +292,18 @@ void FFmpeg_Decoder::close() { if (mFormatCtx->pb != NULL) { - // mFormatCtx->pb->buffer must be freed by hand, - // if not, valgrind will show memleak, see: - // - // https://trac.ffmpeg.org/ticket/1357 - // - if (mFormatCtx->pb->buffer != NULL) - { - av_free(mFormatCtx->pb->buffer); - mFormatCtx->pb->buffer = NULL; - } - av_free(mFormatCtx->pb); - mFormatCtx->pb = NULL; + // mFormatCtx->pb->buffer must be freed by hand, + // if not, valgrind will show memleak, see: + // + // https://trac.ffmpeg.org/ticket/1357 + // + if (mFormatCtx->pb->buffer != NULL) + { + av_free(mFormatCtx->pb->buffer); + mFormatCtx->pb->buffer = NULL; + } + av_free(mFormatCtx->pb); + mFormatCtx->pb = NULL; } avformat_close_input(&mFormatCtx); } @@ -298,19 +316,13 @@ std::string FFmpeg_Decoder::getName() return mFormatCtx->filename; } -void FFmpeg_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) +bool FFmpeg_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) { if(!mStream) - fail("No audio stream info"); - - if((*mStream)->codec->sample_fmt == AV_SAMPLE_FMT_FLT || (*mStream)->codec->sample_fmt == AV_SAMPLE_FMT_FLTP) - mOutputSampleFormat = AV_SAMPLE_FMT_S16; // FIXME: Check for AL_EXT_FLOAT32 support - else if((*mStream)->codec->sample_fmt == AV_SAMPLE_FMT_U8P) - mOutputSampleFormat = AV_SAMPLE_FMT_U8; - else if((*mStream)->codec->sample_fmt == AV_SAMPLE_FMT_S16P) - mOutputSampleFormat = AV_SAMPLE_FMT_S16; - else - mOutputSampleFormat = AV_SAMPLE_FMT_S16; + { + std::cerr<< "No audio stream info" <codec->channel_layout; - - if(ch_layout == 0) - ch_layout = av_get_default_channel_layout((*mStream)->codec->channels); - - mOutputChannelLayout = ch_layout; - if (ch_layout == AV_CH_LAYOUT_5POINT1 || ch_layout == AV_CH_LAYOUT_7POINT1 - || ch_layout == AV_CH_LAYOUT_QUAD) // FIXME: check for AL_EXT_MCFORMATS support - mOutputChannelLayout = AV_CH_LAYOUT_STEREO; - else if (ch_layout != AV_CH_LAYOUT_MONO - && ch_layout != AV_CH_LAYOUT_STEREO) - mOutputChannelLayout = AV_CH_LAYOUT_STEREO; - if(mOutputChannelLayout == AV_CH_LAYOUT_MONO) *chans = ChannelConfig_Mono; else if(mOutputChannelLayout == AV_CH_LAYOUT_STEREO) @@ -347,13 +346,27 @@ void FFmpeg_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType * char str[1024]; av_get_channel_layout_string(str, sizeof(str), (*mStream)->codec->channels, (*mStream)->codec->channel_layout); - fail(std::string("Unsupported channel layout: ")+str); + std::cerr<< "Unsupported channel layout: "<codec->channels == 1) + { + mOutputChannelLayout = AV_CH_LAYOUT_MONO; + *chans = ChannelConfig_Mono; + } + else + { + mOutputChannelLayout = AV_CH_LAYOUT_STEREO; + *chans = ChannelConfig_Stereo; + } } *samplerate = (*mStream)->codec->sample_rate; + int64_t ch_layout = (*mStream)->codec->channel_layout; + if(ch_layout == 0) + ch_layout = av_get_default_channel_layout((*mStream)->codec->channels); - if(mOutputSampleFormat != (*mStream)->codec->sample_fmt - || mOutputChannelLayout != ch_layout) + if(mOutputSampleFormat != (*mStream)->codec->sample_fmt || + mOutputChannelLayout != ch_layout) { mSwr = swr_alloc_set_opts(mSwr, // SwrContext mOutputChannelLayout, // output ch layout @@ -365,24 +378,37 @@ void FFmpeg_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType * 0, // logging level offset NULL); // log context if(!mSwr) - fail(std::string("Couldn't allocate SwrContext")); + { + std::cerr<< "Couldn't allocate SwrContext" < &output) { if(!mStream) - fail("No audio stream"); + { + std::cerr<< "No audio stream" < &output); - virtual size_t getSampleOffset(); - - void fail(const std::string &msg); + size_t read(char *buffer, size_t bytes) override; + void readAll(std::vector &output) override; + size_t getSampleOffset() override; FFmpeg_Decoder& operator=(const FFmpeg_Decoder &rhs); FFmpeg_Decoder(const FFmpeg_Decoder &rhs); diff --git a/apps/openmw/mwsound/movieaudiofactory.cpp b/apps/openmw/mwsound/movieaudiofactory.cpp index f54ab5c06..188514f85 100644 --- a/apps/openmw/mwsound/movieaudiofactory.cpp +++ b/apps/openmw/mwsound/movieaudiofactory.cpp @@ -1,5 +1,7 @@ #include "movieaudiofactory.hpp" +#include + #include #include @@ -13,7 +15,7 @@ namespace MWSound { class MovieAudioDecoder; - class MWSoundDecoderBridge : public Sound_Decoder + class MWSoundDecoderBridge final : public Sound_Decoder { public: MWSoundDecoderBridge(MWSound::MovieAudioDecoder* decoder) @@ -25,12 +27,12 @@ namespace MWSound private: MWSound::MovieAudioDecoder* mDecoder; - virtual void open(const std::string &fname); - virtual void close(); - virtual std::string getName(); - virtual void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type); - virtual size_t read(char *buffer, size_t bytes); - virtual size_t getSampleOffset(); + bool open(const std::string &fname) override; + void close() override; + std::string getName() override; + bool getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) override; + size_t read(char *buffer, size_t bytes) override; + size_t getSampleOffset() override; }; class MovieAudioDecoder : public Video::MovieAudioDecoder @@ -96,9 +98,9 @@ namespace MWSound }; - void MWSoundDecoderBridge::open(const std::string &fname) + bool MWSoundDecoderBridge::open(const std::string &fname) { - throw std::runtime_error("unimplemented"); + return false; } void MWSoundDecoderBridge::close() {} @@ -107,7 +109,7 @@ namespace MWSound return mDecoder->getStreamName(); } - void MWSoundDecoderBridge::getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) + bool MWSoundDecoderBridge::getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) { *samplerate = mDecoder->getOutputSampleRate(); @@ -124,9 +126,8 @@ namespace MWSound *chans = ChannelConfig_Quad; else { - std::stringstream error; - error << "Unsupported channel layout: " << outputChannelLayout; - throw std::runtime_error(error.str()); + std::cerr<< "Unsupported channel layout: "<getOutputSampleFormat(); @@ -140,8 +141,11 @@ namespace MWSound { char str[1024]; av_get_sample_fmt_string(str, sizeof(str), outputSampleFormat); - throw std::runtime_error(std::string("Unsupported sample format: ") + str); + std::cerr<< "Unsupported sample format: "<getInfo(&mSampleRate, &chans, &type); + if(!mDecoder->getInfo(&mSampleRate, &chans, &type)) + return false; mFormat = getALFormat(chans, type); if(!mFormat) return false; @@ -948,14 +949,18 @@ std::pair OpenAL_Output::loadSound(const std::string &fname DecoderPtr decoder = mManager.getDecoder(); // Workaround: Bethesda at some point converted some of the files to mp3, but the references were kept as .wav. if(decoder->mResourceMgr->exists(fname)) - decoder->open(fname); + { + if(!decoder->open(fname)) + return std::make_pair(nullptr, 0); + } else { std::string file = fname; std::string::size_type pos = file.rfind('.'); if(pos != std::string::npos) file = file.substr(0, pos)+".mp3"; - decoder->open(file); + if(!decoder->open(file)) + return std::make_pair(nullptr, 0); } std::vector data; @@ -964,7 +969,8 @@ std::pair OpenAL_Output::loadSound(const std::string &fname ALenum format; int srate; - decoder->getInfo(&srate, &chans, &type); + if(!decoder->getInfo(&srate, &chans, &type)) + return std::make_pair(nullptr, 0); format = getALFormat(chans, type); if(!format) return std::make_pair(nullptr, 0); diff --git a/apps/openmw/mwsound/sound_decoder.hpp b/apps/openmw/mwsound/sound_decoder.hpp index 34bae87d7..57edb1393 100644 --- a/apps/openmw/mwsound/sound_decoder.hpp +++ b/apps/openmw/mwsound/sound_decoder.hpp @@ -34,11 +34,11 @@ namespace MWSound { const VFS::Manager* mResourceMgr; - virtual void open(const std::string &fname) = 0; + virtual bool open(const std::string &fname) = 0; virtual void close() = 0; virtual std::string getName() = 0; - virtual void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) = 0; + virtual bool getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) = 0; virtual size_t read(char *buffer, size_t bytes) = 0; virtual void readAll(std::vector &output); From bfad5ebde451bb0cab4bcb137621d3cf61197024 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Fri, 8 Dec 2017 17:42:20 +0100 Subject: [PATCH 13/31] CS: Fix camera orbit control with keys --- apps/opencs/view/render/cameracontroller.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index f0158fe28..abf68ef93 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -690,7 +690,9 @@ namespace CSVRender osg::Vec3 absoluteUp = osg::Vec3(0,0,1); osg::Vec3d forward = center - eye; - osg::Quat rotation = osg::Quat(value, absoluteUp ^ forward); + + osg::Vec3d axis = absoluteUp ^ forward * (up.z() < 0.0 ? -1.0 : 1.0); + osg::Quat rotation = osg::Quat(value,axis); osg::Vec3d oldOffset = eye - mCenter; osg::Vec3d newOffset = rotation * oldOffset; From 1b77e3ed627afb917d6d4d5ad219dcb6d2587675 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Fri, 8 Dec 2017 18:18:27 +0100 Subject: [PATCH 14/31] CS: Add ortho camera setting --- apps/opencs/model/prefs/state.cpp | 2 ++ apps/opencs/view/render/scenewidget.cpp | 33 +++++++++++++++++++------ apps/opencs/view/render/scenewidget.hpp | 2 ++ 3 files changed, 30 insertions(+), 7 deletions(-) diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index be6534089..f4ba134d0 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -194,6 +194,8 @@ void CSMPrefs::State::declare() declareCategory ("Rendering"); declareDouble ("camera-fov", "Camera FOV", 90.).setPrecision(5).setRange(10.0, 160.0); + declareBool ("camera-ortho", "Orthographic projection for camera", false); + declareDouble ("camera-ortho-size", "Orthographic projection size parameter", 100.0).setPrecision(5).setRange(0.0, 1000.0); declareCategory ("Tooltips"); declareBool ("scene", "Show Tooltips in 3D scenes", true); diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index 7d3ac3f1c..a151c638e 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -67,10 +67,7 @@ RenderWidget::RenderWidget(QWidget *parent, Qt::WindowFlags f) mView->getCamera()->setClearColor( osg::Vec4(0.2, 0.2, 0.6, 1.0) ); mView->getCamera()->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) ); - mView->getCamera()->setProjectionMatrixAsPerspective( - CSMPrefs::get()["Rendering"]["camera-fov"].toDouble(), - static_cast(traits->width)/static_cast(traits->height), - 1.0f, 10000.0f); + updateCameraParameters(); SceneUtil::LightManager* lightMgr = new SceneUtil::LightManager; lightMgr->setStartLight(1); @@ -374,12 +371,34 @@ void SceneWidget::settingChanged (const CSMPrefs::Setting *setting) { mOrbitCamControl->setOrbitSpeedMultiplier(setting->toDouble()); } - else if (*setting=="Rendering/camera-fov") + else if (*setting=="Rendering/camera-fov" || + *setting=="Rendering/camera-ortho" || + *setting=="Rendering/camera-ortho-size") { + updateCameraParameters(); + } +} + +void RenderWidget::updateCameraParameters() +{ + const float near = 1.0; + const float far = 1000.0; + + if (CSMPrefs::get()["Rendering"]["camera-ortho"].isTrue()) + { + const float size = CSMPrefs::get()["Rendering"]["camera-ortho-size"].toDouble(); + const float half_w = size / 100.0 * static_cast(width()); + const float half_h = size / 100.0 * static_cast(height()); + + mView->getCamera()->setProjectionMatrixAsOrtho( + -half_w, half_w, -half_h, half_h, near, far); + } + else + { mView->getCamera()->setProjectionMatrixAsPerspective( - setting->toDouble(), + CSMPrefs::get()["Rendering"]["camera-fov"].toDouble(), static_cast(width())/static_cast(height()), - 1.0f, 10000.0f); + near, far); } } diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index cc3191c81..af7a6f1ec 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -64,6 +64,8 @@ namespace CSVRender osg::ref_ptr mView; osg::ref_ptr mRootNode; + void updateCameraParameters(); + QTimer mTimer; protected slots: From d85f8deaa3b0fd802da2e3713d9d829ab700bd9a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Fri, 8 Dec 2017 20:51:40 +0100 Subject: [PATCH 15/31] CS: Add fixed roll setting, plus ortho fix --- apps/opencs/model/prefs/state.cpp | 3 ++- apps/opencs/view/render/cameracontroller.cpp | 25 +++++++++++++++----- apps/opencs/view/render/cameracontroller.hpp | 4 ++++ apps/opencs/view/render/scenewidget.cpp | 16 +++++++++---- apps/opencs/view/render/scenewidget.hpp | 2 +- 5 files changed, 37 insertions(+), 13 deletions(-) diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index f4ba134d0..9463ae081 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -180,6 +180,7 @@ void CSMPrefs::State::declare() declareDouble ("navi-free-speed-mult", "Free Camera Speed Multiplier (from Modifier)", 8).setRange(0.001, 1000.0); declareDouble ("navi-orbit-rot-speed", "Orbital Camera Rotational Speed", 3.14 / 4).setRange(0.001, 6.28); declareDouble ("navi-orbit-speed-mult", "Orbital Camera Speed Multiplier (from Modifier)", 4).setRange(0.001, 1000.0); + declareBool ("navi-orbit-const-roll", "Keep camera roll constant for orbital camera", true); declareSeparator(); declareBool ("context-select", "Context Sensitive Selection", false); declareDouble ("drag-factor", "Mouse sensitivity during drag operations", 1.0). @@ -191,7 +192,7 @@ void CSMPrefs::State::declare() setTooltip ("Acceleration factor during drag operations while holding down shift"). setRange (0.001, 100.0); declareDouble ("rotate-factor", "Free rotation factor", 0.007).setPrecision(4).setRange(0.0001, 0.1); - + declareCategory ("Rendering"); declareDouble ("camera-fov", "Camera FOV", 90.).setPrecision(5).setRange(10.0, 160.0); declareBool ("camera-ortho", "Orthographic projection for camera", false); diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index abf68ef93..ca80ed34f 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -668,18 +668,25 @@ namespace CSVRender mInitialized = true; } + + void OrbitCameraController::setConstRoll(bool enabled) + { + mConstRoll = enabled; + } void OrbitCameraController::rotateHorizontal(double value) { osg::Vec3d eye, center, up; getCamera()->getViewMatrixAsLookAt(eye, center, up); - osg::Vec3 absoluteUp = osg::Vec3(0,0,1); + osg::Vec3d absoluteUp = osg::Vec3(0,0,1); - osg::Quat rotation = osg::Quat(value, absoluteUp); + osg::Quat rotation = osg::Quat(value, mConstRoll ? absoluteUp : up); osg::Vec3d oldOffset = eye - mCenter; osg::Vec3d newOffset = rotation * oldOffset; - up = rotation * up; + if (mConstRoll) + up = rotation * up; + getCamera()->setViewMatrixAsLookAt(mCenter + newOffset, mCenter, up); } @@ -687,16 +694,22 @@ namespace CSVRender { osg::Vec3d eye, center, up; getCamera()->getViewMatrixAsLookAt(eye, center, up); - osg::Vec3 absoluteUp = osg::Vec3(0,0,1); + osg::Vec3d absoluteUp = osg::Vec3(0,0,1); osg::Vec3d forward = center - eye; - osg::Vec3d axis = absoluteUp ^ forward * (up.z() < 0.0 ? -1.0 : 1.0); + osg::Vec3d axis = absoluteUp ^ forward; + + if (mConstRoll && up.z() < 0.0) + axis *= -1.0; + osg::Quat rotation = osg::Quat(value,axis); osg::Vec3d oldOffset = eye - mCenter; osg::Vec3d newOffset = rotation * oldOffset; + + if (mConstRoll) + up = rotation * up; - up = rotation * up; getCamera()->setViewMatrixAsLookAt(mCenter + newOffset, mCenter, up); } diff --git a/apps/opencs/view/render/cameracontroller.hpp b/apps/opencs/view/render/cameracontroller.hpp index a2ebba51a..658e572c5 100644 --- a/apps/opencs/view/render/cameracontroller.hpp +++ b/apps/opencs/view/render/cameracontroller.hpp @@ -160,6 +160,8 @@ namespace CSVRender /// \brief Flag controller to be re-initialized. void reset(); + void setConstRoll(bool enable); + private: void initialize(); @@ -181,6 +183,8 @@ namespace CSVRender double mOrbitSpeed; double mOrbitSpeedMult; + bool mConstRoll; + private slots: void naviPrimary(bool active); diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index a151c638e..a67a38eb3 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -56,6 +56,7 @@ RenderWidget::RenderWidget(QWidget *parent, Qt::WindowFlags f) traits->vsync = false; mView = new osgViewer::View; + updateCameraParameters( traits->width / static_cast(traits->height) ); osg::ref_ptr window = new osgQt::GraphicsWindowQt(traits.get()); QLayout* layout = new QHBoxLayout(this); @@ -67,8 +68,6 @@ RenderWidget::RenderWidget(QWidget *parent, Qt::WindowFlags f) mView->getCamera()->setClearColor( osg::Vec4(0.2, 0.2, 0.6, 1.0) ); mView->getCamera()->setViewport( new osg::Viewport(0, 0, traits->width, traits->height) ); - updateCameraParameters(); - SceneUtil::LightManager* lightMgr = new SceneUtil::LightManager; lightMgr->setStartLight(1); lightMgr->setLightingMask(Mask_Lighting); @@ -189,6 +188,8 @@ SceneWidget::SceneWidget(std::shared_ptr resourceSyste mOrbitCamControl->setPickingMask(Mask_Reference | Mask_Terrain); + mOrbitCamControl->setConstRoll( CSMPrefs::get()["3D Scene Input"]["navi-orbit-const-roll"].isTrue() ); + // we handle lighting manually mView->setLightingMode(osgViewer::View::NO_LIGHT); @@ -371,6 +372,10 @@ void SceneWidget::settingChanged (const CSMPrefs::Setting *setting) { mOrbitCamControl->setOrbitSpeedMultiplier(setting->toDouble()); } + else if (*setting=="3D Scene Input/navi-orbit-const-roll") + { + mOrbitCamControl->setConstRoll(setting->isTrue()); + } else if (*setting=="Rendering/camera-fov" || *setting=="Rendering/camera-ortho" || *setting=="Rendering/camera-ortho-size") @@ -379,7 +384,7 @@ void SceneWidget::settingChanged (const CSMPrefs::Setting *setting) } } -void RenderWidget::updateCameraParameters() +void RenderWidget::updateCameraParameters(double overrideAspect) { const float near = 1.0; const float far = 1000.0; @@ -387,8 +392,9 @@ void RenderWidget::updateCameraParameters() if (CSMPrefs::get()["Rendering"]["camera-ortho"].isTrue()) { const float size = CSMPrefs::get()["Rendering"]["camera-ortho-size"].toDouble(); - const float half_w = size / 100.0 * static_cast(width()); - const float half_h = size / 100.0 * static_cast(height()); + const float aspect = overrideAspect >= 0.0 ? overrideAspect : (width() / static_cast(height())); + const float half_h = size * 10.0; + const float half_w = half_h * aspect; mView->getCamera()->setProjectionMatrixAsOrtho( -half_w, half_w, -half_h, half_h, near, far); diff --git a/apps/opencs/view/render/scenewidget.hpp b/apps/opencs/view/render/scenewidget.hpp index af7a6f1ec..13a109a9b 100644 --- a/apps/opencs/view/render/scenewidget.hpp +++ b/apps/opencs/view/render/scenewidget.hpp @@ -64,7 +64,7 @@ namespace CSVRender osg::ref_ptr mView; osg::ref_ptr mRootNode; - void updateCameraParameters(); + void updateCameraParameters(double overrideAspect = -1.0); QTimer mTimer; From e309dfd234526bb4d3dc0ed9df0b18a08ca64a0f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Fri, 8 Dec 2017 22:06:03 +0100 Subject: [PATCH 16/31] CS: Rename variables (AppVeyor fix) --- apps/opencs/view/render/scenewidget.cpp | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index a67a38eb3..ecf27e04d 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -386,25 +386,25 @@ void SceneWidget::settingChanged (const CSMPrefs::Setting *setting) void RenderWidget::updateCameraParameters(double overrideAspect) { - const float near = 1.0; - const float far = 1000.0; + const float nearDist = 1.0; + const float farDist = 1000.0; if (CSMPrefs::get()["Rendering"]["camera-ortho"].isTrue()) { const float size = CSMPrefs::get()["Rendering"]["camera-ortho-size"].toDouble(); const float aspect = overrideAspect >= 0.0 ? overrideAspect : (width() / static_cast(height())); - const float half_h = size * 10.0; - const float half_w = half_h * aspect; + const float halfH = size * 10.0; + const float halfW = halfH * aspect; mView->getCamera()->setProjectionMatrixAsOrtho( - -half_w, half_w, -half_h, half_h, near, far); + -halfW, halfW, -halfH, halfH, nearDist, farDist); } else { mView->getCamera()->setProjectionMatrixAsPerspective( CSMPrefs::get()["Rendering"]["camera-fov"].toDouble(), static_cast(width())/static_cast(height()), - near, far); + nearDist, farDist); } } From 06ae61479a95fbad45ff38c4ef3f62e7988c5cbb Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Fri, 8 Dec 2017 22:10:09 -0800 Subject: [PATCH 17/31] If a sound effect fails to load, substitute silence. --- apps/openmw/mwsound/openal_output.cpp | 35 ++++++++++++++++----------- 1 file changed, 21 insertions(+), 14 deletions(-) diff --git a/apps/openmw/mwsound/openal_output.cpp b/apps/openmw/mwsound/openal_output.cpp index 009c019e7..89475ea48 100644 --- a/apps/openmw/mwsound/openal_output.cpp +++ b/apps/openmw/mwsound/openal_output.cpp @@ -948,35 +948,42 @@ std::pair OpenAL_Output::loadSound(const std::string &fname DecoderPtr decoder = mManager.getDecoder(); // Workaround: Bethesda at some point converted some of the files to mp3, but the references were kept as .wav. + bool succeeded; if(decoder->mResourceMgr->exists(fname)) - { - if(!decoder->open(fname)) - return std::make_pair(nullptr, 0); - } + succeeded = decoder->open(fname); else { std::string file = fname; std::string::size_type pos = file.rfind('.'); if(pos != std::string::npos) file = file.substr(0, pos)+".mp3"; - if(!decoder->open(file)) - return std::make_pair(nullptr, 0); + succeeded = decoder->open(file); } std::vector data; - ChannelConfig chans; - SampleType type; ALenum format; int srate; - if(!decoder->getInfo(&srate, &chans, &type)) - return std::make_pair(nullptr, 0); - format = getALFormat(chans, type); - if(!format) return std::make_pair(nullptr, 0); - - decoder->readAll(data); + if(succeeded) + { + ChannelConfig chans; + SampleType type; + if(decoder->getInfo(&srate, &chans, &type)) + { + format = getALFormat(chans, type); + if(format) decoder->readAll(data); + } + } decoder->close(); + if(data.empty()) + { + // If we failed to get any usable audio, substitute with silence. + format = AL_FORMAT_MONO8; + srate = 8000; + data.assign(8000, -128); + } + ALint size; ALuint buf = 0; alGenBuffers(1, &buf); From 08e947319a99021eaa3d16813c97905644a71cbf Mon Sep 17 00:00:00 2001 From: Chris Robinson Date: Sat, 9 Dec 2017 11:00:56 -0800 Subject: [PATCH 18/31] Restore exception throwing to the decoder --- apps/openmw/mwsound/ffmpeg_decoder.cpp | 48 ++++++++------------- apps/openmw/mwsound/ffmpeg_decoder.hpp | 4 +- apps/openmw/mwsound/movieaudiofactory.cpp | 21 ++++----- apps/openmw/mwsound/openal_output.cpp | 52 ++++++++++++----------- apps/openmw/mwsound/sound_decoder.hpp | 4 +- 5 files changed, 56 insertions(+), 73 deletions(-) diff --git a/apps/openmw/mwsound/ffmpeg_decoder.cpp b/apps/openmw/mwsound/ffmpeg_decoder.cpp index 12ea84a42..e2d54876f 100644 --- a/apps/openmw/mwsound/ffmpeg_decoder.cpp +++ b/apps/openmw/mwsound/ffmpeg_decoder.cpp @@ -176,16 +176,16 @@ size_t FFmpeg_Decoder::readAVAudioData(void *data, size_t length) return dec; } -bool FFmpeg_Decoder::open(const std::string &fname) +void FFmpeg_Decoder::open(const std::string &fname) { close(); - try - { - mDataStream = mResourceMgr->get(fname); + mDataStream = mResourceMgr->get(fname); - if((mFormatCtx=avformat_alloc_context()) == NULL) - throw std::runtime_error("Failed to allocate context"); + if((mFormatCtx=avformat_alloc_context()) == NULL) + throw std::runtime_error("Failed to allocate context"); + try + { mFormatCtx->pb = avio_alloc_context(NULL, 0, 0, this, readPacket, writePacket, seek); if(!mFormatCtx->pb || avformat_open_input(&mFormatCtx, fname.c_str(), NULL, NULL) != 0) { @@ -250,16 +250,8 @@ bool FFmpeg_Decoder::open(const std::string &fname) mOutputChannelLayout = (*mStream)->codec->channel_layout; if(mOutputChannelLayout == 0) mOutputChannelLayout = av_get_default_channel_layout((*mStream)->codec->channels); - - return true; - } - catch(std::exception &e) - { - std::cerr<< "Could not open audio file: "<codec); mStream = NULL; @@ -273,8 +265,8 @@ bool FFmpeg_Decoder::open(const std::string &fname) mFormatCtx->pb = NULL; avformat_close_input(&mFormatCtx); + throw; } - return false; } void FFmpeg_Decoder::close() @@ -316,13 +308,10 @@ std::string FFmpeg_Decoder::getName() return mFormatCtx->filename; } -bool FFmpeg_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) +void FFmpeg_Decoder::getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) { if(!mStream) - { - std::cerr<< "No audio stream info" < &output) override; diff --git a/apps/openmw/mwsound/movieaudiofactory.cpp b/apps/openmw/mwsound/movieaudiofactory.cpp index 188514f85..497562516 100644 --- a/apps/openmw/mwsound/movieaudiofactory.cpp +++ b/apps/openmw/mwsound/movieaudiofactory.cpp @@ -27,10 +27,10 @@ namespace MWSound private: MWSound::MovieAudioDecoder* mDecoder; - bool open(const std::string &fname) override; + void open(const std::string &fname) override; void close() override; std::string getName() override; - bool getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) override; + void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) override; size_t read(char *buffer, size_t bytes) override; size_t getSampleOffset() override; }; @@ -98,9 +98,9 @@ namespace MWSound }; - bool MWSoundDecoderBridge::open(const std::string &fname) + void MWSoundDecoderBridge::open(const std::string &fname) { - return false; + throw std::runtime_error("Method not implemented"); } void MWSoundDecoderBridge::close() {} @@ -109,7 +109,7 @@ namespace MWSound return mDecoder->getStreamName(); } - bool MWSoundDecoderBridge::getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) + void MWSoundDecoderBridge::getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) { *samplerate = mDecoder->getOutputSampleRate(); @@ -125,10 +125,8 @@ namespace MWSound else if (outputChannelLayout == AV_CH_LAYOUT_QUAD) *chans = ChannelConfig_Quad; else - { - std::cerr<< "Unsupported channel layout: "<getOutputSampleFormat(); if (outputSampleFormat == AV_SAMPLE_FMT_U8) @@ -141,11 +139,8 @@ namespace MWSound { char str[1024]; av_get_sample_fmt_string(str, sizeof(str), outputSampleFormat); - std::cerr<< "Unsupported sample format: "<getInfo(&mSampleRate, &chans, &type)) + try { + mDecoder->getInfo(&mSampleRate, &chans, &type); + mFormat = getALFormat(chans, type); + } + catch(std::exception &e) { + std::cerr<< "Failed to get stream info: "< OpenAL_Output::loadSound(const std::string &fname { getALError(); - DecoderPtr decoder = mManager.getDecoder(); - // Workaround: Bethesda at some point converted some of the files to mp3, but the references were kept as .wav. - bool succeeded; - if(decoder->mResourceMgr->exists(fname)) - succeeded = decoder->open(fname); - else - { - std::string file = fname; - std::string::size_type pos = file.rfind('.'); - if(pos != std::string::npos) - file = file.substr(0, pos)+".mp3"; - succeeded = decoder->open(file); - } - std::vector data; ALenum format; int srate; - if(succeeded) - { - ChannelConfig chans; - SampleType type; - if(decoder->getInfo(&srate, &chans, &type)) + try { + DecoderPtr decoder = mManager.getDecoder(); + // Workaround: Bethesda at some point converted some of the files to mp3, but the references were kept as .wav. + if(decoder->mResourceMgr->exists(fname)) + decoder->open(fname); + else { - format = getALFormat(chans, type); - if(format) decoder->readAll(data); + std::string file = fname; + std::string::size_type pos = file.rfind('.'); + if(pos != std::string::npos) + file = file.substr(0, pos)+".mp3"; + decoder->open(file); } + + ChannelConfig chans; + SampleType type; + decoder->getInfo(&srate, &chans, &type); + format = getALFormat(chans, type); + if(format) decoder->readAll(data); + } + catch(std::exception &e) { + std::cerr<< "Failed to load audio from "<close(); if(data.empty()) { diff --git a/apps/openmw/mwsound/sound_decoder.hpp b/apps/openmw/mwsound/sound_decoder.hpp index 57edb1393..34bae87d7 100644 --- a/apps/openmw/mwsound/sound_decoder.hpp +++ b/apps/openmw/mwsound/sound_decoder.hpp @@ -34,11 +34,11 @@ namespace MWSound { const VFS::Manager* mResourceMgr; - virtual bool open(const std::string &fname) = 0; + virtual void open(const std::string &fname) = 0; virtual void close() = 0; virtual std::string getName() = 0; - virtual bool getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) = 0; + virtual void getInfo(int *samplerate, ChannelConfig *chans, SampleType *type) = 0; virtual size_t read(char *buffer, size_t bytes) = 0; virtual void readAll(std::vector &output); From c908ad2fba38a7260f41d480ad26343622f13ae1 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sun, 10 Dec 2017 14:38:02 +0400 Subject: [PATCH 19/31] Do not allow to place actors underground via SetPos (bug #3783) --- apps/openmw/mwscript/transformationextensions.cpp | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index c876d4cf7..208a1f46f 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -227,6 +227,17 @@ namespace MWScript } else if(axis == "z") { + // We should not place actors under ground + if (ptr.getClass().isActor()) + { + float terrainHeight = -std::numeric_limits::max(); + if (ptr.getCell()->isExterior()) + terrainHeight = MWBase::Environment::get().getWorld()->getTerrainHeightAt(osg::Vec3f(ax, ay, az)); + + if (pos < terrainHeight) + pos = terrainHeight; + } + updated = MWBase::Environment::get().getWorld()->moveObject(ptr,ax,ay,pos); } else From 0e04a26ef6d3a5453f69073d9f3351a0cd2b5c34 Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sun, 10 Dec 2017 16:10:44 +0400 Subject: [PATCH 20/31] Set duration of magic effects from ingredients (bug #4261) --- apps/openmw/mwmechanics/spellcasting.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwmechanics/spellcasting.cpp b/apps/openmw/mwmechanics/spellcasting.cpp index 8fbf67535..d864dc619 100644 --- a/apps/openmw/mwmechanics/spellcasting.cpp +++ b/apps/openmw/mwmechanics/spellcasting.cpp @@ -968,9 +968,9 @@ namespace MWMechanics float y = roll / std::min(x, 100.f); y *= 0.25f * x; if (magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration) - effect.mDuration = static_cast(y); - else effect.mDuration = 1; + else + effect.mDuration = static_cast(y); if (!(magicEffect->mData.mFlags & ESM::MagicEffect::NoMagnitude)) { if (!(magicEffect->mData.mFlags & ESM::MagicEffect::NoDuration)) From ba46473038f68e6e0c1a0235b518e293668d9bfa Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Wed, 13 Dec 2017 10:53:23 +0400 Subject: [PATCH 21/31] Do not skip weather transitions from SetPos script command (bug #3603) --- apps/openmw/mwscript/transformationextensions.cpp | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/apps/openmw/mwscript/transformationextensions.cpp b/apps/openmw/mwscript/transformationextensions.cpp index 208a1f46f..68b1063e4 100644 --- a/apps/openmw/mwscript/transformationextensions.cpp +++ b/apps/openmw/mwscript/transformationextensions.cpp @@ -202,11 +202,6 @@ namespace MWScript if (!ptr.isInCell()) return; - if (ptr == MWMechanics::getPlayer()) - { - MWBase::Environment::get().getWorld()->getPlayer().setTeleported(true); - } - std::string axis = runtime.getStringLiteral (runtime[0].mInteger); runtime.pop(); Interpreter::Type_Float pos = runtime[0].mFloat; @@ -216,6 +211,8 @@ namespace MWScript float ay = ptr.getRefData().getPosition().pos[1]; float az = ptr.getRefData().getPosition().pos[2]; + // Note: SetPos does not skip weather transitions in vanilla engine, so we do not call setTeleported(true) here. + MWWorld::Ptr updated = ptr; if(axis == "x") { From 269c3227eaca6cf4a2a647e3f3f281950b09d853 Mon Sep 17 00:00:00 2001 From: scrawl <720642+scrawl@users.noreply.github.com> Date: Wed, 13 Dec 2017 10:44:06 +0000 Subject: [PATCH 22/31] Make sure we have cmake for the before_install step --- .travis.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.travis.yml b/.travis.yml index d173ef6f2..02cc7cf20 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,7 +24,7 @@ addons: - llvm-toolchain-precise-3.6 packages: [ # Dev - clang-3.6, libunshield-dev, libtinyxml-dev, + cmake, clang-3.6, libunshield-dev, libtinyxml-dev, # Tests libgtest-dev, google-mock, # Boost From b246580c6389bfe2786804ff454884b3e426e929 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Wed, 13 Dec 2017 20:08:38 +0100 Subject: [PATCH 23/31] Fix orbit camera axis --- apps/opencs/view/render/cameracontroller.cpp | 6 +----- 1 file changed, 1 insertion(+), 5 deletions(-) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index ca80ed34f..57032f5ad 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -697,11 +697,7 @@ namespace CSVRender osg::Vec3d absoluteUp = osg::Vec3(0,0,1); osg::Vec3d forward = center - eye; - - osg::Vec3d axis = absoluteUp ^ forward; - - if (mConstRoll && up.z() < 0.0) - axis *= -1.0; + osg::Vec3d axis = up ^ forward; osg::Quat rotation = osg::Quat(value,axis); osg::Vec3d oldOffset = eye - mCenter; From 79527b746a9e80fb59e73e3507fa69aad9e5b6af Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Thu, 14 Dec 2017 17:29:24 +0100 Subject: [PATCH 24/31] Remove unused variable --- apps/opencs/view/render/cameracontroller.cpp | 1 - 1 file changed, 1 deletion(-) diff --git a/apps/opencs/view/render/cameracontroller.cpp b/apps/opencs/view/render/cameracontroller.cpp index 57032f5ad..37f439fd3 100644 --- a/apps/opencs/view/render/cameracontroller.cpp +++ b/apps/opencs/view/render/cameracontroller.cpp @@ -694,7 +694,6 @@ namespace CSVRender { osg::Vec3d eye, center, up; getCamera()->getViewMatrixAsLookAt(eye, center, up); - osg::Vec3d absoluteUp = osg::Vec3(0,0,1); osg::Vec3d forward = center - eye; osg::Vec3d axis = up ^ forward; From f2777f72424bdd2318f88f0ef184635d629fb23d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Fri, 15 Dec 2017 14:36:12 +0100 Subject: [PATCH 25/31] CS: Mover object-marker-alpha under Rendering --- apps/opencs/model/prefs/state.cpp | 2 +- apps/opencs/view/render/object.cpp | 2 +- apps/opencs/view/render/worldspacewidget.cpp | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index 509d977c4..311615aec 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -192,12 +192,12 @@ void CSMPrefs::State::declare() setTooltip ("Acceleration factor during drag operations while holding down shift"). setRange (0.001, 100.0); declareDouble ("rotate-factor", "Free rotation factor", 0.007).setPrecision(4).setRange(0.0001, 0.1); - declareDouble ("object-marker-alpha", "Object Marker Transparency", 0.5).setPrecision(2).setRange(0,1); declareCategory ("Rendering"); declareDouble ("camera-fov", "Camera FOV", 90.).setPrecision(5).setRange(10.0, 160.0); declareBool ("camera-ortho", "Orthographic projection for camera", false); declareDouble ("camera-ortho-size", "Orthographic projection size parameter", 100.0).setPrecision(5).setRange(0.0, 1000.0); + declareDouble ("object-marker-alpha", "Object Marker Transparency", 0.5).setPrecision(2).setRange(0,1); declareCategory ("Tooltips"); declareBool ("scene", "Show Tooltips in 3D scenes", true); diff --git a/apps/opencs/view/render/object.cpp b/apps/opencs/view/render/object.cpp index df7283b1a..dae6467c5 100644 --- a/apps/opencs/view/render/object.cpp +++ b/apps/opencs/view/render/object.cpp @@ -471,7 +471,7 @@ void CSVRender::Object::setSelected(bool selected) else mRootNode->addChild(mBaseNode); - mMarkerTransparency = CSMPrefs::get()["3D Scene Input"]["object-marker-alpha"].toDouble(); + mMarkerTransparency = CSMPrefs::get()["Rendering"]["object-marker-alpha"].toDouble(); updateMarker(); } diff --git a/apps/opencs/view/render/worldspacewidget.cpp b/apps/opencs/view/render/worldspacewidget.cpp index a80a61a79..af53c86f0 100644 --- a/apps/opencs/view/render/worldspacewidget.cpp +++ b/apps/opencs/view/render/worldspacewidget.cpp @@ -131,7 +131,7 @@ void CSVRender::WorldspaceWidget::settingChanged (const CSMPrefs::Setting *setti mDragWheelFactor = setting->toDouble(); else if (*setting=="3D Scene Input/drag-shift-factor") mDragShiftFactor = setting->toDouble(); - else if (*setting=="3D Scene Input/object-marker-alpha" && !mInConstructor) + else if (*setting=="Rendering/object-marker-alpha" && !mInConstructor) { float alpha = setting->toDouble(); // getSelection is virtual, thus this can not be called from the constructor From 1f5feeddb98e4f1c280bc306f839b539afdb925a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Fri, 15 Dec 2017 14:46:23 +0100 Subject: [PATCH 26/31] CS: Change camera parameter types to int --- apps/opencs/model/prefs/state.cpp | 4 ++-- apps/opencs/view/render/scenewidget.cpp | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index 311615aec..7dfd3543b 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -194,9 +194,9 @@ void CSMPrefs::State::declare() declareDouble ("rotate-factor", "Free rotation factor", 0.007).setPrecision(4).setRange(0.0001, 0.1); declareCategory ("Rendering"); - declareDouble ("camera-fov", "Camera FOV", 90.).setPrecision(5).setRange(10.0, 160.0); + declareInt ("camera-fov", "Camera FOV", 90).setRange(10, 170); declareBool ("camera-ortho", "Orthographic projection for camera", false); - declareDouble ("camera-ortho-size", "Orthographic projection size parameter", 100.0).setPrecision(5).setRange(0.0, 1000.0); + declareInt ("camera-ortho-size", "Orthographic projection size parameter", 100).setRange(10, 10000); declareDouble ("object-marker-alpha", "Object Marker Transparency", 0.5).setPrecision(2).setRange(0,1); declareCategory ("Tooltips"); diff --git a/apps/opencs/view/render/scenewidget.cpp b/apps/opencs/view/render/scenewidget.cpp index ecf27e04d..f24a9de50 100644 --- a/apps/opencs/view/render/scenewidget.cpp +++ b/apps/opencs/view/render/scenewidget.cpp @@ -391,7 +391,7 @@ void RenderWidget::updateCameraParameters(double overrideAspect) if (CSMPrefs::get()["Rendering"]["camera-ortho"].isTrue()) { - const float size = CSMPrefs::get()["Rendering"]["camera-ortho-size"].toDouble(); + const float size = CSMPrefs::get()["Rendering"]["camera-ortho-size"].toInt(); const float aspect = overrideAspect >= 0.0 ? overrideAspect : (width() / static_cast(height())); const float halfH = size * 10.0; const float halfW = halfH * aspect; @@ -402,7 +402,7 @@ void RenderWidget::updateCameraParameters(double overrideAspect) else { mView->getCamera()->setProjectionMatrixAsPerspective( - CSMPrefs::get()["Rendering"]["camera-fov"].toDouble(), + CSMPrefs::get()["Rendering"]["camera-fov"].toInt(), static_cast(width())/static_cast(height()), nearDist, farDist); } From 13dc1bd41e03c48555624e2f525a98ae56bdda66 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Fri, 15 Dec 2017 14:56:03 +0100 Subject: [PATCH 27/31] CS: Add tooltip to camera-ortho-size preference --- apps/opencs/model/prefs/state.cpp | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index 7dfd3543b..34519dcab 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -196,7 +196,9 @@ void CSMPrefs::State::declare() declareCategory ("Rendering"); declareInt ("camera-fov", "Camera FOV", 90).setRange(10, 170); declareBool ("camera-ortho", "Orthographic projection for camera", false); - declareInt ("camera-ortho-size", "Orthographic projection size parameter", 100).setRange(10, 10000); + declareInt ("camera-ortho-size", "Orthographic projection size parameter", 100). + setTooltip("Size of the orthographic frustum, greater value will allow the camera to see more of the world."). + setRange(10, 10000); declareDouble ("object-marker-alpha", "Object Marker Transparency", 0.5).setPrecision(2).setRange(0,1); declareCategory ("Tooltips"); From 01f9d90315877930d6ec16a936a07bd122d8feed Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Miloslav=20=C4=8C=C3=AD=C5=BE?= Date: Fri, 15 Dec 2017 17:22:32 +0100 Subject: [PATCH 28/31] CS: Reorder 3D input menu --- apps/opencs/model/prefs/state.cpp | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/apps/opencs/model/prefs/state.cpp b/apps/opencs/model/prefs/state.cpp index 34519dcab..8a9dad7f3 100644 --- a/apps/opencs/model/prefs/state.cpp +++ b/apps/opencs/model/prefs/state.cpp @@ -169,19 +169,25 @@ void CSMPrefs::State::declare() "list go to the first/last item"); declareCategory ("3D Scene Input"); + + declareDouble ("navi-wheel-factor", "Camera Zoom Sensitivity", 8).setRange(-100.0, 100.0); + declareDouble ("s-navi-sensitivity", "Secondary Camera Movement Sensitivity", 50.0).setRange(-1000.0, 1000.0); + declareSeparator(); + declareDouble ("p-navi-free-sensitivity", "Free Camera Sensitivity", 1/650.).setPrecision(5).setRange(0.0, 1.0); declareBool ("p-navi-free-invert", "Invert Free Camera Mouse Input", false); - declareDouble ("p-navi-orbit-sensitivity", "Orbit Camera Sensitivity", 1/650.).setPrecision(5).setRange(0.0, 1.0); - declareBool ("p-navi-orbit-invert", "Invert Orbit Camera Mouse Input", false); - declareDouble ("s-navi-sensitivity", "Secondary Camera Movement Sensitivity", 50.0).setRange(-1000.0, 1000.0); - declareDouble ("navi-wheel-factor", "Camera Zoom Sensitivity", 8).setRange(-100.0, 100.0); declareDouble ("navi-free-lin-speed", "Free Camera Linear Speed", 1000.0).setRange(1.0, 10000.0); - declareDouble ("navi-free-rot-speed", "Free Camera Rotational Speed", 3.14 / 2).setRange(0.001, 6.28); + declareDouble ("navi-free-rot-speed", "Free Camera Rotational Speed", 3.14 / 2).setRange(0.001, 6.28); declareDouble ("navi-free-speed-mult", "Free Camera Speed Multiplier (from Modifier)", 8).setRange(0.001, 1000.0); + declareSeparator(); + + declareDouble ("p-navi-orbit-sensitivity", "Orbit Camera Sensitivity", 1/650.).setPrecision(5).setRange(0.0, 1.0); + declareBool ("p-navi-orbit-invert", "Invert Orbit Camera Mouse Input", false); declareDouble ("navi-orbit-rot-speed", "Orbital Camera Rotational Speed", 3.14 / 4).setRange(0.001, 6.28); declareDouble ("navi-orbit-speed-mult", "Orbital Camera Speed Multiplier (from Modifier)", 4).setRange(0.001, 1000.0); declareBool ("navi-orbit-const-roll", "Keep camera roll constant for orbital camera", true); declareSeparator(); + declareBool ("context-select", "Context Sensitive Selection", false); declareDouble ("drag-factor", "Mouse sensitivity during drag operations", 1.0). setRange (0.001, 100.0); From e4a1b6b5b891d3f98a7ebbadc332638d8795499e Mon Sep 17 00:00:00 2001 From: Thunderforge Date: Sat, 16 Dec 2017 14:36:27 -0600 Subject: [PATCH 29/31] Explicitly setting CMAKE_CXX_STANDARD to C++11 --- CMakeLists.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/CMakeLists.txt b/CMakeLists.txt index 1593dda2b..1fc9f5016 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -338,6 +338,7 @@ if (NOT WIN32 AND NOT APPLE) endif() # CXX Compiler settings +set(CMAKE_CXX_STANDARD 11) if (CMAKE_CXX_COMPILER_ID STREQUAL GNU OR CMAKE_CXX_COMPILER_ID STREQUAL Clang) set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -Wall -Wextra -Wundef -Wno-unused-parameter -std=c++11 -pedantic -Wno-long-long") add_definitions( -DBOOST_NO_CXX11_SCOPED_ENUMS=ON ) From 1a58171e86b90d1498808facfc955d35288730eb Mon Sep 17 00:00:00 2001 From: Andrei Kortunov Date: Sun, 17 Dec 2017 18:09:25 +0400 Subject: [PATCH 30/31] Do not allow to sell items from containers with zero capacity (bug #4268) --- apps/openmw/mwworld/worldimp.cpp | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 2d38f1518..340876759 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -2446,9 +2446,8 @@ namespace MWWorld if (ptr.getRefData().isDeleted()) return true; - // we should not sell ingrediends from owned organic containers - MWWorld::LiveCellRef* ref = ptr.get(); - if (ref && (ref->mBase->mFlags & ESM::Container::Organic)) + // vanilla Morrowind does not allow to sell items from containers with zero capacity + if (ptr.getClass().getCapacity(ptr) <= 0.f) return true; if (Misc::StringUtils::ciEqual(ptr.getCellRef().getOwner(), mOwner.getCellRef().getRefId())) From b8c25e6bff7ae42c24073523473c0f7f47034a70 Mon Sep 17 00:00:00 2001 From: scrawl <720642+scrawl@users.noreply.github.com> Date: Thu, 21 Dec 2017 14:49:09 +0000 Subject: [PATCH 31/31] Use the correct priority of animation sources in getStartTime (Fixes #4263) --- apps/openmw/mwrender/animation.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/apps/openmw/mwrender/animation.cpp b/apps/openmw/mwrender/animation.cpp index a1aa24871..16ce9b436 100644 --- a/apps/openmw/mwrender/animation.cpp +++ b/apps/openmw/mwrender/animation.cpp @@ -625,7 +625,7 @@ namespace MWRender float Animation::getStartTime(const std::string &groupname) const { - for(AnimSourceList::const_iterator iter(mAnimSources.begin()); iter != mAnimSources.end(); ++iter) + for(AnimSourceList::const_reverse_iterator iter(mAnimSources.rbegin()); iter != mAnimSources.rend(); ++iter) { const NifOsg::TextKeyMap &keys = (*iter)->getTextKeys(); @@ -638,7 +638,7 @@ namespace MWRender float Animation::getTextKeyTime(const std::string &textKey) const { - for(AnimSourceList::const_iterator iter(mAnimSources.begin()); iter != mAnimSources.end(); ++iter) + for(AnimSourceList::const_reverse_iterator iter(mAnimSources.rbegin()); iter != mAnimSources.rend(); ++iter) { const NifOsg::TextKeyMap &keys = (*iter)->getTextKeys();