Fix booting Shantae Half Genie Hero and Ducktales Remastered

This commit is contained in:
Maschell 2022-09-07 01:08:35 +02:00
parent 08d764d249
commit a9914c3e03
6 changed files with 116 additions and 1 deletions

View File

@ -25,7 +25,8 @@ SOURCES := source \
source/applicationendshook \ source/applicationendshook \
source/dynload \ source/dynload \
source/sdrefcount \ source/sdrefcount \
source/symbolnamepatcher source/symbolnamepatcher \
source/patches
DATA := data DATA := data
INCLUDES := source INCLUDES := source

View File

@ -2,6 +2,7 @@
#include "dynload/dynload.h" #include "dynload/dynload.h"
#include "globals.h" #include "globals.h"
#include "logger.h" #include "logger.h"
#include "patches/patches.h"
#include "sdrefcount/refcount.h" #include "sdrefcount/refcount.h"
#include "symbolnamepatcher/symbolname.h" #include "symbolnamepatcher/symbolname.h"
#include <wums.h> #include <wums.h>
@ -23,6 +24,11 @@ WUMS_INITIALIZE(args) {
initSDRefCount(); initSDRefCount();
initSymbolNamePatcher(); initSymbolNamePatcher();
initDynload(); initDynload();
initCommonPatches();
deinitLogging(); deinitLogging();
} }
WUMS_APPLICATION_STARTS() {
commonPatchesStart();
}

View File

@ -0,0 +1,34 @@
#include "globals.h"
#include "logger.h"
#include "patches_replacements.h"
#include <cstdlib>
// init is not called for this module. We need to make sure to init these values in initCommonPatches()
uint32_t gHeapMask;
uint32_t gNonHomebrewFSClientCount;
void initCommonPatches() {
// Determine which region the memory mapping is using. We need this to count the
// number of FSClients which are stored in that region.
auto dummy = malloc(0x4);
if (!dummy) {
gHeapMask = 0x80000000;
} else {
DEBUG_FUNCTION_LINE_ERR("%08X", dummy);
gHeapMask = (uint32_t) dummy & 0xF0000000;
free(dummy);
}
gNonHomebrewFSClientCount = 0;
DEBUG_FUNCTION_LINE("Do common patches");
for (uint32_t i = 0; i < patches_function_replacements_size; i++) {
if (!FunctionPatcherPatchFunction(&patches_function_replacements[i], nullptr)) {
OSFatal("AromaBaseModule: Failed apply common patches");
}
}
DEBUG_FUNCTION_LINE("Common patches finished");
}
void commonPatchesStart() {
gNonHomebrewFSClientCount = 0;
}

9
source/patches/patches.h Normal file
View File

@ -0,0 +1,9 @@
#pragma once
#include <stdint.h>
extern uint32_t gHeapMask;
extern uint32_t gNonHomebrewFSClientCount;
void initCommonPatches();
void commonPatchesStart();

View File

@ -0,0 +1,49 @@
#include "patches_replacements.h"
#include "globals.h"
#include "logger.h"
#include "patches.h"
#include <coreinit/filesystem_fsa.h>
#include <coreinit/title.h>
DECL_FUNCTION(FSStatus, FSAddClient, FSClient *client, FSErrorFlag errorMask) {
auto res = real_FSAddClient(client, errorMask);
if (res == FS_STATUS_OK) {
if (((uint32_t) client & 0xF0000000) != gHeapMask) {
gNonHomebrewFSClientCount++;
}
}
return res;
}
DECL_FUNCTION(FSStatus, FSDelClient, FSClient *client, FSErrorFlag errorMask) {
auto res = real_FSDelClient(client, errorMask);
if (res == FS_STATUS_OK) {
if (((uint32_t) client & 0xF0000000) != gHeapMask) {
gNonHomebrewFSClientCount--;
}
}
return res;
}
DECL_FUNCTION(uint32_t, FSGetClientNum) {
auto titleID = OSGetTitleID();
// Some games rely on the "correct" FSGetClientNum count and only init their
// FS system if FSGetClientNum returns 0. Whitelisting games for this hack seems
// better than breaking other games by accident...
if (titleID == 0x0005000010129000 || // DuckTales: Remastered USA
titleID == 0x0005000010129200 || // DuckTales: Remastered EUR
titleID == 0x00050000101DB200 || // Shantae: Half-Genie Hero USA
titleID == 0x0005000010203200 // Shantae: Half-Genie Hero EUR
) {
DEBUG_FUNCTION_LINE("Fake FSGetClientNum num to %d instead of %d", gNonHomebrewFSClientCount, real_FSGetClientNum());
return gNonHomebrewFSClientCount;
}
return real_FSGetClientNum();
}
function_replacement_data_t patches_function_replacements[] = {
REPLACE_FUNCTION(FSAddClient, LIBRARY_COREINIT, FSAddClient),
REPLACE_FUNCTION(FSDelClient, LIBRARY_COREINIT, FSDelClient),
REPLACE_FUNCTION(FSGetClientNum, LIBRARY_COREINIT, FSGetClientNum),
};
uint32_t patches_function_replacements_size = sizeof(patches_function_replacements) / sizeof(function_replacement_data_t);

View File

@ -0,0 +1,16 @@
#pragma once
#include <cstdint>
#include <function_patcher/function_patching.h>
#ifdef __cplusplus
extern "C" {
#endif
extern function_replacement_data_t patches_function_replacements[];
#ifdef __cplusplus
}
#endif
extern uint32_t patches_function_replacements_size;