Diff for /np2/keystat.c between versions 1.1 and 1.9

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);
   }
   

Removed from v.1.1  
changed lines
  Added in v.1.9


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