mirror of
https://git.code.sf.net/p/newrpl/sources
synced 2024-11-16 19:51:25 +01:00
568 lines
20 KiB
C
568 lines
20 KiB
C
/*
|
|
* Copyright (c) 2014-2015, Claudio Lapilli and the newRPL Team
|
|
* All rights reserved.
|
|
* This file is released under the 3-clause BSD license.
|
|
* See the file LICENSE.txt that shipped with this distribution.
|
|
*/
|
|
|
|
#include <newrpl.h>
|
|
#include <ui.h>
|
|
|
|
INTERRUPT_TYPE __cpu_intoff();
|
|
void __cpu_inton(INTERRUPT_TYPE state);
|
|
void __tmr_eventreschedule();
|
|
|
|
// KEYBOARD, LOW LEVEL GLOBAL VARIABLES
|
|
unsigned short int __keyb_buffer[KEYB_BUFFER] __SYSTEM_GLOBAL__;
|
|
volatile int __keyb_lock __SYSTEM_GLOBAL__;
|
|
int __keyflags __SYSTEM_GLOBAL__;
|
|
int __kused __SYSTEM_GLOBAL__, __kcurrent __SYSTEM_GLOBAL__;
|
|
keymatrix __kmat __SYSTEM_GLOBAL__;
|
|
unsigned int __keyplane __SYSTEM_GLOBAL__;
|
|
int __keynumber __SYSTEM_GLOBAL__, __keycount __SYSTEM_GLOBAL__;
|
|
int __keyb_repeattime __SYSTEM_GLOBAL__, __keyb_longpresstime __SYSTEM_GLOBAL__,
|
|
__keyb_debounce __SYSTEM_GLOBAL__;
|
|
|
|
// LOW-LEVEL ROUTINE TO BE USED BY THE IRQ HANDLERS AND EXCEPTION
|
|
// HANDLERS ONLY
|
|
|
|
keymatrix __keyb_getmatrix();
|
|
|
|
// WRAPPER TO DISABLE INTERRUPTS WHILE READING THE KEYBOARD
|
|
// NEEDED ONLY WHEN CALLED FROM WITHIN AN EXCEPTION HANDLER
|
|
|
|
keymatrix __keyb_getmatrixEX();
|
|
|
|
void __keyb_waitrelease();
|
|
|
|
// RETURNS THE CURRENT WORKING MATRIX INSTEAD OF
|
|
// MESSING WITH THE HARDWARE, BUT ONLY IF KEYBOARD HANDLERS WERE STARTED
|
|
keymatrix keyb_getmatrix();
|
|
|
|
// LOW-LEVEL FUNCTION TO BE USED BY THE
|
|
// EXCEPTION SUBSYSTEM ONLY
|
|
|
|
const unsigned short const __keyb_shiftconvert[8] = {
|
|
0,
|
|
SHIFT_ALPHA | SHIFT_ALPHAHOLD,
|
|
SHIFT_LS | SHIFT_LSHOLD,
|
|
SHIFT_ALPHA | SHIFT_ALPHAHOLD | SHIFT_LS | SHIFT_LSHOLD,
|
|
SHIFT_RS | SHIFT_RSHOLD,
|
|
SHIFT_ALPHA | SHIFT_ALPHAHOLD | SHIFT_RS | SHIFT_RSHOLD,
|
|
SHIFT_LS | SHIFT_LSHOLD | SHIFT_RS | SHIFT_RSHOLD,
|
|
SHIFT_LS | SHIFT_LSHOLD | SHIFT_ALPHA | SHIFT_ALPHAHOLD | SHIFT_RS |
|
|
SHIFT_RSHOLD
|
|
};
|
|
|
|
int __keyb_getkey(int wait)
|
|
{
|
|
|
|
keymatrix m,m_noshift;
|
|
m = __keyb_getmatrixEX();
|
|
|
|
if(wait) {
|
|
// wait for a non-shift key to be pressed
|
|
while((m & (~KEYMATRIX_ALL_SHIFTS)) == 0LL)
|
|
m = __keyb_getmatrixEX();
|
|
}
|
|
|
|
int kcode,kcodebit, shft = KEYMATRIX_ALPHABIT(m) | (KEYMATRIX_LSHIFTBIT(m)<<1) | (KEYMATRIX_RSHIFTBIT(m)<<2);
|
|
|
|
m_noshift=m & (~KEYMATRIX_ALL_SHIFTS);
|
|
unsigned char *mbytes = (unsigned char *)&m_noshift;
|
|
int k;
|
|
for(k = 0, kcodebit = 0; k < 8; ++mbytes, ++k, kcodebit += 8) {
|
|
if(*mbytes != 0) {
|
|
k = *mbytes;
|
|
while(!(k & 1)) {
|
|
k >>= 1;
|
|
++kcodebit;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
kcode=KEYMAP_CODEFROMBIT(kcodebit);
|
|
|
|
if(wait) {
|
|
while((m & (~KEYMATRIX_ALL_SHIFTS)) != 0)
|
|
m = __keyb_getmatrixEX();
|
|
}
|
|
|
|
if(kcodebit < 64)
|
|
return kcode | __keyb_shiftconvert[shft];
|
|
return 0;
|
|
|
|
}
|
|
|
|
#define LONG_KEYPRESSTIME (__keyb_longpresstime)
|
|
#define REPEAT_KEYTIME (__keyb_repeattime)
|
|
#define BOUNCE_KEYTIME (__keyb_debounce)
|
|
|
|
#define KF_RUNNING 1
|
|
#define KF_ALPHALOCK 2
|
|
#define KF_NOREPEAT 4
|
|
#define KF_UPDATED 8
|
|
|
|
void __keyb_postmsg(unsigned int msg)
|
|
{
|
|
|
|
__keyb_buffer[__kcurrent] = msg;
|
|
__kcurrent = (__kcurrent + 1) & (KEYB_BUFFER - 1);
|
|
// CHECK FOR BUFFER OVERRUN
|
|
if(__kcurrent == __kused) {
|
|
// BUFFER OVERRUN, DROP LAST KEY
|
|
__kcurrent = (__kcurrent - 1) & (KEYB_BUFFER - 1);
|
|
}
|
|
|
|
}
|
|
|
|
void keyb_postmsg(unsigned int msg)
|
|
{
|
|
// WARNING: PROBLEMS MAY ARISE IF THE INTERRUPT SERVICE WANTS
|
|
// TO POST A MESSAGE WHILE THE USER IS POSTING ONE.
|
|
while(cpu_getlock(1, &__keyb_lock));
|
|
|
|
__keyb_postmsg(msg);
|
|
__keyb_lock = 0;
|
|
|
|
}
|
|
|
|
unsigned int keyb_getmsg()
|
|
{
|
|
if(__kused == __kcurrent)
|
|
return 0;
|
|
unsigned int msg = __keyb_buffer[__kused];
|
|
__kused = (__kused + 1) & (KEYB_BUFFER - 1);
|
|
return msg;
|
|
}
|
|
|
|
// CHECK IF ANY AVAILABLE KEYSTROKES
|
|
int keyb_anymsg()
|
|
{
|
|
if(__kused == __kcurrent)
|
|
return 0;
|
|
return 1;
|
|
}
|
|
|
|
// FLUSH KEYBOARD BUFFER
|
|
void keyb_flush()
|
|
{
|
|
while(keyb_getmatrix() != 0LL);
|
|
__kused = __kcurrent;
|
|
}
|
|
|
|
// FLUSH KEYBOARD BUFFER WITHOUT WAITING
|
|
void keyb_flushnowait()
|
|
{
|
|
__kused = __kcurrent;
|
|
}
|
|
|
|
// RETURN TRUE IF AN UPDATE HAPPENED
|
|
// USED TO DETECT IF AN INTERRUPT WAS DUE TO THE KEYBOARD
|
|
int keyb_wasupdated()
|
|
{
|
|
int k = __keyflags & KF_UPDATED;
|
|
|
|
__keyflags ^= k;
|
|
return k;
|
|
}
|
|
|
|
// ANALYZE CHANGES IN THE KEYBOARD STATUS AND POST MESSAGES ACCORDINGLY
|
|
#define ALPHALOCK (SHIFT_ALPHA<<17)
|
|
#define OTHER_KEY (SHIFT_ALPHA<<18)
|
|
#define ONE_PRESS (SHIFT_ALPHA<<19)
|
|
#define ALPHASWAP (SHIFT_ALPHA<<20)
|
|
|
|
void __keyb_update()
|
|
{
|
|
|
|
if(cpu_getlock(1, &__keyb_lock))
|
|
return;
|
|
|
|
keymatrix a, b;
|
|
|
|
__keyflags |= KF_UPDATED;
|
|
doupdate:
|
|
|
|
a = __keyb_getmatrix();
|
|
b = a ^ __kmat;
|
|
__kmat = a;
|
|
|
|
// ANALYZE CHANGES
|
|
if(b != 0) {
|
|
// POST MESSAGE
|
|
int key = 0; // KEY HAS THE BIT POSITION OF A KEY, NOT THE KEYCODE
|
|
while(b != 0) {
|
|
if(b & 1) {
|
|
if(a & 1) {
|
|
// POST KEYDN MESSAGE
|
|
if(__keynumber == -key) {
|
|
// DISREGARD SPURIOUS KEYPRESS
|
|
__kmat &= ~(1LL << key); // CLEAR THE KEY
|
|
__keynumber = 0;
|
|
__keycount = 0;
|
|
}
|
|
else {
|
|
__keyb_postmsg(KM_KEYDN + KEYMAP_CODEFROMBIT(key));
|
|
if( (KEYMAP_CODEFROMBIT(key) < 60) || ((KEYMAP_CODEFROMBIT(key) == KB_ALPHA) && (__keyplane & (SHIFT_RS | SHIFT_LS)))) // TREAT SHIFT-ALPHA LIKE REGULAR KEYPRESS
|
|
{
|
|
__keyb_postmsg(KM_PRESS + KEYMAP_CODEFROMBIT(key) +
|
|
(__keyplane & SHIFT_ANY));
|
|
__keynumber = key;
|
|
__keycount = 0;
|
|
|
|
__keyplane &= ~ONE_PRESS;
|
|
|
|
}
|
|
else {
|
|
unsigned int oldplane = __keyplane;
|
|
if(KEYMAP_CODEFROMBIT(key) == KB_LSHIFT) {
|
|
__keyplane &=
|
|
~(SHIFT_RSHOLD | SHIFT_RS | (SHIFT_RS <<
|
|
16));
|
|
__keyplane |= SHIFT_LSHOLD | SHIFT_LS;
|
|
__keyplane ^= SHIFT_LS << 16;
|
|
}
|
|
if(KEYMAP_CODEFROMBIT(key) == KB_RSHIFT) {
|
|
__keyplane &=
|
|
~(SHIFT_LSHOLD | SHIFT_LS | (SHIFT_LS <<
|
|
16));
|
|
__keyplane |= SHIFT_RSHOLD | SHIFT_RS;
|
|
__keyplane ^= SHIFT_RS << 16;
|
|
}
|
|
if(KEYMAP_CODEFROMBIT(key) == KB_ALPHA) {
|
|
__keyplane &= ~OTHER_KEY;
|
|
if(__keyplane & SHIFT_ALPHA) {
|
|
// ALREADY IN ALPHA MODE
|
|
__keyplane |= ALPHASWAP;
|
|
}
|
|
else {
|
|
__keyplane &= ~ONE_PRESS;
|
|
}
|
|
__keyplane |= SHIFT_ALPHAHOLD | SHIFT_ALPHA;
|
|
|
|
}
|
|
if(KEYMAP_CODEFROMBIT(key) == KB_ON) {
|
|
__keyplane |= SHIFT_ONHOLD;
|
|
}
|
|
// THE KM_SHIFT MESSAGE CARRIES THE OLD PLANE IN THE KEY CODE
|
|
// AND THE NEW PLANE IN THE SHIFT CODE.
|
|
__keyb_postmsg(KM_SHIFT | (__keyplane & SHIFT_ANY) |
|
|
MKOLDSHIFT(oldplane | ((oldplane &
|
|
ALPHALOCK) >> 16)));
|
|
|
|
}
|
|
}
|
|
}
|
|
else {
|
|
__keyb_postmsg(KM_KEYUP + KEYMAP_CODEFROMBIT(key));
|
|
|
|
if((KEYMAP_CODEFROMBIT(key) < 60) || ((KEYMAP_CODEFROMBIT(key) == KB_ALPHA) && (__keyplane & (SHIFT_RS | SHIFT_LS)))) {
|
|
if(__keynumber > 0)
|
|
__keynumber = -__keynumber;
|
|
__keycount = -BOUNCE_KEYTIME;
|
|
__keyplane &= ~((SHIFT_LS | SHIFT_RS) << 16);
|
|
|
|
if(!(__keyplane & (SHIFT_HOLD | SHIFT_ALHOLD |
|
|
SHIFT_ONHOLD))) {
|
|
unsigned int oldkeyplane = __keyplane;
|
|
__keyplane &= ~(SHIFT_LS | SHIFT_RS | SHIFT_ALPHA); // KILL ALL SHIFT PLANES
|
|
if(__keyplane & ALPHALOCK)
|
|
__keyplane |= SHIFT_ALPHA; // KEEP ALPHA IF LOCKED
|
|
__keyplane &= ~((SHIFT_ALPHA) << 16);
|
|
|
|
if(oldkeyplane != __keyplane)
|
|
__keyb_postmsg(KM_SHIFT | (__keyplane &
|
|
SHIFT_ANY) | MKOLDSHIFT(oldkeyplane
|
|
| ((oldkeyplane & ALPHALOCK) >>
|
|
16)));
|
|
}
|
|
else {
|
|
|
|
if(__keyplane & SHIFT_ALPHA) {
|
|
// THIS IS A PRESS AND HOLD KEY BEING RAISED
|
|
__keyplane |= OTHER_KEY;
|
|
}
|
|
if(!(__keyplane & (SHIFT_HOLD))) {
|
|
unsigned int oldkeyplane = __keyplane;
|
|
// IT WAS ALPHA-HOLD OR ON-HOLD, KILL SHIFTS
|
|
__keyplane &= ~(SHIFT_LS | SHIFT_RS); // KILL ALL SHIFT PLANES
|
|
|
|
if(oldkeyplane != __keyplane)
|
|
__keyb_postmsg(KM_SHIFT | (__keyplane &
|
|
SHIFT_ANY) |
|
|
MKOLDSHIFT(oldkeyplane |
|
|
((oldkeyplane & ALPHALOCK) >>
|
|
16)));
|
|
|
|
}
|
|
}
|
|
|
|
}
|
|
else {
|
|
unsigned int oldkeyplane = __keyplane;
|
|
if(KEYMAP_CODEFROMBIT(key) == KB_LSHIFT) {
|
|
__keyplane &=
|
|
~((SHIFT_LSHOLD | SHIFT_LS) ^ ((__keyplane
|
|
>> 16) & SHIFT_LS));
|
|
if(!(oldkeyplane & SHIFT_ALHOLD))
|
|
__keyplane &=
|
|
~((SHIFT_ALPHA) ^ (((__keyplane >> 16) |
|
|
(__keyplane >> 17)) &
|
|
SHIFT_ALPHA));
|
|
|
|
}
|
|
if(KEYMAP_CODEFROMBIT(key) == KB_RSHIFT) {
|
|
__keyplane &=
|
|
~((SHIFT_RSHOLD | SHIFT_RS) ^ ((__keyplane
|
|
>> 16) & SHIFT_RS));
|
|
if(!(oldkeyplane & SHIFT_ALHOLD))
|
|
__keyplane &=
|
|
~((SHIFT_ALPHA) ^ (((__keyplane >> 16) |
|
|
(__keyplane >> 17)) &
|
|
SHIFT_ALPHA));
|
|
|
|
}
|
|
if(KEYMAP_CODEFROMBIT(key) == KB_ALPHA) {
|
|
if(__keyplane & ALPHASWAP) {
|
|
// ALPHA WAS PRESSED WHILE ALREADY IN ALPHA MODE
|
|
if(__keyplane & OTHER_KEY) {
|
|
// ANOTHER KEY WAS PRESSED BEFORE RELEASING ALPHA
|
|
__keyplane &= ~ONE_PRESS;
|
|
|
|
}
|
|
else {
|
|
// ALPHA WAS PRESSED AND RELEASED, NO OTHER KEYS
|
|
if(__keyplane & ONE_PRESS) {
|
|
// THIS IS THE SECOND PRESS, KILL ALPHA MODE
|
|
__keyplane &= ~ALPHALOCK;
|
|
__keyplane &= ~SHIFT_ALPHA;
|
|
}
|
|
else
|
|
__keyplane |= ONE_PRESS;
|
|
|
|
// SEND MESSAGE THAT ALPHA MODE CYCLING WAS REQUESTED
|
|
__keyb_postmsg(KM_PRESS + KEYMAP_CODEFROMBIT(key) +
|
|
(__keyplane & SHIFT_ANY));
|
|
__keynumber = key;
|
|
__keycount = 0;
|
|
|
|
}
|
|
__keyplane &= ~ALPHASWAP;
|
|
|
|
}
|
|
else {
|
|
// ALPHA WAS PRESSED FOR THE FIRST TIME FROM OTHER MODE
|
|
if(__keyplane & OTHER_KEY) {
|
|
|
|
__keyplane &= ~SHIFT_ALPHAHOLD;
|
|
}
|
|
else {
|
|
// ALPHA WAS PRESSED AND RELEASED
|
|
__keyplane |= ALPHALOCK;
|
|
|
|
}
|
|
__keyplane &= ~ONE_PRESS;
|
|
|
|
}
|
|
|
|
__keyplane &= ~SHIFT_ALHOLD;
|
|
|
|
}
|
|
if(KEYMAP_CODEFROMBIT(key) == KB_ON) {
|
|
__keyplane &= ~SHIFT_ONHOLD;
|
|
}
|
|
__keyb_postmsg(KM_SHIFT | (__keyplane & SHIFT_ANY) |
|
|
MKOLDSHIFT(oldkeyplane | ((oldkeyplane &
|
|
ALPHALOCK) >> 16)));
|
|
|
|
__keynumber = -key;
|
|
__keycount = -BOUNCE_KEYTIME;
|
|
}
|
|
|
|
}
|
|
}
|
|
b >>= 1;
|
|
a >>= 1;
|
|
++key;
|
|
}
|
|
}
|
|
// ANALYZE STATUS OF CURRENT KEYPRESS
|
|
if(__keynumber >= 0) {
|
|
if(__kmat & (1LL << __keynumber)) {
|
|
// KEY STILL PRESSED, INCREASE COUNTER
|
|
++__keycount;
|
|
if((__keycount > LONG_KEYPRESSTIME)) {
|
|
//if(!(__keyflags&KF_NOREPEAT)) {
|
|
// ONLY CERTAIN KEYS WILL AUTOREPEAT
|
|
switch (KEYMAP_CODEFROMBIT(__keynumber)) {
|
|
case KB_SPC:
|
|
case KB_BKS:
|
|
if(__keyplane & (SHIFT_LS | SHIFT_RS | SHIFT_HOLD |
|
|
SHIFT_ALHOLD)) {
|
|
__keyb_postmsg(KM_LPRESS | KEYMAP_CODEFROMBIT(__keynumber) | (__keyplane &
|
|
SHIFT_ANY));
|
|
__keycount = -LONG_KEYPRESSTIME;
|
|
break;
|
|
}
|
|
// OTHERWISE DO REPEAT
|
|
case KB_UP:
|
|
case KB_DN:
|
|
case KB_LF:
|
|
case KB_RT:
|
|
// THESE ALWAYS REPEAT, EVEN SHIFTED
|
|
__keyb_postmsg(KM_REPEAT | KEYMAP_CODEFROMBIT(__keynumber) | (__keyplane &
|
|
SHIFT_ANY));
|
|
__keycount = -REPEAT_KEYTIME;
|
|
break;
|
|
default:
|
|
// DO NOT AUTOREPEAT, DO LONG PRESS
|
|
__keyb_postmsg(KM_LPRESS | KEYMAP_CODEFROMBIT(__keynumber) | (__keyplane &
|
|
SHIFT_ANY));
|
|
__keycount = -LONG_KEYPRESSTIME;
|
|
}
|
|
|
|
}
|
|
|
|
if(!__keycount) {
|
|
|
|
switch (KEYMAP_CODEFROMBIT(__keynumber)) {
|
|
case KB_SPC:
|
|
case KB_BKS:
|
|
if(__keyplane & (SHIFT_LS | SHIFT_RS | SHIFT_HOLD |
|
|
SHIFT_ALHOLD)) {
|
|
__keyb_postmsg(KM_LREPEAT | KEYMAP_CODEFROMBIT(__keynumber) | (__keyplane &
|
|
SHIFT_ANY));
|
|
__keycount -= LONG_KEYPRESSTIME;
|
|
break;
|
|
}
|
|
// OTHERWISE DO REPEAT
|
|
case KB_UP:
|
|
case KB_DN:
|
|
case KB_LF:
|
|
case KB_RT:
|
|
// THESE ALWAYS REPEAT, EVEN SHIFTED
|
|
__keyb_postmsg(KM_REPEAT | KEYMAP_CODEFROMBIT(__keynumber) | (__keyplane &
|
|
SHIFT_ANY));
|
|
__keycount -= REPEAT_KEYTIME;
|
|
break;
|
|
default:
|
|
// DO NOT AUTOREPEAT, DO LONG PRESS
|
|
__keyb_postmsg(KM_LREPEAT | KEYMAP_CODEFROMBIT(__keynumber) | (__keyplane &
|
|
SHIFT_ANY));
|
|
__keycount -= LONG_KEYPRESSTIME;
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
}
|
|
|
|
// REPEATER
|
|
if(__kmat == 0) {
|
|
if(__keycount >= 0) {
|
|
tmr_events[0].status = 0;
|
|
__keynumber = 0;
|
|
}
|
|
else {
|
|
++__keycount;
|
|
}
|
|
}
|
|
else {
|
|
|
|
if(!(tmr_events[0].status & 1)) {
|
|
// ACTIVATE THE TIMER EVENT IF NOT ALREADY RUNNING
|
|
tmr_events[0].ticks = tmr_ticks() + tmr_events[0].delay;
|
|
tmr_events[0].status = 3;
|
|
__tmr_eventreschedule();
|
|
}
|
|
}
|
|
|
|
// On-C and On-A-F handling
|
|
|
|
if(__kmat == ((1ULL << KEYMAP_BITFROMCODE(KB_ON)) | (1ULL << KEYMAP_BITFROMCODE(KB_A)) | (1ULL << KEYMAP_BITFROMCODE(KB_F)))) {
|
|
// ON-A-F pressed, offer the option to stop the program
|
|
|
|
__keyb_lock = 0;
|
|
|
|
throw_exception("User BREAK requested",
|
|
__EX_CONT | __EX_WARM | __EX_WIPEOUT | __EX_RESET |
|
|
__EX_RPLREGS);
|
|
|
|
// AFTER RETURNING FROM THE EXCEPTION HANDLER, ALL KEYS ARE GUARANTEED TO BE RELEASED
|
|
// DO AN UPDATE TO SEND KEY_UP MESSAGES TO THE APPLICATION AND CORRECT SHIFT PLANES
|
|
goto doupdate;
|
|
|
|
}
|
|
|
|
if(__kmat == ((1ULL << KEYMAP_BITFROMCODE(KB_ON)) | (1ULL << KEYMAP_BITFROMCODE(KB_A)) | (1ULL << KEYMAP_BITFROMCODE(KB_C)))) {
|
|
// ON-A-C pressed, offer the option to stop the program
|
|
|
|
__keyb_lock = 0;
|
|
|
|
throw_exception("RPL Break requested",
|
|
__EX_CONT | __EX_RPLEXIT | __EX_WARM | __EX_RESET);
|
|
|
|
// AFTER RETURNING FROM THE EXCEPTION HANDLER, ALL KEYS ARE GUARANTEED TO BE RELEASED
|
|
// DO AN UPDATE TO SEND KEY_UP MESSAGES TO THE APPLICATION AND CORRECT SHIFT PLANES
|
|
goto doupdate;
|
|
|
|
}
|
|
|
|
__keyb_lock = 0;
|
|
|
|
}
|
|
|
|
void keyb_settiming(int repeat, int longpress, int debounce)
|
|
{
|
|
__keyb_repeattime = (repeat + KEYB_SCANSPEED - 1) / KEYB_SCANSPEED;
|
|
__keyb_longpresstime = (longpress + KEYB_SCANSPEED - 1) / KEYB_SCANSPEED;
|
|
__keyb_debounce = (debounce + KEYB_SCANSPEED - 1) / KEYB_SCANSPEED;
|
|
}
|
|
|
|
void keyb_setrepeat(int repeat)
|
|
{
|
|
if(!repeat)
|
|
__keyflags |= KF_NOREPEAT;
|
|
else
|
|
__keyflags &= ~KF_NOREPEAT;
|
|
}
|
|
|
|
void keyb_setalphalock(int single_alpha_lock)
|
|
{
|
|
if(single_alpha_lock)
|
|
__keyflags |= KF_ALPHALOCK;
|
|
else
|
|
__keyflags &= ~KF_ALPHALOCK;
|
|
|
|
}
|
|
|
|
void keyb_setshiftplane(int leftshift, int rightshift, int alpha, int alphalock)
|
|
{
|
|
// while(keyb_getmatrix()!=0LL) ; // WAIT UNTIL NO MORE KEYS ARE PRESSED TO UPDATE SHIFT STATE
|
|
|
|
int oldplane = __keyplane;
|
|
|
|
if(leftshift)
|
|
__keyplane |= SHIFT_LS | (SHIFT_LS << 16);
|
|
else
|
|
__keyplane &= ~(SHIFT_LS | (SHIFT_LS << 16));
|
|
if(rightshift)
|
|
__keyplane |= SHIFT_RS | (SHIFT_RS << 16);
|
|
else
|
|
__keyplane &= ~(SHIFT_RS | (SHIFT_RS << 16));
|
|
if(alpha || alphalock)
|
|
__keyplane |= SHIFT_ALPHA | (SHIFT_ALPHA << 16);
|
|
else
|
|
__keyplane &= ~(SHIFT_ALPHA | (SHIFT_ALPHA << 16));
|
|
if(alphalock) {
|
|
__keyplane |= SHIFT_ALPHA << 17; // LOCK ALPHA
|
|
__keyplane &= ~(SHIFT_ALPHA << 16);
|
|
}
|
|
else {
|
|
__keyplane &= ~(SHIFT_ALPHA << 17);
|
|
}
|
|
keyb_postmsg(KM_SHIFT | (__keyplane & SHIFT_ANY) | MKOLDSHIFT(oldplane |
|
|
((oldplane & ALPHALOCK) >> 16)));
|
|
|
|
}
|