diff --git a/src/Cafe/GraphicPack/GraphicPack2.cpp b/src/Cafe/GraphicPack/GraphicPack2.cpp index 67ba6edc..295d5dce 100644 --- a/src/Cafe/GraphicPack/GraphicPack2.cpp +++ b/src/Cafe/GraphicPack/GraphicPack2.cpp @@ -1199,15 +1199,14 @@ std::vector GraphicPack2::ParseTitleIds(IniParser& rules, const char* op if (!option_text) return result; + if (*option_text == "*") + { + m_universal = true; + return result; + } + for (auto& token : TokenizeView(*option_text, ',')) { - if (token == "*") - { - m_universal = true; - result.clear(); - break; - } - try { result.emplace_back(ConvertString(token, 16)); diff --git a/src/Cafe/GraphicPack/GraphicPack2.h b/src/Cafe/GraphicPack/GraphicPack2.h index 062ecb75..e33f0946 100644 --- a/src/Cafe/GraphicPack/GraphicPack2.h +++ b/src/Cafe/GraphicPack/GraphicPack2.h @@ -124,7 +124,7 @@ public: bool HasCustomVSyncFrequency() const { return m_vsync_frequency >= 1; } sint32 GetCustomVSyncFrequency() const { return m_vsync_frequency; } - const std::vector& GetCallbacks() const { return m_callbacks; } + const std::vector>& GetCallbacks() const { return m_callbacks; } // texture rules const std::vector& GetTextureRules() const { return m_texture_rules; } @@ -287,7 +287,7 @@ private: std::vector list_patchGroups; - std::vector m_callbacks; + std::vector> m_callbacks; static std::recursive_mutex mtx_patches; static std::vector list_modules; diff --git a/src/Cafe/GraphicPack/GraphicPack2Patches.cpp b/src/Cafe/GraphicPack/GraphicPack2Patches.cpp index 9ac97c8f..7ceaf9d4 100644 --- a/src/Cafe/GraphicPack/GraphicPack2Patches.cpp +++ b/src/Cafe/GraphicPack/GraphicPack2Patches.cpp @@ -172,7 +172,7 @@ void GraphicPack2::ApplyPatchesForModule(const RPLModule* rpl) std::vector list_groups; for (auto itr : list_patchGroups) { - if (itr->matchesCRC(rpl->patchCRC) || (itr->m_isRpxOnlyTarget && rpl->fileInfo.flags & 2)) + if (itr->matchesCRC(rpl->patchCRC) || (itr->m_isRpxOnlyTarget && rpl->IsRPX())) list_groups.emplace_back(itr); } // apply all groups at once @@ -188,7 +188,7 @@ void GraphicPack2::RevertPatchesForModule(const RPLModule* rpl) std::vector list_groups; for (auto itr : list_patchGroups) { - if (itr->matchesCRC(rpl->patchCRC) || (itr->m_isRpxOnlyTarget && rpl->fileInfo.flags & 2)) + if (itr->matchesCRC(rpl->patchCRC) || (itr->m_isRpxOnlyTarget && rpl->IsRPX())) list_groups.emplace_back(itr); } // undo all groups at once diff --git a/src/Cafe/GraphicPack/GraphicPack2Patches.h b/src/Cafe/GraphicPack/GraphicPack2Patches.h index 44a56673..34750533 100644 --- a/src/Cafe/GraphicPack/GraphicPack2Patches.h +++ b/src/Cafe/GraphicPack/GraphicPack2Patches.h @@ -212,6 +212,10 @@ private: bool m_addrRelocated{}; }; +enum class GPCallbackType { + Entry +}; + class PatchGroup { friend class GraphicPack2; @@ -256,7 +260,7 @@ private: std::string name; std::vector list_moduleMatches; std::vector list_patches; - std::vector list_callbacks; + std::vector> list_callbacks; uint32 codeCaveSize; MEMPTR codeCaveMem; bool m_isApplied{}; diff --git a/src/Cafe/GraphicPack/GraphicPack2PatchesApply.cpp b/src/Cafe/GraphicPack/GraphicPack2PatchesApply.cpp index b6dfe6f1..10e9743b 100644 --- a/src/Cafe/GraphicPack/GraphicPack2PatchesApply.cpp +++ b/src/Cafe/GraphicPack/GraphicPack2PatchesApply.cpp @@ -711,12 +711,12 @@ void GraphicPack2::ApplyPatchGroups(std::vector& groups, const RPLM patchInstruction->applyPatch(); } - for (const auto& name : patchGroup->list_callbacks) + for (const auto& [name, type] : patchGroup->list_callbacks) { auto it = patchContext.map_values.find(name); if (it != patchContext.map_values.end()) { - m_callbacks.push_back(it->second); + m_callbacks.push_back(std::make_pair(it->second, type)); } else { diff --git a/src/Cafe/GraphicPack/GraphicPack2PatchesParser.cpp b/src/Cafe/GraphicPack/GraphicPack2PatchesParser.cpp index be11f2c1..d93cc151 100644 --- a/src/Cafe/GraphicPack/GraphicPack2PatchesParser.cpp +++ b/src/Cafe/GraphicPack/GraphicPack2PatchesParser.cpp @@ -433,19 +433,28 @@ bool GraphicPack2::ParseCemuPatchesTxtInternal(MemStreamReader& patchesStream) } else if (parser.matchWordI(".callback")) { - const char* symbolStr; - sint32 symbolLen; - if (parser.parseSymbolName(symbolStr, symbolLen)) - { - currentGroup->list_callbacks.push_back({symbolStr, static_cast(symbolLen)}); - continue; - } + if (parser.matchWordI("entry")) + { + const char* symbolStr; + sint32 symbolLen; + if (parser.parseSymbolName(symbolStr, symbolLen)) + { + currentGroup->list_callbacks.push_back(std::make_pair(std::string(symbolStr, static_cast(symbolLen)), GPCallbackType::Entry)); + continue; + } + else + { + LogPatchesSyntaxError(lineNumber, "'.callback' must reference a symbol after the type"); + CancelParsingPatches(); + return false; + } + } else { - LogPatchesSyntaxError(lineNumber, "'.callback' must be followed by a symbol"); - CancelParsingPatches(); - return false; - } + LogPatchesSyntaxError(lineNumber, "Unrecognized type for '.callback'"); + CancelParsingPatches(); + return false; + } } // next we attempt to parse symbol assignment diff --git a/src/Cafe/OS/RPL/rpl_structs.h b/src/Cafe/OS/RPL/rpl_structs.h index cdf6ec3e..aa734dae 100644 --- a/src/Cafe/OS/RPL/rpl_structs.h +++ b/src/Cafe/OS/RPL/rpl_structs.h @@ -210,6 +210,11 @@ struct RPLModule return 0; return crcTable[sectionIndex]; } + + bool IsRPX() const + { + return fileInfo.flags & 2; + } // state bool isLinked; // set to true if _linkModule was called on this module diff --git a/src/Cafe/OS/libs/coreinit/coreinit_Init.cpp b/src/Cafe/OS/libs/coreinit/coreinit_Init.cpp index 9072daef..04e7d07d 100644 --- a/src/Cafe/OS/libs/coreinit/coreinit_Init.cpp +++ b/src/Cafe/OS/libs/coreinit/coreinit_Init.cpp @@ -212,11 +212,15 @@ void coreinit_start(PPCInterpreter_t* hCPU) padscore::start(); vpad::start(); + // call entry-type callbacks in graphic packs for (const auto gp : GraphicPack2::GetActiveGraphicPacks()) { - for (MPTR callback : gp->GetCallbacks()) + for (const auto [callback, type] : gp->GetCallbacks()) { - PPCCoreCallback(callback); + if (type == GPCallbackType::Entry) + { + PPCCoreCallback(callback); + } } }