Skip to content

Commit

Permalink
reintroduce hooking based input sampling
Browse files Browse the repository at this point in the history
  • Loading branch information
Kethen committed Apr 28, 2024
1 parent 6c96025 commit 67e6ec8
Showing 1 changed file with 83 additions and 3 deletions.
86 changes: 83 additions & 3 deletions main.c
Original file line number Diff line number Diff line change
Expand Up @@ -135,6 +135,80 @@ u32 offset_populate_car_analog_control = 0;
ptr = (void *)patch_buffer; \
}

// XXX ppsspp loading savestate reloads module imports and overwrites this kind of hooking in case HLE
// syscall changed
// https://github.com/hrydgard/ppsspp/blob/master/Core/HLE/sceKernelModule.cpp
// if this kind of hooking on ppsspp cannot be avoided, repatch in a slow thread loop maybe, at least peek
// can be used instead for this particular plugin

// jacking JR_SYSCALL in ppsspp, so just save the two instructions, instead of seeking the target
// also scan other modules for the same pattern and patch them if ppsspp
// for real hw, go the jump target then attempt the more standard two instructions hijack
// hopefully works with the static args loaded sceCtrl functions, at least referencing uofw and joysens
#define HIJACK_SYSCALL_STUB(a, f, ptr) \
{ \
LOG("hijacking syscall stub at 0x%lx with 0x%lx", (u32)a, (u32)f); \
u32 _func_ = (u32)a; \
LOG("original instructions: 0x%lx 0x%lx", _lw(_func_), _lw(_func_ + 4)); \
u32 pattern[2]; \
_sw(_lw(_func_), (u32)pattern); \
_sw(_lw(_func_ + 4), (u32)pattern + 4); \
u32 ff = (u32)f; \
if(!is_emulator){ \
_func_ = GET_JUMP_TARGET(_lw(_func_)); \
LOG("real hardware mode, retargetting function 0x%lx", _func_); \
LOG("original instructions: 0x%lx 0x%lx", _lw(_func_), _lw(_func_ + 4)); \
} \
static u32 patch_buffer[3]; \
if(is_emulator){ \
_sw(_lw(_func_), (u32)patch_buffer); \
_sw(_lw(_func_ + 4), (u32)patch_buffer + 4); \
}else{ \
_sw(_lw(_func_), (u32)patch_buffer); \
_sw(_lw(_func_ + 4), (u32)patch_buffer + 8); \
MAKE_JUMP((u32)patch_buffer + 4, _func_ + 8); \
} \
_sw(0x08000000 | (((u32)(ff) >> 2) & 0x03FFFFFF), _func_); \
_sw(0, _func_ + 4); \
ptr = (void *)patch_buffer; \
if(is_emulator){ \
SceUID modules[32]; \
SceKernelModuleInfo info; \
int i, count = 0; \
if (sceKernelGetModuleIdList(modules, sizeof(modules), &count) >= 0) { \
for (i = 0; i < count; i++) { \
info.size = sizeof(SceKernelModuleInfo); \
if (sceKernelQueryModuleInfo(modules[i], &info) < 0) { \
continue; \
} \
if (strcmp(info.name, MODULE_NAME) == 0) { \
continue; \
} \
LOG("scanning module %s in ppsspp mode", info.name); \
LOG("info.text_addr: 0x%x info.text_size: 0x%x info.nsegment: 0x%x", info.text_addr, info.text_size, (int)info.nsegment); \
u32 j; \
for(j = 0;j < info.nsegment; j++){ \
LOG("info.segmentaddr[%ld]: 0x%x info.segmentsize[%ld]: 0x%x", j, info.segmentaddr[j], j, info.segmentsize[j]); \
} \
if(info.text_size == 0){ \
if(info.nsegment >= 1 && info.segmentaddr[0] == info.text_addr){ \
info.text_size = info.segmentsize[0]; \
} \
} \
u32 k; \
for(k = 0; k < info.text_size; k+=4){ \
u32 addr = k + info.text_addr; \
if(/*_lw((u32)pattern) == _lw(addr + 0) &&*/ _lw((u32)pattern + 4) == _lw(addr + 4)){ \
LOG("found instruction pattern 0x%lx 0x%lx at 0x%lx, patching", pattern[0], pattern[1], addr); \
_sw(0x08000000 | (((u32)(ff) >> 2) & 0x03FFFFFF), addr); \
_sw(0, addr + 4); \
} \
} \
} \
} \
} \
}

static int get_disc_id_version(char *id_out, char *version_out){
char *sfo_path = "disc0:/PSP_GAME/PARAM.SFO";
int fd = sceIoOpen(sfo_path, PSP_O_RDONLY,0);
Expand Down Expand Up @@ -490,9 +564,11 @@ void populate_car_analog_control_patched(u32 param_1, int *param_2, unsigned cha

int k1 = pspSdkSetK1(0);

SceCtrlData pad_data;
int res = sceCtrlPeekBufferPositive(&pad_data, 1);
sample_input(&pad_data, res, 0);
if(is_emulator){
SceCtrlData pad_data;
int res = sceCtrlPeekBufferPositive(&pad_data, 1);
sample_input(&pad_data, res, 0);
}

int mode;
sceCtrlGetSamplingMode(&mode);
Expand Down Expand Up @@ -604,6 +680,10 @@ int init(){
//HIJACK_FUNCTION(offset_populate_car_digital_control, populate_car_digital_control_patched, populate_car_digital_control_orig);
HIJACK_FUNCTION(offset_populate_car_analog_control, populate_car_analog_control_patched, populate_car_analog_control_orig);

if(!is_emulator){
HIJACK_SYSCALL_STUB((u32)sceCtrlReadBufferPositive, sceCtrlReadBufferPositivePatched, sceCtrlReadBufferPositiveOrig);
}

sceKernelDcacheWritebackAll();
sceKernelIcacheClearAll();

Expand Down

0 comments on commit 67e6ec8

Please sign in to comment.