00001
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
00060 sceSifInitRpc(0);
00061
00062
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
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);
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
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
00123
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 ) {
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
00140 CurStatus.buttons ^= 0xffff;
00141 }
00142
00143
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
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
00185 stickCur->xPos = 0.0f;
00186
00187 if ( !FuzzyEqualsi(stickLast->xVal, stickCur->xCenter, kStickDeadRadius) )
00188 isChanged = true;
00189 }
00190 if ( !FuzzyEqualsi(stickCur->yVal, stickCur->yCenter, kStickDeadRadius) ) {
00191
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
00199 stickCur->yPos = 0.0f;
00200
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