/*

	pckey.hpp
	3-24-91
	PC keyboard class for Borland C++

	Copyright 1991
	John W. Small
	All rights reserved
	Use freely but acknowledge authorship and copyright.
	CIS: 73757,2233

	PSW / Power SoftWare
	P.O. Box 10072
	McLean, Virginia 22102 8072
	(703) 759-3838

*/

#ifndef PCKEY_CPP
#define PCKEY_CPP

#include <dos.h>


//  Typematic Rate = 10 x characters per second

enum TypeMaticRate  { TMR300, TMR267, TMR240, TMR218,
	TMR200, TMR185, TMR171, TMR160, TMR150, TMR133,
	TMR120, TMR109, TMR100, TMR092, TMR086, TMR080,
	TMR075, TMR067, TMR060, TMR055, TMR050, TMR046,
	TMR043, TMR040, TMR037, TMR033, TMR030, TMR027,
	TMR025, TMR023, TMR021, TMR020 };


//  Typematic Delay in milliseconds

enum TypeMaticDelay  { TMD250, TMD500, TMD750, TMD1000 };



//  Do not instantiate!

class PCKey  {
// Variables are static to save having to dereference
// the "this" pointer in the inline member functions.
static	unsigned asciiScan;
static	unsigned char enhancedKeyBrd;
static	unsigned enhancedShiftMask;
public:
	PCKey();
	int enhanced()  { return (int) enhancedKeyBrd; }
	int getch()  {
		_AH = enhancedKeyBrd;
		geninterrupt(0x16);
		asciiScan = _AX;
		return (int) _AL;
	}
// Ascii code of last character read with getch()
// or character waiting with kbhit().
	int ascii()
		{ return (int)(asciiScan & 0x00FF); }
// Scan code of last character read with gethch()
// or character waiting with kbhit().
	int scan()
		{ return (int)((asciiScan &0xFF00) >> 8); }
	int kbhit()  {
		_AH = 0x01 | enhancedKeyBrd;
		geninterrupt(0x16);
		asciiScan = _AX;
		return !(int)(_FLAGS & 0x0040);
	}
	unsigned shift()  {
		_AH = 0x02 | enhancedKeyBrd;
		geninterrupt(0x16);
		return (_AX & enhancedShiftMask);
	}
	unsigned InsertStateActive()
		{ return (shift() & 0x0080); }
	unsigned CapsLockActive()
		{ return (shift() & 0x0040); }
	unsigned NumLockActive()
		{ return (shift() & 0x0020); }
	unsigned ScrollLockActive()
		{ return (shift() & 0x0010); }
	unsigned AltPressed()
		{ return (shift() & 0x0008); }
	unsigned CtrlPressed()
		{ return (shift() & 0x0004); }
	unsigned LeftShiftPressed()
		{ return (shift() & 0x0002); }
	unsigned RightShiftPressed()
		{ return (shift() & 0x0001); }
	unsigned ShiftPressed()
		{ return (shift() & 0x0003); }
	unsigned SysReqPressed()
		{ return (shift() & 0x8000); }
	unsigned CapsLockPressed()
		{ return (shift() & 0x4000); }
	unsigned NumLockPressed()
		{ return (shift() & 0x2000); }
	unsigned ScrollLockPressed()
		{ return (shift() & 0x1000); }
	unsigned RightAltPressed()
		{ return (shift() & 0x0800); }
	unsigned RightCtrlPressed()
		{ return (shift() & 0x0400); }
	unsigned LeftAltPressed()
		{ return (shift() & 0x0200); }
	unsigned LeftCtrlPressed()
		{ return (shift() & 0x0100); }
	void setTypeMatic(enum TypeMaticRate TMrate,
		enum TypeMaticDelay TMdelay)  {
		_BX = (TMdelay << 8) | TMrate;
		_AX = 0x0305;
		geninterrupt(0x16);
	}
	int putch(unsigned asciiScan)  {
		_CX = asciiScan;
		_AH = 0x05;
		geninterrupt(0x16);
		return !((int) _AL);
	}
	void flush();
	~PCKey() {}
};

extern PCKey PC;  // Only instant, do not instantiate!


//  Note: Ctrl keys are not special!
//  Returned by getch() and ascii().

#define  CtrlA     1
#define  CtrlB     2
#define  CtrlC     3
#define  CtrlD     4
#define  CtrlE     5
#define  CtrlF     6
#define  CtrlG     7
#define  CtrlH     8
#define  CtrlI     9
#define  CtrlJ    10
#define  CtrlK    11
#define  CtrlL    12
#define  CtrlM    13
#define  CtrlN    14
#define  CtrlO    15
#define  CtrlP    16
#define  CtrlQ    17
#define  CtrlR    18
#define  CtrlS    19
#define  CtrlT    20
#define  CtrlU    21
#define  CtrlV    22
#define  CtrlW    23
#define  CtrlX    24
#define  CtrlY    25
#define  CtrlZ    26


//  Special Key Codes returned via scan() when getch() == 0.

#define  AltA         30
#define  AltB         48
#define  AltC         46
#define  AltD         32
#define  AltE         18
#define  AltF         33
#define  AltG         34
#define  AltH         35
#define  AltI         23
#define  AltJ         36
#define  AltK         37
#define  AltL         38
#define  AltM         50
#define  AltN         49
#define  AltO         24
#define  AltP         25
#define  AltQ         16
#define  AltR         19
#define  AltS         31
#define  AltT         20
#define  AltU         22
#define  AltV         47
#define  AltW         17
#define  AltX         45
#define  AltY         21
#define  AltZ         44

#define  Home         71
#define  UpArr        72
#define  PgUp         73
#define  LArr         75
#define  RArr         77
#define  EndKey       79
#define  DnArr        80
#define  PgDn         81
#define  InsKey       82
#define  DelKey       83

#define  CtrlHome    119
#define  CtrlPgUp    132
#define  CtrlLArr    115
#define  CtrlRArr    116
#define  CtrlEnd     117
#define  CtrlPgDn    118

#define  Alt1        120
#define  Alt2        121
#define  Alt3        122
#define  Alt4        123
#define  Alt5        124
#define  Alt6        125
#define  Alt7        126
#define  Alt8        127
#define  Alt9        128
#define  Alt0        129

#define  AltHyphen   130
#define  AltEquals   131
#define  CtrlPrtSc   114
#define  ShiftTab     15


#define  F1           59
#define  ShiftF1      84
#define  CtrlF1       94
#define  AltF1       104

#define  F2           60
#define  ShiftF2      85
#define  CtrlF2       95
#define  AltF2       105

#define  F3           61
#define  ShiftF3      86
#define  CtrlF3       96
#define  AltF3       106

#define  F4           62
#define  ShiftF4      87
#define  CtrlF4       97
#define  AltF4       107

#define  F5           63
#define  ShiftF5      88
#define  CtrlF5       98
#define  AltF5       108

#define  F6           64
#define  ShiftF6      89
#define  CtrlF6       99
#define  AltF6       109

#define  F7           65
#define  ShiftF7      90
#define  CtrlF7      100
#define  AltF7       110

#define  F8           66
#define  ShiftF8      91
#define  CtrlF8      101
#define  AltF8       111

#define  F9           67
#define  ShiftF9      92
#define  CtrlF9      102
#define  AltF9       112

#define  F10          68
#define  ShiftF10     93
#define  CtrlF10     103
#define  AltF10      113

//  Some BIOS' don't return these.

#define  F11         133
#define  ShiftF11    135
#define  CtrlF11     137
#define  AltF11      139

#define  F12         134
#define  ShiftF12    136
#define  CtrlF12     138
#define  AltF12      140


//  Non special - standard character codes.

#define  ESC          27
#define  CR           13
#define  Tab           9
#define  BackSp        8
#define  Space        32
#define  DelCh       127

//  Returned by extended keys on 101/102 keyboards
//  that duplicate keys available on 84 key format.
//  Consider the home key ...
//  On number pad:  PC.ascii() ==   0  PC.scan() == 71
//  By itself:      PC.ascii() == 224  PC.scan() == 71
#define  EntendKey   224

#endif
