Files
vbagx/source/ngc/input.cpp
dborth 2d9b7ef1f9 [1.0.8 - April 4, 2009]
* "Match Wii Game" controls option! Games that have a Wii equivalent can be
  played using the controls for that Wii game. For example all Zelda games
  can be played with Twilight Princess controls. See the Instructions section
  below for important details.
* Rotation/Tilt sensor games all work
* Solar sensors (Boktai 1/2/3)
* Rumble (except for games that rely on Gameboy Player)
* Keyboard
* PAL support, finally!
* New scaling options, choose how much stretching you want
* Colourised games now partially work but still have distortion
* "Corvette" no longer has a screwed up palette (but still crashes)
* Triggers net reconnection on SMB failure
* Source code refactored, and project file added
* Instructions section added to this readme file
2009-04-10 03:16:28 +00:00

923 lines
21 KiB
C++

/****************************************************************************
* Visual Boy Advance GX
*
* Tantric September 2008
*
* input.cpp
*
* Wii/Gamecube controller management
***************************************************************************/
#include <gccore.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <math.h>
#include <ogcsys.h>
#include <unistd.h>
#include <wiiuse/wpad.h>
#include "vba.h"
#include "button_mapping.h"
#include "audio.h"
#include "video.h"
#include "input.h"
#include "gameinput.h"
#include "vbasupport.h"
#include "wiiusbsupport.h"
#include "gba/GBA.h"
#include "gba/bios.h"
#include "gba/GBAinline.h"
extern bool InMenu;
int rumbleRequest[4] = {0,0,0,0};
static int rumbleCount[4] = {0,0,0,0};
bool cartridgeRumble = false;
int gameRumbleCount = 0, menuRumbleCount = 0, rumbleCountAlready = 0;
unsigned int vbapadmap[10]; // VBA controller buttons
unsigned int gcpadmap[10]; // Gamecube controller Padmap
unsigned int wmpadmap[10]; // Wiimote Padmap
unsigned int ccpadmap[10]; // Classic Controller Padmap
unsigned int ncpadmap[10]; // Nunchuk + wiimote Padmap
unsigned int kbpadmap[10]; // Keyboard Padmap
void ResetControls()
{
int i = 0;
// VBA controller buttons
// All other pads are mapped to this
i=0;
vbapadmap[i++] = VBA_BUTTON_B;
vbapadmap[i++] = VBA_BUTTON_A;
vbapadmap[i++] = VBA_BUTTON_SELECT;
vbapadmap[i++] = VBA_BUTTON_START;
vbapadmap[i++] = VBA_UP;
vbapadmap[i++] = VBA_DOWN;
vbapadmap[i++] = VBA_LEFT;
vbapadmap[i++] = VBA_RIGHT;
vbapadmap[i++] = VBA_BUTTON_L;
vbapadmap[i++] = VBA_BUTTON_R;
/*** Gamecube controller Padmap ***/
i=0;
gcpadmap[i++] = PAD_BUTTON_B;
gcpadmap[i++] = PAD_BUTTON_A;
gcpadmap[i++] = PAD_TRIGGER_Z;
gcpadmap[i++] = PAD_BUTTON_START;
gcpadmap[i++] = PAD_BUTTON_UP;
gcpadmap[i++] = PAD_BUTTON_DOWN;
gcpadmap[i++] = PAD_BUTTON_LEFT;
gcpadmap[i++] = PAD_BUTTON_RIGHT;
gcpadmap[i++] = PAD_TRIGGER_L;
gcpadmap[i++] = PAD_TRIGGER_R;
/*** Wiimote Padmap ***/
i=0;
wmpadmap[i++] = WPAD_BUTTON_1;
wmpadmap[i++] = WPAD_BUTTON_2;
wmpadmap[i++] = WPAD_BUTTON_MINUS;
wmpadmap[i++] = WPAD_BUTTON_PLUS;
wmpadmap[i++] = WPAD_BUTTON_RIGHT;
wmpadmap[i++] = WPAD_BUTTON_LEFT;
wmpadmap[i++] = WPAD_BUTTON_UP;
wmpadmap[i++] = WPAD_BUTTON_DOWN;
wmpadmap[i++] = WPAD_BUTTON_B;
wmpadmap[i++] = WPAD_BUTTON_A;
/*** Classic Controller Padmap ***/
i=0;
ccpadmap[i++] = WPAD_CLASSIC_BUTTON_Y;
ccpadmap[i++] = WPAD_CLASSIC_BUTTON_B;
ccpadmap[i++] = WPAD_CLASSIC_BUTTON_MINUS;
ccpadmap[i++] = WPAD_CLASSIC_BUTTON_PLUS;
ccpadmap[i++] = WPAD_CLASSIC_BUTTON_UP;
ccpadmap[i++] = WPAD_CLASSIC_BUTTON_DOWN;
ccpadmap[i++] = WPAD_CLASSIC_BUTTON_LEFT;
ccpadmap[i++] = WPAD_CLASSIC_BUTTON_RIGHT;
ccpadmap[i++] = WPAD_CLASSIC_BUTTON_FULL_L;
ccpadmap[i++] = WPAD_CLASSIC_BUTTON_FULL_R;
/*** Nunchuk + wiimote Padmap ***/
i=0;
ncpadmap[i++] = WPAD_NUNCHUK_BUTTON_C;
ncpadmap[i++] = WPAD_NUNCHUK_BUTTON_Z;
ncpadmap[i++] = WPAD_BUTTON_MINUS;
ncpadmap[i++] = WPAD_BUTTON_PLUS;
ncpadmap[i++] = WPAD_BUTTON_UP;
ncpadmap[i++] = WPAD_BUTTON_DOWN;
ncpadmap[i++] = WPAD_BUTTON_LEFT;
ncpadmap[i++] = WPAD_BUTTON_RIGHT;
ncpadmap[i++] = WPAD_BUTTON_2;
ncpadmap[i++] = WPAD_BUTTON_1;
/*** Keyboard map ***/
i=0;
kbpadmap[i++] = KB_X; // VBA stupidly has B on the right instead of left
kbpadmap[i++] = KB_Z;
kbpadmap[i++] = KB_BKSP;
kbpadmap[i++] = KB_ENTER;
kbpadmap[i++] = KB_UP;
kbpadmap[i++] = KB_DOWN;
kbpadmap[i++] = KB_LEFT;
kbpadmap[i++] = KB_RIGHT;
kbpadmap[i++] = KB_A;
kbpadmap[i++] = KB_S;
}
/****************************************************************************
* ShutoffRumble
***************************************************************************/
void ShutoffRumble()
{
#ifdef HW_RVL
for(int i=0;i<4;i++)
{
WPAD_Rumble(i, 0);
}
#endif
}
/****************************************************************************
* 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] = 12;
rumbleRequest[i] = 0;
}
else
{
if(rumbleCount[i])
rumbleCount[i]--;
WPAD_Rumble(i, 0); // rumble off
}
}
static void updateRumble() {
bool r = false;
if (InMenu) r = (menuRumbleCount > 0);
else r = cartridgeRumble || (gameRumbleCount > 0) || (menuRumbleCount > 0);
#ifdef HW_RVL
// Rumble wii remote 0
WPAD_Rumble(0, r);
#endif
PAD_ControlMotor(PAD_CHAN0, PAD_MOTOR_RUMBLE);
}
void updateRumbleFrame() {
// If we already rumbled continuously for more than 50 frames,
// then disable rumbling for a while.
if (rumbleCountAlready > 50) {
gameRumbleCount = 0;
menuRumbleCount = 0;
// disable rumbling for 10 more frames
if (rumbleCountAlready > 50+10)
rumbleCountAlready = 0;
else rumbleCountAlready++;
} else if (InMenu) {
if (menuRumbleCount>0)
rumbleCountAlready++;
} else {
if (gameRumbleCount>0 || menuRumbleCount>0 || cartridgeRumble)
rumbleCountAlready++;
}
updateRumble();
if (gameRumbleCount>0 && !InMenu) gameRumbleCount--;
if (menuRumbleCount>0) menuRumbleCount--;
}
void systemCartridgeRumble(bool RumbleOn) {
cartridgeRumble = RumbleOn;
updateRumble();
}
void systemGameRumble(int RumbleForFrames) {
if (RumbleForFrames > gameRumbleCount) gameRumbleCount = RumbleForFrames;
}
void systemGameRumbleOnlyFor(int OnlyRumbleForFrames) {
gameRumbleCount = OnlyRumbleForFrames;
}
void systemMenuRumble(int RumbleForFrames) {
if (RumbleForFrames > menuRumbleCount) menuRumbleCount = RumbleForFrames;
}
/****************************************************************************
* WPAD_Stick
*
* Get X/Y value from Wii Joystick (classic, nunchuk) input
***************************************************************************/
s8 WPAD_Stick(u8 chan, u8 right, int axis)
{
float mag = 0.0;
float ang = 0.0;
WPADData *data = WPAD_Data(chan);
switch (data->exp.type)
{
case WPAD_EXP_NUNCHUK:
case WPAD_EXP_GUITARHERO3:
if (right == 0)
{
mag = data->exp.nunchuk.js.mag;
ang = data->exp.nunchuk.js.ang;
}
break;
case WPAD_EXP_CLASSIC:
if (right == 0)
{
mag = data->exp.classic.ljs.mag;
ang = data->exp.classic.ljs.ang;
}
else
{
mag = data->exp.classic.rjs.mag;
ang = data->exp.classic.rjs.ang;
}
break;
default:
break;
}
/* calculate x/y value (angle need to be converted into radian) */
if (mag > 1.0) mag = 1.0;
else if (mag < -1.0) mag = -1.0;
double val;
if(axis == 0) // x-axis
val = mag * sin((PI * ang)/180.0f);
else // y-axis
val = mag * cos((PI * ang)/180.0f);
return (s8)(val * 128.0f);
}
u32 StandardMovement(unsigned short pad)
{
u32 J = 0;
signed char pad_x = PAD_StickX (pad);
signed char pad_y = PAD_StickY (pad);
#ifdef HW_RVL
signed char wm_ax = WPAD_Stick ((u8)pad, 0, 0);
signed char wm_ay = WPAD_Stick ((u8)pad, 0, 1);
#endif
/***
Gamecube Joystick input, same as normal
***/
// Is XY inside the "zone"?
if (pad_x * pad_x + pad_y * pad_y > PADCAL * PADCAL)
{
if (pad_x > 0 && pad_y == 0) J |= VBA_RIGHT;
if (pad_x < 0 && pad_y == 0) J |= VBA_LEFT;
if (pad_x == 0 && pad_y > 0) J |= VBA_UP;
if (pad_x == 0 && pad_y < 0) J |= VBA_DOWN;
if (pad_x != 0 && pad_y != 0)
{
if ((float)pad_y / pad_x >= -2.41421356237 && (float)pad_y / pad_x < 2.41421356237)
{
if (pad_x >= 0)
J |= VBA_RIGHT;
else
J |= VBA_LEFT;
}
if ((float)pad_x / pad_y >= -2.41421356237 && (float)pad_x / pad_y < 2.41421356237)
{
if (pad_y >= 0)
J |= VBA_UP;
else
J |= VBA_DOWN;
}
}
}
#ifdef HW_RVL
/***
Wii Joystick (classic, nunchuk) input
***/
// Is XY inside the "zone"?
if (wm_ax * wm_ax + wm_ay * wm_ay > PADCAL * PADCAL)
{
/*** we don't want division by zero ***/
if (wm_ax > 0 && wm_ay == 0)
J |= VBA_RIGHT;
if (wm_ax < 0 && wm_ay == 0)
J |= VBA_LEFT;
if (wm_ax == 0 && wm_ay > 0)
J |= VBA_UP;
if (wm_ax == 0 && wm_ay < 0)
J |= VBA_DOWN;
if (wm_ax != 0 && wm_ay != 0)
{
/*** Recalc left / right ***/
float t;
t = (float) wm_ay / wm_ax;
if (t >= -2.41421356237 && t < 2.41421356237)
{
if (wm_ax >= 0)
J |= VBA_RIGHT;
else
J |= VBA_LEFT;
}
/*** Recalc up / down ***/
t = (float) wm_ax / wm_ay;
if (t >= -2.41421356237 && t < 2.41421356237)
{
if (wm_ay >= 0)
J |= VBA_UP;
else
J |= VBA_DOWN;
}
}
}
// Turbo feature, keyboard or gamecube only
if(DownUsbKeys[KB_SPACE])
J |= VBA_SPEED;
// Capture feature
if(DownUsbKeys[KB_PRTSC] | DownUsbKeys[KB_F12])
J |= VBA_CAPTURE;
#endif
return J;
}
u32 StandardDPad(unsigned short pad)
{
u32 J = 0;
u32 jp = PAD_ButtonsHeld(pad);
#ifdef HW_RVL
u32 exp_type;
if ( WPAD_Probe(pad, &exp_type) != 0 )
exp_type = WPAD_EXP_NONE;
u32 wp = WPAD_ButtonsHeld(pad);
if (wp & WPAD_BUTTON_RIGHT)
J |= VBA_RIGHT;
if (wp & WPAD_BUTTON_LEFT)
J |= VBA_LEFT;
if (wp & WPAD_BUTTON_UP)
J |= VBA_UP;
if (wp & WPAD_BUTTON_DOWN)
J |= VBA_DOWN;
if (exp_type == WPAD_EXP_CLASSIC)
{
if (wp & WPAD_CLASSIC_BUTTON_UP)
J |= VBA_UP;
if (wp & WPAD_CLASSIC_BUTTON_DOWN)
J |= VBA_DOWN;
if (wp & WPAD_CLASSIC_BUTTON_LEFT)
J |= VBA_LEFT;
if (wp & WPAD_CLASSIC_BUTTON_RIGHT)
J |= VBA_RIGHT;
}
#endif
if (jp & PAD_BUTTON_UP)
J |= VBA_UP;
if (jp & PAD_BUTTON_DOWN)
J |= VBA_DOWN;
if (jp & PAD_BUTTON_LEFT)
J |= VBA_LEFT;
if (jp & PAD_BUTTON_RIGHT)
J |= VBA_RIGHT;
return J;
}
u32 StandardSideways(unsigned short pad)
{
u32 J = 0;
#ifdef HW_RVL
u32 wp = WPAD_ButtonsHeld(pad);
if (wp & WPAD_BUTTON_RIGHT)
J |= VBA_UP;
if (wp & WPAD_BUTTON_LEFT)
J |= VBA_DOWN;
if (wp & WPAD_BUTTON_UP)
J |= VBA_LEFT;
if (wp & WPAD_BUTTON_DOWN)
J |= VBA_RIGHT;
if (wp & WPAD_BUTTON_PLUS)
J |= VBA_BUTTON_START;
if (wp & WPAD_BUTTON_MINUS)
J |= VBA_BUTTON_SELECT;
if (wp & WPAD_BUTTON_1)
J |= VBA_BUTTON_B;
if (wp & WPAD_BUTTON_2)
J |= VBA_BUTTON_A;
if (cartridgeType == 2)
{
if (wp & WPAD_BUTTON_A)
J |= VBA_BUTTON_R;
if (wp & WPAD_BUTTON_B)
J |= VBA_BUTTON_L;
}
else
{
if (wp & WPAD_BUTTON_B || wp & WPAD_BUTTON_A)
J |= VBA_SPEED;
}
#endif
return J;
}
u32 StandardClassic(unsigned short pad)
{
u32 J = 0;
#ifdef HW_RVL
u32 wp = WPAD_ButtonsHeld(pad);
if (wp & WPAD_CLASSIC_BUTTON_RIGHT)
J |= VBA_RIGHT;
if (wp & WPAD_CLASSIC_BUTTON_LEFT)
J |= VBA_LEFT;
if (wp & WPAD_CLASSIC_BUTTON_UP)
J |= VBA_UP;
if (wp & WPAD_CLASSIC_BUTTON_DOWN)
J |= VBA_DOWN;
if (wp & WPAD_CLASSIC_BUTTON_PLUS)
J |= VBA_BUTTON_START;
if (wp & WPAD_CLASSIC_BUTTON_MINUS)
J |= VBA_BUTTON_SELECT;
if (wp & WPAD_CLASSIC_BUTTON_FULL_L || wp & WPAD_CLASSIC_BUTTON_ZL)
J |= VBA_BUTTON_L;
if (wp & WPAD_CLASSIC_BUTTON_FULL_R || wp & WPAD_CLASSIC_BUTTON_ZR)
J |= VBA_BUTTON_R;
if (wp & WPAD_CLASSIC_BUTTON_A)
J |= VBA_BUTTON_A;
if (wp & WPAD_CLASSIC_BUTTON_B)
J |= VBA_BUTTON_B;
if (wp & WPAD_CLASSIC_BUTTON_Y || wp & WPAD_CLASSIC_BUTTON_X)
J |= VBA_SPEED;
#endif
return J;
}
u32 StandardGamecube(unsigned short pad)
{
u32 J = 0;
u32 jp = PAD_ButtonsHeld(pad);
if (jp & PAD_BUTTON_UP)
J |= VBA_UP;
if (jp & PAD_BUTTON_DOWN)
J |= VBA_DOWN;
if (jp & PAD_BUTTON_LEFT)
J |= VBA_LEFT;
if (jp & PAD_BUTTON_RIGHT)
J |= VBA_RIGHT;
if (jp & PAD_BUTTON_A)
J |= VBA_BUTTON_A;
if (jp & PAD_BUTTON_B)
J |= VBA_BUTTON_B;
if (jp & PAD_BUTTON_START)
J |= VBA_BUTTON_START;
if (jp & PAD_BUTTON_X)
J |= VBA_BUTTON_SELECT;
if (jp & PAD_TRIGGER_L)
J |= VBA_BUTTON_L;
if (jp & PAD_TRIGGER_R)
J |= VBA_BUTTON_R;
if (jp & PAD_TRIGGER_Z || jp & PAD_BUTTON_Y)
J |= VBA_SPEED;
return J;
}
u32 StandardKeyboard(unsigned short pad)
{
u32 J = 0;
#ifdef HW_RVL
if (DownUsbKeys[KB_UP])
J |= VBA_UP;
if (DownUsbKeys[KB_DOWN])
J |= VBA_DOWN;
if (DownUsbKeys[KB_LEFT])
J |= VBA_LEFT;
if (DownUsbKeys[KB_RIGHT])
J |= VBA_RIGHT;
if (DownUsbKeys[KB_SPACE])
J |= VBA_SPEED;
if (DownUsbKeys[KB_F12] || DownUsbKeys[KB_PRTSC])
J |= VBA_CAPTURE;
if (DownUsbKeys[KB_X])
J |= VBA_BUTTON_A;
if (DownUsbKeys[KB_Z])
J |= VBA_BUTTON_B;
if (DownUsbKeys[KB_A])
J |= VBA_BUTTON_L;
if (DownUsbKeys[KB_S])
J |= VBA_BUTTON_R;
if (DownUsbKeys[KB_ENTER])
J |= VBA_BUTTON_START;
if (DownUsbKeys[KB_BKSP])
J |= VBA_BUTTON_SELECT;
#endif
return J;
}
u32 DPadWASD(unsigned short pad)
{
u32 J = 0;
#ifdef HW_RVL
if (DownUsbKeys[KB_W])
J |= VBA_UP;
if (DownUsbKeys[KB_S])
J |= VBA_DOWN;
if (DownUsbKeys[KB_A])
J |= VBA_LEFT;
if (DownUsbKeys[KB_D])
J |= VBA_RIGHT;
#endif
return J;
}
u32 DPadArrowKeys(unsigned short pad)
{
u32 J = 0;
#ifdef HW_RVL
if (DownUsbKeys[KB_UP])
J |= VBA_UP;
if (DownUsbKeys[KB_DOWN])
J |= VBA_DOWN;
if (DownUsbKeys[KB_LEFT])
J |= VBA_LEFT;
if (DownUsbKeys[KB_RIGHT])
J |= VBA_RIGHT;
#endif
return J;
}
u32 DecodeKeyboard(unsigned short pad)
{
u32 J = 0;
#ifdef HW_RVL
for (int i = 0; i < MAXJP; i++)
{
if (DownUsbKeys[kbpadmap[i]]) // keyboard
J |= vbapadmap[i];
}
#endif
return J;
}
u32 DecodeGamecube(unsigned short pad)
{
u32 J = 0;
u32 jp = PAD_ButtonsHeld(pad);
for (int i = 0; i < MAXJP; i++)
{
if (jp & gcpadmap[i])
J |= vbapadmap[i];
}
return J;
}
u32 DecodeWiimote(unsigned short pad)
{
u32 J = 0;
#ifdef HW_RVL
WPADData * wp = WPAD_Data(pad);
for (int i = 0; i < MAXJP; i++)
{
if ( (wp->exp.type == WPAD_EXP_NONE) && (wp->btns_h & wmpadmap[i]) )
J |= vbapadmap[i];
}
#endif
return J;
}
u32 DecodeClassic(unsigned short pad)
{
u32 J = 0;
#ifdef HW_RVL
WPADData * wp = WPAD_Data(pad);
for (int i = 0; i < MAXJP; i++)
{
if ( (wp->exp.type == WPAD_EXP_CLASSIC) && (wp->btns_h & ccpadmap[i]) )
J |= vbapadmap[i];
}
#endif
return J;
}
u32 DecodeNunchuk(unsigned short pad)
{
u32 J = 0;
#ifdef HW_RVL
WPADData * wp = WPAD_Data(pad);
for (int i = 0; i < MAXJP; i++)
{
if ( (wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & ncpadmap[i]) )
J |= vbapadmap[i];
}
#endif
return J;
}
#ifdef HW_RVL
static u32 CCToGC(u32 w) {
u32 gc = 0;
if (w & WPAD_CLASSIC_BUTTON_A) gc |= PAD_BUTTON_A;
if (w & WPAD_CLASSIC_BUTTON_B) gc |= PAD_BUTTON_B;
if (w & WPAD_CLASSIC_BUTTON_X) gc |= PAD_BUTTON_X;
if (w & WPAD_CLASSIC_BUTTON_Y) gc |= PAD_BUTTON_Y;
if (w & WPAD_CLASSIC_BUTTON_PLUS) gc |= PAD_BUTTON_START;
if (w & WPAD_CLASSIC_BUTTON_MINUS) gc |= 0;
if (w & (WPAD_CLASSIC_BUTTON_ZL | WPAD_CLASSIC_BUTTON_ZR)) gc |= PAD_TRIGGER_Z;
if (w & WPAD_CLASSIC_BUTTON_FULL_L) gc |= PAD_TRIGGER_L;
if (w & WPAD_CLASSIC_BUTTON_FULL_R) gc |= PAD_TRIGGER_R;
if (w & WPAD_CLASSIC_BUTTON_UP) gc |= PAD_BUTTON_UP;
if (w & WPAD_CLASSIC_BUTTON_DOWN) gc |= PAD_BUTTON_DOWN;
if (w & WPAD_CLASSIC_BUTTON_LEFT) gc |= PAD_BUTTON_LEFT;
if (w & WPAD_CLASSIC_BUTTON_RIGHT) gc |= PAD_BUTTON_RIGHT;
return gc;
}
#endif
// For developers who don't have gamecube pads but need to test gamecube input
u32 PAD_ButtonsHeldFake(unsigned short pad)
{
u32 gc = 0;
#ifdef HW_RVL
WPADData * wp = WPAD_Data(pad);
if (wp->exp.type == WPAD_EXP_CLASSIC) {
gc = CCToGC(wp->btns_h);
}
#endif
return gc;
}
u32 PAD_ButtonsDownFake(unsigned short pad)
{
u32 gc = 0;
#ifdef HW_RVL
WPADData * wp = WPAD_Data(pad);
if (wp->exp.type == WPAD_EXP_CLASSIC) {
gc = CCToGC(wp->btns_d);
}
#endif
return gc;
}
u32 PAD_ButtonsUpFake(unsigned short pad)
{
u32 gc = 0;
#ifdef HW_RVL
WPADData * wp = WPAD_Data(pad);
if (wp->exp.type == WPAD_EXP_CLASSIC) {
gc = CCToGC(wp->btns_u);
}
#endif
return gc;
}
/****************************************************************************
* DecodeJoy
*
* Reads the STATE (not changes) from a controller and reports
* this STATE (not changes) to VBA
****************************************************************************/
static u32 DecodeJoy(unsigned short pad)
{
TiltScreen = false;
CursorVisible = false;
#ifdef HW_RVL
WPADData * wp = WPAD_Data(pad);
CursorX = wp->ir.x;
CursorY = wp->ir.y;
CursorValid = wp->ir.valid;
#else
CursorX = CursorY = CursorValid = 0;
#endif
// check for games that should have special Wii controls
if (GCSettings.WiiControls)
switch (RomIdCode & 0xFFFFFF)
{
// Zelda
case ZELDA1:
return Zelda1Input(pad);
case ZELDA2:
return Zelda2Input(pad);
case ALINKTOTHEPAST:
return ALinkToThePastInput(pad);
case LINKSAWAKENING:
return LinksAwakeningInput(pad);
case ORACLEOFAGES:
return OracleOfAgesInput(pad);
case ORACLEOFSEASONS:
return OracleOfSeasonsInput(pad);
case MINISHCAP:
return MinishCapInput(pad);
// Metroid
case METROID0:
return MetroidZeroInput(pad);
case METROID1:
return Metroid1Input(pad);
case METROID2:
return Metroid2Input(pad);
case METROID4:
return MetroidFusionInput(pad);
// TMNT
case TMNT:
return TMNTInput(pad);
// Medal Of Honor
case MOHUNDERGROUND:
return MohUndergroundInput(pad);
case MOHINFILTRATOR:
return MohInfiltratorInput(pad);
// Harry Potter
case HARRYPOTTER1GBC:
return HarryPotter1GBCInput(pad);
case HARRYPOTTER2GBC:
return HarryPotter2GBCInput(pad);
case HARRYPOTTER1:
return HarryPotter1Input(pad);
case HARRYPOTTER2:
return HarryPotter2Input(pad);
case HARRYPOTTER3:
return HarryPotter3Input(pad);
case HARRYPOTTER4:
return HarryPotter4Input(pad);
case HARRYPOTTER5:
return HarryPotter5Input(pad);
// Mario
case MARIO1CLASSIC:
case MARIO2CLASSIC:
return Mario1ClassicInput(pad);
case MARIO1DX:
return Mario1DXInput(pad);
case MARIO2ADV:
return Mario2Input(pad);
case MARIO3ADV:
return Mario3Input(pad);
case MARIOWORLD:
return MarioWorldInput(pad);
case YOSHIISLAND:
return YoshiIslandInput(pad);
case MARIOLAND1:
return MarioLand1Input(pad);
case MARIOLAND2:
return MarioLand2Input(pad);
case YOSHIUG:
return UniversalGravitationInput(pad);
// Mario Kart
case MARIOKART:
return MarioKartInput(pad);
// Lego Star Wars
case LSW1:
return LegoStarWars1Input(pad);
case LSW2:
return LegoStarWars2Input(pad);
// Mortal Kombat
case MK1:
return MK1Input(pad);
case MK2:
case MK3:
case MK4:
return MK4Input(pad);
case MKA:
return MKAInput(pad);
case MKDA:
case MKTE:
return MKTEInput(pad);
// WarioWare
case TWISTED:
return TwistedInput(pad);
// Kirby
case KIRBYTNT:
case KIRBYTNTJ:
return KirbyTntInput(pad);
// Boktai
case BOKTAI1:
return BoktaiInput(pad);
case BOKTAI2:
case BOKTAI3:
return Boktai2Input(pad);
// One Piece
case ONEPIECE:
return OnePieceInput(pad);
}
// the function result, J, is a combination of flags for all the VBA buttons that are down
u32 J = StandardMovement(pad);
signed char gc_px = PAD_SubStickX(0);
u32 jp = PAD_ButtonsHeld(pad);
#ifdef HW_RVL
signed char wm_sx = WPAD_Stick (0,1,0); // CC right joystick
#endif
// Turbo feature
if(
(gc_px > 70)
#ifdef HW_RVL
|| (wm_sx > 70)
|| ((wp->btns_h & WPAD_BUTTON_A) && (wp->btns_h & WPAD_BUTTON_B))
#endif
)
J |= VBA_SPEED;
/*** Report pressed buttons (gamepads) ***/
int i;
for (i = 0; i < MAXJP; i++)
{
if ((jp & gcpadmap[i]) // gamecube controller
#ifdef HW_RVL
|| ( (wp->exp.type == WPAD_EXP_NONE) && (wp->btns_h & wmpadmap[i]) ) // wiimote
|| ( (wp->exp.type == WPAD_EXP_CLASSIC) && (wp->btns_h & ccpadmap[i]) ) // classic controller
|| ( (wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & ncpadmap[i]) ) // nunchuk + wiimote
|| ( (DownUsbKeys[kbpadmap[i]]) ) // keyboard
#endif
)
J |= vbapadmap[i];
}
return J;
}
u32 GetJoy(int pad)
{
pad = 0;
s8 gc_px = PAD_SubStickX(0);
s8 gc_py = PAD_SubStickY(0);
#ifdef HW_RVL
s8 wm_sy = WPAD_Stick (0,1,1);
u32 wm_pb = WPAD_ButtonsHeld (0); // wiimote / expansion button info
#endif
// Check for video zoom
if (GCSettings.Zoom)
{
if (gc_py < -36 || gc_py > 36)
zoom((float) gc_py / -36);
#ifdef HW_RVL
if (wm_sy < -36 || wm_sy> 36)
zoom ((float) wm_sy / -36);
#endif
}
// request to go back to menu
if ((gc_px < -70)
#ifdef HW_RVL
|| (wm_pb & WPAD_BUTTON_HOME)
|| (wm_pb & WPAD_CLASSIC_BUTTON_HOME)
|| (DownUsbKeys[KB_ESC])
#endif
)
{
ConfigRequested = 1;
updateRumbleFrame();
return 0;
}
else
{
u32 J = DecodeJoy(pad);
// don't allow up+down or left+right
if ((J & 48) == 48)
J &= ~16;
if ((J & 192) == 192)
J &= ~128;
updateRumbleFrame();
return J;
}
}