summaryrefslogtreecommitdiff
path: root/macosx/CheatController.m
diff options
context:
space:
mode:
authorSND\MaddTheSane_cp <SND\MaddTheSane_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2013-08-17 20:12:12 +0000
committerSND\MaddTheSane_cp <SND\MaddTheSane_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97>2013-08-17 20:12:12 +0000
commit5be0778eaa7d48dfb71f4619e2e6b73b9095ad62 (patch)
treec5f270d8777bd621c737ef3b0d195e1c89808677 /macosx/CheatController.m
parent37ba81a540460a7d34a33c23d2353ac84f887576 (diff)
downloadpcsxr-5be0778eaa7d48dfb71f4619e2e6b73b9095ad62.tar.gz
Finish work on OS X's cheat management.
There is still a bug that changing the label/name of the cheat doesn't set the changed bit. git-svn-id: https://pcsxr.svn.codeplex.com/svn/pcsxr@86707 e17a0e51-4ae3-4d35-97c3-1a29b211df97
Diffstat (limited to 'macosx/CheatController.m')
-rw-r--r--macosx/CheatController.m287
1 files changed, 212 insertions, 75 deletions
diff --git a/macosx/CheatController.m b/macosx/CheatController.m
index 17bbab9e..2e5976f2 100644
--- a/macosx/CheatController.m
+++ b/macosx/CheatController.m
@@ -9,21 +9,35 @@
#import "CheatController.h"
#import "ARCBridge.h"
#import "PcsxrCheatHandler.h"
+#import "PcsxrHexadecimalFormatter.h"
#define kTempCheatCodesName @"tempCheatCodes"
-@interface PcsxrCheatTempObject : NSObject
+#define kCheatsName @"cheats"
+@implementation PcsxrCheatTempObject
+@synthesize address, value;
+
+- (NSNumber *)addressNS
{
- uint32_t address;
- uint16_t value;
+ return @(self.address);
+}
+- (void)setAddressNS:(NSNumber *)addressNS
+{
+ self.address = [addressNS unsignedIntValue];
}
-@property (readwrite) uint32_t address;
-@property (readwrite) uint16_t value;
-- (id)initWithAddress:(uint32_t)add value:(uint16_t)val;
-@end
+- (NSNumber *)valueNS
+{
+ return @(self.value);
+}
+- (void)setValueNS:(NSNumber *)valueNS
+{
+ self.value = [valueNS unsignedShortValue];
+}
-@implementation PcsxrCheatTempObject
-@synthesize address, value;
+- (id)init
+{
+ return self = [self initWithAddress:0x10000000 value:0];
+}
- (id)initWithAddress:(uint32_t)add value:(uint16_t)val
{
@@ -41,13 +55,88 @@
- (NSString*)description
{
- return [NSString stringWithFormat:@"%u %u", address, value];
+ return [NSString stringWithFormat:@"%08x %04x", address, value];
+}
+
+- (BOOL)isEqual:(id)object
+{
+ if ([object isKindOfClass:[PcsxrCheatTempObject class]]) {
+ if (address != [(PcsxrCheatTempObject*)object address]) {
+ return NO;
+ } else if (value != [(PcsxrCheatTempObject*)object value]) {
+ return NO;
+ } else
+ return YES;
+ } else
+ return NO;
+}
+
+- (id)copyWithZone:(NSZone *)zone
+{
+ return [[[self class] alloc] initWithAddress:address value:value];
+}
+
+@end
+
+@implementation PcsxrCheatTemp
+@synthesize cheatName;
+@synthesize cheatValues;
+@synthesize enabled;
+
+- (void)setCheatName:(NSString *)_cheatName
+{
+ if ([cheatName isEqualToString:_cheatName]) {
+ return;
+ }
+ [self willChangeValueForKey:@"cheatName"];
+#if __has_feature(objc_arc)
+ cheatName = _cheatName;
+#else
+ NSString *temp = cheatName;
+ cheatName = [_cheatName copy];
+ [temp release];
+#endif
+ [self didChangeValueForKey:@"cheatName"];
+}
+
+- (id)initWithCheat:(Cheat *)theCheat
+{
+ if (self = [super init]) {
+ self.cheatName = @(theCheat->Descr);
+ self.enabled = theCheat->Enabled ? YES : NO;
+ self.cheatValues = [NSMutableArray arrayWithCapacity:theCheat->n];
+ for (int i = 0; i < theCheat->n; i++) {
+ [cheatValues addObject:AUTORELEASEOBJ([[PcsxrCheatTempObject alloc] initWithCheatCode:&CheatCodes[i+theCheat->First]])];
+ }
+ }
+ return self;
+}
+
+- (NSString *)description
+{
+ return [NSString stringWithFormat:@"[%@%@]\n%@", enabled ? @"*" : @"", cheatName, [cheatValues componentsJoinedByString:@"\n"]];
+}
+
+#if !__has_feature(objc_arc)
+- (void)dealloc
+{
+ self.cheatName = nil;
+ self.cheatValues = nil;
+
+ [super dealloc];
}
+#endif
@end
@implementation CheatController
@synthesize tempCheatCodes;
+@synthesize cheats;
+
+- (NSString *)windowNibName
+{
+ return @"CheatWindow";
+}
- (id)init
{
@@ -57,7 +146,7 @@
- (id)initWithCoder:(NSCoder *)aDecoder
{
if (self = [super initWithCoder:aDecoder]) {
- self.tempCheatCodes = AUTORELEASEOBJ([[NSMutableArray alloc] init]);
+ self.tempCheatCodes = [NSMutableArray array];
}
return self;
}
@@ -65,62 +154,41 @@
- (id)initWithWindow:(NSWindow *)window
{
if (self = [super initWithWindow:window]) {
- self.tempCheatCodes = AUTORELEASEOBJ([[NSMutableArray alloc] init]);
+ self.tempCheatCodes = [NSMutableArray array];
}
return self;
}
-- (void)refresh
+- (void)refreshNSCheatArray
{
- [cheatView reloadData];
+ NSMutableArray *tmpArray = [[NSMutableArray alloc] initWithCapacity:NumCheats];
+ for (int i = 0; i < NumCheats; i++) {
+ [tmpArray addObject:AUTORELEASEOBJ([[PcsxrCheatTemp alloc] initWithCheat:&Cheats[i]])];
+ }
+ self.cheats = tmpArray;
+ RELEASEOBJ(tmpArray);
+ [self setDocumentEdited:NO];
}
-- (NSInteger)numberOfRowsInTableView:(NSTableView *)view
+- (void)observeValueForKeyPath:(NSString *)keyPath ofObject:(id)object change:(NSDictionary *)change context:(void *)context
{
- if (view == cheatView) {
- return NumCheats;
- } else
- return 0;
+ if ([keyPath isEqualToString:kCheatsName]) {
+ [self setDocumentEdited:YES];
+ }
}
-- (id)tableView:(NSTableView *)tableView objectValueForTableColumn:(NSTableColumn *)col row:(NSInteger)idx
+- (void)refresh
{
- if (tableView == cheatView) {
- if (idx >= NumCheats)
- return nil;
- NSString *ident = [col identifier];
- if ([ident isEqualToString:@"COL_NAME"]) {
- return @(Cheats[idx].Descr);
- } else if ([ident isEqualToString:@"COL_ENABLE"]) {
- return @( Cheats[idx].Enabled ? NSOnState : NSOffState);
- }
- NSLog(@"Unknown column identifier: %@", ident);
- return nil;
- } else
- return nil;
+ [cheatView reloadData];
+ [self refreshNSCheatArray];
}
-#if 0
- (void)awakeFromNib
{
- [addressFormatter setPositivePrefix:@"0x"];
- [valueFormatter setPositivePrefix:@"0x"];
-}
-#endif
-
-- (void)tableView:(NSTableView *)tableView setObjectValue:(id)object forTableColumn:(NSTableColumn *)col row:(NSInteger)row
-{
- if (tableView == cheatView) {
- if (row >= NumCheats)
- return;
- NSString *ident = [col identifier];
- if ([ident isEqualToString:@"COL_ENABLE"]) {
- Cheats[row].Enabled = [object integerValue] == NSOnState;
- } else if ([ident isEqualToString:@"COL_NAME"]) {
- free(Cheats[row].Descr);
- Cheats[row].Descr = strdup([object UTF8String]);
- }
- }
+ [valueFormatter setHexPadding:4];
+ [addressFormatter setHexPadding:8];
+ [self refreshNSCheatArray];
+ [self addObserver:self forKeyPath:kCheatsName options:NSKeyValueObservingOptionNew | NSKeyValueObservingOptionOld context:NULL];
}
- (IBAction)loadCheats:(id)sender
@@ -148,15 +216,15 @@
[saveDlg setPrompt:NSLocalizedString(@"Save Cheats", nil)];
if ([saveDlg runModal] == NSFileHandlingPanelOKButton) {
NSURL *url = [saveDlg URL];
- SaveCheats([[url path] fileSystemRepresentation]);
+ NSString *saveString = [cheats componentsJoinedByString:@"\n"];
+ [saveString writeToURL:url atomically:YES encoding:NSUTF8StringEncoding error:NULL];
}
RELEASEOBJ(saveDlg);
}
- (IBAction)clear:(id)sender
{
- ClearAllCheats();
- [self refresh];
+ self.cheats = [NSMutableArray array];
}
- (IBAction)closeCheatEdit:(id)sender
@@ -164,8 +232,18 @@
[NSApp endSheet:editCheatWindow returnCode:[sender tag] == 1 ? NSCancelButton : NSOKButton];
}
+- (IBAction)changeCheat:(id)sender
+{
+ [self setDocumentEdited:YES];
+}
+
- (IBAction)removeCheatValue:(id)sender
{
+ if ([editCheatView selectedRow] < 0) {
+ NSBeep();
+ return;
+ }
+
NSIndexSet *toRemoveIndex = [editCheatView selectedRowIndexes];
[self willChange:NSKeyValueChangeRemoval valuesAtIndexes:toRemoveIndex forKey:kTempCheatCodesName];
[tempCheatCodes removeObjectsAtIndexes:toRemoveIndex];
@@ -176,19 +254,27 @@
{
[self willChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndex:[tempCheatCodes count]] forKey:kTempCheatCodesName];
[tempCheatCodes addObject:AUTORELEASEOBJ([[PcsxrCheatTempObject alloc] init])];
- [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndex:[tempCheatCodes count]] forKey:kTempCheatCodesName];
+ [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndex:[tempCheatCodes count] - 1] forKey:kTempCheatCodesName];
+}
+
+- (void)reloadCheats
+{
+ NSFileManager *manager = [NSFileManager defaultManager];
+ NSURL *tmpURL = [[manager URLForDirectory:NSItemReplacementDirectory inDomain:NSUserDomainMask appropriateForURL:[[NSBundle mainBundle] bundleURL] create:YES error:nil] URLByAppendingPathComponent:@"temp.cht" isDirectory:NO];
+ NSString *tmpStr = [cheats componentsJoinedByString:@"\n"];
+ [tmpStr writeToURL:tmpURL atomically:NO encoding:NSUTF8StringEncoding error:NULL];
+ LoadCheats([[tmpURL path] fileSystemRepresentation]);
+ [manager removeItemAtURL:tmpURL error:NULL];
}
- (void)editCheatCodeSheetDidEnd:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo
{
if (returnCode == NSOKButton) {
- //FIXME: Expand the current cheat code list as needed
- //FIXME: Contract the current cheat code list as needed
-
- const char *tmpCheat = [[tempCheatCodes componentsJoinedByString:@"\n"] cStringUsingEncoding:NSASCIIStringEncoding];
- char *cheatCpy = strdup(tmpCheat);
- EditCheat((int)[cheatView selectedRow], Cheats[[cheatView selectedRow]].Descr, cheatCpy);
- free(cheatCpy);
+ PcsxrCheatTemp *tmpCheat = [cheats objectAtIndex:[cheatView selectedRow]];
+ if (![tmpCheat.cheatValues isEqualToArray:tempCheatCodes]) {
+ tmpCheat.cheatValues = tempCheatCodes;
+ [self setDocumentEdited:YES];
+ }
}
[sheet orderOut:nil];
@@ -196,24 +282,75 @@
- (IBAction)editCheat:(id)sender
{
- [self willChangeValueForKey:kTempCheatCodesName];
- [tempCheatCodes removeAllObjects];
-
- Cheat *currentCheat = &Cheats[[cheatView selectedRow]];
-
- for (NSInteger i = 0; i < currentCheat->n; i++) {
- CheatCode *curCode = &CheatCodes[currentCheat->First + i];
- PcsxrCheatTempObject *tmpobj = [[PcsxrCheatTempObject alloc] initWithCheatCode:curCode];
- [tempCheatCodes addObject:tmpobj];
- RELEASEOBJ(tmpobj);
+ if ([cheatView selectedRow] < 0) {
+ NSBeep();
+ return;
}
- [self didChangeValueForKey:kTempCheatCodesName];
+ NSMutableArray *tmpArray = [[cheats objectAtIndex:[cheatView selectedRow]] cheatValues];
+ NSMutableArray *newCheats = [[NSMutableArray alloc] initWithArray:tmpArray copyItems:YES];
+ self.tempCheatCodes = newCheats;
+ RELEASEOBJ(newCheats);
[NSApp beginSheet:editCheatWindow modalForWindow:[self window] modalDelegate:self didEndSelector:@selector(editCheatCodeSheetDidEnd:returnCode:contextInfo:) contextInfo:NULL];
}
- (IBAction)addCheat:(id)sender
{
- AddCheat(NULL, "0 0");
+ [self willChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndex:[cheats count]] forKey:kCheatsName];
+ PcsxrCheatTemp *tmpCheat = [[PcsxrCheatTemp alloc] init];
+ tmpCheat.cheatName = NSLocalizedString(@"New Cheat", @"New Cheat Name" );
+ PcsxrCheatTempObject *tmpObj = [[PcsxrCheatTempObject alloc] initWithAddress:0x10000000 value:0];
+ NSMutableArray *tmpArray = [NSMutableArray arrayWithObject:tmpObj];
+ RELEASEOBJ(tmpObj);
+ tmpCheat.cheatValues = tmpArray;
+ [cheats addObject:tmpCheat];
+ RELEASEOBJ(tmpCheat);
+ [self didChange:NSKeyValueChangeInsertion valuesAtIndexes:[NSIndexSet indexSetWithIndex:[cheats count] - 1] forKey:kCheatsName];
+ [self setDocumentEdited:YES];
+}
+
+- (IBAction)applyCheats:(id)sender
+{
+ [self reloadCheats];
+ [self setDocumentEdited:NO];
+}
+
+- (BOOL)windowShouldClose:(id)sender
+{
+ if (![sender isDocumentEdited] || ![[self window] isEqual:sender]) {
+ return YES;
+ } else {
+ //TODO: properly use a non-deprecated method here.
+ NSInteger retVal = NSRunAlertPanelRelativeToWindow(NSLocalizedString(@"Unsaved Changes", @"Unsaved changes"), NSLocalizedString(@"The Cheat codes have not been applied. Unapplied cheats will not run nor be saved. Do you wish to save?",nil), NSLocalizedString(@"Save", @"Save"), NSLocalizedString(@"Don't Save",@"Don't Save"), NSLocalizedString(@"Cancel", @"Cancel"), sender);
+ switch (retVal) {
+ case NSAlertDefaultReturn:
+ [self reloadCheats];
+ return YES;
+ break;
+
+ default:
+ [self refreshNSCheatArray];
+ return YES;
+ break;
+
+ case NSAlertOtherReturn:
+ return NO;
+ break;
+ }
+ }
+}
+
+- (IBAction)removeCheats:(id)sender
+{
+ if ([cheatView selectedRow] < 0) {
+ NSBeep();
+ return;
+ }
+
+ NSIndexSet *toRemoveIndex = [cheatView selectedRowIndexes];
+ [self willChange:NSKeyValueChangeRemoval valuesAtIndexes:toRemoveIndex forKey:kCheatsName];
+ [cheats removeObjectsAtIndexes:toRemoveIndex];
+ [self didChange:NSKeyValueChangeRemoval valuesAtIndexes:toRemoveIndex forKey:kCheatsName];
+ [self setDocumentEdited:YES];
}
@end