Main Page   Modules   Namespace List   Class Hierarchy   Alphabetical List   Compound List   File List   Namespace Members   Compound Members   File Members  

pads.cpp

Go to the documentation of this file.
00001 /*           Copyright (C) 2001 Sony Computer Entertainment America
00002                               All Rights Reserved
00003                                SCEA Confidential                                */
00004 
00005 /********************************************
00006  * includes
00007  */
00008 
00009 #include <stdio.h>
00010 #include <string.h>
00011 
00012 #include "eetypes.h"
00013 #include "sifdev.h"
00014 #include "sifrpc.h"
00015 
00016 #include "pads.h"
00017 #include "ps2s/math.h"
00018 
00019 /********************************************
00020  * constants
00021  */
00022 
00023 #define kPad0   0
00024 #define kPad1   1
00025 
00026 #define kPort0  0
00027 #define kSlot0  0
00028 
00029 #define kPadModeStandard 0x4
00030 #define kPadModeAnalog   0x7
00031 
00032 #define kPadSetLockModeUnchanged 0
00033 #define kPadSetLockModeLock 3
00034 #define kPadSetLockModeUnlock 1
00035 
00036 #define kStickMaxRadius 120
00037 #define kStickDeadRadius 25
00038 
00039 /********************************************
00040  * globals
00041  */
00042 
00043 CPad Pad0( kPad0 );
00044 CPad Pad1( kPad1 );
00045 
00046 /********************************************
00047  * Pads
00048  */
00049 
00050 void
00051 Pads::Init( const char* module_path )
00052 {
00053    char temp_buffer[256];
00054    int module_path_len = strlen(module_path);
00055 
00056    // open the pads.. this should be elsewhere..
00057    sceSifInitRpc(0);
00058 
00059    /* load sio2man.irx */
00060    strncpy( temp_buffer, module_path, 256 );
00061    if (temp_buffer[module_path_len-1] == '/')
00062       temp_buffer[module_path_len-1] = '\0';
00063    strncat( temp_buffer, "/sio2man.irx", 256-strlen(temp_buffer) );
00064    if (sceSifLoadModule(temp_buffer, 0, NULL) < 0)
00065    {
00066       printf("Can't load module sio2man\n");
00067       exit(0);
00068    }
00069    /* load padman.irx */
00070    strncpy( temp_buffer, module_path, 256 );
00071    if (temp_buffer[module_path_len-1] == '/')
00072       temp_buffer[module_path_len-1] = '\0';
00073    strncat( temp_buffer, "/padman.irx", 256-strlen(temp_buffer) );
00074    if (sceSifLoadModule(temp_buffer,0, NULL) < 0)
00075    {
00076       printf("Can't load module padman\n");
00077       exit(0);
00078    }
00079 
00080    scePadInit(0); // "must be zero"
00081 
00082    if ( ! Pad0.Open() ) {
00083       printf("Couldn't open Pad0.\n");
00084       exit(-1);
00085    }
00086 }
00087 
00088 void
00089 Pads::Read( void )
00090 {
00091    Pad0.Read();
00092 }
00093 
00094 /********************************************
00095  * CPad
00096  */
00097 
00098 CPad::CPad( unsigned int port )
00099    : uiPort(port), bPadModeSet(false)
00100 {
00101    memset( &CurStatus, 0, sizeof(tPadStatus) );
00102    memset( &LastStatus, 0, sizeof(tPadStatus) );
00103 }
00104 
00105 bool
00106 CPad::Open( void )
00107 {
00108    // slot is only for use with multitap
00109    return scePadPortOpen(uiPort, kSlot0, DmaBuffer);
00110 }
00111 
00112 void
00113 CPad::Read( void )
00114 {
00115    t32 padState = scePadGetState( kPort0, kSlot0 );
00116    if ( padState != scePadStateStable ) return;
00117         
00118    if ( !bPadModeSet ) {
00119       // who knows what the 1 parameter is..  a return val of 1 indicates that the request is
00120       // being processed
00121       if ( scePadSetMainMode(uiPort, kSlot0, 1, kPadSetLockModeUnlock) == 1 )
00122          bPadModeSet = true;
00123    }
00124    else {
00125       tPadStatus padStatus;
00126       scePadRead( uiPort, kSlot0, (tU8*)&padStatus );
00127 
00128       if ( padStatus.success == 0 ) { // 0 indicates success
00129          LastStatus = CurStatus;
00130          padStatus.rightStick = CurStatus.rightStick;
00131          padStatus.leftStick = CurStatus.leftStick;
00132          CurStatus = padStatus;
00133 
00134          t32 id = scePadInfoMode( uiPort, kSlot0, InfoModeCurID, 0 );
00135          if ( id == kPadModeStandard || id == kPadModeAnalog ) {
00136                                 // flip the sense of the bit field (1 = pressed)
00137             CurStatus.buttons ^= 0xffff;
00138          }
00139 
00140          // sticks
00141          if ( WasPushed( Pads::kSelect ) ) {
00142             CurStatus.leftStick.isCentered = false;
00143             CurStatus.rightStick.isCentered = false;
00144          }
00145          CurStatus.leftStick.xVal = CurStatus.l3h;
00146          CurStatus.leftStick.yVal = CurStatus.l3v;
00147          CurStatus.rightStick.xVal = CurStatus.r3h;
00148          CurStatus.rightStick.yVal = CurStatus.r3v;
00149          UpdateStick( &CurStatus.leftStick, &LastStatus.leftStick );
00150          UpdateStick( &CurStatus.rightStick, &LastStatus.rightStick );
00151       }
00152    }
00153 }
00154 
00155 bool
00156 CPad::UpdateStick( tStickData* stickCur, tStickData* stickLast )
00157 {
00158    t8 temp;
00159    bool isChanged = false;
00160 
00161    using namespace Math;
00162 
00163    if ( ! stickCur->isCentered ) {
00164       stickCur->xCenter = stickCur->xVal;
00165       stickCur->yCenter = stickCur->yVal;
00166       stickCur->xPos = 0.0f;
00167       stickCur->yPos = 0.0f;
00168       stickCur->isCentered = true;
00169 
00170       isChanged = true;
00171    }
00172    else {
00173       if ( !FuzzyEqualsi(stickCur->xVal, stickCur->xCenter, kStickDeadRadius) ) {
00174          // stick is not inside the dead zone
00175          temp = ((stickCur->xVal > stickCur->xCenter) ? -kStickDeadRadius : kStickDeadRadius);
00176          stickCur->xPos = (float)(stickCur->xVal - stickCur->xCenter + temp) /
00177             (float)kStickMaxRadius;
00178          isChanged = TRUE;
00179       }
00180       else {
00181          // stick is inside the dead zone
00182          stickCur->xPos = 0.0f;
00183          // if it just entered the dead zone, send out one last event
00184          if ( !FuzzyEqualsi(stickLast->xVal, stickCur->xCenter, kStickDeadRadius) )
00185             isChanged = true;
00186       }
00187       if ( !FuzzyEqualsi(stickCur->yVal, stickCur->yCenter, kStickDeadRadius) ) {
00188          // stick is not inside the dead zone
00189          temp = (stickCur->yVal > stickCur->yCenter) ? kStickDeadRadius : -kStickDeadRadius;
00190          stickCur->yPos = (float)(stickCur->yCenter - stickCur->yVal + temp) /
00191             (float)kStickMaxRadius;
00192          isChanged = true;
00193       }
00194       else {
00195          // stick is inside the dead zone
00196          stickCur->yPos = 0.0f;
00197          // if it just entered the dead zone, send out one last event
00198          if ( !FuzzyEqualsi(stickLast->yVal, stickCur->yCenter, kStickDeadRadius) )
00199             isChanged = true;
00200       }
00201 
00202       stickCur->xPos = Clamp( stickCur->xPos, -1.0f, 1.0f );
00203       stickCur->yPos = Clamp( stickCur->yPos, -1.0f, 1.0f );
00204    }
00205 
00206    return isChanged;
00207 }
00208 
00209 bool
00210 CPad::IsDown( unsigned int button )
00211 {
00212    return CurStatus.buttons & (1 << button);
00213 }
00214 
00215 bool
00216 CPad::IsUp( unsigned int button )
00217 {
00218    return ! (CurStatus.buttons & (1 << button));
00219 }
00220 
00221 bool
00222 CPad::WasPushed( unsigned int button )
00223 {
00224    return (CurStatus.buttons & (1 << button)) && ! (LastStatus.buttons & (1 << button));
00225 }
00226 
00227 bool
00228 CPad::WasReleased( unsigned int button )
00229 {
00230    return ! ((CurStatus.buttons & (1 << button)) && ! (LastStatus.buttons & (1 << button)));
00231 }
00232 

ps2gl version 0.2