diff --git a/MA2ME.xcodeproj/project.pbxproj b/MA2ME.xcodeproj/project.pbxproj index 8ccea97..9658989 100644 --- a/MA2ME.xcodeproj/project.pbxproj +++ b/MA2ME.xcodeproj/project.pbxproj @@ -7,6 +7,7 @@ objects = { /* Begin PBXBuildFile section */ + B64E15A624E9B34700E8AD3D /* Models.plist in Resources */ = {isa = PBXBuildFile; fileRef = B64E15A424E9B34700E8AD3D /* Models.plist */; }; B6BA258024E99BE9005FB8FF /* AppDelegate.m in Sources */ = {isa = PBXBuildFile; fileRef = B6BA257F24E99BE9005FB8FF /* AppDelegate.m */; }; B6BA258224E99BEB005FB8FF /* Assets.xcassets in Resources */ = {isa = PBXBuildFile; fileRef = B6BA258124E99BEB005FB8FF /* Assets.xcassets */; }; B6BA258524E99BEB005FB8FF /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = B6BA258324E99BEB005FB8FF /* MainMenu.xib */; }; @@ -14,6 +15,7 @@ /* End PBXBuildFile section */ /* Begin PBXFileReference section */ + B64E15A524E9B34700E8AD3D /* Base */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = Base; path = Base.lproj/Models.plist; sourceTree = ""; }; B6BA257B24E99BE9005FB8FF /* MA2ME.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = MA2ME.app; sourceTree = BUILT_PRODUCTS_DIR; }; B6BA257E24E99BE9005FB8FF /* AppDelegate.h */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.h; path = AppDelegate.h; sourceTree = ""; }; B6BA257F24E99BE9005FB8FF /* AppDelegate.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = AppDelegate.m; sourceTree = ""; }; @@ -56,6 +58,7 @@ children = ( B6BA257E24E99BE9005FB8FF /* AppDelegate.h */, B6BA257F24E99BE9005FB8FF /* AppDelegate.m */, + B64E15A424E9B34700E8AD3D /* Models.plist */, B6BA258124E99BEB005FB8FF /* Assets.xcassets */, B6BA258324E99BEB005FB8FF /* MainMenu.xib */, B6BA258624E99BEB005FB8FF /* Info.plist */, @@ -124,6 +127,7 @@ files = ( B6BA258224E99BEB005FB8FF /* Assets.xcassets in Resources */, B6BA258524E99BEB005FB8FF /* MainMenu.xib in Resources */, + B64E15A624E9B34700E8AD3D /* Models.plist in Resources */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -142,6 +146,14 @@ /* End PBXSourcesBuildPhase section */ /* Begin PBXVariantGroup section */ + B64E15A424E9B34700E8AD3D /* Models.plist */ = { + isa = PBXVariantGroup; + children = ( + B64E15A524E9B34700E8AD3D /* Base */, + ); + name = Models.plist; + sourceTree = ""; + }; B6BA258324E99BEB005FB8FF /* MainMenu.xib */ = { isa = PBXVariantGroup; children = ( diff --git a/MA2ME/AppDelegate.h b/MA2ME/AppDelegate.h index 59900ff..e613254 100644 --- a/MA2ME/AppDelegate.h +++ b/MA2ME/AppDelegate.h @@ -8,7 +8,7 @@ #import -@interface AppDelegate : NSObject +@interface AppDelegate : NSObject @end diff --git a/MA2ME/AppDelegate.m b/MA2ME/AppDelegate.m index b12108e..65ad706 100644 --- a/MA2ME/AppDelegate.m +++ b/MA2ME/AppDelegate.m @@ -8,15 +8,64 @@ #import "AppDelegate.h" + @interface AppDelegate () @property (weak) IBOutlet NSWindow *window; + + +/* kvo */ +@property NSString *commandLine; + +@property NSString *mameROM; +@property BOOL mameWindow; +@property BOOL mameNoThrottle; +@property BOOL mameDebug; +@property BOOL mameSquarePixels; + +@property NSArray *browserItems; @end @implementation AppDelegate +static NSString *kMyContext = @"kMyContext"; + - (void)applicationDidFinishLaunching:(NSNotification *)aNotification { // Insert code here to initialize your application + + + /* My Copy of XCode/Interface Builder barfs on NSBrowser. */ + + NSBundle *bundle = [NSBundle mainBundle]; + NSString *path = [bundle pathForResource: @"Models" ofType: @"plist"]; + _browserItems = [NSArray arrayWithContentsOfFile: path]; + + NSView *view = [_window contentView]; + + NSRect frame = [view frame]; + frame.origin.y += frame.size.height - 200; + frame.size.height = 200; + + NSBrowser *browser = [[NSBrowser alloc] initWithFrame: frame]; + + [browser setMaxVisibleColumns: 2]; + [browser setTakesTitleFromPreviousColumn: YES]; + [browser setTitled: NO]; + [browser setDelegate: self]; + [browser setAction: @selector(modelClick:)]; + + + + [view addSubview: browser]; + [browser setTitled: YES]; // NSBrowser title bug. + + + [self addObserver: self forKeyPath: @"mameROM" options:0 context: (__bridge void * _Nullable)(kMyContext)]; + [self addObserver: self forKeyPath: @"mameWindow" options:0 context: (__bridge void * _Nullable)(kMyContext)]; + [self addObserver: self forKeyPath: @"mameSquarePixels" options:0 context: (__bridge void * _Nullable)(kMyContext)]; + [self addObserver: self forKeyPath: @"mameDebug" options:0 context: (__bridge void * _Nullable)(kMyContext)]; + [self addObserver: self forKeyPath: @"mameNoThrottle" options:0 context: (__bridge void * _Nullable)(kMyContext)]; + [self buildCommandLine]; } @@ -25,4 +74,110 @@ } +-(void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context { + + if (context == (__bridge void *)kMyContext && object == self) { + [self buildCommandLine]; + } else { + [super observeValueForKeyPath: keyPath ofObject: object change: change context: context]; + } +} + +-(void)buildCommandLine { + + + if (!_mameROM) { + [self setCommandLine: @""]; + return; + } + + NSMutableArray *argv = [NSMutableArray new]; + + [argv addObject: @"mame"]; + [argv addObject: _mameROM]; + + if (_mameDebug) { [argv addObject: @"-debug"]; } + if (_mameWindow) { [argv addObject: @"-window"]; } + if (_mameWindow && _mameSquarePixels) { + [argv addObject: @"-resolution"]; + [argv addObject: @"704x462"]; + [argv addObject: @"-video"]; + [argv addObject: @"-soft"]; + [argv addObject: @"-aspect"]; + [argv addObject: @"704:462"]; + } + + [self setCommandLine: [argv componentsJoinedByString:@" "]]; +} + +-(IBAction)modelClick:(id)sender { + + NSDictionary *item = [self itemForBrowser: sender]; + [self setMameROM: [item objectForKey: @"Mame"]]; +// [self buildCommandLine]; +} + +#pragma mark NSBrowser + +-(NSDictionary *)itemForBrowser: (NSBrowser *)browser { + + NSIndexPath *path = [browser selectionIndexPath]; + + NSArray *a = _browserItems; + NSDictionary *item = nil; + + NSUInteger l = [path length]; + for (NSUInteger i = 0; i < l; ++i) { + NSUInteger ix = [path indexAtPosition: i]; + if (ix > [a count]) return nil; + item = [a objectAtIndex: ix]; + a = [item objectForKey: @"Children"]; + } + + return item; +} +-(NSArray *)itemsForBrowser: (NSBrowser *)browser column: (NSInteger) column { + + NSArray *a = _browserItems; + for (unsigned i = 0; i < column; ++i) { + NSInteger ix = [browser selectedRowInColumn: i]; + if (ix < 0) return 0; + + NSDictionary *item = [a objectAtIndex: ix]; + a = [item objectForKey: @"Children"]; + if (!a) return 0; + } + return a; + +} + +- (void)browser:(NSBrowser *)sender willDisplayCell:(id)cell atRow:(NSInteger)row column:(NSInteger)column { + NSArray *a = [self itemsForBrowser: sender column: column]; + if (!a || row >= [a count]) return; + + NSDictionary *item = [a objectAtIndex: row]; + + NSBrowserCell *bc = (NSBrowserCell *)cell; + + [bc setStringValue: [item objectForKey: @"Name"]]; + [bc setLeaf: ![item objectForKey: @"Children"]]; + +} + + +- (NSString *)browser:(NSBrowser *)sender titleOfColumn:(NSInteger)column { + return column == 0 ? @"Model" : @"Submodel"; +} + +- (id)browser:(NSBrowser *)browser child:(NSInteger)index ofItem:(id)item { + return nil; +} + +- (NSInteger)browser:(NSBrowser *)sender numberOfRowsInColumn:(NSInteger)column { + + NSArray *a = [self itemsForBrowser: sender column: column]; + return [a count]; +} + + @end diff --git a/MA2ME/Base.lproj/MainMenu.xib b/MA2ME/Base.lproj/MainMenu.xib index f387bda..ff73d2e 100644 --- a/MA2ME/Base.lproj/MainMenu.xib +++ b/MA2ME/Base.lproj/MainMenu.xib @@ -1,7 +1,9 @@ - - + + - + + + @@ -10,8 +12,8 @@ - - + + @@ -677,16 +679,88 @@ + - + - - + + - + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/MA2ME/Base.lproj/Models.plist b/MA2ME/Base.lproj/Models.plist new file mode 100644 index 0000000..fe67c95 --- /dev/null +++ b/MA2ME/Base.lproj/Models.plist @@ -0,0 +1,35 @@ + + + + + + Name + Apple IIgs + Mame + apple2gs + Children + + + + Name + Apple IIe + Mame + apple2e + Children + + + Name + Apple IIe + Mame + apple2e + + + Name + Apple IIe (enhanced) + Mame + apple2ee + + + + +