@ Patch by delebile .section .data.romfsRedirPatch, "aw", %progbits .align 4 .global romfsRedirPatch romfsRedirPatch: @ Jumps here before the fsOpenFileDirectly call _mountArchive: b mountArchive .global romfsRedirPatchSubstituted1 romfsRedirPatchSubstituted1: .word 0xdead0000 @ Substituted opcode .global romfsRedirPatchHook1 romfsRedirPatchHook1: .word 0xdead0001 @ Branch to hooked function @ Jumps here before every iFileOpen call _fsRedir: b fsRedir .global romfsRedirPatchSubstituted2 romfsRedirPatchSubstituted2: .word 0xdead0002 @ Substituted opcode .global romfsRedirPatchHook2 romfsRedirPatchHook2: .word 0xdead0003 @ Branch to hooked function @ Mounts the archive and registers it as 'lf:' mountArchive: cmp r3, #3 bne romfsRedirPatchSubstituted1 stmfd sp!, {r0-r4, lr} sub sp, sp, #4 ldr r1, romfsRedirPatchArchiveId mov r0, sp ldr r4, romfsRedirPatchFsMountArchive blx r4 mov r3, #0 mov r2, #0 ldr r1, [sp] adr r0, romfsRedirPatchArchiveName ldr r4, romfsRedirPatchFsRegisterArchive blx r4 add sp, sp, #4 ldmfd sp!, {r0-r4, lr} b romfsRedirPatchSubstituted1 @ Check the path passed to iFileOpen. @ If it is trying to access a RomFS file, we try to @ open it from the LayeredFS folder. @ If the file cannot be opened, we just open @ it from its original archive like nothing happened fsRedir: stmfd sp!, {r0-r12, lr} adr r3, romfsRedirPatchRomFsMount bl compare adrne r3, romfsRedirPatchUpdateRomFsMount blne compare bne endRedir sub sp, sp, #0x400 pathRedir: stmfd sp!, {r0-r3} add r0, sp, #0x10 ldr r3, romfsRedirPatchCustomPath pathRedir_1: ldrb r2, [r3], #1 cmp r2, #0 strneh r2, [r0], #2 bne pathRedir_1 pathRedir_2: ldrh r2, [r1], #2 cmp r2, #0x3A @ ':' bne pathRedir_2 @ Skip a slash if there are two after the mountpoint, @ as some games mistakenly have those ldrh r3, [r1, #2] cmp r3, #0x2F @ '/' pathRedir_3: ldrh r2, [r1], #2 strneh r2, [r0], #2 cmp r2, #0 bne pathRedir_3 ldmfd sp!, {r0-r3} mov r1, sp bl romfsRedirPatchSubstituted2 add sp, sp, #0x400 cmp r0, #0 endRedir: ldmfd sp!, {r0-r12, lr} moveq r0, #0 bxeq lr b romfsRedirPatchSubstituted2 compare: mov r9, r1 add r10, r3, #4 loop: ldrb r12, [r3], #1 ldrb r11, [r9], #2 cmp r11, r12 bxne lr cmp r10, r3 bne loop bx lr .pool .balign 4 .global romfsRedirPatchArchiveName .global romfsRedirPatchFsMountArchive .global romfsRedirPatchFsRegisterArchive .global romfsRedirPatchArchiveId .global romfsRedirPatchRomFsMount .global romfsRedirPatchUpdateRomFsMount .global romfsRedirPatchCustomPath romfsRedirPatchArchiveName : .ascii "lf:\0" romfsRedirPatchFsMountArchive : .word 0xdead0005 romfsRedirPatchFsRegisterArchive : .word 0xdead0006 romfsRedirPatchArchiveId : .word 0xdead0007 romfsRedirPatchRomFsMount : .ascii "rom:" romfsRedirPatchUpdateRomFsMount : .word 0xdead0008 romfsRedirPatchCustomPath : .word 0xdead0004 _romfsRedirPatchEnd: .global romfsRedirPatchSize romfsRedirPatchSize: .word _romfsRedirPatchEnd - romfsRedirPatch