/* RetroArch - A frontend for libretro. * Copyright (C) 2013 - Jason Fetters * * RetroArch is free software: you can redistribute it and/or modify it under the terms * of the GNU General Public License as published by the Free Software Found- * ation, either version 3 of the License, or (at your option) any later version. * * RetroArch is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; * without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR * PURPOSE. See the GNU General Public License for more details. * * You should have received a copy of the GNU General Public License along with RetroArch. * If not, see . */ #import "RetroArch_Apple.h" #import "RAModuleInfo.h" #include "file.h" #include "core_info.h" static NSMutableArray* moduleList; static core_info_list_t* coreList; NSArray* apple_get_modules() { if (!moduleList) { coreList = get_core_info_list(apple_platform.coreDirectory.UTF8String); if (!coreList) return nil; moduleList = [NSMutableArray arrayWithCapacity:coreList->count]; for (int i = 0; coreList && i < coreList->count; i ++) { core_info_t* core = &coreList->list[i]; RAModuleInfo* newInfo = [RAModuleInfo new]; newInfo.path = @(core->path); newInfo.baseName = newInfo.path.lastPathComponent.stringByDeletingPathExtension; newInfo.info = core; newInfo.data = core->data; newInfo.description = @(core->display_name); newInfo.customConfigFile = [NSString stringWithFormat:@"%@/%@.cfg", apple_platform.configDirectory, newInfo.baseName]; newInfo.configFile = newInfo.hasCustomConfig ? newInfo.customConfigFile : apple_platform.globalConfigFile; [moduleList addObject:newInfo]; } [moduleList sortUsingComparator:^(RAModuleInfo* left, RAModuleInfo* right) { return [left.description caseInsensitiveCompare:right.description]; }]; } return moduleList; } @implementation RAModuleInfo - (id)copyWithZone:(NSZone *)zone { return self; } - (bool)supportsFileAtPath:(NSString*)path { return does_core_support_file(self.info, path.UTF8String); } - (void)createCustomConfig { if (!self.hasCustomConfig) [NSFileManager.defaultManager copyItemAtPath:apple_platform.globalConfigFile toPath:self.customConfigFile error:nil]; } - (void)deleteCustomConfig { if (self.hasCustomConfig) [NSFileManager.defaultManager removeItemAtPath:self.customConfigFile error:nil]; } - (bool)hasCustomConfig { return path_file_exists(self.customConfigFile.UTF8String); } @end #ifdef IOS #import "../iOS/views.h" static const void* const associated_string_key = &associated_string_key; // Build a string with a second associated string static NSString* build_string_pair(NSString* stringA, NSString* stringB) { NSString* string_pair = [NSString stringWithString:stringA]; objc_setAssociatedObject(string_pair, associated_string_key, stringB, OBJC_ASSOCIATION_RETAIN_NONATOMIC); return string_pair; } @implementation RAModuleInfoList { RAModuleInfo* _data; uint32_t _firmwareSectionIndex; } - (id)initWithModuleInfo:(RAModuleInfo*)info { self = [super initWithStyle:UITableViewStyleGrouped]; _data = info; [self.sections addObject: [NSArray arrayWithObjects:@"Core", build_string_pair(@"Core Name", objc_get_value_from_config(_data.data, @"corename", @"Unspecified")), nil]]; [self.sections addObject: [NSArray arrayWithObjects:@"Hardware/Software", build_string_pair(@"Developer", objc_get_value_from_config(_data.data, @"manufacturer", @"Unspecified")), build_string_pair(@"Name", objc_get_value_from_config(_data.data, @"systemname", @"Unspecified")), nil]]; // Firmware _firmwareSectionIndex = 1000; uint32_t firmwareCount = 0; if (_data.data && config_get_uint(_data.data, "firmware_count", &firmwareCount) && firmwareCount) { NSMutableArray* firmwareSection = [NSMutableArray arrayWithObject:@"Firmware"]; for (int i = 0; i < firmwareCount; i ++) { NSString* path = objc_get_value_from_config(_data.data, [NSString stringWithFormat:@"firmware%d_path", i + 1], @"Unspecified"); path = [path stringByReplacingOccurrencesOfString:@"%sysdir%" withString:[RetroArch_iOS get].systemDirectory]; [firmwareSection addObject:build_string_pair(objc_get_value_from_config(_data.data, [NSString stringWithFormat:@"firmware%d_desc", i + 1], @"Unspecified"), path)]; } _firmwareSectionIndex = self.sections.count; [self.sections addObject:firmwareSection]; } return self; } - (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath { if (indexPath.section == _firmwareSectionIndex) { NSString* item = (NSString*)[self itemForIndexPath:indexPath]; apple_display_alert(objc_getAssociatedObject(item, associated_string_key), item); } } - (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath { static NSString* const cell_id = @"datacell"; UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:cell_id]; if (!cell) { cell = [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:cell_id]; cell.selectionStyle = UITableViewCellSelectionStyleNone; cell.detailTextLabel.adjustsFontSizeToFitWidth = YES; } NSString* item = (NSString*)[self itemForIndexPath:indexPath]; NSString* value = (NSString*)objc_getAssociatedObject(item, associated_string_key); cell.textLabel.text = item; cell.detailTextLabel.text = value; if (indexPath.section == _firmwareSectionIndex) cell.backgroundColor = path_file_exists(value.UTF8String) ? [UIColor blueColor] : [UIColor redColor]; else cell.backgroundColor = [UIColor whiteColor]; return cell; } @end #endif