Feature: gyroscope controls

This commit is contained in:
Duy Tran Khanh committed 2023-02-05 12:16:46 +07:00
1 parent 5cad42909b
commit 54c2564c2f
8 files changed
+122 -3

No files matched your search

+2
View File
@@ -100,6 +100,7 @@ add_executable(PojavLauncher
external/TOInsetGroupedTableView/TOInsetGroupedTableView/TOInsetGroupedTableView.m
input/ControllerInput.m
input/GyroInput.m
input/KeyboardInput.m
AccountListViewController.m
@@ -143,6 +144,7 @@ target_link_libraries(PojavLauncher
"-framework CAltKit"
"-framework CoreGraphics"
"-framework CoreImage"
"-framework CoreMotion"
"-framework CoreServices"
"-framework GameController"
"-framework QuartzCore"
+3
View File
@@ -122,6 +122,9 @@ void loadPreferences(BOOL reset) {
setDefaultValueForPref(envPrefDict, @"press_duration", @(400));
setDefaultValueForPref(envPrefDict, @"mouse_scale", @(100));
setDefaultValueForPref(envPrefDict, @"mouse_speed", @(100));
setDefaultValueForPref(envPrefDict, @"gyroscope_enable", @NO);
setDefaultValueForPref(envPrefDict, @"gyroscope_invert_x_axis", @NO);
setDefaultValueForPref(envPrefDict, @"gyroscope_sensitivity", @(100));
setDefaultValueForPref(envPrefDict, @"default_ctrl", @"default.json");
setDefaultValueForPref(envPrefDict, @"game_directory", @"default");
setDefaultValueForPref(envPrefDict, @"java_args", @"");
@@ -259,6 +259,32 @@ typedef void(^CreateView)(UITableViewCell *, NSString *, NSDictionary *);
@"hasDetail": @YES,
@"icon": @"slider.horizontal.below.rectangle",
@"type": self.typeSwitch
},
@{@"key": @"gyroscope_enable",
@"hasDetail": @YES,
@"icon": @"gyroscope",
@"type": self.typeSwitch,
@"enableCondition": ^BOOL(){
return realUIIdiom != UIUserInterfaceIdiomTV;
}
},
@{@"key": @"gyroscope_invert_x_axis",
@"hasDetail": @YES,
@"icon": @"arrow.left.and.right",
@"type": self.typeSwitch,
@"enableCondition": ^BOOL(){
return realUIIdiom != UIUserInterfaceIdiomTV;
}
},
@{@"key": @"gyroscope_sensitivity",
@"hasDetail": @YES,
@"icon": @"move.3d",
@"type": self.typeSlider,
@"min": @(50),
@"max": @(300),
@"enableCondition": ^BOOL(){
return realUIIdiom != UIUserInterfaceIdiomTV;
}
}
], @[
// Java tweaks
+26 -2
View File
@@ -12,6 +12,7 @@
#import "customcontrols/CustomControlsUtils.h"
#import "input/ControllerInput.h"
#import "input/GyroInput.h"
#import "input/KeyboardInput.h"
#import "JavaLauncher.h"
@@ -79,7 +80,11 @@ BOOL slideableHotbar;
}
// Perform Gamepad joystick ticking, while also controlling frame rate?
CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:ControllerInput.class selector:@selector(tick)];
id tickInput = ^{
[GyroInput tick];
[ControllerInput tick];
};
CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:tickInput selector:@selector(invoke)];
if (@available(iOS 15.0, tvOS 15.0, *)) {
displayLink.preferredFrameRateRange = CAFrameRateRangeMake(60, 120, 120);
}
@@ -289,6 +294,11 @@ BOOL slideableHotbar;
self.inputTextField.autocorrectionType = UITextAutocorrectionTypeNo;
}
BOOL gyroEnabled = [getPreference(@"gyroscope_enable") boolValue];
BOOL gyroInvertX = [getPreference(@"gyroscope_invert_x_axis") boolValue];
int gyroSensitivity = [getPreference(@"gyroscope_sensitivity") intValue];
[GyroInput updateSensitivity:gyroEnabled?gyroSensitivity:0 invertXAxis:gyroInvertX];
self.mouseSpeed = [getPreference(@"mouse_speed") floatValue] / 100.0;
slideableHotbar = [getPreference(@"slideable_hotbar") boolValue];
@@ -450,7 +460,21 @@ BOOL slideableHotbar;
}
lastVirtualMousePoint = location;
}
callback_SurfaceViewController_onTouch(event, location.x * screenScale, location.y * screenScale);
CGFloat x = location.x;
CGFloat y = location.y;
switch (event) {
case ACTION_DOWN:
lastVirtualMousePoint = location;
break;
case ACTION_MOVE:
event = ACTION_MOVE_MOTION;
x = location.x - lastVirtualMousePoint.x;
y = location.y - lastVirtualMousePoint.y;
lastVirtualMousePoint = location;
break;
}
callback_SurfaceViewController_onTouch(event, x * screenScale, y * screenScale);
}
#pragma mark - Input: on-surface functions
+8
View File
@@ -189,6 +189,14 @@
"preference.detail.virtmouse_enable" = "Enable this option to start with virtual mouse on";
"preference.title.slideable_hotbar" = "Slideable hotbar";
"preference.detail.slideable_hotbar" = "Make the hotbar slideable like the mouse wheel";
"preference.title.gyroscope_enable" = "Enable gyroscope controls";
"preference.detail.gyroscope_enable" = "Enabling this will allow you to turn in game by turning your device";
"preference.title.gyroscope_invert_x_axis" = "Invert gyroscope left and right";
"preference.detail.gyroscope_invert_x_axis" = "Inverts the X-axis of the gyroscope";
"preference.title.gyroscope_sensitivity" = "Gyroscope controls sensitivity";
"preference.detail.gyroscope_sensitivity" = "Adjust the sensitivity of gyroscope controls";
"preference.title.java_home" = "Use Java 17 for Minecraft < 1.17";
"preference.detail.java_home" = "Java 8 is used by default for those versions. Enable this option to force use Java 17, however compatibility with modded is not guaranteed.";
"preference.title.java_args" = "JVM Launch arguments";
+1 -1
View File
@@ -245,7 +245,7 @@ BOOL leftShiftHeld;
// Compute delta since last tick time
CGFloat deltaX = lastXValue * acceleration * 18;
CGFloat deltaY = -lastYValue * acceleration * 18;
CGFloat deltaTimeScale = (frameTime - lastFrameTime) / 0.016666666; // Scale of 1 = 60Hz
CGFloat deltaTimeScale = (frameTime - lastFrameTime) / (1.0/60.0); // Scale of 1 = 60Hz
deltaX *= deltaTimeScale;
deltaY *= deltaTimeScale;
+8
View File
@@ -0,0 +1,8 @@
#import <Foundation/Foundation.h>
@interface GyroInput : NSObject
+ (void)updateSensitivity:(int)sensitivity invertXAxis:(BOOL)invertX;
+ (void)tick;
@end
+48
View File
@@ -0,0 +1,48 @@
#import <CoreMotion/CoreMotion.h>
#import <UIKit/UIKit.h>
#import "GyroInput.h"
#import "../SurfaceViewController.h"
#import "../utils.h"
@implementation GyroInput
static CGFloat lastXValue, lastYValue, lastFrameTime;
static CGFloat gyroSensitivity;
static int gyroInvertX;
static CMMotionManager* cmInstance;
+ (void)updateSensitivity:(int)sensitivity invertXAxis:(BOOL)invertX {
if (cmInstance == nil) {
cmInstance = [[CMMotionManager alloc] init];
}
gyroSensitivity = sensitivity / 100.0;
if (sensitivity > 0) {
gyroInvertX = invertX ? 1 : -1;
[cmInstance startGyroUpdates];
} else {
[cmInstance stopGyroUpdates];
}
}
+ (void)tick {
if (!isGrabbing || gyroSensitivity == 0) return;
// Compute delta since last tick time
CGFloat frameTime = CACurrentMediaTime();
CGFloat factor = gyroSensitivity;
if (lastFrameTime != 0) {
CGFloat deltaTimeScale = (frameTime - lastFrameTime) / (1.0/60.0); // Scale of 1 = 60Hz
factor *= deltaTimeScale;
}
// 100% sensitivity -> 1:1 ratio between real world and ingame camera
lastXValue = cmInstance.gyroData.rotationRate.x / (M_PI*360) * windowWidth * factor * gyroInvertX;
lastYValue = cmInstance.gyroData.rotationRate.y / (M_PI*180) * windowHeight * factor;
SurfaceViewController *vc = (id)(currentWindow().rootViewController);
[vc sendTouchPoint:CGPointMake(lastXValue, lastYValue) withEvent:ACTION_MOVE_MOTION];
lastFrameTime = frameTime;
}
@end