Have the arguments passed to the OS X app be done in a specific order, so i.e. you don't try to load a memory card after the emulator has started, or loading a freeze state before the emulator has started.

git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@85919 e17a0e51-4ae3-4d35-97c3-1a29b211df97
This commit is contained in:
SND\MaddTheSane_cp 2013-07-08 23:46:22 +00:00
parent e0fa342a42
commit 434c738fac
4 changed files with 201 additions and 52 deletions

30
macosx/LaunchArg.h Normal file
View File

@ -0,0 +1,30 @@
//
// LaunchArg.h
// Pcsxr
//
// Created by C.W. Betts on 7/8/13.
//
//
#import <Foundation/Foundation.h>
#import "ARCBridge.h"
typedef enum _LaunchArgOrder {
LaunchArgPreRun = 0,
LaunchArgRun = 2,
LaunchArgPostRun = 4
}LaunchArgOrder;
@interface LaunchArg : NSObject
{
LaunchArgOrder _launchOrder;
dispatch_block_t _theBlock;
NSString *_argument;
}
@property (readonly) LaunchArgOrder launchOrder;
@property (readonly, copy, nonatomic) dispatch_block_t theBlock;
@property (readonly, arcretain) NSString *argument;
- (id)initWithLaunchOrder:(LaunchArgOrder)order block:(dispatch_block_t)block argument:(NSString*)arg;
- (void)addToDictionary:(NSMutableDictionary*)toAdd;
@end

66
macosx/LaunchArg.m Normal file
View File

@ -0,0 +1,66 @@
//
// LaunchArg.m
// Pcsxr
//
// Created by C.W. Betts on 7/8/13.
//
//
#import "LaunchArg.h"
@interface LaunchArg ()
@property (readwrite) LaunchArgOrder launchOrder;
@property (readwrite, copy, nonatomic) dispatch_block_t theBlock;
@property (readwrite, arcretain) NSString *argument;
@end
@implementation LaunchArg
@synthesize argument = _argument;
@synthesize launchOrder = _launchOrder;
@synthesize theBlock = _theBlock;
- (void)setTheBlock:(dispatch_block_t)theBlock
{
#if __has_feature(objc_arc)
_theBlock = [theBlock copy];
#else
if (_theBlock == theBlock) {
return;
}
dispatch_block_t tmpBlock = _theBlock
_theBlock = [theBlock copy];
[tmpBlock release];
#endif
}
- (id)initWithLaunchOrder:(LaunchArgOrder)order block:(dispatch_block_t)block argument:(NSString*)arg
{
if (self = [super init]) {
self.launchOrder = order;
self.theBlock = block;
self.argument = arg;
}
return self;
}
- (void)addToDictionary:(NSMutableDictionary*)toAdd
{
[toAdd setObject:self forKey:self.argument];
}
- (NSString*)description
{
return [NSString stringWithFormat:@"Arg: %@, order: %u, block addr: %p", _argument, _launchOrder, _theBlock];
}
#if !__has_feature(objc_arc)
- (void)dealloc
{
self.theBlock = nil;
self.argument = nil;
[super dealloc];
}
#endif
@end

View File

@ -212,6 +212,7 @@
55BBA69914953887003B2CEC /* PcsxrDiscHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 55BBA69814953887003B2CEC /* PcsxrDiscHandler.m */; };
55BBA69C1495839A003B2CEC /* PcsxrFreezeStateHandler.m in Sources */ = {isa = PBXBuildFile; fileRef = 55BBA69B1495839A003B2CEC /* PcsxrFreezeStateHandler.m */; };
55C7A214148B2B3800C22ABC /* PcsxrMemCardDocument.xib in Resources */ = {isa = PBXBuildFile; fileRef = 55C7A216148B2B3800C22ABC /* PcsxrMemCardDocument.xib */; };
55E0ACE0178B69620005C945 /* LaunchArg.m in Sources */ = {isa = PBXBuildFile; fileRef = 55E0ACDF178B69600005C945 /* LaunchArg.m */; };
55EC05FB1788B1230053AC23 /* PcsxrMemCardArray.m in Sources */ = {isa = PBXBuildFile; fileRef = 55EC05FA1788B1230053AC23 /* PcsxrMemCardArray.m */; };
55EC05FE178916E80053AC23 /* MemBadgeView.m in Sources */ = {isa = PBXBuildFile; fileRef = 55EC05FD178916E70053AC23 /* MemBadgeView.m */; };
712FD1E81093096F00575A92 /* debug.c in Sources */ = {isa = PBXBuildFile; fileRef = 712FD1E51093096F00575A92 /* debug.c */; };
@ -732,6 +733,8 @@
55BBA69A14958399003B2CEC /* PcsxrFreezeStateHandler.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PcsxrFreezeStateHandler.h; sourceTree = "<group>"; };
55BBA69B1495839A003B2CEC /* PcsxrFreezeStateHandler.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PcsxrFreezeStateHandler.m; sourceTree = "<group>"; };
55C7A215148B2B3800C22ABC /* English */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = English; path = English.lproj/PcsxrMemCardDocument.xib; sourceTree = "<group>"; };
55E0ACDE178B695F0005C945 /* LaunchArg.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = LaunchArg.h; sourceTree = "<group>"; };
55E0ACDF178B69600005C945 /* LaunchArg.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = LaunchArg.m; sourceTree = "<group>"; };
55EC05F91788B1230053AC23 /* PcsxrMemCardArray.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = PcsxrMemCardArray.h; sourceTree = "<group>"; };
55EC05FA1788B1230053AC23 /* PcsxrMemCardArray.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = PcsxrMemCardArray.m; sourceTree = "<group>"; };
55EC05FC178916E70053AC23 /* MemBadgeView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = MemBadgeView.h; sourceTree = "<group>"; };
@ -994,23 +997,14 @@
557649B61786AF6F007C4457 /* File Handlers */,
557649B71786AF92007C4457 /* Plug-in handling */,
557649B81786AFB7007C4457 /* Controllers */,
55E0ACE1178B850B0005C945 /* Helper Classes */,
55BB3493169CD42500850200 /* ARCBridge.h */,
7161C2810FDED6D000225F97 /* config.h */,
2BA178A505148D9D0026D74D /* main.m */,
2BBB17DA051E4D0F00B84448 /* Plugin.c */,
2BBB1791051E113B00B84448 /* EmuThread.h */,
2BBB1792051E113B00B84448 /* EmuThread.m */,
7161C2970FDED75300225F97 /* ExtendedKeys.h */,
55A90227147D89380037E18F /* PcsxrMemoryObject.h */,
55A90228147D89380037E18F /* PcsxrMemoryObject.m */,
55EC05F91788B1230053AC23 /* PcsxrMemCardArray.h */,
55EC05FA1788B1230053AC23 /* PcsxrMemCardArray.m */,
55EC05FC178916E70053AC23 /* MemBadgeView.h */,
55EC05FD178916E70053AC23 /* MemBadgeView.m */,
02717969167884DF004AED62 /* hotkeys.h */,
02717967167884C9004AED62 /* hotkeys.m */,
5550D2711683C923006C56B5 /* RecentItemsMenu.h */,
5550D2721683C923006C56B5 /* RecentItemsMenu.m */,
);
name = MacOSX;
sourceTree = "<group>";
@ -1789,6 +1783,25 @@
path = ix86_64;
sourceTree = "<group>";
};
55E0ACE1178B850B0005C945 /* Helper Classes */ = {
isa = PBXGroup;
children = (
2BBB1791051E113B00B84448 /* EmuThread.h */,
2BBB1792051E113B00B84448 /* EmuThread.m */,
55A90227147D89380037E18F /* PcsxrMemoryObject.h */,
55A90228147D89380037E18F /* PcsxrMemoryObject.m */,
55EC05F91788B1230053AC23 /* PcsxrMemCardArray.h */,
55EC05FA1788B1230053AC23 /* PcsxrMemCardArray.m */,
55E0ACDE178B695F0005C945 /* LaunchArg.h */,
55E0ACDF178B69600005C945 /* LaunchArg.m */,
55EC05FC178916E70053AC23 /* MemBadgeView.h */,
55EC05FD178916E70053AC23 /* MemBadgeView.m */,
5550D2711683C923006C56B5 /* RecentItemsMenu.h */,
5550D2721683C923006C56B5 /* RecentItemsMenu.m */,
);
name = "Helper Classes";
sourceTree = "<group>";
};
71F4C5B30FDED15800529849 /* ix86 */ = {
isa = PBXGroup;
children = (
@ -2238,6 +2251,7 @@
D422E67A16DC495800526DCF /* CheatController.m in Sources */,
55EC05FB1788B1230053AC23 /* PcsxrMemCardArray.m in Sources */,
55EC05FE178916E80053AC23 /* MemBadgeView.m in Sources */,
55E0ACE0178B69620005C945 /* LaunchArg.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};

View File

@ -7,6 +7,7 @@
#import "PcsxrPluginHandler.h"
#import "PcsxrDiscHandler.h"
#import "PcsxrFreezeStateHandler.h"
#import "LaunchArg.h"
#include "psxcommon.h"
#include "plugins.h"
#include "misc.h"
@ -366,8 +367,7 @@ HandleArgBase(arg, launchable, otherblock)
#define HandleArgBase(arg, launchable, otherblock) \
if (isLaunchable && launchable) { \
NSString *messageStr = [NSString stringWithFormat:@"The options %@ and %@ are exclusive.", arg, runtimeStr]; \
ParseErrorStr(messageStr); \
ParseErrorStr([NSString stringWithFormat:@"The options %@ and %@ are exclusive.", arg, runtimeStr]); \
} \
if(launchable) { \
isLaunchable = YES; \
@ -376,6 +376,13 @@ runtimeStr = arg; \
otherblock();\
}
#define kPCSXRArgumentCDROM @"--cdrom"
#define kPCSXRArgumentBIOS @"--bios"
#define kPCSXRArgumentISO @"--iso"
#define kPCSXRArgumentMcd @"--mcd"
#define kPCSXRArgumentFreeze @"--freeze"
#define kPCSXRArgumentExitAtClose @"--exitAtClose"
- (void)awakeFromNib
{
pluginList = [[PluginList alloc] init];
@ -404,26 +411,34 @@ otherblock();\
NSString *runtimeStr = nil;
__block short memcardHandled = 0;
__block dispatch_block_t runtimeBlock = NULL;
__block BOOL hasParsedAnArgument = NO;
__block NSString *(^FileTestBlock)() = NULL;
__block NSMutableDictionary *argDict = [[NSMutableDictionary alloc] initWithCapacity:[progArgs count]];
NSMutableArray *unknownOptions = [NSMutableArray array];
dispatch_block_t cdromBlock = ^{
hasParsedAnArgument = YES;
runtimeBlock = [^{
dispatch_block_t otherBlock = ^{
[self runCD:nil];
} copy];
};
hasParsedAnArgument = YES;
LaunchArg *larg = [[LaunchArg alloc] initWithLaunchOrder:LaunchArgRun block:otherBlock argument:kPCSXRArgumentCDROM];
[larg addToDictionary:argDict];
RELEASEOBJ(larg);
};
dispatch_block_t biosBlock = ^{
hasParsedAnArgument = YES;
runtimeBlock = [^{
dispatch_block_t runtimeBlock = ^{
[self runBios:nil];
} copy];
};
LaunchArg *larg = [[LaunchArg alloc] initWithLaunchOrder:LaunchArgRun block:runtimeBlock argument:kPCSXRArgumentBIOS];
[larg addToDictionary:argDict];
RELEASEOBJ(larg);
};
//This block/argument does not need to be sorted
dispatch_block_t emuCloseAtEnd = ^{
hasParsedAnArgument = YES;
self.endAtEmuClose = YES;
@ -432,9 +447,12 @@ otherblock();\
dispatch_block_t isoBlock = ^{
hasParsedAnArgument = YES;
NSString *path = FileTestBlock();
runtimeBlock = [^{
dispatch_block_t runtimeBlock = ^{
[self runURL:[NSURL fileURLWithPath:path isDirectory:NO]];
} copy];
};
LaunchArg *larg = [[LaunchArg alloc] initWithLaunchOrder:LaunchArgRun block:runtimeBlock argument:kPCSXRArgumentISO];
[larg addToDictionary:argDict];
RELEASEOBJ(larg);
};
void (^mcdBlock)(int mcdNumber) = ^(int mcdnumber){
@ -444,18 +462,36 @@ otherblock();\
} else {
memcardHandled |= (1 << mcdnumber);
}
NSString *path = FileTestBlock();
LoadMcd(mcdnumber, (char*)[path fileSystemRepresentation]);
dispatch_block_t runtimeBlock = ^{
LoadMcd(mcdnumber, (char*)[path fileSystemRepresentation]);
};
NSString *mcdArg = [kPCSXRArgumentMcd stringByAppendingFormat:@"%i", mcdnumber];
LaunchArg *larg = [[LaunchArg alloc] initWithLaunchOrder:LaunchArgPreRun block:runtimeBlock argument:mcdArg];
[larg addToDictionary:argDict];
RELEASEOBJ(larg);
};
dispatch_block_t freezeBlock = ^{
hasParsedAnArgument = YES;
NSString *path = FileTestBlock();
[EmuThread defrostAt:path];
dispatch_block_t runtimeBlock = ^{
if (![EmuThread isRunBios]) {
sleep(2);
[EmuThread defrostAt:path];
}
};
LaunchArg *larg = [[LaunchArg alloc] initWithLaunchOrder:LaunchArgPostRun block:runtimeBlock argument:kPCSXRArgumentFreeze];
[larg addToDictionary:argDict];
RELEASEOBJ(larg);
};
BOOL hasFileTestBlock = NO;
NSString *mcd1NSStr = [kPCSXRArgumentMcd stringByAppendingFormat:@"%i", 1];
NSString *mcd2NSStr = [kPCSXRArgumentMcd stringByAppendingFormat:@"%i", 2];
for (__block int i = 1; i < [progArgs count]; i++) {
if (!hasFileTestBlock)
{
@ -466,8 +502,7 @@ otherblock();\
NSString *path = [progArgs objectAtIndex:i];
if (![[NSFileManager defaultManager] fileExistsAtPath:path])
{
NSString *errStr = [NSString stringWithFormat:@"The file \"%@\" does not exist.", path];
ParseErrorStr(errStr);
ParseErrorStr([NSString stringWithFormat:@"The file \"%@\" does not exist.", path]);
return nil;
}
[skipFiles addObject:path];
@ -477,44 +512,48 @@ otherblock();\
}
//DO NOT END these MACROS WITH A SIMICOLON! it will break the if-else if process
HandleArg(@"--iso", YES, isoBlock)
HandleArgElse(@"--cdrom", YES, cdromBlock)
HandleArgElse(@"--bios", YES, biosBlock)
HandleArgElse(@"--exitAtClose", NO, emuCloseAtEnd)
HandleArgElse(@"--mcd1", NO, ^{mcdBlock(1);})
HandleArgElse(@"--mcd2", NO, ^{mcdBlock(2);})
HandleArgElse(@"--freeze", NO, freezeBlock)
HandleArg(kPCSXRArgumentISO, YES, isoBlock)
HandleArgElse(kPCSXRArgumentCDROM, YES, cdromBlock)
HandleArgElse(kPCSXRArgumentBIOS, YES, biosBlock)
HandleArgElse(kPCSXRArgumentExitAtClose, NO, emuCloseAtEnd)
HandleArgElse(mcd1NSStr, NO, ^{mcdBlock(1);})
HandleArgElse(mcd2NSStr, NO, ^{mcdBlock(2);})
HandleArgElse(kPCSXRArgumentFreeze, NO, freezeBlock)
else {
[unknownOptions addObject:[progArgs objectAtIndex:i]];
}
}
#ifdef DEBUG
if ([unknownOptions count]) {
NSString *unknownString = @"The following options weren't recognized by PCSX-R:";
@autoreleasepool {
for (NSString *arg in unknownOptions) {
unknownString = [NSString stringWithFormat:@"%@ %@", unknownString, arg];
}
RETAINOBJNORETURN(unknownString);
}
NSLog(@"%@. This may be due to extra arguments passed by the OS or debugger.", unknownString);
RELEASEOBJ(unknownString);
if ([unknownOptions count]) {
//As there doesn't seem to be a Cocoa/Objective-C method like this...
NSString *unknownString = CFBridgingRelease(CFStringCreateByCombiningStrings(kCFAllocatorDefault, BRIDGE(CFArrayRef, unknownOptions), CFSTR(" ")));
NSLog(@"The following options weren't recognized by PCSX-R: %@. This may be due to extra arguments passed by the OS or debugger.", unknownString);
}
#endif
if (!isLaunchable && hasParsedAnArgument) {
NSString *tmpStr = @"A launch command wasn't found in the command line and an argument that PCSX-R recognizes was.\n";
@autoreleasepool {
for (NSString *arg in progArgs) {
tmpStr = [NSString stringWithFormat:@"%@ %@", tmpStr, arg];
}
tmpStr = [NSString stringWithFormat:@"%@\n\nThe valid launch commands are --iso, --cdrom, and --bios", tmpStr];
RETAINOBJNORETURN(tmpStr);
}
ParseErrorStr(AUTORELEASEOBJ(tmpStr));
NSString *tmpStr = @"";
NSString *arg = CFBridgingRelease(CFStringCreateByCombiningStrings(kCFAllocatorDefault, BRIDGE(CFArrayRef, progArgs), CFSTR(" ")));
tmpStr = [NSString stringWithFormat:@"A launch command wasn't found in the command line and an argument that PCSX-R recognizes was: %@\n\nThe valid launch commands are --iso, --cdrom, and --bios.", arg];
ParseErrorStr(tmpStr);
} else if (hasParsedAnArgument){
runtimeBlock();
RELEASEOBJ(runtimeBlock);
NSArray *argArray = [[argDict allValues] sortedArrayUsingComparator:^NSComparisonResult(id obj1, id obj2) {
LaunchArg *LA1 = obj1;
LaunchArg *LA2 = obj2;
if (LA1.launchOrder > LA2.launchOrder) {
return NSOrderedDescending;
} else if (LA1.launchOrder < LA2.launchOrder) {
return NSOrderedAscending;
} else {
return [LA1.argument compare:LA2.argument];
}
}];
for (LaunchArg *arg in argArray) {
arg.theBlock();
}
}
RELEASEOBJ(argDict);
}
}