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)
{
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.");
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];
int i;
bool8 sram;
if (strlen(code) != 14)
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)
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++)
{
unsigned int byte;
@ -259,7 +280,6 @@ const char * S9xGoldFingerToRaw (const char *code, uint32 &address, bool8 &sram,
}
num_bytes = i;
sram = code[13] == '1';
return (NULL);
}

View File

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

View File

@ -180,6 +180,10 @@
#include "memmap.h"
#include "cheats.h"
#include <string>
#include <sstream>
#include <algorithm>
uint8 S9xGetByteFree (uint32);
void S9xSetByteFree (uint8, uint32);
@ -223,69 +227,151 @@ void S9xInitCheatData (void)
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;
Cheat.c[Cheat.num_cheats].byte = byte;
Cheat.c[Cheat.num_cheats].enabled = enable;
if (save_current_value)
uint32 address;
uint8 byte;
if (S9xProActionReplayToRaw(code.c_str(), address, byte) != NULL &&
S9xGameGenieToRaw(code.c_str(), address, byte) != NULL)
{
Cheat.c[Cheat.num_cheats].saved_byte = S9xGetByteFree(address);
Cheat.c[Cheat.num_cheats].saved = TRUE;
}
uint8 bytes[3];
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)
{
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)
S9xRemoveCheat(which1);
memmove(&Cheat.c[which1], &Cheat.c[which1 + 1], sizeof(Cheat.c[0]) * (Cheat.num_cheats - which1 - 1));
Cheat.num_cheats--;
Cheat.c.erase(iter);
}
}
void S9xDeleteCheats (void)
{
S9xRemoveCheats();
Cheat.num_cheats = 0;
Cheat.c.clear();
}
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;
uint8 *ptr = Memory.Map[block];
int block = (address & 0xffffff) >> MEMMAP_SHIFT;
uint8 *ptr = Memory.Map[block];
if (ptr >= (uint8 *) CMemory::MAP_LAST)
*(ptr + (address & 0xffff)) = Cheat.c[which1].saved_byte;
else
S9xSetByteFree(Cheat.c[which1].saved_byte, address);
if (ptr >= (uint8 *) CMemory::MAP_LAST)
*(ptr + (address & 0xffff)) = c.saved_byte;
else
S9xSetByteFree(c.saved_byte, address);
}
iter++;
}
}
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)
S9xRemoveCheat(i);
}
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;
S9xApplyCheat(which1);
@ -294,62 +380,222 @@ void S9xEnableCheat (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);
Cheat.c[which1].enabled = FALSE;
}
}
void S9xApplyCheat (uint32 which1)
void S9xApplyCheat (uint32 which1, bool8 force_save_current_value)
{
uint32 address = Cheat.c[which1].address;
if (!Cheat.c[which1].saved)
std::vector<SCheat>::iterator iter = Cheat.c[which1].c.begin();
while (iter != Cheat.c[which1].c.end())
{
Cheat.c[which1].saved_byte = S9xGetByteFree(address);
Cheat.c[which1].saved = TRUE;
SCheat& c = *iter;
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)
{
for (uint32 i = 0; i < Cheat.num_cheats; i++)
for (uint32 i = 0; i < Cheat.c.size(); i++)
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;
uint8 data[28];
Cheat.num_cheats = 0;
fs = fopen(filename, "rb");
if (!fs)
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;
Cheat.c[Cheat.num_cheats].byte = data[1];
Cheat.c[Cheat.num_cheats].address = data[2] | (data[3] << 8) | (data[4] << 16);
Cheat.c[Cheat.num_cheats].saved_byte = data[5];
Cheat.c[Cheat.num_cheats].saved = (data[0] & 8) != 0;
memmove(Cheat.c[Cheat.num_cheats].name, &data[8], 20);
Cheat.c[Cheat.num_cheats++].name[20] = 0;
data[strlen(data) - 1] = '\0'; // erase newline
std::vector<std::string> v = csv_split(std::string(data));
if (v.size() != 3) {
fclose(fs);
return (FALSE);
}
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);
@ -357,46 +603,83 @@ bool8 S9xLoadCheatFile (const char *filename)
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)
{
if (Cheat.num_cheats == 0)
if (Cheat.c.size() == 0)
{
remove(filename);
return (TRUE);
}
FILE *fs;
uint8 data[28];
fs = fopen(filename, "wb");
fs = fopen(filename, "w");
if (!fs)
return (FALSE);
for (uint32 i = 0; i < Cheat.num_cheats; i++)
for (uint32 i = 0; i < Cheat.c.size(); i++)
{
memset(data, 0, 28);
if (i == 0)
{
data[6] = 254;
data[7] = 252;
}
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)
struct SCheatItem& c = Cheat.c[i];
std::vector<std::string> v;
v.push_back(c.enabled ? "enabled" : "disabled");
v.push_back(c.code);
v.push_back(c.name);
if (fprintf(fs, "%s\n", csv_join(v, true).c_str()) < 0)
{
fclose(fs);
return (FALSE);

View File

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

View File

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

View File

@ -788,11 +788,10 @@ char * S9xParseArgs (char **argv, int argc)
{
uint32 address;
uint8 bytes[3];
bool8 sram;
uint8 num_bytes;
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++)
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.saved_val = rswatches[watchIndex].CurValue;
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))
{
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);
}
}
DialogBoxParam(hInst, MAKEINTRESOURCE(IDD_CHEAT_FROM_SEARCH), hDlg, DlgCheatSearchAdd, (LPARAM)&cht);
}
}
break;

View File

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

View File

@ -50,7 +50,7 @@ BEGIN
VK_BACK, ID_WINDOW_STRETCH, VIRTKEY, ALT, NOINVERT
END
IDR_RWACCELERATOR ACCELERATORS
IDR_RWACCELERATOR ACCELERATORS
BEGIN
"N", RAMMENU_FILE_NEW, 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
END
IDD_CHEATER DIALOGEX 0, 0, 262, 218
STYLE DS_SETFONT | DS_MODALFRAME | DS_SETFOREGROUND | DS_3DLOOK | DS_CENTER | WS_MINIMIZEBOX | WS_POPUP | WS_VISIBLE | WS_CLIPCHILDREN | WS_CAPTION | WS_SYSMENU
IDD_CHEATER DIALOGEX 0, 0, 320, 240
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"
FONT 8, "MS Sans Serif", 0, 0, 0x1
FONT 8, "MS Shell Dlg", 400, 0, 0x1
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
PUSHBUTTON "&Add",IDC_ADD_CHEAT,215,5,40,15,WS_DISABLED
PUSHBUTTON "&Delete",IDC_DELETE_CHEAT,215,25,40,15,WS_DISABLED
PUSHBUTTON "&Update",IDC_UPDATE_CHEAT,215,45,40,15,WS_DISABLED
PUSHBUTTON "C&lear",IDC_CLEAR_CHEATS,215,65,40,15
EDITTEXT IDC_CHEAT_CODE,86,134,118,15,ES_UPPERCASE | ES_AUTOHSCROLL
EDITTEXT IDC_CHEAT_DESCRIPTION,85,154,119,15,ES_AUTOHSCROLL
EDITTEXT IDC_CHEAT_ADDRESS,85,175,44,15,ES_UPPERCASE | ES_AUTOHSCROLL
EDITTEXT IDC_CHEAT_BYTE,215,175,26,15,ES_UPPERCASE | ES_AUTOHSCROLL
PUSHBUTTON "&OK",IDOK,93,196,50,15
PUSHBUTTON "&Cancel",IDCANCEL,151,196,50,15
RTEXT "Enter Cheat Code:",IDC_LABEL_CHEAT_CODE,23,134,59,15,SS_CENTERIMAGE
RTEXT "Cheat Description",IDC_LABEL_CHEAT_DESCRIPTION,19,154,61,15,SS_CENTERIMAGE
RTEXT "Cheat Address (hex)",IDC_LABEL_CHEAT_ADDRESS,18,175,64,15,SS_CENTERIMAGE
RTEXT "New Value (dec or hex)",IDC_LABEL_CHEAT_BYTE,134,175,74,15,SS_CENTERIMAGE
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,273,5,40,15,WS_DISABLED
PUSHBUTTON "&Delete",IDC_DELETE_CHEAT,273,25,40,15,WS_DISABLED
PUSHBUTTON "&Update",IDC_UPDATE_CHEAT,273,45,40,15,WS_DISABLED
EDITTEXT IDC_CHEAT_CODE,85,134,179,15,ES_UPPERCASE | ES_AUTOHSCROLL
EDITTEXT IDC_CHEAT_NAME,85,154,179,15,ES_AUTOHSCROLL
PUSHBUTTON "C&lear",IDC_CLEAR_CHEATS,268,154,40,15
PUSHBUTTON "Syntax",IDC_CHEAT_SYNTAX,268,133,40,15
EDITTEXT IDC_CHEAT_DEC,85,189,53,15,ES_UPPERCASE | ES_AUTOHSCROLL
EDITTEXT IDC_CHEAT_HEX,195,189,45,15,ES_UPPERCASE | ES_AUTOHSCROLL
PUSHBUTTON "&OK",IDOK,106,218,50,15
PUSHBUTTON "&Cancel",IDCANCEL,164,218,50,15
RTEXT "Cheat Code:",IDC_STATIC,22,134,59,15,SS_CENTERIMAGE
RTEXT "Cheat Description:",IDC_STATIC,20,154,61,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
IDD_NETPLAYPROGRESS DIALOG 0, 0, 186, 61
@ -375,8 +377,8 @@ BEGIN
PUSHBUTTON "&OK",IDOK,85,123,45,13
PUSHBUTTON "&Cancel",IDCANCEL,135,123,45,13
EDITTEXT IDC_NC_ADDRESS,79,7,101,12,ES_AUTOHSCROLL
EDITTEXT IDC_NC_CURRVAL,79,31,101,12,ES_AUTOHSCROLL
EDITTEXT IDC_NC_PREVVAL,79,55,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 | ES_READONLY
EDITTEXT IDC_NC_NEWVAL,79,79,101,12,ES_AUTOHSCROLL
EDITTEXT IDC_NC_DESC,79,103,101,12,ES_AUTOHSCROLL
RTEXT "Address",IDC_STATIC,7,7,70,12,SS_CENTERIMAGE
@ -687,7 +689,7 @@ BEGIN
PUSHBUTTON "&Cancel",IDCANCEL,120,80,50,14
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
CAPTION "Input Prompt"
FONT 8, "Ms Shell Dlg 2"
@ -790,9 +792,9 @@ BEGIN
IDD_CHEATER, DIALOG
BEGIN
LEFTMARGIN, 7
RIGHTMARGIN, 255
RIGHTMARGIN, 313
TOPMARGIN, 7
BOTTOMMARGIN, 211
BOTTOMMARGIN, 233
END
IDD_NETPLAYPROGRESS, DIALOG
@ -1139,7 +1141,7 @@ BEGIN
END
END
RAMWATCH_MENU MENU
RAMWATCH_MENU MENU
BEGIN
POPUP "File"
BEGIN

View File

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

File diff suppressed because it is too large Load Diff

View File

@ -224,6 +224,22 @@
#define _tFromAnsi
#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)
{