mirror of
				https://github.com/vcmi/vcmi.git
				synced 2025-10-31 00:07:39 +02:00 
			
		
		
		
	Merge pull request #2301 from Laserlicht/haptic_feedback
Haptic feedback
This commit is contained in:
		| @@ -74,6 +74,8 @@ | ||||
| 	"vcmi.systemOptions.longTouchMenu.entry"     : "%d milliseconds", | ||||
| 	"vcmi.systemOptions.framerateButton.hover"  : "Show FPS", | ||||
| 	"vcmi.systemOptions.framerateButton.help"   : "{Show FPS}\n\nToggle the visibility of the Frames Per Second counter in the corner of the game window", | ||||
| 	"vcmi.systemOptions.hapticFeedbackButton.hover"  : "Haptic feedback", | ||||
| 	"vcmi.systemOptions.hapticFeedbackButton.help"   : "{Haptic feedback}\n\nToggle the haptic feedback on touch inputs", | ||||
|  | ||||
| 	"vcmi.adventureOptions.infoBarPick.hover" : "Show Messages in Info Panel", | ||||
| 	"vcmi.adventureOptions.infoBarPick.help" : "{Show Messages in Info Panel}\n\nWhenever possible, game messages from visiting map objects will be shown in the info panel, instead of popping up in a separate window.", | ||||
|   | ||||
| @@ -74,6 +74,8 @@ | ||||
| 	"vcmi.systemOptions.longTouchMenu.entry"     : "%d Millisekunden", | ||||
| 	"vcmi.systemOptions.framerateButton.hover"  : "FPS anzeigen", | ||||
| 	"vcmi.systemOptions.framerateButton.help"   : "{FPS anzeigen}\n\n Schaltet die Sichtbarkeit des Zählers für die Bilder pro Sekunde in der Ecke des Spielfensters um.", | ||||
| 	"vcmi.systemOptions.hapticFeedbackButton.hover"  : "Haptisches Feedback", | ||||
| 	"vcmi.systemOptions.hapticFeedbackButton.help"   : "{Haptisches Feedback}\n\nHaptisches Feedback bei Touch-Eingaben.", | ||||
|  | ||||
| 	"vcmi.adventureOptions.infoBarPick.hover" : "Meldungen im Infobereich anzeigen", | ||||
| 	"vcmi.adventureOptions.infoBarPick.help" : "{Meldungen im Infobereich anzeigen}\n\nWann immer möglich, werden Spielnachrichten von besuchten Kartenobjekten in der Infoleiste angezeigt, anstatt als Popup-Fenster zu erscheinen", | ||||
|   | ||||
| @@ -3,6 +3,7 @@ | ||||
|     package="eu.vcmi.vcmi"> | ||||
|  | ||||
|     <uses-permission android:name="android.permission.INTERNET" /> | ||||
|     <uses-permission android:name="android.permission.VIBRATE" /> | ||||
|  | ||||
|     <application | ||||
|         android:extractNativeLibs="true" | ||||
| @@ -50,4 +51,4 @@ | ||||
|             android:exported="false"/> | ||||
|     </application> | ||||
|  | ||||
| </manifest> | ||||
| </manifest> | ||||
|   | ||||
| @@ -3,11 +3,14 @@ package eu.vcmi.vcmi; | ||||
| import android.app.Activity; | ||||
| import android.content.Context; | ||||
| import android.content.Intent; | ||||
| import android.os.Build; | ||||
| import android.os.Environment; | ||||
| import android.os.Looper; | ||||
| import android.os.Message; | ||||
| import android.os.Messenger; | ||||
| import android.os.RemoteException; | ||||
| import android.os.VibrationEffect; | ||||
| import android.os.Vibrator; | ||||
|  | ||||
| import org.libsdl.app.SDL; | ||||
| import org.libsdl.app.SDLActivity; | ||||
| @@ -138,6 +141,17 @@ public class NativeMethods | ||||
|     { | ||||
|         internalProgressDisplay(false); | ||||
|     } | ||||
|      | ||||
|     @SuppressWarnings(Const.JNI_METHOD_SUPPRESS) | ||||
|     public static void hapticFeedback() | ||||
|     { | ||||
|         final Context ctx = SDL.getContext(); | ||||
|         if (Build.VERSION.SDK_INT >= 26) { | ||||
|             ((Vibrator) ctx.getSystemService(ctx.VIBRATOR_SERVICE)).vibrate(VibrationEffect.createPredefined(VibrationEffect.EFFECT_TICK)); | ||||
|         } else { | ||||
|             ((Vibrator) ctx.getSystemService(ctx.VIBRATOR_SERVICE)).vibrate(30); | ||||
|         } | ||||
|     } | ||||
|  | ||||
|     private static void internalProgressDisplay(final boolean show) | ||||
|     { | ||||
|   | ||||
| @@ -22,6 +22,12 @@ | ||||
| #include "../gui/MouseButton.h" | ||||
| #include "../gui/WindowHandler.h" | ||||
|  | ||||
| #if defined(VCMI_ANDROID) | ||||
| #include "../../lib/CAndroidVMHelper.h" | ||||
| #elif defined(VCMI_IOS) | ||||
| #include "../ios/utils.h" | ||||
| #endif | ||||
|  | ||||
| #include <SDL_events.h> | ||||
| #include <SDL_hints.h> | ||||
| #include <SDL_timer.h> | ||||
| @@ -32,6 +38,7 @@ InputSourceTouch::InputSourceTouch() | ||||
| 	params.useRelativeMode = settings["general"]["userRelativePointer"].Bool(); | ||||
| 	params.relativeModeSpeedFactor = settings["general"]["relativePointerSpeedMultiplier"].Float(); | ||||
| 	params.longTouchTimeMilliseconds = settings["general"]["longTouchTimeMilliseconds"].Float(); | ||||
| 	params.hapticFeedbackEnabled = settings["general"]["hapticFeedback"].Bool(); | ||||
|  | ||||
| 	if (params.useRelativeMode) | ||||
| 		state = TouchState::RELATIVE_MODE; | ||||
| @@ -100,6 +107,7 @@ void InputSourceTouch::handleEventFingerDown(const SDL_TouchFingerEvent & tfinge | ||||
| { | ||||
| 	// FIXME: better place to update potentially changed settings? | ||||
| 	params.longTouchTimeMilliseconds = settings["general"]["longTouchTimeMilliseconds"].Float(); | ||||
| 	params.hapticFeedbackEnabled = settings["general"]["hapticFeedback"].Bool(); | ||||
|  | ||||
| 	lastTapTimeTicks = tfinger.timestamp; | ||||
|  | ||||
| @@ -215,6 +223,7 @@ void InputSourceTouch::handleUpdate() | ||||
| 		if (currentTime > lastTapTimeTicks + params.longTouchTimeMilliseconds) | ||||
| 		{ | ||||
| 			GH.events().dispatchShowPopup(GH.getCursorPosition()); | ||||
| 			hapticFeedback(); | ||||
|  | ||||
| 			if (GH.windows().isTopWindowPopup()) | ||||
| 				state = TouchState::TAP_DOWN_LONG; | ||||
| @@ -287,3 +296,14 @@ void InputSourceTouch::emitPinchEvent(const SDL_TouchFingerEvent & tfinger) | ||||
| 	if (distanceOld > params.pinchSensitivityThreshold) | ||||
| 		GH.events().dispatchGesturePinch(lastTapPosition, distanceNew / distanceOld); | ||||
| } | ||||
|  | ||||
| void InputSourceTouch::hapticFeedback() { | ||||
| 	if(params.hapticFeedbackEnabled) { | ||||
| #if defined(VCMI_ANDROID) | ||||
|         CAndroidVMHelper vmHelper; | ||||
|         vmHelper.callStaticVoidMethod(CAndroidVMHelper::NATIVE_METHODS_DEFAULT_CLASS, "hapticFeedback"); | ||||
| #elif defined(VCMI_IOS) | ||||
|     	iOS_utils::hapticFeedback(); | ||||
| #endif | ||||
| 	} | ||||
| } | ||||
|   | ||||
| @@ -79,6 +79,8 @@ struct TouchInputParameters | ||||
| 	uint32_t pinchSensitivityThreshold = 10; | ||||
|  | ||||
| 	bool useRelativeMode = false; | ||||
|  | ||||
| 	bool hapticFeedbackEnabled = false; | ||||
| }; | ||||
|  | ||||
| /// Class that handles touchscreen input from SDL events | ||||
| @@ -94,6 +96,8 @@ class InputSourceTouch | ||||
|  | ||||
| 	void emitPanningEvent(const SDL_TouchFingerEvent & tfinger); | ||||
| 	void emitPinchEvent(const SDL_TouchFingerEvent & tfinger); | ||||
| 	 | ||||
| 	void hapticFeedback(); | ||||
|  | ||||
| public: | ||||
| 	InputSourceTouch(); | ||||
|   | ||||
| @@ -15,4 +15,6 @@ double screenScale(); | ||||
|  | ||||
| void showLoadingIndicator(); | ||||
| void hideLoadingIndicator(); | ||||
|  | ||||
| void hapticFeedback(); | ||||
| } | ||||
|   | ||||
| @@ -43,4 +43,10 @@ void hideLoadingIndicator() | ||||
| 	[indicator removeFromSuperview]; | ||||
| 	indicator = nil; | ||||
| } | ||||
|  | ||||
| void hapticFeedback() | ||||
| { | ||||
|     auto hapticGen = [[UIImpactFeedbackGenerator alloc] initWithStyle:UIImpactFeedbackStyleLight]; | ||||
|     [hapticGen impactOccurred]; | ||||
| } | ||||
| } | ||||
|   | ||||
| @@ -153,6 +153,10 @@ GeneralOptionsTab::GeneralOptionsTab() | ||||
| 	{ | ||||
| 		setBoolSetting("video", "showfps", value); | ||||
| 	}); | ||||
| 	addCallback("hapticFeedbackChanged", [](bool value) | ||||
| 	{ | ||||
| 		setBoolSetting("general", "hapticFeedback", value); | ||||
| 	}); | ||||
|  | ||||
| 	//moved from "other" tab that is disabled for now to avoid excessible tabs with barely any content | ||||
| 	addCallback("availableCreaturesAsDwellingChanged", [=](int value) | ||||
| @@ -190,6 +194,10 @@ GeneralOptionsTab::GeneralOptionsTab() | ||||
| 	std::shared_ptr<CToggleButton> framerateCheckbox = widget<CToggleButton>("framerateCheckbox"); | ||||
| 	framerateCheckbox->setSelected(settings["video"]["showfps"].Bool()); | ||||
|  | ||||
| 	std::shared_ptr<CToggleButton> hapticFeedbackCheckbox = widget<CToggleButton>("hapticFeedbackCheckbox"); | ||||
| 	if (hapticFeedbackCheckbox) | ||||
| 		hapticFeedbackCheckbox->setSelected(settings["general"]["hapticFeedback"].Bool()); | ||||
|  | ||||
| 	std::shared_ptr<CSlider> musicSlider = widget<CSlider>("musicSlider"); | ||||
| 	musicSlider->scrollTo(CCS->musich->getVolume()); | ||||
|  | ||||
|   | ||||
| @@ -33,7 +33,8 @@ | ||||
| 				"extraDump", | ||||
| 				"userRelativePointer", | ||||
| 				"relativePointerSpeedMultiplier", | ||||
| 				"longTouchTimeMilliseconds" | ||||
| 				"longTouchTimeMilliseconds", | ||||
| 				"hapticFeedback" | ||||
| 			], | ||||
| 			"properties" : { | ||||
| 				"playerName" : { | ||||
| @@ -101,6 +102,10 @@ | ||||
| 				"longTouchTimeMilliseconds" : { | ||||
| 					"type" : "number", | ||||
| 					"default" : 1000 | ||||
| 				}, | ||||
| 				"hapticFeedback" : { | ||||
| 					"type" : "boolean", | ||||
| 					"default" : false | ||||
| 				} | ||||
| 			} | ||||
| 		}, | ||||
|   | ||||
| @@ -57,6 +57,10 @@ | ||||
| 					"name": "longTouchLabel", | ||||
| 					"text": "vcmi.systemOptions.longTouchButton.hover", | ||||
| 					"created" : "touchscreen" | ||||
| 				}, | ||||
| 				{ | ||||
| 					"text": "vcmi.systemOptions.hapticFeedbackButton.hover", | ||||
| 					"created" : "mobile" | ||||
| 				} | ||||
| 			] | ||||
| 		}, | ||||
| @@ -76,7 +80,7 @@ | ||||
| 					"name": "scalingButton", | ||||
| 					"type": "buttonGear", | ||||
| 					"help": "vcmi.systemOptions.scalingButton", | ||||
| 					"callback": "setGameScaling", | ||||
| 					"callback": "setGameScaling" | ||||
| 				}, | ||||
| 				{ | ||||
| 					"name": "fullscreenBorderlessCheckbox", | ||||
| @@ -106,6 +110,12 @@ | ||||
| 					"help": "vcmi.systemOptions.longTouchButton", | ||||
| 					"callback": "setLongTouchDuration", | ||||
| 					"created" : "touchscreen" | ||||
| 				}, | ||||
| 				{ | ||||
| 					"name": "hapticFeedbackCheckbox", | ||||
| 					"help": "vcmi.systemOptions.hapticFeedbackButton", | ||||
| 					"callback": "hapticFeedbackChanged", | ||||
| 					"created" : "mobile" | ||||
| 				} | ||||
| 			] | ||||
| 		}, | ||||
|   | ||||
		Reference in New Issue
	
	Block a user