2009-06-09 13:34:52 +02:00
# import < Cocoa / Cocoa . h >
2011-06-08 11:27:25 +02:00
# import "PcsxrController.h"
2009-06-09 13:34:52 +02:00
# import "ConfigurationController.h"
2017-06-30 16:45:32 +02:00
# import "PgxpController.h"
2013-03-03 01:39:53 +01:00
# import "CheatController.h"
2009-06-09 13:34:52 +02:00
# import "EmuThread.h"
2011-12-11 05:11:51 +01:00
# import "PcsxrMemCardHandler.h"
# import "PcsxrPluginHandler.h"
2011-12-12 04:32:21 +01:00
# import "PcsxrDiscHandler.h"
# import "PcsxrFreezeStateHandler.h"
2013-08-01 18:50:36 +02:00
# import "PcsxrCheatHandler.h"
2013-07-09 01:46:22 +02:00
# import "LaunchArg.h"
2013-09-16 22:31:07 +02:00
# include < DiskArbitration / DiskArbitration . h >
# include < IOKit / storage / IOCDMedia . h >
2009-06-09 13:34:52 +02:00
# include "psxcommon.h"
# include "plugins.h"
# include "misc.h"
2013-06-20 22:42:46 +02:00
# include "cdrom.h"
2009-06-09 13:34:52 +02:00
# include "ExtendedKeys.h"
2013-12-30 21:15:56 +01:00
NSDictionary * prefStringKeys = nil ;
NSDictionary * prefByteKeys = nil ;
NSDictionary * prefURLKeys = nil ;
NSMutableArray * biosList = nil ;
NSString * saveStatePath = nil ;
BOOL wasFinderLaunch = NO ;
2013-06-22 08:11:06 +02:00
2014-10-01 21:49:24 +02:00
# define HELPSTR \
2013-12-30 21:15:56 +01:00
"At least one of these must be passed:\n" \
2014-10-01 21:49:24 +02:00
"\t-cdfile path launch with selected ISO\n" \
"\t-runcd launch with a CD-ROM\n" \
"\t-bios launch into the BIOS\n" \
2013-12-30 21:15:56 +01:00
"\n" \
2013-06-22 08:11:06 +02:00
"Additional options:\n" \
2014-10-01 21:49:24 +02:00
"\t-nogui closes PCSX-R at when the emulation has ended\n" \
"\t-mcd1 path sets the fist memory card to path\n" \
"\t-mcd2 path sets the second memory card to path\n" \
"\t-freeze path loads freeze state from path\n" \
"\t-psxout Enable logging\n" \
"\t-slowboot Show PSX splash screen\n" \
2013-12-30 21:15:56 +01:00
"\n" \
2013-06-22 08:11:06 +02:00
"Help:\n" \
2014-10-01 21:49:24 +02:00
"\t-help shows this message\n" \
2013-12-30 21:15:56 +01:00
"\n" \
2013-06-22 08:11:06 +02:00
void ShowHelpAndExit ( FILE * output , int exitCode )
{
fprintf ( output , HELPSTR ) ;
2013-07-10 02:04:59 +02:00
if ( ! NSApp ) {
exit ( exitCode ) ;
} else {
[ NSApp stop : nil ] ;
}
2013-06-22 08:11:06 +02:00
}
@ interface PcsxrController ( )
@ property ( readwrite ) BOOL endAtEmuClose ;
2013-07-10 02:04:59 +02:00
@ property BOOL sleepInBackground ;
@ property BOOL wasPausedBeforeBGSwitch ;
2013-10-05 00:06:37 +02:00
@ property BOOL wasPausedBeforeDiscEject ;
2013-09-10 20:18:15 +02:00
@ property ( strong ) NSMutableArray * skipFiles ;
2013-09-13 23:31:56 +02:00
@ property ( strong ) NSWindow * preferenceWindow ;
@ property ( strong ) NSWindow * cheatWindow ;
2013-09-16 22:31:07 +02:00
@ property ( nonatomic ) DASessionRef diskSession ;
2014-11-10 20:46:07 +01:00
@ property ( strong , readwrite ) CheatController * cheatController ;
2013-06-22 08:11:06 +02:00
@ end
2009-06-09 13:34:52 +02:00
2011-06-08 11:27:25 +02:00
@ implementation PcsxrController
2014-11-10 20:46:07 +01:00
{
ConfigurationController * preferencesController ;
PluginList * pluginList ;
struct _PSXflags {
unsigned int sleepInBackground : 1 ;
unsigned int wasPausedBeforeBGSwitch : 1 ;
unsigned int endAtEmuClose : 1 ;
unsigned int wasPausedBeforeDiscEject : 1 ;
unsigned int reserved : 28 ;
} PSXflags ;
}
2013-01-09 02:50:38 +01:00
@ synthesize recentItems ;
2013-06-22 23:25:16 +02:00
@ synthesize skipFiles ;
2013-08-01 18:50:36 +02:00
@ synthesize cheatController ;
2013-09-13 23:31:56 +02:00
@ synthesize cheatWindow ;
@ synthesize preferenceWindow ;
2013-06-22 23:25:16 +02:00
2013-06-22 21:55:35 +02:00
- ( BOOL ) endAtEmuClose
{
return PSXflags . endAtEmuClose ;
}
- ( void ) setEndAtEmuClose : ( BOOL ) endAtEmuClose
{
PSXflags . endAtEmuClose = endAtEmuClose ;
}
- ( BOOL ) sleepInBackground
{
return PSXflags . sleepInBackground ;
}
- ( void ) setSleepInBackground : ( BOOL ) sleepInBackground
{
PSXflags . sleepInBackground = sleepInBackground ;
}
- ( BOOL ) wasPausedBeforeBGSwitch
{
return PSXflags . wasPausedBeforeBGSwitch ;
}
- ( void ) setWasPausedBeforeBGSwitch : ( BOOL ) wasPausedBeforeBGSwitch
{
PSXflags . wasPausedBeforeBGSwitch = wasPausedBeforeBGSwitch ;
}
2013-01-09 02:50:38 +01:00
2013-10-05 00:06:37 +02:00
- ( BOOL ) wasPausedBeforeDiscEject
{
return PSXflags . wasPausedBeforeDiscEject ;
}
- ( void ) setWasPausedBeforeDiscEject : ( BOOL ) wasPausedBeforeDiscEject
{
PSXflags . wasPausedBeforeDiscEject = wasPausedBeforeDiscEject ;
}
2013-09-16 22:31:07 +02:00
@ synthesize diskSession = _diskSession ;
- ( void ) setDiskSession : ( DASessionRef ) diskSession
2009-06-09 13:34:52 +02:00
{
2013-09-16 22:31:07 +02:00
if ( diskSession = = _diskSession ) {
return ;
}
if ( _diskSession ) {
CFRelease ( _diskSession ) ;
2013-10-05 00:06:37 +02:00
_diskSession = NULL ;
2013-09-16 22:31:07 +02:00
} if ( diskSession ) {
_diskSession = diskSession ;
CFRetain ( diskSession ) ;
}
}
2009-11-02 13:23:10 +01:00
2013-09-16 22:31:07 +02:00
static void PSXDiscAppearedCallback ( DADiskRef disk , void * context )
{
PcsxrController * theSelf = ( __bridge PcsxrController * ) context ;
2013-09-22 06:16:10 +02:00
// sleep ( 3 ) ; // Is this needed ?
2013-09-16 22:31:07 +02:00
SetCdOpenCaseTime ( time ( NULL ) + 2 ) ;
LidInterrupt ( ) ;
/ * and open new cd * /
if ( [ EmuThread active ] )
CDR_open ( ) ;
2013-10-05 04:51:42 +02:00
if ( ! theSelf . wasPausedBeforeDiscEject ) {
2013-09-16 22:31:07 +02:00
[ EmuThread resume ] ;
}
DASessionUnscheduleFromRunLoop ( theSelf . diskSession , CFRunLoopGetMain ( ) , kCFRunLoopCommonModes ) ;
theSelf . diskSession = NULL ;
}
- ( IBAction ) ejectCD : ( id ) sender
{
2013-10-05 00:06:37 +02:00
self . wasPausedBeforeDiscEject = [ EmuThread pauseSafe ] ;
2009-06-09 13:34:52 +02:00
/ * close connection to current cd * /
if ( [ EmuThread active ] )
CDR_close ( ) ;
2013-10-05 00:06:37 +02:00
2009-06-11 11:22:11 +02:00
// switch to another ISO if using internal image reader , otherwise eject the CD
2010-05-12 08:12:04 +02:00
if ( UsingIso ( ) ) {
2013-09-10 20:18:15 +02:00
NSOpenPanel * openDlg = [ NSOpenPanel openPanel ] ;
2011-12-19 00:51:13 +01:00
[ openDlg setAllowedFileTypes : [ PcsxrDiscHandler supportedUTIs ] ] ;
2013-10-05 00:06:37 +02:00
2011-11-09 21:49:54 +01:00
if ( [ openDlg runModal ] = = NSFileHandlingPanelOKButton ) {
2011-12-03 02:32:30 +01:00
NSArray * files = [ openDlg URLs ] ;
2013-09-10 20:43:18 +02:00
SetIsoFile ( [ [ files [ 0 ] path ] fileSystemRepresentation ] ) ;
2013-06-20 22:42:46 +02:00
SetCdOpenCaseTime ( time ( NULL ) + 2 ) ;
LidInterrupt ( ) ;
2009-06-11 11:22:11 +02:00
}
2013-09-16 22:31:07 +02:00
if ( [ EmuThread active ] )
CDR_open ( ) ;
2013-10-05 04:51:42 +02:00
if ( ! self . wasPausedBeforeDiscEject ) {
2013-09-16 22:31:07 +02:00
[ EmuThread resume ] ;
}
2009-06-11 11:22:11 +02:00
} else {
2013-09-16 22:31:07 +02:00
NSMutableString * deviceName ;
NSTask * ejectTask ;
NSRange rdiskRange ;
char * driveLetter = CDR_getDriveLetter ( ) ;
2011-11-09 21:49:54 +01:00
2013-09-16 22:31:07 +02:00
if ( driveLetter ! = NULL ) {
2011-11-09 21:49:54 +01:00
deviceName = [ NSMutableString stringWithString : [ [ NSFileManager defaultManager ] stringWithFileSystemRepresentation : driveLetter length : strlen ( driveLetter ) ] ] ;
2013-10-05 00:06:37 +02:00
2009-06-11 11:22:11 +02:00
// delete the ' r ' in ' rdisk '
rdiskRange = [ deviceName rangeOfString : @ "rdisk" ] ;
if ( rdiskRange . length ! = 0 ) {
rdiskRange . length = 1 ;
[ deviceName deleteCharactersInRange : rdiskRange ] ;
}
// execute hdiutil to eject the device
2013-07-08 03:10:00 +02:00
ejectTask = [ NSTask launchedTaskWithLaunchPath : @ "/usr/bin/hdiutil" arguments : @ [ @ "eject" , deviceName ] ] ;
2009-06-11 11:22:11 +02:00
[ ejectTask waitUntilExit ] ;
2009-06-09 13:34:52 +02:00
}
2013-09-16 22:31:07 +02:00
DASessionRef tmpSession = DASessionCreate ( kCFAllocatorDefault ) ;
CFDictionaryRef match = CFBridgingRetain ( @ { ( NSString * ) kDADiskDescriptionMediaKindKey : @ ( kIOCDMediaClass ) ,
( NSString * ) kDADiskDescriptionMediaWholeKey : @ YES } ) ;
DARegisterDiskAppearedCallback ( tmpSession , match , PSXDiscAppearedCallback , ( __bridge void * ) self ) ;
CFRelease ( match ) ;
DASessionScheduleWithRunLoop ( tmpSession , CFRunLoopGetMain ( ) , kCFRunLoopCommonModes ) ;
self . diskSession = tmpSession ;
CFRelease ( tmpSession ) ;
2009-06-09 13:34:52 +02:00
}
}
2013-09-22 06:16:10 +02:00
- ( void ) emuWindowDidClose : ( NSNotification * ) theNot
{
if ( self . diskSession ) {
DASessionUnscheduleFromRunLoop ( self . diskSession , CFRunLoopGetMain ( ) , kCFRunLoopCommonModes ) ;
self . diskSession = NULL ;
}
}
2009-06-09 13:34:52 +02:00
- ( IBAction ) pause : ( id ) sender
{
if ( [ EmuThread isPaused ] ) {
// [ sender setState : NSOffState ] ;
[ EmuThread resume ] ;
}
else {
// [ sender setState : NSOnState ] ;
[ EmuThread pause ] ;
}
}
2013-03-03 01:39:53 +01:00
- ( IBAction ) showCheatsWindow : ( id ) sender
{
/ * load the nib if it hasn ' t yet * /
if ( cheatWindow = = nil ) {
if ( cheatController = = nil ) {
cheatController = [ [ CheatController alloc ] initWithWindowNibName : @ "CheatWindow" ] ;
}
cheatWindow = [ cheatController window ] ;
}
/ * show the window * /
[ cheatController showWindow : sender ] ;
}
2009-06-09 13:34:52 +02:00
- ( IBAction ) preferences : ( id ) sender
{
/ * load the nib if it hasn ' t yet * /
if ( preferenceWindow = = nil ) {
if ( preferencesController = = nil ) {
preferencesController = [ [ ConfigurationController alloc ] initWithWindowNibName : @ "Configuration" ] ;
}
preferenceWindow = [ preferencesController window ] ;
}
2009-11-02 13:23:10 +01:00
2009-06-09 13:34:52 +02:00
/ * show the window * /
2013-03-03 01:39:53 +01:00
[ preferencesController showWindow : sender ] ;
2009-06-09 13:34:52 +02:00
}
- ( IBAction ) reset : ( id ) sender
{
[ EmuThread reset ] ;
}
- ( IBAction ) runCD : ( id ) sender
{
2010-05-12 08:12:04 +02:00
SetIsoFile ( NULL ) ;
2013-01-10 21:46:32 +01:00
if ( [ [ NSUserDefaults standardUserDefaults ] boolForKey : @ "NetPlay" ] ) {
2013-01-14 23:10:02 +01:00
[ pluginList enableNetPlug ] ;
2013-01-10 21:46:32 +01:00
} else {
2013-01-14 23:10:02 +01:00
[ pluginList disableNetPlug ] ;
2013-01-10 21:46:32 +01:00
}
2009-06-09 13:34:52 +02:00
[ EmuThread run ] ;
}
2009-06-11 11:22:11 +02:00
- ( IBAction ) runIso : ( id ) sender
2009-06-09 13:34:52 +02:00
{
2013-09-10 20:18:15 +02:00
NSOpenPanel * openDlg = [ NSOpenPanel openPanel ] ;
2011-12-19 00:51:13 +01:00
[ openDlg setAllowedFileTypes : [ PcsxrDiscHandler supportedUTIs ] ] ;
2009-06-11 11:22:11 +02:00
2011-11-09 21:49:54 +01:00
if ( [ openDlg runModal ] = = NSFileHandlingPanelOKButton ) {
2013-09-10 20:43:18 +02:00
NSURL * url = [ openDlg URLs ] [ 0 ] ;
2012-12-20 23:42:36 +01:00
[ recentItems addRecentItem : url ] ;
[ self runURL : url ] ;
2009-06-11 11:22:11 +02:00
}
2009-06-09 13:34:52 +02:00
}
2009-11-04 03:46:27 +01:00
- ( IBAction ) runBios : ( id ) sender
2009-06-09 13:34:52 +02:00
{
2010-05-12 08:12:04 +02:00
SetIsoFile ( NULL ) ;
2013-01-14 23:10:02 +01:00
[ pluginList disableNetPlug ] ;
2009-11-04 03:46:27 +01:00
[ EmuThread runBios ] ;
2009-06-09 13:34:52 +02:00
}
2012-12-20 23:42:36 +01:00
- ( void ) runURL : ( NSURL * ) url
{
2013-07-08 09:58:24 +02:00
if ( [ EmuThread active ] = = YES ) {
2013-03-02 19:34:25 +01:00
if ( UsingIso ( ) ) {
SetIsoFile ( [ [ url path ] fileSystemRepresentation ] ) ;
2013-06-20 22:42:46 +02:00
SetCdOpenCaseTime ( time ( NULL ) + 2 ) ;
LidInterrupt ( ) ;
2013-03-02 19:34:25 +01:00
} else {
NSBeep ( ) ;
}
2013-01-09 02:50:38 +01:00
} else {
2013-01-10 21:46:32 +01:00
if ( [ [ NSUserDefaults standardUserDefaults ] boolForKey : @ "NetPlay" ] ) {
2013-01-14 23:10:02 +01:00
[ pluginList enableNetPlug ] ;
2013-01-10 21:46:32 +01:00
} else {
2013-01-14 23:10:02 +01:00
[ pluginList disableNetPlug ] ;
2013-01-10 21:46:32 +01:00
}
2013-06-22 21:55:35 +02:00
SetIsoFile ( [ [ url path ] fileSystemRepresentation ] ) ;
2013-01-09 02:50:38 +01:00
[ EmuThread run ] ;
}
2012-12-20 23:42:36 +01:00
}
2009-06-09 13:34:52 +02:00
- ( IBAction ) freeze : ( id ) sender
{
2012-09-23 21:24:03 +02:00
NSInteger num = [ sender tag ] ;
2013-07-08 09:58:24 +02:00
[ PcsxrController saveState : ( int ) num ] ;
2012-12-15 22:07:55 +01:00
}
2009-06-09 13:34:52 +02:00
2012-12-15 22:07:55 +01:00
+ ( void ) saveState : ( int ) num
{
[ EmuThread freezeAt : [ PcsxrController saveStatePath : num ] which : num ] ;
2009-06-09 13:34:52 +02:00
}
- ( IBAction ) defrost : ( id ) sender
{
2013-07-08 09:58:24 +02:00
NSInteger num = [ sender tag ] ;
[ PcsxrController loadState : ( int ) num ] ;
2012-12-15 22:07:55 +01:00
}
+ ( void ) loadState : ( int ) num
{
[ EmuThread defrostAt : [ PcsxrController saveStatePath : num ] ] ;
2009-06-09 13:34:52 +02:00
}
- ( IBAction ) fullscreen : ( id ) sender
{
GPU_keypressed ( GPU_FULLSCREEN _KEY ) ;
}
2011-11-24 20:03:21 +01:00
- ( IBAction ) pauseInBackground : ( id ) sender
{
2013-06-22 21:55:35 +02:00
self . sleepInBackground = ! self . sleepInBackground ;
[ [ NSUserDefaults standardUserDefaults ] setBool : self . sleepInBackground forKey : @ "PauseInBackground" ] ;
2011-11-24 20:03:21 +01:00
}
2011-11-09 21:49:54 +01:00
- ( BOOL ) validateMenuItem : ( NSMenuItem * ) menuItem
2009-06-09 13:34:52 +02:00
{
if ( [ menuItem action ] = = @ selector ( pause : ) ) {
[ menuItem setState : ( [ EmuThread isPaused ] ? NSOnState : NSOffState ) ] ;
}
2009-11-04 10:20:55 +01:00
if ( [ menuItem action ] = = @ selector ( pause : ) || [ menuItem action ] = = @ selector ( fullscreen : ) )
2009-06-09 13:34:52 +02:00
return [ EmuThread active ] ;
2009-06-11 11:22:11 +02:00
2009-11-04 10:20:55 +01:00
if ( [ menuItem action ] = = @ selector ( reset : ) || [ menuItem action ] = = @ selector ( ejectCD : ) ||
[ menuItem action ] = = @ selector ( freeze : ) )
2009-11-04 03:54:50 +01:00
return [ EmuThread active ] && ! [ EmuThread isRunBios ] ;
2009-11-04 03:46:27 +01:00
if ( [ menuItem action ] = = @ selector ( runCD : ) || [ menuItem action ] = = @ selector ( runIso : ) ||
[ menuItem action ] = = @ selector ( runBios : ) ) {
if ( preferenceWindow ! = nil )
if ( [ preferenceWindow isVisible ] )
2009-11-02 13:23:10 +01:00
return NO ;
2009-11-04 03:46:27 +01:00
2013-03-03 01:39:53 +01:00
if ( cheatWindow ! = nil )
if ( [ cheatWindow isVisible ] )
return NO ;
2011-11-27 02:35:59 +01:00
2009-11-04 03:46:27 +01:00
if ( [ menuItem action ] = = @ selector ( runBios : ) && strcmp ( Config . Bios , "HLE" ) = = 0 )
return NO ;
2009-11-02 13:23:10 +01:00
return ! [ EmuThread active ] ;
}
2009-06-11 11:22:11 +02:00
2009-06-09 13:34:52 +02:00
if ( [ menuItem action ] = = @ selector ( defrost : ) ) {
2009-11-04 10:20:55 +01:00
if ( ! [ EmuThread active ] || [ EmuThread isRunBios ] )
2009-06-09 13:34:52 +02:00
return NO ;
2009-06-11 11:22:11 +02:00
2012-09-21 05:45:38 +02:00
NSString * path = [ saveStatePath stringByAppendingPathComponent : [ NSString stringWithFormat : @ "%s-%3.3ld.pcsxrstate" , CdromId , ( long ) [ menuItem tag ] ] ] ;
2009-06-11 11:22:11 +02:00
return ( CheckState ( ( char * ) [ path fileSystemRepresentation ] ) = = 0 ) ;
2009-06-09 13:34:52 +02:00
}
2009-11-02 13:23:10 +01:00
2009-11-02 13:24:44 +01:00
if ( [ menuItem action ] = = @ selector ( preferences : ) )
return ! [ EmuThread active ] ;
2009-11-02 13:23:10 +01:00
2011-11-24 20:03:21 +01:00
if ( [ menuItem action ] = = @ selector ( pauseInBackground : ) ) {
2013-06-22 21:55:35 +02:00
[ menuItem setState : ( self . sleepInBackground ? NSOnState : NSOffState ) ] ;
2011-11-24 20:03:21 +01:00
return YES ;
}
2013-03-03 01:39:53 +01:00
2009-06-09 13:34:52 +02:00
return YES ;
}
- ( void ) applicationWillResignActive : ( NSNotification * ) aNotification
{
2013-06-22 21:55:35 +02:00
self . wasPausedBeforeBGSwitch = [ EmuThread isPaused ] ;
2009-06-11 11:22:11 +02:00
2013-06-22 21:55:35 +02:00
if ( self . sleepInBackground ) {
2009-06-09 13:34:52 +02:00
[ EmuThread pause ] ;
}
}
- ( void ) applicationDidBecomeActive : ( NSNotification * ) aNotification
{
2013-06-22 21:55:35 +02:00
if ( self . sleepInBackground && ! self . wasPausedBeforeBGSwitch ) {
2009-06-09 13:34:52 +02:00
[ EmuThread resume ] ;
}
}
2013-06-22 21:55:35 +02:00
- ( void ) applicationDidFinishLaunching : ( NSNotification * ) notification
{
2013-06-22 23:25:16 +02:00
self . skipFiles = nil ;
2014-08-19 23:04:32 +02:00
if ( [ [ NSUserDefaults standardUserDefaults ] boolForKey : @ "DidMoveMemoryObjects" ] ) {
NSAlert * memDidMove = [ [ NSAlert alloc ] init ] ;
memDidMove . messageText = NSLocalizedString ( @ "PSX Mem moved Desc" , @ "Playstation Cards did move" ) ;
memDidMove . informativeText = NSLocalizedString ( @ "Psx Mem Moved" , @ "Playstation Cards did move" ) ;
memDidMove . alertStyle = NSInformationalAlertStyle ;
[ memDidMove runModal ] ;
[ [ NSUserDefaults standardUserDefaults ] setBool : NO forKey : @ "DidMoveMemoryObjects" ] ;
}
2013-06-22 21:55:35 +02:00
}
2013-06-22 08:11:06 +02:00
static void ParseErrorStr ( NSString * errStr )
{
2013-07-11 02:03:19 +02:00
NSLog ( @ "Parse error: %@" , errStr ) ;
2013-07-09 09:07:15 +02:00
NSRunCriticalAlertPanel ( @ "Parsing error" , @ "%@\n\nPlease check the command line options and try again.\n\nPCSXR will now quit." , nil , nil , nil , errStr ) ;
2013-06-22 08:11:06 +02:00
ShowHelpAndExit ( stderr , EXIT_FAILURE ) ;
}
// DO NOT END THIS MACRO WITH A SIMICOLON ! it will break the if - else if process
# define HandleArg ( arg , launchable , otherblock ) \
if ( [ [ progArgs objectAtIndex : i ] compare : arg options : NSCaseInsensitiveSearch ] = = NSOrderedSame ) { \
HandleArgBase ( arg , launchable , otherblock )
# define HandleArgElse ( arg , launchable , otherblock ) \
else if ( [ [ progArgs objectAtIndex : i ] compare : arg options : NSCaseInsensitiveSearch ] = = NSOrderedSame ) { \
HandleArgBase ( arg , launchable , otherblock )
# define HandleArgBase ( arg , launchable , otherblock ) \
if ( isLaunchable && launchable ) { \
2013-07-09 01:46:22 +02:00
ParseErrorStr ( [ NSString stringWithFormat : @ "The options %@ and %@ are exclusive." , arg , runtimeStr ] ) ; \
2013-06-22 08:11:06 +02:00
} \
if ( launchable ) { \
isLaunchable = YES ; \
runtimeStr = arg ; \
} \
otherblock ( ) ; \
}
2014-10-01 21:49:24 +02:00
# define kPCSXRArgumentCDROM @ "-runcd"
# define kPCSXRArgumentBIOS @ "-bios"
# define kPCSXRArgumentISO @ "-cdfile"
# define kPCSXRArgumentMcd @ "-mcd"
2013-07-09 09:07:15 +02:00
# define kPCSXRArgumentMcd1 kPCSXRArgumentMcd @ "1"
# define kPCSXRArgumentMcd2 kPCSXRArgumentMcd @ "2"
2014-10-01 21:49:24 +02:00
# define kPCSXRArgumentFreeze @ "-freeze"
# define kPCSXRArgumentExitAtClose @ "-nogui"
# define kPCSXRArgumentLogOutput @ "-psxout"
# define kPCSXRArgumentSlowBoot @ "-slowboot"
2013-07-09 01:46:22 +02:00
2013-09-22 06:16:10 +02:00
- ( void ) dealloc
{
[ [ NSNotificationCenter defaultCenter ] removeObserver : self ] ;
}
2009-06-09 13:34:52 +02:00
- ( void ) awakeFromNib
{
2013-12-30 21:15:56 +01:00
[ [ NSNotificationCenter defaultCenter ]
addObserver : self selector : @ selector ( emuWindowDidClose : )
name : @ "emuWindowDidClose" object : nil ] ;
2009-06-09 13:34:52 +02:00
pluginList = [ [ PluginList alloc ] init ] ;
if ( ! [ pluginList configured ] / * ! Config . Gpu [ 0 ] || ! Config . Spu [ 0 ] || ! Config . Pad1 [ 0 ] || ! Config . Cdr [ 0 ] * / ) {
// configure plugins
[ self preferences : nil ] ;
2013-12-30 21:15:56 +01:00
2009-06-09 13:34:52 +02:00
NSRunCriticalAlertPanel ( NSLocalizedString ( @ "Missing plugins!" , nil ) ,
2013-12-30 21:15:56 +01:00
NSLocalizedString ( @ "Pcsxr is missing one or more critical plugins. You will need to install these in order to play games." , nil ) ,
nil , nil , nil ) ;
2009-06-09 13:34:52 +02:00
}
2013-12-30 21:15:56 +01:00
2011-06-08 11:27:25 +02:00
if ( ! [ PcsxrController biosAvailable ] ) {
2013-08-22 21:42:02 +02:00
NSFileManager * manager = [ NSFileManager defaultManager ] ;
NSURL * supportURL = [ manager URLForDirectory : NSApplicationSupportDirectory inDomain : NSUserDomainMask appropriateForURL : nil create : YES error : NULL ] ;
NSURL * biosURL = [ [ supportURL URLByAppendingPathComponent : @ "Pcsxr" ] URLByAppendingPathComponent : @ "Bios" ] ;
NSInteger retVal = NSRunInformationalAlertPanel ( NSLocalizedString ( @ "Missing BIOS!" , nil ) ,
2013-12-30 21:15:56 +01:00
NSLocalizedString ( @ "Pcsxr wasn't able to locate any Playstation BIOS ROM files. This means that it will run in BIOS simulation mode which is less stable and compatible than using a real Playstation BIOS.\nIf you have a BIOS available, please copy it to\n%@" , nil ) ,
NSLocalizedString ( @ "Okay" , @ "OK" ) , NSLocalizedString ( @ "Show Folder" , @ "Show Folder" ) , nil , [ [ biosURL path ] stringByAbbreviatingWithTildeInPath ] ) ;
2013-08-22 21:42:02 +02:00
if ( retVal = = NSAlertAlternateReturn ) {
[ [ NSWorkspace sharedWorkspace ] activateFileViewerSelectingURLs : @ [ biosURL ] ] ;
}
2009-06-09 13:34:52 +02:00
}
2013-12-30 21:15:56 +01:00
2013-06-22 21:55:35 +02:00
self . sleepInBackground = [ [ NSUserDefaults standardUserDefaults ] boolForKey : @ "PauseInBackground" ] ;
2013-06-22 23:25:16 +02:00
NSArray * progArgs = [ [ NSProcessInfo processInfo ] arguments ] ;
2013-12-30 21:15:56 +01:00
if ( [ progArgs count ] > 1 && ! wasFinderLaunch ) {
2013-06-22 23:25:16 +02:00
self . skipFiles = [ NSMutableArray array ] ;
2013-06-22 08:11:06 +02:00
BOOL isLaunchable = NO ;
NSString * runtimeStr = nil ;
2013-06-22 23:25:16 +02:00
__block short memcardHandled = 0 ;
2013-06-22 08:11:06 +02:00
__block BOOL hasParsedAnArgument = NO ;
__block NSString * ( ^ FileTestBlock ) ( ) = NULL ;
2013-07-09 01:46:22 +02:00
__block NSMutableDictionary * argDict = [ [ NSMutableDictionary alloc ] initWithCapacity : [ progArgs count ] ] ;
2013-06-22 08:11:06 +02:00
2013-06-22 21:55:35 +02:00
NSMutableArray * unknownOptions = [ NSMutableArray array ] ;
2013-06-22 08:11:06 +02:00
dispatch_block _t cdromBlock = ^ {
2013-07-09 01:46:22 +02:00
hasParsedAnArgument = YES ;
2013-08-22 21:42:02 +02:00
LaunchArg * larg = [ [ LaunchArg alloc ] initWithLaunchOrder : LaunchArgRun argument : kPCSXRArgumentCDROM block : ^ {
[ self runCD : nil ] ;
} ] ;
2013-07-09 01:46:22 +02:00
[ larg addToDictionary : argDict ] ;
2013-06-22 08:11:06 +02:00
} ;
dispatch_block _t biosBlock = ^ {
hasParsedAnArgument = YES ;
2013-08-22 21:42:02 +02:00
LaunchArg * larg = [ [ LaunchArg alloc ] initWithLaunchOrder : LaunchArgRun argument : kPCSXRArgumentBIOS block : ^ {
2013-06-22 08:11:06 +02:00
[ self runBios : nil ] ;
2013-08-22 21:42:02 +02:00
} ] ;
2013-07-09 01:46:22 +02:00
[ larg addToDictionary : argDict ] ;
2013-06-22 08:11:06 +02:00
} ;
2014-10-01 21:49:24 +02:00
// This block / argument does not need to be sorted
2013-06-22 08:11:06 +02:00
dispatch_block _t emuCloseAtEnd = ^ {
hasParsedAnArgument = YES ;
2013-08-22 21:42:02 +02:00
LaunchArg * larg = [ [ LaunchArg alloc ] initWithLaunchOrder : LaunchArgPreRun argument : kPCSXRArgumentExitAtClose block : ^ {
2013-07-10 02:04:59 +02:00
self . endAtEmuClose = YES ;
2013-08-22 21:42:02 +02:00
} ] ;
2013-07-10 02:04:59 +02:00
[ larg addToDictionary : argDict ] ;
2013-06-22 08:11:06 +02:00
} ;
2014-10-01 21:49:24 +02:00
dispatch_block _t psxOut = ^ {
hasParsedAnArgument = YES ;
LaunchArg * larg = [ [ LaunchArg alloc ] initWithLaunchOrder : LaunchArgPreRun argument : kPCSXRArgumentLogOutput block : ^ {
Config . PsxOut = true ;
} ] ;
[ larg addToDictionary : argDict ] ;
} ;
dispatch_block _t slowBoot = ^ {
hasParsedAnArgument = YES ;
LaunchArg * larg = [ [ LaunchArg alloc ] initWithLaunchOrder : LaunchArgPreRun argument : kPCSXRArgumentSlowBoot block : ^ {
Config . SlowBoot = true ;
} ] ;
[ larg addToDictionary : argDict ] ;
} ;
2013-06-22 08:11:06 +02:00
dispatch_block _t isoBlock = ^ {
hasParsedAnArgument = YES ;
NSString * path = FileTestBlock ( ) ;
2013-08-22 21:42:02 +02:00
LaunchArg * larg = [ [ LaunchArg alloc ] initWithLaunchOrder : LaunchArgRun argument : kPCSXRArgumentISO block : ^ {
2013-06-26 02:53:22 +02:00
[ self runURL : [ NSURL fileURLWithPath : path isDirectory : NO ] ] ;
2013-08-22 21:42:02 +02:00
} ] ;
2013-07-09 01:46:22 +02:00
[ larg addToDictionary : argDict ] ;
2013-06-22 08:11:06 +02:00
} ;
void ( ^ mcdBlock ) ( int mcdNumber ) = ^ ( int mcdnumber ) {
hasParsedAnArgument = YES ;
2013-06-22 23:25:16 +02:00
if ( memcardHandled & ( 1 < < mcdnumber ) ) {
2013-07-11 02:03:19 +02:00
NSLog ( @ "Memory card %i has already been defined. The latest one passed will be used." , mcdnumber ) ;
2013-06-22 23:25:16 +02:00
} else {
memcardHandled | = ( 1 < < mcdnumber ) ;
}
2013-07-09 01:46:22 +02:00
2013-06-22 08:11:06 +02:00
NSString * path = FileTestBlock ( ) ;
2013-07-09 01:46:22 +02:00
NSString * mcdArg = [ kPCSXRArgumentMcd stringByAppendingFormat : @ "%i" , mcdnumber ] ;
2013-08-22 21:42:02 +02:00
LaunchArg * larg = [ [ LaunchArg alloc ] initWithLaunchOrder : LaunchArgPreRun argument : mcdArg block : ^ {
LoadMcd ( mcdnumber , ( char * ) [ path fileSystemRepresentation ] ) ;
} ] ;
2013-07-09 01:46:22 +02:00
[ larg addToDictionary : argDict ] ;
2013-06-22 08:11:06 +02:00
} ;
dispatch_block _t freezeBlock = ^ {
hasParsedAnArgument = YES ;
NSString * path = FileTestBlock ( ) ;
2013-08-22 21:42:02 +02:00
LaunchArg * larg = [ [ LaunchArg alloc ] initWithLaunchOrder : LaunchArgPostRun argument : kPCSXRArgumentFreeze block : ^ {
2013-07-09 01:46:22 +02:00
if ( ! [ EmuThread isRunBios ] ) {
2014-11-15 04:44:07 +01:00
dispatch_after ( dispatch_time ( DISPATCH_TIME _NOW , ( int64_t ) ( 5 * NSEC_PER _SEC ) ) , dispatch_get _global _queue ( 0 , 0 ) , ^ {
2014-10-02 07:22:50 +02:00
[ EmuThread defrostAt : path ] ;
} ) ;
2013-07-09 01:46:22 +02:00
}
2013-08-22 21:42:02 +02:00
} ] ;
2013-07-09 01:46:22 +02:00
[ larg addToDictionary : argDict ] ;
2013-06-22 08:11:06 +02:00
} ;
2013-12-30 21:15:56 +01:00
2013-06-22 21:55:35 +02:00
BOOL hasFileTestBlock = NO ;
2013-07-09 01:46:22 +02:00
2013-06-22 08:11:06 +02:00
for ( __block int i = 1 ; i < [ progArgs count ] ; i + + ) {
2013-06-22 21:55:35 +02:00
if ( ! hasFileTestBlock )
{
FileTestBlock = ^ NSString * ( ) {
if ( [ progArgs count ] <= + + i ) {
ParseErrorStr ( @ "Not enough arguments." ) ;
}
2013-09-10 20:43:18 +02:00
NSString * path = [ progArgs [ i ] stringByExpandingTildeInPath ] ;
2013-06-22 21:55:35 +02:00
if ( ! [ [ NSFileManager defaultManager ] fileExistsAtPath : path ] )
{
2013-07-09 01:46:22 +02:00
ParseErrorStr ( [ NSString stringWithFormat : @ "The file \" % @ \ " does not exist." , path ] ) ;
2013-06-22 21:55:35 +02:00
return nil ;
}
[ skipFiles addObject : path ] ;
return path ;
} ;
hasFileTestBlock = YES ;
}
2013-06-22 08:11:06 +02:00
2013-12-30 21:15:56 +01:00
// DO NOT END these MACROS WITH A SIMICOLON ! It will break the if - else if process
2013-07-09 01:46:22 +02:00
HandleArg ( kPCSXRArgumentISO , YES , isoBlock )
HandleArgElse ( kPCSXRArgumentCDROM , YES , cdromBlock )
HandleArgElse ( kPCSXRArgumentBIOS , YES , biosBlock )
HandleArgElse ( kPCSXRArgumentExitAtClose , NO , emuCloseAtEnd )
2013-07-09 09:07:15 +02:00
HandleArgElse ( kPCSXRArgumentMcd1 , NO , ^ { mcdBlock ( 1 ) ; } )
HandleArgElse ( kPCSXRArgumentMcd2 , NO , ^ { mcdBlock ( 2 ) ; } )
2013-07-09 01:46:22 +02:00
HandleArgElse ( kPCSXRArgumentFreeze , NO , freezeBlock )
2014-10-01 21:49:24 +02:00
HandleArgElse ( kPCSXRArgumentLogOutput , NO , psxOut )
HandleArgElse ( kPCSXRArgumentSlowBoot , NO , slowBoot )
2013-06-22 08:11:06 +02:00
else {
2013-09-10 20:43:18 +02:00
[ unknownOptions addObject : progArgs [ i ] ] ;
2013-06-22 21:55:35 +02:00
}
}
# ifdef DEBUG
2013-12-30 21:15:56 +01:00
if ( [ unknownOptions count ] ) {
2013-09-10 20:18:15 +02:00
NSString * unknownString = [ unknownOptions componentsJoinedByString : @ " " ] ;
2013-07-09 01:46:22 +02:00
2013-07-11 02:03:19 +02:00
NSLog ( @ "The following options weren't recognized by PCSX-R: %@. This may be due to extra arguments passed by the OS or debugger." , unknownString ) ;
2013-06-22 08:11:06 +02:00
}
2013-06-22 21:55:35 +02:00
# endif
2013-07-10 02:04:59 +02:00
unknownOptions = nil ;
2013-06-22 08:11:06 +02:00
if ( ! isLaunchable && hasParsedAnArgument ) {
2013-07-09 09:07:15 +02:00
NSMutableArray * mutProgArgs = [ NSMutableArray arrayWithArray : progArgs ] ;
2013-09-10 20:43:18 +02:00
NSString * appRawPath = mutProgArgs [ 0 ] ;
2013-07-09 09:07:15 +02:00
// Remove the app file path from the array
[ mutProgArgs removeObjectAtIndex : 0 ] ;
2013-08-24 21:44:48 +02:00
NSString * arg = [ mutProgArgs componentsJoinedByString : @ " " ] ;
NSString * recognizedArgs = [ [ argDict allKeys ] componentsJoinedByString : @ " " ] ;
2013-07-09 01:46:22 +02:00
2013-07-10 02:04:59 +02:00
NSString * tmpStr = [ NSString stringWithFormat : @ "A launch command wasn't found in the command line and one or more arguments that PCSX-R recognizes were: %@.\nThe following command line arguments were passed with the application launch file at %@: %@.\n\nThe valid launch commands are %@, %@, and %@." , recognizedArgs , appRawPath , arg , kPCSXRArgumentISO , kPCSXRArgumentCDROM , kPCSXRArgumentBIOS ] ;
2013-07-09 01:46:22 +02:00
ParseErrorStr ( tmpStr ) ;
} else if ( hasParsedAnArgument ) {
2013-08-24 21:44:48 +02:00
NSArray * argArray = [ [ argDict allValues ] sortedArrayWithOptions : NSSortStable usingComparator : ^ NSComparisonResult ( id obj1 , id obj2 ) {
2013-07-09 01:46:22 +02:00
LaunchArg * LA1 = obj1 ;
LaunchArg * LA2 = obj2 ;
if ( LA1 . launchOrder > LA2 . launchOrder ) {
return NSOrderedDescending ;
} else if ( LA1 . launchOrder < LA2 . launchOrder ) {
return NSOrderedAscending ;
} else {
2013-08-24 21:44:48 +02:00
return NSOrderedSame ;
2013-06-22 08:11:06 +02:00
}
2013-07-09 01:46:22 +02:00
} ] ;
for ( LaunchArg * arg in argArray ) {
arg . theBlock ( ) ;
2013-06-22 08:11:06 +02:00
}
}
}
2009-06-09 13:34:52 +02:00
}
+ ( void ) setConfigFromDefaults
{
const char * str ;
NSUserDefaults * defaults = [ NSUserDefaults standardUserDefaults ] ;
2009-11-29 14:31:23 +01:00
2009-06-09 13:34:52 +02:00
/ *
enumerator = [ prefStringKeys keyEnumerator ] ;
while ( ( key = [ enumerator nextObject ] ) ) {
str = [ [ defaults stringForKey : key ] fileSystemRepresentation ] ;
char * dst = ( char * ) [ [ prefStringKeys objectForKey : key ] pointerValue ] ;
if ( str ! = nil && dst ! = nil ) strncpy ( dst , str , 255 ) ;
} * /
2009-11-29 14:31:23 +01:00
2013-01-10 21:46:32 +01:00
for ( NSString * key in prefByteKeys ) {
2013-09-10 20:43:18 +02:00
u8 * dst = ( u8 * ) [ prefByteKeys [ key ] pointerValue ] ;
2013-06-22 21:55:35 +02:00
if ( dst ! = NULL ) * dst = [ defaults boolForKey : key ] ;
2009-06-09 13:34:52 +02:00
}
// special cases
// str = [ [ defaults stringForKey : @ "PluginPAD" ] fileSystemRepresentation ] ;
// if ( str ! = nil ) strncpy ( Config . Pad2 , str , 255 ) ;
2017-07-01 15:46:09 +02:00
Config . PsxClock = [ defaults floatForKey : @ "CpuOverclockingValue" ] ;
2009-11-29 14:31:23 +01:00
2009-06-09 13:34:52 +02:00
str = [ [ defaults stringForKey : @ "Bios" ] fileSystemRepresentation ] ;
if ( str ) {
NSString * path = [ defaults stringForKey : @ "Bios" ] ;
2013-07-08 09:58:24 +02:00
NSInteger index = [ biosList indexOfObject : path ] ;
2009-06-09 13:34:52 +02:00
if ( -1 = = index ) {
[ biosList insertObject : path atIndex : 0 ] ;
} else if ( 0 < index ) {
[ biosList exchangeObjectAtIndex : index withObjectAtIndex : 0 ] ;
}
}
2009-11-29 14:31:23 +01:00
2013-08-10 21:26:52 +02:00
{
NSFileManager * manager = [ NSFileManager defaultManager ] ;
2014-08-19 23:04:32 +02:00
NSURL * oldMemoryURL = [ [ [ manager URLForDirectory : NSApplicationSupportDirectory inDomain : NSUserDomainMask appropriateForURL : nil create : YES error : NULL ] URLByAppendingPathComponent : @ "Pcsxr" ] URLByAppendingPathComponent : @ "Memory Cards" ] ;
NSURL * memoryURL = [ [ [ manager URLForDirectory : NSDocumentDirectory inDomain : NSUserDomainMask appropriateForURL : nil create : YES error : NULL ] URLByAppendingPathComponent : @ "Pcsxr" ] URLByAppendingPathComponent : @ "Memory Cards" ] ;
2014-08-19 23:24:06 +02:00
if ( ! wasFinderLaunch && [ oldMemoryURL checkResourceIsReachableAndReturnError : NULL ] ) {
2014-08-19 23:04:32 +02:00
NSDictionary * mcds = @ { @ "Mcd1" : [ defaults URLForKey : @ "Mcd1" ] ,
@ "Mcd2" : [ defaults URLForKey : @ "Mcd2" ] } ;
for ( NSString * key in mcds ) {
NSURL * obj = mcds [ key ] ;
NSString * dirPath = [ obj . path stringByStandardizingPath ] ;
NSString * oldDirPath = [ oldMemoryURL . path stringByStandardizingPath ] ;
if ( [ dirPath hasPrefix : oldDirPath ] ) {
NSArray * barePath = [ [ dirPath stringByReplacingOccurrencesOfString : oldDirPath withString : @ "" ] pathComponents ] ;
NSMutableArray * newPath = [ [ memoryURL pathComponents ] mutableCopy ] ;
[ newPath addObjectsFromArray : barePath ] ;
NSURL * replacementPath = [ NSURL fileURLWithPathComponents : newPath ] ;
2014-08-19 23:24:06 +02:00
if ( [ manager moveItemAtURL : obj toURL : replacementPath error : NULL ] ) {
2014-08-19 23:04:32 +02:00
[ defaults setURL : replacementPath forKey : key ] ;
2014-08-19 23:24:06 +02:00
}
2014-08-19 23:04:32 +02:00
}
}
2014-08-19 23:24:06 +02:00
NSArray * memoryFiles = [ manager contentsOfDirectoryAtURL : oldMemoryURL includingPropertiesForKeys : @ [ ] options : 0 error : NULL ] ;
for ( NSURL * memLoc in memoryFiles ) {
[ manager moveItemAtURL : memLoc toURL : [ memoryURL URLByAppendingPathComponent : [ memLoc lastPathComponent ] ] error : NULL ] ;
}
[ manager removeItemAtURL : oldMemoryURL error : NULL ] ;
2014-08-19 23:04:32 +02:00
[ defaults setBool : YES forKey : @ "DidMoveMemoryObjects" ] ;
}
2013-08-10 21:26:52 +02:00
str = [ [ [ defaults URLForKey : @ "Mcd1" ] path ] fileSystemRepresentation ] ;
if ( str ) {
strlcpy ( Config . Mcd1 , str , MAXPATHLEN ) ;
} else {
NSURL * url = [ memoryURL URLByAppendingPathComponent : @ "Mcd001.mcr" ] ;
[ defaults setURL : url forKey : @ "Mcd1" ] ;
str = [ [ url path ] fileSystemRepresentation ] ;
if ( str ! = nil ) strlcpy ( Config . Mcd1 , str , MAXPATHLEN ) ;
}
str = [ [ [ defaults URLForKey : @ "Mcd2" ] path ] fileSystemRepresentation ] ;
if ( str ) {
strlcpy ( Config . Mcd2 , str , MAXPATHLEN ) ;
} else {
NSURL * url = [ memoryURL URLByAppendingPathComponent : @ "Mcd002.mcr" ] ;
[ defaults setURL : url forKey : @ "Mcd2" ] ;
str = [ [ url path ] fileSystemRepresentation ] ;
if ( str ! = nil ) strlcpy ( Config . Mcd2 , str , MAXPATHLEN ) ;
}
}
2009-11-29 14:31:23 +01:00
2009-06-09 13:34:52 +02:00
if ( [ defaults boolForKey : @ "UseHLE" ] || 0 = = [ biosList count ] ) {
strcpy ( Config . Bios , "HLE" ) ;
} else {
2013-09-10 20:43:18 +02:00
str = [ ( NSString * ) biosList [ 0 ] fileSystemRepresentation ] ;
2013-01-10 21:46:32 +01:00
if ( str ! = nil ) strlcpy ( Config . Bios , str , MAXPATHLEN ) ;
2009-06-09 13:34:52 +02:00
else strcpy ( Config . Bios , "HLE" ) ;
}
2009-06-11 11:22:11 +02:00
2011-11-18 05:46:20 +01:00
str = [ [ defaults stringForKey : @ "Net" ] fileSystemRepresentation ] ;
2013-01-10 21:46:32 +01:00
if ( str ) strlcpy ( Config . Net , str , MAXPATHLEN ) ;
2011-11-18 05:46:20 +01:00
else {
strcpy ( Config . Net , "Disabled" ) ;
}
2017-06-30 16:45:32 +02:00
// PGXP settings
[ PgxpController loadPgxpSettings ] ;
2009-06-09 13:34:52 +02:00
}
+ ( void ) setDefaultFromConfig : ( NSString * ) defaultKey
{
NSUserDefaults * defaults = [ NSUserDefaults standardUserDefaults ] ;
2009-11-29 14:31:23 +01:00
2013-09-10 20:43:18 +02:00
char * str = ( char * ) [ prefStringKeys [ defaultKey ] pointerValue ] ;
2009-06-09 13:34:52 +02:00
if ( str ) {
2013-06-22 23:25:16 +02:00
NSString * tmpNSStr = [ [ NSFileManager defaultManager ] stringWithFileSystemRepresentation : str length : strlen ( str ) ] ;
if ( ! tmpNSStr ) {
2013-07-05 23:59:24 +02:00
tmpNSStr = @ ( str ) ;
2013-06-22 23:25:16 +02:00
}
[ defaults setObject : tmpNSStr forKey : defaultKey ] ;
2009-06-09 13:34:52 +02:00
return ;
}
2013-06-26 02:53:22 +02:00
2013-09-10 20:43:18 +02:00
str = ( char * ) [ prefURLKeys [ defaultKey ] pointerValue ] ;
2013-06-26 02:53:22 +02:00
if ( str ) {
NSString * tmpNSStr = [ [ NSFileManager defaultManager ] stringWithFileSystemRepresentation : str length : strlen ( str ) ] ;
if ( ! tmpNSStr ) {
2013-07-09 09:07:15 +02:00
tmpNSStr = @ ( str ) ;
2013-06-26 02:53:22 +02:00
}
[ defaults setURL : [ NSURL fileURLWithPath : tmpNSStr isDirectory : NO ] forKey : defaultKey ] ;
return ;
}
2009-11-29 14:31:23 +01:00
2013-09-10 20:43:18 +02:00
u8 * val = ( u8 * ) [ prefByteKeys [ defaultKey ] pointerValue ] ;
2009-06-09 13:34:52 +02:00
if ( val ) {
[ defaults setInteger : * val forKey : defaultKey ] ;
return ;
}
}
+ ( BOOL ) biosAvailable
{
return ( [ biosList count ] > 0 ) ;
}
// called when class is initialized
+ ( void ) initialize
{
NSString * path ;
const char * str ;
NSUserDefaults * defaults = [ NSUserDefaults standardUserDefaults ] ;
2013-09-10 20:43:18 +02:00
NSDictionary * appDefaults = @ { @ "NoDynarec" : @ YES ,
2014-08-19 23:04:32 +02:00
@ "AutoDetectVideoType" : @ YES ,
@ "UseHLE" : @ NO ,
@ "PauseInBackground" : @ YES ,
@ "Widescreen" : @ NO ,
@ "NetPlay" : @ NO ,
2014-09-27 18:50:21 +02:00
@ "DidMoveMemoryObjects" : @ NO ,
2017-07-01 15:46:09 +02:00
@ "NoFastBoot" : @ NO ,
@ "CpuOverclocking" : @ NO ,
@ "CpuOverclockingValue" : @ 1.5 f ,
@ "WipeoutMemHack" : @ NO } ;
2013-01-10 21:46:32 +01:00
2009-06-09 13:34:52 +02:00
[ defaults registerDefaults : appDefaults ] ;
2009-11-29 14:31:23 +01:00
2013-09-10 20:43:18 +02:00
prefStringKeys = @ { @ "PluginGPU" : [ NSValue valueWithPointer : Config . Gpu ] ,
@ "PluginSPU" : [ NSValue valueWithPointer : Config . Spu ] ,
@ "PluginPAD" : [ NSValue valueWithPointer : Config . Pad1 ] ,
@ "PluginCDR" : [ NSValue valueWithPointer : Config . Cdr ] ,
@ "PluginNET" : [ NSValue valueWithPointer : Config . Net ] ,
@ "PluginSIO1" : [ NSValue valueWithPointer : Config . Sio1 ] } ;
2013-06-26 02:53:22 +02:00
2013-09-10 20:43:18 +02:00
prefURLKeys = @ { @ "Mcd1" : [ NSValue valueWithPointer : Config . Mcd1 ] ,
2014-08-19 23:04:32 +02:00
@ "Mcd2" : [ NSValue valueWithPointer : Config . Mcd2 ] } ;
2013-09-10 20:43:18 +02:00
prefByteKeys = @ { @ "NoXaAudio" : [ NSValue valueWithPointer : & Config . Xa ] ,
@ "SioIrqAlways" : [ NSValue valueWithPointer : & Config . SioIrq ] ,
@ "BlackAndWhiteMDECVideo" : [ NSValue valueWithPointer : & Config . Mdec ] ,
@ "AutoDetectVideoType" : [ NSValue valueWithPointer : & Config . PsxAuto ] ,
@ "VideoTypePAL" : [ NSValue valueWithPointer : & Config . PsxType ] ,
@ "NoCDAudio" : [ NSValue valueWithPointer : & Config . Cdda ] ,
@ "NoDynarec" : [ NSValue valueWithPointer : & Config . Cpu ] ,
@ "ConsoleOutput" : [ NSValue valueWithPointer : & Config . PsxOut ] ,
@ "SpuIrqAlways" : [ NSValue valueWithPointer : & Config . SpuIrq ] ,
@ "RootCounterFix" : [ NSValue valueWithPointer : & Config . RCntFix ] ,
@ "VideoSyncWAFix" : [ NSValue valueWithPointer : & Config . VSyncWA ] ,
2014-09-27 18:50:21 +02:00
@ "Widescreen" : [ NSValue valueWithPointer : & Config . Widescreen ] ,
2017-07-01 15:46:09 +02:00
@ "NoFastBoot" : [ NSValue valueWithPointer : & Config . SlowBoot ] ,
@ "CpuOverclocking" : [ NSValue valueWithPointer : & Config . OverClock ] ,
@ "WipeoutMemHack" : [ NSValue valueWithPointer : & Config . MemHack ] } ;
2009-11-29 14:31:23 +01:00
2009-06-09 13:34:52 +02:00
// setup application support paths
2011-11-09 21:49:54 +01:00
NSFileManager * manager = [ NSFileManager defaultManager ] ;
NSURL * supportURL = [ manager URLForDirectory : NSApplicationSupportDirectory inDomain : NSUserDomainMask appropriateForURL : nil create : YES error : NULL ] ;
if ( supportURL ! = nil ) {
2014-08-19 23:04:32 +02:00
NSURL * PcsxrAppSupport = [ supportURL URLByAppendingPathComponent : @ "Pcsxr" ] ;
NSURL * pcsxrDocument = [ [ manager URLForDirectory : NSDocumentDirectory inDomain : NSUserDomainMask appropriateForURL : nil create : YES error : NULL ] URLByAppendingPathComponent : @ "Pcsxr" ] ;
2012-10-10 02:04:58 +02:00
NSURL * MemCardPath ;
2011-11-09 21:49:54 +01:00
NSURL * url ;
2009-06-09 13:34:52 +02:00
BOOL dir ;
2012-10-10 02:04:58 +02:00
2009-11-29 14:31:23 +01:00
2009-06-09 13:34:52 +02:00
// create them if needed
2012-10-10 02:04:58 +02:00
url = [ PcsxrAppSupport URLByAppendingPathComponent : @ "Bios" ] ;
2011-11-09 21:49:54 +01:00
if ( ! [ url checkResourceIsReachableAndReturnError : NULL ] )
2014-01-13 00:24:21 +01:00
[ manager createDirectoryAtURL : url withIntermediateDirectories : YES attributes : nil error : NULL ] ;
2011-11-09 21:49:54 +01:00
2014-08-19 23:04:32 +02:00
MemCardPath = [ pcsxrDocument URLByAppendingPathComponent : @ "Memory Cards" ] ;
2012-10-10 02:04:58 +02:00
url = MemCardPath ;
2011-11-09 21:49:54 +01:00
if ( ! [ url checkResourceIsReachableAndReturnError : NULL ] )
2014-01-13 00:24:21 +01:00
[ manager createDirectoryAtURL : url withIntermediateDirectories : YES attributes : nil error : NULL ] ;
2011-11-09 21:49:54 +01:00
2012-10-10 02:04:58 +02:00
url = [ PcsxrAppSupport URLByAppendingPathComponent : @ "Patches" ] ;
2011-11-09 21:49:54 +01:00
if ( ! [ url checkResourceIsReachableAndReturnError : NULL ] )
2014-01-13 00:24:21 +01:00
[ manager createDirectoryAtURL : url withIntermediateDirectories : YES attributes : nil error : NULL ] ;
2011-12-17 21:41:31 +01:00
2012-10-10 02:04:58 +02:00
url = [ PcsxrAppSupport URLByAppendingPathComponent : @ "PlugIns" ] ;
2011-12-17 21:41:31 +01:00
if ( ! [ url checkResourceIsReachableAndReturnError : NULL ] )
2014-01-13 00:24:21 +01:00
[ manager createDirectoryAtURL : url withIntermediateDirectories : YES attributes : nil error : NULL ] ;
2011-11-09 21:49:54 +01:00
2012-10-10 02:04:58 +02:00
saveStatePath = [ [ [ PcsxrAppSupport URLByAppendingPathComponent : @ "Save States" ] path ] copy ] ;
2011-11-09 21:49:54 +01:00
if ( ! [ manager fileExistsAtPath : saveStatePath isDirectory : & dir ] )
[ manager createDirectoryAtPath : saveStatePath withIntermediateDirectories : YES attributes : nil error : NULL ] ;
2012-10-10 02:04:58 +02:00
url = [ MemCardPath URLByAppendingPathComponent : @ "Mcd001.mcr" ] ;
2011-11-09 21:49:54 +01:00
str = [ [ url path ] fileSystemRepresentation ] ;
2014-01-13 00:24:21 +01:00
if ( str ! = nil )
strlcpy ( Config . Mcd1 , str , MAXPATHLEN ) ;
2009-11-29 14:31:23 +01:00
2012-10-10 02:04:58 +02:00
url = [ MemCardPath URLByAppendingPathComponent : @ "Mcd002.mcr" ] ;
2011-11-09 21:49:54 +01:00
str = [ [ url path ] fileSystemRepresentation ] ;
2014-01-13 00:24:21 +01:00
if ( str ! = nil )
strlcpy ( Config . Mcd2 , str , MAXPATHLEN ) ;
2009-06-09 13:34:52 +02:00
2012-10-10 02:04:58 +02:00
url = [ PcsxrAppSupport URLByAppendingPathComponent : @ "Bios" ] ;
2011-11-09 21:49:54 +01:00
str = [ [ url path ] fileSystemRepresentation ] ;
2014-01-13 00:24:21 +01:00
if ( str ! = nil )
strlcpy ( Config . BiosDir , str , MAXPATHLEN ) ;
2010-01-23 09:44:23 +01:00
2012-10-10 02:04:58 +02:00
url = [ PcsxrAppSupport URLByAppendingPathComponent : @ "Patches" ] ;
2011-11-09 21:49:54 +01:00
str = [ [ url path ] fileSystemRepresentation ] ;
2013-01-10 21:46:32 +01:00
if ( str ! = nil ) {
strlcpy ( Config . PatchesDir , str , MAXPATHLEN ) ;
}
2009-06-09 13:34:52 +02:00
} else {
strcpy ( Config . BiosDir , "Bios/" ) ;
2010-01-23 09:44:23 +01:00
strcpy ( Config . PatchesDir , "Patches/" ) ;
2009-11-29 14:31:23 +01:00
2013-07-09 09:07:15 +02:00
// NSString constants don ' t need to be retained / released . In fact , retain / releasing them does nothing .
2013-07-06 01:02:13 +02:00
saveStatePath = @ "sstates" ;
2009-06-09 13:34:52 +02:00
}
// set plugin path
2011-11-09 21:49:54 +01:00
path = [ [ NSBundle mainBundle ] builtInPlugInsPath ] ;
2009-06-09 13:34:52 +02:00
str = [ path fileSystemRepresentation ] ;
2014-01-13 00:24:21 +01:00
if ( str ! = nil )
strlcpy ( Config . PluginsDir , str , MAXPATHLEN ) ;
2009-06-09 13:34:52 +02:00
// locate a bios
biosList = [ [ NSMutableArray alloc ] init ] ;
2011-11-09 21:49:54 +01:00
NSString * biosDir = [ manager stringWithFileSystemRepresentation : Config . BiosDir length : strlen ( Config . BiosDir ) ] ;
NSArray * bioses = [ manager contentsOfDirectoryAtPath : biosDir error : NULL ] ;
2009-06-09 13:34:52 +02:00
if ( bioses ) {
2013-01-10 21:46:32 +01:00
for ( NSString * file in bioses ) {
2011-11-09 21:49:54 +01:00
NSDictionary * attrib = [ manager attributesOfItemAtPath : [ [ biosDir stringByAppendingPathComponent : file ] stringByResolvingSymlinksInPath ] error : NULL ] ;
2009-06-11 11:22:11 +02:00
2009-06-09 13:34:52 +02:00
if ( [ [ attrib fileType ] isEqualToString : NSFileTypeRegular ] ) {
unsigned long long size = [ attrib fileSize ] ;
2013-01-10 21:46:32 +01:00
if ( ( size % ( 256 * 1024 ) ) = = 0 && size > 0 ) {
2009-06-09 13:34:52 +02:00
[ biosList addObject : file ] ;
}
}
}
}
2009-11-29 14:31:23 +01:00
2011-06-08 11:27:25 +02:00
[ PcsxrController setConfigFromDefaults ] ;
2009-06-09 13:34:52 +02:00
}
2012-12-15 22:07:55 +01:00
+ ( NSString * ) saveStatePath : ( int ) slot
{
if ( slot >= 0 ) {
2013-01-10 22:00:20 +01:00
return [ saveStatePath stringByAppendingPathComponent : [ NSString stringWithFormat : @ "%s-%3.3d.pcsxrstate" , CdromId , slot ] ] ;
2012-12-15 22:07:55 +01:00
}
return saveStatePath ;
}
2011-12-11 05:11:51 +01:00
- ( BOOL ) application : ( NSApplication * ) theApplication openFile : ( NSString * ) filename
{
2013-12-30 21:20:48 +01:00
NSFileManager * fm = [ NSFileManager defaultManager ] ;
2014-03-28 22:47:05 +01:00
NSWorkspace * workspace = [ NSWorkspace sharedWorkspace ] ;
2013-06-22 21:55:35 +02:00
if ( skipFiles && [ skipFiles count ] ) {
for ( NSString * parsedFile in skipFiles ) {
if ( [ filename isEqualToString : parsedFile ] ) {
return YES ;
}
}
}
2013-12-30 21:20:48 +01:00
if ( ! [ fm fileExistsAtPath : filename ] ) {
2013-07-11 05:24:07 +02:00
NSLog ( @ "Nonexistant file %@ was passed to open." , filename ) ;
2013-06-22 23:39:09 +02:00
return NO ;
}
2013-12-30 21:20:48 +01:00
if ( [ [ filename pathExtension ] compare : @ "bin" options : ( NSCaseInsensitiveSearch | NSWidthInsensitiveSearch ) ] ) {
NSDictionary * attrib = [ fm attributesOfItemAtPath : filename error : NULL ] ;
if ( [ [ attrib fileType ] isEqualToString : NSFileTypeRegular ] && ( [ attrib fileSize ] % ( 256 * 1024 ) ) = = 0 && [ attrib fileSize ] > 0 ) {
NSAlert * biosInfo = [ NSAlert alertWithMessageText : NSLocalizedString ( @ "PlayStation BIOS File" , @ "PSX BIOS File" ) defaultButton : NSLocalizedString ( @ "BIOS_Copy" , @ "copy the BIOS over" ) alternateButton : NSLocalizedString ( @ "Cancel" , @ "Cancel" ) otherButton : NSLocalizedString ( @ "BIOS_Move" , @ "Move the bios over" ) informativeTextWithFormat : NSLocalizedString ( @ "The file \" % @ \ " seems to be a BIOS file. Do you want PCSX-R to copy it to the proper location?" , @ "Can we copy the BIOS?" ) ] ;
biosInfo . alertStyle = NSInformationalAlertStyle ;
switch ( [ biosInfo runModal ] ) {
case NSAlertFirstButtonReturn :
case NSAlertDefaultReturn :
{
NSError * theErr = nil ;
NSURL * biosDirPath = [ NSURL fileURLWithPath : [ fm stringWithFileSystemRepresentation : Config . BiosDir length : strlen ( Config . BiosDir ) ] isDirectory : YES ] ;
NSURL * biosPath = [ biosDirPath URLByAppendingPathComponent : [ filename lastPathComponent ] ] ;
if ( [ biosPath checkResourceIsReachableAndReturnError : NULL ] ) {
NSAlert * alreadyThere = [ NSAlert alertWithMessageText : NSLocalizedString ( @ "BIOS Already Exists" , @ "BIOS file already there." ) defaultButton : nil alternateButton : nil otherButton : nil informativeTextWithFormat : NSLocalizedString ( @ "There already exists a BIOS file at \" % 1 $ @ \ ": not copying the file at \" % 2 $ @ \ ".\n\nIf you do want to use the BIOS file at \" % 2 $ @ \ ", delete the BIOS at \" % 1 $ @ \ "." , @ "What to do" ) , [ biosPath path ] , filename ] ;
alreadyThere . alertStyle = NSCriticalAlertStyle ;
[ alreadyThere runModal ] ;
return NO ;
}
if ( ! [ fm copyItemAtURL : [ NSURL fileURLWithPath : filename isDirectory : NO ] toURL : biosPath error : & theErr ] ) {
[ [ NSAlert alertWithError : theErr ] runModal ] ;
return NO ;
}
}
break ;
case NSAlertThirdButtonReturn :
case NSAlertOtherReturn :
{
NSError * theErr = nil ;
NSURL * biosDirPath = [ NSURL fileURLWithPath : [ fm stringWithFileSystemRepresentation : Config . BiosDir length : strlen ( Config . BiosDir ) ] isDirectory : YES ] ;
NSURL * biosPath = [ biosDirPath URLByAppendingPathComponent : [ filename lastPathComponent ] ] ;
if ( [ biosPath checkResourceIsReachableAndReturnError : NULL ] ) {
2014-01-01 22:20:40 +01:00
NSAlert * alreadyThere = [ NSAlert alertWithMessageText : NSLocalizedString ( @ "BIOS Already Exists" , @ "BIOS file already there." ) defaultButton : nil alternateButton : nil otherButton : nil informativeTextWithFormat : NSLocalizedString ( @ "There already exists a BIOS file at \" % 1 $ @ \ ": not moving the file at \" % 2 $ @ \ ".\n\nIf you do want to use the BIOS file at \" % 2 $ @ \ ", delete the BIOS at \" % 1 $ @ \ "." , @ "What to do" ) , [ biosPath path ] , filename ] ;
2013-12-30 21:20:48 +01:00
alreadyThere . alertStyle = NSCriticalAlertStyle ;
[ alreadyThere runModal ] ;
return NO ;
}
if ( ! [ fm moveItemAtURL : [ NSURL fileURLWithPath : filename isDirectory : NO ] toURL : biosPath error : & theErr ] ) {
[ [ NSAlert alertWithError : theErr ] runModal ] ;
return NO ;
}
}
break ;
default :
break ;
}
return YES ;
}
}
2011-12-15 20:44:34 +01:00
NSError * err = nil ;
2014-03-28 22:47:05 +01:00
NSString * utiFile = [ workspace typeOfFile : filename error : & err ] ;
2011-12-15 20:44:34 +01:00
if ( err ) {
2013-06-22 23:25:16 +02:00
NSRunAlertPanel ( NSLocalizedString ( @ "Error opening file" , nil ) , NSLocalizedString ( @ "Unable to open %@: %@" , nil ) , nil , nil , nil , [ filename lastPathComponent ] , err ) ;
2011-12-15 20:44:34 +01:00
return NO ;
}
2012-05-24 01:20:57 +02:00
static NSArray * handlers = nil ;
if ( handlers = = nil ) {
2013-08-01 18:50:36 +02:00
handlers = @ [ [ PcsxrPluginHandler class ] , [ PcsxrMemCardHandler class ] , [ PcsxrFreezeStateHandler class ] , [ PcsxrDiscHandler class ] , [ PcsxrCheatHandler class ] ] ;
2012-05-24 01:20:57 +02:00
}
2011-12-17 20:08:51 +01:00
BOOL isHandled = NO ;
2011-12-19 00:51:13 +01:00
for ( Class fileHandler in handlers ) {
NSObject < PcsxrFileHandle > * hand = [ [ fileHandler alloc ] init ] ;
BOOL canHandle = NO ;
for ( NSString * uti in [ fileHandler supportedUTIs ] ) {
2014-03-28 22:47:05 +01:00
if ( [ workspace type : utiFile conformsToType : uti ] ) {
2011-12-19 00:51:13 +01:00
canHandle = YES ;
2013-01-09 02:50:38 +01:00
break ;
2011-12-19 00:51:13 +01:00
}
}
if ( canHandle ) {
2013-01-08 23:20:31 +01:00
isHandled = [ hand handleFile : filename ] ;
2012-10-31 02:25:35 +01:00
break ;
2011-12-19 00:51:13 +01:00
}
2011-12-11 05:11:51 +01:00
}
2013-06-22 21:55:35 +02:00
2011-12-17 20:08:51 +01:00
return isHandled ;
2011-12-11 05:11:51 +01:00
}
2009-06-09 13:34:52 +02:00
@ end