PAD polling issue [Resolved. My code bug.]
#1
[Sorry, that was my fault  Blush ]

I'm currently writing my own PAD plugin (native integration with real DualShock controller using STM32+USB custom class). https://github.com/L-proger/pcsx2/tree/develop/RealPad  plugin name is "RealPad". (latest code from below is not yet pushed to github).

Everything works fine, and I can play any games, but now I am implementing the PADfreeze function and have encountered one problem:

I'm testing my PAD plugin with Silent Hill 2 game [SLES_511.56] and i am experiencing the wrong PADstartPoll + PADpoll sequence.
"Current" command is always recording in my plugin for debugging and "freeze" purposes and clears at "PADstartPoll" event so that i can determine at any moment which bytes transmitted since the last PADstartPoll call.
As far as i know, PS2 will not issue any poll sequence longer that 21 bytes. Therefore, i allocated receive/transmit buffers of size == 21 bytes.



Code:
uint8_t UsbGamepad::beginPoll() {
    _state.finalizeCurrentCommand(); //Set "length" field of Command = 0
    auto result = transfer({ UsbRequestType::PollBegin, 0x01 }).data;
    _state.currentCommand.append(0x01, result); //Record byte transfer to current command
    return result;
}
uint8_t UsbGamepad::poll(uint8_t data) {
    auto result = transfer({ UsbRequestType::Poll, data }).data;
    _state.currentCommand.append(data, result);  //Record byte transfer to current command
    return result;
}

And i'm getting "assert" at loading of game (at Konami logo):

Code:
class Command {
public:
    static constexpr std::uint8_t MaxCommandLength = 21;

    std::uint8_t length = 0;
    std::uint8_t txBuffer[MaxCommandLength] = {};
    std::uint8_t rxBuffer[MaxCommandLength] = {};

    void append(uint8_t txValue, uint8_t rxValue) {
        assert(length < MaxCommandLength);  //        <----- Problem here
        txBuffer[length] = txValue;
        rxBuffer[length] = rxValue;
        length++;
    }
...
};

Last successful command is:
0x01, 0x43, 0x00, 0x01, 0x00 .... (others are zeroes, total length == 21 byte) (Enter "config" mode command)

And after that i got PADpoll call with parameter: 0x42 (regular polling command). So, as i can see, my plugin did not receive "PADstartPoll" command!
Of course this leads to "assert" in my code. (marked as "<----- Problem here" in code above).

Is this some kind of "normal" behaviour of PS2 or bug in PCSX2?

p.s. I don't really believe that this is the "normal" behavior of PS2, because it can't read peripheral device without selecting a specific device (pin 6 of gamepad connector, "ATT") on SPI bus (DS2 interface).
Reply

Sponsored links

#2
Sorry, I found an error in my own code. The index of the current pad is incorrectly saved in the "PADstartPoll" function implementation.

I did not find how to delete the topic here, so moderators, please help) or ...

Can you tell me if I have to keep the bytes of the current command, if it is not complete when the PADfreeze is issued? In other words: is it possible for PCSX2 to call "PADfreeze" in the middle of reading a gamepad? Or does PADfreeze always get called after a full command has been sent to the gamepad?
Reply
#3
I'm not totally sure offhand, though I'd tend to think that since someone could stop emulation at any time, that it might not be complete. Then again, I'm not sure how vital it is that it loads exactly the state of the controller from when it was frozen, since I doubt you're actually still pressing the same buttons as you were when it was frozen.

I'm in process for working on my own plugin based heavily off onepad, but haven't actually bothered with the freeze and restore code yet.

I would suggest that for questions about plugin development, the Plugin discussion and support forum is probably the better spot to post, btw.
https://forums.pcsx2.net/Forum-Plugin-di...nd-support
Reply
#4
(02-25-2020, 08:03 AM)arcum42 Wrote: I'm not totally sure offhand, though I'd tend to think that since someone could stop emulation at any time, that it might not be complete. Then again, I'm not sure how vital it is that it loads exactly the state of the controller from when it was frozen, since I doubt you're actually still pressing the same buttons as you were when it was frozen.

I'm in process for working on my own plugin based heavily off onepad, but haven't actually bothered with the freeze and restore code yet.

I would suggest that for questions about plugin development, the Plugin discussion and support forum is probably the better spot to post, btw.
https://forums.pcsx2.net/Forum-Plugin-di...nd-support

I already asked the moderators to delete this topic (because I can’t find the “delete topic” button anywhere Sad  ). So, while it is alive, I prefer not to create more +/- useless (for community) threads and drawing unnecessary attention.

About freezing: I just don’t want to make any assumptions about how the game should feel after “unfreezing” with a different state. I want to do it as best as possible Laugh  Freeze now works fine. By the way, what is the setVRef command? (0x40). I read the official PS2 SDK, decompiled PAD .a libraries, and all I see is a loop with id (0-11) and argument 0x02 for the DS2 device. I do not know what this command is for! 
 - p.s. I know this question is for the "plugins" section, but I do not think anyone can give me an answer Sad
Reply
#5
Largest trouble is that a lot of the people that wrote the relevant code on these sections aren't around any more. Onepad's code for the commands is straight copied from Lilypad, and that was by ChickenLiver, who I haven't seen in years.

And that code just says to set the final result to a variable named "noclue": static const u8 noclue[7] = {0x5A, 0x00, 0x00, 0x02, 0x00, 0x00, 0x5A};

Which makes me think they didn't know either, and just return what it's expecting...
Reply
#6
(02-26-2020, 02:32 AM)arcum42 Wrote: Largest trouble is that a lot of the people that wrote the relevant code on these sections aren't around any more. Onepad's code for the commands is straight copied from Lilypad, and that was by ChickenLiver, who I haven't seen in years.

And that code just says to set the final result to a variable named "noclue": static const u8 noclue[7] = {0x5A, 0x00, 0x00, 0x02, 0x00, 0x00, 0x5A};

Which makes me think they didn't know either, and just return what it's expecting...
I will experiment with the various arguments of this command on a real gamepad and try to find out its purpose.
Reply




Users browsing this thread: 1 Guest(s)