2013-11-22 14:30:02 +00:00
/ * RetroArch - A frontend for libretro .
2014-01-01 00:50:59 +00:00
* Copyright ( C ) 2013 -2014 - Jason Fetters
2013-11-22 14:30:02 +00:00
*
* 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 < objc / runtime . h >
2014-05-22 16:54:10 +00:00
# include "../common/RetroArch_Apple.h"
2014-05-03 17:00:12 +00:00
# include "../../input/input_common.h"
2014-04-26 15:47:21 +00:00
# include "../../input/apple_input.h"
2013-11-22 14:30:02 +00:00
# include "menu.h"
2013-12-10 00:50:46 +00:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * RunActionSheet * /
/ * Creates and displays a UIActionSheet with * /
/ * buttons pulled from a RetroArch * /
/ * string_list structure . * /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2013-12-30 23:20:31 +00:00
static const void * const associated_delegate _key = & associated_delegate _key ;
2013-12-26 21:00:29 +00:00
typedef void ( ^ RAActionSheetCallback ) ( UIActionSheet * , NSInteger ) ;
@ interface RARunActionSheetDelegate : NSObject < UIActionSheetDelegate >
@ property ( nonatomic , copy ) RAActionSheetCallback callbackBlock ;
@ end
@ implementation RARunActionSheetDelegate
- ( id ) initWithCallbackBlock : ( RAActionSheetCallback ) callback
{
if ( ( self = [ super init ] ) )
_callbackBlock = callback ;
return self ;
}
- ( void ) actionSheet : ( UIActionSheet * ) actionSheet willDismissWithButtonIndex : ( NSInteger ) buttonIndex
{
if ( self . callbackBlock )
self . callbackBlock ( actionSheet , buttonIndex ) ;
}
@ end
static void RunActionSheet ( const char * title , const struct string_list * items , UIView * parent , RAActionSheetCallback callback )
2013-12-10 00:50:46 +00:00
{
2014-09-21 01:38:59 +00:00
size_t i ;
2013-12-30 23:20:31 +00:00
RARunActionSheetDelegate * delegate = [ [ RARunActionSheetDelegate alloc ] initWithCallbackBlock : callback ] ;
2013-12-10 00:50:46 +00:00
UIActionSheet * actionSheet = [ UIActionSheet new ] ;
2014-07-08 16:23:30 +00:00
2013-12-12 19:49:18 +00:00
actionSheet . title = BOXSTRING ( title ) ;
2013-12-30 23:20:31 +00:00
actionSheet . delegate = delegate ;
2013-12-10 00:50:46 +00:00
2014-07-08 16:23:30 +00:00
for ( i = 0 ; i < items -> size ; i + + )
2013-12-12 19:49:18 +00:00
[ actionSheet addButtonWithTitle : BOXSTRING ( items -> elems [ i ] . data ) ] ;
2013-12-10 00:50:46 +00:00
2014-07-08 16:23:30 +00:00
actionSheet . cancelButtonIndex = [ actionSheet addButtonWithTitle : BOXSTRING ( "Cancel" ) ] ;
2013-12-30 23:20:31 +00:00
objc_setAssociatedObject ( actionSheet , associated_delegate _key , delegate , OBJC_ASSOCIATION _RETAIN _NONATOMIC ) ;
2013-12-10 00:50:46 +00:00
[ actionSheet showInView : parent ] ;
}
2013-11-22 14:30:02 +00:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * RAMenuBase * /
/ * A menu class that displays RAMenuItemBase * /
/ * objects . * /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
@ implementation RAMenuBase
- ( id ) initWithStyle : ( UITableViewStyle ) style
{
if ( ( self = [ super initWithStyle : style ] ) )
2013-12-26 22:36:00 +00:00
_sections = [ NSMutableArray array ] ;
2013-11-22 14:30:02 +00:00
return self ;
}
- ( NSInteger ) numberOfSectionsInTableView : ( UITableView * ) tableView
{
return self . sections . count ;
}
- ( NSString * ) tableView : ( UITableView * ) tableView titleForHeaderInSection : ( NSInteger ) section
{
return self . hidesHeaders ? nil : self . sections [ section ] [ 0 ] ;
}
- ( NSInteger ) tableView : ( UITableView * ) tableView numberOfRowsInSection : ( NSInteger ) section
{
return [ self . sections [ section ] count ] - 1 ;
}
- ( id ) itemForIndexPath : ( NSIndexPath * ) indexPath
{
return self . sections [ indexPath . section ] [ indexPath . row + 1 ] ;
}
- ( UITableViewCell * ) tableView : ( UITableView * ) tableView cellForRowAtIndexPath : ( NSIndexPath * ) indexPath
{
return [ [ self itemForIndexPath : indexPath ] cellForTableView : tableView ] ;
}
- ( void ) tableView : ( UITableView * ) tableView didSelectRowAtIndexPath : ( NSIndexPath * ) indexPath
{
[ [ self itemForIndexPath : indexPath ] wasSelectedOnTableView : tableView ofController : self ] ;
}
2013-12-16 02:27:17 +00:00
- ( void ) willReloadData
{
}
- ( void ) reloadData
{
[ self willReloadData ] ;
[ [ self tableView ] reloadData ] ;
}
2013-11-22 14:30:02 +00:00
@ end
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * RAMenuItemBasic * /
/ * A simple menu item that displays a text * /
/ * description and calls a block object when * /
/ * selected . * /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
@ implementation RAMenuItemBasic
2014-09-20 20:54:02 +00:00
@ synthesize description ;
@ synthesize userdata ;
@ synthesize action ;
@ synthesize detail ;
2013-11-22 14:30:02 +00:00
+ ( RAMenuItemBasic * ) itemWithDescription : ( NSString * ) description action : ( void ( ^ ) ( ) ) action
{
return [ self itemWithDescription : description action : action detail : Nil ] ;
}
+ ( RAMenuItemBasic * ) itemWithDescription : ( NSString * ) description action : ( void ( ^ ) ( ) ) action detail : ( NSString * ( ^ ) ( ) ) detail
{
return [ self itemWithDescription : description association : nil action : action detail : detail ] ;
}
+ ( RAMenuItemBasic * ) itemWithDescription : ( NSString * ) description association : ( id ) userdata action : ( void ( ^ ) ( ) ) action detail : ( NSString * ( ^ ) ( ) ) detail
{
RAMenuItemBasic * item = [ RAMenuItemBasic new ] ;
item . description = description ;
item . userdata = userdata ;
item . action = action ;
item . detail = detail ;
return item ;
}
- ( UITableViewCell * ) cellForTableView : ( UITableView * ) tableView
{
static NSString * const cell_id = @ "text" ;
UITableViewCell * result = [ tableView dequeueReusableCellWithIdentifier : cell_id ] ;
if ( ! result )
result = [ [ UITableViewCell alloc ] initWithStyle : UITableViewCellStyleValue1 reuseIdentifier : cell_id ] ;
result . selectionStyle = UITableViewCellSelectionStyleNone ;
result . textLabel . text = self . description ;
result . detailTextLabel . text = self . detail ? self . detail ( self . userdata ) : nil ;
return result ;
}
- ( void ) wasSelectedOnTableView : ( UITableView * ) tableView ofController : ( UIViewController * ) controller
{
if ( self . action )
self . action ( self . userdata ) ;
}
@ end
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * RAMenuItemGeneralSetting * /
/ * A simple menu item that displays the * /
/ * state , and allows editing , of a string or * /
/ * numeric setting . * /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
@ interface RAMenuItemGeneralSetting ( ) < UIAlertViewDelegate >
@ property ( nonatomic ) RANumberFormatter * formatter ;
@ end
@ implementation RAMenuItemGeneralSetting
2014-07-17 01:52:21 +00:00
+ ( id ) itemForSetting : ( rarch_setting _t * ) setting
2013-11-22 14:30:02 +00:00
{
2013-11-30 02:34:12 +00:00
switch ( setting -> type )
{
2014-04-19 18:16:29 +00:00
case ST_BOOL :
return [ [ RAMenuItemBooleanSetting alloc ] initWithSetting : setting ] ;
case ST_PATH :
return [ [ RAMenuItemPathSetting alloc ] initWithSetting : setting ] ;
case ST_BIND :
return [ [ RAMenuItemBindSetting alloc ] initWithSetting : setting ] ;
default :
break ;
2013-11-30 02:34:12 +00:00
}
2013-12-04 00:46:30 +00:00
if ( setting -> type = = ST_STRING && setting -> values )
return [ [ RAMenuItemEnumSetting alloc ] initWithSetting : setting ] ;
2013-11-30 02:34:12 +00:00
RAMenuItemGeneralSetting * item = [ [ RAMenuItemGeneralSetting alloc ] initWithSetting : setting ] ;
2013-11-22 14:30:02 +00:00
2014-09-28 16:18:26 +00:00
if (
item . setting -> type = = ST_INT ||
item . setting -> type = = ST_UINT ||
item . setting -> type = = ST_FLOAT )
2013-11-22 14:30:02 +00:00
item . formatter = [ [ RANumberFormatter alloc ] initWithSetting : item . setting ] ;
return item ;
}
2014-07-17 01:52:21 +00:00
- ( id ) initWithSetting : ( rarch_setting _t * ) setting
2013-11-30 02:34:12 +00:00
{
if ( ( self = [ super init ] ) )
2013-12-26 22:36:00 +00:00
_setting = setting ;
2013-11-30 02:34:12 +00:00
return self ;
}
2013-11-22 14:30:02 +00:00
- ( UITableViewCell * ) cellForTableView : ( UITableView * ) tableView
{
2014-09-28 16:18:26 +00:00
char buffer [ PATH_MAX ] ;
2013-11-22 14:30:02 +00:00
static NSString * const cell_id = @ "string_setting" ;
self . parentTable = tableView ;
UITableViewCell * result = [ tableView dequeueReusableCellWithIdentifier : cell_id ] ;
if ( ! result )
{
result = [ [ UITableViewCell alloc ] initWithStyle : UITableViewCellStyleValue1 reuseIdentifier : cell_id ] ;
result . selectionStyle = UITableViewCellSelectionStyleNone ;
}
2013-12-26 21:17:37 +00:00
[ self attachDefaultingGestureTo : result ] ;
2013-11-22 14:30:02 +00:00
2014-07-25 17:35:09 +00:00
result . textLabel . text = BOXSTRING ( "N/A" ) ;
2013-11-22 14:30:02 +00:00
if ( self . setting )
2013-12-03 00:55:58 +00:00
{
2014-08-17 14:20:37 +00:00
if ( self . setting -> short_description )
result . textLabel . text = BOXSTRING ( self . setting -> short_description ) ;
setting_data _get _string _representation ( self . setting , buffer , sizeof ( buffer ) ) ;
if ( buffer [ 0 ] = = ' \ 0 ' )
strlcpy ( buffer , "N/A" , sizeof ( buffer ) ) ;
result . detailTextLabel . text = BOXSTRING ( buffer ) ;
2013-12-03 00:55:58 +00:00
if ( self . setting -> type = = ST_PATH )
result . detailTextLabel . text = [ result . detailTextLabel . text lastPathComponent ] ;
}
2013-11-22 14:30:02 +00:00
return result ;
}
- ( void ) wasSelectedOnTableView : ( UITableView * ) tableView ofController : ( UIViewController * ) controller
{
2014-09-28 16:18:26 +00:00
char buffer [ PATH_MAX ] ;
2014-07-25 17:45:52 +00:00
NSString * desc = BOXSTRING ( "N/A" ) ;
UIAlertView * alertView ;
UITextField * field ;
if ( self . setting && self . setting -> short_description )
desc = BOXSTRING ( self . setting -> short_description ) ;
alertView = [ [ UIAlertView alloc ] initWithTitle : BOXSTRING ( "Enter new value" ) message : desc delegate : self cancelButtonTitle : BOXSTRING ( "Cancel" ) otherButtonTitles : BOXSTRING ( "OK" ) , nil ] ;
2013-11-22 14:30:02 +00:00
alertView . alertViewStyle = UIAlertViewStylePlainTextInput ;
2014-07-25 17:45:52 +00:00
field = [ alertView textFieldAtIndex : 0 ] ;
2013-11-22 14:30:02 +00:00
field . delegate = self . formatter ;
2014-08-17 14:20:37 +00:00
setting_data _get _string _representation ( self . setting , buffer , sizeof ( buffer ) ) ;
if ( buffer [ 0 ] = = ' \ 0 ' )
strlcpy ( buffer , "N/A" , sizeof ( buffer ) ) ;
field . placeholder = BOXSTRING ( buffer ) ;
2013-11-22 14:30:02 +00:00
[ alertView show ] ;
}
- ( void ) alertView : ( UIAlertView * ) alertView clickedButtonAtIndex : ( NSInteger ) buttonIndex
{
2014-04-19 18:16:29 +00:00
NSString * text = ( NSString * ) [ alertView textFieldAtIndex : 0 ] . text ;
2013-11-22 14:30:02 +00:00
if ( buttonIndex = = alertView . firstOtherButtonIndex && text . length )
{
2013-12-26 22:36:00 +00:00
setting_data _set _with _string _representation ( self . setting , [ text UTF8String ] ) ;
2013-11-22 14:30:02 +00:00
[ self . parentTable reloadData ] ;
}
}
2013-12-26 21:17:37 +00:00
- ( void ) attachDefaultingGestureTo : ( UIView * ) view
{
for ( UIGestureRecognizer * i in view . gestureRecognizers )
[ view removeGestureRecognizer : i ] ;
[ view addGestureRecognizer : [ [ UILongPressGestureRecognizer alloc ] initWithTarget : self
action : @ selector ( resetValue : ) ] ] ;
}
- ( void ) resetValue : ( UIGestureRecognizer * ) gesture
{
if ( gesture . state = = UIGestureRecognizerStateBegan )
{
2014-07-08 16:23:30 +00:00
struct string_list * items ;
2013-12-26 21:17:37 +00:00
RAMenuItemGeneralSetting __weak * weakSelf = self ;
2014-07-08 16:23:30 +00:00
items = ( struct string_list * ) string_split ( "OK" , "|" ) ;
2013-12-26 21:17:37 +00:00
RunActionSheet ( "Really Reset Value?" , items , self . parentTable ,
^ ( UIActionSheet * actionSheet , NSInteger buttonIndex )
{
if ( buttonIndex ! = actionSheet . cancelButtonIndex )
setting_data _reset _setting ( self . setting ) ;
[ weakSelf . parentTable reloadData ] ;
} ) ;
string_list _free ( items ) ;
}
}
2013-11-22 14:30:02 +00:00
@ end
2013-11-30 02:34:12 +00:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * RAMenuItemBooleanSetting * /
/ * A simple menu item that displays the * /
/ * state , and allows editing , of a boolean * /
/ * setting . * /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
@ implementation RAMenuItemBooleanSetting
2014-07-17 01:52:21 +00:00
- ( id ) initWithSetting : ( rarch_setting _t * ) setting
2013-11-30 02:34:12 +00:00
{
if ( ( self = [ super init ] ) )
2013-12-26 22:36:00 +00:00
_setting = setting ;
2013-11-30 02:34:12 +00:00
return self ;
}
- ( UITableViewCell * ) cellForTableView : ( UITableView * ) tableView
{
static NSString * const cell_id = @ "boolean_setting" ;
2014-04-19 18:16:29 +00:00
UITableViewCell * result = ( UITableViewCell * ) [ tableView dequeueReusableCellWithIdentifier : cell_id ] ;
2013-11-30 02:34:12 +00:00
if ( ! result )
{
result = [ [ UITableViewCell alloc ] initWithStyle : UITableViewCellStyleValue1 reuseIdentifier : cell_id ] ;
result . selectionStyle = UITableViewCellSelectionStyleNone ;
result . accessoryView = [ UISwitch new ] ;
}
2013-12-12 19:49:18 +00:00
result . textLabel . text = BOXSTRING ( self . setting -> short_description ) ;
2013-11-30 02:34:12 +00:00
[ ( id ) result . accessoryView removeTarget : nil action : NULL forControlEvents : UIControlEventValueChanged ] ;
[ ( id ) result . accessoryView addTarget : self action : @ selector ( handleBooleanSwitch : ) forControlEvents : UIControlEventValueChanged ] ;
if ( self . setting )
[ ( id ) result . accessoryView setOn : * self . setting -> value . boolean ] ;
return result ;
}
- ( void ) handleBooleanSwitch : ( UISwitch * ) swt
{
if ( self . setting )
* self . setting -> value . boolean = swt . on ? true : false ;
}
- ( void ) wasSelectedOnTableView : ( UITableView * ) tableView ofController : ( UIViewController * ) controller
{
}
@ end
2013-11-22 14:30:02 +00:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * RAMenuItemPathSetting * /
/ * A menu item that displays and allows * /
/ * browsing for a path setting . * /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2013-12-26 06:43:10 +00:00
@ interface RAMenuItemPathSetting ( ) @ end
2013-11-22 14:30:02 +00:00
@ implementation RAMenuItemPathSetting
- ( void ) wasSelectedOnTableView : ( UITableView * ) tableView ofController : ( UIViewController * ) controller
{
2014-07-08 16:23:30 +00:00
NSString * path ;
RADirectoryList * list ;
2013-12-26 06:43:10 +00:00
RAMenuItemPathSetting __weak * weakSelf = self ;
2014-07-08 16:23:30 +00:00
path = [ BOXSTRING ( self . setting -> value . string ) stringByDeletingLastPathComponent ] ;
list = [ [ RADirectoryList alloc ] initWithPath : path extensions : self . setting -> values action :
2013-12-26 06:43:10 +00:00
^ ( RADirectoryList * list , RADirectoryItem * item )
{
if ( ! list . allowBlank && ! item )
return ;
if ( list . forDirectory && ! item . isDirectory )
return ;
2013-12-26 22:36:00 +00:00
setting_data _set _with _string _representation ( weakSelf . setting , item ? [ item . path UTF8String ] : "" ) ;
2013-12-26 06:43:10 +00:00
[ [ list navigationController ] popViewControllerAnimated : YES ] ;
[ weakSelf . parentTable reloadData ] ;
} ] ;
2013-12-24 19:03:43 +00:00
list . allowBlank = ( self . setting -> flags & SD_FLAG _ALLOW _EMPTY ) ;
list . forDirectory = ( self . setting -> flags & SD_FLAG _PATH _DIR ) ;
2013-11-22 14:30:02 +00:00
[ controller . navigationController pushViewController : list animated : YES ] ;
}
@ end
2013-12-04 00:46:30 +00:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * RAMenuItemEnumSetting * /
/ * A menu item that displays and allows * /
/ * a setting to be set from a list of * /
/ * allowed choices . * /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
@ implementation RAMenuItemEnumSetting
- ( void ) wasSelectedOnTableView : ( UITableView * ) tableView ofController : ( UIViewController * ) controller
{
2014-07-08 16:23:30 +00:00
struct string_list * items ;
2014-01-06 01:12:04 +00:00
RAMenuItemEnumSetting __weak * weakSelf = self ;
2014-07-08 16:23:30 +00:00
items = ( struct string_list * ) string_split ( self . setting -> values , "|" ) ;
2013-12-26 21:00:29 +00:00
RunActionSheet ( self . setting -> short_description , items , self . parentTable ,
^ ( UIActionSheet * actionSheet , NSInteger buttonIndex )
{
if ( buttonIndex ! = actionSheet . cancelButtonIndex )
{
2013-12-26 22:36:00 +00:00
setting_data _set _with _string _representation ( self . setting , [ [ actionSheet buttonTitleAtIndex : buttonIndex ] UTF8String ] ) ;
2014-01-06 01:12:04 +00:00
[ weakSelf . parentTable reloadData ] ;
2013-12-26 21:00:29 +00:00
}
} ) ;
2013-12-10 00:50:46 +00:00
string_list _free ( items ) ;
2013-12-04 00:46:30 +00:00
}
@ end
2013-11-22 14:30:02 +00:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * RAMenuItemBindSetting * /
/ * A menu item that displays and allows * /
/ * mapping of a keybinding . * /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
@ interface RAMenuItemBindSetting ( ) < UIAlertViewDelegate >
@ property ( nonatomic ) NSTimer * bindTimer ;
@ property ( nonatomic ) UIAlertView * alert ;
@ end
@ implementation RAMenuItemBindSetting
- ( void ) wasSelectedOnTableView : ( UITableView * ) tableView ofController : ( UIViewController * ) controller
{
2014-04-19 18:16:29 +00:00
self . alert = [ [ UIAlertView alloc ] initWithTitle : BOXSTRING ( "RetroArch" )
2013-12-12 19:49:18 +00:00
message : BOXSTRING ( self . setting -> short_description )
2013-11-22 14:30:02 +00:00
delegate : self
2014-04-19 18:16:29 +00:00
cancelButtonTitle : BOXSTRING ( "Cancel" )
otherButtonTitles : BOXSTRING ( "Clear Keyboard" ) , BOXSTRING ( "Clear Joystick" ) , BOXSTRING ( "Clear Axis" ) , nil ] ;
2013-12-06 01:33:31 +00:00
2013-11-22 14:30:02 +00:00
[ self . alert show ] ;
[ self . parentTable reloadData ] ;
self . bindTimer = [ NSTimer scheduledTimerWithTimeInterval : .1 f target : self selector : @ selector ( checkBind : )
userInfo : nil repeats : YES ] ;
}
- ( void ) finishWithClickedButton : ( bool ) clicked
{
if ( ! clicked )
[ self . alert dismissWithClickedButtonIndex : self . alert . cancelButtonIndex animated : YES ] ;
self . alert = nil ;
[ self . parentTable reloadData ] ;
[ self . bindTimer invalidate ] ;
self . bindTimer = nil ;
2013-12-06 01:33:31 +00:00
apple_input _reset _icade _buttons ( ) ;
2013-11-22 14:30:02 +00:00
}
- ( void ) alertView : ( UIAlertView * ) alertView clickedButtonAtIndex : ( NSInteger ) buttonIndex
{
if ( buttonIndex = = alertView . firstOtherButtonIndex )
BINDFOR ( * self . setting ) . key = RETROK_UNKNOWN ;
else if ( buttonIndex = = alertView . firstOtherButtonIndex + 1 )
BINDFOR ( * self . setting ) . joykey = NO_BTN ;
else if ( buttonIndex = = alertView . firstOtherButtonIndex + 2 )
BINDFOR ( * self . setting ) . joyaxis = AXIS_NONE ;
[ self finishWithClickedButton : true ] ;
}
- ( void ) checkBind : ( NSTimer * ) send
{
int32_t value = 0 ;
2014-07-08 16:23:30 +00:00
int32_t index = 0 ;
if ( self . setting -> index )
index = self . setting -> index - 1 ;
2013-11-22 14:30:02 +00:00
if ( ( value = apple_input _find _any _key ( ) ) )
BINDFOR ( * self . setting ) . key = input_translate _keysym _to _rk ( value ) ;
2013-12-10 21:53:01 +00:00
else if ( ( value = apple_input _find _any _button ( index ) ) >= 0 )
2013-11-22 14:30:02 +00:00
BINDFOR ( * self . setting ) . joykey = value ;
2013-12-10 21:53:01 +00:00
else if ( ( value = apple_input _find _any _axis ( index ) ) )
BINDFOR ( * self . setting ) . joyaxis = ( value > 0 ) ? AXIS_POS ( value - 1 ) : AXIS_NEG ( abs ( value ) - 1 ) ;
2013-11-22 14:30:02 +00:00
else
return ;
[ self finishWithClickedButton : false ] ;
}
@ end
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * RAMainMenu * /
/ * Menu object that is displayed immediately * /
/ * after startup . * /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
@ implementation RAMainMenu
- ( id ) init
{
if ( ( self = [ super initWithStyle : UITableViewStylePlain ] ) )
2014-04-19 18:16:29 +00:00
self . title = BOXSTRING ( "RetroArch" ) ;
2013-11-22 14:30:02 +00:00
return self ;
}
2013-12-17 22:38:43 +00:00
- ( void ) viewWillAppear : ( BOOL ) animated
{
[ self reloadData ] ;
}
- ( void ) willReloadData
{
RAMainMenu * __weak weakSelf = self ;
self . sections = [ NSMutableArray array ] ;
2014-07-27 04:51:00 +00:00
[ self . sections addObject : [ NSArray arrayWithObjects : BOXSTRING ( "Content" ) ,
[ RAMenuItemBasic itemWithDescription : BOXSTRING ( "Core" )
action : ^ { [ weakSelf chooseCoreWithPath : nil ] ; }
detail : ^ {
const core_info _t * core = ( const core_info _t * ) core_info _list _get _by _id ( weakSelf . core . UTF8String ) ;
if ( weakSelf . core )
{
return core ? BOXSTRING ( core -> display_name ) : BOXSTRING ( weakSelf . core . UTF8String ) ;
}
else
return BOXSTRING ( "Auto Detect" ) ;
} ] ,
[ RAMenuItemBasic itemWithDescription : BOXSTRING ( "Load Content (History)" ) action : ^ { [ weakSelf loadHistory ] ; } ] ,
[ RAMenuItemBasic itemWithDescription : BOXSTRING ( "Load Content" ) action : ^ { [ weakSelf loadGame ] ; } ] ,
[ RAMenuItemBasic itemWithDescription : BOXSTRING ( "Core Options" )
action : ^ { [ weakSelf . navigationController pushViewController : [ RACoreOptionsMenu new ] animated : YES ] ; } ] ,
nil ] ] ;
2014-07-27 04:56:37 +00:00
[ self . sections addObject : [ NSMutableArray arrayWithObjects : BOXSTRING ( "Settings" ) ,
[ RAMenuItemBasic itemWithDescription : BOXSTRING ( "Settings" )
action : ^ {
char config_name [ PATH_MAX ] ;
fill_pathname _base ( config_name , g_settings . libretro , sizeof ( config_name ) ) ;
[ weakSelf . navigationController pushViewController : [ [ RACoreSettingsMenu alloc ] initWithCore : BOXSTRING ( config_name ) ] animated : YES ] ;
} ] ,
[ RAMenuItemBasic itemWithDescription : BOXSTRING ( "Configurations" )
action : ^ { [ weakSelf . navigationController pushViewController : [ RAFrontendSettingsMenu new ] animated : YES ] ; } ] ,
nil ] ] ;
2014-07-21 02:56:04 +00:00
if ( g_extern . main_is _init )
2013-12-17 22:38:43 +00:00
{
2014-07-21 02:56:04 +00:00
[ self . sections addObject : [ NSArray arrayWithObjects : BOXSTRING ( "States" ) ,
2013-12-17 22:38:43 +00:00
[ RAMenuItemStateSelect new ] ,
2014-07-22 00:21:23 +00:00
[ RAMenuItemBasic itemWithDescription : BOXSTRING ( "Save State" ) action : ^ { [ weakSelf performBasicAction : RARCH_CMD _SAVE _STATE ] ; } ] ,
2014-07-27 04:51:00 +00:00
[ RAMenuItemBasic itemWithDescription : BOXSTRING ( "Load State" ) action : ^ { [ weakSelf performBasicAction : RARCH_CMD _LOAD _STATE ] ; } ] ,
nil ] ] ;
[ self . sections addObject : [ NSArray arrayWithObjects : BOXSTRING ( "Actions" ) ,
[ RAMenuItemBasic itemWithDescription : BOXSTRING ( "Restart Content" ) action : ^ { [ weakSelf performBasicAction : RARCH_CMD _RESET ] ; } ] ,
2013-12-17 22:38:43 +00:00
nil ] ] ;
}
2014-07-10 20:02:54 +00:00
if ( g_extern . main_is _init )
2014-04-26 19:58:18 +00:00
self . navigationItem . leftBarButtonItem = [ [ UIBarButtonItem alloc ] initWithTitle : BOXSTRING ( "Resume" ) style : UIBarButtonItemStyleBordered target : [ RetroArch_iOS get ] action : @ selector ( showGameView ) ] ;
2013-12-17 22:38:43 +00:00
else
self . navigationItem . leftBarButtonItem = nil ;
}
2014-07-22 00:21:23 +00:00
- ( void ) performBasicAction : ( unsigned ) action
2013-12-17 22:38:43 +00:00
{
[ [ RetroArch_iOS get ] showGameView ] ;
2014-07-22 00:21:23 +00:00
rarch_main _command ( action ) ;
2013-12-17 22:38:43 +00:00
}
2013-11-22 14:30:02 +00:00
- ( void ) chooseCoreWithPath : ( NSString * ) path
{
2014-07-08 16:23:30 +00:00
RAMenuCoreList * list ;
2013-11-22 14:30:02 +00:00
RAMainMenu * __weak weakSelf = self ;
2014-07-08 16:23:30 +00:00
list = [ [ RAMenuCoreList alloc ] initWithPath : path allowAutoDetect : ! path
2013-11-22 14:30:02 +00:00
action : ^ ( NSString * core )
{
if ( path )
2014-10-16 21:53:58 +00:00
{
2014-10-17 00:49:25 +00:00
strlcpy ( g_settings . libretro , core . UTF8String , sizeof ( g_settings . libretro ) ) ;
strlcpy ( g_extern . fullpath , path . UTF8String , sizeof ( g_extern . fullpath ) ) ;
rarch_main _command ( RARCH_CMD _LOAD _CORE ) ;
rarch_main _command ( RARCH_CMD _LOAD _CONTENT ) ;
2014-10-16 21:53:58 +00:00
}
2013-11-22 14:30:02 +00:00
else
{
weakSelf . core = core ;
[ weakSelf . tableView reloadData ] ;
[ weakSelf . navigationController popViewControllerAnimated : YES ] ;
}
} ] ;
2013-11-29 23:19:31 +00:00
// Don ' t push view controller if it already launched a game
if ( ! list . actionRan )
[ self . navigationController pushViewController : list animated : YES ] ;
2013-11-22 14:30:02 +00:00
}
- ( void ) loadGame
2014-07-08 16:23:30 +00:00
{
RADirectoryList * list ;
2013-12-26 06:43:10 +00:00
RAMainMenu __weak * weakSelf = self ;
2014-07-08 16:23:30 +00:00
list = [ [ RADirectoryList alloc ] initWithPath : [ RetroArch_iOS get ] . documentsDirectory extensions : NULL action :
2013-12-26 06:43:10 +00:00
^ ( RADirectoryList * list , RADirectoryItem * item )
{
if ( item && ! item . isDirectory )
{
if ( weakSelf . core )
2014-10-16 21:53:58 +00:00
{
2014-10-17 00:49:25 +00:00
strlcpy ( g_settings . libretro , weakSelf . core . UTF8String , sizeof ( g_settings . libretro ) ) ;
strlcpy ( g_extern . fullpath , item . path . UTF8String , sizeof ( g_extern . fullpath ) ) ;
rarch_main _command ( RARCH_CMD _LOAD _CORE ) ;
rarch_main _command ( RARCH_CMD _LOAD _CONTENT ) ;
2014-10-16 21:53:58 +00:00
}
2013-12-26 06:43:10 +00:00
else
[ weakSelf chooseCoreWithPath : item . path ] ;
}
} ] ;
[ self . navigationController pushViewController : list animated : YES ] ;
2013-11-22 14:30:02 +00:00
}
- ( void ) loadHistory
{
2014-07-20 19:38:49 +00:00
char history_path [ PATH_MAX ] ;
2014-08-15 17:33:28 +00:00
fill_pathname _join ( history_path , g_defaults . system_dir , "retroarch-content-history.txt" , sizeof ( history_path ) ) ;
2013-11-22 14:30:02 +00:00
[ self . navigationController pushViewController : [ [ RAHistoryMenu alloc ] initWithHistoryPath : history_path ] animated : YES ] ;
}
@ end
2014-07-22 03:01:35 +00:00
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * RAHistoryMenu * /
/ * Menu object that displays and allows * /
/ * launching a file from the content history . * /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2013-11-22 14:30:02 +00:00
@ implementation RAHistoryMenu
2013-12-16 02:27:17 +00:00
- ( void ) dealloc
{
2014-09-21 03:56:14 +00:00
if ( self . history )
content_playlist _free ( self . history ) ;
2013-12-16 02:27:17 +00:00
}
2014-07-20 19:38:49 +00:00
- ( id ) initWithHistoryPath : ( const char * ) historyPath
2013-11-22 14:30:02 +00:00
{
if ( ( self = [ super initWithStyle : UITableViewStylePlain ] ) )
{
2014-09-21 03:56:14 +00:00
self . history = content_playlist _init ( historyPath , 100 ) ;
2013-12-16 02:27:17 +00:00
[ self reloadData ] ;
2014-04-26 19:58:18 +00:00
self . navigationItem . rightBarButtonItem = [ [ UIBarButtonItem alloc ] initWithTitle : BOXSTRING ( "Clear History" )
2013-12-16 02:27:17 +00:00
style : UIBarButtonItemStyleBordered target : self action : @ selector ( clearHistory ) ] ;
2013-11-22 14:30:02 +00:00
}
return self ;
}
2013-12-16 02:27:17 +00:00
- ( void ) clearHistory
{
2014-09-21 03:56:14 +00:00
if ( self . history )
content_playlist _clear ( self . history ) ;
2013-12-16 02:27:17 +00:00
[ self reloadData ] ;
}
- ( void ) willReloadData
2014-07-08 16:23:30 +00:00
{
2014-09-21 01:38:59 +00:00
size_t i ;
2013-12-16 02:27:17 +00:00
RAHistoryMenu * __weak weakSelf = self ;
2014-07-08 16:23:30 +00:00
NSMutableArray * section = [ NSMutableArray arrayWithObject : BOXSTRING ( "" ) ] ;
2013-12-16 02:27:17 +00:00
2014-09-21 03:56:14 +00:00
for ( i = 0 ; self . history && i < content_playlist _size ( self . history ) ; i + + )
2013-12-16 02:27:17 +00:00
{
2014-08-15 15:54:59 +00:00
RAMenuItemBasic * item ;
const char * path = NULL ;
const char * core_path = NULL ;
const char * core_name = NULL ;
content_playlist _get _index ( weakSelf . history , i , & path , & core_path , & core_name ) ;
item = [
RAMenuItemBasic itemWithDescription : BOXSTRING ( path_basename ( path ? path : "" ) )
action :
^ {
const char * path = NULL ;
const char * core_path = NULL ;
const char * core_name = NULL ;
content_playlist _get _index ( weakSelf . history , i , & path , & core_path , & core_name ) ;
2014-10-17 00:49:25 +00:00
if ( ! path || ! core_path )
return ;
strlcpy ( g_settings . libretro , core_path , sizeof ( g_settings . libretro ) ) ;
strlcpy ( g_extern . fullpath , path , sizeof ( g_extern . fullpath ) ) ;
rarch_main _command ( RARCH_CMD _LOAD _CORE ) ;
rarch_main _command ( RARCH_CMD _LOAD _CONTENT ) ;
2014-08-15 15:54:59 +00:00
}
detail :
^ {
const char * path = NULL ;
const char * core_path = NULL ;
const char * core_name = NULL ;
content_playlist _get _index ( weakSelf . history , i , & path , & core_path , & core_name ) ;
if ( core_name )
return BOXSTRING ( core_name ) ;
return BOXSTRING ( "" ) ;
}
] ;
[ section addObject : item ] ;
2013-12-16 02:27:17 +00:00
}
self . sections = [ NSMutableArray arrayWithObject : section ] ;
2013-11-22 14:30:02 +00:00
}
@ end
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * RASettingsGroupMenu * /
/ * Menu object that displays and allows * /
/ * editing of the a group of * /
/ * rarch_setting _t structures . * /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
@ implementation RASettingsGroupMenu
2014-07-17 01:52:21 +00:00
- ( id ) initWithGroup : ( rarch_setting _t * ) group
2013-11-22 14:30:02 +00:00
{
if ( ( self = [ super initWithStyle : UITableViewStyleGrouped ] ) )
{
2014-07-17 01:52:21 +00:00
rarch_setting _t * i ;
2013-11-22 14:30:02 +00:00
NSMutableArray * settings = nil ;
2014-07-08 16:23:30 +00:00
self . title = BOXSTRING ( group -> name ) ;
for ( i = group + 1 ; i -> type < ST_END _GROUP ; i + + )
2013-11-22 14:30:02 +00:00
{
if ( i -> type = = ST_SUB _GROUP )
2013-12-12 19:49:18 +00:00
settings = [ NSMutableArray arrayWithObjects : BOXSTRING ( i -> name ) , nil ] ;
2013-11-22 14:30:02 +00:00
else if ( i -> type = = ST_END _SUB _GROUP )
{
if ( settings . count )
[ self . sections addObject : settings ] ;
}
2013-11-30 02:34:12 +00:00
else
2013-11-22 14:30:02 +00:00
[ settings addObject : [ RAMenuItemGeneralSetting itemForSetting : i ] ] ;
}
}
return self ;
}
@ end
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * RACoreSettingsMenu * /
/ * Menu object that displays and allows * /
/ * editing of the setting_data list . * /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
@ interface RACoreSettingsMenu ( )
2013-12-26 20:21:41 +00:00
@ property ( nonatomic , copy ) NSString * pathToSave ; // < Leave nil to not save
@ property ( nonatomic , assign ) bool isCustom ;
2013-11-22 14:30:02 +00:00
@ end
@ implementation RACoreSettingsMenu
- ( id ) initWithCore : ( NSString * ) core
{
char buffer [ PATH_MAX ] ;
RACoreSettingsMenu * __weak weakSelf = self ;
if ( ( self = [ super initWithStyle : UITableViewStyleGrouped ] ) )
{
2014-07-08 16:23:30 +00:00
int i , j ;
2014-07-16 19:37:42 +00:00
rarch_setting _t * setting_data , * setting ;
2014-07-08 16:23:30 +00:00
NSMutableArray * settings ;
2014-08-18 11:01:31 +00:00
_isCustom = core_info _get _custom _config ( core . UTF8String , buffer , sizeof ( buffer ) ) ;
2013-12-26 20:21:41 +00:00
if ( _isCustom )
{
2014-07-20 20:20:32 +00:00
const core_info _t * tmp = ( const core_info _t * ) core_info _list _get _by _id ( core . UTF8String ) ;
self . title = tmp ? BOXSTRING ( tmp -> display_name ) : BOXSTRING ( core . UTF8String ) ;
2014-08-17 15:35:17 +00:00
_pathToSave = BOXSTRING ( buffer ) ;
2013-12-26 20:21:41 +00:00
self . navigationItem . rightBarButtonItem = [ [ UIBarButtonItem alloc ] initWithBarButtonSystemItem : UIBarButtonSystemItemTrash target : self action : @ selector ( deleteCustom ) ] ;
}
2013-11-22 14:30:02 +00:00
else
2013-12-26 20:21:41 +00:00
{
2014-04-19 18:16:29 +00:00
self . title = BOXSTRING ( "Global Core Config" ) ;
2014-07-19 20:17:42 +00:00
_pathToSave = BOXSTRING ( g_defaults . config_path ) ;
2013-12-26 20:21:41 +00:00
}
2013-11-22 14:30:02 +00:00
2014-10-14 19:47:57 +00:00
// If we initialized with a nil core ( like when starting up ) driver . menu will be NULL
if ( ! driver . menu )
return NULL ;
2014-10-09 02:04:11 +00:00
setting_data = ( rarch_setting _t * ) driver . menu -> list_settings ;
2014-10-09 03:20:13 +00:00
if ( ! setting_data )
return NULL ;
2014-04-19 18:16:29 +00:00
setting_data _load _config _path ( setting_data , _pathToSave . UTF8String ) ;
2013-11-22 14:30:02 +00:00
// HACK : Load the key mapping table
apple_input _find _any _key ( ) ;
self . core = core ;
2013-12-25 14:48:55 +00:00
// Add common options
2014-07-12 14:03:24 +00:00
const char * emula [ ] = { "General Options" , "rewind_enable" , "fps_show" , 0 } ;
const char * video [ ] = { "Video Options" , "video_scale_integer" , "video_smooth" , 0 } ;
2014-07-26 15:43:01 +00:00
const char * audio [ ] = { "Audio Options" , "audio_enable" , "audio_mute" , "audio_rate_control_delta" , 0 } ;
2014-07-25 16:57:07 +00:00
const char * input [ ] = { "Input Options" , "input_overlay" , "input_overlay_opacity" , 0 } ;
2013-12-25 14:48:55 +00:00
const char * * groups [ ] = { emula , video , audio , input , 0 } ;
2014-07-08 16:23:30 +00:00
for ( i = 0 ; groups [ i ] ; i + + )
2013-12-25 14:48:55 +00:00
{
NSMutableArray * section = [ NSMutableArray arrayWithObject : BOXSTRING ( groups [ i ] [ 0 ] ) ] ;
[ self . sections addObject : section ] ;
2014-07-08 16:23:30 +00:00
for ( j = 1 ; groups [ i ] [ j ] ; j + + )
2014-07-17 02:19:35 +00:00
{
rarch_setting _t * current = ( rarch_setting _t * ) setting_data _find _setting ( setting_data , groups [ i ] [ j ] ) ;
if ( current )
[ section addObject : [ RAMenuItemGeneralSetting itemForSetting : current ] ] ;
}
2013-12-25 14:48:55 +00:00
}
2014-07-08 16:23:30 +00:00
settings = [ NSMutableArray arrayWithObjects : BOXSTRING ( "" ) , nil ] ;
2013-11-22 14:30:02 +00:00
[ self . sections addObject : settings ] ;
2014-07-08 16:56:12 +00:00
for ( setting = & setting_data [ 0 ] ; setting -> type < ST_NONE ; setting + + )
2014-07-08 16:23:30 +00:00
if ( setting -> type = = ST_GROUP )
[ settings addObject : [ RAMenuItemBasic itemWithDescription : BOXSTRING ( setting -> name ) action :
2013-11-22 14:30:02 +00:00
^ {
2014-07-08 16:23:30 +00:00
[ weakSelf . navigationController pushViewController : [ [ RASettingsGroupMenu alloc ] initWithGroup : setting ] animated : YES ] ;
2013-11-22 14:30:02 +00:00
} ] ] ;
}
return self ;
}
- ( void ) dealloc
{
if ( self . pathToSave )
{
2014-04-19 18:16:29 +00:00
config_file _t * config = ( config_file _t * ) config_file _new ( self . pathToSave . UTF8String ) ;
2014-07-08 16:23:30 +00:00
2014-10-08 00:50:54 +00:00
if ( ! config )
return ;
2014-10-09 02:04:11 +00:00
setting_data _save _config ( driver . menu -> list_settings , config ) ;
2014-10-08 00:50:54 +00:00
config_file _write ( config , self . pathToSave . UTF8String ) ;
config_file _free ( config ) ;
2013-11-22 14:30:02 +00:00
}
}
2013-12-26 20:21:41 +00:00
- ( void ) deleteCustom
{
if ( self . isCustom && self . pathToSave )
{
2014-07-21 07:04:45 +00:00
remove ( self . pathToSave . UTF8String ) ;
self . pathToSave = false ;
[ self . navigationController popViewControllerAnimated : YES ] ;
2013-12-26 20:21:41 +00:00
}
}
2013-11-22 14:30:02 +00:00
@ end
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * RAFrontendSettingsMenu * /
/ * Menu object that displays and allows * /
/ * editing of cocoa frontend related * /
/ * settings . * /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2013-12-26 22:36:00 +00:00
@ interface RAFrontendSettingsMenu ( )
@ property ( nonatomic , retain ) NSMutableArray * coreConfigOptions ;
@ end
2013-11-22 14:30:02 +00:00
@ implementation RAFrontendSettingsMenu
- ( id ) init
{
2014-07-17 01:52:21 +00:00
rarch_setting _t * frontend_setting _data = ( rarch_setting _t * ) apple_get _frontend _settings ( ) ;
2013-11-22 14:30:02 +00:00
if ( ( self = [ super initWithGroup : frontend_setting _data ] ) )
2014-07-19 00:59:03 +00:00
{
2014-07-27 04:51:00 +00:00
self . title = BOXSTRING ( "Settings" ) ;
2013-11-22 14:30:02 +00:00
2013-12-26 22:36:00 +00:00
_coreConfigOptions = [ NSMutableArray array ] ;
[ self . sections addObject : _coreConfigOptions ] ;
2013-11-22 14:30:02 +00:00
}
return self ;
}
- ( void ) dealloc
{
2013-12-26 22:36:00 +00:00
}
- ( void ) willReloadData
{
2014-09-21 01:38:59 +00:00
size_t i ;
2014-07-08 16:23:30 +00:00
const core_info _list _t * core_list ;
2013-12-26 22:36:00 +00:00
RAFrontendSettingsMenu * __weak weakSelf = self ;
2014-04-19 18:16:29 +00:00
NSMutableArray * cores = ( NSMutableArray * ) self . coreConfigOptions ;
2013-12-26 22:36:00 +00:00
[ cores removeAllObjects ] ;
2014-04-26 19:58:18 +00:00
[ cores addObject : BOXSTRING ( "Configurations" ) ] ;
[ cores addObject : [ RAMenuItemBasic itemWithDescription : BOXSTRING ( "Global Core Config" )
2013-12-26 22:36:00 +00:00
action : ^ { [ weakSelf showCoreConfigFor : nil ] ; } ] ] ;
2014-04-26 19:58:18 +00:00
[ cores addObject : [ RAMenuItemBasic itemWithDescription : BOXSTRING ( "New Config for Core" )
2013-12-26 22:36:00 +00:00
action : ^ { [ weakSelf createNewConfig ] ; } ] ] ;
2014-07-08 16:23:30 +00:00
2014-07-08 16:29:28 +00:00
if ( ! ( core_list = ( const core_info _list _t * ) core_info _list _get ( ) ) )
2014-07-08 16:23:30 +00:00
return ;
for ( i = 0 ; i < core_list -> count ; i + + )
2013-12-26 22:36:00 +00:00
{
2014-08-17 15:46:00 +00:00
char path [ PATH_MAX ] ;
2014-07-21 00:46:01 +00:00
NSString * core_id = BOXSTRING ( core_list -> list [ i ] . path ) ;
2014-07-08 16:23:30 +00:00
2014-08-18 11:01:31 +00:00
if ( core_info _get _custom _config ( core_id . UTF8String , path , sizeof ( path ) ) )
2013-12-26 22:36:00 +00:00
{
[ cores addObject : [ RAMenuItemBasic itemWithDescription : BOXSTRING ( core_list -> list [ i ] . display_name )
association : core_id
action : ^ ( id userdata ) { [ weakSelf showCoreConfigFor : userdata ] ; }
2014-04-26 19:58:18 +00:00
detail : ^ ( id userdata ) { return BOXSTRING ( "" ) ; } ] ] ;
2013-12-26 22:36:00 +00:00
}
}
2013-11-22 14:30:02 +00:00
}
2013-12-26 20:21:41 +00:00
- ( void ) viewWillAppear : ( BOOL ) animated
{
2013-12-26 22:36:00 +00:00
[ super viewWillAppear : animated ] ;
2013-12-26 20:21:41 +00:00
[ self reloadData ] ;
}
2013-11-22 14:30:02 +00:00
- ( void ) showCoreConfigFor : ( NSString * ) core
{
2013-12-26 22:36:00 +00:00
[ self . navigationController pushViewController : [ [ RACoreSettingsMenu alloc ] initWithCore : core ] animated : YES ] ;
2013-11-22 14:30:02 +00:00
}
2014-07-19 20:51:03 +00:00
static bool copy_config ( const char * src_path , const char * dst_path )
{
char ch ;
FILE * dst ;
FILE * src = fopen ( src_path , "r" ) ;
if ( ! src )
return false ;
dst = fopen ( dst_path , "w" ) ;
if ( ! dst )
{
fclose ( src ) ;
return false ;
}
while ( ( ch = fgetc ( src ) ) ! = EOF )
fputc ( ch , dst ) ;
fclose ( src ) ;
fclose ( dst ) ;
return true ;
}
2013-12-26 22:36:00 +00:00
- ( void ) createNewConfig
2013-11-22 14:30:02 +00:00
{
2013-12-26 22:36:00 +00:00
RAFrontendSettingsMenu * __weak weakSelf = self ;
2013-12-29 20:36:40 +00:00
RAMenuCoreList * list = [ [ RAMenuCoreList alloc ] initWithPath : nil allowAutoDetect : false
action : ^ ( NSString * core )
2013-12-26 22:36:00 +00:00
{
2014-08-17 15:42:45 +00:00
char path [ PATH_MAX ] ;
2014-08-18 11:01:31 +00:00
if ( ! core_info _get _custom _config ( core . UTF8String , path , sizeof ( path ) ) )
2013-12-29 20:36:40 +00:00
{
2014-07-19 20:51:03 +00:00
if ( g_defaults . config_path [ 0 ] ! = ' \ 0 ' && path [ 0 ] ! = ' \ 0 ' )
{
if ( ! copy_config ( g_defaults . config_path , path ) )
RARCH_WARN ( "Could not create custom config at %s." , path ) ;
}
2013-12-29 20:36:40 +00:00
}
2013-12-26 22:36:00 +00:00
[ weakSelf . navigationController popViewControllerAnimated : YES ] ;
} ] ;
[ self . navigationController pushViewController : list animated : YES ] ;
2013-11-22 14:30:02 +00:00
}
@ end
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * RACoreOptionsMenu * /
/ * Menu object that allows editing of * /
/ * options specific to the running core . * /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
2013-12-26 21:00:29 +00:00
@ interface RACoreOptionsMenu ( )
2013-11-22 14:30:02 +00:00
@ property ( nonatomic ) uint32_t currentIndex ;
@ end
@ implementation RACoreOptionsMenu
- ( id ) init
{
if ( ( self = [ super initWithStyle : UITableViewStyleGrouped ] ) )
{
RACoreOptionsMenu * __weak weakSelf = self ;
2014-04-19 18:16:29 +00:00
core_option _manager _t * options = ( core_option _manager _t * ) g_extern . system . core_options ;
2013-11-22 14:30:02 +00:00
2014-04-26 19:58:18 +00:00
NSMutableArray * section = ( NSMutableArray * ) [ NSMutableArray arrayWithObject : BOXSTRING ( "" ) ] ;
2013-11-22 14:30:02 +00:00
[ self . sections addObject : section ] ;
if ( options )
{
2014-04-26 19:58:18 +00:00
unsigned i ;
for ( i = 0 ; i < core_option _size ( options ) ; i + + )
2013-12-12 19:49:18 +00:00
[ section addObject : [ RAMenuItemBasic itemWithDescription : BOXSTRING ( core_option _get _desc ( options , i ) ) association : nil
2013-11-22 14:30:02 +00:00
action : ^ { [ weakSelf editValue : i ] ; }
2013-12-12 19:49:18 +00:00
detail : ^ { return BOXSTRING ( core_option _get _val ( options , i ) ) ; } ] ] ;
2013-11-22 14:30:02 +00:00
}
else
2014-04-26 19:58:18 +00:00
[ section addObject : [ RAMenuItemBasic itemWithDescription : BOXSTRING ( "The running core has no options." ) action : NULL ] ] ;
2013-11-22 14:30:02 +00:00
}
return self ;
}
- ( void ) editValue : ( uint32_t ) index
{
2013-12-26 21:00:29 +00:00
RACoreOptionsMenu __weak * weakSelf = self ;
2013-11-22 14:30:02 +00:00
self . currentIndex = index ;
2013-12-26 21:00:29 +00:00
RunActionSheet ( core_option _get _desc ( g_extern . system . core_options , index ) , core_option _get _vals ( g_extern . system . core_options , index ) , self . tableView ,
^ ( UIActionSheet * actionSheet , NSInteger buttonIndex )
{
if ( buttonIndex ! = actionSheet . cancelButtonIndex )
core_option _set _val ( g_extern . system . core_options , self . currentIndex , buttonIndex ) ;
[ weakSelf . tableView reloadData ] ;
} ) ;
2013-11-22 14:30:02 +00:00
}
@ end
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * RAMenuItemCoreList * /
/ * Menu item that handles display and * /
/ * selection of an item in RAMenuCoreList . * /
/ * This item will not function on anything * /
/ * but an RAMenuCoreList type menu . * /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
@ implementation RAMenuItemCoreList
- ( id ) initWithCore : ( NSString * ) core parent : ( RAMenuCoreList * __weak ) parent
{
if ( ( self = [ super init ] ) )
{
_core = core ;
_parent = parent ;
}
return self ;
}
- ( UITableViewCell * ) cellForTableView : ( UITableView * ) tableView
{
2014-07-08 16:29:28 +00:00
UITableViewCell * result ;
2014-07-20 20:20:32 +00:00
const core_info _t * core = ( const core_info _t * ) core_info _list _get _by _id ( self . core . UTF8String ) ;
2013-11-22 14:30:02 +00:00
static NSString * const cell_id = @ "RAMenuItemCoreList" ;
2014-07-08 16:29:28 +00:00
if ( ! ( result = [ tableView dequeueReusableCellWithIdentifier : cell_id ] ) )
2013-11-22 14:30:02 +00:00
result = [ [ UITableViewCell alloc ] initWithStyle : UITableViewCellStyleValue1 reuseIdentifier : cell_id ] ;
2014-07-20 20:20:32 +00:00
result . textLabel . text = core ? BOXSTRING ( core -> display_name ) : BOXSTRING ( self . core . UTF8String ) ;
2013-11-22 14:30:02 +00:00
return result ;
}
- ( void ) wasSelectedOnTableView : ( UITableView * ) tableView ofController : ( UIViewController * ) controller
{
2013-11-29 23:19:31 +00:00
[ self . parent runAction : self . core ] ;
2013-11-22 14:30:02 +00:00
}
@ end
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * RAMenuCoreList * /
/ * Menu object that displays and allows * /
/ * selection from a list of cores . * /
/ * If the path is not nil , only cores that * /
/ * may support the file is listed . * /
/ * If the path is nil , an ' Auto Detect ' * /
/ * entry is added to the menu , when tapped * /
/ * the action function will be called with * /
/ * nil as the argument . * /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
@ implementation RAMenuCoreList
2013-12-29 20:36:40 +00:00
- ( id ) initWithPath : ( NSString * ) path allowAutoDetect : ( bool ) autoDetect action : ( void ( ^ ) ( NSString * ) ) action
2013-11-22 14:30:02 +00:00
{
if ( ( self = [ super initWithStyle : UITableViewStyleGrouped ] ) )
{
2014-07-08 16:23:30 +00:00
NSMutableArray * core_section ;
core_info _list _t * core_list = NULL ;
2014-04-19 18:16:29 +00:00
self . title = BOXSTRING ( "Choose Core" ) ;
2013-11-22 14:30:02 +00:00
_action = action ;
_path = path ;
2013-12-29 20:36:40 +00:00
if ( autoDetect )
2013-11-22 14:30:02 +00:00
{
RAMenuCoreList * __weak weakSelf = self ;
2014-04-26 19:48:42 +00:00
[ self . sections addObject : @ [ BOXSTRING ( "" ) , [ RAMenuItemBasic itemWithDescription : BOXSTRING ( "Auto Detect" )
2013-11-22 14:30:02 +00:00
action : ^ { if ( weakSelf . action ) weakSelf . action ( nil ) ; } ] ] ] ;
}
2014-07-08 16:23:30 +00:00
core_section = ( NSMutableArray * ) [ NSMutableArray arrayWithObject : BOXSTRING ( "Cores" ) ] ;
2013-11-22 14:30:02 +00:00
[ self . sections addObject : core_section ] ;
2014-07-08 16:29:28 +00:00
if ( ( core_list = ( core_info _list _t * ) core_info _list _get ( ) ) )
2013-11-22 14:30:02 +00:00
{
2013-12-17 21:57:15 +00:00
if ( _path )
2013-11-22 14:30:02 +00:00
{
2014-07-08 16:23:30 +00:00
const core_info _t * core_support = NULL ;
2013-11-22 14:30:02 +00:00
size_t core_count = 0 ;
2014-07-08 16:23:30 +00:00
2014-04-26 19:58:18 +00:00
core_info _list _get _supported _cores ( core_list , _path . UTF8String , & core_support , & core_count ) ;
2013-11-22 14:30:02 +00:00
if ( core_count = = 1 && _action )
2014-07-21 00:46:01 +00:00
[ self runAction : BOXSTRING ( core_support [ 0 ] . path ) ] ;
2013-11-22 14:30:02 +00:00
else if ( core_count > 1 )
2014-04-19 18:16:29 +00:00
[ self load : ( uint32_t ) core_count coresFromList : core_support toSection : core_section ] ;
2013-11-22 14:30:02 +00:00
}
2013-12-17 21:57:15 +00:00
if ( ! _path || [ core_section count ] = = 1 )
2014-04-19 18:16:29 +00:00
[ self load : ( uint32_t ) core_list -> count coresFromList : core_list -> list toSection : core_section ] ;
2013-11-22 14:30:02 +00:00
}
}
return self ;
}
2013-11-29 23:19:31 +00:00
- ( void ) runAction : ( NSString * ) coreID
{
self . actionRan = true ;
if ( self . action )
2014-09-21 03:56:14 +00:00
self . action ( coreID ) ;
2013-11-29 23:19:31 +00:00
}
2013-11-22 14:30:02 +00:00
- ( void ) load : ( uint32_t ) count coresFromList : ( const core_info _t * ) list toSection : ( NSMutableArray * ) array
{
2014-07-08 16:23:30 +00:00
int i ;
2014-07-08 16:29:28 +00:00
2014-07-08 16:23:30 +00:00
for ( i = 0 ; i < count ; i + + )
2014-07-21 00:46:01 +00:00
[ array addObject : [ [ RAMenuItemCoreList alloc ] initWithCore : BOXSTRING ( list [ i ] . path ) parent : self ] ] ;
2013-11-22 14:30:02 +00:00
}
@ end
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
/ * RAMenuItemStateSelect * /
/ * Menu item that allows save state slots * /
/ * 0 -9 to be selected . * /
/ * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * /
@ implementation RAMenuItemStateSelect
- ( UITableViewCell * ) cellForTableView : ( UITableView * ) tableView
{
static NSString * const cell_id = @ "state_slot_setting" ;
UITableViewCell * result = [ tableView dequeueReusableCellWithIdentifier : cell_id ] ;
if ( ! result )
{
result = [ [ UITableViewCell alloc ] initWithStyle : UITableViewCellStyleValue1 reuseIdentifier : cell_id ] ;
result . selectionStyle = UITableViewCellSelectionStyleNone ;
2014-07-08 16:29:28 +00:00
result . textLabel . text = BOXSTRING ( "Slot" ) ;
2013-11-22 14:30:02 +00:00
UISegmentedControl * accessory = [ [ UISegmentedControl alloc ] initWithItems : @ [ @ "0" , @ "1" , @ "2" , @ "3" , @ "4" , @ "5" , @ "6" , @ "7" , @ "8" , @ "9" ] ] ;
2014-01-14 19:31:44 +00:00
[ accessory addTarget : [ self class ] action : @ selector ( changed : ) forControlEvents : UIControlEventValueChanged ] ;
2013-11-22 14:30:02 +00:00
accessory . segmentedControlStyle = UISegmentedControlStyleBar ;
result . accessoryView = accessory ;
}
2014-08-01 23:20:39 +00:00
[ ( id ) result . accessoryView setSelectedSegmentIndex : ( g_settings . state_slot < 10 ) ? g_settings . state_slot : -1 ] ;
2013-11-22 14:30:02 +00:00
return result ;
}
2014-01-14 19:31:44 +00:00
+ ( void ) changed : ( UISegmentedControl * ) sender
2013-11-22 14:30:02 +00:00
{
2014-08-01 23:20:39 +00:00
g_settings . state_slot = ( int ) sender . selectedSegmentIndex ;
2013-11-22 14:30:02 +00:00
}
- ( void ) wasSelectedOnTableView : ( UITableView * ) tableView ofController : ( UIViewController * ) controller
{
}
@ end