From da55fc906a5fccde2f3f83b2dd88d623901f77b1 Mon Sep 17 00:00:00 2001 From: "Carl.Kenner" Date: Wed, 27 May 2009 22:20:21 +0000 Subject: [PATCH] Fix for issue 101: Wii controls for Castlevania gameboy games. --- source/ngc/gameinput.cpp | 136 +++++++++++++++++++++++++++++++++++++- source/ngc/gameinput.h | 13 ++++ source/ngc/input.cpp | 8 +++ source/ngc/vbasupport.cpp | 6 ++ 4 files changed, 161 insertions(+), 2 deletions(-) diff --git a/source/ngc/gameinput.cpp b/source/ngc/gameinput.cpp index 925facc..e36bf39 100644 --- a/source/ngc/gameinput.cpp +++ b/source/ngc/gameinput.cpp @@ -689,8 +689,8 @@ u32 TMNTGBAInput(unsigned short pad) { u32 TMNTGBA2Input(unsigned short pad) { u32 J = StandardMovement(pad) | StandardDPad(pad) | DecodeKeyboard(pad); static u32 LastDir = VBA_RIGHT; - static bool wait = false; - static int holdcount = 0; + //static bool wait = false; + //static int holdcount = 0; bool Jump=0, Attack=0, SpinKick=0, SpecialMove=0, Pause=0, Select=0, Look=0; #ifdef HW_RVL @@ -1619,3 +1619,135 @@ u32 ReturnOfTheKingInput(unsigned short pad) { return J; } +u32 CastlevaniaAdventureInput(unsigned short pad) { + // Only Nunchuk and Classic controls available + // Wiimote, Gamecube and Keyboard controls depend on user configuration + u32 J = StandardMovement(pad) | DecodeGamecube(pad) | DecodeKeyboard(pad) | DecodeWiimote(pad) | DecodeClassic(pad); + bool JumpButton=0, AttackButton=0, GuardButton=0, PauseButton=0, SelectButton=0, SpeedButton=0; +#ifdef HW_RVL + WPADData * wp = WPAD_Data(pad); + // Nunchuk controls are based on Castlevania Wii + if (wp->exp.type == WPAD_EXP_NUNCHUK) { + AttackButton = (fabs(wp->gforce.x)> 1.5) || (fabs(wp->gforce.y)> 1.5) || wp->btns_h & WPAD_BUTTON_B; + JumpButton = wp->btns_h & WPAD_NUNCHUK_BUTTON_C; + GuardButton = wp->btns_h & WPAD_NUNCHUK_BUTTON_Z; + PauseButton = wp->btns_h & WPAD_BUTTON_PLUS; + SelectButton = wp->btns_h & WPAD_BUTTON_MINUS; + SpeedButton = (wp->btns_h & WPAD_BUTTON_A) && (wp->btns_h & WPAD_BUTTON_B); + // Classic controls are based on ...? + } else if (wp->exp.type == WPAD_EXP_CLASSIC) { + AttackButton = wp->btns_h & WPAD_CLASSIC_BUTTON_B; + JumpButton = wp->btns_h & (WPAD_CLASSIC_BUTTON_FULL_R | WPAD_CLASSIC_BUTTON_ZR); + GuardButton = wp->btns_h & (WPAD_CLASSIC_BUTTON_FULL_L | WPAD_CLASSIC_BUTTON_ZL); + PauseButton = wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS; + SelectButton = wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS; + SpeedButton = wp->btns_h & WPAD_CLASSIC_BUTTON_A; + } +#endif + + if (JumpButton) J |= VBA_BUTTON_A; + if (AttackButton) J |= VBA_BUTTON_B; + if (PauseButton) J |= VBA_BUTTON_START; + if (SelectButton) J |= VBA_BUTTON_SELECT; + if (SpeedButton) J |= VBA_SPEED; + if (GuardButton) { + J &= ~VBA_UP; + J |= VBA_DOWN; + } + + return J; +} + +u32 CastlevaniaBelmontInput(unsigned short pad) { + // Only Nunchuk and Classic controls available + // Wiimote, Gamecube and Keyboard controls depend on user configuration + u32 J = StandardMovement(pad) | DecodeGamecube(pad) | DecodeKeyboard(pad) | DecodeWiimote(pad) | DecodeClassic(pad); + bool JumpButton=0, AttackButton=0, ShootButton=0, GuardButton=0, PauseButton=0, SelectButton=0, SpeedButton=0; +#ifdef HW_RVL + WPADData * wp = WPAD_Data(pad); + // Nunchuk controls are based on Castlevania Wii + if (wp->exp.type == WPAD_EXP_NUNCHUK) { + ShootButton = wp->btns_h & WPAD_BUTTON_A; + AttackButton = (fabs(wp->gforce.x)> 1.5) || (fabs(wp->gforce.y)> 1.5) || wp->btns_h & WPAD_BUTTON_B; + JumpButton = wp->btns_h & WPAD_NUNCHUK_BUTTON_C; + GuardButton = wp->btns_h & WPAD_NUNCHUK_BUTTON_Z; + PauseButton = wp->btns_h & WPAD_BUTTON_PLUS; + SelectButton = wp->btns_h & WPAD_BUTTON_MINUS; + SpeedButton = (wp->btns_h & WPAD_BUTTON_A) && (wp->btns_h & WPAD_BUTTON_B); + // Classic controls are based on ...? + } else if (wp->exp.type == WPAD_EXP_CLASSIC) { + ShootButton = wp->btns_h & WPAD_CLASSIC_BUTTON_Y; + AttackButton = wp->btns_h & WPAD_CLASSIC_BUTTON_B; + JumpButton = wp->btns_h & (WPAD_CLASSIC_BUTTON_FULL_R | WPAD_CLASSIC_BUTTON_ZR); + GuardButton = wp->btns_h & (WPAD_CLASSIC_BUTTON_FULL_L | WPAD_CLASSIC_BUTTON_ZL); + PauseButton = wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS; + SelectButton = wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS; + SpeedButton = wp->btns_h & WPAD_CLASSIC_BUTTON_A; + } +#endif + + if (JumpButton) J |= VBA_BUTTON_A; + if (AttackButton) { + J &= ~VBA_UP; + J |= VBA_BUTTON_B; + } + if (ShootButton) J |= VBA_UP | VBA_BUTTON_B; + if (PauseButton) J |= VBA_BUTTON_START; + if (SelectButton) J |= VBA_BUTTON_SELECT; + if (SpeedButton) J |= VBA_SPEED; + if (GuardButton) { + J &= ~VBA_UP; + J |= VBA_DOWN; + } + + return J; +} + +u32 CastlevaniaLegendsInput(unsigned short pad) { + // Only Nunchuk and Classic controls available + // Wiimote, Gamecube and Keyboard controls depend on user configuration + u32 J = StandardMovement(pad) | DecodeGamecube(pad) | DecodeKeyboard(pad) | DecodeWiimote(pad) | DecodeClassic(pad); + bool JumpButton=0, AttackButton=0, ShootButton=0, GuardButton=0, PauseButton=0, SelectButton=0, SpeedButton=0, HyperButton=0; +#ifdef HW_RVL + WPADData * wp = WPAD_Data(pad); + // Nunchuk controls are based on Castlevania Wii + if (wp->exp.type == WPAD_EXP_NUNCHUK) { + ShootButton = wp->btns_h & WPAD_BUTTON_A; + AttackButton = (fabs(wp->gforce.x)> 1.5) || (fabs(wp->gforce.y)> 1.5) || wp->btns_h & WPAD_BUTTON_B; + JumpButton = wp->btns_h & WPAD_NUNCHUK_BUTTON_C; + GuardButton = wp->btns_h & WPAD_NUNCHUK_BUTTON_Z; + PauseButton = wp->btns_h & WPAD_BUTTON_PLUS; + SelectButton = wp->btns_h & WPAD_BUTTON_MINUS; + SpeedButton = (wp->btns_h & WPAD_BUTTON_A) && (wp->btns_h & WPAD_BUTTON_B); + HyperButton = wp->btns_h & WPAD_BUTTON_DOWN; + // Classic controls are based on ...? + } else if (wp->exp.type == WPAD_EXP_CLASSIC) { + ShootButton = wp->btns_h & WPAD_CLASSIC_BUTTON_Y; + AttackButton = wp->btns_h & WPAD_CLASSIC_BUTTON_B; + JumpButton = wp->btns_h & (WPAD_CLASSIC_BUTTON_FULL_R | WPAD_CLASSIC_BUTTON_ZR); + GuardButton = wp->btns_h & (WPAD_CLASSIC_BUTTON_FULL_L | WPAD_CLASSIC_BUTTON_ZL); + PauseButton = wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS; + SelectButton = wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS; + SpeedButton = wp->btns_h & WPAD_CLASSIC_BUTTON_A; + HyperButton = wp->btns_h & WPAD_CLASSIC_BUTTON_X; + } +#endif + + if (JumpButton) J |= VBA_BUTTON_A; + if (AttackButton) { + J &= ~VBA_UP; + J |= VBA_BUTTON_B; + } + if (HyperButton) J |= VBA_BUTTON_A | VBA_BUTTON_B; + if (ShootButton) J |= VBA_UP | VBA_BUTTON_B; + if (PauseButton) J |= VBA_BUTTON_START; + if (SelectButton) J |= VBA_BUTTON_SELECT; + if (SpeedButton) J |= VBA_SPEED; + if (GuardButton) { + J &= ~VBA_UP; + J |= VBA_DOWN; + } + + return J; +} + diff --git a/source/ngc/gameinput.h b/source/ngc/gameinput.h index ff6b99c..e89526f 100644 --- a/source/ngc/gameinput.h +++ b/source/ngc/gameinput.h @@ -99,6 +99,16 @@ #define LOTR3 gid('B','L','R') #define LOTR3RDAGE gid('B','3','A') +#define CVADVENTURE 0xFF000E +#define CVBELMONT 0xFF000F +#define CVLEGENDS 0xFF0010 +#define CVCIRCLEMOON gid('A','A','M') +#define CVHARMONY gid('A','C','H') +#define CVARIA gid('A','2','C') +#define CVCLASSIC gid('F','A','D') +#define CVDOUBLE gid('B','X','K') + + #define MARBLEMADNESS 0xFF000A @@ -181,6 +191,9 @@ u32 OnePieceInput(unsigned short pad); u32 HobbitInput(unsigned short pad); u32 FellowshipOfTheRingInput(unsigned short pad); u32 ReturnOfTheKingInput(unsigned short pad); +u32 CastlevaniaAdventureInput(unsigned short pad); +u32 CastlevaniaBelmontInput(unsigned short pad); +u32 CastlevaniaLegendsInput(unsigned short pad); #endif diff --git a/source/ngc/input.cpp b/source/ngc/input.cpp index 8064299..5984590 100644 --- a/source/ngc/input.cpp +++ b/source/ngc/input.cpp @@ -870,6 +870,14 @@ static u32 DecodeJoy(unsigned short pad) case LOTR2: case LOTR3: return ReturnOfTheKingInput(pad); + + // Castlevania + case CVADVENTURE: + return CastlevaniaAdventureInput(pad); + case CVBELMONT: + return CastlevaniaBelmontInput(pad); + case CVLEGENDS: + return CastlevaniaLegendsInput(pad); } // the function result, J, is a combination of flags for all the VBA buttons that are down diff --git a/source/ngc/vbasupport.cpp b/source/ngc/vbasupport.cpp index cf6119f..75a731d 100644 --- a/source/ngc/vbasupport.cpp +++ b/source/ngc/vbasupport.cpp @@ -790,6 +790,12 @@ static void gbApplyPerImagePreferences() RomIdCode = TMNT2; else if (strcmp(RomTitle, "TMNT3") == 0) RomIdCode = TMNT3; + else if (strcmp(RomTitle, "CASTLEVANIA ADVE") == 0) + RomIdCode = CVADVENTURE; + else if (strcmp(RomTitle, "CASTLEVANIA2 BEL") == 0) + RomIdCode = CVBELMONT; + else if (strcmp(RomTitle, "CASTLEVANIA") == 0 || strcmp(RomTitle, "CV3 GER") == 0) + RomIdCode = CVLEGENDS; } // look for matching palettes if a monochrome gameboy game // (or if a Super Gameboy game, but the palette will be ignored later in that case)