Compare commits

...

67 Commits

Author SHA1 Message Date
Jesús A. Álvarez fdbf6aab7e iPad: when creating a new window, take over and close the previous one 2024-03-04 23:54:25 +01:00
Jesús A. Álvarez 19c0072d4c fix quick actions 2024-03-04 23:39:41 +01:00
Jesús A. Álvarez da3f639ef2 prefer pixel-perfect scaling when filter is set to nearest 2024-03-02 11:51:29 +01:00
Jesús A. Álvarez 65d377884b auto-hide home indicator 2024-03-01 22:49:04 +01:00
Jesús A. Álvarez 2dab9cca28 update README 2024-03-01 22:24:34 +01:00
Jesús A. Álvarez fcb71f79ff visionOS: use native toggles in menus 2024-02-17 15:21:41 +01:00
Jesús A. Álvarez 2ccef4e3a6 visionOS: add “run in background” setting and respect it 2024-02-17 15:21:41 +01:00
Jesús A. Álvarez fca6943bfe close keyboard when closing screen 2024-02-17 14:42:31 +01:00
Jesús A. Álvarez afef4e5b25 always show keyboard again when pressing keyboard button 2024-02-17 14:41:22 +01:00
Jesús A. Álvarez 772ce2c326 handle mouse input with UIHoverGestureRecognizer 2024-02-17 14:35:19 +01:00
Jesús A. Álvarez ef6ef61037 target iOS 13.4 2024-02-17 13:31:39 +01:00
Jesús A. Álvarez 3b4244e4e3 ifdef around all visionOS-specific things 2024-02-17 13:25:32 +01:00
Jesús A. Álvarez c1c7c93c6a handle key input with UIPress (iOS ≥9)
contributed by Steven Troughton-Smith
2024-02-17 13:25:32 +01:00
Jesús A. Álvarez 61dc6ddcd7 target iOS 13.0 2024-02-17 13:20:50 +01:00
Jesús A. Álvarez 0204043e10 add glass background to bar, remove from buttons 2024-02-16 21:29:22 +01:00
Jesús A. Álvarez 043c20b645 visionOS: make keyboard resizable ±25% 2024-02-10 21:37:13 +01:00
Jesús A. Álvarez 7a93412c3f visionOS: add reset, interrupt and shut down controls 2024-02-10 14:52:06 +01:00
Jesús A. Álvarez e1adde78f0 visionOS: hide toolbar from insert disk modal 2024-02-10 14:43:09 +01:00
Jesús A. Álvarez 632f01f169 visionOS: native settings menu 2024-02-10 14:43:09 +01:00
Jesús A. Álvarez ed99d1bbfb visionOS: show layout menu from keyboard button 2024-02-10 14:23:42 +01:00
Jesús A. Álvarez 53cb92f4ef find keyboard layouts from AppDelegate 2024-02-10 14:09:02 +01:00
Jesús A. Álvarez 22256824d2 make AppDelegate a bit swifty 2024-02-10 13:36:20 +01:00
Jesús A. Álvarez 3b96faf502 fix bundle identifier for MacII-512x384 2024-02-10 13:31:28 +01:00
Jesús A. Álvarez 33e01e0847 visionOS: always use touchscreen 2024-02-10 12:19:20 +01:00
Jesús A. Álvarez 7c1f280374 keyboard for visionOS 2024-02-10 12:15:01 +01:00
Jesús A. Álvarez 4aef44bf76 add icon for visionOS 2024-02-10 12:02:13 +01:00
Jesús A. Álvarez cf86226c6b build for visionOS 2024-02-09 16:06:37 +01:00
Jesús A. Álvarez 8f4bc46d12 target iOS 12.0 2024-02-09 15:39:32 +01:00
Jesús A. Álvarez 003c075108 update readme 2023-09-27 20:37:16 +02:00
Jesús A. Álvarez e2707af5ce use release build by default 2023-09-27 19:42:58 +02:00
Jesús A. Álvarez e8c8b8375f add 512×384 variant of Mac II 2023-09-27 19:42:36 +02:00
Jesús A. Álvarez 3db3bb6091 fix build with Xcode 15 2023-09-27 19:29:43 +02:00
Jesús A. Álvarez 7e2fc6ef59 update copyright year, change twitter link to mastodon 2023-02-03 21:48:24 +01:00
Jesús A. Álvarez ceb0813eee steal key events if handled by emulator
fixes #45 somewhat, but not for ⌘-Q or ⌘-H
2023-02-01 18:11:49 +01:00
Jesús A. Álvarez 1cfc5bd94f fix crash when deleting files on iPad 2022-05-26 20:24:05 +02:00
Jesús A. Álvarez aa52115d41 remove xpath usage from makefile 2022-05-26 19:50:48 +02:00
Jesús A. Álvarez 1a4d707447 call it 2.5 2022-05-26 19:15:46 +02:00
Jesús A. Álvarez 0b1eb1a37b add boot disks to app's quick actions 2022-05-26 19:12:09 +02:00
Jesús A. Álvarez d93ae3ce89 use default modal presentation transition for settings and disks
getting it right on iPad and iPhone seems too much of a hack
2022-05-26 17:43:16 +02:00
Jesús A. Álvarez ada4e0a4dd update to Mini vMac 37.03 beta 2022-05-26 16:22:32 +02:00
Bart a70c23fc70 use https URL for submodules 2022-01-05 18:24:09 +01:00
Jesús A. Álvarez d1eab98945 update README 2020-10-01 23:03:02 +02:00
Jesús A. Álvarez 21de19443a fix broken view after interactive sheet dismiss on iOS 13 2020-10-01 22:50:38 +02:00
Jesús A. Álvarez 479b9c243c show delete confirmation as action sheet 2020-10-01 22:50:38 +02:00
Jesús A. Álvarez 09fd85ca16 make launch screen black 2020-10-01 22:50:38 +02:00
Jesús A. Álvarez c4bd05128f use contextual menu for disk images on iOS 13 or later 2020-10-01 22:50:38 +02:00
Jesús A. Álvarez 9b74889621 handle dark mode on activity indicator 2020-10-01 22:50:38 +02:00
Jesús A. Álvarez c548061f42 add missing nullability annotation 2020-10-01 22:50:38 +02:00
Jesús A. Álvarez dfc5c9e01f set minimum target to iOS 9
remove iOS 8 stuff
2020-10-01 22:50:37 +02:00
Jesús A. Álvarez cd0bfb0638 bump version 2020-09-30 22:17:37 +02:00
Jesús A. Álvarez 66ed7bd009 update Mini vMac to b37.200926 2020-09-30 22:15:46 +02:00
Jesús A. Álvarez 79fb9b2c25 clear screen immediately when switching emulators 2020-09-25 22:17:04 +02:00
Jesús A. Álvarez bf2cde331d remove unused files from previous Mini vMac source import 2020-09-25 22:15:39 +02:00
Jesús A. Álvarez dead799d16 only reset speed when saved speed is faster than default
this saves the preferences, but still prevents accidentally locking up the app by setting a fast speed on a low end device
2020-09-25 22:13:52 +02:00
Jesús A. Álvarez fd665a1761 allow changing emulated machine without relaunching the app 2020-09-25 00:29:30 +02:00
Jesús A. Álvarez af3b2ba5b1 cache bundle icons manually
otherwise they seem to get mixed up on iOS 14
2020-09-25 00:16:53 +02:00
Jesús A. Álvarez b72a6f058a update to Mini vMac b37.200912 with patch fixing wintergames 2020-09-24 22:54:05 +02:00
Jesús A. Álvarez d2fda78a9c updated README.md 2020-06-23 20:21:54 +02:00
Jesús A. Álvarez 44f090a506 show gesture help screen by default 2020-06-23 19:19:28 +02:00
Jesús A. Álvarez ddfe6201a6 handle hardware mouse in trackpad mode 2020-06-23 19:07:30 +02:00
Jesús A. Álvarez 5ab79e73e2 don't annotate whole view controller with API_AVAILABLE(ios(13.4)) 2020-06-23 18:39:05 +02:00
Jesús A. Álvarez 9d3f2bd98c add gesture help screen 2020-06-23 18:32:07 +02:00
Jesús A. Álvarez 038ea05f0b remove flip transition between settings and disk views
it's based on ancient hacks that don't look good on modern iOS
2020-06-22 21:07:01 +02:00
Jesús A. Álvarez d2b8238109 update version 2020-06-22 18:16:37 +02:00
Jesús A. Álvarez 22c1849d70 support split screen multitasking 2020-06-22 18:16:37 +02:00
Jesús A. Álvarez 9a76a98ef9 put emulator bundles in Frameworks instead of PlugIns
fixes sideloading with AltStore
2020-06-22 14:38:01 +02:00
Jesús A. Álvarez 95756edc1f makefile: read version from built Info.plist 2020-05-14 19:15:24 +02:00
192 changed files with 3666 additions and 48593 deletions

4
.gitmodules vendored
View File

@ -4,3 +4,7 @@
[submodule "libres"]
path = libres
url = https://github.com/zydeco/libres.git
[submodule "minivmac"]
path = minivmac
url = https://github.com/zydeco/minivmac.git
branch = wintergames

View File

@ -3,7 +3,7 @@ PROJECT="Mini vMac.xcodeproj"
SCHEME="Mini vMac"
CONFIGURATION=Release
APP="build/Build/Products/$(CONFIGURATION)-iphoneos/Mini vMac.app"
VERSION=`xpath 2>/dev/null Mini\ vMac/Info.plist "/plist/dict/key[.='CFBundleShortVersionString']/following-sibling::*[1]/text()"`
VERSION=`plutil -extract CFBundleShortVersionString raw $(APP)/Info.plist -o -`
LDID=ldid
deb: $(APP)

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,7 @@
<?xml version="1.0" encoding="UTF-8"?>
<Workspace
version = "1.0">
<FileRef
location = "self:Mini vMac.xcodeproj">
</FileRef>
</Workspace>

View File

@ -0,0 +1,37 @@
{
"DVTSourceControlWorkspaceBlueprintPrimaryRemoteRepositoryKey" : "9C19786155D97B8ED78AB84AFAAA50249126341A",
"DVTSourceControlWorkspaceBlueprintWorkingCopyRepositoryLocationsKey" : {
},
"DVTSourceControlWorkspaceBlueprintWorkingCopyStatesKey" : {
"9C19786155D97B8ED78AB84AFAAA50249126341A" : 0,
"F2E8D120DACD6BF5E1EFFA012C92CE6FA0E44B4C" : 0,
"45D35ABA2A883CFEB6F6014CF9723CDA568B602B" : 0
},
"DVTSourceControlWorkspaceBlueprintIdentifierKey" : "A273011D-9F4F-4F93-8287-77CF2E175709",
"DVTSourceControlWorkspaceBlueprintWorkingCopyPathsKey" : {
"9C19786155D97B8ED78AB84AFAAA50249126341A" : "minivmac4ios\/",
"F2E8D120DACD6BF5E1EFFA012C92CE6FA0E44B4C" : "minivmac4ios\/libres\/",
"45D35ABA2A883CFEB6F6014CF9723CDA568B602B" : "minivmac4ios\/libmfs\/"
},
"DVTSourceControlWorkspaceBlueprintNameKey" : "Mini vMac",
"DVTSourceControlWorkspaceBlueprintVersion" : 204,
"DVTSourceControlWorkspaceBlueprintRelativePathToProjectKey" : "Mini vMac.xcodeproj",
"DVTSourceControlWorkspaceBlueprintRemoteRepositoriesKey" : [
{
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/zydeco\/libmfs.git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "45D35ABA2A883CFEB6F6014CF9723CDA568B602B"
},
{
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "github.com:zydeco\/minivmac4ios.git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "9C19786155D97B8ED78AB84AFAAA50249126341A"
},
{
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryURLKey" : "https:\/\/github.com\/zydeco\/libres.git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositorySystemKey" : "com.apple.dt.Xcode.sourcecontrol.Git",
"DVTSourceControlWorkspaceBlueprintRemoteRepositoryIdentifierKey" : "F2E8D120DACD6BF5E1EFFA012C92CE6FA0E44B4C"
}
]
}

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1000"
LastUpgradeVersion = "1200"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@ -29,11 +29,9 @@
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
@ -51,8 +49,6 @@
ReferencedContainer = "container:Mini vMac.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"

View File

@ -0,0 +1,66 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1500"
version = "1.7">
<BuildAction
parallelizeBuildables = "YES"
buildImplicitDependencies = "YES">
<BuildActionEntries>
<BuildActionEntry
buildForTesting = "YES"
buildForRunning = "YES"
buildForProfiling = "YES"
buildForArchiving = "YES"
buildForAnalyzing = "YES">
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "28C67BD02AC49E46000C7540"
BuildableName = "MacII-512x384.framework"
BlueprintName = "MacII-512x384"
ReferencedContainer = "container:Mini vMac.xcodeproj">
</BuildableReference>
</BuildActionEntry>
</BuildActionEntries>
</BuildAction>
<TestAction
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES"
shouldAutocreateTestPlan = "YES">
</TestAction>
<LaunchAction
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
useCustomWorkingDirectory = "NO"
ignoresPersistentStateOnLaunch = "NO"
debugDocumentVersioning = "YES"
debugServiceExtension = "internal"
allowLocationSimulation = "YES">
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"
shouldUseLaunchSchemeArgsEnv = "YES"
savedToolIdentifier = ""
useCustomWorkingDirectory = "NO"
debugDocumentVersioning = "YES">
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
BlueprintIdentifier = "28C67BD02AC49E46000C7540"
BuildableName = "MacII-512x384.framework"
BlueprintName = "MacII-512x384"
ReferencedContainer = "container:Mini vMac.xcodeproj">
</BuildableReference>
</MacroExpansion>
</ProfileAction>
<AnalyzeAction
buildConfiguration = "Debug">
</AnalyzeAction>
<ArchiveAction
buildConfiguration = "Release"
revealArchiveInOrganizer = "YES">
</ArchiveAction>
</Scheme>

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1000"
LastUpgradeVersion = "1200"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@ -29,11 +29,9 @@
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
@ -51,8 +49,6 @@
ReferencedContainer = "container:Mini vMac.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1000"
LastUpgradeVersion = "1200"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@ -29,11 +29,9 @@
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
@ -51,8 +49,6 @@
ReferencedContainer = "container:Mini vMac.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1000"
LastUpgradeVersion = "1200"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@ -29,11 +29,9 @@
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
buildConfiguration = "Release"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
@ -51,8 +49,6 @@
ReferencedContainer = "container:Mini vMac.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1000"
LastUpgradeVersion = "1200"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@ -27,8 +27,6 @@
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<MacroExpansion>
<BuildableReference
BuildableIdentifier = "primary"
@ -38,11 +36,11 @@
ReferencedContainer = "container:Mini vMac.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
<Testables>
</Testables>
</TestAction>
<LaunchAction
buildConfiguration = "Release"
buildConfiguration = "Debug"
selectedDebuggerIdentifier = "Xcode.DebuggerFoundation.Debugger.LLDB"
selectedLauncherIdentifier = "Xcode.DebuggerFoundation.Launcher.LLDB"
launchStyle = "0"
@ -71,8 +69,6 @@
isEnabled = "NO">
</CommandLineArgument>
</CommandLineArguments>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1000"
LastUpgradeVersion = "1200"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@ -29,8 +29,6 @@
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
@ -51,8 +49,6 @@
ReferencedContainer = "container:Mini vMac.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1000"
LastUpgradeVersion = "1200"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@ -29,8 +29,6 @@
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
@ -51,8 +49,6 @@
ReferencedContainer = "container:Mini vMac.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"

View File

@ -1,6 +1,6 @@
<?xml version="1.0" encoding="UTF-8"?>
<Scheme
LastUpgradeVersion = "1000"
LastUpgradeVersion = "1200"
version = "1.3">
<BuildAction
parallelizeBuildables = "YES"
@ -29,8 +29,6 @@
shouldUseLaunchSchemeArgsEnv = "YES">
<Testables>
</Testables>
<AdditionalOptions>
</AdditionalOptions>
</TestAction>
<LaunchAction
buildConfiguration = "Debug"
@ -51,8 +49,6 @@
ReferencedContainer = "container:Mini vMac.xcodeproj">
</BuildableReference>
</MacroExpansion>
<AdditionalOptions>
</AdditionalOptions>
</LaunchAction>
<ProfileAction
buildConfiguration = "Release"

View File

@ -19,14 +19,20 @@ extern NSString *DocumentsChangedNotification;
@property (nonatomic, readonly) NSString *userKeyboardLayoutsPath;
@property (nonatomic, readonly) NSArray<NSString*> *diskImageExtensions;
@property (nonatomic, readonly) NSArray<NSBundle*> *emulatorBundles;
@property (nonatomic, readonly) NSString *emulatorBundlesPath;
@property (readonly, nonatomic, getter = isSandboxed) BOOL sandboxed;
@property (readonly, nonatomic) id<Emulator> sharedEmulator;
@property (readonly, nonatomic) NSArray<NSString*> *keyboardLayoutPaths;
+ (instancetype)sharedInstance;
+ (id<Emulator>)sharedEmulator;
@property (class, readonly, strong) AppDelegate *sharedInstance NS_SWIFT_NAME(shared);
@property (class, readonly, strong) id<Emulator> sharedEmulator NS_SWIFT_NAME(emulator);
- (void)loadAndStartEmulator;
- (void)showAlertWithTitle:(NSString *)title message:(NSString *)message;
- (IBAction)showInsertDisk:(id)sender;
- (IBAction)showSettings:(id)sender;
- (IBAction)showGestureHelp:(id)sender;
- (UIScene*)sceneWithName:(NSString*)name;
@end

View File

@ -10,18 +10,18 @@
#import "AppDelegate.h"
#import "SettingsViewController.h"
#import "InsertDiskViewController.h"
#import "ViewController.h"
static AppDelegate *sharedAppDelegate = nil;
static NSObject<Emulator> *sharedEmulator = nil;
NSString *DocumentsChangedNotification = @"documentsChanged";
@interface AppDelegate () <UIViewControllerTransitioningDelegate, UIViewControllerAnimatedTransitioning, BTCMouseDelegate>
@interface AppDelegate () <BTCMouseDelegate>
@end
@implementation AppDelegate
{
UISwipeGestureRecognizerDirection modalPanePresentationDirection;
}
+ (instancetype)sharedInstance {
@ -34,12 +34,9 @@ NSString *DocumentsChangedNotification = @"documentsChanged";
- (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSDictionary *)launchOptions {
sharedAppDelegate = self;
if (![self loadEmulator:[[NSUserDefaults standardUserDefaults] stringForKey:@"machine"]]) {
[self loadEmulator:@"MacPlus4M"];
}
[self initDefaults];
[[AVAudioSession sharedInstance] setCategory:AVAudioSessionCategoryAmbient error:NULL];
[sharedEmulator performSelector:@selector(run) withObject:nil afterDelay:0.1];
[self loadAndStartEmulator];
if ([application respondsToSelector:@selector(btcMouseSetRawMode:)]) {
[application btcMouseSetRawMode:YES];
@ -64,12 +61,13 @@ NSString *DocumentsChangedNotification = @"documentsChanged";
@"speedValue": @(sharedEmulator.initialSpeed),
@"runInBackground": @NO,
@"autoSlow": @(sharedEmulator.initialAutoSlow),
@"screenFilter": kCAFilterLinear
@"screenFilter": kCAFilterLinear,
@"autoShowGestureHelp": @YES,
@"recentDisks": @[]
};
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults registerDefaults:defaultValues];
[defaults setValue:@(sharedEmulator.initialSpeed) forKey:@"speedValue"];
[defaults addObserver:self forKeyPath:@"speedValue" options:0 context:NULL];
}
@ -84,12 +82,15 @@ NSString *DocumentsChangedNotification = @"documentsChanged";
}
}
- (NSString*)emulatorBundlesPath {
return [NSBundle mainBundle].privateFrameworksPath;
}
- (NSArray<NSBundle*>*)emulatorBundles {
NSString *pluginsPath = [NSBundle mainBundle].builtInPlugInsPath;
NSArray<NSString*> *names = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:pluginsPath error:NULL];
NSArray<NSString*> *names = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:self.emulatorBundlesPath error:NULL];
NSMutableArray *emulatorBundles = [NSMutableArray arrayWithCapacity:names.count];
for (NSString *name in [names pathsMatchingExtensions:@[@"mnvm"]]) {
NSBundle *bundle = [NSBundle bundleWithPath:[pluginsPath stringByAppendingPathComponent:name]];
NSBundle *bundle = [NSBundle bundleWithPath:[self.emulatorBundlesPath stringByAppendingPathComponent:name]];
[emulatorBundles addObject:bundle];
}
return emulatorBundles;
@ -97,14 +98,48 @@ NSString *DocumentsChangedNotification = @"documentsChanged";
- (BOOL)loadEmulator:(NSString*)name {
NSString *emulatorBundleName = [name stringByAppendingPathExtension:@"mnvm"];
NSString *emulatorBundlePath = [[NSBundle mainBundle].builtInPlugInsPath stringByAppendingPathComponent:emulatorBundleName];
NSString *emulatorBundlePath = [self.emulatorBundlesPath stringByAppendingPathComponent:emulatorBundleName];
NSBundle *emulatorBundle = [NSBundle bundleWithPath:emulatorBundlePath];
[emulatorBundle load];
sharedEmulator = [[emulatorBundle principalClass] new];
sharedEmulator.rootViewController = self.window.rootViewController;
sharedEmulator.showAlert = ^(NSString *title, NSString *message) {
[self showAlertWithTitle:title message:message];
};
sharedEmulator.dataPath = self.documentsPath;
#if defined(TARGET_OS_VISION) && TARGET_OS_VISION == 1
[ViewController adjustToScreenSize];
#endif
return sharedEmulator != nil;
}
- (void)loadAndStartEmulator {
[self willChangeValueForKey:@"sharedEmulator"];
if (sharedEmulator) {
NSBundle *bundle = sharedEmulator.bundle;
id<Emulator> oldEmulator = sharedEmulator;
sharedEmulator = nil;
[oldEmulator shutdown];
[bundle unload];
}
if (![self loadEmulator:[[NSUserDefaults standardUserDefaults] stringForKey:@"machine"]]) {
[self loadEmulator:@"MacPlus4M"];
}
[self didChangeValueForKey:@"sharedEmulator"];
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
if ([defaults integerForKey:@"speedValue"] > sharedEmulator.initialSpeed) {
[defaults setValue:@(sharedEmulator.initialSpeed) forKey:@"speedValue"];
} else {
sharedEmulator.speed = [defaults integerForKey:@"speedValue"];
}
[sharedEmulator performSelector:@selector(run) withObject:nil afterDelay:0.1];
}
- (id<Emulator>)sharedEmulator {
return sharedEmulator;
}
- (void)applicationDidEnterBackground:(UIApplication *)application {
NSUserDefaults *defaults = [NSUserDefaults standardUserDefaults];
[defaults synchronize];
@ -140,114 +175,43 @@ NSString *DocumentsChangedNotification = @"documentsChanged";
});
return;
}
if ([UIAlertController class]) {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:nil]];
UIViewController *controller = self.window.rootViewController;
while (controller.presentedViewController) {
controller = controller.presentedViewController;
}
[controller presentViewController:alert animated:YES completion:nil];
} else {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
[alertView show];
BOOL wasRunning = sharedEmulator.isRunning;
UIAlertController *alert = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[sharedEmulator setRunning:wasRunning];
}]];
UIViewController *controller = self.window.rootViewController;
while (controller.presentedViewController) {
controller = controller.presentedViewController;
}
[controller presentViewController:alert animated:YES completion:nil];
}
#pragma mark - Settings / Insert Disk panels
- (void)application:(UIApplication *)application performActionForShortcutItem:(UIApplicationShortcutItem *)shortcutItem completionHandler:(void (^)(BOOL))completionHandler {
BOOL success = NO;
if ([shortcutItem.type isEqualToString:@"disk"]) {
NSString *fileName = (NSString*)shortcutItem.userInfo[@"disk"];
NSString *filePath = [self.documentsPath stringByAppendingPathComponent:fileName];
if ([[NSFileManager defaultManager] fileExistsAtPath:filePath] && ![sharedEmulator isDiskInserted:filePath]) {
success = YES;
[sharedEmulator performSelector:@selector(insertDisk:) withObject:filePath afterDelay:1.0];
}
}
completionHandler(success);
}
#pragma mark - Settings / Insert Disk / Help
- (void)showSettings:(id)sender {
[self showModalPanel:@"settings" sender:sender];
[self.window.rootViewController performSelector:@selector(showSettings:) withObject:sender];
}
- (void)showInsertDisk:(id)sender {
[self showModalPanel:@"disk" sender:sender];
[self.window.rootViewController performSelector:@selector(showInsertDisk:) withObject:sender];
}
- (void)showModalPanel:(NSString*)name sender:(id)sender {
Class classToShow, otherClass;
if ([name isEqualToString:@"settings"]) {
classToShow = [SettingsViewController class];
otherClass = [InsertDiskViewController class];
} else {
classToShow = [InsertDiskViewController class];
otherClass = [SettingsViewController class];
}
UIViewController *rootViewController = self.window.rootViewController;
UIViewController *presentedViewController = rootViewController.presentedViewController;
UIViewController *presentedTopViewController = [presentedViewController isKindOfClass:[UINavigationController class]] ? [(UINavigationController*)presentedViewController topViewController] : nil;
if ([presentedTopViewController isKindOfClass:classToShow]) {
[presentedViewController dismissViewControllerAnimated:YES completion:nil];
return;
} else if ([presentedTopViewController isKindOfClass:otherClass]) {
// flip
UIViewController *viewController = [rootViewController.storyboard instantiateViewControllerWithIdentifier:name];
viewController.modalTransitionStyle = UIModalTransitionStyleFlipHorizontal;
viewController.modalPresentationStyle = UIModalPresentationFormSheet;
UIView *windowSnapshotView = [self.window snapshotViewAfterScreenUpdates:NO];
[self.window addSubview:windowSnapshotView];
UIView *oldPanelSnapshotView = [presentedViewController.view snapshotViewAfterScreenUpdates:NO];
[viewController.view addSubview:oldPanelSnapshotView];
[rootViewController dismissViewControllerAnimated:NO completion:^{
[rootViewController presentViewController:viewController animated:NO completion:^{
UIView *emptyView = [[UIView alloc] initWithFrame:viewController.view.bounds];
[windowSnapshotView removeFromSuperview];
viewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
[UIView transitionFromView:oldPanelSnapshotView
toView:emptyView
duration:0.5
options:UIViewAnimationOptionTransitionFlipFromRight
completion:^(BOOL finished) {
[emptyView removeFromSuperview];
}];
}];
}];
} else {
UIViewController *viewController = [rootViewController.storyboard instantiateViewControllerWithIdentifier:name];
viewController.modalTransitionStyle = UIModalTransitionStyleCoverVertical;
viewController.modalPresentationStyle = UIModalPresentationFormSheet;
if ([sender isKindOfClass:[UISwipeGestureRecognizer class]] && NSFoundationVersionNumber >= NSFoundationVersionNumber_iOS_8_0) {
modalPanePresentationDirection = [(UISwipeGestureRecognizer*)sender direction];
viewController.transitioningDelegate = self;
}
[rootViewController presentViewController:viewController animated:YES completion:nil];
}
}
- (id<UIViewControllerAnimatedTransitioning>)animationControllerForPresentedController:(UIViewController *)presented presentingController:(UIViewController *)presenting sourceController:(UIViewController *)source {
return self;
}
- (NSTimeInterval)transitionDuration:(id<UIViewControllerContextTransitioning>)transitionContext {
return 0.3;
}
- (void)animateTransition:(id<UIViewControllerContextTransitioning>)transitionContext {
UIView *containerView = [transitionContext containerView];
UIView *toView = [transitionContext viewForKey:UITransitionContextToViewKey];
[containerView addSubview:toView];
switch (modalPanePresentationDirection) {
case UISwipeGestureRecognizerDirectionLeft:
toView.transform = CGAffineTransformMakeTranslation(containerView.bounds.size.width, 0);
break;
case UISwipeGestureRecognizerDirectionRight:
toView.transform = CGAffineTransformMakeTranslation(-containerView.bounds.size.width, 0);
break;
case UISwipeGestureRecognizerDirectionDown:
toView.transform = CGAffineTransformMakeTranslation(0, -containerView.bounds.size.height);
break;
default:
toView.transform = CGAffineTransformMakeTranslation(0, containerView.bounds.size.height);
}
[UIView animateWithDuration:[self transitionDuration:transitionContext] animations:^{
toView.transform = CGAffineTransformIdentity;
} completion:^(BOOL finished) {
[transitionContext completeTransition:finished];
}];
- (void)showGestureHelp:(id)sender {
[self.window.rootViewController performSelector:@selector(showGestureHelp:) withObject:sender];
}
#pragma mark - Files
@ -293,15 +257,14 @@ NSString *DocumentsChangedNotification = @"documentsChanged";
return userKeyboardLayoutsPath;
}
- (BOOL)application:(UIApplication *)application openURL:(NSURL *)url sourceApplication:(NSString *)sourceApplication annotation:(id)annotation {
NSMutableDictionary *options = [NSMutableDictionary dictionaryWithCapacity:2];
if (sourceApplication) {
options[UIApplicationOpenURLOptionsSourceApplicationKey] = sourceApplication;
- (NSArray<NSString *> *)keyboardLayoutPaths {
NSArray *keyboardLayouts = [[NSBundle mainBundle] pathsForResourcesOfType:@"nfkeyboardlayout" inDirectory:@"Keyboard Layouts"];
NSString *userKeyboardLayoutsPath = [AppDelegate sharedInstance].userKeyboardLayoutsPath;
NSArray *userKeyboardLayouts = [[[NSFileManager defaultManager] contentsOfDirectoryAtPath:userKeyboardLayoutsPath error:nil] filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"pathExtension.lowercaseString = %@", @"nfkeyboardlayout"]];
if (userKeyboardLayouts.count > 0) {
keyboardLayouts = [keyboardLayouts arrayByAddingObjectsFromArray:userKeyboardLayouts];
}
if (annotation) {
options[UIApplicationOpenURLOptionsAnnotationKey] = annotation;
}
return [self application:application openURL:url options:options];
return keyboardLayouts;
}
- (BOOL)importFileToDocuments:(NSURL *)url copy:(BOOL)copy {
@ -362,4 +325,41 @@ NSString *DocumentsChangedNotification = @"documentsChanged";
return YES;
}
#pragma mark - Making a Scene
- (UISceneConfiguration *)application:(UIApplication *)application configurationForConnectingSceneSession:(UISceneSession *)connectingSceneSession options:(UISceneConnectionOptions *)options {
for (NSUserActivity *activity in options.userActivities) {
if ([activity.activityType isEqualToString:@"net.namedfork.keyboard"]) {
return [UISceneConfiguration configurationWithName:@"Keyboard" sessionRole:UIWindowSceneSessionRoleApplication];
}
}
if ([self sceneWithName:@"Default"] == nil) {
[[AppDelegate sharedEmulator] setRunning:YES];
return [UISceneConfiguration configurationWithName:@"Default" sessionRole:UIWindowSceneSessionRoleApplication];
}
return nil;
}
- (void)application:(UIApplication *)application didDiscardSceneSessions:(NSSet<UISceneSession *> *)sceneSessions {
if ([self sceneWithName:@"Default"] == nil) {
if ([[NSUserDefaults standardUserDefaults] boolForKey:@"runInBackground"] == NO) {
[[AppDelegate sharedEmulator] setRunning:NO];
}
UIScene *keyboardScene = [self sceneWithName:@"Keyboard"];
if (keyboardScene != nil) {
// if only keyboard is left, close it too
[application requestSceneSessionDestruction:keyboardScene.session options:nil errorHandler:nil];
}
}
}
- (UIScene*)sceneWithName:(NSString*)name {
for (UIScene *scene in [UIApplication sharedApplication].connectedScenes) {
if ([scene.session.configuration.name isEqualToString:name]) {
return scene;
}
}
return nil;
}
@end

View File

@ -2,113 +2,110 @@
"images" : [
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "2x"
"scale" : "2x",
"size" : "20x20"
},
{
"idiom" : "iphone",
"size" : "20x20",
"scale" : "3x"
"scale" : "3x",
"size" : "20x20"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-Small@2x.png",
"scale" : "2x"
"idiom" : "iphone",
"scale" : "2x",
"size" : "29x29"
},
{
"size" : "29x29",
"idiom" : "iphone",
"filename" : "Icon-Small@3x.png",
"scale" : "3x"
"idiom" : "iphone",
"scale" : "3x",
"size" : "29x29"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-Small-40@2x-1.png",
"scale" : "2x"
"idiom" : "iphone",
"scale" : "2x",
"size" : "40x40"
},
{
"size" : "40x40",
"idiom" : "iphone",
"filename" : "Icon-Small-40@3x.png",
"scale" : "3x"
"idiom" : "iphone",
"scale" : "3x",
"size" : "40x40"
},
{
"size" : "60x60",
"idiom" : "iphone",
"filename" : "Icon-60@2x.png",
"scale" : "2x"
},
{
"size" : "60x60",
"idiom" : "iphone",
"scale" : "2x",
"size" : "60x60"
},
{
"filename" : "Icon-60@3x.png",
"scale" : "3x"
"idiom" : "iphone",
"scale" : "3x",
"size" : "60x60"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "1x"
"scale" : "1x",
"size" : "20x20"
},
{
"idiom" : "ipad",
"size" : "20x20",
"scale" : "2x"
"scale" : "2x",
"size" : "20x20"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-Small.png",
"scale" : "1x"
"idiom" : "ipad",
"scale" : "1x",
"size" : "29x29"
},
{
"size" : "29x29",
"idiom" : "ipad",
"filename" : "Icon-Small@2x-1.png",
"scale" : "2x"
"idiom" : "ipad",
"scale" : "2x",
"size" : "29x29"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-Small-40.png",
"scale" : "1x"
"idiom" : "ipad",
"scale" : "1x",
"size" : "40x40"
},
{
"size" : "40x40",
"idiom" : "ipad",
"filename" : "Icon-Small-40@2x.png",
"scale" : "2x"
"idiom" : "ipad",
"scale" : "2x",
"size" : "40x40"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-76.png",
"scale" : "1x"
"idiom" : "ipad",
"scale" : "1x",
"size" : "76x76"
},
{
"size" : "76x76",
"idiom" : "ipad",
"filename" : "Icon-76@2x.png",
"scale" : "2x"
"idiom" : "ipad",
"scale" : "2x",
"size" : "76x76"
},
{
"size" : "83.5x83.5",
"idiom" : "ipad",
"filename" : "Icon-iPadPro.png",
"scale" : "2x"
"idiom" : "ipad",
"scale" : "2x",
"size" : "83.5x83.5"
},
{
"idiom" : "ios-marketing",
"size" : "1024x1024",
"scale" : "1x"
"scale" : "1x",
"size" : "1024x1024"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
},
"properties" : {
"pre-rendered" : true
"author" : "xcode",
"version" : 1
}
}
}

View File

@ -0,0 +1,13 @@
{
"images" : [
{
"filename" : "back.png",
"idiom" : "vision",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 25 KiB

View File

@ -0,0 +1,12 @@
{
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"frame-size" : {
"height" : 512,
"width" : 512
}
}
}

View File

@ -0,0 +1,17 @@
{
"info" : {
"author" : "xcode",
"version" : 1
},
"layers" : [
{
"filename" : "Front.solidimagestacklayer"
},
{
"filename" : "Middle.solidimagestacklayer"
},
{
"filename" : "Back.solidimagestacklayer"
}
]
}

View File

@ -0,0 +1,13 @@
{
"images" : [
{
"filename" : "Icon.png",
"idiom" : "vision",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 736 B

View File

@ -0,0 +1,12 @@
{
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"frame-size" : {
"height" : 512,
"width" : 512
}
}
}

View File

@ -0,0 +1,13 @@
{
"images" : [
{
"filename" : "screen.png",
"idiom" : "vision",
"scale" : "2x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 934 B

View File

@ -0,0 +1,12 @@
{
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"frame-size" : {
"height" : 512,
"width" : 512
}
}
}

View File

@ -1,6 +1,6 @@
{
"info" : {
"version" : 1,
"author" : "xcode"
"author" : "xcode",
"version" : 1
}
}
}

View File

@ -23,6 +23,11 @@
"filename" : "KBCapsLock~ipad@2x.png",
"idiom" : "ipad",
"scale" : "2x"
},
{
"filename" : "KBCapsLock~ipad@2x 1.png",
"idiom" : "vision",
"scale" : "2x"
}
],
"info" : {

Binary file not shown.

After

Width:  |  Height:  |  Size: 317 B

View File

@ -23,6 +23,11 @@
"filename" : "KBClearDown~ipad@2x.png",
"idiom" : "ipad",
"scale" : "2x"
},
{
"filename" : "KBClearDown~ipad@2x 1.png",
"idiom" : "vision",
"scale" : "2x"
}
],
"info" : {

Binary file not shown.

After

Width:  |  Height:  |  Size: 401 B

View File

@ -23,6 +23,11 @@
"filename" : "KBClearUp~ipad@2x.png",
"idiom" : "ipad",
"scale" : "2x"
},
{
"filename" : "KBClearUp~ipad@2x 1.png",
"idiom" : "vision",
"scale" : "2x"
}
],
"info" : {

Binary file not shown.

After

Width:  |  Height:  |  Size: 563 B

View File

@ -23,6 +23,11 @@
"filename" : "KBCommand@2x~ipad.png",
"idiom" : "ipad",
"scale" : "2x"
},
{
"filename" : "KBCommand@2x~ipad 1.png",
"idiom" : "vision",
"scale" : "2x"
}
],
"info" : {

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

View File

@ -23,6 +23,11 @@
"filename" : "KBDeleteDown~ipad@2x.png",
"idiom" : "ipad",
"scale" : "2x"
},
{
"filename" : "KBDeleteDown~ipad@2x 1.png",
"idiom" : "vision",
"scale" : "2x"
}
],
"info" : {

Binary file not shown.

After

Width:  |  Height:  |  Size: 526 B

View File

@ -23,6 +23,11 @@
"filename" : "KBDeleteUp~ipad@2x.png",
"idiom" : "ipad",
"scale" : "2x"
},
{
"filename" : "KBDeleteUp~ipad@2x 1.png",
"idiom" : "vision",
"scale" : "2x"
}
],
"info" : {

Binary file not shown.

After

Width:  |  Height:  |  Size: 726 B

View File

@ -23,6 +23,11 @@
"filename" : "KBForwardDeleteDown~ipad@2x.png",
"idiom" : "ipad",
"scale" : "2x"
},
{
"filename" : "KBForwardDeleteDown~ipad@2x 1.png",
"idiom" : "vision",
"scale" : "2x"
}
],
"info" : {

Binary file not shown.

After

Width:  |  Height:  |  Size: 526 B

View File

@ -23,6 +23,11 @@
"filename" : "KBForwardDeleteUp~ipad@2x.png",
"idiom" : "ipad",
"scale" : "2x"
},
{
"filename" : "KBForwardDeleteUp~ipad@2x 1.png",
"idiom" : "vision",
"scale" : "2x"
}
],
"info" : {

Binary file not shown.

After

Width:  |  Height:  |  Size: 718 B

View File

@ -1,6 +1,7 @@
{
"images" : [
{
"filename" : "KBHide~ipad 2.png",
"idiom" : "iphone",
"scale" : "1x"
},
@ -23,6 +24,11 @@
"filename" : "KBHide~ipad@2x.png",
"idiom" : "ipad",
"scale" : "2x"
},
{
"filename" : "KBHide~ipad@2x 1.png",
"idiom" : "vision",
"scale" : "2x"
}
],
"info" : {

Binary file not shown.

After

Width:  |  Height:  |  Size: 242 B

Binary file not shown.

After

Width:  |  Height:  |  Size: 438 B

View File

@ -219,6 +219,25 @@
"mode" : "9-part"
},
"scale" : "2x"
},
{
"filename" : "KBKey@2x~ipad-2 1.png",
"idiom" : "vision",
"resizing" : {
"cap-insets" : {
"bottom" : 32,
"left" : 32,
"right" : 32,
"top" : 32
},
"center" : {
"height" : 2,
"mode" : "tile",
"width" : 2
},
"mode" : "9-part"
},
"scale" : "2x"
}
],
"info" : {

Binary file not shown.

After

Width:  |  Height:  |  Size: 634 B

View File

@ -219,6 +219,25 @@
"mode" : "9-part"
},
"scale" : "2x"
},
{
"filename" : "KBKeyDark@2x~ipad-1 1.png",
"idiom" : "vision",
"resizing" : {
"cap-insets" : {
"bottom" : 32,
"left" : 32,
"right" : 32,
"top" : 32
},
"center" : {
"height" : 2,
"mode" : "tile",
"width" : 2
},
"mode" : "9-part"
},
"scale" : "2x"
}
],
"info" : {

Binary file not shown.

After

Width:  |  Height:  |  Size: 636 B

View File

@ -23,6 +23,11 @@
"filename" : "KBNumPad@2x~ipad.png",
"idiom" : "ipad",
"scale" : "2x"
},
{
"filename" : "KBNumPad@2x~ipad 1.png",
"idiom" : "vision",
"scale" : "2x"
}
],
"info" : {

Binary file not shown.

After

Width:  |  Height:  |  Size: 178 B

View File

@ -23,6 +23,11 @@
"filename" : "KBOption@2x~ipad.png",
"idiom" : "ipad",
"scale" : "2x"
},
{
"filename" : "KBOption@2x~ipad 1.png",
"idiom" : "vision",
"scale" : "2x"
}
],
"info" : {

Binary file not shown.

After

Width:  |  Height:  |  Size: 365 B

View File

@ -23,6 +23,11 @@
"filename" : "KBShiftDown~ipad@2x.png",
"idiom" : "ipad",
"scale" : "2x"
},
{
"filename" : "KBShiftDown~ipad@2x 1.png",
"idiom" : "vision",
"scale" : "2x"
}
],
"info" : {

Binary file not shown.

After

Width:  |  Height:  |  Size: 274 B

View File

@ -23,6 +23,11 @@
"filename" : "KBShiftUp~ipad@2x.png",
"idiom" : "ipad",
"scale" : "2x"
},
{
"filename" : "KBShiftUp~ipad@2x 1.png",
"idiom" : "vision",
"scale" : "2x"
}
],
"info" : {

Binary file not shown.

After

Width:  |  Height:  |  Size: 467 B

View File

@ -1,23 +1,26 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "reset.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "reset@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "reset@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}
}

View File

@ -1,23 +1,26 @@
{
"images" : [
{
"idiom" : "universal",
"filename" : "Settings.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"idiom" : "universal",
"filename" : "Settings@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"idiom" : "universal",
"filename" : "Settings@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"version" : 1,
"author" : "xcode"
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}
}

View File

@ -0,0 +1,26 @@
{
"images" : [
{
"filename" : "Swipe2Down.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Swipe2Down@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Swipe2Down@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -0,0 +1,26 @@
{
"images" : [
{
"filename" : "Swipe2Left.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Swipe2Left@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Swipe2Left@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -0,0 +1,26 @@
{
"images" : [
{
"filename" : "Swipe2Right.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Swipe2Right@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Swipe2Right@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -0,0 +1,26 @@
{
"images" : [
{
"filename" : "Swipe2Up.png",
"idiom" : "universal",
"scale" : "1x"
},
{
"filename" : "Swipe2Up@2x.png",
"idiom" : "universal",
"scale" : "2x"
},
{
"filename" : "Swipe2Up@3x.png",
"idiom" : "universal",
"scale" : "3x"
}
],
"info" : {
"author" : "xcode",
"version" : 1
},
"properties" : {
"template-rendering-intent" : "template"
}
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.0 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.4 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 4.3 KiB

View File

@ -1,7 +1,10 @@
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="8150" systemVersion="15A204g" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" initialViewController="01J-lp-oVM">
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="17156" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" launchScreen="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="01J-lp-oVM">
<device id="retina6_1" orientation="portrait" appearance="light"/>
<dependencies>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="8122"/>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="17125"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
@ -13,10 +16,9 @@
<viewControllerLayoutGuide type="bottom" id="xb3-aO-Qok"/>
</layoutGuides>
<view key="view" contentMode="scaleToFill" id="Ze5-6b-2t3">
<rect key="frame" x="0.0" y="0.0" width="600" height="600"/>
<rect key="frame" x="0.0" y="0.0" width="414" height="896"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<animations/>
<color key="backgroundColor" white="1" alpha="1" colorSpace="custom" customColorSpace="calibratedWhite"/>
<color key="backgroundColor" white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</view>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="iYj-Kq-Ea1" userLabel="First Responder" sceneMemberID="firstResponder"/>

View File

@ -1,16 +1,17 @@
<?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="16096" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<document type="com.apple.InterfaceBuilder3.CocoaTouch.Storyboard.XIB" version="3.0" toolsVersion="20037" targetRuntime="iOS.CocoaTouch" propertyAccessControl="none" useAutolayout="YES" useTraitCollections="YES" colorMatched="YES" initialViewController="BYZ-38-t0r">
<device id="retina5_9" orientation="portrait" appearance="light"/>
<dependencies>
<deployment identifier="iOS"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="16086"/>
<plugIn identifier="com.apple.InterfaceBuilder.IBCocoaTouchPlugin" version="20020"/>
<capability name="System colors in document resources" minToolsVersion="11.0"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies>
<scenes>
<!--View Controller-->
<scene sceneID="tne-QT-ifu">
<objects>
<viewController id="BYZ-38-t0r" customClass="ViewController" sceneMemberID="viewController">
<viewController modalPresentationStyle="currentContext" id="BYZ-38-t0r" customClass="ViewController" sceneMemberID="viewController">
<layoutGuides>
<viewControllerLayoutGuide type="top" id="y3c-jy-aDJ"/>
<viewControllerLayoutGuide type="bottom" id="wfy-db-euE"/>
@ -23,24 +24,194 @@
<rect key="frame" x="0.0" y="44" width="375" height="734"/>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</view>
<visualEffectView hidden="YES" opaque="NO" contentMode="scaleToFill" translatesAutoresizingMaskIntoConstraints="NO" id="o5Z-in-kcg">
<rect key="frame" x="37.666666666666657" y="186" width="300" height="440"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" id="VP8-Cw-QnG">
<rect key="frame" x="0.0" y="0.0" width="300" height="440"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<subviews>
<visualEffectView opaque="NO" contentMode="scaleToFill" fixedFrame="YES" translatesAutoresizingMaskIntoConstraints="NO" id="6hC-03-7fj">
<rect key="frame" x="0.0" y="0.0" width="60" height="312"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<view key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" insetsLayoutMarginsFromSafeArea="NO" id="BAe-j4-Jso">
<rect key="frame" x="0.0" y="0.0" width="60" height="312"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
</view>
<vibrancyEffect>
<blurEffect style="regular"/>
</vibrancyEffect>
</visualEffectView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Gestures" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="Mtd-2d-R6u">
<rect key="frame" x="0.0" y="28" width="300" height="21"/>
<fontDescription key="fontDescription" type="system" weight="medium" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Swipe2Left" translatesAutoresizingMaskIntoConstraints="NO" id="pzY-d9-3Z5">
<rect key="frame" x="15" y="66" width="64" height="64"/>
<color key="tintColor" systemColor="labelColor"/>
<constraints>
<constraint firstAttribute="height" constant="64" id="CmV-Bq-j5o"/>
<constraint firstAttribute="width" constant="64" id="gH6-fx-cgO"/>
</constraints>
</imageView>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Swipe2Right" translatesAutoresizingMaskIntoConstraints="NO" id="7WX-Kv-Q7i">
<rect key="frame" x="15" y="152" width="64" height="64"/>
<color key="tintColor" systemColor="labelColor"/>
<constraints>
<constraint firstAttribute="height" constant="64" id="8yn-GP-Kd1"/>
<constraint firstAttribute="width" constant="64" id="dEn-fC-loh"/>
</constraints>
</imageView>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Swipe2Up" translatesAutoresizingMaskIntoConstraints="NO" id="ogt-xN-NKI">
<rect key="frame" x="15" y="238" width="64" height="64"/>
<color key="tintColor" systemColor="labelColor"/>
<constraints>
<constraint firstAttribute="height" constant="64" id="L2w-OD-WT1"/>
<constraint firstAttribute="width" constant="64" id="yKv-YC-eFy"/>
</constraints>
</imageView>
<imageView clipsSubviews="YES" userInteractionEnabled="NO" contentMode="scaleAspectFit" horizontalHuggingPriority="251" verticalHuggingPriority="251" image="Swipe2Down" translatesAutoresizingMaskIntoConstraints="NO" id="GSB-g7-f2Y">
<rect key="frame" x="15" y="324" width="64" height="64"/>
<color key="tintColor" systemColor="labelColor"/>
<constraints>
<constraint firstAttribute="width" constant="64" id="1ZM-my-t5g"/>
<constraint firstAttribute="height" constant="64" id="9hg-7C-WG2"/>
</constraints>
</imageView>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Insert Disk" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="IYD-cg-suz">
<rect key="frame" x="87" y="66" width="80.666666666666686" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Swipe left with two fingers" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="SsX-0c-kRw">
<rect key="frame" x="87" y="95" width="167" height="17"/>
<fontDescription key="fontDescription" type="system" weight="light" pointSize="14"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Show Settings" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="pNn-B0-E5z">
<rect key="frame" x="87" y="152" width="110" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Swipe right with two fingers" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="lHi-aV-uGo">
<rect key="frame" x="86.999999999999986" y="181" width="175.66666666666663" height="17"/>
<fontDescription key="fontDescription" type="system" weight="light" pointSize="14"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Show Keyboard" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="QcY-8W-bqI">
<rect key="frame" x="87" y="238" width="119" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Swipe up with two fingers" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="6u4-fn-SWw">
<rect key="frame" x="86.999999999999986" y="267" width="162.66666666666663" height="17"/>
<fontDescription key="fontDescription" type="system" weight="light" pointSize="14"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Hide Keyboard" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="8kk-bG-T9V">
<rect key="frame" x="87" y="324" width="112" height="21"/>
<fontDescription key="fontDescription" type="system" pointSize="17"/>
<nil key="textColor"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="Swipe down with two fingers" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="5ZP-Fp-fg5">
<rect key="frame" x="87" y="353" width="182" height="17"/>
<fontDescription key="fontDescription" type="system" weight="light" pointSize="14"/>
<nil key="highlightedColor"/>
</label>
<label opaque="NO" userInteractionEnabled="NO" contentMode="left" horizontalHuggingPriority="251" verticalHuggingPriority="251" text="you can disable this help in Settings" textAlignment="center" lineBreakMode="tailTruncation" baselineAdjustment="alignBaselines" adjustsFontForContentSizeCategory="YES" adjustsFontSizeToFit="NO" translatesAutoresizingMaskIntoConstraints="NO" id="eaR-vV-QQc">
<rect key="frame" x="0.0" y="417.66666666666663" width="300" height="14.333333333333314"/>
<fontDescription key="fontDescription" type="system" weight="light" pointSize="11"/>
<nil key="highlightedColor"/>
</label>
</subviews>
<constraints>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="5ZP-Fp-fg5" secondAttribute="trailing" constant="8" id="9Gu-y0-PaJ"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="pNn-B0-E5z" secondAttribute="trailing" constant="8" id="9QD-19-je9"/>
<constraint firstItem="8kk-bG-T9V" firstAttribute="leading" secondItem="GSB-g7-f2Y" secondAttribute="trailing" constant="8" id="Anm-7T-dRr"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="6u4-fn-SWw" secondAttribute="trailing" constant="8" id="CzZ-uK-QDB"/>
<constraint firstItem="pzY-d9-3Z5" firstAttribute="leading" secondItem="VP8-Cw-QnG" secondAttribute="leading" constant="15" id="Ece-TK-n4P"/>
<constraint firstItem="lHi-aV-uGo" firstAttribute="top" secondItem="pNn-B0-E5z" secondAttribute="bottom" constant="8" id="JPX-71-3Bt"/>
<constraint firstItem="5ZP-Fp-fg5" firstAttribute="top" secondItem="8kk-bG-T9V" secondAttribute="bottom" constant="8" id="PRj-jH-UYX"/>
<constraint firstItem="IYD-cg-suz" firstAttribute="leading" secondItem="pzY-d9-3Z5" secondAttribute="trailing" constant="8" id="PVd-ls-uzM"/>
<constraint firstItem="GSB-g7-f2Y" firstAttribute="top" secondItem="ogt-xN-NKI" secondAttribute="bottom" constant="22" id="Pr9-tm-GBe"/>
<constraint firstItem="IYD-cg-suz" firstAttribute="top" secondItem="pzY-d9-3Z5" secondAttribute="top" id="QaT-ga-RpH"/>
<constraint firstItem="QcY-8W-bqI" firstAttribute="top" secondItem="ogt-xN-NKI" secondAttribute="top" id="TCj-tJ-mir"/>
<constraint firstItem="lHi-aV-uGo" firstAttribute="leading" secondItem="7WX-Kv-Q7i" secondAttribute="trailing" constant="8" id="TZw-2f-LzT"/>
<constraint firstItem="7WX-Kv-Q7i" firstAttribute="top" secondItem="pzY-d9-3Z5" secondAttribute="bottom" constant="22" id="Tfj-P8-Hjm"/>
<constraint firstItem="Mtd-2d-R6u" firstAttribute="top" secondItem="VP8-Cw-QnG" secondAttribute="top" constant="28" id="UjE-40-eQC"/>
<constraint firstItem="5ZP-Fp-fg5" firstAttribute="leading" secondItem="GSB-g7-f2Y" secondAttribute="trailing" constant="8" id="UpC-yy-CJC"/>
<constraint firstItem="6u4-fn-SWw" firstAttribute="top" secondItem="QcY-8W-bqI" secondAttribute="bottom" constant="8" id="Uxi-MW-Pdu"/>
<constraint firstItem="Mtd-2d-R6u" firstAttribute="width" secondItem="VP8-Cw-QnG" secondAttribute="width" id="Wzq-tS-xNx"/>
<constraint firstItem="Mtd-2d-R6u" firstAttribute="centerX" secondItem="VP8-Cw-QnG" secondAttribute="centerX" id="YIO-q1-Kal"/>
<constraint firstItem="pzY-d9-3Z5" firstAttribute="top" secondItem="Mtd-2d-R6u" secondAttribute="bottom" constant="17" id="Yiv-2o-k6a"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="IYD-cg-suz" secondAttribute="trailing" constant="8" id="Zl8-zx-U7H"/>
<constraint firstItem="pNn-B0-E5z" firstAttribute="top" secondItem="7WX-Kv-Q7i" secondAttribute="top" id="aNO-vN-07B"/>
<constraint firstItem="SsX-0c-kRw" firstAttribute="top" secondItem="IYD-cg-suz" secondAttribute="bottom" constant="8" id="ay6-dS-d9s"/>
<constraint firstItem="GSB-g7-f2Y" firstAttribute="leading" secondItem="VP8-Cw-QnG" secondAttribute="leading" constant="15" id="gZm-k7-TnC"/>
<constraint firstItem="eaR-vV-QQc" firstAttribute="width" secondItem="VP8-Cw-QnG" secondAttribute="width" id="hGL-WS-EBl"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="lHi-aV-uGo" secondAttribute="trailing" constant="8" id="imt-CF-8d7"/>
<constraint firstItem="ogt-xN-NKI" firstAttribute="leading" secondItem="VP8-Cw-QnG" secondAttribute="leading" constant="15" id="ivK-8T-nqE"/>
<constraint firstItem="QcY-8W-bqI" firstAttribute="leading" secondItem="ogt-xN-NKI" secondAttribute="trailing" constant="8" id="j2z-Af-SeH"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="SsX-0c-kRw" secondAttribute="trailing" constant="8" id="kFP-MT-M1q"/>
<constraint firstItem="pNn-B0-E5z" firstAttribute="leading" secondItem="7WX-Kv-Q7i" secondAttribute="trailing" constant="8" id="mor-uC-od4"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="8kk-bG-T9V" secondAttribute="trailing" constant="8" id="nvs-GX-kwP"/>
<constraint firstItem="6u4-fn-SWw" firstAttribute="leading" secondItem="ogt-xN-NKI" secondAttribute="trailing" constant="8" id="pEX-d7-Ybb"/>
<constraint firstItem="eaR-vV-QQc" firstAttribute="centerX" secondItem="VP8-Cw-QnG" secondAttribute="centerX" id="r6H-B1-mRG"/>
<constraint firstItem="8kk-bG-T9V" firstAttribute="top" secondItem="GSB-g7-f2Y" secondAttribute="top" id="u9p-vU-w4i"/>
<constraint firstAttribute="trailing" relation="greaterThanOrEqual" secondItem="QcY-8W-bqI" secondAttribute="trailing" constant="8" id="uVe-7l-e36"/>
<constraint firstItem="ogt-xN-NKI" firstAttribute="top" secondItem="7WX-Kv-Q7i" secondAttribute="bottom" constant="22" id="xRf-Rk-xeC"/>
<constraint firstAttribute="bottom" secondItem="eaR-vV-QQc" secondAttribute="bottom" constant="8" id="xp5-4f-TyT"/>
<constraint firstItem="SsX-0c-kRw" firstAttribute="leading" secondItem="pzY-d9-3Z5" secondAttribute="trailing" constant="8" id="yXo-zt-NvQ"/>
<constraint firstItem="7WX-Kv-Q7i" firstAttribute="leading" secondItem="VP8-Cw-QnG" secondAttribute="leading" constant="15" id="z6y-It-hYy"/>
</constraints>
</view>
<gestureRecognizers/>
<constraints>
<constraint firstAttribute="width" constant="300" id="iDK-VU-jRi"/>
<constraint firstAttribute="height" constant="440" id="vKz-Fv-ZLf"/>
</constraints>
<blurEffect style="regular"/>
<userDefinedRuntimeAttributes>
<userDefinedRuntimeAttribute type="number" keyPath="layer.cornerRadius">
<integer key="value" value="25"/>
</userDefinedRuntimeAttribute>
<userDefinedRuntimeAttribute type="boolean" keyPath="layer.masksToBounds" value="YES"/>
</userDefinedRuntimeAttributes>
<connections>
<outletCollection property="gestureRecognizers" destination="LgR-E7-y3z" appends="YES" id="xAw-L3-sm3"/>
</connections>
</visualEffectView>
</subviews>
<color key="backgroundColor" red="0.0" green="0.0" blue="0.0" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
<constraints>
<constraint firstItem="o5Z-in-kcg" firstAttribute="centerY" secondItem="8bC-Xf-vdC" secondAttribute="centerY" id="0jF-Nq-kPe"/>
<constraint firstItem="70W-4V-tYr" firstAttribute="bottom" secondItem="wfy-db-euE" secondAttribute="top" id="Xn1-gS-YTJ"/>
<constraint firstItem="o5Z-in-kcg" firstAttribute="centerX" secondItem="8bC-Xf-vdC" secondAttribute="centerX" id="bHO-kd-35A"/>
<constraint firstItem="70W-4V-tYr" firstAttribute="leading" secondItem="8bC-Xf-vdC" secondAttribute="leading" id="ddo-cc-64n"/>
<constraint firstItem="70W-4V-tYr" firstAttribute="top" secondItem="y3c-jy-aDJ" secondAttribute="bottom" id="e9i-3F-kaI"/>
<constraint firstAttribute="trailing" secondItem="70W-4V-tYr" secondAttribute="trailing" id="kDH-sv-91j"/>
</constraints>
</view>
<connections>
<outlet property="helpView" destination="o5Z-in-kcg" id="eha-6S-KGo"/>
<outlet property="screenView" destination="70W-4V-tYr" id="W9r-vA-9kk"/>
<segue destination="DCD-sd-Fu5" kind="presentation" identifier="disk" modalPresentationStyle="formSheet" id="wkd-we-QI6"/>
<segue destination="j8f-3L-8mp" kind="presentation" identifier="settings" modalPresentationStyle="formSheet" id="ak4-wm-owU"/>
<segue destination="cRQ-kQ-dxG" kind="presentation" identifier="disk" id="WX7-3F-M1R"/>
<segue destination="BoP-db-djl" kind="presentation" identifier="settings" id="QXf-fV-uw4"/>
</connections>
</viewController>
<placeholder placeholderIdentifier="IBFirstResponder" id="dkx-z0-nzr" sceneMemberID="firstResponder"/>
<tapGestureRecognizer id="LgR-E7-y3z">
<connections>
<action selector="hideGestureHelp:" destination="BYZ-38-t0r" id="Rgz-KD-Scl"/>
</connections>
</tapGestureRecognizer>
</objects>
<point key="canvasLocation" x="548" y="390.14778325123154"/>
<point key="canvasLocation" x="344.80000000000001" y="380.54187192118229"/>
</scene>
<!--Settings-->
<scene sceneID="Lht-Fe-oRx">
@ -49,10 +220,10 @@
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="grouped" separatorStyle="default" rowHeight="44" sectionHeaderHeight="18" sectionFooterHeight="18" id="9gA-gD-7Wx">
<rect key="frame" x="0.0" y="0.0" width="375" height="758"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" cocoaTouchSystemColor="groupTableViewBackgroundColor"/>
<color key="backgroundColor" systemColor="groupTableViewBackgroundColor"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="speed" id="v4I-0T-H8m">
<rect key="frame" x="0.0" y="55.333332061767578" width="375" height="44"/>
<rect key="frame" x="0.0" y="49" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="v4I-0T-H8m" id="cO5-De-1JT">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
@ -82,7 +253,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="mouse" id="JgY-zN-3ID">
<rect key="frame" x="0.0" y="99.333332061767578" width="375" height="44"/>
<rect key="frame" x="0.0" y="93" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="JgY-zN-3ID" id="iUk-se-WGk">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
@ -111,7 +282,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="keyboard" textLabel="6WO-0z-y7c" style="IBUITableViewCellStyleDefault" id="q7C-00-4ss">
<rect key="frame" x="0.0" y="143.33333206176758" width="375" height="44"/>
<rect key="frame" x="0.0" y="137" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="q7C-00-4ss" id="yUn-mI-DwM">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
@ -127,7 +298,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationWidth="60" reuseIdentifier="machine" textLabel="znE-ML-UrQ" detailTextLabel="xcq-HY-ZDe" style="IBUITableViewCellStyleSubtitle" id="MGj-K1-5lZ">
<rect key="frame" x="0.0" y="187.33333206176758" width="375" height="44"/>
<rect key="frame" x="0.0" y="181" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="MGj-K1-5lZ" id="ueO-zm-JQP">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
@ -143,7 +314,7 @@
<rect key="frame" x="15.999999999999998" y="25.333333333333332" width="30.333333333333332" height="13.333333333333334"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="11"/>
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
<color key="textColor" systemColor="secondaryLabelColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
@ -151,7 +322,7 @@
<inset key="separatorInset" minX="0.0" minY="0.0" maxX="0.0" maxY="0.0"/>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="none" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="display" id="P6n-Bf-s6h">
<rect key="frame" x="0.0" y="231.33333206176758" width="375" height="44"/>
<rect key="frame" x="0.0" y="225" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="P6n-Bf-s6h" id="NgN-Fe-hXo">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
@ -177,7 +348,7 @@
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="about" textLabel="YWX-qF-gPj" detailTextLabel="xr3-v1-hzM" style="IBUITableViewCellStyleValue1" id="Mon-vq-IrO">
<rect key="frame" x="0.0" y="275.33333206176758" width="375" height="44"/>
<rect key="frame" x="0.0" y="269" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="Mon-vq-IrO" id="mGZ-Jb-6j4">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
@ -193,14 +364,14 @@
<rect key="frame" x="317.33333333333331" y="12.999999999999998" width="41.666666666666664" height="19.333333333333332"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="16"/>
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
<color key="textColor" systemColor="secondaryLabelColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
</tableViewCell>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="toggle" textLabel="a1l-XI-MEz" style="IBUITableViewCellStyleDefault" id="1nB-54-Qfk">
<rect key="frame" x="0.0" y="319.33333206176758" width="375" height="44"/>
<rect key="frame" x="0.0" y="313" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="1nB-54-Qfk" id="fZu-5X-Z4B">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
@ -240,20 +411,40 @@
<point key="canvasLocation" x="1996" y="31"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="UQ7-sc-pir">
<scene sceneID="4eA-xl-dqR">
<objects>
<navigationController storyboardIdentifier="settings" id="j8f-3L-8mp" sceneMemberID="viewController">
<navigationBar key="navigationBar" contentMode="scaleToFill" id="7OA-7b-rux">
<navigationController storyboardIdentifier="settings" id="BoP-db-djl" sceneMemberID="viewController">
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="0OU-GK-QgK">
<rect key="frame" x="0.0" y="0.0" width="375" height="56"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<connections>
<segue destination="WUA-f8-k8g" kind="relationship" relationship="rootViewController" id="Zpb-kg-HM5"/>
<segue destination="WUA-f8-k8g" kind="relationship" relationship="rootViewController" id="pw5-9i-jPL"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="8IW-lr-03G" userLabel="First Responder" sceneMemberID="firstResponder"/>
<placeholder placeholderIdentifier="IBFirstResponder" id="Jpf-Y3-KcP" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1318" y="31"/>
<point key="canvasLocation" x="1270" y="30"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="HCe-cW-vFN">
<objects>
<navigationController storyboardIdentifier="disk" toolbarHidden="NO" id="cRQ-kQ-dxG" sceneMemberID="viewController">
<navigationBar key="navigationBar" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="Aek-q5-RuY">
<rect key="frame" x="0.0" y="0.0" width="375" height="56"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<toolbar key="toolbar" opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" insetsLayoutMarginsFromSafeArea="NO" id="Cuq-Py-BdB">
<rect key="frame" x="0.0" y="675" width="375" height="49"/>
<autoresizingMask key="autoresizingMask"/>
</toolbar>
<connections>
<segue destination="mbX-kA-h6M" kind="relationship" relationship="rootViewController" id="X1p-Xh-YQJ"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="DV1-vt-RIw" userLabel="First Responder" customClass="UIResponder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1270" y="734"/>
</scene>
<!--Insert Disk-->
<scene sceneID="a1s-tB-X2g">
@ -262,10 +453,10 @@
<tableView key="view" clipsSubviews="YES" contentMode="scaleToFill" alwaysBounceVertical="YES" dataMode="prototypes" style="plain" separatorStyle="default" rowHeight="44" sectionHeaderHeight="28" sectionFooterHeight="28" id="EFr-QR-Vqc">
<rect key="frame" x="0.0" y="0.0" width="375" height="758"/>
<autoresizingMask key="autoresizingMask" widthSizable="YES" heightSizable="YES"/>
<color key="backgroundColor" systemColor="systemBackgroundColor" cocoaTouchSystemColor="whiteColor"/>
<color key="backgroundColor" systemColor="systemBackgroundColor"/>
<prototypes>
<tableViewCell clipsSubviews="YES" contentMode="scaleToFill" selectionStyle="blue" hidesAccessoryWhenEditing="NO" indentationLevel="1" indentationWidth="0.0" reuseIdentifier="cell" textLabel="8ef-Se-DXA" detailTextLabel="CbL-Kq-e9s" style="IBUITableViewCellStyleValue1" id="iZQ-DG-qho" customClass="FileTableViewCell">
<rect key="frame" x="0.0" y="28" width="375" height="44"/>
<rect key="frame" x="0.0" y="44.666666030883789" width="375" height="44"/>
<autoresizingMask key="autoresizingMask"/>
<tableViewCellContentView key="contentView" opaque="NO" clipsSubviews="YES" multipleTouchEnabled="YES" contentMode="center" tableViewCell="iZQ-DG-qho" id="pcB-3f-clB">
<rect key="frame" x="0.0" y="0.0" width="375" height="44"/>
@ -281,12 +472,12 @@
<rect key="frame" x="324" y="16" width="35" height="15.666666666666666"/>
<autoresizingMask key="autoresizingMask" flexibleMaxX="YES" flexibleMaxY="YES"/>
<fontDescription key="fontDescription" type="system" pointSize="13"/>
<color key="textColor" systemColor="secondaryLabelColor" red="0.23529411759999999" green="0.23529411759999999" blue="0.26274509800000001" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
<color key="textColor" systemColor="secondaryLabelColor"/>
<nil key="highlightedColor"/>
</label>
</subviews>
</tableViewCellContentView>
<color key="tintColor" systemColor="labelColor" cocoaTouchSystemColor="darkTextColor"/>
<color key="tintColor" systemColor="labelColor"/>
</tableViewCell>
</prototypes>
<connections>
@ -334,31 +525,27 @@
</objects>
<point key="canvasLocation" x="2102" y="734"/>
</scene>
<!--Navigation Controller-->
<scene sceneID="V4m-xV-cjV">
<objects>
<navigationController storyboardIdentifier="disk" toolbarHidden="NO" id="DCD-sd-Fu5" sceneMemberID="viewController">
<navigationBar key="navigationBar" contentMode="scaleToFill" id="jFP-L0-vQk">
<rect key="frame" x="0.0" y="0.0" width="375" height="56"/>
<autoresizingMask key="autoresizingMask"/>
</navigationBar>
<toolbar key="toolbar" opaque="NO" clearsContextBeforeDrawing="NO" contentMode="scaleToFill" id="TXk-M9-69L">
<rect key="frame" x="0.0" y="675" width="375" height="49"/>
<autoresizingMask key="autoresizingMask"/>
</toolbar>
<connections>
<segue destination="mbX-kA-h6M" kind="relationship" relationship="rootViewController" id="2hT-RO-fgU"/>
</connections>
</navigationController>
<placeholder placeholderIdentifier="IBFirstResponder" id="oTI-h8-BGr" userLabel="First Responder" sceneMemberID="firstResponder"/>
</objects>
<point key="canvasLocation" x="1318" y="735"/>
</scene>
</scenes>
<resources>
<image name="Interrupt" width="30" height="30"/>
<image name="Reset" width="30" height="30"/>
<image name="Settings" width="30" height="30"/>
<image name="Swipe2Down" width="64" height="64"/>
<image name="Swipe2Left" width="64" height="64"/>
<image name="Swipe2Right" width="64" height="64"/>
<image name="Swipe2Up" width="64" height="64"/>
<image name="floppy30" width="30" height="30"/>
<systemColor name="groupTableViewBackgroundColor">
<color red="0.94901960784313721" green="0.94901960784313721" blue="0.96862745098039216" alpha="1" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="labelColor">
<color white="0.0" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
<systemColor name="secondaryLabelColor">
<color red="0.23529411764705882" green="0.23529411764705882" blue="0.2627450980392157" alpha="0.59999999999999998" colorSpace="custom" customColorSpace="sRGB"/>
</systemColor>
<systemColor name="systemBackgroundColor">
<color white="1" alpha="1" colorSpace="custom" customColorSpace="genericGamma22GrayColorSpace"/>
</systemColor>
</resources>
</document>

View File

@ -1,97 +0,0 @@
#include <stdint.h>
#include <unistd.h>
#define BigEndianUnaligned 0
#define LittleEndianUnaligned 1
#define MayInline inline
#define MayNotInline __attribute__((noinline))
#define SmallGlobals 0
#define cIncludeUnused 0
#define UnusedParam(p) (void) p
#define AutoTimeZone 1
#define AutoLocation 1
/* --- integer types ---- */
typedef uint8_t ui3b;
#define HaveRealui3b 1
typedef int8_t si3b;
#define HaveRealsi3b 1
typedef uint16_t ui4b;
#define HaveRealui4b 1
typedef int16_t si4b;
#define HaveRealsi4b 1
typedef uint32_t ui5b;
#define HaveRealui5b 1
typedef int32_t si5b;
#define HaveRealsi5b 1
#define HaveRealui6b 1
#define HaveRealsi6b 1
/* --- integer representation types ---- */
typedef ui3b ui3r;
#define ui3beqr 1
typedef si3b si3r;
#define si3beqr 1
typedef ui4b ui4r;
#define ui4beqr 1
typedef si4b si4r;
#define si4beqr 1
typedef ui5b ui5r;
#define ui5beqr 1
typedef si5b si5r;
#define si5beqr 1
typedef int64_t si6r;
typedef int64_t si6b;
typedef uint64_t ui6r;
typedef uint64_t ui6b;
#define LIT64(a) a##ULL
/* --- shared config for all variants ---- */
#define NeedIntlChars 1
#define kStrAppName "Mini vMac"
#define kAppVariationStr "minivmac-3.5.8-ios"
#define kStrCopyrightYear "2018"
#define kMaintainerName "Jesús A. Álvarez"
#define kStrHomePage "https://namedfork.net/minivmac"
#define VarFullScreen 0
#define WantInitFullScreen 0
#define MayFullScreen 1
#define WantInitMagnify 0
#define WantInitRunInBackground 0
#define NeedRequestInsertDisk 0
#define NeedDoMoreCommandsMsg 0
#define NeedDoAboutMsg 0
#define UseControlKeys 0
#define UseActvCode 0
#define EnableDemoMsg 0
#define IncludePbufs 1
#define NumPbufs 4
#define dbglog_HAVE 0
#define EnableMouseMotion 1
#define IncludeHostTextClipExchange 1
#define IncludeSonyRawMode 1
#define IncludeSonyGetName 1
#define IncludeSonyNew 1
#define IncludeSonyNameNew 1
#define EmLocalTalk 0

72
Mini vMac/CNFUIALL.h Normal file
View File

@ -0,0 +1,72 @@
/*
see comment in OSGCOMUI.h
This file is automatically generated by the build system,
which tries to know what options are valid in what
combinations. Avoid changing this file manually unless
you know what you're doing.
*/
#include <stdint.h>
#define MayInline inline __attribute__((always_inline))
#define MayNotInline __attribute__((noinline))
#define SmallGlobals 0
#define cIncludeUnused 0
#define UnusedParam(p) (void) p
/* --- integer types ---- */
typedef unsigned char ui3b;
#define HaveRealui3b 1
typedef signed char si3b;
#define HaveRealsi3b 1
typedef unsigned short ui4b;
#define HaveRealui4b 1
typedef short si4b;
#define HaveRealsi4b 1
typedef unsigned int ui5b;
#define HaveRealui5b 1
typedef int si5b;
#define HaveRealsi5b 1
#define HaveRealui6b 1
#define HaveRealsi6b 1
/* --- integer representation types ---- */
typedef ui3b ui3r;
#define ui3beqr 1
typedef si3b si3r;
#define si3beqr 1
typedef ui4b ui4r;
#define ui4beqr 1
typedef si4b si4r;
#define si4beqr 1
typedef ui5b ui5r;
#define ui5beqr 1
typedef si5b si5r;
#define si5beqr 1
typedef int64_t si6r;
typedef int64_t si6b;
typedef uint64_t ui6r;
typedef uint64_t ui6b;
#define LIT64(a) a##ULL
#define NeedIntlChars 1
#define kStrAppName "Mini vMac"
#define kAppVariationStr "minivmac-b37-ios"
#define kStrCopyrightYear "2023"
#define kMaintainerName "Jesús A. Álvarez"
#define kStrHomePage "https://namedfork.net/minivmac"

16
Mini vMac/CNFUIOSG.h Normal file
View File

@ -0,0 +1,16 @@
/*
see comment in OSGCOMUI.h
This file is automatically generated by the build system,
which tries to know what options are valid in what
combinations. Avoid changing this file manually unless
you know what you're doing.
*/
#import <Foundation/Foundation.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <sys/param.h>
#include <sys/time.h>

8
Mini vMac/CNFUIPIC.h Normal file
View File

@ -0,0 +1,8 @@
/*
see comment in PICOMMON.h
This file is automatically generated by the build system,
which tries to know what options are valid in what
combinations. Avoid changing this file manually unless
you know what you're doing.
*/

View File

@ -0,0 +1,64 @@
//
// DefaultSceneDelegate.swift
// Mini vMac
//
// Created by Jesús A. Álvarez on 2024-02-09.
// Copyright © 2024 namedfork. All rights reserved.
//
import UIKit
class DefaultSceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow? // keep window reference to be able to set background colour before destroying
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = scene as? UIWindowScene else {
fatalError("Expected scene of type UIWindowScene but got an unexpected type")
}
guard let appDelegate = AppDelegate.shared else {
fatalError("No app delegate")
}
let size = CGSize(width: 1024.0, height: 684.0)
windowScene.sizeRestrictions?.minimumSize = size
windowScene.sizeRestrictions?.maximumSize = size
window = UIWindow(windowScene: windowScene)
if let window {
appDelegate.window = window
window.rootViewController = UIStoryboard(name: "Main", bundle: .main).instantiateInitialViewController()
window.makeKeyAndVisible()
}
self.destroyOtherSessions(not: session)
}
private func destroyOtherSessions(not session: UISceneSession) {
let app = UIApplication.shared
let options = UIWindowSceneDestructionRequestOptions()
options.windowDismissalAnimation = .decline
for otherSession in app.openSessions.filter({ $0 != session && $0.configuration.name == "Default"}) {
if let window = (otherSession.scene as? UIWindowScene)?.windows.first {
window.rootViewController?.view.removeFromSuperview()
window.backgroundColor = .darkGray
app.requestSceneSessionRefresh(otherSession)
}
app.requestSceneSessionDestruction(otherSession, options: options)
// window will remain visible until window switcher is dismissed!
}
}
func sceneDidEnterBackground(_ scene: UIScene) {
let app = UIApplication.shared
if UserDefaults.standard.bool(forKey: "runInBackground") == false && app.connectedScenes.filter({ $0 != scene && $0.session.configuration.name == "Default"}).isEmpty {
AppDelegate.emulator.isRunning = false
}
}
func sceneDidBecomeActive(_ scene: UIScene) {
AppDelegate.emulator.isRunning = true
}
func windowScene(_ windowScene: UIWindowScene, performActionFor shortcutItem: UIApplicationShortcutItem, completionHandler: @escaping (Bool) -> Void) {
AppDelegate.shared.application(UIApplication.shared, performActionFor: shortcutItem, completionHandler: completionHandler)
}
}

View File

@ -10,7 +10,7 @@
@import CoreGraphics;
@import QuartzCore;
typedef enum : NSInteger {
typedef NS_ENUM(NSInteger, EmulatorSpeed) {
EmulatorSpeedAllOut = -1,
EmulatorSpeed1x = 0,
EmulatorSpeed2x = 1,
@ -18,7 +18,7 @@ typedef enum : NSInteger {
EmulatorSpeed8x = 3,
EmulatorSpeed16x = 4,
EmulatorSpeed32x = 5
} EmulatorSpeed;
};
@protocol Emulator <NSObject>
@ -38,11 +38,13 @@ typedef enum : NSInteger {
@property (nonatomic, readonly) BOOL anyDiskInserted;
@property (nonatomic, readonly) NSString *currentApplication;
+ (instancetype)sharedEmulator;
@property (nonatomic, strong) void (^showAlert)(NSString *title, NSString *message);
@property (nonatomic, strong) UIViewController *rootViewController;
- (void)run;
- (void)reset;
- (void)interrupt;
- (void)shutdown;
- (void)keyDown:(int)scancode;
- (void)keyUp:(int)scancode;

View File

@ -76,7 +76,7 @@
<key>LSSupportsOpeningDocumentsInPlace</key>
<true/>
<key>MNVMVersion</key>
<string>36.04</string>
<string>b37.03</string>
<key>UIBackgroundModes</key>
<array>
<string>audio</string>
@ -92,9 +92,11 @@
<string>armv7</string>
</array>
<key>UIRequiresFullScreen</key>
<true/>
<false/>
<key>UIStatusBarHidden</key>
<true/>
<false/>
<key>UIStatusBarStyle</key>
<string>UIStatusBarStyleDefault</string>
<key>UISupportedInterfaceOrientations</key>
<array>
<string>UIInterfaceOrientationPortrait</string>
@ -174,5 +176,28 @@
</dict>
</dict>
</array>
<key>UIApplicationSceneManifest</key>
<dict>
<key>UIApplicationSupportsMultipleScenes</key>
<true/>
<key>UISceneConfigurations</key>
<dict>
<key>UIWindowSceneSessionRoleApplication</key>
<array>
<dict>
<key>UISceneConfigurationName</key>
<string>Default</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).DefaultSceneDelegate</string>
</dict>
<dict>
<key>UISceneConfigurationName</key>
<string>Keyboard</string>
<key>UISceneDelegateClassName</key>
<string>$(PRODUCT_MODULE_NAME).KeyboardSceneDelegate</string>
</dict>
</array>
</dict>
</dict>
</dict>
</plist>

View File

@ -10,7 +10,7 @@
#import "AppDelegate.h"
#import "UIImage+DiskImageIcon.h"
@interface InsertDiskViewController () <UITextFieldDelegate, UIAlertViewDelegate>
@interface InsertDiskViewController () <UITextFieldDelegate>
@end
@ -31,7 +31,6 @@
NSString *basePath;
NSArray<NSString*> *diskImages, *otherFiles;
UIAlertController *createDiskImageController;
UIAlertView *createDiskImageAlert;
__block __weak UITextField *sizeTextField;
__block __weak UITextField *nameTextField;
NSString *fileToRename;
@ -82,10 +81,10 @@
NSArray *allFiles = [[NSFileManager defaultManager] contentsOfDirectoryAtPath:basePath error:NULL];
diskImages = [allFiles filteredArrayUsingPredicate:[NSPredicate predicateWithFormat:@"%@ containsObject: pathExtension.lowercaseString", [AppDelegate sharedInstance].diskImageExtensions]];
otherFiles = [allFiles filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(NSString* _Nonnull name, NSDictionary<NSString *,id> * _Nullable bindings) {
BOOL isDiskImage = [diskImages containsObject:name];
BOOL isDiskImage = [self->diskImages containsObject:name];
BOOL isDirectory;
BOOL isHidden = [name hasPrefix:@"."];
[[NSFileManager defaultManager] fileExistsAtPath:[basePath stringByAppendingPathComponent:name] isDirectory:&isDirectory];
[[NSFileManager defaultManager] fileExistsAtPath:[self->basePath stringByAppendingPathComponent:name] isDirectory:&isDirectory];
return !(isDirectory || isDiskImage || isHidden);
}]];
}
@ -216,7 +215,7 @@
if (editingStyle == UITableViewCellEditingStyleDelete) {
NSString *filePath = [self fileAtIndexPath:indexPath];
if ([UIAlertController class]) {
[self askDeleteFile:filePath];
[self askDeleteFile:filePath sourceView:[tableView cellForRowAtIndexPath:indexPath]];
} else {
[self deleteFile:filePath];
}
@ -226,6 +225,9 @@
}
- (BOOL)tableView:(UITableView *)tableView shouldShowMenuForRowAtIndexPath:(nonnull NSIndexPath *)indexPath {
if (@available(iOS 13, *)) {
return NO;
}
return [self fileAtIndexPath:indexPath] != nil;
}
@ -239,15 +241,77 @@
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath {
NSString *filePath = [self fileAtIndexPath:indexPath];
if (filePath && ![[AppDelegate sharedEmulator] isDiskInserted:filePath]) {
[self dismissViewControllerAnimated:YES completion:^{
[[AppDelegate sharedEmulator] insertDisk:filePath];
}];
BOOL hadAnyDisksInserted = [AppDelegate sharedEmulator].anyDiskInserted;
if ([self insertDisk:filePath]) {
[self dismissViewControllerAnimated:YES completion:nil];
if (!hadAnyDisksInserted) {
// Add to quick actions if it was booted from (no disks inserted previously and still inserted after 10s)
dispatch_after(dispatch_time(DISPATCH_TIME_NOW, (int64_t)(10.0 * NSEC_PER_SEC)), dispatch_get_main_queue(), ^{
id<Emulator> emulator = [AppDelegate sharedEmulator];
if (emulator.isRunning && [emulator isDiskInserted:filePath]) {
[self updateApplicationShortcutsWithDisk:filePath];
}
});
}
}
}
#pragma mark - Quick Actions
- (void)updateApplicationShortcutsWithDisk:(NSString*)filePath {
// Update user defaults
NSUserDefaults *userDefaults = [NSUserDefaults standardUserDefaults];
NSString *fileName = filePath.lastPathComponent;
NSMutableArray *recentDisks = [userDefaults arrayForKey:@"recentDisks"].mutableCopy;
if ([recentDisks containsObject:fileName]) {
return;
}
[recentDisks insertObject:fileName atIndex:0];
if (recentDisks.count > 4) {
[recentDisks removeObjectsInRange:NSMakeRange(4, recentDisks.count - 4)];
}
[userDefaults setObject:recentDisks forKey:@"recentDisks"];
// Update quick actions
NSMutableArray *shortcutItems = [NSMutableArray arrayWithCapacity:4];
for (NSString *diskName in recentDisks) {
UIApplicationShortcutItem *shortcutItem = [self shortcutItemForDisk:diskName];
if (shortcutItem) {
[shortcutItems addObject:shortcutItem];
}
}
[UIApplication sharedApplication].shortcutItems = shortcutItems;
}
- (nullable UIApplicationShortcutItem*)shortcutItemForDisk:(NSString*)fileName {
BOOL isDiskImage = [[AppDelegate sharedInstance].diskImageExtensions containsObject:fileName.pathExtension.lowercaseString];
if (!isDiskImage) {
return nil;
}
NSString *filePath = [basePath stringByAppendingPathComponent:fileName];
NSString *title = [fileName stringByDeletingPathExtension];
UIApplicationShortcutIcon *icon = nil;
NSDictionary *attributes = [[NSURL fileURLWithPath:filePath] resourceValuesForKeys:@[NSURLTotalFileSizeKey, NSURLFileSizeKey] error:NULL];
if (attributes && attributes[NSURLTotalFileSizeKey]) {
NSInteger fileSize = [attributes[NSURLTotalFileSizeKey] integerValue];
NSInteger numBlocks = fileSize / 512;
icon = [UIApplicationShortcutIcon iconWithTemplateImageName:numBlocks == 800 || numBlocks == 1600 ? @"floppy" : @"floppyV"];
} else {
return nil;
}
return [[UIApplicationShortcutItem alloc] initWithType:@"disk" localizedTitle:title localizedSubtitle:nil icon:icon userInfo:@{@"disk": fileName}];
}
#pragma mark - File Actions
- (BOOL)insertDisk:(NSString*)filePath {
id<Emulator> emulator = [AppDelegate sharedEmulator];
if (filePath && ![emulator isDiskInserted:filePath]) {
return [emulator insertDisk:filePath];
}
return NO;
}
- (void)deleteFile:(NSString*)filePath {
NSError *error = nil;
if ([[NSFileManager defaultManager] removeItemAtPath:filePath error:&error]) {
@ -259,43 +323,33 @@
}
}
- (void)askDeleteFile:(NSString*)filePath {
- (void)askDeleteFile:(NSString*)filePath sourceView:(UIView*)sourceView {
NSString *fileName = filePath.lastPathComponent;
NSString *message = [NSString stringWithFormat:NSLocalizedString(@"Are you sure you want to delete %@? This operation cannot be undone.", nil), fileName];
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Delete File", nil) message:message preferredStyle:UIAlertControllerStyleAlert];
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Delete File", nil) message:message preferredStyle:UIAlertControllerStyleActionSheet];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil) style:UIAlertActionStyleCancel handler:nil]];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Delete", nil) style:UIAlertActionStyleDestructive handler:^(UIAlertAction * _Nonnull action) {
[self deleteFile:filePath];
}]];
alertController.popoverPresentationController.sourceView = sourceView;
[self presentViewController:alertController animated:YES completion:nil];
}
- (void)askRenameFile:(NSString*)filePath {
NSString *fileName = filePath.lastPathComponent;
if ([UIAlertController class]) {
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:fileName message:NSLocalizedString(@"Enter new name", nil) preferredStyle:UIAlertControllerStyleAlert];
[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
nameTextField = textField;
textField.delegate = self;
textField.placeholder = fileName;
textField.text = fileName;
}];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil) style:UIAlertActionStyleCancel handler:nil]];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Rename", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSString *newName = alertController.textFields.firstObject.text;
[self renameFile:filePath toName:newName];
}]];
[self presentViewController:alertController animated:YES completion:nil];
} else {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:fileName message:NSLocalizedString(@"Enter new name", nil) delegate:self cancelButtonTitle:NSLocalizedString(@"Cancel", nil) otherButtonTitles:NSLocalizedString(@"Rename", nil), nil];
alertView.alertViewStyle = UIAlertViewStylePlainTextInput;
nameTextField = [alertView textFieldAtIndex:0];
nameTextField.delegate = self;
nameTextField.placeholder = fileName;
nameTextField.text = fileName;
fileToRename = filePath;
[alertView show];
}
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:fileName message:NSLocalizedString(@"Enter new name", nil) preferredStyle:UIAlertControllerStyleAlert];
[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
self->nameTextField = textField;
textField.delegate = self;
textField.placeholder = fileName;
textField.text = fileName;
}];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil) style:UIAlertActionStyleCancel handler:nil]];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Rename", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSString *newName = alertController.textFields.firstObject.text;
[self renameFile:filePath toName:newName];
}]];
[self presentViewController:alertController animated:YES completion:nil];
}
- (void)renameFile:(NSString*)filePath toName:(NSString*)newName {
@ -319,39 +373,27 @@
#pragma mark - Disk Image Creation
- (void)createDiskImage {
if ([UIAlertController class]) {
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Create Disk Image", nil) message:nil preferredStyle:UIAlertControllerStyleAlert];
[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.placeholder = NSLocalizedString(@"name", nil);
[textField addTarget:self action:@selector(validateCreateDiskImageInput:) forControlEvents:UIControlEventAllEditingEvents];
}];
[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
[self _configureNewDiskSizeField:textField];
}];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil) style:UIAlertActionStyleCancel handler:nil]];
UIAlertAction *createAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Create", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSString *name = [self _newDiskImageName];
off_t size = [self _newDiskImageSize];
createDiskImageController = nil;
[self createDiskImageWithName:name size:size];
}];
[alertController addAction:createAction];
createAction.enabled = NO;
[self presentViewController:alertController animated:YES completion:nil];
createDiskImageController = alertController;
} else {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Create Disk Image", nil) message:nil delegate:self cancelButtonTitle:NSLocalizedString(@"Cancel", nil) otherButtonTitles:NSLocalizedString(@"Create", nil), nil];
alertView.alertViewStyle = UIAlertViewStyleLoginAndPasswordInput;
nameTextField = [alertView textFieldAtIndex:0];
nameTextField.delegate = self;
nameTextField.placeholder = NSLocalizedString(@"name", nil);
[nameTextField addTarget:self action:@selector(validateCreateDiskImageInput:) forControlEvents:UIControlEventAllEditingEvents];
[self _configureNewDiskSizeField:[alertView textFieldAtIndex:1]];
createDiskImageAlert = alertView;
[alertView show];
}
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Create Disk Image", nil) message:nil preferredStyle:UIAlertControllerStyleAlert];
[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
textField.placeholder = NSLocalizedString(@"name", nil);
[textField addTarget:self action:@selector(validateCreateDiskImageInput:) forControlEvents:UIControlEventAllEditingEvents];
}];
[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
[self _configureNewDiskSizeField:textField];
}];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil) style:UIAlertActionStyleCancel handler:nil]];
UIAlertAction *createAction = [UIAlertAction actionWithTitle:NSLocalizedString(@"Create", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
NSString *name = [self _newDiskImageName];
off_t size = [self _newDiskImageSize];
self->createDiskImageController = nil;
[self createDiskImageWithName:name size:size];
}];
[alertController addAction:createAction];
createAction.enabled = NO;
[self presentViewController:alertController animated:YES completion:nil];
createDiskImageController = alertController;
}
- (void)_configureNewDiskSizeField:(UITextField*)textField {
@ -378,7 +420,7 @@
- (BOOL)validateCreateDiskImageInput:(id)sender {
BOOL valid = NO;
if (self.presentedViewController == createDiskImageController || createDiskImageAlert.visible) {
if (self.presentedViewController == createDiskImageController) {
NSString *name = [self _newDiskImageName];
BOOL nameIsValid = (name.length > 0) && ![name hasPrefix:@"."] && ![name containsString:@"/"] && ![name containsString:@"*"];
@ -400,15 +442,13 @@
- (NSString*)_newDiskImageName {
if (createDiskImageController != nil) {
return createDiskImageController.textFields[0].text;
} else if (createDiskImageAlert.visible) {
return nameTextField.text;
} else {
return nil;
}
}
- (off_t)_newDiskImageSize {
if (createDiskImageController == nil && !createDiskImageAlert.visible) {
if (createDiskImageController == nil) {
return 0;
}
UISegmentedControl *unitsControl = (UISegmentedControl*)sizeTextField.rightView;
@ -427,51 +467,84 @@
return;
}
UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleWhiteLarge];
activityIndicatorView.color = [UIColor blackColor];
if ([UIAlertController class]) {
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Creating Disk Image", nil) message:@"\n\n\n" preferredStyle:UIAlertControllerStyleAlert];
[self presentViewController:alertController animated:true completion:^{
UIView *alertView = alertController.view;
activityIndicatorView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
activityIndicatorView.center = CGPointMake(alertView.bounds.size.width / 2.0, alertView.bounds.size.height / 2.0 + 32.0);
[alertView addSubview:activityIndicatorView];
[activityIndicatorView startAnimating];
[self _writeNewDiskImage:fd size:size activityIndicator:activityIndicatorView progressAlert:alertController];
}];
} else {
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Creating Disk Image", nil) message:nil delegate:nil cancelButtonTitle:nil otherButtonTitles:nil];
[alertView addSubview:activityIndicatorView];
[activityIndicatorView startAnimating];
[alertView setValue:activityIndicatorView forKey:@"accessoryView"];
[alertView show];
[self _writeNewDiskImage:fd size:size activityIndicator:activityIndicatorView progressAlert:alertView];
}
[self showFileActivityIndicatorWithTitle:NSLocalizedString(@"Creating Disk Image", nil) completion:^(UIActivityIndicatorView *activityIndicatorView) {
[self _writeNewDiskImage:fd size:size activityIndicator:activityIndicatorView];
}];
}
- (void)_writeNewDiskImage:(int)fd size:(off_t)size activityIndicator:(UIActivityIndicatorView*)activityIndicatorView progressAlert:(id)progressAlert {
long queue = NSFoundationVersionNumber >= NSFoundationVersionNumber_iOS_8_0 ? QOS_CLASS_USER_INITIATED : DISPATCH_QUEUE_PRIORITY_HIGH;
dispatch_async(dispatch_get_global_queue(queue, 0), ^{
- (void)showFileActivityIndicatorWithTitle:(NSString*)title completion:(void (^_Nonnull)(UIActivityIndicatorView* activityIndicatorView))completionBlock {
UIActivityIndicatorView *activityIndicatorView = [[UIActivityIndicatorView alloc] initWithActivityIndicatorStyle:UIActivityIndicatorViewStyleLarge];
if (@available(iOS 13, *)) {
activityIndicatorView.color = [UIColor labelColor];
} else {
activityIndicatorView.color = [UIColor blackColor];
}
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:@"\n\n\n" preferredStyle:UIAlertControllerStyleAlert];
[self presentViewController:alertController animated:true completion:^{
UIView *alertView = alertController.view;
activityIndicatorView.autoresizingMask = UIViewAutoresizingFlexibleLeftMargin | UIViewAutoresizingFlexibleRightMargin | UIViewAutoresizingFlexibleTopMargin | UIViewAutoresizingFlexibleBottomMargin;
activityIndicatorView.center = CGPointMake(alertView.bounds.size.width / 2.0, alertView.bounds.size.height / 2.0 + 32.0);
[alertView addSubview:activityIndicatorView];
[activityIndicatorView startAnimating];
completionBlock(activityIndicatorView);
}];
}
- (void)dismissFileActivityIndicator:(UIActivityIndicatorView*)activityIndicatorView withErrorTitle:(NSString*)errorTitle message:(NSString*)errorMessage {
dispatch_async(dispatch_get_main_queue(), ^{
[activityIndicatorView stopAnimating];
[self dismissViewControllerAnimated:YES completion:^{
if (errorTitle) {
[[AppDelegate sharedInstance] showAlertWithTitle:errorTitle message:errorMessage];
}
}];
[self.tableView beginUpdates];
[self loadDirectoryContents];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
[self.tableView endUpdates];
});
}
- (void)_writeNewDiskImage:(int)fd size:(off_t)size activityIndicator:(UIActivityIndicatorView*)activityIndicatorView {
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
int error = 0;
if (ftruncate(fd, size)) {
error = errno;
}
close(fd);
[self dismissFileActivityIndicator:activityIndicatorView
withErrorTitle:error ? NSLocalizedString(@"Could not create disk image", nil) : nil
message:error ? @(strerror(error)) : nil];
});
}
- (NSString*)nameForDuplicatingPath:(NSString*)filePath {
NSFileManager *fileManager = [NSFileManager defaultManager];
NSString *fileName = filePath.lastPathComponent;
NSString *copyPath = [NSString stringWithFormat:@"%@/%@ copy.%@", filePath.stringByDeletingLastPathComponent, fileName.lastPathComponent.stringByDeletingPathExtension, fileName.pathExtension];
for (int copyNumber = 2; [fileManager fileExistsAtPath:copyPath]; copyNumber++) {
copyPath = [NSString stringWithFormat:@"%@/%@ copy %d.%@", filePath.stringByDeletingLastPathComponent, fileName.lastPathComponent.stringByDeletingPathExtension, copyNumber, fileName.pathExtension];
}
return copyPath;
}
- (void)duplicateDiskImage:(NSString*)filePath {
[self showFileActivityIndicatorWithTitle:NSLocalizedString(@"Duplicating disk image", nil) completion:^(UIActivityIndicatorView *activityIndicatorView) {
[self _duplicateDiskImage:filePath activityIndicator:activityIndicatorView];
}];
}
- (void)_duplicateDiskImage:(NSString*)filePath activityIndicator:(UIActivityIndicatorView*)activityIndicatorView {
dispatch_async(dispatch_get_global_queue(QOS_CLASS_USER_INITIATED, 0), ^{
NSError *error = nil;
[[NSFileManager defaultManager] copyItemAtPath:filePath toPath:[self nameForDuplicatingPath:filePath] error:&error];
dispatch_async(dispatch_get_main_queue(), ^{
[activityIndicatorView stopAnimating];
if ([progressAlert isKindOfClass:[UIAlertController class]]) {
[self dismissViewControllerAnimated:YES completion:^{
if (error) {
[[AppDelegate sharedInstance] showAlertWithTitle:NSLocalizedString(@"Could not create disk image", nil) message:[[NSString alloc] initWithUTF8String:strerror(error)]];
}
}];
} else if ([progressAlert isKindOfClass:[UIAlertView class]]) {
UIAlertView *alert = progressAlert;
[alert dismissWithClickedButtonIndex:0 animated:NO];
[self dismissViewControllerAnimated:YES completion:^{
if (error) {
[[AppDelegate sharedInstance] showAlertWithTitle:NSLocalizedString(@"Could not create disk image", nil) message:[[NSString alloc] initWithUTF8String:strerror(error)]];
[[AppDelegate sharedInstance] showAlertWithTitle:NSLocalizedString(@"Could not duplicate disk image", nil) message:error.localizedDescription];
}
}
}];
[self.tableView beginUpdates];
[self loadDirectoryContents];
[self.tableView reloadSections:[NSIndexSet indexSetWithIndex:0] withRowAnimation:UITableViewRowAnimationFade];
@ -479,6 +552,7 @@
});
});
}
#pragma mark - Text Field Delegate
- (BOOL)textField:(UITextField *)textField shouldChangeCharactersInRange:(NSRange)range replacementString:(NSString *)string {
@ -510,25 +584,43 @@
}
}
#pragma mark - Alert Delegate
#pragma mark - Context Menu
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex {
if (fileToRename && buttonIndex == alertView.firstOtherButtonIndex) {
[self renameFile:fileToRename toName:nameTextField.text];
fileToRename = nil;
} else if (createDiskImageAlert != nil) {
NSString *name = [self _newDiskImageName];
off_t size = [self _newDiskImageSize];
createDiskImageAlert = nil;
[self createDiskImageWithName:name size:size];
- (UIContextMenuConfiguration *)tableView:(UITableView *)tableView contextMenuConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath point:(CGPoint)point API_AVAILABLE(ios(13.0)) {
FileTableViewCell *cell = [tableView cellForRowAtIndexPath:indexPath];
if (cell.filePath == nil) {
return nil;
}
}
- (BOOL)alertViewShouldEnableFirstOtherButton:(UIAlertView *)alertView {
if (alertView == createDiskImageAlert) {
return [self validateCreateDiskImageInput:alertView];
UIAction *insertAction = [UIAction actionWithTitle:@"Insert" image:[UIImage systemImageNamed:@"play.fill"] identifier:nil handler:^(__kindof UIAction * _Nonnull action) {
[self insertDisk:cell.filePath];
}];
UIAction *deleteAction = [UIAction actionWithTitle:@"Delete" image:[UIImage systemImageNamed:@"trash"] identifier:nil handler:^(__kindof UIAction * _Nonnull action) {
[cell delete:self];
}];
deleteAction.attributes = UIMenuElementAttributesDestructive;
if ([[AppDelegate sharedEmulator] isDiskInserted:cell.filePath]) {
insertAction.attributes = UIMenuElementAttributesDisabled;
deleteAction.attributes = UIMenuElementAttributesDisabled;
}
return YES;
NSArray<UIAction*> *actions = @[
insertAction,
[UIAction actionWithTitle:@"Rename" image:[UIImage systemImageNamed:@"pencil"] identifier:nil handler:^(__kindof UIAction * _Nonnull action) {
[cell rename:self];
}],
[UIAction actionWithTitle:@"Duplicate" image:[UIImage systemImageNamed:@"plus.square.on.square"] identifier:nil handler:^(__kindof UIAction * _Nonnull action) {
[self duplicateDiskImage:cell.filePath];
}],
[UIAction actionWithTitle:@"Share" image:[UIImage systemImageNamed:@"square.and.arrow.up"] identifier:nil handler:^(__kindof UIAction * _Nonnull action) {
[cell share:self];
}],
deleteAction
];
return [UIContextMenuConfiguration configurationWithIdentifier:nil previewProvider:nil actionProvider:^UIMenu * _Nullable(NSArray<UIMenuElement *> * _Nonnull suggestedActions) {
return [UIMenu menuWithTitle:@"" children:actions];
}];
}
@end
@ -605,7 +697,7 @@
}
- (void)delete:(id)sender {
[self.controller askDeleteFile:self.filePath];
[self.controller askDeleteFile:self.filePath sourceView:self];
}
@end

View File

@ -18,8 +18,8 @@ const NSUInteger KBKeyEventStickyKey = 1 << 24;
self.dark = NO;
self.titleLabel.adjustsFontSizeToFitWidth = YES;
self.titleLabel.lineBreakMode = NSLineBreakByTruncatingTail;
self.titleLabel.minimumScaleFactor = 0.5;
self.titleEdgeInsets = UIEdgeInsetsMake(0, 2, 0, 2);
self.titleLabel.minimumScaleFactor = 0.3;
self.titleLabel.allowsDefaultTighteningForTruncation = YES;
UIColor *labelColor;
if (@available(iOS 13.0, *)) {
labelColor = [UIColor labelColor];
@ -28,6 +28,8 @@ const NSUInteger KBKeyEventStickyKey = 1 << 24;
}
[self setTitleColor:labelColor forState:UIControlStateNormal];
self.tintColor = labelColor;
self.contentEdgeInsets = UIEdgeInsetsMake(4, 4, 6, 4);
self.contentMode = UIViewContentModeScaleAspectFit;
}
return self;
}

View File

@ -9,6 +9,12 @@
#import <UIKit/UIKit.h>
#import "KBKeyboardLayout.h"
#define KC_COMMAND 55
#define KC_SHIFT 56
#define KC_CAPSLOCK 57
#define KC_OPTION 58
#define KC_CONTROL 59
@class KBKey;
@protocol KBKeyboardViewDelegate <NSObject>
@ -22,9 +28,10 @@
@property (weak, nonatomic, nullable) id<KBKeyboardViewDelegate> delegate;
@property (nonatomic, strong, nullable) KBKeyboardLayout *layout;
@property (nonatomic, strong, nullable) UIMenu *layoutMenu;
@property (nonatomic, readonly, nonnull) NSArray<KBKey*>* keys;
@property (nonatomic, readonly, nonnull) NSArray<KBKey*>* stickyKeys;
- (instancetype)initWithFrame:(CGRect)frame safeAreaInsets:(UIEdgeInsets)safeAreaInsets;
- (instancetype _Nonnull)initWithFrame:(CGRect)frame safeAreaInsets:(UIEdgeInsets)safeAreaInsets;
@end

View File

@ -9,26 +9,23 @@
#import "KBKeyboardView.h"
#import "KBKey.h"
#define KC_COMMAND 55
#define KC_SHIFT 56
#define KC_CAPSLOCK 57
#define KC_OPTION 58
#define KC_CONTROL 59
@implementation KBKeyboardView {
NSMutableArray *keyPlanes;
NSMutableArray *keyPlanes, *emptyKeyPlanes;
NSMutableSet *modifiers;
NSMutableIndexSet *keysDown;
CGAffineTransform defaultKeyTransform;
CGFloat fontSize;
CGSize selectedSize;
UIEdgeInsets safeAreaInsets;
CGSize intrinsicSize;
}
- (instancetype)initWithFrame:(CGRect)frame safeAreaInsets:(UIEdgeInsets)insets {
self = [super initWithFrame:frame];
if (self) {
safeAreaInsets = insets;
intrinsicSize = frame.size;
#if !defined(TARGET_OS_VISION) || TARGET_OS_VISION == 0
if (@available(iOS 13.0, *)) {
self.backgroundColor = [UIColor clearColor];
UIVisualEffectView *backgroundView = [[UIVisualEffectView alloc] initWithEffect:[UIBlurEffect effectWithStyle:UIBlurEffectStyleSystemThickMaterial]];
@ -37,8 +34,10 @@
} else {
self.backgroundColor = [UIColor colorWithRed:0xEB / 255.0 green:0xF0 / 255.0 blue:0xF7 / 255.0 alpha:0.9];
}
#endif
modifiers = [NSMutableSet setWithCapacity:4];
keysDown = [NSMutableIndexSet indexSet];
self.autoresizesSubviews = NO;
}
return self;
}
@ -47,6 +46,50 @@
return [self initWithFrame:frame safeAreaInsets:UIEdgeInsetsZero];
}
- (CGSize)intrinsicContentSize {
return intrinsicSize;
}
- (BOOL)isCompactKeyboardSize:(CGSize)size {
return size.width < 768.0;
}
#if defined(TARGET_OS_VISION) && TARGET_OS_VISION == 1
- (void)layoutSubviews {
// TODO: optimize this if needed
CGSize size = self.bounds.size;
CGFloat scale = size.width / intrinsicSize.width;
CGAffineTransform transform = CGAffineTransformMakeScale(scale, scale);
if (!CGAffineTransformEqualToTransform(transform, defaultKeyTransform)) {
defaultKeyTransform = transform;
keyPlanes = emptyKeyPlanes.mutableCopy;
fontSize = 30.0 * scale;
[self switchToKeyPlane:0];
}
}
#endif
- (CGSize)findBestSizeForWidth:(CGFloat)preferredWidth inArray:(NSArray<NSValue*>*)sizes {
CGSize selectedSize = CGSizeZero;
for (NSValue *key in sizes) {
CGSize size = key.CGSizeValue;
if (size.width > selectedSize.width && size.width <= preferredWidth) {
selectedSize = size;
if (size.width == preferredWidth) {
// exact match
break;
}
}
}
// still not found, use smallest width
if (CGSizeEqualToSize(selectedSize, CGSizeZero)) {
selectedSize = sizes.firstObject.CGSizeValue;
}
return selectedSize;
}
- (void)setLayout:(KBKeyboardLayout *)layout {
if ([_layout isEqual:layout]) {
return;
@ -57,32 +100,18 @@
CGRect safeFrame = UIEdgeInsetsInsetRect(self.frame, safeAreaInsets);
CGFloat frameWidth = safeFrame.size.width;
CGFloat preferredWidth = frameWidth;
selectedSize = CGSizeZero;
for (NSValue *key in layout.availableSizes) {
CGSize size = key.CGSizeValue;
if (!CGSizeEqualToSize(size, CGSizeZero) && size.width > selectedSize.width && size.width <= preferredWidth) {
selectedSize = size;
}
}
// try sideways
if (CGSizeEqualToSize(selectedSize, CGSizeZero)) {
preferredWidth = safeFrame.size.height;
for (NSValue *key in layout.availableSizes) {
CGSize size = key.CGSizeValue;
if (!CGSizeEqualToSize(size, CGSizeZero) && size.width > selectedSize.width && size.width <= preferredWidth) {
selectedSize = size;
}
}
}
// still not found
if (CGSizeEqualToSize(selectedSize, CGSizeZero)) {
return;
}
// find best size in class
BOOL isCompactSize = self.traitCollection.horizontalSizeClass == UIUserInterfaceSizeClassCompact;
NSArray<NSValue*> *sizes = [[layout.availableSizes filteredArrayUsingPredicate:[NSPredicate predicateWithBlock:^BOOL(NSValue *size, NSDictionary<NSString *,id> * _Nullable bindings) {
return [self isCompactKeyboardSize:size.CGSizeValue] == isCompactSize;
}]] sortedArrayUsingComparator:^NSComparisonResult(NSValue * _Nonnull size1, NSValue * _Nonnull size2) {
return size1.CGSizeValue.width - size2.CGSizeValue.width;
}];
selectedSize = [self findBestSizeForWidth:preferredWidth inArray:sizes];
defaultKeyTransform = CGAffineTransformIdentity;
fontSize = [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone ? 22.0 : 30.0;
fontSize = [self isCompactKeyboardSize:selectedSize] ? 22.0 : 30.0;
if (preferredWidth != selectedSize.width || preferredWidth != frameWidth) {
// adjust width
if (frameWidth / selectedSize.width > 2 || frameWidth / selectedSize.width < 0.5) {
@ -90,7 +119,7 @@
defaultKeyTransform = CGAffineTransformMakeScale(frameWidth / selectedSize.width, frameWidth / selectedSize.width);
} else if (frameWidth < selectedSize.width) {
// shrink keyboard
defaultKeyTransform = CGAffineTransformMakeScale(frameWidth / selectedSize.width, 1.33333);
defaultKeyTransform = CGAffineTransformMakeScale(frameWidth / selectedSize.width, 1.0);
} else {
// iPhone keyboard on bigger phone
CGFloat wScale = safeFrame.size.width / selectedSize.width;
@ -105,40 +134,56 @@
for (int i = 0; i < numberOfKeyPlanes; i++) {
[keyPlanes addObject:[NSNull null]];
}
emptyKeyPlanes = keyPlanes.mutableCopy;
[self switchToKeyPlane:0];
}
- (void)_addKeyWithFrame:(CGRect)keyFrame scanCode:(int8_t)scancode fontScale:(CGFloat)fontScale dark:(BOOL)dark sticky:(BOOL)sticky toKeyPlane:(NSMutableArray*)keyPlane {
KBKey *key = nil;
if (@available(iOS 11, *)) {
keyFrame.origin.x += safeAreaInsets.left;
}
if (scancode == VKC_HIDE) {
key = [[KBHideKey alloc] initWithFrame:keyFrame];
#if defined(TARGET_OS_VISION) && TARGET_OS_VISION == 1
if (self.layoutMenu != nil) {
key.showsMenuAsPrimaryAction = YES;
key.menu = self.layoutMenu;
} else {
return;
}
#else
[key addTarget:self action:@selector(hideKeyboard:) forControlEvents:UIControlEventTouchUpInside];
#endif
} else if (scancode == VKC_SHIFT_CAPS) {
key = [[KBShiftCapsKey alloc] initWithFrame:keyFrame];
key.scancode = KC_SHIFT;
[key addTarget:self action:@selector(capsKey:) forControlEvents:KBKeyEventStickyKey];
} else if (sticky) {
key = [[KBStickyKey alloc] initWithFrame:keyFrame];
key.scancode = scancode;
[key addTarget:self action:@selector(stickyKey:) forControlEvents:KBKeyEventStickyKey];
} else {
key = [[KBKey alloc] initWithFrame:keyFrame];
key.scancode = scancode;
[key addTarget:self action:@selector(keyDown:) forControlEvents:UIControlEventTouchDown];
[key addTarget:self action:@selector(keyUp:) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchDragExit | UIControlEventTouchCancel];
}
key.dark = dark;
NSString *label = [_layout labelForScanCode:scancode];
if ([label containsString:@"\n"]) {
fontScale *= [self isCompactKeyboardSize:selectedSize] ? 0.6 : 0.65;
}
key.label = label;
key.titleLabel.font = [UIFont systemFontOfSize:self->fontSize * fontScale weight:UIFontWeightRegular];
[keyPlane addObject:key];
}
- (NSArray *)_loadKeyPlane:(NSUInteger)plane {
NSMutableArray *keyPlane = [NSMutableArray arrayWithCapacity:64];
[_layout enumerateKeysForSize:selectedSize plane:plane transform:defaultKeyTransform usingBlock:^(int8_t scancode, CGRect keyFrame, CGFloat fontScale, BOOL dark, BOOL sticky) {
KBKey *key = nil;
keyFrame.origin.x += safeAreaInsets.left;
if (scancode == VKC_HIDE) {
key = [[KBHideKey alloc] initWithFrame:keyFrame];
[key addTarget:self action:@selector(hideKeyboard:) forControlEvents:UIControlEventTouchUpInside];
} else if (scancode == VKC_SHIFT_CAPS) {
key = [[KBShiftCapsKey alloc] initWithFrame:keyFrame];
key.scancode = KC_SHIFT;
[key addTarget:self action:@selector(capsKey:) forControlEvents:KBKeyEventStickyKey];
} else if (sticky) {
key = [[KBStickyKey alloc] initWithFrame:keyFrame];
key.scancode = scancode;
[key addTarget:self action:@selector(stickyKey:) forControlEvents:KBKeyEventStickyKey];
} else {
key = [[KBKey alloc] initWithFrame:keyFrame];
key.scancode = scancode;
[key addTarget:self action:@selector(keyDown:) forControlEvents:UIControlEventTouchDown];
[key addTarget:self action:@selector(keyUp:) forControlEvents:UIControlEventTouchUpInside | UIControlEventTouchDragExit | UIControlEventTouchCancel];
}
key.dark = dark;
NSString *label = [_layout labelForScanCode:scancode];
if ([label containsString:@"\n"]) {
fontScale *= [UIDevice currentDevice].userInterfaceIdiom == UIUserInterfaceIdiomPhone ? 0.6 : 0.65;
}
key.label = label;
key.titleLabel.font = [UIFont systemFontOfSize:fontSize * fontScale weight:&UIFontWeightRegular ? UIFontWeightRegular : 1.0];
[keyPlane addObject:key];
[self _addKeyWithFrame:keyFrame scanCode:scancode fontScale:fontScale dark:dark sticky:sticky toKeyPlane:keyPlane];
}];
return keyPlane;
}

View File

@ -0,0 +1,51 @@
//
// KeyboardSceneDelegate.swift
// Mini vMac
//
// Created by Jesús A. Álvarez on 2024-02-10.
// Copyright © 2024 namedfork. All rights reserved.
//
import UIKit
#if os(visionOS)
class KeyboardSceneDelegate: UIResponder, UIWindowSceneDelegate {
var window: UIWindow?
func scene(_ scene: UIScene, willConnectTo session: UISceneSession, options connectionOptions: UIScene.ConnectionOptions) {
guard let windowScene = scene as? UIWindowScene else {
fatalError("Expected scene of type UIWindowScene but got an unexpected type")
}
guard let mainViewController = AppDelegate.shared.window.rootViewController as? ViewController else {
fatalError("No main view controller")
}
scene.activationConditions.canActivateForTargetContentIdentifierPredicate = NSPredicate(format: "self == 'net.namedfork.keyboard'", argumentArray: nil)
let defaultSize = mainViewController.keyboardViewController.preferredContentSize
let minSize = defaultSize.applying(.init(scaleX: 0.75, y: 0.75))
let maxSize = defaultSize.applying(.init(scaleX: 1.25, y: 1.25))
windowScene.sizeRestrictions?.minimumSize = minSize
windowScene.sizeRestrictions?.maximumSize = maxSize
windowScene.requestGeometryUpdate(UIWindowScene.GeometryPreferences.Vision(
size: defaultSize,
minimumSize: minSize,
maximumSize: maxSize,
resizingRestrictions: .uniform
))
window = UIWindow(windowScene: windowScene)
// destroy existing keyboard window
if let oldWindow = mainViewController.keyboardViewController?.view?.window {
oldWindow.rootViewController = nil
if let oldScene = oldWindow.windowScene?.session.scene {
UIApplication.shared.requestSceneSessionDestruction(oldScene.session, options: nil)
}
}
if let window {
window.rootViewController = mainViewController.keyboardViewController
window.makeKeyAndVisible()
}
}
}
#endif

View File

@ -1,13 +0,0 @@
//
// MNVMApplication.h
// Mini vMac
//
// Created by Jesús A. Álvarez on 14/05/2016.
// Copyright © 2016-2018 namedfork. All rights reserved.
//
#import <UIKit/UIKit.h>
@interface MNVMApplication : UIApplication
@end

View File

@ -1,119 +0,0 @@
//
// MNVMApplication.m
// Mini vMac
//
// Created by Jesús A. Álvarez on 14/05/2016.
// Copyright © 2016-2018 namedfork. All rights reserved.
//
#import "MNVMApplication.h"
#import "AppDelegate.h"
@interface UIApplication ()
- (void)handleKeyUIEvent:(UIEvent *)event;
@end
Class keyboardEventClass = nil;
static int8_t usb_to_adb_scancode[] = {
-1, -1, -1, -1, 0, 11, 8, 2, 14, 3, 5, 4, 34, 38, 40, 37,
46, 45, 31, 35, 12, 15, 1, 17, 32, 9, 13, 7, 16, 6, 18, 19,
20, 21, 23, 22, 26, 28, 25, 29, 36, 53, 51, 48, 49, 27, 24, 33,
30, 42, 42, 41, 39, 10, 43, 47, 44, 57, 122, 120, 99, 118, 96, 97,
98, 100, 101, 109, 103, 111, 105, 107, 113, 114, 115, 116, 117, 119, 121, 60,
59, 61, 62, 71, 75, 67, 78, 69, 76, 83, 84, 85, 86, 87, 88, 89,
91, 92, 82, 65, 50, 55, 126, 81, 105, 107, 113, 106, 64, 79, 80, 90,
-1, -1, -1, -1, -1, 114, -1, -1, -1, -1, -1, -1, -1, -1, -1, 74,
72, 73, -1, -1, -1, 95, -1, 94, -1, 93, -1, -1, -1, -1, -1, -1,
104, 102, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1,
54, 56, 58, 55, 54, 56, 58, 55, -1, -1, -1, -1, -1, -1, -1, -1,
-1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1
};
@interface UIPhysicalKeyboardEvent : UIPressesEvent
@property (nonatomic, readonly) BOOL _isKeyDown;
@property (nonatomic, readonly) long _keyCode;
@property (nonatomic) int _modifierFlags;
@property(retain, nonatomic) NSString *_unmodifiedInput;
@property(retain, nonatomic) NSString *_modifiedInput;
@end
@implementation MNVMApplication
{
BOOL physicalCapsLocked;
}
+ (void)load {
// class is not visible
keyboardEventClass = NSClassFromString(@"UIPhysicalKeyboardEvent");
}
- (void)handleKeyboardEvent:(UIPhysicalKeyboardEvent *)event {
long keycode = event._keyCode;
int scancode = -1;
if (keycode >= 0 && keycode < sizeof(usb_to_adb_scancode)) {
scancode = usb_to_adb_scancode[keycode];
}
if (scancode == 57) {
// caps lock
if (event._isKeyDown && !physicalCapsLocked) {
[[AppDelegate sharedEmulator] keyDown:scancode];
physicalCapsLocked = YES;
} else if (event._isKeyDown && physicalCapsLocked) {
[[AppDelegate sharedEmulator] keyUp:scancode];
physicalCapsLocked = NO;
}
} else if (scancode >= 0 && [AppDelegate sharedEmulator].running) {
if (event._isKeyDown) {
[self _updateCapsLockStatus:event];
[[AppDelegate sharedEmulator] keyDown:scancode];
} else {
[[AppDelegate sharedEmulator] keyUp:scancode];
}
}
}
- (void)_updateCapsLockStatus:(UIPhysicalKeyboardEvent *)event {
if (event._modifierFlags == 0 && event._unmodifiedInput.length == 1 && event._modifiedInput.length == 1) {
unichar unmodifiedChar = [event._unmodifiedInput characterAtIndex:0];
unichar modifiedChar = [event._modifiedInput characterAtIndex:0];
if ([[NSCharacterSet lowercaseLetterCharacterSet] characterIsMember:unmodifiedChar]) {
BOOL currentCapsLock = [[NSCharacterSet uppercaseLetterCharacterSet] characterIsMember:modifiedChar];
if (currentCapsLock != physicalCapsLocked) {
physicalCapsLocked = currentCapsLock;
if (physicalCapsLocked) {
[[AppDelegate sharedEmulator] keyDown:57];
} else {
[[AppDelegate sharedEmulator] keyUp:57];
}
}
}
}
}
- (void)handleKeyUIEvent:(UIEvent *)event {
[super handleKeyUIEvent:event];
static dispatch_once_t onceToken;
static BOOL handleKeyboardEvents = YES;
dispatch_once(&onceToken, ^{
if ([NSProcessInfo instancesRespondToSelector:@selector(operatingSystemVersion)]) {
handleKeyboardEvents = [NSProcessInfo processInfo].operatingSystemVersion.majorVersion >= 9;
} else {
handleKeyboardEvents = NO;
}
});
BOOL emulatorIsFrontmost = [AppDelegate sharedEmulator].running && [AppDelegate sharedInstance].window.rootViewController.presentedViewController == nil;
if ([event isKindOfClass:keyboardEventClass] && handleKeyboardEvents && emulatorIsFrontmost) {
[self handleKeyboardEvent:(UIPhysicalKeyboardEvent*)event];
}
}
@end

View File

@ -27,11 +27,8 @@
@import UIKit;
@import AudioUnit;
@import AudioToolbox;
#include "SYSDEPNS.h"
#include "ENDIANAC.h"
#include "MYOSGLUE.h"
#include "STRCNENG.h"
#include "EMCONFIG.h"
#include "OSGCOMUI.h"
#include "OSGCOMUD.h"
#import "EmulatorProtocol.h"
#define kRAM_Size (kRAMa_Size + kRAMb_Size)
@ -39,14 +36,14 @@ EXPORTVAR(ui3p, RAM)
EXPORTVAR(ui3p, VidROM)
EXPORTVAR(ui3p, VidMem)
@interface Emulator : NSObject <Emulator, UIAlertViewDelegate>
@interface MNVMBundleClassName : NSObject <Emulator>
- (void)makeNewDisk:(NSString*)name size:(NSInteger)size;
- (void)updateScreen:(CGImageRef)screenImage;
@end
static Emulator *sharedEmulator = nil;
static __weak MNVMBundleClassName *sharedEmulator = nil;
#pragma mark - some simple utilities
@ -408,7 +405,7 @@ LOCALFUNC tMacErr vSonyEject0(tDrive Drive_No, blnr deleteit) {
}
#endif
[[NSNotificationCenter defaultCenter] postNotificationName:[Emulator sharedEmulator].ejectDiskNotification object:[Emulator sharedEmulator] userInfo:userInfo];
[[NSNotificationCenter defaultCenter] postNotificationName:sharedEmulator.ejectDiskNotification object:sharedEmulator userInfo:userInfo];
return mnvm_noErr;
}
@ -458,7 +455,7 @@ LOCALFUNC blnr Sony_Insert0(FILE *refnum, blnr locked, NSString *filePath) {
} else {
NSDictionary *userInfo = @{@"path": filePath,
@"drive": @(Drive_No)};
[[NSNotificationCenter defaultCenter] postNotificationName:[Emulator sharedEmulator].insertDiskNotification object:[Emulator sharedEmulator] userInfo:userInfo];
[[NSNotificationCenter defaultCenter] postNotificationName:sharedEmulator.insertDiskNotification object:sharedEmulator userInfo:userInfo];
/* printf("Sony_Insert0 %d\n", (int)Drive_No); */
@ -790,7 +787,7 @@ LOCALPROC HaveChangedScreenBuff(ui4r top, ui4r left, ui4r bottom, ui4r right) {
if (colorSpace) {
CGImageRef screenImage = CGImageCreate(vMacScreenWidth, vMacScreenHeight, bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpace, options, screenDataProvider, NULL, false, kCGRenderingIntentDefault);
[[Emulator sharedEmulator] updateScreen:screenImage];
[sharedEmulator updateScreen:screenImage];
CGImageRelease(screenImage);
}
}
@ -1474,21 +1471,8 @@ LOCALPROC MacMsgDisplayOn() {
if (SavedBriefMsg != nullpr) {
NSString *title = NSStringCreateFromSubstCStr(SavedBriefMsg, falseblnr);
NSString *message = NSStringCreateFromSubstCStr(SavedLongMsg, falseblnr);
if ([UIAlertController class]) {
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:title message:message preferredStyle:UIAlertControllerStyleAlert];
blnr wasStopped = SpeedStopped;
[alertController addAction:[UIAlertAction actionWithTitle:@"OK" style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
SpeedStopped = wasStopped;
}]];
SpeedStopped = trueblnr;
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertController animated:YES completion:nil];
} else {
// fallback for iOS 7
UIAlertView *alertView = [[UIAlertView alloc] initWithTitle:title message:message delegate:nil cancelButtonTitle:@"OK" otherButtonTitles: nil];
alertView.delegate = sharedEmulator;
SpeedStopped = trueblnr;
[alertView show];
}
sharedEmulator.showAlert(title, message);
SpeedStopped = trueblnr;
SavedBriefMsg = nullpr;
SavedLongMsg = nullpr;
}
@ -1647,31 +1631,26 @@ GLOBALPROC WaitForNextTick(void) {
#pragma mark - Objective-C Interface
static dispatch_once_t onceToken;
@implementation Emulator
@implementation MNVMBundleClassName
{
__block __weak UITextField *nameTextField;
}
@synthesize dataPath;
+ (instancetype)sharedEmulator {
dispatch_once(&onceToken, ^{
sharedEmulator = [self new];
});
return sharedEmulator;
}
@synthesize showAlert;
@synthesize rootViewController;
- (instancetype)init {
if ((self = [super init])) {
dispatch_once(&onceToken, ^{
sharedEmulator = self;
});
sharedEmulator = self;
}
return self;
}
- (void)shutdown {
RequestMacOff = trueblnr;
}
- (void)run {
ZapOSGLUVars();
if (InitOSGLU()) {
@ -1798,35 +1777,25 @@ static dispatch_once_t onceToken;
}
- (void)makeNewDisk:(NSString*)name size:(NSInteger)size {
if ([UIAlertController class]) {
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Export File", nil) message:NSLocalizedString(@"Enter new name", nil) preferredStyle:UIAlertControllerStyleAlert];
[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
nameTextField = textField;
nameTextField.placeholder = name;
nameTextField.text = name;
}];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil) style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
[self didMakeNewDisk:nil size:0];
}]];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Save", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self didMakeNewDisk:nameTextField.text size:size];
}]];
[[UIApplication sharedApplication].keyWindow.rootViewController presentViewController:alertController animated:YES completion:nil];
} else {
// iOS 7 fallback
UIAlertView *alert = [[UIAlertView alloc] initWithTitle:NSLocalizedString(@"Export File", nil) message:NSLocalizedString(@"Enter new name", nil) delegate:self cancelButtonTitle:NSLocalizedString(@"Cancel", nil) otherButtonTitles:NSLocalizedString(@"Save", nil), nil];
alert.alertViewStyle = UIAlertViewStylePlainTextInput;
nameTextField = [alert textFieldAtIndex:0];
nameTextField.placeholder = name;
nameTextField.text = name;
[alert show];
}
UIAlertController *alertController = [UIAlertController alertControllerWithTitle:NSLocalizedString(@"Export File", nil) message:NSLocalizedString(@"Enter new name", nil) preferredStyle:UIAlertControllerStyleAlert];
[alertController addTextFieldWithConfigurationHandler:^(UITextField * _Nonnull textField) {
self->nameTextField = textField;
self->nameTextField.placeholder = name;
self->nameTextField.text = name;
}];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Cancel", nil) style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
[self didMakeNewDisk:nil size:0];
}]];
[alertController addAction:[UIAlertAction actionWithTitle:NSLocalizedString(@"Save", nil) style:UIAlertActionStyleDefault handler:^(UIAlertAction * _Nonnull action) {
[self didMakeNewDisk:self->nameTextField.text size:size];
}]];
[sharedEmulator.rootViewController presentViewController:alertController animated:YES completion:nil];
}
- (void)didMakeNewDisk:(NSString*)fileName size:(NSInteger)size {
if (fileName) {
NSString *filePath = [self.dataPath stringByAppendingPathComponent:fileName];
MakeNewDisk0(size, filePath);
MakeNewDisk0((ui5b)size, filePath);
}
#if IncludeSonyNameNew
if (vSonyNewDiskName != NotAPbuf) {
@ -1838,19 +1807,6 @@ static dispatch_once_t onceToken;
SpeedStopped = falseblnr;
}
- (void)alertView:(UIAlertView *)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex {
if (nameTextField) {
NSString *fileName = nil;
if (buttonIndex == alertView.firstOtherButtonIndex) {
fileName = nameTextField.text;
}
[self didMakeNewDisk:fileName size:vSonyNewDiskSize];
}
if (SpeedStopped) {
SpeedStopped = falseblnr;
}
}
#pragma mark - Keyboard
- (int)translateScanCode:(int)scancode {

View File

@ -1,24 +0,0 @@
#define RomFileName "Mac128K.ROM"
#define WantInitSpeedValue 2
#define WantInitNotAutoSlow 0
#define EnableAutoSlow 1
#define MySoundEnabled 1
#define MySoundRecenterSilence 0
#define kLn2SoundSampSz 3
#define NumDrives 2
#define vMacScreenHeight 342
#define vMacScreenWidth 512
#define vMacScreenDepth 0
#define kROM_Size 0x00010000
#ifdef PLIST_PREPROCESSOR
#define MNVMBundleDisplayName Mac 128K
#define MNVMBundleGetInfoString 128K, 512×342
#else
#include "../CNFGGLOB.h"
#endif

View File

@ -0,0 +1,47 @@
/*
see comment in OSGCOMUD.h
This file is automatically generated by the build system,
which tries to know what options are valid in what
combinations. Avoid changing this file manually unless
you know what you're doing.
*/
#define MySoundEnabled 1
#define MySoundRecenterSilence 0
#define kLn2SoundSampSz 3
#define dbglog_HAVE 0
#define WantAbnormalReports 0
#define NumDrives 2
#define NonDiskProtect 0
#define IncludeSonyRawMode 1
#define IncludeSonyGetName 1
#define IncludeSonyNew 1
#define IncludeSonyNameNew 1
#define vMacScreenHeight 342
#define vMacScreenWidth 512
#define vMacScreenDepth 0
#define kROM_Size 0x00010000
#define IncludePbufs 1
#define NumPbufs 4
#define EnableMouseMotion 1
#define IncludeHostTextClipExchange 1
#define EnableAutoSlow 1
#define EmLocalTalk 0
#define AutoLocation 1
#define AutoTimeZone 1
#define MNVMBundleClassName Mac128KEmulator
#ifdef PLIST_PREPROCESSOR
#define MNVMBundleDisplayName Mac 128K
#define MNVMBundleGetInfoString 128K, 512×342
#endif

View File

@ -0,0 +1,33 @@
/*
see comment in OSGCOMUD.h
This file is automatically generated by the build system,
which tries to know what options are valid in what
combinations. Avoid changing this file manually unless
you know what you're doing.
*/
#define RomFileName "Mac128K.ROM"
#define kCheckSumRom_Size 0x00010000
#define kRomCheckSum1 0x28BA61CE
#define kRomCheckSum2 0x28BA4E50
#define RomStartCheckSum 1
#define SaveDialogEnable 1
#define EnableAltKeysMode 0
#define VarFullScreen 1
#define WantInitFullScreen 0
#define MayFullScreen 1
#define MayNotFullScreen 1
#define WantInitMagnify 0
#define EnableMagnify 1
#define MyWindowScale 2
#define WantInitRunInBackground 0
#define WantInitNotAutoSlow 0
#define WantInitSpeedValue 3
#define WantEnblCtrlInt 1
#define WantEnblCtrlRst 1
#define WantEnblCtrlKtg 1
#define UseControlKeys 1
#define UseActvCode 0
#define EnableDemoMsg 0

View File

@ -1,20 +1,22 @@
/*
Configuration options used by platform independent code.
This file is automatically generated by the build system,
which tries to know what options are valid in what
combinations. Avoid changing this file manually unless
you know what you're doing.
*/
see comment in PICOMMON.h
This file is automatically generated by the build system,
which tries to know what options are valid in what
combinations. Avoid changing this file manually unless
you know what you're doing.
*/
#define EmClassicKbrd 1
#define EmADB 0
#define EmRTC 1
#define EmPMU 0
#define EmVIA1 1
#define EmVIA2 0
#define Use68020 0
#define EmFPU 0
#define EmMMU 0
#define EmClassicSnd 1
#define EmASC 0
#define CurEmMd kEmMd_128K
@ -24,6 +26,9 @@
#define WantCycByPriOp 1
#define WantCloserCyc 0
#define kAutoSlowSubTicks 16384
#define kAutoSlowTime 34
#define kRAMa_Size 0x00020000
#define kRAMb_Size 0
@ -50,87 +55,87 @@
/* the Wire variables are 1/0, not true/false */
enum {
Wire_VIA1_iA0_SoundVolb0,
#define SoundVolb0 (Wires[Wire_VIA1_iA0_SoundVolb0])
#define VIA1_iA0 (Wires[Wire_VIA1_iA0_SoundVolb0])
Wire_VIA1_iA1_SoundVolb1,
#define SoundVolb1 (Wires[Wire_VIA1_iA1_SoundVolb1])
#define VIA1_iA1 (Wires[Wire_VIA1_iA1_SoundVolb1])
Wire_VIA1_iA2_SoundVolb2,
#define SoundVolb2 (Wires[Wire_VIA1_iA2_SoundVolb2])
#define VIA1_iA2 (Wires[Wire_VIA1_iA2_SoundVolb2])
Wire_VIA1_iA4_MemOverlay,
#define MemOverlay (Wires[Wire_VIA1_iA4_MemOverlay])
#define VIA1_iA4 (Wires[Wire_VIA1_iA4_MemOverlay])
#define VIA1_iA4_ChangeNtfy MemOverlay_ChangeNtfy
Wire_VIA1_iA6_SCRNvPage2,
#define SCRNvPage2 (Wires[Wire_VIA1_iA6_SCRNvPage2])
#define VIA1_iA6 (Wires[Wire_VIA1_iA6_SCRNvPage2])
Wire_VIA1_iA5_IWMvSel,
#define IWMvSel (Wires[Wire_VIA1_iA5_IWMvSel])
#define VIA1_iA5 (Wires[Wire_VIA1_iA5_IWMvSel])
Wire_VIA1_iA7_SCCwaitrq,
#define SCCwaitrq (Wires[Wire_VIA1_iA7_SCCwaitrq])
#define VIA1_iA7 (Wires[Wire_VIA1_iA7_SCCwaitrq])
Wire_VIA1_iB0_RTCdataLine,
#define RTCdataLine (Wires[Wire_VIA1_iB0_RTCdataLine])
#define VIA1_iB0 (Wires[Wire_VIA1_iB0_RTCdataLine])
#define VIA1_iB0_ChangeNtfy RTCdataLine_ChangeNtfy
Wire_VIA1_iB1_RTCclock,
#define RTCclock (Wires[Wire_VIA1_iB1_RTCclock])
#define VIA1_iB1 (Wires[Wire_VIA1_iB1_RTCclock])
#define VIA1_iB1_ChangeNtfy RTCclock_ChangeNtfy
Wire_VIA1_iB2_RTCunEnabled,
#define RTCunEnabled (Wires[Wire_VIA1_iB2_RTCunEnabled])
#define VIA1_iB2 (Wires[Wire_VIA1_iB2_RTCunEnabled])
#define VIA1_iB2_ChangeNtfy RTCunEnabled_ChangeNtfy
Wire_VIA1_iA3_SoundBuffer,
#define SoundBuffer (Wires[Wire_VIA1_iA3_SoundBuffer])
#define VIA1_iA3 (Wires[Wire_VIA1_iA3_SoundBuffer])
Wire_VIA1_iB3_MouseBtnUp,
#define MouseBtnUp (Wires[Wire_VIA1_iB3_MouseBtnUp])
#define VIA1_iB3 (Wires[Wire_VIA1_iB3_MouseBtnUp])
Wire_VIA1_iB4_MouseX2,
#define MouseX2 (Wires[Wire_VIA1_iB4_MouseX2])
#define VIA1_iB4 (Wires[Wire_VIA1_iB4_MouseX2])
Wire_VIA1_iB5_MouseY2,
#define MouseY2 (Wires[Wire_VIA1_iB5_MouseY2])
#define VIA1_iB5 (Wires[Wire_VIA1_iB5_MouseY2])
Wire_VIA1_iCB2_KybdDat,
#define VIA1_iCB2 (Wires[Wire_VIA1_iCB2_KybdDat])
#define VIA1_iCB2_ChangeNtfy Kybd_DataLineChngNtfy
Wire_VIA1_iB6_SCRNbeamInVid,
#define SCRNbeamInVid (Wires[Wire_VIA1_iB6_SCRNbeamInVid])
#define VIA1_iB6 (Wires[Wire_VIA1_iB6_SCRNbeamInVid])
Wire_VIA1_iB7_SoundDisable,
#define SoundDisable (Wires[Wire_VIA1_iB7_SoundDisable])
#define VIA1_iB7 (Wires[Wire_VIA1_iB7_SoundDisable])
Wire_VIA1_InterruptRequest,
#define VIA1_InterruptRequest (Wires[Wire_VIA1_InterruptRequest])
#define VIA1_interruptChngNtfy VIAorSCCinterruptChngNtfy
Wire_SCCInterruptRequest,
#define SCCInterruptRequest (Wires[Wire_SCCInterruptRequest])
#define SCCinterruptChngNtfy VIAorSCCinterruptChngNtfy
kNumWires
};
@ -160,8 +165,6 @@ enum {
#define KYBD_ShiftInData VIA1_ShiftOutData
#define KYBD_ShiftOutData VIA1_ShiftInData
#define kCheckSumRom_Size kROM_Size
#define kExtn_Block_Base 0x00F40000
#define kExtn_ln2Spc 5

View File

@ -0,0 +1,47 @@
/*
see comment in OSGCOMUD.h
This file is automatically generated by the build system,
which tries to know what options are valid in what
combinations. Avoid changing this file manually unless
you know what you're doing.
*/
#define MySoundEnabled 1
#define MySoundRecenterSilence 0
#define kLn2SoundSampSz 3
#define dbglog_HAVE 0
#define WantAbnormalReports 0
#define NumDrives 6
#define NonDiskProtect 0
#define IncludeSonyRawMode 1
#define IncludeSonyGetName 1
#define IncludeSonyNew 1
#define IncludeSonyNameNew 1
#define vMacScreenHeight 384
#define vMacScreenWidth 512
#define vMacScreenDepth 3
#define kROM_Size 0x00040000
#define IncludePbufs 1
#define NumPbufs 4
#define EnableMouseMotion 1
#define IncludeHostTextClipExchange 1
#define EnableAutoSlow 1
#define EmLocalTalk 0
#define AutoLocation 1
#define AutoTimeZone 1
#define MNVMBundleClassName MacIIEmulator512x384
#ifdef PLIST_PREPROCESSOR
#define MNVMBundleDisplayName Mac II
#define MNVMBundleGetInfoString 8M, 512×384
#endif

View File

@ -0,0 +1,33 @@
/*
see comment in OSGCOMUD.h
This file is automatically generated by the build system,
which tries to know what options are valid in what
combinations. Avoid changing this file manually unless
you know what you're doing.
*/
#define RomFileName "MacII.ROM"
#define kCheckSumRom_Size 0x00040000
#define kRomCheckSum1 0x9779D2C4
#define kRomCheckSum2 0x97221136
#define RomStartCheckSum 1
#define SaveDialogEnable 1
#define EnableAltKeysMode 0
#define VarFullScreen 1
#define WantInitFullScreen 0
#define MayFullScreen 1
#define MayNotFullScreen 1
#define WantInitMagnify 0
#define EnableMagnify 1
#define MyWindowScale 2
#define WantInitRunInBackground 0
#define WantInitNotAutoSlow 0
#define WantInitSpeedValue 2
#define WantEnblCtrlInt 1
#define WantEnblCtrlRst 1
#define WantEnblCtrlKtg 1
#define UseControlKeys 1
#define UseActvCode 0
#define EnableDemoMsg 0

Some files were not shown because too many files have changed in this diff Show More