Skip to content

Commit 86f0c1b

Browse files
authored
Merge pull request #43 from CreeperMario/master
Added support for alternate controls
2 parents 38aeec7 + cb147f6 commit 86f0c1b

File tree

12 files changed

+377
-17
lines changed

12 files changed

+377
-17
lines changed

data/images/player0_point.png

17.3 KB
Loading

hbas.elf

-2.78 MB
Binary file not shown.

hbas_dbg.elf

-2.97 MB
Binary file not shown.

src/Application.cpp

Lines changed: 68 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@
2020
#include "gui/FreeTypeGX.h"
2121
#include "gui/VPadController.h"
2222
#include "gui/WPadController.h"
23+
#include "gui/DVPadController.h"
24+
#include "gui/DWPadController.h"
2325
#include "resources/Resources.h"
2426
#include "sounds/SoundHandler.hpp"
2527
#include "utils/logger.h"
@@ -151,19 +153,79 @@ void Application::executeThread(void)
151153
log_printf("Entering main loop\n");
152154

153155
//! main GX2 loop (60 Hz cycle with max priority on core 1)
154-
while(!exitApplication)
155-
{
156-
//! Read out inputs
157-
for(int i = 0; i < 5; i++)
156+
while(!exitApplication)
157+
{
158+
//! Read out inputs
159+
for(int i = 0; i < 5; i++)
158160
{
161+
if(controller[i] == NULL) continue;
162+
159163
if(controller[i]->update(video->getTvWidth(), video->getTvHeight()) == false)
160164
continue;
161-
165+
162166
if(controller[i]->data.buttons_d & VPAD_BUTTON_HOME)
163167
exitApplication = true;
164-
168+
165169
//! update controller states
166170
mainWindow->update(controller[i]);
171+
172+
//If the + button on the GamePad is pressed, switch to DPAD mode and vice versa.
173+
if((i == 0) && (controller[i]->data.buttons_d & GuiTrigger::BUTTON_PLUS))
174+
{
175+
if(controller[i]->isDPadMode)
176+
{
177+
delete controller[i];
178+
controller[i] = new VPadController(GuiTrigger::CHANNEL_1);
179+
}
180+
else
181+
{
182+
delete controller[i];
183+
controller[i] = new DVPadController(GuiTrigger::CHANNEL_1);
184+
}
185+
}
186+
187+
//If the + button on any other controller is pressed, switch to DPAD mode and vice versa.
188+
else if(controller[i]->data.buttons_d & GuiTrigger::BUTTON_PLUS)
189+
{
190+
if(controller[i]->isDPadMode)
191+
{
192+
delete controller[i];
193+
switch(i)
194+
{
195+
case 1:
196+
controller[i] = new WPadController(GuiTrigger::CHANNEL_2);
197+
break;
198+
case 2:
199+
controller[i] = new WPadController(GuiTrigger::CHANNEL_3);
200+
break;
201+
case 3:
202+
controller[i] = new WPadController(GuiTrigger::CHANNEL_4);
203+
break;
204+
case 4:
205+
controller[i] = new WPadController(GuiTrigger::CHANNEL_5);
206+
break;
207+
}
208+
}
209+
else
210+
{
211+
delete controller[i];
212+
switch(i)
213+
{
214+
case 1:
215+
controller[i] = new DWPadController(GuiTrigger::CHANNEL_2);
216+
break;
217+
case 2:
218+
controller[i] = new DWPadController(GuiTrigger::CHANNEL_3);
219+
break;
220+
case 3:
221+
controller[i] = new DWPadController(GuiTrigger::CHANNEL_4);
222+
break;
223+
case 4:
224+
controller[i] = new DWPadController(GuiTrigger::CHANNEL_5);
225+
break;
226+
}
227+
}
228+
}
167229
}
168230

169231
//! start rendering DRC

src/gui/DVPadController.h

Lines changed: 92 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,92 @@
1+
/**
2+
* This class implements the DPAD mode for the GamePad, allowing you to use the DPAD to move a virtual
3+
* on screen pointer, rather than using the touch screen. The program will not be able to detect
4+
* any DPAD/A button presses in this mode, as it may interfere with the user who is navigating the pointer.
5+
*
6+
* Created by CreeperMario in July 2017.
7+
*/
8+
9+
#ifndef DPAD_CONTROLLER_H_
10+
#define DPAD_CONTROLLER_H_
11+
12+
#include "GuiController.h"
13+
#include "dynamic_libs/vpad_functions.h"
14+
15+
class DVPadController : public GuiController
16+
{
17+
public:
18+
19+
//!Constructor
20+
DVPadController(int channel) : GuiController(channel)
21+
{
22+
memset(&vpad, 0, sizeof(VPADData));
23+
memset(&data, 0, sizeof(PadData));
24+
memset(&lastData, 0, sizeof(PadData));
25+
26+
data.validPointer = true;
27+
isDPadMode = true;
28+
showPointer = true;
29+
}
30+
31+
//!Destructor
32+
virtual ~DVPadController() {}
33+
34+
//Remove the DPAD buttons (by clearing their bits) so that they aren't used by the Gui processes.
35+
u32 fixButtons(u32 buttons)
36+
{
37+
buttons &= ~VPAD_BUTTON_LEFT;
38+
buttons &= ~VPAD_BUTTON_RIGHT;
39+
buttons &= ~VPAD_BUTTON_UP;
40+
buttons &= ~VPAD_BUTTON_DOWN;
41+
buttons &= ~VPAD_BUTTON_A;
42+
return buttons;
43+
}
44+
45+
bool update(int width, int height)
46+
{
47+
lastData = data;
48+
49+
int vpadError = -1;
50+
VPADRead(0, &vpad, 1, &vpadError);
51+
52+
if(vpadError == 0)
53+
{
54+
if(vpad.btns_h & VPAD_BUTTON_LEFT)
55+
{
56+
if(data.x > -(width / 2)) data.x -= 10;
57+
}
58+
if(vpad.btns_h & VPAD_BUTTON_RIGHT)
59+
{
60+
if(data.x < (width / 2)) data.x += 10;
61+
}
62+
if(vpad.btns_h & VPAD_BUTTON_UP)
63+
{
64+
if(data.y < (height / 2)) data.y += 10;
65+
}
66+
if(vpad.btns_h & VPAD_BUTTON_DOWN)
67+
{
68+
if(data.y > -(height / 2)) data.y -= 10;
69+
}
70+
71+
if(vpad.btns_h & VPAD_BUTTON_A)
72+
data.touched = true;
73+
else
74+
data.touched = false;
75+
76+
data.buttons_r = fixButtons(vpad.btns_r);
77+
data.buttons_h = fixButtons(vpad.btns_h);
78+
data.buttons_d = fixButtons(vpad.btns_d);
79+
data.lstick = vpad.lstick;
80+
data.rstick = vpad.rstick;
81+
82+
return true;
83+
}
84+
85+
return false;
86+
}
87+
88+
private:
89+
VPADData vpad;
90+
};
91+
92+
#endif

src/gui/DWPadController.h

Lines changed: 165 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,165 @@
1+
/**
2+
* This class implements the DPAD mode for Wii Remote, Classic and Pro controllers, allowing you to use
3+
* the DPAD on your controller to move a virtual on screen pointer, rather than having to point at the
4+
* screen. This means that users who do not have a sensor bar or primarily use Classic/Pro controllers
5+
* can now use this program without trouble. The program will not be able to detect any DPAD button
6+
* presses in this mode, as it may interfere with the user who is navigating the pointer.
7+
*
8+
* Created by CreeperMario in July 2017.
9+
*/
10+
11+
#ifndef DWPAD_CONTROLLER_H_
12+
#define DWPAD_CONTROLLER_H_
13+
14+
#include "GuiController.h"
15+
#include "dynamic_libs/padscore_functions.h"
16+
17+
class DWPadController : public GuiController
18+
{
19+
public:
20+
21+
//!Constructor
22+
DWPadController(int channel) : GuiController(channel)
23+
{
24+
memset(&kpadData, 0, sizeof(KPADData));
25+
26+
data.validPointer = true;
27+
isDPadMode = true;
28+
showPointer = true;
29+
}
30+
31+
//!Destructor
32+
virtual ~DWPadController() {}
33+
34+
//Remove the DPAD buttons (by ignoring their bits) so that they aren't used by the Gui processes.
35+
u32 remapWiiMoteButtons(u32 buttons)
36+
{
37+
u32 temp = 0;
38+
39+
if(buttons & WPAD_BUTTON_MINUS)
40+
temp |= GuiTrigger::BUTTON_MINUS;
41+
if(buttons & WPAD_BUTTON_PLUS)
42+
temp |= GuiTrigger::BUTTON_PLUS;
43+
if(buttons & WPAD_BUTTON_2)
44+
temp |= GuiTrigger::BUTTON_2;
45+
if(buttons & WPAD_BUTTON_1)
46+
temp |= GuiTrigger::BUTTON_1;
47+
if(buttons & WPAD_BUTTON_B)
48+
temp |= GuiTrigger::BUTTON_B;
49+
if(buttons & WPAD_BUTTON_A)
50+
temp |= GuiTrigger::BUTTON_A;
51+
if(buttons & WPAD_BUTTON_Z) //Nunchuk only
52+
temp |= GuiTrigger::BUTTON_Z;
53+
if(buttons & WPAD_BUTTON_C) //Nunchuk only
54+
temp |= GuiTrigger::BUTTON_C;
55+
if(buttons & WPAD_BUTTON_HOME)
56+
temp |= GuiTrigger::BUTTON_HOME;
57+
58+
return temp;
59+
}
60+
61+
//Remove the DPAD buttons (by ignoring their bits) so that they aren't used by the Gui processes.
62+
u32 remapClassicButtons(u32 buttons)
63+
{
64+
u32 temp = 0;
65+
66+
if(buttons & WPAD_CLASSIC_BUTTON_MINUS)
67+
temp |= GuiTrigger::BUTTON_MINUS;
68+
if(buttons & WPAD_CLASSIC_BUTTON_PLUS)
69+
temp |= GuiTrigger::BUTTON_PLUS;
70+
if(buttons & WPAD_CLASSIC_BUTTON_X)
71+
temp |= GuiTrigger::BUTTON_X;
72+
if(buttons & WPAD_CLASSIC_BUTTON_Y)
73+
temp |= GuiTrigger::BUTTON_Y;
74+
if(buttons & WPAD_CLASSIC_BUTTON_B)
75+
temp |= GuiTrigger::BUTTON_B;
76+
if(buttons & WPAD_CLASSIC_BUTTON_A)
77+
temp |= GuiTrigger::BUTTON_A;
78+
if(buttons & WPAD_CLASSIC_BUTTON_HOME)
79+
temp |= GuiTrigger::BUTTON_HOME;
80+
if(buttons & WPAD_CLASSIC_BUTTON_ZR)
81+
temp |= GuiTrigger::BUTTON_ZR;
82+
if(buttons & WPAD_CLASSIC_BUTTON_ZL)
83+
temp |= GuiTrigger::BUTTON_ZL;
84+
if(buttons & WPAD_CLASSIC_BUTTON_R)
85+
temp |= GuiTrigger::BUTTON_R;
86+
if(buttons & WPAD_CLASSIC_BUTTON_L)
87+
temp |= GuiTrigger::BUTTON_L;
88+
89+
return temp;
90+
}
91+
92+
bool update(int width, int height)
93+
{
94+
lastData = data;
95+
u32 controller_type;
96+
97+
//! check if the controller is connected
98+
if(WPADProbe(chanIdx-1, &controller_type) != 0)
99+
return false;
100+
101+
KPADRead(chanIdx-1, &kpadData, 1);
102+
103+
if(kpadData.device_type <= 1)
104+
{
105+
if(kpadData.btns_h & WPAD_BUTTON_LEFT)
106+
{
107+
if(data.x > -(width / 2)) data.x -= 10;
108+
}
109+
if(kpadData.btns_h & WPAD_BUTTON_RIGHT)
110+
{
111+
if(data.x < (width / 2)) data.x += 10;
112+
}
113+
if(kpadData.btns_h & WPAD_BUTTON_UP)
114+
{
115+
if(data.y < (height / 2)) data.y += 10;
116+
}
117+
if(kpadData.btns_h & WPAD_BUTTON_DOWN)
118+
{
119+
if(data.y > -(height / 2)) data.y -= 10;
120+
}
121+
122+
data.buttons_r = remapWiiMoteButtons(kpadData.btns_r);
123+
data.buttons_h = remapWiiMoteButtons(kpadData.btns_h);
124+
data.buttons_d = remapWiiMoteButtons(kpadData.btns_d);
125+
126+
data.lstick.x = kpadData.nunchuck.stick_x;
127+
data.lstick.y = kpadData.nunchuck.stick_y;
128+
}
129+
else
130+
{
131+
if(kpadData.classic.btns_h & WPAD_CLASSIC_BUTTON_LEFT)
132+
{
133+
if(data.x > -(width / 2)) data.x -= 10;
134+
}
135+
if(kpadData.classic.btns_h & WPAD_CLASSIC_BUTTON_RIGHT)
136+
{
137+
if(data.x < (width / 2)) data.x += 10;
138+
}
139+
if(kpadData.classic.btns_h & WPAD_CLASSIC_BUTTON_UP)
140+
{
141+
if(data.y < (height / 2)) data.y += 10;
142+
}
143+
if(kpadData.classic.btns_h & WPAD_CLASSIC_BUTTON_DOWN)
144+
{
145+
if(data.y > -(height / 2)) data.y -= 10;
146+
}
147+
148+
data.buttons_r = remapClassicButtons(kpadData.classic.btns_r);
149+
data.buttons_h = remapClassicButtons(kpadData.classic.btns_h);
150+
data.buttons_d = remapClassicButtons(kpadData.classic.btns_d);
151+
152+
data.lstick.x = kpadData.classic.lstick_x;
153+
data.lstick.y = kpadData.classic.lstick_y;
154+
data.rstick.x = kpadData.classic.rstick_x;
155+
data.rstick.y = kpadData.classic.rstick_y;
156+
}
157+
158+
return true;
159+
}
160+
161+
private:
162+
KPADData kpadData;
163+
};
164+
165+
#endif

src/gui/GuiController.h

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,8 @@ class GuiController
5050
chanIdx = 4;
5151
break;
5252
}
53+
isDPadMode = false;
54+
showPointer = false;
5355
}
5456

5557
//!Destructor
@@ -75,6 +77,8 @@ class GuiController
7577
int chanIdx;
7678
PadData data;
7779
PadData lastData;
80+
bool isDPadMode;
81+
bool showPointer;
7882

7983
};
8084

0 commit comments

Comments
 (0)