Changes and fixes to input, mark nonatomic to others

- Controller: implement ticking, swapped thumbstick mapping to match
common usage
- External mouse should continue sending move while mouse button is
being held
- Tweak touch scroll velocity division to 100
This commit is contained in:
Duy Tran Khanh committed 2022-10-02 10:54:04 +07:00
1 parent 6464c62d36
commit b46c64cc59
12 files changed
+117 -74

No files matched your search

+1 -1
View File
@@ -3,7 +3,7 @@
@interface FileListViewController () {
}
@property(nonatomic, strong) NSMutableArray *fileList;
@property(nonatomic) NSMutableArray *fileList;
@end
+3
View File
@@ -72,6 +72,7 @@ int versionSelectedAt = 0;
[self.toolbar addSubview:self.progressViewSub];
self.buttonInstall = [UIButton buttonWithType:UIButtonTypeSystem];
setButtonPointerInteraction(self.buttonInstall);
self.buttonInstall.enabled = NO;
[self.buttonInstall setTitle:NSLocalizedString(@"Play", nil) forState:UIControlStateNormal];
self.buttonInstall.autoresizingMask = AUTORESIZE_MASKS;
@@ -83,6 +84,7 @@ int versionSelectedAt = 0;
[self.toolbar addSubview:self.buttonInstall];
UIButton *buttonCustomControls = [UIButton buttonWithType:UIButtonTypeSystem];
setButtonPointerInteraction(buttonCustomControls);
[buttonCustomControls setTitle:NSLocalizedString(@"launcher.menu.custom_controls", nil) forState:UIControlStateNormal];
buttonCustomControls.autoresizingMask = AUTORESIZE_MASKS;
buttonCustomControls.frame = CGRectMake(0, self.toolbar.frame.size.height/2, splitWidth, self.toolbar.frame.size.height/2);
@@ -90,6 +92,7 @@ int versionSelectedAt = 0;
[self.toolbar addSubview:buttonCustomControls];
UIButton *buttonInstallJar = [UIButton buttonWithType:UIButtonTypeSystem];
setButtonPointerInteraction(buttonInstallJar);
[buttonInstallJar setTitle:NSLocalizedString(@"launcher.menu.install_jar", nil) forState:UIControlStateNormal];
buttonInstallJar.autoresizingMask = AUTORESIZE_MASKS;
buttonInstallJar.frame = CGRectMake(splitWidth*2, self.toolbar.frame.size.height/2, splitWidth, self.toolbar.frame.size.height/2);
+1 -1
View File
@@ -5,7 +5,7 @@
#import "ios_uikit_bridge.h"
@interface LauncherPrefGameDirViewController ()<UITextFieldDelegate>
@property NSMutableArray *array;
@property(nonatomic) NSMutableArray *array;
@end
@implementation LauncherPrefGameDirViewController
+3 -3
View File
@@ -12,9 +12,9 @@
typedef void(^CreateView)(UITableViewCell *, NSString *, NSDictionary *);
@interface LauncherPreferencesViewController2()<UIPickerViewDataSource, UIPickerViewDelegate> {}
@property NSArray<NSString*>* prefSections;
@property NSArray<NSArray<NSDictionary*>*>* prefContents;
@property BOOL prefDetailVisible;
@property(nonatomic) NSArray<NSString*>* prefSections;
@property(nonatomic) NSArray<NSArray<NSDictionary*>*>* prefContents;
@property(nonatomic) BOOL prefDetailVisible;
@property CreateView typeButton, typeChildPane, typePickField, typeTextField, typeSlider, typeSwitch;
@end
+11 -8
View File
@@ -25,7 +25,7 @@ extern NSMutableDictionary *prefDict;
#pragma mark - LoginViewController
@interface LoginViewController () <ASWebAuthenticationPresentationContextProviding> {}
@property ASWebAuthenticationSession *authVC;
@property(nonatomic) ASWebAuthenticationSession *authVC;
@end
@implementation LoginViewController
@@ -38,11 +38,11 @@ extern NSMutableDictionary *prefDict;
[[NSNotificationCenter defaultCenter] addObserver:self selector:@selector(msaLoginCallback:) name:@"MSALoginCallback" object:nil];
CGRect screenBounds = [[UIScreen mainScreen] bounds];
CGRect screenBounds = UIScreen.mainScreen.bounds;
int width = (int) roundf(screenBounds.size.width);
int height = (int) roundf(screenBounds.size.height) - self.navigationController.navigationBar.frame.size.height;
int rawHeight = (int) roundf(screenBounds.size.height);
CGFloat width = screenBounds.size.width;
CGFloat height = screenBounds.size.height - self.navigationController.navigationBar.frame.size.height;
CGFloat rawHeight = screenBounds.size.height;
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.view.frame];
scrollView.autoresizingMask = UIViewAutoresizingFlexibleHeight | UIViewAutoresizingFlexibleWidth;
@@ -99,7 +99,8 @@ extern NSMutableDictionary *prefDict;
self.navigationItem.rightBarButtonItem = [[UIBarButtonItem alloc] initWithTitle:NSLocalizedString(@"login.menu.about", nil) style:UIBarButtonItemStyleDone target:self action:@selector(aboutLauncher)];
}
UIButton *button_faq = [UIButton buttonWithType:UIButtonTypeRoundedRect];
UIButton *button_faq = [UIButton buttonWithType:UIButtonTypeSystem];
setButtonPointerInteraction(button_faq);
[button_faq setTitle:NSLocalizedString(@"FAQ", @"Frequently asked questions") forState:UIControlStateNormal];
button_faq.frame = CGRectMake(widthSplit2 - (((width - widthSplit * 2.0) / 2) / 2), (height - 80.0), (width - widthSplit * 2.0) / 2, 40.0);
if([date isEqualToString:@"06-29"] || [date isEqualToString:@"06-30"] || [date isEqualToString:@"07-01"]) {
@@ -117,7 +118,8 @@ extern NSMutableDictionary *prefDict;
}
[scrollView addSubview:button_faq];
UIButton *button_login = [UIButton buttonWithType:UIButtonTypeRoundedRect];
UIButton *button_login = [UIButton buttonWithType:UIButtonTypeSystem];
setButtonPointerInteraction(button_login);
[button_login setTitle:NSLocalizedString(@"Sign in", nil) forState:UIControlStateNormal];
button_login.frame = CGRectMake(button_faq.frame.origin.x - button_faq.frame.size.width - 20, (height - 80.0), (width - widthSplit * 2.0) / 2, 40.0);
if([date isEqualToString:@"06-29"] || [date isEqualToString:@"06-30"] || [date isEqualToString:@"07-01"]) {
@@ -147,7 +149,8 @@ extern NSMutableDictionary *prefDict;
}
[scrollView addSubview:button_login];
UIButton *button_accounts = [UIButton buttonWithType:UIButtonTypeRoundedRect];
UIButton *button_accounts = [UIButton buttonWithType:UIButtonTypeSystem];
setButtonPointerInteraction(button_accounts);
[button_accounts setTitle:NSLocalizedString(@"Accounts", nil) forState:UIControlStateNormal];
button_accounts.frame = CGRectMake(button_faq.frame.origin.x + button_faq.frame.size.width + 20, (height - 80.0), (width - widthSplit * 2.0) / 2, 40.0);
if([date isEqualToString:@"06-29"] || [date isEqualToString:@"06-30"] || [date isEqualToString:@"07-01"]) {
+4 -3
View File
@@ -5,11 +5,12 @@
CGRect virtualMouseFrame;
CGPoint lastVirtualMousePoint;
@interface SurfaceViewController : UIViewController
@property(nonatomic, strong) GameSurfaceView* surfaceView;
@property(nonatomic) GameSurfaceView* surfaceView;
@property UIImageView* mousePointerView;
@property UIPanGestureRecognizer* scrollPanGesture;
@property(nonatomic) UIPanGestureRecognizer* scrollPanGesture;
- (void)sendTouchPoint:(CGPoint)location withEvent:(int)event;
@end
+31 -29
View File
@@ -220,6 +220,12 @@ BOOL slideableHotbar;
[self.navigationItem setHidesBackButton:YES animated:YES];
[self.navigationController setNavigationBarHidden:YES animated:YES];
// Perform Gamepad joystick ticking, while alos controlling frame rate?
CADisplayLink *displayLink = [CADisplayLink displayLinkWithTarget:ControllerInput.class selector:@selector(tick)];
if (@available(iOS 15.0, *)) {
displayLink.preferredFrameRateRange = CAFrameRateRangeMake(60, 120, 120);
}
[displayLink addToRunLoop:NSRunLoop.currentRunLoop forMode:NSRunLoopCommonModes];
CGRect screenBounds = [[UIScreen mainScreen] bounds];
CGFloat screenScale = [[UIScreen mainScreen] scale];
@@ -355,7 +361,7 @@ self.view.frame.size.width * 0.3 - 36.0 * 0.7, self.view.frame.size.height)];
self.mouseConnectCallback = [[NSNotificationCenter defaultCenter] addObserverForName:GCMouseDidConnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
NSLog(@"Input: Mouse connected!");
GCMouse* mouse = note.object;
[self registerMouseCallbacks: mouse];
[self registerMouseCallbacks:mouse];
[self setNeedsUpdateOfPrefersPointerLocked];
}];
self.mouseDisconnectCallback = [[NSNotificationCenter defaultCenter] addObserverForName:GCMouseDidDisconnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) {
@@ -407,6 +413,7 @@ self.view.frame.size.width * 0.3 - 36.0 * 0.7, self.view.frame.size.height)];
[self updateJetsamControl];
[self updatePreferenceChanges];
[self executebtn_special_togglebtn:0];
[self launchMinecraft];
}
@@ -830,36 +837,34 @@ CGPoint lastCenterPoint;
}
- (void)surfaceOnHover:(UIHoverGestureRecognizer *)sender API_AVAILABLE(ios(13.0)) {
if (@available(iOS 13.0, *)) {
if (@available(iOS 14.0, *)) {
if (isGrabbing) return;
}
CGPoint point = [sender locationInView:self.rootView];
// NSLog(@"Mouse move!!");
// NSLog(@"Mouse pos = %f, %f", point.x, point.y);
switch (sender.state) {
case UIGestureRecognizerStateBegan:
[self sendTouchPoint:point withEvent:ACTION_DOWN];
break;
case UIGestureRecognizerStateChanged:
[self sendTouchPoint:point withEvent:ACTION_MOVE];
break;
case UIGestureRecognizerStateEnded:
case UIGestureRecognizerStateCancelled:
[self sendTouchPoint:point withEvent:ACTION_UP];
break;
default:
// point = CGPointMake(-1, -1);
break;
}
if (@available(iOS 14.0, *)) {
if (isGrabbing) return;
}
CGPoint point = [sender locationInView:self.rootView];
// NSLog(@"Mouse move!!");
// NSLog(@"Mouse pos = %f, %f", point.x, point.y);
switch (sender.state) {
case UIGestureRecognizerStateBegan:
[self sendTouchPoint:point withEvent:ACTION_DOWN];
break;
case UIGestureRecognizerStateChanged:
[self sendTouchPoint:point withEvent:ACTION_MOVE];
break;
case UIGestureRecognizerStateEnded:
case UIGestureRecognizerStateCancelled:
[self sendTouchPoint:point withEvent:ACTION_UP];
break;
default:
// point = CGPointMake(-1, -1);
break;
}
}
-(void)surfaceOnLongpress:(UILongPressGestureRecognizer *)sender
{
if (!slideableHotbar) {
CGFloat screenScale = [[UIScreen mainScreen] scale];
CGPoint location = [sender locationInView:self.rootView];
CGFloat screenScale = UIScreen.mainScreen.scale;
currentHotbarSlot = callback_SurfaceViewController_touchHotbar(location.x * screenScale, location.y * screenScale);
}
if (sender.state == UIGestureRecognizerStateBegan) {
@@ -895,19 +900,16 @@ CallbackBridge_nativeSendKey(GLFW_KEY_Q, 0, 0, 0);
sender.state == UIGestureRecognizerStateEnded) {
CGPoint velocity = [sender velocityInView:self.rootView];
if (velocity.x != 0.0f || velocity.y != 0.0f) {
CallbackBridge_nativeSendScroll((CGFloat) (velocity.x/10.0), (CGFloat) (velocity.y/10.0));
CallbackBridge_nativeSendScroll(velocity.x/100.0, velocity.y/100.0);
}
}
}
// FIXME: incomplete
- (UIPointerRegion *)pointerInteraction:(UIPointerInteraction *)interaction regionForRequest:(UIPointerRegionRequest *)request defaultRegion:(UIPointerRegion *)defaultRegion API_AVAILABLE(ios(13.4)) API_AVAILABLE(ios(13.4)) API_AVAILABLE(ios(13.4)){
NSLog(@"regionForRequest called");
return nil;
}
- (UIPointerStyle *)pointerInteraction:(UIPointerInteraction *)interaction styleForRegion:(UIPointerRegion *)region API_AVAILABLE(ios(13.4)){
NSLog(@"styleForRegion called");
return [UIPointerStyle hiddenPointerStyle];
}
@@ -1111,7 +1113,7 @@ int touchesMovedCount;
for (UITouch *touch in touches) {
if (@available(iOS 14.0, *)) { // 13.4
if (touch.type == UITouchTypeIndirectPointer) {
if (isGrabbing && touch.type == UITouchTypeIndirectPointer) {
continue; // handle this in a different place
}
}
+1
View File
@@ -6,5 +6,6 @@
+ (void)initKeycodeTable;
+ (void)registerControllerCallbacks:(GCController *)controller;
+ (void)unregisterControllerCallbacks:(GCController *)controller;
+ (void)tick;
@end
+43 -24
View File
@@ -4,6 +4,10 @@
#include "../glfw_keycodes.h"
CFAbsoluteTime lastFrameTime;
CGFloat lastXValue; // lastHorizontalValue
CGFloat lastYValue; // lastVerticalValue
@implementation ControllerInput
NSMutableDictionary *gameMap, *menuMap;
@@ -166,34 +170,27 @@ BOOL leftShiftHeld;
gamepad.leftThumbstick.valueChangedHandler = ^(GCControllerDirectionPad * _Nonnull dpad, float xValue, float yValue) {
if (!isGrabbing) {
UIImageView *pointerView = [(id)currentWindow().rootViewController mousePointerView];
virtualMouseFrame.origin.x += xValue;
virtualMouseFrame.origin.y += yValue;
pointerView.frame = virtualMouseFrame;
lastXValue = xValue;
lastYValue = yValue;
}
CGFloat screenScale = UIScreen.mainScreen.scale;
callback_SurfaceViewController_onTouch(ACTION_MOVE_MOTION,
isGrabbing ? xValue : virtualMouseFrame.origin.x*screenScale,
isGrabbing ? yValue : virtualMouseFrame.origin.y*screenScale
);
};
gamepad.rightThumbstick.valueChangedHandler = ^(GCControllerDirectionPad * _Nonnull dpad, float xValue, float yValue) {
if (!isGrabbing) {
return;
if (isGrabbing) {
lastXValue = xValue;
lastYValue = yValue;
}
dpad.up.pressedChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
[self sendKeyEvent:GLFW_KEY_W pressed:pressed];
};
dpad.left.pressedChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
[self sendKeyEvent:GLFW_KEY_A pressed:pressed];
};
dpad.down.pressedChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
[self sendKeyEvent:GLFW_KEY_S pressed:pressed];
};
dpad.right.pressedChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
[self sendKeyEvent:GLFW_KEY_D pressed:pressed];
};
};
gamepad.rightThumbstick.up.pressedChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
[self sendKeyEvent:GLFW_KEY_W pressed:pressed];
};
gamepad.rightThumbstick.left.pressedChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
[self sendKeyEvent:GLFW_KEY_A pressed:pressed];
};
gamepad.rightThumbstick.down.pressedChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
[self sendKeyEvent:GLFW_KEY_S pressed:pressed];
};
gamepad.rightThumbstick.right.pressedChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
[self sendKeyEvent:GLFW_KEY_D pressed:pressed];
};
if (@available(iOS 12.1, *)) {
gamepad.leftThumbstickButton.pressedChangedHandler = ^(GCControllerButtonInput * _Nonnull button, float value, BOOL pressed) {
@@ -205,6 +202,28 @@ BOOL leftShiftHeld;
}
}
/**
* Send the new mouse position, computing the delta
*/
+ (void)tick {
// There isn't a convenient way to get ns, use ms at this point
CGFloat frameTimeMilis = CACurrentMediaTime();
// GameController automatically performs deadzone calculations
// so we just take the raw input
if (lastFrameTime != 0 && (lastXValue != 0 || lastYValue != 0)) {
CGFloat acceleration = MathUtils_dist(0, 0, lastXValue, lastYValue); // magnitude
CGFloat deltaX = lastXValue * acceleration * 18;
CGFloat deltaY = -lastYValue * acceleration * 18;
CGFloat deltaTimeScale = (frameTimeMilis - lastFrameTime) / 0.016666666; // Scale of 1 = 60Hz
deltaX *= deltaTimeScale;
deltaY *= deltaTimeScale;
SurfaceViewController *vc = (id)(currentWindow().rootViewController);
[vc sendTouchPoint:CGPointMake(deltaX, deltaY) withEvent:ACTION_MOVE_MOTION];
}
lastFrameTime = frameTimeMilis;
}
+ (void)unregisterControllerCallbacks:(GCController *)controller {
GCExtendedGamepad *gamepad = controller.extendedGamepad;
gamepad.leftShoulder.pressedChangedHandler = nil;
+8 -5
View File
@@ -105,16 +105,19 @@ void init_logDeviceAndVer(char *argument) {
const char *deviceSoftware = [[[UIDevice currentDevice] systemVersion] cStringUsingEncoding:NSUTF8StringEncoding];
// PojavLauncher version
regLog("[Pre-Init] PojavLauncher version: %s - branch %s commit %s", CONFIG_TYPE, CONFIG_BRANCH, CONFIG_COMMIT);
regLog("[Pre-Init] PojavLauncher version: %s, branch: %s, commit: %s", CONFIG_TYPE, CONFIG_BRANCH, CONFIG_COMMIT);
setenv("POJAV_DETECTEDHW", deviceHardware, 1);
setenv("POJAV_DETECTEDSW", deviceSoftware, 1);
if (getenv("POJAV_DETECTEDJB")) {
regLog("[Pre-Init] %s with iOS %s (Jailbroken)", deviceHardware, deviceSoftware);
} else {
regLog("[Pre-Init] %s with iOS %s (Unjailbroken)", deviceHardware, deviceSoftware);
NSString *tsPath = [NSString stringWithFormat:@"%s/../_TrollStore", getenv("BUNDLE_PATH")];
const char *type = "Unjailbroken";
if ([fm fileExistsAtPath:tsPath]) {
type = "TrollStore";
} else if (getenv("POJAV_DETECTEDJB")) {
type = "Jailbroken";
}
regLog("[Pre-Init] %s with iOS %s (%s)", deviceHardware, deviceSoftware, type);
NSString *jvmPath = [NSString stringWithFormat:@"%s/jvm", getenv("BUNDLE_PATH")];
if (![fm fileExistsAtPath:jvmPath]) {
+1
View File
@@ -94,6 +94,7 @@ CGFloat MathUtils_dist(CGFloat x1, CGFloat y1, CGFloat x2, CGFloat y2);
CGFloat MathUtils_map(CGFloat x, CGFloat in_min, CGFloat in_max, CGFloat out_min, CGFloat out_max);
CGFloat dpToPx(CGFloat dp);
CGFloat pxToDp(CGFloat px);
void setButtonPointerInteraction(UIButton *button);
void setViewBackgroundColor(UIView* view);
void _CGDataProviderReleaseBytePointerCallback(void *info,const void *pointer);
+10
View File
@@ -75,6 +75,16 @@ CGFloat pxToDp(CGFloat px) {
return px / screenScale;
}
void setButtonPointerInteraction(UIButton *button) {
if(@available (iOS 13.4, *)) {
button.pointerInteractionEnabled = YES;
button.pointerStyleProvider = ^ UIPointerStyle* (UIButton* button, UIPointerEffect* proposedEffect, UIPointerShape* proposedShape) {
UITargetedPreview *preview = [[UITargetedPreview alloc] initWithView:button];
return [UIPointerStyle styleWithEffect:[UIPointerHighlightEffect effectWithPreview:preview] shape:proposedShape];
};
}
}
void setViewBackgroundColor(UIView* view) {
if(@available(iOS 13.0, *)) {
view.backgroundColor = UIColor.systemBackgroundColor;