From abd5f48be9f1fd0bd447d8090a0953c8b04aa6ea Mon Sep 17 00:00:00 2001 From: thepikachugamer <44107089+Naim2000@users.noreply.github.com> Date: Sat, 24 Feb 2024 15:41:19 -0500 Subject: [PATCH] USB Keyboard support (#8) --- Makefile | 4 +- source/menu.c | 58 +++++++--------- source/wad-manager.c | 2 + source/wkb.c | 157 +++++++++++++++++++++++++++++++++++-------- source/wkb.h | 9 ++- 5 files changed, 161 insertions(+), 69 deletions(-) diff --git a/Makefile b/Makefile index 8640072..c4985d4 100644 --- a/Makefile +++ b/Makefile @@ -21,7 +21,7 @@ include $(DEVKITPPC)/wii_rules TARGET := boot BUILD := build SOURCES := source include source/libtinysmb source/libpng source/libpng/pngu -DATA := data +DATA := data INCLUDES := #--------------------------------------------------------------------------------- @@ -36,7 +36,7 @@ LDFLAGS = $(MACHDEP) -Wl,-Map,$(notdir $@).map #--------------------------------------------------------------------------------- # any extra libraries we wish to link with the project #--------------------------------------------------------------------------------- -LIBS := -lmxml -ltinysmb -lpng -lfat -lwiidrc -lwiiuse -lbte -logc -lm -lz -lwiilight +LIBS := -lmxml -ltinysmb -lpng -lfat -lwiikeyboard -lwiidrc -lwiiuse -lbte -logc -lm -lz -lwiilight #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing diff --git a/source/menu.c b/source/menu.c index e09b04a..326ca2f 100644 --- a/source/menu.c +++ b/source/menu.c @@ -3,6 +3,7 @@ #include #include #include +#include #include #include #include @@ -16,7 +17,7 @@ #include "video.h" #include "wad.h" #include "wpad.h" -#include +#include "wkb.h" #include "globals.h" #include "iospatch.h" #include "appboot.h" @@ -646,42 +647,26 @@ int Menu_BatchProcessWads(fatFile *files, int fileCount, char *inFilePath, int i if (thisFile->installstate < 0) { - char str[41]; - strncpy(str, thisFile->filename, 40); //Only 40 chars to fit the screen - str[40]=0; + printf(" %.40s ", thisFile->filename); i++; switch (thisFile->installstate) { - case -106: - { - printf(" %s Not installed?\n", str); - } break; - case -996: - { - printf(" %s Read error\n", str); - } break; - case -998: - { - printf(" %s Skipped\n", str); - } break; - case -999: - { - printf(" %s BRICK BLOCKED\n", str); - } break; - case -1036: - { - printf(" %s Needed IOS missing\n", str); - } break; - case -4100: - { - printf(" %s No trucha bug?\n", str); - } break; - default: - { - printf(" %s error %d\n", str, thisFile->installstate); - } break; + case -106: puts("Not installed?"); break; + case -996: puts("Read error"); break; + case -998: puts("Skipped"); break; + case -999: puts("BRICK BLOCKED"); break; + case -1036: puts("Needed IOS missing"); break; + case -2011: puts("No trucha bug?"); break; + /* + * from libogc. + * This rarely happens unless the WAD had an invalid ticket/tmd size + * (certs were not stripped after downloading from NUS maybe?) + */ + case ES_EINVAL: puts("Invalid WAD?"); break; + + default: printf("error %d\n", thisFile->installstate); break; } if(i == 17) @@ -1496,9 +1481,10 @@ u32 WaitButtons(void) u32 buttons = 0; u32 buttonsGC = 0; u32 buttonsDRC = 0; + u16 buttonsWKB = 0; /* Wait for button pressing */ - while (!buttons && !buttonsGC && !buttonsDRC) + while (!(buttons | buttonsGC | buttonsDRC | buttonsWKB)) { // Wii buttons buttons = Wpad_GetButtons(); @@ -1509,6 +1495,9 @@ u32 WaitButtons(void) // DRC buttons buttonsDRC = WiiDRC_GetButtons(); + // USB Keyboard buttons + buttonsWKB = WKB_GetButtons(); + VIDEO_WaitVSync(); } @@ -1581,6 +1570,9 @@ u32 WaitButtons(void) buttons |= WPAD_BUTTON_1; } + if (buttonsWKB) + buttons |= buttonsWKB; + return buttons; } // WaitButtons diff --git a/source/wad-manager.c b/source/wad-manager.c index 134affb..28fb32c 100644 --- a/source/wad-manager.c +++ b/source/wad-manager.c @@ -14,6 +14,7 @@ #include "sys.h" #include "video.h" #include "wpad.h" +#include "wkb.h" #include "fat.h" #include "nand.h" #include "globals.h" @@ -179,6 +180,7 @@ int main(int argc, char **argv) Wpad_Init(); PAD_Init(); WiiDRC_Init(); + WKB_Initialize(); WIILIGHT_Init(); /* Print disclaimer */ diff --git a/source/wkb.c b/source/wkb.c index f04ed68..36fcfbb 100644 --- a/source/wkb.c +++ b/source/wkb.c @@ -1,47 +1,146 @@ +/* + * Most of this code was adapted from Priiloader. + * https://github.com/DacoTaco/priiloader/blob/master/tools/DacosLove/source/Input.cpp + */ + +#include +#include + #include "wkb.h" -/* - -s32 USBKeyboard_Open(const eventcallback cb); -void USBKeyboard_Close(void); - -bool USBKeyboard_IsConnected(void); -s32 USBKeyboard_Scan(void); - -s32 USBKeyboard_SetLed(const USBKeyboard_led led, bool on); -s32 USBKeyboard_ToggleLed(const USBKeyboard_led led); -*/ - -s32 WkbInit(void) +enum { - s32 retval = 0; + /* Configuration i guess */ + WKB_THREAD_PRIORITY = 0x7F, + WKB_THREAD_STACK = 0x4000, + WKB_THREAD_UDELAY = 400, + WKB_ANIMATION_UDELAY= 250000, - retval = USBKeyboard_Initialize(); + /* The keys themselves */ + WKB_ARROW_UP = 0x52, + WKB_ARROW_DOWN = 0x51, + WKB_ARROW_LEFT = 0x50, + WKB_ARROW_RIGHT = 0x4F, - return (retval); + WKB_SPACEBAR = 0x2C, + WKB_ENTER = 0x28, + WKB_NUMPAD_ENTER = 0x58, + WKB_BACKSPACE = 0x2A, + WKB_DELETE = 0x4C, + WKB_ESCAPE = 0x29, + WKB_HOME = 0x4A, -} // WkbInit + WKB_KEY_PLUS = 0x2E, + WKB_KEY_MINUS = 0x2D, -s32 WkbDeInit(void) + WKB_KEY_X = 0x1B, + WKB_KEY_Y = 0x1C, + WKB_KEY_1 = 0x1E, + WKB_KEY_2 = 0x1F, +}; + +static lwp_t WKBThreadHandle = LWP_THREAD_NULL; +static volatile bool WKBThreadActive; +static u16 WKBButtonsPressed; + +static void WKBEventHandler(USBKeyboard_event evt) { - s32 retval = 0; + // OSReport("Keyboard event: {%i, 0x%02hhx}", evt.type, evt.keyCode); - retval = USBKeyboard_Deinitialize(); + if (!(evt.type == USBKEYBOARD_PRESSED || evt.type == USBKEYBOARD_RELEASED)) + return; - return (retval); + u16 button; + switch (evt.keyCode) + { + /* + * Maybe I should create an array with a map of keycodes to the corresponding WPAD buttons. + * Like there's just this u16 WKBKeyMap[0x100] somewhere here and I can just say button = WKBKeyMap[evt.keyCode]; + */ + case WKB_ENTER: + case WKB_NUMPAD_ENTER: button = WPAD_BUTTON_A; break; + case WKB_BACKSPACE: button = WPAD_BUTTON_B; break; -} // WkbDeInit + case WKB_ARROW_UP: button = WPAD_BUTTON_UP; break; + case WKB_ARROW_DOWN: button = WPAD_BUTTON_DOWN; break; + case WKB_ARROW_LEFT: button = WPAD_BUTTON_LEFT; break; + case WKB_ARROW_RIGHT: button = WPAD_BUTTON_RIGHT; break; -u32 WkbWaitKey (void) + case WKB_ESCAPE: + case WKB_HOME: button = WPAD_BUTTON_HOME; break; + case WKB_KEY_PLUS: button = WPAD_BUTTON_PLUS; break; + case WKB_KEY_MINUS: button = WPAD_BUTTON_MINUS; break; + case WKB_KEY_1: button = WPAD_BUTTON_1; break; + + default: return; + } + + if (evt.type == USBKEYBOARD_PRESSED) + WKBButtonsPressed |= button; + else + WKBButtonsPressed &= ~button; +} + +static void* WKBThread(__attribute__((unused)) void* arg) { - u32 retval = 0; + while (WKBThreadActive) + { + /* + * Despite having a return type of s32, USBKeyboard_Open() returns 1 if it was successful, rather than 0. + * So this statement right here will check if a USB keyboard was detected, and if not, try open it again. + */ + if (!USBKeyboard_IsConnected() && USBKeyboard_Open(WKBEventHandler) == true) + { + /* + * And once it does open it successfully: + * + * "wake up the keyboard by sending it a command. + * im looking at you, bastard LINQ keyboard." + * - https://github.com/DacoTaco/priiloader/blob/master/tools/DacosLove/source/Input.cpp#L93-L94 + * + * Just thought i would make this a fun lil animation :) + */ + for (int led = 0; led < 3; led++) { USBKeyboard_SetLed(led, true); usleep(WKB_ANIMATION_UDELAY); } + } - // Stub - return (retval); + USBKeyboard_Scan(); + usleep(WKB_THREAD_UDELAY); + } -} // WkbWaitKey + for (int led = 3; led; led--) { USBKeyboard_SetLed(led, false); usleep(WKB_ANIMATION_UDELAY); } + return NULL; +} + +void WKB_Initialize(void) +{ + USB_Initialize(); + USBKeyboard_Initialize(); + + WKBThreadActive = true; + LWP_CreateThread(&WKBThreadHandle, WKBThread, NULL, NULL, WKB_THREAD_STACK, WKB_THREAD_PRIORITY); +} + +void WKB_Deinitialize(void) +{ + WKBThreadActive = false; + usleep(WKB_THREAD_UDELAY); + + USBKeyboard_Close(); + USBKeyboard_Deinitialize(); + + if (WKBThreadHandle != LWP_THREAD_NULL) + LWP_JoinThread(WKBThreadHandle, NULL); + + WKBThreadHandle = LWP_THREAD_NULL; +} + +u16 WKB_GetButtons(void) +{ + u16 buttons = WKBButtonsPressed; + WKBButtonsPressed = 0; + + return buttons; +} -//void Wpad_Disconnect(void); -//u32 Wpad_GetButtons(void); diff --git a/source/wkb.h b/source/wkb.h index 568572f..6dce244 100644 --- a/source/wkb.h +++ b/source/wkb.h @@ -5,15 +5,14 @@ //#include //#include //#include -#include // u8, u16, etc... +#include // u8, u16, etc... #include #include /* Prototypes */ -s32 WkbInit(void); -u32 WkbWaitKey (void); -//void Wpad_Disconnect(void); -//u32 Wpad_GetButtons(void); +void WKB_Initialize(void); +void WKB_Deinitialize(void); +u16 WKB_GetButtons(void); #endif