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

ps2gl version cvs