| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596 |
- #include "ios_system.h"
- #include <wchar.h>
- #include <iron_gpu.h>
- #include <iron_system.h>
- #include <iron_math.h>
- #include <objc/runtime.h>
- #include <mach/mach_time.h>
- #import <Foundation/Foundation.h>
- #import <UIKit/UIKit.h>
- #define MAX_TOUCH_COUNT 10
- extern char mobile_title[1024];
- static void *touches[MAX_TOUCH_COUNT];
- static int backing_width;
- static int backing_height;
- static bool shift_down = false;
- static bool visible;
- static MyView *my_view;
- static MyViewController *my_view_controller;
- static bool keyboard_shown = false;
- static char language[3];
- static char sysid[512];
- static const char *video_formats[] = {"mp4", NULL};
- static void (*resize_callback)(int x, int y, void *data) = NULL;
- static void *resize_callback_data = NULL;
- void iron_internal_call_resize_callback(int width, int height) {
- if (resize_callback != NULL) {
- resize_callback(width, height, resize_callback_data);
- }
- }
- static int get_touch_index(void *touch) {
- for (int i = 0; i < MAX_TOUCH_COUNT; ++i) {
- if (touches[i] == touch) {
- return i;
- }
- }
- return -1;
- }
- static int add_touch(void *touch) {
- for (int i = 0; i < MAX_TOUCH_COUNT; ++i) {
- if (touches[i] == NULL) {
- touches[i] = touch;
- return i;
- }
- }
- return -1;
- }
- static int remove_touch(void *touch) {
- for (int i = 0; i < MAX_TOUCH_COUNT; ++i) {
- if (touches[i] == touch) {
- touches[i] = NULL;
- return i;
- }
- }
- return -1;
- }
- int iron_window_width() {
- return backing_width;
- }
- int iron_window_height() {
- return backing_height;
- }
- CAMetalLayer *get_metal_layer(void) {
- return [my_view metal_layer];
- }
- id get_metal_device(void) {
- return [my_view metal_device];
- }
- id get_metal_queue(void) {
- return [my_view metal_queue];
- }
- void iron_display_init(void) {}
- iron_display_mode_t iron_display_current_mode(int display) {
- iron_display_mode_t dm;
- dm.width = iron_window_width();
- dm.height = iron_window_height();
- dm.frequency = (int)[[UIScreen mainScreen] maximumFramesPerSecond];
- dm.bits_per_pixel = 32;
- return dm;
- }
- int iron_count_displays(void) {
- return 1;
- }
- int iron_primary_display(void) {
- return 0;
- }
- void iron_internal_mouse_lock(void) {}
- void iron_internal_mouse_unlock(void) {}
- bool iron_mouse_can_lock(void) {
- return false;
- }
- void iron_mouse_show(void) {}
- void iron_mouse_hide(void) {}
- void iron_mouse_set_position(int x, int y) {}
- void iron_mouse_get_position(int *x, int *y) {}
- void iron_mouse_set_cursor(int cursor_index) {}
- bool with_autoreleasepool(bool (*f)(void)) {
- @autoreleasepool {
- return f();
- }
- }
- const char *iron_get_resource_path(void) {
- return [[[NSBundle mainBundle] resourcePath] cStringUsingEncoding:1];
- }
- bool iron_internal_handle_messages(void) {
- SInt32 result;
- do {
- result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE);
- } while (result == kCFRunLoopRunHandledSource);
- return true;
- }
- void iron_set_keep_screen_on(bool on) {}
- void iron_keyboard_show(void) {
- keyboard_shown = true;
- [my_view show_keyboard];
- }
- void iron_keyboard_hide(void) {
- keyboard_shown = false;
- [my_view hide_keyboard];
- }
- bool iron_keyboard_active(void) {
- return keyboard_shown;
- }
- void iron_load_url(const char *url) {
- [[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithUTF8String:url]]];
- }
- const char *iron_language(void) {
- NSString *nsstr = [[NSLocale preferredLanguages] objectAtIndex:0];
- const char *lang = [nsstr UTF8String];
- language[0] = lang[0];
- language[1] = lang[1];
- language[2] = 0;
- return language;
- }
- void iron_internal_shutdown(void) {}
- void iron_init(iron_window_options_t *win) {
- gpu_init(win->depth_bits, true);
- }
- const char *iron_system_id(void) {
- const char *name = [[[UIDevice currentDevice] name] UTF8String];
- const char *vendorId = [[[[UIDevice currentDevice] identifierForVendor] UUIDString] UTF8String];
- strcpy(sysid, name);
- strcat(sysid, "-");
- strcat(sysid, vendorId);
- return sysid;
- }
- const char *iron_internal_save_path(void) {
- NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
- NSString *resolvedPath = [paths objectAtIndex:0];
- NSString *appName = [NSString stringWithUTF8String:iron_application_name()];
- resolvedPath = [resolvedPath stringByAppendingPathComponent:appName];
- NSFileManager *fileMgr = [[NSFileManager alloc] init];
- NSError *error;
- [fileMgr createDirectoryAtPath:resolvedPath withIntermediateDirectories:YES attributes:nil error:&error];
- resolvedPath = [resolvedPath stringByAppendingString:@"/"];
- return [resolvedPath cStringUsingEncoding:1];
- }
- const char **iron_video_formats(void) {
- return video_formats;
- }
- double iron_frequency(void) {
- mach_timebase_info_data_t info;
- mach_timebase_info(&info);
- return (double)info.denom / (double)info.numer / 1e-9;
- }
- uint64_t iron_timestamp(void) {
- uint64_t time = mach_absolute_time();
- return time;
- }
- int main(int argc, char *argv[]) {
- int res = 0;
- @autoreleasepool {
- [IronSceneDelegate description]; // otherwise removed by the linker
- res = UIApplicationMain(argc, argv, nil, nil);
- }
- return res;
- }
- int iron_window_x() {
- return 0;
- }
- int iron_window_y() {
- return 0;
- }
- void iron_window_resize(int width, int height) {}
- void iron_window_move(int x, int y) {}
- void iron_window_change_mode(iron_window_mode_t mode) {}
- void iron_window_destroy() {}
- void iron_window_show() {}
- void iron_window_hide() {}
- void iron_window_set_title(const char *title) {}
- void iron_window_create(iron_window_options_t *win) {}
- void iron_window_set_resize_callback(void (*callback)(int x, int y, void *data), void *data) {
- resize_callback = callback;
- resize_callback_data = data;
- }
- void iron_window_set_close_callback(bool (*callback)(void *), void *data) {}
- iron_window_mode_t iron_window_get_mode() {
- return IRON_WINDOW_MODE_FULLSCREEN;
- }
- int iron_window_display() {
- return 0;
- }
- @implementation MyView
- + (Class)layerClass {
- return [CAMetalLayer class];
- }
- - (void)hoverGesture:(UIHoverGestureRecognizer *)recognizer {
- CGPoint point = [recognizer locationInView:self];
- float x = point.x * self.contentScaleFactor;
- float y = point.y * self.contentScaleFactor;
- iron_internal_pen_trigger_move(x, y, 0.0); // Pencil hover
- }
- - (id)initWithFrame:(CGRect)frame {
- self = [super initWithFrame:(CGRect)frame];
- self.contentScaleFactor = [UIScreen mainScreen].scale;
- backing_width = frame.size.width * self.contentScaleFactor;
- backing_height = frame.size.height * self.contentScaleFactor;
- for (int i = 0; i < MAX_TOUCH_COUNT; ++i) {
- touches[i] = NULL;
- }
- device = MTLCreateSystemDefaultDevice();
- queue = [device newCommandQueue];
- library = [device newDefaultLibrary];
- CAMetalLayer *layer = (CAMetalLayer *)self.layer;
- layer.device = device;
- layer.pixelFormat = MTLPixelFormatBGRA8Unorm;
- layer.framebufferOnly = YES;
- layer.opaque = YES;
- layer.backgroundColor = nil;
- [self addGestureRecognizer:[[UIHoverGestureRecognizer alloc] initWithTarget:self action:@selector(hoverGesture:)]];
- return self;
- }
- - (void)layoutSubviews {
- backing_width = self.frame.size.width * self.contentScaleFactor;
- backing_height = self.frame.size.height * self.contentScaleFactor;
- gpu_resize(backing_width, backing_height);
- iron_internal_call_resize_callback(backing_width, backing_height);
- }
- - (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
- for (UITouch *touch in touches) {
- int index = get_touch_index((__bridge void *)touch);
- if (index == -1) {
- index = add_touch((__bridge void *)touch);
- }
- if (index >= 0) {
- CGPoint point = [touch locationInView:self];
- float x = point.x * self.contentScaleFactor;
- float y = point.y * self.contentScaleFactor;
- if (index == 0) {
- iron_internal_mouse_trigger_press(event.buttonMask == UIEventButtonMaskSecondary ? 1 : 0, x, y);
- }
- iron_internal_surface_trigger_touch_start(index, x, y);
- if (touch.type == UITouchTypePencil) {
- iron_internal_pen_trigger_press(x, y, 0.0);
- }
- }
- }
- }
- - (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
- for (UITouch *touch in touches) {
- int index = get_touch_index((__bridge void *)touch);
- if (index >= 0) {
- CGPoint point = [touch locationInView:self];
- float x = point.x * self.contentScaleFactor;
- float y = point.y * self.contentScaleFactor;
- if (index == 0) {
- iron_internal_mouse_trigger_move(x, y);
- }
- iron_internal_surface_trigger_move(index, x, y);
- }
- }
- }
- - (void)touchesEstimatedPropertiesUpdated:(NSSet<UITouch *> *)touches {
- for (UITouch *touch in touches) {
- if (touch.type == UITouchTypePencil) {
- CGPoint point = [touch locationInView:self];
- float x = point.x * self.contentScaleFactor;
- float y = point.y * self.contentScaleFactor;
- iron_internal_pen_trigger_move(x, y, touch.force);
- }
- }
- }
- - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
- for (UITouch *touch in touches) {
- int index = remove_touch((__bridge void *)touch);
- if (index >= 0) {
- CGPoint point = [touch locationInView:self];
- float x = point.x * self.contentScaleFactor;
- float y = point.y * self.contentScaleFactor;
- if (index == 0) {
- iron_internal_mouse_trigger_release(event.buttonMask == UIEventButtonMaskSecondary ? 1 : 0, x, y);
- }
- iron_internal_surface_trigger_touch_end(index, x, y);
- if (touch.type == UITouchTypePencil) {
- iron_internal_pen_trigger_release(x, y, 0.0);
- }
- }
- }
- }
- - (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
- for (UITouch *touch in touches) {
- int index = remove_touch((__bridge void *)touch);
- if (index >= 0) {
- CGPoint point = [touch locationInView:self];
- float x = point.x * self.contentScaleFactor;
- float y = point.y * self.contentScaleFactor;
- if (index == 0) {
- iron_internal_mouse_trigger_release(event.buttonMask == UIEventButtonMaskSecondary ? 1 : 0, x, y);
- }
- iron_internal_surface_trigger_touch_end(index, x, y);
- if (touch.type == UITouchTypePencil) {
- iron_internal_pen_trigger_release(x, y, 0.0);
- }
- }
- }
- }
- - (void)show_keyboard {
- [self becomeFirstResponder];
- }
- - (void)hide_keyboard {
- [self resignFirstResponder];
- }
- - (BOOL)hasText {
- return YES;
- }
- - (void)insertText:(NSString *)text {
- if ([text length] == 1) {
- unichar ch = [text characterAtIndex:[text length] - 1];
- if (ch == 8212) {
- ch = '_';
- }
- if (ch == L'\n') {
- iron_internal_keyboard_trigger_key_down(IRON_KEY_RETURN);
- iron_internal_keyboard_trigger_key_up(IRON_KEY_RETURN);
- return;
- }
- if (ch == L'.') {
- iron_internal_keyboard_trigger_key_down(IRON_KEY_PERIOD);
- iron_internal_keyboard_trigger_key_up(IRON_KEY_PERIOD);
- }
- else if (ch == L'%') {
- iron_internal_keyboard_trigger_key_down(IRON_KEY_PERCENT);
- iron_internal_keyboard_trigger_key_up(IRON_KEY_PERCENT);
- }
- else if (ch == L'(') {
- iron_internal_keyboard_trigger_key_down(IRON_KEY_OPEN_PAREN);
- iron_internal_keyboard_trigger_key_up(IRON_KEY_OPEN_PAREN);
- }
- else if (ch == L'&') {
- iron_internal_keyboard_trigger_key_down(IRON_KEY_AMPERSAND);
- iron_internal_keyboard_trigger_key_up(IRON_KEY_AMPERSAND);
- }
- else if (ch == L'$') {
- iron_internal_keyboard_trigger_key_down(IRON_KEY_DOLLAR);
- iron_internal_keyboard_trigger_key_up(IRON_KEY_DOLLAR);
- }
- else if (ch == L'#') {
- iron_internal_keyboard_trigger_key_down(IRON_KEY_HASH);
- iron_internal_keyboard_trigger_key_up(IRON_KEY_HASH);
- }
- else if (ch >= L'a' && ch <= L'z') {
- if (shift_down) {
- iron_internal_keyboard_trigger_key_up(IRON_KEY_SHIFT);
- shift_down = false;
- }
- iron_internal_keyboard_trigger_key_down(ch + IRON_KEY_A - L'a');
- iron_internal_keyboard_trigger_key_up(ch + IRON_KEY_A - L'a');
- }
- else {
- if (!shift_down) {
- iron_internal_keyboard_trigger_key_down(IRON_KEY_SHIFT);
- shift_down = true;
- }
- iron_internal_keyboard_trigger_key_down(ch + IRON_KEY_A - L'A');
- iron_internal_keyboard_trigger_key_up(ch + IRON_KEY_A - L'A');
- }
- iron_internal_keyboard_trigger_key_press(ch);
- }
- }
- - (void)deleteBackward {
- iron_internal_keyboard_trigger_key_down(IRON_KEY_BACKSPACE);
- iron_internal_keyboard_trigger_key_up(IRON_KEY_BACKSPACE);
- }
- - (BOOL)canBecomeFirstResponder {
- return YES;
- }
- - (void)onKeyboardHide:(NSNotification *)notification {
- iron_keyboard_hide();
- }
- - (CAMetalLayer *)metal_layer {
- return (CAMetalLayer *)self.layer;
- }
- - (id<MTLDevice>)metal_device {
- return device;
- }
- - (id<MTLCommandQueue>)metal_queue {
- return queue;
- }
- @end
- @implementation MyViewController
- - (void)loadView {
- visible = true;
- self.view = my_view = [[MyView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
- [self.view addInteraction: [[UIDropInteraction alloc] initWithDelegate: self]];
- [self setNeedsUpdateOfScreenEdgesDeferringSystemGestures];
- }
- - (void)setVisible:(BOOL)value {
- visible = value;
- }
- void importFile(NSURL *url) {
- NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);
- NSString *folderName = [NSString stringWithUTF8String:mobile_title];
- NSString *filePath = [[paths objectAtIndex:0] stringByAppendingPathComponent:folderName];
- if (![[NSFileManager defaultManager] fileExistsAtPath:filePath]) {
- [[NSFileManager defaultManager] createDirectoryAtPath:filePath withIntermediateDirectories:NO attributes:nil error:nil];
- }
- NSString *suggestedName = url.path.lastPathComponent;
- filePath = [filePath stringByAppendingPathComponent:suggestedName];
- CFURLRef cfurl = (__bridge CFURLRef)url;
- CFURLStartAccessingSecurityScopedResource(cfurl);
- [[NSFileManager defaultManager] copyItemAtPath:url.path toPath:filePath error:nil];
- CFURLStopAccessingSecurityScopedResource(cfurl);
- wchar_t *wpath = (wchar_t *)[filePath cStringUsingEncoding:NSUTF32LittleEndianStringEncoding];
- iron_internal_drop_files_callback(wpath);
- }
- - (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url {
- // wchar_t *filePath = (wchar_t *)[url.path cStringUsingEncoding:NSUTF32LittleEndianStringEncoding];
- // CFURLRef cfurl = (__bridge CFURLRef)url;
- // CFURLStartAccessingSecurityScopedResource(cfurl);
- // iron_internal_drop_files_callback(filePath);
- // CFURLStopAccessingSecurityScopedResource(cfurl);
- importFile(url);
- }
- - (void)dropInteraction:(UIDropInteraction *)interaction performDrop:(id<UIDropSession>)session {
- CGPoint point = [session locationInView:self.view];
- float x = point.x * my_view.contentScaleFactor;
- float y = point.y * my_view.contentScaleFactor;
- iron_internal_mouse_trigger_move(x, y);
- iron_internal_surface_trigger_move(0, x, y);
- for (UIDragItem *item in session.items) {
- [item.itemProvider loadInPlaceFileRepresentationForTypeIdentifier:item.itemProvider.registeredTypeIdentifiers[0] completionHandler:^(NSURL * _Nullable url, BOOL isInPlace, NSError * _Nullable error) {
- importFile(url);
- }];
- }
- }
- - (UIDropProposal *)dropInteraction:(UIDropInteraction *)interaction sessionDidUpdate:(id<UIDropSession>)session {
- return [[UIDropProposal alloc] initWithDropOperation: UIDropOperationCopy];
- }
- - (UIRectEdge)preferredScreenEdgesDeferringSystemGestures {
- return UIRectEdgeAll;
- }
- @end
- @implementation IronSceneDelegate
- - (void)mainLoop {
- @autoreleasepool {
- kickstart(0, NULL);
- }
- }
- - (void)scene:(UIScene *)scene willConnectToSession:(UISceneSession *)session options:(UISceneConnectionOptions *)connectionOptions {
- #ifdef IRON_A2
- AVAudioSession *sessionInstance = [AVAudioSession sharedInstance];
- NSError *error;
- NSString *category = AVAudioSessionCategoryAmbient;
- [sessionInstance setCategory:category error:&error];
- #endif
- UIWindowScene *windowScene = (UIWindowScene *)scene;
- self.window = [[UIWindow alloc] initWithWindowScene:windowScene];
- self.window.frame = windowScene.coordinateSpace.bounds;
- [self.window setBackgroundColor:[UIColor blackColor]];
- my_view_controller = [[MyViewController alloc] init];
- my_view_controller.view.multipleTouchEnabled = YES;
- [self.window setRootViewController:my_view_controller];
- [self.window makeKeyAndVisible];
- [my_view_controller setVisible:YES];
- [self performSelectorOnMainThread:@selector(mainLoop) withObject:nil waitUntilDone:NO];
- }
- - (void)sceneDidDisconnect:(UIScene *)scene {
- iron_internal_shutdown_callback();
- }
- - (void)sceneDidBecomeActive:(UIScene *)scene {
- iron_internal_resume_callback();
- }
- - (void)sceneWillResignActive:(UIScene *)scene {
- iron_internal_pause_callback();
- }
- - (void)sceneWillEnterForeground:(UIScene *)scene {
- iron_internal_foreground_callback();
- }
- - (void)sceneDidEnterBackground:(UIScene *)scene {
- iron_internal_background_callback();
- }
- @end
- #ifdef WITH_GAMEPAD
- const char *iron_gamepad_vendor(int gamepad) {
- return "nobody";
- }
- const char *iron_gamepad_product_name(int gamepad) {
- return "none";
- }
- bool iron_gamepad_connected(int num) {
- return true;
- }
- void iron_gamepad_rumble(int gamepad, float left, float right) {}
- #endif
|