/**************************************************************************** * libwiigui Template * Tantric 2009 * Cyan 2015 * * input.cpp * Wii/GameCube controller management ***************************************************************************/ #include #include #include #include #include #include #include #include #include "libs/libdrc/wiidrc.h" #include "menu.h" #include "video.h" #include "input.h" #include "GUI/gui.h" #include "sys.h" #include "gecko.h" int rumbleRequest[4] = { 0, 0, 0, 0 }; GuiTrigger userInput[4]; static int rumbleCount[4] = { 0, 0, 0, 0 }; extern bool isWiiVC; // in sys.cpp /**************************************************************************** * UpdatePads * * called by postRetraceCallback in InitGCVideo - scans gcpad and wpad ***************************************************************************/ void UpdatePads() { WPAD_ScanPads(); PAD_ScanPads(); for (int i = 3; i >= 0; i--) { memcpy(&userInput[i].wpad, WPAD_Data(i), sizeof(WPADData)); userInput[i].chan = i; userInput[i].pad.btns_d = PAD_ButtonsDown(i); userInput[i].pad.btns_u = PAD_ButtonsUp(i); userInput[i].pad.btns_h = PAD_ButtonsHeld(i); userInput[i].pad.stickX = PAD_StickX(i); userInput[i].pad.stickY = PAD_StickY(i); userInput[i].pad.substickX = PAD_SubStickX(i); userInput[i].pad.substickY = PAD_SubStickY(i); userInput[i].pad.triggerL = PAD_TriggerL(i); userInput[i].pad.triggerR = PAD_TriggerR(i); if (Settings.rumble == ON) DoRumble(i); if(userInput[i].wpad.exp.type == WPAD_EXP_NUNCHUK) { if((userInput[i].wpad.btns_h & WPAD_NUNCHUK_BUTTON_Z) && (userInput[i].wpad.btns_d & WPAD_NUNCHUK_BUTTON_C)) ScreenShot(); } if((userInput[i].pad.btns_h & PAD_TRIGGER_R) && (userInput[i].pad.btns_d & PAD_TRIGGER_Z)) ScreenShot(); } // WiiU gamepad (DRC) when using WiiVC injected WiiU channels // Copy the drc state to Gamecube pad state if(WiiDRC_Inited() && WiiDRC_Connected()) { WiiDRC_ScanPads(); // DRC buttons state written to gamecube pad data userInput[0].pad.btns_d |= wiidrc_to_pad(WiiDRC_ButtonsDown()); userInput[0].pad.btns_u |= wiidrc_to_pad(WiiDRC_ButtonsUp()); userInput[0].pad.btns_h |= wiidrc_to_pad(WiiDRC_ButtonsHeld()); // DRC stick state written to gamecube pad data int x = 0, y = 0; 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; userInput[0].pad.stickX = x; userInput[0].pad.stickY = y; userInput[0].pad.substickX = WiiDRC_rStickX(); userInput[0].pad.substickY = WiiDRC_rStickY(); } } /**************************************************************************** * ScreensaverTime ***************************************************************************/ static inline u32 ScreensaverTime(int setting) { switch (setting) { case 0: return 0xFFFFFF; case 1: return 180; case 2: return 300; case 3: return 600; case 4: return 1200; case 5: return 1800; case 6: return 3600; default: break; } return 0xFFFFFF; } /**************************************************************************** * SetWPADTimeout ***************************************************************************/ void SetWPADTimeout() { WPAD_SetIdleTimeout(ScreensaverTime(Settings.screensaver)); } /**************************************************************************** * ControlActivityTimeOut ***************************************************************************/ bool ControlActivityTimeout(void) { u32 minTime = 0xFFFFFF; for(int i = 0; i < 3; ++i) if(pointer[i]->getLastActivCounter() < minTime) minTime = pointer[i]->getLastActivCounter(); // not very accurate but it's not required here return (minTime/(Settings.PAL50 ? 50 : 60) > ScreensaverTime(Settings.screensaver)); } /**************************************************************************** * SetupPads * * Sets up userInput triggers for use ***************************************************************************/ void SetupPads() { PAD_Init(); WPAD_Init(); // check WiiVC to init WiiU gamepad WiiDRC_Init(); isWiiVC = WiiDRC_Inited(); // read wiimote accelerometer and IR data WPAD_SetDataFormat(WPAD_CHAN_ALL, WPAD_FMT_BTNS_ACC_IR); WPAD_SetVRes(WPAD_CHAN_ALL, screenwidth, screenheight); for (int i = 0; i < 4; i++) { userInput[i].chan = i; } SetWPADTimeout(); } /**************************************************************************** * ShutoffRumble ***************************************************************************/ void ShutoffRumble() { for (int i = 0; i < 4; i++) { WPAD_Rumble(i, 0); rumbleCount[i] = 0; } } /**************************************************************************** * DoRumble ***************************************************************************/ void DoRumble(int i) { if (rumbleRequest[i] && rumbleCount[i] < 3) { WPAD_Rumble(i, 1); // rumble on rumbleCount[i]++; } else if (rumbleRequest[i]) { rumbleCount[i] = 20; rumbleRequest[i] = 0; } else { if (rumbleCount[i]) rumbleCount[i]--; WPAD_Rumble(i, 0); // rumble off } } /**************************************************************************** * WiiDRC to WPAD * * Sets WPAD button state based on WiiDRC (WiiU gamepad in WiiVC) pressed buttons. ***************************************************************************/ u32 wiidrc_to_wpad(u32 btns) { u32 ret = 0; if(btns & WIIDRC_BUTTON_LEFT) ret |= WPAD_BUTTON_LEFT; if(btns & WIIDRC_BUTTON_RIGHT) ret |= WPAD_BUTTON_RIGHT; if(btns & WIIDRC_BUTTON_UP) ret |= WPAD_BUTTON_UP; if(btns & WIIDRC_BUTTON_DOWN) ret |= WPAD_BUTTON_DOWN; if(btns & WIIDRC_BUTTON_A) ret |= WPAD_BUTTON_A; if(btns & WIIDRC_BUTTON_B) ret |= WPAD_BUTTON_B; if(btns & WIIDRC_BUTTON_X) ret |= WPAD_BUTTON_1; if(btns & WIIDRC_BUTTON_Y) ret |= WPAD_BUTTON_2; if((btns & WIIDRC_BUTTON_L) || (btns & WIIDRC_BUTTON_ZL) || (btns & WIIDRC_BUTTON_MINUS)) ret |= WPAD_BUTTON_MINUS; if((btns & WIIDRC_BUTTON_R) || (btns & WIIDRC_BUTTON_ZR) || (btns & WIIDRC_BUTTON_PLUS)) ret |= WPAD_BUTTON_PLUS; if(btns & WIIDRC_BUTTON_HOME) ret |= WPAD_BUTTON_HOME; return (ret&0xffff) ; } /**************************************************************************** * WiiDRC to PAD * * Sets PAD button state based on WiiDRC (WiiU gamepad in WiiVC) pressed buttons. ***************************************************************************/ u32 wiidrc_to_pad(u32 btns) { u32 ret = 0; if(btns & WIIDRC_BUTTON_LEFT) ret |= PAD_BUTTON_LEFT; if(btns & WIIDRC_BUTTON_RIGHT) ret |= PAD_BUTTON_RIGHT; if(btns & WIIDRC_BUTTON_UP) ret |= PAD_BUTTON_UP; if(btns & WIIDRC_BUTTON_DOWN) ret |= PAD_BUTTON_DOWN; if(btns & WIIDRC_BUTTON_A) ret |= PAD_BUTTON_A; if(btns & WIIDRC_BUTTON_B) ret |= PAD_BUTTON_B; if(btns & WIIDRC_BUTTON_X) ret |= PAD_BUTTON_X; if(btns & WIIDRC_BUTTON_Y) ret |= PAD_BUTTON_Y; if((btns & WIIDRC_BUTTON_L) || (btns & WIIDRC_BUTTON_ZL) || (btns & WIIDRC_BUTTON_MINUS)) ret |= PAD_TRIGGER_L; if((btns & WIIDRC_BUTTON_R) || (btns & WIIDRC_BUTTON_ZR) || (btns & WIIDRC_BUTTON_PLUS)) ret |= PAD_TRIGGER_R; if(btns & WIIDRC_BUTTON_HOME) ret |= PAD_BUTTON_START; return (ret&0xffff) ; }