Merge branch 'OpenMW:master' into master

This commit is contained in:
Andy Lanzone 2025-05-09 22:57:21 -07:00 committed by GitHub
commit b4e0590a10
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
8 changed files with 66 additions and 31 deletions

View File

@ -232,6 +232,7 @@ Programmers
Tess (tescoShoppah)
thegriglat
Thomas Luppi (Digmaster)
Tim Hagberg (hazardMan)
tlmullis
trav
tri4ng1e

View File

@ -231,7 +231,9 @@
Bug #8378: Korean bitmap fonts are unusable
Bug #8439: Creatures without models can crash the game
Bug #8441: Freeze when using video main menu replacers
Bug #8445: Launcher crashes on exit when cell name loading thread is still running
Bug #8462: Crashes when resizing the window on macOS
Bug #8465: Blue screen w/ antialiasing and post-processing on macOS
Feature #1415: Infinite fall failsafe
Feature #2566: Handle NAM9 records for manual cell references
Feature #3501: OpenMW-CS: Instance Editing - Shortcuts for axial locking

View File

@ -82,7 +82,7 @@ message(STATUS "Configuring OpenMW...")
set(OPENMW_VERSION_MAJOR 0)
set(OPENMW_VERSION_MINOR 49)
set(OPENMW_VERSION_RELEASE 0)
set(OPENMW_LUA_API_REVISION 72)
set(OPENMW_LUA_API_REVISION 73)
set(OPENMW_POSTPROCESSING_API_REVISION 2)
set(OPENMW_VERSION_COMMITHASH "")

View File

@ -159,6 +159,7 @@ Launcher::DataFilesPage::DataFilesPage(const Files::ConfigurationManager& cfg, C
, mGameSettings(gameSettings)
, mLauncherSettings(launcherSettings)
, mNavMeshToolInvoker(new Process::ProcessInvoker(this))
, mReloadCellsThread(&DataFilesPage::reloadCells, this)
{
ui.setupUi(this);
setObjectName("DataFilesPage");
@ -205,6 +206,16 @@ Launcher::DataFilesPage::DataFilesPage(const Files::ConfigurationManager& cfg, C
slotAddonDataChanged();
}
Launcher::DataFilesPage::~DataFilesPage()
{
{
const std::lock_guard lock(mReloadCellsMutex);
mAbortReloadCells = true;
mStartReloadCells.notify_one();
}
mReloadCellsThread.join();
}
void Launcher::DataFilesPage::buildView()
{
QToolButton* refreshButton = mSelector->refreshButton();
@ -991,31 +1002,45 @@ bool Launcher::DataFilesPage::showDeleteMessageBox(const QString& text)
void Launcher::DataFilesPage::slotAddonDataChanged()
{
QStringList selectedFiles = selectedFilePaths();
if (previousSelectedFiles != selectedFiles)
if (mSelectedFiles != selectedFiles)
{
previousSelectedFiles = selectedFiles;
// Loading cells for core Morrowind + Expansions takes about 0.2 seconds, which is enough to cause a
// barely perceptible UI lag. Splitting into its own thread to alleviate that.
std::thread loadCellsThread(&DataFilesPage::reloadCells, this, selectedFiles);
loadCellsThread.detach();
const std::lock_guard lock(mReloadCellsMutex);
mSelectedFiles = std::move(selectedFiles);
mReloadCells = true;
mStartReloadCells.notify_one();
}
}
// Mutex lock to run reloadCells synchronously.
static std::mutex reloadCellsMutex;
void Launcher::DataFilesPage::reloadCells(QStringList selectedFiles)
void Launcher::DataFilesPage::reloadCells()
{
// Use a mutex lock so that we can prevent two threads from executing the rest of this code at the same time
// Based on https://stackoverflow.com/a/5429695/531762
std::unique_lock<std::mutex> lock(reloadCellsMutex);
std::unique_lock lock(mReloadCellsMutex);
while (true)
{
mStartReloadCells.wait(lock);
if (mAbortReloadCells)
return;
if (!std::exchange(mReloadCells, false))
continue;
QStringList selectedFiles = mSelectedFiles;
lock.unlock();
// The following code will run only if there is not another thread currently running it
CellNameLoader cellNameLoader;
QSet<QString> set = cellNameLoader.getCellNames(selectedFiles);
QStringList cellNamesList(set.begin(), set.end());
std::sort(cellNamesList.begin(), cellNamesList.end());
emit signalLoadedCellsChanged(cellNamesList);
emit signalLoadedCellsChanged(std::move(cellNamesList));
lock.lock();
if (mAbortReloadCells)
return;
}
}
void Launcher::DataFilesPage::startNavMeshTool()

View File

@ -10,6 +10,10 @@
#include <QStringList>
#include <QWidget>
#include <condition_variable>
#include <mutex>
#include <thread>
class QSortFilterProxyModel;
class QAbstractItemModel;
class QMenu;
@ -47,6 +51,7 @@ namespace Launcher
public:
explicit DataFilesPage(const Files::ConfigurationManager& cfg, Config::GameSettings& gameSettings,
Config::LauncherSettings& launcherSettings, MainDialog* parent = nullptr);
~DataFilesPage();
QAbstractItemModel* profilesModel() const;
@ -119,7 +124,7 @@ namespace Launcher
Config::LauncherSettings& mLauncherSettings;
QString mPreviousProfile;
QStringList previousSelectedFiles;
QStringList mSelectedFiles;
QString mDataLocal;
QStringList mKnownArchives;
QStringList mNewDataDirs;
@ -127,6 +132,12 @@ namespace Launcher
Process::ProcessInvoker* mNavMeshToolInvoker;
NavMeshToolProgress mNavMeshToolProgress;
bool mReloadCells = false;
bool mAbortReloadCells = false;
std::mutex mReloadCellsMutex;
std::condition_variable mStartReloadCells;
std::thread mReloadCellsThread;
void addArchive(const QString& name, Qt::CheckState selected, int row = -1);
void addArchivesFromDir(const QString& dir);
void buildView();
@ -140,7 +151,7 @@ namespace Launcher
void addProfile(const QString& profile, bool setAsCurrent);
void checkForDefaultProfile();
void populateFileViews(const QString& contentModelName);
void reloadCells(QStringList selectedFiles);
void reloadCells();
void refreshDataFilesView();
void updateNavMeshProgress(int minDataSize);
void slotCopySelectedItemsPaths();

View File

@ -64,7 +64,7 @@ namespace MWLua
= [](SelfObject& self) { return "openmw.self[" + self.toString() + "]"; };
selfAPI["object"] = sol::readonly_property([](SelfObject& self) -> LObject { return LObject(self); });
selfAPI["controls"] = sol::readonly_property([](SelfObject& self) { return &self.mControls; });
selfAPI["isActive"] = [](SelfObject& self) { return &self.mIsActive; };
selfAPI["isActive"] = [](SelfObject& self) -> bool { return self.mIsActive; };
selfAPI["enableAI"] = [](SelfObject& self, bool v) { self.mControls.mDisableAI = !v; };
selfAPI["ATTACK_TYPE"]
= LuaUtil::makeStrictReadOnly(LuaUtil::tableFromPairs<std::string_view, MWMechanics::AttackType>(lua,

View File

@ -503,6 +503,7 @@ namespace MWRender
if (mSamples > 1)
{
fbos[FBO_Multisample] = new osg::FrameBufferObject;
fbos[FBO_Intercept] = new osg::FrameBufferObject;
auto colorRB = createFrameBufferAttachmentFromTemplate(
Usage::RENDER_BUFFER, width, height, textures[Tex_Scene], mSamples);
if (mNormals && mNormalsSupported)
@ -511,6 +512,8 @@ namespace MWRender
Usage::RENDER_BUFFER, width, height, textures[Tex_Normal], mSamples);
fbos[FBO_Multisample]->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER1, normalRB);
fbos[FBO_FirstPerson]->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER1, normalRB);
fbos[FBO_Intercept]->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER1,
Stereo::createMultiviewCompatibleAttachment(textures[Tex_Normal]));
}
auto depthRB = createFrameBufferAttachmentFromTemplate(
Usage::RENDER_BUFFER, width, height, textures[Tex_Depth], mSamples);
@ -519,11 +522,8 @@ namespace MWRender
osg::FrameBufferObject::BufferComponent::PACKED_DEPTH_STENCIL_BUFFER, depthRB);
fbos[FBO_FirstPerson]->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0, colorRB);
fbos[FBO_Intercept] = new osg::FrameBufferObject;
fbos[FBO_Intercept]->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER0,
Stereo::createMultiviewCompatibleAttachment(textures[Tex_Scene]));
fbos[FBO_Intercept]->setAttachment(osg::FrameBufferObject::BufferComponent::COLOR_BUFFER1,
Stereo::createMultiviewCompatibleAttachment(textures[Tex_Normal]));
}
else
{

View File

@ -245,11 +245,7 @@ namespace fx
else if (key == "author")
mAuthor = parseString();
else if (key == "glsl_version")
{
int version = parseInteger();
if (mUBO && version > 330)
mGLSLVersion = version;
}
mGLSLVersion = std::max(mGLSLVersion, parseInteger());
else if (key == "flags")
mFlags = parseFlags();
else if (key == "hdr")