Skip to content

Commit 9e38012

Browse files
authored
wiiu: add USB keyboard support (#83)
1 parent ed6b5f8 commit 9e38012

File tree

4 files changed

+175
-0
lines changed

4 files changed

+175
-0
lines changed

src/video/wiiu/SDL_wiiukeyboard.c

Lines changed: 132 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,132 @@
1+
/*
2+
Simple DirectMedia Layer
3+
Copyright (C) 1997-2023 Sam Lantinga <[email protected]>
4+
5+
This software is provided 'as-is', without any express or implied
6+
warranty. In no event will the authors be held liable for any damages
7+
arising from the use of this software.
8+
9+
Permission is granted to anyone to use this software for any purpose,
10+
including commercial applications, and to alter it and redistribute it
11+
freely, subject to the following restrictions:
12+
13+
1. The origin of this software must not be misrepresented; you must not
14+
claim that you wrote the original software. If you use this software
15+
in a product, an acknowledgment in the product documentation would be
16+
appreciated but is not required.
17+
2. Altered source versions must be plainly marked as such, and must not be
18+
misrepresented as being the original software.
19+
3. This notice may not be removed or altered from any source distribution.
20+
*/
21+
22+
#include "SDL_wiiukeyboard.h"
23+
24+
#include "../../SDL_internal.h"
25+
26+
#include "../../events/SDL_keyboard_c.h"
27+
28+
#include <nsyskbd/nsyskbd.h>
29+
30+
#define EVENT_BUFFER_SIZE 10
31+
32+
static struct WIIUKBD_EventBuffer {
33+
KBDKeyEvent events[EVENT_BUFFER_SIZE];
34+
int current;
35+
} event_buffer = {0};
36+
37+
/* I'm not sure if this is really necessary, but I'm adding
38+
* it anyway in case the wii u calls back from another thread */
39+
static SDL_mutex *event_buffer_mutex = NULL;
40+
41+
static void SDL_WIIUKeyboard_AttachCallback(KBDAttachEvent *kde)
42+
{
43+
(void)kde;
44+
}
45+
46+
static void SDL_WIIUKeyboard_DetachCallback(KBDAttachEvent *kde)
47+
{
48+
(void)kde;
49+
}
50+
51+
static void SDL_WIIUKeyboard_KeyCallback(KBDKeyEvent *e)
52+
{
53+
SDL_LockMutex(event_buffer_mutex);
54+
55+
/* add the key event to our buffer */
56+
if (event_buffer.current < EVENT_BUFFER_SIZE)
57+
event_buffer.events[event_buffer.current++] = *e;
58+
59+
SDL_UnlockMutex(event_buffer_mutex);
60+
}
61+
62+
static void WIIU_SendKeyEventText(KBDKeyEvent *e)
63+
{
64+
const Uint16 symbol = e->asUTF16Character;
65+
unsigned char utf8[4] = {0};
66+
67+
/* ignore private symbols, used for special keys */
68+
if ((symbol >= 0xE000 && symbol <= 0xF8FF) || symbol == 0xFFFF)
69+
return;
70+
71+
/* convert UCS-2 to UTF-8 */
72+
if (symbol < 0x80) {
73+
utf8[0] = symbol;
74+
} else if (symbol < 0x800) {
75+
utf8[0] = 0xC0 | (symbol >> 6);
76+
utf8[1] = 0x80 | (symbol & 0x3F);
77+
} else {
78+
utf8[0] = 0xE0 | (symbol >> 12);
79+
utf8[1] = 0x80 | ((symbol >> 6) & 0x3F);
80+
utf8[2] = 0x80 | (symbol & 0x3F);
81+
}
82+
83+
SDL_SendKeyboardText((char *)utf8);
84+
}
85+
86+
void SDL_WIIU_PumpKeyboardEvents(_THIS)
87+
{
88+
int i;
89+
90+
SDL_LockMutex(event_buffer_mutex);
91+
92+
/* process each key event */
93+
for (i = 0; i < event_buffer.current; i++) {
94+
SDL_SendKeyboardKey(
95+
event_buffer.events[i].isPressedDown ? SDL_PRESSED : SDL_RELEASED,
96+
(SDL_Scancode)event_buffer.events[i].hidCode
97+
);
98+
99+
if (event_buffer.events[i].isPressedDown)
100+
WIIU_SendKeyEventText(&event_buffer.events[i]);
101+
}
102+
103+
/* reset the buffer */
104+
event_buffer.current = 0;
105+
106+
SDL_UnlockMutex(event_buffer_mutex);
107+
}
108+
109+
/* returns non-zero on success */
110+
int SDL_WIIU_InitKeyboard(_THIS)
111+
{
112+
event_buffer_mutex = SDL_CreateMutex();
113+
if (!event_buffer_mutex)
114+
return 0;
115+
116+
if (KBDSetup(SDL_WIIUKeyboard_AttachCallback, SDL_WIIUKeyboard_DetachCallback, SDL_WIIUKeyboard_KeyCallback))
117+
return 0;
118+
119+
return 1;
120+
}
121+
122+
/* returns non-zero on success; this should ONLY be called after a successful keyboard init */
123+
int SDL_WIIU_QuitKeyboard(_THIS)
124+
{
125+
if (KBDTeardown())
126+
return 0;
127+
128+
/* by this point the mutex is definitely not locked */
129+
SDL_DestroyMutex(event_buffer_mutex);
130+
131+
return 1;
132+
}

src/video/wiiu/SDL_wiiukeyboard.h

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
/*
2+
Simple DirectMedia Layer
3+
Copyright (C) 1997-2023 Sam Lantinga <[email protected]>
4+
5+
This software is provided 'as-is', without any express or implied
6+
warranty. In no event will the authors be held liable for any damages
7+
arising from the use of this software.
8+
9+
Permission is granted to anyone to use this software for any purpose,
10+
including commercial applications, and to alter it and redistribute it
11+
freely, subject to the following restrictions:
12+
13+
1. The origin of this software must not be misrepresented; you must not
14+
claim that you wrote the original software. If you use this software
15+
in a product, an acknowledgment in the product documentation would be
16+
appreciated but is not required.
17+
2. Altered source versions must be plainly marked as such, and must not be
18+
misrepresented as being the original software.
19+
3. This notice may not be removed or altered from any source distribution.
20+
*/
21+
22+
#ifndef SDL_wiiukeyboard_h
23+
#define SDL_wiiukeyboard_h
24+
25+
#include "../../SDL_internal.h"
26+
#include "../../events/SDL_events_c.h"
27+
28+
void SDL_WIIU_PumpKeyboardEvents(_THIS);
29+
int SDL_WIIU_InitKeyboard(_THIS);
30+
int SDL_WIIU_QuitKeyboard(_THIS);
31+
32+
#endif /* SDL_wiiukeyboard_h */

src/video/wiiu/SDL_wiiuvideo.c

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -36,6 +36,7 @@
3636
#include "../../events/SDL_keyboard_c.h"
3737
#include "../../events/SDL_events_c.h"
3838
#include "SDL_wiiuvideo.h"
39+
#include "SDL_wiiukeyboard.h"
3940
#include "SDL_wiiu_gfx_heap.h"
4041

4142
#include "../../render/wiiu/SDL_render_wiiu.h"
@@ -269,6 +270,8 @@ static int WIIU_VideoInit(_THIS)
269270
mode.refresh_rate = 60;
270271
SDL_AddBasicVideoDisplay(&mode);
271272

273+
videodata->kbd_init = SDL_WIIU_InitKeyboard(_this);
274+
272275
return 0;
273276
}
274277

@@ -293,6 +296,9 @@ static void WIIU_VideoQuit(_THIS)
293296
ProcUIShutdown();
294297
}
295298

299+
if (videodata->kbd_init)
300+
SDL_WIIU_QuitKeyboard(_this);
301+
296302
running = SDL_FALSE;
297303
}
298304

@@ -335,6 +341,8 @@ static void WIIU_PumpEvents(_THIS)
335341
ProcUIDrawDoneRelease();
336342
}
337343
}
344+
345+
SDL_WIIU_PumpKeyboardEvents(_this);
338346
}
339347

340348
static void WIIU_DeleteDevice(SDL_VideoDevice *device)

src/video/wiiu/SDL_wiiuvideo.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,9 @@ struct WIIU_VideoData
5050
GX2DrcRenderMode drcRenderMode;
5151
void *drcScanBuffer;
5252
uint32_t drcScanBufferSize;
53+
54+
// did the keyboard code initialize properly?
55+
int kbd_init;
5356
};
5457

5558
#endif /* SDL_VIDEO_DRIVER_WIIU */

0 commit comments

Comments
 (0)