diff --git a/Makefile b/Makefile index ebe766b..d5ec56a 100644 --- a/Makefile +++ b/Makefile @@ -36,7 +36,7 @@ LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map LIBS := -lgrrlib LIBS += -lfreetype LIBS += -lpngu -lpng -ljpeg -lz -lfat -ldi -LIBS += -lwiilight -lwiiuse +LIBS += -lwiilight -lwiiuse -lwupc #LIBS += -lmodplay -lasnd LIBS += -lbte -logc -lm LIBS += -lCheckRegion diff --git a/boot.elf b/boot.elf index e9b24e6..8e586a1 100644 Binary files a/boot.elf and b/boot.elf differ diff --git a/include/SysMenuInfo.h b/include/SysMenuInfo.h index 4281151..c9d2089 100644 --- a/include/SysMenuInfo.h +++ b/include/SysMenuInfo.h @@ -36,11 +36,13 @@ typedef struct { u32 deviceID; - bool deviceType; + u8 deviceType; u32 boot2version; u32 sysMenuVer; u32 dvdSupport; s32 sysMenuIOS; + s32 sysMenuIOSVersion; + s32 sysMenuIOSType; float sysNinVersion; char sysMenuRegion; s32 systemRegion; diff --git a/include/sys.h b/include/sys.h index 11d2e72..5e77a41 100644 --- a/include/sys.h +++ b/include/sys.h @@ -43,7 +43,13 @@ enum { enum { CONSOLE_WII = 0, - CONSOLE_WII_U + CONSOLE_WII_U, + CONSOLE_UNKNOWN +}; + +enum { + IOS_WII = 0, + IOS_WII_U }; enum { @@ -51,7 +57,8 @@ enum { HBC_HAXX, HBC_JODI, HBC_1_0_7, - HBC_LULZ + HBC_LULZ, + HBC_OPEN }; enum { @@ -70,6 +77,12 @@ enum { TID_WFS }; +#define HBC_TID_HAXX 0x48415858 +#define HBC_TID_JODI 0x4A4F4449 +#define HBC_TID_1_0_7 0xAF1BF516 +#define HBC_TID_LULZ 0x4C554C5A +#define HBC_TID_OPEN 0x4F484243 + typedef struct { s32 revision; bool isStub; @@ -121,14 +134,8 @@ typedef struct _U8Entry }; } __attribute__( ( packed ) ) U8Entry; -typedef struct { - const u32 titleID; - const s32 revision; -} vIOSdb_t; - extern const char *Regions[]; extern u8 sysMenuInfoContent; -extern const vIOSdb_t vIOSdb[]; #ifdef __cplusplus extern "C" @@ -143,7 +150,7 @@ u32 GetSysMenuVersion(void); float GetSysMenuNintendoVersion(u32 sysVersion); u32 GetBoot2Version(void); u32 GetDeviceID(void); -bool CheckIOSType(void); +bool CheckIOSType(u32 titleID, s32 revision); bool CheckFakeSignature(void); bool CheckESIdentify(void); bool CheckFlashAccess(void); diff --git a/include/tools.h b/include/tools.h index 1e49e13..b8a9b0a 100644 --- a/include/tools.h +++ b/include/tools.h @@ -17,7 +17,7 @@ extern "C" #define UpdateTime() current_time = gettime(); typedef struct { - bool forceNoAHBPROT; + bool AHB_At_Start; bool debug; int skipIOSlist[512]; int skipIOScnt; diff --git a/libs/include/wupc/usage.txt b/libs/include/wupc/usage.txt new file mode 100644 index 0000000..49c310f --- /dev/null +++ b/libs/include/wupc/usage.txt @@ -0,0 +1,24 @@ +libwupc - A WiiU Pro Controller Library for Wii Homebrew Applications by FIX94 +Modifications by JoostinOnline +WiiU Pro Controller Documentation from TeHaxor69 + +1. Copy the "lib" and "include" folder into your "libogc" folder. Alternatively, run "make install" from command line + +2. Make these modifications to your Makefile: +-Add "-lwupc" right after "-lwiiuse" to your LIBS +-Add ",-wrap,wiiuse_register" to your LDFLAGS + +3. Modify your code like this: +-Make sure to include in all files you use WUPC calls +-Call "WUPC_Init" before "WPAD_Init" +-Call "WUPC_Shutdown" before "WPAD_Shutdown" +-Either use the separate calls or use WUPC_Data at the same place you would normally use the WPAD calls for your data handling +-If you use ButtonsUp, ButtonsUp and/or ButtonsHeld, make sure to call "WUPC_ScanPads" before "WPAD_ScanPads". If you dont use any of these you can ignore "WUPC_ScanPads" + +Notes: +-The X and Y-Axis are going from about -1024 to +1024, make sure you adjust your calculations to that +-The Buttons are using the same layout as the classic controller buttons, so you can use the "WPAD_CLASSIC_BUTTON_" definitions in instead of the ones included in wupc.h +-The Battery Status goes from 0 (critical) to 4 (full) +-The "WUPC_SetPowerButtonCallback" and "WUPC_SetBatteryDeadCallback" functions will have the same effect as "WPAD_SetPowerButtonCallback" and "WPAD_SetBatteryDeadCallback" (respectively), so there is no need to use both the WPAD and WUPC versions. + +Have Fun! \ No newline at end of file diff --git a/libs/include/wupc/wupc.h b/libs/include/wupc/wupc.h new file mode 100644 index 0000000..a61ab86 --- /dev/null +++ b/libs/include/wupc/wupc.h @@ -0,0 +1,108 @@ +/**************************************************************************** + * Copyright (C) 2014 FIX94 + * Changes, based on revision 3, by JoostinOnline + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation, either version 3 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + ****************************************************************************/ +#ifndef _WUPC_H_ +#define _WUPC_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +typedef struct WUPCData_s { + s16 xAxisL; + s16 xAxisR; + s16 yAxisL; + s16 yAxisR; + u32 button; + u8 battery; + u8 extra; +} WUPCData; + +enum { + WUPC_CHAN_0, + WUPC_CHAN_1, + WUPC_CHAN_2, + WUPC_CHAN_3, + WUPC_MAX_REMOTES +}; + +enum { + WUPC_BATTERY_CRITICAL, + WUPC_BATTERY_LOW, + WUPC_BATTERY_MEDIUM, + WUPC_BATTERY_HIGH, + WUPC_BATTERY_FULL +}; + +enum { + WUPC_STATE_DISABLED, + WUPC_STATE_ENABLED +}; + +#define WUPC_ERR_NONE 0 +#define WUPC_ERR_NOT_READY -1 +#define WUPC_ERR_BAD_CHANNEL -2 +#define WUPC_ERR_BADCONF -3 +#define WUPC_ERR_UNKNOWN -4 + +#define WUPC_EXTRA_BUTTON_RSTICK 0x01 +#define WUPC_EXTRA_BUTTON_LSTICK 0x02 +#define WUPC_EXTRA_CHARGING 0x04 +#define WUPC_EXTRA_USBCONNECTED 0x08 + +// Identical to WPAD_CLASSIC_BUTTON_ values in wpad.h +#define WUPC_BUTTON_UP (0x0001<<16) +#define WUPC_BUTTON_LEFT (0x0002<<16) +#define WUPC_BUTTON_ZR (0x0004<<16) +#define WUPC_BUTTON_X (0x0008<<16) +#define WUPC_BUTTON_A (0x0010<<16) +#define WUPC_BUTTON_Y (0x0020<<16) +#define WUPC_BUTTON_B (0x0040<<16) +#define WUPC_BUTTON_ZL (0x0080<<16) +#define WUPC_BUTTON_FULL_R (0x0200<<16) +#define WUPC_BUTTON_PLUS (0x0400<<16) +#define WUPC_BUTTON_HOME (0x0800<<16) +#define WUPC_BUTTON_MINUS (0x1000<<16) +#define WUPC_BUTTON_FULL_L (0x2000<<16) +#define WUPC_BUTTON_DOWN (0x4000<<16) +#define WUPC_BUTTON_RIGHT (0x8000<<16) + +typedef void (*WUPCShutdownCallback)(s32 chan); + +s32 WUPC_Init(void); // Call before WPAD_Init() +s32 WUPC_Disconnect(u8 chan); +void WUPC_Shutdown(void); // Call before WPAD_Shutdown() +void WUPC_SetIdleTimeout(u32 seconds); +void WUPC_SetPowerButtonCallback(WUPCShutdownCallback cb); +void WUPC_SetBatteryDeadCallback(WUPCShutdownCallback cb); +WUPCData *WUPC_Data(u8 chan); +void WUPC_Rumble(u8 chan, bool rumble); +u32 WUPC_ScanPads(void); +u32 WUPC_ButtonsUp(u8 chan); +u32 WUPC_ButtonsDown(u8 chan); +u32 WUPC_ButtonsHeld(u8 chan); +s16 WUPC_lStickX(u8 chan); +s16 WUPC_lStickY(u8 chan); +s16 WUPC_rStickX(u8 chan); +s16 WUPC_rStickY(u8 chan); +u8 WUPC_BatteryLevel(u8 chan); + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/libs/lib/libwupc.a b/libs/lib/libwupc.a new file mode 100644 index 0000000..7baabd5 Binary files /dev/null and b/libs/lib/libwupc.a differ diff --git a/libwupc.patch b/libwupc.patch new file mode 100644 index 0000000..538e80a --- /dev/null +++ b/libwupc.patch @@ -0,0 +1,622 @@ +Index: include/wupc/wupc.h +=================================================================== +--- include/wupc/wupc.h (revision 3) ++++ include/wupc/wupc.h (working copy) +@@ -1,5 +1,6 @@ + /**************************************************************************** + * Copyright (C) 2014 FIX94 ++ * Changes, based on revision 3, by JoostinOnline + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -21,7 +22,7 @@ + extern "C" { + #endif + +-struct WUPCData { ++typedef struct WUPCData_s { + s16 xAxisL; + s16 xAxisR; + s16 yAxisL; +@@ -29,20 +30,68 @@ + u32 button; + u8 battery; + u8 extra; ++} WUPCData; ++ ++enum { ++ WUPC_CHAN_0, ++ WUPC_CHAN_1, ++ WUPC_CHAN_2, ++ WUPC_CHAN_3, ++ WUPC_MAX_REMOTES + }; + ++enum { ++ WUPC_BATTERY_CRITICAL, ++ WUPC_BATTERY_LOW, ++ WUPC_BATTERY_MEDIUM, ++ WUPC_BATTERY_HIGH, ++ WUPC_BATTERY_FULL ++}; ++ ++enum { ++ WUPC_STATE_DISABLED, ++ WUPC_STATE_ENABLED ++}; ++ ++#define WUPC_ERR_NONE 0 ++#define WUPC_ERR_NOT_READY -1 ++#define WUPC_ERR_BAD_CHANNEL -2 ++#define WUPC_ERR_BADCONF -3 ++#define WUPC_ERR_UNKNOWN -4 ++ + #define WUPC_EXTRA_BUTTON_RSTICK 0x01 + #define WUPC_EXTRA_BUTTON_LSTICK 0x02 +- + #define WUPC_EXTRA_CHARGING 0x04 + #define WUPC_EXTRA_USBCONNECTED 0x08 + +-void WUPC_Init(); +-void WUPC_Disconnect(u8 chan); +-void WUPC_Shutdown(); +-struct WUPCData *WUPC_Data(u8 chan); ++// Identical to WPAD_CLASSIC_BUTTON_ values in wpad.h ++#define WUPC_BUTTON_UP (0x0001<<16) ++#define WUPC_BUTTON_LEFT (0x0002<<16) ++#define WUPC_BUTTON_ZR (0x0004<<16) ++#define WUPC_BUTTON_X (0x0008<<16) ++#define WUPC_BUTTON_A (0x0010<<16) ++#define WUPC_BUTTON_Y (0x0020<<16) ++#define WUPC_BUTTON_B (0x0040<<16) ++#define WUPC_BUTTON_ZL (0x0080<<16) ++#define WUPC_BUTTON_FULL_R (0x0200<<16) ++#define WUPC_BUTTON_PLUS (0x0400<<16) ++#define WUPC_BUTTON_HOME (0x0800<<16) ++#define WUPC_BUTTON_MINUS (0x1000<<16) ++#define WUPC_BUTTON_FULL_L (0x2000<<16) ++#define WUPC_BUTTON_DOWN (0x4000<<16) ++#define WUPC_BUTTON_RIGHT (0x8000<<16) ++ ++typedef void (*WUPCShutdownCallback)(s32 chan); ++ ++s32 WUPC_Init(void); // Call before WPAD_Init() ++s32 WUPC_Disconnect(u8 chan); ++void WUPC_Shutdown(void); // Call before WPAD_Shutdown() ++void WUPC_SetIdleTimeout(u32 seconds); ++void WUPC_SetPowerButtonCallback(WUPCShutdownCallback cb); ++void WUPC_SetBatteryDeadCallback(WUPCShutdownCallback cb); ++WUPCData *WUPC_Data(u8 chan); + void WUPC_Rumble(u8 chan, bool rumble); +-u32 WUPC_UpdateButtonStats(); ++u32 WUPC_ScanPads(void); + u32 WUPC_ButtonsUp(u8 chan); + u32 WUPC_ButtonsDown(u8 chan); + u32 WUPC_ButtonsHeld(u8 chan); +@@ -50,6 +99,7 @@ + s16 WUPC_lStickY(u8 chan); + s16 WUPC_rStickX(u8 chan); + s16 WUPC_rStickY(u8 chan); ++u8 WUPC_BatteryLevel(u8 chan); + + #ifdef __cplusplus + } +Index: lib/libwupc.a +=================================================================== +Cannot display: file marked as a binary type. +svn:mime-type = application/octet-stream +Index: Makefile +=================================================================== +--- Makefile (revision 3) ++++ Makefile (working copy) +@@ -20,13 +20,21 @@ + SOURCES := source + DATA := data + INCLUDES := include +- ++INCDIR := $(LIBOGC_INC)/wupc/ ++INCFILE := include/wupc/wupc ++LIBFILE := lib/$(TARGET) + #--------------------------------------------------------------------------------- + # options for code generation + #--------------------------------------------------------------------------------- +-CFLAGS = -g -O2 -Wall -Wextra $(MACHDEP) $(INCLUDE) ++CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE) + + #--------------------------------------------------------------------------------- ++# list of directories containing libraries, this must be the top level containing ++# include and lib ++#--------------------------------------------------------------------------------- ++LIBDIRS := $(DEVKITPRO)/libogc ++ ++#--------------------------------------------------------------------------------- + # no real need to edit anything past this point unless you need to add additional + # rules for different file extensions + #--------------------------------------------------------------------------------- +@@ -64,16 +72,27 @@ + + #--------------------------------------------------------------------------------- + $(BUILD): ++ @echo Building ... + @[ -d $@ ] || mkdir -p $@ + @make --no-print-directory -C $(BUILD) -f $(CURDIR)/Makefile + + #--------------------------------------------------------------------------------- + clean: +- @echo clean ... ++ @echo Cleaning ... + @rm -fr $(BUILD) $(OUTPUT).a + ++#--------------------------------------------------------------------------------- + ++install: ++ @echo Installing ... ++ @mkdir -p $(INCDIR) ++ @install -v -m 644 $(LIBFILE).a $(LIBOGC_LIB) ++ @install -v -m 644 $(INCFILE).h $(INCDIR) + #--------------------------------------------------------------------------------- ++ ++all: clean $(BUILD) install ++#--------------------------------------------------------------------------------- ++ + else + + DEPENDS := $(OFILES:.o=.d) +Index: source/wupc.c +=================================================================== +--- source/wupc.c (revision 3) ++++ source/wupc.c (working copy) +@@ -1,5 +1,6 @@ + /**************************************************************************** + * Copyright (C) 2014 FIX94 ++ * Changes, based on revision 3, by JoostinOnline + * + * This program is free software: you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by +@@ -20,8 +21,12 @@ + #include + #include + #include ++#include + #include + #include ++#include ++#include ++ + #include "wupc_structs.h" + #include "wupc/wupc.h" + +@@ -29,21 +34,41 @@ + + static vu32 __WUPC_ChannelsUsed = 0; + ++static syswd_t __wupc_timer; + static conf_pads __WUPC_Devices; +-static struct WUPCStat *__WUPC_Connected[4]; ++static struct WUPCStat *__WUPC_Connected[WUPC_MAX_REMOTES]; + static struct WUPCStat __WUPC_Status[CONF_PAD_MAX_REGISTERED]; +-static struct WUPCData __WUPC_PadData[4]; +-static struct WUPCButtons __WUPC_PadButtons[4]; ++static WUPCData __WUPC_PadData[WUPC_MAX_REMOTES]; ++static struct WUPCButtons __WUPC_PadButtons[WUPC_MAX_REMOTES]; ++static struct _wpad_cb __wupccb[WUPC_MAX_REMOTES]; ++static s32 __wupc_idletimeout = 300; + +-static u32 __WUPC_Inited = 0; ++static vu32 __WUPC_Inited = WUPC_STATE_DISABLED; + + static const u8 __WUPC_LEDState[] = { 0x10, 0x20, 0x40, 0x80 }; + +-#define CHAN_MAX 4 ++#define TRANSFER_CALIBRATE 0 ++#define TRANSFER_DONE 1 + +-#define TRANSFER_CALIBRATE 0 +-#define TRANSFER_DONE 1 ++static void __wupc_timeouthandler(syswd_t alarm,void *cbarg) ++{ ++ s32 i; ++ struct _wpad_cb *wupccb = (struct _wpad_cb*)cbarg; + ++ ++_thread_dispatch_disable_level; ++ for(i=WUPC_MAX_REMOTES; i--;) { ++ wupccb = &__wupccb[i]; ++ if(__WUPC_Connected[i] != NULL) { ++ wupccb->idle_time++; ++ if(wupccb->idle_time>=__wupc_idletimeout) { ++ wupccb->idle_time = 0; ++ WUPC_Disconnect(i); ++ } ++ } ++ } ++ --_thread_dispatch_disable_level; ++} ++ + static void __WUPC_SetLED(struct bte_pcb *sock, u32 state) + { + u8 buf[2]; +@@ -75,7 +100,7 @@ + __WUPC_PadData[chan].battery = (extradata >> 4) & 0x7; + __WUPC_PadData[chan].extra = extradata & 0xF; + } +- return ERR_OK; ++ return WUPC_ERR_NONE; + } + + static s32 __WUPC_HandleConnect(void *arg,struct bte_pcb *pcb,u8 err) +@@ -82,7 +107,7 @@ + { + struct WUPCStat *stat = (struct WUPCStat*)arg; + +- if(__WUPC_ChannelsUsed >= CHAN_MAX) ++ if(__WUPC_ChannelsUsed >= WUPC_MAX_REMOTES) + { + bte_disconnect(pcb); + return err; +@@ -111,25 +136,25 @@ + if(__WUPC_ChannelsUsed) __WUPC_ChannelsUsed--; + + u32 i; +- for(i = stat->channel; i < 3; ++i) ++ for(i = stat->channel; i < WUPC_MAX_REMOTES-1; ++i) + __WUPC_Connected[i] = __WUPC_Connected[i+1]; +- __WUPC_Connected[3] = NULL; ++ __WUPC_Connected[WUPC_MAX_REMOTES-1] = NULL; + + for(i = 0; i < CONF_PAD_MAX_REGISTERED; ++i) + { +- if(__WUPC_Status[i].channel > stat->channel && __WUPC_Status[i].channel != CHAN_MAX) ++ if(__WUPC_Status[i].channel > stat->channel && __WUPC_Status[i].channel != WUPC_MAX_REMOTES) + { + __WUPC_Status[i].channel--; + __WUPC_SetLED(__WUPC_Status[i].sock, __WUPC_Status[i].channel); + } + } +- stat->channel = CHAN_MAX; ++ stat->channel = WUPC_MAX_REMOTES; + return err; + } + + int __WUPC_RegisterPad(struct WUPCStat *stat, struct bd_addr *_bdaddr) + { +- stat->channel = CHAN_MAX; ++ stat->channel = WUPC_MAX_REMOTES; + stat->bdaddr = *_bdaddr; + + if(stat->sock == NULL) +@@ -136,7 +161,7 @@ + { + stat->sock = bte_new(); + if(stat->sock == NULL) +- return ERR_OK; ++ return WUPC_ERR_NONE; + } + + bte_arg(stat->sock, stat); +@@ -145,14 +170,16 @@ + + bte_registerdeviceasync(stat->sock, _bdaddr, __WUPC_HandleConnect); + +- return ERR_OK; ++ return WUPC_ERR_NONE; + } + + int __wrap_wiiuse_register(struct wiimote_listen_t *wml, struct bd_addr *bdaddr, struct wiimote_t *(*assign_cb)(struct bd_addr *bdaddr)) + { +- if(__WUPC_Inited) ++ u32 level; ++ _CPU_ISR_Disable(level); ++ if(__WUPC_Inited == WUPC_STATE_ENABLED) + { +- u8 got_addr[] = { bdaddr->addr[5], bdaddr->addr[4], bdaddr->addr[3], bdaddr->addr[2], bdaddr->addr[1], bdaddr->addr[0] }; ++ const u8 got_addr[] = { bdaddr->addr[5], bdaddr->addr[4], bdaddr->addr[3], bdaddr->addr[2], bdaddr->addr[1], bdaddr->addr[0] }; + u32 i; + for(i = 0; i < __WUPC_Devices.num_registered; ++i) + { +@@ -159,62 +186,98 @@ + if(strstr(__WUPC_Devices.registered[i].name, "-UC") != NULL) + { + u8 *cur_bdaddr = __WUPC_Devices.registered[i].bdaddr; +- if(memcmp(cur_bdaddr, got_addr, 6) == 0) ++ if(memcmp(cur_bdaddr, got_addr, 6) == 0) { ++ _CPU_ISR_Restore(level); + return __WUPC_RegisterPad(&__WUPC_Status[i], bdaddr); ++ } + } + } + } ++ _CPU_ISR_Restore(level); + return __real_wiiuse_register(wml,bdaddr,assign_cb); + } + +-void WUPC_Init() ++s32 WUPC_Init(void) + { +- if(__WUPC_Inited == 1) +- return; +- if(CONF_GetPadDevices(&__WUPC_Devices) < 0) +- return; +- ++ u32 level; ++ struct timespec tb; ++ memset(__wupccb,0,sizeof(struct _wpad_cb)*WUPC_MAX_REMOTES); ++ _CPU_ISR_Disable(level); ++ if(__WUPC_Inited == WUPC_STATE_ENABLED) { ++ _CPU_ISR_Restore(level); ++ return WUPC_ERR_NOT_READY; ++ } ++ if(CONF_GetPadDevices(&__WUPC_Devices) < 0) { ++ _CPU_ISR_Restore(level); ++ return WUPC_ERR_BADCONF; ++ } + u32 i; +- for(i = 0; i < CHAN_MAX; ++i) ++ for(i = WUPC_MAX_REMOTES; i--;) + __WUPC_Connected[i] = NULL; + +- for(i = 0; i < CONF_PAD_MAX_REGISTERED; ++i) +- __WUPC_Status[i].channel = CHAN_MAX; ++ for(i = CONF_PAD_MAX_REGISTERED; i--;) ++ __WUPC_Status[i].channel = WUPC_MAX_REMOTES; + + __WUPC_ChannelsUsed = 0; +- __WUPC_Inited = 1; ++ ++ if (SYS_CreateAlarm(&__wupc_timer) < 0) ++ { ++ WUPC_Shutdown(); ++ _CPU_ISR_Restore(level); ++ return WUPC_ERR_UNKNOWN; ++ } ++ tb.tv_sec = 1; ++ tb.tv_nsec = 0; ++ SYS_SetPeriodicAlarm(__wupc_timer,&tb,&tb,__wupc_timeouthandler,NULL); ++ ++ __WUPC_Inited = WUPC_STATE_ENABLED; ++ _CPU_ISR_Restore(level); ++ return WUPC_ERR_NONE; + } + +-void WUPC_Disconnect(u8 chan) ++s32 WUPC_Disconnect(u8 chan) + { +- if(chan >= CHAN_MAX || __WUPC_Connected[chan] == NULL) return; ++ u32 level; ++ _CPU_ISR_Disable(level); ++ if(__WUPC_Inited == WUPC_STATE_DISABLED) { ++ _CPU_ISR_Restore(level); ++ return WUPC_ERR_NOT_READY; ++ } ++ if(chan >= WUPC_MAX_REMOTES || __WUPC_Connected[chan] == NULL) return WUPC_ERR_BAD_CHANNEL; + bte_disconnect(__WUPC_Connected[chan]->sock); ++ _CPU_ISR_Restore(level); ++ return WUPC_ERR_NONE; + } + +-void WUPC_Shutdown() ++void WUPC_Shutdown(void) + { +- if(__WUPC_Inited == 0) ++ u32 level; ++ _CPU_ISR_Disable(level); ++ if(__WUPC_Inited == WUPC_STATE_DISABLED) { ++ _CPU_ISR_Restore(level); + return; ++ } + +- __WUPC_Inited = 0; ++ __WUPC_Inited = WUPC_STATE_DISABLED; + + u32 i; +- for(i = 0; i < CONF_PAD_MAX_REGISTERED; ++i) ++ for(i = CONF_PAD_MAX_REGISTERED; i--;) + { +- if(__WUPC_Status[i].channel != CHAN_MAX) ++ if(__WUPC_Status[i].channel != WUPC_MAX_REMOTES) + bte_disconnect(__WUPC_Status[i].sock); + } ++ _CPU_ISR_Restore(level); + } + +-struct WUPCData *WUPC_Data(u8 chan) ++WUPCData *WUPC_Data(u8 chan) + { +- if(chan >= CHAN_MAX || __WUPC_Connected[chan] == NULL) return NULL; ++ if(chan >= WUPC_MAX_REMOTES || __WUPC_Connected[chan] == NULL) return NULL; + return &__WUPC_PadData[chan]; + } + + void WUPC_Rumble(u8 chan, bool rumble) + { +- if(chan >= CHAN_MAX || __WUPC_Connected[chan] == NULL) return; ++ if(chan >= WUPC_MAX_REMOTES || __WUPC_Connected[chan] == NULL) return; + + u8 buf[2]; + buf[0] = 0x11; +@@ -222,11 +285,11 @@ + bte_senddata(__WUPC_Connected[chan]->sock,buf,2); + } + +-u32 WUPC_UpdateButtonStats() ++u32 WUPC_ScanPads(void) + { + u32 newstate, oldstate; + u32 i, ret = 0; +- for(i = 0; i < CHAN_MAX; ++i) ++ for(i = 0; i < WUPC_MAX_REMOTES; ++i) + { + if(__WUPC_Connected[i] == NULL) + return ret; +@@ -242,36 +305,67 @@ + + u32 WUPC_ButtonsUp(u8 chan) + { +- if(chan >= CHAN_MAX || __WUPC_Connected[chan] == NULL) return 0; ++ if(chan >= WUPC_MAX_REMOTES || __WUPC_Connected[chan] == NULL) return 0; + return __WUPC_PadButtons[chan].up; + } + u32 WUPC_ButtonsDown(u8 chan) + { +- if(chan >= CHAN_MAX || __WUPC_Connected[chan] == NULL) return 0; ++ if(chan >= WUPC_MAX_REMOTES || __WUPC_Connected[chan] == NULL) return 0; + return __WUPC_PadButtons[chan].down; + } + u32 WUPC_ButtonsHeld(u8 chan) + { +- if(chan >= CHAN_MAX || __WUPC_Connected[chan] == NULL) return 0; ++ if(chan >= WUPC_MAX_REMOTES || __WUPC_Connected[chan] == NULL) return 0; + return __WUPC_PadButtons[chan].state; + } + s16 WUPC_lStickX(u8 chan) + { +- if(chan >= CHAN_MAX || __WUPC_Connected[chan] == NULL) return 0; ++ if(chan >= WUPC_MAX_REMOTES || __WUPC_Connected[chan] == NULL) return 0; + return __WUPC_PadData[chan].xAxisL; + } + s16 WUPC_lStickY(u8 chan) + { +- if(chan >= CHAN_MAX || __WUPC_Connected[chan] == NULL) return 0; ++ if(chan >= WUPC_MAX_REMOTES || __WUPC_Connected[chan] == NULL) return 0; + return __WUPC_PadData[chan].yAxisL; + } + s16 WUPC_rStickX(u8 chan) + { +- if(chan >= CHAN_MAX || __WUPC_Connected[chan] == NULL) return 0; ++ if(chan >= WUPC_MAX_REMOTES || __WUPC_Connected[chan] == NULL) return 0; + return __WUPC_PadData[chan].xAxisR; + } + s16 WUPC_rStickY(u8 chan) + { +- if(chan >= CHAN_MAX || __WUPC_Connected[chan] == NULL) return 0; ++ if(chan >= WUPC_MAX_REMOTES || __WUPC_Connected[chan] == NULL) return 0; + return __WUPC_PadData[chan].yAxisR; + } ++u8 WUPC_BatteryLevel(u8 chan) ++{ ++ if(chan >= WUPC_MAX_REMOTES || __WUPC_Connected[chan] == NULL) return 0; ++ return __WUPC_PadData[chan].battery; ++} ++s32 WUPC_GetStatus(void) ++{ ++ s32 ret; ++ u32 level; ++ ++ _CPU_ISR_Disable(level); ++ ret = __WUPC_Inited; ++ _CPU_ISR_Restore(level); ++ ++ return ret; ++} ++void WUPC_SetIdleTimeout(u32 seconds) ++{ ++ u32 level; ++ ++ _CPU_ISR_Disable(level); ++ __wupc_idletimeout = seconds; ++ _CPU_ISR_Restore(level); ++} ++inline void WUPC_SetPowerButtonCallback(WUPCShutdownCallback cb) { ++ WPAD_SetPowerButtonCallback(cb); ++} ++inline void WUPC_SetBatteryDeadCallback(WUPCShutdownCallback cb) ++{ ++ WPAD_SetBatteryDeadCallback(cb); ++} +\ No newline at end of file +Index: source/wupc_structs.h +=================================================================== +--- source/wupc_structs.h (revision 3) ++++ source/wupc_structs.h (working copy) +@@ -1,7 +1,39 @@ +- + #ifndef _WUPC_STRUCTS_H_ + #define _WUPC_STRUCTS_H_ + ++#define EVENTQUEUE_LENGTH 16 ++ ++struct _wpad_thresh{ ++ s32 btns; ++ s32 ir; ++ s32 js; ++ s32 acc; ++ s32 wb; ++ s32 mp; ++}; ++ ++struct _wpad_cb { ++ wiimote *wm; ++ s32 data_fmt; ++ s32 queue_head; ++ s32 queue_tail; ++ s32 queue_full; ++ u32 queue_length; ++ u32 dropped_events; ++ s32 idle_time; ++ s32 speaker_enabled; ++ struct _wpad_thresh thresh; ++ ++ void *sound_data; ++ u32 sound_len; ++ u32 sound_off; ++ syswd_t sound_alarm; ++ ++ WPADData lstate; ++ WPADData *queue_ext; ++ WPADData queue_int[EVENTQUEUE_LENGTH]; ++}; ++ + struct WUPCStat { + u32 connected; + u32 transferstate; +Index: usage.txt +=================================================================== +--- usage.txt (revision 3) ++++ usage.txt (working copy) +@@ -1,23 +1,24 @@ +-libwupc - A WiiU Pro Controller Library for Wii Homebrew Applications by FIX94 +-WiiU Pro Controller Documentation from TeHaxor69 +- +-1. Copy the "lib" and "include" folder into your "portlibs" folder +- +-2. Make these modifications to your Makefile: +--add "-lwupc" right behind "-lwiiuse" to your LIBS +--add ",-wrap,wiiuse_register" to your LDFLAGS +- +-3. Modify your code like this: +--make sure to include in all files you use WUPC calls +--call "WUPC_Init" before "WPAD_Init" +--call "WUPC_Shutdown" before "WPAD_Shutdown" +--either use the separate calls or use WUPC_Data at the same place you would normally use the WPAD calls for your data handling +--if you use ButtonsUp, ButtonsUp and/or ButtonsHeld, make sure to call "WUPC_UpdateButtonStats" before "WPAD_ScanPads", +-if you dont use any of these you can ignore "WUPC_UpdateButtonStats" +- +-Notes: +--The X and Y-Axis are going from about -1024 to +1024, make sure you adjust your calculations to that +--The Buttons are using the same layout as the classic controller buttons, use the "WPAD_CLASSIC_BUTTON_" definitions in +--The Battery Status goes from 0 (critical) to 4 (full) +- ++libwupc - A WiiU Pro Controller Library for Wii Homebrew Applications by FIX94 ++Modifications by JoostinOnline ++WiiU Pro Controller Documentation from TeHaxor69 ++ ++1. Copy the "lib" and "include" folder into your "libogc" folder. Alternatively, run "make install" from command line ++ ++2. Make these modifications to your Makefile: ++-Add "-lwupc" right after "-lwiiuse" to your LIBS ++-Add ",-wrap,wiiuse_register" to your LDFLAGS ++ ++3. Modify your code like this: ++-Make sure to include in all files you use WUPC calls ++-Call "WUPC_Init" before "WPAD_Init" ++-Call "WUPC_Shutdown" before "WPAD_Shutdown" ++-Either use the separate calls or use WUPC_Data at the same place you would normally use the WPAD calls for your data handling ++-If you use ButtonsUp, ButtonsUp and/or ButtonsHeld, make sure to call "WUPC_ScanPads" before "WPAD_ScanPads". If you dont use any of these you can ignore "WUPC_ScanPads" ++ ++Notes: ++-The X and Y-Axis are going from about -1024 to +1024, make sure you adjust your calculations to that ++-The Buttons are using the same layout as the classic controller buttons, so you can use the "WPAD_CLASSIC_BUTTON_" definitions in instead of the ones included in wupc.h ++-The Battery Status goes from 0 (critical) to 4 (full) ++-The "WUPC_SetPowerButtonCallback" and "WUPC_SetBatteryDeadCallback" functions will have the same effect as "WPAD_SetPowerButtonCallback" and "WPAD_SetBatteryDeadCallback" (respectively), so there is no need to use both the WPAD and WUPC versions. ++ + Have Fun! +\ No newline at end of file diff --git a/source/sys.c b/source/sys.c index a039fee..cd16809 100644 --- a/source/sys.c +++ b/source/sys.c @@ -33,9 +33,47 @@ #define DML_OR_DM (*(vu32*)(appfile+i+10) == 0x4C697465) // true = DML #define CMP_TIME(X) (difftime(unixTime, (X)) >= 0) +typedef struct { + const u32 titleID; + const s32 revision; +} vIOSdb_t; + u8 sysMenuInfoContent = 0; const char *Regions[] = {"NTSC-J", "NTSC-U", "PAL", "", "KOR", "NTSC-J"}; //Last is actually China +// Distinct vIOS versions +static const vIOSdb_t vIOSdb[] = { + {9, 1290}, + {12, 782}, + {13, 1288}, + {14, 1288}, + {15, 1288}, + {17, 1288}, + {21, 1295}, + {22, 1550}, + {28, 2063}, + {31, 3864}, + {33, 3864}, + {34, 3864}, + {35, 3864}, + {36, 3864}, + {37, 5919}, + {38, 4380}, + {41, 3863}, + {43, 3863}, + {45, 3863}, + {46, 3863}, + {48, 4380}, + {53, 5919}, + {55, 5919}, + {56, 5918}, + {57, 6175}, + {58, 6432}, + //{59, 9249}, // All versions of vIOS59 share version numbers its Wii counterpart + {62, 6942}, // v6430 is a version of both the real and virtual IOS62 + {80, 7200} +}; + int get_title_ios(u64 title) { s32 ret, fd; static char filepath[256] ATTRIBUTE_ALIGN(32); @@ -407,14 +445,24 @@ inline bool CheckBeerTicket(u32 titleID) { return ret; } -inline bool CheckIOSType(void) { +inline bool CheckIOSType(u32 titleID, s32 revision) { u32 start_address = IOS_TOP; const char WL_String[] = {0x57, 0x4C, 0x3A, 0x20, 0x30, 0x32, 0x2F, 0x30, 0x32, 0x2F, 0x31, 0x32}; // "WL: 02/02/12" u32 i; - for(i = start_address; i < 0x94000000 - sizeof(WL_String); i++) { - if (memcmp((char*)i, WL_String, sizeof(WL_String)) == 0) return true; + // This method does not work on vIOS59 (any version) or vIOS62v6942 + for(i = MAX_ELEMENTS(vIOSdb); i--;) { + if(titleID == vIOSdb[i].titleID) { + if (revision == vIOSdb[i].revision) + return IOS_WII_U; + else + break; + } } - return false; + // Should work on all vIOS, but requires AHB access + for(i = start_address; i < 0x94000000 - sizeof(WL_String); i++) { + if (memcmp((char*)i, WL_String, sizeof(WL_String)) == 0) return IOS_WII_U; + } + return IOS_WII; } // Check fake signatures (aka Trucha Bug) @@ -805,36 +853,3 @@ s32 get_miosinfo(char *str) } return 0; } - -// Minimum vIOS versions -const vIOSdb_t vIOSdb[] = { - {9, 1290}, - {12, 782}, - {13, 1288}, - {14, 1288}, - {15, 1288}, - {17, 1288}, - {21, 1295}, - {22, 1550}, - {28, 2063}, - {31, 3864}, - {33, 3864}, - {34, 3864}, - {35, 3864}, - {36, 3864}, - {37, 5919}, - {38, 4380}, - {41, 3863}, - {43, 3863}, - {45, 3863}, - {46, 3863}, - {48, 4380}, - {53, 5919}, - {55, 5919}, - {56, 5918}, - {57, 6175}, - {58, 6432}, - {59, 7201}, - {62, 6430}, - {80, 6430} -}; diff --git a/source/sysCheck.c b/source/sysCheck.c index 6a98374..3186261 100644 --- a/source/sysCheck.c +++ b/source/sysCheck.c @@ -14,6 +14,7 @@ #include #include #include +#include #include "runtimeiospatch.h" #include "SysMenuInfo.h" @@ -43,7 +44,7 @@ static u64 current_time = 0; int main(int argc, char **argv) { __exception_setreload(2); - arguments.forceNoAHBPROT = false; + arguments.AHB_At_Start = AHB_ACCESS; memset(arguments.skipIOSlist, 0, sizeof(arguments.skipIOSlist)); arguments.skipIOScnt = 0; arguments.debug = false; @@ -59,9 +60,10 @@ int main(int argc, char **argv) gprintf("--debug=true\n"); logfile("--debug=true\r\n"); } else if(CHECK_ARG("--forceNoAHBPROT=true")) { - arguments.forceNoAHBPROT = true; + arguments.AHB_At_Start = false; gprintf("--forceNoAHBPROT=true\n"); logfile("--forceNoAHBPROT=true\r\n"); + IOS_ReloadIOS(IOS_GetVersion()); } else if(CHECK_ARG("--skipIOS=")) { arguments.skipIOSlist[arguments.skipIOScnt] = atoi(CHECK_ARG_VAL("--skipIOS=")); gprintf("skipIOS[%i] = %i\r\n", arguments.skipIOScnt, arguments.skipIOSlist[arguments.skipIOScnt]); @@ -71,10 +73,13 @@ int main(int argc, char **argv) } } SysSettings_t SystemInfo; - SystemInfo.deviceType = IS_WII_U; + if(arguments.AHB_At_Start) + SystemInfo.deviceType = IS_WII_U; + else + SystemInfo.deviceType = CONSOLE_UNKNOWN; memset(SystemInfo.miosInfo, 0, sizeof(SystemInfo.miosInfo)); - if (AHB_ACCESS && !arguments.forceNoAHBPROT) IosPatch_RUNTIME(true, false, false, true); + if (AHB_ACCESS) IosPatch_RUNTIME(true, false, false, true); SystemInfo.nandAccess = CheckNANDAccess(); // Get and display the current date and time @@ -117,42 +122,50 @@ int main(int argc, char **argv) homebrew.hbf = HBF_NONE; homebrew.hbcIOS = 0; SystemInfo.dvdSupport = 0; - s32 ret = Title_GetVersionNObuf(TITLE_ID(0x00010001, 0x4C554C5A)); + s32 ret = Title_GetVersionNObuf(TITLE_ID(0x00010001, HBC_TID_OPEN)); if (ret<0) { - ret = Title_GetVersionNObuf(TITLE_ID(0x00010001, 0xAF1BF516)); + ret = Title_GetVersionNObuf(TITLE_ID(0x00010001, HBC_TID_LULZ)); if (ret<0) { - ret = Title_GetVersionNObuf(TITLE_ID(0x00010001, 0x4A4F4449)); + ret = Title_GetVersionNObuf(TITLE_ID(0x00010001, HBC_TID_1_0_7)); if (ret<0) { - homebrew.hbc = HBC_HAXX; - ret = Title_GetVersionNObuf(TITLE_ID(0x00010001, 0x48415858)); + ret = Title_GetVersionNObuf(TITLE_ID(0x00010001, HBC_TID_JODI)); if (ret<0) { - homebrew.hbc = HBC_NONE; - } else { homebrew.hbc = HBC_HAXX; + ret = Title_GetVersionNObuf(TITLE_ID(0x00010001, HBC_TID_HAXX)); + if (ret<0) { + homebrew.hbc = HBC_NONE; + } else { + homebrew.hbc = HBC_HAXX; + homebrew.hbcversion = ret; + } + } else { + homebrew.hbc = HBC_JODI; homebrew.hbcversion = ret; } } else { - homebrew.hbc = HBC_JODI; + homebrew.hbc = HBC_1_0_7; homebrew.hbcversion = ret; + if (homebrew.hbcversion == 0) + homebrew.hbcversion = VERSION_1_1_0; } } else { - homebrew.hbc = HBC_1_0_7; - homebrew.hbcversion = ret; - if (homebrew.hbcversion == 0) - homebrew.hbcversion = VERSION_1_1_0; + homebrew.hbc = HBC_LULZ; + homebrew.hbcversion = (ret != 257) + 1; } } else { - homebrew.hbc = HBC_LULZ; - homebrew.hbcversion = (ret != 257) + 1; + homebrew.hbc = HBC_OPEN; + homebrew.hbcversion = ret; } - if (homebrew.hbc == HBC_LULZ) { - homebrew.hbcIOS = get_title_ios(TITLE_ID(0x00010001, 0x4C554C5A)); // LULZ + if (homebrew.hbc == HBC_OPEN) { + homebrew.hbcIOS = get_title_ios(TITLE_ID(0x00010001, HBC_TID_OPEN)); // OPEN + } else if (homebrew.hbc == HBC_LULZ) { + homebrew.hbcIOS = get_title_ios(TITLE_ID(0x00010001, HBC_TID_LULZ)); // LULZ } else if (homebrew.hbc == HBC_1_0_7) { - homebrew.hbcIOS = get_title_ios(TITLE_ID(0x00010001, 0xAF1BF516)); // ???? + homebrew.hbcIOS = get_title_ios(TITLE_ID(0x00010001, HBC_TID_1_0_7)); // ???? } else if (homebrew.hbc == HBC_JODI) { - homebrew.hbcIOS = get_title_ios(TITLE_ID(0x00010001, 0x4A4F4449)); // JODI + homebrew.hbcIOS = get_title_ios(TITLE_ID(0x00010001, HBC_TID_JODI)); // JODI } else if (homebrew.hbc == HBC_HAXX) { - homebrew.hbcIOS = get_title_ios(TITLE_ID(0x00010001, 0x48415858)); // HAXX + homebrew.hbcIOS = get_title_ios(TITLE_ID(0x00010001, HBC_TID_HAXX)); // HAXX } ret = Title_GetVersionNObuf(TITLE_ID(0x00010001, 0x48424630)); //HBF0 @@ -169,7 +182,7 @@ int main(int argc, char **argv) homebrew.hbfversion = ret; } - if (AHB_ACCESS && !arguments.forceNoAHBPROT) { + if (AHB_ACCESS) { DI_Init(); DI_DriveID id; @@ -337,7 +350,7 @@ int main(int argc, char **argv) if (SystemInfo.nandAccess) get_miosinfo(SystemInfo.miosInfo); // Check running IOS type so we don't have to reload it later - SystemInfo.runningIOSType = (SystemInfo.deviceType == CONSOLE_WII_U) && CheckIOSType(); + SystemInfo.runningIOSType = (SystemInfo.deviceType != CONSOLE_WII) && CheckIOSType(SystemInfo.runningIOS, SystemInfo.runningIOSRevision); // For each titles found for (i = SystemInfo.countIOS; i--;) @@ -501,6 +514,7 @@ int main(int argc, char **argv) } CheckTime(); //Select an IOS to test + WUPC_Init(); WPAD_Init(); PAD_Init(); int selectedIOS = -1; @@ -595,6 +609,7 @@ int main(int argc, char **argv) break; } } + WUPC_Shutdown(); WPAD_Shutdown(); if (selectedIOS > -1) { nbTitles = 1; @@ -641,7 +656,7 @@ int main(int argc, char **argv) // Test IOS type gprintf("// Test IOS type\n"); logfile("// Test IOS type\r\n"); - if(SystemInfo.deviceType == CONSOLE_WII_U) ios[i].infovIOS = CheckIOSType(); + if(SystemInfo.deviceType != CONSOLE_WII) ios[i].infovIOS = CheckIOSType(ios[i].titleID, ios[i].revision); // Test fake signature gprintf("// Test fake signature\n"); @@ -673,6 +688,11 @@ int main(int argc, char **argv) logfile("// Test USB 2.0\r\n"); ios[i].infoUSB2 = CheckUSB2(ios[i].titleID); + // Set sysMenuIOSVersion and sysMenuIOSType if currently running the System Menu IOS + if (ios[i].titleID == SystemInfo.sysMenuIOS) { + SystemInfo.sysMenuIOSVersion = ios[i].revision; + SystemInfo.sysMenuIOSType = ios[i].infovIOS; + } // Check Priiloader if (!SystemInfo.nandAccess && SystemInfo.priiloader == -2 && ios[i].infoNANDAccess) { @@ -896,9 +916,15 @@ int main(int argc, char **argv) if (homebrew.hbf > HBF_NONE) sprintf(ReportBuffer[HBF], TXT_HBF, homebrew.hbfversion); + // If console type is unknown (because no AHB access), try to determine it by the IOS80 version. Less reliable + if ((SystemInfo.deviceType == CONSOLE_UNKNOWN) && (SystemInfo.sysMenuIOSType == IOS_WII_U) && (SystemInfo.sysMenuIOS == 80) && (SystemInfo.sysMenuIOSVersion == 7200)) + SystemInfo.deviceType = CONSOLE_WII_U; + + const char *device_types[] = {"Wii", "vWii", TXT_Unknown}; + sprintf(ReportBuffer[HOLLYWOOD], TXT_Hollywood, HOLLYWOOD_VERSION); sprintf(ReportBuffer[CONSOLE_ID], TXT_ConsoleID, SystemInfo.deviceID); - sprintf(ReportBuffer[CONSOLE_TYPE], TXT_ConsoleType, SystemInfo.deviceType ? "vWii" : "Wii"); + sprintf(ReportBuffer[CONSOLE_TYPE], TXT_ConsoleType, device_types[SystemInfo.deviceType]); sprintf(ReportBuffer[COUNTRY], TXT_ShopCountry, (strlen(SystemInfo.country)) ? SystemInfo.country : TXT_Unknown, SystemInfo.shopcode); sprintf(ReportBuffer[BOOT2_VERSION], TXT_vBoot2, SystemInfo.boot2version); sprintf(ReportBuffer[NR_OF_TITLES], TXT_NrOfTitles, SystemInfo.countTitles); @@ -1053,6 +1079,7 @@ int main(int argc, char **argv) int LineNr = 0; + WUPC_Init(); WPAD_Init(); bool reportIsDisplayed = false; while (1) { diff --git a/source/tools.c b/source/tools.c index 37aee19..ff6bcf4 100644 --- a/source/tools.c +++ b/source/tools.c @@ -12,6 +12,7 @@ #include #include #include +#include #include "sys.h" #include "SysMenuInfo.h" @@ -87,65 +88,76 @@ void NandShutdown(void) NandInitialized = false; } -u32 DetectInput(u8 DownOrHeld) { +u32 DetectInput(u8 DownOrHeld) +{ u32 pressed = 0; - u16 gcpressed = 0; - // Wii Remote (and Classic Controller) take precedence over GC to save time - if (WPAD_ScanPads() >= WPAD_ERR_NONE) // Scan the Wii remotes. If there any problems, skip checking buttons + u32 gcpressed = 0; + + // WiiMote, Classic Controller and Wii U Pro Controller take precedence over the GCN Controller to save time + if (WUPC_ScanPads() > WPAD_ERR_NONE) { - if (DownOrHeld == DI_BUTTONS_DOWN) { - pressed = WPAD_ButtonsDown(0) | WPAD_ButtonsDown(1) | WPAD_ButtonsDown(2) | WPAD_ButtonsDown(3); //Store pressed buttons + if (DownOrHeld == DI_BUTTONS_DOWN) + { + pressed = WUPC_ButtonsDown(0) | WUPC_ButtonsDown(1) | WUPC_ButtonsDown(2) | WUPC_ButtonsDown(3); // Store pressed buttons } else { - pressed = WPAD_ButtonsHeld(0) | WPAD_ButtonsHeld(1) | WPAD_ButtonsHeld(2) | WPAD_ButtonsHeld(3); //Store pressed buttons + pressed = WUPC_ButtonsHeld(0) | WUPC_ButtonsHeld(1) | WUPC_ButtonsHeld(2) | WUPC_ButtonsHeld(3); // Store held buttons } - - // Convert to wiimote values - if (pressed & WPAD_CLASSIC_BUTTON_ZR) pressed |= WPAD_BUTTON_PLUS; - if (pressed & WPAD_CLASSIC_BUTTON_ZL) pressed |= WPAD_BUTTON_MINUS; - - if (pressed & WPAD_CLASSIC_BUTTON_PLUS) pressed |= WPAD_BUTTON_PLUS; - if (pressed & WPAD_CLASSIC_BUTTON_MINUS) pressed |= WPAD_BUTTON_MINUS; - - if (pressed & WPAD_CLASSIC_BUTTON_A) pressed |= WPAD_BUTTON_A; - if (pressed & WPAD_CLASSIC_BUTTON_B) pressed |= WPAD_BUTTON_B; - if (pressed & WPAD_CLASSIC_BUTTON_X) pressed |= WPAD_BUTTON_2; - if (pressed & WPAD_CLASSIC_BUTTON_Y) pressed |= WPAD_BUTTON_1; - if (pressed & WPAD_CLASSIC_BUTTON_HOME) pressed |= WPAD_BUTTON_HOME; - - if (pressed & WPAD_CLASSIC_BUTTON_UP) pressed |= WPAD_BUTTON_UP; - if (pressed & WPAD_CLASSIC_BUTTON_DOWN) pressed |= WPAD_BUTTON_DOWN; - if (pressed & WPAD_CLASSIC_BUTTON_LEFT) pressed |= WPAD_BUTTON_LEFT; - if (pressed & WPAD_CLASSIC_BUTTON_RIGHT) pressed |= WPAD_BUTTON_RIGHT; + } else + if (WPAD_ScanPads() > WPAD_ERR_NONE) + { + if (DownOrHeld == DI_BUTTONS_DOWN) + { + pressed = WPAD_ButtonsDown(0) | WPAD_ButtonsDown(1) | WPAD_ButtonsDown(2) | WPAD_ButtonsDown(3); // Store pressed buttons + } else { + pressed = WPAD_ButtonsHeld(0) | WPAD_ButtonsHeld(1) | WPAD_ButtonsHeld(2) | WPAD_ButtonsHeld(3); // Store held buttons + } } - - // Return Classic Controller and Wii Remote values + + // Convert to WiiMote values + if (pressed & WPAD_CLASSIC_BUTTON_ZR) pressed |= WPAD_BUTTON_PLUS; + if (pressed & WPAD_CLASSIC_BUTTON_ZL) pressed |= WPAD_BUTTON_MINUS; + + if (pressed & WPAD_CLASSIC_BUTTON_PLUS) pressed |= WPAD_BUTTON_PLUS; + if (pressed & WPAD_CLASSIC_BUTTON_MINUS) pressed |= WPAD_BUTTON_MINUS; + + if (pressed & WPAD_CLASSIC_BUTTON_A) pressed |= WPAD_BUTTON_A; + if (pressed & WPAD_CLASSIC_BUTTON_B) pressed |= WPAD_BUTTON_B; + if (pressed & WPAD_CLASSIC_BUTTON_X) pressed |= WPAD_BUTTON_2; + if (pressed & WPAD_CLASSIC_BUTTON_Y) pressed |= WPAD_BUTTON_1; + if (pressed & WPAD_CLASSIC_BUTTON_HOME) pressed |= WPAD_BUTTON_HOME; + + if (pressed & WPAD_CLASSIC_BUTTON_UP) pressed |= WPAD_BUTTON_UP; + if (pressed & WPAD_CLASSIC_BUTTON_DOWN) pressed |= WPAD_BUTTON_DOWN; + if (pressed & WPAD_CLASSIC_BUTTON_LEFT) pressed |= WPAD_BUTTON_LEFT; + if (pressed & WPAD_CLASSIC_BUTTON_RIGHT) pressed |= WPAD_BUTTON_RIGHT; + + // Return WiiMote / Classic Controller / Wii U Pro Controller values if (pressed) return pressed; - - // No buttons on the Wii remote or Classic Controller were pressed - if (PAD_ScanPads() >= PAD_ERR_NONE) + + // No buttons on the WiiMote or Classic Controller were pressed + if (PAD_ScanPads() > PAD_ERR_NONE) { - if (DownOrHeld == DI_BUTTONS_HELD) { - gcpressed = PAD_ButtonsHeld(0) | PAD_ButtonsHeld(1) | PAD_ButtonsHeld(2) | PAD_ButtonsHeld(3); //Store pressed buttons + if (DownOrHeld == DI_BUTTONS_DOWN) + { + gcpressed = PAD_ButtonsDown(0) | PAD_ButtonsDown(1) | PAD_ButtonsDown(2) | PAD_ButtonsDown(3); // Store pressed buttons } else { - gcpressed = PAD_ButtonsDown(0) | PAD_ButtonsDown(1) | PAD_ButtonsDown(2) | PAD_ButtonsDown(3); //Store pressed buttons - } - - if (gcpressed) { - // Button on GC controller was pressed - if (gcpressed & PAD_TRIGGER_Z) pressed |= WPAD_NUNCHUK_BUTTON_Z; - if (gcpressed & PAD_TRIGGER_R) pressed |= WPAD_BUTTON_PLUS; - if (gcpressed & PAD_TRIGGER_L) pressed |= WPAD_BUTTON_MINUS; - if (gcpressed & PAD_BUTTON_A) pressed |= WPAD_BUTTON_A; - if (gcpressed & PAD_BUTTON_B) pressed |= WPAD_BUTTON_B; - if (gcpressed & PAD_BUTTON_X) pressed |= WPAD_BUTTON_1; - if (gcpressed & PAD_BUTTON_Y) pressed |= WPAD_BUTTON_2; - if (gcpressed & PAD_BUTTON_MENU) pressed |= WPAD_BUTTON_HOME; - if (gcpressed & PAD_BUTTON_UP) pressed |= WPAD_BUTTON_UP; - if (gcpressed & PAD_BUTTON_LEFT) pressed |= WPAD_BUTTON_LEFT; - if (gcpressed & PAD_BUTTON_DOWN) pressed |= WPAD_BUTTON_DOWN; - if (gcpressed & PAD_BUTTON_RIGHT) pressed |= WPAD_BUTTON_RIGHT; + gcpressed = PAD_ButtonsHeld(0) | PAD_ButtonsHeld(1) | PAD_ButtonsHeld(2) | PAD_ButtonsHeld(3); // Store held buttons } + + // Convert to WiiMote values + if (gcpressed & PAD_TRIGGER_R) pressed |= WPAD_BUTTON_PLUS; + if (gcpressed & PAD_TRIGGER_L) pressed |= WPAD_BUTTON_MINUS; + if (gcpressed & PAD_BUTTON_A) pressed |= WPAD_BUTTON_A; + if (gcpressed & PAD_BUTTON_B) pressed |= WPAD_BUTTON_B; + if (gcpressed & PAD_BUTTON_X) pressed |= WPAD_BUTTON_2; + if (gcpressed & PAD_BUTTON_Y) pressed |= WPAD_BUTTON_1; + if (gcpressed & PAD_BUTTON_MENU) pressed |= WPAD_BUTTON_HOME; + if (gcpressed & PAD_BUTTON_UP) pressed |= WPAD_BUTTON_UP; + if (gcpressed & PAD_BUTTON_DOWN) pressed |= WPAD_BUTTON_DOWN; + if (gcpressed & PAD_BUTTON_LEFT) pressed |= WPAD_BUTTON_LEFT; + if (gcpressed & PAD_BUTTON_RIGHT) pressed |= WPAD_BUTTON_RIGHT; } + return pressed; }