Syncing with the App Store branch (iCloud support)

This commit is contained in:
Lior Halphon 2024-09-14 23:58:58 +03:00
parent 8cb94e7a8b
commit 1931c2830f
14 changed files with 218 additions and 152 deletions

View File

@ -231,6 +231,7 @@
self.navigationController.toolbar.disableCompactLayout = true;
}
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentAtURL:(NSURL *)url
{
[url startAccessingSecurityScopedResource];

View File

@ -218,7 +218,6 @@
if ([GBROMManager.sharedManager romFileForROM:_game.title]) {
[GBROMManager sharedManager].currentROM = _game.title;
[self.navigationController dismissViewControllerAnimated:true completion:nil];
[[NSNotificationCenter defaultCenter] postNotificationName:@"GBROMChanged" object:nil];
}
else {
UIActivityIndicatorViewStyle style = UIActivityIndicatorViewStyleWhite;
@ -237,9 +236,9 @@
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"Could not download ROM"
message:@"Could not download this ROM from Homebrew Hub. Please try again later."
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"Close"
style:UIAlertActionStyleCancel
handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"Close"
style:UIAlertActionStyleCancel
handler:nil]];
[self presentViewController:alert animated:true completion:nil];
self.navigationItem.rightBarButtonItem.customView = nil;
});

View File

@ -1,6 +1,6 @@
#import <UIKit/UIKit.h>
@interface GBLibraryViewController : UITabBarController
@end

View File

@ -1,7 +1,9 @@
#import "GBLibraryViewController.h"
#import "GBLoadROMTableViewController.h"
#import "GBROMViewController.h"
#import "GBHubViewController.h"
#import "GBViewController.h"
#import "GBROMManager.h"
@implementation GBLibraryViewController
@ -19,8 +21,9 @@
- (void)viewDidLoad
{
[super viewDidLoad];
self.viewControllers = @[
[self.class wrapViewController:[[GBLoadROMTableViewController alloc] init]],
[self.class wrapViewController:[[GBROMViewController alloc] init]],
[self.class wrapViewController:[[GBHubViewController alloc] init]],
];
if (@available(iOS 13.0, *)) {
@ -42,7 +45,7 @@
}
}
self.viewControllers[0].tabBarItem.image = [UIImage systemImageNamed:symbol] ?: [UIImage systemImageNamed:@"folder.fill"];
self.viewControllers[1].tabBarItem.image = [UIImage systemImageNamed:@"globe"];
self.viewControllers.lastObject.tabBarItem.image = [UIImage systemImageNamed:@"globe"];
}
else {
self.viewControllers[0].tabBarItem.image = [UIImage imageNamed:@"FolderTemplate"];
@ -50,4 +53,5 @@
}
}
@end

View File

@ -1,5 +0,0 @@
#import <UIKit/UIKit.h>
@interface GBLoadROMTableViewController : UITableViewController
@end

View File

@ -10,6 +10,8 @@
@property (readonly) NSString *batterySaveFile;
@property (readonly) NSString *autosaveStateFile;
@property (readonly) NSString *cheatsFile;
@property (readonly) NSString *localRoot;
- (NSString *)stateFile:(unsigned)index;
- (NSString *)romFileForROM:(NSString *)rom;
@ -21,4 +23,5 @@
- (NSString *)renameROM:(NSString *)rom toName:(NSString *)newName;
- (NSString *)duplicateROM:(NSString *)rom;
- (void)deleteROM:(NSString *)rom;
@end

View File

@ -4,6 +4,8 @@
@implementation GBROMManager
{
NSString *_romFile;
NSMutableDictionary<NSString *,NSString *> *_cloudNameToFile;
bool _doneInitializing;
}
+ (instancetype)sharedManager
@ -21,6 +23,7 @@
self = [super init];
if (!self) return nil;
self.currentROM = [[NSUserDefaults standardUserDefaults] stringForKey:@"GBLastROM"];
_doneInitializing = true;
return self;
}
@ -28,11 +31,16 @@
{
_romFile = nil;
_currentROM = currentROM;
if (currentROM && !self.romFile) {
bool foundROM = self.romFile;
if (currentROM && !foundROM) {
_currentROM = nil;
}
[[NSUserDefaults standardUserDefaults] setObject:_currentROM forKey:@"GBLastROM"];
if (_doneInitializing) {
[[NSNotificationCenter defaultCenter] postNotificationName:@"GBROMChanged" object:nil];
}
}
- (NSString *)romFileForDirectory:(NSString *)romDirectory
@ -47,13 +55,17 @@
return nil;
}
- (NSString *)romDirectoryForROM:(NSString *)romFile
{
return [self.localRoot stringByAppendingPathComponent:romFile];
}
- (NSString *)romFile
{
if (_romFile) return _romFile;
if (!_currentROM) return nil;
NSString *root = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true).firstObject;
NSString *romDirectory = [root stringByAppendingPathComponent:_currentROM];
return _romFile = [self romFileForDirectory:romDirectory];
return _romFile = [self romFileForDirectory:[self romDirectoryForROM:_currentROM]];
}
- (NSString *)romFileForROM:(NSString *)rom
@ -63,9 +75,9 @@
if (rom == _currentROM) {
return self.romFile;
}
NSString *root = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true).firstObject;
NSString *romDirectory = [root stringByAppendingPathComponent:rom];
return [self romFileForDirectory:romDirectory];
return [self romFileForDirectory:[self romDirectoryForROM:rom]];
}
- (NSString *)auxilaryFileForROM:(NSString *)rom withExtension:(NSString *)extension
@ -117,7 +129,7 @@
- (NSArray<NSString *> *)allROMs
{
NSMutableArray<NSString *> *ret = [NSMutableArray array];
NSString *root = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true).firstObject;
NSString *root = self.localRoot;
for (NSString *romDirectory in [NSFileManager.defaultManager contentsOfDirectoryAtPath:root
error:nil]) {
if ([romDirectory hasPrefix:@"."] || [romDirectory isEqualToString:@"Inbox"]) continue;
@ -130,7 +142,7 @@
- (NSString *)makeNameUnique:(NSString *)name
{
NSString *root = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true).firstObject;
NSString *root = self.localRoot;
if (![[NSFileManager defaultManager] fileExistsAtPath:[root stringByAppendingPathComponent:name]]) return name;
unsigned i = 2;
@ -150,27 +162,14 @@
NSString *friendlyName = [[romFile lastPathComponent] stringByDeletingPathExtension];
friendlyName = [regex stringByReplacingMatchesInString:friendlyName options:0 range:NSMakeRange(0, [friendlyName length]) withTemplate:@""];
friendlyName = [friendlyName stringByTrimmingCharactersInSet:[NSCharacterSet whitespaceCharacterSet]];
NSString *root = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true).firstObject;
if ([[NSFileManager defaultManager] fileExistsAtPath:[root stringByAppendingPathComponent:friendlyName]]) {
unsigned i = 2;
while (true) {
NSString *attempt = [friendlyName stringByAppendingFormat:@" %u", i];
if ([[NSFileManager defaultManager] fileExistsAtPath:[root stringByAppendingPathComponent:attempt]]) {
i++;
continue;
}
friendlyName = attempt;
break;
}
}
friendlyName = [self makeNameUnique:friendlyName];
return [self importROM:romFile withName:friendlyName keepOriginal:keep];
}
- (NSString *)importROM:(NSString *)romFile withName:(NSString *)friendlyName keepOriginal:(bool)keep
{
NSString *root = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true).firstObject;
NSString *root = self.localRoot;
NSString *romFolder = [root stringByAppendingPathComponent:friendlyName];
[[NSFileManager defaultManager] createDirectoryAtPath:romFolder
withIntermediateDirectories:false
@ -205,9 +204,9 @@
{
newName = [self makeNameUnique:newName];
if ([rom isEqualToString:_currentROM]) {
_currentROM = newName;
self.currentROM = newName;
}
NSString *root = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true).firstObject;
NSString *root = self.localRoot;
[[NSFileManager defaultManager] moveItemAtPath:[root stringByAppendingPathComponent:rom]
toPath:[root stringByAppendingPathComponent:newName] error:nil];
@ -224,9 +223,14 @@
- (void)deleteROM:(NSString *)rom
{
NSString *root = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true).firstObject;
NSString *root = self.localRoot;
NSString *romDirectory = [root stringByAppendingPathComponent:rom];
[[NSFileManager defaultManager] removeItemAtPath:romDirectory error:nil];
}
- (NSString *)localRoot
{
return NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true).firstObject;
}
@end

14
iOS/GBROMViewController.h Normal file
View File

@ -0,0 +1,14 @@
#import <UIKit/UIKit.h>
@interface GBROMViewController : UITableViewController<UIDocumentPickerDelegate>
/* For inheritance */
- (void)romSelectedAtIndex:(unsigned)index;
- (void)deleteROMAtIndex:(unsigned)index;
- (void)renameROM:(NSString *)oldName toName:(NSString *)newName;
- (void)duplicateROMAtIndex:(unsigned)index;
- (NSString *)rootPath;
/* To be used by subclasses */
- (UITableViewCell *)cellForROM:(NSString *)rom;
@end

View File

@ -1,13 +1,11 @@
#import "GBLoadROMTableViewController.h"
#import "GBROMViewController.h"
#import "GBROMManager.h"
#import "GBViewController.h"
#import "GBLibraryViewController.h"
#import <CoreServices/CoreServices.h>
#import <objc/runtime.h>
@interface GBLoadROMTableViewController() <UIDocumentPickerDelegate>
@end
@implementation GBLoadROMTableViewController
@implementation GBROMViewController
{
NSIndexPath *_renamingPath;
}
@ -36,19 +34,10 @@
return [GBROMManager sharedManager].allROMs.count;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
- (UITableViewCell *)cellForROM:(NSString *)rom
{
if (indexPath.section == 1) {
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
switch (indexPath.item) {
case 0: cell.textLabel.text = @"Import ROM files"; break;
case 1: cell.textLabel.text = @"Show Library in Files"; break;
}
return cell;
}
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
NSString *rom = [GBROMManager sharedManager].allROMs[[indexPath indexAtPosition:1]];
cell.textLabel.text = rom;
cell.textLabel.text = rom.lastPathComponent;
cell.accessoryType = [rom isEqualToString:[GBROMManager sharedManager].currentROM]? UITableViewCellAccessoryCheckmark : UITableViewCellAccessoryNone;
NSString *pngPath = [[[GBROMManager sharedManager] autosaveStateFileForROM:rom] stringByAppendingPathExtension:@"png"];
@ -68,6 +57,20 @@
UIGraphicsEndImageContext();
return cell;
}
- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 1) {
UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil];
switch (indexPath.item) {
case 0: cell.textLabel.text = @"Import ROM files"; break;
case 1: cell.textLabel.text = @"Show Library in Files"; break;
}
return cell;
}
return [self cellForROM:[GBROMManager sharedManager].allROMs[[indexPath indexAtPosition:1]]];
}
- (CGFloat)tableView:(UITableView *)tableView heightForRowAtIndexPath:(NSIndexPath *)indexPath
@ -89,6 +92,12 @@
return @"You can also import ROM files by opening them in SameBoy using the Files app or a web browser, or by sending them over with AirDrop.";
}
- (void)romSelectedAtIndex:(unsigned)index
{
[GBROMManager sharedManager].currentROM = [GBROMManager sharedManager].allROMs[index];
[self.presentingViewController dismissViewControllerAnimated:true completion:nil];
}
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 1) {
@ -110,9 +119,9 @@
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"File Association Conflict"
message:@"Due to a limitation in iOS, the file picker will allow you to select files not supported by SameBoy. SameBoy will only import GB, GBC and ISX files.\n\nIf you have a multi-system emulator installed, updating it could fix this problem."
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"Close"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action) {
[alert addAction:[UIAlertAction actionWithTitle:@"Close"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action) {
[[NSUserDefaults standardUserDefaults] setBool:true forKey:@"GBShownUTIWarning"];
[self tableView:tableView didSelectRowAtIndexPath:indexPath];
}]];
@ -141,22 +150,22 @@
return;
}
case 1: {
[[UIApplication sharedApplication] openURL:[NSURL URLWithString:[NSString stringWithFormat:@"shareddocuments://%@", NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true).firstObject]]
NSURL *url = [NSURL URLWithString:[NSString stringWithFormat:@"shareddocuments://%@",
[self.rootPath stringByAddingPercentEncodingWithAllowedCharacters:[NSCharacterSet URLPathAllowedCharacterSet]]]];
[[UIApplication sharedApplication] openURL:url
options:nil
completionHandler:nil];
return;
}
}
}
[GBROMManager sharedManager].currentROM = [GBROMManager sharedManager].allROMs[[indexPath indexAtPosition:1]];
[self.presentingViewController dismissViewControllerAnimated:true completion:^{
[[NSNotificationCenter defaultCenter] postNotificationName:@"GBROMChanged" object:nil];
}];
[self romSelectedAtIndex:indexPath.row];
}
- (void)documentPicker:(UIDocumentPickerViewController *)controller didPickDocumentsAtURLs:(NSArray <NSURL *>*)urls
{
[(GBViewController *)[UIApplication sharedApplication] handleOpenURLs:urls openInPlace:false];
[(GBViewController *)[UIApplication sharedApplication].delegate handleOpenURLs:urls
openInPlace:false];
}
- (UIModalPresentationStyle)modalPresentationStyle
@ -164,28 +173,34 @@
return UIModalPresentationOverFullScreen;
}
- (void)deleteROMAtIndex:(unsigned)index
{
NSString *rom = [GBROMManager sharedManager].allROMs[index];
[[GBROMManager sharedManager] deleteROM:rom];
[self.tableView deleteRowsAtIndexPaths:@[[NSIndexPath indexPathForRow:index inSection:0]] withRowAnimation:UITableViewRowAnimationAutomatic];
if ([[GBROMManager sharedManager].currentROM isEqualToString:rom]) {
[GBROMManager sharedManager].currentROM = nil;
}
}
- (void)tableView:(UITableView *)tableView commitEditingStyle:(UITableViewCellEditingStyle)editingStyle forRowAtIndexPath:(NSIndexPath *)indexPath
{
if (indexPath.section == 1) return;
if (editingStyle != UITableViewCellEditingStyleDelete) return;
NSString *rom = [GBROMManager sharedManager].allROMs[[indexPath indexAtPosition:1]];
UIAlertController *alert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"Delete ROM “%@”?", rom]
NSString *rom = [self.tableView cellForRowAtIndexPath:indexPath].textLabel.text;
UIAlertController *alert = [UIAlertController alertControllerWithTitle:[NSString stringWithFormat:@"Delete “%@”?", rom]
message: @"Save data for this ROM will also be deleted."
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"Delete"
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction *action) {
[[GBROMManager sharedManager] deleteROM:rom];
[self.tableView deleteRowsAtIndexPaths:@[indexPath] withRowAnimation:UITableViewRowAnimationAutomatic];
if ([[GBROMManager sharedManager].currentROM isEqualToString:rom]) {
[GBROMManager sharedManager].currentROM = nil;
[[NSNotificationCenter defaultCenter] postNotificationName:@"GBROMChanged" object:nil];
}
[alert addAction:[UIAlertAction actionWithTitle:@"Delete"
style:UIAlertActionStyleDestructive
handler:^(UIAlertAction *action) {
[self deleteROMAtIndex:indexPath.row];
}]];
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel"
style:UIAlertActionStyleCancel
handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"Cancel"
style:UIAlertActionStyleCancel
handler:nil]];
[self presentViewController:alert animated:true completion:nil];
}
@ -197,7 +212,7 @@
UITextField *field = [[UITextField alloc] initWithFrame:cell.textLabel.frame];
field.font = cell.textLabel.font;
field.text = cell.textLabel.text;
cell.textLabel.text = @"";
cell.textLabel.textColor = [UIColor clearColor];
[[cell.textLabel superview] addSubview:field];
[field becomeFirstResponder];
[field selectAll:nil];
@ -205,29 +220,36 @@
[field addTarget:self action:@selector(doneRename:) forControlEvents:UIControlEventEditingDidEnd | UIControlEventEditingDidEndOnExit];
}
- (void)renameROM:(NSString *)oldName toName:(NSString *)newName
{
[[GBROMManager sharedManager] renameROM:oldName toName:newName];
[self.tableView reloadData];
}
- (void)doneRename:(UITextField *)sender
{
if (!_renamingPath) return;
NSString *newName = sender.text;
NSString *oldName = [GBROMManager sharedManager].allROMs[[_renamingPath indexAtPosition:1]];
NSString *oldName = [self.tableView cellForRowAtIndexPath:_renamingPath].textLabel.text;
_renamingPath = nil;
if ([newName isEqualToString:oldName]) {
[self.tableView reloadData];
return;
}
if ([newName containsString:@"/"]) {
[self.tableView reloadData];
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"You can't use a name that contains “/”. Please choose another name."
message:nil
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleCancel
handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"OK"
style:UIAlertActionStyleCancel
handler:nil]];
[self presentViewController:alert animated:true completion:nil];
return;
}
[[GBROMManager sharedManager] renameROM:oldName toName:newName];
[self.tableView reloadData];
[self renameROM:oldName toName:newName];
_renamingPath = nil;
}
@ -236,6 +258,13 @@
return indexPath.section == 0;
}
- (void)duplicateROMAtIndex:(unsigned)index
{
[[GBROMManager sharedManager] duplicateROM:[GBROMManager sharedManager].allROMs[index]];
[self.tableView reloadData];
}
// Leave these ROM management to iOS 13.0 and up for now
- (UIContextMenuConfiguration *)tableView:(UITableView *)tableView
contextMenuConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath
@ -266,8 +295,7 @@ contextMenuConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath
image:[UIImage systemImageNamed:@"plus.square.on.square"]
identifier:nil
handler:^(__kindof UIAction *action) {
[[GBROMManager sharedManager] duplicateROM:[GBROMManager sharedManager].allROMs[[indexPath indexAtPosition:1]]];
[self.tableView reloadData];
[self duplicateROMAtIndex:indexPath.row];
}],
deleteAction,
]];
@ -286,4 +314,9 @@ contextMenuConfigurationForRowAtIndexPath:(NSIndexPath *)indexPath
[self.tableView reloadData];
}
- (NSString *)rootPath
{
return [GBROMManager sharedManager].localRoot;
}
@end

View File

@ -696,9 +696,9 @@ static NSString *LocalizedNameForElement(GCControllerElement *element, GBControl
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"No Controllers Connected"
message:@"There are no connected game controllers to configure"
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"Close"
style:UIAlertActionStyleCancel
handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"Close"
style:UIAlertActionStyleCancel
handler:nil]];
[self presentViewController:alert animated:true completion:nil];
return false;

View File

@ -35,6 +35,7 @@
}
}
- (void)viewDidLoad
{
[super viewDidLoad];

View File

@ -57,16 +57,16 @@
// No supporter-only themes outside the App Store release
}
else {
[alert addAction:[UIAlertAction actionWithTitle:@"Apply Theme"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[alert addAction:[UIAlertAction actionWithTitle:@"Apply Theme"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[[NSUserDefaults standardUserDefaults] setObject:_verticalLayout.theme.name forKey:@"GBInterfaceTheme"];
[[self presentingViewController] dismissViewControllerAnimated:true completion:nil];
}]];
}
[alert addAction:[UIAlertAction actionWithTitle:@"Exit Preview"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[alert addAction:[UIAlertAction actionWithTitle:@"Exit Preview"
style:UIAlertActionStyleDefault
handler:^(UIAlertAction *action) {
[[self presentingViewController] dismissViewControllerAnimated:true completion:nil];
}]];
[self presentViewController:alert animated:true completion:^{

View File

@ -27,7 +27,8 @@ typedef enum {
- (void)emptyPrinterFeed;
- (void)saveStateToFile:(NSString *)file;
- (bool)loadStateFromFile:(NSString *)file;
- (bool)handleOpenURLs:(NSArray <NSURL *> *)urls openInPlace:(bool)inPlace;
- (bool)handleOpenURLs:(NSArray <NSURL *> *)urls
openInPlace:(bool)inPlace;
- (void)dismissViewController;
@property (nonatomic) GBRunMode runMode;
@end

View File

@ -32,6 +32,7 @@
bool _rewindOver;
bool _romLoaded;
bool _swappingROM;
bool _loadingState;
UIInterfaceOrientation _orientation;
GBHorizontalLayout *_horizontalLayout;
@ -265,12 +266,12 @@ static void rumbleCallback(GB_gameboy_t *gb, double amp)
_audioLock = [[NSCondition alloc] init];
[self loadROM];
[[NSNotificationCenter defaultCenter] addObserverForName:@"GBROMChanged"
object:nil
queue:nil
usingBlock:^(NSNotification *note) {
[self loadROM];
_swappingROM = true;
[self stop];
[self start];
}];
@ -628,9 +629,9 @@ static void rumbleCallback(GB_gameboy_t *gb, double amp)
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"SameBoy is not properly signed and might not be able to open ROMs"
message:[NSString stringWithFormat:@"The bundle identifier in the Info.plist file (“%@”) does not match the one in the entitlements (“%@”)", plistIdentifier, entIdentifier]
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"Close"
style:UIAlertActionStyleCancel
handler:nil]];
[alert addAction:[UIAlertAction actionWithTitle:@"Close"
style:UIAlertActionStyleCancel
handler:nil]];
[self presentViewController:alert animated:true completion:nil];
}
}
@ -648,7 +649,7 @@ static void rumbleCallback(GB_gameboy_t *gb, double amp)
- (bool)loadStateFromFile:(NSString *)file
{
[self stop];
_loadingState = true;
GB_model_t model;
if (!GB_get_state_model(file.fileSystemRepresentation, &model)) {
if (GB_get_model(&_gb) != model) {
@ -656,53 +657,56 @@ static void rumbleCallback(GB_gameboy_t *gb, double amp)
}
return GB_load_state(&_gb, file.fileSystemRepresentation) == 0;
}
return false;
}
- (void)loadROM
{
_swappingROM = true;
[self stop];
GBROMManager *romManager = [GBROMManager sharedManager];
if (romManager.romFile) {
// Todo: display errors and warnings
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;
}
if (_romLoaded) {
GB_reset(&_gb);
GB_load_battery(&_gb, [GBROMManager sharedManager].batterySaveFile.fileSystemRepresentation);
GB_remove_all_cheats(&_gb);
GB_load_cheats(&_gb, [GBROMManager sharedManager].cheatsFile.UTF8String, false);
if (![self loadStateFromFile:[GBROMManager sharedManager].autosaveStateFile]) {
// 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"]);
if (!_loadingState) {
// Todo: display errors and warnings
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;
}
if (_romLoaded) {
GB_reset(&_gb);
GB_load_battery(&_gb, [GBROMManager sharedManager].batterySaveFile.fileSystemRepresentation);
GB_remove_all_cheats(&_gb);
GB_load_cheats(&_gb, [GBROMManager sharedManager].cheatsFile.UTF8String, false);
if (![self loadStateFromFile:[GBROMManager sharedManager].autosaveStateFile]) {
// 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_switch_model_and_reset(&_gb, [[NSUserDefaults standardUserDefaults] integerForKey:@"GBSGBModel"]);
}
}
GB_rewind_reset(&_gb);
}
GB_rewind_reset(&_gb);
}
else {
_romLoaded = false;
}
_gbView.hidden = !_romLoaded;
dispatch_async(dispatch_get_main_queue(), ^{
_gbView.hidden = !_romLoaded;
});
_swappingROM = false;
_loadingState = false;
}
- (void)applicationDidBecomeActive:(UIApplication *)application
{
if (self.presentedViewController) return;
[self start];
}
@ -758,9 +762,9 @@ static void rumbleCallback(GB_gameboy_t *gb, double amp)
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"SameBoy is not a Game Boy Advance Emulator"
message:@"SameBoy cannot play GBA games. Changing the model to Game Boy Advance lets you play Game Boy games as if on a Game Boy Advance in Game Boy Color mode."
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"Close"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action) {
[alert addAction:[UIAlertAction actionWithTitle:@"Close"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action) {
[self start];
[[NSUserDefaults standardUserDefaults] setBool:true forKey:@"GBShownGBAWarning"];
}]];
@ -836,9 +840,9 @@ static void rumbleCallback(GB_gameboy_t *gb, double amp)
if (completion) {
completion();
}
if (!self.presentedViewController) {
dispatch_async(dispatch_get_main_queue(), ^{
[self start];
}
});
}];
}
@ -846,9 +850,9 @@ static void rumbleCallback(GB_gameboy_t *gb, double amp)
{
/* Hack. Some view controllers dismiss without calling the method above. */
[super setNeedsUpdateOfSupportedInterfaceOrientations];
if (!self.presentedViewController) {
dispatch_async(dispatch_get_main_queue(), ^{
[self start];
}
});
}
- (void)dismissViewController
@ -1047,6 +1051,12 @@ static void rumbleCallback(GB_gameboy_t *gb, double amp)
- (void)run
{
[self loadROM];
if (!_romLoaded) {
_running = false;
_stopping = false;
return;
}
[self preRun];
while (_running) {
if (_rewind) {
@ -1168,8 +1178,8 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
- (void)start
{
if (!_romLoaded) return;
if (_running) return;
if (self.presentedViewController) return;
_running = true;
[[[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil] start];
}
@ -1289,7 +1299,8 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
GB_set_palette(&_gb, &_palette);
}
- (bool)handleOpenURLs:(NSArray <NSURL *> *)urls openInPlace:(bool)inPlace
- (bool)handleOpenURLs:(NSArray <NSURL *> *)urls
openInPlace:(bool)inPlace
{
NSMutableArray<NSURL *> *validURLs = [NSMutableArray array];
NSMutableArray<NSString *> *skippedBasenames = [NSMutableArray array];
@ -1335,10 +1346,9 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
message:[NSString stringWithFormat:@"Could not find any Game Boy ROM files in the following archives:\n%@",
[unusedZips componentsJoinedByString:@"\n"]]
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"Close"
style:UIAlertActionStyleCancel
handler:nil]];
[self stop];
[alert addAction:[UIAlertAction actionWithTitle:@"Close"
style:UIAlertActionStyleCancel
handler:nil]];
[self presentViewController:alert animated:true completion:nil];
}
@ -1347,15 +1357,15 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
message:[NSString stringWithFormat:@"Could not import the following files because they're not supported:\n%@",
[skippedBasenames componentsJoinedByString:@"\n"]]
preferredStyle:UIAlertControllerStyleAlert];
[alert addAction:[UIAlertAction actionWithTitle:@"Close"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action) {
[alert addAction:[UIAlertAction actionWithTitle:@"Close"
style:UIAlertActionStyleCancel
handler:^(UIAlertAction *action) {
[[NSUserDefaults standardUserDefaults] setBool:false forKey:@"GBShownUTIWarning"]; // Somebody might need a reminder
}]];
[self stop];
[self presentViewController:alert animated:true completion:nil];
}
if (validURLs.count == 1 && urls.count == 1) {
NSURL *url = validURLs.firstObject;
NSString *potentialROM = [[url.path stringByDeletingLastPathComponent] lastPathComponent];
@ -1369,7 +1379,6 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
keepOriginal:![url.path hasPrefix:tempDir] && !inPlace];
[url stopAccessingSecurityScopedResource];
}
[[NSNotificationCenter defaultCenter] postNotificationName:@"GBROMChanged" object:nil];
return true;
}
for (NSURL *url in validURLs) {
@ -1383,7 +1392,6 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
keepOriginal:![url.path hasPrefix:tempDir] && !inPlace];
[url stopAccessingSecurityScopedResource];
}
[self stop];
[self openLibrary];
return validURLs.count;
@ -1391,15 +1399,18 @@ didReceiveNotificationResponse:(UNNotificationResponse *)response
- (BOOL)application:(UIApplication *)app openURL:(NSURL *)url options:(NSDictionary<UIApplicationOpenURLOptionsKey,id> *)options
{
if (self.presentedViewController && ![self.presentedViewController isKindOfClass:[UIAlertController class]]) {
[self dismissViewController];
}
NSString *potentialROM = [[url.path stringByDeletingLastPathComponent] lastPathComponent];
if ([[[GBROMManager sharedManager] romFileForROM:potentialROM].stringByStandardizingPath isEqualToString:url.path.stringByStandardizingPath]) {
[self stop];
[GBROMManager sharedManager].currentROM = potentialROM;
[self loadROM];
[self start];
return [GBROMManager sharedManager].currentROM != nil;
}
return [self handleOpenURLs:@[url] openInPlace:[options[UIApplicationOpenURLOptionsOpenInPlaceKey] boolValue]];
return [self handleOpenURLs:@[url]
openInPlace:[options[UIApplicationOpenURLOptionsOpenInPlaceKey] boolValue]];
}
- (void)setRunMode:(GBRunMode)runMode ignoreDynamicSpeed:(bool)ignoreDynamicSpeed