|
|
| version 1.1, 2004/02/18 03:24:48 | version 1.9, 2004/03/30 08:48:46 |
|---|---|
| Line 1 | Line 1 |
| #include "compiler.h" | #include "compiler.h" |
| #include "dosio.h" | |
| #include "textfile.h" | |
| #include "pccore.h" | #include "pccore.h" |
| #include "iocore.h" | #include "iocore.h" |
| #include "keystat.h" | #include "keystat.h" |
| #include "keystat.tbl" | |
| static UINT8 keystat[0x80]; | typedef struct { |
| UINT8 ref[0x80]; | |
| UINT8 extkey; | |
| UINT8 mouselast; | |
| UINT8 padding; | |
| UINT8 d_up; | |
| UINT8 d_dn; | |
| UINT8 d_lt; | |
| UINT8 d_rt; | |
| } KEYSTAT; | |
| static const UINT8 joykeytable[12] = { | NKEYTBL nkeytbl; |
| 0x2a, 0x34, | KEYCTRL keyctrl; |
| 0x29, 0x1c, | static KEYSTAT keystat; |
| 0x3c, 0x48, | |
| 0x3b, 0x46, | |
| 0x3d, 0x4b, | |
| 0x3a, 0x43}; | |
| static const UINT8 kbexflag[0x80] = { | |
| // ESC, 1, 2, 3, 4, 5, 6, 7 ; 00h | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| // 8, 9, 0, −, ^, ¥, BS, TAB ; 08h | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| // Q, W, E, R, T, Y, U, I ; 10h | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| // O, P, @, [, Ret, A, S, D ; 18h | |
| 0, 0, 0, 0, 1, 0, 0, 0, | |
| // F, G, H, J, K, L, ;, : ; 20h | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| // ], Z, X, C, V, B, N, M ; 28h | |
| 0, 1, 1, 0, 0, 0, 0, 0, | |
| // ,, ., /, _, SPC,XFER,RLUP,RLDN ; 30h | |
| 0, 0, 0, 0, 1, 0, 0, 0, | |
| // INS, DEL, ↑, ←, →, ↓,HMCR,HELP ; 38h | |
| 2, 0, 1, 1, 1, 1, 0, 0, | |
| // <−>,</>,<7>,<8>,<9>,<*>,<4>,<5> ; 40h | |
| 0, 0, 0, 1, 0, 0, 1, 0, | |
| // <6>,<+>,<1>,<2>,<3>,<=>,<0>,<,> ; 48h | |
| 1, 0, 0, 1, 0, 0, 0, 0, | |
| // <.>,NFER,vf.1,vf.2,vf.3,vf.4,vf.5, ; 50h | |
| 0, 0, 2, 2, 2, 2, 2, 0, | |
| // , , , , , ,HOME, ; 58h | |
| 0, 0, 0, 0, 0, 0, 0, 0, | |
| // STOP,COPY, f.1, f.2, f.3, f.4, f.5, f.6 ; 60h | |
| 0, 0, 2, 2, 2, 2, 2, 2, | |
| // f.7, f.8, f.9, f10, , , , ; 68h | |
| 2, 2, 2, 2, 0, 0, 0, 0, | |
| // SFT,CAPS,KANA,GRPH,CTRL, , , ; 70h | |
| 2, 2, 2, 2, 2, 0, 0, 0, | |
| // , , , , , , , ; 78h | |
| 0, 0, 0, 0, 0, 0, 0, 0}; | |
| // ---- | void keystat_initialize(void) { |
| void keystat_reset(void) { | char path[MAX_PATH]; |
| ZeroMemory(keystat, sizeof(keystat)); | ZeroMemory(&keystat, sizeof(keystat)); |
| FillMemory(keystat.ref, sizeof(keystat.ref), NKEYREF_NC); | |
| keystat_tblreset(); | |
| getbiospath(path, "key.txt", sizeof(path)); | |
| keystat_tblload(path); | |
| } | } |
| void keystat_senddata(REG8 data) { | 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 char str_userkey1[] = "userkey1"; | |
| static const char str_userkey2[] = "userkey2"; | |
| static REG8 searchkeynum(const char *str, BOOL user) { | |
| const KEYNAME *n; | |
| const KEYNAME *nterm; | |
| n = keyname; | |
| nterm = keyname + (sizeof(keyname) / sizeof(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 char *filename) { | |
| REG8 key; | TEXTFILEH tfh; |
| BOOL keynochange; | char work[256]; |
| const _NKEYM *user; | char *p; |
| UINT i; | char *q; |
| char *r; | |
| key = data & 0x7f; | UINT8 ref; |
| keynochange = FALSE; | UINT8 key[15]; |
| UINT cnt; | |
| // CTRL:カナ 0x71,0x72 bit7==0でトグル処理 (標準処理) | |
| if ((key == 0x71) || (key == 0x72)) { | tfh = textfile_open(filename, 0x800); |
| if (data & 0x80) { | if (tfh == NULL) { |
| return; | goto kstbl_err; |
| } | } |
| data = key | (keystat[key] & 0x80); | while(textfile_read(tfh, work, sizeof(work)) == SUCCESS) { |
| keystat[key] ^= 0x80; | p = milstr_nextword(work); |
| } | q = milstr_chr(p, '\t'); |
| else if ((key == 0x76) || (key == 0x77)) { // user key | if (q == NULL) { |
| user = np2cfg.userkey + (key - 0x76); | q = milstr_chr(p, '='); |
| for (i=0; i<user->keys; i++) { | } |
| key = user->key[i] & 0x7f; | if (q == NULL) { |
| if (!((keystat[key] ^ data) & 0x80)) { | continue; |
| keystat[key] ^= 0x80; | } |
| keyboard_send((REG8)(key | (data & 0x80))); | *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++; | |
| } | } |
| } | } |
| return; | keystat_tblset(ref, key, cnt); |
| } | |
| textfile_close(tfh); | |
| kstbl_err: | |
| return; | |
| } | |
| // ---- | |
| void keystat_ctrl(REG8 dat) { | |
| return; // まだBIOSが未対応 | |
| 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 { | else { |
| if ((np2cfg.XSHIFT) && | switch(keyctrl.mode) { |
| (((key == 0x70) && (np2cfg.XSHIFT & 1)) || | #if defined(SUPPORT_PC9801_119) |
| ((key == 0x74) && (np2cfg.XSHIFT & 2)) || | case 0x95: |
| ((key == 0x73) && (np2cfg.XSHIFT & 4)))) { | keyctrl.kbdtype = dat; |
| if (data & 0x80) { | break; |
| return; | #endif |
| case 0x9d: | |
| break; | |
| case 0x9e: | |
| 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 ((keystat.ref[keycode] == NKEYREF_NC) || | |
| (!(kbexflag[keycode] & KBEX_NONREP))) { | |
| keyboard_send(keycode); | |
| } | } |
| data = key | (keystat[key] & 0x80); | keystat.ref[keycode] = ref; |
| keystat[key] ^= 0x80; | |
| } | } |
| else { | else { |
| // CTRL:カナ 0x79,0x7a bit7をそのまま通知 | #if defined(SUPPORT_PC9801_119) |
| // (ハードウェアでメカニカル処理してる場合) | if ((keyctrl.kbdtype != 0x03) && (keycode >= 0x75)) { |
| if ((key == 0x79) || (key == 0x7a)) { | continue; |
| key -= 0x08; | } |
| data -= 0x08; | #else |
| } | if (keycode >= 0x75) { |
| if (!((keystat[key] ^ data) & 0x80)) { | continue; |
| keystat[key] ^= 0x80; | } |
| } | #endif |
| else { | if ((np2cfg.XSHIFT) && |
| keynochange = TRUE; | (((keycode == 0x70) && (np2cfg.XSHIFT & 1)) || |
| if (kbexflag[key] & 2) { // キーリピート無し | ((keycode == 0x74) && (np2cfg.XSHIFT & 2)) || |
| return; | ((keycode == 0x73) && (np2cfg.XSHIFT & 4)))) { |
| keydata |= 0x80; | |
| } | |
| if (!(keydata & 0x80)) { // シフト | |
| if (keystat.ref[keycode] == NKEYREF_NC) { | |
| keystat.ref[keycode] = ref; | |
| keyboard_send(keycode); | |
| } | } |
| } | } |
| } | else { // シフトメカニカル処理 |
| } | if (keystat.ref[keycode] == NKEYREF_NC) { |
| if ((!np2cfg.KEY_MODE) || (!(kbexflag[key] & 1))) { | keystat.ref[keycode] = ref; |
| if (keynochange) { | data = keycode; |
| if (data & 0x80) { // ver0.30 | } |
| return; | else { |
| keystat.ref[keycode] = NKEYREF_NC; | |
| data = (REG8)(keycode + 0x80); | |
| } | |
| keyboard_send(data); | |
| } | } |
| keyboard_send((REG8)(data ^ 0x80)); | |
| } | } |
| keyboard_send(data); | |
| } | } |
| } | } |
| void keystat_forcerelease(REG8 value) { | void keystat_up(const UINT8 *key, REG8 keys, REG8 ref) { |
| REG8 key; | UINT8 keydata; |
| const _NKEYM *user; | UINT8 keycode; |
| UINT i; | |
| key = value & 0x7f; | while(keys--) { |
| if ((key != 0x76) && (key != 0x77)) { | keydata = *key++; |
| if (keystat[key] & 0x80) { | keycode = (keydata & 0x7f); |
| keystat[key] &= ~0x80; | if (keycode < 0x70) { |
| keyboard_send((REG8)(key | 0x80)); | if (keystat.ref[keycode] == ref) { |
| keystat.ref[keycode] = NKEYREF_NC; | |
| keyboard_send((REG8)(keycode + 0x80)); | |
| } | |
| } | } |
| } | else { |
| else { | #if defined(SUPPORT_PC9801_119) |
| user = np2cfg.userkey + (key - 0x76); | if ((keyctrl.kbdtype != 0x03) && (keycode >= 0x75)) { |
| for (i=0; i<user->keys; i++) { | continue; |
| key = user->key[i] & 0x7f; | } |
| if (keystat[key] & 0x80) { | #else |
| keystat[key] &= ~0x80; | if (keycode >= 0x75) { |
| keyboard_send((REG8)(key | 0x80)); | continue; |
| } | |
| #endif | |
| if ((np2cfg.XSHIFT) && | |
| (((keycode == 0x70) && (np2cfg.XSHIFT & 1)) || | |
| ((keycode == 0x74) && (np2cfg.XSHIFT & 2)) || | |
| ((keycode == 0x73) && (np2cfg.XSHIFT & 4)))) { | |
| keydata |= 0x80; | |
| } | |
| if (!(keydata & 0x80)) { // シフト | |
| if (keystat.ref[keycode] != NKEYREF_NC) { | |
| keystat.ref[keycode] = NKEYREF_NC; | |
| keyboard_send((REG8)(keycode + 0x80)); | |
| } | |
| } | } |
| } | } |
| } | } |
| } | } |
| void keystat_resetcopyhelp(void) { | void keystat_resendstat(void) { |
| REG8 i; | REG8 i; |
| for (i=0x60; i<0x62; i++) { | for (i=0; i<0x80; i++) { |
| if (keystat[i] & 0x80) { | if (keystat.ref[i] != NKEYREF_NC) { |
| keystat[i] &= 0x7f; | keyboard_send(i); |
| keyboard_send((REG8)(i | 0x80)); | |
| } | } |
| } | } |
| } | } |
| void keystat_allrelease(void) { | |
| REG8 i; | // ---- |
| for (i=0; i<0x80; i++) { | void keystat_keydown(REG8 ref) { |
| if (keystat[i] & 0x80) { | |
| keystat[i] &= ~0x80; | UINT8 shift; |
| keyboard_send((REG8)(i | 0x80)); | 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_resetjoykey(void) { | void keystat_keyup(REG8 ref) { |
| int i; | UINT8 shift; |
| REG8 key; | const NKEYM *nkey; |
| for (i=0; i<12; i++) { | if ((ref >= NKEY_USER) && (ref < (NKEY_USER + NKEY_USERKEYS))) { |
| key = joykeytable[i]; | nkey = (NKEYM *)(nkeytbl.user + (ref - NKEY_USER)); |
| if (keystat[key] & 0x80) { | keystat_up(nkey->key, nkey->keys, NKEYREF_USER); |
| keystat[key] &= 0x7f; | } |
| keyboard_send((REG8)(key | 0x80)); | 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_resendstat(void) { | void keystat_releaseref(REG8 ref) { |
| int i; | REG8 i; |
| for (i=0; i<0x80; i++) { | for (i=0; i<0x80; i++) { |
| if (keystat[i]) { | if (keystat.ref[i] == ref) { |
| keyboard_send((REG8)i); | keystat.ref[i] = NKEYREF_NC; |
| keyboard_send((REG8)(i + 0x80)); | |
| } | } |
| } | } |
| } | } |
| void keystat_resetjoykey(void) { | |
| // ---- | REG8 i; |
| typedef struct { | keystat.extkey = 0; |
| UINT8 joysync; | for (i=0; i<0x80; i++) { |
| UINT8 joylast; | if (kbexflag[i] & KBEX_JOYKEY) { |
| UINT8 mouselast; | keystat_releaseref(i); |
| UINT8 padding; | } |
| UINT8 d_up; | } |
| UINT8 d_dn; | } |
| UINT8 d_lt; | |
| UINT8 d_rt; | |
| } KEYEXT; | |
| static KEYEXT keyext; | |
| static const UINT8 mousedelta[] = {1, 1, 1, 1, | |
| 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 2, 3, 3, 4}; | |
| #define MOUSESTEPMAX ((sizeof(mousedelta) / sizeof(UINT8)) - 1) | |
| void keystat_sync(void) { | void keystat_releasekey(REG8 key) { |
| keyext.joysync = 0; | key &= 0x7f; |
| if (keystat.ref[key] != NKEYREF_NC) { | |
| keystat.ref[key] = NKEYREF_NC; | |
| keyboard_send((REG8)(key + 0x80)); | |
| } | |
| } | } |
| REG8 keystat_getjoy(void) { | void keystat_allrelease(void) { |
| BYTE flg; | REG8 i; |
| const BYTE *p; | |
| BYTE bit; | for (i=0; i<0x80; i++) { |
| keystat_releasekey(i); | |
| if (!keyext.joysync) { | |
| keyext.joysync = 1; | |
| flg = 0xff; | |
| p = joykeytable; | |
| for (bit=0x20; bit; bit>>=1) { | |
| if ((keystat[p[0]] & 0x80) || (keystat[p[1]] & 0x80)) { | |
| flg ^= bit; | |
| } | |
| p += 2; | |
| } | |
| keyext.joylast = flg; | |
| } | } |
| return(keyext.joylast); | } |
| REG8 keystat_getjoy(void) { | |
| return(~keystat.extkey); | |
| } | } |
| REG8 keystat_getmouse(SINT16 *x, SINT16 *y) { | REG8 keystat_getmouse(SINT16 *x, SINT16 *y) { |
| REG8 btn; | REG8 btn; |
| BYTE acc; | UINT8 acc; |
| SINT16 tmp; | SINT16 tmp; |
| BYTE ret; | REG8 ret; |
| btn = keystat_getjoy(); | btn = ~keystat.extkey; |
| acc = btn | keyext.mouselast; | acc = btn | keystat.mouselast; |
| keyext.mouselast = (UINT8)btn; | keystat.mouselast = (UINT8)btn; |
| tmp = 0; | tmp = 0; |
| if (!(btn & 1)) { | if (!(btn & 1)) { |
| tmp -= mousedelta[keyext.d_up]; | tmp -= mousedelta[keystat.d_up]; |
| } | } |
| if (!(acc & 1)) { | if (!(acc & 1)) { |
| if (keyext.d_up < MOUSESTEPMAX) { | if (keystat.d_up < MOUSESTEPMAX) { |
| keyext.d_up++; | keystat.d_up++; |
| } | } |
| } | } |
| else { | else { |
| keyext.d_up = 0; | keystat.d_up = 0; |
| } | } |
| if (!(btn & 2)) { | if (!(btn & 2)) { |
| tmp += mousedelta[keyext.d_dn]; | tmp += mousedelta[keystat.d_dn]; |
| } | } |
| if (!(acc & 2)) { | if (!(acc & 2)) { |
| if (keyext.d_dn < MOUSESTEPMAX) { | if (keystat.d_dn < MOUSESTEPMAX) { |
| keyext.d_dn++; | keystat.d_dn++; |
| } | } |
| } | } |
| else { | else { |
| keyext.d_dn = 0; | keystat.d_dn = 0; |
| } | } |
| *y += tmp; | *y += tmp; |
| tmp = 0; | tmp = 0; |
| if (!(btn & 4)) { | if (!(btn & 4)) { |
| tmp -= mousedelta[keyext.d_lt]; | tmp -= mousedelta[keystat.d_lt]; |
| } | } |
| if (!(acc & 4)) { | if (!(acc & 4)) { |
| if (keyext.d_lt < MOUSESTEPMAX) { | if (keystat.d_lt < MOUSESTEPMAX) { |
| keyext.d_lt++; | keystat.d_lt++; |
| } | } |
| } | } |
| else { | else { |
| keyext.d_lt = 0; | keystat.d_lt = 0; |
| } | } |
| if (!(btn & 8)) { | if (!(btn & 8)) { |
| tmp += mousedelta[keyext.d_rt]; | tmp += mousedelta[keystat.d_rt]; |
| } | } |
| if (!(acc & 8)) { | if (!(acc & 8)) { |
| if (keyext.d_rt < MOUSESTEPMAX) { | if (keystat.d_rt < MOUSESTEPMAX) { |
| keyext.d_rt++; | keystat.d_rt++; |
| } | } |
| } | } |
| else { | else { |
| keyext.d_rt = 0; | keystat.d_rt = 0; |
| } | } |
| *x += tmp; | *x += tmp; |
| Line 311 REG8 keystat_getmouse(SINT16 *x, SINT16 | Line 478 REG8 keystat_getmouse(SINT16 *x, SINT16 |
| return(ret); | return(ret); |
| } | } |
| // ---- | |
| // キーコード変更 | |
| 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); | |
| } | |
| } | |
| void keystat_forcerelease(REG8 data) { | |
| REG8 keycode; | |
| keycode = cnvnewcode((REG8)(data & 0x7f)); | |
| keystat_releasekey(keycode); | |
| } | |