Skip to content

Commit 96b5ea5

Browse files
authored
Merge branch 'JohnnyonFlame:master' into master
2 parents 4670c3c + 16662b2 commit 96b5ea5

6 files changed

Lines changed: 84 additions & 12 deletions

File tree

gmloader/libyoyo.cpp

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -47,12 +47,12 @@ ABI_ATTR char (*Variable_SetBuiltIn_Direct)(void* inst, int var_slot, int array_
4747
ABI_ATTR void (*Code_Function_GET_the_function)(int numb,char **name,void **code,int *args, int *unk) = NULL;
4848
ABI_ATTR void (*_RefThing__dec)(void *ref) = NULL;
4949
ABI_ATTR int (*Variable_BuiltIn_Find)(const char *name) = NULL;
50+
ABI_ATTR long (*PrepareGame)(void) = NULL;
5051
ABI_ATTR int (*Code_Variable_Find_Slot_From_Name)(void *instance, const char *name) = NULL;
5152
ABI_ATTR int (*Variable_FindName)(const char *name) = NULL; /* Unavailable in GMS 1.4+, very old symbol */
5253
ABI_ATTR long (*ExecuteIt)(void *self, void *other, void *code, RValue *args) = NULL;
5354
ABI_ATTR long (*ExecuteIt_flags)(void *self, void *other, void *code, RValue *args, int argc) = NULL;
5455

55-
5656
bionic_off_t *g_GameFileLength = NULL; //android had 32bit off_t???
5757
char **g_pWorkingDirectory = NULL;
5858
char *g_fNoAudio = NULL;
@@ -87,6 +87,8 @@ void **g_pGameFileBuffer = NULL;
8787
void **g_ppYYStackTrace = NULL;
8888
int *Extension_Main_number = NULL;
8989

90+
ReentrantHook REHPrepareGame = {};
91+
9092
uint8_t prev_kbd_state[N_KEYS] = {};
9193
uint8_t cur_keys[N_KEYS] = {};
9294

@@ -246,6 +248,16 @@ ABI_ATTR void game_change_reimpl(RValue *ret, void *self, void *other, int argc,
246248
}
247249
}
248250

251+
extern int setup_ended;
252+
ABI_ATTR long PrepareGame_hook()
253+
{
254+
setup_ended = 1;
255+
rehook_unhook(&REHPrepareGame);
256+
long ret = PrepareGame();
257+
warning("- PrepareGame done.\n");
258+
return ret;
259+
}
260+
249261
void patch_libyoyo(so_module *mod)
250262
{
251263
// Load all of the native symbols referenced
@@ -323,6 +335,11 @@ void patch_libyoyo(so_module *mod)
323335
// Depth disable
324336
FIND_SYMBOL(mod, surface_depth_disable, "_Z21F_SurfaceDepthDisableR6RValueP9CInstanceS2_iPS_");
325337

338+
// Hook the start of the game so we know setup is done
339+
ENSURE_SYMBOL(mod, PrepareGame, "_Z11PrepareGamev");
340+
rehook_new(mod, &REHPrepareGame, (uintptr_t)PrepareGame, (uintptr_t)&PrepareGame_hook);
341+
rehook_hook(&REHPrepareGame);
342+
326343
// Disable extension support
327344
FIND_SYMBOL(mod, Extension_Main_number, "Extension_Main_number");
328345
if (gmloader_config.disable_extensions == 1) {

gmloader/libyoyo.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -325,6 +325,7 @@ extern void **g_nYYCode;
325325
extern void **g_pGameFileBuffer;
326326
extern void **g_ppYYStackTrace;
327327
extern int *Extension_Main_number;
328+
extern ReentrantHook REHPrepareGame;
328329

329330
extern const char *gc_workdir;
330331
extern int relaunch_flag;

gmloader/main.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
int relaunch_flag = 0;
2121
char *program_name = nullptr;
2222
const char* gc_workdir = nullptr;
23+
bool override_apk = false;
2324

2425
/*
2526
Don't touch this incantation. It serves no practical
@@ -143,6 +144,7 @@ int main(int argc, char *argv[])
143144
// Apply apk_path override if provided
144145
if (!override_apk_path.empty()) {
145146
gmloader_config.apk_path = override_apk_path;
147+
override_apk = true;
146148
}
147149

148150
char platform_ov[32];

gmloader/texture.cpp

Lines changed: 29 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,8 @@ namespace fs = std::filesystem;
1818
int image_preload_idx = 0;
1919
int setup_ended = 0;
2020

21+
extern bool override_apk;
22+
2123
typedef struct pvrtc_file {
2224
uint32_t Version = 0x03525650;
2325
uint32_t Flags = 0;
@@ -50,7 +52,18 @@ void LoadTextureFromPNG_generic(void *arg1, int arg2, uint32_t *flags, uint32_t
5052
uint32_t idx = (data[1] << 8) >> 8;
5153

5254
// Load from APK first and then try the gamedir
53-
fs::path pvr_path = fs::path(gmloader_config.save_dir) / "textures" / (std::to_string(idx) + ".pvr");
55+
fs::path pvr_path;
56+
if (override_apk) {
57+
// Sanitize the apk path
58+
std::string tex_path = gmloader_config.apk_path;
59+
if (tex_path.rfind("assets/", 0) == 0) {
60+
tex_path = tex_path.substr(7); // Remove "assets/"
61+
}
62+
pvr_path = fs::path(gmloader_config.save_dir) / "textures" / tex_path / (std::to_string(idx) + ".pvr");
63+
}
64+
else {
65+
pvr_path = fs::path(gmloader_config.save_dir) / "textures" / (std::to_string(idx) + ".pvr");
66+
}
5467
int ret = io_load_file(pvr_path.c_str(), (void **)&ext_data, &ext_data_sz);
5568
if (ret != 1) {
5669
fatal_error("Failed to load '%s'!\n", pvr_path.c_str());
@@ -186,23 +199,28 @@ uint32_t png_get_IHDR_hook(struct png_struct *png_ptr, png_info *info_ptr, uint3
186199
*interlace_type = info_ptr->interlace_type;
187200

188201
if (!setup_ended && *width == 2 && *height == 1) {
189-
fs::path path = fs::path(gmloader_config.save_dir) / "textures" / (std::to_string(image_preload_idx) + ".pvr");
190-
uint32_t _sz;
191-
uint32_t *buffer;
192-
193-
*width = 0;
194-
*height = 0;
202+
fs::path path;
203+
if (override_apk) {
204+
// Sanitize the apk path
205+
std::string tex_path = gmloader_config.apk_path;
206+
if (tex_path.rfind("assets/", 0) == 0) {
207+
tex_path = tex_path.substr(7); // Remove "assets/"
208+
}
209+
path = fs::path(gmloader_config.save_dir) / "textures" / tex_path / (std::to_string(image_preload_idx) + ".pvr");
210+
}
211+
else {
212+
path = fs::path(gmloader_config.save_dir) / "textures" / (std::to_string(image_preload_idx) + ".pvr");
213+
}
195214

196215
FILE *f = fopen(path.c_str(), "rb");
197216
if (f) {
198217
fseek(f, 0x18, SEEK_SET);
199218
fread(height, 1, 4, f);
200219
fread(width, 1, 4, f);
201220
fclose(f);
202-
}
203-
204-
if (*width == 0 || *height == 0) {
205-
warning("Texture %d metadata preload failure.\n", image_preload_idx);
221+
} else {
222+
fatal_error("Texture %d metadata preload failure.\n", image_preload_idx);
223+
exit(-1);
206224
}
207225

208226
image_preload_idx++;

loader/so_util.cpp

Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -679,4 +679,25 @@ void hook_symbols(so_module *mod, DynLibHooks *hooks)
679679
for (int i = 0; hooks[i].symbol != NULL; i++) {
680680
hook_symbol(mod, hooks[i].symbol, hooks[i].hook, hooks[i].opt);
681681
}
682+
}
683+
684+
void rehook_new(so_module *mod, ReentrantHook *hook, uintptr_t addr, uintptr_t dst)
685+
{
686+
hook->addr = addr;
687+
memcpy(hook->prologue, (void *)addr, sizeof(hook->prologue));
688+
hook_address(mod, addr, dst);
689+
memcpy(hook->trampoline, (void *)addr, sizeof(hook->trampoline));
690+
rehook_unhook(hook);
691+
}
692+
693+
void rehook_hook(ReentrantHook *hook)
694+
{
695+
memcpy((void *)hook->addr, (void *)hook->trampoline, sizeof(hook->trampoline));
696+
__builtin___clear_cache((void *)hook->addr, (void *)hook->addr+sizeof(hook->trampoline));
697+
}
698+
699+
void rehook_unhook(ReentrantHook *hook)
700+
{
701+
memcpy((void *)hook->addr, (void *)hook->prologue, sizeof(hook->prologue));
702+
__builtin___clear_cache((void *)hook->addr, (void *)hook->addr+sizeof(hook->prologue));
682703
}

loader/so_util.h

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -111,9 +111,22 @@ typedef struct {
111111
int opt;
112112
} DynLibHooks;
113113

114+
/*
115+
Do you need a hook that does something and then goes back to doing the normal
116+
code path? Use this.
117+
*/
118+
typedef struct {
119+
uintptr_t addr;
120+
uint32_t prologue[4]; /* worst case scenario */
121+
uint32_t trampoline[4]; /* in case we want to re-hook it */
122+
} ReentrantHook;
123+
114124
void hook_address(so_module *mod, uintptr_t addr, uintptr_t dst);
115125
void hook_symbol(so_module *mod, const char *symbol, uintptr_t dst, int is_optional);
116126
void hook_symbols(so_module *mod, DynLibHooks *hooks);
127+
void rehook_new(so_module *mod, ReentrantHook *hook, uintptr_t addr, uintptr_t dst);
128+
void rehook_hook(ReentrantHook *hook);
129+
void rehook_unhook(ReentrantHook *hook);
117130

118131
int so_load(so_module *mod, const char *filename, uintptr_t load_addr, void *so_data, size_t sz);
119132
void so_relocate(so_module *mod);

0 commit comments

Comments
 (0)