From 12347c7cd97386cdf144a47a7f9948702289ef8a Mon Sep 17 00:00:00 2001 From: rogerman Date: Fri, 7 Jul 2023 19:31:26 -0700 Subject: [PATCH] Cocoa Port: Continue refactoring the cheat system code, Part IV. - Add the following C++ classes: ClientCheatSearcher, ClientCheatDatabase - Remove the following Obj-C classes: CocoaDSCheatSearch, CocoaDSCheatSearchParams - Remove duplicate GUI code from EmuControllerDelegate.mm and preferencesWindowDelegate.mm - All basic functionality for managing game session cheat items, the cheat database list, and cheat search are now managed through CocoaDSCheatManager. --- desmume/src/frontend/cocoa/cocoa_cheat.h | 190 ++-- desmume/src/frontend/cocoa/cocoa_cheat.mm | 890 ++++++++++-------- desmume/src/frontend/cocoa/cocoa_core.mm | 1 + .../src/frontend/cocoa/openemu/NDSGameCore.mm | 27 +- .../translations/English.lproj/MainMenu.xib | 123 +-- .../userinterface/EmuControllerDelegate.mm | 81 +- .../cocoa/userinterface/cheatWindowDelegate.h | 10 +- .../userinterface/cheatWindowDelegate.mm | 233 +++-- .../preferencesWindowDelegate.mm | 54 +- .../troubleshootingWindowDelegate.mm | 2 +- 10 files changed, 803 insertions(+), 808 deletions(-) diff --git a/desmume/src/frontend/cocoa/cocoa_cheat.h b/desmume/src/frontend/cocoa/cocoa_cheat.h index 0bc458cba..0dc6cb199 100644 --- a/desmume/src/frontend/cocoa/cocoa_cheat.h +++ b/desmume/src/frontend/cocoa/cocoa_cheat.h @@ -28,18 +28,32 @@ class ClientCheatManager; enum CheatType { - CheatType_Internal = 0, + CheatType_Internal = 0, CheatType_ActionReplay = 1, - CheatType_CodeBreaker = 2 + CheatType_CodeBreaker = 2 }; enum CheatFreezeType { - CheatFreezeType_Normal = 0, + CheatFreezeType_Normal = 0, CheatFreezeType_CanDecrease = 1, CheatFreezeType_CanIncrease = 2 }; +enum CheatSearchStyle +{ + CheatSearchStyle_ExactValue = 0, + CheatSearchStyle_Comparative = 1 +}; + +enum CheatSearchCompareStyle +{ + CheatSearchCompareStyle_GreaterThan = 0, + CheatSearchCompareStyle_LesserThan = 1, + CheatSearchCompareStyle_Equals = 2, + CheatSearchCompareStyle_NotEquals = 3 +}; + enum CheatSystemError { CheatSystemError_NoError = 0, @@ -50,6 +64,20 @@ enum CheatSystemError CheatSystemError_FileSaveFailed = 5 }; +union DesmumeCheatSearchItem +{ + uint64_t data; + + struct + { + uint32_t address; + uint32_t value; + }; +}; +typedef union DesmumeCheatSearchItem DesmumeCheatSearchItem; + +typedef std::vector DesmumeCheatSearchResultsList; + class ClientCheatItem { protected: @@ -161,18 +189,58 @@ class ClientCheatList void CopyListToEngine(const bool willApplyOnlyEnabledItems, CHEATS *engineCheatList); }; +class ClientCheatSearcher +{ +protected: + CHEATSEARCH *_desmumeSearcher; + uint8_t _searchValueLength; + size_t _resultsCount; + bool _didSearchStart; + DesmumeCheatSearchResultsList _resultsList; + +public: + ClientCheatSearcher(); + ~ClientCheatSearcher(); + + bool DidStart() const; + void Reset(); + size_t SearchExactValue(uint32_t value, uint8_t valueLength, bool performSignedSearch); + size_t SearchComparative(CheatSearchCompareStyle compareStyle, uint8_t valueLength, bool performSignedSearch); + const DesmumeCheatSearchResultsList& RefreshResults(); + const DesmumeCheatSearchResultsList& GetResults(); + size_t GetResultCount() const; +}; + +class ClientCheatDatabase +{ +protected: + ClientCheatList *_list; + std::string _title; + std::string _date; + std::string _lastFilePath; + +public: + ClientCheatDatabase(); + ~ClientCheatDatabase(); + + ClientCheatList* GetList() const; + ClientCheatList* LoadFromFile(const char *dbFilePath); + + const char* GetTitle() const; + const char* GetDate() const; +}; + class ClientCheatManager { protected: - ClientCheatList *_workingList; - ClientCheatList *_databaseList; + ClientCheatList *_currentSessionList; + ClientCheatDatabase *_currentDatabase; + ClientCheatSearcher *_currentSearcher; + ClientCheatItem *_selectedItem; size_t _selectedItemIndex; uint32_t _untitledCount; - - std::string _databaseTitle; - std::string _databaseDate; - std::string _lastFilePath; + std::string _currentSessionLastFilePath; bool _masterNeedsUpdate; @@ -183,19 +251,11 @@ class ClientCheatManager static CHEATS* GetMaster(); static void SetMaster(const CHEATS *masterCheats); - ClientCheatList* GetWorkingList() const; - ClientCheatList* GetDatabaseList() const; + ClientCheatList* GetSessionList() const; + const char* GetSessionListLastFilePath() 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); + virtual CheatSystemError SessionListLoadFromFile(const char *filePath); + virtual CheatSystemError SessionListSaveToFile(const char *filePath); ClientCheatItem* SetSelectedItemByIndex(size_t index); @@ -212,12 +272,23 @@ class ClientCheatManager size_t GetTotalCheatCount() const; size_t GetActiveCheatCount() const; - ClientCheatList* LoadFromDatabase(const char *dbFilePath); - void LoadFromMaster(); void ApplyToMaster(); void MasterNeedsUpdate(); + ClientCheatList* GetDatabaseList() const; + ClientCheatList* DatabaseListLoadFromFile(const char *dbFilePath); + const char* GetDatabaseTitle() const; + const char* GetDatabaseDate() const; + + bool SearchDidStart() const; + void SearchReset(); + size_t SearchExactValue(uint32_t value, uint8_t valueLength, bool performSignedSearch); + size_t SearchComparative(CheatSearchCompareStyle compareStyle, uint8_t valueLength, bool performSignedSearch); + const DesmumeCheatSearchResultsList& SearchResultsRefresh(); + const DesmumeCheatSearchResultsList& GetSearchResults(); + size_t GetSearchResultCount() const; + void ApplyInternalCheatAtIndex(size_t index); static void ApplyInternalCheatWithItem(const ClientCheatItem *cheatItem); static void ApplyInternalCheatWithParams(uint32_t targetAddress, uint32_t newValue, size_t newValueLength); @@ -275,68 +346,43 @@ class ClientCheatManager @interface CocoaDSCheatManager : NSObject { ClientCheatManager *_internalCheatManager; - NSMutableArray *list; + NSMutableArray *sessionList; + NSMutableArray *databaseList; + NSMutableArray *searchResultsList; + + pthread_rwlock_t *rwlockCoreExecute; } @property (readonly, nonatomic, getter=internalManager) ClientCheatManager *_internalCheatManager; -@property (readonly) NSMutableArray *list; -@property (assign, nonatomic) NSString *dbTitle; -@property (assign, nonatomic) NSString *dbDate; +@property (readonly) NSMutableArray *sessionList; +@property (readonly, nonatomic) NSUInteger itemTotalCount; +@property (readonly, nonatomic) NSUInteger itemActiveCount; +@property (readonly) NSMutableArray *databaseList; +@property (readonly, nonatomic) NSString *databaseTitle; +@property (readonly, nonatomic) NSString *databaseDate; +@property (readonly) NSMutableArray *searchResultsList; +@property (readonly, nonatomic) BOOL searchDidStart; +@property (readonly, nonatomic) NSUInteger searchCount; +@property (assign, nonatomic) pthread_rwlock_t *rwlockCoreExecute; - (id) initWithFileURL:(NSURL *)fileURL; - (CocoaDSCheatItem *) newItem; -- (BOOL) addExistingItem:(CocoaDSCheatItem *)cheatItem; -- (void) remove:(CocoaDSCheatItem *)cheatItem; -- (BOOL) update:(CocoaDSCheatItem *)cheatItem; +- (CocoaDSCheatItem *) addExistingItem:(ClientCheatItem *)cheatItem; +- (CocoaDSCheatItem *) addExistingCocoaItem:(CocoaDSCheatItem *)cocoaCheatItem; +- (void) remove:(CocoaDSCheatItem *)cocoaCheatItem; +- (void) removeAtIndex:(NSUInteger)itemIndex; +- (BOOL) update:(CocoaDSCheatItem *)cocoaCheatItem; - (BOOL) save; -- (NSUInteger) activeCount; -- (NSMutableArray *) cheatListFromDatabase:(NSURL *)fileURL errorCode:(NSInteger *)error; -- (void) applyInternalCheat:(CocoaDSCheatItem *)cheatItem; +- (void) applyInternalCheat:(CocoaDSCheatItem *)cocoaCheatItem; - (void) loadFromMaster; - (void) applyToMaster; -+ (NSMutableArray *) cheatListWithClientListObject:(ClientCheatList *)cheatList; - -@end - -@interface CocoaDSCheatSearch : NSObject -{ - CHEATSEARCH *listData; - NSMutableArray *addressList; - - pthread_rwlock_t *rwlockCoreExecute; - BOOL isUsingDummyRWlock; - - NSUInteger searchCount; -} - -@property (readonly) CHEATSEARCH *listData; -@property (readonly) NSMutableArray *addressList; -@property (assign) pthread_rwlock_t *rwlockCoreExecute; -@property (readonly) NSUInteger searchCount; +- (NSMutableArray *) cheatListFromDatabase:(NSURL *)fileURL errorCode:(NSInteger *)error; +- (NSUInteger) databaseAddSelected; - (NSUInteger) runExactValueSearch:(NSInteger)value byteSize:(UInt8)byteSize signType:(NSInteger)signType; -- (void) runExactValueSearchOnThread:(id)object; - (NSUInteger) runComparativeSearch:(NSInteger)typeID byteSize:(UInt8)byteSize signType:(NSInteger)signType; -- (void) runComparativeSearchOnThread:(id)object; -- (void) reset; - -+ (NSMutableArray *) addressListWithListObject:(CHEATSEARCH *)addressList maxItems:(NSUInteger)maxItemCount; - -@end - -@interface CocoaDSCheatSearchParams : NSObject -{ - NSInteger comparativeSearchType; - NSInteger value; - UInt8 byteSize; - NSInteger signType; -} - -@property (assign) NSInteger comparativeSearchType; -@property (assign) NSInteger value; -@property (assign) UInt8 byteSize; -@property (assign) NSInteger signType; +- (void) searchReset; @end diff --git a/desmume/src/frontend/cocoa/cocoa_cheat.mm b/desmume/src/frontend/cocoa/cocoa_cheat.mm index 2e3bc2dd8..ce3577f13 100644 --- a/desmume/src/frontend/cocoa/cocoa_cheat.mm +++ b/desmume/src/frontend/cocoa/cocoa_cheat.mm @@ -953,81 +953,231 @@ bool IsCheatItemDuplicate(const ClientCheatItem *first, const ClientCheatItem *s #pragma mark - -ClientCheatManager::ClientCheatManager() +ClientCheatSearcher::ClientCheatSearcher() +{ + _desmumeSearcher = new CHEATSEARCH; + _searchValueLength = 4; + _resultsCount = 0; + _didSearchStart = false; + _resultsList.resize(0); +} + +ClientCheatSearcher::~ClientCheatSearcher() +{ + delete this->_desmumeSearcher; +} + +bool ClientCheatSearcher::DidStart() const +{ + return this->_didSearchStart; +} + +void ClientCheatSearcher::Reset() { - _workingList = new ClientCheatList; - _databaseList = new ClientCheatList; + this->_desmumeSearcher->close(); + this->_didSearchStart = false; + this->_resultsCount = 0; - _selectedItem = NULL; - _selectedItemIndex = 0; + this->_desmumeSearcher->getListReset(); + this->_resultsList.resize(0); +} + +size_t ClientCheatSearcher::SearchExactValue(uint32_t value, uint8_t valueLength, bool performSignedSearch) +{ + if (!this->_didSearchStart) + { + this->_searchValueLength = valueLength; + this->_didSearchStart = this->_desmumeSearcher->start((u8)CheatSearchStyle_ExactValue, this->_searchValueLength - 1, 0); + this->_resultsCount = 0; + this->_resultsList.resize(0); + } - _untitledCount = 0; + if (this->_didSearchStart) + { + this->_resultsCount = (size_t)this->_desmumeSearcher->search(value); + this->RefreshResults(); + } - _databaseTitle.resize(0); - _databaseDate.resize(0); - _lastFilePath.resize(0); + return this->_resultsCount; +} + +size_t ClientCheatSearcher::SearchComparative(CheatSearchCompareStyle compareStyle, uint8_t valueLength, bool performSignedSearch) +{ + if (!this->_didSearchStart) + { + this->_searchValueLength = valueLength; + this->_didSearchStart = this->_desmumeSearcher->start((u8)CheatSearchStyle_Comparative, this->_searchValueLength - 1, 0); + this->_resultsCount = 0; + this->_resultsList.resize(0); + } + else + { + this->_resultsCount = (size_t)this->_desmumeSearcher->search((u8)compareStyle); + this->RefreshResults(); + } - _masterNeedsUpdate = true; + return this->_resultsCount; } -ClientCheatManager::~ClientCheatManager() +const DesmumeCheatSearchResultsList& ClientCheatSearcher::RefreshResults() { - delete this->_databaseList; - delete this->_workingList; + bool didReadResult = false; + u32 readAddress = 0; + u32 readValue = 0; + size_t readResultIndex = 0; + + this->_desmumeSearcher->getListReset(); + this->_resultsList.clear(); + + for (size_t i = 0; i < this->_resultsCount; i++) + { + didReadResult = this->_desmumeSearcher->getList(&readAddress, &readValue); + if (didReadResult) + { + DesmumeCheatSearchItem searchResult; + searchResult.address = readAddress; + searchResult.value = readValue; + + this->_resultsList.push_back(searchResult); + readResultIndex++; + } + } + + return this->_resultsList; } -CHEATS* ClientCheatManager::GetMaster() +const DesmumeCheatSearchResultsList& ClientCheatSearcher::GetResults() { - return cheats; + return this->_resultsList; } -void ClientCheatManager::SetMaster(const CHEATS *masterCheats) +size_t ClientCheatSearcher::GetResultCount() const { - cheats = (CHEATS *)masterCheats; + return this->_resultsCount; } -ClientCheatList* ClientCheatManager::GetWorkingList() const +#pragma mark - + +ClientCheatDatabase::ClientCheatDatabase() { - return this->_workingList; + _list = new ClientCheatList; + _title.resize(0); + _date.resize(0); + _lastFilePath.resize(0); } -ClientCheatList* ClientCheatManager::GetDatabaseList() const +ClientCheatDatabase::~ClientCheatDatabase() { - return this->_databaseList; + delete this->_list; } -const char* ClientCheatManager::GetDatabaseTitle() const +ClientCheatList* ClientCheatDatabase::GetList() const { - return this->_databaseTitle.c_str(); + return this->_list; } -void ClientCheatManager::SetDatabaseTitle(const char *dbTitle) +ClientCheatList* ClientCheatDatabase::LoadFromFile(const char *dbFilePath) { - if (dbTitle != NULL) + if (dbFilePath == NULL) + { + return NULL; + } + + CHEATSEXPORT *exporter = new CHEATSEXPORT(); + CheatSystemError dbError = CheatSystemError_NoError; + + bool didFileLoad = exporter->load((char *)dbFilePath); + if (didFileLoad) + { + this->_list->RemoveAll(); + this->_title = (const char *)exporter->gametitle; + this->_date = (const char *)exporter->date; + this->_lastFilePath = dbFilePath; + + const size_t itemCount = exporter->getCheatsNum(); + const CHEATS_LIST *dbItem = exporter->getCheats(); + + for (size_t i = 0; i < itemCount; i++) + { + ClientCheatItem *newItem = this->_list->AddNew(); + if (newItem != NULL) + { + newItem->Init(dbItem[i]); + } + } + } + else + { + dbError = (CheatSystemError)exporter->getErrorCode(); + } + + delete exporter; + exporter = nil; + + if (dbError != CheatSystemError_NoError) { - this->_databaseTitle = dbTitle; + return NULL; } + + return this->_list; } -const char* ClientCheatManager::GetDatabaseDate() const +const char* ClientCheatDatabase::GetTitle() const { - return this->_databaseDate.c_str(); + return this->_title.c_str(); } -void ClientCheatManager::SetDatabaseDate(const char *dbDate) +const char* ClientCheatDatabase::GetDate() const { - if (dbDate != NULL) - { - this->_databaseDate = dbDate; - } + return this->_date.c_str(); +} + +#pragma mark - + +ClientCheatManager::ClientCheatManager() +{ + _currentSessionList = new ClientCheatList; + _currentDatabase = new ClientCheatDatabase; + _currentSearcher = new ClientCheatSearcher; + + _selectedItem = NULL; + _selectedItemIndex = 0; + + _untitledCount = 0; + + _currentSessionLastFilePath.resize(0); + + _masterNeedsUpdate = true; +} + +ClientCheatManager::~ClientCheatManager() +{ + delete this->_currentSearcher; + delete this->_currentDatabase; + delete this->_currentSessionList; +} + +CHEATS* ClientCheatManager::GetMaster() +{ + return cheats; +} + +void ClientCheatManager::SetMaster(const CHEATS *masterCheats) +{ + cheats = (CHEATS *)masterCheats; +} + +ClientCheatList* ClientCheatManager::GetSessionList() const +{ + return this->_currentSessionList; } -const char* ClientCheatManager::GetLastFilePath() const +const char* ClientCheatManager::GetSessionListLastFilePath() const { - return this->_lastFilePath.c_str(); + return this->_currentSessionLastFilePath.c_str(); } -CheatSystemError ClientCheatManager::LoadFromFile(const char *filePath) +CheatSystemError ClientCheatManager::SessionListLoadFromFile(const char *filePath) { CheatSystemError error = CheatSystemError_NoError; @@ -1037,15 +1187,15 @@ bool IsCheatItemDuplicate(const ClientCheatItem *first, const ClientCheatItem *s return error; } - error = this->_workingList->LoadFromFile(filePath); + error = this->_currentSessionList->LoadFromFile(filePath); if (error == CheatSystemError_NoError) { - this->_lastFilePath = filePath; + this->_currentSessionLastFilePath = filePath; - const size_t totalCount = this->_workingList->GetTotalCheatCount(); + const size_t totalCount = this->_currentSessionList->GetTotalCheatCount(); for (size_t i = 0; i < totalCount; i++) { - ClientCheatItem *cheatItem = this->_workingList->GetItemAtIndex(i); + ClientCheatItem *cheatItem = this->_currentSessionList->GetItemAtIndex(i); cheatItem->SetCheatManager(this); } } @@ -1053,7 +1203,7 @@ bool IsCheatItemDuplicate(const ClientCheatItem *first, const ClientCheatItem *s return error; } -CheatSystemError ClientCheatManager::SaveToFile(const char *filePath) +CheatSystemError ClientCheatManager::SessionListSaveToFile(const char *filePath) { CheatSystemError error = CheatSystemError_NoError; @@ -1063,10 +1213,10 @@ bool IsCheatItemDuplicate(const ClientCheatItem *first, const ClientCheatItem *s return error; } - error = this->_workingList->SaveToFile(filePath); + error = this->_currentSessionList->SaveToFile(filePath); if (error == CheatSystemError_NoError) { - this->_lastFilePath = filePath; + this->_currentSessionLastFilePath = filePath; } return error; @@ -1075,14 +1225,14 @@ bool IsCheatItemDuplicate(const ClientCheatItem *first, const ClientCheatItem *s ClientCheatItem* ClientCheatManager::SetSelectedItemByIndex(size_t index) { this->_selectedItemIndex = index; - this->_selectedItem = this->_workingList->GetItemAtIndex(index); + this->_selectedItem = this->_currentSessionList->GetItemAtIndex(index); return this->_selectedItem; } ClientCheatItem* ClientCheatManager::NewItem() { - ClientCheatItem *newItem = this->_workingList->AddNew(); + ClientCheatItem *newItem = this->_currentSessionList->AddNew(); newItem->SetCheatManager(this); this->_untitledCount++; @@ -1108,7 +1258,7 @@ bool IsCheatItemDuplicate(const ClientCheatItem *first, const ClientCheatItem *s ClientCheatItem* ClientCheatManager::AddExistingItemNoDuplicate(const ClientCheatItem *theItem) { - ClientCheatItem *addedItem = this->_workingList->AddExistingItemNoDuplicate(theItem); + ClientCheatItem *addedItem = this->_currentSessionList->AddExistingItemNoDuplicate(theItem); if (addedItem != NULL) { addedItem->SetCheatManager(this); @@ -1124,19 +1274,19 @@ bool IsCheatItemDuplicate(const ClientCheatItem *first, const ClientCheatItem *s void ClientCheatManager::RemoveItem(ClientCheatItem *targetItem) { - this->RemoveItemAtIndex( this->_workingList->GetIndexOfItem(targetItem) ); + this->RemoveItemAtIndex( this->_currentSessionList->GetIndexOfItem(targetItem) ); } void ClientCheatManager::RemoveItemAtIndex(size_t index) { - const ClientCheatItem *targetItem = this->_workingList->GetItemAtIndex(index); + const ClientCheatItem *targetItem = this->_currentSessionList->GetItemAtIndex(index); if (targetItem == NULL) { return; } const bool willChangeMasterUpdateFlag = targetItem->IsEnabled(); - const bool didRemoveItem = this->_workingList->RemoveAtIndex(index); + const bool didRemoveItem = this->_currentSessionList->RemoveAtIndex(index); if (didRemoveItem && willChangeMasterUpdateFlag) { @@ -1160,19 +1310,19 @@ bool IsCheatItemDuplicate(const ClientCheatItem *first, const ClientCheatItem *s return; } - this->ModifyItemAtIndex(srcItem, this->_workingList->GetIndexOfItem(targetItem)); + this->ModifyItemAtIndex(srcItem, this->_currentSessionList->GetIndexOfItem(targetItem)); } void ClientCheatManager::ModifyItemAtIndex(const ClientCheatItem *srcItem, size_t index) { - const ClientCheatItem *targetItem = this->_workingList->GetItemAtIndex(index); + const ClientCheatItem *targetItem = this->_currentSessionList->GetItemAtIndex(index); if ( (srcItem == NULL) || (targetItem == NULL) ) { return; } const bool willChangeMasterUpdateFlag = targetItem->IsEnabled(); - const bool didModifyItem = this->_workingList->UpdateAtIndex(*srcItem, index); + const bool didModifyItem = this->_currentSessionList->UpdateAtIndex(*srcItem, index); if (didModifyItem && willChangeMasterUpdateFlag) { @@ -1182,58 +1332,12 @@ bool IsCheatItemDuplicate(const ClientCheatItem *first, const ClientCheatItem *s size_t ClientCheatManager::GetTotalCheatCount() const { - return this->_workingList->GetTotalCheatCount(); + return this->_currentSessionList->GetTotalCheatCount(); } size_t ClientCheatManager::GetActiveCheatCount() const { - return this->_workingList->GetActiveCheatCount(); -} - -ClientCheatList* ClientCheatManager::LoadFromDatabase(const char *dbFilePath) -{ - if (dbFilePath == NULL) - { - return NULL; - } - - CHEATSEXPORT *exporter = new CHEATSEXPORT(); - CheatSystemError dbError = CheatSystemError_NoError; - - bool didFileLoad = exporter->load((char *)dbFilePath); - if (didFileLoad) - { - this->_databaseList->RemoveAll(); - - this->SetDatabaseTitle((const char *)exporter->gametitle); - this->SetDatabaseDate((const char *)exporter->date); - - const size_t itemCount = exporter->getCheatsNum(); - const CHEATS_LIST *dbItem = exporter->getCheats(); - - for (size_t i = 0; i < itemCount; i++) - { - ClientCheatItem *newItem = this->_databaseList->AddNew(); - if (newItem != NULL) - { - newItem->Init(dbItem[i]); - } - } - } - else - { - dbError = (CheatSystemError)exporter->getErrorCode(); - } - - delete exporter; - exporter = nil; - - if (dbError != CheatSystemError_NoError) - { - return NULL; - } - - return this->_databaseList; + return this->_currentSessionList->GetActiveCheatCount(); } void ClientCheatManager::LoadFromMaster() @@ -1246,24 +1350,24 @@ bool IsCheatItemDuplicate(const ClientCheatItem *first, const ClientCheatItem *s return; } - this->_lastFilePath = masterCheats->getFilePath(); + this->_currentSessionLastFilePath = masterCheats->getFilePath(); - activeCount = this->_workingList->GetActiveCheatCount(); + activeCount = this->_currentSessionList->GetActiveCheatCount(); if (activeCount > 0) { this->_masterNeedsUpdate = true; } - this->_workingList->ReplaceFromEngine(masterCheats); + this->_currentSessionList->ReplaceFromEngine(masterCheats); - const size_t totalCount = this->_workingList->GetTotalCheatCount(); + const size_t totalCount = this->_currentSessionList->GetTotalCheatCount(); for (size_t i = 0; i < totalCount; i++) { - ClientCheatItem *cheatItem = this->_workingList->GetItemAtIndex(i); + ClientCheatItem *cheatItem = this->_currentSessionList->GetItemAtIndex(i); cheatItem->SetCheatManager(this); } - activeCount = this->_workingList->GetActiveCheatCount(); + activeCount = this->_currentSessionList->GetActiveCheatCount(); if (activeCount > 0) { this->_masterNeedsUpdate = true; @@ -1278,7 +1382,7 @@ bool IsCheatItemDuplicate(const ClientCheatItem *first, const ClientCheatItem *s return; } - this->_workingList->CopyListToEngine(true, masterCheats); + this->_currentSessionList->CopyListToEngine(true, masterCheats); this->_masterNeedsUpdate = false; } @@ -1287,9 +1391,64 @@ bool IsCheatItemDuplicate(const ClientCheatItem *first, const ClientCheatItem *s this->_masterNeedsUpdate = true; } +ClientCheatList* ClientCheatManager::GetDatabaseList() const +{ + return this->_currentDatabase->GetList(); +} + +ClientCheatList* ClientCheatManager::DatabaseListLoadFromFile(const char *dbFilePath) +{ + return this->_currentDatabase->LoadFromFile(dbFilePath); +} + +const char* ClientCheatManager::GetDatabaseTitle() const +{ + return this->_currentDatabase->GetTitle(); +} + +const char* ClientCheatManager::GetDatabaseDate() const +{ + return this->_currentDatabase->GetDate(); +} + +bool ClientCheatManager::SearchDidStart() const +{ + return this->_currentSearcher->DidStart(); +} + +void ClientCheatManager::SearchReset() +{ + this->_currentSearcher->Reset(); +} + +size_t ClientCheatManager::SearchExactValue(uint32_t value, uint8_t valueLength, bool performSignedSearch) +{ + return this->_currentSearcher->SearchExactValue(value, valueLength, performSignedSearch); +} + +size_t ClientCheatManager::SearchComparative(CheatSearchCompareStyle compareStyle, uint8_t valueLength, bool performSignedSearch) +{ + return this->_currentSearcher->SearchComparative(compareStyle, valueLength, performSignedSearch); +} + +const DesmumeCheatSearchResultsList& ClientCheatManager::SearchResultsRefresh() +{ + return this->_currentSearcher->RefreshResults(); +} + +const DesmumeCheatSearchResultsList& ClientCheatManager::GetSearchResults() +{ + return this->_currentSearcher->GetResults(); +} + +size_t ClientCheatManager::GetSearchResultCount() const +{ + return this->_currentSearcher->GetResultCount(); +} + void ClientCheatManager::ApplyInternalCheatAtIndex(size_t index) { - ClientCheatManager::ApplyInternalCheatWithItem( this->_workingList->GetItemAtIndex(index) ); + ClientCheatManager::ApplyInternalCheatWithItem( this->_currentSessionList->GetItemAtIndex(index) ); } void ClientCheatManager::ApplyInternalCheatWithItem(const ClientCheatItem *cheatItem) @@ -1822,9 +1981,16 @@ + (NSImage *) iconCodeBreaker @implementation CocoaDSCheatManager @synthesize _internalCheatManager; -@synthesize list; -@dynamic dbTitle; -@dynamic dbDate; +@synthesize sessionList; +@dynamic itemTotalCount; +@dynamic itemActiveCount; +@synthesize databaseList; +@dynamic databaseTitle; +@dynamic databaseDate; +@synthesize searchResultsList; +@dynamic searchCount; +@dynamic searchDidStart; +@synthesize rwlockCoreExecute; - (id)init { @@ -1839,24 +2005,39 @@ - (id) initWithFileURL:(NSURL *)fileURL return self; } + rwlockCoreExecute = NULL; _internalCheatManager = new ClientCheatManager; - if (fileURL != nil) + sessionList = [[NSMutableArray alloc] initWithCapacity:100]; + if (sessionList == nil) { - _internalCheatManager->LoadFromFile([CocoaDSUtil cPathFromFileURL:fileURL]); - - ClientCheatList *clientList = _internalCheatManager->GetWorkingList(); - list = [[CocoaDSCheatManager cheatListWithClientListObject:clientList] retain]; + [self release]; + self = nil; + return self; } - else + + databaseList = [[NSMutableArray alloc] initWithCapacity:100]; + if (databaseList == nil) { - list = [[NSMutableArray alloc] initWithCapacity:100]; - if (list == nil) - { - delete _internalCheatManager; - [self release]; - return nil; - } + [sessionList release]; + [self release]; + self = nil; + return self; + } + + searchResultsList = [[NSMutableArray alloc] initWithCapacity:100]; + if (searchResultsList == nil) + { + [sessionList release]; + [databaseList release]; + [self release]; + self = nil; + return self; + } + + if (fileURL != nil) + { + _internalCheatManager->SessionListLoadFromFile([CocoaDSUtil cPathFromFileURL:fileURL]); } return self; @@ -1864,8 +2045,14 @@ - (id) initWithFileURL:(NSURL *)fileURL - (void)dealloc { - [list release]; - list = nil; + [sessionList release]; + sessionList = nil; + + [databaseList release]; + databaseList = nil; + + [searchResultsList release]; + searchResultsList = nil; delete _internalCheatManager; _internalCheatManager = NULL; @@ -1873,92 +2060,134 @@ - (void)dealloc [super dealloc]; } -- (NSString *) dbTitle +- (NSString *) databaseTitle { return [NSString stringWithCString:_internalCheatManager->GetDatabaseTitle() encoding:NSUTF8StringEncoding]; } -- (void) setDbTitle:(NSString *)theString +- (NSString *) databaseDate { - // Do nothing. This method exists for KVO compliance only. + return [NSString stringWithCString:_internalCheatManager->GetDatabaseDate() encoding:NSUTF8StringEncoding]; } -- (NSString *) dbDate +- (NSUInteger) itemTotalCount { - return [NSString stringWithCString:_internalCheatManager->GetDatabaseDate() encoding:NSUTF8StringEncoding]; + return (NSUInteger)_internalCheatManager->GetTotalCheatCount(); } -- (void) setDbDate:(NSString *)theString +- (NSUInteger) itemActiveCount { - // Do nothing. This method exists for KVO compliance only. + return (NSUInteger)_internalCheatManager->GetActiveCheatCount(); } - (CocoaDSCheatItem *) newItem { CocoaDSCheatItem *newCocoaItem = nil; + [self willChangeValueForKey:@"itemTotalCount"]; + [self willChangeValueForKey:@"itemActiveCount"]; + ClientCheatItem *newItem = _internalCheatManager->NewItem(); + + [self didChangeValueForKey:@"itemTotalCount"]; + [self didChangeValueForKey:@"itemActiveCount"]; + if (newItem == NULL) { return newCocoaItem; } - newCocoaItem = [[CocoaDSCheatItem alloc] initWithCheatItem:newItem]; + newCocoaItem = [[[CocoaDSCheatItem alloc] initWithCheatItem:newItem] autorelease]; if (newCocoaItem == nil) { - delete newItem; - newItem = NULL; + _internalCheatManager->RemoveItem(newItem); + return newCocoaItem; } + [sessionList addObject:newCocoaItem]; + return newCocoaItem; } -- (BOOL) addExistingItem:(CocoaDSCheatItem *)cheatItem +- (CocoaDSCheatItem *) addExistingItem:(ClientCheatItem *)cheatItem { - BOOL result = NO; + CocoaDSCheatItem *addedCocoaItem = nil; + if (cheatItem == nil) + { + return addedCocoaItem; + } - if ( (cheatItem == nil) || [[self list] containsObject:cheatItem] ) + addedCocoaItem = [[[CocoaDSCheatItem alloc] initWithCheatItem:cheatItem] autorelease]; + return [self addExistingCocoaItem:addedCocoaItem]; +} + +- (CocoaDSCheatItem *) addExistingCocoaItem:(CocoaDSCheatItem *)cocoaCheatItem +{ + CocoaDSCheatItem *addedCocoaItem = nil; + if ( (cocoaCheatItem == nil) || ([cocoaCheatItem clientData] == NULL) ) { - return result; + return addedCocoaItem; } - ClientCheatItem *addedItem = _internalCheatManager->AddExistingItemNoDuplicate([cheatItem clientData]); + [self willChangeValueForKey:@"itemTotalCount"]; + [self willChangeValueForKey:@"itemActiveCount"]; + + ClientCheatItem *addedItem = _internalCheatManager->AddExistingItemNoDuplicate([cocoaCheatItem clientData]); + + [self didChangeValueForKey:@"itemTotalCount"]; + [self didChangeValueForKey:@"itemActiveCount"]; + if (addedItem == NULL) { - return result; + return addedCocoaItem; } - result = YES; - return result; + addedCocoaItem = cocoaCheatItem; + [sessionList addObject:addedCocoaItem]; + + return addedCocoaItem; } -- (void) remove:(CocoaDSCheatItem *)cheatItem +- (void) remove:(CocoaDSCheatItem *)cocoaCheatItem { - if (cheatItem == nil) + if ((cocoaCheatItem == NULL) || ![sessionList containsObject:cocoaCheatItem]) { return; } - NSUInteger selectionIndex = [[self list] indexOfObject:cheatItem]; + NSUInteger selectionIndex = [sessionList indexOfObject:cocoaCheatItem]; if (selectionIndex == NSNotFound) { return; } - _internalCheatManager->RemoveItemAtIndex(selectionIndex); + [self removeAtIndex:selectionIndex]; +} + +- (void) removeAtIndex:(NSUInteger)itemIndex +{ + [self willChangeValueForKey:@"itemTotalCount"]; + [self willChangeValueForKey:@"itemActiveCount"]; + + _internalCheatManager->RemoveItemAtIndex((size_t)itemIndex); + + [self didChangeValueForKey:@"itemTotalCount"]; + [self didChangeValueForKey:@"itemActiveCount"]; + + [sessionList removeObjectAtIndex:itemIndex]; } -- (BOOL) update:(CocoaDSCheatItem *)cheatItem +- (BOOL) update:(CocoaDSCheatItem *)cocoaCheatItem { BOOL result = NO; - if (cheatItem == nil) + if (cocoaCheatItem == nil) { return result; } - _internalCheatManager->ModifyItem([cheatItem clientData], [cheatItem clientData]); - [cheatItem update]; + _internalCheatManager->ModifyItem([cocoaCheatItem clientData], [cocoaCheatItem clientData]); + [cocoaCheatItem update]; result = YES; return result; @@ -1966,43 +2195,20 @@ - (BOOL) update:(CocoaDSCheatItem *)cheatItem - (BOOL) save { - const char *lastFilePath = _internalCheatManager->GetLastFilePath(); - const CheatSystemError error = _internalCheatManager->SaveToFile(lastFilePath); + const char *lastFilePath = _internalCheatManager->GetSessionListLastFilePath(); + const CheatSystemError error = _internalCheatManager->SessionListSaveToFile(lastFilePath); return (error == CheatSystemError_NoError) ? YES : NO; } -- (NSUInteger) activeCount -{ - return (NSUInteger)_internalCheatManager->GetActiveCheatCount(); -} - -- (NSMutableArray *) cheatListFromDatabase:(NSURL *)fileURL errorCode:(NSInteger *)error -{ - NSMutableArray *newCocoaDBList = nil; - - if (fileURL == nil) - { - return newCocoaDBList; - } - - ClientCheatList *dbList = _internalCheatManager->LoadFromDatabase([CocoaDSUtil cPathFromFileURL:fileURL]); - if (dbList != NULL) - { - newCocoaDBList = [CocoaDSCheatManager cheatListWithClientListObject:dbList]; - } - - return newCocoaDBList; -} - -- (void) applyInternalCheat:(CocoaDSCheatItem *)cheatItem +- (void) applyInternalCheat:(CocoaDSCheatItem *)cocoaCheatItem { - if (cheatItem == nil) + if (cocoaCheatItem == nil) { return; } - ClientCheatManager::ApplyInternalCheatWithItem([cheatItem clientData]); + ClientCheatManager::ApplyInternalCheatWithItem([cocoaCheatItem clientData]); } - (void) loadFromMaster @@ -2010,15 +2216,26 @@ - (void) loadFromMaster CHEATS *masterCheats = ClientCheatManager::GetMaster(); if (masterCheats != NULL) { + [self willChangeValueForKey:@"itemTotalCount"]; + [self willChangeValueForKey:@"itemActiveCount"]; + _internalCheatManager->LoadFromMaster(); - if (list != nil) + [self didChangeValueForKey:@"itemTotalCount"]; + [self didChangeValueForKey:@"itemActiveCount"]; + + [sessionList removeAllObjects]; + + ClientCheatList *itemList = _internalCheatManager->GetSessionList(); + const size_t itemCount = _internalCheatManager->GetTotalCheatCount(); + for (size_t i = 0; i < itemCount; i++) { - [list release]; + CocoaDSCheatItem *cheatItem = [[CocoaDSCheatItem alloc] initWithCheatItem:itemList->GetItemAtIndex(i)]; + if (cheatItem != nil) + { + [sessionList addObject:[cheatItem autorelease]]; + } } - - ClientCheatList *clientList = _internalCheatManager->GetWorkingList(); - list = [[CocoaDSCheatManager cheatListWithClientListObject:clientList] retain]; } } @@ -2027,268 +2244,159 @@ - (void) applyToMaster _internalCheatManager->ApplyToMaster(); } -+ (NSMutableArray *) cheatListWithClientListObject:(ClientCheatList *)cheatList +- (NSMutableArray *) cheatListFromDatabase:(NSURL *)fileURL errorCode:(NSInteger *)error { - if (cheatList == NULL) + if (fileURL == nil) { return nil; } - NSMutableArray *newList = [NSMutableArray arrayWithCapacity:100]; - if (newList == nil) - { - return newList; - } + [self willChangeValueForKey:@"databaseTitle"]; + [self willChangeValueForKey:@"databaseDate"]; + + ClientCheatList *dbList = _internalCheatManager->DatabaseListLoadFromFile([CocoaDSUtil cPathFromFileURL:fileURL]); - const size_t itemCount = cheatList->GetTotalCheatCount(); - for (size_t i = 0; i < itemCount; i++) + [self didChangeValueForKey:@"databaseTitle"]; + [self didChangeValueForKey:@"databaseDate"]; + + if (dbList != NULL) { - CocoaDSCheatItem *cheatItem = [[CocoaDSCheatItem alloc] initWithCheatItem:cheatList->GetItemAtIndex(i)]; - if (cheatItem != nil) + [databaseList removeAllObjects]; + + const size_t itemCount = dbList->GetTotalCheatCount(); + for (size_t i = 0; i < itemCount; i++) { - [newList addObject:[cheatItem autorelease]]; + CocoaDSCheatItem *cheatItem = [[CocoaDSCheatItem alloc] initWithCheatItem:dbList->GetItemAtIndex(i)]; + if (cheatItem != nil) + { + [databaseList addObject:[cheatItem autorelease]]; + } } } - return newList; + return databaseList; } -@end - -@implementation CocoaDSCheatSearch - -@synthesize listData; -@synthesize addressList; -@dynamic rwlockCoreExecute; -@synthesize searchCount; - -- (id)init +- (NSUInteger) databaseAddSelected { - self = [super init]; - if(self == nil) - { - return self; - } + NSUInteger addedItemCount = 0; - CHEATSEARCH *newListData = new CHEATSEARCH(); - if (newListData == nil) + for (CocoaDSCheatItem *dbItem in databaseList) { - [self release]; - return nil; + if ([dbItem willAdd]) + { + ClientCheatItem *newCheatItem = new ClientCheatItem; + newCheatItem->Init(*[dbItem clientData]); + + CocoaDSCheatItem *newCocoaCheatItem = [self addExistingItem:newCheatItem]; + if (newCocoaCheatItem != nil) + { + addedItemCount++; + } + } } - rwlockCoreExecute = (pthread_rwlock_t *)malloc(sizeof(pthread_rwlock_t)); - pthread_rwlock_init(rwlockCoreExecute, NULL); - isUsingDummyRWlock = YES; - - listData = newListData; - addressList = nil; - searchCount = 0; - - return self; + return addedItemCount; } -- (void)dealloc +- (NSUInteger) runExactValueSearch:(NSInteger)value byteSize:(UInt8)byteSize signType:(NSInteger)signType { - pthread_rwlock_wrlock([self rwlockCoreExecute]); - [self listData]->close(); - pthread_rwlock_unlock([self rwlockCoreExecute]); + [self willChangeValueForKey:@"searchDidStart"]; + [self willChangeValueForKey:@"searchCount"]; - [addressList release]; - delete (CHEATSEARCH *)[self listData]; + pthread_rwlock_rdlock(rwlockCoreExecute); + size_t itemCount = _internalCheatManager->SearchExactValue((u32)value, (u8)byteSize, false); + pthread_rwlock_unlock(rwlockCoreExecute); - if (isUsingDummyRWlock) - { - pthread_rwlock_destroy(rwlockCoreExecute); - free(rwlockCoreExecute); - rwlockCoreExecute = NULL; - } + [self didChangeValueForKey:@"searchDidStart"]; + [self didChangeValueForKey:@"searchCount"]; - [super dealloc]; -} - -- (void) setRwlockCoreExecute:(pthread_rwlock_t *)theRwlock -{ - if (theRwlock == NULL && isUsingDummyRWlock) - { - return; - } - else if (theRwlock == NULL && !isUsingDummyRWlock) - { - rwlockCoreExecute = (pthread_rwlock_t *)malloc(sizeof(pthread_rwlock_t)); - pthread_rwlock_init(rwlockCoreExecute, NULL); - isUsingDummyRWlock = YES; - return; - } - else if (theRwlock != NULL && isUsingDummyRWlock) - { - pthread_rwlock_destroy(rwlockCoreExecute); - free(rwlockCoreExecute); - isUsingDummyRWlock = NO; - rwlockCoreExecute = theRwlock; - } - else if (theRwlock != NULL && !isUsingDummyRWlock) - { - rwlockCoreExecute = theRwlock; - } -} - -- (pthread_rwlock_t *) rwlockCoreExecute -{ - return rwlockCoreExecute; -} - -- (NSUInteger) runExactValueSearch:(NSInteger)value byteSize:(UInt8)byteSize signType:(NSInteger)signType -{ - NSUInteger itemCount = 0; - BOOL listExists = YES; + [searchResultsList removeAllObjects]; - if (searchCount == 0) + if (itemCount > 0) { - byteSize--; + const DesmumeCheatSearchResultsList &dsSearchResults = _internalCheatManager->GetSearchResults(); + const size_t resultCount = dsSearchResults.size(); - pthread_rwlock_rdlock([self rwlockCoreExecute]); - listExists = (NSUInteger)[self listData]->start((u8)CHEATSEARCH_SEARCHSTYLE_EXACT_VALUE, (u8)byteSize, (u8)signType); - pthread_rwlock_unlock([self rwlockCoreExecute]); - } - - if (listExists) - { - pthread_rwlock_rdlock([self rwlockCoreExecute]); - itemCount = (NSUInteger)[self listData]->search((u32)value); - NSMutableArray *newAddressList = [[CocoaDSCheatSearch addressListWithListObject:[self listData] maxItems:100] retain]; - pthread_rwlock_unlock([self rwlockCoreExecute]); + NSMutableDictionary *newItem = nil; - [addressList release]; - addressList = newAddressList; - searchCount++; + for (size_t i = 0; (i < resultCount) && (i < 100); i++) + { + newItem = [NSMutableDictionary dictionaryWithObjectsAndKeys: + [NSString stringWithFormat:@"0x02%06X", dsSearchResults[i].address], @"addressString", + [NSNumber numberWithUnsignedInteger:dsSearchResults[i].value], @"value", + nil]; + + [searchResultsList addObject:newItem]; + } } - [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"org.desmume.DeSmuME.searchDidFinish" object:self userInfo:nil]; - return itemCount; } -- (void) runExactValueSearchOnThread:(id)object -{ - CocoaDSCheatSearchParams *searchParams = (CocoaDSCheatSearchParams *)object; - [self runExactValueSearch:[searchParams value] byteSize:[searchParams byteSize] signType:[searchParams signType]]; -} - - (NSUInteger) runComparativeSearch:(NSInteger)typeID byteSize:(UInt8)byteSize signType:(NSInteger)signType { - NSUInteger itemCount = 0; - BOOL listExists = YES; + const bool wasSearchAlreadyStarted = _internalCheatManager->SearchDidStart(); + + [self willChangeValueForKey:@"searchDidStart"]; + [self willChangeValueForKey:@"searchCount"]; + + pthread_rwlock_rdlock(rwlockCoreExecute); + size_t itemCount = _internalCheatManager->SearchComparative((CheatSearchCompareStyle)typeID, (u8)byteSize, false); + pthread_rwlock_unlock(rwlockCoreExecute); - if (searchCount == 0) + [self didChangeValueForKey:@"searchDidStart"]; + [self didChangeValueForKey:@"searchCount"]; + + [searchResultsList removeAllObjects]; + + if (!wasSearchAlreadyStarted && _internalCheatManager->SearchDidStart()) { - byteSize--; - - pthread_rwlock_rdlock([self rwlockCoreExecute]); - listExists = (NSUInteger)[self listData]->start((u8)CHEATSEARCH_SEARCHSTYLE_COMPARATIVE, (u8)byteSize, (u8)signType); - pthread_rwlock_unlock([self rwlockCoreExecute]); - - addressList = nil; + // Do nothing. } - else + else if (itemCount > 0) { - pthread_rwlock_rdlock([self rwlockCoreExecute]); - itemCount = (NSUInteger)[self listData]->search((u8)typeID); - NSMutableArray *newAddressList = [[CocoaDSCheatSearch addressListWithListObject:[self listData] maxItems:100] retain]; - pthread_rwlock_unlock([self rwlockCoreExecute]); + const DesmumeCheatSearchResultsList &dsSearchResults = _internalCheatManager->GetSearchResults(); + const size_t resultCount = dsSearchResults.size(); - [addressList release]; - addressList = newAddressList; - } - - if (listExists) - { - searchCount++; + NSMutableDictionary *newItem = nil; + + for (size_t i = 0; (i < resultCount) && (i < 100); i++) + { + newItem = [NSMutableDictionary dictionaryWithObjectsAndKeys: + [NSString stringWithFormat:@"0x02%06X", dsSearchResults[i].address], @"addressString", + [NSNumber numberWithUnsignedInteger:dsSearchResults[i].value], @"value", + nil]; + + [searchResultsList addObject:newItem]; + } } - [[NSNotificationCenter defaultCenter] postNotificationOnMainThreadName:@"org.desmume.DeSmuME.searchDidFinish" object:self userInfo:nil]; - return itemCount; } -- (void) runComparativeSearchOnThread:(id)object +- (NSUInteger) searchCount { - CocoaDSCheatSearchParams *searchParams = (CocoaDSCheatSearchParams *)object; - [self runComparativeSearch:[searchParams comparativeSearchType] byteSize:[searchParams byteSize] signType:[searchParams signType]]; + return (NSUInteger)_internalCheatManager->GetSearchResultCount();; } -- (void) reset +- (BOOL) searchDidStart { - pthread_rwlock_wrlock([self rwlockCoreExecute]); - [self listData]->close(); - pthread_rwlock_unlock([self rwlockCoreExecute]); - - searchCount = 0; - [addressList release]; - addressList = nil; + return (_internalCheatManager->SearchDidStart()) ? YES : NO; } -+ (NSMutableArray *) addressListWithListObject:(CHEATSEARCH *)addressList maxItems:(NSUInteger)maxItemCount +- (void) searchReset { - if (addressList == nil) - { - return nil; - } + [searchResultsList removeAllObjects]; - if (maxItemCount == 0) - { - maxItemCount = 1024 * 1024 * 4; - } - - NSMutableArray *newList = [NSMutableArray arrayWithCapacity:maxItemCount]; - if (newList == nil) - { - return newList; - } + [self willChangeValueForKey:@"searchDidStart"]; + [self willChangeValueForKey:@"searchCount"]; - NSMutableDictionary *newItem = nil; - NSUInteger listCount = 0; - u32 address; - u32 value; + _internalCheatManager->SearchReset(); - addressList->getListReset(); - while (addressList->getList(&address, &value) && listCount < maxItemCount) - { - newItem = [NSMutableDictionary dictionaryWithObjectsAndKeys: - [NSString stringWithFormat:@"0x02%06X", address], @"addressString", - [NSNumber numberWithUnsignedInteger:value], @"value", - nil]; - - [newList addObject:newItem]; - listCount++; - } + [self didChangeValueForKey:@"searchDidStart"]; + [self didChangeValueForKey:@"searchCount"]; - return newList; -} - -@end - -@implementation CocoaDSCheatSearchParams - -@synthesize comparativeSearchType; -@synthesize value; -@synthesize byteSize; -@synthesize signType; - -- (id)init -{ - self = [super init]; - if(self == nil) - { - return self; - } - - comparativeSearchType = CHEATSEARCH_COMPARETYPE_EQUALS_TO; - value = 1; - byteSize = 4; - signType = CHEATSEARCH_UNSIGNED; - - return self; } @end diff --git a/desmume/src/frontend/cocoa/cocoa_core.mm b/desmume/src/frontend/cocoa/cocoa_core.mm index 5971a1449..dab23af8d 100644 --- a/desmume/src/frontend/cocoa/cocoa_core.mm +++ b/desmume/src/frontend/cocoa/cocoa_core.mm @@ -167,6 +167,7 @@ - (id)init pthread_attr_destroy(&threadAttr); [cdsGPU setOutputList:cdsOutputList rwlock:&threadParam.rwlockOutputList]; + [cdsCheatManager setRwlockCoreExecute:&threadParam.rwlockCoreExecute]; macOS_driver *newDriver = new macOS_driver; newDriver->SetCoreThreadMutexLock(&threadParam.mutexThreadExecute); diff --git a/desmume/src/frontend/cocoa/openemu/NDSGameCore.mm b/desmume/src/frontend/cocoa/openemu/NDSGameCore.mm index abc53da52..76d82f475 100644 --- a/desmume/src/frontend/cocoa/openemu/NDSGameCore.mm +++ b/desmume/src/frontend/cocoa/openemu/NDSGameCore.mm @@ -1191,34 +1191,31 @@ - (void)setCheat:(NSString *)code setType:(NSString *)type setEnabled:(BOOL)enab // state on an existing cheat, so be sure to account for both cases. // First check if the cheat exists. - CocoaDSCheatItem *cheatItem = (CocoaDSCheatItem *)[addedCheatsDict objectForKey:code]; + CocoaDSCheatItem *cocoaCheatItem = (CocoaDSCheatItem *)[addedCheatsDict objectForKey:code]; - if (cheatItem == nil) + if (cocoaCheatItem == nil) { // If the cheat doesn't already exist, then create a new one and add it. - cheatItem = [[[CocoaDSCheatItem alloc] init] autorelease]; - [cheatItem setCheatType:CHEAT_TYPE_ACTION_REPLAY]; // Default to Action Replay for now - [cheatItem setFreezeType:0]; - [cheatItem setDescription:@""]; // OpenEmu takes care of this - [cheatItem setCode:code]; - [cheatItem setMemAddress:0x00000000]; // UNUSED - [cheatItem setBytes:1]; // UNUSED - [cheatItem setValue:0]; // UNUSED + ClientCheatItem *newCheatItem = new ClientCheatItem; + newCheatItem->SetType(CheatType_ActionReplay); // Default to Action Replay for now + newCheatItem->SetFreezeType(CheatFreezeType_Normal); + newCheatItem->SetDescription(NULL); // OpenEmu takes care of this + newCheatItem->SetRawCodeString([code cStringUsingEncoding:NSUTF8StringEncoding], true); + newCheatItem->SetEnabled((enabled) ? true : false); - [cheatItem setEnabled:enabled]; - [[self cdsCheats] addExistingItem:cheatItem]; + cocoaCheatItem = [[self cdsCheats] addExistingItem:newCheatItem]; // OpenEmu doesn't currently save cheats per game, so assume that the // cheat list is short and that code strings are unique. This allows // us to get away with simply saving the cheat code string and hashing // for it later. - [addedCheatsDict setObject:cheatItem forKey:code]; + [addedCheatsDict setObject:cocoaCheatItem forKey:code]; } else { // If the cheat does exist, then just set its enable state. - [cheatItem setEnabled:enabled]; - [[self cdsCheats] update:cheatItem]; + [cocoaCheatItem setEnabled:enabled]; + [[self cdsCheats] update:cocoaCheatItem]; } } diff --git a/desmume/src/frontend/cocoa/translations/English.lproj/MainMenu.xib b/desmume/src/frontend/cocoa/translations/English.lproj/MainMenu.xib index 39a442b48..be0ebb9d7 100644 --- a/desmume/src/frontend/cocoa/translations/English.lproj/MainMenu.xib +++ b/desmume/src/frontend/cocoa/translations/English.lproj/MainMenu.xib @@ -18129,10 +18129,10 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 NSWindow - {10000, 10000} + {1.7976931348623157e+308, 1.7976931348623157e+308} {640, 480} - + 256 @@ -18148,7 +18148,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 256 {270, 335} - YES NO YES @@ -18157,7 +18156,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 256 {270, 17} - @@ -18275,7 +18273,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {{1, 17}, {270, 335}} - @@ -18289,7 +18286,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {{1, 0}, {270, 17}} - @@ -18298,7 +18294,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 -2147483392 {{256, 17}, {15, 306}} - NO _doScroller: @@ -18309,7 +18304,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 -2147483392 {{1, 323}, {270, 15}} - NO 1 @@ -18319,7 +18313,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {{20, 49}, {272, 353}} - 133682 @@ -18336,7 +18329,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 292 {{113, 12}, {185, 32}} - YES 67108864 @@ -18358,7 +18350,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 292 {{47, 19}, {28, 23}} - YES -2080374784 @@ -18384,7 +18375,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 292 {{20, 19}, {28, 23}} - YES -2080374784 @@ -18418,7 +18408,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{100, 372}, {209, 26}} - YES -2076180416 @@ -18483,7 +18472,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 272 {{2, 32}, {320, 274}} - NSView @@ -18491,7 +18479,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{16, 402}, {130, 18}} - YES 67108864 @@ -18515,7 +18502,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{15, 378}, {83, 17}} - YES 68157504 @@ -18534,7 +18520,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 12 {{14, 303}, {292, 5}} - {0, 0} 67108864 @@ -18554,7 +18539,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{103, 313}, {203, 57}} - YES -1805647871 @@ -18574,7 +18558,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{15, 353}, {83, 17}} - YES 68157504 @@ -18593,7 +18576,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 292 {{114, 3}, {96, 32}} - YES 67108864 @@ -18613,12 +18595,10 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {{1, 1}, {324, 428}} - {{297, 16}, {326, 444}} - {0, 0} 67108864 @@ -18639,7 +18619,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{76, 408}, {190, 18}} - YES -2080374784 @@ -18674,7 +18653,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {{20, 410}, {50, 50}} - YES 134217728 @@ -18693,7 +18671,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{75, 432}, {168, 28}} - YES 69206017 @@ -18712,18 +18689,15 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{29, 419}, {32, 32}} - 28682 100 {640, 480} - - {{0, 0}, {1920, 1177}} {640, 502} - {10000, 10022} + {1.7976931348623157e+308, 1.7976931348623157e+308} CheatManagerWindow YES @@ -18731,7 +18705,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 CheatWindowDelegate - + 256 @@ -18739,7 +18713,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 292 {{17, 4}, {294, 14}} - YES 68157504 @@ -18762,7 +18735,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 1292 {{214, 220}, {16, 16}} - 28938 100 @@ -18771,7 +18743,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{133, 369}, {136, 22}} - YES -2076180416 @@ -18827,7 +18798,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{45, 374}, {86, 14}} - YES 68157504 @@ -18846,7 +18816,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{45, 398}, {86, 14}} - YES 68157504 @@ -18865,7 +18834,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{133, 393}, {136, 22}} - YES -2076180416 @@ -18922,7 +18890,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{0, 237}, {328, 134}} - NSView @@ -18930,7 +18897,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{233, 213}, {80, 28}} - YES 67108864 @@ -18952,7 +18918,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{59, 222}, {150, 14}} - YES 68157504 @@ -18972,7 +18937,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{17, 222}, {45, 14}} - YES 68157504 @@ -18999,7 +18963,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 256 {286, 176} - YES NO YES @@ -19008,7 +18971,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 256 {286, 17} - @@ -19090,7 +19052,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {{1, 17}, {286, 176}} - @@ -19104,7 +19065,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {{1, 0}, {286, 17}} - @@ -19113,7 +19073,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 -2147483392 {{224, 17}, {15, 102}} - NO _doScroller: @@ -19124,7 +19083,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 -2147483392 {{1, 294}, {338, 15}} - NO 1 @@ -19134,7 +19092,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {{20, 20}, {288, 194}} - 133682 @@ -19148,8 +19105,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {328, 434} - - NSView @@ -19175,7 +19130,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {1.7976931348623157e+308, 1.7976931348623157e+308} {500, 272} - + 256 @@ -19191,7 +19146,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 256 {500, 287} - YES NO YES @@ -19200,7 +19154,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 256 {500, 17} - @@ -19288,7 +19241,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {{1, 17}, {500, 287}} - @@ -19299,7 +19251,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 -2147483392 {{224, 17}, {15, 102}} - NO _doScroller: @@ -19310,7 +19261,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 -2147483392 {{1, 249}, {568, 15}} - NO 1 @@ -19325,14 +19275,12 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {{1, 0}, {500, 17}} - {{-1, 57}, {502, 305}} - 133682 @@ -19349,7 +19297,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{17, 370}, {125, 14}} - YES 68157504 @@ -19368,7 +19315,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{17, 392}, {68, 14}} - YES 68157504 @@ -19387,7 +19333,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 292 {{14, 12}, {114, 32}} - YES 67108864 @@ -19409,7 +19354,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 292 {{128, 12}, {114, 32}} - YES 67108864 @@ -19431,7 +19375,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 289 {{390, 12}, {96, 32}} - 1 YES @@ -19454,7 +19397,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 289 {{294, 12}, {96, 32}} - YES 67108864 @@ -19476,7 +19418,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 265 {{372, 370}, {48, 14}} - YES 68157504 @@ -19495,7 +19436,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{144, 370}, {232, 14}} - YES 70254657 @@ -19515,7 +19455,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 265 {{422, 370}, {61, 14}} - YES 70254657 @@ -19535,7 +19474,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{87, 392}, {396, 14}} - YES 70254657 @@ -19552,8 +19490,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {500, 416} - - {{0, 0}, {1920, 1177}} {500, 294} @@ -19561,7 +19497,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 YES - + 268 @@ -19569,7 +19505,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{233, 54}, {80, 28}} - YES 67108864 @@ -19591,7 +19526,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{20, 59}, {210, 19}} - YES YES @@ -19646,7 +19580,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{17, 86}, {294, 14}} - YES 67108864 @@ -19665,7 +19598,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{17, 100}, {294, 14}} - YES 67108864 @@ -19681,8 +19613,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {328, 134} - - NSView @@ -19882,7 +19812,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 NSView - + 272 @@ -19890,7 +19820,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{197, 175}, {109, 32}} - YES 67108864 @@ -19912,7 +19841,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 292 {{17, 7}, {286, 42}} - YES 67108864 @@ -19931,7 +19859,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{17, 246}, {128, 17}} - YES 68157504 @@ -19950,7 +19877,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{149, 241}, {27, 27}} - YES -2080374784 @@ -19973,7 +19899,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{79, 214}, {38, 17}} - YES 68157504 @@ -19996,7 +19921,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{67, 182}, {128, 22}} - YES -1804599231 @@ -20054,7 +19978,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{17, 185}, {45, 17}} - YES 68157504 @@ -20073,7 +19996,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{118, 212}, {77, 22}} - YES -1804599231 @@ -20093,7 +20015,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{17, 215}, {60, 17}} - YES 68157504 @@ -20120,7 +20041,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{18, 14}, {190, 78}} - YES NO 4 @@ -20388,12 +20308,10 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {{1, 1}, {226, 102}} - {{46, 56}, {228, 118}} - {0, 0} 67108864 @@ -20411,12 +20329,10 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {320, 274} - - NSView - + 272 @@ -20451,7 +20367,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {278, 226} - @@ -20503,7 +20418,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {{1, 1}, {278, 226}} - @@ -20515,7 +20429,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 -2147483392 {{263, 1}, {16, 225.890625}} - NO _doScroller: @@ -20526,7 +20439,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 -2147483392 {{-100, -100}, {87, 18}} - NO 1 @@ -20537,7 +20449,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {{20, 15}, {280, 228}} - 133650 @@ -20552,7 +20463,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{17, 249}, {138, 17}} - YES 68157504 @@ -20568,12 +20478,10 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {320, 274} - - NSView - + 301 @@ -20592,7 +20500,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {{101, 117}, {128, 128}} - YES 134217728 @@ -20614,7 +20521,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 268 {{17, 19}, {286, 72}} - YES 67108864 @@ -20634,8 +20540,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 {320, 274} - - NSView @@ -42604,7 +42508,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 hasSelection hasItems - cheatList + cheatWindowDelegateKey cheatSearchStyle cheatSearchSignType cheatSearchSearchValue @@ -84366,7 +84270,7 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 com.apple.InterfaceBuilder.CocoaPlugin {{493, 199}, {640, 480}} - + {10000, 10000} {640, 480} @@ -87361,7 +87265,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 - NSTextView NSBox NSArrayController NSWindow @@ -87384,10 +87287,6 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2 NSWindow - - actionReplayCodeEditorView - NSTextView - cheatConfigBox NSBox diff --git a/desmume/src/frontend/cocoa/userinterface/EmuControllerDelegate.mm b/desmume/src/frontend/cocoa/userinterface/EmuControllerDelegate.mm index 9b11bd416..022a51e05 100644 --- a/desmume/src/frontend/cocoa/userinterface/EmuControllerDelegate.mm +++ b/desmume/src/frontend/cocoa/userinterface/EmuControllerDelegate.mm @@ -1933,73 +1933,7 @@ - (void) loadRomDidFinish:(NSNotification *)aNotification // If the ROM has an associated cheat file, load it now. CocoaDSCore *cdsCore = (CocoaDSCore *)[cdsCoreController content]; - CocoaDSCheatManager *newCheatList = [cdsCore cdsCheatManager]; - if (newCheatList != nil) - { - [newCheatList loadFromMaster]; - - NSMutableDictionary *cheatWindowBindings = (NSMutableDictionary *)[cheatWindowController content]; - - [cheatListController setContent:[newCheatList list]]; - [cheatWindowBindings setValue:newCheatList forKey:@"cheatList"]; - - NSString *filePath = [[NSUserDefaults standardUserDefaults] stringForKey:@"R4Cheat_DatabasePath"]; - if (filePath != nil) - { - NSURL *fileURL = [NSURL fileURLWithPath:filePath]; - NSInteger error = 0; - NSMutableArray *dbList = [newCheatList cheatListFromDatabase:fileURL errorCode:&error]; - if (dbList != nil) - { - [cheatDatabaseController setContent:dbList]; - - NSString *titleString = [newCheatList dbTitle]; - NSString *dateString = [newCheatList dbDate]; - - [cheatWindowBindings setValue:titleString forKey:@"cheatDBTitle"]; - [cheatWindowBindings setValue:dateString forKey:@"cheatDBDate"]; - [cheatWindowBindings setValue:[NSString stringWithFormat:@"%ld", (unsigned long)[dbList count]] forKey:@"cheatDBItemCount"]; - } - else - { - [cheatWindowBindings setValue:@"---" forKey:@"cheatDBItemCount"]; - - switch (error) - { - case CHEATEXPORT_ERROR_FILE_NOT_FOUND: - NSLog(@"R4 Cheat Database read failed! Could not load the database file!"); - [cheatWindowBindings setValue:@"Database not loaded." forKey:@"cheatDBTitle"]; - [cheatWindowBindings setValue:@"CANNOT LOAD FILE" forKey:@"cheatDBDate"]; - break; - - case CHEATEXPORT_ERROR_WRONG_FILE_FORMAT: - NSLog(@"R4 Cheat Database read failed! Wrong file format!"); - [cheatWindowBindings setValue:@"Database load error." forKey:@"cheatDBTitle"]; - [cheatWindowBindings setValue:@"FAILED TO LOAD FILE" forKey:@"cheatDBDate"]; - break; - - case CHEATEXPORT_ERROR_SERIAL_NOT_FOUND: - NSLog(@"R4 Cheat Database read failed! Could not find the serial number for this game in the database!"); - [cheatWindowBindings setValue:@"ROM not found in database." forKey:@"cheatDBTitle"]; - [cheatWindowBindings setValue:@"ROM not found." forKey:@"cheatDBDate"]; - break; - - case CHEATEXPORT_ERROR_EXPORT_FAILED: - NSLog(@"R4 Cheat Database read failed! Could not read the database file!"); - [cheatWindowBindings setValue:@"Database read error." forKey:@"cheatDBTitle"]; - [cheatWindowBindings setValue:@"CANNOT READ FILE" forKey:@"cheatDBDate"]; - break; - - default: - break; - } - } - } - - [cheatWindowDelegate setCdsCheats:newCheatList]; - [[cheatWindowDelegate cdsCheatSearch] setRwlockCoreExecute:[cdsCore rwlockCoreExecute]]; - [cheatWindowDelegate setCheatSearchViewByStyle:CHEATSEARCH_SEARCHSTYLE_EXACT_VALUE]; - } + [cheatWindowDelegate cheatSystemStart:[cdsCore cdsCheatManager]]; // Add the last loaded ROM to the Recent ROMs list. [[NSDocumentController sharedDocumentController] noteNewRecentDocumentURL:[theRom fileURL]]; @@ -2053,22 +1987,11 @@ - (BOOL) unloadRom [[windowController window] displayIfNeeded]; } - // Save the ROM's cheat list before unloading. - [[cdsCore cdsCheatManager] save]; + [cheatWindowDelegate cheatSystemEnd]; // Update the UI to indicate that the ROM has started the process of unloading. [self setStatusText:NSSTRING_STATUS_ROM_UNLOADING]; [romInfoPanelController setContent:[CocoaDSRom romNotLoadedBindings]]; - [cheatListController setContent:nil]; - [cheatWindowDelegate resetSearch:nil]; - [cheatWindowDelegate setCdsCheats:nil]; - [cheatDatabaseController setContent:nil]; - - NSMutableDictionary *cheatWindowBindings = (NSMutableDictionary *)[cheatWindowController content]; - [cheatWindowBindings setValue:@"No ROM loaded." forKey:@"cheatDBTitle"]; - [cheatWindowBindings setValue:@"No ROM loaded." forKey:@"cheatDBDate"]; - [cheatWindowBindings setValue:@"---" forKey:@"cheatDBItemCount"]; - [cheatWindowBindings setValue:nil forKey:@"cheatList"]; // Unload the ROM. if (![cdsCore emuFlagUseExternalBios] || ![cdsCore emuFlagUseExternalFirmware]) diff --git a/desmume/src/frontend/cocoa/userinterface/cheatWindowDelegate.h b/desmume/src/frontend/cocoa/userinterface/cheatWindowDelegate.h index a7a8bc303..0d80e2940 100644 --- a/desmume/src/frontend/cocoa/userinterface/cheatWindowDelegate.h +++ b/desmume/src/frontend/cocoa/userinterface/cheatWindowDelegate.h @@ -21,7 +21,6 @@ @class CocoaDSCheatItem; @class CocoaDSCheatManager; @class CocoaDSCheatSearch; -@class CocoaDSCheatSearchParams; #if MAC_OS_X_VERSION_MAX_ALLOWED > MAC_OS_X_VERSION_10_5 @@ -62,7 +61,6 @@ NSMutableDictionary *bindings; CocoaDSCheatItem *workingCheat; CocoaDSCheatManager *cdsCheats; - CocoaDSCheatSearch *cdsCheatSearch; } @property (assign) IBOutlet NSObject *dummyObject; @@ -95,7 +93,9 @@ @property (readonly) NSMutableDictionary *bindings; @property (retain) CocoaDSCheatItem *workingCheat; @property (retain) CocoaDSCheatManager *cdsCheats; -@property (readonly) CocoaDSCheatSearch *cdsCheatSearch; + +- (BOOL) cheatSystemStart:(CocoaDSCheatManager *)theManager; +- (void) cheatSystemEnd; - (IBAction) addToList:(id)sender; - (IBAction) removeFromList:(id)sender; @@ -107,15 +107,15 @@ - (IBAction) selectCheatSearchStyle:(id)sender; - (IBAction) runExactValueSearch:(id)sender; - (IBAction) runComparativeSearch:(id)sender; -- (void) searchDidFinish:(NSNotification *)aNotification; - (IBAction) resetSearch:(id)sender; - (void) setCheatConfigViewByType:(NSInteger)cheatTypeID; - (void) setCheatSearchViewByStyle:(NSInteger)searchStyleID; +- (void) databaseLoadFromFile:(NSURL *)fileURL; +- (void) addSelectedFromCheatDatabase; - (IBAction) selectAllCheatsInDatabase:(id)sender; - (IBAction) selectNoneCheatsInDatabase:(id)sender; -- (void) addSelectedFromCheatDatabase; - (IBAction) closeCheatDatabaseSheet:(id)sender; - (void) didEndCheatDatabaseSheet:(NSWindow *)sheet returnCode:(NSInteger)returnCode contextInfo:(void *)contextInfo; diff --git a/desmume/src/frontend/cocoa/userinterface/cheatWindowDelegate.mm b/desmume/src/frontend/cocoa/userinterface/cheatWindowDelegate.mm index 53caf472b..b4bf33994 100644 --- a/desmume/src/frontend/cocoa/userinterface/cheatWindowDelegate.mm +++ b/desmume/src/frontend/cocoa/userinterface/cheatWindowDelegate.mm @@ -53,7 +53,6 @@ @implementation CheatWindowDelegate @synthesize codeEditorFont; @synthesize bindings; @synthesize cdsCheats; -@synthesize cdsCheatSearch; @synthesize workingCheat; - (id)init @@ -72,15 +71,6 @@ - (id)init return self; } - cdsCheatSearch = [[CocoaDSCheatSearch alloc] init]; - if (cdsCheatSearch == nil) - { - [bindings release]; - [self release]; - self = nil; - return self; - } - workingCheat = nil; currentView = nil; currentSearchStyleView = nil; @@ -108,12 +98,59 @@ - (void)dealloc { [self setWorkingCheat:nil]; [self setCdsCheats:nil]; - [cdsCheatSearch release]; [bindings release]; [super dealloc]; } +- (BOOL) cheatSystemStart:(CocoaDSCheatManager *)cheatManager +{ + BOOL didStartSuccessfully = NO; + + if (cheatManager == nil) + { + return didStartSuccessfully; + } + + [self setCdsCheats:cheatManager]; + [cheatManager loadFromMaster]; + [cheatListController setContent:[cheatManager sessionList]]; + + NSMutableDictionary *cheatWindowBindings = (NSMutableDictionary *)[cheatWindowController content]; + [cheatWindowBindings setValue:self forKey:@"cheatWindowDelegateKey"]; + + NSString *dbFilePath = [[NSUserDefaults standardUserDefaults] stringForKey:@"R4Cheat_DatabasePath"]; + if (dbFilePath != nil) + { + [self databaseLoadFromFile:[NSURL fileURLWithPath:dbFilePath]]; + } + + [self setCheatSearchViewByStyle:CHEATSEARCH_SEARCHSTYLE_EXACT_VALUE]; + + didStartSuccessfully = YES; + return didStartSuccessfully; +} + +- (void) cheatSystemEnd +{ + CocoaDSCheatManager *cheatManager = [self cdsCheats]; + if (cheatManager != nil) + { + [cheatManager save]; + } + + [cheatDatabaseController setContent:nil]; + [cheatListController setContent:nil]; + [self resetSearch:nil]; + [self setCdsCheats:nil]; + + NSMutableDictionary *cheatWindowBindings = (NSMutableDictionary *)[cheatWindowController content]; + [cheatWindowBindings setValue:@"No ROM loaded." forKey:@"cheatDBTitle"]; + [cheatWindowBindings setValue:@"No ROM loaded." forKey:@"cheatDBDate"]; + [cheatWindowBindings setValue:@"---" forKey:@"cheatDBItemCount"]; + [cheatWindowBindings setValue:nil forKey:@"cheatWindowDelegateKey"]; +} + - (IBAction) addToList:(id)sender { if ([self cdsCheats] == nil) @@ -121,10 +158,10 @@ - (IBAction) addToList:(id)sender return; } - CocoaDSCheatItem *newCheatItem = [[[self cdsCheats] newItem] autorelease]; + CocoaDSCheatItem *newCheatItem = [[self cdsCheats] newItem]; if (newCheatItem != nil) { - [cheatListController addObject:newCheatItem]; + [cheatListController setContent:[[self cdsCheats] sessionList]]; [bindings setValue:[NSNumber numberWithBool:YES] forKey:@"hasItems"]; [[self cdsCheats] save]; } @@ -132,8 +169,8 @@ - (IBAction) addToList:(id)sender - (IBAction) removeFromList:(id)sender { - NSMutableArray *cheatList = (NSMutableArray *)[cheatListController content]; - if ( ([self cdsCheats] == nil) || (cheatList == nil) ) + CocoaDSCheatManager *cheatManager = [self cdsCheats]; + if (cheatManager == nil) { return; } @@ -144,19 +181,19 @@ - (IBAction) removeFromList:(id)sender return; } - NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:selectionIndex]; - NSArray *selectedObjects = [cheatListController selectedObjects]; CocoaDSCheatItem *selectedCheat = (CocoaDSCheatItem *)[selectedObjects objectAtIndex:0]; - [[self cdsCheats] remove:selectedCheat]; - [cheatListController removeObject:selectedCheat]; + [cheatManager remove:selectedCheat]; - [[self cdsCheats] save]; + [cheatListController setContent:[cheatManager sessionList]]; + [cheatManager save]; [cheatListTable deselectAll:sender]; - NSUInteger cheatCount = [cheatList count]; + NSUInteger cheatCount = [cheatManager itemTotalCount]; if (cheatCount > 0) { + NSIndexSet *indexSet = [NSIndexSet indexSetWithIndex:selectionIndex]; + if (selectionIndex >= cheatCount) { selectionIndex--; @@ -245,9 +282,11 @@ - (IBAction) runExactValueSearch:(id)sender NSInteger value = [searchField integerValue]; UInt8 byteSize = [[self workingCheat] bytes]; NSInteger signType = [(NSNumber *)[bindings valueForKey:@"cheatSearchSignType"] integerValue]; - NSUInteger addressCount = [cdsCheatSearch runExactValueSearch:value byteSize:byteSize signType:signType]; - [bindings setValue:[NSNumber numberWithUnsignedInteger:addressCount] forKey:@"cheatSearchAddressCount"]; - [cheatSearchListController setContent:[cdsCheatSearch addressList]]; + + NSUInteger resultsCount = [cdsCheats runExactValueSearch:value byteSize:byteSize signType:signType]; + + [bindings setValue:[NSNumber numberWithUnsignedInteger:resultsCount] forKey:@"cheatSearchAddressCount"]; + [cheatSearchListController setContent:[[self cdsCheats] searchResultsList]]; [bindings setValue:[NSNumber numberWithBool:NO] forKey:@"isRunningSearch"]; } @@ -262,7 +301,8 @@ - (IBAction) runComparativeSearch:(id)sender [bindings setValue:[NSNumber numberWithBool:YES] forKey:@"isSearchStarted"]; [bindings setValue:[NSNumber numberWithBool:YES] forKey:@"isRunningSearch"]; - if ([cdsCheatSearch searchCount] == 0) + const BOOL wasSearchAlreadyStarted = [cdsCheats searchDidStart]; + if (!wasSearchAlreadyStarted) { [bindings setValue:@"Running initial search..." forKey:@"cheatSearchAddressCount"]; [window displayIfNeeded]; @@ -271,37 +311,23 @@ - (IBAction) runComparativeSearch:(id)sender NSInteger compSearchTypeID = [CocoaDSUtil getIBActionSenderTag:sender]; UInt8 byteSize = [[self workingCheat] bytes]; NSInteger signType = [(NSNumber *)[bindings valueForKey:@"cheatSearchSignType"] integerValue]; - NSUInteger addressCount = [cdsCheatSearch runComparativeSearch:compSearchTypeID byteSize:byteSize signType:signType]; - [bindings setValue:[NSNumber numberWithUnsignedInteger:addressCount] forKey:@"cheatSearchAddressCount"]; - [cheatSearchListController setContent:[cdsCheatSearch addressList]]; + + NSUInteger newResultsCount = [cdsCheats runComparativeSearch:compSearchTypeID byteSize:byteSize signType:signType]; + [cheatSearchListController setContent:[[self cdsCheats] searchResultsList]]; NSInteger searchStyle = [(NSNumber *)[bindings valueForKey:@"cheatSearchStyle"] integerValue]; - if (searchStyle == CHEATSEARCH_SEARCHSTYLE_COMPARATIVE && [cdsCheatSearch searchCount] == 1) + if (searchStyle == CHEATSEARCH_SEARCHSTYLE_COMPARATIVE) { [self setCheatSearchViewByStyle:CHEATSEARCH_SEARCHSTYLE_COMPARATIVE]; - [bindings setValue:@"Search started!" forKey:@"cheatSearchAddressCount"]; } - [bindings setValue:[NSNumber numberWithBool:NO] forKey:@"isRunningSearch"]; -} - -- (void) searchDidFinish:(NSNotification *)aNotification -{ - CocoaDSCheatSearch *searcher = [aNotification object]; - NSInteger addressCount = 0; - - if (searcher != nil) + if (!wasSearchAlreadyStarted) { - addressCount = [[searcher addressList] count]; - [bindings setValue:[NSNumber numberWithUnsignedInteger:addressCount] forKey:@"cheatSearchAddressCount"]; - [cheatSearchListController setContent:[searcher addressList]]; - - NSInteger searchStyle = [(NSNumber *)[bindings valueForKey:@"cheatSearchStyle"] integerValue]; - if (searchStyle == CHEATSEARCH_SEARCHSTYLE_COMPARATIVE && [searcher searchCount] == 1) - { - [self setCheatSearchViewByStyle:CHEATSEARCH_SEARCHSTYLE_COMPARATIVE]; - [bindings setValue:@"Search started!" forKey:@"cheatSearchAddressCount"]; - } + [bindings setValue:@"Search started!" forKey:@"cheatSearchAddressCount"]; + } + else + { + [bindings setValue:[NSNumber numberWithUnsignedInteger:newResultsCount] forKey:@"cheatSearchAddressCount"]; } [bindings setValue:[NSNumber numberWithBool:NO] forKey:@"isRunningSearch"]; @@ -309,8 +335,8 @@ - (void) searchDidFinish:(NSNotification *)aNotification - (IBAction) resetSearch:(id)sender { - [cheatSearchListController setContent:nil]; - [cdsCheatSearch reset]; + [[self cdsCheats] searchReset]; + [cheatSearchListController setContent:[[self cdsCheats] searchResultsList]]; [bindings setValue:nil forKey:@"cheatSearchSearchValue"]; [bindings setValue:@"Search not started." forKey:@"cheatSearchAddressCount"]; [self setCheatSearchViewByStyle:[(NSNumber *)[bindings valueForKey:@"cheatSearchStyle"] integerValue]]; @@ -370,7 +396,7 @@ - (void) setCheatSearchViewByStyle:(NSInteger)searchStyleID break; case CHEATSEARCH_SEARCHSTYLE_COMPARATIVE: - if ([cdsCheatSearch searchCount] == 0) + if ([cdsCheats searchDidStart] == 0) { newView = viewSearchComparativeStart; } @@ -394,35 +420,83 @@ - (void) setCheatSearchViewByStyle:(NSInteger)searchStyleID } } -- (IBAction) selectAllCheatsInDatabase:(id)sender +- (void) databaseLoadFromFile:(NSURL *)fileURL { - NSMutableArray *dbList = [cheatDatabaseController content]; - if (dbList == nil) + CocoaDSCheatManager *cheatManager = [self cdsCheats]; + NSMutableDictionary *cheatWindowBindings = (NSMutableDictionary *)[cheatWindowController content]; + + if ( (fileURL == nil) || (cheatManager == nil) || (cheatWindowBindings == nil) ) { return; } - for (CocoaDSCheatItem *cheatItem in dbList) + NSInteger error = 0; + NSMutableArray *dbList = [cheatManager cheatListFromDatabase:fileURL errorCode:&error]; + if (dbList != nil) { - [cheatItem setWillAdd:YES]; + [cheatDatabaseController setContent:dbList]; + + NSString *titleString = [cheatManager databaseTitle]; + NSString *dateString = [cheatManager databaseDate]; + + [cheatWindowBindings setValue:titleString forKey:@"cheatDBTitle"]; + [cheatWindowBindings setValue:dateString forKey:@"cheatDBDate"]; + [cheatWindowBindings setValue:[NSString stringWithFormat:@"%ld", (unsigned long)[dbList count]] forKey:@"cheatDBItemCount"]; + } + else + { + [cheatWindowBindings setValue:@"---" forKey:@"cheatDBItemCount"]; + + switch (error) + { + case CHEATEXPORT_ERROR_FILE_NOT_FOUND: + NSLog(@"R4 Cheat Database read failed! Could not load the database file!"); + [cheatWindowBindings setValue:@"Database not loaded." forKey:@"cheatDBTitle"]; + [cheatWindowBindings setValue:@"CANNOT LOAD FILE" forKey:@"cheatDBDate"]; + break; + + case CHEATEXPORT_ERROR_WRONG_FILE_FORMAT: + NSLog(@"R4 Cheat Database read failed! Wrong file format!"); + [cheatWindowBindings setValue:@"Database load error." forKey:@"cheatDBTitle"]; + [cheatWindowBindings setValue:@"FAILED TO LOAD FILE" forKey:@"cheatDBDate"]; + break; + + case CHEATEXPORT_ERROR_SERIAL_NOT_FOUND: + NSLog(@"R4 Cheat Database read failed! Could not find the serial number for this game in the database!"); + [cheatWindowBindings setValue:@"ROM not found in database." forKey:@"cheatDBTitle"]; + [cheatWindowBindings setValue:@"ROM not found." forKey:@"cheatDBDate"]; + break; + + case CHEATEXPORT_ERROR_EXPORT_FAILED: + NSLog(@"R4 Cheat Database read failed! Could not read the database file!"); + [cheatWindowBindings setValue:@"Database read error." forKey:@"cheatDBTitle"]; + [cheatWindowBindings setValue:@"CANNOT READ FILE" forKey:@"cheatDBDate"]; + break; + + default: + break; + } } } -- (IBAction) selectNoneCheatsInDatabase:(id)sender +- (void) addSelectedFromCheatDatabase { - NSMutableArray *dbList = [cheatDatabaseController content]; - if (dbList == nil) + CocoaDSCheatManager *cheatManager = [self cdsCheats]; + if (cheatManager == nil) { return; } - for (CocoaDSCheatItem *cheatItem in dbList) + const NSInteger addedItemCount = [cheatManager databaseAddSelected]; + if (addedItemCount > 0) { - [cheatItem setWillAdd:NO]; + [cheatListController setContent:[[self cdsCheats] sessionList]]; + [[self cdsCheats] save]; + [bindings setValue:[NSNumber numberWithBool:YES] forKey:@"hasItems"]; } } -- (void) addSelectedFromCheatDatabase +- (IBAction) selectAllCheatsInDatabase:(id)sender { NSMutableArray *dbList = [cheatDatabaseController content]; if (dbList == nil) @@ -430,30 +504,23 @@ - (void) addSelectedFromCheatDatabase return; } - size_t addedItemCount = 0; - BOOL didAddItem = NO; - - for (CocoaDSCheatItem *dbItem in dbList) + for (CocoaDSCheatItem *cheatItem in dbList) { - if ([dbItem willAdd]) - { - CocoaDSCheatItem *newCocoaCheatItem = [[[CocoaDSCheatItem alloc] init] autorelease]; - ClientCheatItem *newCheatItem = [newCocoaCheatItem clientData]; - newCheatItem->Init(*[dbItem clientData]); - - didAddItem = [[self cdsCheats] addExistingItem:newCocoaCheatItem]; - if (didAddItem) - { - [cheatListController addObject:newCocoaCheatItem]; - addedItemCount++; - } - } + [cheatItem setWillAdd:YES]; + } +} + +- (IBAction) selectNoneCheatsInDatabase:(id)sender +{ + NSMutableArray *dbList = [cheatDatabaseController content]; + if (dbList == nil) + { + return; } - if (addedItemCount > 0) + for (CocoaDSCheatItem *cheatItem in dbList) { - [[self cdsCheats] save]; - [bindings setValue:[NSNumber numberWithBool:YES] forKey:@"hasItems"]; + [cheatItem setWillAdd:NO]; } } diff --git a/desmume/src/frontend/cocoa/userinterface/preferencesWindowDelegate.mm b/desmume/src/frontend/cocoa/userinterface/preferencesWindowDelegate.mm index 83f9e9cf4..76a3b4c8a 100644 --- a/desmume/src/frontend/cocoa/userinterface/preferencesWindowDelegate.mm +++ b/desmume/src/frontend/cocoa/userinterface/preferencesWindowDelegate.mm @@ -18,6 +18,7 @@ #import "preferencesWindowDelegate.h" #import "EmuControllerDelegate.h" +#import "cheatWindowDelegate.h" #import "cocoa_core.h" #import "cocoa_GPU.h" @@ -580,58 +581,11 @@ - (void) chooseCheatDatabaseDidEnd:(NSOpenPanel *)sheet returnCode:(int)returnCo const BOOL isRomLoaded = [(EmuControllerDelegate *)[emuController content] currentRom] != nil; NSMutableDictionary *cheatWindowBindings = (NSMutableDictionary *)[cheatWindowController content]; - CocoaDSCheatManager *cdsCheats = (CocoaDSCheatManager *)[cheatWindowBindings valueForKey:@"cheatList"]; + CheatWindowDelegate *cheatWindowDelegate = (CheatWindowDelegate *)[cheatWindowBindings valueForKey:@"cheatWindowDelegateKey"]; - if (isRomLoaded == YES && cdsCheats != nil) + if ( (isRomLoaded == YES) && (cheatWindowDelegate != nil) ) { - NSInteger error = 0; - NSMutableArray *dbList = [cdsCheats cheatListFromDatabase:selectedFileURL errorCode:&error]; - if (dbList != nil) - { - [cheatDatabaseController setContent:dbList]; - - NSString *titleString = [cdsCheats dbTitle]; - NSString *dateString = [cdsCheats dbDate]; - - [cheatWindowBindings setValue:titleString forKey:@"cheatDBTitle"]; - [cheatWindowBindings setValue:dateString forKey:@"cheatDBDate"]; - [cheatWindowBindings setValue:[NSString stringWithFormat:@"%ld", (unsigned long)[dbList count]] forKey:@"cheatDBItemCount"]; - } - else - { - // TODO: Display an error message here. - [cheatWindowBindings setValue:@"---" forKey:@"cheatDBItemCount"]; - - switch (error) - { - case CHEATEXPORT_ERROR_FILE_NOT_FOUND: - NSLog(@"R4 Cheat Database read failed! Could not load the database file!"); - [cheatWindowBindings setValue:@"Database not loaded." forKey:@"cheatDBTitle"]; - [cheatWindowBindings setValue:@"CANNOT LOAD FILE" forKey:@"cheatDBDate"]; - break; - - case CHEATEXPORT_ERROR_WRONG_FILE_FORMAT: - NSLog(@"R4 Cheat Database read failed! Wrong file format!"); - [cheatWindowBindings setValue:@"Database load error." forKey:@"cheatDBTitle"]; - [cheatWindowBindings setValue:@"FAILED TO LOAD FILE" forKey:@"cheatDBDate"]; - break; - - case CHEATEXPORT_ERROR_SERIAL_NOT_FOUND: - NSLog(@"R4 Cheat Database read failed! Could not find the serial number for this game in the database!"); - [cheatWindowBindings setValue:@"ROM not found in database." forKey:@"cheatDBTitle"]; - [cheatWindowBindings setValue:@"ROM not found." forKey:@"cheatDBDate"]; - break; - - case CHEATEXPORT_ERROR_EXPORT_FAILED: - NSLog(@"R4 Cheat Database read failed! Could not read the database file!"); - [cheatWindowBindings setValue:@"Database read error." forKey:@"cheatDBTitle"]; - [cheatWindowBindings setValue:@"CANNOT READ FILE" forKey:@"cheatDBDate"]; - break; - - default: - break; - } - } + [cheatWindowDelegate databaseLoadFromFile:selectedFileURL]; } } diff --git a/desmume/src/frontend/cocoa/userinterface/troubleshootingWindowDelegate.mm b/desmume/src/frontend/cocoa/userinterface/troubleshootingWindowDelegate.mm index 939f1e02e..2d79e0d72 100644 --- a/desmume/src/frontend/cocoa/userinterface/troubleshootingWindowDelegate.mm +++ b/desmume/src/frontend/cocoa/userinterface/troubleshootingWindowDelegate.mm @@ -147,7 +147,7 @@ - (IBAction) continueToFinalForm:(id)sender finalFormTextStr = [[finalFormTextStr stringByAppendingString:@"\nAudio - Sound Interpolation Method: "] stringByAppendingString:[[emuControl cdsSpeaker] spuInterpolationModeString]]; finalFormTextStr = [[finalFormTextStr stringByAppendingString:@"\nAudio - Sound Synchronization Method: "] stringByAppendingString:[[emuControl cdsSpeaker] spuSyncMethodString]]; finalFormTextStr = [finalFormTextStr stringByAppendingString:@"\n"]; - finalFormTextStr = [[finalFormTextStr stringByAppendingString:@"\nCheats: "] stringByAppendingString:(([cdsCore isCheatingEnabled] && ([[cdsCore cdsCheatManager] activeCount] > 0)) ? [NSString stringWithFormat:@"YES (ActiveCheatCount=%ld)", (unsigned long)[[cdsCore cdsCheatManager] activeCount]] : @"NO")]; + finalFormTextStr = [[finalFormTextStr stringByAppendingString:@"\nCheats: "] stringByAppendingString:(([cdsCore isCheatingEnabled] && ([[cdsCore cdsCheatManager] itemActiveCount] > 0)) ? [NSString stringWithFormat:@"YES (ActiveCheatCount=%ld)", (unsigned long)[[cdsCore cdsCheatManager] itemActiveCount]] : @"NO")]; finalFormTextStr = [finalFormTextStr stringByAppendingString:@"\n"]; if ([window contentView] == viewSupportRequest)