Feature: gyroscope controls
This commit is contained in:
1 parent
5cad42909b
commit
54c2564c2f
8 files changed
+122
-3
No files matched your search
@@ -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"
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
@@ -0,0 +1,8 @@
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
@interface GyroInput : NSObject
|
||||
|
||||
+ (void)updateSensitivity:(int)sensitivity invertXAxis:(BOOL)invertX;
|
||||
+ (void)tick;
|
||||
|
||||
@end
|
||||
@@ -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
|
||||
Reference in new issue
Block a user