DIP switches completed

This commit is contained in:
Akop Karapetyan 2019-10-27 02:02:27 -07:00
parent a92ea6ea73
commit 96d5157ec3
6 changed files with 106 additions and 12 deletions

View File

@ -26,6 +26,7 @@
@property (readonly) NSString *supportPath;
@property (readonly) NSString *nvramPath;
@property (readonly) NSString *dipSwitchPath;
@property (readonly) NSArray *supportedFormats;

View File

@ -59,9 +59,11 @@ static AppDelegate *sharedInstance = nil;
_supportPath = self.appSupportPath;
_nvramPath = [_supportPath stringByAppendingPathComponent:@"NVRAM"];
_dipSwitchPath = [_supportPath stringByAppendingPathComponent:@"DIPSwitches"];
NSArray *paths = @[
_nvramPath
_nvramPath,
_dipSwitchPath,
];
for (NSString *path in paths)
@ -80,7 +82,13 @@ static AppDelegate *sharedInstance = nil;
}
- (void) applicationWillTerminate:(NSNotification *) aNotification {
NSLog(@"applicationWillTerminate");
[_runloop cancel];
// Give the emulation thread some time to finish
NSDate *start = [NSDate date];
while (!_runloop.isFinished && start.timeIntervalSinceNow > -2)
[NSThread sleepForTimeInterval:0.25];
}
- (BOOL) application:(NSApplication *) sender

View File

@ -78,7 +78,7 @@
<key>NSSupportsAutomaticTermination</key>
<true/>
<key>NSSupportsSuddenTermination</key>
<true/>
<false/>
<key>UTImportedTypeDeclarations</key>
<array>
<dict>

View File

@ -33,12 +33,20 @@
AudSoundPlay();
}
- (NSString *) setName
{
return [NSString stringWithCString:BurnDrvGetText(DRV_NAME)
encoding:NSUTF8StringEncoding];
}
- (NSString *) title
{
return [NSString stringWithCString:BurnDrvGetText(DRV_FULLNAME)
encoding:NSUTF8StringEncoding];
}
#pragma mark - DIP switches
- (NSArray<FBDipSetting *> *) dipSwitches
{
if (!bDrvOkay)
@ -50,11 +58,11 @@
int offset = 0;
BurnDIPInfo dipSwitch;
for (int i = 0; BurnDrvGetDIPInfo(&dipSwitch, i) == 0; i++) {
if (dipSwitch.nFlags == 0xf0)
offset = dipSwitch.nInput;
if (!dipSwitch.szText) // defaruto
continue;
if (dipSwitch.nFlags == 0xf0)
offset = dipSwitch.nInput;
if (dipSwitch.nFlags & 0x40) {
FBDipSetting *set = [FBDipSetting new];
set.name = [NSString stringWithCString:dipSwitch.szText
@ -71,14 +79,20 @@
opt.start = dipSwitch.nInput + offset;
opt.mask = dipSwitch.nMask;
opt.setting = dipSwitch.nSetting;
[(NSMutableArray *) active.switches addObject:opt];
// Default switch
BurnDIPInfo dsw2;
for (int j = 0; BurnDrvGetDIPInfo(&dsw2, j) == 0; j++)
if (dsw2.nFlags == 0xff
&& dsw2.nInput == dipSwitch.nInput
if (dsw2.nFlags == 0xff && dsw2.nInput == dipSwitch.nInput
&& (dsw2.nSetting & dipSwitch.nMask) == dipSwitch.nSetting)
active.defaultIndex = active.selectedIndex = active.switches.count - 1;
active.defaultIndex = active.selectedIndex = active.switches.count;
// Active switch
struct GameInp *pgi = GameInp + opt.start;
if ((pgi->Input.Constant.nConst & opt.mask) == dipSwitch.nSetting)
active.selectedIndex = active.switches.count;
[(NSMutableArray *) active.switches addObject:opt];
}
}
@ -90,9 +104,63 @@
if (bDrvOkay) {
struct GameInp *pgi = GameInp + option.start;
pgi->Input.Constant.nConst = (pgi->Input.Constant.nConst & ~option.mask) | (option.setting & option.mask);
self.dipSwitchesDirty = YES;
}
}
- (BOOL) saveDipState:(NSString *) path
{
NSLog(@"saveDipState");
NSArray<FBDipSetting *> *switches = self.dipSwitches;
if (!switches || switches.count < 1)
return YES;
for (FBDipSetting *sw in switches)
if (sw.defaultIndex != sw.selectedIndex)
goto save;
return YES;
save:
FILE *f = fopen([path cStringUsingEncoding:NSUTF8StringEncoding], "w");
if (!f)
return NO;
for (FBDipSetting *sw in switches) {
FBDipOption *opt = sw.switches[sw.selectedIndex];
fprintf(f, "%x %d %02x\n", opt.start, sw.selectedIndex, opt.setting);
}
fclose(f);
return YES;
}
- (BOOL) restoreDipState:(NSString *) path
{
NSLog(@"restoreDipState");
NSArray<FBDipSetting *> *switches = self.dipSwitches;
if (!switches || switches.count < 1)
return YES;
FILE *f = fopen([path cStringUsingEncoding:NSUTF8StringEncoding], "r");
if (!f)
return NO;
int swIndex;
uint32 start;
uint32 setting;
for (int i = 0; fscanf(f, "%x %d %x", &start, &swIndex, &setting) == 3 && i < switches.count; i++) {
FBDipSetting *sw = switches[i];
if (sw.selectedIndex != swIndex && swIndex < sw.switches.count)
[self applyDip:sw.switches[swIndex]];
}
fclose(f);
return YES;
}
@end
#pragma mark - FBDipSetting

View File

@ -43,7 +43,8 @@
@interface FBMainThread : NSThread
@property (readonly) NSString *running;
@property (readonly) NSString *runningPath;
@property BOOL dipSwitchesDirty;
- (NSString *) log;
- (void) load:(NSString *) path;
@ -59,8 +60,11 @@
- (void) setPaused:(BOOL) isPaused;
- (NSString *) title;
- (NSString *) setName;
- (NSArray<FBDipSetting *> *) dipSwitches;
- (void) applyDip:(FBDipOption *) option;
- (BOOL) restoreDipState:(NSString *) path;
- (BOOL) saveDipState:(NSString *) path;
@end

View File

@ -83,7 +83,7 @@ typedef enum LogEntryType {
while (!self.isCancelled) {
if (pathToLoad == nil) {
[NSThread sleepForTimeInterval:.5]; // Pause until there's something to load
[NSThread sleepForTimeInterval:.1]; // Pause until there's something to load
continue;
}
@ -119,7 +119,13 @@ typedef enum LogEntryType {
continue;
}
_running = pathToLoad;
// Load DIP switch config
NSString *dipPath = [AppDelegate.sharedInstance.dipSwitchPath stringByAppendingPathComponent:
[NSString stringWithFormat:@"%@.dip", self.setName]];
[self restoreDipState:dipPath];
_dipSwitchesDirty = NO;
_runningPath = pathToLoad;
pathToLoad = nil;
@synchronized (observers) {
@ -134,9 +140,14 @@ typedef enum LogEntryType {
}
}
// Runtime loop
while (!self.isCancelled && pathToLoad == nil)
MainFrame();
// Save DIP switch config
if (_dipSwitchesDirty)
[self saveDipState:dipPath];
@synchronized (observers) {
for (id<FBMainThreadDelegate> o in observers) {
dispatch_async(dispatch_get_main_queue(), ^{
@ -146,10 +157,12 @@ typedef enum LogEntryType {
}
}
_running = nil;
_runningPath = nil;
MainEnd();
}
NSLog(@"Exiting FBMainThread");
}
@end