This commit is contained in:
Lieven Dekeyser 2024-03-20 12:41:25 +01:00 committed by GitHub
commit 97669539b2
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
11 changed files with 771 additions and 13 deletions

8
.gitmodules vendored
View File

@ -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

View File

@ -153,6 +153,12 @@
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 */; };
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 */
@ -191,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 */
@ -370,6 +488,14 @@
28F6B4C91CF1FA7A002D76D0 /* about.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; path = about.plist; sourceTree = "<group>"; };
28F6B4CE1CF77099002D76D0 /* compat.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = compat.m; sourceTree = "<group>"; };
28F875921D29402B001E99EB /* PlugIn-Capabilities.plist.xml */ = {isa = PBXFileReference; lastKnownFileType = text.xml; path = "PlugIn-Capabilities.plist.xml"; sourceTree = "<group>"; };
CA06D3322BA255830019B7B7 /* CodeSigning.xcconfig */ = {isa = PBXFileReference; lastKnownFileType = text.xcconfig; path = CodeSigning.xcconfig; sourceTree = "<group>"; };
CA06D3332BA25DC00019B7B7 /* HFSDiskImage.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = HFSDiskImage.m; sourceTree = "<group>"; };
CA06D3342BA25DC00019B7B7 /* HFSDiskImage.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = HFSDiskImage.h; sourceTree = "<group>"; };
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 */
@ -412,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 */,
@ -577,6 +708,7 @@
children = (
28F676BF1CD15E0B00FC6FA6 /* Mini vMac */,
28F676BE1CD15E0B00FC6FA6 /* Products */,
CAF1283B2BA4DBB400E39C26 /* Frameworks */,
);
sourceTree = "<group>";
};
@ -599,6 +731,7 @@
28F676BF1CD15E0B00FC6FA6 /* Mini vMac */ = {
isa = PBXGroup;
children = (
CA06D3322BA255830019B7B7 /* CodeSigning.xcconfig */,
28F676C31CD15E0B00FC6FA6 /* AppDelegate.h */,
28F676C41CD15E0B00FC6FA6 /* AppDelegate.m */,
28BA89861CE73FBC00A98104 /* MNVMApplication.h */,
@ -615,6 +748,8 @@
28848B611CDE97D600B86C45 /* InsertDiskViewController.m */,
28848B631CDE97E900B86C45 /* SettingsViewController.h */,
28848B641CDE97E900B86C45 /* SettingsViewController.m */,
CA06D3342BA25DC00019B7B7 /* HFSDiskImage.h */,
CA06D3332BA25DC00019B7B7 /* HFSDiskImage.m */,
28F676C91CD15E0B00FC6FA6 /* Main.storyboard */,
28F676CC1CD15E0B00FC6FA6 /* Assets.xcassets */,
28BA896E1CE7314500A98104 /* Keyboard */,
@ -637,6 +772,8 @@
28F6B4551CF07C9A002D76D0 /* libhfs */,
28F6B4541CF07C8D002D76D0 /* libmfs */,
28F6B4531CF07C83002D76D0 /* libres */,
CAF1283F2BA4DE2F00E39C26 /* UniversalDetector.xcodeproj */,
CAF128192BA4DB9300E39C26 /* XADMaster.xcodeproj */,
28F676C11CD15E0B00FC6FA6 /* main.m */,
);
name = "Supporting Files";
@ -710,6 +847,44 @@
path = os;
sourceTree = "<group>";
};
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 = "<group>";
};
CAF1283B2BA4DBB400E39C26 /* Frameworks */ = {
isa = PBXGroup;
children = (
CA7CFCA22BA88E8800AAEC3B /* libz.tbd */,
CA7CFCA02BA88E7B00AAEC3B /* libc++.tbd */,
CA7CFC9E2BA88E6B00AAEC3B /* libbz2.tbd */,
);
name = Frameworks;
sourceTree = "<group>";
};
CAF128402BA4DE2F00E39C26 /* Products */ = {
isa = PBXGroup;
children = (
CAF128482BA4DE2F00E39C26 /* UniversalDetector.framework */,
CAF1284A2BA4DE2F00E39C26 /* libUniversalDetector.a */,
CAF1284C2BA4DE2F00E39C26 /* libUniversalDetector.win.a */,
CAF1284E2BA4DE2F00E39C26 /* libUniversalDetector.ios.a */,
CAF128502BA4DE2F00E39C26 /* DetectorTest */,
);
name = Products;
sourceTree = "<group>";
};
/* End PBXGroup section */
/* Begin PBXHeadersBuildPhase section */
@ -863,6 +1038,8 @@
buildRules = (
);
dependencies = (
CAF128582BA4DF0600E39C26 /* PBXTargetDependency */,
CAF128562BA4DEE800E39C26 /* PBXTargetDependency */,
28C67BF52AC49F8D000C7540 /* PBXTargetDependency */,
2872E19E2AC48D770014F276 /* PBXTargetDependency */,
289710E11CFB126D0089D463 /* PBXTargetDependency */,
@ -949,7 +1126,6 @@
};
28F676BC1CD15E0B00FC6FA6 = {
CreatedOnToolsVersion = 7.3;
DevelopmentTeam = UJXNDZ5TNU;
};
28F6B48D1CF07DDD002D76D0 = {
CreatedOnToolsVersion = 7.3.1;
@ -973,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 */,
@ -988,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;
@ -1300,6 +1587,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;
@ -1368,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 */
@ -1848,12 +2146,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;
@ -1863,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 = "";
@ -1871,12 +2170,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;
@ -1886,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 = "";

View File

@ -32,5 +32,7 @@ extern NSString *DocumentsChangedNotification;
- (IBAction)showSettings:(id)sender;
- (IBAction)showGestureHelp:(id)sender;
- (void)showBrowser;
@end

View File

@ -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<Emulator> *sharedEmulator = nil;
NSString *DocumentsChangedNotification = @"documentsChanged";
@interface AppDelegate () <BTCMouseDelegate>
@interface AppDelegate () <BTCMouseDelegate, SFSafariViewControllerDelegate>
@property (nonatomic, strong) SFSafariViewController * browser;
@end
@implementation AppDelegate
@ -281,7 +283,23 @@ NSString *DocumentsChangedNotification = @"documentsChanged";
}
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)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 @@ NSString *DocumentsChangedNotification = @"documentsChanged";
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

View File

@ -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

42
Mini vMac/HFSDiskImage.h Normal file
View File

@ -0,0 +1,42 @@
//
// HFSDiskImage.h
// Mini vMac
//
// Created by Lieven Dekeyser on 13/03/2024.
//
#import <Foundation/Foundation.h>
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

328
Mini vMac/HFSDiskImage.m Normal file
View File

@ -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)

View File

@ -29,7 +29,7 @@ static ScreenView *sharedScreenView = nil;
[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 @@ static ScreenView *sharedScreenView = nil;
- (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 @@ static ScreenView *sharedScreenView = nil;
- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary<NSKeyValueChangeKey,id> *)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];
}
}

View File

@ -281,7 +281,11 @@ API_AVAILABLE(ios(13.4))
}
- (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 {

1
UniversalDetector Submodule

@ -0,0 +1 @@
Subproject commit ac12fd86fc8ad3787ce8d0d1c837adf1283968c9

1
XADMaster Submodule

@ -0,0 +1 @@
Subproject commit 9820dc15efa5d4353d8a5b43c167cee7bffae17c