diff --git a/rpcs3/Emu/Cell/Modules/sysPrxForUser.cpp b/rpcs3/Emu/Cell/Modules/sysPrxForUser.cpp index 0b6a78d6b7..fee6d38fea 100644 --- a/rpcs3/Emu/Cell/Modules/sysPrxForUser.cpp +++ b/rpcs3/Emu/Cell/Modules/sysPrxForUser.cpp @@ -168,8 +168,8 @@ error_code sysPs2Disc_BB7CD1AE() return CELL_OK; } -extern void sysPrxForUser_sys_lwmutex_init(); -extern void sysPrxForUser_sys_lwcond_init(); +extern void sysPrxForUser_sys_lwmutex_init(ppu_static_module*); +extern void sysPrxForUser_sys_lwcond_init(ppu_static_module*); extern void sysPrxForUser_sys_ppu_thread_init(); extern void sysPrxForUser_sys_prx_init(); extern void sysPrxForUser_sys_heap_init(); @@ -181,7 +181,7 @@ extern void sysPrxForUser_sys_game_init(); extern void sysPrxForUser_sys_libc_init(); extern void sysPrxForUser_sys_rsxaudio_init(); -DECLARE(ppu_module_manager::sysPrxForUser)("sysPrxForUser", []() +DECLARE(ppu_module_manager::sysPrxForUser)("sysPrxForUser", [](ppu_static_module* _this) { static ppu_static_module cellGamePs1Emu("cellGamePs1Emu", []() { @@ -217,8 +217,8 @@ DECLARE(ppu_module_manager::sysPrxForUser)("sysPrxForUser", []() REG_FNID(sysPs2Disc, 0xBB7CD1AE, sysPs2Disc_BB7CD1AE); }); - sysPrxForUser_sys_lwmutex_init(); - sysPrxForUser_sys_lwcond_init(); + sysPrxForUser_sys_lwmutex_init(_this); + sysPrxForUser_sys_lwcond_init(_this); sysPrxForUser_sys_ppu_thread_init(); sysPrxForUser_sys_prx_init(); sysPrxForUser_sys_heap_init(); diff --git a/rpcs3/Emu/Cell/Modules/sys_lwcond_.cpp b/rpcs3/Emu/Cell/Modules/sys_lwcond_.cpp index 3b30724651..91c5f9e7b6 100644 --- a/rpcs3/Emu/Cell/Modules/sys_lwcond_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_lwcond_.cpp @@ -369,12 +369,22 @@ error_code sys_lwcond_wait(ppu_thread& ppu, vm::ptr lwcond, u64 ti fmt::throw_exception("Unexpected syscall result (lwcond=*0x%x, result=0x%x)", lwcond, +res); } -void sysPrxForUser_sys_lwcond_init() +void sysPrxForUser_sys_lwcond_init(ppu_static_module* _this) { - REG_FUNC(sysPrxForUser, sys_lwcond_create).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT); - REG_FUNC(sysPrxForUser, sys_lwcond_destroy).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT); - REG_FUNC(sysPrxForUser, sys_lwcond_signal).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT); - REG_FUNC(sysPrxForUser, sys_lwcond_signal_all).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT); - REG_FUNC(sysPrxForUser, sys_lwcond_signal_to).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT); - REG_FUNC(sysPrxForUser, sys_lwcond_wait).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT); + REG_FUNC(sysPrxForUser, sys_lwcond_create); + REG_FUNC(sysPrxForUser, sys_lwcond_destroy); + REG_FUNC(sysPrxForUser, sys_lwcond_signal); + REG_FUNC(sysPrxForUser, sys_lwcond_signal_all); + REG_FUNC(sysPrxForUser, sys_lwcond_signal_to); + REG_FUNC(sysPrxForUser, sys_lwcond_wait); + + _this->add_init_func([](ppu_static_module*) + { + ACCESS_FUNC(sys_lwcond_create).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT); + ACCESS_FUNC(sys_lwcond_destroy).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT); + ACCESS_FUNC(sys_lwcond_signal).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT); + ACCESS_FUNC(sys_lwcond_signal_all).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT); + ACCESS_FUNC(sys_lwcond_signal_to).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT); + ACCESS_FUNC(sys_lwcond_wait).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT); + }); } diff --git a/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp b/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp index 08b2a44ed3..22388db9c3 100644 --- a/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp +++ b/rpcs3/Emu/Cell/Modules/sys_lwmutex_.cpp @@ -379,11 +379,20 @@ error_code sys_lwmutex_unlock(ppu_thread& ppu, vm::ptr lwmutex) return CELL_OK; } -void sysPrxForUser_sys_lwmutex_init() +void sysPrxForUser_sys_lwmutex_init(ppu_static_module* _this) { - REG_FUNC(sysPrxForUser, sys_lwmutex_create).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT); - REG_FUNC(sysPrxForUser, sys_lwmutex_destroy).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT); - REG_FUNC(sysPrxForUser, sys_lwmutex_lock).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT); - REG_FUNC(sysPrxForUser, sys_lwmutex_trylock).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT); - REG_FUNC(sysPrxForUser, sys_lwmutex_unlock).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT); + REG_FUNC(sysPrxForUser, sys_lwmutex_create); + REG_FUNC(sysPrxForUser, sys_lwmutex_destroy); + REG_FUNC(sysPrxForUser, sys_lwmutex_lock); + REG_FUNC(sysPrxForUser, sys_lwmutex_trylock); + REG_FUNC(sysPrxForUser, sys_lwmutex_unlock); + + _this->add_init_func([](ppu_static_module*) + { + ACCESS_FUNC(sys_lwmutex_create).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT); + ACCESS_FUNC(sys_lwmutex_destroy).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT); + ACCESS_FUNC(sys_lwmutex_lock).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT); + ACCESS_FUNC(sys_lwmutex_trylock).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT); + ACCESS_FUNC(sys_lwmutex_unlock).flag(g_cfg.core.hle_lwmutex ? MFF_FORCED_HLE : MFF_PERFECT); + }); } diff --git a/rpcs3/Emu/Cell/PPUModule.cpp b/rpcs3/Emu/Cell/PPUModule.cpp index a874d0ee60..3762a5871e 100644 --- a/rpcs3/Emu/Cell/PPUModule.cpp +++ b/rpcs3/Emu/Cell/PPUModule.cpp @@ -60,6 +60,19 @@ ppu_static_module::ppu_static_module(const char* name) ppu_module_manager::register_module(this); } +void ppu_static_module::add_init_func(void(*func)(ppu_static_module*)) +{ + m_on_init.emplace_back(func); +} + +void ppu_static_module::initialize() +{ + for (auto func : m_on_init) + { + func(this); + } +} + void ppu_module_manager::register_module(ppu_static_module* _module) { ppu_module_manager::s_module_map.emplace(_module->name, _module); @@ -96,6 +109,14 @@ const ppu_static_module* ppu_module_manager::get_module(const std::string& name) return found != map.end() ? found->second : nullptr; } +void ppu_module_manager::initialize_modules() +{ + for (auto& _module : s_module_map) + { + _module.second->initialize(); + } +} + // Global linkage information struct ppu_linkage_info { @@ -136,6 +157,8 @@ static void ppu_initialize_modules(ppu_linkage_info* link) return; } + ppu_module_manager::initialize_modules(); + const std::initializer_list registered { &ppu_module_manager::cellAdec, diff --git a/rpcs3/Emu/Cell/PPUModule.h b/rpcs3/Emu/Cell/PPUModule.h index cf660630f3..46b436d9af 100644 --- a/rpcs3/Emu/Cell/PPUModule.h +++ b/rpcs3/Emu/Cell/PPUModule.h @@ -72,6 +72,8 @@ struct ppu_static_variable // HLE module information class ppu_static_module final { + std::vector m_on_init; + public: const std::string name; @@ -92,6 +94,10 @@ public: { init(this); } + + void add_init_func(void(*func)(ppu_static_module*)); + + void initialize(); }; class ppu_module_manager final @@ -114,6 +120,8 @@ class ppu_module_manager final public: static const ppu_static_module* get_module(const std::string& name); + static void initialize_modules(); + template static auto& register_static_function(const char* _module, const char* name, ppu_function_t func, u32 fnid) { @@ -293,4 +301,6 @@ inline RT ppu_execute(ppu_thread& ppu, Args... args) #define REG_VAR(_module, var) REG_VNID(_module, #var, var) +#define ACCESS_FUNC(func) ppu_module_manager::find_static_function<&func>() + #define UNIMPLEMENTED_FUNC(_module) _module.todo("%s()", __func__)