File:  [RetroPC.NET] / xmil / keystat.c
Revision 1.4: download - view: text, annotated - select for diffs
Tue Jun 3 05:07:30 2008 JST (17 years, 4 months ago) by yui
Branches: MAIN
CVS tags: HEAD
change to c style comment

#include	"compiler.h"
#include	"pccore.h"
#include	"iocore.h"
#include	"keystat.h"
#include	"keystat.tbl"


/* キーコードがないので PC-98シリーズのキーコードをベースとする */
/* … つまり猫のがそのまま使える */


	KEYSTAT		keystat;


static void keydown(REG8 key) {

	REG8	flag;

	flag = keyflag[key];
	if (flag & 0x40) {
		keystat.shift |= flag & 0x1f;
	}
	else if (flag & 0x20) {
		keystat.keybmp |= (1 << (flag & 0x1f));
	}
	if (key < 0x70) {
		keystat.req_int = TRUE;
		keystat.shift |= 0x40;
		keystat.lastkey = key;
		subcpu_sendkey();
	}
}

static void keyup(REG8 key) {

	REG8	flag;

	flag = keyflag[key];
	if (flag & 0x40) {
		keystat.shift &= ~(flag & 0x1f);
	}
	else if (flag & 0x20) {
		keystat.keybmp &= ~(1 << (flag & 0x1f));
	}
	if (key < 0x70) {
		keystat.req_int = TRUE;
		keystat.shift &= ~0x40;
		subcpu_sendkey();
	}
}

UINT keystat_getflag(void) {

	REG8	ks;
	REG8	kf;
	UINT	tbl;
	REG8	kc;

	ks = keystat.shift;
	kc = 0;
	if (ks & 0x40) {
		kf = keyflag[keystat.lastkey];
		ks |= (kf & 0x80);								/* function */
		if (ks & 0x04) {								/* kana */
			if (!(ks & 0x02)) {							/* shift */
				tbl = 4;
			}
			else {
				tbl = 5;
			}
		}
		else if (ks & 0x01) {							/* ctrl */
			tbl = 3;
		}
		else if (ks & 0x10) {							/* grph */
			tbl = 2;
		}
		else if (ks & 0x02) {							/* shift */
			tbl = 1;
		}
		else {
			tbl = 0;
		}
		kc = keytbl[tbl][keystat.lastkey];
		if (ks & 0x08) {								/* caps */
			if (((kc >= 'A') && (kc <= 'Z')) ||
				((kc >= 'a') && (kc <= 'z'))) {
				kc ^= 0x20;
			}
		}
	}
	return((kc << 8) + (ks ^ 0xff));
}

UINT32 keystat_gete3(void) {

	return(keystat.keybmp);
}

REG8 keystat_getjoy(void) {

	return(~keystat.joykey);
}


/* extension */

void keystat_keydown(REG8 ref) {

	REG8	shift;
	REG8	key;

	if (ref < 0x80) {
		if (xmilcfg.KEY_MODE) {
			shift = joyflag[ref];
			if (shift & 0x40) {
				keystat.joykey |= (1 << (shift & 7));
				return;
			}
		}
		if (!keystat.hit[ref]) {
			keystat.hit[ref] = 1;
			keydown(ref);
		}
	}
	else if (ref < 0x90) {
		key = ref - 0x10;
		keystat.hit[key] ^= 1;
		if (keystat.hit[key]) {
			keydown(key);
		}
		else {
			keyup(key);
		}
	}
}

void keystat_keyup(REG8 ref) {

	REG8	shift;

	if (ref < 0x80) {
		if (xmilcfg.KEY_MODE) {
			shift = joyflag[ref];
			if (shift & 0x40) {
				keystat.joykey &= ~(1 << (shift & 7));
				return;
			}
		}
		if (keystat.hit[ref]) {
			keystat.hit[ref] = 0;
			keyup(ref);
		}
	}
}

void keystat_resetjoykey(void) {

	REG8	i;

	keystat.joykey = 0;
	for (i=0; i<0x80; i++) {
		if ((joyflag[i] & 0x40) && (keystat.hit[i])) {
			keystat.hit[i] = 0;
			keyup(i);
		}
	}
}

void keystat_allrelease(void) {

	REG8	i;

	for (i=0; i<0x80; i++) {
		if (keystat.hit[i]) {
			keystat.hit[i] = 0;
			keyup(i);
		}
	}
}

static REG8 cnvnewcode(REG8 oldcode) {

	switch(oldcode) {
		case 0x71:				/* 通常caps */
			return(0x81);

		case 0x72:				/* 通常カナ */
			return(0x82);

		case 0x79:				/* メカニカルロックcaps */
			return(0x71);

		case 0x7a:				/* メカニカルロックcaps */
			return(0x72);

		case 0x76:
			return(0x90);		/* NKEY_USER + 0 */

		case 0x77:
			return(0x91);		/* NKEY_USER + 1 */

		default:
			return(oldcode);
	}
}

void keystat_senddata(REG8 data) {

	REG8	keycode;

	keycode = cnvnewcode((REG8)(data & 0x7f));
	if (!(data & 0x80)) {
		keystat_keydown(keycode);
	}
	else {
		keystat_keyup(keycode);
	}
}


/*		0x80 --> 0x01
 *		Q  W  E  A  D  Z  X  C
 *		[7] [4] [1] [8] [2] [9] [6] [3]
 *		ESC 1  [-] [+] [*] TAB ' ' Ent */

RetroPC.NET-CVS <cvs@retropc.net>