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

📄 fileman.cpp

📁 SNES game emulator. C and asm files.
💻 CPP
📖 第 1 页 / 共 3 页
字号:
/*	FILEMAN.CPP - File manager
*/

#include "Common.hpp"
#include <io.h>
#include <sys\stat.h>
#include <direct.h>
#include <i86.h>
#include <ASSERT.H>
#include "GrEngine.hpp"
#include "CPU.hpp"
#include "FileMan.hpp"
#include "GUI.hpp"
#include "SPC700.hpp"

char romdir [80] = "..", sramdir [80] = "..", instdir [80] = "", sshotdir [80] = "";
char exedir [80];

byte gameres = 1, guires = 4;
byte addsubmethod = 0;
byte soundkhz = 8, soundchannels = 0xFF;
boolean stereosound = false;
byte pcontrol[4] = { 0, 1, 3, 3 };
boolean autobacktrack = true, disallowinst = false;
word backtracktime = 30, backtracknum = 3;
struct windowsettings ws [NUMWINDOWS];

extern struct filemap fm[FTAGS] = {
	"CheatDesc", FCHEAT, FSTRINGALLOC, offsetof (cheatpatchset, desc),     // 0
	"AutoRegOn", FROMSETTING, FBYTE, offsetof (gamesettings, autoreg),
	"FrameSkip", FROMSETTING, FBYTE, offsetof (gamesettings, frameskip),
	"Regulate%", FROMSETTING, FBYTE, offsetof (gamesettings, regpercent),
	"GrSpeedup", FROMSETTING, FBYTE, offsetof (gamesettings, grspeedup),
	"65c816%",   FROMSETTING, FBYTE, offsetof (gamesettings, cpupercent),  // 5
	"SPC700%",   FROMSETTING, FBYTE, offsetof (gamesettings, spcpercent),
	"SoundChs",  FROMSETTING, FWORD, offsetof (gamesettings, soundch),
	"BGs",       FROMSETTING, FBYTE, offsetof (gamesettings, bgs),
	"ForceROM",  FROMSETTING, FBYTE, offsetof (gamesettings, forcerom),
	"ForceCtry", FROMSETTING, FBYTE, offsetof (gamesettings, forcecountry), // 10
	"Interl",    FROMSETTING, FBYTE, offsetof (gamesettings, interleaved),
	"EnableSPC", FROMSETTING, FBYTE, offsetof (gamesettings, emulatespc),
	"SPCSkipM",  FROMSETTING, FBYTE, offsetof (gamesettings, spcskipmethod),
	"OpenWins",  FROMSETTING, FWORD, offsetof (gamesettings, openwindows),
	"NoFastROM", FROMSETTING, FBYTE, offsetof (gamesettings, ignorefastrom),
	"GameRes",   FGLOBAL, FBYTE, (dword) &gameres,        // 15
	"GUIRes",    FGLOBAL, FBYTE, (dword) &guires,
	"AddSubM",   FGLOBAL, FBYTE, (dword) &addsubmethod,
	"SoundKHz",  FGLOBAL, FBYTE, (dword) &soundkhz,
	"StereoSnd", FGLOBAL, FBYTE, (dword) &stereosound,
	"P1Control", FGLOBAL, FBYTE, (dword) &pcontrol[0],      // 20
	"P2Control", FGLOBAL, FBYTE, (dword) &pcontrol[1],
	"P3Control", FGLOBAL, FBYTE, (dword) &pcontrol[2],
	"P4Control", FGLOBAL, FBYTE, (dword) &pcontrol[3],
	"DisableIS", FGLOBAL, FBYTE, (dword) &disallowinst,
	"WaitTrace", FGLOBAL, FBYTE, (dword) &waitretrace,    // 25
	"LeadingEd", FGLOBAL, FBYTE, (dword) &leadingedge,
	"ROMDir",    FGLOBAL, FSTRING, (dword) romdir,
	"SRAMDir",   FGLOBAL, FSTRING, (dword) sramdir,
	"InstDir",   FGLOBAL, FSTRING, (dword) instdir,
	"SShotDir",  FGLOBAL, FSTRING, (dword) sshotdir,      // 30
	"BackGrnd",  FGLOBAL, FBYTE, (dword) &background,
	"ESCQuits",  FGLOBAL, FBYTE, (dword) &escquits,
	"WindowSet", FGLOBAL, FBYTE, (dword) &set.window,
	"TextSet",   FGLOBAL, FBYTE, (dword) &set.text,
	"CtrlSet",   FGLOBAL, FBYTE, (dword) &set.control,     // 35
	"ChoiceSet", FGLOBAL, FBYTE, (dword) &set.choice,
	"ButtonSet", FGLOBAL, FBYTE, (dword) &set.button,
	"BtTextSet", FGLOBAL, FBYTE, (dword) &set.buttontext,
	"TitleSet",  FGLOBAL, FBYTE, (dword) &set.title,
	"TtTextSet", FGLOBAL, FBYTE, (dword) &set.titletext,   // 40
	"FocusSet",  FGLOBAL, FBYTE, (dword) &set.focus,
	"FlashSet",  FGLOBAL, FBYTE, (dword) &set.flash,
	"JoyUp",     FJOYPADSETTING, FBYTE, offsetof (struct snesjoypad, up),
	"JoyDown",   FJOYPADSETTING, FBYTE, offsetof (struct snesjoypad, down),
	"JoyLeft",   FJOYPADSETTING, FBYTE, offsetof (struct snesjoypad, left),   // 45
	"JoyRight",  FJOYPADSETTING, FBYTE, offsetof (struct snesjoypad, right),
	"JoyX",      FJOYPADSETTING, FBYTE, offsetof (struct snesjoypad, x),
	"JoyY",      FJOYPADSETTING, FBYTE, offsetof (struct snesjoypad, y),
	"JoyA",      FJOYPADSETTING, FBYTE, offsetof (struct snesjoypad, a),
	"JoyB",      FJOYPADSETTING, FBYTE, offsetof (struct snesjoypad, b),      // 50
	"JoyL",      FJOYPADSETTING, FBYTE, offsetof (struct snesjoypad, l),
	"JoyR",      FJOYPADSETTING, FBYTE, offsetof (struct snesjoypad, r),
	"JoySelect", FJOYPADSETTING, FBYTE, offsetof (struct snesjoypad, select),
	"JoyStart",  FJOYPADSETTING, FBYTE, offsetof (struct snesjoypad, start),
	"WinPosX",   FWINDOWPOS, FWORD, offsetof (struct windowsettings, x),      // 55
	"WinPosY",   FWINDOWPOS, FWORD, offsetof (struct windowsettings, y),
	"WinZOrder", FWINDOWPOS, FBYTE, offsetof (struct windowsettings, zorder),
	"JoyMinX",   FGLOBAL, FWORD, (dword) &joyminx,
	"JoyMaxX",   FGLOBAL, FWORD, (dword) &joymaxx,
	"JoyMinY",   FGLOBAL, FWORD, (dword) &joyminy,         // 60
	"JoyMaxY",   FGLOBAL, FWORD, (dword) &joymaxy,
	"JoyMidX",   FGLOBAL, FWORD, (dword) &joymidx,
	"JoyMidY",   FGLOBAL, FWORD, (dword) &joymidy,
	"JoyThresh", FGLOBAL, FWORD, (dword) &joythresh,
	"BackNum",   FGLOBAL, FWORD, (dword) &backtracknum,    // 65
	"FPUCopy",   FGLOBAL, FBYTE, (dword) &fpucopy,        
	"Windowing", FROMSETTING, FBYTE, offsetof (gamesettings, windowing),
	"IndirHDMA", FROMSETTING, FBYTE, offsetof (gamesettings, indirecthdma),
	"AutoBackT", FGLOBAL, FBYTE, (dword) &autobacktrack,
	"BackTTime", FGLOBAL, FWORD, (dword) &backtracktime,
	"AskB4Exit", FGLOBAL, FBYTE, (dword) &confirmexit,
	"ShowFPS",   FGLOBAL, FBYTE, (dword) &showfps,
};

	// Commands:
	//
	// New ROM "filename.ext"
	// New Joypad n
	// New Window n
	// New Cheat bbaaaa=vv+...
	//
	// ; Statements starting with a semicolon are ignored.

struct gamesettings gsdefault = {
	"[Defaults]", // char filename [13];
	true,     // boolean autoreg;
	2, 100,   // byte frameskip, regpercent;
	false,    // boolean grspeedup;
	100, 100, // byte cpupercent, spcpercent;
	0xFF,     // word soundch;
	31,       // byte bgs;
	0, 0,     // byte forcerom, forcecountry;
	false,    // boolean interleaved;
	false,    // boolean emulatespc;
	0,        // byte spcskipmethod;
	1,        // word openwindows;
	true,     // boolean ignorefastrom
	true, true// boolean windowing, indirecthdma
};

struct gamesettings *gs [MAXGAMEDATABASE] = {
	&gsdefault // First entry (gs[0]) is the defaults.
};
struct gamesettings *curgs;
int curgsnum = 0;
int numgamesettings = 0;
int gsentries = 1;
boolean romloaded = false, romrunning = false;

void initfilemanager (char *argv0)
{
	char temp[80];
	
	curgs = gs[curgsnum];
	strcpy (temp, argv0);
	stripfilename (temp);
	_fullpath (exedir, temp, 80);
	debug0(exedir);
}

void uninitfilemanager (void)
{
	int x, y;

	for (x = 1; x < MAXGAMEDATABASE; x++) {
		if (gs[x] == NULL) continue;
		for (y = 0; y < gs[x]->patches; y++) {
			free (gs[x]->cheat[y]->desc);
			free (gs[x]->cheat[y]->patch);
			free (gs[x]->cheat[y]);
		}
		free (gs[x]);
	}
}

boolean exists (char *s)
{
	if (access (s, 0) == 0)
		return true;
	else
		return false;
}

boolean isadir (char *s)
{
	static struct _stat buf;

	// first checks whether the path is valid...
    if (_stat (s, &buf) == -1) {
		// no, so it might be an incomplete path.  Decide based on the existance of an extention.
		if (findlastch (s + findlastch(s, SLASH) + 1, '.') == -1) {
			return true;
		} else {
			return false;
		}
	} else if (S_ISDIR(buf.st_mode))
		return true;
	return false;
}

void delstr (char *s, int p, int n)
{
	for (s += p; *s != '\0'; s++) {
		*s = s[n];
		if (*s == '\0') break;
	}
}

int findlastch (char *s, char ch)
{
	int x;
	for (x = strlen(s)-1; x >= 0; x--) {
		if (s[x] == ch) {
			return x;
		}
	}
	return x;
}

int findfirstch (char *s, char ch)
{
	int x;
	for (x = 0; s[x] != '\0'; x++) {
		if (s[x] == ch) {
			return x;
		}
	}
	return -1;
}

int countchar (char *s, char ch)
{
	int n = 0;
	
	while (*s != '\0') {
		if (*s == ch) n++;
		s++;
	}
	return n;
}

void trimspace (char *s)
{
	int y, n;
	
	for (y = 0; s[y] == ' ' || s[y] == 9; y++)
		;
	delstr (s, 0, y);
	for (y = strlen(s)-1, n = 0; (s[y] == ' ' || s[y] == 9) && y >= 0; y--, n++)
		;
	delstr (s, y+1, n);
}

void trimfilespec (char *s)
{
	trimspace (s);
	if (countchar (s, SLASH) > 1 && s [strlen(s) - 1] == SLASH) {
		s [strlen(s) - 1] = '\0';
	}
}

void strippathname (char *name)
{
	int x, p;

	if (isadir (name)) {
		name[0] = '\0';
		return;
	}
	p = findlastch (name, SLASH);
	x = findlastch (name, ':');
	if (x > p) p = x;
	delstr (name, 0, p + 1);
}

void stripfilename (char *name)
{
	int x;
	if (!isadir (name)) {
		x = findlastch (name, SLASH);
		if (name [x - 1] == ':' || x == 0) {
			x++; // Don't delete backslash if file is in root.
		}
		delstr (name, x, strlen (name) - x);
	} else {
		x = strlen(name);
		if (name[x-1] == SLASH)
			name[x-1] = '\0';
	}
}

void getabspath (char *path)
{	// absolute path reletive to executable directory
	char tempcwd [80], temppath [80];
	unsigned dummy;
	
	getcwd (tempcwd, 80);
	_dos_setdrive (exedir [0]-'A'+1, &dummy);
	chdir (exedir);
	_fullpath (temppath, path, 80);
	strcpy (path, temppath);
	_dos_setdrive (tempcwd [0]-'A'+1, &dummy);
	chdir (tempcwd);
}

void combinepathfile (char *comb, char *path, char *fn)
{	// This function doesn't combine two paths... it just appends fn to path
	int x = strlen (path);
	
	strcpy (comb, path);
	if (comb [x-1] != SLASH) {
		comb [x] = SLASH;
		x++;
	}
	strcpy (comb+x, fn);
}

void combinepaths (char *comb, char *path, char *offs)
{
	char tempcwd [80], temppath [80];
	unsigned dummy, originaldrive;
	
	_dos_getdrive (&originaldrive); // Save current drive
	path[0] = toupper(path[0]);
	offs[0] = toupper(offs[0]);
	if (offs[1] == ':')
		_dos_setdrive (offs[0]-'A'+1, &dummy);
	else if (path [1] == ':')
		_dos_setdrive (path[0]-'A'+1, &dummy);
	getcwd (tempcwd, 80); // save current directory

	_fullpath (temppath, path, 80);
	_dos_getdrive (&dummy);
	if (dummy == temppath[0]-'A'+1)
		chdir (path);
	chdir (offs);
	getcwd (comb, 80);

	_dos_setdrive (tempcwd [0]-'A'+1, &dummy);
	chdir (tempcwd); // restore current directory
	_dos_setdrive (originaldrive, &dummy); // Restore current drive
}

#define ntohex(n) ((n) > 9 ? (n)+'A'-10 : (n)+'0')
#define ishexd(c) (((c) >= '0' && (c) <= '9') || ((c) >= 'A' && (c) <= 'Z'))
#define hexton(c) ((c) >= 'A' ? (c)-'A'+10 : (c)-'0')
	// ONLY WORKS ON UPPERCASE HEX!

int verifyspecformat (char *patchspec)
{	// Removes spaces...btw...and converts to uppercase.
	// False=bad format, other=number of patches.
	char *o_patchspec = patchspec;
	int i, n;
	
	strupr (patchspec);
	debug0 ("Checking %s",patchspec);
	while (*patchspec)
		if (*patchspec == ' ')
			for (i = 0; patchspec[i]; i++)
				patchspec[i] = patchspec[i+1];
		else
			patchspec++;
	patchspec = o_patchspec;
	i = 0; n = 0;
	for (;;) {
		if (!((patchspec[i + 4] == '-')  ^ (patchspec[i + 6] == '='))) {
			debug0 ("Not game genie nor native format");
			return false;  // Must have a dash or equals, but not both
		}
		if (!ishexd(patchspec[i]) || !ishexd(patchspec[i+1]) || !ishexd(patchspec[i+2]) ||
			!ishexd(patchspec[i+3]) || (!ishexd(patchspec[i+4]) && patchspec[i+4] != '-') ||
			!ishexd(patchspec[i+5]) || (!ishexd(patchspec[i+6]) && patchspec[i+6] != '=') ||
			!ishexd(patchspec[i+7]) || !ishexd(patchspec[i+8])) {
			debug0 ("Digit problem in cheat");
			return false;  // Must all be hex digits
		}
		n++;
		if (patchspec[i + 6] == '=' && ishexd(patchspec[i+9]) && ishexd(patchspec[i+10])) {
			i += 2; // 2 More digits.
			debug0 ("Word-sized cheat");
		}
		if (strlen (patchspec) - i < 10)
			break;
		if (patchspec[i+9] != '+') {
			debug0 ("Multiple patches detected in cheat");

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -