libretro-meowPC98/keystat.c
2016-03-06 11:11:17 +00:00

605 lines
10 KiB
C
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "compiler.h"
#include "dosio.h"
#include "textfile.h"
#include "pccore.h"
#include "iocore.h"
#include "keystat.h"
#include "keystat.tbl"
#include "softkbd.h"
typedef struct {
UINT8 ref[0x80];
UINT8 extkey;
UINT8 mouselast;
UINT8 padding;
UINT8 d_up;
UINT8 d_dn;
UINT8 d_lt;
UINT8 d_rt;
} KEYSTAT;
NKEYTBL nkeytbl;
KEYCTRL keyctrl;
static KEYSTAT keystat;
void keystat_initialize(void) {
OEMCHAR path[MAX_PATH];
ZeroMemory(&keyctrl, sizeof(keyctrl));
keyctrl.keyrep = 0x21;
keyctrl.capsref = NKEYREF_NC;
keyctrl.kanaref = NKEYREF_NC;
ZeroMemory(&keystat, sizeof(keystat));
FillMemory(keystat.ref, sizeof(keystat.ref), NKEYREF_NC);
keystat_tblreset();
getbiospath(path, OEMTEXT("key.txt"), NELEMENTS(path));
keystat_tblload(path);
}
void keystat_tblreset(void) {
UINT i;
ZeroMemory(&nkeytbl, sizeof(nkeytbl));
for (i=0; i<0x80; i++) {
nkeytbl.key[i].keys = 1;
nkeytbl.key[i].key[0] = (UINT8)i;
}
for (i=0; i<0x10; i++) {
nkeytbl.key[i+0x80].keys = 1;
nkeytbl.key[i+0x80].key[0] = (UINT8)(i + 0xf0);
}
}
void keystat_tblset(REG8 ref, const UINT8 *key, UINT cnt) {
NKEYM *nkey;
if ((ref >= NKEY_USER) && (ref < (NKEY_USER + NKEY_USERKEYS))) {
nkey = (NKEYM *)(nkeytbl.user + (ref - NKEY_USER));
cnt = min(cnt, 15);
}
else if (ref < NKEY_SYSTEM) {
nkey = (NKEYM *)(nkeytbl.key + ref);
cnt = min(cnt, 3);
}
else {
return;
}
nkey->keys = (UINT8)cnt;
if (cnt) {
CopyMemory(nkey->key, key, cnt);
}
}
// ---- config...
static const OEMCHAR str_userkey1[] = OEMTEXT("userkey1");
static const OEMCHAR str_userkey2[] = OEMTEXT("userkey2");
static REG8 searchkeynum(const OEMCHAR *str, BOOL user) {
const KEYNAME *n;
const KEYNAME *nterm;
n = s_keyname;
nterm = s_keyname + NELEMENTS(s_keyname);
while(n < nterm) {
if (!milstr_cmp(n->str, str)) {
return(n->num);
}
n++;
}
if (user) {
if (!milstr_cmp(str_userkey1, str)) {
return(NKEY_USER + 0);
}
if (!milstr_cmp(str_userkey2, str)) {
return(NKEY_USER + 1);
}
}
return(0xff);
}
void keystat_tblload(const OEMCHAR *filename) {
TEXTFILEH tfh;
OEMCHAR work[256];
OEMCHAR *p;
OEMCHAR *q;
OEMCHAR *r;
UINT8 ref;
UINT8 key[15];
UINT cnt;
tfh = textfile_open(filename, 0x800);
if (tfh == NULL) {
goto kstbl_err;
}
while(textfile_read(tfh, work, NELEMENTS(work)) == SUCCESS) {
p = milstr_nextword(work);
q = milstr_chr(p, '\t');
if (q == NULL) {
q = milstr_chr(p, '=');
}
if (q == NULL) {
continue;
}
*q++ = '\0';
r = milstr_chr(p, ' ');
if (r != NULL) {
*r = '\0';
}
ref = searchkeynum(p, TRUE);
if (ref == 0xff) {
continue;
}
cnt = 0;
while((q) && (cnt < 16)) {
p = milstr_nextword(q);
q = milstr_chr(p, ' ');
if (q != NULL) {
*q++ = '\0';
}
key[cnt] = searchkeynum(p, FALSE);
if (key[cnt] != 0xff) {
cnt++;
}
}
keystat_tblset(ref, key, cnt);
}
textfile_close(tfh);
kstbl_err:
return;
}
// ----
static REG8 getledstat(void) {
REG8 ret;
ret = 0;
if (keyctrl.kanaref != NKEYREF_NC) {
ret |= 8;
}
if (keyctrl.capsref != NKEYREF_NC) {
ret |= 4;
}
return(ret);
}
static void reloadled(void) {
keyctrl.kanaref = keystat.ref[0x72];
keyctrl.capsref = keystat.ref[0x71];
#if defined(SUPPORT_SOFTKBD)
softkbd_led(getledstat());
#endif
}
void keystat_ctrlreset(void) {
keyctrl.reqparam = 0;
keystat.ref[0x72] = keyctrl.kanaref;
keystat.ref[0x71] = keyctrl.capsref;
#if defined(SUPPORT_SOFTKBD)
softkbd_led(getledstat());
#endif
}
void keystat_ctrlsend(REG8 dat) {
if (!keyctrl.reqparam) {
keyctrl.mode = dat;
switch(dat) {
#if defined(SUPPORT_PC9801_119)
case 0x95:
#endif
case 0x9c:
case 0x9d:
keyctrl.reqparam = 1;
keyboard_ctrl(0xfa);
break;
#if defined(SUPPORT_PC9801_119)
case 0x96:
keyboard_ctrl(0xfa);
keyboard_ctrl(0xa0);
keyboard_ctrl(0x83);
break;
#endif
case 0x9f:
keyboard_ctrl(0xfa);
keyboard_ctrl(0xa0);
keyboard_ctrl(0x80);
break;
default:
keyboard_ctrl(0xfc);
break;
}
}
else {
switch(keyctrl.mode) {
#if defined(SUPPORT_PC9801_119)
case 0x95:
keyctrl.kbdtype = dat;
keyboard_ctrl(0xfa);
break;
#endif
case 0x9c:
keyboard_ctrl(0xfa);
break;
case 0x9d:
if (dat == 0x60) {
keyboard_ctrl(0xfa);
keyboard_ctrl((REG8)(0x70 + getledstat()));
}
else if ((dat & 0xf0) == 0x70) {
keyboard_ctrl(0xfa);
keystat.ref[0x72] = (dat & 8)?NKEYREF_uPD8255:NKEYREF_NC;
keystat.ref[0x71] = (dat & 4)?NKEYREF_uPD8255:NKEYREF_NC;
reloadled();
}
break;
}
keyctrl.reqparam = 0;
}
}
// ----
void keystat_down(const UINT8 *key, REG8 keys, REG8 ref) {
UINT8 keydata;
UINT8 keycode;
REG8 data;
while(keys--) {
keydata = *key++;
keycode = (keydata & 0x7f);
if (keycode < 0x70) {
#if 1 // 05/02/04
if (keystat.ref[keycode] != NKEYREF_NC) {
if (!(kbexflag[keycode] & KBEX_NONREP)) {
keyboard_send((REG8)(keycode + 0x80));
keystat.ref[keycode] = NKEYREF_NC;
}
}
if (keystat.ref[keycode] == NKEYREF_NC) {
keyboard_send(keycode);
}
#else
if ((keystat.ref[keycode] == NKEYREF_NC) ||
(!(kbexflag[keycode] & KBEX_NONREP))) {
keyboard_send(keycode);
}
#endif
keystat.ref[keycode] = ref;
}
else {
#if defined(SUPPORT_PC9801_119)
if (keyctrl.kbdtype != 0x03)
#endif
{
if (keycode == 0x7d) {
keycode = 0x70;
}
else if (keycode >= 0x75) {
continue;
}
}
if ((np2cfg.XSHIFT) &&
(((keycode == 0x70) && (np2cfg.XSHIFT & 1)) ||
((keycode == 0x74) && (np2cfg.XSHIFT & 2)) ||
((keycode == 0x73) && (np2cfg.XSHIFT & 4)))) {
keydata |= 0x80;
}
if (!(keydata & 0x80)) { // <20>V<EFBFBD>t<EFBFBD>g
if (keystat.ref[keycode] == NKEYREF_NC) {
keystat.ref[keycode] = ref;
keyboard_send(keycode);
}
}
else { // <20>V<EFBFBD>t<EFBFBD>g<EFBFBD><67><EFBFBD>J<EFBFBD>j<EFBFBD>J<EFBFBD><4A><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
if (keystat.ref[keycode] == NKEYREF_NC) {
keystat.ref[keycode] = ref;
data = keycode;
}
else {
keystat.ref[keycode] = NKEYREF_NC;
data = (REG8)(keycode + 0x80);
}
keyboard_send(data);
}
if ((keycode == 0x71) || (keycode == 0x72)) {
reloadled();
}
}
}
}
void keystat_up(const UINT8 *key, REG8 keys, REG8 ref) {
UINT8 keydata;
UINT8 keycode;
while(keys--) {
keydata = *key++;
keycode = (keydata & 0x7f);
if (keycode < 0x70) {
if (keystat.ref[keycode] == ref) {
keystat.ref[keycode] = NKEYREF_NC;
keyboard_send((REG8)(keycode + 0x80));
}
}
else {
#if defined(SUPPORT_PC9801_119)
if (keyctrl.kbdtype != 0x03)
#endif
{
if (keycode == 0x7d) {
keycode = 0x70;
}
else if (keycode >= 0x75) {
continue;
}
}
if ((np2cfg.XSHIFT) &&
(((keycode == 0x70) && (np2cfg.XSHIFT & 1)) ||
((keycode == 0x74) && (np2cfg.XSHIFT & 2)) ||
((keycode == 0x73) && (np2cfg.XSHIFT & 4)))) {
keydata |= 0x80;
}
if (!(keydata & 0x80)) { // <20>V<EFBFBD>t<EFBFBD>g
if (keystat.ref[keycode] != NKEYREF_NC) {
keystat.ref[keycode] = NKEYREF_NC;
keyboard_send((REG8)(keycode + 0x80));
if ((keycode == 0x71) || (keycode == 0x72)) {
reloadled();
}
}
}
}
}
}
void keystat_resendstat(void) {
REG8 i;
for (i=0; i<0x80; i++) {
if (keystat.ref[i] != NKEYREF_NC) {
keyboard_send(i);
}
}
}
// ----
void keystat_keydown(REG8 ref) {
UINT8 shift;
const NKEYM *nkey;
if ((ref >= NKEY_USER) && (ref < (NKEY_USER + NKEY_USERKEYS))) {
nkey = (NKEYM *)(nkeytbl.user + (ref - NKEY_USER));
keystat_down(nkey->key, nkey->keys, NKEYREF_USER);
}
else if (ref < NKEY_SYSTEM) {
if (np2cfg.KEY_MODE) {
shift = kbexflag[ref];
if (shift & KBEX_JOYKEY) {
keystat.extkey |= (1 << (shift & 7));
return;
}
}
nkey = (NKEYM *)(nkeytbl.key + ref);
keystat_down(nkey->key, nkey->keys, ref);
}
}
void keystat_keyup(REG8 ref) {
UINT8 shift;
const NKEYM *nkey;
if ((ref >= NKEY_USER) && (ref < (NKEY_USER + NKEY_USERKEYS))) {
nkey = (NKEYM *)(nkeytbl.user + (ref - NKEY_USER));
keystat_up(nkey->key, nkey->keys, NKEYREF_USER);
}
else if (ref < NKEY_SYSTEM) {
if (np2cfg.KEY_MODE) {
shift = kbexflag[ref];
if (shift & KBEX_JOYKEY) {
keystat.extkey &= ~(1 << (shift & 7));
return;
}
}
nkey = (NKEYM *)(nkeytbl.key + ref);
keystat_up(nkey->key, nkey->keys, ref);
}
}
void keystat_releaseref(REG8 ref) {
REG8 i;
for (i=0; i<0x80; i++) {
if (keystat.ref[i] == ref) {
keystat.ref[i] = NKEYREF_NC;
keyboard_send((REG8)(i + 0x80));
}
}
}
void keystat_resetjoykey(void) {
REG8 i;
keystat.extkey = 0;
for (i=0; i<0x80; i++) {
if (kbexflag[i] & KBEX_JOYKEY) {
keystat_releaseref(i);
}
}
}
void keystat_releasekey(REG8 key) {
key &= 0x7f;
if ((key != 0x71) && (key != 0x72)) {
if (keystat.ref[key] != NKEYREF_NC) {
keystat.ref[key] = NKEYREF_NC;
keyboard_send((REG8)(key + 0x80));
}
}
}
void keystat_allrelease(void) {
REG8 i;
for (i=0; i<0x80; i++) {
keystat_releasekey(i);
}
}
REG8 keystat_getjoy(void) {
return(~keystat.extkey);
}
REG8 keystat_getmouse(SINT16 *x, SINT16 *y) {
REG8 btn;
UINT8 acc;
SINT16 tmp;
REG8 ret;
btn = ~keystat.extkey;
acc = btn | keystat.mouselast;
keystat.mouselast = (UINT8)btn;
tmp = 0;
if (!(btn & 1)) {
tmp -= mousedelta[keystat.d_up];
}
if (!(acc & 1)) {
if (keystat.d_up < MOUSESTEPMAX) {
keystat.d_up++;
}
}
else {
keystat.d_up = 0;
}
if (!(btn & 2)) {
tmp += mousedelta[keystat.d_dn];
}
if (!(acc & 2)) {
if (keystat.d_dn < MOUSESTEPMAX) {
keystat.d_dn++;
}
}
else {
keystat.d_dn = 0;
}
*y += tmp;
tmp = 0;
if (!(btn & 4)) {
tmp -= mousedelta[keystat.d_lt];
}
if (!(acc & 4)) {
if (keystat.d_lt < MOUSESTEPMAX) {
keystat.d_lt++;
}
}
else {
keystat.d_lt = 0;
}
if (!(btn & 8)) {
tmp += mousedelta[keystat.d_rt];
}
if (!(acc & 8)) {
if (keystat.d_rt < MOUSESTEPMAX) {
keystat.d_rt++;
}
}
else {
keystat.d_rt = 0;
}
*x += tmp;
ret = 0x5f;
ret += (btn & 0x10) << 3;
ret += (btn & 0x20);
return(ret);
}
// ----
// <20>L<EFBFBD>[<5B>R<EFBFBD>[<5B>h<EFBFBD>ύX
static REG8 cnvnewcode(REG8 oldcode) {
switch(oldcode) {
case 0x71: // <20>ʏ<EFBFBD>caps
return(0x81);
case 0x72: // <20>ʏ<EFBFBD><CA8F>J<EFBFBD>i
return(0x82);
case 0x79: // <20><><EFBFBD>J<EFBFBD>j<EFBFBD>J<EFBFBD><4A><EFBFBD><EFBFBD><EFBFBD>b<EFBFBD>Ncaps
return(0x71);
case 0x7a: // <20><><EFBFBD>J<EFBFBD>j<EFBFBD>J<EFBFBD><4A><EFBFBD><EFBFBD><EFBFBD>b<EFBFBD>Ncaps
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);
}
}
void keystat_forcerelease(REG8 data) {
REG8 keycode;
keycode = cnvnewcode((REG8)(data & 0x7f));
keystat_releasekey(keycode);
}