From 7624688e3b99f7c80ea3c33179bcde5c87acbff5 Mon Sep 17 00:00:00 2001 From: Lior Halphon Date: Sat, 14 Jan 2023 01:25:36 +0200 Subject: [PATCH] Bare bones ROM loading functionality (requires modification of the app container to add ROMs) --- iOS/GBLoadROMTableViewController.h | 5 +++ iOS/GBLoadROMTableViewController.m | 42 ++++++++++++++++++ iOS/GBROMManager.h | 9 ++++ iOS/GBROMManager.m | 69 ++++++++++++++++++++++++++++++ iOS/GBViewController.m | 27 ++++++++++++ 5 files changed, 152 insertions(+) create mode 100644 iOS/GBLoadROMTableViewController.h create mode 100644 iOS/GBLoadROMTableViewController.m create mode 100644 iOS/GBROMManager.h create mode 100644 iOS/GBROMManager.m diff --git a/iOS/GBLoadROMTableViewController.h b/iOS/GBLoadROMTableViewController.h new file mode 100644 index 0000000..8ac2602 --- /dev/null +++ b/iOS/GBLoadROMTableViewController.h @@ -0,0 +1,5 @@ +#import + +@interface GBLoadROMTableViewController : UITableViewController + +@end diff --git a/iOS/GBLoadROMTableViewController.m b/iOS/GBLoadROMTableViewController.m new file mode 100644 index 0000000..8329d51 --- /dev/null +++ b/iOS/GBLoadROMTableViewController.m @@ -0,0 +1,42 @@ +#import "GBLoadROMTableViewController.h" +#import "GBROMManager.h" + +@interface GBLoadROMTableViewController () + +@end + +@implementation GBLoadROMTableViewController + +- (NSInteger)numberOfSectionsInTableView:(UITableView *)tableView +{ + return 1; +} + +- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section +{ + return [GBROMManager sharedManager].allROMs.count; +} + + +- (UITableViewCell *)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath +{ + UITableViewCell *cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:nil]; + cell.textLabel.text = [GBROMManager sharedManager].allROMs[[indexPath indexAtPosition:1]]; + + return cell; +} + +- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath +{ + [GBROMManager sharedManager].currentROM = [GBROMManager sharedManager].allROMs[[indexPath indexAtPosition:1]]; + [self.presentingViewController dismissViewControllerAnimated:true completion:^{ + [[NSNotificationCenter defaultCenter] postNotificationName:@"GBROMChanged" object:nil]; + }]; +} + +- (BOOL)isModalInPresentation +{ + return true; +} + +@end diff --git a/iOS/GBROMManager.h b/iOS/GBROMManager.h new file mode 100644 index 0000000..cfd6333 --- /dev/null +++ b/iOS/GBROMManager.h @@ -0,0 +1,9 @@ +#import + +@interface GBROMManager : NSObject ++ (instancetype) sharedManager; + +@property (readonly) NSArray *allROMs; +@property (nonatomic) NSString *currentROM; +@property (readonly) NSString *romFile; +@end diff --git a/iOS/GBROMManager.m b/iOS/GBROMManager.m new file mode 100644 index 0000000..b0b8349 --- /dev/null +++ b/iOS/GBROMManager.m @@ -0,0 +1,69 @@ +#import "GBROMManager.h" + +@implementation GBROMManager +{ + NSString *_romFile; +} + ++ (instancetype)sharedManager +{ + static dispatch_once_t onceToken; + static GBROMManager *manager; + dispatch_once(&onceToken, ^{ + manager = [[self alloc] init]; + }); + return manager; +} + +- (instancetype)init +{ + self = [super init]; + if (!self) return nil; + self.currentROM = [[NSUserDefaults standardUserDefaults] stringForKey:@"GBLastROM"]; + return self; +} + +- (void)setCurrentROM:(NSString *)currentROM +{ + _romFile = nil; + _currentROM = currentROM; + if (currentROM && !self.romFile) { + _currentROM = nil; + } + + [[NSUserDefaults standardUserDefaults] setObject:_currentROM forKey:@"GBLastROM"]; +} + +- (NSString *)romFileForDirectory:(NSString *)romDirectory +{ + for (NSString *filename in [NSFileManager.defaultManager enumeratorAtPath:romDirectory]) { + if ([@[@"gb", @"gbc", @"isx"] containsObject:filename.pathExtension.lowercaseString]) { + return [romDirectory stringByAppendingPathComponent:filename]; + } + } + + return nil; +} + +- (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]; +} + +- (NSArray *)allROMs +{ + NSMutableArray *ret = [NSMutableArray array]; + NSString *root = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, true).firstObject; + for (NSString *romDirectory in [NSFileManager.defaultManager enumeratorAtPath:root]) { + if ([self romFileForDirectory:[root stringByAppendingPathComponent:romDirectory]]) { + [ret addObject:romDirectory]; + } + } + return ret; +} + +@end diff --git a/iOS/GBViewController.m b/iOS/GBViewController.m index ef1bb6e..09dd436 100644 --- a/iOS/GBViewController.m +++ b/iOS/GBViewController.m @@ -3,6 +3,8 @@ #import "GBVerticalLayout.h" #import "GBViewMetal.h" #import "GBAudioClient.h" +#import "GBROMManager.h" +#import "GBLoadROMTableViewController.h" #include @implementation GBViewController @@ -11,6 +13,7 @@ GBView *_gbView; volatile bool _running; volatile bool _stopping; + bool _romLoaded; GBLayout *_currentLayout; GBHorizontalLayout *_horizontalLayout; GBVerticalLayout *_verticalLayout; @@ -138,11 +141,34 @@ 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 * _Nonnull note) { + [self loadROM]; + [self start]; + }]; return true; } +- (void)loadROM +{ + GBROMManager *romManager = [GBROMManager sharedManager]; + if (romManager.romFile) { + // Todo: display errors and warnings + _romLoaded = GB_load_rom(&_gb, romManager.romFile.fileSystemRepresentation) == 0; + } +} + - (void)applicationDidBecomeActive:(UIApplication *)application { + if (self.presentedViewController) return; + if (!_romLoaded) { + [self presentViewController:[[GBLoadROMTableViewController alloc] init] + animated:true + completion:nil]; + } [self start]; } @@ -253,6 +279,7 @@ static void rumbleCallback(GB_gameboy_t *gb, double amp) - (void)start { + if (!_romLoaded) return; if (_running) return; _running = true; [[[NSThread alloc] initWithTarget:self selector:@selector(run) object:nil] start];