diff options
| author | SND\MaddTheSane_cp <SND\MaddTheSane_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2013-08-17 20:12:12 +0000 |
|---|---|---|
| committer | SND\MaddTheSane_cp <SND\MaddTheSane_cp@e17a0e51-4ae3-4d35-97c3-1a29b211df97> | 2013-08-17 20:12:12 +0000 |
| commit | 5be0778eaa7d48dfb71f4619e2e6b73b9095ad62 (patch) | |
| tree | c5f270d8777bd621c737ef3b0d195e1c89808677 /macosx/CheatController.m | |
| parent | 37ba81a540460a7d34a33c23d2353ac84f887576 (diff) | |
| download | pcsxr-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.m | 287 |
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 |
