 |
forums.ps2dev.org Homebrew PS2, PSP & PS3 Development Discussions
|
| View previous topic :: View next topic |
| Author |
Message |
iceman755
Joined: 21 Jul 2008 Posts: 34
|
Posted: Tue Jun 16, 2009 2:56 am Post subject: How to disable buttons in game??? |
|
|
Since a few days I'm "flirting" with hooking the controls function, I have disable the buttons in the vsh, but no matter how I try, I cannot do it when inside a game.
I was looking the remapsp source and I figured out that I have to patch differents functions than the vshCtrlReadBufferPositive to disable the buttons in game, the functions are (to do what I want to do):
sceCtrlPeekBufferPositive
sceCtrlReadBufferPositive
Is it correct???
Supposing it is, how can this be achieve??? because I have tried various ways to do it.
Basically what I do is this:
| Code: | #include <pspsdk.h>
#include <pspkernel.h>
#include <pspctrl.h>
#include <psppower.h>
#include <systemctrl.h>
#include <stdio.h>
#include "blit.h"
#define STATE_OFF 0
#define STATE_ON 1
PSP_MODULE_INFO("test", 0x1000, 1, 0);
int printState=STATE_OFF;
int scePeekPositiveControl(SceCtrlData *pad_data, int count)
{
int res = sceCtrlPeekBufferPositive(pad_data, count);
int k1 = pspSdkSetK1(0);
if (pad_data->Buttons & PSP_CTRL_LTRIGGER)
{
if(printState==STATE_OFF)
printState=STATE_ON;
else
printState=STATE_OFF;
}
if(printState==STATE_ON)
pad_data->Buttons=0;
pspSdkSetK1(k1);
return res;
}
int sceReadPositiveControl(SceCtrlData *pad_data, int count)
{
int res = sceCtrlReadBufferPositive(pad_data, count);
int k1 = pspSdkSetK1(0);
if (pad_data->Buttons & PSP_CTRL_LTRIGGER)
{
if(printState==STATE_OFF)
printState=STATE_ON;
else
printState=STATE_OFF;
}
if(printState==STATE_ON)
pad_data->Buttons=0;
pspSdkSetK1(k1);
return res;
}
void display_thread(SceSize args, void *argp)
{
while(1)
{
if(printState==STATE_ON)
{
blit_string(0, 0, "Buttons Disabled", 0xffffff, 0x000000);
}
sceKernelDelayThreadCB(10);
}
}
int module_start(SceSize args, void *argp)
{
sctrlHENPatchSyscall(sctrlHENFindFunction("sceController_Service", "sceCtrl", 0x3A622550),scePeekPositiveControl);;
sctrlHENPatchSyscall(sctrlHENFindFunction("sceController_Service", "sceCtrl", 0x1F803938),sceReadPositiveControl);;
sceKernelDcacheWritebackAll();
sceKernelIcacheClearAll();
int display_thid = sceKernelCreateThread("mydisplay", display_thread, 1, 0x1000, 0, NULL);
if(display_thid >= 0) sceKernelStartThread(display_thid, args, argp);
return 0;
} |
Obviously this is not working, the psp crash when starting a game. I don't going to put the mix of the try with the vsh hooking code, cause is a mess. But here is the code for the vshCtrlReadBufferPositive hooking:
| Code: |
#include <pspsdk.h>
#include <pspkernel.h>
#include <pspctrl.h>
#include <psppower.h>
#include <systemctrl.h>
#include <stdio.h>
#include <string.h>
#include "blit.h"
#define STATE_OFF 0
#define STATE_ON 1
PSP_MODULE_INFO("hooktest", 0x1000, 1, 0);
int (* vshCtrlReadBufferPositive)(SceCtrlData *pad_data, int count);
int printState=STATE_OFF;
void (* PatchSyscall)(u32 funcaddr, void *newfunc);
int vshreadControl(SceCtrlData *pad_data, int count)
{
int res = vshCtrlReadBufferPositive(pad_data, count);
int k1 = pspSdkSetK1(0);
if ((pad_data->Buttons & PSP_CTRL_LTRIGGER) && (pad_data->Buttons & PSP_CTRL_RTRIGGER))
{
if(printState==STATE_OFF)
printState=STATE_ON;
else
{
printState=STATE_OFF;
pad_data->Buttons=0;
}
}
if(printState==STATE_ON)
pad_data->Buttons=0;
pspSdkSetK1(k1);
return res;
}
STMOD_HANDLER previous = NULL;
u32 orgaddr;
int OnModuleStart(SceModule2 *mod)
{
if (strcmp(mod->modname, "sceVshBridge_Driver") == 0)
{
orgaddr=sctrlHENFindFunction("sceVshBridge_Driver", "sceVshBridge", 0xC6395C03);
vshCtrlReadBufferPositive = (void *)orgaddr;
sctrlHENPatchSyscall(orgaddr, vshreadControl);
sceKernelDcacheWritebackAll();
sceKernelIcacheClearAll();
}
if (!previous)
return 0;
return previous(mod);
}
void display_thread(SceSize args, void *argp)
{
while(1)
{
if(printState==STATE_ON)
blit_string(0, 0, "Buttons Disabled", 0xffffff, 0x000000);
sceKernelDelayThreadCB(10);
}
}
int module_start(SceSize args, void *argp)
{
previous = sctrlHENSetStartModuleHandler(OnModuleStart);
int display_thid = sceKernelCreateThread("mydisplay", display_thread, 1, 0x1000, 0, NULL);
if(display_thid >= 0)
sceKernelStartThread(display_thid, args, argp);
return 0;
} |
This last piece of code is working. _________________ "Libera eas de ore leonis, ne absorbeat eas tartarus, ne cadant in obscurum" |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Tue Jun 16, 2009 11:01 pm Post subject: |
|
|
The priority of 1 maybe too high, causing it to freeze, even though you have a sceKernelDelayThreadCB(10). Try making it 0x18 or something. And the CB variant is unnecessary as you haven't registered any callbacks.
You should hook sceCtrlReadBufferPositive/Negative too as they are the ones most commonly used.
There is a small error in the function hook. *pad_data is an array of pointers to structures. You have to loop through each of them for i=0 to count. There is no need to set K1 over here either. It might be safer to disable interrupts though.
| Code: | for (int i=0; i<count; i++){
if (pad_data[i]->Buttons & PSP_CTRL_LTRIGGER)
{
if(printState==STATE_OFF)
printState=STATE_ON;
else
printState=STATE_OFF;
}
if(printState==STATE_ON)
pad_data[i]->Buttons=0;
} |
vshCtrlReadBuffer positive is only used by the XMB for reading the Home/Volume and other kernel mode buttons. It's not used in games. |
|
| Back to top |
|
 |
iceman755
Joined: 21 Jul 2008 Posts: 34
|
Posted: Wed Jun 17, 2009 6:15 am Post subject: |
|
|
Thanks for taking your valuable time to help XD
I think I've done what you told me that I need to fix, but I skip the loop through pad_data, becasue it was acting very eery, it never reenable the buttons unless I keep press the Ltrigger (wich is the disable/enable button).
It keep crashing until I add prototypes for the functions to hook to, to figured out this I saw the code from the user Maku on this post: http://forums.ps2dev.org/viewtopic.php?t=12102
The hook is working, but I have a question, these functions can be hooked any time during the start of the psp, or I have to wait the load of an especific module??? I know that I don't need to hook these functions in the VSH, I'm asking because I want to do it all in one prx, anyway I'm going to prove it and see what the results are.
Thanks again XDDD
The code for disable the buttons that I have so far:
| Code: | #include <pspsdk.h>
#include <pspkernel.h>
#include <pspctrl.h>
#include <psppower.h>
#include <systemctrl.h>
#include <stdio.h>
#include "blit.h"
#define STATE_OFF 0
#define STATE_ON 1
PSP_MODULE_INFO("test", 0x1000, 1, 0);
PSP_MAIN_THREAD_ATTR(0);
int printState=STATE_OFF;
int (*sceCtrlPeekBufferPositiveORG)(pad_data, count);
int (*sceCtrlPeekBufferNegativeORG)(pad_data, count);
int (*sceCtrlReadBufferPositiveORG)(pad_data, count);
int (*sceCtrlReadBufferNegativeORG)(pad_data, count);
int scePeekPositiveControl(SceCtrlData *pad_data, int count)
{
int res = sceCtrlPeekBufferPositiveORG(pad_data, count);
int i;
int intc = pspSdkDisableInterrupts();
//for(i=0;i<count;i++)
//{
if (pad_data->Buttons & PSP_CTRL_LTRIGGER)
{
if(printState==STATE_OFF)
printState=STATE_ON;
else
printState=STATE_OFF;
}
if(printState==STATE_ON)
pad_data->Buttons=0;
//}
pspSdkEnableInterrupts(intc);
return res;
}
int scePeekNegativeControl(SceCtrlData *pad_data, int count)
{
int res = sceCtrlPeekBufferNegativeORG(pad_data, count);
int i;
int intc = pspSdkDisableInterrupts();
//for(i=0;i<count;i++)
//{
if (pad_data->Buttons & PSP_CTRL_LTRIGGER)
{
if(printState==STATE_OFF)
printState=STATE_ON;
else
printState=STATE_OFF;
}
if(printState==STATE_ON)
pad_data->Buttons=0;
//}
pspSdkEnableInterrupts(intc);
return res;
}
int sceReadPositiveControl(SceCtrlData *pad_data, int count)
{
int res = sceCtrlReadBufferPositiveORG(pad_data, count);
int i;
int intc = pspSdkDisableInterrupts();
//for(i=0;i<count;i++)
//{
if (pad_data->Buttons & PSP_CTRL_LTRIGGER)
{
if(printState==STATE_OFF)
printState=STATE_ON;
else
printState=STATE_OFF;
}
if(printState==STATE_ON)
pad_data->Buttons=0;
//}
pspSdkEnableInterrupts(intc);
return res;
}
int sceReadNegativeControl(SceCtrlData *pad_data, int count)
{
int res = sceCtrlReadBufferNegativeORG(pad_data, count);
int i;
int intc = pspSdkDisableInterrupts();
//for(i=0;i<count;i++)
//{
if (pad_data->Buttons & PSP_CTRL_LTRIGGER)
{
if(printState==STATE_OFF)
printState=STATE_ON;
else
printState=STATE_OFF;
}
if(printState==STATE_ON)
pad_data->Buttons=0;
//}
pspSdkEnableInterrupts(intc);
return res;
}
void display_thread(SceSize args, void *argp)
{
while(1)
{
if(printState==STATE_ON)
{
blit_string(0, 0, "Controls: disable", 0xffffff, 0x000000);
}
else
{
blit_string(0, 0, "Controls: enable", 0xffffff, 0x000000);
}
sceKernelDelayThread(0x18);
}
}
int module_start(SceSize args, void *argp)
{
sceCtrlPeekBufferPositiveORG=sctrlHENFindFunction("sceController_Service", "sceCtrl", 0x3A622550);
sceCtrlPeekBufferNegativeORG=sctrlHENFindFunction("sceController_Service", "sceCtrl", 0xC152080A);
sceCtrlReadBufferPositiveORG=sctrlHENFindFunction("sceController_Service", "sceCtrl", 0x1F803938);
sceCtrlReadBufferNegativeORG=sctrlHENFindFunction("sceController_Service", "sceCtrl", 0x60B81F86);
sctrlHENPatchSyscall(sceCtrlPeekBufferPositiveORG,scePeekPositiveControl);
sctrlHENPatchSyscall(sceCtrlPeekBufferNegativeORG,scePeekNegativeControl);
sctrlHENPatchSyscall(sceCtrlReadBufferPositiveORG,sceReadPositiveControl);
sctrlHENPatchSyscall(sceCtrlReadBufferNegativeORG,sceReadNegativeControl);
sceKernelDcacheWritebackAll();
sceKernelIcacheClearAll();
int display_thid = sceKernelCreateThread("mydisplay", display_thread, 1, 0x1000, 0, NULL);
if(display_thid >= 0) sceKernelStartThread(display_thid, args, argp);
return 0;
} |
_________________ "Libera eas de ore leonis, ne absorbeat eas tartarus, ne cadant in obscurum" |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Wed Jun 17, 2009 3:33 pm Post subject: |
|
|
| iceman755 wrote: |
The hook is working, but I have a question, these functions can be hooked any time during the start of the psp, or I have to wait the load of an especific module??? |
You must wait until ctrl.prx (sceController_Service) is loaded first. You can either use
| Code: | while (sceKernelFindModuleByName("sceController_Service") == NULL)
{
sceKernelDelayThread(20);
} |
DON'T do this in module_start though. Create a thread and wait in the thread.
Or you can use sctrlHENStartModuleHandler. |
|
| Back to top |
|
 |
|
|
You cannot post new topics in this forum You cannot reply to topics in this forum You cannot edit your posts in this forum You cannot delete your posts in this forum You cannot vote in polls in this forum
|
Powered by phpBB © 2001, 2005 phpBB Group
|