11#pragma once
2- #include <vpad/input.h >
2+ #include < cstdint >
33
4+ // Game input, populated from SDL joystick events. The same code path works
5+ // for every Wii U input device (GamePad, Pro Controller, Wii Remote +/-
6+ // extensions, Classic Controller) because SDL2-wuhb's WIIU_JoystickInit
7+ // already initialises VPAD + KPAD + URCC and emits a single SDL_JOYBUTTONDOWN
8+ // per physical button press, with a canonical button index that matches
9+ // across all device types. See devkitPro/SDL src/joystick/wiiu for the
10+ // per-device index maps:
11+ //
12+ // 0=A 1=B 2=X 3=Y
13+ // 4=STICK_L_PUSH 5=STICK_R_PUSH
14+ // 6=L 7=R 8=ZL 9=ZR
15+ // 10=PLUS 11=MINUS
16+ // 12=LEFT 13=UP 14=RIGHT 15=DOWN
17+ // 16=LSTICK_LEFT 17=LSTICK_UP 18=LSTICK_RIGHT 19=LSTICK_DOWN
18+ // 20=RSTICK_LEFT 21=RSTICK_UP 22=RSTICK_RIGHT 23=RSTICK_DOWN
19+ //
20+ // SDL handles the stick-as-d-pad emulation for us: when the stick crosses
21+ // the threshold, SDL fires a SDL_JOYBUTTONDOWN with the corresponding
22+ // LSTICK_* index, then SDL_JOYBUTTONUP when it returns to centre. Same
23+ // edge-triggered semantics as the actual D-pad. We don't need to poll axes.
24+ //
25+ // App::run's event loop calls Input::onJoyButtonDown() for each
26+ // SDL_JOYBUTTONDOWN. Per frame, App::update() calls Input::read() which
27+ // returns a freshly drained snapshot.
428struct Input {
529 bool up = false ;
630 bool down = false ;
@@ -16,32 +40,33 @@ struct Input {
1640 bool zr = false ;
1741 bool plus = false ;
1842 bool minus = false ;
19- bool home = false;
43+ bool home = false ; // never fires: Aroma intercepts HOME before us
2044
21- static Input read () {
22- Input in ;
23- VPADStatus status ;
24- VPADReadError err ;
25- if (VPADRead (VPAD_CHAN_0 , & status , 1 , & err ) > 0 ) {
26- uint32_t btn = status .trigger ;
27- float lx = status .leftStick .x ;
28- float ly = status .leftStick .y ;
29- in .up = (btn & VPAD_BUTTON_UP ) || ly > 0.5f ;
30- in .down = (btn & VPAD_BUTTON_DOWN ) || ly < -0.5f ;
31- in .left = (btn & VPAD_BUTTON_LEFT ) || lx < -0.5f ;
32- in .right = (btn & VPAD_BUTTON_RIGHT ) || lx > 0.5f ;
33- in .a = btn & VPAD_BUTTON_A ;
34- in .b = btn & VPAD_BUTTON_B ;
35- in .l = btn & VPAD_BUTTON_L ;
36- in .r = btn & VPAD_BUTTON_R ;
37- in .y = btn & VPAD_BUTTON_Y ;
38- in .x = btn & VPAD_BUTTON_X ;
39- in .zl = btn & VPAD_BUTTON_ZL ;
40- in .zr = btn & VPAD_BUTTON_ZR ;
41- in .plus = btn & VPAD_BUTTON_PLUS ;
42- in .minus = btn & VPAD_BUTTON_MINUS ;
43- in .home = btn & VPAD_BUTTON_HOME ;
44- }
45- return in ;
46- }
45+ // SDL2-wuhb button indices. Order MUST match the arrays in the SDL
46+ // joystick driver (devkitPro/SDL src/joystick/wiiu/SDL_wiiujoystick.h).
47+ enum BtnIdx {
48+ BTN_A = 0 , BTN_B , BTN_X , BTN_Y ,
49+ BTN_STICK_L_PUSH , BTN_STICK_R_PUSH ,
50+ BTN_L , BTN_R , BTN_ZL , BTN_ZR ,
51+ BTN_PLUS , BTN_MINUS ,
52+ BTN_LEFT , BTN_UP , BTN_RIGHT , BTN_DOWN ,
53+ BTN_LSTICK_LEFT , BTN_LSTICK_UP , BTN_LSTICK_RIGHT , BTN_LSTICK_DOWN ,
54+ BTN_RSTICK_LEFT , BTN_RSTICK_UP , BTN_RSTICK_RIGHT , BTN_RSTICK_DOWN ,
55+ BTN_COUNT
56+ };
57+
58+ // Called from App::run's event loop when a SDL_JOYBUTTONDOWN arrives.
59+ // Accumulates presses across the frame; read() drains.
60+ static void onJoyButtonDown (int buttonIdx);
61+
62+ // Drain the accumulator into a fresh Input. Called once per frame in
63+ // App::update(), BEFORE the active screen's handleInput. Resets the
64+ // accumulator so the same press isn't seen twice.
65+ static Input read ();
66+
67+ private:
68+ // Bitfield of indices pressed since last read(). 24 bits used; uint32_t
69+ // is comfortable. Not atomic: SDL_PollEvent runs on the main thread, as
70+ // does read().
71+ static uint32_t s_pressedBits;
4772};
0 commit comments