Bug Summary

File:Source/Core/Core/Src/HW/SI_DeviceDanceMat.cpp
Location:line 67, column 24
Description:The left operand of '>>' is a garbage value

Annotated Source Code

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 ---
25CSIDevice_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
44int 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)
1
Control jumps to 'case CMD_DIRECT:' at line 59
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;
2
Variable 'low' declared without an initial value
63 GetData(high, low);
3
Calling 'GetData'
22
Returning from 'GetData'
64 for (int i = 0; i < (_iLength - 1) / 2; i++)
23
Loop condition is true. Entering loop body
65 {
66 _pBuffer[0 + i] = (high >> (i * 8)) & 0xff;
67 _pBuffer[4 + i] = (low >> (i * 8)) & 0xff;
24
The left operand of '>>' is a garbage value
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?)
114bool 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))
4
Taking false branch
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())
5
Taking false branch
133 {
134 Movie::PlayController(&PadStatus, ISIDevice::m_iDeviceNumber);
135 Movie::InputUpdate();
136 }
137 else if(Movie::IsRecordingInput())
6
Taking false branch
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)
7
Taking false branch
151 map |= 0x1000;
152 if (PadStatus.button & PAD_BUTTON_DOWN0x0004)
8
Taking false branch
153 map |= 0x2;
154 if (PadStatus.button & PAD_BUTTON_LEFT0x0001)
9
Taking false branch
155 map |= 0x8;
156 if (PadStatus.button & PAD_BUTTON_RIGHT0x0002)
10
Taking false branch
157 map |= 0x4;
158 if (PadStatus.button & PAD_BUTTON_Y0x0800)
11
Taking false branch
159 map |= 0x200;
160 if (PadStatus.button & PAD_BUTTON_A0x0100)
12
Taking false branch
161 map |= 0x10;
162 if (PadStatus.button & PAD_BUTTON_B0x0200)
13
Taking false branch
163 map |= 0x100;
164 if (PadStatus.button & PAD_BUTTON_X0x0400)
14
Taking false branch
165 map |= 0x800;
166 if (PadStatus.button & PAD_TRIGGER_Z0x0010)
15
Taking false branch
167 map |= 0x400;
168 if (PadStatus.button & PAD_BUTTON_START0x1000)
16
Taking false branch
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)
17
Taking false branch
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)
18
Taking false branch
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)
19
Taking false branch
193 {
194 // Identifies the dance mat
195 _Low = 0x8080ffff;
196 }
197 else if (m_Mode == 3)
20
Taking false branch
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)
21
Taking false branch
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
218void 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_GetPadNum(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
257void 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}