u32 MK1Input(unsigned short pad) {
	OurHealth = gbReadMemory(0xD695);
	OpponentHealth = gbReadMemory(0xD696);
	OurX = gbReadMemory(0xCF00);
	OpponentX = gbReadMemory(0xCF26);
	//u8 OurChar = gbReadMemory(0xD685);
	//u8 OpponentChar = gbReadMemory(0xD686);
	u8 MenuChar = gbReadMemory(0xD61D)+1;
	static u8 OldMenuChar = 0;
	// Rumble when they change character
	if (MenuChar != OldMenuChar) {
		systemGameRumble(4);
		OldMenuChar = MenuChar;
	}
	u32 J = GetMKInput(pad, 8);
	if (LK || HK || BL) J |= VBA_BUTTON_A;
	if (LP || HP || BL) J |= VBA_BUTTON_B;
	if (Start) J |= VBA_BUTTON_START;
	if (Select) J |= VBA_BUTTON_SELECT;
	// Fix kick controls to what they should be!
	if (!(J & (VBA_UP | VBA_DOWN))) {
		if (B && HK) { // Make B+HK do roundhouse, while B+LK does sweep!
			J &= ~VBA_BACK;
			J |= VBA_FORWARD;
		} else if (F && HK) { // Make F+HK do normal high kick
			J &= ~VBA_FORWARD;
		} else if (F && LK) { // Make F+LK also do normal high kick, since no low kicks
			J &= ~VBA_FORWARD;
		}
	}
	if (Throw) J |= VBA_FORWARD | VBA_BUTTON_B;
	if (CS) J |= VBA_SPEED;
	return J;
}
Beispiel #2
0
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 MK3Input(unsigned short pad) {
	OurHealth = gbReadMemory(0xC0D6);
	OpponentHealth = gbReadMemory(0xC0D7);
	//u8 OurChar = gbReadMemory(0xC0F0); // 
	u8 OpponentChar = gbReadMemory(0xC0F1); // also CD40, D526
	OurX = gbReadMemory(0xCD02) | (gbReadMemory(0xCD03) << 8);
	OpponentX = gbReadMemory(0xCD42) | (gbReadMemory(0xCD43) << 8);
	bool InSelectScreen=false, InGame=false;
	if (gbReadMemory(0xC51E)==0x00 && gbReadMemory(0xC522)==0xFF) InSelectScreen = true;
	if (gbReadMemory(0xC080)==0x00 && gbReadMemory(0xC522)==0x00) InGame = true;
	static bool WasInSelectScreen = false;
	static u8 MenuChar = 0;
	static u8 MenuSubChar = 0;
	if (InSelectScreen) MenuChar = gbReadMemory(0xD4CE);
		
	static u8 OldMenuChar = 0;
	// Rumble when they change character
	if (MenuChar != OldMenuChar) {
		if (InSelectScreen && !InGame) {
			systemGameRumble(4);
			MK3SetPal(1,MenuChar);
			MK3RenameEveryoneProperlyExcept(255);
			MenuSubChar=0;
		}
		OldMenuChar = MenuChar;
	}

	// Special Characters in-game
	if (!InSelectScreen) {
		// Set opponent colour
		MK3SetPal(2, OpponentChar);
		// Our colour
		if (MenuSubChar!=0) {
			MK3SetSubchar(MenuChar, MenuSubChar);
		}
	}

	// Get input, and rumble for 2 frames if hurt
	u32 J = GetMKInput(pad, 2);
	if (LK || HK) J |= VBA_BUTTON_A;
	if (LP || HP) J |= VBA_BUTTON_B;
	if (BL) J |= VBA_BUTTON_START;
	if (Throw) {
		if (InGame) J |= VBA_BUTTON_B;
		else J |= VBA_BUTTON_START;
	}
	if (Start) {
		if (InGame) J |= VBA_BUTTON_SELECT;
		else J |= VBA_BUTTON_START;
	}
	if (Select) J |= VBA_BUTTON_SELECT;
	if (InSelectScreen && (Start || Throw || HP || LP || HK || LK || BL)) {
		J |= VBA_BUTTON_START;
	}
	// Fix kick controls to what they should be!
	if (!InSelectScreen && !(J & (VBA_UP | VBA_DOWN))) {
		if (B && HK && !LK) { // Make B+HK do roundhouse, while B+LK does sweep!
			J &= ~VBA_BACK;
			J |= VBA_FORWARD;
		} else if (F && HK) { // Make F+HK do normal high kick
			J &= ~VBA_FORWARD;
		} else if (F && LK) { // Make F+LK also do normal high kick, since no low kicks
			J &= ~VBA_FORWARD;
		}
	}
	// Fix punch controls to what they should be!
	if ((!InSelectScreen) && (J & VBA_DOWN)) {
		// Make D+LP do crouch punch instead of uppercut
		if (LP && !F && !B && !LK && !HK && !HP) { 
			J &= ~VBA_BACK;
			J |= VBA_FORWARD;
		}
	}
	// Run, sometimes does roundhouse kick (Midway's fault, not mine)
	if (CS && InGame) J |= VBA_FORWARD | VBA_BUTTON_A | VBA_BUTTON_B;
	// Allow to choose secret characters from menu
	static bool CancelMovement = false;
	if (InSelectScreen) {
		if ((MenuChar==1 && (J & VBA_DOWN))
		|| (MenuChar==3 && (J & VBA_RIGHT))
		|| (MenuChar==5 && (J & VBA_LEFT))
		|| (MenuChar==7 && (J & VBA_UP))) {
			CancelMovement = true;
			gbWriteMemory(0xD4CE,4);
		} else if (MenuChar==8 && (J & VBA_RIGHT)) {
			gbWriteMemory(0xD4CE,MK3_SHAOKHAN);
		}
		if (CancelMovement) {
			if (J & (VBA_RIGHT | VBA_LEFT | VBA_UP | VBA_DOWN))
				J &= ~(VBA_RIGHT | VBA_LEFT | VBA_UP | VBA_DOWN);
			else CancelMovement = false;
		}
		WasInSelectScreen = true;
	} else {
		CancelMovement = false;
		if (WasInSelectScreen) {
			// We just chose a character, so apply anything special here
			// Cyborg Sub-Zero
			if (MenuChar==MK3_SUBZERO && MenuSubChar==1)
				gbWriteMemory(0xD4CE,MK3_SEKTOR);			
			// Frost
			else if (MenuChar==MK3_SUBZERO && MenuSubChar==3)
				gbWriteMemory(0xD4CE,MK3_SINDEL);			
			// Cyborg Kano
			else if (MenuChar==MK3_KANO && MenuSubChar==1)
				gbWriteMemory(0xD4CE,MK3_SEKTOR);			
			// Cyborg Kabal
			else if (MenuChar==MK3_KABAL && MenuSubChar==1)
				gbWriteMemory(0xD4CE,MK3_SEKTOR);
			// Human Cyrax
			else if (MenuChar==MK3_CYRAX && MenuSubChar==1)
				gbWriteMemory(0xD4CE,MK3_SUBZERO);
			// Human Sektor
			else if (MenuChar==MK3_SEKTOR && MenuSubChar==1)
				gbWriteMemory(0xD4CE,MK3_SUBZERO);
			// Human Smoke, Reptile, Scorpion
			else if (MenuChar==MK3_SMOKE && MenuSubChar>=1)
				gbWriteMemory(0xD4CE,MK3_SUBZERO);
			// Reiko
			else if (MenuChar==MK3_SHAOKHAN && MenuSubChar==1)
				gbWriteMemory(0xD4CE,MK3_SUBZERO);
			WasInSelectScreen = false;
		}
	}

	bool CostumeButton = InSelectScreen && (CS || (J & VBA_BUTTON_SELECT)); // Change Style/Select changes costume
	static bool OldCostumeButton = 0;

	if (CostumeButton && !OldCostumeButton) {
		int OldSubChar = MenuSubChar;
		MenuSubChar = MK3SetSubchar(MenuChar, MenuSubChar+1, true);
		if (MenuSubChar!=OldSubChar) systemGameRumble(8);
	}
	OldCostumeButton = CostumeButton;
	//DebugPrintf("%d,%d C=%d M=%d", MenuChar,MenuSubChar,gbReadMemory(0xC0F0),gbReadMemory(0xCD00));

	return J;
}
u32 MKAInput(unsigned short pad)
{
	bool InMenu= false;
	if (CPUReadHalfWord(0x2000008)==0xFFFC) InMenu=true;
	else InMenu = false;
	
	OurHealth = CPUReadByte(0x2000020);
	OpponentHealth = CPUReadByte(0x2000020+0x68);
	OurX = (s16)CPUReadHalfWord(0x2000008);
	OpponentX = (s16)CPUReadHalfWord(0x2000008+0x68);
	u8 OurChar =   CPUReadByte(0x2000025); // also 202f6a8
	//u8 OpponentChar = CPUReadByte(0x2000025+0x68);
		
	// Special characters
	static int MenuChar = 0;
	static int MenuSubchar = 0;
	static bool WasInMenu = false;
	static u8 OurOldChar = 255;
	static u8 OriginalColour = 0;
	static bool OldCostumeButton = false;
	bool CostumeButton = false;
	if (OriginalColour == 0) OriginalColour = CPUReadByte(0x2000004);
	// Manually changed characters, so reset MenuChar and SubChar
	if (InMenu && OurChar!=OurOldChar && OurChar!=0) {
		//DebugPrintf("%d %d %d", OurChar, OurOldChar, MenuChar);
		MenuChar = OurChar;
		MenuSubchar = 0;
		OriginalColour = CPUReadByte(0x2000004);
		systemGameRumble(4);
		MKARenameEveryoneProperlyExcept(255);
	} else if (InMenu && OurChar!=OurOldChar) {
		// Either changing character to Rain, or more likely starting combat
		// if changing to rain, they might actually end up changing to Cyborg Rain or Tremor
		MenuChar = OurChar;
		OriginalColour = CPUReadByte(0x2000004);
	}
	
	// Special Characters in-game
	if (!InMenu) {
	    // in the game we just changed from 0 back to our real character
		// unless OurChar is Jax and Subchar is 3 or 4 in which case MenuChar should be 0
		// So check for Tremor, also check for Shao Khan
		if (OurOldChar==0 && OurChar!=0) {
			if (OurChar==MKA_Jax && (MenuSubchar==3 || MenuSubchar==4))
				MenuChar=0;
			else if (OurChar==MKA_ShaoKhan && (MenuSubchar==2 || MenuSubchar==3))
				MenuChar=MKA_ShangTsung;
			else
				MenuChar=OurChar;
		}
		if (MenuSubchar!=0) {
			//u8 OldMaxFrame = CPUReadByte(0x2000048);
			MKANextSubchar(MenuChar, MenuSubchar-1, OriginalColour);
			if (OurOldChar==0 && OurChar!=0) MKARenameEveryoneProperlyExcept(OurChar);
			if (CPUReadByte(0x200001D)>=CPUReadByte(0x2000048))
				gbaWriteByte(0x200001D,CPUReadByte(0x2000048)-1);			
			//if (CPUReadByte(0x200001D)>=OldMaxFrame && OldMaxFrame>0)
			//	gbaWriteByte(0x200001D,OldMaxFrame-1);			
			if (MenuChar==MKA_Reptile && MenuSubchar==3)
				MKARandomNinja();
			else if (MenuChar==MKA_Reptile && MenuSubchar==4)
				MKARandomCyborg();
			else if (MenuChar==MKA_Jade && MenuSubchar==1)
				MKARandomFemale();
		} else {
			if (OurOldChar==0 && OurChar!=0)
				MKARenameEveryoneProperlyExcept(OurChar);
		}
		OurOldChar=CPUReadByte(0x2000025);
	}
	WasInMenu = InMenu;
	
	//DebugPrintf("M=%d O=%d MC=%d,%d Old=%d",InMenu,OurChar,MenuChar,MenuSubchar,OurOldChar);
	
	//  CONTROLS
	u32 J = GetMKInput(pad);
	if (LK || HK) J |= VBA_BUTTON_A;
	if (LP || HP) J |= VBA_BUTTON_B;
	if (BL) J |= VBA_BUTTON_R;
	if (CS) J |= VBA_BUTTON_L;
	if (Throw) {
		if (InMenu) J |= VBA_BUTTON_A;
		else J |= VBA_FORWARD | VBA_BUTTON_B;
	} 
	if (Start) J |= VBA_BUTTON_START;
	if (Select) J |= VBA_BUTTON_SELECT;
	// Fix kick controls to what they should be!
	if (!InMenu && !(J & (VBA_UP | VBA_DOWN))) {
		if (B && LK && !HK) { // Make B+HK do roundhouse, while B+LK does sweep!
			J |= VBA_DOWN;
		}
	} else if (!InMenu && (J & VBA_DOWN)) { // Make D+HK do crouch HK, while D+LK does crouch LK
		if (HK && !LK && !B && !F && !LP && !HP) { 
			J &= ~VBA_BACK;
			J |= VBA_FORWARD;
		}
	}
	// Fix punch controls to what they should be!
	if ((!InMenu) && (J & VBA_DOWN)) {
		// Make D+LP do crouch punch instead of uppercut
		if (LP && !F && !B && !LK && !HK && !HP) { 
			J &= ~VBA_BACK;
			J |= VBA_FORWARD;
		}
	}

	CostumeButton = InMenu && (CS || (J & VBA_BUTTON_SELECT)); // Change Style/Select changes costume

	if (CostumeButton && !OldCostumeButton) {
		int OldSubChar = MenuSubchar;
		u8 OldMaxFrame = CPUReadByte(0x2000048);
		MenuSubchar = MKANextSubchar(MenuChar, MenuSubchar, OriginalColour);
		if (MenuSubchar!=OldSubChar) systemGameRumble(8);
		OurOldChar = CPUReadByte(0x2000025);
		// apply change instantly and safely by skipping to last frame of new animation
		gbaWriteByte(0x200001D,CPUReadByte(0x2000048)-1);
		if (CPUReadByte(0x200001D)>=OldMaxFrame && OldMaxFrame>0)
			gbaWriteByte(0x200001D,OldMaxFrame-1);			
	}
	OurOldChar = CPUReadByte(0x2000025);
	OldCostumeButton = CostumeButton;
	
	return J;
}
u32 GetMKInput(unsigned short pad, int rumbleTime=4) {
	u32 J = StandardMovement(pad) | DecodeWiimote(pad);
    HP=0;LP=0;HK=0;LK=0;BL=0;Throw=0;CS=0;F=0;B=0;Select=0;Start=0;SpecialMove=0;

	// Rumble when they lose health!
	if (OurHealth < OurOldHealth)
		systemGameRumble(rumbleTime);
	OurOldHealth = OurHealth;
		
#ifdef HW_RVL
	WPADData * wp = WPAD_Data(pad);

	if (wp->exp.type == WPAD_EXP_NUNCHUK) {
		// Punch
		if (wp->btns_h & WPAD_BUTTON_LEFT) LP = true;
		if (wp->btns_h & WPAD_BUTTON_UP) HP = true;
		// Kick
		if (wp->btns_h & WPAD_BUTTON_DOWN) LK = true;
		if (wp->btns_h & WPAD_BUTTON_RIGHT) HK = true;
		// Block
		if (wp->btns_h & WPAD_NUNCHUK_BUTTON_Z) BL = true;
		// Throw
		if (wp->btns_h & WPAD_BUTTON_A) Throw = true;
		// Run / Change Styles
		if (wp->btns_h & WPAD_NUNCHUK_BUTTON_C) CS = true;
		// Start and Select
		if (wp->btns_h & WPAD_BUTTON_MINUS) Select=true;
		if (wp->btns_h & WPAD_BUTTON_PLUS) Start=true;
		// Special move
		if (wp->btns_h & WPAD_BUTTON_B) SpecialMove=true;
	} else if (wp->exp.type == WPAD_EXP_CLASSIC) {
		// D-Pad
		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;
		// Punch
		if (wp->btns_h & WPAD_CLASSIC_BUTTON_Y) LP = true;
		if (wp->btns_h & WPAD_CLASSIC_BUTTON_X) HP = true;
		// Kick
		if (wp->btns_h & WPAD_CLASSIC_BUTTON_B) LK = true;
		if (wp->btns_h & WPAD_CLASSIC_BUTTON_A) HK = true;
		// Throw
		if (wp->btns_h & WPAD_CLASSIC_BUTTON_ZR) Throw = true;
		// Block
		if (wp->btns_h & WPAD_CLASSIC_BUTTON_FULL_R) BL = true; // block
		// Run / Change Styles
		if (wp->btns_h & (WPAD_CLASSIC_BUTTON_FULL_L | WPAD_CLASSIC_BUTTON_ZL)) CS = true;
		// Start and Select
		if (wp->btns_h & WPAD_CLASSIC_BUTTON_MINUS) Select = true;
		if (wp->btns_h & WPAD_CLASSIC_BUTTON_PLUS) Start = true;
		// Special move
		if (wp->btns_h & WPAD_BUTTON_B) SpecialMove=true;
	}
#endif
	{
		u32 gc = PAD_ButtonsHeld(pad);
		// DPad moves
		if (gc & PAD_BUTTON_UP) J |= VBA_UP;
		if (gc & PAD_BUTTON_DOWN) J |= VBA_DOWN;
		if (gc & PAD_BUTTON_LEFT) J |= VBA_LEFT;
		if (gc & PAD_BUTTON_RIGHT) J |= VBA_RIGHT;
		// Start and Select
		if (gc & PAD_BUTTON_START) Start = true;
		// Punch
		if (gc & PAD_BUTTON_B) LP = true;
		if (gc & PAD_BUTTON_Y) HP = true;
		// Kick
		if (gc & PAD_BUTTON_A) LK = true;
		if (gc & PAD_BUTTON_X) HK = true;
		// Block
		if (gc & PAD_TRIGGER_R) BL = true;
		// Run / Change Style
		if (gc & PAD_TRIGGER_L) CS = true;
		// Throw
		if (gc & PAD_TRIGGER_Z) Throw = true;
	}
	// Check which side they are on
	if (OurX < OpponentX) {
		VBA_FORWARD = VBA_RIGHT;
		VBA_BACK = VBA_LEFT;
	} else {
		VBA_FORWARD = VBA_LEFT;
		VBA_BACK = VBA_RIGHT;
	}
	if (J & VBA_FORWARD) F = true;
	if (J & VBA_BACK) B = true;
	return J;
}