| View previous topic :: View next topic |
| Author |
Message |
lgnr
Joined: 17 Dec 2009 Posts: 39
|
Posted: Mon Jan 25, 2010 9:25 am Post subject: [SOLVED] sceCtrlReadLatch() strange behavior |
|
|
It got a little bigger than i expected. I'll try to explain:
I was writing/learning with a controller homebrew to use with some WinAPI stuff. That turned out to be really fun and useful. Here starts my problem:
I have used SceCtrlData objects and sceCtrlReadBufferPositive() to get key presses.
Everything was going great untill i felt the need to use key releases events. I know i could have just used sceCtrlReadBufferNegative(), but another solution seemed more easy and usefull, since it gets just ONE key press, which is what I'm looking for. So in one of the topics here, someone suggested using SceCtrlLatch and sceCtrlReadLatch(), which is great. Everything worked out. Its all working. Only problem is: PSP freezes on program exit.
Here the main loop from main.c:
| Code: |
while(1)
{
if((button = get_button(&ispressed)))
{
if(button == PSP_CTRL_SELECT)
{
//Do some stuff
}
else
{
//----> This also works
printf("\nPressed = %d\n", ispressed);
//-----> Send info to socket on server - Its working
//A dumb try to avoid freezing
sleep(2000);
}
}
}
|
And here is the get_button function:
| Code: |
int get_button(int *ispressed)
{
SceCtrlLatch latch;
sceCtrlSetSamplingCycle(0);
sceCtrlSetSamplingMode(PSP_CTRL_MODE_DIGITAL);
while(1)
{
//Read Pad
sceCtrlReadLatch(&latch);
if(latch.uiMake)
{
//Means a button was pressed
*ispressed = 1;
if(latch.uiMake & PSP_CTRL_CROSS) return PSP_CTRL_CROSS;
else if(latch.uiMake & PSP_CTRL_CIRCLE) return PSP_CTRL_CIRCLE;
else if(latch.uiMake & PSP_CTRL_SQUARE) return PSP_CTRL_SQUARE;
else if(latch.uiMake & PSP_CTRL_TRIANGLE) return PSP_CTRL_TRIANGLE;
else if(latch.uiMake & PSP_CTRL_START) return PSP_CTRL_START;
else if(latch.uiMake & PSP_CTRL_SELECT) return PSP_CTRL_SELECT;
else if(latch.uiMake & PSP_CTRL_LTRIGGER) return PSP_CTRL_LTRIGGER;
else if(latch.uiMake & PSP_CTRL_RTRIGGER) return PSP_CTRL_RTRIGGER;
else if(latch.uiMake & PSP_CTRL_UP) return PSP_CTRL_UP;
else if(latch.uiMake & PSP_CTRL_DOWN) return PSP_CTRL_DOWN;
else if(latch.uiMake & PSP_CTRL_LEFT) return PSP_CTRL_LEFT;
else if(latch.uiMake & PSP_CTRL_RIGHT) return PSP_CTRL_RIGHT;
//And if a useless button was pressed, return 0
else return 0;
}
else if(latch.uiBreak)
{
//Means a button was relesead
*ispressed = 0;
if(latch.uiBreak & PSP_CTRL_CROSS) return PSP_CTRL_CROSS;
else if(latch.uiBreak & PSP_CTRL_CIRCLE) return PSP_CTRL_CIRCLE;
else if(latch.uiBreak & PSP_CTRL_SQUARE) return PSP_CTRL_SQUARE;
else if(latch.uiBreak & PSP_CTRL_TRIANGLE) return PSP_CTRL_TRIANGLE;
else if(latch.uiBreak & PSP_CTRL_START) return PSP_CTRL_START;
else if(latch.uiBreak & PSP_CTRL_SELECT) return PSP_CTRL_SELECT;
else if(latch.uiBreak & PSP_CTRL_LTRIGGER) return PSP_CTRL_LTRIGGER;
else if(latch.uiBreak & PSP_CTRL_RTRIGGER) return PSP_CTRL_RTRIGGER;
else if(latch.uiBreak & PSP_CTRL_UP) return PSP_CTRL_UP;
else if(latch.uiBreak & PSP_CTRL_DOWN) return PSP_CTRL_DOWN;
else if(latch.uiBreak & PSP_CTRL_LEFT) return PSP_CTRL_LEFT;
else if(latch.uiBreak & PSP_CTRL_RIGHT) return PSP_CTRL_RIGHT;
//And if a useless button was released, return 0
else return 0;
}
}
}
|
Summing up: everything is great untill the program quits. Then the PSP freezes and you have to force shutdown. As when you press the 'home' button the program is running the while(1) from the get_button() function, we can assume the problem is in the function, right? Can it have something to do with the 'event' of pressing the 'home' button? I'm really out of guesses.
Sorry for my bad English and thanks in advance. Also, others suggestions are encouraged. Thanks!
Last edited by lgnr on Tue Jan 26, 2010 11:10 am; edited 1 time in total |
|
| Back to top |
|
 |
Devun_06
Joined: 17 Jun 2006 Posts: 15
|
Posted: Mon Jan 25, 2010 10:25 am Post subject: |
|
|
If you get the home button, your code skips to send the information to the socket on a server, then waits a little while to avoid freezing. If you assume waiting will fix the problem, that means another thread must be running that isn't quite finished yet in some cases. If that's the case, use sceKernelDelayThread() and set it to wait long enough for the other thread to complete(I don't know what code is omitted).
If that's not the case, meaning that wait doesn't actually help any, and didn't before, then you need to, or should install the callbacks for the home key. If you do, I suggest you continue to ignore reading it since it'll be handled by the callback thread.
If you don't want to use that method, you need to create a method for reaching your application's final return statement. Call a break or a return if a certain case is met in your main's while loop. You're using an int for button checking, in C, anything above zero is true, so return -1 or lower for a special case, and manually handle the exit(this cannot be done if you have the callbacks setup).
The problem could be your code that's omitted. |
|
| Back to top |
|
 |
lgnr
Joined: 17 Dec 2009 Posts: 39
|
Posted: Mon Jan 25, 2010 11:09 am Post subject: |
|
|
Thanks for the reply. I'll try to handle the home button particularly. But what puzzles me, and what makes me think that the trouble is not with the rest of the code, is that it does NOT freeze with the sceCtrlReadBufferPositive().
I do not run other threads, so i guess thats not the reason.
Anyway, I was thinking that perhaps the problem is with the function. I mean, the functions runs on every key press, since it returns a value and calls the function again. And it creates a new SceCtrlLatch struct everytime.
I'll try to do something like
| Code: |
else if(button == PSP_CTRL_HOME)
{
//does nothins
}
...
|
I'll post here when I do, but I thought I might have any other evident problem. Again, what puzzles me is that it runs OK with the sceCtrlReadBufferPositive() and the SceCtrlData struct.
Thanks dude! |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Tue Jan 26, 2010 2:01 am Post subject: |
|
|
Add a sceDisplayWaitVblankStart() inside the loop. The syscon sends control packets at 60Hz anyway.
Use this instead of latch.
| Code: | prevButtons = 0;
while (1)
{
sceCtrlReadBufferPositive(&newButtons, 1)
if ((prevButtons^newButtons) & PSP_CTRL_CROSS)
{
if (newButtons & PSP_CTRL_CROSS)
//make cross
else
//break cross
}
prevButtons = newButtons;
sceDisplayWaitVblankStart();
} |
Last edited by Torch on Tue Jan 26, 2010 6:03 am; edited 1 time in total |
|
| Back to top |
|
 |
Davee
Joined: 22 Jun 2009 Posts: 59
|
Posted: Tue Jan 26, 2010 5:58 am Post subject: |
|
|
| Might wanna lookup a bit on structures there. :/ |
|
| Back to top |
|
 |
Raphael

Joined: 17 Jan 2006 Posts: 646 Location: Germany
|
Posted: Tue Jan 26, 2010 8:50 am Post subject: |
|
|
There is the one and only reason why your program hangs up on exit. It has nothing to do with the *latch functions. Fix it and it will work. _________________ <Don't push the river, it flows.>
http://wordpress.fx-world.org - my devblog
http://wiki.fx-world.org - VFPU documentation wiki
Alexander Berl |
|
| Back to top |
|
 |
lgnr
Joined: 17 Dec 2009 Posts: 39
|
Posted: Tue Jan 26, 2010 9:06 am Post subject: |
|
|
So just sceDisplayWaitVblankStart(); wont fix it?
Thanks y'all guys. |
|
| Back to top |
|
 |
lgnr
Joined: 17 Dec 2009 Posts: 39
|
Posted: Tue Jan 26, 2010 10:58 am Post subject: |
|
|
| sceDisplayWaitVblankStart(); fixed it. |
|
| Back to top |
|
 |
Torch

Joined: 28 May 2008 Posts: 842
|
Posted: Tue Jan 26, 2010 2:20 pm Post subject: |
|
|
You should really only be using sceDisplayVblankStart() within your rendering loop when you're making a proper application. Its not required for sceCtrlReadBuffer* functions because they already delay internally to keep up with the sampling rate.
There's no need for a separate loop for reading buttons unless you specifically need high resolution buffered input independent of your game FPS. |
|
| Back to top |
|
 |
|