⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gui.cpp

📁 SNES game emulator. C and asm files.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
	{	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 + -