plugin_loader: Add new flags to 3gx files (#2021)

This commit is contained in:
PabloMK7 2024-05-01 00:31:23 +02:00 committed by GitHub
parent 63fbc37426
commit 5928eefe95
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 30 additions and 4 deletions

View File

@ -20,7 +20,10 @@ typedef struct CTR_PACKED
u32 embeddedExeLoadFunc : 1; u32 embeddedExeLoadFunc : 1;
u32 embeddedSwapSaveLoadFunc : 1; u32 embeddedSwapSaveLoadFunc : 1;
u32 memoryRegionSize : 2; u32 memoryRegionSize : 2;
u32 unused : 28; u32 compatibility : 2;
u32 eventsSelfManaged : 1;
u32 swapNotNeeded : 1;
u32 unused : 24;
}; };
}; };
u32 exeLoadChecksum; u32 exeLoadChecksum;
@ -67,6 +70,12 @@ typedef struct CTR_PACKED
} _3gx_Header; } _3gx_Header;
enum _3gx_Compatibility {
PLG_COMPAT_CONSOLE = 0,
PLG_COMPAT_EMULATOR = 1,
PLG_COMPAT_CONSOLE_EMULATOR = 2,
};
Result Check_3gx_Magic(IFile *file); Result Check_3gx_Magic(IFile *file);
Result Read_3gx_Header(IFile *file, _3gx_Header *header); Result Read_3gx_Header(IFile *file, _3gx_Header *header);
Result Read_3gx_ParseHeader(IFile *file, _3gx_Header *header); Result Read_3gx_ParseHeader(IFile *file, _3gx_Header *header);

View File

@ -91,6 +91,8 @@ typedef struct
u8 pluginMemoryStrategy; u8 pluginMemoryStrategy;
u32 exeLoadChecksum; u32 exeLoadChecksum;
u32 swapLoadChecksum; u32 swapLoadChecksum;
bool eventsSelfManaged;
} PluginLoaderContext; } PluginLoaderContext;
extern PluginLoaderContext PluginLoaderCtx; extern PluginLoaderContext PluginLoaderCtx;

View File

@ -205,6 +205,19 @@ bool TryToLoadPlugin(Handle process)
if (!res && R_FAILED((res = Read_3gx_Header(&plugin, &fileHeader)))) if (!res && R_FAILED((res = Read_3gx_Header(&plugin, &fileHeader))))
ctx->error.message = "Couldn't read file"; ctx->error.message = "Couldn't read file";
// Check compatibility
if (!res && fileHeader.infos.compatibility == PLG_COMPAT_EMULATOR) {
ctx->error.message = "Plugin is only compatible with emulators";
return false;
}
// Flags
if (!res) {
ctx->eventsSelfManaged = fileHeader.infos.eventsSelfManaged;
if (ctx->pluginMemoryStrategy == PLG_STRATEGY_SWAP && fileHeader.infos.swapNotNeeded)
ctx->pluginMemoryStrategy = PLG_STRATEGY_NONE;
}
// Set memory region size according to header // Set memory region size according to header
if (!res && R_FAILED((res = MemoryBlock__SetSize(memRegionSizes[fileHeader.infos.memoryRegionSize])))) { if (!res && R_FAILED((res = MemoryBlock__SetSize(memRegionSizes[fileHeader.infos.memoryRegionSize])))) {
ctx->error.message = "Couldn't set memblock size."; ctx->error.message = "Couldn't set memblock size.";

View File

@ -449,7 +449,7 @@ static void __strex__(s32 *addr, s32 val)
void PLG__NotifyEvent(PLG_Event event, bool signal) void PLG__NotifyEvent(PLG_Event event, bool signal)
{ {
if (!PluginLoaderCtx.plgEventPA) return; if (PluginLoaderCtx.eventsSelfManaged || !PluginLoaderCtx.plgEventPA) return;
__strex__(PluginLoaderCtx.plgEventPA, event); __strex__(PluginLoaderCtx.plgEventPA, event);
if (signal) if (signal)
@ -458,6 +458,7 @@ void PLG__NotifyEvent(PLG_Event event, bool signal)
void PLG__WaitForReply(void) void PLG__WaitForReply(void)
{ {
if (PluginLoaderCtx.eventsSelfManaged) return;
__strex__(PluginLoaderCtx.plgReplyPA, PLG_WAIT); __strex__(PluginLoaderCtx.plgReplyPA, PLG_WAIT);
svcArbitrateAddress(PluginLoaderCtx.arbiter, (u32)PluginLoaderCtx.plgReplyPA, ARBITRATION_WAIT_IF_LESS_THAN_TIMEOUT, PLG_OK, 10000000000ULL); svcArbitrateAddress(PluginLoaderCtx.arbiter, (u32)PluginLoaderCtx.plgReplyPA, ARBITRATION_WAIT_IF_LESS_THAN_TIMEOUT, PLG_OK, 10000000000ULL);
} }
@ -482,8 +483,8 @@ static void WaitForProcessTerminated(void *arg)
(void)arg; (void)arg;
PluginLoaderContext *ctx = &PluginLoaderCtx; PluginLoaderContext *ctx = &PluginLoaderCtx;
// Wait until all threads of the process have finished (svcWaitSynchronization == 0) or 5 seconds have passed. // Wait until all threads of the process have finished (svcWaitSynchronization == 0) or 2.5 seconds have passed.
for (u32 i = 0; svcWaitSynchronization(ctx->target, 0) != 0 && i < 100; i++) svcSleepThread(50000000); // 50ms for (u32 i = 0; svcWaitSynchronization(ctx->target, 0) != 0 && i < 50; i++) svcSleepThread(50000000); // 50ms
// Unmap plugin's memory before closing the process // Unmap plugin's memory before closing the process
if (!ctx->pluginIsSwapped) { if (!ctx->pluginIsSwapped) {
@ -500,6 +501,7 @@ static void WaitForProcessTerminated(void *arg)
ctx->isExeLoadFunctionset = false; ctx->isExeLoadFunctionset = false;
ctx->isSwapFunctionset = false; ctx->isSwapFunctionset = false;
ctx->pluginMemoryStrategy = PLG_STRATEGY_SWAP; ctx->pluginMemoryStrategy = PLG_STRATEGY_SWAP;
ctx->eventsSelfManaged = false;
g_blockMenuOpen = 0; g_blockMenuOpen = 0;
MemoryBlock__ResetSwapSettings(); MemoryBlock__ResetSwapSettings();
//if (!ctx->userLoadParameters.noIRPatch) //if (!ctx->userLoadParameters.noIRPatch)