Add diable gameshark code

This commit is contained in:
zilmar 2021-03-06 10:56:24 +10:30
parent bc81e041f8
commit b35d59408a
5 changed files with 141 additions and 70 deletions

View File

@ -112,9 +112,7 @@ Note=Here you can Choose Options with Mario with His Cap on & An Extra in His Ha
38 Flying Mario Cap In Hand
$Have\Debug Mode
A032D598 00??
01 On
00 Off
A032D598 0001:0000
$Have\Level Select
A032D58C 0001

View File

@ -184,9 +184,33 @@ CEnhancement::CEnhancement(const char * Ident, const char * Entry) :
//Gameshark Code
while (CurrentLine < Lines.size())
{
char TempFormat[128] = { 0 };
const char * Line = Lines[CurrentLine].c_str();
const char * Pos = strchr(Line, ' ');
if (strlen(Line) != 13 || Pos == nullptr || (Pos - Line) != 8)
size_t LineLen = strlen(Line);
if (LineLen >= (sizeof(TempFormat) / sizeof(TempFormat[0])))
{
break;
}
for (size_t i = 0, n = LineLen; i < n; i++)
{
if (isxdigit(Line[i]))
{
TempFormat[i] = 'X';
}
else if (Line[i] == ' ' || Line[i] == '?' || Line[i] == ':')
{
TempFormat[i] = Line[i];
}
else
{
TempFormat[i] = '#';
}
}
if (strcmp(TempFormat, "XXXXXXXX XXXX") != 0 &&
strcmp(TempFormat, "XXXXXXXX XX??") != 0 &&
strcmp(TempFormat, "XXXXXXXX ????") != 0 &&
strcmp(TempFormat, "XXXXXXXX XXXX:XXXX") != 0)
{
break;
}

View File

@ -12,6 +12,22 @@
#include <Common/path.h>
#include <Common/Util.h>
CEnhancements::GAMESHARK_CODE::GAMESHARK_CODE(const GAMESHARK_CODE&rhs)
{
m_Command = rhs.m_Command;
m_Value = rhs.m_Value;
m_HasDisableValue = rhs.m_HasDisableValue;
m_DisableValue = rhs.m_DisableValue;
}
CEnhancements::GAMESHARK_CODE::GAMESHARK_CODE(uint32_t Command, uint16_t Value, bool HasDisableValue, uint16_t DisableValue) :
m_Command(Command),
m_Value(Value),
m_HasDisableValue(HasDisableValue),
m_DisableValue(DisableValue)
{
}
CEnhancements::CEnhancements() :
m_ScanFileThread(stScanFileThread),
m_Scan(true),
@ -54,19 +70,19 @@ void CEnhancements::ApplyGSButton(CMipsMemoryVM & MMU, bool /*UpdateChanges*/)
for (size_t CurrentEntry = 0; CurrentEntry < CodeEntry.size(); CurrentEntry++)
{
const GAMESHARK_CODE & Code = CodeEntry[CurrentEntry];
switch (Code.Command & 0xFF000000) {
switch (Code.Command() & 0xFF000000) {
case 0x88000000:
ModifyMemory8(MMU, 0x80000000 | (Code.Command & 0xFFFFFF), (uint8_t)Code.Value);
ModifyMemory8(MMU, 0x80000000 | (Code.Command() & 0xFFFFFF), (uint8_t)Code.Value(), Code.HasDisableValue(), (uint8_t)Code.DisableValue());
break;
case 0x89000000:
ModifyMemory16(MMU, 0x80000000 | (Code.Command & 0xFFFFFF), Code.Value);
ModifyMemory16(MMU, 0x80000000 | (Code.Command() & 0xFFFFFF), Code.Value(), Code.HasDisableValue(), Code.DisableValue());
break;
// Xplorer64
case 0xA8000000:
ModifyMemory8(MMU, 0x80000000 | (ConvertXP64Address(Code.Command) & 0xFFFFFF), (uint8_t)ConvertXP64Value(Code.Value));
ModifyMemory8(MMU, 0x80000000 | (ConvertXP64Address(Code.Command()) & 0xFFFFFF), (uint8_t)ConvertXP64Value(Code.Value()), Code.HasDisableValue(), (uint8_t)Code.DisableValue());
break;
case 0xA9000000:
ModifyMemory16(MMU, 0x80000000 | (ConvertXP64Address(Code.Command) & 0xFFFFFF), ConvertXP64Value(Code.Value));
ModifyMemory16(MMU, 0x80000000 | (ConvertXP64Address(Code.Command()) & 0xFFFFFF), ConvertXP64Value(Code.Value()), Code.HasDisableValue(), Code.DisableValue());
break;
}
}
@ -322,29 +338,37 @@ void CEnhancements::LoadActive(CEnhancementList & List, CPlugins * Plugins)
const CEnhancement::CodeEntries Entries = Enhancement.GetEntries();
CODES Code;
Code.reserve(Entries.size());
for (size_t i = 0, n = Entries.size(); i < n; i++)
{
GAMESHARK_CODE CodeEntry;
CodeEntry.Command = Entries[i].Command;
uint32_t Command = Entries[i].Command;
uint16_t Value = 0, DisableValue = 0;
bool HasDisableValue = false;
if (strncmp(Entries[i].Value.c_str(), "????", 4) == 0)
{
CodeEntry.Value = Enhancement.SelectedOption();
Value = Enhancement.SelectedOption();
}
else if (strncmp(Entries[i].Value.c_str(), "??", 2) == 0)
{
CodeEntry.Value = (uint8_t)(strtoul(&(Entries[i].Value.c_str()[2]), 0, 16), 0, 16);
CodeEntry.Value |= Enhancement.SelectedOption() << 16;
Value = (uint8_t)(strtoul(&(Entries[i].Value.c_str()[2]), 0, 16), 0, 16);
Value |= Enhancement.SelectedOption() << 16;
}
else if (strncmp(&Entries[i].Value[2], "??", 2) == 0)
{
CodeEntry.Value = (uint16_t)(strtoul(Entries[i].Value.c_str(), 0, 16) << 16);
CodeEntry.Value |= Enhancement.SelectedOption();
Value = (uint16_t)(strtoul(Entries[i].Value.c_str(), 0, 16) << 16);
Value |= Enhancement.SelectedOption();
}
else
{
CodeEntry.Value = (uint16_t)strtoul(Entries[i].Value.c_str(), 0, 16);
Value = (uint16_t)strtoul(Entries[i].Value.c_str(), 0, 16);
}
Code.push_back(CodeEntry);
if (Entries[i].Value.size() > 8 && Entries[i].Value[4] == ':')
{
HasDisableValue = true;
DisableValue = (uint16_t)strtoul(&Entries[i].Value[5], 0, 16);
}
Code.emplace_back(GAMESHARK_CODE(Command, Value, HasDisableValue, DisableValue));
}
m_ActiveCodes.push_back(Code);
}
@ -361,7 +385,7 @@ void CEnhancements::ApplyGameSharkCodes(CMipsMemoryVM & MMU, CODES & CodeEntry,
uint16_t wMemory;
uint8_t bMemory;
switch (Code.Command & 0xFF000000)
switch (Code.Command() & 0xFF000000)
{
case 0x50000000: // Gameshark / AR
if ((CurrentEntry + 1) >= (int)CodeEntry.size())
@ -372,31 +396,31 @@ void CEnhancements::ApplyGameSharkCodes(CMipsMemoryVM & MMU, CODES & CodeEntry,
{
const GAMESHARK_CODE & NextCodeEntry = CodeEntry[CurrentEntry + 1];
int numrepeats = (Code.Command & 0x0000FF00) >> 8;
int offset = Code.Command & 0x000000FF;
int numrepeats = (Code.Command() & 0x0000FF00) >> 8;
int offset = Code.Command() & 0x000000FF;
uint32_t Address;
int incr = Code.Value;
int incr = Code.Value();
int i;
switch (NextCodeEntry.Command & 0xFF000000) {
switch (NextCodeEntry.Command() & 0xFF000000) {
case 0x10000000: // Xplorer64
case 0x80000000:
Address = 0x80000000 | (NextCodeEntry.Command & 0xFFFFFF);
wMemory = NextCodeEntry.Value;
Address = 0x80000000 | (NextCodeEntry.Command() & 0xFFFFFF);
wMemory = NextCodeEntry.Value();
for (i = 0; i < numrepeats; i++)
{
ModifyMemory8(MMU, Address, (uint8_t)wMemory);
ModifyMemory8(MMU, Address, (uint8_t)wMemory, NextCodeEntry.HasDisableValue(), (uint8_t)NextCodeEntry.DisableValue());
Address += offset;
wMemory += (uint16_t)incr;
}
break;
case 0x11000000: // Xplorer64
case 0x81000000:
Address = 0x80000000 | (NextCodeEntry.Command & 0xFFFFFF);
wMemory = NextCodeEntry.Value;
Address = 0x80000000 | (NextCodeEntry.Command() & 0xFFFFFF);
wMemory = NextCodeEntry.Value();
for (i = 0; i < numrepeats; i++)
{
ModifyMemory16(MMU, Address, wMemory);
ModifyMemory16(MMU, Address, wMemory, NextCodeEntry.HasDisableValue(), NextCodeEntry.DisableValue());
Address += offset;
wMemory += (uint16_t)incr;
}
@ -408,41 +432,41 @@ void CEnhancements::ApplyGameSharkCodes(CMipsMemoryVM & MMU, CODES & CodeEntry,
case 0x30000000:
case 0x82000000:
case 0x84000000:
ModifyMemory8(MMU, 0x80000000 | (Code.Command & 0xFFFFFF), (uint8_t)Code.Value);
ModifyMemory8(MMU, 0x80000000 | (Code.Command() & 0xFFFFFF), (uint8_t)Code.Value(), Code.HasDisableValue(), (uint8_t)Code.DisableValue());
break;
case 0x81000000:
ModifyMemory16(MMU, 0x80000000 | (Code.Command & 0xFFFFFF), Code.Value);
ModifyMemory16(MMU, 0x80000000 | (Code.Command() & 0xFFFFFF), Code.Value(), Code.HasDisableValue(), Code.DisableValue());
break;
case 0xA0000000:
ModifyMemory8(MMU, 0xA0000000 | (Code.Command & 0xFFFFFF), (uint8_t)Code.Value);
ModifyMemory8(MMU, 0xA0000000 | (Code.Command() & 0xFFFFFF), (uint8_t)Code.Value(), Code.HasDisableValue(), (uint8_t)Code.DisableValue());
break;
case 0xA1000000:
ModifyMemory16(MMU, 0xA0000000 | (Code.Command & 0xFFFFFF), Code.Value);
ModifyMemory16(MMU, 0xA0000000 | (Code.Command() & 0xFFFFFF), Code.Value(), Code.HasDisableValue(), Code.DisableValue());
break;
case 0xD0000000:
MMU.LB_VAddr(0x80000000 | (Code.Command & 0xFFFFFF), bMemory);
if (bMemory == Code.Value)
MMU.LB_VAddr(0x80000000 | (Code.Command() & 0xFFFFFF), bMemory);
if (bMemory == Code.Value())
{
ApplyGameSharkCodes(MMU, CodeEntry, CurrentEntry + 1);
}
break;
case 0xD1000000:
MMU.LH_VAddr(0x80000000 | (Code.Command & 0xFFFFFF), wMemory);
if (wMemory == Code.Value)
MMU.LH_VAddr(0x80000000 | (Code.Command() & 0xFFFFFF), wMemory);
if (wMemory == Code.Value())
{
ApplyGameSharkCodes(MMU, CodeEntry, CurrentEntry + 1);
}
break;
case 0xD2000000:
MMU.LB_VAddr(0x80000000 | (Code.Command & 0xFFFFFF), bMemory);
if (bMemory != Code.Value)
MMU.LB_VAddr(0x80000000 | (Code.Command() & 0xFFFFFF), bMemory);
if (bMemory != Code.Value())
{
ApplyGameSharkCodes(MMU, CodeEntry, CurrentEntry + 1);
}
break;
case 0xD3000000:
MMU.LH_VAddr(0x80000000 | (Code.Command & 0xFFFFFF), wMemory);
if (wMemory != Code.Value)
MMU.LH_VAddr(0x80000000 | (Code.Command() & 0xFFFFFF), wMemory);
if (wMemory != Code.Value())
{
ApplyGameSharkCodes(MMU, CodeEntry, CurrentEntry + 1);
}
@ -450,32 +474,32 @@ void CEnhancements::ApplyGameSharkCodes(CMipsMemoryVM & MMU, CODES & CodeEntry,
case 0x31000000:
case 0x83000000:
case 0x85000000:
ModifyMemory16(MMU, 0x80000000 | (Code.Command & 0xFFFFFF), Code.Value);
ModifyMemory16(MMU, 0x80000000 | (Code.Command() & 0xFFFFFF), Code.Value(), Code.HasDisableValue(), Code.DisableValue());
break;
case 0xE8000000:
ModifyMemory8(MMU, 0x80000000 | (ConvertXP64Address(Code.Command) & 0xFFFFFF), (uint8_t)ConvertXP64Value(Code.Value));
ModifyMemory8(MMU, 0x80000000 | (ConvertXP64Address(Code.Command()) & 0xFFFFFF), (uint8_t)ConvertXP64Value(Code.Value()), Code.HasDisableValue(), (uint8_t)Code.DisableValue());
break;
case 0xE9000000:
ModifyMemory16(MMU, 0x80000000 | (ConvertXP64Address(Code.Command) & 0xFFFFFF), ConvertXP64Value(Code.Value));
ModifyMemory16(MMU, 0x80000000 | (ConvertXP64Address(Code.Command()) & 0xFFFFFF), ConvertXP64Value(Code.Value()), Code.HasDisableValue(), Code.DisableValue());
break;
case 0xC8000000:
ModifyMemory8(MMU, 0xA0000000 | (ConvertXP64Address(Code.Command) & 0xFFFFFF), (uint8_t)Code.Value);
ModifyMemory8(MMU, 0xA0000000 | (ConvertXP64Address(Code.Command()) & 0xFFFFFF), (uint8_t)Code.Value(), Code.HasDisableValue(), (uint8_t)Code.DisableValue());
break;
case 0xC9000000:
ModifyMemory16(MMU, 0xA0000000 | (ConvertXP64Address(Code.Command) & 0xFFFFFF), ConvertXP64Value(Code.Value));
ModifyMemory16(MMU, 0xA0000000 | (ConvertXP64Address(Code.Command()) & 0xFFFFFF), ConvertXP64Value(Code.Value()), Code.HasDisableValue(), Code.DisableValue());
break;
case 0xB8000000:
case 0xBA000000:
MMU.LB_VAddr(0x80000000 | (ConvertXP64Address(Code.Command) & 0xFFFFFF), bMemory);
if (bMemory == ConvertXP64Value(Code.Value))
MMU.LB_VAddr(0x80000000 | (ConvertXP64Address(Code.Command()) & 0xFFFFFF), bMemory);
if (bMemory == ConvertXP64Value(Code.Value()))
{
ApplyGameSharkCodes(MMU, CodeEntry, CurrentEntry + 1);
}
break;
case 0xB9000000:
case 0xBB000000:
MMU.LH_VAddr(0x80000000 | (ConvertXP64Address(Code.Command) & 0xFFFFFF), wMemory);
if (wMemory == ConvertXP64Value(Code.Value))
MMU.LH_VAddr(0x80000000 | (ConvertXP64Address(Code.Command()) & 0xFFFFFF), wMemory);
if (wMemory == ConvertXP64Value(Code.Value()))
{
ApplyGameSharkCodes(MMU, CodeEntry, CurrentEntry + 1);
}
@ -498,7 +522,7 @@ uint32_t CEnhancements::EntrySize(const CODES & CodeEntry, uint32_t CurrentEntry
return 0;
}
const GAMESHARK_CODE & Code = CodeEntry[CurrentEntry];
switch (Code.Command & 0xFF000000)
switch (Code.Command() & 0xFF000000)
{
case 0x50000000: // Gameshark / AR
if ((CurrentEntry + 1) >= (int)CodeEntry.size())
@ -506,7 +530,7 @@ uint32_t CEnhancements::EntrySize(const CODES & CodeEntry, uint32_t CurrentEntry
return 1;
}
switch (CodeEntry[CurrentEntry + 1].Command & 0xFF000000)
switch (CodeEntry[CurrentEntry + 1].Command() & 0xFF000000)
{
case 0x10000000: // Xplorer64
case 0x80000000:
@ -530,12 +554,19 @@ uint32_t CEnhancements::EntrySize(const CODES & CodeEntry, uint32_t CurrentEntry
return 1;
}
void CEnhancements::ModifyMemory8(CMipsMemoryVM & MMU, uint32_t Address, uint8_t Value)
void CEnhancements::ModifyMemory8(CMipsMemoryVM & MMU, uint32_t Address, uint8_t Value, bool HasDisableValue, uint8_t DisableValue)
{
MEM_VALUE8 OriginalValue;
if (!MMU.LB_VAddr(Address, OriginalValue.Original))
if (HasDisableValue)
{
return;
OriginalValue.Original = DisableValue;
}
else
{
if (!MMU.LB_VAddr(Address, OriginalValue.Original))
{
return;
}
}
if (OriginalValue.Original == Value)
{
@ -550,12 +581,19 @@ void CEnhancements::ModifyMemory8(CMipsMemoryVM & MMU, uint32_t Address, uint8_t
std::pair<ORIGINAL_VALUES8::iterator, bool> itr = m_OriginalValues8.insert(ORIGINAL_VALUES8::value_type(Address, OriginalValue));
}
void CEnhancements::ModifyMemory16(CMipsMemoryVM & MMU, uint32_t Address, uint16_t Value)
void CEnhancements::ModifyMemory16(CMipsMemoryVM & MMU, uint32_t Address, uint16_t Value, bool HasDisableValue, uint16_t DisableValue)
{
MEM_VALUE16 OriginalValue;
if (!MMU.LH_VAddr(Address, OriginalValue.Original))
if (HasDisableValue)
{
return;
OriginalValue.Original = DisableValue;
}
else
{
if (!MMU.LH_VAddr(Address, OriginalValue.Original))
{
return;
}
}
if (OriginalValue.Original == Value)
{

View File

@ -32,10 +32,25 @@ public:
CEnhancementList Enhancements(void);
private:
struct GAMESHARK_CODE
class GAMESHARK_CODE
{
uint32_t Command;
uint16_t Value;
public:
GAMESHARK_CODE(const GAMESHARK_CODE&);
GAMESHARK_CODE(uint32_t Command, uint16_t Value, bool HasDisableValue, uint16_t DisableValue);
uint32_t Command(void) const { return m_Command; }
uint16_t Value(void) const { return m_Value; }
bool HasDisableValue(void) const { return m_HasDisableValue; }
uint16_t DisableValue(void) const { return m_DisableValue; }
private:
GAMESHARK_CODE();
GAMESHARK_CODE& operator=(const GAMESHARK_CODE&);
uint32_t m_Command;
uint16_t m_Value;
bool m_HasDisableValue;
uint16_t m_DisableValue;
};
struct MEM_VALUE16
@ -61,8 +76,8 @@ private:
void LoadEnhancements(const char * Ident, SectionFiles & Files, std::unique_ptr<CEnhancmentFile> & File, CEnhancementList & EnhancementList);
void ApplyGameSharkCodes(CMipsMemoryVM & MMU, CODES & CodeEntry, uint32_t CurrentEntry);
uint32_t EntrySize(const CODES & CodeEntry, uint32_t CurrentEntry);
void ModifyMemory8(CMipsMemoryVM & MMU, uint32_t Address, uint8_t Value);
void ModifyMemory16(CMipsMemoryVM & MMU, uint32_t Address, uint16_t Value);
void ModifyMemory8(CMipsMemoryVM & MMU, uint32_t Address, uint8_t Value, bool HasDisableValue, uint8_t DisableValue);
void ModifyMemory16(CMipsMemoryVM & MMU, uint32_t Address, uint16_t Value, bool HasDisableValue, uint16_t DisableValue);
void ScanFileThread(void);
void WaitScanDone(void);
void GameChanged(void);

View File

@ -793,10 +793,6 @@ bool CEditCheat::ReadEnhancement(CEnhancement & Enhancement)
NumLines = CheatOptions.GetLineCount();
std::string OptionsStr;
CEnhancement::CodeOptions Options;
if (NumLines > 0 && TestEnhancement.CodeOptionSize() == 0)
{
return false;
}
for (int i = 0; i < NumLines; i++)
{
wchar_t wc_str[128];
@ -848,7 +844,7 @@ void CEditCheat::DetailsChanged(void)
GetDlgItem(IDC_LABEL_OPTIONS).EnableWindow(HasOptions);
GetDlgItem(IDC_LABEL_OPTIONS_FORMAT).EnableWindow(HasOptions);
GetDlgItem(IDC_CHEAT_OPTIONS).EnableWindow(HasOptions);
GetDlgItem(IDC_ADD).EnableWindow(true);
GetDlgItem(IDC_ADD).EnableWindow(Enhancement.CodeOptionSize() == 0 || Enhancement.GetOptions().size() > 0);
}
}
@ -885,7 +881,7 @@ bool CEditCheat::ValuesChanged(void)
if (Result == IDYES)
{
CEnhancement Enhancement(CEnhancement::CheatIdent);
if (!ReadEnhancement(Enhancement))
if (ReadEnhancement(Enhancement) && (Enhancement.CodeOptionSize() == 0 || Enhancement.GetOptions().size() > 0))
{
SendMessage(WM_COMMAND, MAKELPARAM(IDC_ADD, 0));
}