📄 fileman.cpp
字号:
return false;
}
i += 10;
debug0 ("i+10");
}
if (strlen (patchspec) - i != 9)
return false;
return n;
}
int createpatch (char *patchspec, char *desc, boolean gui)
{ // Patch is created in curgs rom setting
// Patchspec will be converted to uppercase and have spaces removed.
// Returns -1 if the patchspec is invalid or out of memory
// NULL description accepted.
struct cheatpatchset *cheat;
byte value;
dword addr;
int howmany, x;
if (curgs->patches >= MAXPATCHSETS) {
addmessage ("Exceeded maximum of %d cheat entries!", MAXPATCHSETS);
}
//debug0 ("Createpatch entered.");
if ((howmany = verifyspecformat (patchspec)) == false)
return -1;
//debug0 ("Howmany: %d", howmany);
if ((curgs->cheat[curgs->patches] = (struct cheatpatchset *) malloc (sizeof (struct cheatpatchset))) == NULL ||\
(curgs->cheat[curgs->patches]->patch = (struct cheatpatch *) malloc (sizeof (struct cheatpatch) * howmany)) == NULL) {
if (gui) addmessage ("OUT OF MEMORY!");
else printf ("OUT OF MEMORY!");
return -1;
}
if (desc != NULL)
if ((curgs->cheat[curgs->patches]->desc = (char *) malloc (strlen (desc) + 1)) == NULL) {
if (gui) addmessage ("OUT OF MEMORY!");
else printf ("OUT OF MEMORY!");
return -1;
} else {
strcpy (curgs->cheat[curgs->patches]->desc, desc);
}
else
curgs->cheat[curgs->patches]->desc = NULL;
//debug0 ("desc:%P curgs->cheat[curgs->patches]->desc %P", desc, curgs->cheat[curgs->patches]->desc);
cheat = curgs->cheat[curgs->patches];
for (x = 0; x < howmany; x++) {
if (patchspec[4] == '-') {
//debug0 ("%d Game Genie!", x);
getggmeaning (patchspec, value, addr);
//debug0 ("Value:%d addr:%X", value, addr);
cheat->patch[x].wordsized = false;
//debug0 ("curgs->cheat[curgs->patches]->patch[0].wordsized %d", curgs->cheat[curgs->patches]->patch[0].wordsized);
cheat->patch[x].newval = value;
cheat->patch[x].prevval = *SNESMEM (addr);
patchspec += 10;
} else {
//debug0 ("%d Raw patch!", x);
addr = (hexton(patchspec[0]) << 20) + (hexton(patchspec[1]) << 16) + \
(hexton(patchspec[2]) << 12) + (hexton(patchspec[3]) << 8) + \
(hexton(patchspec[4]) << 4) + hexton(patchspec[5]);
if (ishexd(patchspec[9]) && ishexd(patchspec[10])) {
//debug0 ("Word patch detected!", x);
cheat->patch[x].newval = \
(hexton(patchspec[7]) << 12) + (hexton(patchspec[8]) << 8) + \
(hexton(patchspec[9]) << 4) + hexton(patchspec[10]);
cheat->patch[x].wordsized = true;
patchspec += 12;
} else {
cheat->patch[x].newval = \
(hexton(patchspec[7]) << 4) + hexton(patchspec[8]);
cheat->patch[x].wordsized = false;
patchspec += 10;
}
}
cheat->patch[x].bank = addr >> 16;
cheat->patch[x].addr = addr & 0xFFFF;
}
// debug0 ("curgs->patches = %d curgs->cheat[curgs->patches]->patch[0].wordsized %d",curgs->patches, curgs->cheat[curgs->patches]->patch[0].wordsized);
//debug0 ("curgs->cheat[curgs->patches]->desc %P", curgs->cheat[curgs->patches]->desc);
curgs->patches++;
cheat->addrs = howmany;
cheat->enabled = false;
return curgs->patches - 1;
}
void deletepatch (int n)
{
int x;
assert (n < curgs->patches);
free (curgs->cheat[n]->desc);
free (curgs->cheat[n]->patch);
free (curgs->cheat[n]);
curgs->patches--;
for (x = n; x < curgs->patches; x++) {
curgs->cheat[x] = curgs->cheat[x+1];
}
}
static byte gghex [16] = {
13, 15, 4, 7, 0, 9, 1, 5, 6, 11, 12, 8, 10, 2, 3, 14
};
static byte ggaddrmap [24] = {
'i','j','k','l','q','r','s','t',
'o','p','a','b','c','d','u','v',
'w','x','e','f','g','h','m','n'
};
void getggmeaning (char *strcode, byte &value, dword &addr)
{ // strcode will be converted to uppercase. It MUST be in the format xxxx-xxxx.
int x;
dword code, code2;
strupr (strcode);
code = (gghex [hexton (strcode[0])] << 28);
code |= (gghex [hexton (strcode[1])] << 24);
code |= (gghex [hexton (strcode[2])] << 20);
code |= (gghex [hexton (strcode[3])] << 16);
code |= (gghex [hexton (strcode[5])] << 12);
code |= (gghex [hexton (strcode[6])] << 8);
code |= (gghex [hexton (strcode[7])] << 4);
code |= gghex [hexton (strcode[8])];
debug0 ("Code:%X", code);
code2 = 0;
for (x = 0; x < 24; x++) {
code2 |= ((code >> x) & 1) << ('x' - ggaddrmap [23-x]);
}
value = code >> 24;
addr = code2 & 0x00FFFFFF;
}
int reversegghex (byte n)
{
int y;
for (y = 0; y < 16; y++)
if (gghex[y] == n)
return y;
debug0 ("ERROR TRANSLATING TO GG CODE (n=%d)", n);
return 0;
}
char *getggcode (byte value, dword addr)
{
static char codestr [10];
dword code, code2;
int x, y;
code = (value << 24) + addr;
code2 = value << 24;
for (x = 0; x < 24; x++) {
code2 |= ((code >> ('x' - ggaddrmap [23-x])) & 1) << x;
}
y = reversegghex ((code2 >> 28) & 15); codestr [0] = ntohex (y);
y = reversegghex ((code2 >> 24) & 15); codestr [1] = ntohex (y);
y = reversegghex ((code2 >> 20) & 15); codestr [2] = ntohex (y);
y = reversegghex ((code2 >> 16) & 15); codestr [3] = ntohex (y);
y = reversegghex ((code2 >> 12) & 15); codestr [5] = ntohex (y);
y = reversegghex ((code2 >> 8) & 15); codestr [6] = ntohex (y);
y = reversegghex ((code2 >> 4) & 15); codestr [7] = ntohex (y);
y = reversegghex (code2 & 15); codestr [8] = ntohex (y);
codestr [4] = '-';
codestr [9] = '\0';
return codestr;
}
char *getpatchname (int pn, boolean ggformat)
{ // Patch is returned in a STATIC char buffer.
static char s [80];
struct cheatpatch *c = curgs->cheat[pn]->patch;
int y, p;
if (pn >= curgs->patches) {
s[0] = '\0'; return s;
}
if (ggformat) {
for (y = 0, p = 0; y < curgs->cheat[pn]->addrs; y++) {
if (c[y].wordsized) {
strcpy (s + p, getggcode (c[y].newval >> 8, (c[y].bank << 16) + c[y].addr + 1));
s [p + 9] = '+';
p += 10;
}
strcpy (s + p, getggcode (c[y].newval, (c[y].bank << 16) + c[y].addr));
s [p + 9] = '+';
p += 10;
}
s[p-1] = '\0';
} else {
for (y = 0, p = 0; y < curgs->cheat[pn]->addrs; y++) {
debug0 ("Starting #%d",y);
s[p++] = ntohex (c[y].bank >> 4);
s[p++] = ntohex ((c[y].bank) & 15);
s[p++] = ntohex (c[y].addr >> 12);
s[p++] = ntohex ((c[y].addr >> 8) & 15);
s[p++] = ntohex ((c[y].addr >> 4) & 15);
s[p++] = ntohex (c[y].addr & 15);
s[p++] = '=';
if (c[y].wordsized) {
s[p++] = ntohex (c[y].newval >> 12);
s[p++] = ntohex ((c[y].newval >> 8) & 15);
}
s[p++] = ntohex ((c[y].newval >> 4) & 15);
s[p++] = ntohex (c[y].newval & 15);
s[p] = '+';
if (y != curgs->cheat[pn]->addrs - 1)
p++;
}
s[p] = '\0';
}
debug0 ("Done!");
return s;
}
int findgsnum (char *filename)
{
int y, sp, cp;
sp = findlastch (filename, SLASH) + 1;
cp = findlastch (filename, ':') + 1;
if (cp > sp) sp = cp;
for (y = 0; y < gsentries; y++) {
if (stricmp (filename + sp, gs[y]->filename) == 0) {
return y;
}
}
return 0; // Not found/default
}
void createromentry (char *filename)
{
int y, sp, cp;
sp = findlastch (filename, SLASH) + 1;
cp = findlastch (filename, ':') + 1;
if (cp > sp) sp = cp;
debug0 ("createromentry %s", filename + sp);
y = findgsnum (filename);
if (y != 0 || (y == 0 && stricmp (filename + sp, "[Defaults]") == 0)) {
curgsnum = y;
curgs = gs[y];
debug0 ("found existing entry");
return;
} else
y = gsentries;
gsentries++;
debug0 ("making new entry %d (y=%d)", gsentries, y);
gs [y] = (struct gamesettings *) malloc (sizeof (struct gamesettings));
curgsnum = y;
curgs = gs[y];
memcpy (gs[y], gs[0], sizeof (struct gamesettings)); // Load default values
strcpy (gs[y]->filename, filename + sp);
}
static int lline;
void loadline (FILE *fp, char *l)
{
int x;
boolean inquote;
do {
inquote = false;
for (x = 0; x < 100; x++) {
l [x] = fgetc (fp);
if (l [x] == '"')
inquote = !inquote;
if (l [x] == ';' && !inquote)
l [x] = '\0';
if (l [x] == '\n' || feof (fp)) {
l [x] = '\0';
lline++;
break;
}
}
trimspace (l);
} while (l [0] == '\0' && !feof (fp));
//debug0 ("line loaded: %s len: %d", l, strlen (l));
}
void loadsettings (char *filename)
{
FILE *fp;
byte *addr = NULL;
char full[80], l[100], utag[10];
int x, t, ep, prevgsnum = curgsnum;
int curjoy = 0, curwin = 0, curcheat = 0;
boolean inquote;
strcpy (full, filename);
getabspath (full);
printf ("Loading configuration file: %s\n", full);
debug0 ("Loading configuration file: %s (saved curgsnum: %d)", full, curgsnum);
lline = 0;
for (x = 1; x < NUMWINDOWS; x++)
win[x]->zorder = -1; // Make sure windows are closed by default...
storewinsettings (); // get defaults in case config file doesn't load it
if ((fp = fopen (full, "rt")) == NULL) {
debug0 ("Error opening config file (%s) to load!", full);
printf ("Error opening config file (%s) to load!\nOperation aborted.", full);
sleep (1);
return;
}
printf ("Opened successfully\n");
do {
loadline (fp, l);
for (inquote = 0, x = 0; l [x] != '\0'; x++) {
if (l [x] == '"')
inquote = !inquote;
if (!inquote)
l [x] = toupper (l [x]);
}
if (l[0] == '\0')
continue;
if (l[0] == 'N' && l[1] == 'E' && l[2] == 'W' && l[3] == ' ') {
delstr (l, 0, 4);
trimspace (l);
ep = findfirstch (l, ' ');
if (ep < 0) ep = 0;
l[ep] = '\0';
ep++;
trimspace (l + ep);
if (strcmp (l, "ROM") == 0) {
if (l[ep] != '"' || l[ep + strlen(l + ep) - 1] != '"') {
printf ("Warning! Line %d: Missing or misplaced quote mark(s) - Ignoring\n", lline);
printf (" Note! ROM file spec was: %s\n", l + ep);
} else {
delstr (l + ep, 0, 1);
delstr (l + ep, strlen(l + ep) - 1, 1);
createromentry (l + ep);
}
} else if (strcmp (l, "JOYPAD") == 0) {
curjoy = atoi (l + ep);
//debug0 ("New Joypad %d", curjoy);
} else if (strcmp (l, "WINDOW") == 0) {
curwin = atoi (l + ep);
//debug0 ("New Window %d", curwin);
} else if (strcmp (l, "CHEAT") == 0) {
if (toupper(l[ep]) == 'O' && toupper(l[ep+1]) == 'N') {
ep += 3;
x = true;
} else
x = false;
// Create new cheat code...
curcheat = createpatch (l + ep, NULL, false);
if (curcheat == -1) {
printf ("Error in cheat code format! Cheat patch not created.");
fflush (stdout);
} else {
curgs->cheat[curcheat]->enabled = x;
//debug0 ("New Cheat %d %s", curcheat, l+ep);
//debug0 ("curcheat%d curgs->patches = %d curgs->cheat[curgs->patches-1]->patch[0].wordsized %d",curcheat,curgs->patches, curgs->cheat[curgs->patches-1]->patch[0].wordsized);
//debug0 ("curgs->patches:%d Addrs:%d enabled:%d [0].wordsized:%d [0].bank %X [0].addr %X [0].newval %X desc%P",
// curgs->patches, curgs->cheat[curcheat]->addrs, curgs->cheat[curcheat]->enabled,
// curgs->cheat[curcheat]->patch[0].wordsized, curgs->cheat[curcheat]->patch[0].bank,
// curgs->cheat[curcheat]->patch[0].addr, curgs->cheat[curcheat]->patch[0].newval, curgs->cheat[curcheat]->desc);
}
} else {
printf ("Warning! Line %d: Unrecognised or missing NEW spec - Ignoring\n", lline);
printf (" Note! NEW spec was: \"%s\"\n", l);
}
} else if ((ep = findfirstch (l, '=')) > 0) {
l[ep] = '\0';
ep++;
//debug0 ("Var tag: %s Equals: %s", l, l+ep);
// Search for variable tag in fm array
for (t = 0; t < FTAGS; t++) {
strcpy (utag, fm [t].tag);
strupr (utag);
if (strcmp (utag, l) == 0)
break;
}
if (t >= FTAGS) {
printf ("Warning! Line %d: Unrecognised variable - Ignoring\n", lline);
printf (" Note! Variable was: %s\n", l);
} else {
//debug0("fm [t].datatype %d name %s (%d)", fm [t].datatype, l, FSTRINGALLOC);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -