diff --git a/JavaApp/libs_caciocavallo/cacio-androidnw-1.10-SNAPSHOT.jar b/JavaApp/libs_caciocavallo/cacio-androidnw-1.10-SNAPSHOT.jar index 4d8b0ad1..d9313f77 100644 Binary files a/JavaApp/libs_caciocavallo/cacio-androidnw-1.10-SNAPSHOT.jar and b/JavaApp/libs_caciocavallo/cacio-androidnw-1.10-SNAPSHOT.jar differ diff --git a/JavaApp/libs_caciocavallo17/cacio-tta-1.18-SNAPSHOT.jar b/JavaApp/libs_caciocavallo17/cacio-tta-1.18-SNAPSHOT.jar index aba8d955..91bc6420 100644 Binary files a/JavaApp/libs_caciocavallo17/cacio-tta-1.18-SNAPSHOT.jar and b/JavaApp/libs_caciocavallo17/cacio-tta-1.18-SNAPSHOT.jar differ diff --git a/Makefile b/Makefile index 5a413bbe..cb1eb7a7 100644 --- a/Makefile +++ b/Makefile @@ -222,7 +222,6 @@ package: native java jre assets @cp -R $(SOURCEDIR)/Natives/en.lproj/LaunchScreen.storyboardc $(WORKINGDIR)/PojavLauncher.app/Base.lproj/ || exit 1 @cp -R $(SOURCEDIR)/Natives/resources/* $(WORKINGDIR)/PojavLauncher.app/ || exit 1 @cp $(WORKINGDIR)/*.dylib $(WORKINGDIR)/PojavLauncher.app/Frameworks/ || exit 1 - @cp -R $(WORKINGDIR)/*.framework $(WORKINGDIR)/PojavLauncher.app/Frameworks/ || exit 1 @cp -R $(SOURCEDIR)/JavaApp/libs/* $(WORKINGDIR)/PojavLauncher.app/libs/ || exit 1 @cp $(SOURCEDIR)/JavaApp/local_out/*.jar $(WORKINGDIR)/PojavLauncher.app/libs/ || exit 1 @cp -R $(SOURCEDIR)/JavaApp/libs_caciocavallo* $(WORKINGDIR)/PojavLauncher.app/ || exit 1 @@ -263,17 +262,13 @@ deploy: @echo '[PojavLauncher v$(VERSION)] deploy - start' @ldid -S$(SOURCEDIR)/entitlements.xml $(WORKINGDIR)/PojavLauncher.app/PojavLauncher; \ if [ '$(NOSTDIN)' = '1' ]; then \ - echo '$(SUDOPASS)' | sudo -S rm -rf /Applications/PojavLauncher.app/Frameworks/libOSMesaOverride.dylib.framework; \ echo '$(SUDOPASS)' | sudo -S mv $(WORKINGDIR)/*.dylib /Applications/PojavLauncher.app/Frameworks/; \ - echo '$(SUDOPASS)' | sudo -S mv $(WORKINGDIR)/*.framework /Applications/PojavLauncher.app/Frameworks/; \ echo '$(SUDOPASS)' | sudo -S mv $(WORKINGDIR)/PojavLauncher.app/PojavLauncher /Applications/PojavLauncher.app/PojavLauncher; \ echo '$(SUDOPASS)' | sudo -S mv $(SOURCEDIR)/JavaApp/local_out/*.jar /Applications/PojavLauncher.app/libs/; \ cd /Applications/PojavLauncher.app/Frameworks; \ echo '$(SUDOPASS)' | sudo -S chown -R 501:501 /Applications/PojavLauncher.app/*; \ else \ - sudo rm -rf /Applications/PojavLauncher.app/Frameworks/libOSMesaOverride.dylib.framework; \ sudo mv $(WORKINGDIR)/*.dylib /Applications/PojavLauncher.app/Frameworks/; \ - sudo mv $(WORKINGDIR)/*.framework /Applications/PojavLauncher.app/Frameworks/; \ sudo mv $(WORKINGDIR)/PojavLauncher.app/PojavLauncher /Applications/PojavLauncher.app/PojavLauncher; \ sudo mv $(SOURCEDIR)/JavaApp/local_out/*.jar /Applications/PojavLauncher.app/libs/; \ cd /Applications/PojavLauncher.app/Frameworks; \ diff --git a/Natives/CMakeLists.txt b/Natives/CMakeLists.txt index d3aab634..5ff6144b 100644 --- a/Natives/CMakeLists.txt +++ b/Natives/CMakeLists.txt @@ -50,16 +50,11 @@ set(CMAKE_EXE_LINKER_FLAGS "${CMAKE_EXE_LINKER_FLAGS} -rpath @executable_path/Fr set(CMAKE_SHARED_LINKER_FLAGS "${CMAKE_SHARED_LINKER_FLAGS} -rpath @executable_path/Frameworks -rpath @loader_path/Frameworks") -find_library(OSMESA_LIB libOSMesa.8.dylib) - -add_library(libOSMesaOverride.dylib SHARED gl_mesa3d_patch.m) -set_target_properties(libOSMesaOverride.dylib PROPERTIES - FRAMEWORK TRUE - MACOSX_FRAMEWORK_IDENTIFIER dylib.mesa3d.libOSMesaOverride -) -target_link_libraries(libOSMesaOverride.dylib +add_library(OSMesaOverride SHARED gl_mesa3d_patch.m) +target_link_libraries(OSMesaOverride "${GLOBAL_LDFLAGS}" - "${OSMESA_LIB}" + "-L${CMAKE_FRAMEWORK_PATH}" + "-lOSMesa.8" ) diff --git a/Natives/CustomControlsViewController+UndoManager.m b/Natives/CustomControlsViewController+UndoManager.m index 891378e3..5da48cd5 100644 --- a/Natives/CustomControlsViewController+UndoManager.m +++ b/Natives/CustomControlsViewController+UndoManager.m @@ -22,11 +22,11 @@ for (ControlSubButton *subButton in ((ControlDrawer *)button).buttons) { [self.ctrlView addSubview:subButton]; } - [self.cc_dictionary[@"mDrawerDataList"] insertObject:((ControlDrawer *)button).drawerData atIndex:index.intValue]; + [self.ctrlView.layoutDictionary[@"mDrawerDataList"] insertObject:((ControlDrawer *)button).drawerData atIndex:index.intValue]; [self.ctrlView addSubview:button]; } else { undo.actionName = localize(@"custom_controls.control_menu.add_button", nil); - [self.cc_dictionary[@"mControlDataList"] insertObject:button.properties atIndex:index.intValue]; + [self.ctrlView.layoutDictionary[@"mControlDataList"] insertObject:button.properties atIndex:index.intValue]; [self.ctrlView addSubview:button]; } @@ -46,12 +46,12 @@ [parent syncButtons]; } else if ([button isKindOfClass:[ControlDrawer class]]) { ControlDrawer *drawer = (ControlDrawer *)button; - index = @([self.cc_dictionary[@"mDrawerDataList"] indexOfObject:drawer.drawerData]); + index = @([self.ctrlView.layoutDictionary[@"mDrawerDataList"] indexOfObject:drawer.drawerData]); [drawer.buttons makeObjectsPerformSelector:@selector(removeFromSuperview)]; - [self.cc_dictionary[@"mDrawerDataList"] removeObject:drawer.drawerData]; + [self.ctrlView.layoutDictionary[@"mDrawerDataList"] removeObject:drawer.drawerData]; } else { - index = @([self.cc_dictionary[@"mControlDataList"] indexOfObject:button.properties]); - [self.cc_dictionary[@"mControlDataList"] removeObject:button.properties]; + index = @([self.ctrlView.layoutDictionary[@"mControlDataList"] indexOfObject:button.properties]); + [self.ctrlView.layoutDictionary[@"mControlDataList"] removeObject:button.properties]; } [button removeFromSuperview]; self.resizeView.hidden = YES; diff --git a/Natives/CustomControlsViewController.h b/Natives/CustomControlsViewController.h index 4b31802c..a6977c8b 100644 --- a/Natives/CustomControlsViewController.h +++ b/Natives/CustomControlsViewController.h @@ -1,5 +1,6 @@ #import #import "customcontrols/ControlButton.h" +#import "customcontrols/ControlLayout.h" @interface ControlHandleView : UIView @property(nonatomic, weak) ControlButton* target; @@ -9,8 +10,7 @@ @property(nonatomic) UIGestureRecognizer* currentGesture; -@property(nonatomic) NSMutableDictionary* cc_dictionary; -@property(nonatomic) UIView* ctrlView; +@property(nonatomic) ControlLayout* ctrlView; @property(nonatomic) ControlHandleView* resizeView; - (void)initKeyCodeMap; diff --git a/Natives/CustomControlsViewController.m b/Natives/CustomControlsViewController.m index ffd6f630..c9e3becf 100644 --- a/Natives/CustomControlsViewController.m +++ b/Natives/CustomControlsViewController.m @@ -7,7 +7,6 @@ #import "ios_uikit_bridge.h" #import "customcontrols/ControlDrawer.h" -#import "customcontrols/ControlLayout.h" #import "customcontrols/CustomControlsUtils.h" #include @@ -104,7 +103,7 @@ NSMutableArray *keyCodeMap, *keyValueMap; [self.ctrlView addGestureRecognizer:longpressGesture]; self.currentFileName = [getPreference(@"default_ctrl") stringByDeletingPathExtension]; [self initKeyCodeMap]; - [self loadControlFile:[NSString stringWithFormat:@"%s/controlmap/%@", getenv("POJAV_HOME"), getPreference(@"default_ctrl")]]; + [self loadControlFile:getPreference(@"default_ctrl")]; } - (void)viewWillDisappear:(BOOL)animated { @@ -172,22 +171,14 @@ NSMutableArray *keyCodeMap, *keyValueMap; sender.scale = 1.0; } -- (void)loadControlFile:(NSString *)controlFilePath { - for (UIView *view in self.ctrlView.subviews) { - if ([view isKindOfClass:[ControlButton class]]) { - [view removeFromSuperview]; - } - } - - self.cc_dictionary = parseJSONFromFile(controlFilePath); - if (self.cc_dictionary == nil) return; - - loadControlObject(self.ctrlView, self.cc_dictionary, ^void(ControlButton* button) { +- (void)loadControlFile:(NSString *)file { + [self.ctrlView loadControlFile:file]; + for (ControlButton *button in self.ctrlView.subviews) { [button addGestureRecognizer:[[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(showControlPopover:)]]; [button addGestureRecognizer:[[UIPanGestureRecognizer alloc] initWithTarget:self action:@selector(onTouch:)]]; - }); + } } - (void)viewDidLayoutSubviews { @@ -308,7 +299,7 @@ NSMutableArray *keyCodeMap, *keyValueMap; NSArray *textFields = controller.textFields; UITextField *field = textFields[0]; NSError *error; - NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self.cc_dictionary options:NSJSONWritingPrettyPrinted error:&error]; + NSData *jsonData = [NSJSONSerialization dataWithJSONObject:self.ctrlView.layoutDictionary options:NSJSONWritingPrettyPrinted error:&error]; if (jsonData == nil) { showDialog(self, localize(@"custom_controls.control_menu.save.error.json", nil), error.localizedDescription); return; @@ -357,15 +348,16 @@ NSMutableArray *keyCodeMap, *keyValueMap; - (void)actionMenuLoad { [self actionOpenFilePicker:^void(NSString* name) { self.currentFileName = name; - [self loadControlFile:[NSString stringWithFormat:@"%s/controlmap/%@.json", getenv("POJAV_HOME"), name]]; + [self loadControlFile:[NSString stringWithFormat:@"%@.json", name]]; }]; } - (void)actionMenuSetDef { [self actionOpenFilePicker:^void(NSString* name) { self.currentFileName = name; - [self loadControlFile:[NSString stringWithFormat:@"%s/controlmap/%@.json", getenv("POJAV_HOME"), name]]; - setPreference(@"default_ctrl", [NSString stringWithFormat:@"%@.json", name]); + name = [NSString stringWithFormat:@"%@.json", name]; + [self loadControlFile:name]; + setPreference(@"default_ctrl", name); }]; } @@ -411,7 +403,7 @@ NSMutableArray *keyCodeMap, *keyValueMap; ControlButton *button; if (drawer == nil) { button = [ControlButton buttonWithProperties:dict]; - [self doAddButton:button atIndex:@([self.cc_dictionary[@"mControlDataList"] count])]; + [self doAddButton:button atIndex:@([self.ctrlView.layoutDictionary[@"mControlDataList"] count])]; [button snapAndAlignX:self.selectedPoint.origin.x-25.0 Y:self.selectedPoint.origin.y-25.0]; [button update]; } else { @@ -447,7 +439,7 @@ NSMutableArray *keyCodeMap, *keyValueMap; data[@"properties"] = properties; data[@"buttonProperties"] = [[NSMutableArray alloc] init]; ControlDrawer *button = [ControlDrawer buttonWithData:data]; - [self doAddButton:button atIndex:@([self.cc_dictionary[@"mDrawerDataList"] count])]; + [self doAddButton:button atIndex:@([self.ctrlView.layoutDictionary[@"mDrawerDataList"] count])]; [button snapAndAlignX:self.selectedPoint.origin.x-25.0 Y:self.selectedPoint.origin.y-25.0]; [button update]; diff --git a/Natives/JavaGUIViewController.m b/Natives/JavaGUIViewController.m index 6c2f1c9c..f9219474 100644 --- a/Natives/JavaGUIViewController.m +++ b/Natives/JavaGUIViewController.m @@ -1,7 +1,11 @@ +#import "customcontrols/ControlLayout.h" +#import "customcontrols/CustomControlsUtils.h" #import "JavaGUIViewController.h" #import "JavaLauncher.h" #import "LauncherPreferences.h" +#import "TrackedTextField.h" #import "ios_uikit_bridge.h" +#include "glfw_keycodes.h" #include "utils.h" static int* rgbArray; @@ -25,6 +29,39 @@ JNIEXPORT void JNICALL Java_net_kdt_pojavlaunch_uikit_UIKit_refreshAWTBuffer(JNI }); } +void AWTInputBridge_nativeSendData(int type, int i1, int i2, int i3, int i4) { + if (runtimeJNIEnvPtr == NULL) { + return; + } + + if (method_ReceiveInput == NULL) { + class_CTCAndroidInput = (*runtimeJNIEnvPtr)->FindClass(runtimeJNIEnvPtr, "net/java/openjdk/cacio/ctc/CTCAndroidInput"); + if ((*runtimeJNIEnvPtr)->ExceptionCheck(runtimeJNIEnvPtr) == JNI_TRUE) { + (*runtimeJNIEnvPtr)->ExceptionClear(runtimeJNIEnvPtr); + class_CTCAndroidInput = (*runtimeJNIEnvPtr)->FindClass(runtimeJNIEnvPtr, "com/github/caciocavallosilano/cacio/ctc/CTCAndroidInput"); + } + assert(class_CTCAndroidInput != NULL); + method_ReceiveInput = (*runtimeJNIEnvPtr)->GetStaticMethodID(runtimeJNIEnvPtr, class_CTCAndroidInput, "receiveData", "(IIIII)V"); + assert(method_ReceiveInput != NULL); + } + + (*runtimeJNIEnvPtr)->CallStaticVoidMethod( + runtimeJNIEnvPtr, + class_CTCAndroidInput, + method_ReceiveInput, + type, i1, i2, i3, i4 + ); +} + +void AWTInputBridge_sendChar(jchar keychar) { + AWTInputBridge_nativeSendData(EVENT_TYPE_CHAR, (unsigned int)keychar, 0, 0, 0); +} + +void AWTInputBridge_sendKey(int keycode) { + // TODO: iOS -> AWT keycode mapping + AWTInputBridge_nativeSendData(EVENT_TYPE_KEY, 0, keycode, 0, 0); +} + @implementation SurfaceView const void * _CGDataProviderGetBytePointerCallbackAWT(void *info) { return (const void *)rgbArray; @@ -62,7 +99,9 @@ const void * _CGDataProviderGetBytePointerCallbackAWT(void *info) { @property BOOL virtualMouseEnabled; @property CGRect virtualMouseFrame; -@property UIImageView* mousePointerView; +@property(nonatomic) TrackedTextField* inputTextField; +@property(nonatomic) UIImageView* mousePointerView; +@property(nonatomic) ControlLayout* ctrlView; @end @@ -91,6 +130,7 @@ const void * _CGDataProviderGetBytePointerCallbackAWT(void *info) { scrollView.delegate = self; scrollView.minimumZoomScale = 1; scrollView.maximumZoomScale = 5; + scrollView.scrollEnabled = NO; scrollView.zoomScale = 1; surfaceView = [[SurfaceView alloc] initWithFrame:self.view.frame]; @@ -98,9 +138,36 @@ const void * _CGDataProviderGetBytePointerCallbackAWT(void *info) { [self.view addSubview:scrollView]; -// TODO -/* - self.virtualMouseEnabled = [getPreference(@"virtmouse_enable") boolValue]; + self.inputTextField = [[TrackedTextField alloc] initWithFrame:CGRectMake(0, -32.0, self.view.frame.size.width, 30.0)]; + if (@available(iOS 13.0, *)) { + self.inputTextField.backgroundColor = UIColor.secondarySystemBackgroundColor; + } else { + self.inputTextField.backgroundColor = UIColor.groupTableViewBackgroundColor; + } + self.inputTextField.font = [UIFont fontWithName:@"Menlo-Regular" size:20]; + self.inputTextField.clearsOnBeginEditing = YES; + self.inputTextField.textAlignment = NSTextAlignmentCenter; + self.inputTextField.sendChar = ^(jchar keychar){ + AWTInputBridge_sendChar(keychar); + }; + self.inputTextField.sendKey = ^(int key, int scancode, int action, int mods) { + if (action == 0) return; + switch (key) { + case GLFW_KEY_BACKSPACE: + AWTInputBridge_sendKey('\b'); // VK_BACK_SPACE + break; + case GLFW_KEY_DPAD_LEFT: + AWTInputBridge_sendKey(0xE2); // VK_KP_LEFT; + break; + case GLFW_KEY_DPAD_RIGHT: + AWTInputBridge_sendKey(0xE3); // VK_KP_RIGHT; + break; + } + }; + [self.view addSubview:self.inputTextField]; + + self.virtualMouseEnabled = NO; + //[getPreference(@"virtmouse_enable") boolValue]; scrollView.bounces = !self.virtualMouseEnabled; self.virtualMouseFrame = CGRectMake(screenBounds.size.width / 2, screenBounds.size.height / 2, 18, 27); self.mousePointerView = [[UIImageView alloc] initWithFrame:self.virtualMouseFrame]; @@ -108,7 +175,6 @@ const void * _CGDataProviderGetBytePointerCallbackAWT(void *info) { self.mousePointerView.image = [UIImage imageNamed:@"MousePointer"]; self.mousePointerView.userInteractionEnabled = NO; [self.view addSubview:self.mousePointerView]; -*/ UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(surfaceOnClick:)]; @@ -118,6 +184,11 @@ const void * _CGDataProviderGetBytePointerCallbackAWT(void *info) { tapGesture.cancelsTouchesInView = NO; [surfaceView addGestureRecognizer:tapGesture]; + // Borrowing custom controls, might be useful later (full-blown jar launcher with control support?) + self.ctrlView = [[ControlLayout alloc] initWithFrame:UIEdgeInsetsInsetRect(self.view.frame, self.view.safeAreaInsets)]; + [self.view addSubview:self.ctrlView]; + [self loadCustomControls]; + rgbArray = calloc(4, (size_t) (windowWidth * windowHeight)); dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{ @@ -125,46 +196,101 @@ const void * _CGDataProviderGetBytePointerCallbackAWT(void *info) { }); } -- (void)surfaceOnClick:(UITapGestureRecognizer *)sender { - if (runtimeJNIEnvPtr == NULL) { - return; - } +- (void)loadCustomControls { + NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; + dict[@"version"] = @(4); + dict[@"scaledAt"] = @(100); + dict[@"mControlDataList"] = [[NSMutableArray alloc] init]; + //dict[@"mDrawerDataList"] = [[NSMutableArray alloc] init]; + [dict[@"mControlDataList"] addObject:createButton(@"Keyboard", + (int[]){SPECIALBTN_KEYBOARD,0,0,0}, + @"${margin}", @"${margin}", + BTN_RECT + )]; +#if 0 // WIP: virtual mouse + [dict[@"mControlDataList"] addObject:createButton(@"Mouse", + (int[]){SPECIALBTN_VIRTUALMOUSE,0,0,0}, + @"${right} - ${margin}", @"${margin}", + BTN_RECT + )]; +#endif + [dict[@"mControlDataList"] addObject:createButton(@"PRI", + (int[]){SPECIALBTN_MOUSEPRI,0,0,0}, + @"${margin}", @"${bottom} - ${margin}", + BTN_RECT + )]; + [dict[@"mControlDataList"] addObject:createButton(@"SEC", + (int[]){SPECIALBTN_MOUSESEC,0,0,0}, + @"${margin} * 2 + ${width}", @"${bottom} - ${margin}", + BTN_RECT + )]; + [self.ctrlView loadControlLayout:dict]; - if (method_ReceiveInput == NULL) { - class_CTCAndroidInput = (*runtimeJNIEnvPtr)->FindClass(runtimeJNIEnvPtr, "net/java/openjdk/cacio/ctc/CTCAndroidInput"); - if ((*runtimeJNIEnvPtr)->ExceptionCheck(runtimeJNIEnvPtr) == JNI_TRUE) { - (*runtimeJNIEnvPtr)->ExceptionClear(runtimeJNIEnvPtr); - class_CTCAndroidInput = (*runtimeJNIEnvPtr)->FindClass(runtimeJNIEnvPtr, "com/github/caciocavallosilano/cacio/ctc/CTCAndroidInput"); + // Implement a subset of custom controls functionalites enough for few buttons + for (ControlButton *button in self.ctrlView.subviews) { + [button addTarget:self action:@selector(executebtn_down:) forControlEvents:UIControlEventTouchDown]; + [button addTarget:self action:@selector(executebtn_up:) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchUpOutside]; + } +} + +- (void)executebtn:(ControlButton *)sender withAction:(int)action { + int held = action == ACTION_DOWN; + for (int i = 0; i < 4; i++) { + int keycode = ((NSNumber *)sender.properties[@"keycodes"][i]).intValue; + if (keycode < 0) { + switch (keycode) { + case SPECIALBTN_KEYBOARD: + if (held) return; + [self toggleSoftKeyboard]; + break; + + case SPECIALBTN_MOUSEPRI: + AWTInputBridge_nativeSendData(EVENT_TYPE_MOUSE_BUTTON, BUTTON1_DOWN_MASK, held, 0, 0); + break; + + case SPECIALBTN_MOUSEMID: + AWTInputBridge_nativeSendData(EVENT_TYPE_MOUSE_BUTTON, BUTTON2_DOWN_MASK, held, 0, 0); + break; + + case SPECIALBTN_MOUSESEC: + AWTInputBridge_nativeSendData(EVENT_TYPE_MOUSE_BUTTON, BUTTON3_DOWN_MASK, held, 0, 0); + break; + + case SPECIALBTN_VIRTUALMOUSE: + if (held) return; + virtualMouseEnabled = !virtualMouseEnabled; + self.mousePointerView.hidden = !virtualMouseEnabled; + setPreference(@"virtmouse_enable", @(virtualMouseEnabled)); + break; + + default: + NSLog(@"Warning: button %@ sent unknown special keycode: %d", sender.titleLabel.text, keycode); + break; + } + } else if (keycode > 0) { + // unimplemented } - assert(class_CTCAndroidInput != NULL); - method_ReceiveInput = (*runtimeJNIEnvPtr)->GetStaticMethodID(runtimeJNIEnvPtr, class_CTCAndroidInput, "receiveData", "(IIIII)V"); - assert(method_ReceiveInput != NULL); } +} +- (void)executebtn_down:(ControlButton *)button { + [self executebtn:button withAction:ACTION_DOWN]; +} + +- (void)executebtn_up:(ControlButton *)button { + [self executebtn:button withAction:ACTION_UP]; +} + +- (void)surfaceOnClick:(UITapGestureRecognizer *)sender { if (sender.state == UIGestureRecognizerStateRecognized) { float resolution = ((NSNumber *)getPreference(@"resolution")).floatValue / 100.0; CGFloat screenScale = [[UIScreen mainScreen] scale]; CGPoint location = [sender locationInView:sender.view]; CGFloat x = location.x * screenScale * resolution; CGFloat y = location.y * screenScale * resolution; - (*runtimeJNIEnvPtr)->CallStaticVoidMethod( - runtimeJNIEnvPtr, - class_CTCAndroidInput, - method_ReceiveInput, - EVENT_TYPE_CURSOR_POS, (int)x, (int)y, 0, 0 - ); - (*runtimeJNIEnvPtr)->CallStaticVoidMethod( - runtimeJNIEnvPtr, - class_CTCAndroidInput, - method_ReceiveInput, - EVENT_TYPE_MOUSE_BUTTON, BUTTON1_DOWN_MASK, 1, 0, 0 - ); - (*runtimeJNIEnvPtr)->CallStaticVoidMethod( - runtimeJNIEnvPtr, - class_CTCAndroidInput, - method_ReceiveInput, - EVENT_TYPE_MOUSE_BUTTON, BUTTON1_DOWN_MASK, 0, 0, 0 - ); + AWTInputBridge_nativeSendData(EVENT_TYPE_CURSOR_POS, (int)x, (int)y, 0, 0); + AWTInputBridge_nativeSendData(EVENT_TYPE_MOUSE_BUTTON, BUTTON1_DOWN_MASK, 1, 0, 0); + AWTInputBridge_nativeSendData(EVENT_TYPE_MOUSE_BUTTON, BUTTON1_DOWN_MASK, 0, 0, 0); } } @@ -179,10 +305,29 @@ const void * _CGDataProviderGetBytePointerCallbackAWT(void *info) { } */ +- (void)toggleSoftKeyboard { + if (self.inputTextField.isFirstResponder) { + [self.inputTextField resignFirstResponder]; + } else { + [self.inputTextField becomeFirstResponder]; + } +} + - (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView { return surfaceView; } +- (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator +{ + [coordinator animateAlongsideTransition:^(id _Nonnull context) { + self.ctrlView.frame = UIEdgeInsetsInsetRect(self.view.frame, self.view.safeAreaInsets); + [self.ctrlView.subviews makeObjectsPerformSelector:@selector(update)]; + } completion:^(id _Nonnull context) { + self.virtualMouseFrame = self.mousePointerView.frame; + }]; + [super viewWillTransitionToSize:size withTransitionCoordinator:coordinator]; +} + - (UIRectEdge)preferredScreenEdgesDeferringSystemGestures { return UIRectEdgeBottom; } @@ -191,4 +336,8 @@ const void * _CGDataProviderGetBytePointerCallbackAWT(void *info) { return NO; } +- (BOOL)prefersStatusBarHidden { + return YES; +} + @end diff --git a/Natives/JavaLauncher.m b/Natives/JavaLauncher.m index 491b37a0..10250694 100644 --- a/Natives/JavaLauncher.m +++ b/Natives/JavaLauncher.m @@ -172,14 +172,8 @@ int launchJVM(NSString *username, id launchTarget, int width, int height, int mi margv[++margc] = "-Djava.system.class.loader=net.kdt.pojavlaunch.PojavClassLoader"; margv[++margc] = "-Xms128M"; margv[++margc] = [NSString stringWithFormat:@"-Xmx%dM", allocmem].UTF8String; - margv[++margc] = [NSString stringWithFormat:@ - "-Djava.library.path=%1$s/Frameworks:" - "%1$s/Frameworks/libOSMesaOverride.dylib.framework:" - "%1$s/Frameworks/libMoltenVK.dylib.framework", - getenv("BUNDLE_PATH")].UTF8String; - margv[++margc] = [NSString stringWithFormat:@ - "-Djna.boot.library.path=%s/Frameworks/libjnidispatch.dylib.framework", - getenv("BUNDLE_PATH")].UTF8String; + margv[++margc] = [NSString stringWithFormat:@"-Djava.library.path=%1$s/Frameworks", getenv("BUNDLE_PATH")].UTF8String; + margv[++margc] = [NSString stringWithFormat:@"-Djna.boot.library.path=%s/Frameworks", getenv("BUNDLE_PATH")].UTF8String; margv[++margc] = [NSString stringWithFormat:@"-Duser.dir=%s", getenv("POJAV_GAME_DIR")].UTF8String; margv[++margc] = [NSString stringWithFormat:@"-Duser.home=%s", getenv("POJAV_HOME")].UTF8String; margv[++margc] = [NSString stringWithFormat:@"-Duser.timezone=%@", NSTimeZone.localTimeZone.name].UTF8String; diff --git a/Natives/SurfaceViewController+Navigation.m b/Natives/SurfaceViewController+Navigation.m index fd864913..44944f89 100644 --- a/Natives/SurfaceViewController+Navigation.m +++ b/Natives/SurfaceViewController+Navigation.m @@ -129,7 +129,7 @@ static CGPoint lastCenterPoint; - (void)actionOpenCustomControls { [self animateMenuScale:1 duration:0.5]; - [self.ctrlView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; + [self.ctrlView removeAllButtons]; CustomControlsViewController *vc = [[CustomControlsViewController alloc] init]; vc.modalPresentationStyle = UIModalPresentationOverFullScreen; [self presentViewController:vc animated:NO completion:nil]; diff --git a/Natives/SurfaceViewController.h b/Natives/SurfaceViewController.h index 23feba2b..2eaa2c67 100644 --- a/Natives/SurfaceViewController.h +++ b/Natives/SurfaceViewController.h @@ -1,5 +1,6 @@ #import +#import "customcontrols/ControlLayout.h" #import "GameSurfaceView.h" BOOL canAppendToLog; @@ -10,7 +11,7 @@ CGPoint lastVirtualMousePoint; @interface SurfaceViewController : UIViewController -@property(nonatomic) UIView *ctrlView; +@property(nonatomic) ControlLayout *ctrlView; @property(nonatomic) GameSurfaceView* surfaceView; @property(nonatomic) UIView *touchView; @property UIImageView* mousePointerView; diff --git a/Natives/SurfaceViewController.m b/Natives/SurfaceViewController.m index 7e675b94..99e6f45d 100644 --- a/Natives/SurfaceViewController.m +++ b/Natives/SurfaceViewController.m @@ -8,7 +8,6 @@ #ifdef INTERNAL_VIRTUAL_JOYSTICK #import "customcontrols/ControlJoystick.h" #endif -#import "customcontrols/ControlLayout.h" #import "customcontrols/ControlSubButton.h" #import "customcontrols/CustomControlsUtils.h" @@ -45,7 +44,6 @@ BOOL slideableHotbar; } @property(nonatomic) TrackedTextField *inputTextField; -@property(nonatomic) NSMutableDictionary* cc_dictionary; @property(nonatomic) NSMutableArray* swipeableButtons; @property(nonatomic) ControlButton* swipingButton; @property(nonatomic) UITouch *primaryTouch, *hotbarTouch; @@ -181,6 +179,15 @@ BOOL slideableHotbar; self.inputTextField.font = [UIFont fontWithName:@"Menlo-Regular" size:20]; self.inputTextField.clearsOnBeginEditing = YES; self.inputTextField.textAlignment = NSTextAlignmentCenter; + self.inputTextField.sendChar = ^(jchar keychar){ + CallbackBridge_nativeSendChar(keychar); + }; + self.inputTextField.sendCharMods = ^(jchar keychar, int mods){ + CallbackBridge_nativeSendCharMods(keychar, mods); + }; + self.inputTextField.sendKey = ^(int key, int scancode, int action, int mods) { + CallbackBridge_nativeSendKey(key, scancode, action, mods); + }; NSString *controlFilePath = [NSString stringWithFormat:@"%s/controlmap/%@", getenv("POJAV_HOME"), (NSString *)getPreference(@"default_ctrl")]; @@ -194,6 +201,7 @@ BOOL slideableHotbar; [self registerMouseCallbacks:mouse]; self.mousePointerView.hidden = isGrabbing; virtualMouseEnabled = YES; + [self setNeedsUpdateOfPrefersPointerLocked]; }]; self.mouseDisconnectCallback = [[NSNotificationCenter defaultCenter] addObserverForName:GCMouseDidDisconnectNotification object:nil queue:[NSOperationQueue mainQueue] usingBlock:^(NSNotification *note) { NSLog(@"Input: Mouse disconnected!"); @@ -202,6 +210,7 @@ BOOL slideableHotbar; mouse.mouseInput.leftButton.pressedChangedHandler = nil; mouse.mouseInput.middleButton.pressedChangedHandler = nil; mouse.mouseInput.rightButton.pressedChangedHandler = nil; + [self setNeedsUpdateOfPrefersPointerLocked]; }]; if (GCMouse.current != nil) { [self registerMouseCallbacks: GCMouse.current]; @@ -354,21 +363,9 @@ BOOL slideableHotbar; } - (void)loadCustomControls { - [self.ctrlView.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; [self.swipeableButtons removeAllObjects]; - [self.cc_dictionary removeAllObjects]; - - NSString *controlFilePath = [NSString stringWithFormat:@"%s/controlmap/%@", getenv("POJAV_HOME"), (NSString *)getPreference(@"default_ctrl")]; - - self.cc_dictionary = parseJSONFromFile(controlFilePath); - if (self.cc_dictionary[@"error"] != nil) { - showDialog(self, localize(@"Error", nil), [NSString stringWithFormat:@"Could not open %@: %@", controlFilePath, [self.cc_dictionary[@"error"] localizedDescription]]); - return; - } - - CGFloat currentScale = [self.cc_dictionary[@"scaledAt"] floatValue]; - CGFloat savedScale = [getPreference(@"button_scale") floatValue]; - loadControlObject(self.ctrlView, self.cc_dictionary, ^void(ControlButton* button) { + [self.ctrlView loadControlFile:getPreference(@"default_ctrl")]; + for (ControlButton *button in self.ctrlView.subviews) { BOOL isSwipeable = [button.properties[@"isSwipeable"] boolValue]; button.canBeHidden = YES; @@ -387,9 +384,7 @@ BOOL slideableHotbar; [button addGestureRecognizer:panRecognizerButton]; [self.swipeableButtons addObject:button]; } - }); - - self.cc_dictionary[@"scaledAt"] = @(savedScale); + } } - (void)viewWillTransitionToSize:(CGSize)size withTransitionCoordinator:(id)coordinator @@ -416,11 +411,7 @@ BOOL slideableHotbar; ctrlFrame.size.height = tmpHeight; } self.ctrlView.frame = ctrlFrame; - for (UIView *view in self.ctrlView.subviews) { - if ([view isKindOfClass:[ControlButton class]]) { - [(ControlButton *)view update]; - } - } + [self.ctrlView.subviews makeObjectsPerformSelector:@selector(update)]; // Update game resolution [self updateSavedResolution]; @@ -585,8 +576,6 @@ BOOL slideableHotbar; mouse.mouseInput.scroll.yAxis.valueChangedHandler = ^(GCControllerAxisInput * _Nonnull axis, float value) { CallbackBridge_nativeSendScroll(0, -value); }; - - [self setNeedsUpdateOfPrefersPointerLocked]; } - (void)surfaceOnClick:(UITapGestureRecognizer *)sender { @@ -709,11 +698,10 @@ BOOL slideableHotbar; #pragma mark - On-screen button functions int currentVisibility = 1; -- (void)executebtn:(UIButton *)sender withAction:(int)action { - ControlButton *button = (ControlButton *)sender; +- (void)executebtn:(ControlButton *)sender withAction:(int)action { int held = action == ACTION_DOWN; for (int i = 0; i < 4; i++) { - int keycode = ((NSNumber *)button.properties[@"keycodes"][i]).intValue; + int keycode = ((NSNumber *)sender.properties[@"keycodes"][i]).intValue; if (keycode < 0) { switch (keycode) { case SPECIALBTN_KEYBOARD: @@ -767,7 +755,7 @@ int currentVisibility = 1; break; default: - NSLog(@"Warning: button %@ sent unknown special keycode: %d", button.titleLabel.text, keycode); + NSLog(@"Warning: button %@ sent unknown special keycode: %d", sender.titleLabel.text, keycode); break; } } else if (keycode > 0) { diff --git a/Natives/TrackedTextField.h b/Natives/TrackedTextField.h index 8023e60d..20aa35c2 100644 --- a/Natives/TrackedTextField.h +++ b/Natives/TrackedTextField.h @@ -1,5 +1,11 @@ #import +#include "jni.h" + @interface TrackedTextField : UITextField +@property(nonatomic, copy) void(^sendChar)(jchar codepoint); +@property(nonatomic, copy) void(^sendCharMods)(jchar codepoint, int mods); +@property(nonatomic, copy) void(^sendKey)(int key, int scancode, int action, int mods); + @end diff --git a/Natives/TrackedTextField.m b/Natives/TrackedTextField.m index 6be51b97..51eb9f0e 100644 --- a/Natives/TrackedTextField.m +++ b/Natives/TrackedTextField.m @@ -21,8 +21,8 @@ extern bool isUseStackQueueCall; - (void)sendMultiBackspaces:(int)times { for (int i = 0; i < times; i++) { - CallbackBridge_nativeSendKey(GLFW_KEY_BACKSPACE, 0, 1, 0); - CallbackBridge_nativeSendKey(GLFW_KEY_BACKSPACE, 0, 0, 0); + self.sendKey(GLFW_KEY_BACKSPACE, 0, 1, 0); + self.sendKey(GLFW_KEY_BACKSPACE, 0, 0, 0); } } @@ -35,11 +35,11 @@ extern bool isUseStackQueueCall; - (void)sendText:(NSString *)text { for (int i = 0; i < text.length; i++) { // Directly convert unichar to jchar since both are in UTF-16 encoding. - jchar theChar = (jchar) [text characterAtIndex:i]; - if (isUseStackQueueCall) { - CallbackBridge_nativeSendCharMods(theChar, 0); + unichar theChar = [text characterAtIndex:i]; + if (isUseStackQueueCall && self.sendCharMods != nil) { + self.sendCharMods(theChar, 0); } else { - CallbackBridge_nativeSendChar(theChar); + self.sendChar(theChar); } } } @@ -65,8 +65,8 @@ extern bool isUseStackQueueCall; self.lastPointX = point.x; int key = (diff > 0) ? GLFW_KEY_DPAD_RIGHT : GLFW_KEY_DPAD_LEFT; - CallbackBridge_nativeSendKey(key, 0, 1, 0); - CallbackBridge_nativeSendKey(key, 0, 0, 0); + self.sendKey(key, 0, 1, 0); + self.sendKey(key, 0, 0, 0); } - (void)endFloatingCursor { @@ -80,8 +80,8 @@ extern bool isUseStackQueueCall; int start = [self offsetFromPosition:self.beginningOfDocument toPosition:position]; if (start - self.lastTextPos != 0) { int key = (start - self.lastTextPos > 0) ? GLFW_KEY_DPAD_RIGHT : GLFW_KEY_DPAD_LEFT; - CallbackBridge_nativeSendKey(key, 0, 1, 0); - CallbackBridge_nativeSendKey(key, 0, 0, 0); + self.sendKey(key, 0, 1, 0); + self.sendKey(key, 0, 0, 0); } self.lastTextPos = start; return position; @@ -137,4 +137,16 @@ extern bool isUseStackQueueCall; return [super replaceRangeWithTextWithoutClosingTyping:range replacementText:text]; } +// Handle multistage text input +- (void)setAttributedMarkedText:(NSAttributedString *)markedText selectedRange:(NSRange)selectedRange { + // Delete the marked range + NSInteger markedLength = [self offsetFromPosition:self.markedTextRange.start toPosition:self.markedTextRange.end]; + [self sendMultiBackspaces:markedLength]; + + [super setAttributedMarkedText:markedText selectedRange:selectedRange]; + + // Insert the new text + [self sendText:markedText.string]; +} + @end diff --git a/Natives/customcontrols/ControlButton.h b/Natives/customcontrols/ControlButton.h index 058d5dfc..a63a6e65 100644 --- a/Natives/customcontrols/ControlButton.h +++ b/Natives/customcontrols/ControlButton.h @@ -12,8 +12,8 @@ } @property BOOL canBeHidden, isToggleOn; -@property(nonatomic, strong) NSMutableDictionary* properties; -@property UIColor* savedBackgroundColor; +@property(nonatomic) NSMutableDictionary* properties; +@property(nonatomic) UIColor* savedBackgroundColor; + (id)buttonWithProperties:(NSMutableDictionary *)propArray; diff --git a/Natives/customcontrols/ControlButton.m b/Natives/customcontrols/ControlButton.m index 2fd488af..dcb6847e 100644 --- a/Natives/customcontrols/ControlButton.m +++ b/Natives/customcontrols/ControlButton.m @@ -1,4 +1,5 @@ #import "ControlButton.h" +#import "ControlLayout.h" #import "CustomControlsUtils.h" #import "../LauncherPreferences.h" #import "../utils.h" @@ -72,13 +73,12 @@ } - (void)preProcessProperties { - CGFloat currentScale = [current_control_object[@"scaledAt"] floatValue]; + CGFloat currentScale = [((ControlLayout *)self.superview).layoutDictionary[@"scaledAt"] floatValue]; CGFloat savedScale = [getPreference(@"button_scale") floatValue]; if (currentScale != savedScale) { self.properties[@"width"] = @([self.properties[@"width"] floatValue] * savedScale / currentScale); self.properties[@"height"] = @([self.properties[@"height"] floatValue] * savedScale / currentScale); } - //current_control_object[@"scaledAt"] = getPreference(@"button_scale"); } - (NSString *)processFunctions:(NSString *)string { @@ -150,6 +150,8 @@ } - (void)update { + NSAssert(self.superview != nil, @"should not be nil"); + // net/kdt/pojavlaunch/customcontrols/ControlData.update() [self preProcessProperties]; diff --git a/Natives/customcontrols/ControlLayout.h b/Natives/customcontrols/ControlLayout.h index ebc4e5b9..74ce8f72 100644 --- a/Natives/customcontrols/ControlLayout.h +++ b/Natives/customcontrols/ControlLayout.h @@ -1,4 +1,11 @@ #import @interface ControlLayout : UIView + +@property(nonatomic) NSMutableDictionary *layoutDictionary; + +- (void)loadControlLayout:(NSMutableDictionary *)layoutDictionary; +- (void)loadControlFile:(NSString *)path; +- (void)removeAllButtons; + @end diff --git a/Natives/customcontrols/ControlLayout.m b/Natives/customcontrols/ControlLayout.m index c0a36d64..005644f1 100644 --- a/Natives/customcontrols/ControlLayout.m +++ b/Natives/customcontrols/ControlLayout.m @@ -1,12 +1,44 @@ #import "ControlButton.h" #import "ControlLayout.h" #import "ControlSubButton.h" +#import "CustomControlsUtils.h" +#import "../LauncherPreferences.h" +#import "../ios_uikit_bridge.h" #import "../utils.h" @interface ControlLayout () @end @implementation ControlLayout + +- (void)loadControlLayout:(NSMutableDictionary *)layoutDictionary { + self.layoutDictionary = layoutDictionary; + + CGFloat currentScale = [self.layoutDictionary[@"scaledAt"] floatValue]; + CGFloat savedScale = [getPreference(@"button_scale") floatValue]; + loadControlObject(self, self.layoutDictionary); + + self.layoutDictionary[@"scaledAt"] = @(savedScale); +} + +- (void)loadControlFile:(NSString *)name { + [self removeAllButtons]; + + NSString *controlFilePath = [NSString stringWithFormat:@"%s/controlmap/%@", getenv("POJAV_HOME"), name]; + + self.layoutDictionary = parseJSONFromFile(controlFilePath); + if (self.layoutDictionary[@"error"] != nil) { + showDialog(currentVC(), localize(@"Error", nil), [NSString stringWithFormat:@"Could not open %@: %@", controlFilePath, [self.layoutDictionary[@"error"] localizedDescription]]); + return; + } + [self loadControlLayout:self.layoutDictionary]; +} + +- (void)removeAllButtons { + [self.subviews makeObjectsPerformSelector:@selector(removeFromSuperview)]; + [self.layoutDictionary removeAllObjects]; +} + - (BOOL)canPerformAction:(SEL)action withSender:(id)sender { return action == @selector(actionMenuExit:) || diff --git a/Natives/customcontrols/CustomControlsUtils.h b/Natives/customcontrols/CustomControlsUtils.h index bfc57d6d..9752accf 100644 --- a/Natives/customcontrols/CustomControlsUtils.h +++ b/Natives/customcontrols/CustomControlsUtils.h @@ -1,11 +1,14 @@ #import #import "ControlButton.h" -NSMutableDictionary* current_control_object; +#define BTN_RECT 80.0, 30.0 +#define BTN_SQUARE 50.0, 50.0 + +NSMutableDictionary* createButton(NSString* name, int* keycodes, NSString* dynamicX, NSString* dynamicY, CGFloat width, CGFloat height); UIColor* convertARGB2UIColor(int argb); int convertUIColor2ARGB(UIColor* color); int convertUIColor2RGB(UIColor* color); BOOL convertLayoutIfNecessary(NSMutableDictionary* dict); void generateAndSaveDefaultControl(); -void loadControlObject(UIView* targetView, NSMutableDictionary* controlDictionary, void(^walkToButton)(ControlButton* button)); +void loadControlObject(UIView* targetView, NSMutableDictionary* controlDictionary); diff --git a/Natives/customcontrols/CustomControlsUtils.m b/Natives/customcontrols/CustomControlsUtils.m index 04a83d57..6f4249df 100644 --- a/Natives/customcontrols/CustomControlsUtils.m +++ b/Natives/customcontrols/CustomControlsUtils.m @@ -6,9 +6,6 @@ #include "../glfw_keycodes.h" #include "../utils.h" -#define BTN_RECT 80.0, 30.0 -#define BTN_SQUARE 50.0, 50.0 - NSMutableDictionary* createButton(NSString* name, int* keycodes, NSString* dynamicX, NSString* dynamicY, CGFloat width, CGFloat height) { NSMutableDictionary *dict = [[NSMutableDictionary alloc] init]; dict[@"name"] = name; @@ -305,10 +302,9 @@ void generateAndSaveDefaultControl() { */ } -void loadControlObject(UIView* targetView, NSMutableDictionary* controlDictionary, void(^walkToButton)(ControlButton* button)) { +void loadControlObject(UIView* targetView, NSMutableDictionary* controlDictionary) { NSMutableString *errorString = [[NSMutableString alloc] init]; - current_control_object = controlDictionary; if (convertLayoutIfNecessary(controlDictionary)) { NSMutableArray *controlDataList = controlDictionary[@"mControlDataList"]; setPreference(@"internal_current_button_scale", controlDictionary[@"scaledAt"]); @@ -316,7 +312,6 @@ void loadControlObject(UIView* targetView, NSMutableDictionary* controlDictionar //APPLY_SCALE(buttonDict[@"strokeWidth"]); @try { ControlButton *button = [ControlButton buttonWithProperties:buttonDict]; - walkToButton(button); [targetView addSubview:button]; [button update]; } @catch (NSException *exception) { @@ -334,14 +329,12 @@ void loadControlObject(UIView* targetView, NSMutableDictionary* controlDictionar [errorString appendFormat:@"%@: %@\n", drawerData[@"name"], exception.reason]; } if (isControlModifiable) drawer.areButtonsVisible = YES; - walkToButton(drawer); [targetView addSubview:drawer]; //NSLog(@"DBG Added drawer=%@", drawer); for (NSMutableDictionary *subButton in drawerData[@"buttonProperties"]) { ControlSubButton *subView = [ControlSubButton buttonWithProperties:subButton]; [drawer addButton:subView]; - walkToButton(subView); [targetView addSubview:subView]; } [drawer syncButtons]; diff --git a/Natives/egl_bridge.m b/Natives/egl_bridge.m index fee6b4df..2f7b473a 100644 --- a/Natives/egl_bridge.m +++ b/Natives/egl_bridge.m @@ -171,7 +171,7 @@ void loadSymbols() { char fileName[2048]; switch (config_renderer) { case RENDERER_VK_ZINK: - sprintf((char *)fileName, "%s/Frameworks/%s.framework/%s", getenv("BUNDLE_PATH"), getenv("POJAV_RENDERER"), getenv("POJAV_RENDERER")); + sprintf((char *)fileName, "%s/Frameworks/%s", getenv("BUNDLE_PATH"), getenv("POJAV_RENDERER")); break; case RENDERER_MTL_ANGLE: sprintf((char *)fileName, "%s/Frameworks/MetalANGLE.framework/MetalANGLE", getenv("BUNDLE_PATH")); @@ -201,7 +201,7 @@ void loadSymbolsVirGL() { config_renderer = RENDERER_VIRGL; char fileName[2048]; - sprintf((char *)fileName, "%s/Frameworks/libvirgl_test_server.dylib.framework/libvirgl_test_server.dylib", getenv("BUNDLE_PATH")); + sprintf((char *)fileName, "%s/Frameworks/libvirgl_test_server.dylib", getenv("BUNDLE_PATH")); void *handle = dlopen(fileName, RTLD_LAZY); NSLog(@"VirGL: libvirgl_test_server = %p", handle); if (!handle) { @@ -376,6 +376,8 @@ void pojavSetWindowHint(int hint, int value) { NSLog(@"GLFW: Unimplemented API 0x%x", value); abort(); } + } else if (hint == GLFW_OPENGL_PROFILE || hint == GLFW_CONTEXT_VERSION_MAJOR) { + pojavInit_OpenGL(); } else if (strcmp(getenv("POJAV_RENDERER"), "auto")==0 && hint == GLFW_CONTEXT_VERSION_MAJOR && value >= 3) { // Free unused gl4es library void *renderer_handle = dlopen(RENDERER_NAME_GL4ES, RTLD_GLOBAL); diff --git a/Natives/glfw_keycodes.h b/Natives/glfw_keycodes.h index 89932c1e..4e9b6695 100644 --- a/Natives/glfw_keycodes.h +++ b/Natives/glfw_keycodes.h @@ -36,6 +36,7 @@ #define GLFW_OPENGL_API 0x30001 #define GLFW_CONTEXT_VERSION_MAJOR 0x00022002 +#define GLFW_OPENGL_PROFILE 0x00022008 /*! @defgroup hat_state Joystick hat states * @brief Joystick hat states. diff --git a/Natives/resources/Frameworks/libMoltenVK.dylib b/Natives/resources/Frameworks/libMoltenVK.dylib new file mode 100644 index 00000000..a73214e0 Binary files /dev/null and b/Natives/resources/Frameworks/libMoltenVK.dylib differ diff --git a/Natives/resources/Frameworks/libMoltenVK.dylib.framework/Info.plist b/Natives/resources/Frameworks/libMoltenVK.dylib.framework/Info.plist deleted file mode 100644 index 3f2a1a73..00000000 Binary files a/Natives/resources/Frameworks/libMoltenVK.dylib.framework/Info.plist and /dev/null differ diff --git a/Natives/resources/Frameworks/libMoltenVK.dylib.framework/libMoltenVK.dylib b/Natives/resources/Frameworks/libMoltenVK.dylib.framework/libMoltenVK.dylib deleted file mode 100755 index 02c4b244..00000000 Binary files a/Natives/resources/Frameworks/libMoltenVK.dylib.framework/libMoltenVK.dylib and /dev/null differ diff --git a/Natives/resources/Frameworks/libOSMesa.8.dylib.framework/libOSMesa.8.dylib b/Natives/resources/Frameworks/libOSMesa.8.dylib similarity index 98% rename from Natives/resources/Frameworks/libOSMesa.8.dylib.framework/libOSMesa.8.dylib rename to Natives/resources/Frameworks/libOSMesa.8.dylib index 8c7a816c..e2f5bc3e 100644 Binary files a/Natives/resources/Frameworks/libOSMesa.8.dylib.framework/libOSMesa.8.dylib and b/Natives/resources/Frameworks/libOSMesa.8.dylib differ diff --git a/Natives/resources/Frameworks/libOSMesa.8.dylib.framework/Info.plist b/Natives/resources/Frameworks/libOSMesa.8.dylib.framework/Info.plist deleted file mode 100644 index 0854e5c4..00000000 Binary files a/Natives/resources/Frameworks/libOSMesa.8.dylib.framework/Info.plist and /dev/null differ diff --git a/Natives/resources/Frameworks/libglapi.0.dylib.framework/libglapi.0.dylib b/Natives/resources/Frameworks/libglapi.0.dylib old mode 100755 new mode 100644 similarity index 100% rename from Natives/resources/Frameworks/libglapi.0.dylib.framework/libglapi.0.dylib rename to Natives/resources/Frameworks/libglapi.0.dylib diff --git a/Natives/resources/Frameworks/libglapi.0.dylib.framework/Info.plist b/Natives/resources/Frameworks/libglapi.0.dylib.framework/Info.plist deleted file mode 100644 index 6fb4fc7a..00000000 Binary files a/Natives/resources/Frameworks/libglapi.0.dylib.framework/Info.plist and /dev/null differ diff --git a/Natives/resources/Frameworks/libjnidispatch.dylib.framework/libjnidispatch.dylib b/Natives/resources/Frameworks/libjnidispatch.dylib similarity index 100% rename from Natives/resources/Frameworks/libjnidispatch.dylib.framework/libjnidispatch.dylib rename to Natives/resources/Frameworks/libjnidispatch.dylib diff --git a/Natives/resources/Frameworks/libjnidispatch.dylib.framework/Info.plist b/Natives/resources/Frameworks/libjnidispatch.dylib.framework/Info.plist deleted file mode 100644 index bec2cc7a..00000000 --- a/Natives/resources/Frameworks/libjnidispatch.dylib.framework/Info.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - libjnidispatch.dylib - CFBundleIconFile - - CFBundleIdentifier - dylib.java.libjnidispatch - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - FMWK - CFBundleShortVersionString - 5.8.0 - CFBundleSignature - ???? - CFBundleVersion - 1 - CSResourcesFileMapped - - - diff --git a/Natives/resources/Frameworks/libvirgl_test_server.dylib.framework/libvirgl_test_server.dylib b/Natives/resources/Frameworks/libvirgl_test_server.dylib old mode 100755 new mode 100644 similarity index 100% rename from Natives/resources/Frameworks/libvirgl_test_server.dylib.framework/libvirgl_test_server.dylib rename to Natives/resources/Frameworks/libvirgl_test_server.dylib diff --git a/Natives/resources/Frameworks/libvirgl_test_server.dylib.framework/Info.plist b/Natives/resources/Frameworks/libvirgl_test_server.dylib.framework/Info.plist deleted file mode 100644 index 290fe10a..00000000 --- a/Natives/resources/Frameworks/libvirgl_test_server.dylib.framework/Info.plist +++ /dev/null @@ -1,26 +0,0 @@ - - - - - CFBundleDevelopmentRegion - English - CFBundleExecutable - libvirgl_test_server.dylib - CFBundleIconFile - - CFBundleIdentifier - dylib.mesa3d.libvirgl_test_server - CFBundleInfoDictionaryVersion - 6.0 - CFBundlePackageType - FMWK - CFBundleShortVersionString - - CFBundleSignature - ???? - CFBundleVersion - - CSResourcesFileMapped - - - diff --git a/README.md b/README.md index c8c2229f..e5681dc4 100644 --- a/README.md +++ b/README.md @@ -9,15 +9,15 @@ ## Introduction - PojavLauncher is a Minecraft: Java Edition launcher for Android and iOS based on [Boardwalk](https://github.com/zhuowei/Boardwalk). -- This launcher can launch most of available Minecraft versions (up to latest 1.19.2, including Combat Test versions). -- Modding via Forge and Fabric are also supported. +- This launcher can launch most of available Minecraft versions (up to latest 1.19.x, including Combat Test versions). +- Modding via Forge, Fabric, Quilt are also supported. - Older versions of Forge and Fabric can be used with OpenJDK 8. - This repository contains source code for iOS/iPadOS platform. - For Android platform, check out [PojavLauncher repository](https://github.com/PojavLauncherTeam/PojavLauncher). ## Getting started with PojavLauncher -The [PojavLauncher Website](https://pojavlauncherteam.github.io/INSTALL.html#ios) has extensive documentation on how to install, set up, and play! For those who wish to install quickly, here's the basics (on iOS 12 or later): +The [PojavLauncher Website](https://pojavlauncherteam.github.io/INSTALL.html#ios) has extensive documentation on how to install, set up, and play! For those who wish to install quickly, here's the basics (on iOS 12.2 or later): Note: This is experimental, although game works smoothly, you should not set Render distance too much. @@ -62,19 +62,20 @@ PojavLauncher is amazing, and surprisingly stable, and it wouldn't be this way w - [Caciocavallo](https://github.com/PojavLauncherTeam/caciocavallo): [GNU GPLv2 License](https://github.com/PojavLauncherTeam/caciocavallo/blob/master/LICENSE). - [jsr305](https://code.google.com/p/jsr-305): [3-Clause BSD License](http://opensource.org/licenses/BSD-3-Clause). - [org.json](https://github.com/stleary/JSON-java): [The JSON License](https://www.json.org/license.html). -- [Boardwalk](https://github.com/zhuowei/Boardwalk): [Apache 2.0 License](https://github.com/zhuowei/Boardwalk/blob/master/LICENSE) +- [Boardwalk](https://github.com/zhuowei/Boardwalk): [Apache 2.0 License](https://github.com/zhuowei/Boardwalk/blob/master/LICENSE) - [GL4ES](https://github.com/ptitSeb/gl4es) by @lunixbochs @ptitSeb: [MIT License](https://github.com/ptitSeb/gl4es/blob/master/LICENSE). - [Mesa 3D Graphics Library](https://gitlab.freedesktop.org/mesa/mesa): [MIT License](https://docs.mesa3d.org/license.html). -- [MetalANGLE](https://github.com/kakashidinho/metalangle) by @kakashidinho and ANGLE team: [BSD 2.0 License](https://github.com/kakashidinho/metalangle/blob/master/LICENSE). +- [MetalANGLE](https://github.com/khanhduytran0/metalangle) by @kakashidinho and ANGLE team: [BSD 2.0 License](https://github.com/kakashidinho/metalangle/blob/master/LICENSE). - [MoltenVK](https://github.com/KhronosGroup/MoltenVK): [Apache 2.0 License](https://github.com/KhronosGroup/MoltenVK/blob/master/LICENSE). +- [openal-soft](https://github.com/kcat/openal-soft): [LGPLv2 License](https://github.com/kcat/openal-soft/blob/master/COPYING). - [Azul Zulu JDK](https://www.azul.com/downloads/?package=jdk): [GNU GPLv2 License](https://openjdk.java.net/legal/gplv2+ce.html). - [LWJGL3](https://github.com/PojavLauncherTeam/lwjgl3): [BSD-3 License](https://github.com/LWJGL/lwjgl3/blob/master/LICENSE.md). - [LWJGLX](https://github.com/PojavLauncherTeam/lwjglx) (LWJGL2 API compatibility layer for LWJGL3): unknown license. - [Alderis](https://github.com/hbang/Alderis) (color picker for iOS < 14): [Apache 2.0 License](https://github.com/hbang/Alderis/blob/master/LICENSE.md). -- [DBNumberedSlider](https://github.com/immago/DBNumberedSlider): [Apache 2.0 License](https://github.com/immago/DBNumberedSlider/blob/master/LICENSE) -- [fishhook](https://github.com/facebook/fishhook) (jailed environment usage only): [BSD-3 License](https://github.com/facebook/fishhook/blob/main/LICENSE). +- [DBNumberedSlider](https://github.com/khanhduytran0/DBNumberedSlider): [Apache 2.0 License](https://github.com/immago/DBNumberedSlider/blob/master/LICENSE) +- [fishhook](https://github.com/khanhduytran0/fishhook) (jailed environment usage only): [BSD-3 License](https://github.com/facebook/fishhook/blob/main/LICENSE). - [Java Native Access](https://github.com/java-native-access/jna): [Apache 2.0 License](https://github.com/java-native-access/jna/blob/master/LICENSE). -- [shaderc](https://github.com/google/shaderc) (used by mods that uses Vulkan for rendering): [Apache 2.0 License](https://github.com/google/shaderc/blob/main/LICENSE). +- [shaderc](https://github.com/khanhduytran0/shaderc) (used by mods that uses Vulkan for rendering): [Apache 2.0 License](https://github.com/google/shaderc/blob/main/LICENSE). - [TOInsetGroupedTableView](https://github.com/TimOliver/TOInsetGroupedTableView): [MIT License](https://github.com/TimOliver/TOInsetGroupedTableView/blob/master/LICENSE). - [AltKit](https://github.com/rileytestut/AltKit) - Thanks to [MCHeads](https://mc-heads.net) for providing Minecraft avatars.