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

📄 miscfunc.cpp

📁 SNES game emulator. C and asm files.
💻 CPP
字号:
/*	MiscFunc.cpp - Miscellaneous low-level functions for the keyboard, joystick, mouse,
	and timer (PIT chip timer 0).
*/
#include "Common.hpp"
#include <STDARG.H>
#include "GrEngine.hpp"
#include "CPU.hpp"

union REGPACK regs;

#define DEBUGFILES 2
FILE *debugfp [DEBUGFILES];
char debugfn [] = "DEBUG?.DOC";

void startdebug (int fn)
{
#ifndef NODEBUGOUT
	int y;
	
	if (fn < 0) {
		for (y = 0; y < DEBUGFILES; y++) {
			debugfn [5] = '0' + y;
			debugfp [y] = fopen (debugfn, "a");
		}
	} else {
		debugfn [5] = '0' + fn;
		debugfp [fn] = fopen (debugfn, "a");
	}
#endif
}

void restartdebug (int fn)
{
#ifndef NODEBUGOUT
	int y;
	
	if (fn < 0) {
		for (y = 0; y < DEBUGFILES; y++) {
			debugfn [5] = '0' + y;
			debugfp [y] = fopen (debugfn, "w");
		}
	} else {
		debugfn [5] = '0' + fn;
		debugfp [fn] = fopen (debugfn, "w");
	}
#endif
}

void enddebug (int fn)
{
#ifndef NODEBUGOUT
	int y;

	if (fn < 0) {
		for (y = 0; y < DEBUGFILES; y++) {
			if (debugfp [y] != NULL) {
				debugf (y, "Debug Log Closed.");
				fclose (debugfp [y]);
			}
		}
	} else {
		if (debugfp [fn] != NULL) {
			debugf (fn, "Debug Log Closed.");
			fclose (debugfp [fn]);
		}
	}
#endif
}

void debugf  (int fn, char *format, ...)
{
#ifndef NODEBUGOUT
	va_list arglist;

	fprintf (debugfp [fn], "%d ", debug_instr);
	va_start (arglist, format);
	vfprintf (debugfp [fn], format, arglist);
	fprintf (debugfp [fn], "\n");
	fflush (debugfp [fn]);
	va_end (arglist);
#endif
}

void debug0 (char *format, ...)
{
#ifndef NODEBUGOUT
	va_list arglist;

	fprintf (debugfp [0], "%d ", debug_instr);
	va_start (arglist, format);
	vfprintf (debugfp [0], format, arglist);
	fprintf (debugfp [0], "\n");
	fflush (debugfp [0]);
	va_end (arglist);
#endif
}

volatile long int ticks, tmsec, oldmsoffset = 0, oldticks;
	// Timer variables: ticks every 5msec, tmsec is number of milliseconds, oldticks is
	// Number of ticks that would have tocked with PIT chip default programming (~18.2/sec)
#define precision 200
	// 200 ticks per second, 5msec/tick
void (__interrupt __far *prevint08) ();
void __interrupt __far timerhandler ();

void inittimer (void)
{
	int value;
	 
	ticks = 0;
	tmsec = 0;
	oldticks = 0;
    prevint08 = _dos_getvect (0x08);
	_disable();                          // disable interrupts.
	outp(0x43, 0x36);              // Set mode to recieve instruction?
	value = 1193180L / precision;
	outp(0x40, value & 255); // Set new clock-tick interval.
	outp(0x40, value >> 8);
	_dos_setvect (0x08, timerhandler);
	_enable();                           // enable interrupts.
}

void tdelay (int msec)
{
	int start = tmsec;

	while (start + msec > tmsec) ;
}

void uninittimer (void)
{
	_disable();                          // disable interrupts.
	outp(0x43, 0x36);               // set mode to recieve instruction?
	outp(0x40, 0x00);               // reset clock-tick interval to normal?
	outp(0x40, 0x00);               // reset clock-tick interval to normal?
	_dos_setvect (0x08, prevint08);
	_enable();                           // enable interrupts.
}

void __interrupt __far timerhandler ()
{
	++ticks;
	tmsec += 5;
	oldmsoffset += 5;
	if (oldmsoffset == 55) {
		oldmsoffset = 0;
		oldticks++;
		_chain_intr (prevint08);
	}
	outp(0x20, 0x20);			// but it was in the C source I made this class from.
}

int mousex = 0, mousey = 0, mouseres = 2; // Mouse position (pixels) & resolution (sensitivity)
int mickeysx = 0, mickeysy = 0; // Measure of mouse movement
boolean lbutton = 0, rbutton = 0; // Mouse buttons

void initmouse ()
{
	regs.w.ax = 0;
	intr (0x33, &regs);
}

void checkmouse ()
{
	regs.w.ax = 3;
	intr (0x33, &regs);
	lbutton = regs.w.bx & 1;
	rbutton = (regs.w.bx >> 1) & 1;
	if (vidmode == 2) {
		mousex = regs.w.cx / 2;
		mousey = regs.w.dx;
	} else { // If not in Mode 13H mouse driver might report mouse positions with granularity, so they can't be trusted
		regs.w.ax = 11;
		intr (0x33, &regs);
		mickeysx += (signed short) regs.w.cx;
		mickeysy += (signed short) regs.w.dx;
		mousex += (mickeysx / mouseres);
		mickeysx %= mouseres;
		if (mousex >= xres) mousex = xres - 1;
		if (mousex < 0) mousex = 0;
		mousey += (mickeysy / mouseres);
		mickeysy %= mouseres;
		if (mousey >= yres) mousey = yres - 1;
		if (mousey < 0) mousey = 0;
	}
}

void (__interrupt __far *prevint09) ();
void __interrupt __far keyboardhandler ();

extern struct snesjoypad joykey [6] = {
	// X,Y,A,B, L,R, Select,Start
	{ KEYUP, KEYDOWN, KEYLEFT, KEYRIGHT, 31, 45, 32, 46, 17, 18, KEYTAB, KEYENTER },
	// Up/Down/Left/Right S/X/D/C W/E Tab/Start
	{ 55, 78, 53, 74, 71, 79, 73, 81, 82, 83, 26, 27 },
	// Keyp*/Keyp+///KeyP- Home/End/PgUp/PgDn Ins/Del [/]
	{ 100, 101, 102, 103, 105, 104, 107, 106, 74, 78, 53, 55 },
	// JoyUp/JoyDn/JoyLt/JoyRt B1/B2/B3/B4 KeyP-/KeyP+ //*
	{ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 },
	// Off/Off/Off/Off Off/Off/Off/Off Off/Off Off/Off
	{ 20, 34, 33, 35, 16, 30, 17, 31, 18, 32, 15, 42 },
	// T/G/F/H Q/A/W/S E/D Tab/LShift
	{ KEYUP, KEYDOWN, KEYLEFT, KEYRIGHT, 24, 38, 25, 39, 26, 27, 54, KEYENTER }
	// Up/Down/Left/Right O/L/P/; [/] RShift/Enter
};

char keyname [128] [6] = {
	/* 0  */ "[OFF]", "ESC", "1", "2", "3",
	/* 5  */ "4", "5", "6", "7", "8",
	/* 10 */ "9", "0", "- _", "= +", "BkSpc",
	/* 15 */ "Tab", "Q", "W", "E", "R",
	/* 20 */ "T", "Y", "U", "I", "O",
	/* 25 */ "P", "[ {", "} ]", "Enter", "Ctrl",
	/* 30 */ "A", "S", "D", "F", "G",
	/* 35 */ "H", "J", "K", "L", "; :",
	/* 40 */ "' \"", "` ~", "LShft", "\\", "Z",
	/* 45 */ "X", "C", "V", "B", "N",
	/* 50 */ "M", ", <", ". >", "/ ?", "RShft",
	/* 55 */ "KeyP*", "Alt", "Space", "CpsLk", "F1",
	/* 60 */ "F2", "F3", "F4", "F5", "F6",
	/* 65 */ "F7", "F8", "F9", "F10", "NumLk",
	/* 70 */ "ScrLk", "Home", "Up", "PgUp", "KeyP-",
	/* 75 */ "Left", "[???]", "Right", "KeyP+", "End",
	/* 80 */ "Down", "PgDn", "Insrt", "Del", "[???]",
	/* 85 */ "[???]", "[???]", "F11", "F12", "[???]",
	/* 90 */ "[???]", "[???]", "[???]", "[???]", "[???]",
	/* 95 */ "[???]", "[???]", "[???]", "[???]", "[???]",
	/* 100*/ "JoyUp", "JoyDn", "JoyLt", "JoyRt", "Joy#1",
	/* 105*/ "Joy#2", "Joy#3", "Joy#4", "Joy#5", "Joy#6",
	/* 110*/ "Joy#7", "Joy#8", "Joy#9", "Jy#10", "[???]",
	/* 115*/ "[???]", "[???]", "[???]", "[???]", "[???]",
	/* 120*/ "[???]", "[???]", "[???]", "[???]", "[???]",
	/* 125*/ "[???]", "[???]", "[???]"
};

volatile boolean keydown [128];

void initkeyboard (void)
{
    prevint09 = _dos_getvect (0x09);
	_dos_setvect (0x09, keyboardhandler);
}

void uninitkeyboard (void)
{
	_dos_setvect (0x09, prevint09);
}

void __interrupt __far keyboardhandler ()
{
	int keycode;

	keycode = inp (0x60);
	if (keycode & 0x80)
		keydown [keycode & 0x7F] = false;
	else
		keydown [keycode] = true;
	_chain_intr (prevint09);
}

word joyminx = 10000, joymaxx = 0, joyminy = 10000, joymaxy = 0;
word joythresh = 30, joymidx = -1, joymidy = -1, joyposx, joyposy;

void resetjoysettings ()
{
	joyminx = 10000, joymaxx = 0, joyminy = 10000, joymaxy = 0, joythresh = 30;
}

void checkjoystick ()
{
	int x, y, b, t;
	int axisx = 0, axisy = 0, timeoffx = 0, timeoffy = 0;
	int rangex, rangey, curx, cury, offsx, offsy;
	
	_disable ();
	outp (0x201, 0xFF); // Trigger joystick
	b = inp (0x201);
		// Get button status
	for (x = 104; x < 114; x++)
		keydown [x] = false;
	for (x = 0; x < 4; x++)
		if ((b & (0x10 << x)) == 0)
			keydown [104 + x] = true;
		// Get stick position in raw time
	joyposx = 0;
	joyposy = 0;
	for (t = 0; joyposx == 0 || joyposy == 0; t++) {
		if ((b & 1) == 0) timeoffx++;
		if (joyposx == 0 && (timeoffx > 5 || t > 10000))
			joyposx = t;
		if ((b & 2) == 0) timeoffy++;
		if (joyposy == 0 && (timeoffy > 5 || t > 10000))
			joyposy = t;
		b = inp (0x201);
	}
	_enable ();
		// Extend range if neccesary
	if (joyposx < joyminx)
		joyminx = joyposx;
	if (joyposx > joymaxx)
		joymaxx = joyposx;
	if (joyposy < joyminy)
		joyminy = joyposy;
	if (joyposy > joymaxy)
		joymaxy = joyposy;
		// Find percent position
	x = 0;
	y = 0;
	if (joyposx < joymidx) {
		curx = joyposx - joyminx;
		rangex = joymidx - joyminx;
		offsx = 0;
	} else {
		curx = joyposx - joymidx;
		rangex = joymaxx - joymidx;
		offsx = 50;
	}
	if (joyposy < joymidy) {
		cury = joyposy - joyminy;
		rangey = joymidy - joyminy;
		offsy = 0;
	} else {
		cury = joyposy - joymidy;
		rangey = joymaxy - joymidy;
		offsy = 50;
	};
	if (rangex == 0 || rangey == 0) {
		x = 50;
		y = 50;
	} else {
		x = (curx * 50 / rangex) + offsx;
		y = (cury * 50 / rangey) + offsy;
	}
		// Finally, find whether to register up/down/left/right
	if (x <= 50 - joythresh) keydown [102] = true;
	else                     keydown [102] = false;
	if (x >= 50 + joythresh) keydown [103] = true;
	else                     keydown [103] = false;
	if (y <= 50 - joythresh) keydown [100] = true;
	else                     keydown [100] = false;
	if (y >= 50 + joythresh) keydown [101] = true;
	else                     keydown [101] = false;
}

⌨️ 快捷键说明

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