Page 1 of 1

Trouble using DualShock controllers

Posted: October 15th, 2014, 12:58 pm
by LameGuy64
On a real console, this controller prototype I made works fine but for some reason, it crashes on a emulator (no$psx to be exact) after exactly 3 frames have passed... Have I done something wrong on how I initialize the controller library or what?

Also, I don't know how to control the vibrators of the controller or automatically activate analog mode when such a controller is detected... The docs lack enough detail on how to pull this off and Sony's controller example is completely broken (missing files) which doesn't help much with this situation.

Code: Select all

#include <stdio.h>
#include <sys/types.h>
#include <libgte.h>
#include <libgpu.h>
#include <libetc.h>
#include <libapi.h>
#include <libpad.h>
#include <libmcrd.h>


// Pad info struct (to simplify things a lot)
typedef struct {
	u_char   status;		// Always 0 if a controller is detected
	u_char   psize:4;
	u_char   type:4;
	
	struct {
		u_short select:1;
		u_short l3:1;
		u_short r3:1;
		u_short start:1;
		u_short up:1;
		u_short left:1;
		u_short down:1;
		u_short right:1;
		u_short l2:1;
		u_short r2:1;
		u_short l1:1;
		u_short r1:1;
		u_short triangle:1;
		u_short circle:1;
		u_short cross:1;
		u_short square:1;
	} button;
	
	u_char   rstickx;
	u_char   rsticky;
	u_char   lstickx;
	u_char   lsticky;
	
} PADINFO;


char	PadBuff[2][34];	// Buffer to store 34 bytes worth of pad data

// For controlling the vibrators of a DualShock controller (can't get it to work though)
u_char	PadActAlign[] = { 0x00, 0x01, 0xff, 0xff, 0xff, 0xff };
u_char	PadAct[6] = {0};


// Very basic display stuff
DISPENV	disp;
DRAWENV draw;
RECT	crect;
int		bnum=0;


int main() {
	
	int  i,result,count;
	long Slot1result, Slot2result, CardCmd=0;
	
	PADINFO PadStats[2];
	
	
	// Reset GPU
	ResetGraph(0);
	
	// Setup font environment
	FntLoad(960, 0);
	FntOpen(0, 0, 320, 240, 0, 512);

	
	// Init controller
	PadInitDirect(&PadBuff[0][0], &PadBuff[1][0]);
	PadSetAct(0x00, PadAct, 6);
	PadSetActAlign(0x00, PadActAlign);
	PadStartCom();
	
	
	// Main loop
	while(1) {
		
		ClearImage(&crect, 0, 64, 0);
		FntPrint("\n\n %d\n", count);
		
		for (i=0; i<2; i++) {
			
			// Copy pad data from the buffers to one of the PADINFO structs for easy interpretation
			memcpy((u_char*)&PadStats[i], (u_char*)&PadBuff[i][0], sizeof(PadStats));
			*(u_short*)&PadStats[i].button ^= 0xffff;
			
			if (PadStats[i].status == 0) {
				
				FntPrint(" CONTROLLER %d DATA:\n", i+1);
				FntPrint("  STAT:%d\n", PadStats[i].status);
				FntPrint("  TYPE:%d - ", PadStats[i].type);
				switch(PadStats[i].type) {
					case 4:
						FntPrint("16-BUTTON PAD\n");
						break;						
					case 5:
						FntPrint("ANALOG JOYSTICK\n");
						break;
					case 7:
						FntPrint("ANALOG CONTROLLER\n");
						break;
					default:
						FntPrint("UNKNOWN/NOT SUPPORTED\n");
						break;
				}
				
				switch(PadStats[i].type) {
					case 5:
					case 7:
						FntPrint("  RGT ANALOG X:%d\n", PadStats[i].rstickx);
						FntPrint("  RGT ANALOG Y:%d\n", PadStats[i].rsticky);
						FntPrint("  LFT ANALOG X:%d\n", PadStats[i].lstickx);
						FntPrint("  LFT ANALOG Y:%d\n", PadStats[i].lsticky);
						
						if (i==0) {
							if (PadStats[i].button.l3) PadAct[0] = 255;
							if (PadStats[i].button.r3) PadAct[1] = 255;
						}
						
					case 4:
						FntPrint("\n ");
						if (PadStats[i].button.up)			FntPrint("UP ");
						if (PadStats[i].button.down)		FntPrint("DOWN ");
						if (PadStats[i].button.left)		FntPrint("LEFT ");
						if (PadStats[i].button.right)		FntPrint("RIGHT ");
						
						if (PadStats[i].button.cross)		FntPrint("CROSS ");
						if (PadStats[i].button.square)		FntPrint("SQUARE ");
						if (PadStats[i].button.circle)		FntPrint("CIRCLE ");
						if (PadStats[i].button.triangle)	FntPrint("TRIANGLE ");
						
						if (PadStats[i].button.start)		FntPrint("START ");
						if (PadStats[i].button.select)		FntPrint("SELECT ");
						if (PadStats[i].button.l1)			FntPrint("L1 ");
						if (PadStats[i].button.r1)			FntPrint("R1 ");
						if (PadStats[i].button.l2)			FntPrint("L2 ");
						if (PadStats[i].button.r2)			FntPrint("R2 ");
						if (PadStats[i].button.l3)			FntPrint("L3 ");
						if (PadStats[i].button.r3)			FntPrint("R3 ");
						
						break;
						
				}
				
				
				FntPrint("\n\n");
				
			} else {
				FntPrint(" NO CONTROLLER DETECTED IN PORT %d\n", i+1);
			}
			
		}
		
		crect.w = 320;	crect.h = 240;
		crect.x = 0;	crect.y = 256*(bnum);
		SetDefDispEnv(&disp, 0, 256*(1-bnum), 320, 240);
		SetDefDrawEnv(&draw, 0, 256*(bnum), 320, 240);
		bnum ^= 1;
		
		FntFlush(-1);
		DrawSync(0);
		
		VSync(0);
		PutDispEnv(&disp);
		PutDrawEnv(&draw);
		SetDispMask(1);
		
		count = (count+1)%60;
		
	}
	
}
Any useful help will be gladly appreciated!

Re: Trouble using DualShock controllers

Posted: October 15th, 2014, 6:18 pm
by Administrator

Code: Select all

SCEE Dual Shock Technical Article #1
Author: Mike Kavallierou (Mike_Kavallierou@*.*.com)

Revision History
Created         Can't remember
Modified        11/08/98 -      Added actuator loading checks to
				multitap sample
                                added some FAQ's
Modified        22/12/98 -      Added correct handling of other expanded
				controllers and detection of JogCon to
				multitap sample

Archive created: pkzip -r -P dualshck.zip *.* 
================================================================

This archive contains Dualsh.doc, an overview of the
Dual Shock controller.


Directory Structure
===================

DROPOUT
Document and source code detailing how to get around
the problem of the Dual Shock dropping out of analog mode
during a games' execution.

MULTITAP
Using multiple Dual Shock controllers
DUALSHCK.ZIP

Re: Trouble using DualShock controllers

Posted: October 16th, 2014, 11:48 am
by LameGuy64
Thanks! That should be enough for solving my controller issues.