2019-07-14 05:42:21 +02:00
|
|
|
/*****************************************************************************\
|
|
|
|
Snes9x - Portable Super Nintendo Entertainment System (TM) emulator.
|
|
|
|
This file is licensed under the Snes9x License.
|
|
|
|
For further information, consult the LICENSE file in the root directory.
|
|
|
|
\*****************************************************************************/
|
|
|
|
|
|
|
|
/***********************************************************************************
|
|
|
|
SNES9X for Mac OS (c) Copyright John Stiles
|
|
|
|
|
|
|
|
Snes9x for Mac OS X
|
|
|
|
|
|
|
|
(c) Copyright 2001 - 2011 zones
|
|
|
|
(c) Copyright 2002 - 2005 107
|
|
|
|
(c) Copyright 2002 PB1400c
|
|
|
|
(c) Copyright 2004 Alexander and Sander
|
|
|
|
(c) Copyright 2004 - 2005 Steven Seeger
|
|
|
|
(c) Copyright 2005 Ryan Vogt
|
2022-02-07 00:03:46 +01:00
|
|
|
(c) Copyright 2019 - 2022 Michael Donald Buckley
|
2019-07-14 05:42:21 +02:00
|
|
|
***********************************************************************************/
|
|
|
|
|
|
|
|
|
|
|
|
#include "port.h"
|
|
|
|
#include "cheats.h"
|
|
|
|
|
|
|
|
#define __STDC_FORMAT_MACROS
|
|
|
|
#include <inttypes.h>
|
|
|
|
|
|
|
|
#include "mac-prefix.h"
|
|
|
|
#include "mac-dialog.h"
|
|
|
|
#include "mac-os.h"
|
|
|
|
#include "mac-stringtools.h"
|
|
|
|
#include "mac-cheat.h"
|
|
|
|
|
|
|
|
#define kDataBrowser 'BRSR'
|
|
|
|
#define kCmCheckBox 'CHK_'
|
|
|
|
#define kCmAddress 'ADDR'
|
|
|
|
#define kCmValue 'VALU'
|
|
|
|
#define kCmDescription 'DESC'
|
|
|
|
#define kNewButton 'NEW_'
|
|
|
|
#define kDelButton 'DEL_'
|
|
|
|
#define kAllButton 'ALL_'
|
|
|
|
|
|
|
|
extern SCheatData Cheat;
|
|
|
|
|
2023-03-08 19:23:32 +01:00
|
|
|
bool S9xGameGenieToRaw(const std::string &code, uint32 &address, uint8 &byte);
|
|
|
|
bool S9xProActionReplayToRaw(const std::string &code, uint32 &address, uint8 &byte);
|
|
|
|
|
2022-02-07 00:03:46 +01:00
|
|
|
@implementation S9xCheatItem
|
|
|
|
|
|
|
|
- (void)setAddress:(uint32)address value:(uint8)value cheatDescription:(const char *)cheatDescription
|
2019-07-14 05:42:21 +02:00
|
|
|
{
|
2022-02-07 00:03:46 +01:00
|
|
|
bool enabled = self.enabled.boolValue;
|
|
|
|
|
|
|
|
char code[256];
|
|
|
|
sprintf(code, "%x=%x", address, value);
|
|
|
|
S9xModifyCheatGroup(self.cheatID, cheatDescription, code);
|
|
|
|
|
|
|
|
if (enabled)
|
2019-07-14 05:42:21 +02:00
|
|
|
{
|
2022-02-07 00:03:46 +01:00
|
|
|
S9xEnableCheatGroup(self.cheatID);
|
2019-07-14 05:42:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-07 00:03:46 +01:00
|
|
|
@dynamic address;
|
|
|
|
- (NSNumber *)address
|
2019-07-14 05:42:21 +02:00
|
|
|
{
|
2023-03-08 19:23:32 +01:00
|
|
|
return @(Cheat.group[self.cheatID].cheat[0].address);
|
2022-02-07 00:03:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setAddress:(NSNumber *)address
|
|
|
|
{
|
2023-03-08 19:23:32 +01:00
|
|
|
[self setAddress:address.unsignedIntValue value:Cheat.group[self.cheatID].cheat[0].byte cheatDescription:self.cheatDescription.UTF8String];
|
2022-02-07 00:03:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
@dynamic value;
|
|
|
|
- (NSNumber *)value
|
|
|
|
{
|
2023-03-08 19:23:32 +01:00
|
|
|
return @(Cheat.group[self.cheatID].cheat[0].byte);
|
2022-02-07 00:03:46 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
- (void)setValue:(NSNumber *)value
|
|
|
|
{
|
2023-03-08 19:23:32 +01:00
|
|
|
[self setAddress:Cheat.group[self.cheatID].cheat[0].address value:value.unsignedCharValue cheatDescription:self.cheatDescription.UTF8String];
|
2019-07-14 05:42:21 +02:00
|
|
|
}
|
|
|
|
|
2022-02-07 00:03:46 +01:00
|
|
|
@dynamic enabled;
|
|
|
|
- (NSNumber *)enabled
|
2019-07-14 05:42:21 +02:00
|
|
|
{
|
2023-03-08 19:23:32 +01:00
|
|
|
return @(Cheat.group[self.cheatID].enabled);
|
2022-02-07 00:03:46 +01:00
|
|
|
}
|
2019-07-14 05:42:21 +02:00
|
|
|
|
2022-02-07 00:03:46 +01:00
|
|
|
- (void)setEnabled:(NSNumber *)enabled
|
|
|
|
{
|
|
|
|
if (enabled.boolValue)
|
2019-07-14 05:42:21 +02:00
|
|
|
{
|
2022-02-07 00:03:46 +01:00
|
|
|
S9xEnableCheatGroup(self.cheatID);
|
|
|
|
}
|
|
|
|
else
|
|
|
|
{
|
|
|
|
S9xDisableCheatGroup(self.cheatID);
|
2019-07-14 05:42:21 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2022-02-07 00:03:46 +01:00
|
|
|
@dynamic cheatDescription;
|
|
|
|
- (NSString *)cheatDescription
|
2019-07-14 05:42:21 +02:00
|
|
|
{
|
2023-03-08 19:23:32 +01:00
|
|
|
return [NSString stringWithUTF8String:Cheat.group[self.cheatID].name.c_str()];
|
2019-07-14 05:42:21 +02:00
|
|
|
}
|
|
|
|
|
2022-02-07 00:03:46 +01:00
|
|
|
- (void)setCheatDescription:(NSString *)cheatDescription
|
2019-07-14 05:42:21 +02:00
|
|
|
{
|
2023-03-08 19:23:32 +01:00
|
|
|
[self setAddress:Cheat.group[self.cheatID].cheat[0].address value:Cheat.group[self.cheatID].cheat[0].byte cheatDescription:cheatDescription.UTF8String];
|
2019-07-14 05:42:21 +02:00
|
|
|
}
|
|
|
|
|
2022-02-07 00:03:46 +01:00
|
|
|
- (void)delete
|
2019-07-14 05:42:21 +02:00
|
|
|
{
|
2022-02-07 00:03:46 +01:00
|
|
|
S9xDeleteCheatGroup(self.cheatID);
|
2019-07-14 05:42:21 +02:00
|
|
|
}
|
|
|
|
|
2022-02-07 00:03:46 +01:00
|
|
|
@end
|
|
|
|
|
|
|
|
extern "C"
|
|
|
|
{
|
|
|
|
|
|
|
|
bool CheatValuesFromCode(NSString *code, uint32 *address, uint8 *value)
|
2019-07-14 05:42:21 +02:00
|
|
|
{
|
2022-02-07 00:03:46 +01:00
|
|
|
const char *text = code.UTF8String;
|
|
|
|
|
|
|
|
if (!S9xGameGenieToRaw (text, *address, *value))
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!S9xProActionReplayToRaw (text, *address, *value))
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (sscanf (text, "%x = %x", (unsigned int *)address, (unsigned int *)value) == 2)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
else if (sscanf (text, "%x / %x", (unsigned int *)address, (unsigned int *)value) == 2)
|
|
|
|
{
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
return false;
|
2019-07-14 05:42:21 +02:00
|
|
|
}
|
|
|
|
|
2022-02-07 00:03:46 +01:00
|
|
|
void CreateCheatFromAddress(NSNumber *address, NSNumber *value, NSString *cheatDescription)
|
2019-07-14 05:42:21 +02:00
|
|
|
{
|
2022-02-07 00:03:46 +01:00
|
|
|
char code[256];
|
|
|
|
sprintf(code, "%x=%x", address.unsignedIntValue, value.unsignedCharValue);
|
|
|
|
S9xAddCheatGroup(cheatDescription.UTF8String, code);
|
2023-03-08 19:23:32 +01:00
|
|
|
S9xEnableCheatGroup(Cheat.group.size() - 1);
|
2019-07-14 05:42:21 +02:00
|
|
|
}
|
|
|
|
|
2022-02-07 00:03:46 +01:00
|
|
|
void CreateCheatFromCode(NSString *code, NSString *cheatDescription)
|
|
|
|
{
|
|
|
|
S9xAddCheatGroup(cheatDescription.UTF8String, code.UTF8String);
|
2023-03-08 19:23:32 +01:00
|
|
|
S9xEnableCheatGroup(Cheat.group.size() - 1);
|
2022-02-07 00:03:46 +01:00
|
|
|
}
|
2019-07-14 05:42:21 +02:00
|
|
|
|
2022-02-07 00:03:46 +01:00
|
|
|
NSArray<S9xCheatItem *> *GetAllCheats(void)
|
2019-07-14 05:42:21 +02:00
|
|
|
{
|
2022-02-07 00:03:46 +01:00
|
|
|
NSMutableArray *cheats = [NSMutableArray new];
|
|
|
|
uint32 cheatID = 0;
|
|
|
|
|
2023-03-08 19:23:32 +01:00
|
|
|
for (auto it : Cheat.group)
|
2022-02-07 00:03:46 +01:00
|
|
|
{
|
|
|
|
S9xCheatItem *cheat = [S9xCheatItem new];
|
|
|
|
cheat.cheatID = cheatID++;
|
|
|
|
|
|
|
|
[cheats addObject:cheat];
|
|
|
|
}
|
|
|
|
|
|
|
|
return cheats;
|
|
|
|
}
|
2019-07-14 05:42:21 +02:00
|
|
|
}
|