forums.ps2dev.org Forum Index forums.ps2dev.org
Homebrew PS2, PSP & PS3 Development Discussions
 
 FAQFAQ   SearchSearch   MemberlistMemberlist   UsergroupsUsergroups   RegisterRegister 
 ProfileProfile   Log in to check your private messagesLog in to check your private messages   Log inLog in 

[SOLVED] sceCtrlReadLatch() strange behavior

 
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development
View previous topic :: View next topic  
Author Message
lgnr



Joined: 17 Dec 2009
Posts: 39

PostPosted: Mon Jan 25, 2010 9:25 am    Post subject: [SOLVED] sceCtrlReadLatch() strange behavior Reply with quote

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
View user's profile Send private message
Devun_06



Joined: 17 Jun 2006
Posts: 15

PostPosted: Mon Jan 25, 2010 10:25 am    Post subject: Reply with quote

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
View user's profile Send private message
lgnr



Joined: 17 Dec 2009
Posts: 39

PostPosted: Mon Jan 25, 2010 11:09 am    Post subject: Reply with quote

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
View user's profile Send private message
Torch



Joined: 28 May 2008
Posts: 842

PostPosted: Tue Jan 26, 2010 2:01 am    Post subject: Reply with quote

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
View user's profile Send private message
Davee



Joined: 22 Jun 2009
Posts: 59

PostPosted: Tue Jan 26, 2010 5:58 am    Post subject: Reply with quote

Might wanna lookup a bit on structures there. :/
Back to top
View user's profile Send private message
Raphael



Joined: 17 Jan 2006
Posts: 646
Location: Germany

PostPosted: Tue Jan 26, 2010 8:50 am    Post subject: Reply with quote

Quote:

while(1)

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
View user's profile Send private message Visit poster's website
lgnr



Joined: 17 Dec 2009
Posts: 39

PostPosted: Tue Jan 26, 2010 9:06 am    Post subject: Reply with quote

So just sceDisplayWaitVblankStart(); wont fix it?
Thanks y'all guys.
Back to top
View user's profile Send private message
lgnr



Joined: 17 Dec 2009
Posts: 39

PostPosted: Tue Jan 26, 2010 10:58 am    Post subject: Reply with quote

sceDisplayWaitVblankStart(); fixed it.
Back to top
View user's profile Send private message
Torch



Joined: 28 May 2008
Posts: 842

PostPosted: Tue Jan 26, 2010 2:20 pm    Post subject: Reply with quote

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
View user's profile Send private message
Display posts from previous:   
Post new topic   Reply to topic    forums.ps2dev.org Forum Index -> PSP Development All times are GMT + 10 Hours
Page 1 of 1

 
Jump to:  
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