From 00fe8fa2319c83ffe6562ea184a22424cab450ab Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Sun, 25 Jun 2023 00:56:37 -0700 Subject: [PATCH 1/2] Try to fix hsG3DDeviceSelector enumerator issues --- .../Plasma/PubUtilLib/plPipeline/hsG3DDeviceSelector.cpp | 7 +++++-- Sources/Plasma/PubUtilLib/plPipeline/hsG3DDeviceSelector.h | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/Sources/Plasma/PubUtilLib/plPipeline/hsG3DDeviceSelector.cpp b/Sources/Plasma/PubUtilLib/plPipeline/hsG3DDeviceSelector.cpp index 8049ef9c44..5e7f20c184 100644 --- a/Sources/Plasma/PubUtilLib/plPipeline/hsG3DDeviceSelector.cpp +++ b/Sources/Plasma/PubUtilLib/plPipeline/hsG3DDeviceSelector.cpp @@ -243,7 +243,10 @@ hsG3DDeviceModeRecord& hsG3DDeviceModeRecord::operator=(const hsG3DDeviceModeRec /////////////////////////////////////////////////// /////////////////////////////////////////////////// -std::list hsG3DDeviceSelector::sEnumerators; +std::list& hsG3DDeviceSelector::Enumerators() { + static std::list sEnumerators; + return sEnumerators; +} hsG3DDeviceSelector::~hsG3DDeviceSelector() { @@ -354,7 +357,7 @@ void hsG3DDeviceSelector::Enumerate(hsWindowHndl winRef) ITryDirect3DTnL(winRef); #endif - for (const auto& enumerator : sEnumerators) { + for (const auto& enumerator : Enumerators()) { enumerator(fRecords); } } diff --git a/Sources/Plasma/PubUtilLib/plPipeline/hsG3DDeviceSelector.h b/Sources/Plasma/PubUtilLib/plPipeline/hsG3DDeviceSelector.h index 3dfc1582fd..a4912218f5 100644 --- a/Sources/Plasma/PubUtilLib/plPipeline/hsG3DDeviceSelector.h +++ b/Sources/Plasma/PubUtilLib/plPipeline/hsG3DDeviceSelector.h @@ -323,7 +323,7 @@ class hsG3DDeviceSelector : public hsRefCnt typedef std::function&)> DeviceEnumerator; protected: - static std::list sEnumerators; + static std::list& Enumerators(); std::vector fRecords; @@ -344,7 +344,7 @@ class hsG3DDeviceSelector : public hsRefCnt void ISetFudgeFactors( uint8_t chipsetID, hsG3DDeviceRecord &record ); public: - static void AddDeviceEnumerator(const DeviceEnumerator& de) { sEnumerators.emplace_back(de); } + static void AddDeviceEnumerator(const DeviceEnumerator& de) { Enumerators().emplace_back(de); } hsG3DDeviceSelector() { } virtual ~hsG3DDeviceSelector(); From cf58afd1f79a5d38180f9d32d703dbb79c6c77db Mon Sep 17 00:00:00 2001 From: Darryl Pogue Date: Fri, 16 Jun 2023 21:46:59 -0700 Subject: [PATCH 2/2] Set up cross-platform ModDLL loading Co-Authored-By: dgelessus --- .../Plasma/Apps/plClient/Mac-Cocoa/main.mm | 2 - Sources/Plasma/Apps/plClient/main.cpp | 2 - Sources/Plasma/Apps/plClient/plClient.cpp | 58 +++++++++++++++++++ Sources/Plasma/Apps/plClient/plClient.h | 4 +- .../Apps/plClient/win32/plClient_Win.cpp | 30 ---------- Sources/Plasma/CoreLib/HeadSpin.h | 3 + 6 files changed, 64 insertions(+), 35 deletions(-) diff --git a/Sources/Plasma/Apps/plClient/Mac-Cocoa/main.mm b/Sources/Plasma/Apps/plClient/Mac-Cocoa/main.mm index 0101728f20..0059ef3ebd 100644 --- a/Sources/Plasma/Apps/plClient/Mac-Cocoa/main.mm +++ b/Sources/Plasma/Apps/plClient/Mac-Cocoa/main.mm @@ -132,8 +132,6 @@ @interface AppDelegate : NSWindowController // For ModDLL loading +#endif #define MSG_LOADING_BAR @@ -373,6 +377,60 @@ bool plClient::Shutdown() return false; } +void plClient::InitDLLs() { + hsStatusMessage("Init dlls client\n"); + + std::vector dlls = plFileSystem::ListDir("ModDLL", +#if defined(HS_BUILD_FOR_WIN32) + "*.dll" +#elif defined(HS_BUILD_FOR_APPLE) + "*.dylib" +#else + "*.so" +#endif + ); + + for (auto iter = dlls.begin(); iter != dlls.end(); ++iter) + { +#ifdef HS_BUILD_FOR_WIN32 + hsLibraryHndl mod = LoadLibraryW(iter->WideString().data()); +#else + hsLibraryHndl mod = dlopen(iter->AsString().c_str(), RTLD_LAZY | RTLD_LOCAL); +#endif + + if (mod) + { +#ifdef HS_BUILD_FOR_WIN32 + pInitGlobalsFunc initGlobals = reinterpret_cast(GetProcAddress(mod, "InitGlobals")); +#else + pInitGlobalsFunc initGlobals = reinterpret_cast(dlsym(mod, "InitGlobals")); +#endif + + (*initGlobals)(hsgResMgr::ResMgr(), plFactory::GetTheFactory(), plgTimerCallbackMgr::Mgr(), + hsTimer::GetTheTimer(), plNetClientApp::GetInstance()); + fLoadedDLLs.emplace_back(mod); + } + } +} + +void plClient::ShutdownDLLs() +{ + for (hsLibraryHndl mod : fLoadedDLLs) + { +#ifdef HS_BUILD_FOR_WIN32 + BOOL ret = FreeLibrary(mod); + if (!ret) + hsStatusMessage(ST::format("Failed to free lib: {}", hsCOMError(hsLastWin32Error, GetLastError())).c_str()); +#else + int ret = dlclose(mod); + if (ret) + hsStatusMessage(ST::format("Failed to free lib: {}", dlerror()).c_str()); +#endif + } + + fLoadedDLLs.clear(); +} + void plClient::InitAuxInits() { // Use another init directory specified in Command line Arg -i diff --git a/Sources/Plasma/Apps/plClient/plClient.h b/Sources/Plasma/Apps/plClient/plClient.h index dd839cb5c8..5baafffa45 100644 --- a/Sources/Plasma/Apps/plClient/plClient.h +++ b/Sources/Plasma/Apps/plClient/plClient.h @@ -178,7 +178,9 @@ class plClient : public hsKeyedObject int fNumPostLoadMsgs; float fPostLoadMsgInc; - + + std::vector fLoadedDLLs; + void ICompleteInit (); void IOnAsyncInitComplete (); void IHandlePatcherMsg (plResPatcherMsg * msg); diff --git a/Sources/Plasma/Apps/plClient/win32/plClient_Win.cpp b/Sources/Plasma/Apps/plClient/win32/plClient_Win.cpp index 0604e448c5..b8aaa4215a 100644 --- a/Sources/Plasma/Apps/plClient/win32/plClient_Win.cpp +++ b/Sources/Plasma/Apps/plClient/win32/plClient_Win.cpp @@ -51,12 +51,10 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include "plClient.h" #include "plWinDpi/plWinDpi.h" -#include "pnFactory/plFactory.h" #include "pnNetCommon/plNetApp.h" #include "plProgressMgr/plProgressMgr.h" extern ITaskbarList3* gTaskbarList; -static std::vector fLoadedDLLs; void plClient::IResizeNativeDisplayDevice(int width, int height, bool windowed) { @@ -146,34 +144,6 @@ void plClient::IUpdateProgressIndicator(plOperationProgress* progress) } } -void plClient::InitDLLs() -{ - hsStatusMessage("Init dlls client\n"); - std::vector dlls = plFileSystem::ListDir("ModDLL", "*.dll"); - for (auto iter = dlls.begin(); iter != dlls.end(); ++iter) - { - HMODULE hMod = LoadLibraryW(iter->WideString().data()); - if (hMod) - { - pInitGlobalsFunc initGlobals = (pInitGlobalsFunc)GetProcAddress(hMod, "InitGlobals"); - (*initGlobals)(hsgResMgr::ResMgr(), plFactory::GetTheFactory(), plgTimerCallbackMgr::Mgr(), - hsTimer::GetTheTimer(), plNetClientApp::GetInstance()); - fLoadedDLLs.emplace_back(hMod); - } - } -} - -void plClient::ShutdownDLLs() -{ - for (HMODULE dll : fLoadedDLLs) - { - BOOL ret = FreeLibrary(dll); - if (!ret) - hsStatusMessage("Failed to free lib\n"); - } - fLoadedDLLs.clear(); -} - // Show the client window void plClient::ShowClientWindow() { diff --git a/Sources/Plasma/CoreLib/HeadSpin.h b/Sources/Plasma/CoreLib/HeadSpin.h index 6f0cf62804..0b81ff9d7d 100644 --- a/Sources/Plasma/CoreLib/HeadSpin.h +++ b/Sources/Plasma/CoreLib/HeadSpin.h @@ -71,14 +71,17 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com typedef HWND hsWindowHndl; typedef HINSTANCE hsWindowInst; typedef HINSTANCE HMODULE; + typedef HMODULE hsLibraryHndl; typedef long HRESULT; typedef void* HANDLE; #elif HS_BUILD_FOR_MACOS typedef void* hsWindowHndl; typedef void* hsWindowInst; + typedef void* hsLibraryHndl; #else typedef int32_t* hsWindowHndl; typedef int32_t* hsWindowInst; + typedef void* hsLibraryHndl; #endif // HS_BUILD_FOR_WIN32 //======================================