Basic mod installer implementation

This commit is contained in:
Duy Tran Khanh committed 2021-08-03 16:06:32 +07:00
1 parent 0668d016bf
commit f2566e3da5
14 files changed
+358 -89

No files matched your search

@@ -117,19 +117,19 @@ public final class Tools
// URLClassLoader loader = new URLClassLoader(urlList.toArray(new URL[0]), ClassLoader.getSystemClassLoader());
PojavClassLoader loader = (PojavClassLoader) ClassLoader.getSystemClassLoader();
for (String s : launchClassPath.split(":")) {
if (!s.isEmpty()) {
loader.addURL(new File(s).toURI().toURL());
PojavClassLoader loader = (PojavClassLoader) ClassLoader.getSystemClassLoader();
for (String s : launchClassPath.split(":")) {
if (!s.isEmpty()) {
loader.addURL(new File(s).toURI().toURL());
}
}
}
Class<?> clazz = loader.loadClass(versionInfo.mainClass);
Method method = clazz.getMethod("main", String[].class);
method.invoke(null, new Object[]{launchArgs});
System.out.println("It went past main(). Should not reach here!");
// throw new RuntimeException("Game exited. Check latestlog.txt for more details.");
} catch (Throwable th) {
showError(th);
}
@@ -1,7 +1,11 @@
package net.kdt.pojavlaunch.uikit;
import java.io.*;
import java.lang.reflect.*;
import java.util.jar.*;
import net.java.openjdk.cacio.ctc.CTCScreen;
import net.kdt.pojavlaunch.utils.MCOptionUtils;
import net.kdt.pojavlaunch.PLaunchApp;
import net.kdt.pojavlaunch.*;
import org.lwjgl.glfw.*;
public class UIKit {
@@ -10,6 +14,59 @@ public class UIKit {
public static final int ACTION_MOVE = 2;
private static int guiScale;
public static void callback_JavaGUIViewController_launchJarFile(final String filepath, int width, int height) {
System.setProperty("cacio.managed.screensize", width + "x" + height);
// Thread for refreshing the AWT buffer
new Thread(() -> {
try {
long lastTime = System.currentTimeMillis();
while (true) {
int[] pixelsArray = null;
try{
pixelsArray = CTCScreen.getCurrentScreenRGB();
} catch (NullPointerException e) {
Thread.sleep(500);
}
if (pixelsArray != null) {
//System.out.println(java.util.Arrays.toString(pixelsArray));
refreshAWTBuffer(pixelsArray);
}
long currentTime = System.currentTimeMillis();
if (currentTime - lastTime < 16) {
Thread.sleep(16 - (currentTime - lastTime));
}
lastTime = currentTime;
}
} catch (InterruptedException e) {
e.printStackTrace();
}
}, "AWTFBRefreshThread").start();
// Thread for launching the JAR file
new Thread(() -> {
String mainClassName = null;
try {
JarFile jarfile = new JarFile(filepath);
String mainClass = jarfile.getManifest().getMainAttributes().getValue("Main-Class");
jarfile.close();
if (mainClass == null) {
throw new IllegalArgumentException("no main manifest attribute, in \"" + filepath + "\"");
}
PojavClassLoader loader = (PojavClassLoader) ClassLoader.getSystemClassLoader();
loader.addURL(new File(filepath).toURI().toURL());
Class<?> clazz = loader.loadClass(mainClass);
Method method = clazz.getMethod("main", String[].class);
method.invoke(null, new Object[]{new String[]{}});
// throw new RuntimeException("Application exited");
} catch (Throwable th) {
Tools.showError(th, true);
}
}, "ModInstallerThread").start();
}
public static void callback_LauncherViewController_installMinecraft(String versionPath) {
PLaunchApp.installMinecraft(versionPath);
@@ -73,7 +130,9 @@ public class UIKit {
static {
System.loadLibrary("pojavexec");
}
public static native void refreshAWTBuffer(int[] array);
public static native int launchUI(String[] uiArgs);
// public static native void runOnUIThread(UIKitCallback callback);
+8 -5
View File
@@ -107,14 +107,14 @@ native:
-DCONFIG_COMMIT="$(COMMIT)" \
..
@cd Natives/build && cmake --build . --config Release --target awt_headless awt_xawt pojavexec PojavLauncher
@rm Natives/build/libawt_headless.dylib || exit 1
@rm Natives/build/libawt_headless.dylib
@echo 'Finished build task - native application'
java:
@echo 'Starting build task - java application'
@cd JavaApp; \
mkdir -p local_out/classes; \
$(JDK)/javac -cp "libs/*" -d local_out/classes $(JAVAFILES) || exit 1; \
$(JDK)/javac -cp "libs/*:libs_caciocavallo/*" -d local_out/classes $(JAVAFILES) || exit 1; \
cd local_out/classes; \
$(JDK)/jar -cf ../launcher.jar * || exit 1; \
echo 'Finished build task - java application'
@@ -135,7 +135,8 @@ package:
@echo 'Starting build task - package for external devices'
@if [ '$(IOS)' = '0' ]; then \
cp -R Natives/resources/* Natives/build/PojavLauncher.app/ || exit 1; \
cp Natives/build/*.dylib Natives/build/PojavLauncher.app/Frameworks/ || exit 1; \
cp Natives/build/libawt_xawt.dylib Natives/build/PojavLauncher.app/Frameworks/ || exit 1; \
cp Natives/build/libpojavexec.dylib Natives/build/PojavLauncher.app/Frameworks/ || exit 1; \
mkdir Natives/build/PojavLauncher.app/{libs,libs_caciocavallo}; \
cp JavaApp/local_out/launcher.jar Natives/build/PojavLauncher.app/libs/launcher.jar || exit 1; \
cp -R JavaApp/libs/* Natives/build/PojavLauncher.app/libs/ || exit 1; \
@@ -151,7 +152,8 @@ package:
cp -R Natives/en.lproj/*.storyboardc Natives/build/PojavLauncher.app/Base.lproj/ || exit 1; \
cp -R Natives/Info.plist Natives/build/PojavLauncher.app/Info.plist || exit 1;\
cp -R Natives/PkgInfo Natives/build/PojavLauncher.app/PkgInfo || exit 1; \
cp -R Natives/build/*.dylib Natives/build/PojavLauncher.app/Frameworks/ || exit 1; \
cp Natives/build/libawt_xawt.dylib Natives/build/PojavLauncher.app/Frameworks/ || exit 1; \
cp Natives/build/libpojavexec.dylib Natives/build/PojavLauncher.app/Frameworks/ || exit 1; \
cp -R Natives/resources/* Natives/build/PojavLauncher.app/ || exit 1; \
cp -R JavaApp/libs Natives/build/PojavLauncher.app/libs || exit 1; \
cp -R JavaApp/libs_caciocavallo Natives/build/PojavLauncher.app/libs_caciocavallo || exit 1; \
@@ -217,7 +219,8 @@ deploy:
sudo ldid -Sentitlements.xml Natives/build/PojavLauncher.app/PojavLauncher; \
sudo cp JavaApp/local_out/launcher.jar /Applications/PojavLauncher.app/libs/launcher.jar; \
sudo cp Natives/build/PojavLauncher.app/PojavLauncher /Applications/PojavLauncher.app/PojavLauncher; \
sudo cp Natives/build/*.dylib /Applications/PojavLauncher.app/Frameworks/; \
sudo cp Natives/build/libawt_xawt.dylib /Applications/PojavLauncher.app/Frameworks/; \
sudo cp Natives/build/libpojavexec.dylib /Applications/PojavLauncher.app/Frameworks/; \
sudo killall PojavLauncher; \
fi
@echo 'Finished build task - deploy to local device'
+1 -1
View File
@@ -5,7 +5,7 @@
#import <sys/utsname.h>
#ifndef NDEBUG
#ifdef NDEBUG
# define CONFIG_TYPE "release"
#else
# define CONFIG_TYPE "debug"
+1
View File
@@ -32,6 +32,7 @@ add_library(pojavexec SHARED
AboutLauncherViewController.m
AppDelegate.m
CustomControlsViewController.m
JavaGUIViewController.m
LauncherFAQViewController.m
LauncherPreferences.m
LauncherPreferencesViewController.m
+12
View File
@@ -0,0 +1,12 @@
#import <UIKit/UIKit.h>
@interface SurfaceView : UIView {
CALayer* layer;
CGColorSpaceRef colorSpace;
CGDataProviderDirectCallbacks callbacks;
}
@end
@interface JavaGUIViewController : UIViewController
@property NSString* filepath;
@end
+170
View File
@@ -0,0 +1,170 @@
#import "JavaGUIViewController.h"
#import "ios_uikit_bridge.h"
#include "utils.h"
static int* rgbArray;
SurfaceView* surfaceView;
jclass class_CTCAndroidInput;
jmethodID method_ReceiveInput;
JNIEXPORT void JNICALL Java_net_kdt_pojavlaunch_uikit_UIKit_refreshAWTBuffer(JNIEnv* env, jclass clazz, jintArray jreRgbArray) {
int *tmpArray = (*env)->GetIntArrayElements(env, jreRgbArray, 0);
memcpy(rgbArray, tmpArray, savedWidth * savedHeight * 4);
(*env)->ReleaseIntArrayElements(env, jreRgbArray, tmpArray, JNI_ABORT);
dispatch_async(dispatch_get_main_queue(), ^{
[surfaceView displayLayer:surfaceView.layer];
});
}
@implementation SurfaceView
const void * _CGDataProviderGetBytePointerCallback(void *info) {
return (const void *)rgbArray;
}
void _CGDataProviderReleaseBytePointerCallback(void *info,const void *pointer) {
}
- (void)displayLayer:(CALayer *)theLayer
{
CGDataProviderRef bitmapProvider = CGDataProviderCreateDirect(NULL, savedWidth * savedHeight * 4, &callbacks);
CGImageRef bitmap = CGImageCreate(savedWidth, savedHeight, 8, 32, 4 * savedWidth, colorSpace, kCGImageAlphaFirst | kCGBitmapByteOrder32Little, bitmapProvider, NULL, FALSE, kCGRenderingIntentDefault);
theLayer.contents = (__bridge id) bitmap;
CGImageRelease(bitmap);
CGDataProviderRelease(bitmapProvider);
// CGColorSpaceRelease(colorSpace);
}
- (id)initWithFrame:(CGRect)frame
{
self = [super initWithFrame:frame];
layer = [self layer];
layer.opaque = YES;
colorSpace = CGColorSpaceCreateDeviceRGB();
callbacks.version = 0;
callbacks.getBytePointer = _CGDataProviderGetBytePointerCallback;
callbacks.releaseBytePointer = _CGDataProviderReleaseBytePointerCallback;
callbacks.getBytesAtPosition = NULL;
callbacks.releaseInfo = NULL;
return self;
}
@end
@interface JavaGUIViewController ()<UIGestureRecognizerDelegate, UIScrollViewDelegate> {
}
// - (void)method
@end
@implementation JavaGUIViewController
- (void)viewDidLoad
{
[super viewDidLoad];
[self.navigationController setNavigationBarHidden:YES animated:NO];
[self setNeedsUpdateOfScreenEdgesDeferringSystemGestures];
[self setNeedsUpdateOfHomeIndicatorAutoHidden];
CGRect screenBounds = [[UIScreen mainScreen] bounds];
CGFloat screenScale = [[UIScreen mainScreen] scale];
int width = (int) roundf(screenBounds.size.width);
int height = (int) roundf(screenBounds.size.height);
savedWidth = roundf(width * screenScale);
savedHeight = roundf(height * screenScale);
UIScrollView *scrollView = [[UIScrollView alloc] initWithFrame:self.view.frame];
scrollView.delegate = self;
scrollView.minimumZoomScale = 1;
scrollView.maximumZoomScale = 5;
scrollView.zoomScale = 1;
surfaceView = [[SurfaceView alloc] initWithFrame:self.view.frame];
[scrollView addSubview:surfaceView];
[self.view addSubview:scrollView];
// Update color mode once
if(@available(iOS 13.0, *)) {
[self traitCollectionDidChange:nil];
} else {
self.view.backgroundColor = [UIColor whiteColor];
}
UITapGestureRecognizer *tapGesture = [[UITapGestureRecognizer alloc]
initWithTarget:self action:@selector(surfaceOnClick:)];
tapGesture.delegate = self;
tapGesture.numberOfTapsRequired = 1;
tapGesture.numberOfTouchesRequired = 1;
tapGesture.cancelsTouchesInView = NO;
[surfaceView addGestureRecognizer:tapGesture];
rgbArray = calloc(4, (size_t) (savedWidth * savedHeight));
UIKit_launchJarFile(self.filepath.UTF8String);
}
- (void)surfaceOnClick:(UITapGestureRecognizer *)sender {
if (method_ReceiveInput == NULL) {
class_CTCAndroidInput = (*runtimeJNIEnvPtr_JRE)->FindClass(runtimeJNIEnvPtr_JRE, "net/java/openjdk/cacio/ctc/CTCAndroidInput");
assert(class_CTCAndroidInput != NULL);
method_ReceiveInput = (*runtimeJNIEnvPtr_JRE)->GetStaticMethodID(runtimeJNIEnvPtr_JRE, class_CTCAndroidInput, "receiveData", "(IIIII)V");
assert(method_ReceiveInput != NULL);
}
if (sender.state == UIGestureRecognizerStateRecognized) {
CGFloat screenScale = [[UIScreen mainScreen] scale];
CGPoint location = [sender locationInView:sender.view];
CGFloat x = location.x * screenScale;
CGFloat y = location.y * screenScale;
(*runtimeJNIEnvPtr_JRE)->CallStaticVoidMethod(
runtimeJNIEnvPtr_JRE,
class_CTCAndroidInput,
method_ReceiveInput,
EVENT_TYPE_CURSOR_POS, (int)x, (int)y, 0, 0
);
(*runtimeJNIEnvPtr_JRE)->CallStaticVoidMethod(
runtimeJNIEnvPtr_JRE,
class_CTCAndroidInput,
method_ReceiveInput,
EVENT_TYPE_MOUSE_BUTTON, BUTTON1_DOWN_MASK, 1, 0, 0
);
(*runtimeJNIEnvPtr_JRE)->CallStaticVoidMethod(
runtimeJNIEnvPtr_JRE,
class_CTCAndroidInput,
method_ReceiveInput,
EVENT_TYPE_MOUSE_BUTTON, BUTTON1_DOWN_MASK, 0, 0, 0
);
}
}
- (UIView *)viewForZoomingInScrollView:(UIScrollView *)scrollView {
return surfaceView;
}
- (UIRectEdge)preferredScreenEdgesDeferringSystemGestures {
return UIRectEdgeBottom;
}
- (BOOL)prefersHomeIndicatorAutoHidden {
return NO;
}
-(void)traitCollectionDidChange:(UITraitCollection *)previousTraitCollection {
if(@available(iOS 13.0, *)) {
if (UITraitCollection.currentTraitCollection.userInterfaceStyle == UIUserInterfaceStyleDark) {
self.view.backgroundColor = [UIColor blackColor];
} else {
self.view.backgroundColor = [UIColor whiteColor];
}
}
}
@end
+59 -9
View File
@@ -1,11 +1,12 @@
#import "CustomControlsViewController.h"
#import "JavaGUIViewController.h"
#import "LauncherPreferences.h"
#import "LauncherPreferencesViewController.h"
#import "LauncherViewController.h"
#include "utils.h"
@interface LauncherViewController () <UIPickerViewDataSource, UIPickerViewDelegate> {
@interface LauncherViewController () <UIDocumentPickerDelegate, UIPickerViewDataSource, UIPickerViewDelegate> {
}
// - (void)method
@@ -72,11 +73,23 @@ int versionSelectedAt = 0;
[scrollView addSubview:versionTextField];
self.navigationItem.rightBarButtonItems = @[
[[UIBarButtonItem alloc] initWithTitle:@"Custom controls" style:UIBarButtonItemStyleDone target:self action:@selector(enterCustomControls)],
[[UIBarButtonItem alloc] initWithTitle:@"Settings" style:UIBarButtonItemStyleDone target:self action:@selector(enterPreferences)]
];
self.navigationItem.rightBarButtonItem =
[[UIBarButtonItem alloc] initWithTitle:@"Options" style:UIBarButtonItemStyleDone target:self action:@selector(displayOptions:)];
if (@available(iOS 14.0, *)) {
// use UIMenu
UIAction *option1 = [UIAction actionWithTitle:@"Launch a mod installer" image:nil identifier:nil
handler:^(__kindof UIAction * _Nonnull action) {[self enterModInstaller];}];
UIAction *option2 = [UIAction actionWithTitle:@"Custom controls" image:nil identifier:nil
handler:^(__kindof UIAction * _Nonnull action) {[self enterCustomControls];}];
UIAction *option3 = [UIAction actionWithTitle:@"Settings" image:nil identifier:nil
handler:^(__kindof UIAction * _Nonnull action) {[self enterPreferences];}];
UIMenu *menu = [UIMenu menuWithTitle:@"Options" image:nil identifier:nil
options:UIMenuOptionsDisplayInline children:@[option1, option2, option3]];
self.navigationItem.rightBarButtonItem.action = nil;
self.navigationItem.rightBarButtonItem.primaryAction = nil;
self.navigationItem.rightBarButtonItem.menu = menu;
}
install_progress_bar = [[UIProgressView alloc] initWithFrame:CGRectMake(4.0, height - 58.0, width - 8.0, 6.0)];
[scrollView addSubview:install_progress_bar];
@@ -181,23 +194,60 @@ int versionSelectedAt = 0;
}
#pragma mark - Button click events
- (void)displayOptions:(UIBarButtonItem*)sender {
if (@available(iOS 14.0, *)) {
// use UIMenu
} else {
// use UIAlertController
UIAlertController *fullAlert = [UIAlertController alertControllerWithTitle:@"Options" message:@"" preferredStyle:UIAlertControllerStyleActionSheet];
UIAlertAction *option1 = [UIAlertAction actionWithTitle:@"Launch a mod installer" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * _Nonnull action) {[self enterModInstaller];}];
UIAlertAction *option2 = [UIAlertAction actionWithTitle:@"Custom controls" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * _Nonnull action) {[self enterCustomControls];}];
UIAlertAction *option3 = [UIAlertAction actionWithTitle:@"Settings" style:UIAlertActionStyleDefault
handler:^(UIAlertAction * _Nonnull action) {[self enterPreferences];}];
fullAlert.popoverPresentationController.barButtonItem = sender;
[self presentViewController:fullAlert animated:YES completion:nil];
[fullAlert addAction:option1];
[fullAlert addAction:option2];
[fullAlert addAction:option3];
}
}
- (void)enterCustomControls {
CustomControlsViewController *vc = [[CustomControlsViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
}
- (void)enterModInstaller {
UIDocumentPickerViewController *documentPicker = [[UIDocumentPickerViewController alloc] initWithDocumentTypes:@[@"com.sun.java-archive"]
inMode:UIDocumentPickerModeImport];
documentPicker.delegate = self;
documentPicker.modalPresentationStyle = UIModalPresentationFormSheet;
[self presentViewController:documentPicker animated:YES completion:nil];
}
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url {
if (controller.documentPickerMode == UIDocumentPickerModeImport) {
JavaGUIViewController *vc = [[JavaGUIViewController alloc] init];
vc.filepath = url.path;
NSLog(@"ModInstaller: launching %@", vc.filepath);
[self.navigationController pushViewController:vc animated:YES];
}
}
- (void)enterPreferences {
LauncherPreferencesViewController *vc = [[LauncherPreferencesViewController alloc] init];
[self.navigationController pushViewController:vc animated:YES];
}
- (void)launchMinecraft:(id)sender {
[(UIButton*) sender setEnabled:NO];
- (void)launchMinecraft:(UIButton *)sender {
[sender setEnabled:NO];
NSObject *object = [versionList objectAtIndex:[versionPickerView selectedRowInComponent:0]];
NSString *result;
if ([object isKindOfClass:[NSString class]]) {
result = (NSString*) object;
result = (NSString *)object;
} else {
result = [object valueForKey:@"url"];
}
+1 -1
View File
@@ -19,7 +19,7 @@
void loginAccountInput(UINavigationController *controller, int type, const char* data_c) {
JNIEnv *env;
(*runtimeJavaVMPtr)->AttachCurrentThread(runtimeJavaVMPtr, &env, NULL);
(*runtimeJavaVMPtr)->GetEnv(runtimeJavaVMPtr, &env, JNI_VERSION_1_6);
jstring data = (*env)->NewStringUTF(env, data_c);
@@ -168,6 +168,13 @@ void generateAndSaveDefaultControl() {
@"${bottom} - ${margin}",
BTN_RECT
)];
// Additional button for old versions that don't enter fullscreen automatically
[dict[@"mControlDataList"] addObject:createButton(@"Fullscreen",
(int[]){GLFW_KEY_F11,0,0,0},
@"${right} - ${margin}",
@"${bottom} - ${margin} * 2 - ${height}",
BTN_RECT
)];
NSOutputStream *os = [[NSOutputStream alloc] initToFileAtPath:
[@(getenv("POJAV_PATH_CONTROL")) stringByAppendingString:@"/default.json"] append:NO];
[os open];
-49
View File
@@ -56,14 +56,6 @@ jint JNI_OnLoad(JavaVM* vm, void* reserved) {
// Should be?
void JNI_OnUnload(JavaVM* vm, void* reserved) {
/*
if (dalvikJavaVMPtr == vm) {
} else {
}
DetachCurrentThread(vm);
*/
runtimeJNIEnvPtr_JRE = NULL;
}
@@ -88,24 +80,6 @@ ADD_CALLBACK_WWIN(WindowPos);
#undef ADD_CALLBACK_WWIN
jboolean attachThread(bool isAndroid, JNIEnv** secondJNIEnvPtr) {
#ifdef DEBUG
debug("Debug: Attaching %s thread to %s, javavm.isNull=%d\n", isAndroid ? "Android" : "JRE", isAndroid ? "JRE" : "Android", (isAndroid ? runtimeJavaVMPtr : dalvikJavaVMPtr) == NULL);
#endif
if (*secondJNIEnvPtr != NULL || (!isUseStackQueueCall)) return JNI_TRUE;
if (isAndroid && runtimeJavaVMPtr) {
(*runtimeJavaVMPtr)->AttachCurrentThread(runtimeJavaVMPtr, secondJNIEnvPtr, NULL);
return JNI_TRUE;
} else if (!isAndroid && dalvikJavaVMPtr) {
(*dalvikJavaVMPtr)->AttachCurrentThread(dalvikJavaVMPtr, secondJNIEnvPtr, NULL);
return JNI_TRUE;
}
return JNI_FALSE;
}
void getJavaInputBridge(jclass* clazz, jmethodID* method) {
#ifdef DEBUG
debug("Debug: Initializing input bridge, method.isNull=%d, jnienv.isNull=%d\n", *method == NULL, runtimeJNIEnvPtr_ANDROID == NULL);
@@ -272,29 +246,6 @@ JNIEXPORT jint JNICALL Java_net_kdt_pojavlaunch_uikit_UIKit_launchUI(JNIEnv* env
}
}
JNIEXPORT jboolean JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeAttachThreadToOther(JNIEnv* env, jclass clazz, jboolean isAndroid, jboolean isUseStackQueueBool) {
#ifdef DEBUG
LOGD("Debug: JNI attaching thread, isUseStackQueue=%d\n", isUseStackQueue);
#endif
jboolean result;
isUseStackQueueCall = (int) isUseStackQueueBool;
if (isAndroid) {
result = attachThread(true, &runtimeJNIEnvPtr_ANDROID);
} else {
result = attachThread(false, &dalvikJNIEnvPtr_JRE);
// getJavaInputBridge(&inputBridgeClass_JRE, &inputBridgeMethod_JRE);
}
if (isUseStackQueueCall && isAndroid && result) {
isPrepareGrabPos = true;
}
getJavaInputBridge(&inputBridgeClass_ANDROID, &inputBridgeMethod_ANDROID);
return result;
}
JNIEXPORT jstring JNICALL Java_org_lwjgl_glfw_CallbackBridge_nativeClipboard(JNIEnv* env, jclass clazz, jint action, jstring copySrc) {
DEBUG_LOGD("Debug: Clipboard access is going on\n");
return UIKit_accessClipboard(env, action, copySrc);
+1
View File
@@ -5,5 +5,6 @@
void showDialog(UIViewController *viewController, NSString* title, NSString* message);
jstring UIKit_accessClipboard(JNIEnv* env, jint action, jstring copySrc);
jboolean UIKit_updateProgress(float progress, const char* message);
void UIKit_launchJarFile(const char* filepath);
void UIKit_launchMinecraftSurfaceVC();
void UIKit_setButtonSkippable();
+25 -13
View File
@@ -13,6 +13,12 @@
jboolean skipDownloadAssets;
jclass class_CTCScreen;
jmethodID method_GetRGB;
jclass class_CTCAndroidInput;
jmethodID method_ReceiveInput;
void internal_showDialog(UIViewController *viewController, NSString* title, NSString* message) {
UIAlertController* alert = [UIAlertController alertControllerWithTitle:title
message:message
@@ -45,12 +51,7 @@ JNIEXPORT void JNICALL Java_net_kdt_pojavlaunch_uikit_UIKit_showError(JNIEnv* en
dispatch_async(dispatch_get_main_queue(), ^{
UIViewController *viewController = nil;
if (@available(iOS 13.0, *)) {
viewController = UIApplication.sharedApplication.windows.lastObject.rootViewController;
} else {
viewController = [[(AppDelegate*) [[UIApplication sharedApplication]delegate] window] rootViewController];
}
UIViewController *viewController = UIApplication.sharedApplication.windows.lastObject.rootViewController;
UIAlertController* alert = [UIAlertController
alertControllerWithTitle:title_o message:message_o
@@ -128,15 +129,26 @@ void UIKit_setButtonSkippable() {
skipDownloadAssets = JNI_FALSE;
}
void UIKit_launchJarFile(const char* filepath) {
jclass uikitBridgeClass = (*runtimeJNIEnvPtr_JRE)->FindClass(runtimeJNIEnvPtr_JRE, "net/kdt/pojavlaunch/uikit/UIKit");
assert(uikitBridgeClass != NULL);
jstring filepathStr = (*runtimeJNIEnvPtr_JRE)->NewStringUTF(runtimeJNIEnvPtr_JRE, filepath);
jmethodID method = (*runtimeJNIEnvPtr_JRE)->GetStaticMethodID(runtimeJNIEnvPtr_JRE, uikitBridgeClass, "callback_JavaGUIViewController_launchJarFile", "(Ljava/lang/String;II)V");
assert(method != NULL);
(*runtimeJNIEnvPtr_JRE)->CallStaticVoidMethod(
runtimeJNIEnvPtr_JRE,
uikitBridgeClass, method,
filepathStr,
savedWidth, savedHeight
);
(*runtimeJNIEnvPtr_JRE)->DeleteLocalRef(runtimeJNIEnvPtr_JRE, filepathStr);
}
void UIKit_launchMinecraftSurfaceVC() {
dispatch_async(dispatch_get_main_queue(), ^{
UIViewController *rootController = nil;
if (@available(iOS 13.0, *)) {
rootController = UIApplication.sharedApplication.windows.lastObject.rootViewController;
} else {
rootController = (UIViewController*) [[(AppDelegate*) [[UIApplication sharedApplication]delegate] window] rootViewController];
}
UIViewController *rootController = UIApplication.sharedApplication.windows.lastObject.rootViewController;
UIStoryboard *storyboard = [UIStoryboard storyboardWithName:@"MinecraftSurface" bundle:nil];
SurfaceViewController *vc = [storyboard instantiateViewControllerWithIdentifier:@"MinecraftSurfaceVC"];
vc.modalPresentationStyle = UIModalPresentationFullScreen;
+4 -1
View File
@@ -7,6 +7,10 @@
#define ACTION_UP 1
#define ACTION_MOVE 2
#define BUTTON1_DOWN_MASK 1 << 10 // left btn
#define BUTTON2_DOWN_MASK 1 << 11 // mid btn
#define BUTTON3_DOWN_MASK 1 << 12 // right btn
#define EVENT_TYPE_CHAR 1000
#define EVENT_TYPE_CHAR_MODS 1001
#define EVENT_TYPE_CURSOR_ENTER 1002
@@ -33,7 +37,6 @@ JavaVM* runtimeJavaVMPtr;
JNIEnv* runtimeJNIEnvPtr_ANDROID;
JNIEnv* runtimeJNIEnvPtr_JRE;
JavaVM* dalvikJavaVMPtr;
JNIEnv* dalvikJNIEnvPtr_ANDROID;
JNIEnv* dalvikJNIEnvPtr_JRE;