DOSBox-X
|
00001 #include "np2glue.h" 00002 //#include "compiler.h" 00003 00004 #if defined(SUPPORT_KEYDISP) 00005 00006 #include "pccore.h" 00007 #include "iocore.h" 00008 #include "sound.h" 00009 #include "fmboard.h" 00010 #include "keydisp.h" 00011 00012 typedef struct { 00013 UINT16 posx; 00014 UINT16 pals; 00015 const UINT8 *data; 00016 } KDKEYPOS; 00017 00018 typedef struct { 00019 UINT8 k[KEYDISP_NOTEMAX]; 00020 UINT8 r[KEYDISP_NOTEMAX]; 00021 UINT remain; 00022 UINT8 flag; 00023 UINT8 padding[3]; 00024 } KDCHANNEL; 00025 00026 typedef struct { 00027 UINT8 ch; 00028 UINT8 key; 00029 } KDDELAYE; 00030 00031 typedef struct { 00032 UINT pos; 00033 UINT rem; 00034 UINT8 warm; 00035 UINT8 warmbase; 00036 } KDDELAY; 00037 00038 typedef struct { 00039 UINT16 fnum[4]; 00040 UINT8 lastnote[4]; 00041 UINT8 flag; 00042 UINT8 extflag; 00043 } KDFMCTRL; 00044 00045 typedef struct { 00046 UINT16 fto[4]; 00047 UINT8 lastnote[4]; 00048 UINT8 flag; 00049 UINT8 mix; 00050 UINT8 padding[2]; 00051 } KDPSGCTRL; 00052 00053 typedef struct { 00054 UINT8 mode; 00055 UINT8 dispflag; 00056 UINT8 framepast; 00057 UINT8 keymax; 00058 UINT8 fmmax; 00059 UINT8 psgmax; 00060 UINT8 fmpos[KEYDISP_FMCHMAX]; 00061 UINT8 psgpos[KEYDISP_PSGMAX]; 00062 const UINT8 *pfmreg[KEYDISP_FMCHMAX]; 00063 KDDELAY delay; 00064 KDCHANNEL ch[KEYDISP_CHMAX]; 00065 KDFMCTRL fmctl[KEYDISP_FMCHMAX]; 00066 KDPSGCTRL psgctl[KEYDISP_PSGMAX]; 00067 UINT8 pal8[KEYDISP_PALS]; 00068 UINT16 pal16[KEYDISP_LEVEL*2]; 00069 RGB32 pal32[KEYDISP_LEVEL*2]; 00070 KDKEYPOS keypos[128]; 00071 KDDELAYE delaye[KEYDISP_DELAYEVENTS]; 00072 } KEYDISP; 00073 00074 static KEYDISP keydisp; 00075 00076 #include "keydisp.res" 00077 00078 00079 // ---- event 00080 00081 static void keyon(UINT ch, UINT8 note) { 00082 00083 UINT i; 00084 KDCHANNEL *kdch; 00085 00086 note &= 0x7f; 00087 kdch = keydisp.ch + ch; 00088 for (i=0; i<kdch->remain; i++) { 00089 if (kdch->k[i] == note) { // ヒットした 00090 for (; i<(kdch->remain-1); i++) { 00091 kdch->k[i] = kdch->k[i+1]; 00092 kdch->r[i] = kdch->r[i+1]; 00093 } 00094 kdch->k[i] = note; 00095 kdch->r[i] = 0x80 | (KEYDISP_LEVEL - 1); 00096 kdch->flag |= 1; 00097 return; 00098 } 00099 } 00100 if (i < KEYDISP_NOTEMAX) { 00101 kdch->k[i] = note; 00102 kdch->r[i] = 0x80 | (KEYDISP_LEVEL - 1); 00103 kdch->flag |= 1; 00104 kdch->remain++; 00105 } 00106 } 00107 00108 static void keyoff(UINT ch, UINT8 note) { 00109 00110 UINT i; 00111 KDCHANNEL *kdch; 00112 00113 note &= 0x7f; 00114 kdch = keydisp.ch + ch; 00115 for (i=0; i<kdch->remain; i++) { 00116 if (kdch->k[i] == note) { // ヒットした 00117 kdch->r[i] = 0x80 | (KEYDISP_LEVEL - 2); 00118 kdch->flag |= 1; 00119 break; 00120 } 00121 } 00122 } 00123 00124 static void chkeyoff(UINT ch) { 00125 00126 UINT i; 00127 KDCHANNEL *kdch; 00128 00129 kdch = keydisp.ch + ch; 00130 for (i=0; i<kdch->remain; i++) { 00131 if ((kdch->r[i] & (~0x80)) >= (KEYDISP_LEVEL - 1)) { 00132 kdch->r[i] = 0x80 | (KEYDISP_LEVEL - 2); 00133 kdch->flag |= 1; 00134 } 00135 } 00136 } 00137 00138 static void keyalloff(void) { 00139 00140 UINT8 i; 00141 00142 for (i=0; i<KEYDISP_CHMAX; i++) { 00143 chkeyoff(i); 00144 } 00145 } 00146 00147 static void keyallreload(void) { 00148 00149 UINT i; 00150 00151 for (i=0; i<KEYDISP_CHMAX; i++) { 00152 keydisp.ch[i].flag = 2; 00153 } 00154 } 00155 00156 static void keyallclear(void) { 00157 00158 ZeroMemory(keydisp.ch, sizeof(keydisp.ch)); 00159 keyallreload(); 00160 } 00161 00162 00163 // ---- delay event 00164 00165 static void delayreset(void) { 00166 00167 keydisp.delay.warm = keydisp.delay.warmbase; 00168 keydisp.delay.pos = 0; 00169 keydisp.delay.rem = 0; 00170 ZeroMemory(keydisp.delaye, sizeof(keydisp.delaye)); 00171 keyalloff(); 00172 } 00173 00174 static void delayexecevent(UINT8 framepast) { 00175 00176 KDDELAYE *ebase; 00177 UINT pos; 00178 UINT rem; 00179 KDDELAYE *ev; 00180 00181 ebase = keydisp.delaye; 00182 pos = keydisp.delay.pos; 00183 rem = keydisp.delay.rem; 00184 while((keydisp.delay.warm) && (framepast)) { 00185 keydisp.delay.warm--; 00186 framepast--; 00187 if (rem >= KEYDISP_DELAYEVENTS) { 00188 ev = ebase + pos; 00189 rem--; 00190 if (ev->ch == 0xff) { 00191 keydisp.delay.warm++; 00192 } 00193 else if (ev->key & 0x80) { 00194 keyon(ev->ch, ev->key); 00195 rem--; 00196 } 00197 else { 00198 keyoff(ev->ch, ev->key); 00199 } 00200 pos = (pos + 1) & (KEYDISP_DELAYEVENTS - 1); 00201 } 00202 ebase[(pos + rem) & (KEYDISP_DELAYEVENTS - 1)].ch = 0xff; 00203 rem++; 00204 } 00205 while(framepast) { 00206 framepast--; 00207 while(rem) { 00208 rem--; 00209 ev = ebase + pos; 00210 if (ev->ch == 0xff) { 00211 pos = (pos + 1) & (KEYDISP_DELAYEVENTS - 1); 00212 break; 00213 } 00214 if (ev->key & 0x80) { 00215 keyon(ev->ch, ev->key); 00216 } 00217 else { 00218 keyoff(ev->ch, ev->key); 00219 } 00220 pos = (pos + 1) & (KEYDISP_DELAYEVENTS - 1); 00221 } 00222 ebase[(pos + rem) & (KEYDISP_DELAYEVENTS - 1)].ch = 0xff; 00223 rem++; 00224 } 00225 keydisp.delay.pos = pos; 00226 keydisp.delay.rem = rem; 00227 } 00228 00229 static void delaysetevent(UINT8 ch, UINT8 key) { 00230 00231 KDDELAYE *e; 00232 00233 e = keydisp.delaye; 00234 if (keydisp.delay.rem < KEYDISP_DELAYEVENTS) { 00235 e += (keydisp.delay.pos + keydisp.delay.rem) & 00236 (KEYDISP_DELAYEVENTS - 1); 00237 keydisp.delay.rem++; 00238 e->ch = ch; 00239 e->key = key; 00240 } 00241 else { 00242 e += keydisp.delay.pos; 00243 keydisp.delay.pos += (keydisp.delay.pos + 1) & 00244 (KEYDISP_DELAYEVENTS - 1); 00245 if (e->ch == 0xff) { 00246 keydisp.delay.warm++; 00247 } 00248 else if (e->key & 0x80) { 00249 keyon(e->ch, e->key); 00250 } 00251 else { 00252 keyoff(e->ch, e->key); 00253 } 00254 e->ch = ch; 00255 e->key = key; 00256 } 00257 } 00258 00259 00260 // ---- FM 00261 00262 static UINT8 getfmnote(UINT16 fnum) { 00263 00264 UINT8 ret; 00265 int i; 00266 00267 ret = (fnum >> 11) & 7; 00268 ret *= 12; 00269 ret += 24; 00270 fnum &= 0x7ff; 00271 00272 while(fnum < FNUM_MIN) { 00273 if (!ret) { 00274 return(0); 00275 } 00276 ret -= 12; 00277 fnum <<= 1; 00278 } 00279 while(fnum > FNUM_MAX) { 00280 fnum >>= 1; 00281 ret += 12; 00282 } 00283 for (i=0; fnum >= fnumtbl[i]; i++) { 00284 ret++; 00285 } 00286 if (ret > 127) { 00287 return(127); 00288 } 00289 return(ret); 00290 } 00291 00292 static void fmkeyoff(UINT8 ch, KDFMCTRL *k) { 00293 00294 delaysetevent(keydisp.fmpos[ch], k->lastnote[0]); 00295 } 00296 00297 static void fmkeyon(UINT8 ch, KDFMCTRL *k) { 00298 00299 const UINT8 *pReg; 00300 00301 fmkeyoff(ch, k); 00302 pReg = keydisp.pfmreg[ch]; 00303 if (pReg) 00304 { 00305 pReg = pReg + 0xa0; 00306 k->fnum[0] = ((pReg[4] & 0x3f) << 8) + pReg[0]; 00307 k->lastnote[0] = getfmnote(k->fnum[0]); 00308 delaysetevent(keydisp.fmpos[ch], (UINT8)(k->lastnote[0] | 0x80)); 00309 } 00310 } 00311 00312 static void fmkeyreset(void) { 00313 00314 ZeroMemory(keydisp.fmctl, sizeof(keydisp.fmctl)); 00315 } 00316 00317 void keydisp_fmkeyon(UINT8 ch, UINT8 value) { 00318 00319 KDFMCTRL *k; 00320 00321 if (keydisp.mode != KEYDISP_MODEFM) { 00322 return; 00323 } 00324 if (ch < keydisp.fmmax) { 00325 k = keydisp.fmctl + ch; 00326 value &= 0xf0; 00327 if (k->flag != value) { 00328 if (value) { 00329 fmkeyon(ch, k); 00330 } 00331 else { 00332 fmkeyoff(ch, k); 00333 } 00334 k->flag = value; 00335 } 00336 } 00337 } 00338 00339 static void fmkeysync(void) { 00340 00341 UINT8 ch; 00342 KDFMCTRL *k; 00343 const UINT8 *pReg; 00344 UINT16 fnum; 00345 00346 for (ch=0, k=keydisp.fmctl; ch<keydisp.fmmax; ch++, k++) { 00347 if (k->flag) { 00348 pReg = keydisp.pfmreg[ch]; 00349 if (pReg) 00350 { 00351 pReg = pReg + 0xa0; 00352 fnum = ((pReg[4] & 0x3f) << 8) + pReg[0]; 00353 if (k->fnum[0] != fnum) { 00354 UINT8 n; 00355 k->fnum[0] = fnum; 00356 n = getfmnote(fnum); 00357 if (k->lastnote[0] != n) { 00358 fmkeyoff(ch, k); 00359 } 00360 k->lastnote[0] = n; 00361 delaysetevent(keydisp.fmpos[ch], 00362 (UINT8)(k->lastnote[0] | 0x80)); 00363 } 00364 } 00365 } 00366 } 00367 } 00368 00369 00370 // ---- PSG 00371 00372 static const void *psgtbl[3] = {&psg1, &psg2, &psg3}; 00373 00374 static UINT8 getpsgnote(UINT16 tone) { 00375 00376 UINT8 ret; 00377 int i; 00378 00379 ret = 60; 00380 tone &= 0xfff; 00381 00382 while(tone < FTO_MIN) { 00383 tone <<= 1; 00384 ret += 12; 00385 if (ret >= 128) { 00386 return(127); 00387 } 00388 } 00389 while(tone > FTO_MAX) { 00390 if (!ret) { 00391 return(0); 00392 } 00393 tone >>= 1; 00394 ret -= 12; 00395 } 00396 for (i=0; tone < ftotbl[i]; i++) { 00397 ret++; 00398 } 00399 if (ret >= 128) { 00400 return(127); 00401 } 00402 return(ret); 00403 } 00404 00405 static void psgmix(UINT8 ch, PSGGEN psg) { 00406 00407 KDPSGCTRL *k; 00408 00409 k = keydisp.psgctl + ch; 00410 if ((k->mix ^ psg->reg.mixer) & 7) { 00411 UINT8 i, bit, pos; 00412 k->mix = psg->reg.mixer; 00413 pos = keydisp.psgpos[ch]; 00414 for (i=0, bit=1; i<3; i++, pos++, bit<<=1) { 00415 if (k->flag & bit) { 00416 k->flag ^= bit; 00417 delaysetevent(pos, k->lastnote[i]); 00418 } 00419 else if ((!(k->mix & bit)) && (psg->reg.vol[i] & 0x1f)) { 00420 k->flag |= bit; 00421 k->fto[i] = LOADINTELWORD(psg->reg.tune[i]) & 0xfff; 00422 k->lastnote[i] = getpsgnote(k->fto[i]); 00423 delaysetevent(pos, (UINT8)(k->lastnote[i] | 0x80)); 00424 } 00425 } 00426 } 00427 } 00428 00429 static void psgvol(UINT8 ch, PSGGEN psg, UINT8 i) { 00430 00431 KDPSGCTRL *k; 00432 UINT8 bit; 00433 UINT8 pos; 00434 UINT16 tune; 00435 00436 k = keydisp.psgctl + ch; 00437 bit = (1 << i); 00438 pos = keydisp.psgpos[ch] + i; 00439 if (psg->reg.vol[i] & 0x1f) { 00440 if (!((k->mix | k->flag) & bit)) { 00441 k->flag |= bit; 00442 tune = LOADINTELWORD(psg->reg.tune[i]); 00443 tune &= 0xfff; 00444 k->fto[i] = tune; 00445 k->lastnote[i] = getpsgnote(tune); 00446 delaysetevent(pos, (UINT8)(k->lastnote[i] | 0x80)); 00447 } 00448 } 00449 else if (k->flag & bit) { 00450 k->flag ^= bit; 00451 delaysetevent(pos, k->lastnote[i]); 00452 } 00453 } 00454 00455 static void psgkeyreset(void) { 00456 00457 ZeroMemory(keydisp.psgctl, sizeof(keydisp.psgctl)); 00458 } 00459 00460 void keydisp_psgmix(void *psg) { 00461 00462 UINT8 c; 00463 00464 if (keydisp.mode != KEYDISP_MODEFM) { 00465 return; 00466 } 00467 for (c=0; c<keydisp.psgmax; c++) { 00468 if (psgtbl[c] == psg) { 00469 psgmix(c, (PSGGEN)psg); 00470 break; 00471 } 00472 } 00473 } 00474 00475 void keydisp_psgvol(void *psg, UINT8 ch) { 00476 00477 UINT8 c; 00478 00479 if (keydisp.mode != KEYDISP_MODEFM) { 00480 return; 00481 } 00482 for (c=0; c<keydisp.psgmax; c++) { 00483 if (psgtbl[c] == psg) { 00484 psgvol(c, (PSGGEN)psg, ch); 00485 break; 00486 } 00487 } 00488 } 00489 00490 static void psgkeysync(void) { 00491 00492 UINT8 ch; 00493 KDPSGCTRL *k; 00494 UINT8 bit; 00495 UINT8 i; 00496 UINT8 pos; 00497 PSGGEN psg; 00498 UINT16 tune; 00499 UINT8 n; 00500 00501 for (ch=0, k=keydisp.psgctl; ch<keydisp.psgmax; ch++, k++) { 00502 psg = (PSGGEN)psgtbl[ch]; 00503 pos = keydisp.psgpos[ch]; 00504 for (i=0, bit=1; i<3; i++, pos++, bit<<=1) { 00505 if (k->flag & bit) { 00506 tune = LOADINTELWORD(psg->reg.tune[i]); 00507 tune &= 0xfff; 00508 if (k->fto[i] != tune) { 00509 k->fto[i] = tune; 00510 n = getpsgnote(tune); 00511 if (k->lastnote[i] != n) { 00512 delaysetevent(pos, k->lastnote[i]); 00513 k->lastnote[i] = n; 00514 delaysetevent(pos, (UINT8)(n | 0x80)); 00515 } 00516 } 00517 } 00518 } 00519 } 00520 } 00521 00522 00523 // ---- BOARD change... 00524 00525 static void setfmhdl(UINT8 items, UINT base) { 00526 00527 while(items--) { 00528 if ((keydisp.keymax < KEYDISP_CHMAX) && 00529 (keydisp.fmmax < KEYDISP_FMCHMAX)) { 00530 keydisp.fmpos[keydisp.fmmax] = keydisp.keymax++; 00531 keydisp.pfmreg[keydisp.fmmax] = opn.reg + base; 00532 keydisp.fmmax++; 00533 base++; 00534 if ((base & 3) == 3) { 00535 base += 0x100 - 3; 00536 } 00537 } 00538 } 00539 } 00540 00541 #if defined(SUPPORT_PX) 00542 static void setfmhdlex(const OPN_T *pOpn, UINT nItems, UINT nBase) { 00543 00544 while(nItems--) { 00545 if ((keydisp.keymax < KEYDISP_CHMAX) && 00546 (keydisp.fmmax < KEYDISP_FMCHMAX)) { 00547 keydisp.fmpos[keydisp.fmmax] = keydisp.keymax++; 00548 keydisp.pfmreg[keydisp.fmmax] = pOpn->reg + nBase; 00549 keydisp.fmmax++; 00550 nBase++; 00551 if ((nBase & 3) == 3) { 00552 nBase += 0x100 - 3; 00553 } 00554 } 00555 } 00556 } 00557 #endif // defined(SUPPORT_PX) 00558 00559 static void setpsghdl(UINT8 items) { 00560 00561 while(items--) { 00562 if ((keydisp.keymax <= (KEYDISP_CHMAX - 3)) && 00563 (keydisp.psgmax < KEYDISP_PSGMAX)) { 00564 keydisp.psgpos[keydisp.psgmax++] = keydisp.keymax; 00565 keydisp.keymax += 3; 00566 } 00567 } 00568 } 00569 00570 void keydisp_setfmboard(UINT b) { 00571 00572 keydisp.keymax = 0; 00573 keydisp.fmmax = 0; 00574 keydisp.psgmax = 0; 00575 00576 #if defined(SUPPORT_PX) 00577 if (b == 0x30) 00578 { 00579 setfmhdlex(&opn, 12, 0); 00580 setfmhdlex(&opn2, 12, 0); 00581 setpsghdl(2); 00582 b = 0; 00583 } 00584 if (b == 0x50) 00585 { 00586 setfmhdlex(&opn, 12, 0); 00587 setfmhdlex(&opn2, 12, 0); 00588 setfmhdlex(&opn3, 6, 0); 00589 setpsghdl(3); 00590 b = 0; 00591 } 00592 00593 #endif // defined(SUPPORT_PX) 00594 00595 if (b & 0x02) { 00596 if (!(b & 0x04)) { 00597 setfmhdl(3, 0); 00598 } 00599 else { // 2枚刺しの時レジスタ移動 00600 setfmhdl(3, 0x200); 00601 } 00602 setpsghdl(1); 00603 } 00604 if (b & 0x04) { 00605 setfmhdl(6, 0); 00606 setpsghdl(1); 00607 } 00608 if (b & 0x08) { 00609 setfmhdl(6, 0); 00610 setpsghdl(1); 00611 } 00612 if (b & 0x20) { 00613 setfmhdl(6, 0); 00614 setpsghdl(1); 00615 } 00616 if (b & 0x40) { 00617 setfmhdl(12, 0); 00618 setpsghdl(1); 00619 } 00620 if (b & 0x80) { 00621 setpsghdl(3); 00622 } 00623 delayreset(); 00624 fmkeyreset(); 00625 psgkeyreset(); 00626 00627 if (keydisp.mode == KEYDISP_MODEFM) { 00628 keydisp.dispflag |= KEYDISP_FLAGSIZING; 00629 } 00630 } 00631 00632 00633 // ---- MIDI 00634 00635 void keydisp_midi(const UINT8 *cmd) { 00636 00637 if (keydisp.mode != KEYDISP_MODEMIDI) { 00638 return; 00639 } 00640 switch(cmd[0] & 0xf0) { 00641 case 0x80: 00642 keyoff(cmd[0] & 0x0f, cmd[1]); 00643 break; 00644 00645 case 0x90: 00646 if (cmd[2] & 0x7f) { 00647 keyon(cmd[0] & 0x0f, cmd[1]); 00648 } 00649 else { 00650 keyoff(cmd[0] & 0x0f, cmd[1]); 00651 } 00652 break; 00653 00654 case 0xb0: 00655 if ((cmd[1] == 0x78) || (cmd[1] == 0x79) || (cmd[1] == 0x7b)) { 00656 chkeyoff(cmd[0] & 0x0f); 00657 } 00658 break; 00659 00660 case 0xfe: 00661 keyalloff(); 00662 break; 00663 } 00664 } 00665 00666 00667 // ---- draw 00668 00669 static int getdispkeys(void) { 00670 00671 int keys; 00672 00673 switch(keydisp.mode) { 00674 case KEYDISP_MODEFM: 00675 keys = keydisp.keymax; 00676 break; 00677 00678 case KEYDISP_MODEMIDI: 00679 keys = 16; 00680 break; 00681 00682 default: 00683 keys = 0; 00684 break; 00685 } 00686 if (keys > KEYDISP_CHMAX) { 00687 keys = KEYDISP_CHMAX; 00688 } 00689 return(keys); 00690 } 00691 00692 static void clearrect(CMNVRAM *vram, int x, int y, int cx, int cy) { 00693 00694 CMNPAL col; 00695 00696 switch(vram->bpp) { 00697 #if defined(SUPPORT_8BPP) 00698 case 8: 00699 col.pal8 = keydisp.pal8[KEYDISP_PALBG]; 00700 break; 00701 #endif 00702 #if defined(SUPPORT_16BPP) 00703 case 16: 00704 col.pal16 = keydisp.pal16[KEYDISP_LEVEL]; 00705 break; 00706 #endif 00707 #if defined(SUPPORT_24BPP) 00708 case 24: 00709 #endif 00710 #if defined(SUPPORT_32BPP) 00711 case 32: 00712 #endif 00713 #if defined(SUPPORT_24BPP) || defined(SUPPORT_32BPP) 00714 col.pal32 = keydisp.pal32[KEYDISP_LEVEL]; 00715 break; 00716 #endif 00717 default: 00718 return; 00719 } 00720 cmndraw_fill(vram, x, y, cx, cy, col); 00721 } 00722 00723 static void drawkeybg(CMNVRAM *vram) { 00724 00725 CMNPAL bg; 00726 CMNPAL fg; 00727 int i; 00728 00729 switch(vram->bpp) { 00730 #if defined(SUPPORT_8BPP) 00731 case 8: 00732 bg.pal8 = keydisp.pal8[KEYDISP_PALBG]; 00733 fg.pal8 = keydisp.pal8[KEYDISP_PALFG]; 00734 break; 00735 #endif 00736 #if defined(SUPPORT_16BPP) 00737 case 16: 00738 bg.pal16 = keydisp.pal16[KEYDISP_LEVEL]; 00739 fg.pal16 = keydisp.pal16[0]; 00740 break; 00741 #endif 00742 #if defined(SUPPORT_24BPP) 00743 case 24: 00744 bg.pal32 = keydisp.pal32[KEYDISP_LEVEL]; 00745 fg.pal32 = keydisp.pal32[0]; 00746 break; 00747 #endif 00748 #if defined(SUPPORT_32BPP) 00749 case 32: 00750 bg.pal32 = keydisp.pal32[KEYDISP_LEVEL]; 00751 fg.pal32 = keydisp.pal32[0]; 00752 break; 00753 #endif 00754 default: 00755 return; 00756 } 00757 for (i=0; i<10; i++) { 00758 cmndraw_setpat(vram, keybrd1, i * KEYDISP_KEYCX, 0, bg, fg); 00759 } 00760 cmndraw_setpat(vram, keybrd2, 10 * KEYDISP_KEYCX, 0, bg, fg); 00761 } 00762 00763 static BOOL draw1key(CMNVRAM *vram, KDCHANNEL *kdch, UINT n) { 00764 00765 KDKEYPOS *pos; 00766 UINT pal; 00767 CMNPAL fg; 00768 00769 pos = keydisp.keypos + (kdch->k[n] & 0x7f); 00770 pal = kdch->r[n] & 0x7f; 00771 switch(vram->bpp) { 00772 #if defined(SUPPORT_8BPP) 00773 case 8: 00774 if (pal != (KEYDISP_LEVEL - 1)) { 00775 fg.pal8 = keydisp.pal8[ 00776 (pos->pals)?KEYDISP_PALBG:KEYDISP_PALFG]; 00777 cmndraw_setfg(vram, pos->data, pos->posx, 0, fg); 00778 kdch->r[n] = 0; 00779 return(TRUE); 00780 } 00781 fg.pal8 = keydisp.pal8[KEYDISP_PALHIT]; 00782 break; 00783 #endif 00784 #if defined(SUPPORT_16BPP) 00785 case 16: 00786 fg.pal16 = keydisp.pal16[pal + pos->pals]; 00787 break; 00788 #endif 00789 #if defined(SUPPORT_24BPP) 00790 case 24: 00791 fg.pal32 = keydisp.pal32[pal + pos->pals]; 00792 break; 00793 #endif 00794 #if defined(SUPPORT_32BPP) 00795 case 32: 00796 fg.pal32 = keydisp.pal32[pal + pos->pals]; 00797 break; 00798 #endif 00799 default: 00800 return(FALSE); 00801 } 00802 cmndraw_setfg(vram, pos->data, pos->posx, 0, fg); 00803 return(FALSE); 00804 } 00805 00806 static BOOL draw1ch(CMNVRAM *vram, UINT8 framepast, KDCHANNEL *kdch) { 00807 00808 BOOL draw; 00809 UINT i; 00810 BOOL coll; 00811 UINT8 nextf; 00812 UINT j; 00813 00814 draw = FALSE; 00815 if (kdch->flag & 2) { 00816 drawkeybg(vram); 00817 draw = TRUE; 00818 } 00819 if (kdch->flag) { 00820 coll = FALSE; 00821 nextf = 0; 00822 for (i=0; i<kdch->remain; i++) { 00823 if ((kdch->r[i] & 0x80) || (kdch->flag & 2)) { 00824 kdch->r[i] &= ~0x80; 00825 if (kdch->r[i] < (KEYDISP_LEVEL - 1)) { 00826 if (kdch->r[i] > framepast) { 00827 kdch->r[i] -= framepast; 00828 kdch->r[i] |= 0x80; 00829 nextf = 1; 00830 } 00831 else { 00832 kdch->r[i] = 0; 00833 coll = TRUE; 00834 } 00835 } 00836 coll |= draw1key(vram, kdch, i); 00837 draw = TRUE; 00838 } 00839 } 00840 if (coll) { 00841 for (i=0; i<kdch->remain; i++) { 00842 if (!kdch->r[i]) { 00843 break; 00844 } 00845 } 00846 for (j=i; i<kdch->remain; i++) { 00847 if (kdch->r[i]) { 00848 kdch->k[j] = kdch->k[i]; 00849 kdch->r[j] = kdch->r[i]; 00850 j++; 00851 } 00852 } 00853 kdch->remain = j; 00854 } 00855 kdch->flag = nextf; 00856 } 00857 return(draw); 00858 } 00859 00860 00861 // ---- 00862 00863 void keydisp_initialize(void) { 00864 00865 int r; 00866 UINT16 x; 00867 int i; 00868 00869 r = 0; 00870 x = 0; 00871 do { 00872 for (i=0; i<12 && r<128; i++, r++) { 00873 keydisp.keypos[r].posx = keyposdef[i].posx + x; 00874 keydisp.keypos[r].pals = keyposdef[i].pals; 00875 keydisp.keypos[r].data = keyposdef[i].data; 00876 } 00877 x += 28; 00878 } while(r < 128); 00879 keyallclear(); 00880 } 00881 00882 void keydisp_setpal(CMNPALFN *palfn) { 00883 00884 UINT i; 00885 RGB32 pal32[KEYDISP_PALS]; 00886 00887 if (palfn == NULL) { 00888 return; 00889 } 00890 if (palfn->get8) { 00891 for (i=0; i<KEYDISP_PALS; i++) { 00892 keydisp.pal8[i] = (*palfn->get8)(palfn, i); 00893 } 00894 } 00895 if (palfn->get32) { 00896 for (i=0; i<KEYDISP_PALS; i++) { 00897 pal32[i].d = (*palfn->get32)(palfn, i); 00898 cmndraw_makegrad(keydisp.pal32, KEYDISP_LEVEL, 00899 pal32[KEYDISP_PALFG], pal32[KEYDISP_PALHIT]); 00900 cmndraw_makegrad(keydisp.pal32 + KEYDISP_LEVEL, KEYDISP_LEVEL, 00901 pal32[KEYDISP_PALBG], pal32[KEYDISP_PALHIT]); 00902 } 00903 if (palfn->cnv16) { 00904 for (i=0; i<KEYDISP_LEVEL*2; i++) { 00905 keydisp.pal16[i] = (*palfn->cnv16)(palfn, keydisp.pal32[i]); 00906 } 00907 } 00908 } 00909 keydisp.dispflag |= KEYDISP_FLAGREDRAW; 00910 } 00911 00912 void keydisp_setmode(UINT8 mode) { 00913 00914 if (keydisp.mode != mode) { 00915 keydisp.mode = mode; 00916 keydisp.dispflag |= KEYDISP_FLAGREDRAW | KEYDISP_FLAGSIZING; 00917 keyallclear(); 00918 if (mode == KEYDISP_MODEFM) { 00919 delayreset(); 00920 fmkeyreset(); 00921 psgkeyreset(); 00922 } 00923 } 00924 else { 00925 keyalloff(); 00926 } 00927 } 00928 00929 void keydisp_setdelay(UINT8 frames) { 00930 00931 keydisp.delay.warmbase = frames; 00932 delayreset(); 00933 } 00934 00935 UINT8 keydisp_process(UINT8 framepast) { 00936 00937 int keys; 00938 int i; 00939 00940 if (framepast) { 00941 if (keydisp.mode == KEYDISP_MODEFM) { 00942 fmkeysync(); 00943 psgkeysync(); 00944 delayexecevent(framepast); 00945 } 00946 keydisp.framepast += framepast; 00947 } 00948 keys = getdispkeys(); 00949 for (i=0; i<keys; i++) { 00950 if (keydisp.ch[i].flag) { 00951 keydisp.dispflag |= KEYDISP_FLAGDRAW; 00952 break; 00953 } 00954 } 00955 return(keydisp.dispflag); 00956 } 00957 00958 void keydisp_getsize(int *width, int *height) { 00959 00960 if (width) { 00961 *width = KEYDISP_WIDTH; 00962 } 00963 if (height) { 00964 *height = (getdispkeys() * KEYDISP_KEYCY) + 1; 00965 } 00966 keydisp.dispflag &= ~KEYDISP_FLAGSIZING; 00967 } 00968 00969 BOOL keydisp_paint(CMNVRAM *vram, BOOL redraw) { 00970 00971 BOOL draw; 00972 int keys; 00973 int i; 00974 KDCHANNEL *p; 00975 00976 draw = FALSE; 00977 if ((vram == NULL) || 00978 (vram->width < KEYDISP_WIDTH) || (vram->height < 1)) { 00979 goto kdpnt_exit; 00980 } 00981 if (keydisp.dispflag & KEYDISP_FLAGREDRAW){ 00982 redraw = TRUE; 00983 } 00984 if (redraw) { 00985 keyallreload(); 00986 clearrect(vram, 0, 0, KEYDISP_WIDTH, 1); 00987 clearrect(vram, 0, 0, 1, vram->height); 00988 draw = TRUE; 00989 } 00990 vram->ptr += vram->xalign + vram->yalign; // ptr (1, 1) 00991 keys = (vram->height - 1) / KEYDISP_KEYCY; 00992 keys = min(keys, getdispkeys()); 00993 for (i=0, p=keydisp.ch; i<keys; i++, p++) { 00994 draw |= draw1ch(vram, keydisp.framepast, p); 00995 vram->ptr += KEYDISP_KEYCY * vram->yalign; 00996 } 00997 keydisp.dispflag &= ~(KEYDISP_FLAGDRAW | KEYDISP_FLAGREDRAW); 00998 keydisp.framepast = 0; 00999 01000 kdpnt_exit: 01001 return(draw); 01002 } 01003 #endif 01004