Copy Link
Add to Bookmark
Report

making dual shock controllers vibrate

PS_2's profile picture
Published in 
Playstation
 · 26 Jun 2021
making dual shock controllers vibrate
Pin it

  • each pad has two actuators (things that make it vibrate)
  • actuator 0 for each pad has an on and an off setting equal to 0 or 1 respectivly
    • this is the way the vibration in porsche challenge is done

  • actuator 1 for each pad has a setting between 0 and 255, where 0 is off, and 255 is most vibration
    • this is the way the vibration was done for tekken 3
    • (note: you can use both types of vibration at once)

  
/**
dual shock demo file
*/


#include <sys/types.h>
#include <libetc.h>
#include <libgte.h>
#include <libgpu.h>
#include <libgs.h>
#include <libpad.h>
#include <memory.h>
#include <pad.h>

#define DS_PAD_1 0 //port id for pad 1
#define DS_PAD_2 1 //port id for pad 2

#define OT_LENGTH 10
GsOT myOT[2];
GsOT_TAG myOT_TAG[2][1<<OT_LENGTH];

#define PACKETMAX 1000
PACKET GPUPacketArea[2][PACKETMAX*24];

#define SCREEN_WIDTH 320
#define SCREEN_HEIGHT 240

#define vibBuffLength 8
static u_char padbuff[2][34]; //read buffers for pads
u_char transmissionBuffer[2][vibBuffLength]; //vibration buffers for pads
int activeBuffer;
/************ protoypes ***************/
int main(void);
int InitDSPads(void); //inits dual shock pads
void InitAll(void); //inits system
void DisplayAll(void); //displays OT contents onscreen
u_long DSPadRead(void); //gets button info from pads
void GetStablePad(int); //makes pads stable (specify which pad 0 or 1)

/************ methods ***************/
int main(void) {
int i, currentVibBuff=0;
u_long pad, oldPad;
static u_char align[6]={0,1,0xFF,0xFF,0xFF,0xFF}; //array used to 'align' activators
GsLINE pointer; //line used to point to actuator values onscreen

ResetCallback();

SetVideoMode(MODE_PAL);
InitAll();

InitDSPads(); //init dual shock pads

pointer.y0=pointer.y1=20; //init pointer line for pointing to act. values onscreen
pointer.x0=10; pointer.x1=25;
pointer.r=pointer.g=pointer.b=255;
pointer.attribute=0;

for(i=0; i<vibBuffLength;i++) //this makes sure the transmission buffer is empty (all zeros=no vibration)
transmissionBuffer[DS_PAD_1][i]=0x00;

GetStablePad(DS_PAD_1); //before setting up the transmission buffers pads must be in stable state
PadSetAct(DS_PAD_1, transmissionBuffer[DS_PAD_1], vibBuffLength); //registers transmission buffer (call this once)

// GetStablePad(DS_PAD_2); //before setting up the transmission buffers pads must be in stable state
// PadSetAct(DS_PAD_2, transmissionBuffer[DS_PAD_2], vibBuffLength); //registers transmission buffer (call this once)

GetStablePad(DS_PAD_1); //before 'aligning' transmission buffers, pads must be in stable state
if (!PadSetActAlign(DS_PAD_1, align)) {printf("error aligning pad 1's actuators"); exit(-1);}

GetStablePad(DS_PAD_1); //before getting PadInfoAct, pads must be in stable state
printf("total number of actuators in pad 1 is %d\n",PadInfoAct(DS_PAD_1, -1, 0)); //get info about actuator 1 in pad 1
printf("total number of actuators in pad 2 is %d\n",PadInfoAct(DS_PAD_2, -1, 0)); //get info about actuator 1 in pad 1
GetStablePad(DS_PAD_1); //yep you guessed it :)
printf("pad 1 InfoMode is %d\n",PadInfoMode(DS_PAD_1, 1, 2)); //get info about the mode of pad1

//now, to make pad vibrate just put correct info into transmissionBuffer

while(1) { //this is the main loop
if(pad&Pad1tri) {
//pressing triangle stops pads vibrating by setting trans. buffers to 0
printf("no more vibrations\n");
for(i=0; i<vibBuffLength;i++)
transmissionBuffer[DS_PAD_1][i]=0x00;
}

//the next 2 control the amount of vibration
if(pad&Pad1Up) {if(transmissionBuffer[DS_PAD_1][currentVibBuff]<250) transmissionBuffer[DS_PAD_1][currentVibBuff]+=1;}
if(pad&Pad1Down) {if(transmissionBuffer[DS_PAD_1][currentVibBuff]>0) transmissionBuffer[DS_PAD_1][currentVibBuff]-=1;}
//these control the movement of the onscreen 'pointer'
if(pad&Pad1Left) if ((oldPad!=pad)&&(pointer.x0>30)) {currentVibBuff--; pointer.x0-=24; pointer.x1-=24;}
if(pad&Pad1Right) if ((oldPad!=pad)&&(pointer.x0<10+(vibBuffLength-1)*24)) {currentVibBuff++; pointer.x0+=24; pointer.x1+=24;}

if(pad&Pad1crc) {
//this aligns pads - use it if pads will not vibrate when X is pressed
//(this will occur if pad mode is changed from digital to analogue)
printf("aligning pads\n");
GetStablePad(DS_PAD_1);
PadSetAct(DS_PAD_1, transmissionBuffer[DS_PAD_1], vibBuffLength);
GetStablePad(DS_PAD_1);
if (!PadSetActAlign(DS_PAD_1, align)) {printf("error aligning pad 1's actuators"); exit(-1);}
}

if(pad&Pad1x) {
//this puts max. values in all the positions of the transmission buffer
printf("vibrating pad\n");
for(i=0; i<vibBuffLength;i++)
transmissionBuffer[DS_PAD_1][i]=0xFF;
}

activeBuffer=GsGetActiveBuff();
GsSetWorkBase((PACKET*)GPUPacketArea[activeBuffer]);
GsClearOt(0, 0, &myOT[activeBuffer]);
//print the values of trans. buffer to screen
for (i=0; i<vibBuffLength; i++)
FntPrint("%2x ",transmissionBuffer[DS_PAD_1][i]);
// FntPrint("\n\npad1: act1=%d act2=%d", PadInfoAct(DS_PAD_1, 0, 1), PadInfoAct(DS_PAD_1, 1, 1));
GsSortLine(&pointer, &myOT[activeBuffer], 0);
DisplayAll();
oldPad=pad;
pad=DSPadRead();
}
printf("finished\n");
return(0);
}

int InitDSPads(void) {
printf("about to init DS Pad\n");
PadInitDirect(padbuff[DS_PAD_1], padbuff[DS_PAD_2]); //inits both controllers
//cant use PadInit() as it will not transfer information to padds properly
PadStartCom();
PadEnableCom(3); //enables both controllers
}

void DisplayAll(void) {
DrawSync(0);
VSync(0);
GsSwapDispBuff();
GsSortClear(0,0,0,&myOT[activeBuffer]);
GsDrawOt(&myOT[activeBuffer]);
FntFlush(-1);
}

void InitAll(void) {
GsInitGraph(SCREEN_WIDTH, SCREEN_HEIGHT, GsINTER|GsOFSGPU, 0,0);
GsDefDispBuff(0,0,0,SCREEN_HEIGHT);
myOT[0].length=OT_LENGTH;
myOT[1].length=OT_LENGTH;
myOT[0].org=myOT_TAG[0];
myOT[1].org=myOT_TAG[1];
GsClearOt(0,0,&myOT[0]);
GsClearOt(0,0,&myOT[1]);

FntLoad(960, 256);
FntOpen(10,10,SCREEN_WIDTH-10,SCREEN_HEIGHT-20,0,512);
SetDispMask(1); /* start display */
}

u_long DSPadRead(void) {
return(~(*(*padbuff+3) | *(*padbuff+2) << 8 | *(*padbuff+3) << 16 | *(*padbuff+2) << 24));
}

void GetStablePad(int port) {
//this is just a simple loop that keeps going till both pads are in a stable state
while (PadGetState(port)!=PadStateStable)
;//loop till both pads are in a stable state
}

← previous
next →
loading
sending ...
New to Neperos ? Sign Up for free
download Neperos App from Google Play
install Neperos as PWA

Let's discover also

Recent Articles

Recent Comments

Neperos cookies
This website uses cookies to store your preferences and improve the service. Cookies authorization will allow me and / or my partners to process personal data such as browsing behaviour.

By pressing OK you agree to the Terms of Service and acknowledge the Privacy Policy

By pressing REJECT you will be able to continue to use Neperos (like read articles or write comments) but some important cookies will not be set. This may affect certain features and functions of the platform.
OK
REJECT