Reading the controller - VERY slow?

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

Moderators: cheriff, TyRaNiD

Post Reply
Paco
Posts: 54
Joined: Sun Oct 09, 2005 6:53 pm

Reading the controller - VERY slow?

Post by Paco »

Hey there! I'm using the standard sequence for reading the controller:

Code: Select all

m_iPrevMode = sceCtrlSetSamplingCycle(0);
sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG);
...

    SceCtrlData pad;
    sceCtrlReadBufferPositive(&pad, 1);
However, I'm finding it extremely slow to execute. I tried calling the not-documented sceCtrlPeekBufferPositive function in this fashion:

Code: Select all

  if (sceCtrlPeekBufferPositive(&pad, 1) >= 0) // Also tried a plain > 0
  {
    sceCtrlReadBufferPositive(&pad, 1);
but that didn't help. I suspect the controller only outputs data at specific intervals (60 times per second?), so if you try to read it more often than that, it will loop and wait for new data. Any other ideas about these functions and their behaviour?
Paco
Brunni
Posts: 186
Joined: Sat Oct 08, 2005 10:27 pm

Post by Brunni »

It seems that sceCtrlReadBufferPositive waits the VBlank, so it's very slow, but sceCtrlPeekBufferPositive doesn't. Else, they are identical (sceCtrlPeekBufferPositive also fills your SceCtrlData). So what you should do is simply:

Code: Select all

m_iPrevMode = sceCtrlSetSamplingCycle(0); 
sceCtrlSetSamplingMode(PSP_CTRL_MODE_ANALOG); 
... 

    SceCtrlData pad; 
    sceCtrlPeekBufferPositive(&pad, 1); 
And it will be fast ;)
Fanjita
Posts: 217
Joined: Wed Sep 28, 2005 9:31 am

Post by Fanjita »

If that doesn't work, you could always consider using the controller latch functions. I haven't seen any documentation on how they work, but having looked at some of the values output alongside the standard ctrl read functions, I think it's something like this:

There are latch types for various key operations : make (press), break (release), I forget the others.

You clear the latches on the type you're interested in, using the setLatch function, then at some later point in time you can just read with the getLatch function to see if the appropriate button was pressed (the button bit masks are the same in the latch functions as the read functions).

I guess this is only useful for keypresses where you don't care too much about realtime response (i.e. it only tells you if they pressed a key since you last reset the latch, rather than if it is currently held).

One other thing you could experiment with : perhaps the setSampleCycle call controls the wait for vblank?
Paco
Posts: 54
Joined: Sun Oct 09, 2005 6:53 pm

Post by Paco »

Brunni wrote:It seems that sceCtrlReadBufferPositive waits the VBlank, so it's very slow, but sceCtrlPeekBufferPositive doesn't. Else, they are identical (sceCtrlPeekBufferPositive also fills your SceCtrlData).
That worked beautifully well, and I haven't found any ill effects with anything: buttons, detecting button presses and releases, analog pad, everything seems to behave exactly as before but without the slowdown:

Code: Select all

    sceCtrlPeekBufferPositive(&pad, 1);   // This one doesn't wait for VSync
    eEvent.m_eHold = pad.Buttons;
    // (pad.Buttons ^ m_uButtonStates) is the set of buttons that have changed state
    eEvent.m_ePressed  = (pad.Buttons ^ m_uButtonStates) & pad.Buttons;
    eEvent.m_eReleased = (pad.Buttons ^ m_uButtonStates) & ~pad.Buttons;
    eEvent.m_fX =  (float(pad.Lx)-127.5)/127.5f;
    eEvent.m_fY = -(float(pad.Ly)-127.5)/127.5f;
    m_uButtonStates = pad.Buttons;
This seems to me like a simple and flawless way to read the pad... What could the purpose of all the other functions? Perhaps queuing input when you don't read the pad for some time (say loading a level, or in very low fps situations)?
Paco
Fanjita
Posts: 217
Joined: Wed Sep 28, 2005 9:31 am

Post by Fanjita »

It's useful for not consuming too much CPU when waiting in a "please press a button to continue" loop, I guess.
Post Reply