Update cheat system. It becomes bsnes-compatible.

Notes:
- New Snes9x can read old CHT format. Aside from that, I wrote a tool that converts the old CHT to the new one. It helps you if you want to convert a lot of files at a time. http://www.mediafire.com/?v8yb0yy1czsdyxh
- New CHT format (CSV) doesn't have a field of "saved value".

Development Notes:
- I'm afraid I worked on only Windows version. Other ports might need a little modification. (especially when you uses SCheat structure on your port-specific code.) To use the new cheat code on your port, you need to call S9xAddCheat (enable, save_current_value, code, name), instead of S9xAddCheat(enable, save_current_value, address, byte, name)
This commit is contained in:
gocha 2012-08-17 08:05:25 +09:00
parent 6cd98accd9
commit 7dec44e1e3
12 changed files with 883 additions and 932 deletions

View File

@ -223,21 +223,38 @@ static bool8 S9xAllHex (const char *code, int len)
const char * S9xProActionReplayToRaw (const char *code, uint32 &address, uint8 &byte) const char * S9xProActionReplayToRaw (const char *code, uint32 &address, uint8 &byte)
{ {
uint32 data = 0; bool valid = false;
int len = strlen(code);
if (len == 9 && S9xAllHex(code, 6) && *(code + 6) == ':' && S9xAllHex(code + 7, 2)) {
uint32 address_, byte_;
*(char*)(code + 6) = '\0';
if (sscanf(code, "%x", &address_) == 1 && sscanf(code + 7, "%x", &byte_) == 1) {
address = address_;
byte = (uint8) byte_;
valid = true;
}
*(char*)(code + 6) = ':';
}
else if (len == 8 && S9xAllHex(code, 8)) {
uint32 data;
if (sscanf(code, "%x", &data) == 1) {
address = data >> 8;
byte = (uint8) data;
valid = true;
}
}
if (strlen(code) != 8 || !S9xAllHex(code, 8) || sscanf(code, "%x", &data) != 1) if (valid)
return (NULL);
else
return ("Invalid Pro Action Replay code - should be 8 hex digits in length."); return ("Invalid Pro Action Replay code - should be 8 hex digits in length.");
address = data >> 8;
byte = (uint8) data;
return (NULL);
} }
const char * S9xGoldFingerToRaw (const char *code, uint32 &address, bool8 &sram, uint8 &num_bytes, uint8 bytes[3]) const char * S9xGoldFingerToRaw (const char *code, uint32 &address, uint8 &num_bytes, uint8 bytes[3])
{ {
char tmp[15]; char tmp[15];
int i; int i;
bool8 sram;
if (strlen(code) != 14) if (strlen(code) != 14)
return ("Invalid Gold Finger code - should be 14 hex digits in length."); return ("Invalid Gold Finger code - should be 14 hex digits in length.");
@ -247,6 +264,10 @@ const char * S9xGoldFingerToRaw (const char *code, uint32 &address, bool8 &sram,
if (sscanf(tmp, "%x", &address) != 1) if (sscanf(tmp, "%x", &address) != 1)
return ("Invalid Gold Finger code."); return ("Invalid Gold Finger code.");
sram = code[13] == '1';
if (sram)
return ("Unsupported Gold Finger code - writing to SRAM is not supported.");
for (i = 0; i < 3; i++) for (i = 0; i < 3; i++)
{ {
unsigned int byte; unsigned int byte;
@ -259,7 +280,6 @@ const char * S9xGoldFingerToRaw (const char *code, uint32 &address, bool8 &sram,
} }
num_bytes = i; num_bytes = i;
sram = code[13] == '1';
return (NULL); return (NULL);
} }

View File

@ -179,22 +179,28 @@
#ifndef _CHEATS_H_ #ifndef _CHEATS_H_
#define _CHEATS_H_ #define _CHEATS_H_
#define MAX_CHEATS 150 #include <vector>
#include <string>
struct SCheat struct SCheat
{ {
uint32 address; uint32 address;
uint8 byte; uint8 byte;
uint8 saved_byte; uint8 saved_byte;
bool8 enabled;
bool8 saved; bool8 saved;
char name[22]; };
struct SCheatItem
{
std::vector<SCheat> c;
std::string code;
std::string name;
bool8 enabled;
}; };
struct SCheatData struct SCheatData
{ {
struct SCheat c[MAX_CHEATS]; std::vector<SCheatItem> c;
uint32 num_cheats;
uint8 CWRAM[0x20000]; uint8 CWRAM[0x20000];
uint8 CSRAM[0x10000]; uint8 CSRAM[0x10000];
uint8 CIRAM[0x2000]; uint8 CIRAM[0x2000];
@ -236,18 +242,22 @@ typedef enum
extern SCheatData Cheat; extern SCheatData Cheat;
extern Watch watches[16]; extern Watch watches[16];
void S9xApplyCheat (uint32); void S9xApplyCheat (uint32, bool8 = TRUE);
void S9xApplyCheats (void); void S9xApplyCheats (bool8 = TRUE);
void S9xRemoveCheat (uint32); void S9xRemoveCheat (uint32);
void S9xRemoveCheats (void); void S9xRemoveCheats (void);
void S9xDeleteCheat (uint32); void S9xDeleteCheat (uint32);
void S9xDeleteCheats (void); void S9xDeleteCheats (void);
void S9xEnableCheat (uint32); void S9xEnableCheat (uint32);
void S9xDisableCheat (uint32); void S9xDisableCheat (uint32);
void S9xAddCheat (bool8, bool8, uint32, uint8); bool S9xIsValidCheatCode(const char *);
void S9xAddCheat (bool8, bool8, const char *, const char *);
void S9xAddCheat (bool8, bool8, uint32, uint8, const char * = "");
void S9xInitCheatData (void); void S9xInitCheatData (void);
void S9xInitWatchedAddress (void); void S9xInitWatchedAddress (void);
bool8 IsOldCheatFile (const char *);
bool8 S9xLoadCheatFile (const char *); bool8 S9xLoadCheatFile (const char *);
bool8 S9xLoadCheatFileOld (const char *);
bool8 S9xSaveCheatFile (const char *); bool8 S9xSaveCheatFile (const char *);
void S9xStartCheatSearch (SCheatData *); void S9xStartCheatSearch (SCheatData *);
@ -258,6 +268,6 @@ void S9xOutputCheatSearchResults (SCheatData *);
const char * S9xGameGenieToRaw (const char *, uint32 &, uint8 &); const char * S9xGameGenieToRaw (const char *, uint32 &, uint8 &);
const char * S9xProActionReplayToRaw (const char *, uint32 &, uint8 &); const char * S9xProActionReplayToRaw (const char *, uint32 &, uint8 &);
const char * S9xGoldFingerToRaw (const char *, uint32 &, bool8 &, uint8 &, uint8 bytes[3]); const char * S9xGoldFingerToRaw (const char *, uint32 &, uint8 &, uint8 bytes[3]);
#endif #endif

View File

@ -180,6 +180,10 @@
#include "memmap.h" #include "memmap.h"
#include "cheats.h" #include "cheats.h"
#include <string>
#include <sstream>
#include <algorithm>
uint8 S9xGetByteFree (uint32); uint8 S9xGetByteFree (uint32);
void S9xSetByteFree (uint8, uint32); void S9xSetByteFree (uint8, uint32);
@ -223,69 +227,151 @@ void S9xInitCheatData (void)
Cheat.FillRAM = Memory.FillRAM; Cheat.FillRAM = Memory.FillRAM;
} }
void S9xAddCheat (bool8 enable, bool8 save_current_value, uint32 address, uint8 byte) bool S9xIsValidCheatCode(const char *codestring)
{ {
if (Cheat.num_cheats < sizeof(Cheat.c) / sizeof(Cheat.c[0])) std::string codes(codestring);
if (codes.empty() || codes[codes.length() - 1] == '+')
return false; // std::getline cannot handle this case
std::istringstream iss(codes);
std::string code;
while(std::getline(iss, code, '+'))
{ {
Cheat.c[Cheat.num_cheats].address = address; uint32 address;
Cheat.c[Cheat.num_cheats].byte = byte; uint8 byte;
Cheat.c[Cheat.num_cheats].enabled = enable; if (S9xProActionReplayToRaw(code.c_str(), address, byte) != NULL &&
S9xGameGenieToRaw(code.c_str(), address, byte) != NULL)
if (save_current_value)
{ {
Cheat.c[Cheat.num_cheats].saved_byte = S9xGetByteFree(address); uint8 bytes[3];
Cheat.c[Cheat.num_cheats].saved = TRUE; uint8 num_bytes;
}
Cheat.num_cheats++; if (S9xGoldFingerToRaw(code.c_str(), address, num_bytes, bytes) != NULL)
return false; // invalid format
}
}
return true;
}
static inline bool S9xCompileCheat(struct SCheatItem& cheat, bool8 save_current_value)
{
std::string codes(cheat.code);
std::vector<SCheat> cheatVector;
if (codes.empty() || codes[codes.length() - 1] == '+')
return false; // std::getline cannot handle this case
std::istringstream iss(codes);
std::string code;
while(std::getline(iss, code, '+'))
{
SCheat c;
if (S9xProActionReplayToRaw(code.c_str(), c.address, c.byte) == NULL ||
S9xGameGenieToRaw(code.c_str(), c.address, c.byte) == NULL)
{
c.saved = save_current_value;
if (c.saved) {
c.saved_byte = S9xGetByteFree(c.address);
}
cheatVector.push_back(c);
}
else
{
uint32 address;
uint8 bytes[3];
uint8 num_bytes;
if (S9xGoldFingerToRaw(code.c_str(), address, num_bytes, bytes) == NULL)
{
for (int i = 0; i < num_bytes; i++)
{
c.address = address + i;
c.byte = bytes[i];
c.saved = save_current_value;
if (c.saved) {
c.saved_byte = S9xGetByteFree(c.address);
}
cheatVector.push_back(c);
}
}
else
return false; // invalid format
}
}
cheat.c.clear();
copy(cheatVector.begin(), cheatVector.end(), std::back_inserter(cheat.c));
return true;
}
void S9xAddCheat (bool8 enable, bool8 save_current_value, const char *code, const char *name)
{
struct SCheatItem cheat;
cheat.code = code;
cheat.name = name;
cheat.enabled = enable;
if (S9xCompileCheat(cheat, save_current_value))
Cheat.c.push_back(cheat);
}
void S9xAddCheat (bool8 enable, bool8 save_current_value, uint32 address, uint8 byte, const char *name)
{
if (address >= 0x000000 && address <= 0xFFFFFF) {
char code[10];
sprintf(code, "%06X:%02X", address, byte);
S9xAddCheat(enable, save_current_value, code, name);
} }
} }
void S9xDeleteCheat (uint32 which1) void S9xDeleteCheat (uint32 which1)
{ {
if (which1 < Cheat.num_cheats) std::vector<SCheatItem>::iterator iter = Cheat.c.begin();
std::advance(iter, which1);
if (which1 < Cheat.c.size())
{ {
if (Cheat.c[which1].enabled) if (Cheat.c[which1].enabled)
S9xRemoveCheat(which1); S9xRemoveCheat(which1);
Cheat.c.erase(iter);
memmove(&Cheat.c[which1], &Cheat.c[which1 + 1], sizeof(Cheat.c[0]) * (Cheat.num_cheats - which1 - 1));
Cheat.num_cheats--;
} }
} }
void S9xDeleteCheats (void) void S9xDeleteCheats (void)
{ {
S9xRemoveCheats(); S9xRemoveCheats();
Cheat.num_cheats = 0; Cheat.c.clear();
} }
void S9xRemoveCheat (uint32 which1) void S9xRemoveCheat (uint32 which1)
{ {
if (Cheat.c[which1].saved) std::vector<SCheat>::iterator iter = Cheat.c[which1].c.begin();
while (iter != Cheat.c[which1].c.end())
{ {
uint32 address = Cheat.c[which1].address; SCheat& c = *iter;
if (c.saved)
{
uint32 address = c.address;
int block = (address & 0xffffff) >> MEMMAP_SHIFT; int block = (address & 0xffffff) >> MEMMAP_SHIFT;
uint8 *ptr = Memory.Map[block]; uint8 *ptr = Memory.Map[block];
if (ptr >= (uint8 *) CMemory::MAP_LAST) if (ptr >= (uint8 *) CMemory::MAP_LAST)
*(ptr + (address & 0xffff)) = Cheat.c[which1].saved_byte; *(ptr + (address & 0xffff)) = c.saved_byte;
else else
S9xSetByteFree(Cheat.c[which1].saved_byte, address); S9xSetByteFree(c.saved_byte, address);
}
iter++;
} }
} }
void S9xRemoveCheats (void) void S9xRemoveCheats (void)
{ {
for (uint32 i = 0; i < Cheat.num_cheats; i++) for (uint32 i = 0; i < Cheat.c.size(); i++)
if (Cheat.c[i].enabled) if (Cheat.c[i].enabled)
S9xRemoveCheat(i); S9xRemoveCheat(i);
} }
void S9xEnableCheat (uint32 which1) void S9xEnableCheat (uint32 which1)
{ {
if (which1 < Cheat.num_cheats && !Cheat.c[which1].enabled) if (which1 < Cheat.c.size() && !Cheat.c[which1].enabled)
{ {
Cheat.c[which1].enabled = TRUE; Cheat.c[which1].enabled = TRUE;
S9xApplyCheat(which1); S9xApplyCheat(which1);
@ -294,62 +380,222 @@ void S9xEnableCheat (uint32 which1)
void S9xDisableCheat (uint32 which1) void S9xDisableCheat (uint32 which1)
{ {
if (which1 < Cheat.num_cheats && Cheat.c[which1].enabled) if (which1 < Cheat.c.size() && Cheat.c[which1].enabled)
{ {
S9xRemoveCheat(which1); S9xRemoveCheat(which1);
Cheat.c[which1].enabled = FALSE; Cheat.c[which1].enabled = FALSE;
} }
} }
void S9xApplyCheat (uint32 which1) void S9xApplyCheat (uint32 which1, bool8 force_save_current_value)
{ {
uint32 address = Cheat.c[which1].address; std::vector<SCheat>::iterator iter = Cheat.c[which1].c.begin();
while (iter != Cheat.c[which1].c.end())
if (!Cheat.c[which1].saved)
{ {
Cheat.c[which1].saved_byte = S9xGetByteFree(address); SCheat& c = *iter;
Cheat.c[which1].saved = TRUE; uint32 address = c.address;
if (force_save_current_value)
{
c.saved_byte = S9xGetByteFree(address);
c.saved = TRUE;
}
int block = (address & 0xffffff) >> MEMMAP_SHIFT;
uint8 *ptr = Memory.Map[block];
if (ptr >= (uint8 *) CMemory::MAP_LAST)
*(ptr + (address & 0xffff)) = c.byte;
else
S9xSetByteFree(c.byte, address);
iter++;
} }
int block = (address & 0xffffff) >> MEMMAP_SHIFT;
uint8 *ptr = Memory.Map[block];
if (ptr >= (uint8 *) CMemory::MAP_LAST)
*(ptr + (address & 0xffff)) = Cheat.c[which1].byte;
else
S9xSetByteFree(Cheat.c[which1].byte, address);
} }
void S9xApplyCheats (void) void S9xApplyCheats (bool8 force_save_current_value)
{ {
if (Settings.ApplyCheats) if (Settings.ApplyCheats)
{ {
for (uint32 i = 0; i < Cheat.num_cheats; i++) for (uint32 i = 0; i < Cheat.c.size(); i++)
if (Cheat.c[i].enabled) if (Cheat.c[i].enabled)
S9xApplyCheat(i); S9xApplyCheat(i, force_save_current_value);
} }
} }
bool8 S9xLoadCheatFile (const char *filename) std::string& string_replace (std::string& str, const std::string& from, const std::string& to)
{
std::string::size_type pos = 0;
while (pos = str.find(from, pos), pos != std::string::npos) {
str.replace(pos, from.length(), to);
pos += to.length();
}
return str;
}
std::string csv_escape(const std::string &token, bool quoteAlways = false)
{
std::string res(token);
bool needsQuote = false;
if (res.find("\"", 0) != std::string::npos) {
needsQuote = true;
string_replace(res, "\"", "\"\"");
}
if (res.find(",", 0) != std::string::npos ||
res.find("\n", 0) != std::string::npos) {
needsQuote = true;
}
if (needsQuote || quoteAlways) {
res.insert(0, "\"");
res.append("\"");
}
return res;
}
std::string csv_unescape(const std::string &token)
{
std::string res(token);
if (res.length() >= 2 && res[0] == '\"' && res[res.length() - 1] == '\"') {
res.erase(res.length() - 1, 1);
res.erase(0, 1);
}
string_replace(res, "\"\"", "\"");
return res;
}
std::vector<std::string> csv_split(const std::string &str, bool *valid = NULL)
{
std::vector<std::string> res;
if (valid != NULL) {
*valid = true;
}
std::string::size_type start = 0;
std::string::size_type current = 0;
std::string::size_type found;
bool insideQuote = false;
while ((found = str.find_first_of(",\"", current)) != std::string::npos) {
char c = str[found];
if (c == '\"') {
if (insideQuote) {
if (str[found + 1] == '\"') {
found++; // skip the next quote
}
else {
if (valid != NULL && str[found + 1] != ',' && str[found + 1] != '\0' && str[found + 1] != '\r' && str[found + 1] != '\n') {
*valid = false;
}
insideQuote = false;
}
}
else {
if (valid != NULL && found > 0 && str[found - 1] != ',' && str[found - 1] != '\r' && str[found - 1] != '\n') {
*valid = false;
}
insideQuote = true;
}
}
else if (c == ',') {
if (!insideQuote) {
res.push_back(std::string(str, start, found - start));
start = found + 1;
}
}
current = found + 1;
}
res.push_back(std::string(str, start, str.size() - start));
if (valid != NULL && insideQuote) {
*valid = false;
}
for (int i = 0; i < res.size(); i++) {
res[i] = csv_unescape(res[i]);
}
return res;
}
std::string csv_join(std::vector<std::string> &v, bool quoteAlways = false)
{
std::string res;
std::vector<std::string>::iterator iter = v.begin();
bool first = true;
while(iter != v.end())
{
if (first) {
first = false;
}
else {
res.append(",");
}
res.append(csv_escape(*iter, quoteAlways));
iter++;
}
return res;
}
bool8 IsOldCheatFile (const char *filename)
{ {
FILE *fs; FILE *fs;
uint8 data[28];
Cheat.num_cheats = 0;
fs = fopen(filename, "rb"); fs = fopen(filename, "rb");
if (!fs) if (!fs)
return (FALSE); return (FALSE);
while (fread((void *) data, 1, 28, fs) == 28) int c = fgetc(fs);
fclose(fs);
return ((c & ~(4 | 8)) == 0);
}
bool8 S9xLoadCheatFile (const char *filename)
{
FILE *fs;
char data[1024];
if (IsOldCheatFile(filename))
return S9xLoadCheatFileOld(filename);
Cheat.c.clear();
fs = fopen(filename, "r");
if (!fs)
return (FALSE);
while (fgets(data, 1024, fs) != NULL)
{ {
Cheat.c[Cheat.num_cheats].enabled = (data[0] & 4) == 0; data[strlen(data) - 1] = '\0'; // erase newline
Cheat.c[Cheat.num_cheats].byte = data[1];
Cheat.c[Cheat.num_cheats].address = data[2] | (data[3] << 8) | (data[4] << 16); std::vector<std::string> v = csv_split(std::string(data));
Cheat.c[Cheat.num_cheats].saved_byte = data[5]; if (v.size() != 3) {
Cheat.c[Cheat.num_cheats].saved = (data[0] & 8) != 0; fclose(fs);
memmove(Cheat.c[Cheat.num_cheats].name, &data[8], 20); return (FALSE);
Cheat.c[Cheat.num_cheats++].name[20] = 0; }
struct SCheatItem c;
if (v[0] == "enabled") {
c.enabled = TRUE;
}
else if (v[0] == "disabled") {
c.enabled = FALSE;
}
else {
fclose(fs);
return (FALSE);
}
c.code = v[1];
c.name = v[2];
if (!S9xCompileCheat(c, FALSE))
{
fclose(fs);
return (FALSE);
}
Cheat.c.push_back(c);
} }
fclose(fs); fclose(fs);
@ -357,46 +603,83 @@ bool8 S9xLoadCheatFile (const char *filename)
return (TRUE); return (TRUE);
} }
bool8 S9xLoadCheatFileOld (const char *filename)
{
FILE *fs;
uint8 data[28];
Cheat.c.clear();
fs = fopen(filename, "rb");
if (!fs)
return (FALSE);
while (fread((void *) data, 1, 28, fs) == 28)
{
struct SCheatItem c;
uint32 address;
uint8 byte;
uint8 saved_byte;
bool8 saved;
c.enabled = (data[0] & 4) == 0;
byte = data[1];
address = data[2] | (data[3] << 8) | (data[4] << 16);
saved_byte = data[5];
saved = (data[0] & 8) != 0;
char code[10];
char name[22];
sprintf(code, "%06X%02X", address, byte);
memmove(name, &data[8], 20);
name[20] = '\0';
c.code = code;
c.name = name;
if (!S9xCompileCheat(c, FALSE))
{
fclose(fs);
return (FALSE);
}
std::vector<SCheat>::iterator iter = c.c.begin();
while (iter != c.c.end())
{
iter->saved_byte = saved_byte;
iter->saved = saved;
iter++;
}
Cheat.c.push_back(c);
}
fclose(fs);
S9xSaveCheatFile(filename);
return (TRUE);
}
bool8 S9xSaveCheatFile (const char *filename) bool8 S9xSaveCheatFile (const char *filename)
{ {
if (Cheat.num_cheats == 0) if (Cheat.c.size() == 0)
{ {
remove(filename); remove(filename);
return (TRUE); return (TRUE);
} }
FILE *fs; FILE *fs;
uint8 data[28];
fs = fopen(filename, "wb"); fs = fopen(filename, "w");
if (!fs) if (!fs)
return (FALSE); return (FALSE);
for (uint32 i = 0; i < Cheat.num_cheats; i++) for (uint32 i = 0; i < Cheat.c.size(); i++)
{ {
memset(data, 0, 28); struct SCheatItem& c = Cheat.c[i];
std::vector<std::string> v;
if (i == 0) v.push_back(c.enabled ? "enabled" : "disabled");
{ v.push_back(c.code);
data[6] = 254; v.push_back(c.name);
data[7] = 252; if (fprintf(fs, "%s\n", csv_join(v, true).c_str()) < 0)
}
if (!Cheat.c[i].enabled)
data[0] |= 4;
if (Cheat.c[i].saved)
data[0] |= 8;
data[1] = Cheat.c[i].byte;
data[2] = (uint8) (Cheat.c[i].address >> 0);
data[3] = (uint8) (Cheat.c[i].address >> 8);
data[4] = (uint8) (Cheat.c[i].address >> 16);
data[5] = Cheat.c[i].saved_byte;
memmove(&data[8], Cheat.c[i].name, 19);
if (fwrite(data, 28, 1, fs) != 1)
{ {
fclose(fs); fclose(fs);
return (FALSE); return (FALSE);

View File

@ -448,7 +448,7 @@ void S9xEndScreenRefresh (void)
else else
S9xControlEOF(); S9xControlEOF();
S9xApplyCheats(); S9xApplyCheats(FALSE);
#ifdef DEBUGGER #ifdef DEBUGGER
if (CPU.Flags & FRAME_ADVANCE_FLAG) if (CPU.Flags & FRAME_ADVANCE_FLAG)

View File

@ -1759,7 +1759,7 @@ bool8 CMemory::LoadROMInt (int32 ROMfillSize)
InitROM(); InitROM();
S9xInitCheatData(); S9xInitCheatData();
S9xApplyCheats(); S9xApplyCheats(FALSE);
S9xReset(); S9xReset();
@ -1930,7 +1930,7 @@ bool8 CMemory::LoadMultiCartInt ()
InitROM(); InitROM();
S9xInitCheatData(); S9xInitCheatData();
S9xApplyCheats(); S9xApplyCheats(FALSE);
S9xReset(); S9xReset();

View File

@ -788,11 +788,10 @@ char * S9xParseArgs (char **argv, int argc)
{ {
uint32 address; uint32 address;
uint8 bytes[3]; uint8 bytes[3];
bool8 sram;
uint8 num_bytes; uint8 num_bytes;
const char *error; const char *error;
if ((error = S9xGoldFingerToRaw(argv[++i], address, sram, num_bytes, bytes)) == NULL) if ((error = S9xGoldFingerToRaw(argv[++i], address, num_bytes, bytes)) == NULL)
{ {
for (int c = 0; c < num_bytes; c++) for (int c = 0; c < num_bytes; c++)
S9xAddCheat(TRUE, FALSE, address + c, bytes[c]); S9xAddCheat(TRUE, FALSE, address + c, bytes[c]);

View File

@ -1203,16 +1203,7 @@ LRESULT CALLBACK RamWatchProc(HWND hDlg, UINT uMsg, WPARAM wParam, LPARAM lParam
cht.new_val = rswatches[watchIndex].CurValue; cht.new_val = rswatches[watchIndex].CurValue;
cht.saved_val = rswatches[watchIndex].CurValue; cht.saved_val = rswatches[watchIndex].CurValue;
extern INT_PTR CALLBACK DlgCheatSearchAdd(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam); extern INT_PTR CALLBACK DlgCheatSearchAdd(HWND hDlg, UINT msg, WPARAM wParam, LPARAM lParam);
if(DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_CHEAT_FROM_SEARCH), hDlg, DlgCheatSearchAdd, (LPARAM)&cht)) DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_CHEAT_FROM_SEARCH), hDlg, DlgCheatSearchAdd, (LPARAM)&cht);
{
int p;
for(p=0; p<cht.size; p++)
{
S9xAddCheat(TRUE, cht.saved, cht.address +p, ((cht.new_val>>(8*p))&0xFF));
//add cheat
strcpy(Cheat.c[Cheat.num_cheats-1].name, cht.name);
}
}
} }
} }
break; break;

View File

@ -160,11 +160,11 @@
#define IDC_JPTOGGLE 1126 #define IDC_JPTOGGLE 1126
#define IDC_LOCALVIDMEM 1126 #define IDC_LOCALVIDMEM 1126
#define IDC_VSYNC 1126 #define IDC_VSYNC 1126
#define IDC_CHEAT_DESCRIPTION 1127 #define IDC_CHEAT_NAME 1127
#define IDC_KEYBOARD 1127 #define IDC_KEYBOARD 1127
#define IDC_ALLOWLEFTRIGHT 1127 #define IDC_ALLOWLEFTRIGHT 1127
#define IDC_CHEAT_ADDRESS 1128 #define IDC_CHEAT_DEC 1128
#define IDC_CHEAT_BYTE 1129 #define IDC_CHEAT_HEX 1129
#define IDC_ADD_CHEAT 1130 #define IDC_ADD_CHEAT 1130
#define IDC_CHEAT_LIST 1131 #define IDC_CHEAT_LIST 1131
#define IDC_PICTURE 1132 #define IDC_PICTURE 1132
@ -253,13 +253,9 @@
#define IDC_LABEL_UP10 1189 #define IDC_LABEL_UP10 1189
#define IDC_LABEL_MAXSKIP 1190 #define IDC_LABEL_MAXSKIP 1190
#define IDC_LABEL_UP11 1190 #define IDC_LABEL_UP11 1190
#define IDC_LABEL_CHEAT_CODE 1191
#define IDC_LABEL_UP12 1191 #define IDC_LABEL_UP12 1191
#define IDC_LABEL_CHEAT_DESCRIPTION 1192
#define IDC_LABEL_UP13 1192 #define IDC_LABEL_UP13 1192
#define IDC_LABEL_CHEAT_ADDRESS 1193
#define IDC_LABEL_UP14 1193 #define IDC_LABEL_UP14 1193
#define IDC_LABEL_CHEAT_BYTE 1194
#define IDC_LABEL_UP15 1194 #define IDC_LABEL_UP15 1194
#define IDC_LABEL_SERVERADDY 1195 #define IDC_LABEL_SERVERADDY 1195
#define IDC_LABEL_UP16 1195 #define IDC_LABEL_UP16 1195
@ -368,6 +364,7 @@
#define IDC_SHADER_HLSL_BROWSE 3016 #define IDC_SHADER_HLSL_BROWSE 3016
#define IDC_SHADER_GROUP 3017 #define IDC_SHADER_GROUP 3017
#define IDC_SHADER_GLSL_BROWSE 3018 #define IDC_SHADER_GLSL_BROWSE 3018
#define IDC_CHEAT_SYNTAX 3018
#define IDC_RAMLIST 5000 #define IDC_RAMLIST 5000
//#define IDC_C_SEARCH 5001 //#define IDC_C_SEARCH 5001
#define IDC_C_ADDCHEAT 5002 #define IDC_C_ADDCHEAT 5002
@ -578,7 +575,7 @@
#ifndef APSTUDIO_READONLY_SYMBOLS #ifndef APSTUDIO_READONLY_SYMBOLS
#define _APS_NEXT_RESOURCE_VALUE 151 #define _APS_NEXT_RESOURCE_VALUE 151
#define _APS_NEXT_COMMAND_VALUE 40175 #define _APS_NEXT_COMMAND_VALUE 40175
#define _APS_NEXT_CONTROL_VALUE 3018 #define _APS_NEXT_CONTROL_VALUE 3019
#define _APS_NEXT_SYMED_VALUE 101 #define _APS_NEXT_SYMED_VALUE 101
#endif #endif
#endif #endif

View File

@ -50,7 +50,7 @@ BEGIN
VK_BACK, ID_WINDOW_STRETCH, VIRTKEY, ALT, NOINVERT VK_BACK, ID_WINDOW_STRETCH, VIRTKEY, ALT, NOINVERT
END END
IDR_RWACCELERATOR ACCELERATORS IDR_RWACCELERATOR ACCELERATORS
BEGIN BEGIN
"N", RAMMENU_FILE_NEW, VIRTKEY, CONTROL "N", RAMMENU_FILE_NEW, VIRTKEY, CONTROL
"O", RAMMENU_FILE_OPEN, VIRTKEY, CONTROL "O", RAMMENU_FILE_OPEN, VIRTKEY, CONTROL
@ -248,26 +248,28 @@ BEGIN
CONTROL "VSync",IDC_VSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,102,37,10 CONTROL "VSync",IDC_VSYNC,"Button",BS_AUTOCHECKBOX | WS_TABSTOP,11,102,37,10
END END
IDD_CHEATER DIALOGEX 0, 0, 262, 218 IDD_CHEATER DIALOGEX 0, 0, 320, 240
STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU
CAPTION "Cheat Entry and Editor" CAPTION "Cheat Entry and Editor"
FONT 8, "MS Sans Serif", 0, 0, 0x1 FONT 8, "MS Shell Dlg", 400, 0, 0x1
BEGIN BEGIN
CONTROL "List1",IDC_CHEAT_LIST,"SysListView32",LVS_REPORT | LVS_SINGLESEL | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,5,5,200,125,WS_EX_CLIENTEDGE CONTROL "List1",IDC_CHEAT_LIST,"SysListView32",LVS_REPORT | LVS_SHOWSELALWAYS | LVS_NOSORTHEADER | WS_BORDER | WS_TABSTOP,5,5,260,125,WS_EX_CLIENTEDGE
PUSHBUTTON "&Add",IDC_ADD_CHEAT,215,5,40,15,WS_DISABLED PUSHBUTTON "&Add",IDC_ADD_CHEAT,273,5,40,15,WS_DISABLED
PUSHBUTTON "&Delete",IDC_DELETE_CHEAT,215,25,40,15,WS_DISABLED PUSHBUTTON "&Delete",IDC_DELETE_CHEAT,273,25,40,15,WS_DISABLED
PUSHBUTTON "&Update",IDC_UPDATE_CHEAT,215,45,40,15,WS_DISABLED PUSHBUTTON "&Update",IDC_UPDATE_CHEAT,273,45,40,15,WS_DISABLED
PUSHBUTTON "C&lear",IDC_CLEAR_CHEATS,215,65,40,15 EDITTEXT IDC_CHEAT_CODE,85,134,179,15,ES_UPPERCASE | ES_AUTOHSCROLL
EDITTEXT IDC_CHEAT_CODE,86,134,118,15,ES_UPPERCASE | ES_AUTOHSCROLL EDITTEXT IDC_CHEAT_NAME,85,154,179,15,ES_AUTOHSCROLL
EDITTEXT IDC_CHEAT_DESCRIPTION,85,154,119,15,ES_AUTOHSCROLL PUSHBUTTON "C&lear",IDC_CLEAR_CHEATS,268,154,40,15
EDITTEXT IDC_CHEAT_ADDRESS,85,175,44,15,ES_UPPERCASE | ES_AUTOHSCROLL PUSHBUTTON "Syntax",IDC_CHEAT_SYNTAX,268,133,40,15
EDITTEXT IDC_CHEAT_BYTE,215,175,26,15,ES_UPPERCASE | ES_AUTOHSCROLL EDITTEXT IDC_CHEAT_DEC,85,189,53,15,ES_UPPERCASE | ES_AUTOHSCROLL
PUSHBUTTON "&OK",IDOK,93,196,50,15 EDITTEXT IDC_CHEAT_HEX,195,189,45,15,ES_UPPERCASE | ES_AUTOHSCROLL
PUSHBUTTON "&Cancel",IDCANCEL,151,196,50,15 PUSHBUTTON "&OK",IDOK,106,218,50,15
RTEXT "Enter Cheat Code:",IDC_LABEL_CHEAT_CODE,23,134,59,15,SS_CENTERIMAGE PUSHBUTTON "&Cancel",IDCANCEL,164,218,50,15
RTEXT "Cheat Description",IDC_LABEL_CHEAT_DESCRIPTION,19,154,61,15,SS_CENTERIMAGE RTEXT "Cheat Code:",IDC_STATIC,22,134,59,15,SS_CENTERIMAGE
RTEXT "Cheat Address (hex)",IDC_LABEL_CHEAT_ADDRESS,18,175,64,15,SS_CENTERIMAGE RTEXT "Cheat Description:",IDC_STATIC,20,154,61,15,SS_CENTERIMAGE
RTEXT "New Value (dec or hex)",IDC_LABEL_CHEAT_BYTE,134,175,74,15,SS_CENTERIMAGE RTEXT "decimal",IDC_STATIC,52,189,30,15,SS_CENTERIMAGE
RTEXT "hexadecimal",IDC_STATIC,143,189,45,15,SS_CENTERIMAGE
GROUPBOX "Radix Converter",IDC_STATIC,29,177,235,36,0,WS_EX_TRANSPARENT
END END
IDD_NETPLAYPROGRESS DIALOG 0, 0, 186, 61 IDD_NETPLAYPROGRESS DIALOG 0, 0, 186, 61
@ -375,8 +377,8 @@ BEGIN
PUSHBUTTON "&OK",IDOK,85,123,45,13 PUSHBUTTON "&OK",IDOK,85,123,45,13
PUSHBUTTON "&Cancel",IDCANCEL,135,123,45,13 PUSHBUTTON "&Cancel",IDCANCEL,135,123,45,13
EDITTEXT IDC_NC_ADDRESS,79,7,101,12,ES_AUTOHSCROLL EDITTEXT IDC_NC_ADDRESS,79,7,101,12,ES_AUTOHSCROLL
EDITTEXT IDC_NC_CURRVAL,79,31,101,12,ES_AUTOHSCROLL EDITTEXT IDC_NC_CURRVAL,79,31,101,12,ES_AUTOHSCROLL | ES_READONLY
EDITTEXT IDC_NC_PREVVAL,79,55,101,12,ES_AUTOHSCROLL EDITTEXT IDC_NC_PREVVAL,79,55,101,12,ES_AUTOHSCROLL | ES_READONLY
EDITTEXT IDC_NC_NEWVAL,79,79,101,12,ES_AUTOHSCROLL EDITTEXT IDC_NC_NEWVAL,79,79,101,12,ES_AUTOHSCROLL
EDITTEXT IDC_NC_DESC,79,103,101,12,ES_AUTOHSCROLL EDITTEXT IDC_NC_DESC,79,103,101,12,ES_AUTOHSCROLL
RTEXT "Address",IDC_STATIC,7,7,70,12,SS_CENTERIMAGE RTEXT "Address",IDC_STATIC,7,7,70,12,SS_CENTERIMAGE
@ -687,7 +689,7 @@ BEGIN
PUSHBUTTON "&Cancel",IDCANCEL,120,80,50,14 PUSHBUTTON "&Cancel",IDCANCEL,120,80,50,14
END END
IDD_PROMPT DIALOG 0, 0, 186, 68 IDD_PROMPT DIALOG 0, 0, 186, 68
STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU STYLE DS_SETFONT | DS_MODALFRAME | DS_3DLOOK | DS_FIXEDSYS | DS_CENTER | WS_POPUP | WS_VISIBLE | WS_CAPTION | WS_SYSMENU
CAPTION "Input Prompt" CAPTION "Input Prompt"
FONT 8, "Ms Shell Dlg 2" FONT 8, "Ms Shell Dlg 2"
@ -790,9 +792,9 @@ BEGIN
IDD_CHEATER, DIALOG IDD_CHEATER, DIALOG
BEGIN BEGIN
LEFTMARGIN, 7 LEFTMARGIN, 7
RIGHTMARGIN, 255 RIGHTMARGIN, 313
TOPMARGIN, 7 TOPMARGIN, 7
BOTTOMMARGIN, 211 BOTTOMMARGIN, 233
END END
IDD_NETPLAYPROGRESS, DIALOG IDD_NETPLAYPROGRESS, DIALOG
@ -1139,7 +1141,7 @@ BEGIN
END END
END END
RAMWATCH_MENU MENU RAMWATCH_MENU MENU
BEGIN BEGIN
POPUP "File" POPUP "File"
BEGIN BEGIN

View File

@ -534,6 +534,8 @@ Nintendo is a trade mark.")
#define SEARCH_COLUMN_ADDRESS TEXT("Address") #define SEARCH_COLUMN_ADDRESS TEXT("Address")
#define SEARCH_COLUMN_VALUE TEXT("Value") #define SEARCH_COLUMN_VALUE TEXT("Value")
#define SEARCH_COLUMN_DESCRIPTION TEXT("Description") #define SEARCH_COLUMN_DESCRIPTION TEXT("Description")
#define CHEAT_COLUMN_CODE TEXT("Code")
#define CHEAT_COLUMN_DESCRIPTION TEXT("Description")
// ROM dialog // ROM dialog

File diff suppressed because it is too large Load Diff

View File

@ -224,6 +224,22 @@
#define _tFromAnsi #define _tFromAnsi
#endif #endif
#include <string>
#include <sstream>
namespace std {
#ifndef tstring
#ifdef UNICODE
typedef wstring tstring;
typedef wstringbuf tstringbuf;
typedef wstringstream tstringstream;
#else
typedef string tstring;
typedef stringbuf tstringbuf;
typedef stringstream tstringstream;
#endif
#endif
}
/****************************************************************************/ /****************************************************************************/
inline static void Log (const char *str) inline static void Log (const char *str)
{ {