More Wii controls for Metroid games.

This commit is contained in:
Carl.Kenner 2009-03-11 22:30:10 +00:00
parent cba63e69a6
commit 28f2f392bd
4 changed files with 576 additions and 4 deletions

View File

@ -1900,6 +1900,16 @@ u32 MetroidZeroInput(unsigned short pad)
u32 J = StandardMovement(pad); u32 J = StandardMovement(pad);
u32 jp = PAD_ButtonsHeld(pad); u32 jp = PAD_ButtonsHeld(pad);
u8 BallState = CPUReadByte(0x30015df); // 0 = stand, 1 = crouch, 2 = ball u8 BallState = CPUReadByte(0x30015df); // 0 = stand, 1 = crouch, 2 = ball
u16 Health = CPUReadByte(0x3001536); // 0 = stand, 1 = crouch, 2 = ball
static u16 OldHealth = 0;
static int RumbleCount = 0;
// Rumble when they lose health!
if (Health < OldHealth)
if (RumbleCount < 20)
RumbleCount = 20;
OldHealth = Health;
static int Morph = 0; static int Morph = 0;
static int AimCount = 0; static int AimCount = 0;
static int MissileCount = 0; static int MissileCount = 0;
@ -1911,9 +1921,15 @@ u32 MetroidZeroInput(unsigned short pad)
WPADData * wp = WPAD_Data(pad); WPADData * wp = WPAD_Data(pad);
// Visor if (wp->btns_h & WPAD_BUTTON_UP)
J |= VBA_SPEED;
if (wp->btns_h & WPAD_BUTTON_LEFT)
J |= VBA_BUTTON_L;
if (wp->btns_h & WPAD_BUTTON_RIGHT)
J |= VBA_BUTTON_R;
// Visor doesn't exist, use as start button
if (wp->btns_h & WPAD_BUTTON_MINUS) if (wp->btns_h & WPAD_BUTTON_MINUS)
; J |= VBA_BUTTON_START;
// Hyper (toggle super missiles) // Hyper (toggle super missiles)
if (wp->btns_h & WPAD_BUTTON_PLUS) if (wp->btns_h & WPAD_BUTTON_PLUS)
J |= VBA_BUTTON_SELECT; J |= VBA_BUTTON_SELECT;
@ -1969,7 +1985,7 @@ u32 MetroidZeroInput(unsigned short pad)
} }
// Morph Bdall // Morph Bdall
if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_C)) if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_d & WPAD_NUNCHUK_BUTTON_C))
{ {
if (BallState == 2) if (BallState == 2)
{ // ball { // ball
@ -2049,6 +2065,227 @@ u32 MetroidZeroInput(unsigned short pad)
break; break;
} }
switch (Morph)
{
case 1:
J &= ~(VBA_UP | VBA_DOWN | VBA_LEFT | VBA_RIGHT | VBA_BUTTON_L);
J |= VBA_DOWN;
Morph = 2;
break;
case 2:
J &= ~(VBA_UP | VBA_DOWN | VBA_LEFT | VBA_RIGHT | VBA_BUTTON_L);
Morph = 3;
break;
case 3:
J &= ~(VBA_UP | VBA_DOWN | VBA_LEFT | VBA_RIGHT | VBA_BUTTON_L);
J |= VBA_DOWN;
Morph = 0;
break;
case -1:
case -2:
case -3:
J &= ~(VBA_UP | VBA_DOWN | VBA_LEFT | VBA_RIGHT | VBA_BUTTON_L);
J |= VBA_UP;
Morph--;
break;
case -4:
case -5:
case -6:
J &= ~(VBA_UP | VBA_DOWN | VBA_LEFT | VBA_RIGHT | VBA_BUTTON_L);
Morph--;
break;
case -7:
case -8:
case -9:
J &= ~(VBA_UP | VBA_DOWN | VBA_LEFT | VBA_RIGHT | VBA_BUTTON_L);
J |= VBA_UP;
Morph--;
break;
case -10:
Morph = 0;
break;
}
// Menu
if (jp & PAD_BUTTON_START)
J |= VBA_BUTTON_START;
if (RumbleCount>0)
{
WPAD_Rumble(pad, 1);
RumbleCount--;
}
else WPAD_Rumble(pad, 0);
if ((J & 48) == 48)
J &= ~16;
if ((J & 192) == 192)
J &= ~128;
return J;
}
u32 MetroidFusionInput(unsigned short pad)
{
u32 J = StandardMovement(pad);
u32 jp = PAD_ButtonsHeld(pad);
u8 BallState = CPUReadByte(0x3001329); // 0 = stand, 2 = crouch, 5 = ball
u16 Health = CPUReadHalfWord(0x3001310);
static u16 OldHealth = 0;
static int RumbleCount = 0;
// Rumble when they lose health!
if (Health < OldHealth)
if (RumbleCount < 20)
RumbleCount = 20;
OldHealth = Health;
static int Morph = 0;
static int AimCount = 0;
static int MissileCount = 0;
if (BallState == 5) // Can't exit morph ball without pressing C!
J &= ~VBA_UP;
if (BallState == 2) // Can't enter morph ball without pressing C!
J &= ~VBA_DOWN;
WPADData * wp = WPAD_Data(pad);
if (wp->btns_h & WPAD_BUTTON_LEFT)
J |= VBA_BUTTON_L;
if (wp->btns_h & WPAD_BUTTON_RIGHT)
J |= VBA_BUTTON_R;
// Visor doesn't exist, just use as select button
if (wp->btns_h & WPAD_BUTTON_MINUS)
J |= VBA_BUTTON_SELECT;
// Hyper isn't available, just use start button as start
if (wp->btns_h & WPAD_BUTTON_PLUS)
J |= VBA_BUTTON_START;
// Map
if (wp->btns_h & WPAD_BUTTON_1)
J |= VBA_BUTTON_START;
// Hint
if (wp->btns_h & WPAD_BUTTON_2)
J |= VBA_BUTTON_R;
// Z-Target
if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z))
J |= VBA_SPEED;
// Jump
if (wp->btns_h & WPAD_BUTTON_B && BallState!=5)
J |= VBA_BUTTON_A;
else if (BallState==5 && fabs(wp->gforce.y)> 1.5)
J |= VBA_BUTTON_A;
// Fire
if (wp->btns_h & WPAD_BUTTON_A)
J |= VBA_BUTTON_B;
// Aim
if (wp->orient.pitch < -45 && BallState !=5)
{
J |= VBA_UP;
AimCount = 0;
}
else if (wp->orient.pitch < -22 && BallState !=5)
{
if (AimCount>=0) AimCount = -1;
}
else if (wp->orient.pitch> 45 && BallState !=5)
{
if (AimCount<10) AimCount=10;
}
else if (wp->orient.pitch> 22 && BallState !=5)
{
if (AimCount<=0 || AimCount>=10) AimCount = 1;
}
else
{
AimCount=0;
}
// Morph Bdall
if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_d & WPAD_NUNCHUK_BUTTON_C))
{
if (BallState == 5)
{ // ball
Morph = -1;
}
else if (BallState == 2)
{
Morph = 2;
}
else
{
Morph = 1;
}
}
// Missile
if (wp->btns_h & WPAD_BUTTON_DOWN)
{
MissileCount = 1;
}
switch (AimCount)
{
case 1:
J &= ~(VBA_UP | VBA_DOWN | VBA_BUTTON_L);
J |= VBA_BUTTON_L;
AimCount++;
break;
case 2:
J &= ~(VBA_UP | VBA_DOWN | VBA_BUTTON_L);
J |= VBA_BUTTON_L | VBA_DOWN;
AimCount++;
break;
case 3:
J |= VBA_BUTTON_L;
break;
case -1:
J &= ~(VBA_UP | VBA_DOWN | VBA_BUTTON_L);
J |= 0;
AimCount--;
break;
case -2:
J &= ~(VBA_UP | VBA_DOWN | VBA_BUTTON_L);
J |= VBA_BUTTON_L;
AimCount--;
break;
case -3:
J |= VBA_BUTTON_L;
break;
case 10:
case 11:
J |= VBA_BUTTON_A;
AimCount++;
break;
case 12:
case 13:
J |= VBA_DOWN;
AimCount++;
break;
case 14:
J |= VBA_DOWN;
break;
}
switch (MissileCount)
{
case 1:
case 2:
J |= VBA_BUTTON_R;
MissileCount++;
break;
case 3:
case 4:
J |= VBA_BUTTON_R | VBA_BUTTON_B;
MissileCount++;
break;
case 5:
MissileCount = 0;
break;
}
switch (Morph) switch (Morph)
{ {
case 1: case 1:
@ -2091,6 +2328,321 @@ u32 MetroidZeroInput(unsigned short pad)
if (jp & PAD_BUTTON_START) if (jp & PAD_BUTTON_START)
J |= VBA_BUTTON_START; J |= VBA_BUTTON_START;
if (RumbleCount>0)
{
WPAD_Rumble(pad, 1);
RumbleCount--;
}
else WPAD_Rumble(pad, 0);
if ((J & 48) == 48)
J &= ~16;
if ((J & 192) == 192)
J &= ~128;
return J;
}
u32 Metroid1Input(unsigned short pad)
{
u32 J = StandardMovement(pad);
u32 jp = PAD_ButtonsHeld(pad);
u8 BallState = CPUReadByte(0x3007500); // 3 = ball, other = stand
u8 MissileState = CPUReadByte(0x300730E); // 1 = missile, 0 = beam
u16 Health = CPUReadHalfWord(0x3007306); // Binary Coded Decimal
static u16 OldHealth = 0;
static int RumbleCount = 0;
// Rumble when they lose health!
if (Health < OldHealth)
if (RumbleCount < 20)
RumbleCount = 20;
OldHealth = Health;
static int Morph = 0;
if (BallState == 3) // Can't exit morph ball without pressing C!
J &= ~VBA_UP;
if (BallState != 3) // Can't enter morph ball without pressing C!
J &= ~VBA_DOWN;
WPADData * wp = WPAD_Data(pad);
// No visors
if (wp->btns_h & WPAD_BUTTON_MINUS)
J |= VBA_BUTTON_SELECT;
// Start button just pauses
if (wp->btns_h & WPAD_BUTTON_PLUS)
J |= VBA_BUTTON_START;
// Map (doesn't exist)
if (wp->btns_h & WPAD_BUTTON_1)
J |= VBA_BUTTON_START;
// Hint (doesn't exist)
if (wp->btns_h & WPAD_BUTTON_2)
J |= VBA_SPEED;
// Z-Target
if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z))
;
// Jump
if (wp->btns_h & WPAD_BUTTON_B && BallState!=5)
J |= VBA_BUTTON_A;
else if (BallState==5 && fabs(wp->gforce.y)> 1.5)
J |= VBA_BUTTON_A;
// Fire
if (wp->btns_h & WPAD_BUTTON_A) {
if (MissileState)
J |= VBA_BUTTON_SELECT;
else
J |= VBA_BUTTON_B;
}
// Aim
if (wp->orient.pitch < -45 && BallState !=3)
J |= VBA_UP;
// Morph Ball
if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_d & WPAD_NUNCHUK_BUTTON_C))
{
if (BallState == 3)
{ // ball
Morph = -1;
}
else
{
Morph = 2;
}
}
// Missile
if (wp->btns_h & WPAD_BUTTON_DOWN)
{
if (!(MissileState))
J |= VBA_BUTTON_SELECT;
else
J |= VBA_BUTTON_B;
}
if (wp->btns_u & WPAD_BUTTON_DOWN)
{
if (MissileState)
J |= VBA_BUTTON_SELECT;
}
switch (Morph)
{
case 1:
J &= ~(VBA_UP | VBA_DOWN | VBA_LEFT | VBA_RIGHT | VBA_BUTTON_L);
J |= VBA_DOWN;
Morph = 2;
break;
case 2:
J &= ~(VBA_UP | VBA_DOWN | VBA_LEFT | VBA_RIGHT | VBA_BUTTON_L);
Morph = 3;
break;
case 3:
J &= ~(VBA_UP | VBA_DOWN | VBA_LEFT | VBA_RIGHT | VBA_BUTTON_L);
J |= VBA_DOWN;
Morph = 0;
break;
case -1:
case -2:
J &= ~(VBA_UP | VBA_DOWN | VBA_LEFT | VBA_RIGHT | VBA_BUTTON_L);
J |= VBA_UP;
Morph--;
break;
case -3:
case -4:
J &= ~(VBA_UP | VBA_DOWN | VBA_LEFT | VBA_RIGHT | VBA_BUTTON_L);
Morph--;
break;
case -5:
case -6:
J &= ~(VBA_UP | VBA_DOWN | VBA_LEFT | VBA_RIGHT | VBA_BUTTON_L);
J |= VBA_UP;
Morph--;
break;
case -7:
Morph = 0;
break;
}
// Menu
if (jp & PAD_BUTTON_START)
J |= VBA_BUTTON_START;
if (RumbleCount>0)
{
WPAD_Rumble(pad, 1);
RumbleCount--;
}
else WPAD_Rumble(pad, 0);
if ((J & 48) == 48)
J &= ~16;
if ((J & 192) == 192)
J &= ~128;
return J;
}
u32 Metroid2Input(unsigned short pad)
{
u32 J = StandardMovement(pad);
u32 jp = PAD_ButtonsHeld(pad);
u8 BallState = gbReadMemory(0xD020); // 4 = crouch, 5 = ball, other = stand
u8 MissileState = gbReadMemory(0xD04D); // 8 = missile hatch open, 0 = missile closed
u8 Health = gbReadMemory(0xD051); // Binary Coded Decimal
static u8 OldHealth = 0;
static int RumbleCount = 0;
// Rumble when they lose (or gain) health! (since I'm not checking energy tanks)
if (Health != OldHealth)
if (RumbleCount < 20)
RumbleCount = 20;
OldHealth = Health;
static int Morph = 0;
static int AimCount = 0;
if (BallState == 5) // Can't exit morph ball without pressing C!
J &= ~VBA_UP;
if (BallState == 4) // Can't enter morph ball without pressing C!
J &= ~VBA_DOWN;
WPADData * wp = WPAD_Data(pad);
// No visors
if (wp->btns_h & WPAD_BUTTON_MINUS)
J |= VBA_BUTTON_SELECT;
// Start button just pauses
if (wp->btns_h & WPAD_BUTTON_PLUS)
J |= VBA_BUTTON_START;
// Map (doesn't exist)
if (wp->btns_h & WPAD_BUTTON_1)
J |= VBA_BUTTON_START;
// Hint (doesn't exist)
if (wp->btns_h & WPAD_BUTTON_2)
J |= VBA_SPEED;
// Z-Target
if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z))
;
// Jump
if (wp->btns_h & WPAD_BUTTON_B && BallState!=5)
J |= VBA_BUTTON_A;
else if (BallState==5 && fabs(wp->gforce.y)> 1.5)
J |= VBA_BUTTON_A;
// Fire
if (wp->btns_h & WPAD_BUTTON_A) {
if (MissileState & 8)
J |= VBA_BUTTON_SELECT;
else
J |= VBA_BUTTON_B;
}
// Aim
/*if (CursorValid && CursorY < 96 && BallState!=2)
J |= VBA_UP;
else if (CursorValid && CursorY < 192 && BallState!=2)
J |= VBA_BUTTON_L;
else if (CursorValid && CursorY < 288 && BallState!=2)
J |= 0;
else if (CursorValid && CursorY < 384 && BallState!=2)
J |= VBA_BUTTON_L & VBA_DOWN;
else if (CursorValid && BallState==0)
J |= VBA_DOWN;*/
if (wp->orient.pitch < -45 && BallState !=5)
{
J |= VBA_UP;
AimCount = 0;
}
else if (wp->orient.pitch> 45 && BallState !=5 && BallState !=4)
{
//if (AimCount<10) AimCount=10;
}
else
{
AimCount=0;
}
// Morph Ball
if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_d & WPAD_NUNCHUK_BUTTON_C))
{
if (BallState == 5)
{ // ball
Morph = -1;
}
else if (BallState == 4)
{
Morph = 2;
}
else
{
Morph = 1;
}
}
// Missile
if (wp->btns_h & WPAD_BUTTON_DOWN)
{
if (!(MissileState & 8))
J |= VBA_BUTTON_SELECT;
else
J |= VBA_BUTTON_B;
}
if (wp->btns_u & WPAD_BUTTON_DOWN)
{
if (MissileState & 8)
J |= VBA_BUTTON_SELECT;
}
switch (Morph)
{
case 1:
J &= ~(VBA_UP | VBA_DOWN | VBA_LEFT | VBA_RIGHT | VBA_BUTTON_L);
J |= VBA_DOWN;
Morph = 2;
break;
case 2:
J &= ~(VBA_UP | VBA_DOWN | VBA_LEFT | VBA_RIGHT | VBA_BUTTON_L);
Morph = 3;
break;
case 3:
J &= ~(VBA_UP | VBA_DOWN | VBA_LEFT | VBA_RIGHT | VBA_BUTTON_L);
J |= VBA_DOWN;
Morph = 0;
break;
case -1:
case -2:
J &= ~(VBA_UP | VBA_DOWN | VBA_LEFT | VBA_RIGHT | VBA_BUTTON_L);
J |= VBA_UP;
Morph--;
break;
case -3:
case -4:
J &= ~(VBA_UP | VBA_DOWN | VBA_LEFT | VBA_RIGHT | VBA_BUTTON_L);
Morph--;
break;
case -5:
case -6:
J &= ~(VBA_UP | VBA_DOWN | VBA_LEFT | VBA_RIGHT | VBA_BUTTON_L);
J |= VBA_UP;
Morph--;
break;
case -7:
Morph = 0;
break;
}
// Menu
if (jp & PAD_BUTTON_START)
J |= VBA_BUTTON_START;
if (RumbleCount>0)
{
WPAD_Rumble(pad, 1);
RumbleCount--;
}
else WPAD_Rumble(pad, 0);
if ((J & 48) == 48) if ((J & 48) == 48)
J &= ~16; J &= ~16;
if ((J & 192) == 192) if ((J & 192) == 192)

View File

@ -26,6 +26,9 @@
#define MINISHCAP gid('B','Z','M') #define MINISHCAP gid('B','Z','M')
#define METROID0 gid('B','M','X') #define METROID0 gid('B','M','X')
#define METROID1 gid('F','M','R')
#define METROID2 0xFF0009
#define METROID4 gid('A','M','T')
#define MARIO1CLASSIC gid('F','S','M') #define MARIO1CLASSIC gid('F','S','M')
#define MARIO1DX gid('A','H','Y') #define MARIO1DX gid('A','H','Y')
@ -103,6 +106,9 @@ u32 LinksAwakeningInput(unsigned short pad);
u32 OracleOfAgesInput(unsigned short pad); u32 OracleOfAgesInput(unsigned short pad);
u32 MinishCapInput(unsigned short pad); u32 MinishCapInput(unsigned short pad);
u32 MetroidZeroInput(unsigned short pad); u32 MetroidZeroInput(unsigned short pad);
u32 Metroid1Input(unsigned short pad);
u32 Metroid2Input(unsigned short pad);
u32 MetroidFusionInput(unsigned short pad);
u32 TMNTInput(unsigned short pad); u32 TMNTInput(unsigned short pad);
u32 HarryPotter1Input(unsigned short pad); u32 HarryPotter1Input(unsigned short pad);
u32 HarryPotter1GBCInput(unsigned short pad); u32 HarryPotter1GBCInput(unsigned short pad);

View File

@ -523,6 +523,12 @@ static u32 DecodeJoy(unsigned short pad)
// Metroid // Metroid
case METROID0: case METROID0:
return MetroidZeroInput(pad); return MetroidZeroInput(pad);
case METROID1:
return Metroid1Input(pad);
case METROID2:
return Metroid2Input(pad);
case METROID4:
return MetroidFusionInput(pad);
// TMNT // TMNT
case TMNT: case TMNT:

View File

@ -704,6 +704,8 @@ static void gbApplyPerImagePreferences()
RomIdCode = MARIOLAND1; RomIdCode = MARIOLAND1;
else if (strcmp(title, "MARIOLAND2") == 0) else if (strcmp(title, "MARIOLAND2") == 0)
RomIdCode = MARIOLAND2; RomIdCode = MARIOLAND2;
else if (strcmp(title, "METROID2") == 0)
RomIdCode = METROID2;
} }
} }
@ -873,9 +875,14 @@ bool LoadVBAROM(int method)
cartridgeType = 2; cartridgeType = 2;
else if(utilIsGBImage(zippedFilename)) else if(utilIsGBImage(zippedFilename))
cartridgeType = 1; cartridgeType = 1;
else {
WaitPrompt("Rom must be 1st file in zip, or unzipped!");
return false;
}
} }
else // loading the file failed else // loading the file failed
{ {
WaitPrompt("Empty or invalid zip file!");
return false; return false;
} }
} }
@ -883,7 +890,8 @@ bool LoadVBAROM(int method)
// leave before we do anything // leave before we do anything
if(cartridgeType != 1 && cartridgeType != 2) if(cartridgeType != 1 && cartridgeType != 2)
{ {
WaitPrompt("Unknown game image!"); // Not zip gba agb gbc cgb sgb gb mb bin elf or dmg!
WaitPrompt("Invalid filename extension! Not a rom?");
return false; return false;
} }