Files
armorpaint/base/sources/backends/ios_system.m
T

752 lines
18 KiB
Objective-C
Raw Normal View History

2025-02-26 18:46:36 +01:00
#include "ios_system.h"
#include <iron_gpu.h>
#include <iron_system.h>
#import <Foundation/Foundation.h>
#include <iron_math.h>
#include <objc/runtime.h>
#import <AVFAudio/AVFAudio.h>
#include <wchar.h>
#import <UIKit/UIKit.h>
#include <iron_video.h>
#import <AudioToolbox/AudioToolbox.h>
#include <mach/mach_time.h>
static const int touchmaxcount = 20;
static void *touches[touchmaxcount];
static void initTouches(void) {
for (int i = 0; i < touchmaxcount; ++i) {
touches[i] = NULL;
}
}
static int getTouchIndex(void *touch) {
for (int i = 0; i < touchmaxcount; ++i) {
if (touches[i] == touch)
return i;
}
return -1;
}
static int addTouch(void *touch) {
for (int i = 0; i < touchmaxcount; ++i) {
if (touches[i] == NULL) {
touches[i] = touch;
return i;
}
}
return -1;
}
static int removeTouch(void *touch) {
for (int i = 0; i < touchmaxcount; ++i) {
if (touches[i] == touch) {
touches[i] = NULL;
return i;
}
}
return -1;
}
static GLint backingWidth, backingHeight;
2025-03-09 17:02:12 +01:00
int iron_window_width() {
2025-02-26 18:46:36 +01:00
return backingWidth;
}
2025-03-09 17:02:12 +01:00
int iron_window_height() {
2025-02-26 18:46:36 +01:00
return backingHeight;
}
@implementation GLView
+ (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;
// Pencil hover
2025-03-09 17:02:12 +01:00
iron_internal_pen_trigger_move(0, x, y, 0.0);
2025-02-26 18:46:36 +01:00
}
- (id)initWithFrame:(CGRect)frame {
self = [super initWithFrame:(CGRect)frame];
self.contentScaleFactor = [UIScreen mainScreen].scale;
backingWidth = frame.size.width * self.contentScaleFactor;
backingHeight = frame.size.height * self.contentScaleFactor;
initTouches();
device = MTLCreateSystemDefaultDevice();
commandQueue = [device newCommandQueue];
library = [device newDefaultLibrary];
CAMetalLayer *metalLayer = (CAMetalLayer *)self.layer;
metalLayer.device = device;
metalLayer.pixelFormat = MTLPixelFormatBGRA8Unorm;
metalLayer.framebufferOnly = YES;
// metalLayer.presentsWithTransaction = YES;
metalLayer.opaque = YES;
metalLayer.backgroundColor = nil;
[self addGestureRecognizer:[[UIHoverGestureRecognizer alloc] initWithTarget:self action:@selector(hoverGesture:)]];
return self;
}
- (void)begin {
}
- (void)end {
}
2025-03-09 17:02:12 +01:00
void iron_internal_call_resize_callback(int width, int height);
2025-02-26 18:46:36 +01:00
- (void)layoutSubviews {
backingWidth = self.frame.size.width * self.contentScaleFactor;
backingHeight = self.frame.size.height * self.contentScaleFactor;
CAMetalLayer *metalLayer = (CAMetalLayer *)self.layer;
metalLayer.drawableSize = CGSizeMake(backingWidth, backingHeight);
2025-03-09 17:02:12 +01:00
iron_internal_call_resize_callback(backingWidth, backingHeight);
2025-02-26 18:46:36 +01:00
}
- (void)dealloc {
}
- (void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
int index = getTouchIndex((__bridge void *)touch);
if (index == -1)
index = addTouch((__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) {
2025-03-09 17:02:12 +01:00
iron_internal_mouse_trigger_press(0, event.buttonMask == UIEventButtonMaskSecondary ? 1 : 0, x, y);
2025-02-26 18:46:36 +01:00
}
2025-03-09 17:02:12 +01:00
iron_internal_surface_trigger_touch_start(index, x, y);
2025-02-26 18:46:36 +01:00
if (touch.type == UITouchTypePencil) {
2025-03-09 17:02:12 +01:00
iron_internal_pen_trigger_press(0, x, y, 0.0);
2025-02-26 18:46:36 +01:00
}
}
}
}
- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
int index = getTouchIndex((__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) {
2025-03-09 17:02:12 +01:00
iron_internal_mouse_trigger_move(0, x, y);
2025-02-26 18:46:36 +01:00
}
2025-03-09 17:02:12 +01:00
iron_internal_surface_trigger_move(index, x, y);
2025-02-26 18:46:36 +01:00
}
}
}
- (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;
2025-03-09 17:02:12 +01:00
iron_internal_pen_trigger_move(0, x, y, touch.force);
2025-02-26 18:46:36 +01:00
}
}
}
- (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
int index = removeTouch((__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) {
2025-03-09 17:02:12 +01:00
iron_internal_mouse_trigger_release(0, event.buttonMask == UIEventButtonMaskSecondary ? 1 : 0, x, y);
2025-02-26 18:46:36 +01:00
}
2025-03-09 17:02:12 +01:00
iron_internal_surface_trigger_touch_end(index, x, y);
2025-02-26 18:46:36 +01:00
if (touch.type == UITouchTypePencil) {
2025-03-09 17:02:12 +01:00
iron_internal_pen_trigger_release(0, x, y, 0.0);
2025-02-26 18:46:36 +01:00
}
}
}
}
- (void)touchesCancelled:(NSSet *)touches withEvent:(UIEvent *)event {
for (UITouch *touch in touches) {
int index = removeTouch((__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) {
2025-03-09 17:02:12 +01:00
iron_internal_mouse_trigger_release(0, event.buttonMask == UIEventButtonMaskSecondary ? 1 : 0, x, y);
2025-02-26 18:46:36 +01:00
}
2025-03-09 17:02:12 +01:00
iron_internal_surface_trigger_touch_end(index, x, y);
2025-02-26 18:46:36 +01:00
if (touch.type == UITouchTypePencil) {
2025-03-09 17:02:12 +01:00
iron_internal_pen_trigger_release(0, x, y, 0.0);
2025-02-26 18:46:36 +01:00
}
}
}
}
static NSString *keyboardstring;
static UITextField *myTextField = NULL;
static bool shiftDown = false;
- (void)showKeyboard {
[self becomeFirstResponder];
}
- (void)hideKeyboard {
[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') {
2025-03-09 17:02:12 +01:00
iron_internal_keyboard_trigger_key_down(IRON_KEY_RETURN);
iron_internal_keyboard_trigger_key_up(IRON_KEY_RETURN);
2025-02-26 18:46:36 +01:00
return;
}
if (ch == L'.') {
2025-03-09 17:02:12 +01:00
iron_internal_keyboard_trigger_key_down(IRON_KEY_PERIOD);
iron_internal_keyboard_trigger_key_up(IRON_KEY_PERIOD);
2025-02-26 18:46:36 +01:00
}
else if (ch == L'%') {
2025-03-09 17:02:12 +01:00
iron_internal_keyboard_trigger_key_down(IRON_KEY_PERCENT);
iron_internal_keyboard_trigger_key_up(IRON_KEY_PERCENT);
2025-02-26 18:46:36 +01:00
}
else if (ch == L'(') {
2025-03-09 17:02:12 +01:00
iron_internal_keyboard_trigger_key_down(IRON_KEY_OPEN_PAREN);
iron_internal_keyboard_trigger_key_up(IRON_KEY_OPEN_PAREN);
2025-02-26 18:46:36 +01:00
}
else if (ch == L'&') {
2025-03-09 17:02:12 +01:00
iron_internal_keyboard_trigger_key_down(IRON_KEY_AMPERSAND);
iron_internal_keyboard_trigger_key_up(IRON_KEY_AMPERSAND);
2025-02-26 18:46:36 +01:00
}
else if (ch == L'$') {
2025-03-09 17:02:12 +01:00
iron_internal_keyboard_trigger_key_down(IRON_KEY_DOLLAR);
iron_internal_keyboard_trigger_key_up(IRON_KEY_DOLLAR);
2025-02-26 18:46:36 +01:00
}
else if (ch == L'#') {
2025-03-09 17:02:12 +01:00
iron_internal_keyboard_trigger_key_down(IRON_KEY_HASH);
iron_internal_keyboard_trigger_key_up(IRON_KEY_HASH);
2025-02-26 18:46:36 +01:00
}
else if (ch >= L'a' && ch <= L'z') {
if (shiftDown) {
2025-03-09 17:02:12 +01:00
iron_internal_keyboard_trigger_key_up(IRON_KEY_SHIFT);
2025-02-26 18:46:36 +01:00
shiftDown = false;
}
2025-03-09 17:02:12 +01:00
iron_internal_keyboard_trigger_key_down(ch + IRON_KEY_A - L'a');
iron_internal_keyboard_trigger_key_up(ch + IRON_KEY_A - L'a');
2025-02-26 18:46:36 +01:00
}
else {
if (!shiftDown) {
2025-03-09 17:02:12 +01:00
iron_internal_keyboard_trigger_key_down(IRON_KEY_SHIFT);
2025-02-26 18:46:36 +01:00
shiftDown = true;
}
2025-03-09 17:02:12 +01:00
iron_internal_keyboard_trigger_key_down(ch + IRON_KEY_A - L'A');
iron_internal_keyboard_trigger_key_up(ch + IRON_KEY_A - L'A');
2025-02-26 18:46:36 +01:00
}
2025-03-09 17:02:12 +01:00
iron_internal_keyboard_trigger_key_press(ch);
2025-02-26 18:46:36 +01:00
}
}
- (void)deleteBackward {
2025-03-09 17:02:12 +01:00
iron_internal_keyboard_trigger_key_down(IRON_KEY_BACKSPACE);
iron_internal_keyboard_trigger_key_up(IRON_KEY_BACKSPACE);
2025-02-26 18:46:36 +01:00
}
- (BOOL)canBecomeFirstResponder {
return YES;
}
- (void)onKeyboardHide:(NSNotification *)notification {
2025-03-09 17:02:12 +01:00
iron_keyboard_hide();
2025-02-26 18:46:36 +01:00
}
- (CAMetalLayer *)metalLayer {
return (CAMetalLayer *)self.layer;
}
- (id<MTLDevice>)metalDevice {
return device;
}
- (id<MTLLibrary>)metalLibrary {
return library;
}
- (id<MTLCommandQueue>)metalQueue {
return commandQueue;
}
@end
static GLView *glView;
static bool visible;
void beginGL(void) {
if (!visible) {
return;
}
[glView begin];
}
void endGL(void) {
if (!visible) {
return;
}
[glView end];
}
void showKeyboard(void) {
[glView showKeyboard];
}
void hideKeyboard(void) {
[glView hideKeyboard];
}
CAMetalLayer *getMetalLayer(void) {
return [glView metalLayer];
}
id getMetalDevice(void) {
return [glView metalDevice];
}
id getMetalLibrary(void) {
return [glView metalLibrary];
}
id getMetalQueue(void) {
return [glView metalQueue];
}
@implementation GLViewController
- (void)loadView {
visible = true;
self.view = glView = [[GLView alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[self.view addInteraction: [[UIDropInteraction alloc] initWithDelegate: self]];
[self setNeedsUpdateOfScreenEdgesDeferringSystemGestures];
}
- (void)setVisible:(BOOL)value {
visible = value;
}
#include <iron_system.h>
extern char mobile_title[1024];
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];
2025-03-09 17:02:12 +01:00
iron_internal_drop_files_callback(wpath);
2025-02-26 18:46:36 +01:00
}
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url {
// wchar_t *filePath = (wchar_t *)[url.path cStringUsingEncoding:NSUTF32LittleEndianStringEncoding];
// CFURLRef cfurl = (__bridge CFURLRef)url;
// CFURLStartAccessingSecurityScopedResource(cfurl);
2025-03-09 17:02:12 +01:00
// iron_internal_drop_files_callback(filePath);
2025-02-26 18:46:36 +01:00
// CFURLStopAccessingSecurityScopedResource(cfurl);
importFile(url);
}
- (void)dropInteraction:(UIDropInteraction *)interaction performDrop:(id<UIDropSession>)session {
CGPoint point = [session locationInView:self.view];
float x = point.x * glView.contentScaleFactor;
float y = point.y * glView.contentScaleFactor;
2025-03-09 17:02:12 +01:00
iron_internal_mouse_trigger_move(0, x, y);
iron_internal_surface_trigger_move(0, x, y);
2025-02-26 18:46:36 +01:00
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
2025-03-09 17:02:12 +01:00
@implementation IronAppDelegate
2025-02-26 18:46:36 +01:00
static UIWindow *window;
static GLViewController *glViewController;
void loadURL(const char *url) {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithUTF8String:url]]];
}
- (void)mainLoop {
@autoreleasepool {
kickstart(0, NULL);
}
}
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
AVAudioSession *sessionInstance = [AVAudioSession sharedInstance];
NSError *error;
// set the session category
NSString *category = AVAudioSessionCategoryAmbient;
bool success = [sessionInstance setCategory:category error:&error];
if (!success)
NSLog(@"Error setting AVAudioSession category! %@\n", [error localizedDescription]);
window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
[window setBackgroundColor:[UIColor blackColor]];
glViewController = [[GLViewController alloc] init];
glViewController.view.multipleTouchEnabled = YES;
[window setRootViewController:glViewController];
[window makeKeyAndVisible];
[self performSelectorOnMainThread:@selector(mainLoop) withObject:nil waitUntilDone:NO];
return YES;
}
2025-03-09 17:02:12 +01:00
void IronUpdateKeyboard(void);
2025-02-26 18:46:36 +01:00
- (void)applicationWillEnterForeground:(UIApplication *)application {
[glViewController setVisible:YES];
2025-03-09 17:02:12 +01:00
iron_internal_foreground_callback();
2025-02-26 18:46:36 +01:00
}
- (void)applicationDidBecomeActive:(UIApplication *)application {
2025-03-09 17:02:12 +01:00
iron_internal_resume_callback();
2025-02-26 18:46:36 +01:00
}
- (void)applicationWillResignActive:(UIApplication *)application {
2025-03-09 17:02:12 +01:00
iron_internal_pause_callback();
2025-02-26 18:46:36 +01:00
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
[glViewController setVisible:NO];
2025-03-09 17:02:12 +01:00
iron_internal_background_callback();
2025-02-26 18:46:36 +01:00
}
- (void)applicationWillTerminate:(UIApplication *)application {
2025-03-09 17:02:12 +01:00
iron_internal_shutdown_callback();
2025-02-26 18:46:36 +01:00
}
@end
2025-03-09 17:02:12 +01:00
void iron_display_init(void) {}
2025-02-26 18:46:36 +01:00
2025-03-09 17:02:12 +01:00
iron_display_mode_t iron_display_available_mode(int display, int mode) {
iron_display_mode_t dm;
dm.width = iron_window_width();
dm.height = iron_window_height();
2025-02-26 18:46:36 +01:00
dm.frequency = 60;
dm.bits_per_pixel = 32;
return dm;
}
2025-03-09 17:02:12 +01:00
int iron_display_count_available_modes(int display) {
2025-02-26 18:46:36 +01:00
return 1;
}
2025-03-09 17:02:12 +01:00
bool iron_display_available(int display) {
2025-02-26 18:46:36 +01:00
return true;
}
2025-03-09 17:02:12 +01:00
const char *iron_display_name(int display) {
2025-02-26 18:46:36 +01:00
return "Display";
}
2025-03-09 17:02:12 +01:00
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();
2025-02-26 18:46:36 +01:00
dm.frequency = (int)[[UIScreen mainScreen] maximumFramesPerSecond];
dm.bits_per_pixel = 32;
return dm;
}
2025-03-09 17:02:12 +01:00
int iron_count_displays(void) {
2025-02-26 18:46:36 +01:00
return 1;
}
2025-03-09 17:02:12 +01:00
int iron_primary_display(void) {
2025-02-26 18:46:36 +01:00
return 0;
}
@implementation Motion
@end
2025-03-09 17:02:12 +01:00
void iron_internal_mouse_lock(void) {}
2025-02-26 18:46:36 +01:00
2025-03-09 17:02:12 +01:00
void iron_internal_mouse_unlock(void) {}
2025-02-26 18:46:36 +01:00
2025-03-09 17:02:12 +01:00
bool iron_mouse_can_lock(void) {
2025-02-26 18:46:36 +01:00
return false;
}
2025-03-09 17:02:12 +01:00
void iron_mouse_show(void) {}
2025-02-26 18:46:36 +01:00
2025-03-09 17:02:12 +01:00
void iron_mouse_hide(void) {}
2025-02-26 18:46:36 +01:00
2025-03-09 17:02:12 +01:00
void iron_mouse_set_position(int x, int y) {}
2025-02-26 18:46:36 +01:00
2025-03-09 17:02:12 +01:00
void iron_mouse_get_position(int *x, int *y) {}
2025-02-26 18:46:36 +01:00
2025-03-09 17:02:12 +01:00
void iron_mouse_set_cursor(int cursor_index) {}
2025-02-26 18:46:36 +01:00
bool withAutoreleasepool(bool (*f)(void)) {
@autoreleasepool {
return f();
}
}
static bool keyboardshown = false;
const char *iphonegetresourcepath(void) {
return [[[NSBundle mainBundle] resourcePath] cStringUsingEncoding:1];
}
2025-03-09 17:02:12 +01:00
bool iron_internal_handle_messages(void) {
2025-02-26 18:46:36 +01:00
SInt32 result;
do {
result = CFRunLoopRunInMode(kCFRunLoopDefaultMode, 0, TRUE);
} while (result == kCFRunLoopRunHandledSource);
return true;
}
2025-03-09 17:02:12 +01:00
void iron_set_keep_screen_on(bool on) {}
2025-02-26 18:46:36 +01:00
void showKeyboard(void);
void hideKeyboard(void);
2025-03-09 17:02:12 +01:00
void iron_keyboard_show(void) {
2025-02-26 18:46:36 +01:00
keyboardshown = true;
showKeyboard();
}
2025-03-09 17:02:12 +01:00
void iron_keyboard_hide(void) {
2025-02-26 18:46:36 +01:00
keyboardshown = false;
hideKeyboard();
}
2025-03-09 17:02:12 +01:00
bool iron_keyboard_active(void) {
2025-02-26 18:46:36 +01:00
return keyboardshown;
}
void loadURL(const char *url);
2025-03-09 17:02:12 +01:00
void iron_load_url(const char *url) {
2025-02-26 18:46:36 +01:00
loadURL(url);
}
static char language[3];
2025-03-09 17:02:12 +01:00
const char *iron_language(void) {
2025-02-26 18:46:36 +01:00
NSString *nsstr = [[NSLocale preferredLanguages] objectAtIndex:0];
const char *lang = [nsstr UTF8String];
language[0] = lang[0];
language[1] = lang[1];
language[2] = 0;
return language;
}
2025-03-09 17:02:12 +01:00
void IronUpdateKeyboard(void) {
2025-02-26 18:46:36 +01:00
if (keyboardshown) {
hideKeyboard();
showKeyboard();
}
else {
hideKeyboard();
}
}
2025-03-09 17:02:12 +01:00
void iron_internal_shutdown(void) {}
2025-02-26 18:46:36 +01:00
2025-03-09 17:02:12 +01:00
void iron_init(const char *name, int width, int height, struct iron_window_options *win) {
iron_window_options_t defaultWin;
2025-02-26 18:46:36 +01:00
if (win == NULL) {
2025-03-09 17:02:12 +01:00
iron_window_options_set_defaults(&defaultWin);
2025-02-26 18:46:36 +01:00
win = &defaultWin;
}
2025-03-09 17:02:12 +01:00
iron_g5_internal_init();
iron_g4_internal_init_window(win->depth_bits, true);
2025-02-26 18:46:36 +01:00
}
void endGL(void);
void swapBuffersiOS(void) {
endGL();
}
static char sysid[512];
2025-03-09 17:02:12 +01:00
const char *iron_system_id(void) {
2025-02-26 18:46:36 +01:00
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;
}
static const char *getSavePath(void) {
NSArray *paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES);
NSString *resolvedPath = [paths objectAtIndex:0];
2025-03-09 17:02:12 +01:00
NSString *appName = [NSString stringWithUTF8String:iron_application_name()];
2025-02-26 18:46:36 +01:00
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];
}
2025-03-09 17:02:12 +01:00
const char *iron_internal_save_path(void) {
2025-02-26 18:46:36 +01:00
return getSavePath();
}
static const char *videoFormats[] = {"mp4", NULL};
2025-03-09 17:02:12 +01:00
const char **iron_video_formats(void) {
2025-02-26 18:46:36 +01:00
return videoFormats;
}
2025-03-09 17:02:12 +01:00
double iron_frequency(void) {
2025-02-26 18:46:36 +01:00
mach_timebase_info_data_t info;
mach_timebase_info(&info);
return (double)info.denom / (double)info.numer / 1e-9;
}
2025-03-09 17:02:12 +01:00
iron_ticks_t iron_timestamp(void) {
iron_ticks_t time = mach_absolute_time();
2025-02-26 18:46:36 +01:00
return time;
}
2025-03-09 17:02:12 +01:00
const char *iron_gamepad_vendor(int gamepad) {
2025-02-26 18:46:36 +01:00
return "nobody";
}
2025-03-09 17:02:12 +01:00
const char *iron_gamepad_product_name(int gamepad) {
2025-02-26 18:46:36 +01:00
return "none";
}
2025-03-09 17:02:12 +01:00
bool iron_gamepad_connected(int num) {
2025-02-26 18:46:36 +01:00
return true;
}
2025-03-09 17:02:12 +01:00
void iron_gamepad_rumble(int gamepad, float left, float right) {}
2025-02-26 18:46:36 +01:00
int main(int argc, char *argv[]) {
int retVal = 0;
@autoreleasepool {
2025-03-09 17:02:12 +01:00
[IronAppDelegate description]; // otherwise removed by the linker
retVal = UIApplicationMain(argc, argv, nil, @"IronAppDelegate");
2025-02-26 18:46:36 +01:00
}
return retVal;
}
static void (*resizeCallback)(int x, int y, void *data) = NULL;
static void *resizeCallbackData = NULL;
2025-03-09 17:02:12 +01:00
int iron_window_x() {
2025-02-26 18:46:36 +01:00
return 0;
}
2025-03-09 17:02:12 +01:00
int iron_window_y() {
2025-02-26 18:46:36 +01:00
return 0;
}
2025-03-09 17:02:12 +01:00
void iron_window_resize(int width, int height) {}
2025-02-26 18:46:36 +01:00
2025-03-09 17:02:12 +01:00
void iron_window_move(int x, int y) {}
2025-02-26 18:46:36 +01:00
2025-03-09 17:02:12 +01:00
void iron_window_change_features(int features) {}
2025-02-26 18:46:36 +01:00
2025-03-09 17:02:12 +01:00
void iron_window_change_mode(iron_window_mode_t mode) {}
2025-02-26 18:46:36 +01:00
2025-03-09 17:02:12 +01:00
void iron_window_destroy() {}
2025-02-26 18:46:36 +01:00
2025-03-09 17:02:12 +01:00
void iron_window_show() {}
2025-02-26 18:46:36 +01:00
2025-03-09 17:02:12 +01:00
void iron_window_hide() {}
2025-02-26 18:46:36 +01:00
2025-03-09 17:02:12 +01:00
void iron_window_set_title(const char *title) {}
2025-02-26 18:46:36 +01:00
2025-03-09 17:02:12 +01:00
void iron_window_create(iron_window_options_t *win) {}
2025-02-26 18:46:36 +01:00
2025-03-09 17:02:12 +01:00
void iron_window_set_resize_callback(void (*callback)(int x, int y, void *data), void *data) {
2025-02-26 18:46:36 +01:00
resizeCallback = callback;
resizeCallbackData = data;
}
2025-03-09 17:02:12 +01:00
void iron_internal_call_resize_callback(int width, int height) {
2025-02-26 18:46:36 +01:00
if (resizeCallback != NULL) {
resizeCallback(width, height, resizeCallbackData);
}
}
2025-03-09 17:02:12 +01:00
void iron_window_set_close_callback(bool (*callback)(void *), void *data) {}
2025-02-26 18:46:36 +01:00
2025-03-09 17:02:12 +01:00
iron_window_mode_t iron_window_get_mode() {
return IRON_WINDOW_MODE_FULLSCREEN;
2025-02-26 18:46:36 +01:00
}
2025-03-09 17:02:12 +01:00
int iron_window_display() {
2025-02-26 18:46:36 +01:00
return 0;
}