From e2cc280c86c000138186109f359e850aafe1eb62 Mon Sep 17 00:00:00 2001 From: Lieven Dekeyser Date: Wed, 13 Mar 2024 23:11:04 +0100 Subject: [PATCH 1/5] Make DEVELOPMENT_TEAM configurable without touching the project file --- Mini vMac.xcodeproj/project.pbxproj | 7 ++++--- Mini vMac/CodeSigning.xcconfig | 11 +++++++++++ 2 files changed, 15 insertions(+), 3 deletions(-) create mode 100644 Mini vMac/CodeSigning.xcconfig diff --git a/Mini vMac.xcodeproj/project.pbxproj b/Mini vMac.xcodeproj/project.pbxproj index b562202..9fcbaa7 100644 --- a/Mini vMac.xcodeproj/project.pbxproj +++ b/Mini vMac.xcodeproj/project.pbxproj @@ -370,6 +370,7 @@ 28F6B4C91CF1FA7A002D76D0 /* about.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = about.plist; sourceTree = ""; }; 28F6B4CE1CF77099002D76D0 /* compat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = compat.m; sourceTree = ""; }; 28F875921D29402B001E99EB /* PlugIn-Capabilities.plist.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "PlugIn-Capabilities.plist.xml"; sourceTree = ""; }; + CA06D3322BA255830019B7B7 /* CodeSigning.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = CodeSigning.xcconfig; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -599,6 +600,7 @@ 28F676BF1CD15E0B00FC6FA6 /* Mini vMac */ = { isa = PBXGroup; children = ( + CA06D3322BA255830019B7B7 /* CodeSigning.xcconfig */, 28F676C31CD15E0B00FC6FA6 /* AppDelegate.h */, 28F676C41CD15E0B00FC6FA6 /* AppDelegate.m */, 28BA89861CE73FBC00A98104 /* MNVMApplication.h */, @@ -949,7 +951,6 @@ }; 28F676BC1CD15E0B00FC6FA6 = { CreatedOnToolsVersion = 7.3; - DevelopmentTeam = UJXNDZ5TNU; }; 28F6B48D1CF07DDD002D76D0 = { CreatedOnToolsVersion = 7.3.1; @@ -1848,12 +1849,12 @@ }; 28F676D51CD15E0B00FC6FA6 /* Debug */ = { isa = XCBuildConfiguration; + baseConfigurationReference = CA06D3322BA255830019B7B7 /* CodeSigning.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CURRENT_PROJECT_VERSION = 14; - DEVELOPMENT_TEAM = UJXNDZ5TNU; HEADER_SEARCH_PATHS = "$(SRCROOT)"; INFOPLIST_FILE = "Mini vMac/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; @@ -1871,12 +1872,12 @@ }; 28F676D61CD15E0B00FC6FA6 /* Release */ = { isa = XCBuildConfiguration; + baseConfigurationReference = CA06D3322BA255830019B7B7 /* CodeSigning.xcconfig */; buildSettings = { ASSETCATALOG_COMPILER_APPICON_NAME = AppIcon; CODE_SIGN_IDENTITY = "iPhone Developer"; "CODE_SIGN_IDENTITY[sdk=iphoneos*]" = "iPhone Developer"; CURRENT_PROJECT_VERSION = 14; - DEVELOPMENT_TEAM = UJXNDZ5TNU; HEADER_SEARCH_PATHS = "$(SRCROOT)"; INFOPLIST_FILE = "Mini vMac/Info.plist"; IPHONEOS_DEPLOYMENT_TARGET = 9.0; diff --git a/Mini vMac/CodeSigning.xcconfig b/Mini vMac/CodeSigning.xcconfig new file mode 100644 index 0000000..590d97c --- /dev/null +++ b/Mini vMac/CodeSigning.xcconfig @@ -0,0 +1,11 @@ +// +// CodeSigning.xcconfig +// Mini vMac +// +// Created by Lieven Dekeyser on 13/03/2024. +// +// Configuration settings file format documentation can be found at: +// https://help.apple.com/xcode/#/dev745c5c974 + +// You can find your Team ID on https://developer.apple.com/account#MembershipDetailsCard +DEVELOPMENT_TEAM=UJXNDZ5TNU From 7060fc5b237b5ee574766a0d5e51ca2dd34297d4 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Jesu=CC=81s=20A=2E=20A=CC=81lvarez?= Date: Fri, 1 Mar 2024 23:31:06 +0100 Subject: [PATCH 2/5] prefer pixel-perfect scaling when filter is set to nearest --- Mini vMac/ScreenView.m | 28 +++++++++++++++++++++------- 1 file changed, 21 insertions(+), 7 deletions(-) diff --git a/Mini vMac/ScreenView.m b/Mini vMac/ScreenView.m index 97eee3c..926f265 100644 --- a/Mini vMac/ScreenView.m +++ b/Mini vMac/ScreenView.m @@ -29,7 +29,7 @@ - (void)awakeFromNib { [self updateVideoLayer]; [self.layer addSublayer:videoLayer]; [[AppDelegate sharedInstance] addObserver:self forKeyPath:@"sharedEmulator" options:NSKeyValueObservingOptionNew context:NULL]; - [[NSUserDefaults standardUserDefaults] addObserver:self forKeyPath:@"screenFilter" options:NSKeyValueObservingOptionNew context:NULL]; + [[NSUserDefaults standardUserDefaults] addObserver:self forKeyPath:@"screenFilter" options:NSKeyValueObservingOptionNew|NSKeyValueObservingOptionOld context:NULL]; } + (instancetype)sharedScreenView { @@ -57,17 +57,25 @@ - (void)updateVideoLayer { - (void)layoutSubviews { [super layoutSubviews]; CGRect viewBounds = self.bounds; - CGFloat screenScale = MAX(screenSize.width / viewBounds.size.width, screenSize.height / viewBounds.size.height); - if (screenScale > 0.9 && screenScale <= 1.0) { + CGFloat screenScale = MIN(viewBounds.size.width / screenSize.width, viewBounds.size.height / screenSize.height); + NSString *screenFilter = [[NSUserDefaults standardUserDefaults] stringForKey:@"screenFilter"]; + if ([screenFilter isEqualToString:kCAFilterNearest] && screenScale > 1.0) { + screenScale = floor(screenScale); + } else if (screenScale > 1.0 && screenScale <= 1.1) { screenScale = 1.0; } - screenBounds = CGRectMake(0, 0, screenSize.width / screenScale, screenSize.height / screenScale); + screenBounds = CGRectMake(0, 0, screenSize.width * screenScale, screenSize.height * screenScale); screenBounds.origin.x = (viewBounds.size.width - screenBounds.size.width)/2; screenBounds = CGRectIntegral(screenBounds); + + if ([UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPad && (viewBounds.size.height - screenBounds.size.height) >= 30.0) { + // move under multitasking indicator on iPad + screenBounds.origin.y += 30; + } videoLayer.frame = screenBounds; - screenBounds.origin.y = self.frame.origin.y; + screenBounds.origin.y += self.frame.origin.y; BOOL scaleIsIntegral = (floor(screenScale) == screenScale); - NSString *screenFilter = scaleIsIntegral ? kCAFilterNearest : [[NSUserDefaults standardUserDefaults] stringForKey:@"screenFilter"]; + if (scaleIsIntegral) screenFilter = kCAFilterNearest; videoLayer.magnificationFilter = screenFilter; videoLayer.minificationFilter = screenFilter; } @@ -75,13 +83,19 @@ - (void)layoutSubviews { - (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { if ([object isEqual:[NSUserDefaults standardUserDefaults]]) { if ([keyPath isEqualToString:@"screenFilter"]) { + NSString *oldValue = change[NSKeyValueChangeOldKey]; NSString *value = change[NSKeyValueChangeNewKey]; videoLayer.magnificationFilter = value; videoLayer.minificationFilter = value; + if ([value isEqualToString:kCAFilterNearest] || [oldValue isEqualToString:kCAFilterNearest]) { + [self setNeedsLayout]; + [self layoutIfNeeded]; + } } } else if (object == [AppDelegate sharedInstance] && [keyPath isEqualToString:@"sharedEmulator"]) { [self updateVideoLayer]; - [self layoutSubviews]; + [self setNeedsLayout]; + [self layoutIfNeeded]; } } From aa64a915faf71f3f1abc9954c6c016060a7c85c6 Mon Sep 17 00:00:00 2001 From: Lieven Dekeyser Date: Fri, 15 Mar 2024 19:30:43 +0100 Subject: [PATCH 3/5] Add HFSDiskImage class for creating disk images and adding files to them --- Mini vMac.xcodeproj/project.pbxproj | 6 + Mini vMac/HFSDiskImage.h | 42 ++++ Mini vMac/HFSDiskImage.m | 328 ++++++++++++++++++++++++++++ 3 files changed, 376 insertions(+) create mode 100644 Mini vMac/HFSDiskImage.h create mode 100644 Mini vMac/HFSDiskImage.m diff --git a/Mini vMac.xcodeproj/project.pbxproj b/Mini vMac.xcodeproj/project.pbxproj index 9fcbaa7..c12835f 100644 --- a/Mini vMac.xcodeproj/project.pbxproj +++ b/Mini vMac.xcodeproj/project.pbxproj @@ -153,6 +153,7 @@ 28F6B4C21CF07F5C002D76D0 /* liblibres.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 28F6B4B61CF07F32002D76D0 /* liblibres.a */; }; 28F6B4CA1CF1FA7A002D76D0 /* about.plist in Resources */ = {isa = PBXBuildFile; fileRef = 28F6B4C91CF1FA7A002D76D0 /* about.plist */; }; 28F6B4CF1CF77099002D76D0 /* compat.m in Sources */ = {isa = PBXBuildFile; fileRef = 28F6B4CE1CF77099002D76D0 /* compat.m */; }; + CA06D3352BA25DC10019B7B7 /* HFSDiskImage.m in Sources */ = {isa = PBXBuildFile; fileRef = CA06D3332BA25DC00019B7B7 /* HFSDiskImage.m */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -371,6 +372,8 @@ 28F6B4CE1CF77099002D76D0 /* compat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = compat.m; sourceTree = ""; }; 28F875921D29402B001E99EB /* PlugIn-Capabilities.plist.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "PlugIn-Capabilities.plist.xml"; sourceTree = ""; }; CA06D3322BA255830019B7B7 /* CodeSigning.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = CodeSigning.xcconfig; sourceTree = ""; }; + CA06D3332BA25DC00019B7B7 /* HFSDiskImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HFSDiskImage.m; sourceTree = ""; }; + CA06D3342BA25DC00019B7B7 /* HFSDiskImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HFSDiskImage.h; sourceTree = ""; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -617,6 +620,8 @@ 28848B611CDE97D600B86C45 /* InsertDiskViewController.m */, 28848B631CDE97E900B86C45 /* SettingsViewController.h */, 28848B641CDE97E900B86C45 /* SettingsViewController.m */, + CA06D3342BA25DC00019B7B7 /* HFSDiskImage.h */, + CA06D3332BA25DC00019B7B7 /* HFSDiskImage.m */, 28F676C91CD15E0B00FC6FA6 /* Main.storyboard */, 28F676CC1CD15E0B00FC6FA6 /* Assets.xcassets */, 28BA896E1CE7314500A98104 /* Keyboard */, @@ -1301,6 +1306,7 @@ 28D5A3FD1CD6868F001A33F6 /* TouchScreen.m in Sources */, 28F676C51CD15E0B00FC6FA6 /* AppDelegate.m in Sources */, 28BA89801CE7315400A98104 /* KBKeyboardView.m in Sources */, + CA06D3352BA25DC10019B7B7 /* HFSDiskImage.m in Sources */, 28F676C21CD15E0B00FC6FA6 /* main.m in Sources */, ); runOnlyForDeploymentPostprocessing = 0; diff --git a/Mini vMac/HFSDiskImage.h b/Mini vMac/HFSDiskImage.h new file mode 100644 index 0000000..9f3ec72 --- /dev/null +++ b/Mini vMac/HFSDiskImage.h @@ -0,0 +1,42 @@ +// +// HFSDiskImage.h +// Mini vMac +// +// Created by Lieven Dekeyser on 13/03/2024. +// + +#import + +NS_ASSUME_NONNULL_BEGIN + +@interface HFSDiskImage : NSObject + +@property (nonatomic, readonly, copy) NSString * path; +@property (nonatomic, readonly, getter=isOpen) BOOL open; +@property (nonatomic, readonly, getter=isReadOnly) BOOL readOnly; + ++ (nullable HFSDiskImage *)createDiskImageWithName:(NSString *)name size:(size_t)volumeSize atPath:(NSString *)path; + +- (nullable instancetype)initWithPath:(NSString *)path; + +- (instancetype)init __unavailable; ++ (instancetype)new __unavailable; + +- (BOOL)openForReading; +- (BOOL)openForReadingAndWriting; + +- (BOOL)close; + +- (BOOL)addFile:(NSString *)sourceFile; + +@end // HFSDiskImage + + +@interface HFSDiskImage (Import) + ++ (nullable HFSDiskImage *)importFileIntoTemporaryDiskImage:(NSString *)sourceFile; + +@end // HFSDiskImage (Import) + + +NS_ASSUME_NONNULL_END diff --git a/Mini vMac/HFSDiskImage.m b/Mini vMac/HFSDiskImage.m new file mode 100644 index 0000000..2cd6df5 --- /dev/null +++ b/Mini vMac/HFSDiskImage.m @@ -0,0 +1,328 @@ +// +// HFSDiskImage.m +// Mini vMac +// +// Created by Lieven Dekeyser on 13/03/2024. +// + +#import "HFSDiskImage.h" +#include "libhfs.h" + +@interface NSString (HFSSafe) +- (nullable NSString *)hfsSafeFileName; +- (nullable NSString *)hfsSafeVolumeName; +@end // NSString (HFSSafe) + + +@interface HFSDiskImage () +@property (nonatomic, copy) NSString * path; +@end // HFSDiskImage() + +@implementation HFSDiskImage +{ + hfsvol * _volume; +} + ++ (nullable HFSDiskImage *)createDiskImageWithName:(NSString *)name size:(size_t)volumeSize atPath:(NSString *)path +{ + NSFileManager * fm = [NSFileManager defaultManager]; + if ([fm fileExistsAtPath:path]) + { + return nil; + } + + + int fileDescriptor = open(path.fileSystemRepresentation, O_CREAT | O_TRUNC | O_EXCL | O_WRONLY, 0644); + if (fileDescriptor == -1) + { + return nil; + } + + int error = 0; + if (ftruncate(fileDescriptor, volumeSize)) + { + error = errno; + } + else + { + const char * volumeName = [name cStringUsingEncoding:NSMacOSRomanStringEncoding]; + if (volumeName != nil) + { + error = hfs_format(path.fileSystemRepresentation, 0, 0, volumeName, 0, NULL); + } + else + { + error = EINVAL; + } + } + + close(fileDescriptor); + + if (error != 0) + { + [fm removeItemAtPath:path error:nil]; + return nil; + } + + return [[self alloc] initWithPath:path]; +} + +- (nullable instancetype)initWithPath:(NSString *)path +{ + if ((self = [super init])) + { + _readOnly = NO; + _volume = nil; + self.path = path; + } + return self; +} + +- (void)dealloc +{ + [self close]; +} + +- (BOOL)isOpen +{ + return _volume != NULL; +} + +- (BOOL)openForReading +{ + return [self _openWithMode:HFS_MODE_RDONLY]; +} + +- (BOOL)openForReadingAndWriting +{ + return [self _openWithMode:HFS_MODE_RDWR]; +} + +- (BOOL)_openWithMode:(int)mode +{ + if ([self isOpen]) + { + return YES; + } + + _volume = hfs_mount(self.path.fileSystemRepresentation, 0, mode); + _readOnly = (mode != HFS_MODE_RDWR); + + return [self isOpen]; +} + +- (BOOL)close +{ + if (_volume) + { + int error = hfs_umount(_volume); + if (error == 0) { + _volume = NULL; + } + } + + return ![self isOpen]; +} + +- (BOOL)addFile:(NSString *)sourceFilePath +{ + if (![self isOpen] || [self isReadOnly]) + { + return NO; + } + + NSString * fileName = [[sourceFilePath lastPathComponent] hfsSafeFileName]; + if (fileName == nil) + { + return NO; + } + + const char * targetPath = [[NSString stringWithFormat:@":%@", fileName] cStringUsingEncoding:NSMacOSRomanStringEncoding]; + if (targetPath == NULL) + { + return NO; + } + + + FILE * sourceFile = fopen(sourceFilePath.fileSystemRepresentation, "r"); + if (sourceFile == NULL) + { + return NO; + } + + BOOL error = NO; + hfsfile * file = hfs_create(_volume, targetPath, "SIT!", "SITx"); // FIXME: type and creator from extension + if (file) + { + const size_t bufferSize = HFS_BLOCKSZ; + uint8_t buffer[bufferSize] = { 0 }; + + size_t bytesRead = 0; + while ((bytesRead = fread(buffer, 1, bufferSize, sourceFile)) > 0) + { + unsigned long bytesWritten = hfs_write(file, buffer, bytesRead); + if (bytesWritten < bytesRead) + { + error = YES; + break; + } + } + + hfs_close(file); + file = NULL; + } + else + { + error = YES; + } + + fclose(sourceFile); + sourceFile = NULL; + + return error == NO; +} + +@end // HFSDiskImage + + +@implementation HFSDiskImage (Import) + ++ (HFSDiskImage *)importFileIntoTemporaryDiskImage:(NSString *)sourceFile +{ + NSFileManager * fm = [NSFileManager defaultManager]; + NSError * error = nil; + size_t fileSize = [fm attributesOfItemAtPath:sourceFile error:&error].fileSize; + if (fileSize == 0) + { + return nil; + } + + + NSString * tempFolder = NSTemporaryDirectory(); + + NSString * volumeName = [[[sourceFile lastPathComponent] stringByDeletingPathExtension] hfsSafeVolumeName]; + if (volumeName == nil) + { + return nil; + } + NSString * diskImagePath = [tempFolder stringByAppendingPathComponent:[NSString stringWithFormat:@"%@.img", volumeName]]; + int tries = 1; + while ([fm fileExistsAtPath:diskImagePath]) + { + ++tries; + diskImagePath = [tempFolder stringByAppendingPathComponent:[NSString stringWithFormat:@"%@ %d.img", volumeName, tries]]; + } + + + HFSDiskImage * diskImage = [HFSDiskImage createDiskImageWithName:volumeName size:(fileSize + (512*1024)) atPath:diskImagePath]; + if (diskImage == NULL || ![diskImage openForReadingAndWriting]) + { + return nil; + } + + BOOL result = [diskImage addFile:sourceFile]; + + [diskImage close]; + + if (result) + { + return diskImage; + } + else + { + return nil; + } + +} + +@end // HFSDiskImage (Import) + + + +@implementation NSString (HFSSafe) + +- (NSString *)macOSRomanSafeStringGettingLength:(NSUInteger *)outLength +{ + NSData * converted = [self dataUsingEncoding:NSMacOSRomanStringEncoding allowLossyConversion:YES]; + if (converted) + { + if (outLength) + { + *outLength = [converted length]; + } + return [[NSString alloc] initWithData:converted encoding:NSMacOSRomanStringEncoding]; + } + else + { + return nil; + } +} + +- (NSString *)macOSRomanSafeStringWithMaxLength:(NSUInteger)maxLength +{ + NSData * converted = [self dataUsingEncoding:NSMacOSRomanStringEncoding allowLossyConversion:YES]; + if (converted) + { + NSUInteger convertedLength = [converted length]; + if (convertedLength > maxLength) + { + converted = [converted subdataWithRange:NSMakeRange(0, maxLength)]; + } + + return [[NSString alloc] initWithData:converted encoding:NSMacOSRomanStringEncoding]; + } + else + { + return nil; + } +} + +- (NSString *)hfsSafeFileName +{ + NSString * noColons = [self stringByReplacingOccurrencesOfString:@":" withString:@"_"]; + NSUInteger convertedStringLength = 0; + NSString * convertedString = [noColons macOSRomanSafeStringGettingLength:&convertedStringLength]; + if (convertedString) + { + if (convertedStringLength <= HFS_MAX_FLEN) + { + return convertedString; + } + else + { + // keep path extension if possible: + NSUInteger pathExtensionLength = 0; + NSString * pathExtension = [[self pathExtension] macOSRomanSafeStringGettingLength:&pathExtensionLength]; + if (pathExtension) + { + NSInteger remainingLength = HFS_MAX_FLEN - pathExtensionLength - 1; + if (remainingLength > 2) + { + NSString * trimmedName = [[self stringByDeletingPathExtension] macOSRomanSafeStringWithMaxLength:remainingLength]; + return [trimmedName stringByAppendingPathExtension:pathExtension]; + + } + else + { + return [[self stringByDeletingPathExtension] macOSRomanSafeStringWithMaxLength:HFS_MAX_FLEN]; + } + } + else + { + return [self macOSRomanSafeStringWithMaxLength:HFS_MAX_FLEN]; + } + } + } + else + { + return nil; + } +} + +- (NSString *)hfsSafeVolumeName +{ + NSString * noColons = [self stringByReplacingOccurrencesOfString:@":" withString:@"_"]; + return [noColons macOSRomanSafeStringWithMaxLength:HFS_MAX_VLEN]; +} + +@end // NSString (HFSSafe) From 39ac903fa325e1563a9df4595d8b627f9bc4fbfc Mon Sep 17 00:00:00 2001 From: Lieven Dekeyser Date: Fri, 15 Mar 2024 19:41:46 +0100 Subject: [PATCH 4/5] Display a browser view when swiping down with 2 fingers + wrap downloaded files into an HFS disk image to allow opening them in the emulator --- Mini vMac/AppDelegate.h | 2 ++ Mini vMac/AppDelegate.m | 51 ++++++++++++++++++++++++++++++++++++-- Mini vMac/ViewController.m | 6 ++++- 3 files changed, 56 insertions(+), 3 deletions(-) diff --git a/Mini vMac/AppDelegate.h b/Mini vMac/AppDelegate.h index 1884bf0..34e12db 100644 --- a/Mini vMac/AppDelegate.h +++ b/Mini vMac/AppDelegate.h @@ -32,5 +32,7 @@ extern NSString *DocumentsChangedNotification; - (IBAction)showSettings:(id)sender; - (IBAction)showGestureHelp:(id)sender; +- (void)showBrowser; + @end diff --git a/Mini vMac/AppDelegate.m b/Mini vMac/AppDelegate.m index c2ac758..e2e1f64 100644 --- a/Mini vMac/AppDelegate.m +++ b/Mini vMac/AppDelegate.m @@ -7,16 +7,18 @@ // @import AVFoundation; +@import SafariServices; #import "AppDelegate.h" #import "SettingsViewController.h" #import "InsertDiskViewController.h" +#import "HFSDiskImage.h" static AppDelegate *sharedAppDelegate = nil; static NSObject *sharedEmulator = nil; NSString *DocumentsChangedNotification = @"documentsChanged"; -@interface AppDelegate () - +@interface AppDelegate () +@property (nonatomic, strong) SFSafariViewController * browser; @end @implementation AppDelegate @@ -281,7 +283,23 @@ - (BOOL)importFileToDocuments:(NSURL *)url copy:(BOOL)copy { } - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary *)options { + [self.window.rootViewController dismissViewControllerAnimated:NO completion:nil]; + if (url.fileURL) { + + // FIXME: detect file type of imported file + // if archive first unarchive + // - if the resulting file(s) contain ROM files, copy to Documents + // - if the resulting file(s) contain disk images, copy those to Documents + // - if the resulting file(s) contain other files, embed them in an HFS Disk Image and copy that to Documents + + // FIXME: this is temporary code to test importing files into disk images + HFSDiskImage * tempDiskImage = [HFSDiskImage importFileIntoTemporaryDiskImage:url.path]; + if (tempDiskImage) { + [sharedEmulator insertDisk:tempDiskImage.path]; + return YES; + } + // opening file NSString *inboxPath = [self.documentsPath stringByAppendingPathComponent:@"Inbox"]; if ([url.path.stringByStandardizingPath hasPrefix:inboxPath]) { @@ -304,4 +322,33 @@ - (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDiction return YES; } +- (void)showBrowser { + NSURL * url = [NSURL URLWithString:@"https://macintoshgarden.org"]; + if (url == nil) { + return; + } + + if (self.window.rootViewController.presentedViewController) { + __weak typeof(self) weakSelf = self; + [self.window.rootViewController dismissViewControllerAnimated:NO completion:^{ + [weakSelf showBrowser]; + }]; + return; + } + + SFSafariViewController * vc = self.browser; + if (vc == nil) { + vc = [[SFSafariViewController alloc] initWithURL:url]; + vc.modalPresentationStyle = UIModalPresentationPageSheet; + vc.delegate = self; + self.browser = vc; + } + + [self.window.rootViewController presentViewController:vc animated:YES completion:nil]; +} + +- (void)safariViewControllerDidFinish:(SFSafariViewController *)controller { + [self.window.rootViewController dismissViewControllerAnimated:YES completion:nil]; +} + @end diff --git a/Mini vMac/ViewController.m b/Mini vMac/ViewController.m index f4a1384..1dabc63 100644 --- a/Mini vMac/ViewController.m +++ b/Mini vMac/ViewController.m @@ -281,7 +281,11 @@ - (void)showKeyboard:(id)sender { } - (void)hideKeyboard:(id)sender { - [self setKeyboardVisible:NO animated:YES]; + if (self.keyboardVisible) { + [self setKeyboardVisible:NO animated:YES]; + } else { + [[AppDelegate sharedInstance] showBrowser]; + } } - (void)setKeyboardVisible:(BOOL)visible animated:(BOOL)animated { From e648636f68361ffeeae506d8d756d5f604a32155 Mon Sep 17 00:00:00 2001 From: Lieven Dekeyser Date: Fri, 15 Mar 2024 20:55:52 +0100 Subject: [PATCH 5/5] Add XADMaster --- .gitmodules | 8 + Mini vMac.xcodeproj/project.pbxproj | 293 ++++++++++++++++++++++++++++ UniversalDetector | 1 + XADMaster | 1 + 4 files changed, 303 insertions(+) create mode 160000 UniversalDetector create mode 160000 XADMaster diff --git a/.gitmodules b/.gitmodules index 708beb9..c835c6c 100644 --- a/.gitmodules +++ b/.gitmodules @@ -8,3 +8,11 @@ path = minivmac url = https://github.com/zydeco/minivmac.git branch = wintergames +[submodule "UniversalDetector"] + path = UniversalDetector + url = https://github.com/MacPaw/universal-detector.git + branch = master +[submodule "XADMaster"] + path = XADMaster + url = https://github.com/MacPaw/XADMaster.git + branch = master diff --git a/Mini vMac.xcodeproj/project.pbxproj b/Mini vMac.xcodeproj/project.pbxproj index c12835f..3de0df3 100644 --- a/Mini vMac.xcodeproj/project.pbxproj +++ b/Mini vMac.xcodeproj/project.pbxproj @@ -154,6 +154,11 @@ 28F6B4CA1CF1FA7A002D76D0 /* about.plist in Resources */ = {isa = PBXBuildFile; fileRef = 28F6B4C91CF1FA7A002D76D0 /* about.plist */; }; 28F6B4CF1CF77099002D76D0 /* compat.m in Sources */ = {isa = PBXBuildFile; fileRef = 28F6B4CE1CF77099002D76D0 /* compat.m */; }; CA06D3352BA25DC10019B7B7 /* HFSDiskImage.m in Sources */ = {isa = PBXBuildFile; fileRef = CA06D3332BA25DC00019B7B7 /* HFSDiskImage.m */; }; + CA7CFC9C2BA88DA800AAEC3B /* libUniversalDetector.ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CAF1284E2BA4DE2F00E39C26 /* libUniversalDetector.ios.a */; }; + CA7CFC9D2BA88DA800AAEC3B /* libXADMaster.ios.a in Frameworks */ = {isa = PBXBuildFile; fileRef = CAF1282E2BA4DB9300E39C26 /* libXADMaster.ios.a */; }; + CA7CFC9F2BA88E6B00AAEC3B /* libbz2.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = CA7CFC9E2BA88E6B00AAEC3B /* libbz2.tbd */; }; + CA7CFCA12BA88E7B00AAEC3B /* libc++.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = CA7CFCA02BA88E7B00AAEC3B /* libc++.tbd */; }; + CA7CFCA32BA88E8800AAEC3B /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = CA7CFCA22BA88E8800AAEC3B /* libz.tbd */; }; /* End PBXBuildFile section */ /* Begin PBXContainerItemProxy section */ @@ -192,6 +197,118 @@ remoteGlobalIDString = 28C67BD02AC49E46000C7540; remoteInfo = "MacII-512x384"; }; + CAF128272BA4DB9300E39C26 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CAF128192BA4DB9300E39C26 /* XADMaster.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 8DC2EF5B0486A6940098B216; + remoteInfo = XADMaster; + }; + CAF128292BA4DB9300E39C26 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CAF128192BA4DB9300E39C26 /* XADMaster.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 1B34A97511C2FD0500396C26; + remoteInfo = libXADMaster.a; + }; + CAF1282B2BA4DB9300E39C26 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CAF128192BA4DB9300E39C26 /* XADMaster.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 1B91CD5E11D97E7C0081E40A; + remoteInfo = libXADMaster.win.a; + }; + CAF1282D2BA4DB9300E39C26 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CAF128192BA4DB9300E39C26 /* XADMaster.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 1B467B0115CD9A73001AB1DD; + remoteInfo = libXADMaster.ios.a; + }; + CAF1282F2BA4DB9300E39C26 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CAF128192BA4DB9300E39C26 /* XADMaster.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 1B23DDC01185EBA300620319; + remoteInfo = unar; + }; + CAF128312BA4DB9300E39C26 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CAF128192BA4DB9300E39C26 /* XADMaster.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 1B91D18F11E1677B0081E40A; + remoteInfo = lsar; + }; + CAF128332BA4DB9300E39C26 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CAF128192BA4DB9300E39C26 /* XADMaster.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 1B91CDAC11D981E20081E40A; + remoteInfo = unar.exe; + }; + CAF128352BA4DB9300E39C26 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CAF128192BA4DB9300E39C26 /* XADMaster.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 1B91D2EE11E694860081E40A; + remoteInfo = lsar.exe; + }; + CAF128372BA4DB9300E39C26 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CAF128192BA4DB9300E39C26 /* XADMaster.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 73DA3465206B6BF1006ADB42; + remoteInfo = XADMasterTests; + }; + CAF128472BA4DE2F00E39C26 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CAF1283F2BA4DE2F00E39C26 /* UniversalDetector.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 8DC2EF5B0486A6940098B216; + remoteInfo = UniversalDetector; + }; + CAF128492BA4DE2F00E39C26 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CAF1283F2BA4DE2F00E39C26 /* UniversalDetector.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 1B23E0871190F29400620319; + remoteInfo = libUniversalDetector.a; + }; + CAF1284B2BA4DE2F00E39C26 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CAF1283F2BA4DE2F00E39C26 /* UniversalDetector.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 1B91CBE011D821A70081E40A; + remoteInfo = libUniversalDetector.win.a; + }; + CAF1284D2BA4DE2F00E39C26 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CAF1283F2BA4DE2F00E39C26 /* UniversalDetector.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 1B467B2615CD9B1F001AB1DD; + remoteInfo = libUniversalDetector.ios.a; + }; + CAF1284F2BA4DE2F00E39C26 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CAF1283F2BA4DE2F00E39C26 /* UniversalDetector.xcodeproj */; + proxyType = 2; + remoteGlobalIDString = 1B0DDCAB0A2D0AD10009B697; + remoteInfo = DetectorTest; + }; + CAF128552BA4DEE800E39C26 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CAF128192BA4DB9300E39C26 /* XADMaster.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 1B34A97411C2FD0500396C26; + remoteInfo = libXADMaster.a; + }; + CAF128572BA4DF0600E39C26 /* PBXContainerItemProxy */ = { + isa = PBXContainerItemProxy; + containerPortal = CAF1283F2BA4DE2F00E39C26 /* UniversalDetector.xcodeproj */; + proxyType = 1; + remoteGlobalIDString = 1B23E0861190F29400620319; + remoteInfo = libUniversalDetector.a; + }; /* End PBXContainerItemProxy section */ /* Begin PBXCopyFilesBuildPhase section */ @@ -374,6 +491,11 @@ CA06D3322BA255830019B7B7 /* CodeSigning.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = CodeSigning.xcconfig; sourceTree = ""; }; CA06D3332BA25DC00019B7B7 /* HFSDiskImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HFSDiskImage.m; sourceTree = ""; }; CA06D3342BA25DC00019B7B7 /* HFSDiskImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HFSDiskImage.h; sourceTree = ""; }; + CA7CFC9E2BA88E6B00AAEC3B /* libbz2.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libbz2.tbd; path = usr/lib/libbz2.tbd; sourceTree = SDKROOT; }; + CA7CFCA02BA88E7B00AAEC3B /* libc++.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = "libc++.tbd"; path = "usr/lib/libc++.tbd"; sourceTree = SDKROOT; }; + CA7CFCA22BA88E8800AAEC3B /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; }; + CAF128192BA4DB9300E39C26 /* XADMaster.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = XADMaster.xcodeproj; path = XADMaster/XADMaster.xcodeproj; sourceTree = SOURCE_ROOT; }; + CAF1283F2BA4DE2F00E39C26 /* UniversalDetector.xcodeproj */ = {isa = PBXFileReference; lastKnownFileType = "wrapper.pb-project"; name = UniversalDetector.xcodeproj; path = UniversalDetector/UniversalDetector.xcodeproj; sourceTree = SOURCE_ROOT; }; /* End PBXFileReference section */ /* Begin PBXFrameworksBuildPhase section */ @@ -416,6 +538,11 @@ isa = PBXFrameworksBuildPhase; buildActionMask = 2147483647; files = ( + CA7CFCA32BA88E8800AAEC3B /* libz.tbd in Frameworks */, + CA7CFCA12BA88E7B00AAEC3B /* libc++.tbd in Frameworks */, + CA7CFC9F2BA88E6B00AAEC3B /* libbz2.tbd in Frameworks */, + CA7CFC9C2BA88DA800AAEC3B /* libUniversalDetector.ios.a in Frameworks */, + CA7CFC9D2BA88DA800AAEC3B /* libXADMaster.ios.a in Frameworks */, 28F6B4C01CF07F5C002D76D0 /* liblibhfs.a in Frameworks */, 28F6B4C11CF07F5C002D76D0 /* liblibmfs.a in Frameworks */, 28F6B4C21CF07F5C002D76D0 /* liblibres.a in Frameworks */, @@ -581,6 +708,7 @@ children = ( 28F676BF1CD15E0B00FC6FA6 /* Mini vMac */, 28F676BE1CD15E0B00FC6FA6 /* Products */, + CAF1283B2BA4DBB400E39C26 /* Frameworks */, ); sourceTree = ""; }; @@ -644,6 +772,8 @@ 28F6B4551CF07C9A002D76D0 /* libhfs */, 28F6B4541CF07C8D002D76D0 /* libmfs */, 28F6B4531CF07C83002D76D0 /* libres */, + CAF1283F2BA4DE2F00E39C26 /* UniversalDetector.xcodeproj */, + CAF128192BA4DB9300E39C26 /* XADMaster.xcodeproj */, 28F676C11CD15E0B00FC6FA6 /* main.m */, ); name = "Supporting Files"; @@ -717,6 +847,44 @@ path = os; sourceTree = ""; }; + CAF1281A2BA4DB9300E39C26 /* Products */ = { + isa = PBXGroup; + children = ( + CAF128282BA4DB9300E39C26 /* XADMaster.framework */, + CAF1282A2BA4DB9300E39C26 /* libXADMaster.a */, + CAF1282C2BA4DB9300E39C26 /* libXADMaster.win.a */, + CAF1282E2BA4DB9300E39C26 /* libXADMaster.ios.a */, + CAF128302BA4DB9300E39C26 /* unar */, + CAF128322BA4DB9300E39C26 /* lsar */, + CAF128342BA4DB9300E39C26 /* unar.exe */, + CAF128362BA4DB9300E39C26 /* lsar.exe */, + CAF128382BA4DB9300E39C26 /* XADMasterTests.xctest */, + ); + name = Products; + sourceTree = ""; + }; + CAF1283B2BA4DBB400E39C26 /* Frameworks */ = { + isa = PBXGroup; + children = ( + CA7CFCA22BA88E8800AAEC3B /* libz.tbd */, + CA7CFCA02BA88E7B00AAEC3B /* libc++.tbd */, + CA7CFC9E2BA88E6B00AAEC3B /* libbz2.tbd */, + ); + name = Frameworks; + sourceTree = ""; + }; + CAF128402BA4DE2F00E39C26 /* Products */ = { + isa = PBXGroup; + children = ( + CAF128482BA4DE2F00E39C26 /* UniversalDetector.framework */, + CAF1284A2BA4DE2F00E39C26 /* libUniversalDetector.a */, + CAF1284C2BA4DE2F00E39C26 /* libUniversalDetector.win.a */, + CAF1284E2BA4DE2F00E39C26 /* libUniversalDetector.ios.a */, + CAF128502BA4DE2F00E39C26 /* DetectorTest */, + ); + name = Products; + sourceTree = ""; + }; /* End PBXGroup section */ /* Begin PBXHeadersBuildPhase section */ @@ -870,6 +1038,8 @@ buildRules = ( ); dependencies = ( + CAF128582BA4DF0600E39C26 /* PBXTargetDependency */, + CAF128562BA4DEE800E39C26 /* PBXTargetDependency */, 28C67BF52AC49F8D000C7540 /* PBXTargetDependency */, 2872E19E2AC48D770014F276 /* PBXTargetDependency */, 289710E11CFB126D0089D463 /* PBXTargetDependency */, @@ -979,6 +1149,16 @@ mainGroup = 28F676B41CD15E0B00FC6FA6; productRefGroup = 28F676BE1CD15E0B00FC6FA6 /* Products */; projectDirPath = ""; + projectReferences = ( + { + ProductGroup = CAF128402BA4DE2F00E39C26 /* Products */; + ProjectRef = CAF1283F2BA4DE2F00E39C26 /* UniversalDetector.xcodeproj */; + }, + { + ProductGroup = CAF1281A2BA4DB9300E39C26 /* Products */; + ProjectRef = CAF128192BA4DB9300E39C26 /* XADMaster.xcodeproj */; + }, + ); projectRoot = ""; targets = ( 28F676BC1CD15E0B00FC6FA6 /* Mini vMac */, @@ -994,6 +1174,107 @@ }; /* End PBXProject section */ +/* Begin PBXReferenceProxy section */ + CAF128282BA4DB9300E39C26 /* XADMaster.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = XADMaster.framework; + remoteRef = CAF128272BA4DB9300E39C26 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + CAF1282A2BA4DB9300E39C26 /* libXADMaster.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libXADMaster.a; + remoteRef = CAF128292BA4DB9300E39C26 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + CAF1282C2BA4DB9300E39C26 /* libXADMaster.win.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libXADMaster.win.a; + remoteRef = CAF1282B2BA4DB9300E39C26 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + CAF1282E2BA4DB9300E39C26 /* libXADMaster.ios.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libXADMaster.ios.a; + remoteRef = CAF1282D2BA4DB9300E39C26 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + CAF128302BA4DB9300E39C26 /* unar */ = { + isa = PBXReferenceProxy; + fileType = "compiled.mach-o.executable"; + path = unar; + remoteRef = CAF1282F2BA4DB9300E39C26 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + CAF128322BA4DB9300E39C26 /* lsar */ = { + isa = PBXReferenceProxy; + fileType = "compiled.mach-o.executable"; + path = lsar; + remoteRef = CAF128312BA4DB9300E39C26 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + CAF128342BA4DB9300E39C26 /* unar.exe */ = { + isa = PBXReferenceProxy; + fileType = "compiled.mach-o.executable"; + path = unar.exe; + remoteRef = CAF128332BA4DB9300E39C26 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + CAF128362BA4DB9300E39C26 /* lsar.exe */ = { + isa = PBXReferenceProxy; + fileType = "compiled.mach-o.executable"; + path = lsar.exe; + remoteRef = CAF128352BA4DB9300E39C26 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + CAF128382BA4DB9300E39C26 /* XADMasterTests.xctest */ = { + isa = PBXReferenceProxy; + fileType = wrapper.cfbundle; + path = XADMasterTests.xctest; + remoteRef = CAF128372BA4DB9300E39C26 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + CAF128482BA4DE2F00E39C26 /* UniversalDetector.framework */ = { + isa = PBXReferenceProxy; + fileType = wrapper.framework; + path = UniversalDetector.framework; + remoteRef = CAF128472BA4DE2F00E39C26 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + CAF1284A2BA4DE2F00E39C26 /* libUniversalDetector.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libUniversalDetector.a; + remoteRef = CAF128492BA4DE2F00E39C26 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + CAF1284C2BA4DE2F00E39C26 /* libUniversalDetector.win.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libUniversalDetector.win.a; + remoteRef = CAF1284B2BA4DE2F00E39C26 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + CAF1284E2BA4DE2F00E39C26 /* libUniversalDetector.ios.a */ = { + isa = PBXReferenceProxy; + fileType = archive.ar; + path = libUniversalDetector.ios.a; + remoteRef = CAF1284D2BA4DE2F00E39C26 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; + CAF128502BA4DE2F00E39C26 /* DetectorTest */ = { + isa = PBXReferenceProxy; + fileType = "compiled.mach-o.executable"; + path = DetectorTest; + remoteRef = CAF1284F2BA4DE2F00E39C26 /* PBXContainerItemProxy */; + sourceTree = BUILT_PRODUCTS_DIR; + }; +/* End PBXReferenceProxy section */ + /* Begin PBXResourcesBuildPhase section */ 283422C81CF8EF8C0088B634 /* Resources */ = { isa = PBXResourcesBuildPhase; @@ -1375,6 +1656,16 @@ target = 28C67BD02AC49E46000C7540 /* MacII-512x384 */; targetProxy = 28C67BF42AC49F8D000C7540 /* PBXContainerItemProxy */; }; + CAF128562BA4DEE800E39C26 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = libXADMaster.a; + targetProxy = CAF128552BA4DEE800E39C26 /* PBXContainerItemProxy */; + }; + CAF128582BA4DF0600E39C26 /* PBXTargetDependency */ = { + isa = PBXTargetDependency; + name = libUniversalDetector.a; + targetProxy = CAF128572BA4DF0600E39C26 /* PBXContainerItemProxy */; + }; /* End PBXTargetDependency section */ /* Begin PBXVariantGroup section */ @@ -1870,6 +2161,7 @@ ); MARKETING_VERSION = 2.5; OTHER_CFLAGS = "-DUSE_LIBRES"; + OTHER_LDFLAGS = "-all_load"; PRODUCT_BUNDLE_IDENTIFIER = net.namedfork.minivmac; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; @@ -1893,6 +2185,7 @@ ); MARKETING_VERSION = 2.5; OTHER_CFLAGS = "-DUSE_LIBRES"; + OTHER_LDFLAGS = "-all_load"; PRODUCT_BUNDLE_IDENTIFIER = net.namedfork.minivmac; PRODUCT_NAME = "$(TARGET_NAME)"; PROVISIONING_PROFILE = ""; diff --git a/UniversalDetector b/UniversalDetector new file mode 160000 index 0000000..ac12fd8 --- /dev/null +++ b/UniversalDetector @@ -0,0 +1 @@ +Subproject commit ac12fd86fc8ad3787ce8d0d1c837adf1283968c9 diff --git a/XADMaster b/XADMaster new file mode 160000 index 0000000..9820dc1 --- /dev/null +++ b/XADMaster @@ -0,0 +1 @@ +Subproject commit 9820dc15efa5d4353d8a5b43c167cee7bffae17c