📄 gui.cpp
字号:
{ TEXT, { "\x1E 000000 matches (Showing first 0).123456789012345678901234567890123456789","","","","","" },
{ 5,0,0,0,0,0 }, { 168,0,0,0,0,0 }, 0, 0,
1, 0, 0, 0, false
},
};
void fillcodelist (struct guicontrol &c, boolean ggformat)
{
struct listboxinfo *l;
int y, temp;
temp = c.choice;
debug0 ("Initting code list");
initlistbox (c);
l = (struct listboxinfo *) c.text[4];
l->col[1].xoffset = 95;
l->col[2].xoffset = 85;
for (y = curgs->patches - 1; y >= 0; y--) {
addlistentry (c, 0);
debug0 ("Getting patch name...");
changelistentry (c, 0, 0, getpatchname (y, ggformat));
changelistentry (c, 0, 1, curgs->cheat[y]->desc);
changelistentry (c, 0, 2, curgs->cheat[y]->enabled ? "*" : " ");
}
if (temp < l->entries && temp >= 0) // Restore cheat code highlighted before
c.choice = temp;
debug0 ("Done init");
}
void updatecheatsearchlisting (int changeto, boolean changetoword = false)
{
int x, count = 0;
const static char cfoundb = 15, cnummatches = 16;
int addr[6];
for (x = 0; x < 128*1024; x++) {
if (ramcheatmarker[x >> 3] & (1 << (x & 7))) {
if (count < 6)
addr[count] = x;
count++;
}
}
for (x = 0; x < 6; x++)
sprintf (ccc[cfoundb].text[x], "");
if (count == 128*1024 || !romrunning) {
sprintf (ccc[cnummatches].text[0], "\x1E After you've finished a search, click a code button.", count, count > 6 ? 6 : count);
} else {
for (x = 0; x < 6; x++) {
if (x >= count)
break;
if (changetoword) {
sprintf (ccc[cfoundb].text[x], "%0.6X=%0.4X", 0x7E0000 + addr[x], changeto);
} else {
sprintf (ccc[cfoundb].text[x], "%0.6X=%0.2X", 0x7E0000 + addr[x], changeto);
}
}
sprintf (ccc[cnummatches].text[0], "\x1E %d matches (Showing first %d).", count, count > 6 ? 6 : count);
}
}
byte debug_ram[1024*128];
void cheatcodewindowproc (int msg, int cnum, int v1)
{
static boolean ggformat = false;
const static int clist = 1, cnewcode = 2, cdescr = 3, cadd = 4, cremove = 5, ctoggle = 6, cdformat = 7, clookfor = 9, csetto = 10, cfindall = 11, cfindnext = 12, cfindsize = 13, cfindnear = 14, cfoundb = 15, cnummatches = 16;
struct listboxinfo *l = (struct listboxinfo *) ccc[clist].text[4];
int x, lookfor, what;
debug0 ("Message %d cnum %d v1 %d", msg, cnum, v1);
switch (msg) {
case OPENWINDOW:
fillcodelist (ccc[clist], ggformat);
strcpy (cheatcodewindow.title+13, curgs->filename);
break;
case CLOSEWINDOW:
debug0 ("UnInitting code list");
uninitlistbox (ccc[clist]);
debug0 ("Done unInitting code list");
break;
case NEWGUIFRAME:
if ((guiframes & 8) == 0)
updatecheatsearchlisting (atoi (ccc[csetto].text[0]), ccc[cfindsize].choice);
break;
case CONTROLCHANGE:
if ((cnum == ctoggle || cnum == cremove || cnum == clist) && l->entries == 0)
break;
if (cnum == cdformat) {
ggformat = !ggformat;
fillcodelist (ccc[clist], ggformat);
} else if (cnum == ctoggle && ccc[clist].choice >= 0) {
togglecheat (ccc[clist].choice);
changelistentry (ccc[clist], ccc[clist].choice, 2, curgs->cheat[ccc[clist].choice]->enabled ? "*" : " ");
} else if (cnum == clist) { // Double-click
sendmessage (&cheatcodewindow, CONTROLCHANGE, ctoggle, 0);
} else if (cnum == cfindall) {
memset (ramcheatmarker, 0xFF, sizeof (ramcheatmarker));
sendmessage (&cheatcodewindow, CONTROLCHANGE, cfindnext, 0);
} else if (cnum == csetto) {
updatecheatsearchlisting (atoi (ccc[csetto].text[0]), ccc[cfindsize].choice);
} else if (cnum == cfindnext) {
addmessage ("Searching...");
showgui ();
lookfor = atoi (ccc[clookfor].text[0]);
for (x = 0; x < 1024*128; x++) {
if (ramcheatmarker[x >> 3] & (1 << (x & 7))) {
if (ccc[cfindsize].choice) // find word
what = *(word*)SNESMEM(0x7E0000 + x);
else
what = *SNESMEM(0x7E0000 + x);
if (what != lookfor && (!ccc[cfindnear].choice || what-1 != lookfor) &&\
(!ccc[cfindnear].choice || what+1 != lookfor)) {
ramcheatmarker[x >> 3] &= ~(1 << (x & 7));
}
}
}
updatecheatsearchlisting (atoi (ccc[csetto].text[0]), ccc[cfindsize].choice);
} else if (cnum == cfoundb) {
strcpy (ccc[cnewcode].text[0], ccc[cfoundb].text[v1]);
} else if (cnum == cadd) {
x = createpatch (ccc[cnewcode].text[0], ccc[cdescr].text[0], false);
if (x < 0) {
messagebox ("Add Code", "Code is not valid (or out of memory.)");
} else {
curgs->cheat[x]->enabled = true;
fillcodelist (ccc[clist], ggformat);
ccc[clist].choice = l->entries - 1;
}
} else if (cnum == cremove) {
deletepatch (ccc[clist].choice);
fillcodelist (ccc[clist], ggformat);
}
break;
case KEYCHAR:
if (v1 == 194) {
memset (ramcheatmarker, 0xFF, sizeof (ramcheatmarker));
memcpy (debug_ram, ram, 1024*128);
addmessage ("Debug search reset.");
}
if (v1 == 195 || v1 == 196) { // F9
if (v1 == 195) addmessage ("Looking for lower values than before");
else addmessage ("Looking for higher values than before");
for (x = 0; x < 1024*128; x++) {
if (ramcheatmarker[x >> 3] & (1 << (x & 7))) {
if (ccc[cfindsize].choice) { // find word
what = *(word*)(ram + x);
lookfor = *(word*)(debug_ram + x);
} else {
what = ram [x];
lookfor = debug_ram [x];
}
if (!(v1 == 195 && what < lookfor) && !(v1 == 196 && what > lookfor)) {
ramcheatmarker[x >> 3] &= ~(1 << (x & 7));
}
}
}
memcpy (debug_ram, ram, 1024*128);
}
break;
}
defwindowproc (cheatcodewindow, msg, cnum, v1);
}
struct guiwindow cheatcodewindow = {
"Cheat codes: [?]",
ccc, cheatcodewindowproc,
NUMCHEATCODECONTROLS,
true, 40, 10, 255, 180
};
struct guicontrol lc [NUMLOADCONTROLS] = {
{ LISTBOX, { NULL,NULL,NULL,NULL,NULL,NULL },
{ 5,0,0,0,0,0 }, { 15,0,0,0,0,0 }, 100, 163,
2, 0, 0, 0, false
},
{ TEXT, { "ROM mapping:","Name:","ROM Size:","File Size:","SRAM Size:","" },
{ 110,110,110,110,110,0 }, { 35,45,65,75,85,0 }, 0, 0,
5, 0, 0, 0, false
},
{ TEXT, { "FastROM:","Country #:","License #:","Version #:","Apparent","" },
{ 110,110,110,110,175,0 }, { 95,105,115,125,27,0 }, 0, 0,
5, 0, 0, 0, false
},
{ TEXT, { "XxROM","[Name]\0 89012345678901","??? MBits","????? KBytes","??? KBits","" },
{ 175,110,160,150,160,0 }, { 35,55,65,75,85,0 }, 0, 0,
5, 0, 0, 0, false
},
{ TEXT, { "Y/N","xxx","xxx","1.xxx","","" },
{ 160,160,160,160,0,0 }, { 95,105,115,125,0,0 }, 0, 0,
4, 0, 0, 0, false
},
{ INPUT, { "\0R12345678901234567890123456789012345678901234567890123456789","","","","","" }, // ROM dir
{ 80,0,0,0,0,0 }, { 182,0,0,0,0,0 }, 130, 11,
1, 0, 60, 0, false
},
{ BUTTON, { "ChDir/Open","","","","","" },
{ 110,0,0,0,0,0 }, { 15,0,0,0,0,0 }, 60, 15,
1, 0, 0, 0, false
},
{ TEXT, { "ROM Directory","","","","","" },
{ 5,0,0,0,0,0 }, { 185,0,0,0,0,0 }, 0, 0,
1, 0, 0, 0, false
},
{ RADIO, { "Autodetect type","Force HiROM","Force LoROM","","","" },
{ 110,110,110,0,0,0 }, { 135,144,153,0,0,0 }, 0, 0,
3, 0, 0, 0, false
}
};
void fillfilelist (struct guicontrol &c, char *path)
{
struct listboxinfo *l = (struct listboxinfo *) c.text[4];
unsigned y, p, temp;
unsigned original;
char temps [80];
DIR *dirp;
struct dirent *direntp;
char *ext;
l->col[1].xoffset = 55;
_dos_getdrive (&original);
for (y = 26; y > 0; y--) {
_dos_setdrive (y, &temp);
_dos_getdrive (&temp);
if (temp == y) {
addlistentry (c, 0);
temps [0] = 'A'+y-1;
temps [1] = ':';
temps [2] = '\0';
changelistentry (c, 0, 0, temps);
changelistentry (c, 0, 1, "<Drive>");
}
}
_dos_setdrive (original, &temp);
dirp = opendir (path);
if (dirp != NULL) {
p = 0;
while (1) {
direntp = readdir (dirp);
if (direntp == NULL) break;
strcpy (temps, direntp->d_name);
strupr (temps);
ext = temps + findfirstch (temps, '.') + 1;
if ((direntp->d_attr & _A_SUBDIR) != 0 ||
(ext[0] == 'S' && ext [2] == 'C' && (ext [1] == 'M' || ext [1] == 'F' || ext [1] == 'W' )) ||
(ext[0] == 'F' && ext [1] == 'I' && ext [2] == 'G') || (ext[0] == '1' && ext [1] == '\0')) {
addlistentry (c, p);
changelistentry (c, p, 0, temps);
if ((direntp->d_attr & _A_SUBDIR) != 0)
changelistentry (c, p, 1, "<Dir>");
p++;
}
}
closedir (dirp);
}
}
void loadwindowproc (int msg, int cnum, int v1)
{
const static int cfiles = 0, cromdir = 5, copen = 6, cforcerom = 8;
struct listboxinfo *l = (struct listboxinfo *) lc[cfiles].text[4];
char newpath [80], *fn;
long x;
static char curfn [20];
static struct headerdata curh;
FILE *fp;
switch (msg) {
case OPENWINDOW:
initlistbox (lc[cfiles]);
strcpy (lc[cromdir].text[0], romdir);
fillfilelist (lc[cfiles], lc[cromdir].text[0]);
if (loadwindow.y + loadwindow.h > yres) {
loadwindow.y = yres - loadwindow.h;
}
break;
case CLOSEWINDOW:
uninitlistbox (lc[cfiles]);
break;
case KEYCHAR:
if (cnum == cromdir && v1 == 13) {
strcpy (romdir, lc[cromdir].text[0]);
initlistbox (lc[cfiles]);
fillfilelist (lc[cfiles], lc[cromdir].text[0]);
}
break;
case NEWGUIFRAME:
if ((guiframes & 3) == 0) { // Update ROM info display
if (lc[cfiles].text[1][findlistentry (lc[cfiles], lc[cfiles].choice, 1)] != '<') {
lc[1].hidden = false; lc[2].hidden = false;
lc[3].hidden = false; lc[4].hidden = false;
fn = lc[cfiles].text[0] + findlistentry (lc[cfiles], lc[cfiles].choice, 0);
if (stricmp (fn, curfn) != 0) {
x = findgsnum (fn);
lc[cforcerom].choice = gs[x]->forcerom;
combinepathfile (newpath, romdir, fn);
loadromheaderdata (newpath, &curh,
lc[cforcerom].choice == 1 ? FORCEHIROM : (lc[cforcerom].choice == 2 ? FORCELOROM : 0));
fp = fopen (newpath, "rb");
fseek (fp, 0, SEEK_END);
x = ftell (fp);
fclose (fp);
sprintf (lc[3].text[3], "%d KBytes", x / 1024);
strcpy (curfn, fn);
strcpy (lc[3].text[1], curh.name);
if (curh.hirom) {
lc[3].text[0][0] = 'H'; lc[3].text[0][1] = 'i';
} else {
lc[3].text[0][0] = 'L'; lc[3].text[0][1] = 'o';
}
sprintf (lc[3].text[2], "%d MBits", curh.romsize);
sprintf (lc[3].text[4], "%d KBits", curh.sramsize);
if (curh.fastrom) {
lc[4].text[0][0] = 'Y'; lc[4].text[0][1] = 'e'; lc[4].text[0][2] = 's';
} else {
lc[4].text[0][0] = 'N'; lc[4].text[0][1] = 'o'; lc[4].text[0][2] = '\0';
}
sprintf (lc[4].text[1], "%d", curh.country);
sprintf (lc[4].text[2], "%d", curh.license);
sprintf (lc[4].text[3], "1.%d", curh.version);
}
} else {
lc[1].hidden = true; lc[2].hidden = true;
lc[3].hidden = true; lc[4].hidden = true;
}
}
break;
case CONTROLCHANGE:
if (cnum == cfiles) {
x = findlistentry (lc[cfiles], v1, 1);
if (lc[cfiles].text[1][x] == '<') { // Change directory
combinepaths (newpath, romdir, lc[cfiles].text[0] + findlistentry (lc[cfiles], v1, 0));
strcpy (romdir, newpath);
strcpy (lc[cromdir].text[0], newpath);
initlistbox (lc[cfiles]);
fillfilelist (lc[cfiles], newpath);
} else { // Load ROM
debug0 ("Before combinepathfile");
combinepathfile (newpath, romdir, lc[cfiles].text[0] + findlistentry (lc[cfiles], v1, 0));
debug0 ("Before loadrom");
debug0 ("Newpath:%s", newpath);
loadrom (newpath, true,
lc[cforcerom].choice == 1 ? FORCEHIROM : (lc[cforcerom].choice == 2 ? FORCELOROM : 0));
memset (ramcheatmarker, 0xFF, sizeof (ramcheatmarker));
updatecheatsearchlisting (0);
// Reset the cheat searcher marked memory list.
}
}
if (cnum == copen)
sendmessage (&loadwindow, CONTROLCHANGE, cfiles, lc[cfiles].choice);
if (cnum == cforcerom) {
x = findgsnum (curfn);
gs[x]->forcerom = lc[cforcerom].choice; // enforce choice made
curfn [0] = '\0'; // will cause reload of rom header data
}
break;
}
defwindowproc (loadwindow, msg, cnum, v1);
}
struct guiwindow loadwindow = {
"Load File: *.SMC;*.SFC;*.SWC;*.FIG;*.1",
lc, loadwindowproc,
NUMLOADCONTROLS,
true, 40, 10, 220, 200
};
struct guicontrol mbc [NUMMESSAGEBOXCONTROLS] = {
{ TEXT, { "\0\0123456789012345678901234567890123456789012345678901234567890","","","","","" },
{ 5,0,0,0,0,0 }, { 17,0,0,0,0,0 }, 0, 0,
1, 0, 0, 0, false
},
{ BUTTON, { "OK","","","","","" },
{ 5,0,0,0,0,0 }, { 27,0,0,0,0,0 }, 35, 15,
1, 0, 0, 0, false, false, true
},
{ SLIDER, { "MBit read","","","","","" },
{ 45,0,0,0,0,0 }, { 33,0,0,0,0,0 }, 75, 0,
0, 0, 1, 1, false
},
};
void messagebox (char *title, char *msg)
{
boolean bdown = false, prevexec = false, prevlb = false, curexec;
int x;
mbc [2].hidden = true;
mbc [1].hidden = false;
strcpy (mbc[0].text[0], msg);
strcpy (messagewindow.title, title);
showwindow (&messagewindow);
msgboxesc = false;
do {
prevexec = keydown [KEYSPACE] | keydown [KEYENTER];
prevlb = lbutton;
checkjoystick (); // In case the purpose of the message box is to calibrate the joystick.
setguisettings ();
showgui ();
curexec = keydown [KEYSPACE] | keydown [KEYENTER];
if (curexec && !prevexec)
sendmessage (&messagewindow, KEYPRESS, 1, KEYENTER);
if (!curexec && prevexec)
sendmessage (&messagewindow, KEYRELEASE, 1, KEYENTER);
if (lbutton && !prevlb)
sendmessage (&messagewindow, MOUSEPRESS, -1, 0);
if (!lbutton && prevlb)
sendmessage (&messagewindow, MOUSERELEASE, -1, 0);
if (kbhit ()) {
x = getch ();
if (x == 0)
x = getch () + 128;
sendmessage (&messagewindow, KEYCHAR, 1, x);
}
} while (messagewindow.zorder == 0);
}
void messagewindowproc (int msg, int cnum, int v1)
{
messagewindow.focus = 1; // OK button, which is invisible when loading files
switch (msg) {
case CONTROLCHANGE:
if (cnum == 1) {
killwindow (&messagewindow);
return;
}
break;
case KEYCHAR:
if (v1 == 27) {
msgboxesc = true;
killwindow (&messagewindow);
return;
}
break;
}
defwindowproc (messagewindow, msg, cnum, v1);
}
struct guiwindow messagewindow = {
"[?]",
mbc, messagewindowproc,
NUMMESSAGEBOXCONTROLS,
false, 95, 150, 180, 48
};
struct guiwindow *win [NUMWINDOWS] = {
&mainwindow,
&saveloadwindow,
&startupwindow,
&ingamewindow,
&joypadwindow,
&guisettingwindow,
&cheatcodewindow,
&loadwindow,
&messagewindow
};
/*
. 北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北北
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -