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) Tess (tescoShoppah)
thegriglat thegriglat
Thomas Luppi (Digmaster) Thomas Luppi (Digmaster)
Tim Hagberg (hazardMan)
tlmullis tlmullis
trav trav
tri4ng1e tri4ng1e

View File

@ -231,7 +231,9 @@
Bug #8378: Korean bitmap fonts are unusable Bug #8378: Korean bitmap fonts are unusable
Bug #8439: Creatures without models can crash the game Bug #8439: Creatures without models can crash the game
Bug #8441: Freeze when using video main menu replacers 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 #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 #1415: Infinite fall failsafe
Feature #2566: Handle NAM9 records for manual cell references Feature #2566: Handle NAM9 records for manual cell references
Feature #3501: OpenMW-CS: Instance Editing - Shortcuts for axial locking 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_MAJOR 0)
set(OPENMW_VERSION_MINOR 49) set(OPENMW_VERSION_MINOR 49)
set(OPENMW_VERSION_RELEASE 0) 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_POSTPROCESSING_API_REVISION 2)
set(OPENMW_VERSION_COMMITHASH "") set(OPENMW_VERSION_COMMITHASH "")

View File

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

View File

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

View File

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

View File

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

View File

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