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

📄 fileman.cpp

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