diff --git a/HISTORY.txt b/HISTORY.txt index a6c626e..9a5dd23 100644 --- a/HISTORY.txt +++ b/HISTORY.txt @@ -135,6 +135,7 @@ Genesis Plus GX 1.7.5 (xx/xx/xxxx) (Eke-Eke) * added configurable FPS display & toggleable fast-forward key combo (HOME + MINUS with Wii controllers or R TRIGGER + START with Gamecube controller) * added 50hz progressive mode (576p) support for emulation +* added WiiU GamePad Controller support on vWii (Fix94) * reduced SRAM files size * improved A/V Sync: when VSYNC is enabled, audio resampler output rate is now adjusted (+/-0,1 %) to always keep audio & video synchronized and input lag is reduced by one frame. diff --git a/LICENSE.txt b/LICENSE.txt index 5c2d9ef..87ab7d5 100644 --- a/LICENSE.txt +++ b/LICENSE.txt @@ -74,7 +74,7 @@ OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------------------- -LIBCHDR is distributed under following licenses: +LIBCHDR is distributed with code under following licenses: MAME CHD interface @@ -166,11 +166,35 @@ original LZMA SDK code, either in source code form or as a compiled binary, for any purpose, commercial or non-commercial, and by any means. ----------------------------------------------------------------------------------------- +NTSC FILTER LIBRARY +------------------- + +Copyright (C) 2006-2007 Shay Green. This module is free software; you +can redistribute it and/or modify it under the terms of the GNU Lesser +General Public License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. This +module 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 Lesser General Public License for more +details. You should have received a copy of the GNU Lesser General Public +License along with this module; if not, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ -NTSC Filter and Blip Buffer libraries are distributed under the -terms of the GNU Lesser General Public License (LGPL) +BLIP BUFFER LIBRARY +------------------- + +Copyright (C) 2003-2009 Shay Green. This library is free software; +you can redistribute it and/or modify it under the terms of the GNU Lesser +General Public License as published by the Free Software Foundation; either +version 2.1 of the License, or (at your option) any later version. This +library 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 Lesser General Public License for more +details. You should have received a copy of the GNU Lesser General Public +License along with this module; if not, write to the Free Software Foundation, +Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA */ + GNU LESSER GENERAL PUBLIC LICENSE @@ -679,7 +703,111 @@ That's all there is to it! ---------------------------------------------------------------------------------------- -Gamecube & Wii ports are linked with LIBASND library and includes code distributed under +Gamecube & Wii ports are linked with LIBOGC library which is distributed under +the following license: + + Copyright (C) 2004 - 2009 + Michael Wiedenbauer (shagkur) + Dave Murphy (WinterMute) + + This software is provided 'as-is', without any express or implied + warranty. In no event will the authors be held liable for any + damages arising from the use of this software. + + Permission is granted to anyone to use this software for any + purpose, including commercial applications, and to alter it and + redistribute it freely, subject to the following restrictions: + + 1. The origin of this software must not be misrepresented; you + must not claim that you wrote the original software. If you use + this software in a product, an acknowledgment in the product + documentation would be appreciated but is not required. + 2. Altered source versions must be plainly marked as such, and + must not be misrepresented as being the original software. + 3. This notice may not be removed or altered from any source + distribution. + +---------------------------------------------------------------------------------------- + +Gamecube & Wii ports are linked with LIBFAT library which is distributed under +the following license: + + Copyright (c) 2006 - 2012 + Michael "Chishm" Chisholm + Dave "WinterMute" Murphy + + Redistribution and use in source and binary forms, with or without modification, + are permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, + this list of conditions and the following disclaimer. + 2. Redistributions in binary form must reproduce the above copyright notice, + this list of conditions and the following disclaimer in the documentation and/or + other materials provided with the distribution. + 3. The name of the author may not be used to endorse or promote products derived + from this software without specific prior written permission. + + THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY + AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR BE + LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL + DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; + LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, + EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +---------------------------------------------------------------------------------------- + +Gamecube & Wii ports are linked with LIBPNG library which is distributed under +the following license: + + Copyright (c) 1998-2010 Glenn Randers-Pehrson + (Version 0.96 Copyright (c) 1996, 1997 Andreas Dilger) + (Version 0.88 Copyright (c) 1995, 1996 Guy Eric Schalnat, Group 42, Inc.) + + The PNG Reference Library is supplied "AS IS". The Contributing Authors + and Group 42, Inc. disclaim all warranties, expressed or implied, + including, without limitation, the warranties of merchantability and of + fitness for any purpose. The Contributing Authors and Group 42, Inc. + assume no liability for direct, indirect, incidental, special, exemplary, + or consequential damages, which may result from the use of the PNG + Reference Library, even if advised of the possibility of such damage. + + There is no warranty against interference with your enjoyment of the + + library or against infringement. There is no warranty that our + + efforts or the library will fulfill any of your particular purposes + + or needs. This library is provided with all faults, and the entire + + risk of satisfactory quality, performance, accuracy, and effort is with + + the user. + + Permission is hereby granted to use, copy, modify, and distribute this + source code, or portions hereof, for any purpose, without fee, subject + to the following restrictions: + + 1. The origin of this source code must not be misrepresented. + + 2. Altered versions must be plainly marked as such and + must not be misrepresented as being the original source. + + 3. This Copyright notice may not be removed or altered from + any source or altered source distribution. + + The Contributing Authors and Group 42, Inc. specifically permit, without + fee, and encourage the use of this source code as a component to + supporting the PNG file format in commercial products. If you use this + source code in a product, acknowledgment is not required but would be + appreciated. + +---------------------------------------------------------------------------------------- + +Gamecube & Wii ports are linked with LIBASND library which is distributed under the following license: Copyright (c) 2008 Hermes @@ -709,5 +837,25 @@ THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ---------------------------------------------------------------------------------------- +Wii port is linked with WiiDRC library which is distributed under +the following license: +Copyright (c) 2017 FIX94 +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in all +copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE +SOFTWARE. diff --git a/builds/genplus_wii.dol b/builds/genplus_wii.dol index d20c01a..20e1ded 100644 Binary files a/builds/genplus_wii.dol and b/builds/genplus_wii.dol differ diff --git a/gx/config.h b/gx/config.h index 9bc3097..4357258 100644 --- a/gx/config.h +++ b/gx/config.h @@ -3,7 +3,7 @@ * * Genesis Plus GX configuration file support * - * Copyright Eke-Eke (2007-2016) + * Copyright Eke-Eke (2007-2017) * * Redistribution and use of this code or any derivative works are permitted * provided that the following conditions are met: @@ -97,7 +97,7 @@ typedef struct t_input_config input[MAX_INPUTS]; uint16 pad_keymap[4][MAX_KEYS+1]; #ifdef HW_RVL - uint32 wpad_keymap[4*3][MAX_KEYS]; + uint32 wpad_keymap[4*3+1][MAX_KEYS]; uint8 autosleep; int32 calx; int32 caly; diff --git a/gx/gui/menu.c b/gx/gui/menu.c index 77e0194..ae0d673 100644 --- a/gx/gui/menu.c +++ b/gx/gui/menu.c @@ -47,6 +47,7 @@ #ifdef HW_RVL #include +#include "wiidrc.h" #endif #include @@ -122,6 +123,7 @@ extern const u8 ctrl_gamecube_png[]; extern const u8 ctrl_classic_png[]; extern const u8 ctrl_nunchuk_png[]; extern const u8 ctrl_wiimote_png[]; +extern const u8 ctrl_wiiu_png[]; #endif /* Generic images */ @@ -2350,13 +2352,14 @@ static void ctrlmenu(void) /* Player Configuration device items */ #ifdef HW_RVL - gui_item items_device[5] = + gui_item items_device[6] = { {NULL,ctrl_option_off_png ,"Input\nDevice","Select Input Controller",534,244,24,24}, {NULL,ctrl_gamecube_png ,"Input\nDevice","Select Input Controller",530,246,36,24}, {NULL,ctrl_wiimote_png ,"Input\nDevice","Select Input Controller",526,250,40,12}, {NULL,ctrl_nunchuk_png ,"Input\nDevice","Select Input Controller",532,242,32,32}, {NULL,ctrl_classic_png ,"Input\nDevice","Select Input Controller",526,242,40,32}, + {NULL,ctrl_wiiu_png ,"Input\nDevice","Select Input Controller",526,246,40,24}, }; #else gui_item items_device[2] = @@ -2392,6 +2395,10 @@ static void ctrlmenu(void) items_device[2].texture = gxTextureOpenPNG(items_device[2].data,0); items_device[3].texture = gxTextureOpenPNG(items_device[3].data,0); items_device[4].texture = gxTextureOpenPNG(items_device[4].data,0); + if (WiiDRC_Inited()) + { + items_device[5].texture = gxTextureOpenPNG(items_device[5].data,0); + } #endif /* restore current menu elements */ @@ -2920,6 +2927,18 @@ static void ctrlmenu(void) } if (config.input[player].port >= 4) + { + /* test WiiU gamepad */ + config.input[player].device = 4; + config.input[player].port = 0; + } + } + + /* autodetect WiiU gamepad */ + if (config.input[player].device == 4) + { + /* support for only one gamepad */ + if (!WiiDRC_Inited() || !WiiDRC_Connected() || (config.input[player].port >= 1)) { /* no input controller left */ config.input[player].device = -1; @@ -3087,6 +3106,10 @@ static void ctrlmenu(void) gxTextureClose(&items_device[2].texture); gxTextureClose(&items_device[3].texture); gxTextureClose(&items_device[4].texture); + if (WiiDRC_Inited()) + { + gxTextureClose(&items_device[5].texture); + } #endif } diff --git a/gx/gx_input.c b/gx/gx_input.c index ccf7a12..2d6bb34 100644 --- a/gx/gx_input.c +++ b/gx/gx_input.c @@ -3,7 +3,7 @@ * * Genesis Plus GX input support * - * Copyright Eke-Eke (2007-2015) + * Copyright Eke-Eke (2007-2017) * * Redistribution and use of this code or any derivative works are permitted * provided that the following conditions are met: @@ -40,10 +40,12 @@ #include "shared.h" #include "font.h" #include "gui.h" +#include "menu.h" #include "cheats.h" #ifdef HW_RVL #include +#include "wiidrc.h" #endif /* Analog sticks sensitivity */ @@ -77,11 +79,12 @@ #define PAD_RIGHT 3 /* default directions mapping */ -static u32 wpad_dirmap[3][4] = +static u32 wpad_dirmap[4][4] = { - {WPAD_BUTTON_RIGHT, WPAD_BUTTON_LEFT, WPAD_BUTTON_UP, WPAD_BUTTON_DOWN}, /* WIIMOTE */ - {WPAD_BUTTON_UP, WPAD_BUTTON_DOWN, WPAD_BUTTON_LEFT, WPAD_BUTTON_RIGHT}, /* WIIMOTE + NUNCHUK */ - {WPAD_CLASSIC_BUTTON_UP, WPAD_CLASSIC_BUTTON_DOWN, WPAD_CLASSIC_BUTTON_LEFT, WPAD_CLASSIC_BUTTON_RIGHT} /* CLASSIC */ + {WPAD_BUTTON_RIGHT, WPAD_BUTTON_LEFT, WPAD_BUTTON_UP, WPAD_BUTTON_DOWN}, /* WIIMOTE */ + {WPAD_BUTTON_UP, WPAD_BUTTON_DOWN, WPAD_BUTTON_LEFT, WPAD_BUTTON_RIGHT}, /* WIIMOTE + NUNCHUK */ + {WPAD_CLASSIC_BUTTON_UP, WPAD_CLASSIC_BUTTON_DOWN, WPAD_CLASSIC_BUTTON_LEFT, WPAD_CLASSIC_BUTTON_RIGHT}, /* CLASSIC */ + {WIIDRC_BUTTON_UP, WIIDRC_BUTTON_DOWN, WIIDRC_BUTTON_LEFT, WIIDRC_BUTTON_RIGHT} /* WIIU GAMEPAD */ }; #define WPAD_BUTTONS_HELD (WPAD_BUTTON_UP | WPAD_BUTTON_DOWN | WPAD_BUTTON_LEFT | WPAD_BUTTON_RIGHT | \ @@ -89,6 +92,10 @@ static u32 wpad_dirmap[3][4] = WPAD_CLASSIC_BUTTON_UP | WPAD_CLASSIC_BUTTON_DOWN | WPAD_CLASSIC_BUTTON_LEFT | WPAD_CLASSIC_BUTTON_RIGHT | \ WPAD_CLASSIC_BUTTON_FULL_L | WPAD_CLASSIC_BUTTON_FULL_R | WPAD_CLASSIC_BUTTON_A) +#define WIIU_BUTTONS_HELD (WIIDRC_BUTTON_UP | WIIDRC_BUTTON_DOWN | WIIDRC_BUTTON_LEFT | WIIDRC_BUTTON_RIGHT | \ + WIIDRC_BUTTON_MINUS | WIIDRC_BUTTON_PLUS | WIIDRC_BUTTON_A | \ + WIIDRC_BUTTON_L | WIIDRC_BUTTON_ZL | WIIDRC_BUTTON_R | WIIDRC_BUTTON_ZR) + #endif #define PAD_BUTTONS_HELD (PAD_BUTTON_UP | PAD_BUTTON_DOWN | PAD_BUTTON_LEFT | PAD_BUTTON_RIGHT | \ @@ -444,7 +451,7 @@ static void pad_update(s8 chan, u8 i) { /* Calculate angle (in degree) */ ang = 90.0 - (atan((float)y / (float)x) * 180.0 / M_PI); - if (x < 0) ang += 180.0; + if (x < 0) ang += 180.0; /* 8 bottom sensors = 8 areas */ if ((ang > 22.5) && (ang <= 67.5)) input.pad[i] |= INPUT_ACTIVATOR_2L; @@ -465,7 +472,7 @@ static void pad_update(s8 chan, u8 i) { /* Calculate angle (in degree) */ ang = 90.0 - (atan((float)y / (float)x) * 180.0 / M_PI); - if (x < 0) ang += 180.0; + if (x < 0) ang += 180.0; /* 8 top sensors = 8 areas */ if ((ang > 22.5) && (ang <= 67.5)) input.pad[i] |= INPUT_ACTIVATOR_2U; @@ -523,7 +530,7 @@ static int wpad_StickX(WPADData *data, u8 right) /* adjust against center position */ pos -= center; - /* return interpolated range [-128;127] */ + /* return interpolated range [-128;127] */ if (pos > 0) { return (int)(127.0 * ((float)pos / (float)(max - center))); @@ -572,7 +579,7 @@ static int wpad_StickY(WPADData *data, u8 right) /* adjust against center position */ pos -= center; - /* return interpolated range [-128;127] */ + /* return interpolated range [-128;127] */ if (pos > 0) { return (int)(127.0 * ((float)pos / (float)(max - center))); @@ -595,13 +602,25 @@ static void wpad_config(u8 exp, int chan, int first_key, int last_key) inputs_disabled = 1; /* Check if device is connected */ - WPAD_Probe(chan, &p); + if (exp <= WPAD_EXP_CLASSIC) + { + WPAD_Probe(chan, &p); + } + else + { + if (WiiDRC_Inited() && WiiDRC_Connected()) + { + p = exp; + } + } + + /* Device not detected */ if (((exp > WPAD_EXP_NONE) && (p != exp)) || (p == 255)) { - /* device not detected */ - if (exp == WPAD_EXP_NONE) sprintf(msg, "WIIMOTE #%d is not connected !", chan+1); - if (exp == WPAD_EXP_NUNCHUK) sprintf(msg, "NUNCHUK #%d is not connected !", chan+1); - if (exp == WPAD_EXP_CLASSIC) sprintf(msg, "CLASSIC #%d is not connected !", chan+1); + if (exp == WPAD_EXP_NONE) sprintf(msg, "WIIMOTE #%d is not connected !", chan+1); + else if (exp == WPAD_EXP_NUNCHUK) sprintf(msg, "NUNCHUK #%d is not connected !", chan+1); + else if (exp == WPAD_EXP_CLASSIC) sprintf(msg, "CLASSIC #%d is not connected !", chan+1); + else sprintf(msg, "WIIU GAMEPAD is not connected !"); GUI_WaitPrompt("Error",msg); /* re-enable background PAD scanning and exit */ @@ -616,10 +635,21 @@ static void wpad_config(u8 exp, int chan, int first_key, int last_key) if (strcmp(keyname[first_key], "N.A")) { /* remove any pending buttons */ - while (WPAD_ButtonsHeld(chan)) + if (exp <= WPAD_EXP_CLASSIC) { - VIDEO_WaitVSync(); - WPAD_ScanPads(); + while (WPAD_ButtonsHeld(chan)) + { + VIDEO_WaitVSync(); + WPAD_ScanPads(); + } + } + else + { + while (WiiDRC_ButtonsHeld()) + { + VIDEO_WaitVSync(); + WiiDRC_ScanPads(); + } } /* configurable button */ @@ -631,8 +661,16 @@ static void wpad_config(u8 exp, int chan, int first_key, int last_key) while (!p) { VIDEO_WaitVSync(); - WPAD_ScanPads(); - p = WPAD_ButtonsDown(chan); + if (exp <= WPAD_EXP_CLASSIC) + { + WPAD_ScanPads(); + p = WPAD_ButtonsDown(chan); + } + else + { + WiiDRC_ScanPads(); + p = WiiDRC_ButtonsDown(); + } } /* detect pressed key */ @@ -683,9 +721,20 @@ static void wpad_config(u8 exp, int chan, int first_key, int last_key) break; } + /* WiiU GamePad Controller */ default: { - first_key = MAX_KEYS; + if (p & WIIDRC_BUTTON_A) p = WIIDRC_BUTTON_A; + else if (p & WIIDRC_BUTTON_B) p = WIIDRC_BUTTON_B; + else if (p & WIIDRC_BUTTON_X) p = WIIDRC_BUTTON_X; + else if (p & WIIDRC_BUTTON_Y) p = WIIDRC_BUTTON_Y; + else if (p & WIIDRC_BUTTON_ZL) p = WIIDRC_BUTTON_ZL; + else if (p & WIIDRC_BUTTON_ZR) p = WIIDRC_BUTTON_ZR; + else if (p & WIIDRC_BUTTON_PLUS) p = WIIDRC_BUTTON_PLUS; + else if (p & WIIDRC_BUTTON_MINUS) p = WIIDRC_BUTTON_MINUS; + else if (p & WIIDRC_BUTTON_L) p = WIIDRC_BUTTON_L; + else if (p & WIIDRC_BUTTON_R) p = WIIDRC_BUTTON_R; + else first_key = MAX_KEYS; break; } } @@ -693,17 +742,28 @@ static void wpad_config(u8 exp, int chan, int first_key, int last_key) /* update key mapping */ if (first_key < MAX_KEYS) { - config.wpad_keymap[exp + (chan * 3)][first_key] = p; + config.wpad_keymap[4*exp + chan][first_key] = p; } } } while (first_key++ < last_key); /* remove any pending buttons */ - while (WPAD_ButtonsHeld(chan)) + if (exp <= WPAD_EXP_CLASSIC) { - VIDEO_WaitVSync(); - WPAD_ScanPads(); + while (WPAD_ButtonsHeld(chan)) + { + VIDEO_WaitVSync(); + WPAD_ScanPads(); + } + } + else + { + while (WiiDRC_ButtonsHeld()) + { + VIDEO_WaitVSync(); + WiiDRC_ScanPads(); + } } /* re-enable background PAD scanning and exit */ @@ -715,21 +775,59 @@ static void wpad_update(s8 chan, u8 i, u32 exp) /* WPAD data */ WPADData *data = WPAD_Data(chan); - /* WPAD status */ + /* Button status */ u32 p = data->btns_h; /* Analog sticks */ - s8 x = 0; - s8 y = 0; + s16 x = 0; + s16 y = 0; - if (exp != WPAD_EXP_NONE) + /* WiiU GamePad Controller support */ + if (exp > WPAD_EXP_CLASSIC) { + WiiDRC_ScanPads(); + if (WiiDRC_ShutdownRequested()) + { + Shutdown = ConfigRequested = 1; + reload = 0; + return; + } + + p = WiiDRC_ButtonsHeld(); + + /* Default Wii controller menu keys */ + if (WiiDRC_ButtonsDown() & WIIDRC_BUTTON_HOME) + { + /* Default fast-forward key combo */ + if (p & WIIDRC_BUTTON_MINUS) + { + audioSync ^= AUDIO_WAIT; + videoSync = (audioSync && config.vsync && (gc_pal != vdp_pal)) ? VIDEO_WAIT : 0; + return; + } + + /* Return to emulator settings */ + ConfigRequested = 1; + return; + } + + /* Left Analog Stick */ + x = (WiiDRC_lStickX() * 128) / 75; + y = (WiiDRC_lStickY() * 128) / 75; + if (x > 127) x = 127; + else if (x < -128) x = -128; + if (y > 127) y = 127; + else if (y < -128) y = -128; + } + else if (exp != WPAD_EXP_NONE) + { + /* Left Analog Stick */ x = wpad_StickX(data,0); y = wpad_StickY(data,0); } /* Retrieve current key mapping */ - u32 *wpad_keymap = config.wpad_keymap[exp + (chan * 3)]; + u32 *wpad_keymap = config.wpad_keymap[4*exp + chan]; /* Emulated device */ switch (input.dev[i]) @@ -772,11 +870,24 @@ static void wpad_update(s8 chan, u8 i, u32 exp) input.analog[i][1] = y ? (127 - y) : 128; /* Right Stick analog position [0-255] */ - if (exp == WPAD_EXP_CLASSIC) + if (exp >= WPAD_EXP_CLASSIC) { - /* Classic Controller right stick */ - x = wpad_StickX(data,1); - y = wpad_StickY(data,1); + if (exp > WPAD_EXP_CLASSIC) + { + /* WiiU GamePad Controller right stick */ + x = (WiiDRC_rStickX() * 128) / 75; + y = (WiiDRC_rStickY() * 128) / 75; + if (x > 127) x = 127; + else if (x < -128) x = -128; + if (y > 127) y = 127; + else if (y < -128) y = -128; + } + else + { + /* Classic Controller right stick */ + x = wpad_StickX(data,1); + y = wpad_StickY(data,1); + } /* Emulated stick is unidirectional but can be rotated */ if (abs(x) > abs(y)) @@ -867,7 +978,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp) case DEVICE_LIGHTGUN: { /* Gun screen position (x,y) */ - if (exp != WPAD_EXP_CLASSIC) + if (exp < WPAD_EXP_CLASSIC) { /* Wiimote IR */ struct ir_t ir; @@ -888,7 +999,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp) } else { - /* Classic Controller analog stick */ + /* Left analog stick */ input.analog[i][0] += x / ANALOG_SENSITIVITY; input.analog[i][1] -= y / ANALOG_SENSITIVITY; @@ -927,7 +1038,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp) if (event.button & 2) input.pad[i] |= INPUT_MOUSE_CENTER; if (event.button & 4) input.pad[i] |= INPUT_MOUSE_LEFT; } - else if (exp != WPAD_EXP_CLASSIC) + else if (exp == WPAD_EXP_NONE) { /* Wiimote IR (buggy) */ struct ir_t ir; @@ -942,7 +1053,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp) } else { - /* Classic Controller analog stick position (-127;+127) -> (-255;+255) */ + /* Left analog stick position (-127;+127) -> (-255;+255) */ input.analog[i][0] = (x / ANALOG_SENSITIVITY) * 2; input.analog[i][1] = (y / ANALOG_SENSITIVITY) * 2; } @@ -971,7 +1082,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp) else if (p & PAD_BUTTON_RIGHT) input.pad[i] |= INPUT_RIGHT; /* PEN screen position (x,y) */ - if (exp != WPAD_EXP_CLASSIC) + if (exp < WPAD_EXP_CLASSIC) { /* Wiimote IR */ struct ir_t ir; @@ -984,7 +1095,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp) } else { - /* Classic Controller analog stick */ + /* Left analog stick */ input.analog[0][0] += x / ANALOG_SENSITIVITY; input.analog[0][1] -= y / ANALOG_SENSITIVITY; @@ -1008,7 +1119,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp) case DEVICE_TEREBI: { /* PEN screen position (x,y) */ - if (exp != WPAD_EXP_CLASSIC) + if (exp < WPAD_EXP_CLASSIC) { /* Wiimote IR */ struct ir_t ir; @@ -1021,7 +1132,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp) } else { - /* Classic Controller analog stick */ + /* Left analog stick */ input.analog[0][0] += x / ANALOG_SENSITIVITY; input.analog[0][1] -= y / ANALOG_SENSITIVITY; @@ -1041,7 +1152,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp) case DEVICE_GRAPHIC_BOARD: { /* PEN screen position (x,y) */ - if (exp != WPAD_EXP_CLASSIC) + if (exp < WPAD_EXP_CLASSIC) { /* Wiimote IR */ struct ir_t ir; @@ -1054,7 +1165,7 @@ static void wpad_update(s8 chan, u8 i, u32 exp) } else { - /* Classic Controller analog stick */ + /* Left analog stick */ input.analog[0][0] += x / ANALOG_SENSITIVITY; input.analog[0][1] -= y / ANALOG_SENSITIVITY; @@ -1130,6 +1241,7 @@ void gx_input_Init(void) WPAD_Init(); WPAD_SetDataFormat(WPAD_CHAN_ALL,WPAD_FMT_BTNS_ACC_IR); WPAD_SetVRes(WPAD_CHAN_ALL,640,480); + WiiDRC_Init(); #endif } @@ -1195,6 +1307,15 @@ int gx_input_FindDevices(void) } break; } + + case 4: /* WiiU GamePad Controller */ + { + if (WiiDRC_Inited() && WiiDRC_Connected()) + { + found++; + } + break; + } #endif default: @@ -1236,34 +1357,44 @@ void gx_input_SetDefault(void) for (i=0; i<4; i++) { /* Wiimote (horizontal) */ - config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONA] = WPAD_BUTTON_A; - config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONB] = WPAD_BUTTON_1; - config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONC] = WPAD_BUTTON_2; - config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_START] = WPAD_BUTTON_PLUS; - config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONX] = 0; - config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONY] = 0; - config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_BUTTONZ] = 0; - config.wpad_keymap[i*3 + WPAD_EXP_NONE][KEY_MODE] = 0; + config.wpad_keymap[4*WPAD_EXP_NONE + i][KEY_BUTTONA] = WPAD_BUTTON_A; + config.wpad_keymap[4*WPAD_EXP_NONE + i][KEY_BUTTONB] = WPAD_BUTTON_1; + config.wpad_keymap[4*WPAD_EXP_NONE + i][KEY_BUTTONC] = WPAD_BUTTON_2; + config.wpad_keymap[4*WPAD_EXP_NONE + i][KEY_START] = WPAD_BUTTON_PLUS; + config.wpad_keymap[4*WPAD_EXP_NONE + i][KEY_BUTTONX] = 0; + config.wpad_keymap[4*WPAD_EXP_NONE + i][KEY_BUTTONY] = 0; + config.wpad_keymap[4*WPAD_EXP_NONE + i][KEY_BUTTONZ] = 0; + config.wpad_keymap[4*WPAD_EXP_NONE + i][KEY_MODE] = 0; /* Wiimote + Nunchuk */ - config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONA] = WPAD_NUNCHUK_BUTTON_Z; - config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONB] = WPAD_BUTTON_B; - config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONC] = WPAD_BUTTON_A; - config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_START] = WPAD_BUTTON_PLUS; - config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONX] = WPAD_NUNCHUK_BUTTON_C; - config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONY] = WPAD_BUTTON_1; - config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_BUTTONZ] = WPAD_BUTTON_2; - config.wpad_keymap[i*3 + WPAD_EXP_NUNCHUK][KEY_MODE] = WPAD_BUTTON_MINUS; + config.wpad_keymap[4*WPAD_EXP_NUNCHUK + i][KEY_BUTTONA] = WPAD_NUNCHUK_BUTTON_Z; + config.wpad_keymap[4*WPAD_EXP_NUNCHUK + i][KEY_BUTTONB] = WPAD_BUTTON_B; + config.wpad_keymap[4*WPAD_EXP_NUNCHUK + i][KEY_BUTTONC] = WPAD_BUTTON_A; + config.wpad_keymap[4*WPAD_EXP_NUNCHUK + i][KEY_START] = WPAD_BUTTON_PLUS; + config.wpad_keymap[4*WPAD_EXP_NUNCHUK + i][KEY_BUTTONX] = WPAD_NUNCHUK_BUTTON_C; + config.wpad_keymap[4*WPAD_EXP_NUNCHUK + i][KEY_BUTTONY] = WPAD_BUTTON_1; + config.wpad_keymap[4*WPAD_EXP_NUNCHUK + i][KEY_BUTTONZ] = WPAD_BUTTON_2; + config.wpad_keymap[4*WPAD_EXP_NUNCHUK + i][KEY_MODE] = WPAD_BUTTON_MINUS; /* Classic Controller */ - config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_BUTTONA] = WPAD_CLASSIC_BUTTON_Y; - config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_BUTTONB] = WPAD_CLASSIC_BUTTON_B; - config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_BUTTONC] = WPAD_CLASSIC_BUTTON_A; - config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_START] = WPAD_CLASSIC_BUTTON_PLUS; - config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_BUTTONX] = WPAD_CLASSIC_BUTTON_ZL; - config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_BUTTONY] = WPAD_CLASSIC_BUTTON_ZR; - config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_BUTTONZ] = WPAD_CLASSIC_BUTTON_X; - config.wpad_keymap[i*3 + WPAD_EXP_CLASSIC][KEY_MODE] = WPAD_CLASSIC_BUTTON_MINUS; + config.wpad_keymap[4*WPAD_EXP_CLASSIC + i][KEY_BUTTONA] = WPAD_CLASSIC_BUTTON_Y; + config.wpad_keymap[4*WPAD_EXP_CLASSIC + i][KEY_BUTTONB] = WPAD_CLASSIC_BUTTON_B; + config.wpad_keymap[4*WPAD_EXP_CLASSIC + i][KEY_BUTTONC] = WPAD_CLASSIC_BUTTON_A; + config.wpad_keymap[4*WPAD_EXP_CLASSIC + i][KEY_START] = WPAD_CLASSIC_BUTTON_PLUS; + config.wpad_keymap[4*WPAD_EXP_CLASSIC + i][KEY_BUTTONX] = WPAD_CLASSIC_BUTTON_ZL; + config.wpad_keymap[4*WPAD_EXP_CLASSIC + i][KEY_BUTTONY] = WPAD_CLASSIC_BUTTON_ZR; + config.wpad_keymap[4*WPAD_EXP_CLASSIC + i][KEY_BUTTONZ] = WPAD_CLASSIC_BUTTON_X; + config.wpad_keymap[4*WPAD_EXP_CLASSIC + i][KEY_MODE] = WPAD_CLASSIC_BUTTON_MINUS; + + /* WiiU GamePad Controller */ + config.wpad_keymap[4*3][KEY_BUTTONA] = WIIDRC_BUTTON_Y; + config.wpad_keymap[4*3][KEY_BUTTONB] = WIIDRC_BUTTON_B; + config.wpad_keymap[4*3][KEY_BUTTONC] = WIIDRC_BUTTON_A; + config.wpad_keymap[4*3][KEY_START] = WIIDRC_BUTTON_PLUS; + config.wpad_keymap[4*3][KEY_BUTTONX] = WIIDRC_BUTTON_L; + config.wpad_keymap[4*3][KEY_BUTTONY] = WIIDRC_BUTTON_R; + config.wpad_keymap[4*3][KEY_BUTTONZ] = WIIDRC_BUTTON_X; + config.wpad_keymap[4*3][KEY_MODE] = WIIDRC_BUTTON_MINUS; } #endif @@ -1276,8 +1407,20 @@ void gx_input_SetDefault(void) } #ifdef HW_RVL + /* autodetect connected WiiU Gamepad Controller */ + if (WiiDRC_Inited() && WiiDRC_Connected()) + { + config.input[0].device = 4; + config.input[0].port = 0; + i = 1; + } + else + { + i = 0; + } + /* autodetect connected Wii Controllers */ - for (i=0; i<4; i++) + while (i++ < 4) { exp = 255; WPAD_Probe(i, &exp); @@ -1596,12 +1739,35 @@ void gx_input_UpdateMenu(void) else if (x < -ANALOG_SENSITIVITY) hp |= PAD_BUTTON_LEFT; else if (y > ANALOG_SENSITIVITY) hp |= PAD_BUTTON_UP; else if (y < -ANALOG_SENSITIVITY) hp |= PAD_BUTTON_DOWN; + + /* WiiU GamePad status */ + u32 pwu = 0; + u32 hwu = 0; + if (WiiDRC_Inited()) + { + WiiDRC_ScanPads(); + if (WiiDRC_ShutdownRequested()) + { + Shutdown = ConfigRequested = 1; + reload = 0; + return; + } + pwu = WiiDRC_ButtonsDown(); + hwu = WiiDRC_ButtonsHeld() & WIIU_BUTTONS_HELD; + x = WiiDRC_lStickX(); + y = WiiDRC_lStickY(); + if (x > ANALOG_SENSITIVITY) hp |= PAD_BUTTON_RIGHT; + else if (x < -ANALOG_SENSITIVITY) hp |= PAD_BUTTON_LEFT; + else if (y > ANALOG_SENSITIVITY) hp |= PAD_BUTTON_UP; + else if (y < -ANALOG_SENSITIVITY) hp |= PAD_BUTTON_DOWN; + } + #endif /* check if any direction/selection key is being held or just being pressed/released */ #ifdef HW_RVL - if (pp||pw) held_cnt = 0; - else if (hp||hw) held_cnt++; + if (pp||pw||pwu) held_cnt = 0; + else if (hp||hw||hwu) held_cnt++; else held_cnt = 0; #else if (pp) held_cnt = 0; @@ -1616,6 +1782,7 @@ void gx_input_UpdateMenu(void) pp |= hp; #ifdef HW_RVL pw |= hw; + pwu |= hwu; #endif /* delay until next triggering (adjusts direction/selection update speed) */ @@ -1651,7 +1818,20 @@ void gx_input_UpdateMenu(void) if (pw & (WPAD_BUTTON_1|WPAD_BUTTON_B|WPAD_CLASSIC_BUTTON_B)) pp |= PAD_BUTTON_B; if (pw & (WPAD_BUTTON_HOME|WPAD_CLASSIC_BUTTON_HOME)) pp |= PAD_TRIGGER_Z; if (pw & (WPAD_BUTTON_PLUS|WPAD_CLASSIC_BUTTON_PLUS|WPAD_CLASSIC_BUTTON_FULL_L)) pp |= PAD_TRIGGER_L; - if (pw & (WPAD_BUTTON_MINUS|WPAD_CLASSIC_BUTTON_MINUS|WPAD_CLASSIC_BUTTON_FULL_L)) pp |= PAD_TRIGGER_R; + if (pw & (WPAD_BUTTON_MINUS|WPAD_CLASSIC_BUTTON_MINUS|WPAD_CLASSIC_BUTTON_FULL_R)) pp |= PAD_TRIGGER_R; + + /* WiiU GamePad direction keys */ + if (pwu & WIIDRC_BUTTON_UP) pp |= PAD_BUTTON_UP; + else if (pwu & WIIDRC_BUTTON_DOWN) pp |= PAD_BUTTON_DOWN; + else if (pwu & WIIDRC_BUTTON_LEFT) pp |= PAD_BUTTON_LEFT; + else if (pwu & WIIDRC_BUTTON_RIGHT) pp |= PAD_BUTTON_RIGHT; + + /* WiiU GamePad button keys */ + if (pwu & WIIDRC_BUTTON_A) pp |= PAD_BUTTON_A; + if (pwu & WIIDRC_BUTTON_B) pp |= PAD_BUTTON_B; + if (pwu & WIIDRC_BUTTON_HOME) pp |= PAD_TRIGGER_Z; + if (pwu & (WIIDRC_BUTTON_PLUS|WIIDRC_BUTTON_L|WIIDRC_BUTTON_ZL)) pp |= PAD_TRIGGER_L; + if (pwu & (WIIDRC_BUTTON_MINUS|WIIDRC_BUTTON_R|WIIDRC_BUTTON_ZR)) pp |= PAD_TRIGGER_R; #endif /* Update menu inputs */ diff --git a/gx/gx_input.h b/gx/gx_input.h index 6d50c0c..eaf9751 100644 --- a/gx/gx_input.h +++ b/gx/gx_input.h @@ -3,7 +3,7 @@ * * Genesis Plus GX input support * - * Copyright Eke-Eke (2007-2015) + * Copyright Eke-Eke (2007-2017) * * Redistribution and use of this code or any derivative works are permitted * provided that the following conditions are met: diff --git a/gx/images/ctrl_wiiu.png b/gx/images/ctrl_wiiu.png new file mode 100644 index 0000000..2789ce0 Binary files /dev/null and b/gx/images/ctrl_wiiu.png differ