00001
00004 #include <iostream>
00005 #include <string.h>
00006 #include "Joypad.h"
00007
00016 NablaPS2Utils::JoypadManager::JoypadManager(int JoypadNumber) : m_AStickTreshold(30) {
00017
00018
00019 PadHandle = open(JoyDev[JoypadNumber], O_RDONLY);
00020 if (Status() == PS2PAD_STAT_READY) {
00021
00022 m_UpdateType();
00023 if (m_Type != PS2PAD_TYPE_DUALSHOCK &&
00024 m_Type != PS2PAD_TYPE_DIGITAL)
00025 Close();
00026 }
00027 m_AnalogLocked = false;
00028
00029
00030 memset(m_AnalogStick, 0, sizeof(m_AnalogStick));
00031 memset(m_Buttons, 0, sizeof(m_Buttons));
00032 }
00033
00040 NablaPS2Utils::JoypadManager::~JoypadManager() {
00041
00042 UnlockAnalogMode();
00043 Close();
00044 }
00045
00051 void NablaPS2Utils::JoypadManager::m_UpdateType() {
00052
00053 m_ReadData();
00054 PadDataType *Data = (PadDataType *) m_PadData;
00055 m_Type = Data->Type;
00056 }
00057
00067 int NablaPS2Utils::JoypadManager::Status() {
00068
00069 if (PadHandle > 0) {
00070
00071 ioctl(PadHandle, PS2PAD_IOCGETSTAT, &m_Status);
00072 while(m_Status == PS2PAD_STAT_BUSY) {
00073
00074 ioctl(PadHandle, PS2PAD_IOCGETSTAT, &m_Status);
00075 }
00076 }
00077 else {
00078
00079 m_Status = PS2PAD_STAT_ERROR;
00080 }
00081 return m_Status;
00082 }
00083
00088 void NablaPS2Utils::JoypadManager::WaitUntilBusy() {
00089
00090 if (PadHandle > 0) {
00091
00092 int Status;
00093 ioctl(PadHandle, PS2PAD_IOCGETSTAT, &Status);
00094 while(Status == PS2PAD_STAT_BUSY) {
00095
00096 ioctl(PadHandle, PS2PAD_IOCGETSTAT, &Status);
00097 }
00098 }
00099 }
00106 bool NablaPS2Utils::JoypadManager::ReadPadData() {
00107
00108 return m_ReadData();
00109 }
00113 int NablaPS2Utils::JoypadManager::GetType() {
00114
00115 return m_Type;
00116 }
00117
00127 bool NablaPS2Utils::JoypadManager::SetAnalogMode(bool AMEnable) {
00128
00129 ps2pad_mode PS2PMode;
00130 PS2PMode.lock = 1;
00131 if (AMEnable)
00132 PS2PMode.offs = 1;
00133 else
00134 PS2PMode.offs = 0;
00135 ioctl(PadHandle, PS2PAD_IOCSETMODE, &PS2PMode);
00136
00137
00138 m_UpdateType();
00139 return true;
00140 }
00141
00148 bool NablaPS2Utils::JoypadManager::LockAnalogMode() {
00149
00150 m_AnalogLocked = true;
00151 ps2pad_mode PS2PMode;
00152 PS2PMode.offs = 1;
00153 PS2PMode.lock = 3;
00154 ioctl(PadHandle, PS2PAD_IOCSETMODE, &PS2PMode);
00155 return true;
00156 }
00157
00162 bool NablaPS2Utils::JoypadManager::UnlockAnalogMode() {
00163
00164 if (m_AnalogLocked) {
00165
00166 ps2pad_mode PS2PMode;
00167 PS2PMode.offs = 1;
00168 PS2PMode.lock = 2;
00169 ioctl(PadHandle, PS2PAD_IOCSETMODE, &PS2PMode);
00170 }
00171 return true;
00172 }
00178 bool NablaPS2Utils::JoypadManager::AnalogButtonSupported() {
00179
00180 int Supported = 0;
00181 if (Status() == PS2PAD_STAT_READY) {
00182
00183 ioctl(PadHandle, PS2PAD_IOCPRESSMODEINFO, &Supported);
00184 }
00185 return Supported == 1;
00186 }
00187
00192 void NablaPS2Utils::JoypadManager::EnableActuators() {
00193
00194
00195 ps2pad_act PSact;
00196 memset(PSact.data, -1, sizeof(PSact.data));
00197 PSact.len = 6;
00198 PSact.data[0] = 0;
00199 PSact.data[1] = 1;
00200 ioctl(PadHandle, PS2PAD_IOCSETACTALIGN, &PSact);
00201
00202 WaitUntilBusy();
00203 m_constActuatorStatus = false;
00204 m_VariableActuatorValue = 0;
00205 }
00206
00211 bool NablaPS2Utils::JoypadManager::ActuatorsSupported() {
00212
00213 ps2pad_actinfo PSActInfo;
00214
00215
00216 PSActInfo.actno = -1;
00217 PSActInfo.term = 0;
00218 PSActInfo.result = 0;
00219 ioctl(PadHandle, PS2PAD_IOCACTINFO, &PSActInfo);
00220
00221
00222 return (PSActInfo.result == 2);
00223 }
00224
00232 void NablaPS2Utils::JoypadManager::SetActuatorConst(bool Status) {
00233
00234
00235 if (m_Type == PS2PAD_TYPE_DUALSHOCK) {
00236
00237 ps2pad_act PSact;
00238 PSact.len = 6;
00239 memset(PSact.data, -1, sizeof(PSact.data));
00240 if (Status)
00241 PSact.data[0] = 1;
00242 else
00243 PSact.data[0] = 0;
00244
00245 PSact.data[1] = m_VariableActuatorValue;
00246
00247 m_constActuatorStatus = Status;
00248 ioctl(PadHandle, PS2PAD_IOCSETACT, &PSact);
00249 }
00250 }
00251
00257 void NablaPS2Utils::JoypadManager::SetActuatorVariable(unsigned char Value) {
00258
00259 if (m_Type == PS2PAD_TYPE_DUALSHOCK) {
00260
00261 ps2pad_act PSact;
00262 PSact.len = 6;
00263 memset(PSact.data, -1, sizeof(PSact.data));
00264 PSact.data[1] = Value;
00265 PSact.data[0] = m_constActuatorStatus;
00266 m_VariableActuatorValue = PSact.data[1];
00267 ioctl(PadHandle, PS2PAD_IOCSETACT, &PSact);
00268 }
00269 }
00276 bool NablaPS2Utils::JoypadManager::SetAnalogButtonStatus(bool ABEnable) {
00277
00278 if (Status() == PS2PAD_STAT_READY) {
00279
00280 if (ABEnable)
00281 ioctl(PadHandle, PS2PAD_IOCENTERPRESSMODE);
00282 else
00283 ioctl(PadHandle, PS2PAD_IOCEXITPRESSMODE);
00284 m_AnalogButtonEnabled = ABEnable;
00285 return true;
00286 }
00287 return false;
00288 }
00289
00293 void NablaPS2Utils::JoypadManager::Close() {
00294
00295 if (PadHandle >= 0)
00296 close(PadHandle);
00297 PadHandle = -1;
00298 }
00299
00300
00306 bool NablaPS2Utils::JoypadManager::m_ReadData() {
00307
00308 if (Status() == PS2PAD_STAT_READY) {
00309
00310 int ReadBytes = read(PadHandle, m_PadData, PS2PAD_DATASIZE);
00311 if (ReadBytes > 0) {
00312
00313
00314 m_AnalyzeRead();
00315 return true;
00316 }
00317 }
00318
00319
00320 return false;
00321 }
00322
00329 float NablaPS2Utils::JoypadManager::m_ReadStickValueX(unsigned char Value) {
00330
00331
00332
00333 float Unbiased = Value - 127.5;
00334 if (Unbiased < m_AStickTreshold && Unbiased > -m_AStickTreshold) {
00335
00336 return 0.0f;
00337 }
00338 return Unbiased / 127.5f;
00339 }
00340
00347 float NablaPS2Utils::JoypadManager::m_ReadStickValueY(unsigned char Value) {
00348
00349 float Unbiased = Value - 127.5;
00350 if (Unbiased < m_AStickTreshold && Unbiased > -m_AStickTreshold) {
00351
00352 return 0.0f;
00353 }
00354
00355
00356
00357 return -Unbiased / 127.5f;
00358 }
00359
00366 void NablaPS2Utils::JoypadManager::m_AnalyzeRead() {
00367
00368
00369
00370
00371 PadDataType *Data = (PadDataType *) m_PadData;
00372 for (int I = 0; I < 16; ++I) {
00373
00374 int CurStatus = Data->DButtons & (1 << I);
00375 if (CurStatus) {
00376
00377
00378
00379
00380 if (m_Buttons[I].State == Pressed || m_Buttons[I].State == MPressed)
00381 m_Buttons[I].State = Released;
00382 else
00383 m_Buttons[I].State = Unpressed;
00384 }
00385 else {
00386
00387 if (m_Buttons[I].State == Unpressed || m_Buttons[I].State == Released)
00388 m_Buttons[I].State = Pressed;
00389 else
00390 m_Buttons[I].State = MPressed;
00391 }
00392 }
00393
00394
00395 m_AnalogStick[RX] = m_ReadStickValueX(Data->AnalogSRX);
00396 m_AnalogStick[RY] = m_ReadStickValueY(Data->AnalogSRY);
00397 m_AnalogStick[LX] = m_ReadStickValueX(Data->AnalogSLX);
00398 m_AnalogStick[LY] = m_ReadStickValueY(Data->AnalogSLY);
00399
00400
00401 if (m_AnalogButtonEnabled) {
00402
00403 m_Buttons[CIRCLE].PressureLevel = Data->PadCircle / 255.0f;
00404 m_Buttons[SQUARE].PressureLevel = Data->PadSquare / 255.0f;
00405 m_Buttons[TRIANGLE].PressureLevel = Data->PadTriangle / 255.0f;
00406 m_Buttons[CROSS].PressureLevel = Data->PadCross / 255.0f;
00407 m_Buttons[R1].PressureLevel = Data->PadR1 / 255.0f;
00408 m_Buttons[R2].PressureLevel = Data->PadR2 / 255.0f;
00409 m_Buttons[L1].PressureLevel = Data->PadL1 / 255.0f;
00410 m_Buttons[L2].PressureLevel = Data->PadL2 / 255.0f;
00411 m_Buttons[LEFT].PressureLevel = Data->PadL / 255.0f;
00412 m_Buttons[DOWN].PressureLevel = Data->PadD / 255.0f;
00413 m_Buttons[RIGHT].PressureLevel = Data->PadR / 255.0f;
00414 m_Buttons[UP].PressureLevel = Data->PadU / 255.0f;
00415 }
00416 }