diff --git a/apple/OSX/platform.m b/apple/OSX/platform.m index b15d053e14..09580ca852 100644 --- a/apple/OSX/platform.m +++ b/apple/OSX/platform.m @@ -230,7 +230,7 @@ - (NSString*)retroarchConfigPath { NSArray* paths = NSSearchPathForDirectoriesInDomains(NSApplicationSupportDirectory, NSUserDomainMask, YES); - return [paths[0] stringByAppendingPathComponent:@"RetroArch/retroarch.cfg"]; + return [paths[0] stringByAppendingPathComponent:@"RetroArch"]; } - (NSString*)corePath diff --git a/apple/RetroArch/RAModuleInfo.h b/apple/RetroArch/RAModuleInfo.h index 5370b97f6a..063143a5cb 100644 --- a/apple/RetroArch/RAModuleInfo.h +++ b/apple/RetroArch/RAModuleInfo.h @@ -27,10 +27,18 @@ @property core_info_t* info; @property config_file_t* data; @property (strong) NSString* description; +@property (strong) NSString* customConfigPath; + (NSArray*)getModules; - (bool)supportsFileAtPath:(NSString*)path; ++ (NSString*)globalConfigPath; + +- (void)createCustomConfig; +- (void)deleteCustomConfig; +- (bool)hasCustomConfig; +- (NSString*)configPath; + @end #endif diff --git a/apple/RetroArch/RAModuleInfo.m b/apple/RetroArch/RAModuleInfo.m index f4ffe70784..bd148684bb 100644 --- a/apple/RetroArch/RAModuleInfo.m +++ b/apple/RetroArch/RAModuleInfo.m @@ -44,6 +44,9 @@ static core_info_list_t* coreList; newInfo.data = core->data; newInfo.description = [NSString stringWithUTF8String:core->display_name]; + NSString* baseName = newInfo.path.lastPathComponent.stringByDeletingPathExtension; + newInfo.customConfigPath = [NSString stringWithFormat:@"%@/%@.cfg", apple_platform.retroarchConfigPath, baseName]; + [moduleList addObject:newInfo]; } @@ -70,6 +73,37 @@ static core_info_list_t* coreList; return does_core_support_file(self.info, path.UTF8String); } ++ (NSString*)globalConfigPath +{ + static NSString* path; + if (!path) + path = [NSString stringWithFormat:@"%@/retroarch.cfg", apple_platform.retroarchConfigPath]; + + return path; +} + +- (void)createCustomConfig +{ + if (!self.hasCustomConfig) + [NSFileManager.defaultManager copyItemAtPath:RAModuleInfo.globalConfigPath toPath:self.customConfigPath error:nil]; +} + +- (void)deleteCustomConfig +{ + if (self.hasCustomConfig) + [NSFileManager.defaultManager removeItemAtPath:self.customConfigPath error:nil]; +} + +- (bool)hasCustomConfig +{ + return path_file_exists(self.customConfigPath.UTF8String); +} + +- (NSString*)configPath +{ + return self.hasCustomConfig ? self.customConfigPath : RAModuleInfo.globalConfigPath; +} + @end #ifdef IOS diff --git a/apple/RetroArch/RetroArch_Apple.h b/apple/RetroArch/RetroArch_Apple.h index a714bb70c1..90dccbb0da 100644 --- a/apple/RetroArch/RetroArch_Apple.h +++ b/apple/RetroArch/RetroArch_Apple.h @@ -27,7 +27,8 @@ @protocol RetroArch_Platform - (void)loadingCore:(RAModuleInfo*)core withFile:(const char*)file; - (void)unloadingCore:(RAModuleInfo*)core; -- (NSString*)retroarchConfigPath; + +- (NSString*)retroarchConfigPath; // < This returns the directory that contains retroarch.cfg and other custom configs - (NSString*)corePath; @end diff --git a/apple/RetroArch/main.m b/apple/RetroArch/main.m index 7d9f392040..3680400c9d 100644 --- a/apple/RetroArch/main.m +++ b/apple/RetroArch/main.m @@ -133,7 +133,7 @@ void apple_run_core(RAModuleInfo* core, const char* file) static const char* argv[] = { "retroarch", "-c", config_path, "-L", core_path, file_path, 0 }; - strlcpy(config_path, apple_platform.retroarchConfigPath.UTF8String, sizeof(config_path)); + strlcpy(config_path, apple_core.configPath.UTF8String, sizeof(config_path)); if (file && core) { diff --git a/apple/iOS/platform.m b/apple/iOS/platform.m index 74b6d5f16c..1642e00189 100644 --- a/apple/iOS/platform.m +++ b/apple/iOS/platform.m @@ -84,8 +84,6 @@ static void handle_touch_event(NSArray* touches) bool _isGameTop, _isRomList; uint32_t _settingMenusInBackStack; uint32_t _enabledOrientations; - - RAModuleInfo* _module; } + (RetroArch_iOS*)get @@ -216,7 +214,7 @@ static void handle_touch_event(NSArray* touches) - (NSString*)retroarchConfigPath { - return [NSString stringWithFormat:@"%@/retroarch.cfg", self.systemDirectory]; + return self.systemDirectory; } - (NSString*)corePath @@ -321,7 +319,7 @@ static void handle_touch_event(NSArray* touches) - (IBAction)showSettings { - [self pushViewController:[[RASettingsList alloc] initWithModule:_module] animated:YES]; + [self pushViewController:[[RASettingsList alloc] initWithModule:apple_core] animated:YES]; } - (IBAction)showSystemSettings diff --git a/apple/iOS/settings.m b/apple/iOS/settings.m index b386204a4c..af5a4cbc06 100644 --- a/apple/iOS/settings.m +++ b/apple/iOS/settings.m @@ -47,6 +47,8 @@ enum SettingTypes double rangeMin; // < The mininum value of a range setting double rangeMax; // < The maximum value of a range setting + + void (^reload)(RASettingData* action, id userdata); } @end @@ -187,10 +189,11 @@ static RASettingData* aspect_setting(config_file_t* config, NSString* label) return result; } -static RASettingData* custom_action(NSString* action, NSString* value, id data) +static RASettingData* custom_action(NSString* action, NSString* value, id data, void (^reload_func)(RASettingData* action, id userdata)) { RASettingData* result = [[RASettingData alloc] initWithType:CustomAction label:action name:nil]; result->value = value; + result->reload = reload_func; if (data != nil) objc_setAssociatedObject(result, "USERDATA", data, OBJC_ASSOCIATION_RETAIN_NONATOMIC); @@ -252,7 +255,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) - (id)initWithModule:(RAModuleInfo*)module { _module = module; - _configPath = RetroArch_iOS.get.retroarchConfigPath; + _configPath = _module ? _module.configPath : RAModuleInfo.globalConfigPath; config_file_t* config = config_file_new([_configPath UTF8String]); @@ -261,7 +264,8 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) NSArray* settings = [NSArray arrayWithObjects: [NSArray arrayWithObjects:@"Core", - custom_action(@"Core Info", nil, nil), + custom_action(@"Core Info", nil, nil, 0), + _module.hasCustomConfig ? custom_action(@"Delete Custom Config", nil, nil, 0) : nil, nil], [NSArray arrayWithObjects:@"Video", @@ -353,6 +357,12 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) { if ([@"Core Info" isEqualToString:setting->label]) [[RetroArch_iOS get] pushViewController:[[RAModuleInfoList alloc] initWithModuleInfo:_module] animated:YES]; + else if([@"Delete Custom Config" isEqualToString:setting->label]) + { + [_module deleteCustomConfig]; + _cancelSave = true; + [self.navigationController popViewControllerAnimated:YES]; + } } @end @@ -361,6 +371,20 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) - (id)init { config_file_t* config = config_file_new([[RetroArch_iOS get].systemConfigPath UTF8String]); + + NSMutableArray* modules = [NSMutableArray array]; + [modules addObject:@"Cores"]; + [modules addObject:custom_action(@"Global Core Config", nil, nil, 0)]; + + NSArray* moduleList = [RAModuleInfo getModules]; + for (RAModuleInfo* i in moduleList) + { + [modules addObject:custom_action(i.description, nil, i, ^(RASettingData* action, RAModuleInfo* userdata) + { + action->value = userdata.hasCustomConfig ? @"[Custom]" : @"[Global]"; + })]; + } + NSArray* bluetoothOptions = [NSArray arrayWithObjects:@"keyboard", @"Keyboard", @"icade", @"iCade Device", @@ -369,7 +393,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) NSArray* settings = [NSArray arrayWithObjects: [NSArray arrayWithObjects:@"Frontend", - custom_action(@"Diagnostic Log", nil, nil), + custom_action(@"Diagnostic Log", nil, nil, 0), boolean_setting(config, @"ios_tv_mode", @"TV Mode", @"false"), nil], [NSArray arrayWithObjects:@"Bluetooth", @@ -381,9 +405,7 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) boolean_setting(config, @"ios_allow_landscape_left", @"Landscape Left", @"true"), boolean_setting(config, @"ios_allow_landscape_right", @"Landscape Right", @"true"), nil], - [NSArray arrayWithObjects:@"Cores", - custom_action(@"Core Configuration", nil, nil), - nil], + modules, nil ]; @@ -417,8 +439,45 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) [[RetroArch_iOS get] pushViewController:[RALogView new] animated:YES]; else if ([@"Enable BTstack" isEqualToString:setting->label]) btstack_set_poweron([setting->value isEqualToString:@"true"]); - else if([@"Core Configuration" isEqualToString:setting->label]) + else if([@"Global Core Config" isEqualToString:setting->label]) [RetroArch_iOS.get pushViewController:[[RASettingsList alloc] initWithModule:nil] animated:YES]; + else + { + RAModuleInfo* data = (RAModuleInfo*)objc_getAssociatedObject(setting, "USERDATA"); + if (data) + { + if (!data.hasCustomConfig) + { + UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"RetroArch" + message:@"No custom configuration for this core exists, " + "would you like to create one?" + delegate:self + cancelButtonTitle:@"No" + otherButtonTitles:@"Yes", nil]; + objc_setAssociatedObject(alert, "MODULE", data, OBJC_ASSOCIATION_RETAIN_NONATOMIC); + [alert show]; + } + else + [RetroArch_iOS.get pushViewController:[[RASettingsList alloc] initWithModule:data] animated:YES]; + } + } +} + +- (void)alertView:(UIAlertView*)alertView willDismissWithButtonIndex:(NSInteger)buttonIndex +{ + RAModuleInfo* data = (RAModuleInfo*)objc_getAssociatedObject(alertView, "MODULE"); + + if (data) + { + if (buttonIndex == alertView.firstOtherButtonIndex) + { + [data createCustomConfig]; + [self.tableView reloadData]; + } + + [RetroArch_iOS.get pushViewController:[[RASettingsList alloc] initWithModule:data] animated:YES]; + } + } @end @@ -613,7 +672,10 @@ static NSArray* build_input_port_group(config_file_t* config, uint32_t player) cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"default"]; cell.accessoryType = UITableViewCellAccessoryDisclosureIndicator; } - + + if (setting->reload) + setting->reload(setting, objc_getAssociatedObject(setting, "USERDATA")); + cell.textLabel.text = setting->label; if (setting->type == ButtonSetting)