diff --git a/desmume/src/frontend/cocoa/DefaultKeyMappings.plist b/desmume/src/frontend/cocoa/DefaultKeyMappings.plist
index becb36f2e..a2a95e311 100644
--- a/desmume/src/frontend/cocoa/DefaultKeyMappings.plist
+++ b/desmume/src/frontend/cocoa/DefaultKeyMappings.plist
@@ -54,7 +54,7 @@
Set Speed
Enable/Disable Speed Limiter
Enable/Disable Auto Frame Skip
- Enable/Disable Cheats
+ Enable/Disable Cheat System
Enable/Disable GPU State
DefaultInputProfiles
@@ -805,7 +805,7 @@
Enable/Disable Auto Frame Skip
- Enable/Disable Cheats
+ Enable/Disable Cheat System
Enable/Disable GPU State
diff --git a/desmume/src/frontend/cocoa/DefaultUserPrefs.plist b/desmume/src/frontend/cocoa/DefaultUserPrefs.plist
index ca35299bb..911f9e18a 100644
--- a/desmume/src/frontend/cocoa/DefaultUserPrefs.plist
+++ b/desmume/src/frontend/cocoa/DefaultUserPrefs.plist
@@ -829,7 +829,7 @@
Enable/Disable Auto Frame Skip
- Enable/Disable Cheats
+ Enable/Disable Cheat System
Enable/Disable GPU State
diff --git a/desmume/src/frontend/cocoa/cocoa_cheat.h b/desmume/src/frontend/cocoa/cocoa_cheat.h
index a6ebad067..71ce7b709 100644
--- a/desmume/src/frontend/cocoa/cocoa_cheat.h
+++ b/desmume/src/frontend/cocoa/cocoa_cheat.h
@@ -16,6 +16,7 @@
along with the this software. If not, see .
*/
+#include
#import
#undef BOOL
@@ -46,6 +47,78 @@ enum CheatSystemError
CheatSystemError_ExportError = 4
};
+class ClientCheatItem
+{
+protected:
+ CHEATS_LIST *_engineItemPtr;
+
+ bool _isEnabled;
+ bool _willAddFromDB;
+
+ CheatType _cheatType;
+ std::string _descriptionString;
+ void *_clientData;
+
+ // Internal cheat type parameters
+ CheatFreezeType _freezeType;
+ char _addressString[10+1];
+ uint32_t _address;
+ uint32_t _value;
+ uint8_t _valueLength;
+
+ // Action Replay parameters
+ uint32_t _codeCount;
+ std::string _rawCodeString;
+ std::string _cleanCodeString;
+
+ void _ConvertInternalToActionReplay();
+ void _ConvertActionReplayToInternal();
+
+public:
+ ClientCheatItem();
+ ~ClientCheatItem();
+
+ void Init(const CHEATS_LIST &inCheatItem);
+ void Init(const ClientCheatItem &inCheatItem);
+
+ void SetEngineItemPtr(CHEATS_LIST *cheatItemPtr);
+ CHEATS_LIST* GetEngineItemPtr() const;
+
+ void SetEnabled(bool theState);
+ bool IsEnabled() const;
+
+ void SetWillAddFromDB(bool theState);
+ bool WillAddFromDB() const;
+
+ CheatType GetType() const;
+ void SetType(CheatType requestedType);
+ bool IsSupportedType() const;
+
+ const char* GetDescription() const;
+ void SetDescription(const char *descriptionString);
+
+ CheatFreezeType GetFreezeType() const;
+ void SetFreezeType(CheatFreezeType theFreezeType);
+
+ uint32_t GetAddress() const;
+ void SetAddress(uint32_t theAddress);
+ const char* GetAddressString() const;
+ const char* GetAddressSixDigitString() const;
+ void SetAddressSixDigitString(const char *sixDigitString);
+
+ uint32_t GetValue() const;
+ void SetValue(uint32_t theValue);
+ uint8_t GetValueLength() const;
+ void SetValueLength(uint8_t byteLength);
+
+ void SetRawCodeString(const char *rawString, const bool willSaveValidatedRawString);
+ const char* GetRawCodeString() const;
+ const char* GetCleanCodeString() const;
+ uint32_t GetCodeCount() const;
+
+ void ClientToDesmumeCheatItem(CHEATS_LIST *outCheatItem) const;
+};
+
/********************************************************************************************
CocoaDSCheatItem - OBJECTIVE-C CLASS
@@ -59,16 +132,16 @@ enum CheatSystemError
********************************************************************************************/
@interface CocoaDSCheatItem : NSObject
{
- CHEATS_LIST *data;
- CHEATS_LIST *internalData;
+ ClientCheatItem *_internalData;
BOOL willAdd;
- pthread_mutex_t mutexData;
CocoaDSCheatItem *workingCopy;
CocoaDSCheatItem *parent;
+
+ BOOL _isMemAddressAlreadyUpdating;
}
-@property (assign) CHEATS_LIST *data;
+@property (assign, nonatomic) CHEATS_LIST *data;
@property (assign) BOOL willAdd;
@property (assign, nonatomic) BOOL enabled;
@property (assign, nonatomic) NSInteger cheatType;
@@ -86,16 +159,13 @@ enum CheatSystemError
@property (readonly) CocoaDSCheatItem *workingCopy;
@property (assign) CocoaDSCheatItem *parent;
+- (id) initWithCheatItem:(CocoaDSCheatItem *)cdsCheatItem;
- (id) initWithCheatData:(CHEATS_LIST *)cheatData;
-- (BOOL) retainData;
- (char *) descriptionCString;
- (void) update;
- (CocoaDSCheatItem *) createWorkingCopy;
- (void) destroyWorkingCopy;
-- (void) mergeFromWorkingCopy;
- (void) mergeToParent;
-- (void) setDataWithDictionary:(NSDictionary *)dataDict;
-- (NSDictionary *) dataDictionary;
+ (void) setIconInternalCheat:(NSImage *)iconImage;
+ (NSImage *) iconInternalCheat;
@@ -151,7 +221,6 @@ enum CheatSystemError
+ (void) applyInternalCheatWithAddress:(UInt32)address value:(UInt32)value bytes:(NSUInteger)bytes;
+ (NSMutableArray *) cheatListWithListObject:(CHEATS *)cheatList;
+ (NSMutableArray *) cheatListWithItemStructArray:(CHEATS_LIST *)cheatItemArray count:(NSUInteger)itemCount;
-+ (NSMutableDictionary *) cheatItemWithType:(NSInteger)cheatTypeID description:(NSString *)description;
@end
diff --git a/desmume/src/frontend/cocoa/cocoa_cheat.mm b/desmume/src/frontend/cocoa/cocoa_cheat.mm
index 9dc18bb55..eb197658f 100644
--- a/desmume/src/frontend/cocoa/cocoa_cheat.mm
+++ b/desmume/src/frontend/cocoa/cocoa_cheat.mm
@@ -24,6 +24,572 @@
#include "../../MMU.h"
#undef BOOL
+
+size_t CheatConvertRawCodeToCleanCode(const char *inRawCodeString, const size_t requestedCodeCount, std::string &outCleanCodeString)
+{
+ size_t cleanCodeLength = 0;
+ if ( (inRawCodeString == NULL) ||
+ (requestedCodeCount == 0) )
+ {
+ return cleanCodeLength;
+ }
+
+ char *cleanCodeWorkingBuffer = (char *)malloc((requestedCodeCount * 16) + 1);
+ memset(cleanCodeWorkingBuffer, 0, (requestedCodeCount * 16) + 1);
+
+ size_t rawCodeLength = strlen(inRawCodeString);
+ // remove wrong chars
+ for (size_t i = 0; (i < rawCodeLength) && (cleanCodeLength < (requestedCodeCount * 16)); i++)
+ {
+ char c = inRawCodeString[i];
+ //apparently 100% of pokemon codes were typed with the letter O in place of zero in some places
+ //so let's try to adjust for that here
+ static const char *AR_Valid = "Oo0123456789ABCDEFabcdef";
+ if (strchr(AR_Valid, c))
+ {
+ if ( (c == 'o') || (c == 'O') )
+ {
+ c = '0';
+ }
+
+ cleanCodeWorkingBuffer[cleanCodeLength++] = c;
+ }
+ }
+
+ if ( (cleanCodeLength % 16) != 0)
+ {
+ // Code lines must always come in 8+8, where the first 8 characters
+ // are used for the target address, and the second 8 characters are
+ // used for the 32-bit value written to the target address. Therefore,
+ // if the string length isn't divisible by 16, then it is considered
+ // invalid.
+ cleanCodeLength = 0;
+ free(cleanCodeWorkingBuffer);
+ return cleanCodeLength;
+ }
+
+ outCleanCodeString = cleanCodeWorkingBuffer;
+ free(cleanCodeWorkingBuffer);
+
+ return (cleanCodeLength / 16);
+}
+
+size_t CheatConvertCleanCodeToRawCode(const char *inCleanCodeString, std::string &outRawCodeString)
+{
+ if (inCleanCodeString == NULL)
+ {
+ return 0;
+ }
+
+ // Clean code strings are assumed to be already validated, so we're not
+ // going to bother with any more validation here.
+
+ const size_t cleanCodeLength = strlen(inCleanCodeString);
+ const size_t codeCount = cleanCodeLength / 16;
+ const size_t rawCodeLength = codeCount * (16 + 1 + 1);
+
+ char *rawCodeWorkingBuffer = (char *)malloc(rawCodeLength);
+ memset(rawCodeWorkingBuffer, 0, rawCodeLength);
+
+ for (size_t i = 0; i < codeCount; i++)
+ {
+ const size_t c = i * 16;
+ const size_t r = i * (16 + 1 + 1);
+
+ rawCodeWorkingBuffer[r + 0] = inCleanCodeString[c + 0];
+ rawCodeWorkingBuffer[r + 1] = inCleanCodeString[c + 1];
+ rawCodeWorkingBuffer[r + 2] = inCleanCodeString[c + 2];
+ rawCodeWorkingBuffer[r + 3] = inCleanCodeString[c + 3];
+ rawCodeWorkingBuffer[r + 4] = inCleanCodeString[c + 4];
+ rawCodeWorkingBuffer[r + 5] = inCleanCodeString[c + 5];
+ rawCodeWorkingBuffer[r + 6] = inCleanCodeString[c + 6];
+ rawCodeWorkingBuffer[r + 7] = inCleanCodeString[c + 7];
+ rawCodeWorkingBuffer[r + 8] = ' ';
+ rawCodeWorkingBuffer[r + 9] = inCleanCodeString[c + 8];
+ rawCodeWorkingBuffer[r +10] = inCleanCodeString[c + 9];
+ rawCodeWorkingBuffer[r +11] = inCleanCodeString[c +10];
+ rawCodeWorkingBuffer[r +12] = inCleanCodeString[c +11];
+ rawCodeWorkingBuffer[r +13] = inCleanCodeString[c +12];
+ rawCodeWorkingBuffer[r +14] = inCleanCodeString[c +13];
+ rawCodeWorkingBuffer[r +15] = inCleanCodeString[c +14];
+ rawCodeWorkingBuffer[r +16] = inCleanCodeString[c +15];
+ rawCodeWorkingBuffer[r +17] = '\n';
+ }
+
+ rawCodeWorkingBuffer[rawCodeLength - 1] = '\0';
+ outRawCodeString = rawCodeWorkingBuffer;
+
+ return codeCount;
+}
+
+ClientCheatItem::ClientCheatItem()
+{
+ _engineItemPtr = NULL;
+
+ _isEnabled = false;
+ _willAddFromDB = false;
+
+ _cheatType = CheatType_Internal;
+ _descriptionString = "No description.";
+ _clientData = NULL;
+ _freezeType = CheatFreezeType_Normal;
+ _address = 0x02000000;
+ strncpy(_addressString, "0x02000000", sizeof(_addressString));
+ _valueLength = 1;
+ _value = 0;
+
+ _codeCount = 1;
+ _rawCodeString = "02000000 00000000";
+ _cleanCodeString = "0200000000000000";
+}
+
+ClientCheatItem::~ClientCheatItem()
+{
+
+}
+
+void ClientCheatItem::Init(const CHEATS_LIST &inCheatItem)
+{
+ char workingCodeBuffer[32];
+
+ this->_isEnabled = (inCheatItem.enabled) ? true : false;
+
+ this->_cheatType = (CheatType)inCheatItem.type;
+ this->_descriptionString = inCheatItem.description;
+
+ this->_freezeType = (CheatFreezeType)inCheatItem.freezeType;
+ this->_valueLength = inCheatItem.size + 1; // CHEATS_LIST.size value range is [1...4], but starts counting from 0.
+ this->_address = inCheatItem.code[0][0];
+ this->_addressString[0] = '0';
+ this->_addressString[1] = 'x';
+ snprintf(this->_addressString + 2, sizeof(this->_addressString) - 2, "%08X", this->_address);
+ this->_value = inCheatItem.code[0][1];
+
+ snprintf(workingCodeBuffer, 18, "%08X %08X", this->_address, this->_value);
+ this->_rawCodeString = workingCodeBuffer;
+ snprintf(workingCodeBuffer, 17, "%08X%08X", this->_address, this->_value);
+ this->_cleanCodeString = workingCodeBuffer;
+
+ if (this->_cheatType == CheatType_Internal)
+ {
+ this->_codeCount = 1;
+ }
+ else if (this->_cheatType == CheatType_ActionReplay)
+ {
+ this->_codeCount = inCheatItem.num;
+
+ for (size_t i = 1; i < this->_codeCount; i++)
+ {
+ snprintf(workingCodeBuffer, 19, "\n%08X %08X", inCheatItem.code[i][0], inCheatItem.code[i][1]);
+ this->_rawCodeString += workingCodeBuffer;
+ snprintf(workingCodeBuffer, 17, "%08X%08X", inCheatItem.code[i][0], inCheatItem.code[i][1]);
+ this->_cleanCodeString += workingCodeBuffer;
+ }
+ }
+}
+
+void ClientCheatItem::Init(const ClientCheatItem &inCheatItem)
+{
+ this->_isEnabled = inCheatItem.IsEnabled();
+
+ this->_cheatType = inCheatItem.GetType();
+ this->_descriptionString = inCheatItem.GetDescription();
+
+ this->_freezeType = inCheatItem.GetFreezeType();
+ this->_valueLength = inCheatItem.GetValueLength();
+ this->_address = inCheatItem.GetAddress();
+ strncpy(this->_addressString, inCheatItem.GetAddressString(), sizeof(this->_addressString));
+ this->_value = inCheatItem.GetValue();
+
+ this->_codeCount = inCheatItem.GetCodeCount();
+ this->_rawCodeString = inCheatItem.GetRawCodeString();
+ this->_cleanCodeString = inCheatItem.GetCleanCodeString();
+}
+
+void ClientCheatItem::SetEngineItemPtr(CHEATS_LIST *cheatItemPtr)
+{
+ this->_engineItemPtr = cheatItemPtr;
+}
+
+CHEATS_LIST* ClientCheatItem::GetEngineItemPtr() const
+{
+ return this->_engineItemPtr;
+}
+
+void ClientCheatItem::SetEnabled(bool theState)
+{
+ this->_isEnabled = theState;
+
+ if (this->_engineItemPtr != NULL)
+ {
+ this->_engineItemPtr->enabled = (theState) ? 1 : 0;
+ }
+}
+
+bool ClientCheatItem::IsEnabled() const
+{
+ return this->_isEnabled;
+}
+
+void ClientCheatItem::SetWillAddFromDB(bool theState)
+{
+ this->_willAddFromDB = theState;
+}
+
+bool ClientCheatItem::WillAddFromDB() const
+{
+ return this->_willAddFromDB;
+}
+
+CheatType ClientCheatItem::GetType() const
+{
+ return this->_cheatType;
+}
+
+void ClientCheatItem::SetType(CheatType requestedType)
+{
+ switch (requestedType)
+ {
+ case CheatType_Internal:
+ case CheatType_ActionReplay:
+ case CheatType_CodeBreaker:
+ // Do nothing.
+ break;
+
+ default:
+ // Bail if the cheat type is invalid.
+ return;
+ }
+
+ this->_cheatType = requestedType;
+
+ if (this->_engineItemPtr != NULL)
+ {
+ this->_engineItemPtr->type = (u8)requestedType;
+ }
+}
+
+bool ClientCheatItem::IsSupportedType() const
+{
+ return (this->_cheatType != CheatType_CodeBreaker);
+}
+
+const char* ClientCheatItem::GetDescription() const
+{
+ return this->_descriptionString.c_str();
+}
+
+void ClientCheatItem::SetDescription(const char *descriptionString)
+{
+ if (descriptionString == NULL)
+ {
+ this->_descriptionString = "";
+ }
+ else
+ {
+ this->_descriptionString = descriptionString;
+ }
+
+ if (this->_engineItemPtr != NULL)
+ {
+ strncpy(this->_engineItemPtr->description, this->_descriptionString.c_str(), sizeof(this->_engineItemPtr->description));
+ }
+}
+
+CheatFreezeType ClientCheatItem::GetFreezeType() const
+{
+ return this->_freezeType;
+}
+
+void ClientCheatItem::SetFreezeType(CheatFreezeType theFreezeType)
+{
+ switch (theFreezeType)
+ {
+ case CheatFreezeType_Normal:
+ case CheatFreezeType_CanDecrease:
+ case CheatFreezeType_CanIncrease:
+ // Do nothing.
+ break;
+
+ default:
+ // Bail if the freeze type is invalid.
+ return;
+ }
+
+ this->_freezeType = theFreezeType;
+
+ if (this->_engineItemPtr != NULL)
+ {
+ this->_engineItemPtr->freezeType = (u8)theFreezeType;
+ }
+}
+
+uint32_t ClientCheatItem::GetAddress() const
+{
+ if (this->_cheatType != CheatType_Internal)
+ {
+ return 0;
+ }
+
+ return this->_address;
+}
+
+void ClientCheatItem::SetAddress(uint32_t theAddress)
+{
+ this->_address = theAddress;
+
+ this->_addressString[0] = '0';
+ this->_addressString[1] = 'x';
+ snprintf(this->_addressString + 2, 9, "%08X", theAddress);
+ this->_addressString[10] = '\0';
+
+ if (this->_cheatType == CheatType_Internal)
+ {
+ this->_ConvertInternalToActionReplay();
+ }
+
+ if ( (this->_engineItemPtr != NULL) && (this->_cheatType == CheatType_Internal) )
+ {
+ this->_engineItemPtr->code[0][0] = theAddress;
+ }
+}
+
+const char* ClientCheatItem::GetAddressString() const
+{
+ return this->_addressString;
+}
+
+const char* ClientCheatItem::GetAddressSixDigitString() const
+{
+ return (this->_addressString + 4);
+}
+
+void ClientCheatItem::SetAddressSixDigitString(const char *sixDigitString)
+{
+ this->_addressString[0] = '0';
+ this->_addressString[1] = 'x';
+ this->_addressString[2] = '0';
+ this->_addressString[3] = '2';
+
+ if (sixDigitString == NULL)
+ {
+ this->_addressString[4] = '0';
+ this->_addressString[5] = '0';
+ this->_addressString[6] = '0';
+ this->_addressString[7] = '0';
+ this->_addressString[8] = '0';
+ this->_addressString[9] = '0';
+ }
+ else
+ {
+ this->_addressString[4] = sixDigitString[0];
+ this->_addressString[5] = sixDigitString[1];
+ this->_addressString[6] = sixDigitString[2];
+ this->_addressString[7] = sixDigitString[3];
+ this->_addressString[8] = sixDigitString[4];
+ this->_addressString[9] = sixDigitString[5];
+ }
+
+ this->_addressString[10] = '\0';
+ sscanf(this->_addressString + 2, "%x", &this->_address);
+
+ if (this->_cheatType == CheatType_Internal)
+ {
+ this->_ConvertInternalToActionReplay();
+ }
+
+ if ( (this->_engineItemPtr != NULL) && (this->_cheatType == CheatType_Internal) )
+ {
+ this->_engineItemPtr->code[0][0] = this->_address;
+ }
+}
+
+uint32_t ClientCheatItem::GetValue() const
+{
+ return this->_value;
+}
+
+void ClientCheatItem::SetValue(uint32_t theValue)
+{
+ this->_value = theValue;
+
+ if (this->_cheatType == CheatType_Internal)
+ {
+ this->_ConvertInternalToActionReplay();
+ }
+
+ if ( (this->_engineItemPtr != NULL) && (this->_cheatType == CheatType_Internal) )
+ {
+ this->_engineItemPtr->code[0][1] = (u32)theValue;
+ }
+}
+
+uint8_t ClientCheatItem::GetValueLength() const
+{
+ return this->_valueLength;
+}
+
+void ClientCheatItem::SetValueLength(uint8_t byteLength)
+{
+ this->_valueLength = byteLength;
+
+ if (this->_cheatType == CheatType_Internal)
+ {
+ this->_ConvertInternalToActionReplay();
+ }
+
+ if ( (this->_engineItemPtr != NULL) && (this->_cheatType == CheatType_Internal) )
+ {
+ this->_engineItemPtr->size = (u8)(byteLength - 1); // CHEATS_LIST.size value range is [1...4], but starts counting from 0.
+ }
+}
+
+void ClientCheatItem::SetRawCodeString(const char *rawString, const bool willSaveValidatedRawString)
+{
+ std::string newCleanCodeString;
+
+ size_t cleanCodeCount = CheatConvertRawCodeToCleanCode(rawString, 1024, this->_cleanCodeString);
+ if (cleanCodeCount == 0)
+ {
+ return;
+ }
+
+ this->_codeCount = (uint32_t)cleanCodeCount;
+
+ if (willSaveValidatedRawString)
+ {
+ // Using the validated clean code string, the raw code string will be
+ // rewritten using the following format for each line:
+ // XXXXXXXX XXXXXXXX\n
+ CheatConvertCleanCodeToRawCode(this->_cleanCodeString.c_str(), this->_rawCodeString);
+ }
+ else
+ {
+ // The passed in raw code string will be saved, regardless of any syntax
+ // errors, flaws, or formatting issues that it may contain.
+ this->_rawCodeString = rawString;
+ }
+
+ if (this->_cheatType == CheatType_ActionReplay)
+ {
+ this->_ConvertActionReplayToInternal();
+ }
+
+ if (this->_engineItemPtr != NULL)
+ {
+ CHEATS::XXCodeFromString(this->_cleanCodeString.c_str(), *this->_engineItemPtr);
+ }
+}
+
+const char* ClientCheatItem::GetRawCodeString() const
+{
+ return this->_rawCodeString.c_str();
+}
+
+const char* ClientCheatItem::GetCleanCodeString() const
+{
+ return this->_cleanCodeString.c_str();
+}
+
+uint32_t ClientCheatItem::GetCodeCount() const
+{
+ return this->_codeCount;
+}
+
+void ClientCheatItem::_ConvertInternalToActionReplay()
+{
+ char workingCodeBuffer[16+1+1];
+
+ u32 truncatedValue = this->_value;
+
+ switch (this->_valueLength)
+ {
+ case 1:
+ truncatedValue &= 0x000000FF;
+ break;
+
+ case 2:
+ truncatedValue &= 0x0000FFFF;
+ break;
+
+ case 3:
+ truncatedValue &= 0x00FFFFFF;
+ break;
+
+ default:
+ break;
+ }
+
+ memset(workingCodeBuffer, 0, sizeof(workingCodeBuffer));
+ snprintf(workingCodeBuffer, 16+1+1, "%08X %08X", this->_address, truncatedValue);
+ this->_rawCodeString = workingCodeBuffer;
+
+ memset(workingCodeBuffer, 0, sizeof(workingCodeBuffer));
+ snprintf(workingCodeBuffer, 16+1, "%08X%08X", this->_address, truncatedValue);
+ this->_cleanCodeString = workingCodeBuffer;
+
+ this->_codeCount = 1;
+}
+
+void ClientCheatItem::_ConvertActionReplayToInternal()
+{
+ this->_addressString[0] = '0';
+ this->_addressString[1] = 'x';
+ strncpy(this->_addressString + 2, this->_cleanCodeString.c_str(), 8);
+ this->_addressString[10] = '\0';
+ sscanf(this->_addressString + 2, "%x", &this->_address);
+
+ char workingCodeBuffer[9];
+ memset(workingCodeBuffer, 0, sizeof(workingCodeBuffer));
+ strncpy(workingCodeBuffer, this->_cleanCodeString.c_str() + 8, 8);
+ sscanf(workingCodeBuffer, "%x", &this->_value);
+
+ this->_valueLength = 4;
+}
+
+void ClientCheatItem::ClientToDesmumeCheatItem(CHEATS_LIST *outCheatItem) const
+{
+ if (outCheatItem == NULL)
+ {
+ return;
+ }
+
+ outCheatItem->type = this->_cheatType;
+ outCheatItem->enabled = (this->_isEnabled) ? 1 : 0;
+ strncpy(outCheatItem->description, this->_descriptionString.c_str(), sizeof(outCheatItem->description));
+
+ switch (this->_cheatType)
+ {
+ case CheatType_Internal:
+ outCheatItem->num = 1;
+ outCheatItem->size = this->_valueLength - 1; // CHEATS_LIST.size value range is [1...4], but starts counting from 0.
+ outCheatItem->freezeType = (u8)this->_freezeType;
+ outCheatItem->code[0][0] = this->_address;
+ outCheatItem->code[0][1] = this->_value;
+ break;
+
+ case CheatType_ActionReplay:
+ case CheatType_CodeBreaker:
+ {
+ outCheatItem->num = this->_codeCount;
+ outCheatItem->size = 3;
+ outCheatItem->freezeType = CheatFreezeType_Normal;
+
+ for (size_t i = 0; i < this->_codeCount; i++)
+ {
+ sscanf(this->_cleanCodeString.c_str() + (i * 16) + 0, "%x", &outCheatItem->code[i][0]);
+ sscanf(this->_cleanCodeString.c_str() + (i * 16) + 8, "%x", &outCheatItem->code[i][1]);
+ }
+ break;
+ }
+
+ default:
+ break;
+ }
+}
+
+#pragma mark -
+
@implementation CocoaDSCheatItem
static NSImage *iconInternalCheat = nil;
@@ -53,7 +619,7 @@ - (id)init
return [self initWithCheatData:nil];
}
-- (id) initWithCheatData:(CHEATS_LIST *)cheatData
+- (id) initWithCheatItem:(CocoaDSCheatItem *)cdsCheatItem
{
self = [super init];
if(self == nil)
@@ -61,38 +627,55 @@ - (id) initWithCheatData:(CHEATS_LIST *)cheatData
return self;
}
- if (cheatData == NULL)
+ _internalData = new ClientCheatItem;
+
+ willAdd = NO;
+ workingCopy = nil;
+ parent = nil;
+ _isMemAddressAlreadyUpdating = NO;
+
+ if (cdsCheatItem != nil)
{
- // Allocate our own cheat item struct since we weren't provided with one.
- internalData = (CHEATS_LIST *)malloc(sizeof(CHEATS_LIST));
- if (internalData == NULL)
+ _internalData->SetEnabled(([cdsCheatItem enabled]) ? true : false);
+ _internalData->SetDescription([[cdsCheatItem description] cStringUsingEncoding:NSUTF8StringEncoding]);
+ _internalData->SetType((CheatType)[cdsCheatItem cheatType]);
+ _internalData->SetFreezeType((CheatFreezeType)[cdsCheatItem freezeType]);
+
+ if (_internalData->GetType() == CheatType_Internal)
{
- [self release];
- return nil;
+ _internalData->SetValueLength([cdsCheatItem bytes]);
+ _internalData->SetAddress([cdsCheatItem memAddress]);
+ _internalData->SetValue((u32)[cdsCheatItem value]);
+ }
+ else
+ {
+ _internalData->SetRawCodeString([[cdsCheatItem code] cStringUsingEncoding:NSUTF8StringEncoding], false);
}
-
- data = internalData;
-
- [self setEnabled:NO];
- [self setCheatType:CHEAT_TYPE_INTERNAL];
- [self setFreezeType:CheatFreezeType_Normal];
- [self setDescription:@""];
- [self setCode:@""];
- [self setMemAddress:0x00000000];
- [self setBytes:1];
- [self setValue:0];
}
- else
+
+ return self;
+}
+
+- (id) initWithCheatData:(CHEATS_LIST *)cheatData
+{
+ self = [super init];
+ if(self == nil)
{
- internalData = NULL;
- data = cheatData;
+ return self;
}
- pthread_mutex_init(&mutexData, NULL);
+ _internalData = new ClientCheatItem;
+
+ if (cheatData != NULL)
+ {
+ _internalData->SetEngineItemPtr(cheatData);
+ _internalData->Init(*cheatData);
+ }
willAdd = NO;
workingCopy = nil;
parent = nil;
+ _isMemAddressAlreadyUpdating = NO;
return self;
}
@@ -101,80 +684,30 @@ - (void) dealloc
{
[self destroyWorkingCopy];
- free(internalData);
- internalData = NULL;
-
- pthread_mutex_destroy(&mutexData);
+ delete _internalData;
+ _internalData = NULL;
[super dealloc];
}
- (CHEATS_LIST *) data
{
- pthread_mutex_lock(&mutexData);
- CHEATS_LIST *returnData = data;
- pthread_mutex_unlock(&mutexData);
-
- return returnData;
+ return _internalData->GetEngineItemPtr();
}
- (void) setData:(CHEATS_LIST *)cheatData
{
- if (cheatData == NULL)
- {
- return;
- }
-
- pthread_mutex_lock(&mutexData);
- data = cheatData;
- pthread_mutex_unlock(&mutexData);
-
- [self update];
-
- if (workingCopy != nil)
- {
- pthread_mutex_lock(&mutexData);
-
- CHEATS_LIST *thisData = data;
- CHEATS_LIST *workingData = [workingCopy data];
- *workingData = *thisData;
-
- pthread_mutex_unlock(&mutexData);
-
- [workingCopy update];
- }
-}
-
-- (BOOL) retainData
-{
- BOOL result = YES;
-
- if (internalData == NULL)
- {
- internalData = (CHEATS_LIST *)malloc(sizeof(CHEATS_LIST));
- if (internalData == NULL)
- {
- result = NO;
- return result;
- }
- }
-
- pthread_mutex_lock(&mutexData);
- *internalData = *data;
- data = internalData;
- pthread_mutex_unlock(&mutexData);
-
- return result;
+ _internalData->SetEngineItemPtr(cheatData);
}
- (BOOL) enabled
{
- return (data->enabled != 0) ? YES : NO;
+ return _internalData->IsEnabled() ? YES : NO;
}
- (void) setEnabled:(BOOL)theState
{
- data->enabled = (theState) ? 1 : 0;
+ _internalData->SetEnabled((theState) ? true : false);
if (workingCopy != nil)
{
@@ -184,18 +717,18 @@ - (void) setEnabled:(BOOL)theState
- (NSString *) description
{
- return [NSString stringWithCString:(const char *)&data->description[0] encoding:NSUTF8StringEncoding];
+ return [NSString stringWithCString:_internalData->GetDescription() encoding:NSUTF8StringEncoding];
}
- (void) setDescription:(NSString *)desc
{
if (desc == nil)
{
- memset(&data->description[0], 0, sizeof(data->description));
+ _internalData->SetDescription(NULL);
}
else
{
- [desc getCString:&data->description[0] maxLength:sizeof(data->description) encoding:NSUTF8StringEncoding];
+ _internalData->SetDescription([desc cStringUsingEncoding:NSUTF8StringEncoding]);
}
if (workingCopy != nil)
@@ -206,33 +739,38 @@ - (void) setDescription:(NSString *)desc
- (char *) descriptionCString
{
- return &data->description[0];
+ return (char *)_internalData->GetDescription();
}
- (NSInteger) cheatType
{
- return (NSInteger)data->type;
+ return (NSInteger)_internalData->GetType();
}
- (void) setCheatType:(NSInteger)theType
{
- data->type = (u8)theType;
+ _internalData->SetType((CheatType)theType);
switch (theType)
{
case CHEAT_TYPE_INTERNAL:
[self setCheatTypeIcon:iconInternalCheat];
[self setIsSupportedCheatType:YES];
+ [self setMemAddress:[self memAddress]];
+ [self setValue:[self value]];
+ [self setBytes:[self bytes]];
break;
case CHEAT_TYPE_ACTION_REPLAY:
[self setCheatTypeIcon:iconActionReplay];
[self setIsSupportedCheatType:YES];
+ [self setCode:[self code]];
break;
case CHEAT_TYPE_CODE_BREAKER:
[self setCheatTypeIcon:iconCodeBreaker];
[self setIsSupportedCheatType:NO];
+ [self setCode:[self code]];
break;
default:
@@ -277,24 +815,7 @@ - (NSImage *) cheatTypeIcon
- (BOOL) isSupportedCheatType
{
- BOOL isSupported = YES;
-
- switch ([self cheatType])
- {
- case CHEAT_TYPE_INTERNAL:
- case CHEAT_TYPE_ACTION_REPLAY:
- isSupported = YES;
- break;
-
- case CHEAT_TYPE_CODE_BREAKER:
- isSupported = NO;
- break;
-
- default:
- break;
- }
-
- return isSupported;
+ return (_internalData->IsSupportedType()) ? YES : NO;
}
- (void) setIsSupportedCheatType:(BOOL)isSupported
@@ -304,12 +825,12 @@ - (void) setIsSupportedCheatType:(BOOL)isSupported
- (NSInteger) freezeType
{
- return (NSInteger)data->freezeType;
+ return (NSInteger)_internalData->GetFreezeType();
}
- (void) setFreezeType:(NSInteger)theType
{
- data->freezeType = (u8)theType;
+ _internalData->SetFreezeType((CheatFreezeType)theType);
if (workingCopy != nil)
{
@@ -319,12 +840,12 @@ - (void) setFreezeType:(NSInteger)theType
- (UInt8) bytes
{
- return (UInt8)(data->size + 1);
+ return _internalData->GetValueLength();
}
- (void) setBytes:(UInt8)byteSize
{
- data->size = (u8)(byteSize - 1);
+ _internalData->SetValueLength(byteSize);
if (workingCopy != nil)
{
@@ -334,7 +855,7 @@ - (void) setBytes:(UInt8)byteSize
- (NSUInteger) codeCount
{
- return (NSUInteger)data->num;
+ return (NSUInteger)_internalData->GetCodeCount();
}
- (void) setCodeCount:(NSUInteger)count
@@ -344,22 +865,7 @@ - (void) setCodeCount:(NSUInteger)count
- (NSString *) code
{
- NSString *codeLine = @"";
- NSString *cheatCodes = @"";
-
- NSUInteger numberCodes = [self codeCount];
- if (numberCodes > MAX_XX_CODE)
- {
- return nil;
- }
-
- for (NSUInteger i = 0; i < numberCodes; i++)
- {
- codeLine = [NSString stringWithFormat:@"%08X %08X\n", data->code[i][0], data->code[i][1]];
- cheatCodes = [cheatCodes stringByAppendingString:codeLine];
- }
-
- return cheatCodes;
+ return [NSString stringWithCString:_internalData->GetRawCodeString() encoding:NSUTF8StringEncoding];
}
- (void) setCode:(NSString *)theCode
@@ -369,14 +875,7 @@ - (void) setCode:(NSString *)theCode
return;
}
- size_t codeCStringSize = MAX_XX_CODE * 10 * 2 * sizeof(char);
- char *codeCString = (char *)calloc(codeCStringSize, 1);
- [theCode getCString:codeCString maxLength:codeCStringSize encoding:NSUTF8StringEncoding];
-
- CHEATS::XXCodeFromString(codeCString, *data);
-
- free(codeCString);
- codeCString = NULL;
+ _internalData->SetRawCodeString([theCode cStringUsingEncoding:NSUTF8StringEncoding], true);
[self setCodeCount:[self codeCount]];
[self setBytes:[self bytes]];
@@ -389,24 +888,23 @@ - (void) setCode:(NSString *)theCode
- (UInt32) memAddress
{
- if ([self cheatType] != CHEAT_TYPE_INTERNAL) // Needs to be the Internal Cheat type
- {
- return 0;
- }
-
- return (data->code[0][0] | 0x02000000);
+ return _internalData->GetAddress();
}
- (void) setMemAddress:(UInt32)theAddress
{
- if ([self cheatType] != CHEAT_TYPE_INTERNAL) // Needs to be the Internal Cheat type
- {
- return;
- }
-
theAddress &= 0x00FFFFFF;
theAddress |= 0x02000000;
- data->code[0][0] = theAddress;
+
+ _internalData->SetAddress(theAddress);
+
+ if (!_isMemAddressAlreadyUpdating)
+ {
+ _isMemAddressAlreadyUpdating = YES;
+ NSString *addrString = [NSString stringWithCString:_internalData->GetAddressSixDigitString() encoding:NSUTF8StringEncoding];
+ [self setMemAddressSixDigitString:addrString];
+ _isMemAddressAlreadyUpdating = NO;
+ }
if (workingCopy != nil)
{
@@ -416,20 +914,20 @@ - (void) setMemAddress:(UInt32)theAddress
- (NSString *) memAddressString
{
- return [NSString stringWithFormat:@"0x%08X", (unsigned int)[self memAddress]];
+ return [NSString stringWithCString:_internalData->GetAddressString() encoding:NSUTF8StringEncoding];
}
- (void) setMemAddressString:(NSString *)addressString
{
- if ([self cheatType] != CHEAT_TYPE_INTERNAL) // Needs to be the Internal Cheat type
+ if (!_isMemAddressAlreadyUpdating)
{
- return;
+ _isMemAddressAlreadyUpdating = YES;
+ u32 address = 0x00000000;
+ [[NSScanner scannerWithString:addressString] scanHexInt:&address];
+ [self setMemAddress:address];
+ _isMemAddressAlreadyUpdating = NO;
}
- u32 address = 0x00000000;
- [[NSScanner scannerWithString:addressString] scanHexInt:&address];
- [self setMemAddress:address];
-
if (workingCopy != nil)
{
[workingCopy setMemAddressString:addressString];
@@ -438,7 +936,7 @@ - (void) setMemAddressString:(NSString *)addressString
- (NSString *) memAddressSixDigitString
{
- return [NSString stringWithFormat:@"%06X", (unsigned int)([self memAddress] & 0x00FFFFFF)];
+ return [NSString stringWithCString:_internalData->GetAddressSixDigitString() encoding:NSUTF8StringEncoding];
}
- (void) setMemAddressSixDigitString:(NSString *)addressString
@@ -448,22 +946,12 @@ - (void) setMemAddressSixDigitString:(NSString *)addressString
- (SInt64) value
{
- if ([self cheatType] != CHEAT_TYPE_INTERNAL) // Needs to be the Internal Cheat type
- {
- return 0;
- }
-
- return (data->code[0][1]);
+ return _internalData->GetValue();
}
- (void) setValue:(SInt64)theValue
{
- if ([self cheatType] != CHEAT_TYPE_INTERNAL) // Needs to be the Internal Cheat type
- {
- return;
- }
-
- data->code[0][1] = (u32)theValue;
+ _internalData->SetValue((u32)theValue);
if (workingCopy != nil)
{
@@ -480,9 +968,9 @@ - (void) update
if ([self cheatType] == CHEAT_TYPE_INTERNAL)
{
- [self setBytes:[self bytes]];
- [self setMemAddress:[self memAddress]];
+ [self setMemAddressSixDigitString:[self memAddressSixDigitString]];
[self setValue:[self value]];
+ [self setBytes:[self bytes]];
}
else
{
@@ -490,6 +978,30 @@ - (void) update
}
}
+- (void) copyFrom:(CocoaDSCheatItem *)cdsCheatItem
+{
+ if (cdsCheatItem == nil)
+ {
+ return;
+ }
+
+ [self setEnabled:[cdsCheatItem enabled]];
+ [self setDescription:[cdsCheatItem description]];
+ [self setCheatType:[cdsCheatItem cheatType]];
+ [self setFreezeType:[cdsCheatItem freezeType]];
+
+ if ([self cheatType] == CHEAT_TYPE_INTERNAL)
+ {
+ [self setMemAddress:[cdsCheatItem memAddress]];
+ [self setValue:[cdsCheatItem value]];
+ [self setBytes:[cdsCheatItem bytes]];
+ }
+ else
+ {
+ [self setCode:[cdsCheatItem code]];
+ }
+}
+
- (CocoaDSCheatItem *) createWorkingCopy
{
CocoaDSCheatItem *newWorkingCopy = nil;
@@ -499,8 +1011,7 @@ - (CocoaDSCheatItem *) createWorkingCopy
[workingCopy release];
}
- newWorkingCopy = [[CocoaDSCheatItem alloc] initWithCheatData:[self data]];
- [newWorkingCopy retainData];
+ newWorkingCopy = [[CocoaDSCheatItem alloc] initWithCheatItem:self];
[newWorkingCopy setParent:self];
workingCopy = newWorkingCopy;
@@ -513,23 +1024,6 @@ - (void) destroyWorkingCopy
workingCopy = nil;
}
-- (void) mergeFromWorkingCopy
-{
- if (workingCopy == nil)
- {
- return;
- }
-
- CHEATS_LIST *thisData = [self data];
- CHEATS_LIST *workingData = [workingCopy data];
-
- pthread_mutex_lock(&mutexData);
- *thisData = *workingData;
- pthread_mutex_unlock(&mutexData);
-
- [self update];
-}
-
- (void) mergeToParent
{
if (parent == nil)
@@ -537,92 +1031,7 @@ - (void) mergeToParent
return;
}
- CHEATS_LIST *thisData = [self data];
- CHEATS_LIST *parentData = [parent data];
-
- pthread_mutex_lock(&mutexData);
- *parentData = *thisData;
- pthread_mutex_unlock(&mutexData);
-
- [parent update];
-}
-
-- (void) setDataWithDictionary:(NSDictionary *)dataDict
-{
- if (dataDict == nil)
- {
- return;
- }
-
- NSNumber *enabledNumber = (NSNumber *)[dataDict valueForKey:@"enabled"];
- if (enabledNumber != nil)
- {
- [self setEnabled:[enabledNumber boolValue]];
- }
-
- NSString *descriptionString = (NSString *)[dataDict valueForKey:@"description"];
- if (descriptionString != nil)
- {
- [self setDescription:descriptionString];
- }
-
- NSNumber *freezeTypeNumber = (NSNumber *)[dataDict valueForKey:@"freezeType"];
- if (freezeTypeNumber != nil)
- {
- [self setFreezeType:[freezeTypeNumber integerValue]];
- }
-
- NSNumber *cheatTypeNumber = (NSNumber *)[dataDict valueForKey:@"cheatType"];
- if (cheatTypeNumber != nil)
- {
- [self setCheatType:[cheatTypeNumber integerValue]];
- }
-
- if ([self cheatType] == CHEAT_TYPE_INTERNAL)
- {
- NSNumber *bytesNumber = (NSNumber *)[dataDict valueForKey:@"bytes"];
- if (bytesNumber != nil)
- {
- [self setBytes:[bytesNumber unsignedIntegerValue]];
- }
-
- NSNumber *memAddressNumber = (NSNumber *)[dataDict valueForKey:@"memAddress"];
- if (memAddressNumber != nil)
- {
- [self setMemAddress:(u32)[memAddressNumber unsignedIntegerValue]];
- }
-
- NSNumber *valueNumber = (NSNumber *)[dataDict valueForKey:@"value"];
- if (valueNumber != nil)
- {
- [self setValue:[valueNumber integerValue]];
- }
- }
- else
- {
- NSString *codeString = (NSString *)[dataDict valueForKey:@"code"];
- if (codeString != nil)
- {
- [self setCode:codeString];
- }
- }
-}
-
-- (NSDictionary *) dataDictionary
-{
- return [NSDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithBool:[self enabled]], @"enabled",
- [NSNumber numberWithInteger:[self cheatType]], @"cheatType",
- [self description], @"description",
- [NSNumber numberWithInteger:[self freezeType]], @"freezeType",
- [NSNumber numberWithUnsignedInteger:[self codeCount]], @"codeCount",
- [NSNumber numberWithUnsignedInteger:[self bytes]], @"bytes",
- [NSNumber numberWithUnsignedInt:[self memAddress]], @"memAddress",
- [self memAddressString], @"memAddressString",
- [NSNumber numberWithInteger:[self value]], @"value",
- [self code], @"code",
- [NSNumber numberWithBool:[self isSupportedCheatType]], @"isSupportedCheatType",
- nil];
+ [parent copyFrom:self];
}
+ (void) setIconInternalCheat:(NSImage *)iconImage
@@ -880,7 +1289,6 @@ - (void) remove:(CocoaDSCheatItem *)cheatItem
[(CocoaDSCheatItem *)[[self list] objectAtIndex:(i + 1)] setData:[self listData]->getItemPtrAtIndex(i)];
}
- [cheatItem setData:nil];
[[self list] removeObject:cheatItem];
}
@@ -986,7 +1394,7 @@ - (NSMutableArray *) cheatListFromDatabase:(NSURL *)fileURL errorCode:(NSInteger
for (CocoaDSCheatItem *cheatItem in newDBList)
{
[cheatItem setWillAdd:NO];
- [cheatItem retainData];
+ [cheatItem setData:NULL];
}
}
}
@@ -1106,30 +1514,6 @@ + (NSMutableArray *) cheatListWithItemStructArray:(CHEATS_LIST *)cheatItemArray
return newList;
}
-+ (NSMutableDictionary *) cheatItemWithType:(NSInteger)cheatTypeID description:(NSString *)description
-{
- BOOL isSupported = YES;
-
- if (cheatTypeID == CHEAT_TYPE_CODE_BREAKER)
- {
- isSupported = NO;
- }
-
- return [NSMutableDictionary dictionaryWithObjectsAndKeys:
- [NSNumber numberWithBool:NO], @"enabled",
- [NSNumber numberWithInteger:cheatTypeID], @"cheatType",
- description, @"description",
- [NSNumber numberWithInteger:0], @"freezeType",
- [NSNumber numberWithUnsignedInteger:0], @"codeCount",
- [NSNumber numberWithUnsignedInteger:4], @"bytes",
- [NSNumber numberWithInteger:0], @"memAddress",
- @"0x00000000", @"memAddressString",
- [NSNumber numberWithInteger:0], @"value",
- @"", @"code",
- [NSNumber numberWithBool:isSupported], @"isSupportedCheatType",
- nil];
-}
-
@end
@implementation CocoaDSCheatSearch
diff --git a/desmume/src/frontend/cocoa/cocoa_globals.h b/desmume/src/frontend/cocoa/cocoa_globals.h
index 7e6a1605f..43a13b846 100644
--- a/desmume/src/frontend/cocoa/cocoa_globals.h
+++ b/desmume/src/frontend/cocoa/cocoa_globals.h
@@ -46,8 +46,8 @@
#define NSSTRING_TITLE_ENABLE_SPEED_LIMIT NSLocalizedString(@"Enable Speed Limit", nil)
#define NSSTRING_TITLE_DISABLE_AUTO_FRAME_SKIP NSLocalizedString(@"Disable Auto Frame Skip", nil)
#define NSSTRING_TITLE_ENABLE_AUTO_FRAME_SKIP NSLocalizedString(@"Enable Auto Frame Skip", nil)
-#define NSSTRING_TITLE_DISABLE_CHEATS NSLocalizedString(@"Disable Cheats", nil)
-#define NSSTRING_TITLE_ENABLE_CHEATS NSLocalizedString(@"Enable Cheats", nil)
+#define NSSTRING_TITLE_DISABLE_CHEATS NSLocalizedString(@"Disable Cheat System", nil)
+#define NSSTRING_TITLE_ENABLE_CHEATS NSLocalizedString(@"Enable Cheat System", nil)
#define NSSTRING_TITLE_DISABLE_HUD NSLocalizedString(@"Disable HUD", nil)
#define NSSTRING_TITLE_ENABLE_HUD NSLocalizedString(@"Enable HUD", nil)
#define NSSTRING_TITLE_EXIT_FULL_SCREEN NSLocalizedString(@"Exit Full Screen", nil)
diff --git a/desmume/src/frontend/cocoa/translations/English.lproj/MainMenu.xib b/desmume/src/frontend/cocoa/translations/English.lproj/MainMenu.xib
index c94087d66..39a442b48 100644
--- a/desmume/src/frontend/cocoa/translations/English.lproj/MainMenu.xib
+++ b/desmume/src/frontend/cocoa/translations/English.lproj/MainMenu.xib
@@ -810,7 +810,7 @@
Slot2WindowDelegate
@@ -88893,8 +88977,8 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
- IBProjectSource
- userinterface/Slot2WindowDelegate.h
+ IBDocumentRelativeSource
+ ../../userinterface/Slot2WindowDelegate.h
@@ -88974,8 +89058,8 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
- IBProjectSource
- userinterface/troubleshootingWindowDelegate.h
+ IBDocumentRelativeSource
+ ../../userinterface/troubleshootingWindowDelegate.h
@@ -89010,833 +89094,8 @@ y7bMNcy1zTXNtc42zrbPN8+40DnQutE80b7SP9LB00TTxtRJ1MvVTtXR1lXW2Ndc1+DYZNjo2WzZ8dp2
- IBProjectSource
- userinterface/WifiSettingsPanel.h
-
-
-
-
-
- NSActionCell
- NSCell
-
- IBFrameworkSource
- AppKit.framework/Headers/NSActionCell.h
-
-
-
- NSApplication
- NSResponder
-
- IBFrameworkSource
- AppKit.framework/Headers/NSApplication.h
-
-
-
- NSApplication
-
- IBFrameworkSource
- AppKit.framework/Headers/NSApplicationScripting.h
-
-
-
- NSApplication
-
- IBFrameworkSource
- AppKit.framework/Headers/NSColorPanel.h
-
-
-
- NSApplication
-
- IBFrameworkSource
- AppKit.framework/Headers/NSHelpManager.h
-
-
-
- NSApplication
-
- IBFrameworkSource
- AppKit.framework/Headers/NSPageLayout.h
-
-
-
- NSApplication
-
- IBFrameworkSource
- AppKit.framework/Headers/NSUserInterfaceItemSearching.h
-
-
-
- NSArrayController
- NSObjectController
-
- IBFrameworkSource
- AppKit.framework/Headers/NSArrayController.h
-
-
-
- NSBox
- NSView
-
- IBFrameworkSource
- AppKit.framework/Headers/NSBox.h
-
-
-
- NSBrowser
- NSControl
-
- IBFrameworkSource
- AppKit.framework/Headers/NSBrowser.h
-
-
-
- NSButton
- NSControl
-
- IBFrameworkSource
- AppKit.framework/Headers/NSButton.h
-
-
-
- NSButtonCell
- NSActionCell
-
- IBFrameworkSource
- AppKit.framework/Headers/NSButtonCell.h
-
-
-
- NSCell
- NSObject
-
- IBFrameworkSource
- AppKit.framework/Headers/NSCell.h
-
-
-
- NSColorWell
- NSControl
-
- IBFrameworkSource
- AppKit.framework/Headers/NSColorWell.h
-
-
-
- NSControl
- NSView
-
- IBFrameworkSource
- AppKit.framework/Headers/NSControl.h
-
-
-
- NSController
- NSObject
-
- IBFrameworkSource
- AppKit.framework/Headers/NSController.h
-
-
-
- NSDatePicker
- NSControl
-
- IBFrameworkSource
- AppKit.framework/Headers/NSDatePicker.h
-
-
-
- NSDatePickerCell
- NSActionCell
-
- IBFrameworkSource
- AppKit.framework/Headers/NSDatePickerCell.h
-
-
-
- NSDocumentController
- NSObject
-
- id
- id
- id
- id
-
-
-
- clearRecentDocuments:
- id
-
-
- newDocument:
- id
-
-
- openDocument:
- id
-
-
- saveAllDocuments:
- id
-
-
-
- IBFrameworkSource
- AppKit.framework/Headers/NSDocumentController.h
-
-
-
- NSDrawer
- NSResponder
-
- IBFrameworkSource
- AppKit.framework/Headers/NSDrawer.h
-
-
-
- NSFormatter
- NSObject
-
- IBFrameworkSource
- Foundation.framework/Headers/NSFormatter.h
-
-
-
- NSImageCell
- NSCell
-
- IBFrameworkSource
- AppKit.framework/Headers/NSImageCell.h
-
-
-
- NSImageView
- NSControl
-
- IBFrameworkSource
- AppKit.framework/Headers/NSImageView.h
-
-
-
- NSLevelIndicator
- NSControl
-
- IBFrameworkSource
- AppKit.framework/Headers/NSLevelIndicator.h
-
-
-
- NSLevelIndicatorCell
- NSActionCell
-
- IBFrameworkSource
- AppKit.framework/Headers/NSLevelIndicatorCell.h
-
-
-
- NSMatrix
- NSControl
-
- IBFrameworkSource
- AppKit.framework/Headers/NSMatrix.h
-
-
-
- NSMenu
- NSObject
-
- IBFrameworkSource
- AppKit.framework/Headers/NSMenu.h
-
-
-
- NSMenuItem
- NSObject
-
- IBFrameworkSource
- AppKit.framework/Headers/NSMenuItem.h
-
-
-
- NSMenuItemCell
- NSButtonCell
-
- IBFrameworkSource
- AppKit.framework/Headers/NSMenuItemCell.h
-
-
-
- NSMovieView
- NSView
-
- IBFrameworkSource
- AppKit.framework/Headers/NSMovieView.h
-
-
-
- NSNumberFormatter
- NSFormatter
-
- IBFrameworkSource
- Foundation.framework/Headers/NSNumberFormatter.h
-
-
-
- NSObject
-
- IBFrameworkSource
- AppKit.framework/Headers/NSAccessibility.h
-
-
-
- NSObject
-
-
-
- NSObject
-
-
-
- NSObject
-
-
-
- NSObject
-
-
-
- NSObject
-
- IBFrameworkSource
- AppKit.framework/Headers/NSDictionaryController.h
-
-
-
- NSObject
-
- IBFrameworkSource
- AppKit.framework/Headers/NSDragging.h
-
-
-
- NSObject
-
- IBFrameworkSource
- AppKit.framework/Headers/NSFontManager.h
-
-
-
- NSObject
-
- IBFrameworkSource
- AppKit.framework/Headers/NSFontPanel.h
-
-
-
- NSObject
-
- IBFrameworkSource
- AppKit.framework/Headers/NSKeyValueBinding.h
-
-
-
- NSObject
-
-
-
- NSObject
-
- IBFrameworkSource
- AppKit.framework/Headers/NSNibLoading.h
-
-
-
- NSObject
-
- IBFrameworkSource
- AppKit.framework/Headers/NSOutlineView.h
-
-
-
- NSObject
-
- IBFrameworkSource
- AppKit.framework/Headers/NSPasteboard.h
-
-
-
- NSObject
-
- IBFrameworkSource
- AppKit.framework/Headers/NSSavePanel.h
-
-
-
- NSObject
-
- IBFrameworkSource
- AppKit.framework/Headers/NSTableView.h
-
-
-
- NSObject
-
- IBFrameworkSource
- AppKit.framework/Headers/NSToolbarItem.h
-
-
-
- NSObject
-
- IBFrameworkSource
- AppKit.framework/Headers/NSView.h
-
-
-
- NSObject
-
- IBFrameworkSource
- Foundation.framework/Headers/NSArchiver.h
-
-
-
- NSObject
-
- IBFrameworkSource
- Foundation.framework/Headers/NSClassDescription.h
-
-
-
- NSObject
-
- IBFrameworkSource
- Foundation.framework/Headers/NSError.h
-
-
-
- NSObject
-
- IBFrameworkSource
- Foundation.framework/Headers/NSFileManager.h
-
-
-
- NSObject
-
- IBFrameworkSource
- Foundation.framework/Headers/NSKeyValueCoding.h
-
-
-
- NSObject
-
- IBFrameworkSource
- Foundation.framework/Headers/NSKeyValueObserving.h
-
-
-
- NSObject
-
- IBFrameworkSource
- Foundation.framework/Headers/NSKeyedArchiver.h
-
-
-
- NSObject
-
- IBFrameworkSource
- Foundation.framework/Headers/NSObject.h
-
-
-
- NSObject
-
- IBFrameworkSource
- Foundation.framework/Headers/NSObjectScripting.h
-
-
-
- NSObject
-
- IBFrameworkSource
- Foundation.framework/Headers/NSPortCoder.h
-
-
-
- NSObject
-
- IBFrameworkSource
- Foundation.framework/Headers/NSRunLoop.h
-
-
-
- NSObject
-
- IBFrameworkSource
- Foundation.framework/Headers/NSScriptClassDescription.h
-
-
-
- NSObject
-
- IBFrameworkSource
- Foundation.framework/Headers/NSScriptKeyValueCoding.h
-
-
-
- NSObject
-
- IBFrameworkSource
- Foundation.framework/Headers/NSScriptObjectSpecifiers.h
-
-
-
- NSObject
-
- IBFrameworkSource
- Foundation.framework/Headers/NSScriptWhoseTests.h
-
-
-
- NSObject
-
- IBFrameworkSource
- Foundation.framework/Headers/NSThread.h
-
-
-
- NSObject
-
- IBFrameworkSource
- Foundation.framework/Headers/NSURL.h
-
-
-
- NSObject
-
- IBFrameworkSource
- Foundation.framework/Headers/NSURLConnection.h
-
-
-
- NSObject
-
- IBFrameworkSource
- Foundation.framework/Headers/NSURLDownload.h
-
-
-
- NSObject
-
- IBFrameworkSource
- QuartzCore.framework/Headers/CAAnimation.h
-
-
-
- NSObject
-
- IBFrameworkSource
- QuartzCore.framework/Headers/CALayer.h
-
-
-
- NSObject
-
- IBFrameworkSource
- QuartzCore.framework/Headers/CIImageProvider.h
-
-
-
- NSObjectController
- NSController
-
- IBFrameworkSource
- AppKit.framework/Headers/NSObjectController.h
-
-
-
- NSOutlineView
- NSTableView
-
-
-
- NSPanel
- NSWindow
-
- IBFrameworkSource
- AppKit.framework/Headers/NSPanel.h
-
-
-
- NSPopUpButton
- NSButton
-
- IBFrameworkSource
- AppKit.framework/Headers/NSPopUpButton.h
-
-
-
- NSPopUpButtonCell
- NSMenuItemCell
-
- IBFrameworkSource
- AppKit.framework/Headers/NSPopUpButtonCell.h
-
-
-
- NSProgressIndicator
- NSView
-
- IBFrameworkSource
- AppKit.framework/Headers/NSProgressIndicator.h
-
-
-
- NSResponder
-
- IBFrameworkSource
- AppKit.framework/Headers/NSInterfaceStyle.h
-
-
-
- NSResponder
- NSObject
-
- IBFrameworkSource
- AppKit.framework/Headers/NSResponder.h
-
-
-
- NSScrollView
- NSView
-
- IBFrameworkSource
- AppKit.framework/Headers/NSScrollView.h
-
-
-
- NSScroller
- NSControl
-
- IBFrameworkSource
- AppKit.framework/Headers/NSScroller.h
-
-
-
- NSSearchField
- NSTextField
-
- IBFrameworkSource
- AppKit.framework/Headers/NSSearchField.h
-
-
-
- NSSearchFieldCell
- NSTextFieldCell
-
- IBFrameworkSource
- AppKit.framework/Headers/NSSearchFieldCell.h
-
-
-
- NSSegmentedCell
- NSActionCell
-
- IBFrameworkSource
- AppKit.framework/Headers/NSSegmentedCell.h
-
-
-
- NSSegmentedControl
- NSControl
-
- IBFrameworkSource
- AppKit.framework/Headers/NSSegmentedControl.h
-
-
-
- NSSlider
- NSControl
-
- IBFrameworkSource
- AppKit.framework/Headers/NSSlider.h
-
-
-
- NSSliderCell
- NSActionCell
-
- IBFrameworkSource
- AppKit.framework/Headers/NSSliderCell.h
-
-
-
- NSStepper
- NSControl
-
- IBFrameworkSource
- AppKit.framework/Headers/NSStepper.h
-
-
-
- NSStepperCell
- NSActionCell
-
- IBFrameworkSource
- AppKit.framework/Headers/NSStepperCell.h
-
-
-
- NSTabView
- NSView
-
- IBFrameworkSource
- AppKit.framework/Headers/NSTabView.h
-
-
-
- NSTabViewItem
- NSObject
-
- IBFrameworkSource
- AppKit.framework/Headers/NSTabViewItem.h
-
-
-
- NSTableColumn
- NSObject
-
- IBFrameworkSource
- AppKit.framework/Headers/NSTableColumn.h
-
-
-
- NSTableHeaderView
- NSView
-
- IBFrameworkSource
- AppKit.framework/Headers/NSTableHeaderView.h
-
-
-
- NSTableView
- NSControl
-
-
-
- NSText
- NSView
-
- IBFrameworkSource
- AppKit.framework/Headers/NSText.h
-
-
-
- NSTextField
- NSControl
-
- IBFrameworkSource
- AppKit.framework/Headers/NSTextField.h
-
-
-
- NSTextFieldCell
- NSActionCell
-
- IBFrameworkSource
- AppKit.framework/Headers/NSTextFieldCell.h
-
-
-
- NSTextView
- NSText
-
- IBFrameworkSource
- AppKit.framework/Headers/NSTextView.h
-
-
-
- NSToolbar
- NSObject
-
- IBFrameworkSource
- AppKit.framework/Headers/NSToolbar.h
-
-
-
- NSToolbarItem
- NSObject
-
-
-
- NSUserDefaultsController
- NSController
-
- IBFrameworkSource
- AppKit.framework/Headers/NSUserDefaultsController.h
-
-
-
- NSView
-
- IBFrameworkSource
- AppKit.framework/Headers/NSClipView.h
-
-
-
- NSView
-
-
-
- NSView
-
- IBFrameworkSource
- AppKit.framework/Headers/NSRulerView.h
-
-
-
- NSView
- NSResponder
-
-
-
- NSWindow
-
-
-
- NSWindow
- NSResponder
-
- IBFrameworkSource
- AppKit.framework/Headers/NSWindow.h
-
-
-
- NSWindow
-
- IBFrameworkSource
- AppKit.framework/Headers/NSWindowScripting.h
-
-
-
- NSWindowController
- NSResponder
-
- showWindow:
- id
-
-
- showWindow:
-
- showWindow:
- id
-
-
-
- IBFrameworkSource
- AppKit.framework/Headers/NSWindowController.h
+ IBDocumentRelativeSource
+ ../../userinterface/WifiSettingsPanel.h
diff --git a/desmume/src/frontend/cocoa/userinterface/InputManager.mm b/desmume/src/frontend/cocoa/userinterface/InputManager.mm
index 604295afd..9d5224006 100644
--- a/desmume/src/frontend/cocoa/userinterface/InputManager.mm
+++ b/desmume/src/frontend/cocoa/userinterface/InputManager.mm
@@ -1170,7 +1170,7 @@ - (id)init
ClientCommandAttributes cmdToggleSpeedLimiter = NewCommandAttributesWithFunction("Enable/Disable Speed Limiter", &ClientCommandToggleSpeedLimiter);
ClientCommandAttributes cmdToggleAutoFrameSkip = NewCommandAttributesWithFunction("Enable/Disable Auto Frame Skip", &ClientCommandToggleAutoFrameSkip);
- ClientCommandAttributes cmdToggleCheats = NewCommandAttributesWithFunction("Enable/Disable Cheats", &ClientCommandToggleCheats);
+ ClientCommandAttributes cmdToggleCheats = NewCommandAttributesWithFunction("Enable/Disable Cheat System", &ClientCommandToggleCheats);
ClientCommandAttributes cmdCoreExecute = NewCommandAttributesWithFunction("Execute", &ClientCommandCoreExecute);
ClientCommandAttributes cmdCorePause = NewCommandAttributesWithFunction("Pause", &ClientCommandCorePause);
ClientCommandAttributes cmdToggleExecutePause = NewCommandAttributesWithFunction("Execute/Pause", &ClientCommandToggleExecutePause);
@@ -1227,7 +1227,7 @@ - (id)init
defaultCommandAttributes["Set Speed"] = cmdToggleSpeed;
defaultCommandAttributes["Enable/Disable Speed Limiter"] = cmdToggleSpeedLimiter;
defaultCommandAttributes["Enable/Disable Auto Frame Skip"] = cmdToggleAutoFrameSkip;
- defaultCommandAttributes["Enable/Disable Cheats"] = cmdToggleCheats;
+ defaultCommandAttributes["Enable/Disable Cheat System"] = cmdToggleCheats;
defaultCommandAttributes["Execute"] = cmdCoreExecute;
defaultCommandAttributes["Pause"] = cmdCorePause;
defaultCommandAttributes["Execute/Pause"] = cmdToggleExecutePause;
diff --git a/desmume/src/frontend/cocoa/userinterface/cheatWindowDelegate.h b/desmume/src/frontend/cocoa/userinterface/cheatWindowDelegate.h
index 42e1b86cb..8199e494a 100644
--- a/desmume/src/frontend/cocoa/userinterface/cheatWindowDelegate.h
+++ b/desmume/src/frontend/cocoa/userinterface/cheatWindowDelegate.h
@@ -58,6 +58,7 @@
NSWindow *cheatDatabaseSheet;
NSUInteger untitledCount;
+ NSFont *codeEditorFont;
NSMutableDictionary *bindings;
CocoaDSCheatItem *workingCheat;
@@ -92,6 +93,7 @@
@property (readonly) IBOutlet NSWindow *cheatDatabaseSheet;
@property (assign) NSUInteger untitledCount;
+@property (assign) NSFont *codeEditorFont;
@property (readonly) NSMutableDictionary *bindings;
@property (retain) CocoaDSCheatItem *workingCheat;
@property (retain) CocoaDSCheatManager *cdsCheats;
diff --git a/desmume/src/frontend/cocoa/userinterface/cheatWindowDelegate.mm b/desmume/src/frontend/cocoa/userinterface/cheatWindowDelegate.mm
index 633c5d41d..fa1ac8857 100644
--- a/desmume/src/frontend/cocoa/userinterface/cheatWindowDelegate.mm
+++ b/desmume/src/frontend/cocoa/userinterface/cheatWindowDelegate.mm
@@ -1,6 +1,6 @@
/*
Copyright (C) 2011 Roger Manuel
- Copyright (C) 2012-2022 DeSmuME team
+ Copyright (C) 2012-2023 DeSmuME team
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
@@ -51,6 +51,7 @@ @implementation CheatWindowDelegate
@synthesize cheatDatabaseSheet;
@synthesize untitledCount;
+@synthesize codeEditorFont;
@synthesize bindings;
@synthesize cdsCheats;
@synthesize cdsCheatSearch;
@@ -85,6 +86,7 @@ - (id)init
currentView = nil;
currentSearchStyleView = nil;
untitledCount = 0;
+ codeEditorFont = [NSFont fontWithName:@"Monaco" size:13.0];
[bindings setValue:[NSNumber numberWithBool:NO] forKey:@"hasSelection"];
[bindings setValue:[NSNumber numberWithBool:NO] forKey:@"hasItems"];
@@ -242,7 +244,8 @@ - (IBAction) selectCheatType:(id)sender
NSInteger cheatTypeID = [CocoaDSUtil getIBActionSenderTag:sender];
CocoaDSCheatItem *cheatItem = [cheatSelectedItemController content];
- cheatItem.cheatType = cheatTypeID;
+ [window makeFirstResponder:nil]; // Force end of editing of any text fields.
+ [cheatItem setCheatType:cheatTypeID];
[self setCheatConfigViewByType:cheatTypeID];
}
@@ -458,8 +461,7 @@ - (void) addSelectedFromCheatDatabase
{
if (cheatItem.willAdd)
{
- CocoaDSCheatItem *newCheatItem = [[[CocoaDSCheatItem alloc] initWithCheatData:cheatItem.data] autorelease];
- [newCheatItem retainData];
+ CocoaDSCheatItem *newCheatItem = [[[CocoaDSCheatItem alloc] initWithCheatItem:cheatItem] autorelease];
[cheatListController addObject:newCheatItem];
[self.cdsCheats add:newCheatItem];
}