From 4e9f297c3eabf48654eb368c3689e314dc708007 Mon Sep 17 00:00:00 2001
From: Duc Le <duchuule@users.noreply.github.com>
Date: Sat, 19 Sep 2015 17:01:09 +0000
Subject: [PATCH] add option to change between hold and toggle turbo mode

---
 ControllerInput.cpp        |  6 +++++-
 EmulatorSettings.h         | 14 ++++++++++++++
 HIDControllerInput.cpp     | 19 ++++++++++++++-----
 KeyboardInput.cpp          |  5 ++++-
 Package.appxmanifest       |  2 +-
 SettingsPage.xaml          | 15 +++++++++++++--
 SettingsPage.xaml.cpp      | 10 ++++++++++
 SettingsPage.xaml.h        |  1 +
 VirtualControllerInput.cpp |  5 ++++-
 vbaFunctions.cpp           | 26 ++++++++++++++++----------
 10 files changed, 82 insertions(+), 21 deletions(-)

diff --git a/ControllerInput.cpp b/ControllerInput.cpp
index 7aa6596..ecc89ee 100644
--- a/ControllerInput.cpp
+++ b/ControllerInput.cpp
@@ -1,5 +1,6 @@
 #ifndef NO_XBOX
 #include "ControllerInput.h"
+#include "EmulatorSettings.h"
 
 namespace VBA10
 {
@@ -25,7 +26,10 @@ namespace VBA10
 		{
 			XINPUT_STATE state = this->xboxPad->GetState();
 
-			this->state.TurboTogglePressed = (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB);
+			if (EmulatorSettings::Current->TurboBehavior == 0)
+				this->state.TurboTogglePressed = (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB);
+			else
+				this->state.TurboPressed = (state.Gamepad.wButtons & XINPUT_GAMEPAD_RIGHT_THUMB);
 
 			this->state.LeftPressed = ((state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_LEFT) || (state.Gamepad.sThumbLX < (-XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)));
 			this->state.RightPressed = ((state.Gamepad.wButtons & XINPUT_GAMEPAD_DPAD_RIGHT) || (state.Gamepad.sThumbLX > (XINPUT_GAMEPAD_LEFT_THUMB_DEADZONE)));
diff --git a/EmulatorSettings.h b/EmulatorSettings.h
index 19de746..0a407d1 100644
--- a/EmulatorSettings.h
+++ b/EmulatorSettings.h
@@ -167,6 +167,18 @@ namespace VBA10
 			}
 		}
 
+		property int TurboBehavior
+		{
+			int get()
+			{
+				return GetValueOrDefault<int>(TurboBehaviorKey, TurboBehaviorDefault);
+			}
+			void set(int value)
+			{
+				AddOrUpdateValue(TurboBehaviorKey, value);
+			}
+		}
+
 
 #pragma region Button positions
 
@@ -607,6 +619,7 @@ namespace VBA10
 		Platform::String^ ThemeKey = "ThemeKey";
 		Platform::String^ SmoothButtonKey = "SmoothButtonKey";
 		Platform::String^ HideHamburgerKey = "HideHamburgerKey";
+		Platform::String^ TurboBehaviorKey = "TurboBehaviorKey";
 
 #pragma region button positions
 		Platform::String^ PadLeftPKey = "PadLeftPKey";
@@ -660,6 +673,7 @@ namespace VBA10
 		const int ThemeDefault = 0; 
 		const int SmoothButtonDefault = 3;
 		const bool HideHamburgerDefault = false;
+		const int TurboBehaviorDefault = 0;
 
 
 
diff --git a/HIDControllerInput.cpp b/HIDControllerInput.cpp
index a2290e8..00b50e4 100644
--- a/HIDControllerInput.cpp
+++ b/HIDControllerInput.cpp
@@ -1,4 +1,5 @@
 #include "HIDControllerInput.h"
+#include "EmulatorSettings.h"
 
 using namespace Windows::Devices::HumanInterfaceDevice;
 using namespace Platform::Collections;
@@ -107,6 +108,8 @@ namespace VBA10
 		if (this->shouldUpdate == false)
 			return;
 
+		bool turboButtonPressed = false;
+
 		//check buttons
 		auto bcontrols = inputReport->ActivatedBooleanControls;
 
@@ -118,7 +121,7 @@ namespace VBA10
 
 			if (booleanControlMapping->HasKey(id))
 				GetMapping(booleanControlMapping->Lookup(id), &state.LeftPressed, &state.RightPressed, &state.UpPressed, &state.DownPressed,
-					&state.APressed, &state.BPressed, &state.LPressed, &state.RPressed, &state.SelectPressed, &state.StartPressed, &state.TurboTogglePressed);
+					&state.APressed, &state.BPressed, &state.LPressed, &state.RPressed, &state.SelectPressed, &state.StartPressed, &turboButtonPressed);
 		}
 
 		//check numeric control
@@ -135,29 +138,35 @@ namespace VBA10
 			{
 				if (controlExt->Mapping->HasKey(1))
 					GetMapping(controlExt->Mapping->Lookup(1), &state.LeftPressed, &state.RightPressed, &state.UpPressed, &state.DownPressed,
-						&state.APressed, &state.BPressed, &state.LPressed, &state.RPressed, &state.SelectPressed, &state.StartPressed, &state.TurboTogglePressed);
+						&state.APressed, &state.BPressed, &state.LPressed, &state.RPressed, &state.SelectPressed, &state.StartPressed, &turboButtonPressed);
 			}
 			else if (controlExt->Type == 1 && control->Value - controlExt->DefaultValue < -0.25 * controlExt->DefaultValue) //axis-
 			{
 				if (controlExt->Mapping->HasKey(-1))
 					GetMapping(controlExt->Mapping->Lookup(-1), &state.LeftPressed, &state.RightPressed, &state.UpPressed, &state.DownPressed,
-						&state.APressed, &state.BPressed, &state.LPressed, &state.RPressed, &state.SelectPressed, &state.StartPressed, &state.TurboTogglePressed);
+						&state.APressed, &state.BPressed, &state.LPressed, &state.RPressed, &state.SelectPressed, &state.StartPressed, &turboButtonPressed);
 			}
 			else if (controlExt->Type == 1 && control->Value - controlExt->DefaultValue > 0.25 * controlExt->DefaultValue) //axis+
 			{
 				if (controlExt->Mapping->HasKey(1))
 					GetMapping(controlExt->Mapping->Lookup(1), &state.LeftPressed, &state.RightPressed, &state.UpPressed, &state.DownPressed,
-						&state.APressed, &state.BPressed, &state.LPressed, &state.RPressed, &state.SelectPressed, &state.StartPressed, &state.TurboTogglePressed);
+						&state.APressed, &state.BPressed, &state.LPressed, &state.RPressed, &state.SelectPressed, &state.StartPressed, &turboButtonPressed);
 			}
 			else if (controlExt->Type == 2 && control->Value != controlExt->DefaultValue) //hat d-pad
 			{
 				if (controlExt->Mapping->HasKey(control->Value))
 					GetMapping(controlExt->Mapping->Lookup(control->Value), &state.LeftPressed, &state.RightPressed, &state.UpPressed, &state.DownPressed,
-						&state.APressed, &state.BPressed, &state.LPressed, &state.RPressed, &state.SelectPressed, &state.StartPressed, &state.TurboTogglePressed);
+						&state.APressed, &state.BPressed, &state.LPressed, &state.RPressed, &state.SelectPressed, &state.StartPressed, &turboButtonPressed);
 			}
 		}
 
 
+		//transfer turbo button press to appropriate turbo behavior
+		if (EmulatorSettings::Current->TurboBehavior == 0)
+			state.TurboTogglePressed = turboButtonPressed;
+		else
+			state.TurboPressed = turboButtonPressed;
+
 	}
 
 	void HIDControllerInput::Update(bool shouldUpdate)
diff --git a/KeyboardInput.cpp b/KeyboardInput.cpp
index 582e61b..278ad04 100644
--- a/KeyboardInput.cpp
+++ b/KeyboardInput.cpp
@@ -24,7 +24,10 @@ namespace VBA10
 	{
 		ZeroMemory(&state, sizeof(ControllerState));
 
-		this->state.TurboTogglePressed = (bool)(window->GetKeyState(GetTurboKeyBinding()) & CoreVirtualKeyStates::Down);
+		if (EmulatorSettings::Current->TurboBehavior == 0)
+			this->state.TurboTogglePressed = (bool)(window->GetKeyState(GetTurboKeyBinding()) & CoreVirtualKeyStates::Down);
+		else
+			this->state.TurboPressed = (bool)(window->GetKeyState(GetTurboKeyBinding()) & CoreVirtualKeyStates::Down);
 
 		this->state.StartPressed = (bool)(window->GetKeyState(GetStartKeyBinding()) & CoreVirtualKeyStates::Down);
 		this->state.SelectPressed = (bool)(window->GetKeyState(GetSelectKeyBinding()) & CoreVirtualKeyStates::Down);
diff --git a/Package.appxmanifest b/Package.appxmanifest
index 5826734..267ac1a 100644
--- a/Package.appxmanifest
+++ b/Package.appxmanifest
@@ -1,6 +1,6 @@
 <?xml version="1.0" encoding="utf-8"?>
 <Package xmlns="http://schemas.microsoft.com/appx/manifest/foundation/windows10" xmlns:mp="http://schemas.microsoft.com/appx/2014/phone/manifest" xmlns:uap="http://schemas.microsoft.com/appx/manifest/uap/windows10" IgnorableNamespaces="uap mp">
-  <Identity Name="16994Sparksoft.VBA10" Publisher="CN=9289A21E-3389-49E2-A9E0-46AA1289C3CB" Version="1.12.162.0" />
+  <Identity Name="16994Sparksoft.VBA10" Publisher="CN=9289A21E-3389-49E2-A9E0-46AA1289C3CB" Version="1.13.165.0" />
   <mp:PhoneIdentity PhoneProductId="2b9558e5-6253-426c-8989-3284f508e743" PhonePublisherId="00000000-0000-0000-0000-000000000000" />
   <Properties>
     <DisplayName>VBA10</DisplayName>
diff --git a/SettingsPage.xaml b/SettingsPage.xaml
index ca1ae25..ca3ee3e 100644
--- a/SettingsPage.xaml
+++ b/SettingsPage.xaml
@@ -131,8 +131,19 @@
                                   Header="D-Pad Style"
                                   Margin =" 0, 0, 0, 12">
                             <ComboBoxItem>8-way</ComboBoxItem>
-                            <ComboBoxItem>fixed analogue stick</ComboBoxItem>
-                            <ComboBoxItem>dynamic analogue stick</ComboBoxItem>
+                            <ComboBoxItem>Fixed analogue stick</ComboBoxItem>
+                            <ComboBoxItem>Dynamic analogue stick</ComboBoxItem>
+                        </ComboBox>
+
+                        <ComboBox Name="cboTurboBehavior" 
+                                  HorizontalAlignment="Stretch" 
+                                  VerticalAlignment="Top" 
+                                  SelectedIndex="0"
+                                  Header="Turbo Button Behavior"
+                                  Margin =" 0, 0, 0, 12"
+                                  SelectionChanged="cboTurboBehavior_SelectionChanged">
+                            <ComboBoxItem>Toggle turbo on/off</ComboBoxItem>
+                            <ComboBoxItem>Hold to activate</ComboBoxItem>
                         </ComboBox>
 
                         <Button x:Name="editButonLayoutBtn" 
diff --git a/SettingsPage.xaml.cpp b/SettingsPage.xaml.cpp
index 5705785..5d4943c 100644
--- a/SettingsPage.xaml.cpp
+++ b/SettingsPage.xaml.cpp
@@ -79,6 +79,7 @@ SettingsPage::SettingsPage()
 	this->controllerOpacitySlider->Value = (double)GetControllerOpacity();
 	this->deadzoneSlider->Value = (double)GetDeadzone();
 	this->dpadComboBox->SelectedIndex = EmulatorSettings::Current->DPadStyle;
+	this->cboTurboBehavior->SelectedIndex = EmulatorSettings::Current->TurboBehavior;
 
 	//change the settings that depend on enabletouchcontrol
 	touchToggle_Toggled(nullptr, nullptr);
@@ -715,3 +716,12 @@ void SettingsPage::hideHamburgerToggle_Toggled(Platform::Object^ sender, Windows
 		EmulatorSettings::Current->HideHamburger = this->hideHamburgerToggle->IsOn;
 	}
 }
+
+
+void SettingsPage::cboTurboBehavior_SelectionChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e)
+{
+	if (initdone)
+	{
+		EmulatorSettings::Current->TurboBehavior = this->cboTurboBehavior->SelectedIndex;
+	}
+}
diff --git a/SettingsPage.xaml.h b/SettingsPage.xaml.h
index 9dc5d8c..52b45e9 100644
--- a/SettingsPage.xaml.h
+++ b/SettingsPage.xaml.h
@@ -80,5 +80,6 @@ namespace VBA10
 		void cboTheme_SelectionChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e);
 		void editButonLayoutBtn_Click(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
 		void hideHamburgerToggle_Toggled(Platform::Object^ sender, Windows::UI::Xaml::RoutedEventArgs^ e);
+		void cboTurboBehavior_SelectionChanged(Platform::Object^ sender, Windows::UI::Xaml::Controls::SelectionChangedEventArgs^ e);
 	};
 }
diff --git a/VirtualControllerInput.cpp b/VirtualControllerInput.cpp
index 7fd969c..ddb59d1 100644
--- a/VirtualControllerInput.cpp
+++ b/VirtualControllerInput.cpp
@@ -396,7 +396,10 @@ namespace VBA10
 					}
 					if (this->turboRect.Contains(point))
 					{
-						this->state.TurboTogglePressed = true;
+						if (EmulatorSettings::Current->TurboBehavior == 0)
+							this->state.TurboTogglePressed = true;
+						else 
+							this->state.TurboPressed = true;
 					}
 					if (this->comboRect.Contains(point))
 					{
diff --git a/vbaFunctions.cpp b/vbaFunctions.cpp
index 6582a3e..fa1974d 100644
--- a/vbaFunctions.cpp
+++ b/vbaFunctions.cpp
@@ -254,16 +254,22 @@ u32 systemReadJoypad(int gamepad)
 		}
 	}
 
-	if(EmulatorSettings::Current->EnableTurbo &&
-		(oldKeyboardState.TurboPressed && !keyboardState->TurboPressed) ||
-		(oldControllerState.TurboPressed && !controllerState->TurboPressed) ||
-		(oldvControllerState.TurboPressed && !vControllerState->TurboPressed) ||
-		(oldHidState.TurboPressed && !hidState->TurboPressed))
-	{
-		EmulatorSettings::Current->EnableTurbo = false;
-	}
-
-	if(EmulatorSettings::Current->EnableTurbo || keyboardState->TurboPressed || controllerState->TurboPressed || vControllerState->TurboPressed || hidState->TurboPressed)
+	//if(EmulatorSettings::Current->EnableTurbo &&
+	//	(oldKeyboardState.TurboPressed && !keyboardState->TurboPressed) ||
+	//	(oldControllerState.TurboPressed && !controllerState->TurboPressed) ||
+	//	(oldvControllerState.TurboPressed && !vControllerState->TurboPressed) ||
+	//	(oldHidState.TurboPressed && !hidState->TurboPressed))
+	//{
+	//	EmulatorSettings::Current->EnableTurbo = false;
+	//}
+
+	bool useTurbo = EmulatorSettings::Current->EnableTurbo;
+
+	//reverse function if turbopressed
+	if (keyboardState->TurboPressed || controllerState->TurboPressed || vControllerState->TurboPressed || hidState->TurboPressed)
+		useTurbo = !useTurbo;
+
+	if(useTurbo )
 		res |= 1024;
 	
 	oldControllerState = *controllerState;