How to disable buttons in game???

Discuss the development of new homebrew software, tools and libraries.

Moderators: cheriff, TyRaNiD

Post Reply
iceman755
Posts: 30
Joined: Mon Jul 21, 2008 1:12 am

How to disable buttons in game???

Post by iceman755 »

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: Select all

#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&#40;"test", 0x1000, 1, 0&#41;;

int printState=STATE_OFF;

int scePeekPositiveControl&#40;SceCtrlData *pad_data, int count&#41;
	&#123;
		int res = sceCtrlPeekBufferPositive&#40;pad_data, count&#41;;
	
		int k1 = pspSdkSetK1&#40;0&#41;;
   
		if &#40;pad_data->Buttons & PSP_CTRL_LTRIGGER&#41; 
			&#123;
				if&#40;printState==STATE_OFF&#41;
					printState=STATE_ON;
				else
					printState=STATE_OFF;			
			&#125;
	
		if&#40;printState==STATE_ON&#41;
			pad_data->Buttons=0;
		
		pspSdkSetK1&#40;k1&#41;;
   
		return res;
	&#125;

int sceReadPositiveControl&#40;SceCtrlData *pad_data, int count&#41;
	&#123;
		int res = sceCtrlReadBufferPositive&#40;pad_data, count&#41;;
	
		int k1 = pspSdkSetK1&#40;0&#41;;
   
		if &#40;pad_data->Buttons & PSP_CTRL_LTRIGGER&#41; 
			&#123;
				if&#40;printState==STATE_OFF&#41;
					printState=STATE_ON;
				else
					printState=STATE_OFF;			
			&#125;
	
		if&#40;printState==STATE_ON&#41;
			pad_data->Buttons=0;
		
		pspSdkSetK1&#40;k1&#41;;
   
		return res;
	&#125;

void display_thread&#40;SceSize args, void *argp&#41;
	&#123;
		while&#40;1&#41;
			&#123;
				if&#40;printState==STATE_ON&#41;
					&#123;
						blit_string&#40;0, 0, "Buttons Disabled", 0xffffff, 0x000000&#41;;
					&#125;
				sceKernelDelayThreadCB&#40;10&#41;;
			&#125;
	&#125;

int module_start&#40;SceSize args, void *argp&#41;
	&#123;	
		sctrlHENPatchSyscall&#40;sctrlHENFindFunction&#40;"sceController_Service", "sceCtrl", 0x3A622550&#41;,scePeekPositiveControl&#41;;;
		sctrlHENPatchSyscall&#40;sctrlHENFindFunction&#40;"sceController_Service", "sceCtrl", 0x1F803938&#41;,sceReadPositiveControl&#41;;;
	
		sceKernelDcacheWritebackAll&#40;&#41;;
		sceKernelIcacheClearAll&#40;&#41;;
	
		int display_thid = sceKernelCreateThread&#40;"mydisplay", display_thread, 1, 0x1000, 0, NULL&#41;;
		if&#40;display_thid >= 0&#41; sceKernelStartThread&#40;display_thid, args, argp&#41;;
   	
		return 0;
	&#125;
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: Select all

#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&#40;"hooktest", 0x1000, 1, 0&#41;;

int &#40;* vshCtrlReadBufferPositive&#41;&#40;SceCtrlData *pad_data, int count&#41;;

int printState=STATE_OFF;

void &#40;* PatchSyscall&#41;&#40;u32 funcaddr, void *newfunc&#41;;


int vshreadControl&#40;SceCtrlData *pad_data, int count&#41;
	&#123;
		int res = vshCtrlReadBufferPositive&#40;pad_data, count&#41;;
   
		int k1 = pspSdkSetK1&#40;0&#41;;
   
		if &#40;&#40;pad_data->Buttons & PSP_CTRL_LTRIGGER&#41; && &#40;pad_data->Buttons & PSP_CTRL_RTRIGGER&#41;&#41; 
			&#123;
				if&#40;printState==STATE_OFF&#41;
					printState=STATE_ON;
				else
					&#123;
						printState=STATE_OFF;
						pad_data->Buttons=0;
					&#125;
			&#125;
	
		if&#40;printState==STATE_ON&#41;
			pad_data->Buttons=0;
		
		pspSdkSetK1&#40;k1&#41;;
   
		return res;
	&#125;

STMOD_HANDLER previous = NULL;
u32 orgaddr;

int OnModuleStart&#40;SceModule2 *mod&#41;
	&#123;	
		if &#40;strcmp&#40;mod->modname, "sceVshBridge_Driver"&#41; == 0&#41;
			&#123;	
				orgaddr=sctrlHENFindFunction&#40;"sceVshBridge_Driver", "sceVshBridge", 0xC6395C03&#41;;
				vshCtrlReadBufferPositive = &#40;void *&#41;orgaddr;
				sctrlHENPatchSyscall&#40;orgaddr, vshreadControl&#41;;
	 
				sceKernelDcacheWritebackAll&#40;&#41;;
				sceKernelIcacheClearAll&#40;&#41;;
			&#125;
   
		if &#40;!previous&#41;
			return 0;
   
		return previous&#40;mod&#41;;
	&#125;

void display_thread&#40;SceSize args, void *argp&#41;
	&#123;
		while&#40;1&#41;
			&#123;
				if&#40;printState==STATE_ON&#41;
					blit_string&#40;0, 0, "Buttons Disabled", 0xffffff, 0x000000&#41;;
					
				sceKernelDelayThreadCB&#40;10&#41;;
			&#125;
	&#125;

int module_start&#40;SceSize args, void *argp&#41;
&#123;	
	
	previous = sctrlHENSetStartModuleHandler&#40;OnModuleStart&#41;;
		
	int display_thid = sceKernelCreateThread&#40;"mydisplay", display_thread, 1, 0x1000, 0, NULL&#41;;
	if&#40;display_thid >= 0&#41; 
		sceKernelStartThread&#40;display_thid, args, argp&#41;;
   	
   return 0;
&#125; 
This last piece of code is working.
"Libera eas de ore leonis, ne absorbeat eas tartarus, ne cadant in obscurum"
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

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: Select all

for &#40;int i=0; i<count; i++&#41;&#123;
      if &#40;pad_data&#91;i&#93;->Buttons & PSP_CTRL_LTRIGGER&#41;
         &#123;
            if&#40;printState==STATE_OFF&#41;
               printState=STATE_ON;
            else
               printState=STATE_OFF;         
         &#125;
   
      if&#40;printState==STATE_ON&#41;
         pad_data&#91;i&#93;->Buttons=0;
&#125;
vshCtrlReadBuffer positive is only used by the XMB for reading the Home/Volume and other kernel mode buttons. It's not used in games.
iceman755
Posts: 30
Joined: Mon Jul 21, 2008 1:12 am

Post by iceman755 »

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: Select all

#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&#40;"test", 0x1000, 1, 0&#41;;
PSP_MAIN_THREAD_ATTR&#40;0&#41;;

int printState=STATE_OFF;

int &#40;*sceCtrlPeekBufferPositiveORG&#41;&#40;pad_data, count&#41;;
int &#40;*sceCtrlPeekBufferNegativeORG&#41;&#40;pad_data, count&#41;;
int &#40;*sceCtrlReadBufferPositiveORG&#41;&#40;pad_data, count&#41;;
int &#40;*sceCtrlReadBufferNegativeORG&#41;&#40;pad_data, count&#41;;


int scePeekPositiveControl&#40;SceCtrlData *pad_data, int count&#41;
	&#123;
		int res = sceCtrlPeekBufferPositiveORG&#40;pad_data, count&#41;;
		int i;
		int intc = pspSdkDisableInterrupts&#40;&#41;;
		
		//for&#40;i=0;i<count;i++&#41;
			//&#123;
				if &#40;pad_data->Buttons & PSP_CTRL_LTRIGGER&#41;
					&#123;
						if&#40;printState==STATE_OFF&#41;
							printState=STATE_ON;
						else
							printState=STATE_OFF;         
					&#125;
				if&#40;printState==STATE_ON&#41;
					pad_data->Buttons=0;
			//&#125;
				
		pspSdkEnableInterrupts&#40;intc&#41;;
		
		return res;
	&#125;
	
int scePeekNegativeControl&#40;SceCtrlData *pad_data, int count&#41;
	&#123;
		int res = sceCtrlPeekBufferNegativeORG&#40;pad_data, count&#41;;
		int i;
		int intc = pspSdkDisableInterrupts&#40;&#41;;
		
		//for&#40;i=0;i<count;i++&#41;
			//&#123;
				if &#40;pad_data->Buttons & PSP_CTRL_LTRIGGER&#41;
					&#123;
						if&#40;printState==STATE_OFF&#41;
							printState=STATE_ON;
						else
							printState=STATE_OFF;         
					&#125;
				if&#40;printState==STATE_ON&#41;
					pad_data->Buttons=0;
			//&#125;
		
		pspSdkEnableInterrupts&#40;intc&#41;;
		
		return res;
	&#125;

int sceReadPositiveControl&#40;SceCtrlData *pad_data, int count&#41;
	&#123;
		int res = sceCtrlReadBufferPositiveORG&#40;pad_data, count&#41;;
		int i;
		int intc = pspSdkDisableInterrupts&#40;&#41;;
		
		//for&#40;i=0;i<count;i++&#41;
			//&#123;
				if &#40;pad_data->Buttons & PSP_CTRL_LTRIGGER&#41;
					&#123;
						if&#40;printState==STATE_OFF&#41;
							printState=STATE_ON;
						else
							printState=STATE_OFF;         
					&#125;
				if&#40;printState==STATE_ON&#41;
					pad_data->Buttons=0;
			//&#125;
		
		pspSdkEnableInterrupts&#40;intc&#41;;
		
		return res;
	&#125;
	
int sceReadNegativeControl&#40;SceCtrlData *pad_data, int count&#41;
	&#123;
		int res = sceCtrlReadBufferNegativeORG&#40;pad_data, count&#41;;
		int i;
		int intc = pspSdkDisableInterrupts&#40;&#41;;
		
		//for&#40;i=0;i<count;i++&#41;
			//&#123;
				if &#40;pad_data->Buttons & PSP_CTRL_LTRIGGER&#41;
					&#123;
						if&#40;printState==STATE_OFF&#41;
							printState=STATE_ON;
						else
							printState=STATE_OFF;         
					&#125;
				if&#40;printState==STATE_ON&#41;
					pad_data->Buttons=0;
			//&#125;
		
		pspSdkEnableInterrupts&#40;intc&#41;;
		
		return res;
	&#125;

void display_thread&#40;SceSize args, void *argp&#41;
	&#123;
		while&#40;1&#41;
			&#123;
				if&#40;printState==STATE_ON&#41;
					&#123;
						blit_string&#40;0, 0, "Controls&#58; disable", 0xffffff, 0x000000&#41;;
					&#125;
				else
					&#123;
						blit_string&#40;0, 0, "Controls&#58; enable", 0xffffff, 0x000000&#41;;
					&#125;
					
				sceKernelDelayThread&#40;0x18&#41;;
			&#125;
	&#125;

int module_start&#40;SceSize args, void *argp&#41;
	&#123;	
		sceCtrlPeekBufferPositiveORG=sctrlHENFindFunction&#40;"sceController_Service", "sceCtrl", 0x3A622550&#41;;
		sceCtrlPeekBufferNegativeORG=sctrlHENFindFunction&#40;"sceController_Service", "sceCtrl", 0xC152080A&#41;;
		sceCtrlReadBufferPositiveORG=sctrlHENFindFunction&#40;"sceController_Service", "sceCtrl", 0x1F803938&#41;;
		sceCtrlReadBufferNegativeORG=sctrlHENFindFunction&#40;"sceController_Service", "sceCtrl", 0x60B81F86&#41;;
		
		sctrlHENPatchSyscall&#40;sceCtrlPeekBufferPositiveORG,scePeekPositiveControl&#41;;
		sctrlHENPatchSyscall&#40;sceCtrlPeekBufferNegativeORG,scePeekNegativeControl&#41;;
		sctrlHENPatchSyscall&#40;sceCtrlReadBufferPositiveORG,sceReadPositiveControl&#41;;
		sctrlHENPatchSyscall&#40;sceCtrlReadBufferNegativeORG,sceReadNegativeControl&#41;;
	
		sceKernelDcacheWritebackAll&#40;&#41;;
		sceKernelIcacheClearAll&#40;&#41;;
	
		int display_thid = sceKernelCreateThread&#40;"mydisplay", display_thread, 1, 0x1000, 0, NULL&#41;;
		if&#40;display_thid >= 0&#41; sceKernelStartThread&#40;display_thid, args, argp&#41;;
   	
		return 0;
	&#125; 
"Libera eas de ore leonis, ne absorbeat eas tartarus, ne cadant in obscurum"
User avatar
Torch
Posts: 825
Joined: Wed May 28, 2008 2:50 am

Post by Torch »

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: Select all

while &#40;sceKernelFindModuleByName&#40;"sceController_Service"&#41; == NULL&#41;
&#123;
    sceKernelDelayThread&#40;20&#41;;
&#125;
DON'T do this in module_start though. Create a thread and wait in the thread.

Or you can use sctrlHENStartModuleHandler.
Post Reply