diff --git a/readme.txt b/readme.txt index 4c37ccd..b0083fa 100644 --- a/readme.txt +++ b/readme.txt @@ -12,7 +12,8 @@ With it you can play GBA/Game Boy Color/Game Boy games on your Wii/GameCube. -=[ Features ]=- -* Wiimote, Nunchuk, Classic, Gamecube controller, Keyboard, and Mouse support +* Wiimote, Nunchuk, Classic, Gamecube controller, and Keyboard support +* Rotation sensors, Solar sensors, and Rumble support * Optional special Wii controls built-in for some games * SRAM and State saving * IPS/UPS/PPF patch support @@ -27,6 +28,23 @@ With it you can play GBA/Game Boy Color/Game Boy games on your Wii/GameCube. |0O×ĝo· UPDATE HISTORY ·oĝ×O0| `¨•¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨' +[What's New 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 + [What's New 1.0.7 - January 27, 2009] * Updated to VBA-M r847 * Corrected sound interpolation @@ -155,6 +173,558 @@ it to your Gamecube, or by booting a bootable DVD with VBAGX on it. This document doesn't cover how to do any of that. A good source for information on these topics is the tehskeen forums: http://www.tehskeen.com/forums/ +ח–­—–­—–­—–­ –­—–­—–­—–­—–­—–­—–­—–­—–­—–­— ­—–­—–­—–­—–­—–­—–­—–­—-­—–­-–•Ĵ +|0O×ĝo· INSTRUCTIONS ·oĝ×O0| +`¨•¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨' +Note! You will need to unplug and replug the USB keyboard (perhaps more than +once) while in the emulator to get it to work. A keyboard is not required. + +If you have upgraded from a previous version, the emulator will start with a +message that your preferences have been reset. Press A and you will be taken +to the preferences menu. You will need to set your preferences how you want +them. + +Otherwise the emulator will start at the main menu. + +Navigate the menu with the D-Pad, and select options with the A button. +Press B to cancel out of a menu. Cancelling out of the main menu with B will +return you to the game, if you have chosen one. + +When choosing a file, the B button takes you up a folder. Once you get to +the root directory pressing B will cancel and take you back to the menu. +There may be more than one page of files, even if it doesn't look like it. +Keep pressing down or up to go to the next page, or use left and right. + +If you don't want to load ROMs from the SD card, you can go to the +preferences menu and choose where to load from. You can load from SD cards, +USB memory sticks/hard drives, DVD (if you installed DVDX), gamecube memory +cards, or from shared folders over the network (this is called SMB). + +ROMs can be in ZIP files, but the ROM must be the first file in the ZIP. If +not, you will get an error. ROMs can also be in .7z files, or ordinary rom +files. + +Patches can be used to colourise a monochrome gameboy game, or to translate +a game into your language, or to stop the game from needing special hardware. +Search the internet for patches. Many games have been translated by fans. +They can be in IPS or UPS format. You don't need to patch anything yourself. +Just put the IPS or UPS file in the vbagx/roms folder along with the rom +itself. The patch must have the same name as the rom. Patches can not be put +inside the ZIP file. If a rom is zipped, you might need to check inside the +zip for the actual rom filename. + +Colourised games still have some distortion in this version, but it is +improved from the previous version, and better than VBA-M. + +You must not use patched versions of Boktai roms! (Except for the translation +patch for Boktai 3, which is highly recommended). The patches are for old +emulators that don't support the solar sensor. VBA GX and NO$GBA support the +solar sensor natively, and the patch will stop them from working. + +You must also not use patched versions of WarioWare Twisted, Kirby's Tilt n +Tumble, or Yoshi's Universal Gravitation (Topsy Turvy). The original roms +are fully supported, and the patch will stop them from working. + +-=[ Controls ]=- + +The default controls are... + ++ = Gameboy Start Button +- = Gameboy Select Button +Home = Show emulator's game menu + +Wii Remote by itself: +Hold the Wii Remote sideways. +2 = Gameboy A Button +1 = Gameboy B Button +A = Gameboy R Button +B = Gameboy L Button + +Wii Remote + Nunchuk: +Hold the Nunchuk and ignore the Wii Remote. +Z = Gameboy A Button +C = Gameboy B Button + +Classic Controller: +Use the buttons as labelled. +A = Gameboy A Button +B = Gameboy B Button +R = Gameboy R Button +L = Gameboy L Button + +Keyboard: +X = Gameboy A Button +Z = Gameboy B Button +S = Gameboy R Button +A = Gameboy L Button +Enter = Gameboy Start Button +Backspace = Gameboy Select Button +Space = Fast forward + +You can configure the controls how you want from the controls menu. Different +controls will be used depending on what you have plugged into the Wii Remote. +Nunchuk means Nunchuk + Wii Remote. Gamecube controllers and Keyboards can +be used at the same time as Wii Remotes and all control the same player. +When configuring controls, press HOME to cancel. + +But the controls you choose will be overridden for certain games if you +choose "Match Wii Game" (or "Match Gamecube Game" on a Gamecube) and you have +the appropriate expansion plugged in. If the game does not have special Wii +controls, then the controls you chose will be used. + +Gameboy and Gameboy colour games don't have L and R buttons. Those buttons +only work in Gameboy Advance games. + +In addition to the controls you can configure, these other controls apply: + +HOME, Escape: returns you to the emulator's game menu. Then press B to go +to the main menu and B again to return to the game. +A+B, Spacebar, or right analog stick: fast forward +Right analog stick: zoom (if enabled) + +-=[ Match Wii Controls ]=- + +Special Wii controls exist for the following games: + +These Zelda games can be played with Twilight Princess controls: +The Legend Of Zelda, Zelda 2, A Link To The Past, Link's Awakening (DX), Oracle of Ages, +Oracle of Seasons, Minish Cap + +These Mario games can be played with Mario Galaxy controls: +Super Mario Bros., Super Mario Bros. DX, Super Mario 2, Super Mario (2) +Advance, Super Mario 3, Super Mario World, Yoshi's Island, +Yoshi's Universal Gravitation (Topsy Turvy) + +Mario Kart can be played with Mario Kart wii controls + +These Metroid games can be played with Metroid Prime 3 controls: +Metroid Zero Mission, Metroid 1, Metroid 2, Metroid Fusion + +These Mortal Kombat games can be played with Mortal Kombat Armageddon controls: +Mortal Kombat, Mortal Kombat II, Mortal Kombat 3, Mortal Kombat 4, Mortal +Kombat Advance, Mortal Kombat Deadly Alliance, Mortal Kombat Tournament +Edition + +These Lego games can be played with Lego Star Wars the Complete Saga +controls: +Lego Star Wars The Video Game, Lego Star Wars The Original Trilogy + +TMNT can be played with TMNT Wii controls. + +These Harry Potter games can be played with Harry Potter and the Order of +the Phoenix Wii controls: +Harry Potter 1, Harry Potter 1 GBC, Harry Potter 2, Harry Potter 2 GBC, Harry Potter 3, Harry Potter 4, Harry Potter 5 + +These Medal Of Honour games can be played with Medal Of Honour Wii controls: +Medal Of Honour Underground, Medal Of Honour Infiltrator + +One Piece can be played with One Piece Unlimited Adventure controls. + +Boktai 1, Boktai 2, Boktai 3, Kirby's Tilt n Tumble, and WarioWare Twisted can be played with +controls I designed for them. + +-=[ Zelda, Match Wii Controls ]=- + +Turn "Match Wii Controls" ON to use these controls. + +All Zelda games use the same controls as Twilight Princess on the Wii or +Gamecube. You can also connect a Classic Controller to use similar controls +to the Ocarina Of Time for the Virtual Console, but with the R trigger +acting as the B button and an inventory like Twilight Princess. With nothing +plugged in to the Wii Remote, your configured controls are used instead. + +The Wii Zelda controls are: +=========================== + +Swing your Wii Remote to draw or swing your sword. Press A to put your sword +away again. The 2 handed sword can't be drawn this way, and must be drawn +manually from the items menu, but you can swing it like normal. + +Shake your Nunchuk to do a spin attack. + +Use the Z Button to Z-Target and to draw and use your shield. While +Z-Targetting you will sidestep in some games. If you have a Gust Jar +equipped instead of a shield, it will be used for Z-Targetting. + +Use the A Button to perform an action, such as rolling, talking to people, +reading signs, picking things up, throwing things, shrinking or growing, +pulling things, etc. It will also put away your sword or shield. In Zelda 2, +it will jump. + +Use the C Button to fast forward. It was originally the camera button in +Twilight Princess. + +Press the B Button to use the currently selected item. 3 other items will be +mapped to Left, Down, and Right D-Pad buttons. Swap the currently selected +item with one of those items by pressing that D-Pad button. The three slots +correspond to the first 3 slots in your inventory. In Minish Cap, the D-Pad +buttons use the item directly instead of swapping it with the B Button, and +the B Button is the same as the down button. In Minish Cap the left item is +always the Kinstones and the down and right items correspond to the B and A +slots. + +Up on the D-Pad talks to Midna, or to your hat. It will take you to the save +screen in Link's Awakening, or to the secondary items screen in the Oracle +games. + +The 1 Button goes to the Map screen. +The - Button goes to the Items screen. +The + Button goes to the Quest Status screen + +On the Items screen, choose an item and then press either the B Button or the +D-Pad button to move it to that slot. The change may not be visible until you +go to another screen and back. In Link's Awakening you can toggle Bomb +Arrows by choosing the bombs and pressing Z. It will rumble for a short time +when bomb arrows are deactivated, and for a long time when bomb arrows are +activated. You still need to equip the bow to use bomb arrows. In Minish Cap +you should be able to use the IR pointer function to select items. + +The Gamecube controller Zelda controls are: +=========================================== + +B is the sword button. Use it to draw or swing your sword. Hold B for a spin +attack. Press A to put the sword away again. The 2 handed sword can't be +drawn this way, and must be selected manually from the items screen, but can +be swung with this (or any other) button. + +Use the L Trigger to L-Target and to draw and use your shield. While +L-Targetting you will sidestep in some games. If you have a Gust Jar +equipped instead of a shield, it will be used for L-Targetting. + +Use the A Button to perform an action, such as rolling, talking to people, +reading signs, picking things up, throwing things, shrinking or growing, +etc. It will also put away your sword or shield. In Zelda 2, it will jump. + +Use the R Trigger to pull on blocks or walls, or to lift things. You must +have a bracelet or gloves to lift some objects. The bracelet or gloves will +be equipped automatically. This feature is unique to the Gamecube controller. + +Use the right analog stick to fast forward. It was originally the camera +control in Twilight Princess. + +Press the X or Y buttons to use the two equipped items. These two items both +share the B slot, except in Minish Cap where one is in the A slot. The item +that was not used last will be in the first slot in your inventory. + +Right on the D-Pad takes you to the map. +Up on the D-Pad takes you to the items screen. +Start takes you to the quest status screen. + +The Z trigger talks to Midna, or to your hat. It will take you to the save +screen in Link's Awakening, or to the secondary items screen in the Oracle +games. + +The Classic controller Zelda controls are: +========================================== + +B is the sword button. Use it to draw or swing your sword. Hold B for a spin +attack. Press A to put the sword away again. The 2 handed sword can't be +drawn this way, and must be selected manually from the items screen, but can +be swung with this (or any other) button. + +Use the L Trigger to L-Target and to draw and use your shield. While +L-Targetting you will sidestep in some games. If you have a Gust Jar +equipped instead of a shield, it will be used for L-Targetting. + +Use the A Button to perform an action, such as rolling, talking to people, +reading signs, picking things up, throwing things, shrinking or growing, +pulling, etc. It will also put away your sword or shield. In Zelda 2, it +will jump. + +Use the ZL Button to fast forward. + +Press the R Button to use the currently selected item. 3 other items will be +mapped to Left, Down, and Right on the right analog stick. They are also +mapped to ZR, Y, and X. Swap the currently selected item with one of those +items by pressing that button or direction. The three slots correspond to +the first 3 slots in your inventory. In Minish Cap, the D-Pad buttons use the +item directly instead of swapping it with the B Button, and the B Button is +the same as the down button. In Minish Cap the left item is always the +Kinstones and the down and right items correspond to the B and A slots. + ++ (Start) takes you to the subscreens. +- (Select) takes you to the map or changes subscreens. + +Up on the analog stick talks to Midna, or to your hat. + + +-=[ Mario, Match Wii Controls ]=- + +Turn "Match Wii Controls" ON to use these controls. + +All Mario or Yoshi games use the same controls as Super Mario Galaxy on the +Wii. You can also connect a Classic Controller to use similar controls to +Super Mario World on the SNES. + +The Wii Mario controls are: +=========================== + +Shake the Wii Remote to do a spin attack, or to shoot fireballs when you are +fire Mario. In some games that have a spin attack, you will need to use the +B Button instead to shoot fireballs. You can also dismount Yoshi by shaking. + +Walk by moving the joystick a little, run by moving the joystick a lot. + +A = jump +B = shoot, run, hold on to things, yoshi's tongue, etc. +Z = crouch or lay egg. Press Z while in the air to butt stomp. +C = camera. Hold C to look around with the joystick. +D-Pad = look around, or walk in some games ++ = pause +1 = throw egg if you are Yoshi + +The Classic Controller Mario controls are: +========================================== + +Walk by moving the joystick a little, run by moving the joystick a lot. + +B = jump +A = spin attack +X/Y = shoot, run, hold on to things, yoshi's tongue, etc. +ZL or sometimes L = crouch or lay egg. Press in the air to butt stomp. ++ = pause +L/R sometimes look around + + +-=[ Yoshi's Universal Gravitation (Topsy Turvy), Match Wii Controls ]=- + +Turn "Match Wii Controls" ON to use these controls. + +The controls are the same as all other Mario or Yoshi games, except that +tilting the Wii Remote tilts the world and the screen. This affects +everything in the world and also how you move. + + +-=[ Metroid, Match Wii Controls ]=- + +Turn "Match Wii Controls" ON to use these controls. + +All Metroid games use the same controls as Metroid Prime 3: Corruption on +the Wii. You aim up and down by pointing the Wii Remote up and down. + +The Wii Metroid controls are: +============================= +Aim up and down by pointing the Wii Remote up and down. + +Flick the Wii remote up while in Morph Ball to spring jump. + +A = shoot +B = jump +Down on D-Pad = fire missile +C = toggle Morph Ball +- = start ++ = toggle super missiles +1 = map +2 = hint + + +-=[ TMNT, Match Wii Controls ]=- + +Turn "Match Wii Controls" ON to use these controls. + +The TMNT game based on the CGI movie uses the same controls as TMNT on Wii. +They are not fully implemented yet. + +The Wii TMNT controls are: +========================== +Shake the Wii Remote or Nunchuk to attack or to throw away a weapon if +in the air. Also shake to pick up a weapon. + +A = jump +B = swap turtle + +-=[ Boktai, Match Wii Controls ]=- + +Turn "Match Wii Controls" ON to use these controls. + +The 3 Boktai games use special controls that I created. They are not based on +anything, since the real game uses a solar sensor. + +The controls are the same with or without a Nunchuk. + +The Wii Boktai controls are: +============================ + +Point your Wii Remote at the sky to quickly charge your Gun Del Sol. Point +your Wii Remote at the ground to block the sunlight and prevent it from +charging or overheating. Or hold it like normal to use it like normal. + +Press Home to set the real life weather in the emulator's game menu. Note +that if it is night time in real life, there will not be any sun, regardless +of what you set the weather to. Please set the weather honestly or it spoils +the fun. Note that maximum sun is not actually the best, since it rots fruit, +and overheats your gun. The weather must be set each time you play, it is not +saved. + +Swing your Wii Remote to swing your sword or other weapon, if you have one. + +D-Pad or Nunchuk joystick walks. + +Press B to fire your Gun Del Sol. + +A = read signs, open chests, talk to people +C or 2 = look around, or change subscreen (R) ++ = start +- = select +Z or 1 = change element, or change subscreen (L) +1 (if Nunchuk plugged in) = fast forward + +-=[ WarioWare Twisted, Match Wii Controls ]=- + +Turn "Match Wii Controls" ON to use these controls. + +WarioWare Twisted uses similar controls to the Gameboy game. + +The Wii WarioWare Twisted controls are: +======================================= + +Rotate the Wii Remote to rotate. + +Hold Z to lock the current menu item. + +A = Select +B = Cancel ++ = Start + +-=[ Kirby's Tilt n Tumble, Match Wii Controls ]=- + +Turn "Match Wii Controls" ON to use these controls. + +Kirby's Tilt n Tumble uses similar controls to the Gameboy game. + +The Kirby Tilt n Tumble controls are: +===================================== + +Tilt the Wii Remote to tilt the world. Shake the Wii Remote to flick Kirby +and the monsters up into the air. + +A = shoot yourself out of holes in the ground, or jump from clouds. + +-=[ Mortal Kombat, Match Wii Controls ]=- + +Turn "Match Wii Controls" ON to use these controls. + +All Mortal Kombat games use the same controls as Mortal Kombat Armaggedon +for the Wii, except that special moves gestures are not implemented yet. +Note that the Gameboy games all only have 1 punch and 1 kick, rather than +the 4 attacks on other consoles. + +The Mortal Kombat Wii controls are: +=================================== + +Use the Nunchuk joystick to move and jump. + +D-Pad up/left = punch +D-Pad down/right = kick + +Z = block +A = throw +C = change style, run +- = pause + +-=[ Lego Star Wars, Match Wii Controls ]=- + +Turn "Match Wii Controls" ON to use these controls. + +Both Lego Star Wars games use the same controls as Lego Star Wars: The +Complete Saga for the Wii. + +The Lego Star Wars Wii controls are: +==================================== +Swing the Wii Remote to swing your lightsaber. +Flick the Wii Remote up to grapple. + +A = Jump +B = Shoot +Z = Use the force, build lego +C = Change characters, talk to people +- = force power, special ability ++ = start +1/2 = fast forward + +-=[ Harry Potter, Match Wii Controls ]=- + +Turn "Match Wii Controls" ON to use these controls. + +All the Harry Potter games use the same controls as Harry Potter & The Order +Of The Phoenix on the Wii. They also use the keyboard controls from the PC +version of each game. Spell gestures are not supported yet. + +The Harry Potter Wii controls are: +================================== +Wave the Wii Remote to cast a spell. +Nunchuk joystick walks. +D-Pad changes subscreen in the map and navigates menu. +In Harry Potter and the Order of the Phoenix you must use the IR Pointer +to select where to cast a spell. + +A = Talk, open door, push button, interract, etc. / Jinx +B = Use your wand / charm / cancel +Z = run (fast forward) / sneak +C = show location name / flute / jump +- = Maurauders map / Tasks ++ = pause / menu +1/2 = change spells + +-=[ Medal of Honour, Match Wii Controls ]=- + +Turn "Match Wii Controls" ON to use these controls. + +All the Medal of Honour games use the same controls as various +Medal of Honour games and modes on the Wii. + +The Medal of Honour Wii controls are: +===================================== + +In Medal of Honour Underground you turn by aiming with the Wii Remote IR +pointer on the screen like any FPS game. In Medal of Honour Infiltrator, +you don't. + +Swing the Wiimote up to reload. +Move with the Nunchuk joystick. + +B = shoot +- = use ++ = pause, objectives, menu +2 / D-Pad Up = reload +D-Pad Left/Right = change weapons +D-Pad Down = toggle crouch +C = strafe +1 = run + +-=[ One Piece, Match Wii Controls ]=- + +Turn "Match Wii Controls" ON to use these controls. + +One Piece uses the same controls as One Piece Unlimited Adventure on the Wii +or One Piece Grand Adventure (and others) on the Gamecube. + +The One Piece Wii controls are: +=============================== + +A = attack +B = jump +- = change character ++ = pause +C = dash (double click and hold) +Z = grab +2 = fast forward +1 = select (maybe does nothing) + +The One Piece Gamecube controls are: +=============================== + +A = attack +X = attack up +Y = jump +B = grab +R Trigger = change character +start = pause +L Trigger = dash (double click and hold) +Z = grab +right analog stick = fast forward +1 = select (maybe does nothing) + ¸,ĝ¤°`°¤ĝ,¸¸,ĝ¤°`°¤ĝ,¸,ĝ¤°`°¤ĝ,¸¸,ĝ¤°`°¤ĝ,¸,ĝ¤°`°¤ĝ,¸¸,ĝ¤°`°¤ĝ,¸,ĝ¤°`°¤ĝ,¸¸,ĝ¤ -=[ Credits ]=- diff --git a/source/ngc/gameinput.cpp b/source/ngc/gameinput.cpp index 8306921..1ea5f82 100644 --- a/source/ngc/gameinput.cpp +++ b/source/ngc/gameinput.cpp @@ -5,13 +5,12 @@ * * gameinput.cpp * - * Wii controls for individual games + * Wii/Gamecube controls for individual games ***************************************************************************/ -#ifdef HW_RVL - #include #include +#include #include #include #include @@ -31,1226 +30,17 @@ #include "gba/bios.h" #include "gba/GBAinline.h" -u8 ZeldaDxLeftPos = 2, ZeldaDxRightPos = 3, ZeldaDxDownPos = 4; -u8 ZeldaDxShieldPos = 5, ZeldaDxSwordPos = 5; +char DebugStr[50] = ""; -void ZeldaDxSwapBItem(u8 pos) -{ - u8 OldBItem = gbReadMemory(0xDB00 + 0); - gbWriteMemory(0xDB00 + 0, gbReadMemory(0xDB00 + pos)); - gbWriteMemory(0xDB00 + pos, OldBItem); -} +/*void DebugPrintf(const char *format, ...) { + va_list args; + va_start( args, format ); + vsprintf( DebugStr, format, args ); + va_end( args ); +}*/ -void ZeldaDxSwap(u8 pos1, u8 pos2) -{ - u8 OldItem = gbReadMemory(0xDB00 + pos1); - gbWriteMemory(0xDB00 + pos1, gbReadMemory(0xDB00 + pos2)); - gbWriteMemory(0xDB00 + pos2, OldItem); -} -bool ZeldaDxDrawShield() -{ - if (gbReadMemory(0xDB00 + 1) == 4) - return true; - ZeldaDxShieldPos = 0xFF; - for (int i = 0; i <= 11; i++) - { - if (gbReadMemory(0xDB00 + i) == 4) - { - ZeldaDxShieldPos = i; - } - } - if (ZeldaDxShieldPos == 0xFF) - return false; - if (ZeldaDxShieldPos != 1) - { - - gbWriteMemory(0xDB00 + ZeldaDxShieldPos, gbReadMemory(0xDB00 + 1)); // put A item away - gbWriteMemory(0xDB00 + 1, 4); // set A item to shield - } - return true; -} - -bool ZeldaDxDrawBombs() -{ - if (gbReadMemory(0xDB00 + 1) == 2) - return true; - ZeldaDxShieldPos = 0xFF; - for (int i = 0; i <= 11; i++) - { - if (gbReadMemory(0xDB00 + i) == 2) - { - ZeldaDxShieldPos = i; - } - } - if (ZeldaDxShieldPos == 0xFF) - return false; - if (ZeldaDxShieldPos != 2) - { - - gbWriteMemory(0xDB00 + ZeldaDxShieldPos, gbReadMemory(0xDB00 + 1)); // put A item away - gbWriteMemory(0xDB00 + 1, 2); // set A item to bombs - } - return true; -} - -bool ZeldaDxDrawSword() -{ - if (gbReadMemory(0xDB00 + 1) == 1) - return true; - ZeldaDxSwordPos = 0xFF; - for (int i = 0; i <= 11; i++) - { - if (gbReadMemory(0xDB00 + i) == 1) - { - ZeldaDxSwordPos = i; - } - } - if (ZeldaDxSwordPos == 0xFF) - return false; - if (ZeldaDxSwordPos != 1) - { - gbWriteMemory(0xDB00 + ZeldaDxSwordPos, gbReadMemory(0xDB00 + 1)); // put A item away - gbWriteMemory(0xDB00 + 1, 1); // set A item to sword - } - return true; -} - -void ZeldaDxSheathSword() -{ - if (ZeldaDxSwordPos == 0xFF || gbReadMemory(0xDB00 + 1) != 1) - return; - gbWriteMemory(0xDB00 + 1, gbReadMemory(0xDB00 + ZeldaDxSwordPos)); - gbWriteMemory(0xDB00 + ZeldaDxSwordPos, 1); - ZeldaDxSwordPos = 0xFF; -} - -void ZeldaDxCheat() -{ - for (int i = 0; i <= 11; i++) - { - gbWriteMemory(0xDB00 + i, i + 1); - } - gbWriteMemory(0xDB15, 5); // leaves - gbWriteMemory(0xDB43, 3); // bracelet level - gbWriteMemory(0xDB44, 3); // shield level - gbWriteMemory(0xDB45, 0x30); // arrows - gbWriteMemory(0xDB49, 7); // songs - gbWriteMemory(0xDB4C, 0x30); // powder - gbWriteMemory(0xDB4D, 0x30); // bombs - gbWriteMemory(0xDB4E, 3); // sword level - gbWriteMemory(0xDB5D, 0x9); // rupees - gbWriteMemory(0xDB5E, 0x99); // rupees - gbWriteMemory(0xDBD0, 1); // keys -} - -u32 LinksAwakeningInput(unsigned short pad) -{ - static bool QuestScreen = false; - static int StartCount = 0; - static int SwordCount = 0; - static bool BombArrows = false; - static int DelayCount = 0; - bool OnItemScreen = gbReadMemory(0xC16C) == 0x20; // 0x20 = items, 0x10 = normal - - u32 J = StandardMovement(pad); - - u8 Health = gbReadMemory(0xDB5A); - u8 CursorPos = gbReadMemory(0xC1B6) + 2; - u8 SelItem = 0; - if (CursorPos < 12) - SelItem = gbReadMemory(0xDB00 + CursorPos); - static u8 OldHealth = 0; - - // Rumble when they lose health! - if (Health < OldHealth) - systemGameRumble(20); - OldHealth = Health; - - WPADData * wp = WPAD_Data(pad); - - // Action button, and put away sword - if (wp->btns_h & WPAD_BUTTON_A) - { - if (QuestScreen && OnItemScreen) - { - if (StartCount>=0) StartCount = -80; - } - else - { - if (!OnItemScreen) - ZeldaDxSheathSword(); - else - systemGameRumble(5); - J |= VBA_BUTTON_A; - } - } - - // Sword - if (fabs(wp->gforce.x)> 1.5 && !OnItemScreen) - { - if (ZeldaDxDrawSword()) - { - if (SwordCount<3) SwordCount = 3; - } - QuestScreen = false; - } - // Spin attack - if ((wp->exp.type == WPAD_EXP_NUNCHUK) && fabs(wp->exp.nunchuk.gforce.x)> 0.6 && !OnItemScreen) - { - if (ZeldaDxDrawSword()) - { - if (SwordCount<60) SwordCount=60; - } - QuestScreen = false; - } - if (SwordCount>0) - { - if (SwordCount == 50) - systemGameRumbleOnlyFor(50); - if (!OnItemScreen) - J |= VBA_BUTTON_A; - SwordCount--; - } - - // Talk to Midna, er... I mean save the game - if (wp->btns_h & WPAD_BUTTON_UP) - { - J |= VBA_BUTTON_A | VBA_BUTTON_B | VBA_BUTTON_START | VBA_BUTTON_SELECT; - systemGameRumbleOnlyFor(5); - QuestScreen = false; - } - - // Left Item - if (wp->btns_h & WPAD_BUTTON_LEFT) - { - if (OnItemScreen) ZeldaDxSwap(ZeldaDxLeftPos, CursorPos); - else ZeldaDxSwapBItem(ZeldaDxLeftPos); - systemGameRumbleOnlyFor(5); - QuestScreen = false; - } - // Right Item - if (wp->btns_h & WPAD_BUTTON_RIGHT) - { - if (OnItemScreen) ZeldaDxSwap(ZeldaDxRightPos, CursorPos); - else ZeldaDxSwapBItem(ZeldaDxRightPos); - systemGameRumbleOnlyFor(5); - QuestScreen = false; - } - // Down Item - if (wp->btns_h & WPAD_BUTTON_DOWN) - { - if (OnItemScreen) ZeldaDxSwap(ZeldaDxDownPos, CursorPos); - else ZeldaDxSwapBItem(ZeldaDxDownPos); - systemGameRumbleOnlyFor(5); - QuestScreen = false; - } - // B Item - if (wp->btns_h & WPAD_BUTTON_B) - { - if (QuestScreen && OnItemScreen) - { - if (StartCount>=0) StartCount = -80; - } - else - { - if (OnItemScreen) - { - /*if (BombArrows) { - if (SelItem==5) { // bow - } else { - BombArrows = false; - } - }*/ - systemGameRumble(5); - DelayCount = 10; - } - else - { - u8 BButtonItem = gbReadMemory(0xDB00); - if (BombArrows && (BButtonItem==5)) - { - if (ZeldaDxDrawBombs()) - { - J |= VBA_BUTTON_A; - DelayCount++; - } - } - else DelayCount = 10; - } - if (DelayCount>1) - J |= VBA_BUTTON_B; - } - } - else DelayCount = 0; - - // Items - if (wp->btns_h & WPAD_BUTTON_MINUS) - { - if (QuestScreen) QuestScreen = false; - else J |= VBA_BUTTON_START; - } - // Quest - if (wp->btns_h & WPAD_BUTTON_PLUS) - { - StartCount = 80; - if (OnItemScreen) StartCount = -StartCount; - } - if (StartCount>0) - { - if (StartCount>75) - J |= VBA_BUTTON_START; - StartCount--; - if (StartCount==0) QuestScreen = true; - } - else if (StartCount<0) - { - QuestScreen = false; - if (StartCount>=-5) - J |= VBA_BUTTON_START; - StartCount++; - } - if (QuestScreen && OnItemScreen) - J |= VBA_BUTTON_SELECT; - - // Map - if (wp->btns_h & WPAD_BUTTON_1) - { - QuestScreen = false; - J |= VBA_BUTTON_SELECT; - } - - // Cheat - if (wp->btns_h & WPAD_BUTTON_2) - { - ZeldaDxCheat(); - QuestScreen = false; - } - - // Z Button uses shield - if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) && !OnItemScreen) - { - if (!SwordCount) - { - if (ZeldaDxDrawShield()) - J |= VBA_BUTTON_A; - } - QuestScreen = false; - } - // Z Button Selects bomb arrows on or off - if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) && OnItemScreen) - { - if (SelItem==2 || SelItem==5) - { // toggle bomb arrows - BombArrows = !BombArrows; - if (BombArrows) systemGameRumbleOnlyFor(16); - else systemGameRumbleOnlyFor(4); - if (SelItem==2 && BombArrows) - J |= VBA_BUTTON_A; - } - else if (BombArrows) - { // switch off bomb arrows - BombArrows = false; - systemGameRumbleOnlyFor(4); - J |= VBA_BUTTON_A; - } - QuestScreen = false; - } - // Camera (fast forward) - if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_C)) - { - J |= VBA_SPEED; - QuestScreen = false; - } - - return J; -} - -u32 OracleOfAgesInput(unsigned short pad) -{ - u32 J = StandardMovement(pad); - u32 jp = PAD_ButtonsHeld(pad); - //static u8 SubscreenWanted = 0xFF; - //static bool waiting = false; - u8 Health = 0; - static u8 OldHealth = 0; - //static u8 AButtonItem = 0; - //static u8 BButtonItem = 0; - //static int frame = 0; - u32 SwordButton = 0; - u32 ZTargetButton = 0; - //if (AButtonItem<=6 && AButtonItem>=1) SwordButton = VBA_BUTTON_A; - //else if (BButtonItem<=6 && BButtonItem>=1) SwordButton = VBA_BUTTON_B; - //else SwordButton = VBA_BUTTON_START; - SwordButton = VBA_BUTTON_B; - // Shield - //if (BButtonItem>=0xD && BButtonItem<=0xE) ZTargetButton = VBA_BUTTON_B; - //else if (AButtonItem>=0xD && AButtonItem<=0xE) ZTargetButton = VBA_BUTTON_A; - ZTargetButton = VBA_BUTTON_A; - - // Rumble when they lose health! - if (Health < OldHealth) - systemGameRumble(20); - OldHealth = Health; - - WPADData * wp = WPAD_Data(pad); - - // Talk to Midna, er... I mean nobody - if (wp->btns_h & WPAD_BUTTON_UP) - J |= 0; - - // Right Item - if (wp->btns_h & WPAD_BUTTON_RIGHT) - { - J |= VBA_BUTTON_A; - } - // Down Item - if (wp->btns_h & WPAD_BUTTON_DOWN) - { - J |= VBA_BUTTON_B; - } - // Action - if (wp->btns_h & WPAD_BUTTON_A) - J |= VBA_BUTTON_A; - // Kinstone (doesn't work) - if (wp->btns_h & WPAD_BUTTON_LEFT) - J |= VBA_BUTTON_L; - // Menu - if (wp->btns_h & WPAD_BUTTON_2) - J |= VBA_BUTTON_START; - // Map - if (wp->btns_h & WPAD_BUTTON_1) - J |= VBA_BUTTON_SELECT; - // Quest - if (wp->btns_h & WPAD_BUTTON_PLUS) - J |= VBA_BUTTON_START; - // Items - if (wp->btns_h & WPAD_BUTTON_MINUS) - J |= VBA_BUTTON_START; - // Sword - if (fabs(wp->gforce.x)> 1.5) - J |= SwordButton; - // Z-Targetting - if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z)) - J |= ZTargetButton; - // Camera (fast forward) - if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_C)) - J |= VBA_SPEED; - - // Menu - if (jp & PAD_BUTTON_START) - J |= VBA_BUTTON_START; - // Inventory - if (jp & PAD_BUTTON_UP) - J |= VBA_BUTTON_START; - // Map - if (jp & PAD_BUTTON_RIGHT) - J |= VBA_BUTTON_SELECT; - // Kinstone - if (jp & PAD_BUTTON_LEFT) - J |= VBA_BUTTON_L; - // Action - if (jp & PAD_BUTTON_A) - J |= VBA_BUTTON_A; - if (jp & PAD_TRIGGER_R) - J |= VBA_BUTTON_A; - // Sword - if (jp & PAD_BUTTON_B) - J |= SwordButton; - // Right Item - if (jp & PAD_BUTTON_X) - J |= VBA_BUTTON_A; - // left Item - if (jp & PAD_BUTTON_Y) - J |= VBA_BUTTON_B; - // Talk to Midna, er... I mean... - if (jp & PAD_TRIGGER_Z) - J |= VBA_BUTTON_SELECT; - // Z-Targetting - if (jp & PAD_TRIGGER_L) - J |= ZTargetButton; - - return J; -} - -u32 MinishCapInput(unsigned short pad) -{ - u32 J = StandardMovement(pad); - u32 jp = PAD_ButtonsHeld(pad); - WPADData * wp = WPAD_Data(pad); - static u8 SubscreenWanted = 0xFF; - static bool waiting = false; - u8 Subscreen = CPUReadByte(0x200008C); - if (Subscreen == 0x64) - Subscreen = 0; // Boss battle (balloon) - - u8 RButtonAction = CPUReadByte(0x200af32); - u8 GameStart = CPUReadByte(0x2000086); - - u8 SelBox = CPUReadByte(0x2000083); - u8 Health = CPUReadByte(0x2002aea); - u8 LoadMenu = CPUReadByte(0x200AF57); - static u8 OldHealth = 0; - static u8 AButtonItem = 0; - static u8 BButtonItem = 0; - if (Subscreen == 0x2c) - { - AButtonItem = CPUReadByte(0x200af3c); - BButtonItem = CPUReadByte(0x200af5c); - } - else if (Subscreen == 0) - { - AButtonItem = CPUReadByte(0x200af5c); - BButtonItem = CPUReadByte(0x200af7c); - } - static int frame = 0; - u32 SwordButton = 0; - u32 ZTargetButton = 0; - if (AButtonItem <= 6 && AButtonItem >= 1) - SwordButton = VBA_BUTTON_A; - else if (BButtonItem <= 6 && BButtonItem >= 1) - SwordButton = VBA_BUTTON_B; - else - SwordButton = VBA_BUTTON_START; - // Shield - if (BButtonItem >= 0xD && BButtonItem <= 0xE) - ZTargetButton = VBA_BUTTON_B; - else if (AButtonItem >= 0xD && AButtonItem <= 0xE) - ZTargetButton = VBA_BUTTON_A; - // Gust Jar also does Z targetting - else if (BButtonItem == 0x11) - ZTargetButton = VBA_BUTTON_B; - else if (AButtonItem == 0x11) - ZTargetButton = VBA_BUTTON_A; - else - ZTargetButton = 0; - - // Rumble when they lose health! - if (Health < OldHealth) - systemGameRumble(20); - OldHealth = Health; - - int cx, cy, SelRow, SelCol, CursorRow = 0xFF, CursorCol = 0xFF; - static int OldCursorRow = 0xFF; - static int OldCursorCol = 0xFF; - CursorVisible = ((Subscreen != 0 && Subscreen != 0x64) || LoadMenu == 2); - if (CursorVisible) - { - cx = (CursorX * 240) / 640; - cy = (CursorY * 160) / 480; - } - else - { - cx = -1; - cy = -1; - } - // Wii Pointer selection on item screen - if (Subscreen == 0x2c) - { - SelRow = SelBox / 4; - SelCol = SelBox % 4; - if (SelBox == 16) - { - SelRow = 3; - SelCol = 4; - } - else if (SelRow < 3 && SelCol >= 2) - SelCol++; - if (cy >= 35 && cy <= 55) - CursorRow = 0; - else if (cy >= 59 && cy <= 79) - CursorRow = 1; - else if (cy >= 83 && cy <= 103) - CursorRow = 2; - else if (cy >= 107 && cy <= 127) - CursorRow = 3; - else - CursorRow = 0xFF; - if (CursorRow < 3) - { - if (cx >= 52 && cx <= 79) - CursorCol = 0; - else if (cx >= 88 && cx <= 116) - CursorCol = 1; - else if (cx >= 124 && cx <= 152) - CursorCol = 3; - else if (cx >= 160 && cx <= 188) - CursorCol = 4; - else - CursorCol = 0xFF; - } - else - { - if (cx >= 157 && cx <= 204) - CursorCol = 4; - else if (cx >= 52 && cx < 152) - CursorCol = (cx - 52) / 25; - else - CursorCol = 0xFF; - } - if (CursorCol != 0xFF && CursorRow != 0xFF && (CursorCol != SelCol - || CursorRow != SelRow)) - { - if (CursorCol > SelCol) - J |= VBA_RIGHT; - else if (CursorCol < SelCol) - J |= VBA_LEFT; - else if (CursorRow > SelRow) - J |= VBA_DOWN; - else if (CursorRow < SelRow) - J |= VBA_UP; - } - } - else if (Subscreen == 0x38) - { - switch (SelBox) - { - case 0: - case 1: - case 10: - case 9: - case 11: - SelRow = 0; - break; - case 12: - SelRow = 1; - break; - case 2: - case 3: - case 13: - case 14: - case 15: - SelRow = 2; - break; - case 6: - case 7: - case 8: - case 4: - case 5: - SelRow = 3; - break; - default: - SelRow = 0xFF; - break; - } - switch (SelBox) - { - case 0: - case 2: - case 6: - SelCol = 0; - break; - case 7: - SelCol = 1; - break; - case 1: - case 3: - case 8: - SelCol = 2; - break; - case 10: - case 13: - case 4: - SelCol = 3; - break; - case 9: - case 12: - case 14: - SelCol = 4; - break; - case 11: - case 15: - case 5: - SelCol = 5; - break; - default: - SelCol = 0xFF; - break; - } - if (cy >= 109 && cy <= 130) - { - CursorRow = 3; - if (cx >= 36 && cx <= 113) - CursorCol = (cx - 36) / 26; - else if (cx >= 118 && cx <= 165) - CursorCol = 3; - else if (cx >= 168 && cx <= 215) - CursorCol = 5; - else - CursorCol = 0xFF; - } - else - { - if (cx >= 35 && cx <= 70) - { - CursorCol = 0; - if (cy >= 40 && cy <= 73) - CursorRow = 0; - else if (cy >= 79 && cy <= 104) - CursorRow = 2; - else - CursorRow = 0xFF; - } - else if (cx >= 78 && cx <= 113) - { - CursorCol = 2; - if (cy >= 40 && cy <= 73) - CursorRow = 0; - else if (cy >= 79 && cy <= 104) - CursorRow = 2; - else - CursorRow = 0xFF; - } - else - { - if (cx >= 125 && cx <= 148) - { - CursorCol = 3; - if (cy >= 44 && cy <= 65) - CursorRow = 0; - else if (cy >= 83 && cy <= 104) - CursorRow = 2; - else - CursorRow = 0xFF; - } - else if (cx >= 151 && cx <= 172) - { - CursorCol = 4; - if (cy >= 31 && cy <= 53) - CursorRow = 0; - else if (cy >= 57 && cy <= 78) - CursorRow = 1; - else if (cy >= 83 && cy <= 104) - CursorRow = 2; - else - CursorRow = 0xFF; - } - else if (cx >= 175 && cx <= 198) - { - CursorCol = 5; - if (cy >= 44 && cy <= 65) - CursorRow = 0; - else if (cy >= 83 && cy <= 104) - CursorRow = 2; - else - CursorRow = 0xFF; - } - else - { - CursorCol = 0xFF; - CursorRow = 0xFF; - } - } - } - - if (CursorCol != 0xFF && CursorRow != 0xFF && (CursorCol != SelCol - || CursorRow != SelRow)) - { - if (CursorCol > SelCol) - J |= VBA_RIGHT; - else if (CursorCol < SelCol) - J |= VBA_LEFT; - else if (CursorRow > SelRow) - J |= VBA_DOWN; - else if (CursorRow < SelRow) - J |= VBA_UP; - } - } - if ((CursorRow == 0xFF || CursorCol == 0xFF) && (OldCursorRow == 0xFF - || OldCursorCol == 0xFF)) - { - // no change, still not pointing at anything - } - else if (CursorVisible && (CursorRow != OldCursorRow || CursorCol - != OldCursorCol)) - { - // Cursor changed buttons, so rumble - systemGameRumble(5); - } - OldCursorRow = CursorRow; - OldCursorCol = CursorCol; - - if (wp->btns_h & WPAD_BUTTON_MINUS) - { // items - if (Subscreen == 0x2c) SubscreenWanted = 0; - else SubscreenWanted = 0x2c; - waiting = false; - } - else if (wp->btns_h & WPAD_BUTTON_1) - { // map - if (Subscreen == 0x0c || Subscreen==0x70) SubscreenWanted = 0; - else SubscreenWanted = 0x0c; - waiting = false; - } - else if (wp->btns_h & WPAD_BUTTON_PLUS) - { // quest - if (Subscreen == 0x38) SubscreenWanted = 0; - else SubscreenWanted = 0x38; - waiting = false; - } - else if (wp->btns_h & WPAD_BUTTON_A && Subscreen == 0x2c && SelBox!=16) - { - SubscreenWanted = 0; - waiting = false; - } - else if (wp->btns_h & WPAD_BUTTON_B && Subscreen == 0x38) - { - SubscreenWanted = 0; - waiting = false; - } - if (GameStart==2 || GameStart==3) - { - SubscreenWanted = 0; - waiting = false; - if (wp->btns_h & WPAD_BUTTON_PLUS || (wp->btns_h & WPAD_BUTTON_A && wp->btns_h & WPAD_BUTTON_B)) - J |= VBA_BUTTON_START; - return J; - } - else if (LoadMenu==2) - { - if (wp->btns_h & WPAD_BUTTON_UP) - J |= VBA_UP; - if (wp->btns_h & WPAD_BUTTON_DOWN) - J |= VBA_DOWN; - if (wp->btns_h & WPAD_BUTTON_LEFT) - J |= VBA_LEFT; - if (wp->btns_h & WPAD_BUTTON_RIGHT) - J |= VBA_RIGHT; - if (wp->btns_h & WPAD_BUTTON_A) - J |= VBA_BUTTON_A; - if (wp->btns_h & WPAD_BUTTON_B) - J |= VBA_BUTTON_B; - - if (wp->btns_h & WPAD_BUTTON_PLUS) - J |= VBA_BUTTON_R; - if (wp->btns_h & WPAD_BUTTON_MINUS) - J |= VBA_BUTTON_L; - if (wp->btns_h & WPAD_BUTTON_1) - J |= VBA_BUTTON_SELECT; - if (wp->btns_h & WPAD_BUTTON_2) - J |= VBA_BUTTON_START; - if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_C)) - J |= VBA_BUTTON_SELECT; - if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z)) - J |= VBA_BUTTON_START; - return J; - } - - //sprintf(DebugStr, "%f A=%02x B=%02x R=%02x s%02x,%02x, wait=%d", fabs(data.exp.nunchuk.gforce.x), AButtonItem, BButtonItem, RButtonAction, Subscreen, SubscreenWanted, waiting); - - //0c = map - //70 = dungeon map - //38 = quest - //2c = items - //89 = KINSTONE PIECES - //f0 = SWORD TECHNIQUES - //00 = none or changing or save - //64 = Boss battle (balloon thing) - //FF = don't care! - //; - if (Subscreen == 0x70 && SubscreenWanted == 0x0c) - { - SubscreenWanted = 0xFF; - waiting = false; - } - - if (Subscreen != SubscreenWanted && SubscreenWanted != 0xFF) - { - frame++; - if (frame % 2 == 0) - switch (Subscreen) - { - case 0: - frame = 0; - if (!waiting) - { - waiting = true; - //waittime = - J |= VBA_BUTTON_START; - } - break; - case 0x0c: // map - case 0x70: - if (SubscreenWanted == 0x38) - J |= VBA_BUTTON_L; // quest - else if (SubscreenWanted == 0x2c) - J |= VBA_BUTTON_R; // items - else - J |= VBA_BUTTON_START; - waiting = false; - break; - case 0x2c: // items - if (SubscreenWanted == 0x0c || SubscreenWanted == 0x70) - J |= VBA_BUTTON_L; // map - else if (SubscreenWanted == 0x38) - J |= VBA_BUTTON_R; // quest - else - J |= VBA_BUTTON_START; - waiting = false; - break; - case 0x38: // quest - if (SubscreenWanted == 0x2c) - J |= VBA_BUTTON_L; // map - else if (SubscreenWanted == 0x0c || SubscreenWanted == 0x70) - J |= VBA_BUTTON_R; // quest - else - J |= VBA_BUTTON_START; - // CAKTODO: kinstone and sword techniques - waiting = false; - break; - case 0x89: // kinstone - case 0xF0: // sword techniques - J |= VBA_BUTTON_B; // cancel - waiting = false; - break; - - } - } - else - { - SubscreenWanted = 0xFF; - waiting = false; - } - - /*** Report wp->btns_h buttons (gamepads) ***/ - - // Talk to Midna, er... I mean Ezlo - if (wp->btns_h & WPAD_BUTTON_UP) - J |= VBA_BUTTON_SELECT; - - // Save button - if ((Subscreen==0x2c && SelBox==16) || (Subscreen==0x38 && SelBox==5)) - { - if (wp->btns_h & WPAD_BUTTON_A) - { - J |= VBA_BUTTON_A; - systemGameRumble(12); - } - } - else if (Subscreen==0x2c) - { - } - else if (Subscreen==0x38 && SelBox==4) - { // Sleep button returns to menu instead of sleep - if (wp->btns_h & WPAD_BUTTON_A) - { - ConfigRequested = 1; - return 0; - } - } - else - { - // Action - if (wp->btns_h & WPAD_BUTTON_A) - J |= VBA_BUTTON_R; - if (RButtonAction==0x03 && (wp->exp.type == WPAD_EXP_NUNCHUK)) - { - if (fabs(wp->exp.nunchuk.gforce.y)> 0.6) - { - J |= VBA_BUTTON_R; - systemGameRumble(5); - } - } - else if (wp->exp.type == WPAD_EXP_NUNCHUK) - { - if (fabs(wp->exp.nunchuk.gforce.x)> 0.6) - { // Wiiuse bug!!! Not correct values - J |= SwordButton; - systemGameRumble(20); - } - // CAKTODO hold down attack button to do spin attack - - } - } - // Right Item - if (wp->btns_h & WPAD_BUTTON_RIGHT) - { - J |= VBA_BUTTON_A; - if (Subscreen==0x2c) - { - systemGameRumble(10); - } - } - // Down Item - if (Subscreen==0x38) - { - } - else - { - if (wp->btns_h & WPAD_BUTTON_B) - { - J |= VBA_BUTTON_B; - if (Subscreen==0x2c) - { - systemGameRumble(10); - } - } - } - if (wp->btns_h & WPAD_BUTTON_DOWN) - { - J |= VBA_BUTTON_B; - if (Subscreen==0x2c) - { - systemGameRumble(10); - } - } - // Kinstone (doesn't work in items screen) - if (wp->btns_h & WPAD_BUTTON_LEFT && Subscreen != 0x2c) - J |= VBA_BUTTON_L; - // Menu - if (wp->btns_h & WPAD_BUTTON_2) - J |= VBA_BUTTON_START; - // Sword - if (Subscreen == 0 && fabs(wp->gforce.x)> 1.5) - J |= SwordButton; - // Z-Targetting - if (Subscreen==0 && (wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z)) - J |= ZTargetButton; - // Camera (use as extra way of pressing A without using DPad) - if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_C)) - J |= VBA_BUTTON_A; - - // Menu - if (jp & PAD_BUTTON_START) - J |= VBA_BUTTON_START; - // Inventory - if (jp & PAD_BUTTON_UP) - J |= VBA_BUTTON_START; - // Map - if (jp & PAD_BUTTON_RIGHT) - J |= VBA_BUTTON_START; - // Kinstone - if (jp & PAD_BUTTON_LEFT) - J |= VBA_BUTTON_L; - // Action - if (jp & PAD_BUTTON_A) - J |= VBA_BUTTON_R; - if (jp & PAD_TRIGGER_R) - J |= VBA_BUTTON_R; - // Sword - if (jp & PAD_BUTTON_B) - J |= VBA_BUTTON_B; - // Right Item - if (jp & PAD_BUTTON_X) - J |= VBA_BUTTON_A; - // left Item - if (jp & PAD_BUTTON_Y) - J |= VBA_BUTTON_B; - // Talk to Midna, er... I mean Ezlo - if (jp & PAD_TRIGGER_Z) - J |= VBA_BUTTON_SELECT; - // Z-Targetting - if (jp & PAD_TRIGGER_L) - J |= VBA_BUTTON_A; - - return J; -} - -u32 ALinkToThePastInput(unsigned short pad) -{ - u32 J = StandardMovement(pad); - u8 Health = 0; - static u8 OldHealth = 0; - - // Rumble when they lose health! - if (Health < OldHealth) - systemGameRumble(20); - OldHealth = Health; - - WPADData * wp = WPAD_Data(pad); - - // Talk to Midna, er... I mean ... nobody - if (wp->btns_h & WPAD_BUTTON_UP) - J |= VBA_BUTTON_START; - - // Action - if (wp->btns_h & WPAD_BUTTON_A) - J |= VBA_BUTTON_R; - if (wp->exp.type == WPAD_EXP_NUNCHUK) - { - if (fabs(wp->exp.nunchuk.gforce.x)> 0.6) - { // Wiiuse bug!!! Not correct values - J |= VBA_BUTTON_B; - systemGameRumble(20); - } - // CAKTODO hold down attack button to do spin attack - - } - // Use item - if (wp->btns_h & WPAD_BUTTON_B) - { - J |= VBA_BUTTON_A; - } - if (wp->btns_h & WPAD_BUTTON_LEFT) - { - J |= VBA_BUTTON_A; - } - if (wp->btns_h & WPAD_BUTTON_RIGHT) - { - J |= VBA_BUTTON_A; - } - if (wp->btns_h & WPAD_BUTTON_DOWN) - { - J |= VBA_BUTTON_A; - } - // Menu (like Quest Status) - if (wp->btns_h & WPAD_BUTTON_PLUS) - J |= VBA_BUTTON_START; - // Items - if (wp->btns_h & WPAD_BUTTON_MINUS) - J |= VBA_BUTTON_SELECT; - // Map - if (wp->btns_h & WPAD_BUTTON_1) - J |= VBA_BUTTON_L; - // Sword - if (fabs(wp->gforce.x)> 1.5) - J |= VBA_BUTTON_B; - if (wp->btns_h & WPAD_BUTTON_2) - J |= VBA_BUTTON_B; - // Shield has no controls - // Camera (speed) - if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_C)) - J |= VBA_SPEED; - - return J; -} - -u32 Zelda1Input(unsigned short pad) -{ - u32 J = StandardMovement(pad); - u8 Health = 0; - static u8 OldHealth = 0; - - // Rumble when they lose health! - if (Health < OldHealth) - systemGameRumble(20); - OldHealth = Health; - - WPADData * wp = WPAD_Data(pad); - - // Talk to Midna, er... I mean ... nobody - if (wp->btns_h & WPAD_BUTTON_UP) - J |= 0; - - // Action - if (wp->btns_h & WPAD_BUTTON_A) - J |= VBA_BUTTON_A; - if (wp->exp.type == WPAD_EXP_NUNCHUK) - { - if (fabs(wp->exp.nunchuk.gforce.x)> 0.6) - { // Wiiuse bug!!! Not correct values - J |= VBA_BUTTON_A; - systemGameRumble(20); - } - } - // Use item - if (wp->btns_h & WPAD_BUTTON_B) - { - J |= VBA_BUTTON_B; - } - if (wp->btns_h & WPAD_BUTTON_LEFT) - { - J |= VBA_BUTTON_B; - } - if (wp->btns_h & WPAD_BUTTON_RIGHT) - { - J |= VBA_BUTTON_A; - } - if (wp->btns_h & WPAD_BUTTON_DOWN) - { - J |= VBA_BUTTON_B; - } - // Menu (like Quest Status) - if (wp->btns_h & WPAD_BUTTON_PLUS) - J |= VBA_BUTTON_SELECT; - // Items - if (wp->btns_h & WPAD_BUTTON_MINUS) - J |= VBA_BUTTON_START; - // Map - if (wp->btns_h & WPAD_BUTTON_1) - J |= 0; - // Sword - if (fabs(wp->gforce.x)> 1.5) - J |= VBA_BUTTON_A; - // Shield has no controls - // Camera (speed) - if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_C)) - J |= VBA_SPEED; - - return J; -} - -u32 Zelda2Input(unsigned short pad) -{ - u32 J = StandardMovement(pad); - u8 Health = 0; - static u8 OldHealth = 0; - - // Rumble when they lose health! - if (Health < OldHealth) - systemGameRumble(20); - OldHealth = Health; - - WPADData * wp = WPAD_Data(pad); - - // Talk to Midna, er... I mean ... nobody - if (wp->btns_h & WPAD_BUTTON_UP) - J |= 0; - - // Jump - if (wp->btns_h & WPAD_BUTTON_A) - J |= VBA_BUTTON_A; - // spin attack - if (wp->exp.type == WPAD_EXP_NUNCHUK) - { - if (fabs(wp->exp.nunchuk.gforce.x)> 0.6) - { // Wiiuse bug!!! Not correct values - J |= VBA_BUTTON_B; - systemGameRumble(20); - } - } - // Use item - if (wp->btns_h & WPAD_BUTTON_B) - { - J |= VBA_BUTTON_SELECT; - } - if (wp->btns_h & WPAD_BUTTON_LEFT) - { - J |= VBA_BUTTON_SELECT; - } - if (wp->btns_h & WPAD_BUTTON_RIGHT) - { - J |= VBA_BUTTON_SELECT; - } - if (wp->btns_h & WPAD_BUTTON_DOWN) - { - J |= VBA_BUTTON_SELECT; - } - // Menu (like Quest Status) - if (wp->btns_h & WPAD_BUTTON_PLUS) - J |= VBA_BUTTON_START; - // Items - if (wp->btns_h & WPAD_BUTTON_MINUS) - J |= VBA_BUTTON_START; - // Map - if (wp->btns_h & WPAD_BUTTON_1) - J |= 0; - // Sword - if (fabs(wp->gforce.x)> 1.5) - J |= VBA_BUTTON_B; - // No shield control, just duck - if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z)) - J |= VBA_DOWN; - // Camera (speed) - if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_C)) - J |= VBA_SPEED; - - - return J; -} - -u32 MK1Input(unsigned short pad) -{ +u32 MK1Input(unsigned short pad) { u32 J = StandardMovement(pad); u8 Health = gbReadMemory(0xc695); static u8 OldHealth = 0; @@ -1260,6 +50,7 @@ u32 MK1Input(unsigned short pad) systemGameRumble(5); OldHealth = Health; +#ifdef HW_RVL WPADData * wp = WPAD_Data(pad); // Punch @@ -1286,6 +77,7 @@ u32 MK1Input(unsigned short pad) // CAKTODO } +#endif return J; } @@ -1300,6 +92,7 @@ u32 MK4Input(unsigned short pad) systemGameRumble(20); OldHealth = Health; +#ifdef HW_RVL WPADData * wp = WPAD_Data(pad); // Punch @@ -1325,6 +118,7 @@ u32 MK4Input(unsigned short pad) { // CAKTODO } +#endif return J; } @@ -1340,6 +134,7 @@ u32 MKAInput(unsigned short pad) systemGameRumble(20); OldHealth = Health; +#ifdef HW_RVL WPADData * wp = WPAD_Data(pad); // Punch @@ -1365,6 +160,7 @@ u32 MKAInput(unsigned short pad) { // CAKTODO } +#endif return J; } @@ -1373,6 +169,7 @@ u32 MKTEInput(unsigned short pad) { static u32 prevJ = 0, prevPrevJ = 0; u32 J = StandardMovement(pad); +#ifdef HW_RVL WPADData * wp = WPAD_Data(pad); u8 Health; u8 Side; @@ -1440,15 +237,14 @@ u32 MKTEInput(unsigned short pad) if (wp->btns_h & WPAD_BUTTON_PLUS) J |= VBA_BUTTON_START; // Special move - if (wp->btns_h & WPAD_BUTTON_B) - { + if (wp->btns_h & WPAD_BUTTON_B) { // CAKTODO } // Speed - if (wp->btns_h & WPAD_BUTTON_1 || wp->btns_h & WPAD_BUTTON_2) - { + if (wp->btns_h & WPAD_BUTTON_1 || wp->btns_h & WPAD_BUTTON_2) { J |= VBA_SPEED; } +#endif if ((J & 48) == 48) J &= ~16; @@ -1460,155 +256,26 @@ u32 MKTEInput(unsigned short pad) return J; } -u32 MarioKartInput(unsigned short pad) -{ - u32 J = StandardMovement(pad); - u32 jp = PAD_ButtonsHeld(pad); - WPADData * wp = WPAD_Data(pad); - static u32 frame = 0; - +u32 LegoStarWars1Input(unsigned short pad) { + u32 J = StandardMovement(pad) | DecodeGamecube(pad) | DecodeKeyboard(pad); + // Rumble when they lose health! u8 Health = 0; static u8 OldHealth = 0; - float fraction; - - // Rumble when they lose health! - if (Health < OldHealth) - systemGameRumble(20); - OldHealth = Health; - - // Start/Select - if (wp->btns_h & WPAD_BUTTON_PLUS) - J |= VBA_BUTTON_START; - if (wp->btns_h & WPAD_BUTTON_MINUS) - J |= VBA_BUTTON_SELECT; - - if (wp->exp.type == WPAD_EXP_NONE) - { - // Use item - if (wp->btns_h & WPAD_BUTTON_RIGHT) - { - J |= VBA_BUTTON_L | VBA_UP; - J &= ~VBA_DOWN; - } - else if (wp->btns_h & WPAD_BUTTON_LEFT) - { - J |= VBA_BUTTON_L | VBA_DOWN; - J &= ~VBA_UP; - } - else if (wp->btns_h & WPAD_BUTTON_UP || wp->btns_h & WPAD_BUTTON_DOWN) - J |= VBA_BUTTON_L; - // Accelerate - if (wp->btns_h & WPAD_BUTTON_2) - J |= VBA_BUTTON_A; - // Brake - if (wp->btns_h & WPAD_BUTTON_1) - J |= VBA_BUTTON_B; - // Jump/Power slide - if (wp->btns_h & WPAD_BUTTON_A) - J |= VBA_BUTTON_R; - if (wp->btns_h & WPAD_BUTTON_B) - J |= VBA_BUTTON_R; - if (wp->orient.pitch> 12) - { - fraction = (wp->orient.pitch - 12)/60.0f; - if ((frame % 60)/60.0f < fraction) - J |= VBA_LEFT; - } - else if (wp->orient.pitch <- 12) - { - fraction = -(wp->orient.pitch + 10)/60.0f; - if ((frame % 60)/60.0f < fraction) - J |= VBA_RIGHT; - } - - } - else if (wp->exp.type == WPAD_EXP_NUNCHUK) - { - // Use item - if (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) - J |= VBA_BUTTON_L; - // Accelerate - if (wp->btns_h & WPAD_BUTTON_A) - J |= VBA_BUTTON_A; - // Brake - if (wp->btns_h & WPAD_BUTTON_B) - J |= VBA_BUTTON_B; - // Jump - if (fabs(wp->gforce.y)> 1.5 ) - J |= VBA_BUTTON_R; - if (wp->btns_h & WPAD_BUTTON_UP || wp->btns_h & WPAD_BUTTON_LEFT || wp->btns_h & WPAD_BUTTON_RIGHT || wp->btns_h & WPAD_BUTTON_DOWN) - J |= VBA_BUTTON_R; - } - else if (wp->exp.type == WPAD_EXP_CLASSIC) - { - // Use item - if (wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_L) - J |= VBA_BUTTON_L; - // Accelerate - if (wp->btns_h & WPAD_CLASSIC_BUTTON_A) - J |= VBA_BUTTON_A; - // Brake - if (wp->btns_h & WPAD_BUTTON_B) - J |= VBA_BUTTON_B; - // Jump - if (wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_R) - J |= VBA_BUTTON_R; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_UP || wp->btns_h & WPAD_CLASSIC_BUTTON_LEFT || wp->btns_h & WPAD_CLASSIC_BUTTON_RIGHT || wp->btns_h & WPAD_CLASSIC_BUTTON_DOWN) - J |= VBA_BUTTON_R; - // Start/Select - if (wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS) - J |= VBA_BUTTON_START; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS) - J |= VBA_BUTTON_SELECT; - } - - - if (jp & PAD_BUTTON_START) - J |= VBA_BUTTON_START; - if (jp & PAD_BUTTON_X || jp & PAD_BUTTON_Y) - J |= VBA_BUTTON_SELECT; - if (jp & PAD_BUTTON_A) - J |= VBA_BUTTON_A; - if (jp & PAD_BUTTON_B) - J |= VBA_BUTTON_B; - if (jp & PAD_TRIGGER_L) - J |= VBA_BUTTON_L; - if (jp & PAD_TRIGGER_R) - J |= VBA_BUTTON_R; - if (jp & PAD_BUTTON_UP || jp & PAD_BUTTON_DOWN || jp & PAD_BUTTON_LEFT - || jp & PAD_BUTTON_RIGHT) - J |= VBA_BUTTON_R; - - frame++; - - return J; -} - -u32 LegoStarWars1Input(unsigned short pad) -{ - u32 J = StandardMovement(pad); - - u8 Health = 0; - static u8 OldHealth = 0; - - // Rumble when they lose health! if (Health < OldHealth) systemGameRumble(20); OldHealth = Health; +#ifdef HW_RVL WPADData * wp = WPAD_Data(pad); // Start/Select if (wp->btns_h & WPAD_BUTTON_PLUS) J |= VBA_BUTTON_START; - if (wp->exp.type == WPAD_EXP_NONE) - { + if (wp->exp.type == WPAD_EXP_NONE) { // CAKTODO - J |= StandardSideways(pad); - } - else if (wp->exp.type == WPAD_EXP_NUNCHUK) - { + J |= DecodeWiimote(pad); + } else if (wp->exp.type == WPAD_EXP_NUNCHUK) { // build, use force if (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) J |= VBA_BUTTON_L; @@ -1629,42 +296,32 @@ u32 LegoStarWars1Input(unsigned short pad) J |= VBA_BUTTON_R; if (wp->btns_h & WPAD_BUTTON_1 || wp->btns_h & WPAD_BUTTON_2) J |= VBA_SPEED; - } - else if (wp->exp.type == WPAD_EXP_CLASSIC) - { - // CAKTODO same as game boy for now - J |= StandardClassic(pad); - } - - // CAKTODO same as game boy for now - J |= StandardGamecube(pad) | StandardKeyboard(pad); - + } else if (wp->exp.type == WPAD_EXP_CLASSIC) { + J |= DecodeClassic(pad); + } else J |= DecodeWiimote(pad); +#endif return J; } -u32 LegoStarWars2Input(unsigned short pad) -{ - u32 J = StandardMovement(pad); +u32 LegoStarWars2Input(unsigned short pad) { + u32 J = StandardMovement(pad) | DecodeGamecube(pad) | DecodeKeyboard(pad); + // Rumble when they lose health! u8 Health = 0; static u8 OldHealth = 0; - - // Rumble when they lose health! if (Health < OldHealth) systemGameRumble(20); OldHealth = Health; +#ifdef HW_RVL WPADData * wp = WPAD_Data(pad); // Start/Select if (wp->btns_h & WPAD_BUTTON_PLUS) J |= VBA_BUTTON_START; - if (wp->exp.type == WPAD_EXP_NONE) - { - J |= StandardSideways(pad); - } - else if (wp->exp.type == WPAD_EXP_NUNCHUK) - { + if (wp->exp.type == WPAD_EXP_NONE) { + J |= DecodeWiimote(pad); + } else if (wp->exp.type == WPAD_EXP_NUNCHUK) { // build, force transform, pull lever if (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) J |= VBA_BUTTON_R; @@ -1689,763 +346,170 @@ u32 LegoStarWars2Input(unsigned short pad) if (wp->btns_h & WPAD_BUTTON_1 || wp->btns_h & WPAD_BUTTON_2) J |= VBA_SPEED; + } else if (wp->exp.type == WPAD_EXP_CLASSIC) { + J |= DecodeClassic(pad); } - else if (wp->exp.type == WPAD_EXP_CLASSIC) - { - // CAKTODO same as game boy for now - J |= StandardClassic(pad); - } - - // CAKTODO same as game boy for now - J |= StandardGamecube(pad) | StandardKeyboard(pad); - +#endif return J; } -u32 MetroidZeroInput(unsigned short pad) -{ - u32 J = StandardMovement(pad); - u32 jp = PAD_ButtonsHeld(pad); - u8 BallState = CPUReadByte(0x30015df); // 0 = stand, 1 = crouch, 2 = ball - u16 Health = CPUReadByte(0x3001536); // 0 = stand, 1 = crouch, 2 = ball - static u16 OldHealth = 0; - - // Rumble when they lose health! - if (Health < OldHealth) - systemGameRumble(20); - OldHealth = Health; - - static int Morph = 0; - static int AimCount = 0; - static int MissileCount = 0; - - if (BallState == 2) // Can't exit morph ball without pressing C! - J &= ~VBA_UP; - if (BallState == 1) // Can't enter morph ball without pressing C! - J &= ~VBA_DOWN; +u32 TMNTInput(unsigned short pad) { + u32 J = StandardMovement(pad) | StandardDPad(pad) | DecodeClassic(pad) | DecodeKeyboard(pad) | DecodeGamecube(pad); + static u32 LastDir = VBA_RIGHT; + static bool wait = false; + static int holdcount = 0; + bool Jump=0, Attack=0, SpinKick=0, Roll=0, Pause=0, Select=0; +#ifdef HW_RVL WPADData * wp = WPAD_Data(pad); + if (wp->exp.type == WPAD_EXP_NUNCHUK) { + Jump = (wp->btns_h & WPAD_BUTTON_A); + Attack = (fabs(wp->gforce.x)> 1.5); + SpinKick = (fabs(wp->exp.nunchuk.gforce.x)> 0.5); + Roll = (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z || wp->btns_h & WPAD_NUNCHUK_BUTTON_C); + Pause = (wp->btns_h & WPAD_BUTTON_PLUS); + Select = (wp->btns_h & WPAD_BUTTON_MINUS); + // Swap Turtles or super turtle summon + if (wp->btns_h & WPAD_BUTTON_B) { + if (wp->exp.nunchuk.orient.pitch < -35 && wp->orient.pitch < -35) + J |= VBA_BUTTON_L | VBA_BUTTON_R; + else J |= VBA_BUTTON_R; + } + } else if (wp->exp.type == WPAD_EXP_CLASSIC) { + Jump = (wp->btns_h & WPAD_CLASSIC_BUTTON_B); + Attack = (wp->btns_h & WPAD_CLASSIC_BUTTON_A); + SpinKick = (wp->btns_h & WPAD_CLASSIC_BUTTON_X); + Pause = (wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS); + Select = (wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS); + Roll = (wp->btns_h & (WPAD_CLASSIC_BUTTON_FULL_L | WPAD_CLASSIC_BUTTON_FULL_R | WPAD_CLASSIC_BUTTON_ZL | WPAD_CLASSIC_BUTTON_ZR)); + // Swap Turtles or super turtle summon + if (wp->btns_h & WPAD_CLASSIC_BUTTON_Y) { + holdcount++; + if (holdcount > 20) + J |= VBA_BUTTON_L | VBA_BUTTON_R; + } + if (wp->btns_u & WPAD_CLASSIC_BUTTON_Y) { + if (holdcount <= 20) + J |= VBA_BUTTON_R; + holdcount = 0; + } + } else { + Jump = (wp->btns_h & WPAD_BUTTON_A); + Attack = (fabs(wp->gforce.x)> 1.5); + Pause = (wp->btns_h & WPAD_BUTTON_PLUS); + Select = (wp->btns_h & WPAD_BUTTON_MINUS); + // Swap Turtles or super turtle summon + if (wp->btns_h & WPAD_BUTTON_B) { + if (wp->orient.pitch < -40) + J |= VBA_BUTTON_L | VBA_BUTTON_R; + else J |= VBA_BUTTON_R; + } + SpinKick = (wp->btns_h & WPAD_BUTTON_1); + Roll = (wp->btns_h & WPAD_BUTTON_2); + } - 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) - J |= VBA_BUTTON_START; - // Hyper (toggle super missiles) - if (wp->btns_h & WPAD_BUTTON_PLUS) - J |= VBA_BUTTON_SELECT; - // 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)) - ; - - // Jump - if (wp->btns_h & WPAD_BUTTON_B && BallState!=2) - J |= VBA_BUTTON_A; - else if (BallState==2 && fabs(wp->gforce.y)> 1.5) - J |= VBA_BUTTON_A; - // Fire - if (wp->btns_h & WPAD_BUTTON_A) - 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 !=2) - { +#endif + u32 gc = PAD_ButtonsHeld(pad); + u32 released = PAD_ButtonsUp(pad); + // DPad moves + if (gc & PAD_BUTTON_UP) J |= VBA_UP; - AimCount = 0; + if (gc & PAD_BUTTON_DOWN) + J |= VBA_DOWN; + if (gc & PAD_BUTTON_LEFT) + J |= VBA_LEFT; + if (gc & PAD_BUTTON_RIGHT) + J |= VBA_RIGHT; + // Jump + if (gc & PAD_BUTTON_A) J |= VBA_BUTTON_A; + // Swap turtles, hold for super family move + if (gc & PAD_BUTTON_B) { + holdcount++; + if (holdcount > 20) + J |= VBA_BUTTON_L | VBA_BUTTON_R; } - else if (wp->orient.pitch < -22 && BallState !=2) - { - if (AimCount>=0) AimCount = -1; - } - else if (wp->orient.pitch> 45 && BallState ==0) - { - if (AimCount<10) AimCount=10; - } - else if (wp->orient.pitch> 22 && BallState !=2) - { - 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 == 2) - { // ball - Morph = -1; - } - else if (BallState == 1) - { - 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: - J |= VBA_BUTTON_A; - AimCount++; - break; - case 11: - J |= VBA_DOWN; - AimCount++; - break; - case 12: - J |= VBA_DOWN; - break; - } - - switch (MissileCount) - { - case 1: - case 2: + if (released & PAD_BUTTON_B) { + if (holdcount <= 20) J |= VBA_BUTTON_R; - MissileCount++; - break; - case 3: - case 4: - J |= VBA_BUTTON_R | VBA_BUTTON_B; - MissileCount++; - break; - case 5: - MissileCount = 0; - break; + holdcount = 0; } - - 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; - - 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; - - // Rumble when they lose health! - if (Health < OldHealth) - systemGameRumble(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) - { - 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; - - 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; - - // Rumble when they lose health! - if (Health < OldHealth) - systemGameRumble(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; - - 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; - - // Rumble when they lose (or gain) health! (since I'm not checking energy tanks) - if (Health != OldHealth) - systemGameRumble(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; - - return J; -} - -u32 TMNTInput(unsigned short pad) -{ - u32 J = StandardMovement(pad) | StandardDPad(pad); - //u32 jp = PAD_ButtonsHeld(pad); - - WPADData * wp = WPAD_Data(pad); - - // Jump - if (wp->btns_h & WPAD_BUTTON_A) - J |= VBA_BUTTON_A; // Attack - if (fabs(wp->gforce.x)> 1.5) - J |= VBA_BUTTON_B; - // Kick Attack - if (fabs(wp->exp.nunchuk.gforce.x)> 0.5) - J |= VBA_BUTTON_B; - - if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z)) - J |= VBA_BUTTON_B; // Double tap D-Pad to roll CAKTODO - - - // Swap Turtles - if (wp->btns_h & WPAD_BUTTON_B) - J |= VBA_BUTTON_R; + if (gc & PAD_BUTTON_X) Attack = true; + // Spin kick + if (gc & PAD_BUTTON_Y) SpinKick = true; // Pause - if (wp->btns_h & WPAD_BUTTON_PLUS) - J |= VBA_BUTTON_START; + if (gc & PAD_BUTTON_START) Pause = true; // Select - if (wp->btns_h & WPAD_BUTTON_MINUS) - J |= VBA_BUTTON_SELECT; + if (gc & PAD_TRIGGER_Z) Select = true; // Roll - if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_C)) - J |= 0; // Double tap D-Pad to roll CAKTODO + if (gc & PAD_TRIGGER_L || gc & PAD_TRIGGER_R) Roll = true; - // CAKTODO + if (Jump) J |= VBA_BUTTON_A; + if (Attack) J |= VBA_BUTTON_B; + if (SpinKick) J |= VBA_BUTTON_B | VBA_BUTTON_A; + if (Pause) J |= VBA_BUTTON_START; + if (Select) J |= VBA_BUTTON_SELECT; + if (Roll) { + if (!wait) { + J |= LastDir; // Double tap D-Pad to roll CAKTODO + wait = true; + } else wait = false; + } + + + if (J & VBA_RIGHT) LastDir = VBA_RIGHT; + else if (J & VBA_LEFT) LastDir = VBA_LEFT; return J; } -u32 HarryPotter1GBCInput(unsigned short pad) -{ - u32 J = StandardMovement(pad) | StandardDPad(pad); +u32 HarryPotter1GBCInput(unsigned short pad) { + u32 J = StandardMovement(pad) | StandardDPad(pad) | DPadWASD(pad) | DPadArrowKeys(pad) + | DecodeGamecube(pad); //u8 ScreenMode = gbReadMemory(0xFFCF); //u8 CursorItem = gbReadMemory(0xFFD5); +#ifdef HW_RVL + WPADData * wp = WPAD_Data(pad); + + // Pause Menu + if (wp->btns_h & WPAD_BUTTON_PLUS) + J |= VBA_BUTTON_START; + // Map (well, it tells you where you are) + if (wp->btns_h & WPAD_BUTTON_MINUS) + J |= VBA_BUTTON_SELECT; + + // talk or interact + if (wp->btns_h & WPAD_BUTTON_A) + J |= VBA_BUTTON_A; + // cancel + if (wp->btns_h & WPAD_BUTTON_B) + J |= VBA_BUTTON_B; + // spells + if (fabs(wp->gforce.x)> 1.5) + J |= VBA_BUTTON_A; + + if (wp->btns_h & WPAD_BUTTON_1) + J |= VBA_BUTTON_L; + if (wp->btns_h & WPAD_BUTTON_1) + J |= VBA_BUTTON_R; + + // Run (uses emulator speed button) + if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z)) + J |= VBA_SPEED; + // Camera, just tells you what room you are in. CAKTODO make press and release trigger it + if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_C)) + J |= VBA_BUTTON_SELECT; +#endif + + // CAKTODO spell gestures + + return J; +} + +u32 HarryPotter2GBCInput(unsigned short pad) { + u32 J = StandardMovement(pad) | StandardDPad(pad) | DPadWASD(pad) | DPadArrowKeys(pad) + | DecodeGamecube(pad); +#ifdef HW_RVL WPADData * wp = WPAD_Data(pad); // Pause Menu @@ -2478,52 +542,15 @@ u32 HarryPotter1GBCInput(unsigned short pad) J |= VBA_BUTTON_SELECT; // CAKTODO spell gestures +#endif return J; } -u32 HarryPotter2GBCInput(unsigned short pad) -{ - u32 J = StandardMovement(pad) | StandardDPad(pad); - WPADData * wp = WPAD_Data(pad); - - // Pause Menu - if (wp->btns_h & WPAD_BUTTON_PLUS) - J |= VBA_BUTTON_START; - // Map (well, it tells you where you are) - if (wp->btns_h & WPAD_BUTTON_MINUS) - J |= VBA_BUTTON_SELECT; - - // talk or interact - if (wp->btns_h & WPAD_BUTTON_A) - J |= VBA_BUTTON_A; - // cancel - if (wp->btns_h & WPAD_BUTTON_B) - J |= VBA_BUTTON_B; - // spells - if (fabs(wp->gforce.x)> 1.5) - J |= VBA_BUTTON_A; - - if (wp->btns_h & WPAD_BUTTON_1) - J |= VBA_BUTTON_L; - if (wp->btns_h & WPAD_BUTTON_1) - J |= VBA_BUTTON_R; - - // Run (uses emulator speed button) - if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z)) - J |= VBA_SPEED; - // Camera, just tells you what room you are in. CAKTODO make press and release trigger it - if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_C)) - J |= VBA_BUTTON_SELECT; - - // CAKTODO spell gestures - - return J; -} - -u32 HarryPotter1Input(unsigned short pad) -{ - u32 J = StandardMovement(pad); +u32 HarryPotter1Input(unsigned short pad) { + u32 J = StandardMovement(pad) | DPadWASD(pad) | DPadArrowKeys(pad) + | DecodeGamecube(pad); +#ifdef HW_RVL WPADData * wp = WPAD_Data(pad); // DPad works in the map @@ -2563,14 +590,15 @@ u32 HarryPotter1Input(unsigned short pad) J |= VBA_BUTTON_L; // CAKTODO spell gestures - +#endif return J; } -u32 HarryPotter2Input(unsigned short pad) -{ - u32 J = StandardMovement(pad); +u32 HarryPotter2Input(unsigned short pad) { + u32 J = StandardMovement(pad) | DPadWASD(pad) | DPadArrowKeys(pad) + | DecodeGamecube(pad); +#ifdef HW_RVL WPADData * wp = WPAD_Data(pad); // DPad works in the map @@ -2612,14 +640,15 @@ u32 HarryPotter2Input(unsigned short pad) J |= VBA_BUTTON_R; // CAKTODO spell gestures - +#endif return J; } -u32 HarryPotter3Input(unsigned short pad) -{ - u32 J = StandardMovement(pad); +u32 HarryPotter3Input(unsigned short pad) { + u32 J = StandardMovement(pad) | DPadWASD(pad) | DPadArrowKeys(pad) + | DecodeGamecube(pad); +#ifdef HW_RVL WPADData * wp = WPAD_Data(pad); // DPad works in the map @@ -2661,14 +690,23 @@ u32 HarryPotter3Input(unsigned short pad) // CAKTODO spell gestures // swing sideways for Flipendo // point at ceiling for Lumos - +#endif return J; } -u32 HarryPotter4Input(unsigned short pad) -{ - u32 J = StandardMovement(pad); +u32 HarryPotter4Input(unsigned short pad) { + u32 J = StandardMovement(pad) | DPadArrowKeys(pad) + | DecodeGamecube(pad); +#ifdef HW_RVL + if (DownUsbKeys[KB_A]) J |= VBA_BUTTON_L; + if (DownUsbKeys[KB_D]) J |= VBA_BUTTON_R; + if (DownUsbKeys[KB_ENTER] || DownUsbKeys[KB_X]) J |= VBA_BUTTON_A; + if (DownUsbKeys[KB_C]) J |= VBA_BUTTON_B; + if (DownUsbKeys[KB_TAB]) J |= VBA_BUTTON_SELECT; + if (DownUsbKeys[KB_SPACE]) J |= VBA_BUTTON_START; + if (DownUsbKeys[KB_LSHIFT] || DownUsbKeys[KB_RSHIFT]) J |= VBA_SPEED; + WPADData * wp = WPAD_Data(pad); // DPad works in the map @@ -2710,14 +748,23 @@ u32 HarryPotter4Input(unsigned short pad) // CAKTODO spell gestures // swing sideways for Flipendo // point at ceiling for Lumos - +#endif return J; } -u32 HarryPotter5Input(unsigned short pad) -{ - u32 J = StandardMovement(pad); +u32 HarryPotter5Input(unsigned short pad) { + u32 J = StandardMovement(pad) | DecodeGamecube(pad) | DPadWASD(pad); +#ifdef HW_RVL + // Keyboard controls based on Harry Potter 5 for PC + if (DownUsbKeys[KB_LEFT]) J |= VBA_BUTTON_L; + if (DownUsbKeys[KB_RIGHT]) J |= VBA_BUTTON_R; + if (DownUsbKeys[KB_UP] || DownUsbKeys[KB_DOWN]) J |= VBA_BUTTON_B; + if (DownUsbKeys[KB_ENTER]) J |= VBA_BUTTON_A; + if (DownUsbKeys[KB_TAB]) J |= VBA_BUTTON_SELECT; + if (DownUsbKeys[KB_SPACE]) J |= VBA_BUTTON_START; + if (DownUsbKeys[KB_LSHIFT] || DownUsbKeys[KB_RSHIFT]) J |= VBA_SPEED; + WPADData * wp = WPAD_Data(pad); // Wand cursor, normally controlled by DPad, now controlled by Wiimote! @@ -2726,8 +773,7 @@ u32 HarryPotter5Input(unsigned short pad) static int oldcx = 0; static int oldcy = 0; u8 WandOut = CPUReadByte(0x200e0dd); - if (WandOut && CursorValid) - { + if (WandOut && CursorValid) { cx = (CursorX * 268)/640; cy = (CursorY * 187)/480; if (cx<0x14) cx=0x14; @@ -2769,844 +815,19 @@ u32 HarryPotter5Input(unsigned short pad) J |= VBA_SPEED; // CAKTODO spell gestures +#endif return J; } -u32 Mario1DXInput(unsigned short pad) -{ - u32 J = StandardMovement(pad); - WPADData * wp = WPAD_Data(pad); - - bool run = false; - - - run = (wp->exp.type==WPAD_EXP_NUNCHUK && wp->exp.nunchuk.js.mag> 0.83) || (wp->exp.type==WPAD_EXP_CLASSIC && wp->exp.classic.ljs.mag> 0.83); - run = run && ((J & VBA_LEFT) || (J & VBA_RIGHT)); - - if (wp->exp.type==WPAD_EXP_NUNCHUK) - { - // Pause - if (wp->btns_h & WPAD_BUTTON_PLUS) - J |= VBA_BUTTON_START; - // Select - if (wp->btns_h & WPAD_BUTTON_MINUS) - J |= VBA_BUTTON_SELECT; - - // Jump - if (wp->btns_h & WPAD_BUTTON_A) - J |= VBA_BUTTON_A; - // Run, pick up - if (wp->btns_h & WPAD_BUTTON_B || run) - J |= VBA_BUTTON_B; - // Starspin shoots when using fireflower - if (fabs(wp->gforce.x)> 1.5) - J |= VBA_BUTTON_B; - - // Camera (must come before Crouch) - if (!(wp->btns_h & WPAD_NUNCHUK_BUTTON_C)) - J &= ~(VBA_DOWN | VBA_UP); - if (wp->btns_h & WPAD_BUTTON_UP) - J |= VBA_UP; - if (wp->btns_h & WPAD_BUTTON_DOWN) - J |= VBA_DOWN; - // Crouch (must come after Camera) - if (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) - J |= VBA_DOWN; - - // Speed - if (wp->btns_h & WPAD_BUTTON_1 || wp->btns_h & WPAD_BUTTON_2) - J |= VBA_SPEED; - } - else if (wp->exp.type == WPAD_EXP_CLASSIC) - { - // Pause - if (wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS) - J |= VBA_BUTTON_START; - // Select - if (wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS) - J |= VBA_BUTTON_SELECT; - // Jump - if (wp->btns_h & WPAD_CLASSIC_BUTTON_B) - J |= VBA_BUTTON_A; - // Run, pick up, throw, fire - if (wp->btns_h & WPAD_CLASSIC_BUTTON_X || wp->btns_h & WPAD_CLASSIC_BUTTON_Y || run) - J |= VBA_BUTTON_B; - // Spin attack - if (wp->btns_h & WPAD_CLASSIC_BUTTON_A) - J |= VBA_BUTTON_B; - // Camera - J &= ~(VBA_DOWN | VBA_UP); - if (wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_L) - J |= VBA_DOWN; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_R) - J |= VBA_UP; - // Crouch - if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZL) - { - J |= VBA_DOWN; - J &= ~VBA_UP; - } - // DPad movement/camera - if (wp->btns_h & WPAD_CLASSIC_BUTTON_UP) - J |= VBA_UP; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_DOWN) - J |= VBA_DOWN; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_LEFT) - J |= VBA_LEFT; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_RIGHT) - J |= VBA_RIGHT; - // Speed - if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZR) - J |= VBA_SPEED; - } - else - J |= StandardSideways(pad); - - - J |= StandardGamecube(pad) | StandardKeyboard(pad); - - return J; -} - -u32 Mario1ClassicInput(unsigned short pad) -{ - u32 J = StandardMovement(pad) | StandardDPad(pad); - WPADData * wp = WPAD_Data(pad); - - bool run = false; - - run = (wp->exp.type==WPAD_EXP_NUNCHUK && wp->exp.nunchuk.js.mag> 0.83) || (wp->exp.type==WPAD_EXP_CLASSIC && wp->exp.classic.ljs.mag> 0.83); - run = run && ((J & VBA_LEFT) || (J & VBA_RIGHT)); - - if (wp->exp.type==WPAD_EXP_NUNCHUK) - { - // Pause - if (wp->btns_h & WPAD_BUTTON_PLUS) - J |= VBA_BUTTON_START; - // Select - if (wp->btns_h & WPAD_BUTTON_MINUS) - J |= VBA_BUTTON_SELECT; - - // Jump - if (wp->btns_h & WPAD_BUTTON_A) - J |= VBA_BUTTON_A; - // Run, pick up - if (wp->btns_h & WPAD_BUTTON_B || run) - J |= VBA_BUTTON_B; - // Starspin shoots when using fireflower - if (fabs(wp->gforce.x)> 1.5) - J |= VBA_BUTTON_B; - - // Crouch - if (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) - { - J |= VBA_DOWN; - J &= ~VBA_UP; - } - - // Speed - if (wp->btns_h & WPAD_BUTTON_1 || wp->btns_h & WPAD_BUTTON_2) - J |= VBA_SPEED; - } - else if (wp->exp.type == WPAD_EXP_CLASSIC) - { - // DPad movement - if (wp->btns_h & WPAD_CLASSIC_BUTTON_UP) - J |= VBA_UP; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_DOWN) - J |= VBA_DOWN; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_LEFT) - J |= VBA_LEFT; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_RIGHT) - J |= VBA_RIGHT; - // Pause - if (wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS) - J |= VBA_BUTTON_START; - // Select - if (wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS) - J |= VBA_BUTTON_SELECT; - // Jump - if (wp->btns_h & WPAD_CLASSIC_BUTTON_B) - J |= VBA_BUTTON_A; - // Run, pick up, throw, fire - if (wp->btns_h & WPAD_CLASSIC_BUTTON_X || wp->btns_h & WPAD_CLASSIC_BUTTON_Y || run) - J |= VBA_BUTTON_B; - // Spin attack - if (wp->btns_h & WPAD_CLASSIC_BUTTON_A) - J |= VBA_BUTTON_B; - // Crouch - if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZL || wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_L) - { - J |= VBA_DOWN; - J &= ~VBA_UP; - } - // Speed - if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZR) - J |= VBA_SPEED; - } - else - J |= StandardSideways(pad); - - - J |= StandardGamecube(pad) | StandardKeyboard(pad); - - return J; -} - -u32 MarioLand1Input(unsigned short pad) -{ - u32 J = StandardMovement(pad) | StandardDPad(pad); - WPADData * wp = WPAD_Data(pad); - bool run = false; - - run = (wp->exp.type==WPAD_EXP_NUNCHUK && wp->exp.nunchuk.js.mag> 0.83) || (wp->exp.type==WPAD_EXP_CLASSIC && wp->exp.classic.ljs.mag> 0.83); - run = run && ((J & VBA_LEFT) || (J & VBA_RIGHT)); - - if (wp->exp.type == WPAD_EXP_NONE) - J |= StandardSideways(pad); - else if (wp->exp.type == WPAD_EXP_CLASSIC) - { - // DPad movement - if (wp->btns_h & WPAD_CLASSIC_BUTTON_UP) - J |= VBA_UP; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_DOWN) - J |= VBA_DOWN; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_LEFT) - J |= VBA_LEFT; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_RIGHT) - J |= VBA_RIGHT; - // Pause - if (wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS) - J |= VBA_BUTTON_START; - // Select - if (wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS) - J |= VBA_BUTTON_SELECT; - // Jump - if (wp->btns_h & WPAD_CLASSIC_BUTTON_B) - J |= VBA_BUTTON_A; - // Run, pick up, throw, fire - if (wp->btns_h & WPAD_CLASSIC_BUTTON_X || wp->btns_h & WPAD_CLASSIC_BUTTON_Y || run) - J |= VBA_BUTTON_B; - // Spin attack - if (wp->btns_h & WPAD_CLASSIC_BUTTON_A) - J |= VBA_BUTTON_B; - // Crouch - if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZL || wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_L) - { - J |= VBA_DOWN; - J &= ~VBA_UP; - } - // Speed - if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZR || wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_R) - J |= VBA_SPEED; - } - else if (wp->exp.type == WPAD_EXP_NUNCHUK) - { - // Pause - if (wp->btns_h & WPAD_BUTTON_PLUS) - J |= VBA_BUTTON_START; - // Select - if (wp->btns_h & WPAD_BUTTON_MINUS) - J |= VBA_BUTTON_SELECT; - // Jump - if (wp->btns_h & WPAD_BUTTON_A) - J |= VBA_BUTTON_A; - // Run, pick up, throw, fire - if (wp->btns_h & WPAD_BUTTON_B || run) - J |= VBA_BUTTON_B; - if (fabs(wp->gforce.x)> 1.5) - J |= VBA_BUTTON_B; - // Crouch - if (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) - J |= VBA_DOWN; - // Speed - if (wp->btns_h & WPAD_NUNCHUK_BUTTON_C || wp->btns_h & WPAD_BUTTON_1 || wp->btns_h & WPAD_BUTTON_2) - J |= VBA_SPEED; - } - else - J |= StandardSideways(pad); - // CAKTODO joystick run - - J |= StandardGamecube(pad) | StandardKeyboard(pad); - - return J; -} - -u32 MarioLand2Input(unsigned short pad) -{ - u32 J = StandardMovement(pad); - WPADData * wp = WPAD_Data(pad); - bool run = false; - - run = (wp->exp.type==WPAD_EXP_NUNCHUK && wp->exp.nunchuk.js.mag> 0.83) || (wp->exp.type==WPAD_EXP_CLASSIC && wp->exp.classic.ljs.mag> 0.83); - run = run && ((J & VBA_LEFT) || (J & VBA_RIGHT)); - - if (wp->exp.type == WPAD_EXP_NONE) - J |= StandardSideways(pad); - else if (wp->exp.type == WPAD_EXP_CLASSIC) - { - // DPad movement - if (wp->btns_h & WPAD_CLASSIC_BUTTON_UP) - J |= VBA_UP; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_DOWN) - J |= VBA_DOWN; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_LEFT) - J |= VBA_LEFT; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_RIGHT) - J |= VBA_RIGHT; - // Pause - if (wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS) - J |= VBA_BUTTON_START; - // Select - if (wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS) - J |= VBA_BUTTON_SELECT; - // Jump - if (wp->btns_h & WPAD_CLASSIC_BUTTON_B) - J |= VBA_BUTTON_A; - // Run, pick up, throw, fire - if (wp->btns_h & WPAD_CLASSIC_BUTTON_X || wp->btns_h & WPAD_CLASSIC_BUTTON_Y || run) - J |= VBA_BUTTON_B; - // Spin attack - if (wp->btns_h & WPAD_CLASSIC_BUTTON_A) - J |= VBA_DOWN | VBA_BUTTON_A; - // Camera - if (wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_L) - J |= VBA_DOWN | VBA_BUTTON_B; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_R) - J |= VBA_UP | VBA_BUTTON_B; - // Crouch - if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZL && (!(wp->btns_h & WPAD_CLASSIC_BUTTON_A))) - { - J |= VBA_DOWN; - // if the run button is held down, crouching also looks down - // which we don't want when using the Z button - J &= ~VBA_BUTTON_B; - J &= ~VBA_UP; - } - // Speed - if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZR) - J |= VBA_SPEED; - - } - else if (wp->exp.type == WPAD_EXP_NUNCHUK) - { - // Pause - if (wp->btns_h & WPAD_BUTTON_PLUS) - J |= VBA_BUTTON_START; - // Select - if (wp->btns_h & WPAD_BUTTON_MINUS) - J |= VBA_BUTTON_SELECT; - // Jump - if (wp->btns_h & WPAD_BUTTON_A) - J |= VBA_BUTTON_A; - // Run, pick up, throw, fire - if (wp->btns_h & WPAD_BUTTON_B || run) - J |= VBA_BUTTON_B; - // Spin attack - if (fabs(wp->gforce.x)> 1.4) - J |= VBA_DOWN | VBA_BUTTON_A; - // Camera - if (wp->btns_h & WPAD_NUNCHUK_BUTTON_C) - J |= VBA_BUTTON_B; - if (wp->btns_h & WPAD_BUTTON_UP) - J |= VBA_BUTTON_B | VBA_UP; - if (wp->btns_h & WPAD_BUTTON_DOWN) - J |= VBA_BUTTON_B | VBA_DOWN; - if (wp->btns_h & WPAD_BUTTON_LEFT) - J |= VBA_BUTTON_B | VBA_LEFT; - if (wp->btns_h & WPAD_BUTTON_RIGHT) - J |= VBA_BUTTON_B | VBA_RIGHT; - // Crouch - if (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z && (!(wp->btns_h & WPAD_BUTTON_A))) - { - J |= VBA_DOWN; - // if the run button is held down, crouching also looks down - // which we don't want when using the Z button - J &= ~VBA_BUTTON_B; - J &= ~VBA_UP; - } - // Speed - if (wp->btns_h & WPAD_BUTTON_1 || wp->btns_h & WPAD_BUTTON_2) - J |= VBA_SPEED; - } - else - J |= StandardSideways(pad); - - J |= StandardGamecube(pad) | StandardKeyboard(pad); - - return J; - -} - -u32 Mario2Input(unsigned short pad) -{ - u32 J = StandardMovement(pad); - WPADData * wp = WPAD_Data(pad); - - // DPad looks around - if (wp->btns_h & WPAD_BUTTON_RIGHT) - J |= VBA_BUTTON_R; - if (wp->btns_h & WPAD_BUTTON_LEFT) - J |= VBA_BUTTON_L; - if (wp->btns_h & WPAD_BUTTON_UP) - J |= VBA_BUTTON_L; - if (wp->btns_h & WPAD_BUTTON_DOWN) - J |= VBA_BUTTON_L; - - // Pause - if (wp->btns_h & WPAD_BUTTON_PLUS) - J |= VBA_BUTTON_START; - // Select - if (wp->btns_h & WPAD_BUTTON_MINUS) - J |= VBA_BUTTON_SELECT; - - // Jump - if (wp->btns_h & WPAD_BUTTON_A) - J |= VBA_BUTTON_A; - // Run, pick up - if (wp->btns_h & WPAD_BUTTON_B) - J |= VBA_BUTTON_B; - if (fabs(wp->gforce.x)> 1.5) - J |= VBA_BUTTON_B; - - // Crouch - if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z)) - J |= VBA_DOWN; - - if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_C)) - J |= VBA_BUTTON_L; - if (wp->btns_h & WPAD_BUTTON_1) - J |= VBA_BUTTON_R; - if (wp->btns_h & WPAD_BUTTON_2) - J |= VBA_BUTTON_R; - - return J; -} - -u32 MarioWorldInput(unsigned short pad) -{ - u32 J = StandardMovement(pad) | StandardDPad(pad); - - //J &= ~(VBA_DOWN | VBA_UP); - u32 jp = PAD_ButtonsHeld(pad); - - u8 CarryState = CPUReadByte(0x3003F06); // 01 = carrying, 00 = not carrying - u8 InYoshisMouth = CPUReadByte(0x3003F53); // FF = nothing, 00 = no level, else thing - u8 FallState = CPUReadByte(0x3003FA1); // 0B = jump, 24 = fall - u8 RidingYoshi = CPUReadByte(0x3004302); // 00 = not riding, 01 = riding - static bool NeedStomp = false; - bool dontrun = false; - bool run = false; - static bool dontletgo = false; - dontrun = (InYoshisMouth != 0 && InYoshisMouth != 0xFF && RidingYoshi); - bool BButton = false; - - WPADData * wp = WPAD_Data(pad); - - run = (wp->exp.type==WPAD_EXP_NUNCHUK && wp->exp.nunchuk.js.mag> 0.83) || (wp->exp.type==WPAD_EXP_CLASSIC && wp->exp.classic.ljs.mag> 0.83); - BButton = (wp->exp.type == WPAD_EXP_CLASSIC && (wp->btns_h & WPAD_CLASSIC_BUTTON_X || wp->btns_h & WPAD_CLASSIC_BUTTON_Y)) || wp->btns_h & WPAD_BUTTON_B; - - BButton = BButton || jp & PAD_BUTTON_B; - if (run && CarryState && !BButton) - dontletgo = true; - if (!CarryState) - dontletgo = false; - - // Pause - if (wp->btns_h & WPAD_BUTTON_PLUS) - J |= VBA_BUTTON_START; - // Select - if (wp->btns_h & WPAD_BUTTON_MINUS) - J |= VBA_BUTTON_SELECT; - - // Jump - if (wp->btns_h & WPAD_BUTTON_A) - J |= VBA_BUTTON_A; - // Run, pick up - if ((run && !dontrun) || wp->btns_h & WPAD_BUTTON_B || dontletgo) - J |= VBA_BUTTON_B; - if (wp->btns_h & WPAD_BUTTON_B && dontletgo) - { - J = J & ~VBA_BUTTON_B; - dontletgo = false; - } - // Spin attack - if (fabs(wp->gforce.x)> 1.5) - J |= VBA_BUTTON_R; - - // Butt stomp - if (FallState!=0 && (wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) && (!RidingYoshi)) - NeedStomp = true; - if (FallState!=0 && (wp->exp.type == WPAD_EXP_CLASSIC) && (wp->btns_h & WPAD_CLASSIC_BUTTON_ZL || wp->btns_h & WPAD_CLASSIC_BUTTON_ZR) && (!RidingYoshi)) - NeedStomp = true; - // Crouch - if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z)) - { - J |= VBA_DOWN; // Crouch - J &= ~VBA_UP; - } - - // Camera - if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_C)) - { - if (J & VBA_DOWN || J & VBA_UP) - J |= VBA_BUTTON_L; - else if (J & VBA_RIGHT || J & VBA_LEFT) - { - J |= VBA_BUTTON_L; - J &= ~VBA_RIGHT; - J &= ~VBA_LEFT; - } - } - - if (wp->exp.type == WPAD_EXP_CLASSIC) - { - if (wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS) - J |= VBA_BUTTON_START; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS) - J |= VBA_BUTTON_SELECT; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_X || wp->btns_h & WPAD_CLASSIC_BUTTON_Y) - J |= VBA_BUTTON_B; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_B) - J |= VBA_BUTTON_A; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_A || wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_R) - J |= VBA_BUTTON_R; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_L) - J |= VBA_BUTTON_L; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZL || wp->btns_h & WPAD_CLASSIC_BUTTON_ZR) - { - J |= VBA_DOWN; // Crouch - J &= ~VBA_UP; - } - } - - BButton = (wp->exp.type == WPAD_EXP_CLASSIC && (wp->btns_h & WPAD_CLASSIC_BUTTON_X || wp->btns_h & WPAD_CLASSIC_BUTTON_Y)) || wp->btns_h & WPAD_BUTTON_B; - - if (jp & PAD_BUTTON_A) - J |= VBA_BUTTON_A; - if (jp & PAD_BUTTON_B) - J |= VBA_BUTTON_B; - if (jp & PAD_BUTTON_X) - J |= VBA_BUTTON_R; - if (jp & PAD_BUTTON_Y) - J |= VBA_BUTTON_SELECT; - if (jp & PAD_TRIGGER_R) - J |= VBA_BUTTON_R; - if (jp & PAD_TRIGGER_L) - J |= VBA_BUTTON_L; - if (jp & PAD_BUTTON_START) - J |= VBA_BUTTON_START; - if (jp & PAD_TRIGGER_Z) - { - J |= VBA_DOWN; - J &= ~VBA_UP; - } - // if we try to use Yoshi's tongue while running, release run for one frame - if (run && BButton && !dontrun && !dontletgo) - { - J &= ~VBA_BUTTON_B; - } - if (NeedStomp && FallState == 0 && !RidingYoshi) - { - J |= VBA_BUTTON_R; // spin attack only works when on ground - NeedStomp = false; - } - - J |= StandardKeyboard(pad); - - return J; -} - -u32 Mario3Input(unsigned short pad) -{ - u32 J = StandardMovement(pad) | StandardDPad(pad); - WPADData * wp = WPAD_Data(pad); - bool run = false; - - run = (wp->exp.type==WPAD_EXP_NUNCHUK && wp->exp.nunchuk.js.mag> 0.83) || (wp->exp.type==WPAD_EXP_CLASSIC && wp->exp.classic.ljs.mag> 0.83); - run = run && ((J & VBA_LEFT) || (J & VBA_RIGHT)); - - if (wp->exp.type == WPAD_EXP_NONE) - J |= StandardSideways(pad); - else if (wp->exp.type == WPAD_EXP_CLASSIC) - { - // DPad movement - if (wp->btns_h & WPAD_CLASSIC_BUTTON_UP) - J |= VBA_UP; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_DOWN) - J |= VBA_DOWN; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_LEFT) - J |= VBA_LEFT; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_RIGHT) - J |= VBA_RIGHT; - // Pause - if (wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS) - J |= VBA_BUTTON_START; - // Select - if (wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS) - J |= VBA_BUTTON_L; - // Replay menu - if (wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_R) - J |= VBA_BUTTON_SELECT; - // Jump - if (wp->btns_h & WPAD_CLASSIC_BUTTON_B) - J |= VBA_BUTTON_A; - // Run, pick up, throw, fire - if (wp->btns_h & WPAD_CLASSIC_BUTTON_X || wp->btns_h & WPAD_CLASSIC_BUTTON_Y || run) - J |= VBA_BUTTON_B; - // Spin attack (racoon costume, fire flower) - if (wp->btns_h & WPAD_CLASSIC_BUTTON_A) - J |= VBA_BUTTON_B; - // Crouch - if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZL || wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_L) - { - J |= VBA_DOWN; - J &= ~VBA_UP; - } - // Speed - if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZR) - J |= VBA_SPEED; - - } - else if (wp->exp.type == WPAD_EXP_NUNCHUK) - { - // Pause - if (wp->btns_h & WPAD_BUTTON_PLUS) - J |= VBA_BUTTON_START; - // Select - if (wp->btns_h & WPAD_BUTTON_MINUS) - J |= VBA_BUTTON_L; - // Replay Menu - if (wp->btns_h & WPAD_BUTTON_1) - J |= VBA_BUTTON_SELECT; - // Jump - if (wp->btns_h & WPAD_BUTTON_A) - J |= VBA_BUTTON_A; - // Run, pick up, throw, fire - if (wp->btns_h & WPAD_BUTTON_B || run) - J |= VBA_BUTTON_B; - // Spin attack (racoon, fire flower) - if (fabs(wp->gforce.x)> 1.4) - J |= VBA_BUTTON_B; - // Crouch - if (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) - { - J |= VBA_DOWN; - J &= ~VBA_UP; - } - // Speed - if (wp->btns_h & WPAD_BUTTON_2) - J |= VBA_SPEED; - } - else - J |= StandardSideways(pad); - - J |= StandardGamecube(pad) | StandardKeyboard(pad); - - return J; -} - -u32 YoshiIslandInput(unsigned short pad) -{ - u32 J = StandardMovement(pad) | StandardDPad(pad); - - u32 jp = PAD_ButtonsHeld(pad); - - //static bool NeedStomp = false; - //bool dontrun = false; - //bool run = false; - //static bool dontletgo = false; - //bool BButton = false; - - WPADData * wp = WPAD_Data(pad); - //run = (wp->exp.type==WPAD_EXP_NUNCHUK && wp->exp.nunchuk.js.mag > 0.83) || (wp->exp.type==WPAD_EXP_CLASSIC && wp->exp.classic.ljs.mag > 0.83); - //BButton = (wp->exp.type == WPAD_EXP_CLASSIC && (wp->btns_h & WPAD_CLASSIC_BUTTON_X || wp->btns_h & WPAD_CLASSIC_BUTTON_Y)) || wp->btns_h & WPAD_BUTTON_B; - - //BButton = BButton || jp & PAD_BUTTON_B; - - - /*** Report wp->btns_h buttons (gamepads) ***/ - - - // Pause - if (wp->btns_h & WPAD_BUTTON_PLUS) - J |= VBA_BUTTON_START; - // Select - if (wp->btns_h & WPAD_BUTTON_MINUS) - J |= VBA_BUTTON_SELECT; - - // Jump - if (wp->btns_h & WPAD_BUTTON_A) - J |= VBA_BUTTON_A; - // Run, pick up - if (wp->btns_h & WPAD_BUTTON_B) - J |= VBA_BUTTON_B; - // throw - if (wp->btns_h & WPAD_BUTTON_1 || wp->btns_h & WPAD_BUTTON_2) - J |= VBA_BUTTON_R; - - // Butt stomp - //if (FallState!=0 && (wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) && (!RidingYoshi)) - // NeedStomp = true; - //if (FallState!=0 && (wp->exp.type == WPAD_EXP_CLASSIC) && (wp->btns_h & WPAD_CLASSIC_BUTTON_ZL || wp->btns_h & WPAD_CLASSIC_BUTTON_ZR) && (!RidingYoshi)) - // NeedStomp = true; - - // Crouch, lay egg - if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z)) - { - J |= VBA_DOWN; // Crouch - J &= ~VBA_UP; - } - - // Camera - if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_C)) - { - J |= VBA_BUTTON_L; - } - - if (wp->exp.type == WPAD_EXP_CLASSIC) - { - if (wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS) - J |= VBA_BUTTON_START; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS) - J |= VBA_BUTTON_SELECT; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_X) - J |= VBA_BUTTON_B; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_Y) - J |= VBA_BUTTON_R; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_B) - J |= VBA_BUTTON_A; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_A || wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_R) - J |= VBA_BUTTON_R; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_L) - J |= VBA_BUTTON_L; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZL || wp->btns_h & WPAD_CLASSIC_BUTTON_ZR) - { - J |= VBA_DOWN; // Crouch - J &= ~VBA_UP; - } - } - - if (jp & PAD_BUTTON_A) - J |= VBA_BUTTON_A; - if (jp & PAD_BUTTON_B) - J |= VBA_BUTTON_B; - if (jp & PAD_BUTTON_X) - J |= VBA_BUTTON_R; - if (jp & PAD_BUTTON_Y) - J |= VBA_BUTTON_SELECT; - if (jp & PAD_TRIGGER_R) - J |= VBA_BUTTON_R; - if (jp & PAD_TRIGGER_L) - J |= VBA_BUTTON_L; - if (jp & PAD_BUTTON_START) - J |= VBA_BUTTON_START; - if (jp & PAD_TRIGGER_Z) - { - J |= VBA_DOWN; - J &= ~VBA_UP; - } - //if (NeedStomp && FallState==0 && !RidingYoshi) { - // J |= VBA_BUTTON_R; // spin attack only works when on ground - // NeedStomp = false; - //} - - return J; -} - -u32 UniversalGravitationInput(unsigned short pad) -{ - TiltScreen = true; - u32 J = StandardMovement(pad); - - //u32 jp = PAD_ButtonsHeld(pad); - - //static bool NeedStomp = false; - //bool dontrun = false; - //bool run = false; - //static bool dontletgo = false; - //bool BButton = false; - - WPADData * wp = WPAD_Data(pad); - //run = (wp->exp.type==WPAD_EXP_NUNCHUK && wp->exp.nunchuk.js.mag > 0.83) || (wp->exp.type==WPAD_EXP_CLASSIC && wp->exp.classic.ljs.mag > 0.83); - - if (wp->exp.type == WPAD_EXP_NUNCHUK) - { - TiltSideways = false; - J |= StandardDPad(pad); - // Pause - if (wp->btns_h & WPAD_BUTTON_PLUS) - J |= VBA_BUTTON_START; - // Select, L & R do nothing! - if (wp->btns_h & WPAD_BUTTON_MINUS) - J |= VBA_BUTTON_SELECT; - if (wp->btns_h & WPAD_BUTTON_1) - J |= VBA_BUTTON_L | VBA_SPEED; - if (wp->btns_h & WPAD_BUTTON_2) - J |= VBA_BUTTON_R | VBA_SPEED; - - // Jump - if (wp->btns_h & WPAD_BUTTON_A) - J |= VBA_BUTTON_A; - // tongue - if (wp->btns_h & WPAD_BUTTON_B) - J |= VBA_BUTTON_B; - // Crouch, butt stomp - if (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) - { - J |= VBA_DOWN; // Crouch - J &= ~VBA_UP; - } - // Camera - if (wp->btns_h & WPAD_NUNCHUK_BUTTON_C) - { - J |= VBA_UP; - } - } - else if (wp->exp.type == WPAD_EXP_CLASSIC) - { - TiltSideways = false; - J |= StandardDPad(pad); - // A bit stupid playing with the classic controller, but nevermind. - if (wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS) - J |= VBA_BUTTON_START; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS) - J |= VBA_BUTTON_SELECT; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_X) - J |= VBA_BUTTON_B; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_Y) - J |= VBA_BUTTON_R; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_B || wp->btns_h & WPAD_CLASSIC_BUTTON_A) - J |= VBA_BUTTON_A; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_L || wp->btns_h & WPAD_CLASSIC_BUTTON_ZL) - J |= VBA_DOWN; - if (wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_R) - J |= VBA_UP; - if (WPAD_CLASSIC_BUTTON_ZR) - J |= VBA_SPEED; - } - else - { - TiltSideways = true; - J |= StandardSideways(pad); - } - - // A bit stupid playing with keyboard or gamecube pad when you need to tilt the wiimote... - J |= StandardKeyboard(pad) | StandardGamecube(pad); - - return J; -} - -u32 TwistedInput(unsigned short pad) -{ +u32 TwistedInput(unsigned short pad) { // Change this to true if you want to see the screen tilt. TiltScreen = false; - u32 J = StandardMovement(pad); + u32 J = StandardMovement(pad) | DecodeKeyboard(pad) | DecodeGamecube(pad); +#ifdef HW_RVL WPADData * wp = WPAD_Data(pad); - if (wp->exp.type == WPAD_EXP_NUNCHUK) - { + if (wp->exp.type == WPAD_EXP_NUNCHUK) { TiltSideways = false; J |= StandardDPad(pad); // Pause @@ -3632,35 +853,26 @@ u32 TwistedInput(unsigned short pad) // Speed if (wp->btns_h & WPAD_NUNCHUK_BUTTON_C) J |= VBA_SPEED; - } - else if (wp->exp.type == WPAD_EXP_CLASSIC) - { + } else if (wp->exp.type == WPAD_EXP_CLASSIC) { TiltSideways = false; J |= StandardDPad(pad) | StandardClassic(pad); - } - else - { + } else { TiltSideways = true; J |= StandardSideways(pad); if (wp->btns_h & WPAD_BUTTON_B) J |= VBA_SPEED; } - - // A bit stupid playing with keyboard or gamecube pad when you need to tilt the wiimote... - J |= StandardKeyboard(pad) | StandardGamecube(pad); - +#endif return J; } -u32 KirbyTntInput(unsigned short pad) -{ +u32 KirbyTntInput(unsigned short pad) { TiltScreen = false; - u32 J = StandardMovement(pad); + u32 J = StandardMovement(pad) | DecodeGamecube(pad) | DecodeKeyboard(pad); +#ifdef HW_RVL WPADData * wp = WPAD_Data(pad); - - if (wp->exp.type == WPAD_EXP_NUNCHUK) - { + if (wp->exp.type == WPAD_EXP_NUNCHUK) { TiltSideways = false; J |= StandardDPad(pad); // Pause @@ -3683,17 +895,12 @@ u32 KirbyTntInput(unsigned short pad) // Speed if (wp->btns_h & WPAD_NUNCHUK_BUTTON_C) J |= VBA_SPEED; - } - else if (wp->exp.type == WPAD_EXP_CLASSIC) - { + } else if (wp->exp.type == WPAD_EXP_CLASSIC) { TiltSideways = false; - J |= StandardDPad(pad) | StandardClassic(pad); + J |= StandardDPad(pad) | DecodeClassic(pad); if (wp->btns_h & WPAD_BUTTON_A) J |= VBA_BUTTON_A; - - } - else - { + } else { TiltSideways = true; J |= StandardSideways(pad); if (wp->btns_h & WPAD_BUTTON_A) @@ -3701,79 +908,56 @@ u32 KirbyTntInput(unsigned short pad) if (wp->btns_h & WPAD_BUTTON_B) J |= VBA_SPEED; } - - // A bit stupid playing with keyboard or gamecube pad when you need to tilt the wiimote... - J |= StandardKeyboard(pad) | StandardGamecube(pad); - +#endif return J; } -u32 MohInfiltratorInput(unsigned short pad) -{ - u32 J = StandardMovement(pad); - - +u32 MohInfiltratorInput(unsigned short pad) { + u32 J = StandardMovement(pad) | DecodeGamecube(pad) | DecodeKeyboard(pad); +#ifdef HW_RVL WPADData * wp = WPAD_Data(pad); - if (wp->exp.type == WPAD_EXP_NONE) - J |= StandardSideways(pad); - else if (wp->exp.type == WPAD_EXP_CLASSIC) - { - J |= StandardClassic(pad); - } - else if (wp->exp.type == WPAD_EXP_NUNCHUK) - { + J |= DecodeWiimote(pad); + else if (wp->exp.type == WPAD_EXP_CLASSIC) { + J |= DecodeClassic(pad); + } else if (wp->exp.type == WPAD_EXP_NUNCHUK) { // Pause, objectives, menu if (wp->btns_h & WPAD_BUTTON_PLUS) - J |= VBA_BUTTON_START; + J |= VBA_BUTTON_START; // Action button, use if (wp->btns_h & WPAD_BUTTON_MINUS) - J |= VBA_BUTTON_L; + J |= VBA_BUTTON_L; // Use sights/scope, not needed in this game if (wp->btns_h & WPAD_BUTTON_A) - J |= VBA_BUTTON_A | VBA_BUTTON_L; + J |= VBA_BUTTON_A | VBA_BUTTON_L; // Shoot if (wp->btns_h & WPAD_BUTTON_B) - J |= VBA_BUTTON_A; + J |= VBA_BUTTON_A; // Reload if (fabs(wp->gforce.y)> 1.6 || wp->btns_h & WPAD_BUTTON_UP || wp->btns_h & WPAD_BUTTON_2) - J |= VBA_BUTTON_L; + J |= VBA_BUTTON_L; // Strafe if (wp->btns_h & WPAD_NUNCHUK_BUTTON_C) - J |= VBA_BUTTON_R; + J |= VBA_BUTTON_R; // Change weapon if (wp->btns_h & WPAD_BUTTON_LEFT || wp->btns_h & WPAD_BUTTON_RIGHT) - J |= VBA_BUTTON_B; + J |= VBA_BUTTON_B; // Speed if (wp->btns_h & WPAD_BUTTON_1) - J |= VBA_SPEED; - } - else - J |= StandardSideways(pad); - - J |= StandardGamecube(pad) | StandardKeyboard(pad); - + J |= VBA_SPEED; + } else + J |= DecodeWiimote(pad); +#endif return J; } -u32 MohUndergroundInput(unsigned short pad) -{ - u32 J = StandardMovement(pad); - WPADData * wp = WPAD_Data(pad); +u32 MohUndergroundInput(unsigned short pad) { + u32 J = StandardMovement(pad) | DecodeClassic(pad) | DecodeWiimote(pad) | DecodeGamecube(pad) | DecodeKeyboard(pad); static bool crouched = false; +#ifdef HW_RVL + WPADData * wp = WPAD_Data(pad); - if (wp->exp.type == WPAD_EXP_NONE) - { - J |= StandardSideways(pad); - CursorVisible = false; - } - else if (wp->exp.type == WPAD_EXP_CLASSIC) - { - J |= StandardClassic(pad); - CursorVisible = false; - } - else if (wp->exp.type == WPAD_EXP_NUNCHUK) - { + if (wp->exp.type == WPAD_EXP_NUNCHUK) { // Joystick controls L and R, not left and right if (J & VBA_LEFT) J |= VBA_BUTTON_L; @@ -3782,8 +966,7 @@ u32 MohUndergroundInput(unsigned short pad) J &= ~(VBA_LEFT | VBA_RIGHT); // Cursor controls left and right for turning CursorVisible = true; - if (CursorValid) - { + if (CursorValid) { if (CursorX < 320 - 40) J |= VBA_LEFT; else if (CursorX> 320 + 40) @@ -3795,164 +978,188 @@ u32 MohUndergroundInput(unsigned short pad) // Pause, objectives, menu if (wp->btns_h & WPAD_BUTTON_PLUS) - J |= VBA_BUTTON_START; + J |= VBA_BUTTON_START; // Action button, not needed in this game if (wp->btns_h & WPAD_BUTTON_MINUS) - J |= 0; + J |= 0; // Use sights/scope, not needed in this game if (wp->btns_h & WPAD_BUTTON_A) - J |= VBA_BUTTON_A; + J |= VBA_BUTTON_A; // Shoot if (wp->btns_h & WPAD_BUTTON_B) - J |= VBA_BUTTON_A; + J |= VBA_BUTTON_A; // Reload if (fabs(wp->gforce.y)> 1.6 || wp->btns_h & WPAD_BUTTON_UP || wp->btns_h & WPAD_BUTTON_2) - J |= VBA_BUTTON_SELECT; + J |= VBA_BUTTON_SELECT; // Change weapon if (wp->btns_h & WPAD_BUTTON_LEFT || wp->btns_h & WPAD_BUTTON_RIGHT) - J |= VBA_BUTTON_B; + J |= VBA_BUTTON_B; // Speed if (wp->btns_h & WPAD_BUTTON_1) - J |= VBA_SPEED; - } - else - { - J |= StandardSideways(pad); + J |= VBA_SPEED; + } else { CursorVisible = false; } +#endif - J |= StandardGamecube(pad) | StandardKeyboard(pad); if (crouched && (!(J & VBA_BUTTON_L)) && (!(J & VBA_BUTTON_R))) J |= VBA_BUTTON_L | VBA_BUTTON_R; return J; } -u32 BoktaiInput(unsigned short pad) -{ - u32 J = StandardMovement(pad); +u32 BoktaiInput(unsigned short pad) { + u32 J = StandardMovement(pad) | StandardDPad(pad) + | DecodeKeyboard(pad) | DecodeGamecube(pad) | DecodeClassic(pad); +#ifdef HW_RVL WPADData * wp = WPAD_Data(pad); static bool GunRaised = false; - - J |= StandardDPad(pad); // Action if (wp->btns_h & WPAD_BUTTON_A) - J |= VBA_BUTTON_A; + J |= VBA_BUTTON_A; // Hold Gun Del Sol up to the light to recharge - if ((-wp->orient.pitch)> 45) - { + if ((-wp->orient.pitch)> 45) { GunRaised = true; - } - else if ((-wp->orient.pitch) < 40) - { + } else if ((-wp->orient.pitch) < 40) { GunRaised = false; } if (GunRaised) - J |= VBA_BUTTON_A; + J |= VBA_BUTTON_A; // Fire Gun Del Sol if (wp->btns_h & WPAD_BUTTON_B) - J |= VBA_BUTTON_B; + J |= VBA_BUTTON_B; // Look around or change subscreen if (wp->btns_h & WPAD_BUTTON_2) - J |= VBA_BUTTON_R; + J |= VBA_BUTTON_R; // Start if (wp->btns_h & WPAD_BUTTON_PLUS) - J |= VBA_BUTTON_START; + J |= VBA_BUTTON_START; // Select if (wp->btns_h & WPAD_BUTTON_MINUS) - J |= VBA_BUTTON_SELECT; + J |= VBA_BUTTON_SELECT; - if (wp->exp.type == WPAD_EXP_CLASSIC) - { - J |= StandardClassic(pad); - } - else if (wp->exp.type == WPAD_EXP_NUNCHUK) - { + if (wp->exp.type == WPAD_EXP_NUNCHUK) { // Look around if (wp->btns_h & WPAD_NUNCHUK_BUTTON_C) - J |= VBA_BUTTON_R; + J |= VBA_BUTTON_R; // Change element or change subscreen if (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) - J |= VBA_BUTTON_L; + J |= VBA_BUTTON_L; if (wp->btns_h & WPAD_BUTTON_1) - J |= VBA_SPEED; - } - else - { + J |= VBA_SPEED; + } else { // Change element or change subscreen if (wp->btns_h & WPAD_BUTTON_1) - J |= VBA_BUTTON_L; + J |= VBA_BUTTON_L; } - - J |= StandardGamecube(pad) | StandardKeyboard(pad); - +#endif return J; } -u32 Boktai2Input(unsigned short pad) -{ - u32 J = StandardMovement(pad); +u32 Boktai2Input(unsigned short pad) { + u32 J = StandardMovement(pad) | StandardDPad(pad) + | DecodeKeyboard(pad) | DecodeGamecube(pad) | DecodeClassic(pad); +#ifdef HW_RVL WPADData * wp = WPAD_Data(pad); static bool GunRaised = false; + // Action + if (wp->btns_h & WPAD_BUTTON_A) + J |= VBA_BUTTON_A; + // Hold gun or hand up to the light to recharge + if ((-wp->orient.pitch)> 45) { + GunRaised = true; + } else if ((-wp->orient.pitch) < 40) { + GunRaised = false; + } + if (GunRaised) + J |= VBA_BUTTON_A; + // Fire Gun Del Sol + if (wp->btns_h & WPAD_BUTTON_B) + J |= VBA_BUTTON_B; + // Swing sword or hammer or stab spear + if (fabs(wp->gforce.x)> 1.8) + J |= VBA_BUTTON_B; + // Look around or change subscreen + if (wp->btns_h & WPAD_BUTTON_2) + J |= VBA_BUTTON_R; + // Start + if (wp->btns_h & WPAD_BUTTON_PLUS) + J |= VBA_BUTTON_START; + // Select + if (wp->btns_h & WPAD_BUTTON_MINUS) + J |= VBA_BUTTON_SELECT; - J |= StandardDPad(pad); - // Action - if (wp->btns_h & WPAD_BUTTON_A) - J |= VBA_BUTTON_A; - // Hold gun or hand up to the light to recharge - if ((-wp->orient.pitch)> 45) - { - GunRaised = true; - } - else if ((-wp->orient.pitch) < 40) - { - GunRaised = false; - } - if (GunRaised) - J |= VBA_BUTTON_A; - // Fire Gun Del Sol - if (wp->btns_h & WPAD_BUTTON_B) - J |= VBA_BUTTON_B; - // Swing sword or hammer or stab spear - if (fabs(wp->gforce.x)> 1.8) - J |= VBA_BUTTON_B; - // Look around or change subscreen - if (wp->btns_h & WPAD_BUTTON_2) - J |= VBA_BUTTON_R; - // Start - if (wp->btns_h & WPAD_BUTTON_PLUS) - J |= VBA_BUTTON_START; - // Select - if (wp->btns_h & WPAD_BUTTON_MINUS) - J |= VBA_BUTTON_SELECT; - - if (wp->exp.type == WPAD_EXP_CLASSIC) - { - J |= StandardClassic(pad); - } - else if (wp->exp.type == WPAD_EXP_NUNCHUK) - { + if (wp->exp.type == WPAD_EXP_NUNCHUK) { // Look around if (wp->btns_h & WPAD_NUNCHUK_BUTTON_C) - J |= VBA_BUTTON_R; + J |= VBA_BUTTON_R; // Change element or change subscreen if (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) - J |= VBA_BUTTON_L; + J |= VBA_BUTTON_L; if (wp->btns_h & WPAD_BUTTON_1) J |= VBA_SPEED; - } - else - { + } else { // Change element or change subscreen if (wp->btns_h & WPAD_BUTTON_1) J |= VBA_BUTTON_L; } - - J |= StandardGamecube(pad) | StandardKeyboard(pad); +#endif return J; } +u32 OnePieceInput(unsigned short pad) { + // Only Nunchuk and Gamecube controls available + // Keyboard, Wiimote and Classic controls depend on user configuration + u32 J = StandardMovement(pad) + | DecodeKeyboard(pad) | DecodeWiimote(pad) | DecodeClassic(pad); + static u32 LastDir = VBA_RIGHT; + bool JumpButton=0, AttackButton=0, ViewButton=0, CharacterButton=0, PauseButton=0, + DashButton=0, GrabButton=0, SpeedButton=0, AttackUpButton = 0; +#ifdef HW_RVL + WPADData * wp = WPAD_Data(pad); + // Nunchuk controls are based on One Piece: Unlimited Adventure for the Wii + if (wp->exp.type == WPAD_EXP_NUNCHUK) { + J |= StandardDPad(pad); + JumpButton = wp->btns_h & WPAD_BUTTON_B; + AttackButton = wp->btns_h & WPAD_BUTTON_A; + CharacterButton = wp->btns_h & WPAD_BUTTON_MINUS; + PauseButton = wp->btns_h & WPAD_BUTTON_PLUS; + DashButton = wp->btns_h & WPAD_NUNCHUK_BUTTON_C; + GrabButton = wp->btns_h & WPAD_NUNCHUK_BUTTON_Z; + ViewButton = wp->btns_h & WPAD_BUTTON_1; // doesn't do anything? + SpeedButton = wp->btns_h & WPAD_BUTTON_2; + } #endif + // Gamecube controls are based on One Piece Grand Adventure + { + u32 gc = PAD_ButtonsHeld(pad); + signed char gc_px = PAD_SubStickX(pad); + if (gc_px > 70) J |= VBA_SPEED; + JumpButton = JumpButton || gc & PAD_BUTTON_Y; + AttackButton = AttackButton || gc & PAD_BUTTON_A; + GrabButton = GrabButton || gc & PAD_BUTTON_B; + AttackUpButton = AttackUpButton || gc & PAD_BUTTON_X; + DashButton = DashButton || gc & PAD_TRIGGER_L; + PauseButton = PauseButton || gc & PAD_BUTTON_START; + CharacterButton = CharacterButton || gc & PAD_TRIGGER_R; // supposed to be block + } + + if (JumpButton) J |= VBA_BUTTON_A; + if (AttackButton) J |= VBA_BUTTON_B; + if (AttackUpButton) J |= VBA_UP | VBA_BUTTON_B; + if (CharacterButton) J |= VBA_BUTTON_L; + if (DashButton) J |= LastDir; + if (PauseButton) J |= VBA_BUTTON_START; + if (GrabButton) J |= VBA_BUTTON_R; + if (SpeedButton) J |= VBA_SPEED; + if (ViewButton) J |= VBA_BUTTON_SELECT; // doesn't do anything? + + if (J & VBA_RIGHT) LastDir = VBA_RIGHT; + else if (J & VBA_LEFT) LastDir = VBA_LEFT; + + return J; +} + diff --git a/source/ngc/gameinput.h b/source/ngc/gameinput.h index 4d1f60e..767c725 100644 --- a/source/ngc/gameinput.h +++ b/source/ngc/gameinput.h @@ -82,6 +82,8 @@ #define CORVETTE gid('A','V','C') +#define ONEPIECE gid('B','O','N') + u8 gbReadMemory(register u16 address); void gbWriteMemory(register u16 address, register u8 value); @@ -91,6 +93,18 @@ u32 StandardSideways(unsigned short pad); u32 StandardClassic(unsigned short pad); u32 StandardGamecube(unsigned short pad); u32 StandardKeyboard(unsigned short pad); +u32 DPadWASD(unsigned short pad); +u32 DPadArrowKeys(unsigned short pad); +u32 DecodeKeyboard(unsigned short pad); +u32 DecodeWiimote(unsigned short pad); +u32 DecodeClassic(unsigned short pad); +u32 DecodeGamecube(unsigned short pad); +u32 DecodeNunchuk(unsigned short pad); + +// For developers who don't have gamecube pads but need to test gamecube input +u32 PAD_ButtonsDownFake(unsigned short pad); +u32 PAD_ButtonsHeldFake(unsigned short pad); +u32 PAD_ButtonsUpFake(unsigned short pad); u32 MarioLand1Input(unsigned short pad); u32 MarioLand2Input(unsigned short pad); @@ -106,6 +120,7 @@ u32 Zelda2Input(unsigned short pad); u32 ALinkToThePastInput(unsigned short pad); u32 LinksAwakeningInput(unsigned short pad); u32 OracleOfAgesInput(unsigned short pad); +u32 OracleOfSeasonsInput(unsigned short pad); u32 MinishCapInput(unsigned short pad); u32 MetroidZeroInput(unsigned short pad); u32 Metroid1Input(unsigned short pad); @@ -132,6 +147,7 @@ u32 TwistedInput(unsigned short pad); u32 KirbyTntInput(unsigned short pad); u32 BoktaiInput(unsigned short pad); u32 Boktai2Input(unsigned short pad); +u32 OnePieceInput(unsigned short pad); #endif diff --git a/source/ngc/input.cpp b/source/ngc/input.cpp index 63b9997..31408fd 100644 --- a/source/ngc/input.cpp +++ b/source/ngc/input.cpp @@ -537,6 +537,160 @@ u32 StandardKeyboard(unsigned short pad) 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 * @@ -547,132 +701,138 @@ u32 StandardKeyboard(unsigned short pad) 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; - - // check for games that should have special Wii controls (uses wiimote + nunchuk) - if (GCSettings.WiiControls && wp->exp.type == WPAD_EXP_NUNCHUK) - { - 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: - case ORACLEOFSEASONS: - return OracleOfAgesInput(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: //CAKTODO move this somewhere not depended on WiiControls setting - return TwistedInput(pad); - - // Kirby - case KIRBYTNT: - case KIRBYTNTJ: - return KirbyTntInput(pad); - - // Boktai - case BOKTAI1: - return BoktaiInput(pad); - case BOKTAI2: - case BOKTAI3: - return Boktai2Input(pad); - } - } +#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); diff --git a/source/ngc/inputmario.cpp b/source/ngc/inputmario.cpp new file mode 100644 index 0000000..c2c61c6 --- /dev/null +++ b/source/ngc/inputmario.cpp @@ -0,0 +1,891 @@ +/**************************************************************************** + * Visual Boy Advance GX + * + * Carl Kenner Febuary 2009 + * + * gameinput.cpp + * + * Wii/Gamecube controls for individual games + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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" + +u32 MarioKartInput(unsigned short pad) { + u32 J = StandardMovement(pad); + static u32 frame = 0; +#ifdef HW_RVL + WPADData * wp = WPAD_Data(pad); + + u8 Health = 0; + static u8 OldHealth = 0; + float fraction; + + // Rumble when they lose health! + if (Health < OldHealth) + systemGameRumble(20); + OldHealth = Health; + + // Start/Select + if (wp->btns_h & WPAD_BUTTON_PLUS) + J |= VBA_BUTTON_START; + if (wp->btns_h & WPAD_BUTTON_MINUS) + J |= VBA_BUTTON_SELECT; + + if (wp->exp.type == WPAD_EXP_NONE) + { + // Use item + if (wp->btns_h & WPAD_BUTTON_RIGHT) + { + J |= VBA_BUTTON_L | VBA_UP; + J &= ~VBA_DOWN; + } + else if (wp->btns_h & WPAD_BUTTON_LEFT) + { + J |= VBA_BUTTON_L | VBA_DOWN; + J &= ~VBA_UP; + } + else if (wp->btns_h & WPAD_BUTTON_UP || wp->btns_h & WPAD_BUTTON_DOWN) + J |= VBA_BUTTON_L; + // Accelerate + if (wp->btns_h & WPAD_BUTTON_2) + J |= VBA_BUTTON_A; + // Brake + if (wp->btns_h & WPAD_BUTTON_1) + J |= VBA_BUTTON_B; + // Jump/Power slide + if (wp->btns_h & WPAD_BUTTON_A) + J |= VBA_BUTTON_R; + if (wp->btns_h & WPAD_BUTTON_B) + J |= VBA_BUTTON_R; + if (wp->orient.pitch> 12) { + fraction = (wp->orient.pitch - 12)/60.0f; + if ((frame % 60)/60.0f < fraction) + J |= VBA_LEFT; + } else if (wp->orient.pitch <- 12) { + fraction = -(wp->orient.pitch + 10)/60.0f; + if ((frame % 60)/60.0f < fraction) + J |= VBA_RIGHT; + } + } else if (wp->exp.type == WPAD_EXP_NUNCHUK) { + // Use item + if (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) + J |= VBA_BUTTON_L; + // Accelerate + if (wp->btns_h & WPAD_BUTTON_A) + J |= VBA_BUTTON_A; + // Brake + if (wp->btns_h & WPAD_BUTTON_B) + J |= VBA_BUTTON_B; + // Jump + if (fabs(wp->gforce.y)> 1.5 ) + J |= VBA_BUTTON_R; + if (wp->btns_h & WPAD_BUTTON_UP || wp->btns_h & WPAD_BUTTON_LEFT || wp->btns_h & WPAD_BUTTON_RIGHT || wp->btns_h & WPAD_BUTTON_DOWN) + J |= VBA_BUTTON_R; + } else if (wp->exp.type == WPAD_EXP_CLASSIC) { + // Use item + if (wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_L) + J |= VBA_BUTTON_L; + // Accelerate + if (wp->btns_h & WPAD_CLASSIC_BUTTON_A) + J |= VBA_BUTTON_A; + // Brake + if (wp->btns_h & WPAD_BUTTON_B) + J |= VBA_BUTTON_B; + // Jump + if (wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_R) + J |= VBA_BUTTON_R; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_UP || wp->btns_h & WPAD_CLASSIC_BUTTON_LEFT || wp->btns_h & WPAD_CLASSIC_BUTTON_RIGHT || wp->btns_h & WPAD_CLASSIC_BUTTON_DOWN) + J |= VBA_BUTTON_R; + // Start/Select + if (wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS) + J |= VBA_BUTTON_START; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS) + J |= VBA_BUTTON_SELECT; + } +#endif + + u32 gc = PAD_ButtonsHeld(pad); + if (gc & PAD_BUTTON_START) + J |= VBA_BUTTON_START; + if (gc & PAD_BUTTON_X || gc & PAD_BUTTON_Y) + J |= VBA_BUTTON_SELECT; + if (gc & PAD_BUTTON_A) + J |= VBA_BUTTON_A; + if (gc & PAD_BUTTON_B) + J |= VBA_BUTTON_B; + if (gc & PAD_TRIGGER_L) + J |= VBA_BUTTON_L; + if (gc & PAD_TRIGGER_R) + J |= VBA_BUTTON_R; + if (gc & PAD_BUTTON_UP || gc & PAD_BUTTON_DOWN || gc & PAD_BUTTON_LEFT + || gc & PAD_BUTTON_RIGHT) + J |= VBA_BUTTON_R; + + frame++; + + return J; +} + +u32 Mario1DXInput(unsigned short pad) { + u32 J = StandardMovement(pad) | DecodeGamecube(pad) | DecodeKeyboard(pad); +#ifdef HW_RVL + WPADData * wp = WPAD_Data(pad); + + bool run = false; + run = (wp->exp.type==WPAD_EXP_NUNCHUK && wp->exp.nunchuk.js.mag> 0.83) || (wp->exp.type==WPAD_EXP_CLASSIC && wp->exp.classic.ljs.mag> 0.83); + run = run && ((J & VBA_LEFT) || (J & VBA_RIGHT)); + + if (wp->exp.type==WPAD_EXP_NUNCHUK) { + // Pause + if (wp->btns_h & WPAD_BUTTON_PLUS) + J |= VBA_BUTTON_START; + // Select + if (wp->btns_h & WPAD_BUTTON_MINUS) + J |= VBA_BUTTON_SELECT; + + // Jump + if (wp->btns_h & WPAD_BUTTON_A) + J |= VBA_BUTTON_A; + // Run, pick up + if (wp->btns_h & WPAD_BUTTON_B || run) + J |= VBA_BUTTON_B; + // Starspin shoots when using fireflower + if (fabs(wp->gforce.x)> 1.5) + J |= VBA_BUTTON_B; + + // Camera (must come before Crouch) + if (!(wp->btns_h & WPAD_NUNCHUK_BUTTON_C)) + J &= ~(VBA_DOWN | VBA_UP); + if (wp->btns_h & WPAD_BUTTON_UP) + J |= VBA_UP; + if (wp->btns_h & WPAD_BUTTON_DOWN) + J |= VBA_DOWN; + // Crouch (must come after Camera) + if (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) + J |= VBA_DOWN; + + // Speed + if (wp->btns_h & WPAD_BUTTON_1 || wp->btns_h & WPAD_BUTTON_2) + J |= VBA_SPEED; + } else if (wp->exp.type == WPAD_EXP_CLASSIC) { + // Pause + if (wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS) + J |= VBA_BUTTON_START; + // Select + if (wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS) + J |= VBA_BUTTON_SELECT; + // Jump + if (wp->btns_h & WPAD_CLASSIC_BUTTON_B) + J |= VBA_BUTTON_A; + // Run, pick up, throw, fire + if (wp->btns_h & WPAD_CLASSIC_BUTTON_X || wp->btns_h & WPAD_CLASSIC_BUTTON_Y || run) + J |= VBA_BUTTON_B; + // Spin attack + if (wp->btns_h & WPAD_CLASSIC_BUTTON_A) + J |= VBA_BUTTON_B; + // Camera + J &= ~(VBA_DOWN | VBA_UP); + if (wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_L) + J |= VBA_DOWN; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_R) + J |= VBA_UP; + // Crouch + if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZL) { + J |= VBA_DOWN; + J &= ~VBA_UP; + } + // DPad movement/camera + if (wp->btns_h & WPAD_CLASSIC_BUTTON_UP) + J |= VBA_UP; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_DOWN) + J |= VBA_DOWN; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_LEFT) + J |= VBA_LEFT; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_RIGHT) + J |= VBA_RIGHT; + // Speed + if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZR) + J |= VBA_SPEED; + } else + J |= StandardSideways(pad); +#endif + return J; +} + +u32 Mario1ClassicInput(unsigned short pad) { + u32 J = StandardMovement(pad) | DecodeGamecube(pad) | DecodeKeyboard(pad); +#ifdef HW_RVL + WPADData * wp = WPAD_Data(pad); + + bool run = false; + + run = (wp->exp.type==WPAD_EXP_NUNCHUK && wp->exp.nunchuk.js.mag> 0.83) || (wp->exp.type==WPAD_EXP_CLASSIC && wp->exp.classic.ljs.mag> 0.83); + run = run && ((J & VBA_LEFT) || (J & VBA_RIGHT)); + + if (wp->exp.type==WPAD_EXP_NUNCHUK) { + J |= StandardDPad(pad); + // Pause + if (wp->btns_h & WPAD_BUTTON_PLUS) + J |= VBA_BUTTON_START; + // Select + if (wp->btns_h & WPAD_BUTTON_MINUS) + J |= VBA_BUTTON_SELECT; + + // Jump + if (wp->btns_h & WPAD_BUTTON_A) + J |= VBA_BUTTON_A; + // Run, pick up + if (wp->btns_h & WPAD_BUTTON_B || run) + J |= VBA_BUTTON_B; + // Starspin shoots when using fireflower + if (fabs(wp->gforce.x)> 1.5) + J |= VBA_BUTTON_B; + + // Crouch + if (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) { + J |= VBA_DOWN; + J &= ~VBA_UP; + } + + // Speed + if (wp->btns_h & WPAD_BUTTON_1 || wp->btns_h & WPAD_BUTTON_2) + J |= VBA_SPEED; + } else if (wp->exp.type == WPAD_EXP_CLASSIC) { + // DPad movement + J |= StandardDPad(pad); + // Pause + if (wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS) + J |= VBA_BUTTON_START; + // Select + if (wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS) + J |= VBA_BUTTON_SELECT; + // Jump + if (wp->btns_h & WPAD_CLASSIC_BUTTON_B) + J |= VBA_BUTTON_A; + // Run, pick up, throw, fire + if (wp->btns_h & WPAD_CLASSIC_BUTTON_X || wp->btns_h & WPAD_CLASSIC_BUTTON_Y || run) + J |= VBA_BUTTON_B; + // Spin attack + if (wp->btns_h & WPAD_CLASSIC_BUTTON_A) + J |= VBA_BUTTON_B; + // Crouch + if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZL || wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_L) + { + J |= VBA_DOWN; + J &= ~VBA_UP; + } + // Speed + if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZR) + J |= VBA_SPEED; + } else + J |= StandardSideways(pad); +#endif + return J; +} + +u32 MarioLand1Input(unsigned short pad) { + u32 J = StandardMovement(pad) | DecodeKeyboard(pad) | DecodeGamecube(pad); +#ifdef HW_RVL + WPADData * wp = WPAD_Data(pad); + bool run = false; + + run = (wp->exp.type==WPAD_EXP_NUNCHUK && wp->exp.nunchuk.js.mag> 0.83) || (wp->exp.type==WPAD_EXP_CLASSIC && wp->exp.classic.ljs.mag> 0.83); + run = run && ((J & VBA_LEFT) || (J & VBA_RIGHT)); + + if (wp->exp.type == WPAD_EXP_NONE) + J |= StandardSideways(pad); + else if (wp->exp.type == WPAD_EXP_CLASSIC) { + J |= StandardDPad(pad); + // Pause + if (wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS) + J |= VBA_BUTTON_START; + // Select + if (wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS) + J |= VBA_BUTTON_SELECT; + // Jump + if (wp->btns_h & WPAD_CLASSIC_BUTTON_B) + J |= VBA_BUTTON_A; + // Run, pick up, throw, fire + if (wp->btns_h & WPAD_CLASSIC_BUTTON_X || wp->btns_h & WPAD_CLASSIC_BUTTON_Y || run) + J |= VBA_BUTTON_B; + // Spin attack + if (wp->btns_h & WPAD_CLASSIC_BUTTON_A) + J |= VBA_BUTTON_B; + // Crouch + if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZL || wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_L) + { + J |= VBA_DOWN; + J &= ~VBA_UP; + } + // Speed + if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZR || wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_R) + J |= VBA_SPEED; + } else if (wp->exp.type == WPAD_EXP_NUNCHUK) { + J |= StandardDPad(pad); + // Pause + if (wp->btns_h & WPAD_BUTTON_PLUS) + J |= VBA_BUTTON_START; + // Select + if (wp->btns_h & WPAD_BUTTON_MINUS) + J |= VBA_BUTTON_SELECT; + // Jump + if (wp->btns_h & WPAD_BUTTON_A) + J |= VBA_BUTTON_A; + // Run, pick up, throw, fire + if (wp->btns_h & WPAD_BUTTON_B || run) + J |= VBA_BUTTON_B; + if (fabs(wp->gforce.x)> 1.5) + J |= VBA_BUTTON_B; + // Crouch + if (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) + J |= VBA_DOWN; + // Speed + if (wp->btns_h & WPAD_NUNCHUK_BUTTON_C || wp->btns_h & WPAD_BUTTON_1 || wp->btns_h & WPAD_BUTTON_2) + J |= VBA_SPEED; + } + else + J |= DecodeWiimote(pad); +#endif + + return J; +} + +u32 MarioLand2Input(unsigned short pad) { + u32 J = StandardMovement(pad) | DecodeKeyboard(pad) | DecodeGamecube(pad); +#ifdef HW_RVL + WPADData * wp = WPAD_Data(pad); + bool run = false; + + run = (wp->exp.type==WPAD_EXP_NUNCHUK && wp->exp.nunchuk.js.mag> 0.83) || (wp->exp.type==WPAD_EXP_CLASSIC && wp->exp.classic.ljs.mag> 0.83); + run = run && ((J & VBA_LEFT) || (J & VBA_RIGHT)); + + if (wp->exp.type == WPAD_EXP_NONE) + J |= StandardSideways(pad); + else if (wp->exp.type == WPAD_EXP_CLASSIC) { + J |= StandardDPad(pad); + // Pause + if (wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS) + J |= VBA_BUTTON_START; + // Select + if (wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS) + J |= VBA_BUTTON_SELECT; + // Jump + if (wp->btns_h & WPAD_CLASSIC_BUTTON_B) + J |= VBA_BUTTON_A; + // Run, pick up, throw, fire + if (wp->btns_h & WPAD_CLASSIC_BUTTON_X || wp->btns_h & WPAD_CLASSIC_BUTTON_Y || run) + J |= VBA_BUTTON_B; + // Spin attack + if (wp->btns_h & WPAD_CLASSIC_BUTTON_A) + J |= VBA_DOWN | VBA_BUTTON_A; + // Camera + if (wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_L) + J |= VBA_DOWN | VBA_BUTTON_B; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_R) + J |= VBA_UP | VBA_BUTTON_B; + // Crouch + if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZL && (!(wp->btns_h & WPAD_CLASSIC_BUTTON_A))) { + J |= VBA_DOWN; + // if the run button is held down, crouching also looks down + // which we don't want when using the Z button + J &= ~VBA_BUTTON_B; + J &= ~VBA_UP; + } + // Speed + if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZR) + J |= VBA_SPEED; + } else if (wp->exp.type == WPAD_EXP_NUNCHUK) { + // Pause + if (wp->btns_h & WPAD_BUTTON_PLUS) + J |= VBA_BUTTON_START; + // Select + if (wp->btns_h & WPAD_BUTTON_MINUS) + J |= VBA_BUTTON_SELECT; + // Jump + if (wp->btns_h & WPAD_BUTTON_A) + J |= VBA_BUTTON_A; + // Run, pick up, throw, fire + if (wp->btns_h & WPAD_BUTTON_B || run) + J |= VBA_BUTTON_B; + // Spin attack + if (fabs(wp->gforce.x)> 1.4) + J |= VBA_DOWN | VBA_BUTTON_A; + // Camera + if (wp->btns_h & WPAD_NUNCHUK_BUTTON_C) + J |= VBA_BUTTON_B; + if (wp->btns_h & WPAD_BUTTON_UP) + J |= VBA_BUTTON_B | VBA_UP; + if (wp->btns_h & WPAD_BUTTON_DOWN) + J |= VBA_BUTTON_B | VBA_DOWN; + if (wp->btns_h & WPAD_BUTTON_LEFT) + J |= VBA_BUTTON_B | VBA_LEFT; + if (wp->btns_h & WPAD_BUTTON_RIGHT) + J |= VBA_BUTTON_B | VBA_RIGHT; + // Crouch + if (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z && (!(wp->btns_h & WPAD_BUTTON_A))) { + J |= VBA_DOWN; + // if the run button is held down, crouching also looks down + // which we don't want when using the Z button + J &= ~VBA_BUTTON_B; + J &= ~VBA_UP; + } + // Speed + if (wp->btns_h & WPAD_BUTTON_1 || wp->btns_h & WPAD_BUTTON_2) + J |= VBA_SPEED; + } else + J |= DecodeWiimote(pad); +#endif + return J; +} + +u32 Mario2Input(unsigned short pad) +{ + u32 J = StandardMovement(pad) | DecodeGamecube(pad) | DecodeKeyboard(pad) | DecodeWiimote(pad); +#ifdef HW_RVL + WPADData * wp = WPAD_Data(pad); + bool run = false; + run = (wp->exp.type==WPAD_EXP_NUNCHUK && wp->exp.nunchuk.js.mag> 0.83) || (wp->exp.type==WPAD_EXP_CLASSIC && wp->exp.classic.ljs.mag> 0.83); + run = run && ((J & VBA_LEFT) || (J & VBA_RIGHT)); + + if (wp->exp.type == WPAD_EXP_NUNCHUK) { + // DPad looks around + if (wp->btns_h & WPAD_BUTTON_RIGHT) + J |= VBA_BUTTON_R; + if (wp->btns_h & WPAD_BUTTON_LEFT) + J |= VBA_BUTTON_L; + if (wp->btns_h & WPAD_BUTTON_UP) + J |= VBA_BUTTON_L; + if (wp->btns_h & WPAD_BUTTON_DOWN) + J |= VBA_BUTTON_L; + + // Pause + if (wp->btns_h & WPAD_BUTTON_PLUS) + J |= VBA_BUTTON_START; + // Select + if (wp->btns_h & WPAD_BUTTON_MINUS) + J |= VBA_BUTTON_SELECT; + + // Jump + if (wp->btns_h & WPAD_BUTTON_A) + J |= VBA_BUTTON_A; + // Run, pick up + if (wp->btns_h & WPAD_BUTTON_B) + J |= VBA_BUTTON_B; + if (fabs(wp->gforce.x)> 1.5) + J |= VBA_BUTTON_B; + + // Crouch + if (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) + J |= VBA_DOWN; + + if (wp->btns_h & WPAD_NUNCHUK_BUTTON_C) + J |= VBA_BUTTON_L; + if (wp->btns_h & WPAD_BUTTON_1) + J |= VBA_BUTTON_R; + if (wp->btns_h & WPAD_BUTTON_2) + J |= VBA_BUTTON_R; + } else if (wp->exp.type == WPAD_EXP_CLASSIC) { + // DPad movement + J |= StandardDPad(pad); + // Pause + if (wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS) + J |= VBA_BUTTON_START; + // Select + if (wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS) + J |= VBA_BUTTON_SELECT; + // Jump + if (wp->btns_h & WPAD_CLASSIC_BUTTON_B) + J |= VBA_BUTTON_A; + // Run, pick up, throw, fire + if (wp->btns_h & WPAD_CLASSIC_BUTTON_X || wp->btns_h & WPAD_CLASSIC_BUTTON_Y || run) + J |= VBA_BUTTON_B; + // Spin attack + if (wp->btns_h & WPAD_CLASSIC_BUTTON_A) + J |= VBA_BUTTON_A; + // R + if (wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_R) + J |= VBA_BUTTON_R; + // Crouch + if (wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_L || wp->btns_h & WPAD_CLASSIC_BUTTON_ZL) { + J |= VBA_DOWN; + J &= ~VBA_UP; + } + // Speed + if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZR) + J |= VBA_SPEED; + } +#endif + return J; +} + +u32 MarioWorldInput(unsigned short pad) { + u32 J = StandardMovement(pad) | DecodeGamecube(pad) | DecodeKeyboard(pad); + u8 CarryState = CPUReadByte(0x3003F06); // 01 = carrying, 00 = not carrying + u8 InYoshisMouth = CPUReadByte(0x3003F53); // FF = nothing, 00 = no level, else thing + u8 FallState = CPUReadByte(0x3003FA1); // 0B = jump, 24 = fall + u8 RidingYoshi = CPUReadByte(0x3004302); // 00 = not riding, 01 = riding + static bool NeedStomp = false; + bool dontrun = false; + bool run = false; + static bool dontletgo = false; + dontrun = (InYoshisMouth != 0 && InYoshisMouth != 0xFF && RidingYoshi); + bool BButton = false; +#ifdef HW_RVL + WPADData * wp = WPAD_Data(pad); + + run = (wp->exp.type==WPAD_EXP_NUNCHUK && wp->exp.nunchuk.js.mag> 0.83) || (wp->exp.type==WPAD_EXP_CLASSIC && wp->exp.classic.ljs.mag> 0.83); + BButton = (wp->exp.type == WPAD_EXP_CLASSIC && (wp->btns_h & WPAD_CLASSIC_BUTTON_X || wp->btns_h & WPAD_CLASSIC_BUTTON_Y)) || wp->btns_h & WPAD_BUTTON_B; +#endif + u32 gc = PAD_ButtonsHeld(pad); + BButton = BButton || gc & PAD_BUTTON_B; + if (run && CarryState && !BButton) + dontletgo = true; + if (!CarryState) + dontletgo = false; +#ifdef HW_RVL + if (wp->exp.type == WPAD_EXP_NUNCHUK) { + J |= StandardDPad(pad); + // Pause + if (wp->btns_h & WPAD_BUTTON_PLUS) + J |= VBA_BUTTON_START; + // Select + if (wp->btns_h & WPAD_BUTTON_MINUS) + J |= VBA_BUTTON_SELECT; + + // Jump + if (wp->btns_h & WPAD_BUTTON_A) + J |= VBA_BUTTON_A; + // Run, pick up + if ((run && !dontrun) || wp->btns_h & WPAD_BUTTON_B || dontletgo) + J |= VBA_BUTTON_B; + if (wp->btns_h & WPAD_BUTTON_B && dontletgo) { + J = J & ~VBA_BUTTON_B; + dontletgo = false; + } + // Spin attack + if (fabs(wp->gforce.x)> 1.5) + J |= VBA_BUTTON_R; + + // Butt stomp + if (FallState!=0 && (wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) && (!RidingYoshi)) + NeedStomp = true; + if (FallState!=0 && (wp->exp.type == WPAD_EXP_CLASSIC) && (wp->btns_h & WPAD_CLASSIC_BUTTON_ZL || wp->btns_h & WPAD_CLASSIC_BUTTON_ZR) && (!RidingYoshi)) + NeedStomp = true; + // Crouch + if (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) { + J |= VBA_DOWN; // Crouch + J &= ~VBA_UP; + } + + // Camera + if (wp->btns_h & WPAD_NUNCHUK_BUTTON_C) { + if (J & VBA_DOWN || J & VBA_UP) + J |= VBA_BUTTON_L; + else if (J & VBA_RIGHT || J & VBA_LEFT) { + J |= VBA_BUTTON_L; + J &= ~VBA_RIGHT; + J &= ~VBA_LEFT; + } + } + } else if (wp->exp.type == WPAD_EXP_CLASSIC) { + J |= StandardDPad(pad); + // Pause + if (wp->btns_h & WPAD_BUTTON_PLUS) + J |= VBA_BUTTON_START; + // Select + if (wp->btns_h & WPAD_BUTTON_MINUS) + J |= VBA_BUTTON_SELECT; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS) + J |= VBA_BUTTON_START; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS) + J |= VBA_BUTTON_SELECT; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_X || wp->btns_h & WPAD_CLASSIC_BUTTON_Y) + J |= VBA_BUTTON_B; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_B) + J |= VBA_BUTTON_A; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_A || wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_R) + J |= VBA_BUTTON_R; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_L) + J |= VBA_BUTTON_L; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZL || wp->btns_h & WPAD_CLASSIC_BUTTON_ZR) + { + J |= VBA_DOWN; // Crouch + J &= ~VBA_UP; + } + } + + BButton = (wp->exp.type == WPAD_EXP_CLASSIC && (wp->btns_h & WPAD_CLASSIC_BUTTON_X || wp->btns_h & WPAD_CLASSIC_BUTTON_Y)) || wp->btns_h & WPAD_BUTTON_B; +#endif + // Gamecube controller + if (gc & PAD_BUTTON_A) + J |= VBA_BUTTON_A; + if (gc & PAD_BUTTON_B) + J |= VBA_BUTTON_B; + if (gc & PAD_BUTTON_X) + J |= VBA_BUTTON_R; + if (gc & PAD_BUTTON_Y) + J |= VBA_BUTTON_SELECT; + if (gc & PAD_TRIGGER_R) + J |= VBA_BUTTON_R; + if (gc & PAD_TRIGGER_L) + J |= VBA_BUTTON_L; + if (gc & PAD_BUTTON_START) + J |= VBA_BUTTON_START; + if (gc & PAD_TRIGGER_Z) { + J |= VBA_DOWN; + J &= ~VBA_UP; + } + // if we try to use Yoshi's tongue while running, release run for one frame + if (run && BButton && !dontrun && !dontletgo) + J &= ~VBA_BUTTON_B; + if (NeedStomp && FallState == 0 && !RidingYoshi) { + J |= VBA_BUTTON_R; // spin attack only works when on ground + NeedStomp = false; + } + + return J; +} + +u32 Mario3Input(unsigned short pad) +{ + u32 J = StandardMovement(pad) | DecodeGamecube(pad) | DecodeKeyboard(pad); +#ifdef HW_RVL + WPADData * wp = WPAD_Data(pad); + bool run = false; + + run = (wp->exp.type==WPAD_EXP_NUNCHUK && wp->exp.nunchuk.js.mag> 0.83) || (wp->exp.type==WPAD_EXP_CLASSIC && wp->exp.classic.ljs.mag> 0.83); + run = run && ((J & VBA_LEFT) || (J & VBA_RIGHT)); + + if (wp->exp.type == WPAD_EXP_NONE) + J |= DecodeWiimote(pad); + else if (wp->exp.type == WPAD_EXP_CLASSIC) { + // DPad movement + J |= StandardDPad(pad); + // Pause + if (wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS) + J |= VBA_BUTTON_START; + // Select + if (wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS) + J |= VBA_BUTTON_L; + // Replay menu + if (wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_R) + J |= VBA_BUTTON_SELECT; + // Jump + if (wp->btns_h & WPAD_CLASSIC_BUTTON_B) + J |= VBA_BUTTON_A; + // Run, pick up, throw, fire + if (wp->btns_h & WPAD_CLASSIC_BUTTON_X || wp->btns_h & WPAD_CLASSIC_BUTTON_Y || run) + J |= VBA_BUTTON_B; + // Spin attack (racoon costume, fire flower) + if (wp->btns_h & WPAD_CLASSIC_BUTTON_A) + J |= VBA_BUTTON_B; + // Crouch + if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZL || wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_L) { + J |= VBA_DOWN; + J &= ~VBA_UP; + } + // Speed + if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZR) + J |= VBA_SPEED; + + } else if (wp->exp.type == WPAD_EXP_NUNCHUK) { + J |= StandardDPad(pad); + // Pause + if (wp->btns_h & WPAD_BUTTON_PLUS) + J |= VBA_BUTTON_START; + // Select + if (wp->btns_h & WPAD_BUTTON_MINUS) + J |= VBA_BUTTON_L; + // Replay Menu + if (wp->btns_h & WPAD_BUTTON_1) + J |= VBA_BUTTON_SELECT; + // Jump + if (wp->btns_h & WPAD_BUTTON_A) + J |= VBA_BUTTON_A; + // Run, pick up, throw, fire + if (wp->btns_h & WPAD_BUTTON_B || run) + J |= VBA_BUTTON_B; + // Spin attack (racoon, fire flower) + if (fabs(wp->gforce.x)> 1.4) + J |= VBA_BUTTON_B; + // Crouch + if (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) + { + J |= VBA_DOWN; + J &= ~VBA_UP; + } + // Speed + if (wp->btns_h & WPAD_BUTTON_2) + J |= VBA_SPEED; + } +#endif + + return J; +} + +u32 YoshiIslandInput(unsigned short pad) +{ + u32 J = StandardMovement(pad) | DecodeWiimote(pad) | DecodeGamecube(pad) | DecodeKeyboard(pad); + +#ifdef HW_RVL + WPADData * wp = WPAD_Data(pad); + if (wp->exp.type == WPAD_EXP_NUNCHUK) { + J |= StandardDPad(pad); + // Pause + if (wp->btns_h & WPAD_BUTTON_PLUS) + J |= VBA_BUTTON_START; + // Select + if (wp->btns_h & WPAD_BUTTON_MINUS) + J |= VBA_BUTTON_SELECT; + + // Jump + if (wp->btns_h & WPAD_BUTTON_A) + J |= VBA_BUTTON_A; + // Run, pick up + if (wp->btns_h & WPAD_BUTTON_B) + J |= VBA_BUTTON_B; + // throw + if (wp->btns_h & WPAD_BUTTON_1 || wp->btns_h & WPAD_BUTTON_2) + J |= VBA_BUTTON_R; + + // Crouch, lay egg + if (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) { + J |= VBA_DOWN; // Crouch + J &= ~VBA_UP; + } + + // Camera + if (wp->btns_h & WPAD_NUNCHUK_BUTTON_C) + J |= VBA_BUTTON_L; + + } else if (wp->exp.type == WPAD_EXP_CLASSIC) { + J |= StandardDPad(pad); + if (wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS) + J |= VBA_BUTTON_START; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS) + J |= VBA_BUTTON_SELECT; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_X) + J |= VBA_BUTTON_B; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_Y) + J |= VBA_BUTTON_R; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_B) + J |= VBA_BUTTON_A; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_A || wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_R) + J |= VBA_BUTTON_R; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_L) + J |= VBA_BUTTON_L; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZL || wp->btns_h & WPAD_CLASSIC_BUTTON_ZR) + { + J |= VBA_DOWN; // Crouch + J &= ~VBA_UP; + } + } +#endif + // Gamecube controller + { + u32 gc = PAD_ButtonsHeld(pad); + if (gc & PAD_BUTTON_A) + J |= VBA_BUTTON_A; + if (gc & PAD_BUTTON_B) + J |= VBA_BUTTON_B; + if (gc & PAD_BUTTON_X) + J |= VBA_BUTTON_R; + if (gc & PAD_BUTTON_Y) + J |= VBA_BUTTON_SELECT; + if (gc & PAD_TRIGGER_R) + J |= VBA_BUTTON_R; + if (gc & PAD_TRIGGER_L) + J |= VBA_BUTTON_L; + if (gc & PAD_BUTTON_START) + J |= VBA_BUTTON_START; + if (gc & PAD_TRIGGER_Z) { + J |= VBA_DOWN; + J &= ~VBA_UP; + } + } + return J; +} + +u32 UniversalGravitationInput(unsigned short pad) { + TiltScreen = true; + u32 J = StandardMovement(pad) | DecodeGamecube(pad) | DecodeKeyboard(pad); +#ifdef HW_RVL + WPADData * wp = WPAD_Data(pad); + if (wp->exp.type == WPAD_EXP_NUNCHUK) { + J |= StandardDPad(pad); + TiltSideways = false; + // Pause + if (wp->btns_h & WPAD_BUTTON_PLUS) + J |= VBA_BUTTON_START; + // Select, L & R do nothing! + if (wp->btns_h & WPAD_BUTTON_MINUS) + J |= VBA_BUTTON_SELECT; + if (wp->btns_h & WPAD_BUTTON_1) + J |= VBA_BUTTON_L | VBA_SPEED; + if (wp->btns_h & WPAD_BUTTON_2) + J |= VBA_BUTTON_R | VBA_SPEED; + + // Jump + if (wp->btns_h & WPAD_BUTTON_A) + J |= VBA_BUTTON_A; + // tongue + if (wp->btns_h & WPAD_BUTTON_B) + J |= VBA_BUTTON_B; + // Crouch, butt stomp + if (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) { + J |= VBA_DOWN; // Crouch + J &= ~VBA_UP; + } + // Camera + if (wp->btns_h & WPAD_NUNCHUK_BUTTON_C) { + J |= VBA_UP; + } + } + else if (wp->exp.type == WPAD_EXP_CLASSIC) { + TiltSideways = false; + J |= StandardDPad(pad); + // A bit stupid playing with the classic controller, but nevermind. + if (wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS) + J |= VBA_BUTTON_START; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS) + J |= VBA_BUTTON_SELECT; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_X) + J |= VBA_BUTTON_B; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_Y) + J |= VBA_BUTTON_R; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_B || wp->btns_h & WPAD_CLASSIC_BUTTON_A) + J |= VBA_BUTTON_A; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_L || wp->btns_h & WPAD_CLASSIC_BUTTON_ZL) + J |= VBA_DOWN; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_R) + J |= VBA_UP; + if (WPAD_CLASSIC_BUTTON_ZR) + J |= VBA_SPEED; + } else { + J |= StandardSideways(pad); + TiltSideways = true; + } +#endif + return J; +} + diff --git a/source/ngc/inputmetroid.cpp b/source/ngc/inputmetroid.cpp new file mode 100644 index 0000000..1afd93f --- /dev/null +++ b/source/ngc/inputmetroid.cpp @@ -0,0 +1,655 @@ +/**************************************************************************** + * Visual Boy Advance GX + * + * Carl Kenner Febuary 2009 + * + * gameinput.cpp + * + * Wii/Gamecube controls for individual games + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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" + +u32 MetroidZeroInput(unsigned short pad) { + u32 J = StandardMovement(pad) | DecodeGamecube(pad) | DecodeClassic(pad) | DecodeKeyboard(pad); + u8 BallState = CPUReadByte(0x30015df); // 0 = stand, 1 = crouch, 2 = ball + u16 Health = CPUReadByte(0x3001536); // 0 = stand, 1 = crouch, 2 = ball + static u16 OldHealth = 0; + + // Rumble when they lose health! + if (Health < OldHealth) + systemGameRumble(20); + OldHealth = Health; + + static int Morph = 0; + static int AimCount = 0; + static int MissileCount = 0; + + if (BallState == 2) // Can't exit morph ball without pressing C! + J &= ~VBA_UP; + if (BallState == 1) // Can't enter morph ball without pressing C! + J &= ~VBA_DOWN; + +#ifdef HW_RVL + WPADData * wp = WPAD_Data(pad); + + 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) + J |= VBA_BUTTON_START; + // Hyper (toggle super missiles) + if (wp->btns_h & WPAD_BUTTON_PLUS) + J |= VBA_BUTTON_SELECT; + // 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)) + ; + + // Jump + if (wp->btns_h & WPAD_BUTTON_B && BallState!=2) + J |= VBA_BUTTON_A; + else if (BallState==2 && fabs(wp->gforce.y)> 1.5) + J |= VBA_BUTTON_A; + // Fire + if (wp->btns_h & WPAD_BUTTON_A) + 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 !=2) { + J |= VBA_UP; + AimCount = 0; + } else if (wp->orient.pitch < -22 && BallState !=2) { + if (AimCount>=0) AimCount = -1; + } else if (wp->orient.pitch> 45 && BallState ==0) { + if (AimCount<10) AimCount=10; + } else if (wp->orient.pitch> 22 && BallState !=2) { + if (AimCount<=0 || AimCount>=10) AimCount = 1; + } else { + AimCount=0; + } + + // Morph Ball + if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_d & WPAD_NUNCHUK_BUTTON_C)) { + if (BallState == 2) { // ball + Morph = -1; + } else if (BallState == 1) { + 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: + J |= VBA_BUTTON_A; + AimCount++; + break; + case 11: + J |= VBA_DOWN; + AimCount++; + break; + case 12: + 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) { + 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; + } +#endif + + return J; +} + +u32 MetroidFusionInput(unsigned short pad) { + u32 J = StandardMovement(pad) | DecodeGamecube(pad) | DecodeClassic(pad) | DecodeKeyboard(pad); + u8 BallState = CPUReadByte(0x3001329); // 0 = stand, 2 = crouch, 5 = ball + u16 Health = CPUReadHalfWord(0x3001310); + static u16 OldHealth = 0; + + // Rumble when they lose health! + if (Health < OldHealth) + systemGameRumble(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; + +#ifdef HW_RVL + 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; + } +#endif + + 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) { + 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; + } + + return J; +} + +u32 Metroid1Input(unsigned short pad) { + u32 J = StandardMovement(pad) | DecodeGamecube(pad) | DecodeClassic(pad) | DecodeKeyboard(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; + + // Rumble when they lose health! + if (Health < OldHealth) + systemGameRumble(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; + +#ifdef HW_RVL + 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; + } +#endif + 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; + } + + return J; +} + +u32 Metroid2Input(unsigned short pad) { + u32 J = StandardMovement(pad) | DecodeGamecube(pad) | DecodeClassic(pad) | DecodeKeyboard(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; + + // Rumble when they lose (or gain) health! (since I'm not checking energy tanks) + if (Health != OldHealth) + systemGameRumble(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; + +#ifdef HW_RVL + 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; + } +#endif + + 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; + } + + return J; +} + diff --git a/source/ngc/inputzelda.cpp b/source/ngc/inputzelda.cpp new file mode 100644 index 0000000..02cd4c0 --- /dev/null +++ b/source/ngc/inputzelda.cpp @@ -0,0 +1,1654 @@ +/**************************************************************************** + * Visual Boy Advance GX + * + * Carl Kenner Febuary 2009 + * + * inputzelda.cpp + * + * Wii/Gamecube controls for Legend of Zelda games + ***************************************************************************/ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#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" + +u8 ZeldaDxLeftPos = 2, ZeldaDxRightPos = 3, ZeldaDxDownPos = 4; +u8 ZeldaDxShieldPos = 5, ZeldaDxSwordPos = 5, ZeldaDxBraceletPos = 5; + +void ZeldaSwap(u8 pos1, u8 pos2, u16 addr) +{ + u8 OldItem = gbReadMemory(addr + pos1); + gbWriteMemory(addr + pos1, gbReadMemory(addr + pos2)); + gbWriteMemory(addr + pos2, OldItem); +} + +u8 DrawnItemPos = 0xFF; + +bool ZeldaDrawItem(u8 ItemNumber, u16 addr, int boxes) +{ + if (gbReadMemory(addr + 1) == ItemNumber) + return true; + DrawnItemPos = 0xFF; + for (int i = 0; i < boxes; i++) + { + if (gbReadMemory(addr + i) == ItemNumber) + { + DrawnItemPos = i; + } + } + if (DrawnItemPos == 0xFF) + return false; + if (DrawnItemPos != 1) + { + + gbWriteMemory(addr + DrawnItemPos, gbReadMemory(addr + 1)); // put A item away + gbWriteMemory(addr + 1, ItemNumber); // set A item to shield + } + return true; +} + +bool ZeldaDxDrawBombs() +{ + if (gbReadMemory(0xDB00 + 1) == 2) + return true; + ZeldaDxShieldPos = 0xFF; + for (int i = 0; i <= 11; i++) + { + if (gbReadMemory(0xDB00 + i) == 2) + { + ZeldaDxShieldPos = i; + } + } + if (ZeldaDxShieldPos == 0xFF) + return false; + if (ZeldaDxShieldPos != 2) + { + + gbWriteMemory(0xDB00 + ZeldaDxShieldPos, gbReadMemory(0xDB00 + 1)); // put A item away + gbWriteMemory(0xDB00 + 1, 2); // set A item to bombs + } + return true; +} + +bool ZeldaDxDrawSword() +{ + if (gbReadMemory(0xDB00 + 1) == 1) + return true; + ZeldaDxSwordPos = 0xFF; + for (int i = 0; i <= 11; i++) + { + if (gbReadMemory(0xDB00 + i) == 1) + { + ZeldaDxSwordPos = i; + } + } + if (ZeldaDxSwordPos == 0xFF) + return false; + if (ZeldaDxSwordPos != 1) + { + gbWriteMemory(0xDB00 + ZeldaDxSwordPos, gbReadMemory(0xDB00 + 1)); // put A item away + gbWriteMemory(0xDB00 + 1, 1); // set A item to sword + } + return true; +} + +void ZeldaDxSheathSword() +{ + if (ZeldaDxSwordPos == 0xFF || gbReadMemory(0xDB00 + 1) != 1) + return; + gbWriteMemory(0xDB00 + 1, gbReadMemory(0xDB00 + ZeldaDxSwordPos)); + gbWriteMemory(0xDB00 + ZeldaDxSwordPos, 1); + ZeldaDxSwordPos = 0xFF; +} + +void ZeldaDxCheat() +{ + gbWriteMemory(0xDB00 + 11, 0); + for (int i = 0; i <= 10; i++) + { + gbWriteMemory(0xDB00 + i, i + 1); + } + gbWriteMemory(0xDB15, 5); // leaves + gbWriteMemory(0xDB43, 3); // bracelet level + gbWriteMemory(0xDB44, 3); // shield level + gbWriteMemory(0xDB45, 0x30); // arrows + gbWriteMemory(0xDB49, 7); // songs + gbWriteMemory(0xDB4C, 0x30); // powder + gbWriteMemory(0xDB4D, 0x30); // bombs + gbWriteMemory(0xDB4E, 3); // sword level + gbWriteMemory(0xDB5D, 0x9); // rupees + gbWriteMemory(0xDB5E, 0x99); // rupees + gbWriteMemory(0xDBD0, 1); // keys +} + +void ZeldaAgesCheat() +{ + int j = 1; + for (int i = 0; i <= 14; i++, j++) + { + switch(j) { + case 2: case 0xb: case 0x10: case 0x18: + j++; + break; + case 7: case 0x12: + j+=3; + } + gbWriteMemory(0xC688 + i, j); + } + gbWriteMemory(0xC697, 0); + gbWriteMemory(0xC698, 0); + gbWriteMemory(0xC699, 0); + gbWriteMemory(0xC6AF, 3); // shield + gbWriteMemory(0xC6B2, 3); // sword + gbWriteMemory(0xC6B6, 2); // long shot? + gbWriteMemory(0xC6B7, 3); // harp's chosen song + gbWriteMemory(0xC6B8, 2); // power glove + for (j=0xC69F; j<=0xC6A2; j++) gbWriteMemory(j, 0xFF); // secondary items + gbWriteMemory(0xC6A3, 0x0C); // mermaid suit + for (j=0xC6A4; j<=0xC6A5; j++) gbWriteMemory(j, 0xFF); // secondary items, Brother emblem + for (j=0xC6B9; j<=0xC6BD; j++) gbWriteMemory(j, 0x05); // seeds + gbWriteMemory(0xC6BF, 0xFF); // essences + gbWriteMemory(0xCF14, 0xEA); // GBA shop +} + +void ZeldaSeasonsCheat() +{ + gbWriteMemory(0xC68F, 0); + gbWriteMemory(0xC690, 0); + gbWriteMemory(0xC691, 0); + int j = 1; + for (int i = 0; i <= 16; i++, j++) + { + switch(j) { + case 2: case 4: case 9: case 0xb: case 0x14: case 0x18: + j++; + break; + case 0xF: case 0x1a: + j+=4; + } + gbWriteMemory(0xC680 + i, j); + } + for (j=0xC696; j<=0xC69C; j++) gbWriteMemory(j, 0xFF); // secondary items + gbWriteMemory(0xC6A9, 3); // shield + gbWriteMemory(0xC6AA, 9); // bombs + gbWriteMemory(0xC6AC, 3); // sword + gbWriteMemory(0xC6B0, 0xF); // rod of seasons + gbWriteMemory(0xC6B1, 2); // boomerang + gbWriteMemory(0xC6B2, 2); // ? + gbWriteMemory(0xC6B3, 2); // sling shot + gbWriteMemory(0xC6B4, 2); // feather/cape + for (j=0xC6B5; j<=0xC6BA; j++) gbWriteMemory(j, 0x05); // seeds + gbWriteMemory(0xC6BF, 0xFF); // essences + gbWriteMemory(0xC6C6, 3); // ring box + gbWriteMemory(0xCF14, 0xEA); // GBA shop +} + +u32 LinksAwakeningInput(unsigned short pad) // aka Zelda DX +{ + u16 ItemsAddr = 0xDB00; + static bool QuestScreen = false; + static int StartCount = 0; + static int SwordCount = 0; + static bool BombArrows = false; + static int DelayCount = 0; + bool OnItemScreen = gbReadMemory(0xC16C) == 0x20; // 0x20 = items, 0x10 = normal + + // There are no Zelda games for PC, so let user choose keyboard controls. + // There is Zelda 1 & 2 for Wii VC wiimote but it doesn't make sense to use their controls, + // so let user choose sideways wiimote controls. + u32 J = StandardMovement(pad) | DecodeKeyboard(pad) | DecodeWiimote(pad); + + u8 CursorPos = gbReadMemory(0xC1B6) + 2; + u8 SelItem = 0; + if (CursorPos < 12) + SelItem = gbReadMemory(ItemsAddr + CursorPos); + + // Rumble when they lose health! + u8 Health = gbReadMemory(0xDB5A); + static u8 OldHealth = 0; + if (Health < OldHealth) + systemGameRumble(20); + OldHealth = Health; + + bool ActionButton=0, SwordButton=0, ShieldButton=0, PullButton=0, + ItemsButton=0, QuestButton=0, MapButton=0, SpeedButton=0, CheatButton=0, MidnaButton=0, +#ifdef HW_RVL + LeftItemButton=0, DownItemButton=0, RightItemButton=0, +#endif + BItemButton=0, UseLeftItemButton=0, UseRightItemButton=0; + +#ifdef HW_RVL + WPADData * wp = WPAD_Data(pad); + // Nunchuk controls are based on Twilight Princess for the Wii + if (wp->exp.type == WPAD_EXP_NUNCHUK) { + ActionButton = wp->btns_h & WPAD_BUTTON_A; + ShieldButton = wp->btns_h & WPAD_NUNCHUK_BUTTON_Z; + SpeedButton = wp->btns_h & WPAD_NUNCHUK_BUTTON_C; + MidnaButton = wp->btns_h & WPAD_BUTTON_UP; + LeftItemButton = wp->btns_d & WPAD_BUTTON_LEFT; + DownItemButton = wp->btns_d & WPAD_BUTTON_DOWN; + RightItemButton = wp->btns_d & WPAD_BUTTON_RIGHT; + BItemButton = wp->btns_h & WPAD_BUTTON_B; + ItemsButton = wp->btns_h & WPAD_BUTTON_MINUS; + QuestButton = wp->btns_h & WPAD_BUTTON_PLUS; + MapButton = wp->btns_h & WPAD_BUTTON_1; + UseLeftItemButton = UseRightItemButton = false; + CheatButton = wp->btns_h & WPAD_BUTTON_2; + + // Sword + SwordButton = false; + if (fabs(wp->gforce.x)> 1.5 && !OnItemScreen) { + if (ZeldaDxDrawSword()) { + if (SwordCount<3) SwordCount = 3; + } + QuestScreen = false; + } + // Spin attack + if (fabs(wp->exp.nunchuk.gforce.x)> 0.6 && !OnItemScreen) { + if (ZeldaDxDrawSword()) { + if (SwordCount<60) SwordCount=60; + } + QuestScreen = false; + } + if (SwordCount>0) { + if (SwordCount == 50) + systemGameRumbleOnlyFor(50); + if (!OnItemScreen) + SwordButton = true; + SwordCount--; + } + // Classic controller controls are loosely based on Ocarina of Time virtual console + // but with R as the B button like in Twilight Princess + } else if (wp->exp.type == WPAD_EXP_CLASSIC) { + J |= StandardDPad(pad); + signed char wm_sx = WPAD_Stick(pad,1,0); // CC right joystick + signed char wm_sy = WPAD_Stick(pad,1,1); // CC right joystick + static bool StickReady = true; + ActionButton = wp->btns_h & WPAD_CLASSIC_BUTTON_A; + SwordButton = wp->btns_h & WPAD_CLASSIC_BUTTON_B; + ShieldButton = wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_L || wp->exp.classic.ls_raw >= 0x10; + LeftItemButton = wp->btns_d & WPAD_CLASSIC_BUTTON_ZR || (StickReady && wm_sx < -70); + DownItemButton = wp->btns_d & WPAD_CLASSIC_BUTTON_Y || (StickReady && wm_sy < -70); + RightItemButton = wp->btns_d & WPAD_CLASSIC_BUTTON_X || (StickReady && wm_sx > 70); + MidnaButton = wm_sy > 70; // right stick up + if (abs(wm_sx)>70 || abs(wm_sy)>70) StickReady = false; + else if (abs(wm_sx)<50 && abs(wm_sy)<50) StickReady = true; + BItemButton = wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_R || wp->exp.classic.rs_raw >= 0x10; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS) + J |= VBA_BUTTON_START; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS) + J |= VBA_BUTTON_SELECT; + SpeedButton = wp->btns_h & WPAD_CLASSIC_BUTTON_ZL; + // Must use Wiimote for these buttons + CheatButton = wp->btns_d & WPAD_BUTTON_2; + } + CheatButton = CheatButton || DownUsbKeys[KB_C]; +#endif + // Gamecube controls are based on Twilight Princess for the Gamecube + { + u32 gc = PAD_ButtonsHeld(pad); + signed char gc_px = PAD_SubStickX(pad); + if (gc_px > 70) J |= VBA_SPEED; + ActionButton = ActionButton || gc & PAD_BUTTON_A; + PullButton = PullButton || gc & PAD_TRIGGER_R; + SwordButton = SwordButton || gc & PAD_BUTTON_B; + ShieldButton = ShieldButton || gc & PAD_TRIGGER_L; + MidnaButton = MidnaButton || gc & PAD_TRIGGER_Z; + UseLeftItemButton = UseLeftItemButton || gc & PAD_BUTTON_Y; + UseRightItemButton = UseRightItemButton || gc & PAD_BUTTON_X; + ItemsButton = ItemsButton || gc & PAD_BUTTON_UP; + QuestButton = QuestButton || gc & PAD_BUTTON_START; + MapButton = MapButton || gc & PAD_BUTTON_RIGHT; + SpeedButton = SpeedButton || gc & PAD_BUTTON_DOWN; + CheatButton = CheatButton || gc & PAD_BUTTON_LEFT; + } + + // Action button, and put away sword + if (ActionButton) { + if (QuestScreen && OnItemScreen) { + if (StartCount>=0) StartCount = -80; + } else { + if (OnItemScreen) systemGameRumble(5); + else { + // Unless they are trying to use 2 items at once, put away A item + if (!BItemButton && !UseLeftItemButton && !UseRightItemButton) { + if (!ZeldaDrawItem(0, ItemsAddr, 12)) // draw nothing if possible + ZeldaDrawItem(4, ItemsAddr, 12); // or draw shield + } + } + J |= VBA_BUTTON_A; + } + } + // Sword button + if (SwordButton) { + if (ZeldaDxDrawSword()) + J |= VBA_BUTTON_A; + } + // Pull button (Gamecube R Trigger) automatically switches to bracelet + if (PullButton) { + if (ZeldaDrawItem(3, ItemsAddr, 12)) + J |= VBA_BUTTON_A; + } + // Shield and Z targetting + if (ShieldButton && !OnItemScreen) { + if (!SwordCount) { + if (ZeldaDrawItem(4, ItemsAddr, 12)) + J |= VBA_BUTTON_A; + } + QuestScreen = false; + } + // Z Button Selects bomb arrows on or off + if (ShieldButton && OnItemScreen) { + if (SelItem==2 || SelItem==5) { // toggle bomb arrows + BombArrows = !BombArrows; + if (BombArrows) systemGameRumbleOnlyFor(16); + else systemGameRumbleOnlyFor(4); + if (SelItem==2 && BombArrows) + J |= VBA_BUTTON_A; + } else if (BombArrows) { // switch off bomb arrows + BombArrows = false; + systemGameRumbleOnlyFor(4); + J |= VBA_BUTTON_A; + } + QuestScreen = false; + } + + + static bool BIsLeft = true; + if (UseLeftItemButton) + { + if (!BIsLeft) { + // Swap B with first inventory item + ZeldaSwap(0, ZeldaDxLeftPos, ItemsAddr); + BIsLeft = true; + } + if (OnItemScreen) { + systemGameRumbleOnlyFor(5); + J |= VBA_BUTTON_B; + } else { + u8 BButtonItem = gbReadMemory(ItemsAddr); + if (BombArrows && (BButtonItem==5)) { + if (ZeldaDrawItem(2, ItemsAddr, 12)) { + J |= VBA_BUTTON_A; + DelayCount++; + } + } + else DelayCount = 10; + if (DelayCount>1) + J |= VBA_BUTTON_B; + } + QuestScreen = false; + } + if (UseRightItemButton) + { + if (BIsLeft) { + // Swap B with first inventory item + ZeldaSwap(0, ZeldaDxLeftPos, ItemsAddr); + BIsLeft = false; + } + if (OnItemScreen) { + systemGameRumbleOnlyFor(5); + J |= VBA_BUTTON_B; + } else { + u8 BButtonItem = gbReadMemory(ItemsAddr); + if (BombArrows && (BButtonItem==5)) { + if (ZeldaDrawItem(2, ItemsAddr, 12)) { + J |= VBA_BUTTON_A; + DelayCount++; + } + } + else DelayCount = 10; + if (DelayCount>1) + J |= VBA_BUTTON_B; + } + QuestScreen = false; + } + +#ifdef HW_RVL + // Left Item + if (LeftItemButton) { + if (OnItemScreen) ZeldaSwap(ZeldaDxLeftPos, CursorPos, ItemsAddr); + else ZeldaSwap(0, ZeldaDxLeftPos, ItemsAddr); + systemGameRumbleOnlyFor(5); + QuestScreen = false; + } + // Right Item + if (RightItemButton) { + if (OnItemScreen) ZeldaSwap(ZeldaDxRightPos, CursorPos, ItemsAddr); + else ZeldaSwap(0, ZeldaDxRightPos, ItemsAddr); + systemGameRumbleOnlyFor(5); + QuestScreen = false; + } + // Down Item + if (DownItemButton) { + if (OnItemScreen) ZeldaSwap(ZeldaDxDownPos, CursorPos, ItemsAddr); + else ZeldaSwap(0, ZeldaDxDownPos, ItemsAddr); + systemGameRumbleOnlyFor(5); + QuestScreen = false; + } + // B Item + if (BItemButton) { + if (QuestScreen && OnItemScreen) { + if (StartCount>=0) StartCount = -80; + } else { + if (OnItemScreen) { + /*if (BombArrows) { + if (SelItem==5) { // bow + } else { + BombArrows = false; + } + }*/ + systemGameRumble(5); + DelayCount = 10; + } else { + u8 BButtonItem = gbReadMemory(ItemsAddr); + if (BombArrows && (BButtonItem==5)) { + if (ZeldaDrawItem(2, ItemsAddr, 12)) { + J |= VBA_BUTTON_A; + DelayCount++; + } + } else DelayCount = 10; + } + if (DelayCount>1) + J |= VBA_BUTTON_B; + } + } +#endif + if (!BItemButton && !UseLeftItemButton && !UseRightItemButton) + DelayCount = 0; + + // Talk to Midna, er... I mean save the game + if (MidnaButton) { + J |= VBA_BUTTON_A | VBA_BUTTON_B | VBA_BUTTON_START | VBA_BUTTON_SELECT; + systemGameRumbleOnlyFor(5); + QuestScreen = false; + } + // Map + if (MapButton) { + QuestScreen = false; + J |= VBA_BUTTON_SELECT; + } + // Items + if (ItemsButton) { + if (QuestScreen) QuestScreen = false; + else J |= VBA_BUTTON_START; + } + // Quest Status + if (QuestButton) { + StartCount = 80; + if (OnItemScreen) StartCount = -StartCount; + } + if (StartCount>0) { + if (StartCount>75) + J |= VBA_BUTTON_START; + StartCount--; + if (StartCount==0) QuestScreen = true; + } + else if (StartCount<0) + { + QuestScreen = false; + if (StartCount>=-5) + J |= VBA_BUTTON_START; + StartCount++; + } + if (QuestScreen && OnItemScreen) + J |= VBA_BUTTON_SELECT; + + // Cheat + if (CheatButton) { + ZeldaDxCheat(); + QuestScreen = false; + } + // Camera (fast forward) + if (SpeedButton) { + J |= VBA_SPEED; + QuestScreen = false; + } + + return J; +} + +static u32 ZeldaOracleInput(bool Seasons, unsigned short pad) { + u16 ItemsAddr; + if (Seasons) ItemsAddr = 0xC680; + else ItemsAddr = 0xC688; + static u32 OldJ = 0; + // There are no Zelda games for PC, so let user choose keyboard controls. + // There is Zelda 1 & 2 for Wii VC wiimote but it doesn't make sense to use their controls, + // so let user choose sideways wiimote controls. + u32 J = StandardMovement(pad) | DecodeKeyboard(pad) | DecodeWiimote(pad); + + // Rumble when they lose health! + u8 Health; + if (Seasons) Health = gbReadMemory(0xC6A2); // health in quarters... note C6A3 is max health + else Health = gbReadMemory(0xC6AA); // health in quarters... note C6AB is max health + static u8 OldHealth = 0; + if (Health < OldHealth) + systemGameRumble(20); + OldHealth = Health; + + static int DesiredSubscreen = -1; + int Subscreen = 0; + switch (gbReadMemory(0xCBCB)) { + case 0: + Subscreen = 0; + break; + case 1: + Subscreen = 1+gbReadMemory(0xCBCF); + break; + case 2: + Subscreen = 4; + break; + case 3: + Subscreen = 5; + break; + } + + bool ActionButton=0, SwordButton=0, ShieldButton=0, PullButton=0, + ItemsButton=0, QuestButton=0, MapButton=0, SpeedButton=0, CheatButton=0, MidnaButton=0, +#ifdef HW_RVL + LeftItemButton=0, DownItemButton=0, RightItemButton=0, BItemButton=0, +#endif + UseLeftItemButton=0, UseRightItemButton=0; + + bool OnItemScreen = (Subscreen == 1); + +#ifdef HW_RVL + static int SwordCount = 0; + WPADData * wp = WPAD_Data(pad); + // Nunchuk controls are based on Twilight Princess for the Wii + if (wp->exp.type == WPAD_EXP_NUNCHUK) { + ActionButton = wp->btns_h & WPAD_BUTTON_A; + ShieldButton = wp->btns_h & WPAD_NUNCHUK_BUTTON_Z; + SpeedButton = wp->btns_h & WPAD_NUNCHUK_BUTTON_C; + MidnaButton = wp->btns_d & WPAD_BUTTON_UP; + LeftItemButton = wp->btns_d & WPAD_BUTTON_LEFT; + DownItemButton = wp->btns_d & WPAD_BUTTON_DOWN; + RightItemButton = wp->btns_d & WPAD_BUTTON_RIGHT; + BItemButton = wp->btns_h & WPAD_BUTTON_B; + ItemsButton = wp->btns_d & WPAD_BUTTON_MINUS; + QuestButton = wp->btns_d & WPAD_BUTTON_PLUS; + MapButton = wp->btns_d & WPAD_BUTTON_1; + CheatButton = wp->btns_d & WPAD_BUTTON_2; + // Sword + SwordButton = false; + if (fabs(wp->gforce.x)> 1.5 && !OnItemScreen) + { + if (SwordCount<3) SwordCount = 3; + } + // Spin attack + if (fabs(wp->exp.nunchuk.gforce.x)> 0.6 && !OnItemScreen) + { + if (SwordCount<60) SwordCount=60; + } + if (SwordCount>0) + { + if (SwordCount == 50) + systemGameRumbleOnlyFor(50); + if (!OnItemScreen) + SwordButton = true; + SwordCount--; + } + // Classic controller controls are loosely based on Ocarina of Time virtual console + // but with R as the B button like in Twilight Princess + } else if (wp->exp.type == WPAD_EXP_CLASSIC) { + J |= StandardDPad(pad); + signed char wm_sx = WPAD_Stick(pad,1,0); // CC right joystick + signed char wm_sy = WPAD_Stick(pad,1,1); // CC right joystick + static bool StickReady = true; + ActionButton = wp->btns_h & WPAD_CLASSIC_BUTTON_A; + SwordButton = wp->btns_h & WPAD_CLASSIC_BUTTON_B; + ShieldButton = wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_L || wp->exp.classic.ls_raw >= 0x10; + LeftItemButton = wp->btns_d & WPAD_CLASSIC_BUTTON_ZR || (StickReady && wm_sx < -70); + DownItemButton = wp->btns_d & WPAD_CLASSIC_BUTTON_Y || (StickReady && wm_sy < -70); + RightItemButton = wp->btns_d & WPAD_CLASSIC_BUTTON_X || (StickReady && wm_sx > 70); + if (abs(wm_sx)>70 || abs(wm_sy)>70) StickReady = false; + else if (abs(wm_sx)<50 && abs(wm_sy)<50) StickReady = true; + BItemButton = wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_R || wp->exp.classic.rs_raw >= 0x10; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS) + J |= VBA_BUTTON_START; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS) + J |= VBA_BUTTON_SELECT; + SpeedButton = wp->btns_h & WPAD_CLASSIC_BUTTON_ZL; + // Must use Wiimote for these buttons + CheatButton = wp->btns_d & WPAD_BUTTON_2; + } + CheatButton = CheatButton || DownUsbKeys[KB_C]; +#endif + // Gamecube controls are based on Twilight Princess for the Gamecube + { + u32 gc = PAD_ButtonsHeld(pad); + u32 pressed = PAD_ButtonsDown(pad); + signed char gc_px = PAD_SubStickX(pad); + if (gc_px > 70) J |= VBA_SPEED; + ActionButton = ActionButton || gc & PAD_BUTTON_A; + PullButton = PullButton || gc & PAD_TRIGGER_R; + SwordButton = SwordButton || gc & PAD_BUTTON_B; + ShieldButton = ShieldButton || gc & PAD_TRIGGER_L; + MidnaButton = MidnaButton || pressed & PAD_TRIGGER_Z; + UseLeftItemButton = UseLeftItemButton || gc & PAD_BUTTON_Y; + UseRightItemButton = UseRightItemButton || gc & PAD_BUTTON_X; + ItemsButton = ItemsButton || pressed & PAD_BUTTON_UP; + QuestButton = QuestButton || pressed & PAD_BUTTON_START; + MapButton = MapButton || pressed & PAD_BUTTON_RIGHT; + SpeedButton = SpeedButton || gc & PAD_BUTTON_DOWN; + CheatButton = CheatButton || gc & PAD_BUTTON_LEFT; + } + + static int OldDesiredSubscreen = -1, DelayCount = 0; + OldDesiredSubscreen = DesiredSubscreen; + // Items + if (ItemsButton) { + if (Subscreen == 1) DesiredSubscreen = 0; + else DesiredSubscreen = 1; + DelayCount = 1; + } + // Talk to Midna, er... I mean go to secondary items screen + if (MidnaButton) { + if (Subscreen == 2) DesiredSubscreen = 0; + else DesiredSubscreen = 2; + DelayCount = 1; + } + // Quest Status + if (QuestButton) { + if (Subscreen == 3) DesiredSubscreen = 0; + else DesiredSubscreen = 3; + DelayCount = 1; + } + // Map + if (MapButton) { + if (Subscreen == 4) DesiredSubscreen = 0; + else DesiredSubscreen = 4; + DelayCount = 1; + } + + // after using sword, need to release A button before using shield + static int SheathCount = 0; + if (OldJ & VBA_BUTTON_A) { + if (gbReadMemory(ItemsAddr+1)==5) + SheathCount = 15; + } + +#ifdef HW_RVL + u8 CursorPos = gbReadMemory(0xCBD0)+2; + + // Can't swap items if using two handed sword unless on item screen + if (OnItemScreen || (gbReadMemory(ItemsAddr+0)!=0x0C && gbReadMemory(ItemsAddr+1)!=0x0C)) { + // Left Item + if (LeftItemButton) + { + if (OnItemScreen) ZeldaSwap(2, CursorPos, ItemsAddr); + else ZeldaSwap(0, ZeldaDxLeftPos, ItemsAddr); + systemGameRumbleOnlyFor(5); + } + // Right Item + if (RightItemButton) + { + if (OnItemScreen) ZeldaSwap(4, CursorPos, ItemsAddr); + else ZeldaSwap(0, ZeldaDxRightPos, ItemsAddr); + systemGameRumbleOnlyFor(5); + } + // Down Item + if (DownItemButton) + { + if (OnItemScreen) ZeldaSwap(3, CursorPos, ItemsAddr); + else ZeldaSwap(0, ZeldaDxDownPos, ItemsAddr); + systemGameRumbleOnlyFor(5); + } + } + // B Item + if (BItemButton) + { + if (OnItemScreen) systemGameRumbleOnlyFor(5); + J |= VBA_BUTTON_B; + } +#endif + + static bool BIsLeft = true; + if (UseLeftItemButton) + { + if (!BIsLeft) { + // Fix two-handed sword before swap + if (gbReadMemory(ItemsAddr+0)==0x0C && gbReadMemory(ItemsAddr+1)==0x0C && !OnItemScreen) { + } else { + bool DrawingTwoHanded = (gbReadMemory(ItemsAddr+2)==0x0C); + if (DrawingTwoHanded) + DrawingTwoHanded = ZeldaDrawItem(0, ItemsAddr, 18); // put A item away (by drawing emptiness) + // Swap B with first inventory item + ZeldaSwap(0, ZeldaDxLeftPos, ItemsAddr); + if (DrawingTwoHanded) + gbWriteMemory(ItemsAddr+1, 0x0C); + BIsLeft = true; + } + } + if (OnItemScreen) systemGameRumbleOnlyFor(5); + J |= VBA_BUTTON_B; + } + if (UseRightItemButton) + { + if (BIsLeft) { + // Fix two-handed sword before swap + if (gbReadMemory(ItemsAddr+0)==0x0C && gbReadMemory(ItemsAddr+1)==0x0C && !OnItemScreen) { + } else { + bool DrawingTwoHanded = (gbReadMemory(ItemsAddr+2)==0x0C); + if (DrawingTwoHanded) + DrawingTwoHanded = ZeldaDrawItem(0, ItemsAddr, 18); // put A item away (by drawing emptiness) + // Swap B with first inventory item + ZeldaSwap(0, ZeldaDxLeftPos, ItemsAddr); + if (DrawingTwoHanded) + gbWriteMemory(ItemsAddr+1, 0x0C); + BIsLeft = false; + } + } + if (OnItemScreen) systemGameRumbleOnlyFor(5); + J |= VBA_BUTTON_B; + } + + // Action + if (ActionButton) { + if (!OnItemScreen) { + // If not using 2-handed sword then switch to holding nothing or shield + if (gbReadMemory(ItemsAddr+1)!=0x0C && !ZeldaDrawItem(0, ItemsAddr, 18))// draw nothing or shield + ZeldaDrawItem(1, ItemsAddr, 18); + } + J |= VBA_BUTTON_A; + } + // Z-Targetting + if (ShieldButton && !SwordButton) { + // Fix two-handed sword before swap + if (gbReadMemory(ItemsAddr+0)==0x0C && gbReadMemory(ItemsAddr+1)==0x0C) + gbWriteMemory(ItemsAddr+0, 0); + if (SheathCount>0) {// was using sword before + ZeldaDrawItem(1, ItemsAddr, 18); + SheathCount--; + } + else if (ZeldaDrawItem(1, ItemsAddr, 18)) + J |= VBA_BUTTON_A; + } + // Pulling + if (PullButton) { + // Fix two-handed sword before swap + if (gbReadMemory(ItemsAddr+0)==0x0C && gbReadMemory(ItemsAddr+1)==0x0C) + gbWriteMemory(ItemsAddr+0, 0); + if (ZeldaDrawItem(0x16, ItemsAddr, 18)) + J |= VBA_BUTTON_A; + } + // Sword + if (SwordButton) { + if (ShieldButton && gbReadMemory(ItemsAddr+1)==1) // was using shield before + ZeldaDrawItem(5, ItemsAddr, 18); + else if (gbReadMemory(ItemsAddr)==0x0C || gbReadMemory(ItemsAddr+1)==0x0C || ZeldaDrawItem(5, ItemsAddr, 18)) + J |= VBA_BUTTON_A; + } + // Camera (fast forward) + if (SpeedButton) + J |= VBA_SPEED; + // Cheat + if (CheatButton) { + if (Seasons) ZeldaSeasonsCheat(); + else ZeldaAgesCheat(); + } + + if (DesiredSubscreen == Subscreen) + DesiredSubscreen = -1; + static int OldSubscreen = 0; + if (Subscreen != OldSubscreen) { + if (Subscreen==1) DelayCount = 80; // wait for items screen to fade in + else DelayCount = 20; // wait to swap subscreens + } + OldSubscreen = Subscreen; + + if (DelayCount > 0) { + // do nothing + DelayCount--; + } else if (DesiredSubscreen == 0) { // game + switch(Subscreen) { + case 1: case 2: case 3: case 5: default: + J |= VBA_BUTTON_START; + break; + case 4: // map + J |= VBA_BUTTON_SELECT; + } + } else if (DesiredSubscreen == 1) { // items + switch(Subscreen) { + case 0: case 5: default: // game or save + J |= VBA_BUTTON_START; + break; + case 2: case 3: case 4: + J |= VBA_BUTTON_SELECT; + } + } else if (DesiredSubscreen == 2) { // secondary items + switch(Subscreen) { + case 0: case 5: default: // game or save + J |= VBA_BUTTON_START; + break; + case 1: case 3: case 4: + J |= VBA_BUTTON_SELECT; + } + } else if (DesiredSubscreen == 3) { // quest status + switch(Subscreen) { + case 0: case 5: default: // game or save + J |= VBA_BUTTON_START; + break; + case 1: case 2: case 4: + J |= VBA_BUTTON_SELECT; + } + } else if (DesiredSubscreen == 4) { // map + switch(Subscreen) { + case 0: // game + J |= VBA_BUTTON_SELECT; + break; + case 1: case 2: case 3: case 5: default: + J |= VBA_BUTTON_START; + } + } else if (DesiredSubscreen == 5) { // save + switch(Subscreen) { + case 0: default: // game + J |= VBA_BUTTON_START; + break; + case 1: case 2: case 4: // other + J |= VBA_BUTTON_SELECT; + break; + case 3: // quest status + J |= VBA_RIGHT; + // give up, this is as close as I can be bothered to get + DesiredSubscreen = -1; + } + } + OldJ = J; + return J; +} + +u32 OracleOfAgesInput(unsigned short pad) +{ + return ZeldaOracleInput(false, pad); +} + +u32 OracleOfSeasonsInput(unsigned short pad) +{ + return ZeldaOracleInput(true, pad); +} + +u32 MinishCapInput(unsigned short pad) +{ + u32 J = StandardMovement(pad) | DecodeKeyboard(pad) | DecodeWiimote(pad); + + // Rumble when they lose health! + u8 Health = CPUReadByte(0x2002aea); + static u8 OldHealth = 0; + if (Health < OldHealth) + systemGameRumble(20); + OldHealth = Health; + + static u8 SubscreenWanted = 0xFF; + static bool waiting = false; + u8 Subscreen = CPUReadByte(0x200008C); + if (Subscreen == 0x64) + Subscreen = 0; // Boss battle (balloon) + + u8 GameStart = CPUReadByte(0x2000086); + + u8 SelBox = CPUReadByte(0x2000083); + + + u8 LoadMenu = CPUReadByte(0x200AF57); + static u8 AButtonItem = 0; + static u8 BButtonItem = 0; + if (Subscreen == 0x2c) { + AButtonItem = CPUReadByte(0x200af3c); + BButtonItem = CPUReadByte(0x200af5c); + } else if (Subscreen == 0) { + AButtonItem = CPUReadByte(0x200af5c); + BButtonItem = CPUReadByte(0x200af7c); + } + static int frame = 0; + u32 SwordButtonNumber = 0; + u32 ZTargetButton = 0; + if (AButtonItem <= 6 && AButtonItem >= 1) + SwordButtonNumber = VBA_BUTTON_A; + else if (BButtonItem <= 6 && BButtonItem >= 1) + SwordButtonNumber = VBA_BUTTON_B; + else + SwordButtonNumber = VBA_BUTTON_START; + // Shield + if (BButtonItem >= 0xD && BButtonItem <= 0xE) + ZTargetButton = VBA_BUTTON_B; + else if (AButtonItem >= 0xD && AButtonItem <= 0xE) + ZTargetButton = VBA_BUTTON_A; + // Gust Jar also does Z targetting + else if (BButtonItem == 0x11) + ZTargetButton = VBA_BUTTON_B; + else if (AButtonItem == 0x11) + ZTargetButton = VBA_BUTTON_A; + else + ZTargetButton = 0; + + bool ActionButton=0, SwordButton=0, ShieldButton=0, PullButton=0, + ItemsButton=0, QuestButton=0, MapButton=0, SpeedButton=0, CheatButton=0, MidnaButton=0, + LeftItemButton=0, DownItemButton=0, RightItemButton=0, + BItemButton=0, UseLeftItemButton=0, UseRightItemButton=0; + + +#ifdef HW_RVL + bool OnItemScreen = (Subscreen==0x2c); + u8 RButtonAction = CPUReadByte(0x200af32); + WPADData * wp = WPAD_Data(pad); + // Wii Pointer selection on item screen + int cx, cy, SelRow, SelCol, CursorRow = 0xFF, CursorCol = 0xFF; + static int OldCursorRow = 0xFF; + static int OldCursorCol = 0xFF; + CursorVisible = ((Subscreen != 0 && Subscreen != 0x64) || LoadMenu == 2); + if (CursorVisible) { + cx = (CursorX * 240) / 640; + cy = (CursorY * 160) / 480; + } else { + cx = -1; + cy = -1; + } + if (Subscreen == 0x2c) { + SelRow = SelBox / 4; + SelCol = SelBox % 4; + if (SelBox == 16) { + SelRow = 3; + SelCol = 4; + } + else if (SelRow < 3 && SelCol >= 2) + SelCol++; + if (cy >= 35 && cy <= 55) + CursorRow = 0; + else if (cy >= 59 && cy <= 79) + CursorRow = 1; + else if (cy >= 83 && cy <= 103) + CursorRow = 2; + else if (cy >= 107 && cy <= 127) + CursorRow = 3; + else + CursorRow = 0xFF; + if (CursorRow < 3) + { + if (cx >= 52 && cx <= 79) + CursorCol = 0; + else if (cx >= 88 && cx <= 116) + CursorCol = 1; + else if (cx >= 124 && cx <= 152) + CursorCol = 3; + else if (cx >= 160 && cx <= 188) + CursorCol = 4; + else + CursorCol = 0xFF; + } + else + { + if (cx >= 157 && cx <= 204) + CursorCol = 4; + else if (cx >= 52 && cx < 152) + CursorCol = (cx - 52) / 25; + else + CursorCol = 0xFF; + } + if (CursorCol != 0xFF && CursorRow != 0xFF && (CursorCol != SelCol + || CursorRow != SelRow)) + { + if (CursorCol > SelCol) + J |= VBA_RIGHT; + else if (CursorCol < SelCol) + J |= VBA_LEFT; + else if (CursorRow > SelRow) + J |= VBA_DOWN; + else if (CursorRow < SelRow) + J |= VBA_UP; + } + } + else if (Subscreen == 0x38) + { + switch (SelBox) + { + case 0: + case 1: + case 10: + case 9: + case 11: + SelRow = 0; + break; + case 12: + SelRow = 1; + break; + case 2: + case 3: + case 13: + case 14: + case 15: + SelRow = 2; + break; + case 6: + case 7: + case 8: + case 4: + case 5: + SelRow = 3; + break; + default: + SelRow = 0xFF; + break; + } + switch (SelBox) + { + case 0: + case 2: + case 6: + SelCol = 0; + break; + case 7: + SelCol = 1; + break; + case 1: + case 3: + case 8: + SelCol = 2; + break; + case 10: + case 13: + case 4: + SelCol = 3; + break; + case 9: + case 12: + case 14: + SelCol = 4; + break; + case 11: + case 15: + case 5: + SelCol = 5; + break; + default: + SelCol = 0xFF; + break; + } + if (cy >= 109 && cy <= 130) { + CursorRow = 3; + if (cx >= 36 && cx <= 113) + CursorCol = (cx - 36) / 26; + else if (cx >= 118 && cx <= 165) + CursorCol = 3; + else if (cx >= 168 && cx <= 215) + CursorCol = 5; + else + CursorCol = 0xFF; + } else { + if (cx >= 35 && cx <= 70) { + CursorCol = 0; + if (cy >= 40 && cy <= 73) + CursorRow = 0; + else if (cy >= 79 && cy <= 104) + CursorRow = 2; + else + CursorRow = 0xFF; + } else if (cx >= 78 && cx <= 113) { + CursorCol = 2; + if (cy >= 40 && cy <= 73) + CursorRow = 0; + else if (cy >= 79 && cy <= 104) + CursorRow = 2; + else + CursorRow = 0xFF; + } else { + if (cx >= 125 && cx <= 148) { + CursorCol = 3; + if (cy >= 44 && cy <= 65) + CursorRow = 0; + else if (cy >= 83 && cy <= 104) + CursorRow = 2; + else + CursorRow = 0xFF; + } else if (cx >= 151 && cx <= 172) { + CursorCol = 4; + if (cy >= 31 && cy <= 53) + CursorRow = 0; + else if (cy >= 57 && cy <= 78) + CursorRow = 1; + else if (cy >= 83 && cy <= 104) + CursorRow = 2; + else + CursorRow = 0xFF; + } else if (cx >= 175 && cx <= 198) { + CursorCol = 5; + if (cy >= 44 && cy <= 65) + CursorRow = 0; + else if (cy >= 83 && cy <= 104) + CursorRow = 2; + else + CursorRow = 0xFF; + } else { + CursorCol = 0xFF; + CursorRow = 0xFF; + } + } + } + + if (CursorCol != 0xFF && CursorRow != 0xFF && (CursorCol != SelCol + || CursorRow != SelRow)) { + if (CursorCol > SelCol) + J |= VBA_RIGHT; + else if (CursorCol < SelCol) + J |= VBA_LEFT; + else if (CursorRow > SelRow) + J |= VBA_DOWN; + else if (CursorRow < SelRow) + J |= VBA_UP; + } + } + if ((CursorRow == 0xFF || CursorCol == 0xFF) && (OldCursorRow == 0xFF || OldCursorCol == 0xFF)) { + // no change, still not pointing at anything + } else if (CursorVisible && (CursorRow != OldCursorRow || CursorCol != OldCursorCol)) { + // Cursor changed buttons, so rumble + //systemGameRumble(5); + } + OldCursorRow = CursorRow; + OldCursorCol = CursorCol; + + static int SwordCount = 0; + // Nunchuk controls are based on Twilight Princess for the Wii + if (wp->exp.type == WPAD_EXP_NUNCHUK) { + ActionButton = wp->btns_h & WPAD_BUTTON_A; + ShieldButton = wp->btns_h & WPAD_NUNCHUK_BUTTON_Z; + SpeedButton = wp->btns_h & WPAD_NUNCHUK_BUTTON_C; + MidnaButton = wp->btns_h & WPAD_BUTTON_UP; + LeftItemButton = wp->btns_h & WPAD_BUTTON_LEFT; + DownItemButton = wp->btns_h & WPAD_BUTTON_DOWN; + RightItemButton = wp->btns_h & WPAD_BUTTON_RIGHT; + BItemButton = wp->btns_h & WPAD_BUTTON_B; + ItemsButton = wp->btns_d & WPAD_BUTTON_MINUS; + QuestButton = wp->btns_d & WPAD_BUTTON_PLUS; + MapButton = wp->btns_d & WPAD_BUTTON_1; + CheatButton = wp->btns_h & WPAD_BUTTON_2; + // Sword + SwordButton = false; + if (fabs(wp->gforce.x)> 1.5 && !OnItemScreen) { + if (SwordCount<3) SwordCount = 3; + } + // Throw gesture + if (RButtonAction==0x03) { + if (fabs(wp->exp.nunchuk.gforce.y)> 0.6) { + J |= VBA_BUTTON_R; + systemGameRumble(5); + } + // Spin attack + } else if (fabs(wp->exp.nunchuk.gforce.x)> 0.6 && !OnItemScreen) { + if (SwordCount<60) SwordCount=60; + } + if (SwordCount>0) { + if (SwordCount == 50) + systemGameRumbleOnlyFor(50); + if (!OnItemScreen) + SwordButton = true; + SwordCount--; + } + // Classic controller controls are loosely based on Ocarina of Time virtual console + // but with R as the B button like in Twilight Princess + } else if (wp->exp.type == WPAD_EXP_CLASSIC) { + J |= StandardDPad(pad); + signed char wm_sx = WPAD_Stick(pad,1,0); // CC right joystick + signed char wm_sy = WPAD_Stick(pad,1,1); // CC right joystick + static bool StickReady = true; + ActionButton = wp->btns_h & WPAD_CLASSIC_BUTTON_A; + SwordButton = wp->btns_h & WPAD_CLASSIC_BUTTON_B; + ShieldButton = wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_L || wp->exp.classic.ls_raw >= 0x10; + if (abs(wm_sx)>80 || abs(wm_sy)>80) StickReady = true; + LeftItemButton = wp->btns_h & WPAD_CLASSIC_BUTTON_ZR || (StickReady && wm_sx < -70); + DownItemButton = wp->btns_h & WPAD_CLASSIC_BUTTON_Y || (StickReady && wm_sy < -70); + RightItemButton = wp->btns_h & WPAD_CLASSIC_BUTTON_X || (StickReady && wm_sx > 70); + MidnaButton = wm_sy > 70; + if (abs(wm_sx)<70 && abs(wm_sy)<70) StickReady = false; + BItemButton = wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_R || wp->exp.classic.rs_raw >= 0x10; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS) + J |= VBA_BUTTON_START; + if (wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS) + J |= VBA_BUTTON_SELECT; + SpeedButton = wp->btns_h & WPAD_CLASSIC_BUTTON_ZL; + // Must use Wiimote for these buttons + CheatButton = wp->btns_h & WPAD_BUTTON_2; + } + CheatButton = CheatButton || DownUsbKeys[KB_C]; +#endif + // Gamecube controls are based on Twilight Princess for the Gamecube + { + u32 gc = PAD_ButtonsHeld(pad); + u32 pressed = PAD_ButtonsDown(pad); + signed char gc_px = PAD_SubStickX(pad); + if (gc_px > 70) J |= VBA_SPEED; + ActionButton = ActionButton || gc & PAD_BUTTON_A; + PullButton = PullButton || gc & PAD_TRIGGER_R; + SwordButton = SwordButton || gc & PAD_BUTTON_B; + ShieldButton = ShieldButton || gc & PAD_TRIGGER_L; + MidnaButton = MidnaButton || pressed & PAD_TRIGGER_Z; + UseLeftItemButton = UseLeftItemButton || gc & PAD_BUTTON_Y; + UseRightItemButton = UseRightItemButton || gc & PAD_BUTTON_X; + ItemsButton = ItemsButton || pressed & PAD_BUTTON_UP; + QuestButton = QuestButton || pressed & PAD_BUTTON_START; + MapButton = MapButton || pressed & PAD_BUTTON_RIGHT; + SpeedButton = SpeedButton || gc & PAD_BUTTON_DOWN; + LeftItemButton = CheatButton || gc & PAD_BUTTON_LEFT; + } + + if (ItemsButton) { // items + if (Subscreen == 0x2c) SubscreenWanted = 0; + else SubscreenWanted = 0x2c; + waiting = false; + } else if (MapButton) { // map + if (Subscreen == 0x0c || Subscreen==0x70) SubscreenWanted = 0; + else SubscreenWanted = 0x0c; + waiting = false; + } else if (QuestButton) { // quest + if (Subscreen == 0x38) SubscreenWanted = 0; + else SubscreenWanted = 0x38; + waiting = false; + } else if (ActionButton && Subscreen == 0x2c && SelBox!=16) { + SubscreenWanted = 0; + waiting = false; + } else if (BItemButton && Subscreen == 0x38) { + SubscreenWanted = 0; + waiting = false; + } + if (GameStart==2 || GameStart==3) { + SubscreenWanted = 0; + waiting = false; + if (QuestButton || (ActionButton && BButtonItem)) + J |= VBA_BUTTON_START; + return J; + } else if (LoadMenu==2) { + if (MidnaButton) + J |= VBA_UP; + if (DownItemButton) + J |= VBA_DOWN; + if (LeftItemButton) + J |= VBA_LEFT; + if (RightItemButton) + J |= VBA_RIGHT; + if (ActionButton) + J |= VBA_BUTTON_A; + if (BButtonItem) + J |= VBA_BUTTON_B; + + if (QuestButton) + J |= VBA_BUTTON_R; + if (ItemsButton) + J |= VBA_BUTTON_L; + if (MapButton) + J |= VBA_BUTTON_SELECT; + if (CheatButton) + J |= VBA_BUTTON_START; + if (SpeedButton) + J |= VBA_BUTTON_SELECT; + if (ShieldButton) + J |= VBA_BUTTON_START; + return J; + } + + //0c = map + //70 = dungeon map + //38 = quest + //2c = items + //89 = KINSTONE PIECES + //f0 = SWORD TECHNIQUES + //00 = none or changing or save + //64 = Boss battle (balloon thing) + //FF = don't care! + //; + if (Subscreen == 0x70 && SubscreenWanted == 0x0c) { + SubscreenWanted = 0xFF; + waiting = false; + } + + if (Subscreen != SubscreenWanted && SubscreenWanted != 0xFF) { + frame++; + if (frame % 2 == 0) + switch (Subscreen) { + case 0: + frame = 0; + if (!waiting) { + waiting = true; + //waittime = + J |= VBA_BUTTON_START; + } + break; + case 0x0c: // map + case 0x70: + if (SubscreenWanted == 0x38) + J |= VBA_BUTTON_L; // quest + else if (SubscreenWanted == 0x2c) + J |= VBA_BUTTON_R; // items + else + J |= VBA_BUTTON_START; + waiting = false; + break; + case 0x2c: // items + if (SubscreenWanted == 0x0c || SubscreenWanted == 0x70) + J |= VBA_BUTTON_L; // map + else if (SubscreenWanted == 0x38) + J |= VBA_BUTTON_R; // quest + else + J |= VBA_BUTTON_START; + waiting = false; + break; + case 0x38: // quest + if (SubscreenWanted == 0x2c) + J |= VBA_BUTTON_L; // map + else if (SubscreenWanted == 0x0c || SubscreenWanted == 0x70) + J |= VBA_BUTTON_R; // quest + else + J |= VBA_BUTTON_START; + // CAKTODO: kinstone and sword techniques + waiting = false; + break; + case 0x89: // kinstone + case 0xF0: // sword techniques + J |= VBA_BUTTON_B; // cancel + waiting = false; + break; + + } + } else { + SubscreenWanted = 0xFF; + waiting = false; + } + + /*** Report wp->btns_h buttons (gamepads) ***/ + + // Talk to Midna, er... I mean Ezlo + if (MidnaButton) + J |= VBA_BUTTON_SELECT; + + // Save button + if ((Subscreen==0x2c && SelBox==16) || (Subscreen==0x38 && SelBox==5)) { + if (ActionButton) { + J |= VBA_BUTTON_A; + systemGameRumble(12); + } + } else if (Subscreen==0x2c) { + } else if (Subscreen==0x38 && SelBox==4) { // Sleep button returns to menu instead of sleep + if (ActionButton) { + ConfigRequested = 1; + return 0; + } + } else if (Subscreen==0x38) { // Action button counts as A Button on quest status screen + // Action + if (ActionButton) { + J |= VBA_BUTTON_A; + //systemGameRumble(4); + } + } else { + // Action + if (ActionButton) + J |= VBA_BUTTON_R; + } + // Right Item + if (RightItemButton || UseRightItemButton) { + J |= VBA_BUTTON_A; + if (Subscreen==0x2c) { + systemGameRumble(10); + } + } + // Down Item + if (Subscreen==0x38) { + } else { + if (BItemButton) { + J |= VBA_BUTTON_B; + if (Subscreen==0x2c) { + systemGameRumble(10); + } + } + } + if (DownItemButton || UseLeftItemButton) { + J |= VBA_BUTTON_B; + if (Subscreen==0x2c) { + systemGameRumble(10); + } + } + // Kinstone (doesn't work in items screen) + if (LeftItemButton && Subscreen != 0x2c) + J |= VBA_BUTTON_L; + // Menu + if (CheatButton) + J |= VBA_BUTTON_START; + // Sword + if (Subscreen == 0 && SwordButton) + J |= SwordButtonNumber; + // Z-Targetting + if (Subscreen==0 && ShieldButton) + J |= ZTargetButton; + // Camera (use as extra way of pressing A without using DPad) + if (SpeedButton) + J |= VBA_BUTTON_A; + // Pull (I was going to check RButtonAction, but the in-game text always tells you to + // use R as the action button, so let's just make Gamecube R = Gameboy R) + if (PullButton) + J |= VBA_BUTTON_R; + + return J; +} + +u32 ALinkToThePastInput(unsigned short pad) +{ + u32 J = StandardMovement(pad); + u8 Health = 0; + static u8 OldHealth = 0; + + // Rumble when they lose health! + if (Health < OldHealth) + systemGameRumble(20); + OldHealth = Health; + +#ifdef HW_RVL + WPADData * wp = WPAD_Data(pad); + + // Talk to Midna, er... I mean ... nobody + if (wp->btns_h & WPAD_BUTTON_UP) + J |= VBA_BUTTON_START; + + // Action + if (wp->btns_h & WPAD_BUTTON_A) + J |= VBA_BUTTON_R; + if (wp->exp.type == WPAD_EXP_NUNCHUK) + { + if (fabs(wp->exp.nunchuk.gforce.x)> 0.6) + { // Wiiuse bug!!! Not correct values + J |= VBA_BUTTON_B; + systemGameRumble(20); + } + // CAKTODO hold down attack button to do spin attack + + } + // Use item + if (wp->btns_h & WPAD_BUTTON_B) + { + J |= VBA_BUTTON_A; + } + if (wp->btns_h & WPAD_BUTTON_LEFT) + { + J |= VBA_BUTTON_A; + } + if (wp->btns_h & WPAD_BUTTON_RIGHT) + { + J |= VBA_BUTTON_A; + } + if (wp->btns_h & WPAD_BUTTON_DOWN) + { + J |= VBA_BUTTON_A; + } + // Menu (like Quest Status) + if (wp->btns_h & WPAD_BUTTON_PLUS) + J |= VBA_BUTTON_START; + // Items + if (wp->btns_h & WPAD_BUTTON_MINUS) + J |= VBA_BUTTON_SELECT; + // Map + if (wp->btns_h & WPAD_BUTTON_1) + J |= VBA_BUTTON_L; + // Sword + if (fabs(wp->gforce.x)> 1.5) + J |= VBA_BUTTON_B; + if (wp->btns_h & WPAD_BUTTON_2) + J |= VBA_BUTTON_B; + // Shield has no controls + // Camera (speed) + if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_C)) + J |= VBA_SPEED; +#endif + + return J; +} + +u32 Zelda1Input(unsigned short pad) +{ + u32 J = StandardMovement(pad); + u8 Health = 0; + static u8 OldHealth = 0; + + // Rumble when they lose health! + if (Health < OldHealth) + systemGameRumble(20); + OldHealth = Health; + +#ifdef HW_RVL + WPADData * wp = WPAD_Data(pad); + + // Talk to Midna, er... I mean ... nobody + if (wp->btns_h & WPAD_BUTTON_UP) + J |= 0; + + // Action + if (wp->btns_h & WPAD_BUTTON_A) + J |= VBA_BUTTON_A; + if (wp->exp.type == WPAD_EXP_NUNCHUK) + { + if (fabs(wp->exp.nunchuk.gforce.x)> 0.6) + { // Wiiuse bug!!! Not correct values + J |= VBA_BUTTON_A; + systemGameRumble(20); + } + } + // Use item + if (wp->btns_h & WPAD_BUTTON_B) + { + J |= VBA_BUTTON_B; + } + if (wp->btns_h & WPAD_BUTTON_LEFT) + { + J |= VBA_BUTTON_B; + } + if (wp->btns_h & WPAD_BUTTON_RIGHT) + { + J |= VBA_BUTTON_A; + } + if (wp->btns_h & WPAD_BUTTON_DOWN) + { + J |= VBA_BUTTON_B; + } + // Menu (like Quest Status) + if (wp->btns_h & WPAD_BUTTON_PLUS) + J |= VBA_BUTTON_SELECT; + // Items + if (wp->btns_h & WPAD_BUTTON_MINUS) + J |= VBA_BUTTON_START; + // Map + if (wp->btns_h & WPAD_BUTTON_1) + J |= 0; + // Sword + if (fabs(wp->gforce.x)> 1.5) + J |= VBA_BUTTON_A; + // Shield has no controls + // Camera (speed) + if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_C)) + J |= VBA_SPEED; +#endif + + return J; +} + +u32 Zelda2Input(unsigned short pad) { + u32 J = StandardMovement(pad); + u8 Health = 0; + static u8 OldHealth = 0; + + // Rumble when they lose health! + if (Health < OldHealth) + systemGameRumble(20); + OldHealth = Health; + +#ifdef HW_RVL + WPADData * wp = WPAD_Data(pad); + + // Talk to Midna, er... I mean ... nobody + if (wp->btns_h & WPAD_BUTTON_UP) + J |= 0; + + // Jump + if (wp->btns_h & WPAD_BUTTON_A) + J |= VBA_BUTTON_A; + // spin attack + if (wp->exp.type == WPAD_EXP_NUNCHUK) + { + if (fabs(wp->exp.nunchuk.gforce.x)> 0.6) + { // Wiiuse bug!!! Not correct values + J |= VBA_BUTTON_B; + systemGameRumble(20); + } + } + // Use item + if (wp->btns_h & WPAD_BUTTON_B) + { + J |= VBA_BUTTON_SELECT; + } + if (wp->btns_h & WPAD_BUTTON_LEFT) + { + J |= VBA_BUTTON_SELECT; + } + if (wp->btns_h & WPAD_BUTTON_RIGHT) + { + J |= VBA_BUTTON_SELECT; + } + if (wp->btns_h & WPAD_BUTTON_DOWN) + { + J |= VBA_BUTTON_SELECT; + } + // Menu (like Quest Status) + if (wp->btns_h & WPAD_BUTTON_PLUS) + J |= VBA_BUTTON_START; + // Items + if (wp->btns_h & WPAD_BUTTON_MINUS) + J |= VBA_BUTTON_START; + // Map + if (wp->btns_h & WPAD_BUTTON_1) + J |= 0; + // Sword + if (fabs(wp->gforce.x)> 1.5) + J |= VBA_BUTTON_B; + // No shield control, just duck + if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z)) + J |= VBA_DOWN; + // Camera (speed) + if ((wp->exp.type == WPAD_EXP_NUNCHUK) && (wp->btns_h & WPAD_NUNCHUK_BUTTON_C)) + J |= VBA_SPEED; +#endif + return J; +} + diff --git a/source/ngc/menu.cpp b/source/ngc/menu.cpp index c826dae..ab87fc1 100644 --- a/source/ngc/menu.cpp +++ b/source/ngc/menu.cpp @@ -45,6 +45,7 @@ extern "C" extern int menu; extern bool ROMLoaded; +extern char DebugStr[50]; /**************************************************************************** * Load Manager @@ -281,7 +282,7 @@ PreferencesMenu () static int GameMenu () { - int gamemenuCount = 9; + int gamemenuCount = 10; char gamemenu[][50] = { "Return to Game", "Reset Game", @@ -289,7 +290,8 @@ GameMenu () "Load Game Snapshot", "Save Game Snapshot", "Reset Zoom", "Weather: 100% sun", - "Back to Main Menu" + "Back to Main Menu", + "" }; int ret, retval = 0; @@ -324,6 +326,8 @@ GameMenu () sprintf(gamemenu[7], "Weather: %d%% sun", SunBars*10); else gamemenu[7][0] = '\0'; + + sprintf(gamemenu[9], "%s", DebugStr); ret = RunMenu (gamemenu, gamemenuCount, "Game Menu"); @@ -639,8 +643,13 @@ ConfigureControllers () while (quit == 0) { + #ifdef HW_RVL sprintf (ctlrmenu[0], "Match Wii Game: %s", GCSettings.WiiControls == true ? " ON" : "OFF"); + #else + sprintf (ctlrmenu[0], "Match Gamecube Game: %s", + GCSettings.WiiControls == true ? " ON" : "OFF"); + #endif /*** Controller Config Menu ***/ ret = RunMenu (ctlrmenu, ctlrmenucount, "Configure Controllers"); diff --git a/source/ngc/video.cpp b/source/ngc/video.cpp index 5320387..429f0b7 100644 --- a/source/ngc/video.cpp +++ b/source/ngc/video.cpp @@ -245,34 +245,56 @@ static void draw_square(Mtx v) GX_End(); } -void Menu_DrawImg(f32 xpos, f32 ypos, u16 width, u16 height, u8 data[], f32 degrees, f32 scaleX, f32 scaleY, u8 alpha); - static void draw_cursor(Mtx v) { - if (!CursorVisible) + if (!CursorVisible || !CursorValid) return; -/* -#ifdef HW_RVL - WPADData *wp = WPAD_Data(0); - if(wp->ir.valid) - Menu_DrawImg(wp->ir.x-48, wp->ir.y-48, 96, 96, pointer1->GetImage(), wp->ir.angle, 1, 1, 255); -#endif -*/ + GX_InitTexObj(&texobj, pointer1->GetImage(), 96, 96, GX_TF_RGBA8,GX_CLAMP, GX_CLAMP,GX_FALSE); + GX_LoadTexObj(&texobj, GX_TEXMAP0); + GX_SetBlendMode(GX_BM_BLEND,GX_BL_DSTALPHA,GX_BL_INVSRCALPHA,GX_LO_CLEAR); + GX_SetTevOp (GX_TEVSTAGE0, GX_REPLACE); + GX_SetVtxDesc (GX_VA_TEX0, GX_DIRECT); Mtx m; // model matrix. guMtxIdentity(m); - guMtxScaleApply(m, m, 0.05f, 0.05f, 0.06f); - guMtxTransApply(m, m, CursorX-320, 240-CursorY, -100); + guMtxScaleApply(m, m, 0.070f, 0.10f, 0.06f); + // I needed to hack this position + guMtxTransApply(m, m, CursorX-315, 220-CursorY, -100); GX_LoadPosMtxImm(m, GX_PNMTX0); GX_Begin(GX_QUADS, GX_VTXFMT0, 4); - draw_vert(0, 0, 0.0, 0.0); - draw_vert(1, 0, 1.0, 0.0); - draw_vert(2, 0, 1.0, 1.0); - draw_vert(3, 0, 0.0, 1.0); + + // I needed to hack the texture coords to cut out the opaque bit around the outside + draw_vert(0, 0, 0.4, 0.45); + draw_vert(1, 0, 0.76, 0.45); + draw_vert(2, 0, 0.76, 0.97); + draw_vert(3, 0, 0.4, 0.97); + GX_End(); + + GX_ClearVtxDesc (); + GX_SetVtxDesc (GX_VA_POS, GX_INDEX8); + GX_SetVtxDesc (GX_VA_CLR0, GX_INDEX8); + GX_SetVtxDesc (GX_VA_TEX0, GX_DIRECT); + + GX_SetVtxAttrFmt (GX_VTXFMT0, GX_VA_POS, GX_POS_XYZ, GX_S16, 0); + GX_SetVtxAttrFmt (GX_VTXFMT0, GX_VA_CLR0, GX_CLR_RGBA, GX_RGBA8, 0); + GX_SetVtxAttrFmt (GX_VTXFMT0, GX_VA_TEX0, GX_TEX_ST, GX_F32, 0); + + GX_SetArray (GX_VA_POS, square, 3 * sizeof (s16)); + + GX_SetNumTexGens (1); + GX_SetTexCoordGen (GX_TEXCOORD0, GX_TG_MTX2x4, GX_TG_TEX0, GX_IDENTITY); + + GX_InvVtxCache (); // update vertex cache + + GX_InitTexObj(&texobj, texturemem, vwidth, vheight, GX_TF_RGB565, + GX_CLAMP, GX_CLAMP, GX_FALSE); + if (!(GCSettings.render&1)) + GX_InitTexObjLOD(&texobj,GX_NEAR,GX_NEAR_MIP_NEAR,2.5,9.0,0.0,GX_FALSE,GX_FALSE,GX_ANISO_1); // original/unfiltered video mode: force texture filtering OFF + } /**************************************************************************** @@ -695,51 +717,3 @@ zoom_reset () updateScaling = 1; // update video } -void Menu_DrawImg(f32 xpos, f32 ypos, u16 width, u16 height, u8 data[], f32 degrees, f32 scaleX, f32 scaleY, u8 alpha) -{ - if(data == NULL) - return; - - GXTexObj texObj; - - GX_InitTexObj(&texObj, data, width,height, GX_TF_RGBA8,GX_CLAMP, GX_CLAMP,GX_FALSE); - GX_LoadTexObj(&texObj, GX_TEXMAP0); - - GX_SetTevOp (GX_TEVSTAGE0, GX_MODULATE); - GX_SetVtxDesc (GX_VA_TEX0, GX_DIRECT); - - Mtx m,m1,m2, mv; - width *=.5; - height*=.5; - guMtxIdentity (m1); - guMtxScaleApply(m1,m1,scaleX,scaleY,1.0); - Vector axis = (Vector) {0 , 0, 1 }; - guMtxRotAxisDeg (m2, &axis, degrees); - guMtxConcat(m2,m1,m); - - guMtxTransApply(m,m, xpos+width,ypos+height,0); - guMtxConcat (view, m, mv); - GX_LoadPosMtxImm (mv, GX_PNMTX0); - - GX_Begin(GX_QUADS, GX_VTXFMT0,4); - GX_Position3f32(-width, -height, 0); - GX_Color4u8(0xFF,0xFF,0xFF,alpha); - GX_TexCoord2f32(0, 0); - - GX_Position3f32(width, -height, 0); - GX_Color4u8(0xFF,0xFF,0xFF,alpha); - GX_TexCoord2f32(1, 0); - - GX_Position3f32(width, height, 0); - GX_Color4u8(0xFF,0xFF,0xFF,alpha); - GX_TexCoord2f32(1, 1); - - GX_Position3f32(-width, height, 0); - GX_Color4u8(0xFF,0xFF,0xFF,alpha); - GX_TexCoord2f32(0, 1); - GX_End(); - GX_LoadPosMtxImm (view, GX_PNMTX0); - - GX_SetTevOp (GX_TEVSTAGE0, GX_PASSCLR); - GX_SetVtxDesc (GX_VA_TEX0, GX_NONE); -}