An attempt to mitigate #703, don't reload the ROM or save states if not required; don't assume a new ROM if state failed to load

This commit is contained in:
Lior Halphon
2025-07-21 23:45:06 +03:00
parent 1dfcdffa71
commit cfbc7b481a

View File

@@ -99,6 +99,7 @@ API_AVAILABLE(ios(13.0))
{ {
GB_gameboy_t _gb; GB_gameboy_t _gb;
GBView *_gbView; GBView *_gbView;
dispatch_queue_t _runQueue;
volatile bool _running; volatile bool _running;
volatile bool _stopping; volatile bool _stopping;
@@ -315,6 +316,8 @@ static void rumbleCallback(GB_gameboy_t *gb, double amp)
_window.rootViewController = self; _window.rootViewController = self;
[_window makeKeyAndVisible]; [_window makeKeyAndVisible];
_runQueue = dispatch_queue_create("SameBoy Emulation Queue", NULL);
#pragma clang diagnostic push #pragma clang diagnostic push
#pragma clang diagnostic ignored "-Warc-retain-cycles" #pragma clang diagnostic ignored "-Warc-retain-cycles"
[self addDefaultObserver:^(id newValue) { [self addDefaultObserver:^(id newValue) {
@@ -875,42 +878,63 @@ static void rumbleCallback(GB_gameboy_t *gb, double amp)
if (romManager.romFile) { if (romManager.romFile) {
if (!_skipAutoLoad) { if (!_skipAutoLoad) {
// Todo: display errors and warnings // Todo: display errors and warnings
if ([romManager.romFile.pathExtension.lowercaseString isEqualToString:@"isx"]) { bool needsStateLoad = false;
_romLoaded = GB_load_isx(&_gb, romManager.romFile.fileSystemRepresentation) == 0; if (![_lastSavedROM isEqual:[GBROMManager sharedManager].currentROM]) {
if ([romManager.romFile.pathExtension.lowercaseString isEqualToString:@"isx"]) {
_romLoaded = GB_load_isx(&_gb, romManager.romFile.fileSystemRepresentation) == 0;
}
else {
_romLoaded = GB_load_rom(&_gb, romManager.romFile.fileSystemRepresentation) == 0;
}
needsStateLoad = true;
} }
else { else if (access(romManager.romFile.fileSystemRepresentation, R_OK)) {
_romLoaded = GB_load_rom(&_gb, romManager.romFile.fileSystemRepresentation) == 0; _romLoaded = false;
} }
if (_romLoaded) { if (!_romLoaded) {
dispatch_async(dispatch_get_main_queue(), ^{
romManager.currentROM = nil;
});
}
if (!needsStateLoad) {
NSDate *date = nil;
[[NSURL fileURLWithPath:[GBROMManager sharedManager].autosaveStateFile] getResourceValue:&date
forKey:NSURLContentModificationDateKey
error:nil];
if (![_saveDate isEqual:date]) {
needsStateLoad = true;
}
}
if (_romLoaded && needsStateLoad) {
GB_reset(&_gb); GB_reset(&_gb);
GB_load_battery(&_gb, [GBROMManager sharedManager].batterySaveFile.fileSystemRepresentation); GB_load_battery(&_gb, [GBROMManager sharedManager].batterySaveFile.fileSystemRepresentation);
GB_remove_all_cheats(&_gb); GB_remove_all_cheats(&_gb);
GB_load_cheats(&_gb, [GBROMManager sharedManager].cheatsFile.UTF8String, false); GB_load_cheats(&_gb, [GBROMManager sharedManager].cheatsFile.UTF8String, false);
if (![self loadStateFromFile:[GBROMManager sharedManager].autosaveStateFile]) { if (![self loadStateFromFile:[GBROMManager sharedManager].autosaveStateFile]) {
// Newly played ROM, pick the best model if ([_lastSavedROM isEqual:[GBROMManager sharedManager].currentROM]) {
uint8_t *rom = GB_get_direct_access(&_gb, GB_DIRECT_ACCESS_ROM, NULL, NULL); /* Something weird just happened: we didn't change a ROM, but we failed to load the
latest save state. Save over the existing file, it's probably corrupt in some
if ((rom[0x143] & 0x80)) { way. */
if (!GB_is_cgb(&_gb)) { [self saveStateToFile:[GBROMManager sharedManager].autosaveStateFile];
GB_switch_model_and_reset(&_gb, [[NSUserDefaults standardUserDefaults] integerForKey:@"GBCGBModel"]); }
else {
// Newly played ROM, pick the best model
uint8_t *rom = GB_get_direct_access(&_gb, GB_DIRECT_ACCESS_ROM, NULL, NULL);
if ((rom[0x143] & 0x80)) {
if (!GB_is_cgb(&_gb)) {
GB_switch_model_and_reset(&_gb, [[NSUserDefaults standardUserDefaults] integerForKey:@"GBCGBModel"]);
}
}
else if ((rom[0x146] == 3) && !GB_is_sgb(&_gb)) {
GB_switch_model_and_reset(&_gb, [[NSUserDefaults standardUserDefaults] integerForKey:@"GBSGBModel"]);
} }
} }
else if ((rom[0x146] == 3) && !GB_is_sgb(&_gb)) { GB_rewind_reset(&_gb);
GB_switch_model_and_reset(&_gb, [[NSUserDefaults standardUserDefaults] integerForKey:@"GBSGBModel"]);
}
} }
} }
NSDate *date = nil;
[[NSURL fileURLWithPath:[GBROMManager sharedManager].autosaveStateFile] getResourceValue:&date
forKey:NSURLContentModificationDateKey
error:nil];
// Reset the rewind buffer only if we switched ROMs or had the save state change externally
if (![_lastSavedROM isEqual:[GBROMManager sharedManager].currentROM] ||
![_saveDate isEqual:date]) {
GB_rewind_reset(&_gb);
}
} }
} }
else { else {
@@ -1480,7 +1504,9 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
if (_running) return; if (_running) return;
if (self.presentedViewController) return; if (self.presentedViewController) return;
_running = true; _running = true;
[[[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil] start]; dispatch_async(_runQueue, ^{
[self run];
});
} }
- (void)stop - (void)stop
@@ -1496,6 +1522,7 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
[_audioLock signal]; [_audioLock signal];
[_audioLock unlock]; [_audioLock unlock];
} }
dispatch_sync(_runQueue, ^{});
dispatch_async(dispatch_get_main_queue(), ^{ dispatch_async(dispatch_get_main_queue(), ^{
self.runMode = GBRunModeNormal; self.runMode = GBRunModeNormal;
[_backgroundView fadeOverlayOut]; [_backgroundView fadeOverlayOut];