Skip to content

Commit 36a5d8d

Browse files
authored
wiimote: flesh out Wii U Pro Controller support #227
1 parent 39a1761 commit 36a5d8d

File tree

5 files changed

+72
-23
lines changed

5 files changed

+72
-23
lines changed

gc/wiiuse/wiiuse.h

Lines changed: 26 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -67,6 +67,17 @@
6767
#define CLASSIC_CTRL_BUTTON_RIGHT 0x8000
6868
#define CLASSIC_CTRL_BUTTON_ALL 0xFEFF
6969

70+
/* wii u pro controller extra button codes */
71+
#define WII_U_PRO_CTRL_BUTTON_RSTICK 0x00010000
72+
#define WII_U_PRO_CTRL_BUTTON_LSTICK 0x00020000
73+
#define WII_U_PRO_CTRL_BUTTON_EXTRA 0x00030000
74+
#define WII_U_PRO_CTRL_BUTTON_ALL (WII_U_PRO_CTRL_BUTTON_EXTRA | CLASSIC_CTRL_BUTTON_ALL)
75+
76+
/* wii u pro controller extra data */
77+
#define WII_U_PRO_CTRL_CHARGING 0x04
78+
#define WII_U_PRO_CTRL_WIRED 0x08
79+
#define WII_U_PRO_CTRL_BATTERY 0x70
80+
7081
/* guitar hero 3 button codes */
7182
#define GUITAR_HERO_3_BUTTON_STRUM_UP 0x0001
7283
#define GUITAR_HERO_3_BUTTON_YELLOW 0x0008
@@ -105,6 +116,11 @@
105116
#define EXP_WII_BOARD 4
106117
#define EXP_MOTION_PLUS 5
107118

119+
/* classic controller types */
120+
#define CLASSIC_TYPE_ORIG 0 /* original classic controller (analog triggers) */
121+
#define CLASSIC_TYPE_PRO 1 /* classic controller pro (no analog triggers) */
122+
#define CLASSIC_TYPE_WIIU 2
123+
108124
/* IR correction types */
109125
typedef enum ir_position_t {
110126
WIIUSE_IR_ABOVE,
@@ -458,10 +474,10 @@ typedef struct nunchuk_t {
458474
* @brief Classic controller expansion device.
459475
*/
460476
typedef struct classic_ctrl_t {
461-
short btns; /**< what buttons have just been pressed */
462-
short btns_last; /**< what buttons have just been pressed */
463-
short btns_held; /**< what buttons are being held down */
464-
short btns_released; /**< what buttons were just released this */
477+
u32 btns; /**< what buttons have just been pressed */
478+
u32 btns_last; /**< what buttons have just been pressed */
479+
u32 btns_held; /**< what buttons are being held down */
480+
u32 btns_released; /**< what buttons were just released this */
465481

466482
ubyte rs_raw;
467483
ubyte ls_raw;
@@ -471,7 +487,12 @@ typedef struct classic_ctrl_t {
471487

472488
struct joystick_t ljs; /**< left joystick calibration */
473489
struct joystick_t rjs; /**< right joystick calibration */
474-
ubyte type; /**< original, pro, wiiu pro */
490+
ubyte type; /**< original, pro, wiiu pro */
491+
492+
ubyte charging;
493+
ubyte wired;
494+
ubyte battery;
495+
475496
} classic_ctrl_t;
476497

477498

gc/wiiuse/wpad.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -81,6 +81,9 @@ enum {
8181
#define WPAD_CLASSIC_BUTTON_DOWN (0x4000u<<16)
8282
#define WPAD_CLASSIC_BUTTON_RIGHT (0x8000u<<16)
8383

84+
#define WPAD_WII_U_PRO_BUTTON_RSTICK 0x0001
85+
#define WPAD_WII_U_PRO_BUTTON_LSTICK 0x0002
86+
8487
#define WPAD_GUITAR_HERO_3_BUTTON_STRUM_UP (0x0001<<16)
8588
#define WPAD_GUITAR_HERO_3_BUTTON_YELLOW (0x0008<<16)
8689
#define WPAD_GUITAR_HERO_3_BUTTON_GREEN (0x0010<<16)

wiiuse/classic.c

Lines changed: 35 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -48,7 +48,7 @@
4848
#include "io.h"
4949

5050
static void fix_bad_calibration_values(struct joystick_t* js, short right_stick);
51-
static void classic_ctrl_pressed_buttons(struct classic_ctrl_t* cc, short now);
51+
static void classic_ctrl_pressed_buttons(struct classic_ctrl_t* cc, ubyte *now);
5252

5353
/**
5454
* @brief Handle the handshake data from the classic controller.
@@ -81,7 +81,7 @@ int classic_ctrl_handshake(struct wiimote_t* wm, struct classic_ctrl_t* cc, ubyt
8181

8282
cc->rjs = cc->ljs;
8383

84-
cc->type = 2;
84+
cc->type = CLASSIC_TYPE_WIIU;
8585
}
8686
else {
8787
if (data[offset] == 0xFF) {
@@ -102,9 +102,9 @@ int classic_ctrl_handshake(struct wiimote_t* wm, struct classic_ctrl_t* cc, ubyt
102102
}
103103

104104
if (len > 218 && data[218])
105-
cc->type = 1; /* classic controller pro (no analog triggers) */
105+
cc->type = CLASSIC_TYPE_PRO;
106106
else
107-
cc->type = 0; /* original classic controller (analog triggers) */
107+
cc->type = CLASSIC_TYPE_ORIG;
108108

109109
/* joystick stuff */
110110
cc->ljs.max.x = data[0 + offset] / 4 == 0 ? 64 : data[0 + offset] / 4;
@@ -124,6 +124,7 @@ int classic_ctrl_handshake(struct wiimote_t* wm, struct classic_ctrl_t* cc, ubyt
124124
fix_bad_calibration_values(&cc->ljs, 0);
125125
fix_bad_calibration_values(&cc->rjs, 1);
126126
}
127+
127128
/* handshake done */
128129
wm->event = WIIUSE_CLASSIC_CTRL_INSERTED;
129130
wm->exp.type = EXP_CLASSIC;
@@ -162,8 +163,8 @@ void classic_ctrl_event(struct classic_ctrl_t* cc, ubyte* msg) {
162163
for (i = 0; i < 6; ++i)
163164
msg[i] = (msg[i] ^ 0x17) + 0x17;
164165
*/
165-
if (cc->type==2) {
166-
classic_ctrl_pressed_buttons(cc, BIG_ENDIAN_SHORT(*(short*)(msg + 8)));
166+
if (cc->type==CLASSIC_TYPE_WIIU) {
167+
classic_ctrl_pressed_buttons(cc, msg + 8);
167168

168169
/* 12-bit little endian values adjusted to 8-bit */
169170
cc->ljs.pos.x = (msg[0] >> 4) | (msg[1] << 4);
@@ -173,11 +174,16 @@ void classic_ctrl_event(struct classic_ctrl_t* cc, ubyte* msg) {
173174

174175
cc->ls_raw = cc->btns & CLASSIC_CTRL_BUTTON_FULL_L ? 0x1F : 0;
175176
cc->rs_raw = cc->btns & CLASSIC_CTRL_BUTTON_FULL_R ? 0x1F : 0;
177+
178+
/* Wii U pro controller specific data */
179+
cc->charging = !(((msg[10] & WII_U_PRO_CTRL_CHARGING) >> 2) & 1);
180+
cc->wired = !(((msg[10] & WII_U_PRO_CTRL_WIRED) >> 3) & 1);
181+
cc->battery = ((msg[10] & WII_U_PRO_CTRL_BATTERY) >> 4) & 7;
176182
}
177183
else {
178-
classic_ctrl_pressed_buttons(cc, BIG_ENDIAN_SHORT(*(short*)(msg + 4)));
184+
classic_ctrl_pressed_buttons(cc, msg + 4);
179185

180-
/* left/right buttons */
186+
/* left/right triggers */
181187
cc->ls_raw = (((msg[2] & 0x60) >> 2) | ((msg[3] & 0xE0) >> 5));
182188
cc->rs_raw = (msg[3] & 0x1F);
183189

@@ -194,6 +200,11 @@ void classic_ctrl_event(struct classic_ctrl_t* cc, ubyte* msg) {
194200
cc->ljs.pos.y = (msg[1] & 0x3F);
195201
cc->rjs.pos.x = ((msg[0] & 0xC0) >> 3) | ((msg[1] & 0xC0) >> 5) | ((msg[2] & 0x80) >> 7);
196202
cc->rjs.pos.y = (msg[2] & 0x1F);
203+
204+
/* wipe Wii U pro controller specific data */
205+
cc->charging = 0;
206+
cc->wired = 0;
207+
cc->battery = 0;
197208
}
198209

199210
#ifndef GEKKO
@@ -221,19 +232,29 @@ static void fix_bad_calibration_values(struct joystick_t* js, short right_stick)
221232
* @param cc A pointer to a classic_ctrl_t structure.
222233
* @param msg The message byte specified in the event packet.
223234
*/
224-
static void classic_ctrl_pressed_buttons(struct classic_ctrl_t* cc, short now) {
225-
/* message is inverted (0 is active, 1 is inactive) */
226-
now = ~now & CLASSIC_CTRL_BUTTON_ALL;
235+
static void classic_ctrl_pressed_buttons(struct classic_ctrl_t* cc, ubyte *now) {
236+
u32 buttons = (now[0] << 0x8) | now[1];
237+
238+
if (cc->type==CLASSIC_TYPE_WIIU) {
239+
/* append Wii U Pro Controller stick buttons to top 16 bits */
240+
buttons |= (now[2] << 0x10);
241+
242+
/* message is inverted (0 is active, 1 is inactive) */
243+
buttons = ~buttons & WII_U_PRO_CTRL_BUTTON_ALL;
244+
} else {
245+
/* message is inverted (0 is active, 1 is inactive) */
246+
buttons = ~buttons & CLASSIC_CTRL_BUTTON_ALL;
247+
}
227248

228249
/* preserve old btns pressed */
229250
cc->btns_last = cc->btns;
230251

231252
/* pressed now & were pressed, then held */
232-
cc->btns_held = (now & cc->btns);
253+
cc->btns_held = (buttons & cc->btns);
233254

234255
/* were pressed or were held & not pressed now, then released */
235-
cc->btns_released = ((cc->btns | cc->btns_held) & ~now);
256+
cc->btns_released = ((cc->btns | cc->btns_held) & ~buttons);
236257

237258
/* buttons pressed now */
238-
cc->btns = now;
259+
cc->btns = buttons;
239260
}

wiiuse/io.c

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -102,7 +102,6 @@ void wiiuse_handshake_expansion(struct wiimote_t *wm,ubyte *data,uword len)
102102
case 3:
103103
if(!data || !len) return;
104104
id = BIG_ENDIAN_LONG(*(int*)(&data[220]));
105-
//printf("New exp type: %d\n", id);
106105

107106
switch(id) {
108107
case EXP_ID_CODE_NUNCHUK:

wiiuse/wpad.c

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -492,7 +492,12 @@ static void __wpad_calc_data(WPADData *data,WPADData *lstate,struct accel_t *acc
492492
cc->l_shoulder = ((f32)cc->ls_raw/0x1F);
493493
calc_joystick_state(&cc->ljs, cc->ljs.pos.x, cc->ljs.pos.y);
494494
calc_joystick_state(&cc->rjs, cc->rjs.pos.x, cc->rjs.pos.y);
495-
data->btns_h |= (data->exp.classic.btns<<16);
495+
496+
// overwrite Wiimote buttons (unused) with extra Wii U Pro Controller stick buttons
497+
if (data->exp.classic.type == CLASSIC_TYPE_WIIU)
498+
data->btns_h = (data->exp.classic.btns & WII_U_PRO_CTRL_BUTTON_EXTRA) >> 16;
499+
500+
data->btns_h |= ((data->exp.classic.btns & CLASSIC_CTRL_BUTTON_ALL)<<16);
496501
}
497502
break;
498503

@@ -765,9 +770,9 @@ static void __wpad_eventCB(struct wiimote_t *wm,s32 event)
765770
case WIIUSE_ACK:
766771
break;
767772
default:
768-
WIIUSE_DEBUG("__wpad_eventCB(%02x)", event);
773+
WIIUSE_DEBUG("__wpad_eventCB(%02x)\n", event);
769774
break;
770-
}
775+
}
771776
}
772777

773778
void __wpad_disconnectCB(struct bd_addr *pad_addr, u8 reason)

0 commit comments

Comments
 (0)