| View previous topic :: View next topic |
| Author |
Message |
hotter

Joined: 07 Dec 2008 Posts: 53
|
Posted: Wed Dec 24, 2008 2:23 am Post subject: disable buttons in XMB menu |
|
|
I am making a prx plugin and I want to disable psp buttons in XMB menu (like the VSH menu), they would work just in my prx plugin. How to do that? _________________ Pragramming with:
Microsoft Visual C 2008 + pspsdk MINPSPW 0.8.10 |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Wed Dec 24, 2008 3:47 pm Post subject: |
|
|
It calls vshCtrlReadBufferPositive. It can be hooked with a syscall patch. Or by patching the import call directly. Syscall patch is easier.
There are probably other methods but the advantage of hooking this function is that you can use the value it returns to detect key presses for your plugin. The XMB will call it continuously, so just use the pad data from the call, and make it zero after you're done so that the XMB will not respond to buttons. Your plugin will not have the overhead of its own button reading loop. |
|
| Back to top |
|
 |
hotter

Joined: 07 Dec 2008 Posts: 53
|
Posted: Wed Dec 24, 2008 7:36 pm Post subject: |
|
|
calling sceCtrlReadBufferPositive doesnt help when I call another function, for example delete file. Buttons works in XMB menu because delete file function take too long time... :( _________________ Pragramming with:
Microsoft Visual C 2008 + pspsdk MINPSPW 0.8.10 |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Wed Dec 24, 2008 11:22 pm Post subject: |
|
|
| hotter wrote: | | calling sceCtrlReadBufferPositive doesnt help when I call another function, for example delete file. Buttons works in XMB menu because delete file function take too long time... :( |
Don't call the function! I mean that the XMB calls vshCtrlReadBufferPositive to read buttons. If you hook that function, and make the paddata parameter 0 it will not receive any button presses. And you can use the value before you make it zero in your own program to read the buttons instead of having a separate sceCtrlReadBufferPositive.
Learn how to hook functions with syscall patch. Look at iop.prx source. |
|
| Back to top |
|
 |
KickinAezz
Joined: 03 Jun 2007 Posts: 328
|
Posted: Thu Dec 25, 2008 12:43 am Post subject: |
|
|
Simply use sceCtrlReadBufferPositive in the main loop it will disable XMB entirely until you switch back to sceCtrlPeekBufferPositive. (I remember when I did this long back... but it should work) _________________ Intrigued by PSP system Since December 2006.
Use it more for Development than for Gaming. |
|
| Back to top |
|
 |
NoEffex
Joined: 27 Nov 2008 Posts: 108
|
Posted: Thu Dec 25, 2008 2:14 am Post subject: |
|
|
void buttons_Set(void)
{
sceCtrlSetButtonMasks(0xFFFF, 1);
sceCtrlSetButtonMasks(0x10000, 2);
return;
}
void buttons_unSet(void)
{
sceCtrlSetButtonMasks(0x10000, 0);
sceCtrlSetButtonMasks(0xFFFF, 0);
return;
}
Set makes it so your proggy has access, unset sets it back. |
|
| Back to top |
|
 |
hotter

Joined: 07 Dec 2008 Posts: 53
|
Posted: Thu Dec 25, 2008 5:16 am Post subject: |
|
|
| NoEffex wrote: | void buttons_Set(void)
{
sceCtrlSetButtonMasks(0xFFFF, 1);
sceCtrlSetButtonMasks(0x10000, 2);
return;
}
void buttons_unSet(void)
{
sceCtrlSetButtonMasks(0x10000, 0);
sceCtrlSetButtonMasks(0xFFFF, 0);
return;
}
Set makes it so your proggy has access, unset sets it back. |
well I guess I need to include something like: #include <pspctrl_kernel.h>
but I get error:
main.c:(.text+0x4f8): undefined reference to `sceCtrl_driver_7CA723DC'
Do I need to add something in makefile? _________________ Pragramming with:
Microsoft Visual C 2008 + pspsdk MINPSPW 0.8.10 |
|
| Back to top |
|
 |
NoEffex
Joined: 27 Nov 2008 Posts: 108
|
Posted: Thu Dec 25, 2008 5:53 am Post subject: |
|
|
| Is your prx in user or kernel mode? |
|
| Back to top |
|
 |
hotter

Joined: 07 Dec 2008 Posts: 53
|
Posted: Thu Dec 25, 2008 6:04 am Post subject: |
|
|
I guess it is in kernel mode _________________ Pragramming with:
Microsoft Visual C 2008 + pspsdk MINPSPW 0.8.10 |
|
| Back to top |
|
 |
NoEffex
Joined: 27 Nov 2008 Posts: 108
|
Posted: Thu Dec 25, 2008 7:39 am Post subject: |
|
|
I mean, are you using kernel libs?
ex. in makefile
USE_KERNEL_LIBS=1
USE_KERNEL_LIBC=1
generally indicates kernel prx
I think the button mask is kernel-only, as I use it on several prx's, which are all kernel-mode. |
|
| Back to top |
|
 |
hotter

Joined: 07 Dec 2008 Posts: 53
|
Posted: Thu Dec 25, 2008 9:34 am Post subject: |
|
|
no I dont use these because I cant printf after these... _________________ Pragramming with:
Microsoft Visual C 2008 + pspsdk MINPSPW 0.8.10 |
|
| Back to top |
|
 |
NoEffex
Joined: 27 Nov 2008 Posts: 108
|
Posted: Thu Dec 25, 2008 9:47 am Post subject: |
|
|
pspDebugScreenKprintf
or
#define printf(...) { char buf[256]; sprintf(buf,__VA_ARGS__); pspDebugScreenPuts( buf ); } _________________ Programming with:
Geany + Latest PSPSDK from svn |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Thu Dec 25, 2008 12:51 pm Post subject: |
|
|
| KickinAezz wrote: | | Simply use sceCtrlReadBufferPositive in the main loop it will disable XMB entirely until you switch back to sceCtrlPeekBufferPositive. (I remember when I did this long back... but it should work) |
That doesn't work reliably for everyone. If your loop is not 60 calls per second it will still receive button presses. I use sceCtrlReadBufferPositive in some older plugins and XMB still works. |
|
| Back to top |
|
 |
hotter

Joined: 07 Dec 2008 Posts: 53
|
Posted: Thu Dec 25, 2008 10:39 pm Post subject: |
|
|
where could I find tutorials or something like that to make prx in XMB menu?
Would be cool to see VSHmenu source code :D _________________ Pragramming with:
Microsoft Visual C 2008 + pspsdk MINPSPW 0.8.10 |
|
| Back to top |
|
 |
NoEffex
Joined: 27 Nov 2008 Posts: 108
|
Posted: Fri Dec 26, 2008 7:53 am Post subject: |
|
|
Not sure about the opacity but it looks like it uses the basic debug library, consisting of
pspDebugScreenSetXY(w/e, w/e);
pspDebugScreenSetBackColor(Whatever);
pspDebugScreenSetTextColor(Whatever);
pspDebugScreenPuts("M33 Vshmenu");
and so on. _________________ Programming with:
Geany + Latest PSPSDK from svn |
|
| Back to top |
|
 |
hotter

Joined: 07 Dec 2008 Posts: 53
|
Posted: Sun Dec 28, 2008 12:59 am Post subject: |
|
|
| Torch wrote: |
Learn how to hook functions with syscall patch. Look at iop.prx source. |
where could i find iop.prx source? _________________ Pragramming with:
Microsoft Visual C 2008 + pspsdk MINPSPW 0.8.10 |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
|
| Back to top |
|
 |
hotter

Joined: 07 Dec 2008 Posts: 53
|
Posted: Tue Dec 30, 2008 9:12 pm Post subject: |
|
|
well I tried my best and that is what I get:
| Code: |
//...
int vshReadButtons(SceCtrlData *pad_data, int count)
{
int k1 = pspSdkSetK1(0);
int level = sctrlKernelSetUserLevel(8);
sceCtrlReadBufferPositive(&pad, 1);
sctrlKernelSetUserLevel(level);
pspSdkSetK1(k1);
return 0;
}
int module_start(SceSize args, void *argp)
{
PatchSyscall = (void *)sctrlHENFindFunction("SystemControl", "SystemCtrlForKernel", 0x826668E9);
if (!PatchSyscall)
{
PatchSyscall = (void *)sctrlHENFindFunction("SystemControl", "SystemCtrlForKernel", 0x02BFCB5F);
if (!PatchSyscall)
{
asm("break\n");
return 1;
}
}
orgaddr=sctrlHENFindFunction("vshCtrlReadBufferPositive", "Idontknowwhattowritehere", 0xC6395C03);
PatchSyscall(orgaddr, vshReadButtons);
sceKernelDcacheWritebackAll();
sceKernelIcacheClearAll();
//...
return 0;
}
//...
|
But it doesnt work, could you help? _________________ Pragramming with:
Microsoft Visual C 2008 + pspsdk MINPSPW 0.8.10 |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Tue Dec 30, 2008 9:50 pm Post subject: |
|
|
| Code: |
//...
int (* vshCtrlReadBufferPositive)(SceCtrlData *pad_data, int count);
int vshReadButtons(SceCtrlData *pad_data, int count)
{
int ret, intc;
ret = vshCtrlReadBufferPositive(pad_data, count);
if(ret <= 0)
{
return ret;
}
intc = pspSdkDisableInterrupts();
//your program's button handling goes here. this function will be called automatically by the xmb.
if (pad_data.Buttons & PSP_CTRL_CIRCLE) //etc
{
//do your stuff for the buttons
}
//zero it after use so xmb will not respond
pad_data.Buttons = 0;
pspSdkEnableInterrupts(intc);
return ret;
}
int module_start(SceSize args, void *argp)
{
PatchSyscall = (void *)sctrlHENFindFunction("SystemControl", "SystemCtrlForKernel", 0x826668E9);
if (!PatchSyscall)
{
PatchSyscall = (void *)sctrlHENFindFunction("SystemControl", "SystemCtrlForKernel", 0x02BFCB5F);
if (!PatchSyscall)
{
asm("break\n");
return 1;
}
}
orgaddr=sctrlHENFindFunction("sceVshBridge_Driver", "sceVshBridge", 0xC6395C03);
vshCtrlReadBufferPositive = (void *)orgaddr;
PatchSyscall(orgaddr, vshReadButtons);
sceKernelDcacheWritebackAll();
sceKernelIcacheClearAll();
//...
return 0;
}
//...
|
This method will not increase CPU usage a lot because there needn't be a main loop to read the controls.
Also this method will not break the M33 VSHMenu. If VSHMenu is opened, your plugin will not receive input until the VSHMenu is closed. |
|
| Back to top |
|
 |
hotter

Joined: 07 Dec 2008 Posts: 53
|
Posted: Wed Dec 31, 2008 1:45 am Post subject: |
|
|
well with some changes this code compiles but on psp it still dont work :(
It looks like function havent been patched because XMB still recave buttons ant my functions doesnt get buttons pressed.
It should disable XMB buttons from startup if I add prx to seplugins\vsh.txt and enable it, yes?
what could be wrong? :( _________________ Pragramming with:
Microsoft Visual C 2008 + pspsdk MINPSPW 0.8.10 |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Wed Dec 31, 2008 3:34 am Post subject: |
|
|
You should wait for vshbridge to load before hooking.
| Code: |
//globals
int OnModuleStart(SceModule2 *mod);
STMOD_HANDLER previous = NULL;
...
...
int OnModuleStart(SceModule2 *mod)
{
if (strcmp(mod->modname, "sceVshBridge_Driver") == 0)
{
orgaddr=sctrlHENFindFunction("sceVshBridge_Driver", "sceVshBridge", 0xC6395C03);
vshCtrlReadBufferPositive = (void *)orgaddr;
PatchSyscall(orgaddr, vshReadButtons);
sceKernelDcacheWritebackAll();
sceKernelIcacheClearAll();
}
if (!previous)
return 0;
return previous(mod);
}
int module_start(SceSize args, void *argp)
{
PatchSyscall = (void *)sctrlHENFindFunction("SystemControl", "SystemCtrlForKernel", 0x826668E9);
if (!PatchSyscall)
{
PatchSyscall = (void *)sctrlHENFindFunction("SystemControl", "SystemCtrlForKernel", 0x02BFCB5F);
if (!PatchSyscall)
{
asm("break\n");
return 1;
}
}
sceKernelDcacheWritebackAll();
sceKernelIcacheClearAll();
previous = sctrlHENSetStartModuleHandler(OnModuleStart); //add this
//...
return 0;
}
|
|
|
| Back to top |
|
 |
hotter

Joined: 07 Dec 2008 Posts: 53
|
Posted: Wed Dec 31, 2008 5:13 am Post subject: |
|
|
well now it disables buttons on start up but my program dont get them but I still trying to make it work.
I guess I need to include something because I get error:
error: expected '=', ',', ';', 'asm' or '__attribute__' before 'previous'
on this line:
STMOD_HANDLER previous = NULL; _________________ Pragramming with:
Microsoft Visual C 2008 + pspsdk MINPSPW 0.8.10 |
|
| Back to top |
|
 |
ne0h
Joined: 21 Feb 2008 Posts: 386
|
Posted: Wed Dec 31, 2008 5:43 am Post subject: |
|
|
Look at the header...
There's something wrong... _________________ Get Xplora! |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Wed Dec 31, 2008 3:15 pm Post subject: |
|
|
Its in one of these headers:
#include <pspsdk.h>
#include <pspctrl.h>
#include <pspkernel.h>
#include <systemctrl.h>
Extract the latest M33SDK into your includes and libs. |
|
| Back to top |
|
 |
hotter

Joined: 07 Dec 2008 Posts: 53
|
Posted: Wed Jan 07, 2009 7:08 am Post subject: |
|
|
I searched but I didnt find M33SDK... What if I will remove that variable?
This is edited code:
| Code: |
void (* PatchSyscall)(u32 funcaddr, void *newfunc);
int (* vshCtrlReadBufferPositive)(SceCtrlData *pad_data, int count);
int OnModuleStart(SceModule2 *mod);
u32 orgaddr;
SceCtrlData pad;
int vshReadButtons(SceCtrlData *pad_data, int count)
{
int ret, intc;
ret = vshCtrlReadBufferPositive(pad_data, count);
if(ret <= 0)
{
return ret;
}
intc = pspSdkDisableInterrupts();
pad = *pad_data;
if (pad.Buttons & PSP_CTRL_CIRCLE)
{
//my menu on/off
if(a == 0){ a = 1; }
else{ a = 0; }
}
//if my menu on block buttons
if(a == 1)
{
pad.Buttons = 0;
}
pad_data = &pad;
pspSdkEnableInterrupts(intc);
return ret;
}
int OnModuleStart(SceModule2 *mod)
{
if (strcmp(mod->modname, "sceVshBridge_Driver") == 0)
{
orgaddr=sctrlHENFindFunction("sceVshBridge_Driver", "sceVshBridge", 0xC6395C03);
vshCtrlReadBufferPositive = (void *)orgaddr;
PatchSyscall(orgaddr, vshReadButtons);
sceKernelDcacheWritebackAll();
sceKernelIcacheClearAll();
}
}
int module_start(SceSize args, void *argp)
{
PatchSyscall = (void *)sctrlHENFindFunction("SystemControl", "SystemCtrlForKernel", 0x826668E9);
if (!PatchSyscall)
{
PatchSyscall = (void *)sctrlHENFindFunction("SystemControl", "SystemCtrlForKernel", 0x02BFCB5F);
if (!PatchSyscall)
{
asm("break\n");
return 1;
}
}
sceKernelDcacheWritebackAll();
sceKernelIcacheClearAll();
sctrlHENSetStartModuleHandler(OnModuleStart);
//...
return 0;
}
int module_stop(SceSize args, void *argp)
{
PatchSyscall((u32)vshReadButtons, (void *)orgaddr);
sceKernelDcacheWritebackAll();
sceKernelIcacheClearAll();
return 0;
}
|
My program compiles. My functions gets buttons pushed but when I need to disable XMB menu buttons they are not disabled :( I guess I am doing something wrong in vshReadButtons function no? _________________ Pragramming with:
Microsoft Visual C 2008 + pspsdk MINPSPW 0.8.10 |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Wed Jan 07, 2009 12:37 pm Post subject: |
|
|
You should directly use the value in pad_data. Since its a pointer, referencing it like the first element of an array pad_data[0] will give you the actual value.
You MUST include the previous pointer or it will break other plugins that hook module start, and possibly break M33 patches. The M33SDK comes in the 4.01M33 package.
| Code: | STMOD_HANDLER previous = NULL;
...
...
int OnModuleStart(SceModule2 *mod)
{
...
...
if (!previous)
return 0;
return previous(mod);
}
|
| Code: | int vshReadButtons(SceCtrlData *pad_data, int count)
{
int ret, intc;
ret = vshCtrlReadBufferPositive(pad_data, count);
if(ret <= 0)
{
return ret;
}
intc = pspSdkDisableInterrupts();
if (pad_data[0].Buttons & PSP_CTRL_CIRCLE)
{
//my menu on/off
if(a == 0){ a = 1; }
else{ a = 0; }
}
//if my menu on block buttons
if(a == 1)
{
pad_data[0].Buttons = 0;
}
pspSdkEnableInterrupts(intc);
return ret;
} |
|
|
| Back to top |
|
 |
hotter

Joined: 07 Dec 2008 Posts: 53
|
Posted: Wed Jan 07, 2009 10:11 pm Post subject: |
|
|
It is working!!! almost :D
now the buttons are disabled in XMB when my menu is on so its good, but the same error with "previous" variable. _________________ Pragramming with:
Microsoft Visual C 2008 + pspsdk MINPSPW 0.8.10
Last edited by hotter on Tue Mar 24, 2009 3:29 pm; edited 2 times in total |
|
| Back to top |
|
 |
hotter

Joined: 07 Dec 2008 Posts: 53
|
Posted: Thu Jan 08, 2009 5:07 am Post subject: |
|
|
I added this:
| Code: |
typedef int (* STMOD_HANDLER)(SceModule2 *);
|
and now I guess everything is working good!
Thx for help very much :) _________________ Pragramming with:
Microsoft Visual C 2008 + pspsdk MINPSPW 0.8.10 |
|
| Back to top |
|
 |
SweetNSourOrc
Joined: 11 Jun 2009 Posts: 1
|
Posted: Thu Jun 11, 2009 8:37 am Post subject: I cant get this code to work |
|
|
| Code: |
int vshReadButtons(SceCtrlData *pad_data, int count)
{
int ret, intc;
ret = vshCtrlReadBufferPositive(pad_data, count);
if(ret <= 0)
{
return ret;
}
intc = pspSdkDisableInterrupts();
pad_data[0].Buttons = 0;
pspSdkEnableInterrupts(intc);
return ret;
}
int OnModuleStart(SceModule2 *mod)
{
if (strcmp(mod->modname, "sceVshBridge_Driver") == 0)
{
orgaddr=sctrlHENFindFunction("sceVshBridge_Driver", "sceVshBridge", 0xC6395C03);
vshCtrlReadBufferPositive = (void *)orgaddr;
PatchSyscall(orgaddr, vshReadButtons);
sceKernelDcacheWritebackAll();
sceKernelIcacheClearAll();
}
if (!previous)
return 0;
return previous(mod);
}
int module_start(SceSize args, void *argp)
{
sceCtrlSetButtonMasks(0x001000, 1);
PatchSyscall = (void *)sctrlHENFindFunction("SystemControl", "SystemCtrlForKernel", 0x826668E9);
if (!PatchSyscall)
{
PatchSyscall = (void *)sctrlHENFindFunction("SystemControl", "SystemCtrlForKernel", 0x02BFCB5F);
if (!PatchSyscall)
{
asm("break\n");
return 1;
}
}
sceKernelDcacheWritebackAll();
sceKernelIcacheClearAll();
sctrlHENSetStartModuleHandler(OnModuleStart);
return 0;
}
int module_stop(SceSize args, void *argp)
{
PatchSyscall((u32)vshReadButtons, (void *)orgaddr);
sceKernelDcacheWritebackAll();
sceKernelIcacheClearAll();
return 0;
}
|
For some reason, this code still doesnt disable the keys in VSH for me. Can you guys help? |
|
| Back to top |
|
 |
hyeokje
Joined: 04 Aug 2009 Posts: 3
|
Posted: Tue Aug 04, 2009 11:05 pm Post subject: Re: I cant get this code to work |
|
|
| Code: |
#include <pspsdk.h>
#include <pspctrl.h>
#include <pspkernel.h>
#include <systemctrl.h>
#include <string.h>
PSP_MODULE_INFO("myHold", 0x1000, 1, 1);
STMOD_HANDLER previous = NULL;
void (* PatchSyscall)(u32 funcaddr, void *newfunc);
int (* vshCtrlReadBufferPositive)(SceCtrlData *pad_data, int count);
int OnModuleStart(SceModule2 *mod);
u32 orgaddr;
SceCtrlData pad;
int a;
unsigned int paddata_old;
int vshReadButtons(SceCtrlData *pad_data, int count)
{
int ret, intc;
ret = vshCtrlReadBufferPositive(pad_data, count);
if(ret <= 0)
{
return ret;
}
intc = pspSdkDisableInterrupts();
if(paddata_old != pad_data[0].Buttons)
{
// simultaneously hotkey
// if( (pad_data[0].Buttons & PSP_CTRL_VOLUP) && (pad_data[0].Buttons & PSP_CTRL_VOLDOWN) )
if(pad_data[0].Buttons & PSP_CTRL_NOTE)
{
if(a == 0) { a = 1; }
else { a = 0; }
}
}
paddata_old = pad_data[0].Buttons;
if(a == 1)
{
pad_data[0].Buttons = 0;
}
pspSdkEnableInterrupts(intc);
return ret;
}
int OnModuleStart(SceModule2 *mod)
{
if (strcmp(mod->modname, "sceVshBridge_Driver") == 0)
{
orgaddr=sctrlHENFindFunction("sceVshBridge_Driver", "sceVshBridge", 0xC6395C03);
vshCtrlReadBufferPositive = (void *)orgaddr;
PatchSyscall(orgaddr, vshReadButtons);
sceKernelDcacheWritebackAll();
sceKernelIcacheClearAll();
}
if (!previous) return 0;
return previous(mod);
}
int module_start(SceSize args, void *argp)
{
PatchSyscall = (void *)sctrlHENFindFunction("SystemControl", "SystemCtrlForKernel", 0x826668E9);
if (!PatchSyscall)
{
PatchSyscall = (void *)sctrlHENFindFunction("SystemControl", "SystemCtrlForKernel", 0x02BFCB5F);
if (!PatchSyscall)
{
asm("break\n");
return 1;
}
}
sceKernelDcacheWritebackAll();
sceKernelIcacheClearAll();
previous = sctrlHENSetStartModuleHandler(OnModuleStart);
return 0;
}
int module_stop(SceSize args, void *argp)
{
PatchSyscall((u32)vshReadButtons, (void *)orgaddr);
sceKernelDcacheWritebackAll();
sceKernelIcacheClearAll();
return 0;
}
|
| Code: |
#Makefile
TARGET = myHold
OBJS = myHold.o
BUILD_PRX = 1
PRX_EXPORTS =
USE_KERNEL_LIBC = 1
USE_KERNEL_LIBS = 1
INCDIR =
CFLAGS = -O2 -G0 -Wall
CXXFLAGS = $(CFLAGS) -fno-exceptions -fno-rtti
ASFLAGS = $(CFLAGS)
LIBDIR =
LDFLAGS = -mno-crt0 -nostartfiles
LIBS = -lpspkubridge -lpspsystemctrl_user -lpspsystemctrl_kernel
PSPSDK=$(shell psp-config --pspsdk-path)
include $(PSPSDK)/lib/build.mak
|
This is working, but launching homebrew causes error :(
I edited post, and this code is fully working. Thanks Torch.
Last edited by hyeokje on Sat Aug 08, 2009 2:01 pm; edited 4 times in total |
|
| Back to top |
|
 |
|