| File: | Source/Core/Core/Src/HW/SI_DeviceDanceMat.cpp |
| Location: | line 67, column 28 |
| Description: | The left operand of '>>' is a garbage value |
| 1 | // Copyright 2013 Dolphin Emulator Project | |||
| 2 | // Licensed under GPLv2 | |||
| 3 | // Refer to the license.txt file included. | |||
| 4 | ||||
| 5 | #include <stdio.h> | |||
| 6 | #include <stdlib.h> | |||
| 7 | ||||
| 8 | #include "SI.h" | |||
| 9 | #include "SI_Device.h" | |||
| 10 | #include "SI_DeviceDanceMat.h" | |||
| 11 | ||||
| 12 | #include "EXI_Device.h" | |||
| 13 | #include "EXI_DeviceMic.h" | |||
| 14 | ||||
| 15 | #include "GCPad.h" | |||
| 16 | ||||
| 17 | #include "../Movie.h" | |||
| 18 | ||||
| 19 | #include "../CoreTiming.h" | |||
| 20 | #include "SystemTimers.h" | |||
| 21 | #include "ProcessorInterface.h" | |||
| 22 | #include "../Core.h" | |||
| 23 | ||||
| 24 | // --- Dance mat gamecube controller --- | |||
| 25 | CSIDevice_DanceMat::CSIDevice_DanceMat(SIDevices device, int _iDeviceNumber) | |||
| 26 | : ISIDevice(device, _iDeviceNumber) | |||
| 27 | , m_TButtonComboStart(0) | |||
| 28 | , m_TButtonCombo(0) | |||
| 29 | , m_LastButtonCombo(COMBO_NONE) | |||
| 30 | { | |||
| 31 | memset(&m_Origin, 0, sizeof(SOrigin)); | |||
| 32 | m_Origin.uCommand = CMD_ORIGIN; | |||
| 33 | m_Origin.uOriginStickX = 0x80; // center | |||
| 34 | m_Origin.uOriginStickY = 0x80; | |||
| 35 | m_Origin.uSubStickStickX = 0x80; | |||
| 36 | m_Origin.uSubStickStickY = 0x80; | |||
| 37 | m_Origin.uTrigger_L = 0x00; | |||
| 38 | m_Origin.uTrigger_R = 0x00; | |||
| 39 | ||||
| 40 | // Dunno if we need to do this, game/lib should set it? | |||
| 41 | m_Mode = 0x03; | |||
| 42 | } | |||
| 43 | ||||
| 44 | int CSIDevice_DanceMat::RunBuffer(u8* _pBuffer, int _iLength) | |||
| 45 | { | |||
| 46 | // For debug logging only | |||
| 47 | ISIDevice::RunBuffer(_pBuffer, _iLength); | |||
| 48 | ||||
| 49 | // Read the command | |||
| 50 | EBufferCommands command = static_cast<EBufferCommands>(_pBuffer[3]); | |||
| 51 | ||||
| 52 | // Handle it | |||
| 53 | switch (command) | |||
| ||||
| 54 | { | |||
| 55 | case CMD_RESET: | |||
| 56 | *(u32*)&_pBuffer[0] = SI_DANCEMAT; | |||
| 57 | break; | |||
| 58 | ||||
| 59 | case CMD_DIRECT: | |||
| 60 | { | |||
| 61 | INFO_LOG(SERIALINTERFACE, "PAD - Direct (Length: %d)", _iLength)do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::SERIALINTERFACE, "/home/anal/dolphin-emu/Source/Core/Core/Src/HW/SI_DeviceDanceMat.cpp" , 61, "PAD - Direct (Length: %d)", _iLength); } } while (0); | |||
| 62 | u32 high, low; | |||
| 63 | GetData(high, low); | |||
| 64 | for (int i = 0; i < (_iLength - 1) / 2; i++) | |||
| 65 | { | |||
| 66 | _pBuffer[0 + i] = (high >> (i * 8)) & 0xff; | |||
| 67 | _pBuffer[4 + i] = (low >> (i * 8)) & 0xff; | |||
| ||||
| 68 | } | |||
| 69 | } | |||
| 70 | break; | |||
| 71 | ||||
| 72 | case CMD_ORIGIN: | |||
| 73 | { | |||
| 74 | INFO_LOG(SERIALINTERFACE, "PAD - Get Origin")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::SERIALINTERFACE, "/home/anal/dolphin-emu/Source/Core/Core/Src/HW/SI_DeviceDanceMat.cpp" , 74, "PAD - Get Origin"); } } while (0); | |||
| 75 | u8* pCalibration = reinterpret_cast<u8*>(&m_Origin); | |||
| 76 | for (int i = 0; i < (int)sizeof(SOrigin); i++) | |||
| 77 | { | |||
| 78 | _pBuffer[i ^ 3] = *pCalibration++; | |||
| 79 | } | |||
| 80 | } | |||
| 81 | break; | |||
| 82 | ||||
| 83 | // Recalibrate (FiRES: i am not 100 percent sure about this) | |||
| 84 | case CMD_RECALIBRATE: | |||
| 85 | { | |||
| 86 | INFO_LOG(SERIALINTERFACE, "PAD - Recalibrate")do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::SERIALINTERFACE, "/home/anal/dolphin-emu/Source/Core/Core/Src/HW/SI_DeviceDanceMat.cpp" , 86, "PAD - Recalibrate"); } } while (0); | |||
| 87 | u8* pCalibration = reinterpret_cast<u8*>(&m_Origin); | |||
| 88 | for (int i = 0; i < (int)sizeof(SOrigin); i++) | |||
| 89 | { | |||
| 90 | _pBuffer[i ^ 3] = *pCalibration++; | |||
| 91 | } | |||
| 92 | } | |||
| 93 | break; | |||
| 94 | ||||
| 95 | // DEFAULT | |||
| 96 | default: | |||
| 97 | { | |||
| 98 | ERROR_LOG(SERIALINTERFACE, "Unknown SI command (0x%x)", command)do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR , LogTypes::SERIALINTERFACE, "/home/anal/dolphin-emu/Source/Core/Core/Src/HW/SI_DeviceDanceMat.cpp" , 98, "Unknown SI command (0x%x)", command); } } while (0 ); | |||
| 99 | PanicAlert("SI: Unknown command (0x%x)", command)MsgAlert(false, WARNING, "SI: Unknown command (0x%x)", command ); | |||
| 100 | } | |||
| 101 | break; | |||
| 102 | } | |||
| 103 | ||||
| 104 | return _iLength; | |||
| 105 | } | |||
| 106 | ||||
| 107 | ||||
| 108 | // GetData | |||
| 109 | ||||
| 110 | // Return true on new data (max 7 Bytes and 6 bits ;) | |||
| 111 | // [00?SYXBA] [1LRZUDRL] [x] [y] [cx] [cy] [l] [r] | |||
| 112 | // |\_ ERR_LATCH (error latched - check SISR) | |||
| 113 | // |_ ERR_STATUS (error on last GetData or SendCmd?) | |||
| 114 | bool CSIDevice_DanceMat::GetData(u32& _Hi, u32& _Low) | |||
| 115 | { | |||
| 116 | SPADStatus PadStatus; | |||
| 117 | memset(&PadStatus, 0, sizeof(PadStatus)); | |||
| 118 | ||||
| 119 | Pad::GetStatus(ISIDevice::m_iDeviceNumber, &PadStatus); | |||
| 120 | Movie::CallInputManip(&PadStatus, ISIDevice::m_iDeviceNumber); | |||
| 121 | ||||
| 122 | u32 netValues[2]; | |||
| 123 | if (NetPlay_GetInput(ISIDevice::m_iDeviceNumber, PadStatus, netValues)) | |||
| 124 | { | |||
| 125 | _Hi = netValues[0]; // first 4 bytes | |||
| 126 | _Low = netValues[1]; // last 4 bytes | |||
| 127 | return true; | |||
| 128 | } | |||
| 129 | ||||
| 130 | Movie::SetPolledDevice(); | |||
| 131 | ||||
| 132 | if(Movie::IsPlayingInput()) | |||
| 133 | { | |||
| 134 | Movie::PlayController(&PadStatus, ISIDevice::m_iDeviceNumber); | |||
| 135 | Movie::InputUpdate(); | |||
| 136 | } | |||
| 137 | else if(Movie::IsRecordingInput()) | |||
| 138 | { | |||
| 139 | Movie::RecordInput(&PadStatus, ISIDevice::m_iDeviceNumber); | |||
| 140 | Movie::InputUpdate(); | |||
| 141 | } | |||
| 142 | else | |||
| 143 | { | |||
| 144 | Movie::CheckPadStatus(&PadStatus, ISIDevice::m_iDeviceNumber); | |||
| 145 | } | |||
| 146 | ||||
| 147 | // Map the dpad to the blue arrows, the buttons to the orange arrows | |||
| 148 | // Z = + button, Start = - button | |||
| 149 | u16 map = 0; | |||
| 150 | if (PadStatus.button & PAD_BUTTON_UP0x0008) | |||
| 151 | map |= 0x1000; | |||
| 152 | if (PadStatus.button & PAD_BUTTON_DOWN0x0004) | |||
| 153 | map |= 0x2; | |||
| 154 | if (PadStatus.button & PAD_BUTTON_LEFT0x0001) | |||
| 155 | map |= 0x8; | |||
| 156 | if (PadStatus.button & PAD_BUTTON_RIGHT0x0002) | |||
| 157 | map |= 0x4; | |||
| 158 | if (PadStatus.button & PAD_BUTTON_Y0x0800) | |||
| 159 | map |= 0x200; | |||
| 160 | if (PadStatus.button & PAD_BUTTON_A0x0100) | |||
| 161 | map |= 0x10; | |||
| 162 | if (PadStatus.button & PAD_BUTTON_B0x0200) | |||
| 163 | map |= 0x100; | |||
| 164 | if (PadStatus.button & PAD_BUTTON_X0x0400) | |||
| 165 | map |= 0x800; | |||
| 166 | if (PadStatus.button & PAD_TRIGGER_Z0x0010) | |||
| 167 | map |= 0x400; | |||
| 168 | if (PadStatus.button & PAD_BUTTON_START0x1000) | |||
| 169 | map |= 0x1; | |||
| 170 | ||||
| 171 | _Hi = (u32)(map << 16) | 0x8080; | |||
| 172 | ||||
| 173 | // Low bits are packed differently per mode | |||
| 174 | if (m_Mode == 0 || m_Mode == 5 || m_Mode == 6 || m_Mode == 7) | |||
| 175 | { | |||
| 176 | _Low = (u8)(PadStatus.analogB >> 4); // Top 4 bits | |||
| 177 | _Low |= (u32)((u8)(PadStatus.analogA >> 4) << 4); // Top 4 bits | |||
| 178 | _Low |= (u32)((u8)(PadStatus.triggerRight >> 4) << 8); // Top 4 bits | |||
| 179 | _Low |= (u32)((u8)(PadStatus.triggerLeft >> 4) << 12); // Top 4 bits | |||
| 180 | _Low |= (u32)((u8)(PadStatus.substickY) << 16); // All 8 bits | |||
| 181 | _Low |= (u32)((u8)(PadStatus.substickX) << 24); // All 8 bits | |||
| 182 | } | |||
| 183 | else if (m_Mode == 1) | |||
| 184 | { | |||
| 185 | _Low = (u8)(PadStatus.analogB >> 4); // Top 4 bits | |||
| 186 | _Low |= (u32)((u8)(PadStatus.analogA >> 4) << 4); // Top 4 bits | |||
| 187 | _Low |= (u32)((u8)PadStatus.triggerRight << 8); // All 8 bits | |||
| 188 | _Low |= (u32)((u8)PadStatus.triggerLeft << 16); // All 8 bits | |||
| 189 | _Low |= (u32)((u8)PadStatus.substickY << 24); // Top 4 bits | |||
| 190 | _Low |= (u32)((u8)PadStatus.substickX << 28); // Top 4 bits | |||
| 191 | } | |||
| 192 | else if (m_Mode == 2) | |||
| 193 | { | |||
| 194 | // Identifies the dance mat | |||
| 195 | _Low = 0x8080ffff; | |||
| 196 | } | |||
| 197 | else if (m_Mode == 3) | |||
| 198 | { | |||
| 199 | // Analog A/B are always 0 | |||
| 200 | _Low = (u8)PadStatus.triggerRight; // All 8 bits | |||
| 201 | _Low |= (u32)((u8)PadStatus.triggerLeft << 8); // All 8 bits | |||
| 202 | _Low |= (u32)((u8)PadStatus.substickY << 16); // All 8 bits | |||
| 203 | _Low |= (u32)((u8)PadStatus.substickX << 24); // All 8 bits | |||
| 204 | } | |||
| 205 | else if (m_Mode == 4) | |||
| 206 | { | |||
| 207 | _Low = (u8)(PadStatus.analogB); // All 8 bits | |||
| 208 | _Low |= (u32)((u8)(PadStatus.analogA) << 8); // All 8 bits | |||
| 209 | // triggerLeft/Right are always 0 | |||
| 210 | _Low |= (u32)((u8)PadStatus.substickY << 16); // All 8 bits | |||
| 211 | _Low |= (u32)((u8)PadStatus.substickX << 24); // All 8 bits | |||
| 212 | } | |||
| 213 | return true; | |||
| 214 | } | |||
| 215 | ||||
| 216 | ||||
| 217 | // SendCommand | |||
| 218 | void CSIDevice_DanceMat::SendCommand(u32 _Cmd, u8 _Poll) | |||
| 219 | { | |||
| 220 | UCommand command(_Cmd); | |||
| 221 | ||||
| 222 | switch (command.Command) | |||
| 223 | { | |||
| 224 | // Costis sent it in some demos :) | |||
| 225 | case 0x00: | |||
| 226 | break; | |||
| 227 | ||||
| 228 | case CMD_WRITE: | |||
| 229 | { | |||
| 230 | unsigned int uType = command.Parameter1; // 0 = stop, 1 = rumble, 2 = stop hard | |||
| 231 | unsigned int uStrength = command.Parameter2; | |||
| 232 | ||||
| 233 | // get the correct pad number that should rumble locally when using netplay | |||
| 234 | const u8 numPAD = NetPlay_InGamePadToLocalPad(ISIDevice::m_iDeviceNumber); | |||
| 235 | ||||
| 236 | if (numPAD < 4) | |||
| 237 | Pad::Rumble(numPAD, uType, uStrength); | |||
| 238 | ||||
| 239 | if (!_Poll) | |||
| 240 | { | |||
| 241 | m_Mode = command.Parameter2; | |||
| 242 | INFO_LOG(SERIALINTERFACE, "PAD %i set to mode %i", ISIDevice::m_iDeviceNumber, m_Mode)do { { if (LogTypes::LINFO <= 3) GenericLog(LogTypes::LINFO , LogTypes::SERIALINTERFACE, "/home/anal/dolphin-emu/Source/Core/Core/Src/HW/SI_DeviceDanceMat.cpp" , 242, "PAD %i set to mode %i", ISIDevice::m_iDeviceNumber, m_Mode ); } } while (0); | |||
| 243 | } | |||
| 244 | } | |||
| 245 | break; | |||
| 246 | ||||
| 247 | default: | |||
| 248 | { | |||
| 249 | ERROR_LOG(SERIALINTERFACE, "Unknown direct command (0x%x)", _Cmd)do { { if (LogTypes::LERROR <= 3) GenericLog(LogTypes::LERROR , LogTypes::SERIALINTERFACE, "/home/anal/dolphin-emu/Source/Core/Core/Src/HW/SI_DeviceDanceMat.cpp" , 249, "Unknown direct command (0x%x)", _Cmd); } } while ( 0); | |||
| 250 | PanicAlert("SI: Unknown direct command")MsgAlert(false, WARNING, "SI: Unknown direct command"); | |||
| 251 | } | |||
| 252 | break; | |||
| 253 | } | |||
| 254 | } | |||
| 255 | ||||
| 256 | // Savestate support | |||
| 257 | void CSIDevice_DanceMat::DoState(PointerWrap& p) | |||
| 258 | { | |||
| 259 | p.Do(m_Origin); | |||
| 260 | p.Do(m_Mode); | |||
| 261 | p.Do(m_TButtonComboStart); | |||
| 262 | p.Do(m_TButtonCombo); | |||
| 263 | p.Do(m_LastButtonCombo); | |||
| 264 | } |