How to get controller state?

BIOS, Controllers, Memory Cards, Serial I/O, Parallel I/O, etc.
Post Reply
User avatar
MihaiGamerXD
Active PSXDEV User
Active PSXDEV User
Posts: 38
Joined: Mar 09, 2019
I am a: Programmer
PlayStation Model: SCPH-1001

How to get controller state?

Post by MihaiGamerXD » March 9th, 2019, 9:17 am

Hello everybody, I have a question:
How to get controller state?

For example:
if PadStateFindPad = PAD_ONE {
box_a = 1;
}

else if PadStateFindPad = PAD_TWO {
box_b = 1;
}

else {
box_a = 0;
box_b = 0;
}

Or if there's a documentation, then post it here! Thanks in advance!

User avatar
LameGuy64
Verified
Psy-Q Enthusiast
Psy-Q Enthusiast
Posts: 388
Joined: Apr 10, 2013
I am a: Hobbyist Game Developer
Motto: Commercial or not, play it!
PlayStation Model: H2000/7000
Location: Philippines
Contact:

Post by LameGuy64 » March 9th, 2019, 2:56 pm

The simplest way to read controller input is through PadInit() and PadRead the latter of which would return a bit field of button states which you can mask off using PADL<direction> and PADR<direction> definitions. The more advanced way of reading controller input that also allows you to control the vibration motors is PadInitDirect() and PadStartCom().

Documentation of such functions are found in the libref PDF document and there are a number of sample programs (including my old ones) on this forum that use it. Details regarding the use of the advanced method of reading controller input is described in the libovr PDF document.
Please don't forget to include my name if you share my work around. Credit where it is due.

Dev. Console: SCPH-7000 with SCPH-7501 ROM, MM3, PAL color fix, Direct AV ports, DB-9 port for Serial I/O, and a Xplorer FX with Caetla 0.35.

DTL-H2000 PC: Dell Optiplex GX110, Windows 98SE & Windows XP, Pentium III 933MHz, 384MB SDRAM, ATI Radeon 7000 VE 64MB, Soundblaster Audigy, 40GB Seagate HDD, Hitachi Lite-on CD-RW Drive, ZIP 250 and 3.5" Floppy.

User avatar
MihaiGamerXD
Active PSXDEV User
Active PSXDEV User
Posts: 38
Joined: Mar 09, 2019
I am a: Programmer
PlayStation Model: SCPH-1001

Post by MihaiGamerXD » March 9th, 2019, 8:11 pm

PadInit() Initializes Controller, and I want to know how to get Controller Slots! Example:

If PadPort1FindPad() {
port_a =1
}

If PadPort2FindPad() {
port_b = 1
}

Yagotzirck
Verified
Extreme PSXDEV User
Extreme PSXDEV User
Posts: 131
Joined: Jul 17, 2013

Post by Yagotzirck » March 10th, 2019, 3:29 am

Rhetorical question: did you bother to check the documentation LameGuy addressed you to? :?
LIBREF46.PDF, page 789 wrote: int PadGetState(int port)
[...]

Return value:
[...]
Value     Macro (libpad.h)          Controller connection state
0           PadStateDiscon           Controller disconnected
It took me literally 5 seconds to find it :roll:

User avatar
MihaiGamerXD
Active PSXDEV User
Active PSXDEV User
Posts: 38
Joined: Mar 09, 2019
I am a: Programmer
PlayStation Model: SCPH-1001

Post by MihaiGamerXD » March 10th, 2019, 4:09 am

I tried this:

ret_a=PadGetState(0);

switch(ret_a) {
case PadStateDiscon:
con_a = 0;
case PadStateFindPad:
con_a = 1;
}

ret_b=PadGetState(1);

switch(ret_b) {
case PadStateDiscon:
con_b = 0;
case PadStateFindPad:
con_b = 1;
}

But it shows an error like "Unknown opcode BFC0506C at 00008548" and that's in emulator!

Yagotzirck
Verified
Extreme PSXDEV User
Extreme PSXDEV User
Posts: 131
Joined: Jul 17, 2013

Post by Yagotzirck » March 10th, 2019, 4:47 am

That's a rather redundant way to check if controllers are connected, I'd advise to replace it with this:

Code: Select all

con_a = PadGetState(0) != PadStateDiscon;
con_b = PadGetState(0x10) != PadStateDiscon;
Notice that I used 0x10 since that's the correct code for pad 2 (you used 1 which is actually the code for Multi Tap B).
If it still gives an error you'd better host your project as an attachment, it's hard to say what's exactly causing it otherwise(might as well be something completely unrelated to this).

User avatar
MihaiGamerXD
Active PSXDEV User
Active PSXDEV User
Posts: 38
Joined: Mar 09, 2019
I am a: Programmer
PlayStation Model: SCPH-1001

Post by MihaiGamerXD » March 10th, 2019, 5:08 am

Still gives an error!
Here's the signature!
There are some codes that are used for STR and XA Files! Delete them first!
You do not have the required permissions to view the files attached to this post.

Yagotzirck
Verified
Extreme PSXDEV User
Extreme PSXDEV User
Posts: 131
Joined: Jul 17, 2013

Post by Yagotzirck » March 10th, 2019, 9:09 am

OK, it looks like PadGetState() isn't liked by emulators at all - the best I could achieve was with no$psx using an original BIOS instead of nocash BIOS clone and it gave no errors, but still freezes at a black screen nonetheless :/

I'll try it on a real psx tomorrow and see what happens.

User avatar
MihaiGamerXD
Active PSXDEV User
Active PSXDEV User
Posts: 38
Joined: Mar 09, 2019
I am a: Programmer
PlayStation Model: SCPH-1001

Post by MihaiGamerXD » March 10th, 2019, 9:57 am

No need to do that! Now it works! I need to use PadInitDirect First! Otherwise the game crashes! Thanks for helping me! And I'm sorry! You know I'm aproximatelly noob at coding and I still know how to code, cuz I learned! But I didn't know PadInitDirect must be used!

Yagotzirck
Verified
Extreme PSXDEV User
Extreme PSXDEV User
Posts: 131
Joined: Jul 17, 2013

Post by Yagotzirck » March 10th, 2019, 10:33 am

Ah, glad you sorted it out :) It could've been deduced from LIBOVR46.PDF that PadGetState is meant to be used with PadInitDirect and not with PadInit(even though it wasn't specified in an explicit manner), but I didn't read it thoroughly enough to figure that out :shrug

As for the noob part, that's alright - the fact you try to solve issues on your own rather than waiting for someone else to do everything for you is a good sign ;)
If I may give some criticism I'd suggest you try to keep your code a little bit more tidy (prototypes not matching functions' definitions, PadInit() getting called twice, cluttered-up code, etc), but I suppose that will come later on with experience :)

User avatar
MihaiGamerXD
Active PSXDEV User
Active PSXDEV User
Posts: 38
Joined: Mar 09, 2019
I am a: Programmer
PlayStation Model: SCPH-1001

Post by MihaiGamerXD » March 11th, 2019, 5:00 am

Yes, anyway! I have one more problem: When I remove controller 2, the second box is not disappearing! I also tried with PadStateStable and PadStateFindCTP1, But everything is disappearing! How to fix this?

Example of code:

ret_a = PadGetState(0x00);

switch(ret_a) {
case PadStateDiscon: /If it's disconnected
con_a = 0; //The First Box disappears
case PadStateFindPad: //If it's connected
case PadStateStable: //If it's a Dual Shock Controller
con_a = 0; //The First Box disappears
case PadStateFindCTP1: //If it's a Normal Controller
con_a = 1; //The First Box appears
}

ret_b = PadGetState(0x10);

switch(ret_b) {
case PadStateDiscon: //If it's disconnected
con_b = 0; //The Second Box disappears
case PadStateFindPad: /If it's connected
case PadStateStable: //If it's a Dual Shock Controller
con_b = 0; //The Second Box disappears
case PadStateFindCTP1: //If it's a Normal Controller
con_b = 1; //The Second Box appears
}

if (con_a == 1) //Create the First Box
if (con_b == 1) //Create the Second Box

Yagotzirck
Verified
Extreme PSXDEV User
Extreme PSXDEV User
Posts: 131
Joined: Jul 17, 2013

Post by Yagotzirck » March 11th, 2019, 11:51 pm

If the code's structure hasn't changed from the project you hosted it's pretty easy to figure out the issue:

Code: Select all

int main(void) {
	initialize();
	
	while(1) {
		update();
		draw();
		display();
	}
}
That piece of code is located in initialize(), which means it's executed only once at startup and never executed again; try moving it at the beginning of update() (or create another function specifically for that piece of code, as long as you place it inside the infinite while(1) loop it doesn't really matter) and see what happens.

Oh also, your switch blocks lack breaks, which means that no matter which values ret_a and ret_b hold, it will always fallthrough below the correct case statement and eventually execute con_a = 1 and con_b = 1, respectively.
Here's how you should fix it:

Code: Select all

switch(ret_a) {
case PadStateDiscon: /If it's disconnected
case PadStateStable: //If it's a Dual Shock Controller
	con_a = 0; //The First Box disappears
	break;
case PadStateFindCTP1: //If it's a Normal Controller
	con_a = 1; //The First Box appears
}
Same thing for the switch(ret_b) block.
I allowed PadStateDiscon to fallthrough PadStateStable since they both set con_a to 0, so it's not a mistake ;) .
Last edited by Yagotzirck on March 12th, 2019, 2:43 am, edited 1 time in total.

User avatar
MihaiGamerXD
Active PSXDEV User
Active PSXDEV User
Posts: 38
Joined: Mar 09, 2019
I am a: Programmer
PlayStation Model: SCPH-1001

Post by MihaiGamerXD » March 12th, 2019, 2:01 am

Thank you! It worked perfectly! Now I'm ready to show the example! The example contains XA + STR Playback and controller detect! Is it good to post it? And where can I post this?

Yagotzirck
Verified
Extreme PSXDEV User
Extreme PSXDEV User
Posts: 131
Joined: Jul 17, 2013

Post by Yagotzirck » March 12th, 2019, 2:38 am

I suppose that the Examples (Psy-Q) section should do.

As for whether it's good or not to post it, that's highly subjective - I for one would say to go for it and let people judge for themselves (even though like I said in a previous post the code is a bit messy and with a lot of room for improvement, but all in all it's quite understandable :))

User avatar
MihaiGamerXD
Active PSXDEV User
Active PSXDEV User
Posts: 38
Joined: Mar 09, 2019
I am a: Programmer
PlayStation Model: SCPH-1001

Post by MihaiGamerXD » March 12th, 2019, 3:11 am

Ok! Thank you! I'm going to post the example! And report if you got issues!

User avatar
Shadow
Verified
Admin / PSXDEV
Admin / PSXDEV
Posts: 2670
Joined: Dec 31, 2012
PlayStation Model: H2000/5502
Discord: Shadow^PSXDEV

Post by Shadow » April 28th, 2019, 6:29 am

There's heaps of controller examples from Sony in the Psy-Q SDK. You gotta' tweak them to suit your needs, but they do work well. It becomes extremely messy however once you start adding in the Multitap, DUAL-SHOCK, Lightguns and other peripherals including the Memory Card (those are a bit of a nightmare to handle).
Development Console: SCPH-5502 with 8MB RAM, MM3 Modchip, PAL 60 Colour Modification (for NTSC), PSIO Switch Board, DB-9 breakout headers for both RGB and Serial output and an Xplorer with CAETLA 0.34.

PlayStation Development PC: Windows 98 SE, Pentium 3 at 400MHz, 128MB SDRAM, DTL-H2000, DTL-H2010, DTL-H201A, DTL-S2020 (with 4GB SCSI-2 HDD), 21" Sony G420, CD-R burner, 3.25" and 5.25" Floppy Diskette Drives, ZIP 100 Diskette Drive and an IBM Model M keyboard.

Post Reply

Who is online

Users browsing this forum: No registered users and 4 guests