mirror of
https://github.com/libretro/RetroArch
synced 2025-02-04 21:40:02 +00:00
(iOS) Reduce the amount of object files for Obj-C compiled code
by combining similar files
This commit is contained in:
parent
0d4d3940b8
commit
8ae3fcb6c1
@ -8,10 +8,8 @@
|
||||
|
||||
/* Begin PBXBuildFile section */
|
||||
9605EA9B170288EA001D47B0 /* RAModuleInfo.m in Sources */ = {isa = PBXBuildFile; fileRef = 9605EA9A170288EA001D47B0 /* RAModuleInfo.m */; };
|
||||
96096DD816D1ABAF00BF4499 /* RAModuleInfoList.m in Sources */ = {isa = PBXBuildFile; fileRef = 96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */; };
|
||||
962979F616C43B9500E6DCE0 /* ic_dir.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F416C43B9500E6DCE0 /* ic_dir.png */; };
|
||||
962979F716C43B9500E6DCE0 /* ic_file.png in Resources */ = {isa = PBXBuildFile; fileRef = 962979F516C43B9500E6DCE0 /* ic_file.png */; };
|
||||
96297A0C16C5AD8D00E6DCE0 /* RetroArch_iOS.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */; };
|
||||
96297A0F16C5AEA100E6DCE0 /* main.m in Sources */ = {isa = PBXBuildFile; fileRef = 96297A0E16C5AEA100E6DCE0 /* main.m */; };
|
||||
96297A2716C82FF100E6DCE0 /* overlays in Resources */ = {isa = PBXBuildFile; fileRef = 96297A2616C82FF100E6DCE0 /* overlays */; };
|
||||
96366C5516C9AC3300D64A22 /* CoreAudio.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 96366C5416C9AC3300D64A22 /* CoreAudio.framework */; };
|
||||
@ -22,8 +20,6 @@
|
||||
963F5AC316CC522F009BBD19 /* RASettingsList.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5ABF16CC522F009BBD19 /* RASettingsList.m */; };
|
||||
963F5AC816CC523B009BBD19 /* RAGameView.m in Sources */ = {isa = PBXBuildFile; fileRef = 963F5AC516CC523B009BBD19 /* RAGameView.m */; };
|
||||
966B9CAE16E41C07005B61E1 /* browser.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9CAA16E41C07005B61E1 /* browser.m */; };
|
||||
966B9CB016E41C07005B61E1 /* RADirectoryGrid.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9CAB16E41C07005B61E1 /* RADirectoryGrid.m */; };
|
||||
966B9CB216E41C07005B61E1 /* RADirectoryList.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9CAC16E41C07005B61E1 /* RADirectoryList.m */; };
|
||||
966B9CB416E41C07005B61E1 /* RAModuleList.m in Sources */ = {isa = PBXBuildFile; fileRef = 966B9CAD16E41C07005B61E1 /* RAModuleList.m */; };
|
||||
966B9CBD16E41E7A005B61E1 /* Default-568h@2x.png in Resources */ = {isa = PBXBuildFile; fileRef = 966B9CB816E41E7A005B61E1 /* Default-568h@2x.png */; };
|
||||
966B9CBF16E41E7A005B61E1 /* Default.png in Resources */ = {isa = PBXBuildFile; fileRef = 966B9CB916E41E7A005B61E1 /* Default.png */; };
|
||||
@ -47,12 +43,10 @@
|
||||
/* Begin PBXFileReference section */
|
||||
9605EA99170288EA001D47B0 /* RAModuleInfo.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RAModuleInfo.h; sourceTree = "<group>"; };
|
||||
9605EA9A170288EA001D47B0 /* RAModuleInfo.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAModuleInfo.m; sourceTree = "<group>"; };
|
||||
96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAModuleInfoList.m; sourceTree = "<group>"; };
|
||||
9614C71F16DDC018000B36EF /* RetroArch copy-Info.plist */ = {isa = PBXFileReference; lastKnownFileType = text.plist.xml; name = "RetroArch copy-Info.plist"; path = "/Users/jason/Documents/Projects/ios/RetroArch/ios/RetroArch copy-Info.plist"; sourceTree = "<absolute>"; };
|
||||
962979F416C43B9500E6DCE0 /* ic_dir.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_dir.png; path = "../../android/phoenix/res/drawable-xhdpi/ic_dir.png"; sourceTree = "<group>"; };
|
||||
962979F516C43B9500E6DCE0 /* ic_file.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; name = ic_file.png; path = "../../android/phoenix/res/drawable-xhdpi/ic_file.png"; sourceTree = "<group>"; };
|
||||
96297A0A16C5AD8D00E6DCE0 /* RetroArch_iOS.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = RetroArch_iOS.h; sourceTree = "<group>"; };
|
||||
96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RetroArch_iOS.m; sourceTree = "<group>"; };
|
||||
96297A0D16C5ADDA00E6DCE0 /* views.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = views.h; sourceTree = "<group>"; };
|
||||
96297A0E16C5AEA100E6DCE0 /* main.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = main.m; sourceTree = "<group>"; };
|
||||
96297A2616C82FF100E6DCE0 /* overlays */ = {isa = PBXFileReference; lastKnownFileType = folder; name = overlays; path = ../../media/overlays; sourceTree = "<group>"; };
|
||||
@ -66,8 +60,6 @@
|
||||
963F5AC516CC523B009BBD19 /* RAGameView.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAGameView.m; sourceTree = "<group>"; };
|
||||
966B9CA916E41C07005B61E1 /* browser.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = browser.h; sourceTree = "<group>"; };
|
||||
966B9CAA16E41C07005B61E1 /* browser.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = browser.m; sourceTree = "<group>"; };
|
||||
966B9CAB16E41C07005B61E1 /* RADirectoryGrid.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RADirectoryGrid.m; sourceTree = "<group>"; };
|
||||
966B9CAC16E41C07005B61E1 /* RADirectoryList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RADirectoryList.m; sourceTree = "<group>"; };
|
||||
966B9CAD16E41C07005B61E1 /* RAModuleList.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = RAModuleList.m; sourceTree = "<group>"; };
|
||||
966B9CB816E41E7A005B61E1 /* Default-568h@2x.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = "Default-568h@2x.png"; sourceTree = "<group>"; };
|
||||
966B9CB916E41E7A005B61E1 /* Default.png */ = {isa = PBXFileReference; lastKnownFileType = image.png; path = Default.png; sourceTree = "<group>"; };
|
||||
@ -131,8 +123,6 @@
|
||||
children = (
|
||||
966B9CA916E41C07005B61E1 /* browser.h */,
|
||||
966B9CAA16E41C07005B61E1 /* browser.m */,
|
||||
966B9CAB16E41C07005B61E1 /* RADirectoryGrid.m */,
|
||||
966B9CAC16E41C07005B61E1 /* RADirectoryList.m */,
|
||||
966B9CAD16E41C07005B61E1 /* RAModuleList.m */,
|
||||
);
|
||||
path = browser;
|
||||
@ -201,10 +191,8 @@
|
||||
96F9C28216FFA55F002455B3 /* RALogView.m */,
|
||||
9605EA9A170288EA001D47B0 /* RAModuleInfo.m */,
|
||||
9605EA99170288EA001D47B0 /* RAModuleInfo.h */,
|
||||
96096DD716D1ABAF00BF4499 /* RAModuleInfoList.m */,
|
||||
96C19C2616D455BE00FE8D5A /* rarch_wrapper.h */,
|
||||
96297A0A16C5AD8D00E6DCE0 /* RetroArch_iOS.h */,
|
||||
96297A0B16C5AD8D00E6DCE0 /* RetroArch_iOS.m */,
|
||||
96297A0D16C5ADDA00E6DCE0 /* views.h */,
|
||||
);
|
||||
path = RetroArch;
|
||||
@ -342,17 +330,13 @@
|
||||
isa = PBXSourcesBuildPhase;
|
||||
buildActionMask = 2147483647;
|
||||
files = (
|
||||
96297A0C16C5AD8D00E6DCE0 /* RetroArch_iOS.m in Sources */,
|
||||
96297A0F16C5AEA100E6DCE0 /* main.m in Sources */,
|
||||
963F5AC016CC522F009BBD19 /* RAButtonGetter.m in Sources */,
|
||||
963F5AC116CC522F009BBD19 /* RASettingEnumerationList.m in Sources */,
|
||||
963F5AC216CC522F009BBD19 /* RASettingsSubList.m in Sources */,
|
||||
963F5AC316CC522F009BBD19 /* RASettingsList.m in Sources */,
|
||||
963F5AC816CC523B009BBD19 /* RAGameView.m in Sources */,
|
||||
96096DD816D1ABAF00BF4499 /* RAModuleInfoList.m in Sources */,
|
||||
966B9CAE16E41C07005B61E1 /* browser.m in Sources */,
|
||||
966B9CB016E41C07005B61E1 /* RADirectoryGrid.m in Sources */,
|
||||
966B9CB216E41C07005B61E1 /* RADirectoryList.m in Sources */,
|
||||
966B9CB416E41C07005B61E1 /* RAModuleList.m in Sources */,
|
||||
D48581DE16F823F9004BEB17 /* griffin.c in Sources */,
|
||||
96F9C28316FFA55F002455B3 /* RALogView.m in Sources */,
|
||||
|
@ -17,6 +17,10 @@
|
||||
#import "RAModuleInfo.h"
|
||||
|
||||
static NSMutableArray* moduleList;
|
||||
static NSString* const labels[3] = {@"Core Name", @"Developer", @"Name"};
|
||||
static const char* const keys[3] = {"corename", "manufacturer", "systemname"};
|
||||
static NSString* const sectionNames[2] = {@"Emulator", @"Hardware"};
|
||||
static const uint32_t sectionSizes[2] = {1, 2};
|
||||
|
||||
@implementation RAModuleInfo
|
||||
+ (NSArray*)getModules
|
||||
@ -81,3 +85,56 @@ static NSMutableArray* moduleList;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation RAModuleInfoList
|
||||
{
|
||||
RAModuleInfo* _data;
|
||||
}
|
||||
|
||||
- (id)initWithModuleInfo:(RAModuleInfo*)info
|
||||
{
|
||||
self = [super initWithStyle:UITableViewStyleGrouped];
|
||||
|
||||
_data = info;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView
|
||||
{
|
||||
return sizeof(sectionSizes) / sizeof(sectionSizes[0]);
|
||||
}
|
||||
|
||||
- (NSString*)tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section
|
||||
{
|
||||
return sectionNames[section];
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return sectionSizes[section];
|
||||
}
|
||||
|
||||
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"datacell"];
|
||||
cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"datacell"];
|
||||
|
||||
uint32_t sectionBase = 0;
|
||||
for (int i = 0; i != indexPath.section; i ++)
|
||||
{
|
||||
sectionBase += sectionSizes[i];
|
||||
}
|
||||
|
||||
cell.textLabel.text = labels[sectionBase + indexPath.row];
|
||||
|
||||
char* val = 0;
|
||||
if (_data.data)
|
||||
config_get_string(_data.data, keys[sectionBase + indexPath.row], &val);
|
||||
|
||||
cell.detailTextLabel.text = val ? [NSString stringWithUTF8String:val] : @"Unspecified";
|
||||
free(val);
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -1,72 +0,0 @@
|
||||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
static NSString* const labels[3] = {@"Core Name", @"Developer", @"Name"};
|
||||
static const char* const keys[3] = {"corename", "manufacturer", "systemname"};
|
||||
static NSString* const sectionNames[2] = {@"Emulator", @"Hardware"};
|
||||
static const uint32_t sectionSizes[2] = {1, 2};
|
||||
|
||||
@implementation RAModuleInfoList
|
||||
{
|
||||
RAModuleInfo* _data;
|
||||
}
|
||||
|
||||
- (id)initWithModuleInfo:(RAModuleInfo*)info
|
||||
{
|
||||
self = [super initWithStyle:UITableViewStyleGrouped];
|
||||
|
||||
_data = info;
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSInteger)numberOfSectionsInTableView:(UITableView*)tableView
|
||||
{
|
||||
return sizeof(sectionSizes) / sizeof(sectionSizes[0]);
|
||||
}
|
||||
|
||||
- (NSString*)tableView:(UITableView*)tableView titleForHeaderInSection:(NSInteger)section
|
||||
{
|
||||
return sectionNames[section];
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return sectionSizes[section];
|
||||
}
|
||||
|
||||
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"datacell"];
|
||||
cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleValue1 reuseIdentifier:@"datacell"];
|
||||
|
||||
uint32_t sectionBase = 0;
|
||||
for (int i = 0; i != indexPath.section; i ++)
|
||||
{
|
||||
sectionBase += sectionSizes[i];
|
||||
}
|
||||
|
||||
cell.textLabel.text = labels[sectionBase + indexPath.row];
|
||||
|
||||
char* val = 0;
|
||||
if (_data.data)
|
||||
config_get_string(_data.data, keys[sectionBase + indexPath.row], &val);
|
||||
|
||||
cell.detailTextLabel.text = val ? [NSString stringWithUTF8String:val] : @"Unspecified";
|
||||
free(val);
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
@end
|
@ -1,328 +0,0 @@
|
||||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "rarch_wrapper.h"
|
||||
#include "general.h"
|
||||
#include "frontend/menu/rmenu.h"
|
||||
|
||||
#import "browser/browser.h"
|
||||
#import "settings/settings.h"
|
||||
|
||||
#include "input/BTStack/btdynamic.h"
|
||||
#include "input/BTStack/btpad.h"
|
||||
|
||||
#define kDOCSFOLDER [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]
|
||||
|
||||
// From frontend/frontend_ios.c
|
||||
extern void* rarch_main_ios(void* args);
|
||||
extern void ios_frontend_post_event(void (*fn)(void*), void* userdata);
|
||||
|
||||
static void event_game_reset(void* userdata)
|
||||
{
|
||||
rarch_game_reset();
|
||||
}
|
||||
|
||||
static void event_load_state(void* userdata)
|
||||
{
|
||||
rarch_load_state();
|
||||
}
|
||||
|
||||
static void event_save_state(void* userdata)
|
||||
{
|
||||
rarch_save_state();
|
||||
}
|
||||
|
||||
static void event_set_state_slot(void* userdata)
|
||||
{
|
||||
g_extern.state_slot = (uint32_t)userdata;
|
||||
}
|
||||
|
||||
static void event_quit(void* userdata)
|
||||
{
|
||||
g_extern.system.shutdown = true;
|
||||
}
|
||||
|
||||
static void event_reload_config(void* userdata)
|
||||
{
|
||||
// Need to clear these otherwise stale versions may be used!
|
||||
memset(g_settings.input.overlay, 0, sizeof(g_settings.input.overlay));
|
||||
memset(g_settings.video.xml_shader_path, 0, sizeof(g_settings.video.xml_shader_path));
|
||||
|
||||
uninit_drivers();
|
||||
config_load();
|
||||
init_drivers();
|
||||
}
|
||||
|
||||
@implementation RetroArch_iOS
|
||||
{
|
||||
UIWindow* _window;
|
||||
|
||||
pthread_t _retroThread;
|
||||
|
||||
bool _isGameTop;
|
||||
bool _isPaused;
|
||||
bool _isRunning;
|
||||
}
|
||||
|
||||
+ (void)displayErrorMessage:(NSString*)message
|
||||
{
|
||||
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"RetroArch"
|
||||
message:message
|
||||
delegate:nil
|
||||
cancelButtonTitle:@"OK"
|
||||
otherButtonTitles:nil];
|
||||
[alert show];
|
||||
}
|
||||
|
||||
+ (RetroArch_iOS*)get
|
||||
{
|
||||
return (RetroArch_iOS*)[[UIApplication sharedApplication] delegate];
|
||||
}
|
||||
|
||||
// UIApplicationDelegate
|
||||
- (void)applicationDidFinishLaunching:(UIApplication *)application
|
||||
{
|
||||
self.system_directory = [NSString stringWithFormat:@"%@/.RetroArch", kDOCSFOLDER];
|
||||
mkdir([self.system_directory UTF8String], 0755);
|
||||
|
||||
// Setup window
|
||||
self.delegate = self;
|
||||
[self pushViewController:[RADirectoryList directoryListOrGridWithPath:kDOCSFOLDER] animated:YES];
|
||||
|
||||
_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
||||
_window.rootViewController = self;
|
||||
[_window makeKeyAndVisible];
|
||||
}
|
||||
|
||||
- (void)applicationWillEnterForeground:(UIApplication *)application
|
||||
{
|
||||
[RAGameView.get resume];
|
||||
}
|
||||
|
||||
- (void)applicationDidEnterBackground:(UIApplication *)application
|
||||
{
|
||||
[RAGameView.get suspend];
|
||||
}
|
||||
|
||||
// UINavigationControllerDelegate
|
||||
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
|
||||
{
|
||||
_isGameTop = [viewController isKindOfClass:[RAGameView class]];
|
||||
[[UIApplication sharedApplication] setStatusBarHidden:_isGameTop withAnimation:UIStatusBarAnimationNone];
|
||||
self.navigationBarHidden = _isGameTop;
|
||||
|
||||
self.topViewController.navigationItem.rightBarButtonItem = [self createBluetoothButton];
|
||||
}
|
||||
|
||||
// UINavigationController: Never animate when pushing onto, or popping, an RAGameView
|
||||
- (void)pushViewController:(UIViewController*)theView animated:(BOOL)animated
|
||||
{
|
||||
[super pushViewController:theView animated:animated && !_isGameTop];
|
||||
}
|
||||
|
||||
- (UIViewController*)popViewControllerAnimated:(BOOL)animated
|
||||
{
|
||||
return [super popViewControllerAnimated:animated && !_isGameTop];
|
||||
}
|
||||
|
||||
#pragma mark EMULATION
|
||||
- (void)runGame:(NSString*)path
|
||||
{
|
||||
if (_isRunning)
|
||||
return;
|
||||
|
||||
assert(self.moduleInfo);
|
||||
|
||||
[RASettingsList refreshConfigFile];
|
||||
|
||||
[self pushViewController:RAGameView.get animated:NO];
|
||||
_isRunning = true;
|
||||
|
||||
const char* const sd = [[RetroArch_iOS get].system_directory UTF8String];
|
||||
const char* const cf = (ra_ios_is_file(self.moduleInfo.configPath)) ? [self.moduleInfo.configPath UTF8String] : 0;
|
||||
const char* const libretro = [self.moduleInfo.path UTF8String];
|
||||
|
||||
struct rarch_main_wrap* load_data = malloc(sizeof(struct rarch_main_wrap));
|
||||
load_data->libretro_path = strdup(libretro);
|
||||
load_data->rom_path = strdup([path UTF8String]);
|
||||
load_data->sram_path = strdup(sd);
|
||||
load_data->state_path = strdup(sd);
|
||||
load_data->verbose = false;
|
||||
load_data->config_path = strdup(cf);
|
||||
if (pthread_create(&_retroThread, 0, rarch_main_ios, load_data))
|
||||
{
|
||||
[self rarchExited:NO];
|
||||
}
|
||||
pthread_detach(_retroThread);
|
||||
|
||||
// Read load time settings
|
||||
// TODO: Do this better
|
||||
config_file_t* conf = config_file_new([self.moduleInfo.configPath UTF8String]);
|
||||
bool autoStartBluetooth = false;
|
||||
if (conf && config_get_bool(conf, "ios_auto_bluetooth", &autoStartBluetooth) && autoStartBluetooth)
|
||||
[self startBluetooth];
|
||||
config_file_free(conf);
|
||||
}
|
||||
|
||||
- (void)rarchExited:(BOOL)successful
|
||||
{
|
||||
if (!successful)
|
||||
{
|
||||
[RetroArch_iOS displayErrorMessage:@"Failed to load game."];
|
||||
}
|
||||
|
||||
if (_isRunning)
|
||||
{
|
||||
_isRunning = false;
|
||||
|
||||
// Stop bluetooth (might be annoying but forgetting could eat battery of device AND wiimote)
|
||||
[self stopBluetooth];
|
||||
|
||||
//
|
||||
[self popToViewController:[RAGameView get] animated:NO];
|
||||
[self popViewControllerAnimated:NO];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)refreshConfig
|
||||
{
|
||||
if (_isRunning)
|
||||
ios_frontend_post_event(&event_reload_config, 0);
|
||||
else
|
||||
{
|
||||
// Need to clear these otherwise stale versions may be used!
|
||||
memset(g_settings.input.overlay, 0, sizeof(g_settings.input.overlay));
|
||||
memset(g_settings.video.xml_shader_path, 0, sizeof(g_settings.video.xml_shader_path));
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark PAUSE MENU
|
||||
- (IBAction)showPauseMenu:(id)sender
|
||||
{
|
||||
if (_isRunning && !_isPaused && _isGameTop)
|
||||
{
|
||||
_isPaused = true;
|
||||
[[RAGameView get] openPauseMenu];
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)resetGame:(id)sender
|
||||
{
|
||||
if (_isRunning)
|
||||
ios_frontend_post_event(&event_game_reset, 0);
|
||||
|
||||
[self closePauseMenu:sender];
|
||||
}
|
||||
|
||||
- (IBAction)loadState:(id)sender
|
||||
{
|
||||
if (_isRunning)
|
||||
ios_frontend_post_event(&event_load_state, 0);
|
||||
|
||||
[self closePauseMenu:sender];
|
||||
}
|
||||
|
||||
- (IBAction)saveState:(id)sender
|
||||
{
|
||||
if (_isRunning)
|
||||
ios_frontend_post_event(&event_save_state, 0);
|
||||
|
||||
[self closePauseMenu:sender];
|
||||
}
|
||||
|
||||
- (IBAction)chooseState:(id)sender
|
||||
{
|
||||
if (_isRunning)
|
||||
ios_frontend_post_event(event_set_state_slot, (void*)((UISegmentedControl*)sender).selectedSegmentIndex);
|
||||
}
|
||||
|
||||
- (IBAction)closePauseMenu:(id)sender
|
||||
{
|
||||
[[RAGameView get] closePauseMenu];
|
||||
_isPaused = false;
|
||||
}
|
||||
|
||||
- (IBAction)closeGamePressed:(id)sender
|
||||
{
|
||||
[self closePauseMenu:sender];
|
||||
ios_frontend_post_event(event_quit, 0);
|
||||
}
|
||||
|
||||
- (IBAction)showSettings
|
||||
{
|
||||
[self pushViewController:[RASettingsList new] animated:YES];
|
||||
}
|
||||
|
||||
#pragma mark Bluetooth Helpers
|
||||
- (UIBarButtonItem*)createBluetoothButton
|
||||
{
|
||||
if (btstack_is_loaded())
|
||||
{
|
||||
const bool isBTOn = btstack_is_running();
|
||||
return [[UIBarButtonItem alloc]
|
||||
initWithTitle:isBTOn ? @"Stop Bluetooth" : @"Start Bluetooth"
|
||||
style:UIBarButtonItemStyleBordered
|
||||
target:[RetroArch_iOS get]
|
||||
action:isBTOn ? @selector(stopBluetooth) : @selector(startBluetooth)];
|
||||
}
|
||||
else
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (IBAction)startBluetooth
|
||||
{
|
||||
if (btstack_is_loaded() && !btstack_is_running())
|
||||
{
|
||||
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"RetroArch"
|
||||
message:@"Choose Pad Type"
|
||||
delegate:self
|
||||
cancelButtonTitle:@"Cancel"
|
||||
otherButtonTitles:@"Wii", @"PS3", nil];
|
||||
[alert show];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
|
||||
{
|
||||
if (btstack_is_loaded())
|
||||
{
|
||||
btpad_set_pad_type(buttonIndex == alertView.firstOtherButtonIndex);
|
||||
|
||||
if (buttonIndex != alertView.cancelButtonIndex)
|
||||
{
|
||||
btstack_start();
|
||||
[self.topViewController.navigationItem setRightBarButtonItem:[self createBluetoothButton] animated:YES];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)stopBluetooth
|
||||
{
|
||||
if (btstack_is_loaded())
|
||||
{
|
||||
btstack_stop();
|
||||
[self.topViewController.navigationItem setRightBarButtonItem:[self createBluetoothButton] animated:YES];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
void ios_rarch_exited(void* result)
|
||||
{
|
||||
[[RetroArch_iOS get] rarchExited:result ? NO : YES];
|
||||
}
|
@ -1,119 +0,0 @@
|
||||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#import "conf/config_file.h"
|
||||
#import "browser.h"
|
||||
|
||||
@implementation RADirectoryGrid
|
||||
{
|
||||
NSString* _path;
|
||||
NSArray* _list;
|
||||
}
|
||||
|
||||
- (id)initWithPath:(NSString*)path
|
||||
{
|
||||
_path = path;
|
||||
_list = ra_ios_list_directory(_path);
|
||||
|
||||
[self setTitle: [_path lastPathComponent]];
|
||||
|
||||
unsigned tileWidth = 100;
|
||||
unsigned tileHeight = 100;
|
||||
|
||||
config_file_t* config = config_file_new([[path stringByAppendingPathComponent:@".raconfig"] UTF8String]);
|
||||
if (config)
|
||||
{
|
||||
config_get_uint(config, "cover_width", &tileWidth);
|
||||
config_get_uint(config, "cover_height", &tileHeight);
|
||||
config_file_free(config);
|
||||
}
|
||||
|
||||
// Init collection view
|
||||
UICollectionViewFlowLayout* layout = [UICollectionViewFlowLayout new];
|
||||
layout.itemSize = CGSizeMake(tileWidth, tileHeight);
|
||||
self = [super initWithCollectionViewLayout:layout];
|
||||
|
||||
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"dircell"];
|
||||
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"textcell"];
|
||||
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"imagecell"];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
|
||||
{
|
||||
return [_list count];
|
||||
}
|
||||
|
||||
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
RADirectoryItem* path = [_list objectAtIndex: indexPath.row];
|
||||
|
||||
if(path.isDirectory)
|
||||
[[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListOrGridWithPath:path.path] animated:YES];
|
||||
else
|
||||
[[RetroArch_iOS get] pushViewController:[[RAModuleList alloc] initWithGame:path.path] animated:YES];
|
||||
}
|
||||
|
||||
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
RADirectoryItem* path = [_list objectAtIndex: indexPath.row];
|
||||
UICollectionViewCell* cell = nil;
|
||||
|
||||
if (path.isDirectory)
|
||||
{
|
||||
cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:@"dircell" forIndexPath:indexPath];
|
||||
|
||||
if (!cell.backgroundView)
|
||||
{
|
||||
cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"ic_dir"]];
|
||||
((UIImageView*)cell.backgroundView).contentMode = UIViewContentModeScaleAspectFit;
|
||||
}
|
||||
}
|
||||
else if (path.coverPath)
|
||||
{
|
||||
cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:@"imagecell" forIndexPath:indexPath];
|
||||
|
||||
if (!cell.backgroundView)
|
||||
{
|
||||
cell.backgroundView = [UIImageView new];
|
||||
((UIImageView*)cell.backgroundView).contentMode = UIViewContentModeScaleAspectFit;
|
||||
}
|
||||
|
||||
((UIImageView*)cell.backgroundView).image = [UIImage imageWithContentsOfFile:path.coverPath];
|
||||
}
|
||||
else
|
||||
{
|
||||
cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:@"textcell" forIndexPath:indexPath];
|
||||
|
||||
if (!cell.backgroundView)
|
||||
{
|
||||
cell.backgroundView = [UILabel new];
|
||||
((UILabel*)cell.backgroundView).numberOfLines = 0;
|
||||
((UILabel*)cell.backgroundView).textAlignment = NSTextAlignmentCenter;
|
||||
}
|
||||
|
||||
((UILabel*)cell.backgroundView).text = [path.path lastPathComponent];
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
@end
|
@ -1,77 +0,0 @@
|
||||
/* 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 <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
#import "browser.h"
|
||||
|
||||
@implementation RADirectoryList
|
||||
{
|
||||
NSString* _path;
|
||||
NSArray* _list;
|
||||
}
|
||||
|
||||
+ (id)directoryListOrGridWithPath:(NSString*)path
|
||||
{
|
||||
path = ra_ios_check_path(path);
|
||||
|
||||
if ([UICollectionViewController instancesRespondToSelector:@selector(initWithCollectionViewLayout:)])
|
||||
{
|
||||
NSString* coverDir = [path stringByAppendingPathComponent:@".coverart"];
|
||||
if (ra_ios_is_directory(coverDir))
|
||||
return [[RADirectoryGrid alloc] initWithPath:path];
|
||||
}
|
||||
|
||||
return [[RADirectoryList alloc] initWithPath:path];
|
||||
}
|
||||
|
||||
- (id)initWithPath:(NSString*)path
|
||||
{
|
||||
self = [super initWithStyle:UITableViewStylePlain];
|
||||
|
||||
_path = path;
|
||||
_list = ra_ios_list_directory(_path);
|
||||
|
||||
[self setTitle: [_path lastPathComponent]];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
RADirectoryItem* path = [_list objectAtIndex: indexPath.row];
|
||||
|
||||
if(path.isDirectory)
|
||||
[[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListOrGridWithPath:path.path] animated:YES];
|
||||
else
|
||||
[[RetroArch_iOS get] pushViewController:[[RAModuleList alloc] initWithGame:path.path] animated:YES];
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return [_list count];
|
||||
}
|
||||
|
||||
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
RADirectoryItem* path = [_list objectAtIndex: indexPath.row];
|
||||
|
||||
UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"path"];
|
||||
cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"path"];
|
||||
cell.textLabel.text = [path.path lastPathComponent];
|
||||
cell.accessoryType = (path.isDirectory) ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone;
|
||||
cell.imageView.image = [UIImage imageNamed:(path.isDirectory) ? @"ic_dir" : @"ic_file"];
|
||||
return cell;
|
||||
}
|
||||
|
||||
@end
|
@ -16,6 +16,7 @@
|
||||
#include <dirent.h>
|
||||
#include <sys/stat.h>
|
||||
#import "browser.h"
|
||||
#import "conf/config_file.h"
|
||||
|
||||
@implementation RADirectoryItem
|
||||
+ (RADirectoryItem*)directoryItemFromPath:(const char*)thePath checkForCovers:(BOOL)checkCovers
|
||||
@ -100,3 +101,166 @@ NSString* ra_ios_check_path(NSString* path)
|
||||
|
||||
return [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"];
|
||||
}
|
||||
|
||||
@implementation RADirectoryList
|
||||
{
|
||||
NSString* _path;
|
||||
NSArray* _list;
|
||||
}
|
||||
|
||||
+ (id)directoryListOrGridWithPath:(NSString*)path
|
||||
{
|
||||
path = ra_ios_check_path(path);
|
||||
|
||||
if ([UICollectionViewController instancesRespondToSelector:@selector(initWithCollectionViewLayout:)])
|
||||
{
|
||||
NSString* coverDir = [path stringByAppendingPathComponent:@".coverart"];
|
||||
if (ra_ios_is_directory(coverDir))
|
||||
return [[RADirectoryGrid alloc] initWithPath:path];
|
||||
}
|
||||
|
||||
return [[RADirectoryList alloc] initWithPath:path];
|
||||
}
|
||||
|
||||
- (id)initWithPath:(NSString*)path
|
||||
{
|
||||
self = [super initWithStyle:UITableViewStylePlain];
|
||||
|
||||
_path = path;
|
||||
_list = ra_ios_list_directory(_path);
|
||||
|
||||
[self setTitle: [_path lastPathComponent]];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (void)tableView:(UITableView *)tableView didSelectRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
RADirectoryItem* path = [_list objectAtIndex: indexPath.row];
|
||||
|
||||
if(path.isDirectory)
|
||||
[[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListOrGridWithPath:path.path] animated:YES];
|
||||
else
|
||||
[[RetroArch_iOS get] pushViewController:[[RAModuleList alloc] initWithGame:path.path] animated:YES];
|
||||
}
|
||||
|
||||
- (NSInteger)tableView:(UITableView *)tableView numberOfRowsInSection:(NSInteger)section
|
||||
{
|
||||
return [_list count];
|
||||
}
|
||||
|
||||
- (UITableViewCell*)tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
RADirectoryItem* path = [_list objectAtIndex: indexPath.row];
|
||||
|
||||
UITableViewCell* cell = [self.tableView dequeueReusableCellWithIdentifier:@"path"];
|
||||
cell = (cell != nil) ? cell : [[UITableViewCell alloc] initWithStyle:UITableViewCellStyleDefault reuseIdentifier:@"path"];
|
||||
cell.textLabel.text = [path.path lastPathComponent];
|
||||
cell.accessoryType = (path.isDirectory) ? UITableViewCellAccessoryDisclosureIndicator : UITableViewCellAccessoryNone;
|
||||
cell.imageView.image = [UIImage imageNamed:(path.isDirectory) ? @"ic_dir" : @"ic_file"];
|
||||
return cell;
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
@implementation RADirectoryGrid
|
||||
{
|
||||
NSString* _path;
|
||||
NSArray* _list;
|
||||
}
|
||||
|
||||
- (id)initWithPath:(NSString*)path
|
||||
{
|
||||
_path = path;
|
||||
_list = ra_ios_list_directory(_path);
|
||||
|
||||
[self setTitle: [_path lastPathComponent]];
|
||||
|
||||
unsigned tileWidth = 100;
|
||||
unsigned tileHeight = 100;
|
||||
|
||||
config_file_t* config = config_file_new([[path stringByAppendingPathComponent:@".raconfig"] UTF8String]);
|
||||
if (config)
|
||||
{
|
||||
config_get_uint(config, "cover_width", &tileWidth);
|
||||
config_get_uint(config, "cover_height", &tileHeight);
|
||||
config_file_free(config);
|
||||
}
|
||||
|
||||
// Init collection view
|
||||
UICollectionViewFlowLayout* layout = [UICollectionViewFlowLayout new];
|
||||
layout.itemSize = CGSizeMake(tileWidth, tileHeight);
|
||||
self = [super initWithCollectionViewLayout:layout];
|
||||
|
||||
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"dircell"];
|
||||
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"textcell"];
|
||||
[self.collectionView registerClass:[UICollectionViewCell class] forCellWithReuseIdentifier:@"imagecell"];
|
||||
|
||||
return self;
|
||||
}
|
||||
|
||||
- (NSInteger)numberOfSectionsInCollectionView:(UICollectionView *)collectionView
|
||||
{
|
||||
return 1;
|
||||
}
|
||||
|
||||
- (NSInteger)collectionView:(UICollectionView *)collectionView numberOfItemsInSection:(NSInteger)section
|
||||
{
|
||||
return [_list count];
|
||||
}
|
||||
|
||||
- (void)collectionView:(UICollectionView *)collectionView didSelectItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
RADirectoryItem* path = [_list objectAtIndex: indexPath.row];
|
||||
|
||||
if(path.isDirectory)
|
||||
[[RetroArch_iOS get] pushViewController:[RADirectoryList directoryListOrGridWithPath:path.path] animated:YES];
|
||||
else
|
||||
[[RetroArch_iOS get] pushViewController:[[RAModuleList alloc] initWithGame:path.path] animated:YES];
|
||||
}
|
||||
|
||||
- (UICollectionViewCell *)collectionView:(UICollectionView *)collectionView cellForItemAtIndexPath:(NSIndexPath *)indexPath
|
||||
{
|
||||
RADirectoryItem* path = [_list objectAtIndex: indexPath.row];
|
||||
UICollectionViewCell* cell = nil;
|
||||
|
||||
if (path.isDirectory)
|
||||
{
|
||||
cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:@"dircell" forIndexPath:indexPath];
|
||||
|
||||
if (!cell.backgroundView)
|
||||
{
|
||||
cell.backgroundView = [[UIImageView alloc] initWithImage:[UIImage imageNamed:@"ic_dir"]];
|
||||
((UIImageView*)cell.backgroundView).contentMode = UIViewContentModeScaleAspectFit;
|
||||
}
|
||||
}
|
||||
else if (path.coverPath)
|
||||
{
|
||||
cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:@"imagecell" forIndexPath:indexPath];
|
||||
|
||||
if (!cell.backgroundView)
|
||||
{
|
||||
cell.backgroundView = [UIImageView new];
|
||||
((UIImageView*)cell.backgroundView).contentMode = UIViewContentModeScaleAspectFit;
|
||||
}
|
||||
|
||||
((UIImageView*)cell.backgroundView).image = [UIImage imageWithContentsOfFile:path.coverPath];
|
||||
}
|
||||
else
|
||||
{
|
||||
cell = [self.collectionView dequeueReusableCellWithReuseIdentifier:@"textcell" forIndexPath:indexPath];
|
||||
|
||||
if (!cell.backgroundView)
|
||||
{
|
||||
cell.backgroundView = [UILabel new];
|
||||
((UILabel*)cell.backgroundView).numberOfLines = 0;
|
||||
((UILabel*)cell.backgroundView).textAlignment = NSTextAlignmentCenter;
|
||||
}
|
||||
|
||||
((UILabel*)cell.backgroundView).text = [path.path lastPathComponent];
|
||||
}
|
||||
|
||||
return cell;
|
||||
}
|
||||
|
||||
@end
|
||||
|
@ -18,6 +18,19 @@
|
||||
#include "input/keycode.h"
|
||||
#include "libretro.h"
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <pthread.h>
|
||||
|
||||
#include "rarch_wrapper.h"
|
||||
#include "general.h"
|
||||
#include "frontend/menu/rmenu.h"
|
||||
|
||||
#import "browser/browser.h"
|
||||
#import "settings/settings.h"
|
||||
|
||||
#include "input/BTStack/btdynamic.h"
|
||||
#include "input/BTStack/btpad.h"
|
||||
|
||||
#define GSEVENT_TYPE_KEYDOWN 10
|
||||
#define GSEVENT_TYPE_KEYUP 11
|
||||
#define GSEVENT_TYPE_MODS 12
|
||||
@ -144,3 +157,303 @@ int main(int argc, char *argv[])
|
||||
}
|
||||
}
|
||||
|
||||
#define kDOCSFOLDER [NSHomeDirectory() stringByAppendingPathComponent:@"Documents"]
|
||||
|
||||
// From frontend/frontend_ios.c
|
||||
extern void* rarch_main_ios(void* args);
|
||||
extern void ios_frontend_post_event(void (*fn)(void*), void* userdata);
|
||||
|
||||
static void event_game_reset(void* userdata)
|
||||
{
|
||||
rarch_game_reset();
|
||||
}
|
||||
|
||||
static void event_load_state(void* userdata)
|
||||
{
|
||||
rarch_load_state();
|
||||
}
|
||||
|
||||
static void event_save_state(void* userdata)
|
||||
{
|
||||
rarch_save_state();
|
||||
}
|
||||
|
||||
static void event_set_state_slot(void* userdata)
|
||||
{
|
||||
g_extern.state_slot = (uint32_t)userdata;
|
||||
}
|
||||
|
||||
static void event_quit(void* userdata)
|
||||
{
|
||||
g_extern.system.shutdown = true;
|
||||
}
|
||||
|
||||
static void event_reload_config(void* userdata)
|
||||
{
|
||||
// Need to clear these otherwise stale versions may be used!
|
||||
memset(g_settings.input.overlay, 0, sizeof(g_settings.input.overlay));
|
||||
memset(g_settings.video.xml_shader_path, 0, sizeof(g_settings.video.xml_shader_path));
|
||||
|
||||
uninit_drivers();
|
||||
config_load();
|
||||
init_drivers();
|
||||
}
|
||||
|
||||
@implementation RetroArch_iOS
|
||||
{
|
||||
UIWindow* _window;
|
||||
|
||||
pthread_t _retroThread;
|
||||
|
||||
bool _isGameTop;
|
||||
bool _isPaused;
|
||||
bool _isRunning;
|
||||
}
|
||||
|
||||
+ (void)displayErrorMessage:(NSString*)message
|
||||
{
|
||||
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"RetroArch"
|
||||
message:message
|
||||
delegate:nil
|
||||
cancelButtonTitle:@"OK"
|
||||
otherButtonTitles:nil];
|
||||
[alert show];
|
||||
}
|
||||
|
||||
+ (RetroArch_iOS*)get
|
||||
{
|
||||
return (RetroArch_iOS*)[[UIApplication sharedApplication] delegate];
|
||||
}
|
||||
|
||||
// UIApplicationDelegate
|
||||
- (void)applicationDidFinishLaunching:(UIApplication *)application
|
||||
{
|
||||
self.system_directory = [NSString stringWithFormat:@"%@/.RetroArch", kDOCSFOLDER];
|
||||
mkdir([self.system_directory UTF8String], 0755);
|
||||
|
||||
// Setup window
|
||||
self.delegate = self;
|
||||
[self pushViewController:[RADirectoryList directoryListOrGridWithPath:kDOCSFOLDER] animated:YES];
|
||||
|
||||
_window = [[UIWindow alloc] initWithFrame:[[UIScreen mainScreen] bounds]];
|
||||
_window.rootViewController = self;
|
||||
[_window makeKeyAndVisible];
|
||||
}
|
||||
|
||||
- (void)applicationWillEnterForeground:(UIApplication *)application
|
||||
{
|
||||
[RAGameView.get resume];
|
||||
}
|
||||
|
||||
- (void)applicationDidEnterBackground:(UIApplication *)application
|
||||
{
|
||||
[RAGameView.get suspend];
|
||||
}
|
||||
|
||||
// UINavigationControllerDelegate
|
||||
- (void)navigationController:(UINavigationController *)navigationController willShowViewController:(UIViewController *)viewController animated:(BOOL)animated
|
||||
{
|
||||
_isGameTop = [viewController isKindOfClass:[RAGameView class]];
|
||||
[[UIApplication sharedApplication] setStatusBarHidden:_isGameTop withAnimation:UIStatusBarAnimationNone];
|
||||
self.navigationBarHidden = _isGameTop;
|
||||
|
||||
self.topViewController.navigationItem.rightBarButtonItem = [self createBluetoothButton];
|
||||
}
|
||||
|
||||
// UINavigationController: Never animate when pushing onto, or popping, an RAGameView
|
||||
- (void)pushViewController:(UIViewController*)theView animated:(BOOL)animated
|
||||
{
|
||||
[super pushViewController:theView animated:animated && !_isGameTop];
|
||||
}
|
||||
|
||||
- (UIViewController*)popViewControllerAnimated:(BOOL)animated
|
||||
{
|
||||
return [super popViewControllerAnimated:animated && !_isGameTop];
|
||||
}
|
||||
|
||||
#pragma mark EMULATION
|
||||
- (void)runGame:(NSString*)path
|
||||
{
|
||||
if (_isRunning)
|
||||
return;
|
||||
|
||||
assert(self.moduleInfo);
|
||||
|
||||
[RASettingsList refreshConfigFile];
|
||||
|
||||
[self pushViewController:RAGameView.get animated:NO];
|
||||
_isRunning = true;
|
||||
|
||||
const char* const sd = [[RetroArch_iOS get].system_directory UTF8String];
|
||||
const char* const cf = (ra_ios_is_file(self.moduleInfo.configPath)) ? [self.moduleInfo.configPath UTF8String] : 0;
|
||||
const char* const libretro = [self.moduleInfo.path UTF8String];
|
||||
|
||||
struct rarch_main_wrap* load_data = malloc(sizeof(struct rarch_main_wrap));
|
||||
load_data->libretro_path = strdup(libretro);
|
||||
load_data->rom_path = strdup([path UTF8String]);
|
||||
load_data->sram_path = strdup(sd);
|
||||
load_data->state_path = strdup(sd);
|
||||
load_data->verbose = false;
|
||||
load_data->config_path = strdup(cf);
|
||||
if (pthread_create(&_retroThread, 0, rarch_main_ios, load_data))
|
||||
{
|
||||
[self rarchExited:NO];
|
||||
}
|
||||
pthread_detach(_retroThread);
|
||||
|
||||
// Read load time settings
|
||||
// TODO: Do this better
|
||||
config_file_t* conf = config_file_new([self.moduleInfo.configPath UTF8String]);
|
||||
bool autoStartBluetooth = false;
|
||||
if (conf && config_get_bool(conf, "ios_auto_bluetooth", &autoStartBluetooth) && autoStartBluetooth)
|
||||
[self startBluetooth];
|
||||
config_file_free(conf);
|
||||
}
|
||||
|
||||
- (void)rarchExited:(BOOL)successful
|
||||
{
|
||||
if (!successful)
|
||||
{
|
||||
[RetroArch_iOS displayErrorMessage:@"Failed to load game."];
|
||||
}
|
||||
|
||||
if (_isRunning)
|
||||
{
|
||||
_isRunning = false;
|
||||
|
||||
// Stop bluetooth (might be annoying but forgetting could eat battery of device AND wiimote)
|
||||
[self stopBluetooth];
|
||||
|
||||
//
|
||||
[self popToViewController:[RAGameView get] animated:NO];
|
||||
[self popViewControllerAnimated:NO];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)refreshConfig
|
||||
{
|
||||
if (_isRunning)
|
||||
ios_frontend_post_event(&event_reload_config, 0);
|
||||
else
|
||||
{
|
||||
// Need to clear these otherwise stale versions may be used!
|
||||
memset(g_settings.input.overlay, 0, sizeof(g_settings.input.overlay));
|
||||
memset(g_settings.video.xml_shader_path, 0, sizeof(g_settings.video.xml_shader_path));
|
||||
}
|
||||
}
|
||||
|
||||
#pragma mark PAUSE MENU
|
||||
- (IBAction)showPauseMenu:(id)sender
|
||||
{
|
||||
if (_isRunning && !_isPaused && _isGameTop)
|
||||
{
|
||||
_isPaused = true;
|
||||
[[RAGameView get] openPauseMenu];
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)resetGame:(id)sender
|
||||
{
|
||||
if (_isRunning)
|
||||
ios_frontend_post_event(&event_game_reset, 0);
|
||||
|
||||
[self closePauseMenu:sender];
|
||||
}
|
||||
|
||||
- (IBAction)loadState:(id)sender
|
||||
{
|
||||
if (_isRunning)
|
||||
ios_frontend_post_event(&event_load_state, 0);
|
||||
|
||||
[self closePauseMenu:sender];
|
||||
}
|
||||
|
||||
- (IBAction)saveState:(id)sender
|
||||
{
|
||||
if (_isRunning)
|
||||
ios_frontend_post_event(&event_save_state, 0);
|
||||
|
||||
[self closePauseMenu:sender];
|
||||
}
|
||||
|
||||
- (IBAction)chooseState:(id)sender
|
||||
{
|
||||
if (_isRunning)
|
||||
ios_frontend_post_event(event_set_state_slot, (void*)((UISegmentedControl*)sender).selectedSegmentIndex);
|
||||
}
|
||||
|
||||
- (IBAction)closePauseMenu:(id)sender
|
||||
{
|
||||
[[RAGameView get] closePauseMenu];
|
||||
_isPaused = false;
|
||||
}
|
||||
|
||||
- (IBAction)closeGamePressed:(id)sender
|
||||
{
|
||||
[self closePauseMenu:sender];
|
||||
ios_frontend_post_event(event_quit, 0);
|
||||
}
|
||||
|
||||
- (IBAction)showSettings
|
||||
{
|
||||
[self pushViewController:[RASettingsList new] animated:YES];
|
||||
}
|
||||
|
||||
#pragma mark Bluetooth Helpers
|
||||
- (UIBarButtonItem*)createBluetoothButton
|
||||
{
|
||||
if (btstack_is_loaded())
|
||||
{
|
||||
const bool isBTOn = btstack_is_running();
|
||||
return [[UIBarButtonItem alloc]
|
||||
initWithTitle:isBTOn ? @"Stop Bluetooth" : @"Start Bluetooth"
|
||||
style:UIBarButtonItemStyleBordered
|
||||
target:[RetroArch_iOS get]
|
||||
action:isBTOn ? @selector(stopBluetooth) : @selector(startBluetooth)];
|
||||
}
|
||||
else
|
||||
return nil;
|
||||
}
|
||||
|
||||
- (IBAction)startBluetooth
|
||||
{
|
||||
if (btstack_is_loaded() && !btstack_is_running())
|
||||
{
|
||||
UIAlertView* alert = [[UIAlertView alloc] initWithTitle:@"RetroArch"
|
||||
message:@"Choose Pad Type"
|
||||
delegate:self
|
||||
cancelButtonTitle:@"Cancel"
|
||||
otherButtonTitles:@"Wii", @"PS3", nil];
|
||||
[alert show];
|
||||
}
|
||||
}
|
||||
|
||||
- (void)alertView:(UIAlertView *)alertView clickedButtonAtIndex:(NSInteger)buttonIndex
|
||||
{
|
||||
if (btstack_is_loaded())
|
||||
{
|
||||
btpad_set_pad_type(buttonIndex == alertView.firstOtherButtonIndex);
|
||||
|
||||
if (buttonIndex != alertView.cancelButtonIndex)
|
||||
{
|
||||
btstack_start();
|
||||
[self.topViewController.navigationItem setRightBarButtonItem:[self createBluetoothButton] animated:YES];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
- (IBAction)stopBluetooth
|
||||
{
|
||||
if (btstack_is_loaded())
|
||||
{
|
||||
btstack_stop();
|
||||
[self.topViewController.navigationItem setRightBarButtonItem:[self createBluetoothButton] animated:YES];
|
||||
}
|
||||
}
|
||||
|
||||
@end
|
||||
|
||||
void ios_rarch_exited(void* result)
|
||||
{
|
||||
[[RetroArch_iOS get] rarchExited:result ? NO : YES];
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user