mirror of
https://github.com/ksherlock/ample.git
synced 2024-06-10 00:29:55 +00:00
Eliminate the hard-coded slot values and use the slot name + dictionary for saving between machines.
This commit is contained in:
parent
2198467def
commit
9b3223478c
11
Ample/Slot.h
11
Ample/Slot.h
|
@ -10,16 +10,6 @@
|
|||
#import <Cocoa/Cocoa.h>
|
||||
#import "Media.h"
|
||||
|
||||
/* number of slot types. bitmask used so should be < sizeof(unsigned *8) */
|
||||
#define SLOT_COUNT 28
|
||||
static_assert(SLOT_COUNT <= sizeof(unsigned) * 8, "too many slot types");
|
||||
|
||||
#define kSMARTPORT_SLOT 1
|
||||
#define kBIOS_SLOT 2
|
||||
|
||||
#ifndef SIZEOF
|
||||
#define SIZEOF(x) (sizeof(x) / sizeof(x[0]))
|
||||
#endif
|
||||
|
||||
//NS_ASSUME_NONNULL_BEGIN
|
||||
@class Slot, SlotOption, SlotTableCellView;
|
||||
|
@ -36,6 +26,7 @@ static_assert(SLOT_COUNT <= sizeof(unsigned) * 8, "too many slot types");
|
|||
@property (readonly) NSArray *menuItems;
|
||||
|
||||
@property (readonly) SlotOption *selectedItem;
|
||||
@property (readonly) NSString *selectedValue;
|
||||
|
||||
-(NSArray *)args;
|
||||
-(NSDictionary *)serialize;
|
||||
|
|
108
Ample/Slot.m
108
Ample/Slot.m
|
@ -72,48 +72,6 @@ static NSArray *DeepCopyArray(NSArray *src) {
|
|||
|
||||
@implementation Slot
|
||||
|
||||
static NSDictionary *IndexMap = nil;
|
||||
+(void)load {
|
||||
|
||||
IndexMap = @{
|
||||
@"ramsize": @0,
|
||||
|
||||
@"smartport": @1,
|
||||
@"bios": @2,
|
||||
|
||||
@"sl0": @3,
|
||||
@"sl1": @4,
|
||||
@"sl2": @5,
|
||||
@"sl3": @6,
|
||||
@"sl4": @7,
|
||||
@"sl5": @8,
|
||||
@"sl6": @9,
|
||||
@"sl7": @10,
|
||||
@"exp": @11,
|
||||
@"aux": @12,
|
||||
@"rs232": @13,
|
||||
@"gameio": @14,
|
||||
@"modem": @15,
|
||||
@"printer": @16,
|
||||
|
||||
//nubus mac
|
||||
@"nb9": @17,
|
||||
@"nba": @18,
|
||||
@"nbb": @19,
|
||||
@"nbc": @20,
|
||||
@"nbd": @21,
|
||||
@"nbe": @22,
|
||||
|
||||
@"pds": @23,
|
||||
@"pds030": @24,
|
||||
|
||||
@"centronics": @25,
|
||||
@"mdin": @26,
|
||||
@"mdout": @27
|
||||
};
|
||||
static_assert(kSMARTPORT_SLOT == 1, "Smartport != 1");
|
||||
static_assert(kBIOS_SLOT == 2, "Bios != 2");
|
||||
}
|
||||
|
||||
-(void)reset {
|
||||
[self setSelectedIndex: _defaultIndex >= 0 ? _defaultIndex : 0];
|
||||
|
@ -171,7 +129,7 @@ static NSDictionary *IndexMap = nil;
|
|||
// { 'sl3' : 'uthernet' }
|
||||
|
||||
// special case for smartport since the name isn't used.
|
||||
if (_index == kSMARTPORT_SLOT) {
|
||||
if ([_name isEqualToString: @"-smartport"]) {
|
||||
SlotOption *option = [_options objectAtIndex: _selectedIndex];
|
||||
[option reserialize: dict];
|
||||
return;
|
||||
|
@ -230,9 +188,14 @@ static NSDictionary *IndexMap = nil;
|
|||
|
||||
[option buildMedia: &media];
|
||||
return media;
|
||||
|
||||
}
|
||||
|
||||
-(NSString *)selectedValue {
|
||||
|
||||
if (_selectedIndex < 0) return nil;
|
||||
if (_selectedIndex >= [_options count]) return nil;
|
||||
return [[_options objectAtIndex: _selectedIndex] value];
|
||||
}
|
||||
|
||||
-(NSArray *)selectedChildren {
|
||||
if (_selectedIndex < 0) return nil;
|
||||
|
@ -288,21 +251,22 @@ static NSDictionary *IndexMap = nil;
|
|||
if (c != '-') _name = p;
|
||||
}
|
||||
|
||||
|
||||
-(instancetype)initWithDictionary: (NSDictionary *)data devices: (NSDictionary *)devices {
|
||||
return [self initWithDictionary: data devices: devices index: 0];
|
||||
}
|
||||
|
||||
-(instancetype)initWithDictionary: (NSDictionary *)data devices: (NSDictionary *)devices index: (NSInteger)index {
|
||||
|
||||
BOOL topLevel = NO;
|
||||
_selectedIndex = -1;
|
||||
_defaultIndex = -1;
|
||||
_index = -1;
|
||||
_index = index;
|
||||
|
||||
_name = [data objectForKey: @"name"];
|
||||
_title = [data objectForKey: @"description"];
|
||||
|
||||
NSNumber *x = [IndexMap objectForKey: _name];
|
||||
if (x) {
|
||||
if (index < 0x10000) {
|
||||
topLevel = YES;
|
||||
_index = [x integerValue];
|
||||
_name = [@"-" stringByAppendingString: _name];
|
||||
_title = [_title stringByAppendingString: @":"];
|
||||
}
|
||||
|
@ -310,14 +274,13 @@ static NSDictionary *IndexMap = nil;
|
|||
NSArray *op = [data objectForKey: @"options"];
|
||||
NSMutableArray *options = [NSMutableArray arrayWithCapacity: [op count]];
|
||||
|
||||
|
||||
NSInteger index = 0;
|
||||
NSInteger ix = 0;
|
||||
for (NSDictionary *d in op) {
|
||||
SlotOption *o = [[SlotOption alloc] initWithDictionary: d devices: devices];
|
||||
if ([o isDefault]) {
|
||||
_defaultIndex = index;
|
||||
_defaultIndex = ix;
|
||||
}
|
||||
++index;
|
||||
++ix;
|
||||
if (topLevel) {
|
||||
[o setKeyPath: _name];
|
||||
NSArray *tmp = [o children];
|
||||
|
@ -338,36 +301,6 @@ static NSDictionary *IndexMap = nil;
|
|||
return self;
|
||||
}
|
||||
|
||||
#if 0
|
||||
-(instancetype)initWithName: (NSString *)name title: (NSString *)title data: (NSArray *)data {
|
||||
|
||||
_name = [name copy];
|
||||
_title = [title copy];
|
||||
_selectedIndex = -1;
|
||||
_defaultIndex = -1;
|
||||
_index = -1;
|
||||
|
||||
NSMutableArray *options = [NSMutableArray arrayWithCapacity: [data count]];
|
||||
//NSMutableArray *menuItems = [NSMutableArray arrayWithCapacity: [data count]];
|
||||
|
||||
NSInteger index = 0;
|
||||
for (NSDictionary *d in data) {
|
||||
SlotOption *o = [[SlotOption alloc] initWithDictionary: d];
|
||||
if ([o isDefault]) {
|
||||
_defaultIndex = index;
|
||||
}
|
||||
++index;
|
||||
[options addObject: o];
|
||||
}
|
||||
_options = options;
|
||||
//_menuItems = menuItems;
|
||||
|
||||
_selectedIndex = _defaultIndex;
|
||||
if (_selectedIndex < 0) _selectedIndex = 0;
|
||||
|
||||
return self;
|
||||
}
|
||||
#endif
|
||||
|
||||
-(NSArray *)menuItems {
|
||||
//if (_menuItems) return _menuItems;
|
||||
|
@ -406,7 +339,8 @@ static NSDictionary *IndexMap = nil;
|
|||
|
||||
// [menu setItemArray: ] doesn't work prior to 10.14, apparently.
|
||||
[menu removeAllItems];
|
||||
if (_index == kSMARTPORT_SLOT) {
|
||||
|
||||
if ([_name isEqualToString: @"-smartport"]) {
|
||||
//[menu setItemArray: @[]];
|
||||
[button setHidden: YES];
|
||||
} else {
|
||||
|
@ -630,7 +564,7 @@ NSDictionary *BuildDevices(NSArray *array) {
|
|||
|
||||
NSArray *data = MapArray(slots, ^(id o){
|
||||
|
||||
Slot *s = [[Slot alloc] initWithDictionary: o devices: nil];
|
||||
Slot *s = [[Slot alloc] initWithDictionary: o devices: nil index: 0];
|
||||
return s;
|
||||
});
|
||||
|
||||
|
@ -658,9 +592,11 @@ NSArray *BuildSlots(NSString *name, NSDictionary *data) {
|
|||
NSMutableArray *rv = [NSMutableArray arrayWithCapacity: [slots count]];
|
||||
|
||||
NSDictionary *devices = BuildDevices([data objectForKey: @"devices"]);
|
||||
|
||||
unsigned ix = 0;
|
||||
for (NSDictionary *d in slots) {
|
||||
|
||||
Slot *s = [[Slot alloc] initWithDictionary: d devices: devices];
|
||||
Slot *s = [[Slot alloc] initWithDictionary: d devices: devices index: ++ix];
|
||||
[rv addObject: s];
|
||||
}
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@
|
|||
|
||||
#import <objc/runtime.h>
|
||||
|
||||
|
||||
#define MAX_SLOTS 32
|
||||
|
||||
|
||||
static unsigned RootKey = 0;
|
||||
|
@ -31,18 +31,13 @@ static unsigned RootKey = 0;
|
|||
@implementation SlotViewController {
|
||||
NSArray *_root;
|
||||
|
||||
unsigned _slots_explicit;
|
||||
unsigned _slots_valid;
|
||||
unsigned _slots_default;
|
||||
|
||||
Slot *_slot_object[SLOT_COUNT];
|
||||
NSString *_slot_value[SLOT_COUNT]; // when explicitely set.
|
||||
|
||||
Media _slot_media[SLOT_COUNT];
|
||||
Media _slot_media[MAX_SLOTS];
|
||||
Media _machine_media;
|
||||
|
||||
NSDictionary *_machine_data;
|
||||
|
||||
NSMutableDictionary *_slotValues;
|
||||
|
||||
IBOutlet NSPopover *_popover;
|
||||
|
||||
BOOL _loadingBookmark;
|
||||
|
@ -55,6 +50,7 @@ static unsigned RootKey = 0;
|
|||
_root = @[];
|
||||
objc_setAssociatedObject(_outlineView, &RootKey, _root, OBJC_ASSOCIATION_RETAIN);
|
||||
|
||||
_slotValues = [NSMutableDictionary new];
|
||||
|
||||
//[_outlineView setIndentationPerLevel: 2.0];
|
||||
}
|
||||
|
@ -66,16 +62,13 @@ static unsigned RootKey = 0;
|
|||
|
||||
[_outlineView reloadData];
|
||||
|
||||
_slots_valid = 0;
|
||||
_slots_explicit = 0;
|
||||
_slots_default = 0;
|
||||
[_slotValues removeAllObjects];
|
||||
|
||||
_machine_media = EmptyMedia;
|
||||
_machine_data = nil;
|
||||
|
||||
for (unsigned i = 0; i < SLOT_COUNT; ++i) {
|
||||
for (unsigned i = 0; i < MAX_SLOTS; ++i) {
|
||||
_slot_media[i] = EmptyMedia;
|
||||
_slot_object[i] = nil;
|
||||
_slot_value[i] = nil;
|
||||
}
|
||||
|
||||
[self setResolution: NSMakeSize(0, 0)];
|
||||
|
@ -86,10 +79,8 @@ static unsigned RootKey = 0;
|
|||
|
||||
-(void)loadMachine {
|
||||
|
||||
|
||||
NSDictionary *d = MameMachine(_machine);
|
||||
|
||||
|
||||
if (!d) {
|
||||
[self resetMachine];
|
||||
return;
|
||||
|
@ -103,39 +94,33 @@ static unsigned RootKey = 0;
|
|||
}
|
||||
[self setResolution: res];
|
||||
|
||||
_slots_valid = 0;
|
||||
//_slots_explicit = 0;
|
||||
_slots_default = 0;
|
||||
|
||||
_machine_media = MediaFromDictionary([d objectForKey: @"media"]);
|
||||
|
||||
_machine_data = d;
|
||||
|
||||
for (unsigned i = 0; i < SLOT_COUNT; ++i) {
|
||||
for (unsigned i = 0; i < MAX_SLOTS; ++i) {
|
||||
_slot_media[i] = EmptyMedia;
|
||||
_slot_object[i] = nil;
|
||||
}
|
||||
|
||||
_slot_value[kBIOS_SLOT] = nil; // don't copy over to other machines.
|
||||
|
||||
extern NSArray *BuildSlots(NSString *name, NSDictionary *data);
|
||||
_root = BuildSlots(_machine, d);
|
||||
objc_setAssociatedObject(_outlineView, &RootKey, _root, OBJC_ASSOCIATION_RETAIN);
|
||||
|
||||
for (Slot *item in _root) {
|
||||
NSInteger index = [item index];
|
||||
if (index < 0) continue;
|
||||
unsigned mask = 1 << index;
|
||||
NSString *name = [item name];
|
||||
NSInteger index = [item index] - 1;
|
||||
if (index < 0 || index >= MAX_SLOTS) continue;
|
||||
|
||||
_slots_valid |= mask;
|
||||
if ([item defaultIndex] >= 0)
|
||||
_slots_default |= mask;
|
||||
if ([name isEqualToString: @"-bios"]) continue;
|
||||
|
||||
if (_slot_value[index])
|
||||
[item selectValue: _slot_value[index]];
|
||||
NSString *v = [_slotValues objectForKey: name];
|
||||
if (v) {
|
||||
[item selectValue: v];
|
||||
}
|
||||
// TODO -- reset to default index???
|
||||
|
||||
_slot_media[index] = [item selectedMedia];
|
||||
_slot_object[index] = item;
|
||||
}
|
||||
|
||||
|
||||
|
@ -165,13 +150,10 @@ static unsigned RootKey = 0;
|
|||
|
||||
Media media = EmptyMedia;
|
||||
|
||||
unsigned mask = 1;
|
||||
for (unsigned i = 0; i < SLOT_COUNT; ++i, mask <<= 1) {
|
||||
for (unsigned i = 0; i < MAX_SLOTS; ++i) {
|
||||
|
||||
if (_slots_valid & mask) {
|
||||
MediaAdd(&media, &_slot_media[i]);
|
||||
}
|
||||
}
|
||||
// machine media last.
|
||||
MediaAdd(&media, &_machine_media);
|
||||
|
||||
|
@ -196,34 +178,29 @@ static unsigned RootKey = 0;
|
|||
|
||||
BOOL direct = YES;
|
||||
NSInteger index = [sender tag];
|
||||
if (index < 0) return; //
|
||||
|
||||
if (index >= 0 && index < SLOT_COUNT) {
|
||||
if (index < 0x10000) {
|
||||
direct = YES;
|
||||
} else {
|
||||
direct = NO;
|
||||
index &= ~0x10000;
|
||||
}
|
||||
if (index >= SLOT_COUNT) return; //
|
||||
unsigned mask = 1 << index;
|
||||
|
||||
|
||||
// index 0 = ram = special case...
|
||||
index--;
|
||||
if (index < 0 || index >= MAX_SLOTS) return; //
|
||||
|
||||
SlotOption *o = [[sender selectedItem] representedObject];
|
||||
Slot *item = _slot_object[index];
|
||||
Slot *item = [_root objectAtIndex: index];
|
||||
|
||||
if (direct) {
|
||||
_slots_explicit |= mask;
|
||||
_slot_value[index] = [o value];
|
||||
//_slots_default &= ~mask;
|
||||
NSString *name = [item name];
|
||||
NSString *value = [o value];
|
||||
[_slotValues setObject: value forKey: name];
|
||||
}
|
||||
|
||||
Media media = [item selectedMedia];
|
||||
if (!MediaEqual(&media, &_slot_media[index])) {
|
||||
_slot_media[index] = media;
|
||||
[self rebuildMedia];
|
||||
|
||||
}
|
||||
|
||||
// needs to reload children if expanded.
|
||||
|
@ -244,9 +221,9 @@ static unsigned RootKey = 0;
|
|||
#endif
|
||||
|
||||
NSInteger index = [sender tag];
|
||||
if (index < 0 || index >= SLOT_COUNT) return;
|
||||
|
||||
Slot *item = _slot_object[index];
|
||||
if (index <= 0 || index >= 0x10000) return;
|
||||
index--;
|
||||
Slot *item = [_root objectAtIndex: index];
|
||||
|
||||
NSArray *children = [item selectedChildren];
|
||||
objc_setAssociatedObject(_childOutlineView, &RootKey, children, OBJC_ASSOCIATION_RETAIN);
|
||||
|
@ -266,15 +243,19 @@ static unsigned RootKey = 0;
|
|||
|
||||
-(IBAction)resetSlots:(id)sender {
|
||||
|
||||
_slots_explicit = 0;
|
||||
for (unsigned i = 0; i < SLOT_COUNT; ++i) {
|
||||
|
||||
//_slots_explicit = 0;
|
||||
for (unsigned i = 0; i < MAX_SLOTS; ++i) {
|
||||
_slot_media[i] = EmptyMedia;
|
||||
_slot_value[i] = nil;
|
||||
}
|
||||
for (Slot *item in _root) {
|
||||
NSString *name = [item name];
|
||||
|
||||
[_slotValues removeObjectForKey: name];
|
||||
|
||||
[item reset];
|
||||
// if children, reset them too...
|
||||
NSInteger index = [item index];
|
||||
NSInteger index = [item index] - 1;
|
||||
if (index < 0) continue;
|
||||
_slot_media[index] = [item selectedMedia];
|
||||
}
|
||||
|
@ -367,19 +348,19 @@ static unsigned RootKey = 0;
|
|||
for (Slot *item in _root) {
|
||||
[item reserialize: dict];
|
||||
|
||||
NSInteger index = [item index];
|
||||
if (index >= 0 && index < SLOT_COUNT) {
|
||||
unsigned mask = 1 << index;
|
||||
NSInteger index = [item index] - 1;
|
||||
if (index >= 0 && index < MAX_SLOTS) {
|
||||
|
||||
NSString *name = [item name];
|
||||
[_slotValues removeObjectForKey: name];
|
||||
|
||||
if ([item defaultIndex] != [item selectedIndex]) {
|
||||
_slots_explicit |= mask; // grrr.
|
||||
_slot_value[index] = [[item selectedItem] value];
|
||||
NSString *v = [item selectedValue];
|
||||
if (v) [_slotValues setObject: v forKey: name];
|
||||
}
|
||||
|
||||
_slot_media[index] = [item selectedMedia];
|
||||
}
|
||||
|
||||
++index;
|
||||
}
|
||||
|
||||
// need to do it here so it propogate to media view.
|
||||
|
|
Loading…
Reference in New Issue
Block a user