Cocoa Port: Continue refactoring the cheat system code.

- Add ClientCheatManager C++ class, further reducing dependence on Objective-C code.
This commit is contained in:
rogerman 2023-07-02 22:54:13 -07:00
parent 946f7df9bc
commit d00e6355da
7 changed files with 909 additions and 456 deletions

View File

@ -24,6 +24,7 @@
class CHEATS; class CHEATS;
class CHEATS_LIST; class CHEATS_LIST;
class CHEATSEARCH; class CHEATSEARCH;
class ClientCheatManager;
enum CheatType enum CheatType
{ {
@ -52,12 +53,13 @@ enum CheatSystemError
class ClientCheatItem class ClientCheatItem
{ {
protected: protected:
ClientCheatManager *_cheatManager;
bool _isEnabled; bool _isEnabled;
bool _willAddFromDB; bool _willAddFromDB;
CheatType _cheatType; CheatType _cheatType;
std::string _descriptionString; std::string _descriptionString;
void *_clientData;
// Internal cheat type parameters // Internal cheat type parameters
CheatFreezeType _freezeType; CheatFreezeType _freezeType;
@ -81,6 +83,9 @@ public:
void Init(const CHEATS_LIST &inCheatItem); void Init(const CHEATS_LIST &inCheatItem);
void Init(const ClientCheatItem &inCheatItem); void Init(const ClientCheatItem &inCheatItem);
void SetCheatManager(ClientCheatManager *cheatManager);
ClientCheatManager* GetCheatManager() const;
void SetEnabled(bool theState); void SetEnabled(bool theState);
bool IsEnabled() const; bool IsEnabled() const;
@ -111,6 +116,7 @@ public:
void SetRawCodeString(const char *rawString, const bool willSaveValidatedRawString); void SetRawCodeString(const char *rawString, const bool willSaveValidatedRawString);
const char* GetRawCodeString() const; const char* GetRawCodeString() const;
const char* GetCleanCodeString() const; const char* GetCleanCodeString() const;
const std::string& GetCleanCodeCppString() const;
uint32_t GetCodeCount() const; uint32_t GetCodeCount() const;
void ClientToDesmumeCheatItem(CHEATS_LIST *outCheatItem) const; void ClientToDesmumeCheatItem(CHEATS_LIST *outCheatItem) const;
@ -118,9 +124,11 @@ public:
class ClientCheatList class ClientCheatList
{ {
private:
ClientCheatItem* __AddItem(const ClientCheatItem *srcItem, const bool willCopy, const bool allowDuplicates);
protected: protected:
std::vector<ClientCheatItem *> *_list; std::vector<ClientCheatItem *> *_list;
bool _engineNeedsUpdate;
public: public:
ClientCheatList(); ClientCheatList();
@ -129,41 +137,97 @@ public:
CheatSystemError LoadFromFile(const char *filePath); CheatSystemError LoadFromFile(const char *filePath);
CheatSystemError SaveToFile(const char *filePath); CheatSystemError SaveToFile(const char *filePath);
bool IsItemDuplicate(const ClientCheatItem *srcItem);
ClientCheatItem* AddNew(); ClientCheatItem* AddNew();
ClientCheatItem* Add(ClientCheatItem *srcItem); ClientCheatItem* AddNewItemCopy(const ClientCheatItem *srcItem);
ClientCheatItem* AddNoDuplicate(ClientCheatItem *srcItem); ClientCheatItem* AddNewItemCopyNoDuplicate(const ClientCheatItem *srcItem);
void Remove(ClientCheatItem *targetItem); ClientCheatItem* AddExistingItemNoDuplicate(const ClientCheatItem *srcItem);
void RemoveAtIndex(size_t index);
bool Remove(ClientCheatItem *targetItem);
bool RemoveAtIndex(size_t index);
void RemoveAll(); void RemoveAll();
void Update(const ClientCheatItem &srcItem, ClientCheatItem *targetItem);
ClientCheatItem* UpdateAtIndex(const ClientCheatItem &srcItem, size_t index); bool Update(const ClientCheatItem &srcItem, ClientCheatItem *targetItem);
bool UpdateAtIndex(const ClientCheatItem &srcItem, size_t index);
size_t GetTotalCheatCount() const; size_t GetTotalCheatCount() const;
size_t GetActiveCheatCount() const; size_t GetActiveCheatCount() const;
std::vector<ClientCheatItem *>* GetCheatList() const; std::vector<ClientCheatItem *>* GetCheatList() const;
size_t GetIndexOfItem(const ClientCheatItem *cheatItem) const;
ClientCheatItem* GetItemAtIndex(size_t index) const; ClientCheatItem* GetItemAtIndex(size_t index) const;
void ReplaceFromEngine(const CHEATS *engineCheatList); void ReplaceFromEngine(const CHEATS *engineCheatList);
void CopyListToEngine(const bool willApplyOnlyEnabledItems, CHEATS *engineCheatList); void CopyListToEngine(const bool willApplyOnlyEnabledItems, CHEATS *engineCheatList);
void ApplyListToEngine();
static CHEATS* GetMasterCheatList();
}; };
/******************************************************************************************** class ClientCheatManager
CocoaDSCheatItem - OBJECTIVE-C CLASS {
protected:
ClientCheatList *_workingList;
ClientCheatList *_databaseList;
ClientCheatItem *_selectedItem;
size_t _selectedItemIndex;
uint32_t _untitledCount;
This is an Objective-C wrapper class for DeSmuME's cheat item struct. std::string _databaseTitle;
std::string _databaseDate;
std::string _lastFilePath;
The cheat item data is not freed upon release of this object. This is by design. bool _masterNeedsUpdate;
public:
ClientCheatManager();
~ClientCheatManager();
static CHEATS* GetMaster();
static void SetMaster(const CHEATS *masterCheats);
ClientCheatList* GetWorkingList() const;
ClientCheatList* GetDatabaseList() const;
const char* GetDatabaseTitle() const;
void SetDatabaseTitle(const char *dbTitle);
const char* GetDatabaseDate() const;
void SetDatabaseDate(const char *dbDate);
const char* GetLastFilePath() const;
virtual CheatSystemError LoadFromFile(const char *filePath);
virtual CheatSystemError SaveToFile(const char *filePath);
ClientCheatItem* SetSelectedItemByIndex(size_t index);
ClientCheatItem* NewItem();
ClientCheatItem* AddExistingItemNoDuplicate(const ClientCheatItem *theItem);
void RemoveItem(ClientCheatItem *theItem);
void RemoveItemAtIndex(size_t index);
void RemoveSelectedItem();
void ModifyItem(const ClientCheatItem *srcItem, ClientCheatItem *targetItem);
void ModifyItemAtIndex(const ClientCheatItem *srcItem, size_t index);
size_t GetTotalCheatCount() const;
size_t GetActiveCheatCount() const;
ClientCheatList* LoadFromDatabase(const char *dbFilePath);
void LoadFromMaster();
void ApplyToMaster();
void MasterNeedsUpdate();
void ApplyInternalCheatAtIndex(size_t index);
static void ApplyInternalCheatWithItem(const ClientCheatItem *cheatItem);
static void ApplyInternalCheatWithParams(uint32_t targetAddress, uint32_t newValue, size_t newValueLength);
};
Thread Safety:
Assume that all methods are not thread-safe. This was done for performance
reasons. The caller of this class' methods is expected to handle thread safety.
********************************************************************************************/
@interface CocoaDSCheatItem : NSObject @interface CocoaDSCheatItem : NSObject
{ {
ClientCheatItem *_internalData; ClientCheatItem *_internalData;
BOOL _didAllocateInternalData;
BOOL _disableWorkingCopyUpdate;
BOOL willAdd; BOOL willAdd;
CocoaDSCheatItem *workingCopy; CocoaDSCheatItem *workingCopy;
@ -190,8 +254,8 @@ public:
@property (readonly) CocoaDSCheatItem *workingCopy; @property (readonly) CocoaDSCheatItem *workingCopy;
@property (assign) CocoaDSCheatItem *parent; @property (assign) CocoaDSCheatItem *parent;
- (id) initWithCheatItem:(ClientCheatItem *)cheatItem;
- (id) initWithCocoaCheatItem:(CocoaDSCheatItem *)cdsCheatItem; - (id) initWithCocoaCheatItem:(CocoaDSCheatItem *)cdsCheatItem;
- (id) initWithCheatItem:(ClientCheatItem *)cheatItem;
- (id) initWithCheatData:(const CHEATS_LIST *)cheatData; - (id) initWithCheatData:(const CHEATS_LIST *)cheatData;
- (char *) descriptionCString; - (char *) descriptionCString;
- (void) update; - (void) update;
@ -208,49 +272,31 @@ public:
@end @end
/********************************************************************************************
CocoaDSCheatManager - OBJECTIVE-C CLASS
This is an Objective-C wrapper class for DeSmuME's cheat list class.
Thread Safety:
All methods are thread-safe.
********************************************************************************************/
@interface CocoaDSCheatManager : NSObject @interface CocoaDSCheatManager : NSObject
{ {
ClientCheatList *_clientListData; ClientCheatManager *_internalCheatManager;
NSMutableArray *list; NSMutableArray *list;
NSUInteger untitledCount;
NSString *dbTitle;
NSString *dbDate;
NSURL *lastFileURL;
} }
@property (readonly, nonatomic, getter=clientListData) ClientCheatList *_clientListData; @property (readonly, nonatomic, getter=internalManager) ClientCheatManager *_internalCheatManager;
@property (readonly) NSMutableArray *list; @property (readonly) NSMutableArray *list;
@property (assign) NSUInteger untitledCount; @property (assign, nonatomic) NSString *dbTitle;
@property (copy) NSString *dbTitle; @property (assign, nonatomic) NSString *dbDate;
@property (copy) NSString *dbDate;
@property (retain) NSURL *lastFileURL;
- (id) initWithFileURL:(NSURL *)fileURL; - (id) initWithFileURL:(NSURL *)fileURL;
- (BOOL) add:(CocoaDSCheatItem *)cheatItem; - (CocoaDSCheatItem *) newItem;
- (BOOL) addExistingItem:(CocoaDSCheatItem *)cheatItem;
- (void) remove:(CocoaDSCheatItem *)cheatItem; - (void) remove:(CocoaDSCheatItem *)cheatItem;
- (BOOL) update:(CocoaDSCheatItem *)cheatItem; - (BOOL) update:(CocoaDSCheatItem *)cheatItem;
- (BOOL) save; - (BOOL) save;
- (NSUInteger) activeCount; - (NSUInteger) activeCount;
- (NSMutableArray *) cheatListFromDatabase:(NSURL *)fileURL errorCode:(NSInteger *)error; - (NSMutableArray *) cheatListFromDatabase:(NSURL *)fileURL errorCode:(NSInteger *)error;
- (void) applyInternalCheat:(CocoaDSCheatItem *)cheatItem; - (void) applyInternalCheat:(CocoaDSCheatItem *)cheatItem;
- (void) loadFromEngine; - (void) loadFromMaster;
- (void) applyListToEngine; - (void) applyToMaster;
+ (void) applyInternalCheatWithItem:(CocoaDSCheatItem *)cheatItem;
+ (void) applyInternalCheatWithAddress:(UInt32)address value:(UInt32)value bytes:(NSUInteger)bytes;
+ (NSMutableArray *) cheatListWithListObject:(CHEATS *)cheatList;
+ (NSMutableArray *) cheatListWithClientListObject:(ClientCheatList *)cheatList; + (NSMutableArray *) cheatListWithClientListObject:(ClientCheatList *)cheatList;
+ (NSMutableArray *) cheatListWithItemStructArray:(CHEATS_LIST *)cheatItemArray count:(NSUInteger)itemCount;
@end @end

File diff suppressed because it is too large Load Diff

View File

@ -170,7 +170,7 @@ volatile bool execute = true;
macOS_driver *newDriver = new macOS_driver; macOS_driver *newDriver = new macOS_driver;
newDriver->SetCoreThreadMutexLock(&threadParam.mutexThreadExecute); newDriver->SetCoreThreadMutexLock(&threadParam.mutexThreadExecute);
newDriver->SetCoreExecuteRWLock(self.rwlockCoreExecute); newDriver->SetCoreExecuteRWLock(&threadParam.rwlockCoreExecute);
newDriver->SetExecutionControl(execControl); newDriver->SetExecutionControl(execControl);
driver = newDriver; driver = newDriver;
@ -1151,6 +1151,7 @@ static void* RunCoreThread(void *arg)
CoreThreadParam *param = (CoreThreadParam *)arg; CoreThreadParam *param = (CoreThreadParam *)arg;
CocoaDSCore *cdsCore = (CocoaDSCore *)param->cdsCore; CocoaDSCore *cdsCore = (CocoaDSCore *)param->cdsCore;
CocoaDSGPU *cdsGPU = [cdsCore cdsGPU]; CocoaDSGPU *cdsGPU = [cdsCore cdsGPU];
ClientCheatManager *cheatManager = [[cdsCore cdsCheatManager] internalManager];
ClientExecutionControl *execControl = [cdsCore execControl]; ClientExecutionControl *execControl = [cdsCore execControl];
ClientInputHandler *inputHandler = execControl->GetClientInputHandler(); ClientInputHandler *inputHandler = execControl->GetClientInputHandler();
NSMutableArray *cdsOutputList = [cdsCore cdsOutputList]; NSMutableArray *cdsOutputList = [cdsCore cdsOutputList];
@ -1229,11 +1230,9 @@ static void* RunCoreThread(void *arg)
avCaptureObject = NULL; avCaptureObject = NULL;
} }
ClientCheatList *cheatList = [[cdsCore cdsCheatManager] clientListData];
cheatList->ApplyListToEngine();
// Execute the frame and increment the frame counter. // Execute the frame and increment the frame counter.
pthread_rwlock_wrlock(&param->rwlockCoreExecute); pthread_rwlock_wrlock(&param->rwlockCoreExecute);
cheatManager->ApplyToMaster();
NDS_exec<false>(); NDS_exec<false>();
SPU_Emulate_user(); SPU_Emulate_user();
execControl->FetchOutputPostNDSExec(); execControl->FetchOutputPostNDSExec();

View File

@ -1206,7 +1206,7 @@ void UpdateDisplayPropertiesFromStates(uint64_t displayModeStates, ClientDisplay
[cheatItem setValue:0]; // UNUSED [cheatItem setValue:0]; // UNUSED
[cheatItem setEnabled:enabled]; [cheatItem setEnabled:enabled];
[[self cdsCheats] add:cheatItem]; [[self cdsCheats] addExistingItem:cheatItem];
// OpenEmu doesn't currently save cheats per game, so assume that the // OpenEmu doesn't currently save cheats per game, so assume that the
// cheat list is short and that code strings are unique. This allows // cheat list is short and that code strings are unique. This allows

View File

@ -1936,7 +1936,7 @@
CocoaDSCheatManager *newCheatList = [cdsCore cdsCheatManager]; CocoaDSCheatManager *newCheatList = [cdsCore cdsCheatManager];
if (newCheatList != nil) if (newCheatList != nil)
{ {
[newCheatList loadFromEngine]; [newCheatList loadFromMaster];
NSMutableDictionary *cheatWindowBindings = (NSMutableDictionary *)[cheatWindowController content]; NSMutableDictionary *cheatWindowBindings = (NSMutableDictionary *)[cheatWindowController content];

View File

@ -1,6 +1,6 @@
/* /*
Copyright (C) 2011 Roger Manuel Copyright (C) 2011 Roger Manuel
Copyright (C) 2012 DeSmuME team Copyright (C) 2012-2023 DeSmuME team
This file is free software: you can redistribute it and/or modify This file is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
@ -57,7 +57,6 @@
NSWindow *cheatDatabaseSheet; NSWindow *cheatDatabaseSheet;
NSUInteger untitledCount;
NSFont *codeEditorFont; NSFont *codeEditorFont;
NSMutableDictionary *bindings; NSMutableDictionary *bindings;
@ -92,7 +91,6 @@
@property (readonly) IBOutlet NSWindow *cheatDatabaseSheet; @property (readonly) IBOutlet NSWindow *cheatDatabaseSheet;
@property (assign) NSUInteger untitledCount;
@property (assign) NSFont *codeEditorFont; @property (assign) NSFont *codeEditorFont;
@property (readonly) NSMutableDictionary *bindings; @property (readonly) NSMutableDictionary *bindings;
@property (retain) CocoaDSCheatItem *workingCheat; @property (retain) CocoaDSCheatItem *workingCheat;

View File

@ -50,7 +50,6 @@
@synthesize cheatDatabaseSheet; @synthesize cheatDatabaseSheet;
@synthesize untitledCount;
@synthesize codeEditorFont; @synthesize codeEditorFont;
@synthesize bindings; @synthesize bindings;
@synthesize cdsCheats; @synthesize cdsCheats;
@ -85,7 +84,6 @@
workingCheat = nil; workingCheat = nil;
currentView = nil; currentView = nil;
currentSearchStyleView = nil; currentSearchStyleView = nil;
untitledCount = 0;
codeEditorFont = [NSFont fontWithName:@"Monaco" size:13.0]; codeEditorFont = [NSFont fontWithName:@"Monaco" size:13.0];
[bindings setValue:[NSNumber numberWithBool:NO] forKey:@"hasSelection"]; [bindings setValue:[NSNumber numberWithBool:NO] forKey:@"hasSelection"];
@ -108,8 +106,8 @@
- (void)dealloc - (void)dealloc
{ {
self.workingCheat = nil; [self setWorkingCheat:nil];
self.cdsCheats = nil; [self setCdsCheats:nil];
[cdsCheatSearch release]; [cdsCheatSearch release];
[bindings release]; [bindings release];
@ -118,38 +116,24 @@
- (IBAction) addToList:(id)sender - (IBAction) addToList:(id)sender
{ {
if (self.cdsCheats == nil) if ([self cdsCheats] == nil)
{ {
return; return;
} }
NSString *untitledString = nil; CocoaDSCheatItem *newCheatItem = [[[self cdsCheats] newItem] autorelease];
if (newCheatItem != nil)
self.untitledCount++;
if (self.untitledCount > 1)
{ {
untitledString = [NSString stringWithFormat:@"Untitled %ld", (unsigned long)self.untitledCount];
}
else
{
untitledString = @"Untitled";
}
CocoaDSCheatItem *newCheatItem = [[[CocoaDSCheatItem alloc] init] autorelease];
newCheatItem.cheatType = CHEAT_TYPE_INTERNAL;
newCheatItem.description = untitledString;
[cheatListController addObject:newCheatItem]; [cheatListController addObject:newCheatItem];
[self.cdsCheats add:newCheatItem];
[self.cdsCheats save];
[bindings setValue:[NSNumber numberWithBool:YES] forKey:@"hasItems"]; [bindings setValue:[NSNumber numberWithBool:YES] forKey:@"hasItems"];
[[self cdsCheats] save];
}
} }
- (IBAction) removeFromList:(id)sender - (IBAction) removeFromList:(id)sender
{ {
NSMutableArray *cheatList = (NSMutableArray *)[cheatListController content]; NSMutableArray *cheatList = (NSMutableArray *)[cheatListController content];
if (cdsCheats == nil || cheatList == nil) if ( ([self cdsCheats] == nil) || (cheatList == nil) )
{ {
return; return;
} }
@ -164,10 +148,10 @@
NSArray *selectedObjects = [cheatListController selectedObjects]; NSArray *selectedObjects = [cheatListController selectedObjects];
CocoaDSCheatItem *selectedCheat = (CocoaDSCheatItem *)[selectedObjects objectAtIndex:0]; CocoaDSCheatItem *selectedCheat = (CocoaDSCheatItem *)[selectedObjects objectAtIndex:0];
[self.cdsCheats remove:selectedCheat]; [[self cdsCheats] remove:selectedCheat];
[cheatListController removeObject:selectedCheat]; [cheatListController removeObject:selectedCheat];
[self.cdsCheats save]; [[self cdsCheats] save];
[cheatListTable deselectAll:sender]; [cheatListTable deselectAll:sender];
NSUInteger cheatCount = [cheatList count]; NSUInteger cheatCount = [cheatList count];
@ -213,12 +197,12 @@
// Force end of editing of any text fields. // Force end of editing of any text fields.
[window makeFirstResponder:nil]; [window makeFirstResponder:nil];
[self.cdsCheats applyInternalCheat:self.workingCheat]; [[self cdsCheats] applyInternalCheat:[self workingCheat]];
} }
- (IBAction) applyConfiguration:(id)sender - (IBAction) applyConfiguration:(id)sender
{ {
if (self.workingCheat == nil) if ([self workingCheat] == nil)
{ {
return; return;
} }
@ -226,17 +210,8 @@
// Force end of editing of any text fields. // Force end of editing of any text fields.
[window makeFirstResponder:nil]; [window makeFirstResponder:nil];
[self.workingCheat mergeToParent]; [[self workingCheat] mergeToParent];
[[self cdsCheats] save];
BOOL result = [self.cdsCheats update:self.workingCheat.parent];
if (result)
{
[self.cdsCheats save];
}
else
{
// TODO: Display an error sheet saying that the cheat applying failed.
}
} }
- (IBAction) selectCheatType:(id)sender - (IBAction) selectCheatType:(id)sender
@ -253,13 +228,13 @@
- (IBAction) selectCheatSearchStyle:(id)sender - (IBAction) selectCheatSearchStyle:(id)sender
{ {
NSInteger searchStyle = [CocoaDSUtil getIBActionSenderTag:sender]; NSInteger searchStyle = [CocoaDSUtil getIBActionSenderTag:sender];
[self.bindings setValue:[NSNumber numberWithInteger:searchStyle] forKey:@"cheatSearchStyle"]; [bindings setValue:[NSNumber numberWithInteger:searchStyle] forKey:@"cheatSearchStyle"];
[self setCheatSearchViewByStyle:searchStyle]; [self setCheatSearchViewByStyle:searchStyle];
} }
- (IBAction) runExactValueSearch:(id)sender - (IBAction) runExactValueSearch:(id)sender
{ {
if (self.workingCheat == nil) if ([self workingCheat] == nil)
{ {
return; return;
} }
@ -268,19 +243,18 @@
[bindings setValue:[NSNumber numberWithBool:YES] forKey:@"isRunningSearch"]; [bindings setValue:[NSNumber numberWithBool:YES] forKey:@"isRunningSearch"];
NSInteger value = [searchField integerValue]; NSInteger value = [searchField integerValue];
UInt8 byteSize = self.workingCheat.bytes; UInt8 byteSize = [[self workingCheat] bytes];
NSInteger signType = [(NSNumber *)[self.bindings valueForKey:@"cheatSearchSignType"] integerValue]; NSInteger signType = [(NSNumber *)[bindings valueForKey:@"cheatSearchSignType"] integerValue];
NSUInteger addressCount = [cdsCheatSearch runExactValueSearch:value byteSize:byteSize signType:signType]; NSUInteger addressCount = [cdsCheatSearch runExactValueSearch:value byteSize:byteSize signType:signType];
[bindings setValue:[NSNumber numberWithUnsignedInteger:addressCount] forKey:@"cheatSearchAddressCount"]; [bindings setValue:[NSNumber numberWithUnsignedInteger:addressCount] forKey:@"cheatSearchAddressCount"];
[cheatSearchListController setContent:cdsCheatSearch.addressList]; [cheatSearchListController setContent:[cdsCheatSearch addressList]];
[bindings setValue:[NSNumber numberWithBool:NO] forKey:@"isRunningSearch"]; [bindings setValue:[NSNumber numberWithBool:NO] forKey:@"isRunningSearch"];
} }
- (IBAction) runComparativeSearch:(id)sender - (IBAction) runComparativeSearch:(id)sender
{ {
if (self.workingCheat == nil) if ([self workingCheat] == nil)
{ {
return; return;
} }
@ -288,28 +262,27 @@
[bindings setValue:[NSNumber numberWithBool:YES] forKey:@"isSearchStarted"]; [bindings setValue:[NSNumber numberWithBool:YES] forKey:@"isSearchStarted"];
[bindings setValue:[NSNumber numberWithBool:YES] forKey:@"isRunningSearch"]; [bindings setValue:[NSNumber numberWithBool:YES] forKey:@"isRunningSearch"];
if (cdsCheatSearch.searchCount == 0) if ([cdsCheatSearch searchCount] == 0)
{ {
[bindings setValue:@"Running initial search..." forKey:@"cheatSearchAddressCount"]; [bindings setValue:@"Running initial search..." forKey:@"cheatSearchAddressCount"];
[window displayIfNeeded]; [window displayIfNeeded];
} }
NSInteger compSearchTypeID = [CocoaDSUtil getIBActionSenderTag:sender]; NSInteger compSearchTypeID = [CocoaDSUtil getIBActionSenderTag:sender];
UInt8 byteSize = self.workingCheat.bytes; UInt8 byteSize = [[self workingCheat] bytes];
NSInteger signType = [(NSNumber *)[self.bindings valueForKey:@"cheatSearchSignType"] integerValue]; NSInteger signType = [(NSNumber *)[bindings valueForKey:@"cheatSearchSignType"] integerValue];
NSUInteger addressCount = [cdsCheatSearch runComparativeSearch:compSearchTypeID byteSize:byteSize signType:signType]; NSUInteger addressCount = [cdsCheatSearch runComparativeSearch:compSearchTypeID byteSize:byteSize signType:signType];
[bindings setValue:[NSNumber numberWithUnsignedInteger:addressCount] forKey:@"cheatSearchAddressCount"]; [bindings setValue:[NSNumber numberWithUnsignedInteger:addressCount] forKey:@"cheatSearchAddressCount"];
[cheatSearchListController setContent:cdsCheatSearch.addressList]; [cheatSearchListController setContent:[cdsCheatSearch addressList]];
NSInteger searchStyle = [(NSNumber *)[self.bindings valueForKey:@"cheatSearchStyle"] integerValue]; NSInteger searchStyle = [(NSNumber *)[bindings valueForKey:@"cheatSearchStyle"] integerValue];
if (searchStyle == CHEATSEARCH_SEARCHSTYLE_COMPARATIVE && cdsCheatSearch.searchCount == 1) if (searchStyle == CHEATSEARCH_SEARCHSTYLE_COMPARATIVE && [cdsCheatSearch searchCount] == 1)
{ {
[self setCheatSearchViewByStyle:CHEATSEARCH_SEARCHSTYLE_COMPARATIVE]; [self setCheatSearchViewByStyle:CHEATSEARCH_SEARCHSTYLE_COMPARATIVE];
[bindings setValue:@"Search started!" forKey:@"cheatSearchAddressCount"]; [bindings setValue:@"Search started!" forKey:@"cheatSearchAddressCount"];
} }
[bindings setValue:[NSNumber numberWithBool:NO] forKey:@"isRunningSearch"]; [bindings setValue:[NSNumber numberWithBool:NO] forKey:@"isRunningSearch"];
} }
- (void) searchDidFinish:(NSNotification *)aNotification - (void) searchDidFinish:(NSNotification *)aNotification
@ -319,12 +292,12 @@
if (searcher != nil) if (searcher != nil)
{ {
addressCount = searcher.addressList.count; addressCount = [[searcher addressList] count];
[bindings setValue:[NSNumber numberWithUnsignedInteger:addressCount] forKey:@"cheatSearchAddressCount"]; [bindings setValue:[NSNumber numberWithUnsignedInteger:addressCount] forKey:@"cheatSearchAddressCount"];
[cheatSearchListController setContent:searcher.addressList]; [cheatSearchListController setContent:[searcher addressList]];
NSInteger searchStyle = [(NSNumber *)[self.bindings valueForKey:@"cheatSearchStyle"] integerValue]; NSInteger searchStyle = [(NSNumber *)[bindings valueForKey:@"cheatSearchStyle"] integerValue];
if (searchStyle == CHEATSEARCH_SEARCHSTYLE_COMPARATIVE && searcher.searchCount == 1) if (searchStyle == CHEATSEARCH_SEARCHSTYLE_COMPARATIVE && [searcher searchCount] == 1)
{ {
[self setCheatSearchViewByStyle:CHEATSEARCH_SEARCHSTYLE_COMPARATIVE]; [self setCheatSearchViewByStyle:CHEATSEARCH_SEARCHSTYLE_COMPARATIVE];
[bindings setValue:@"Search started!" forKey:@"cheatSearchAddressCount"]; [bindings setValue:@"Search started!" forKey:@"cheatSearchAddressCount"];
@ -338,9 +311,9 @@
{ {
[cheatSearchListController setContent:nil]; [cheatSearchListController setContent:nil];
[cdsCheatSearch reset]; [cdsCheatSearch reset];
[self.bindings setValue:nil forKey:@"cheatSearchSearchValue"]; [bindings setValue:nil forKey:@"cheatSearchSearchValue"];
[self.bindings setValue:@"Search not started." forKey:@"cheatSearchAddressCount"]; [bindings setValue:@"Search not started." forKey:@"cheatSearchAddressCount"];
[self setCheatSearchViewByStyle:[(NSNumber *)[self.bindings valueForKey:@"cheatSearchStyle"] integerValue]]; [self setCheatSearchViewByStyle:[(NSNumber *)[bindings valueForKey:@"cheatSearchStyle"] integerValue]];
[bindings setValue:[NSNumber numberWithBool:NO] forKey:@"isSearchStarted"]; [bindings setValue:[NSNumber numberWithBool:NO] forKey:@"isSearchStarted"];
} }
@ -397,7 +370,7 @@
break; break;
case CHEATSEARCH_SEARCHSTYLE_COMPARATIVE: case CHEATSEARCH_SEARCHSTYLE_COMPARATIVE:
if (cdsCheatSearch.searchCount == 0) if ([cdsCheatSearch searchCount] == 0)
{ {
newView = viewSearchComparativeStart; newView = viewSearchComparativeStart;
} }
@ -431,7 +404,7 @@
for (CocoaDSCheatItem *cheatItem in dbList) for (CocoaDSCheatItem *cheatItem in dbList)
{ {
cheatItem.willAdd = YES; [cheatItem setWillAdd:YES];
} }
} }
@ -445,7 +418,7 @@
for (CocoaDSCheatItem *cheatItem in dbList) for (CocoaDSCheatItem *cheatItem in dbList)
{ {
cheatItem.willAdd = NO; [cheatItem setWillAdd:NO];
} }
} }
@ -457,19 +430,29 @@
return; return;
} }
for (CocoaDSCheatItem *cheatItem in dbList) size_t addedItemCount = 0;
BOOL didAddItem = NO;
for (CocoaDSCheatItem *dbItem in dbList)
{ {
if (cheatItem.willAdd) if ([dbItem willAdd])
{ {
CocoaDSCheatItem *newCheatItem = [[[CocoaDSCheatItem alloc] initWithCocoaCheatItem:cheatItem] autorelease]; CocoaDSCheatItem *newCocoaCheatItem = [[[CocoaDSCheatItem alloc] init] autorelease];
[cheatListController addObject:newCheatItem]; ClientCheatItem *newCheatItem = [newCocoaCheatItem clientData];
[self.cdsCheats add:newCheatItem]; newCheatItem->Init(*[dbItem clientData]);
didAddItem = [[self cdsCheats] addExistingItem:newCocoaCheatItem];
if (didAddItem)
{
[cheatListController addObject:newCocoaCheatItem];
addedItemCount++;
}
} }
} }
if ([dbList count] > 0) if (addedItemCount > 0)
{ {
[self.cdsCheats save]; [[self cdsCheats] save];
[bindings setValue:[NSNumber numberWithBool:YES] forKey:@"hasItems"]; [bindings setValue:[NSNumber numberWithBool:YES] forKey:@"hasItems"];
} }
} }
@ -490,7 +473,6 @@
{ {
case GUI_RESPONSE_CANCEL: case GUI_RESPONSE_CANCEL:
return; return;
break;
case GUI_RESPONSE_OK: case GUI_RESPONSE_OK:
[self addSelectedFromCheatDatabase]; [self addSelectedFromCheatDatabase];
@ -503,7 +485,7 @@
- (void)windowDidBecomeKey:(NSNotification *)notification - (void)windowDidBecomeKey:(NSNotification *)notification
{ {
[cheatWindowController setContent:self.bindings]; [cheatWindowController setContent:bindings];
} }
- (void)tableViewSelectionDidChange:(NSNotification *)aNotification - (void)tableViewSelectionDidChange:(NSNotification *)aNotification
@ -511,27 +493,27 @@
NSTableView *table = (NSTableView *)[aNotification object]; NSTableView *table = (NSTableView *)[aNotification object];
NSInteger rowIndex = [table selectedRow]; NSInteger rowIndex = [table selectedRow];
if (table == self.cheatListTable) if (table == [self cheatListTable])
{ {
if (rowIndex >= 0) if (rowIndex >= 0)
{ {
NSArray *selectedObjects = [cheatListController selectedObjects]; NSArray *selectedObjects = [cheatListController selectedObjects];
CocoaDSCheatItem *selectedCheat = [selectedObjects objectAtIndex:0]; CocoaDSCheatItem *selectedCheat = [selectedObjects objectAtIndex:0];
self.workingCheat = [selectedCheat createWorkingCopy]; [self setWorkingCheat:[selectedCheat createWorkingCopy]];
[cheatSelectedItemController setContent:self.workingCheat]; [cheatSelectedItemController setContent:[self workingCheat]];
[self setCheatConfigViewByType:selectedCheat.cheatType]; [self setCheatConfigViewByType:[selectedCheat cheatType]];
[bindings setValue:[NSNumber numberWithBool:YES] forKey:@"hasSelection"]; [bindings setValue:[NSNumber numberWithBool:YES] forKey:@"hasSelection"];
} }
else else
{ {
if (self.workingCheat != nil) if ([self workingCheat] != nil)
{ {
[self.workingCheat.parent destroyWorkingCopy]; [[[self workingCheat] parent] destroyWorkingCopy];
} }
[cheatSelectedItemController setContent:nil]; [cheatSelectedItemController setContent:nil];
self.workingCheat = nil; [self setWorkingCheat:nil];
NSRect frameRect = [currentView frame]; NSRect frameRect = [currentView frame];
[currentView retain]; [currentView retain];
@ -542,7 +524,7 @@
[bindings setValue:[NSNumber numberWithBool:NO] forKey:@"hasSelection"]; [bindings setValue:[NSNumber numberWithBool:NO] forKey:@"hasSelection"];
} }
} }
else if (table == self.cheatSearchListTable) else if (table == [self cheatSearchListTable])
{ {
if (rowIndex >= 0) if (rowIndex >= 0)
{ {
@ -550,9 +532,9 @@
NSMutableDictionary *selectedAddress = [selectedObjects objectAtIndex:0]; NSMutableDictionary *selectedAddress = [selectedObjects objectAtIndex:0];
NSString *addressString = [(NSString *)[selectedAddress valueForKey:@"addressString"] substringFromIndex:4]; NSString *addressString = [(NSString *)[selectedAddress valueForKey:@"addressString"] substringFromIndex:4];
if (self.workingCheat != nil) if ([self workingCheat] != nil)
{ {
self.workingCheat.memAddressSixDigitString = addressString; [[self workingCheat] setMemAddressSixDigitString:addressString];
} }
} }
} }