123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284 |
- /* Catacomb Armageddon Source Code
- * Copyright (C) 1993-2014 Flat Rock Software
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License along
- * with this program; if not, write to the Free Software Foundation, Inc.,
- * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- */
- //
- // ID Engine
- // ID_IN.c - Input Manager
- // v1.0d1
- // By Jason Blochowiak
- //
- //
- // This module handles dealing with the various input devices
- //
- // Depends on: Memory Mgr (for demo recording), Sound Mgr (for timing stuff),
- // User Mgr (for command line parms)
- //
- // Globals:
- // LastScan - The keyboard scan code of the last key pressed
- // LastASCII - The ASCII value of the last key pressed
- // DEBUG - there are more globals
- //
- #include "ID_HEADS.H"
- #pragma hdrstop
- #define KeyInt 9 // The keyboard ISR number
- // Stuff for the joystick
- #define JoyScaleMax 32768
- #define JoyScaleShift 8
- #define MaxJoyValue 5000
- // Global variables
- boolean JoystickCalibrated=false; // MDM (GAMERS EDGE) - added
- ControlType ControlTypeUsed; // MDM (GAMERS EDGE) - added
- boolean Keyboard[NumCodes],
- JoysPresent[MaxJoys],
- MousePresent;
- boolean Paused;
- char LastASCII;
- ScanCode LastScan;
- KeyboardDef KbdDefs[MaxKbds] = {{0x1d,0x38,0x47,0x48,0x49,0x4b,0x4d,0x4f,0x50,0x51}};
- JoystickDef JoyDefs[MaxJoys];
- ControlType Controls[MaxPlayers];
- // Demo DemoMode = demo_Off;
- // byte _seg *DemoBuffer;
- // word DemoOffset,DemoSize;
- // Internal variables
- static boolean IN_Started;
- static boolean CapsLock;
- static ScanCode CurCode,LastCode;
- static byte far ASCIINames[] = // Unshifted ASCII for scan codes
- {
- // 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0 ,27 ,'1','2','3','4','5','6','7','8','9','0','-','=',8 ,9 , // 0
- 'q','w','e','r','t','y','u','i','o','p','[',']',13 ,0 ,'a','s', // 1
- 'd','f','g','h','j','k','l',';',39 ,'`',0 ,92 ,'z','x','c','v', // 2
- 'b','n','m',',','.','/',0 ,'*',0 ,' ',0 ,0 ,0 ,0 ,0 ,0 , // 3
- 0 ,0 ,0 ,0 ,0 ,0 ,0 ,'7','8','9','-','4','5','6','+','1', // 4
- '2','3','0',127,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 5
- 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 6
- 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 // 7
- },
- far ShiftNames[] = // Shifted ASCII for scan codes
- {
- // 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0 ,27 ,'!','@','#','$','%','^','&','*','(',')','_','+',8 ,9 , // 0
- 'Q','W','E','R','T','Y','U','I','O','P','{','}',13 ,0 ,'A','S', // 1
- 'D','F','G','H','J','K','L',':',34 ,'~',0 ,'|','Z','X','C','V', // 2
- 'B','N','M','<','>','?',0 ,'*',0 ,' ',0 ,0 ,0 ,0 ,0 ,0 , // 3
- 0 ,0 ,0 ,0 ,0 ,0 ,0 ,'7','8','9','-','4','5','6','+','1', // 4
- '2','3','0',127,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 5
- 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 6
- 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 // 7
- },
- far SpecialNames[] = // ASCII for 0xe0 prefixed codes
- {
- // 0 1 2 3 4 5 6 7 8 9 A B C D E F
- 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 0
- 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,13 ,0 ,0 ,0 , // 1
- 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 2
- 0 ,0 ,0 ,0 ,0 ,'/',0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 3
- 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 4
- 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 5
- 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 6
- 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 // 7
- },
- #if 0
- *ScanNames[] = // Scan code names with single chars
- {
- "?","?","1","2","3","4","5","6","7","8","9","0","-","+","?","?",
- "Q","W","E","R","T","Y","U","I","O","P","[","]","|","?","A","S",
- "D","F","G","H","J","K","L",";","\"","?","?","?","Z","X","C","V",
- "B","N","M",",",".","/","?","?","?","?","?","?","?","?","?","?",
- "?","?","?","?","?","?","?","?","\xf","?","-","\x15","5","\x11","+","?",
- "\x13","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?",
- "?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?",
- "?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?"
- }, // DEBUG - consolidate these
- #endif
- far ExtScanCodes[] = // Scan codes with >1 char names
- {
- 1,0xe,0xf,0x1d,0x2a,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,
- 0x3f,0x40,0x41,0x42,0x43,0x44,0x57,0x59,0x46,0x1c,0x36,
- 0x37,0x38,0x47,0x49,0x4f,0x51,0x52,0x53,0x45,0x48,
- 0x50,0x4b,0x4d,0x00
- };
- #if 0
- *ExtScanNames[] = // Names corresponding to ExtScanCodes
- {
- "Esc","BkSp","Tab","Ctrl","LShft","Space","CapsLk","F1","F2","F3","F4",
- "F5","F6","F7","F8","F9","F10","F11","F12","ScrlLk","Enter","RShft",
- "PrtSc","Alt","Home","PgUp","End","PgDn","Ins","Del","NumLk","Up",
- "Down","Left","Right",""
- };
- #endif
- static Direction DirTable[] = // Quick lookup for total direction
- {
- dir_NorthWest, dir_North, dir_NorthEast,
- dir_West, dir_None, dir_East,
- dir_SouthWest, dir_South, dir_SouthEast
- };
- static void (*INL_KeyHook)(void);
- static void interrupt (*OldKeyVect)(void);
- static char *ParmStrings[] = {"nojoys","nomouse",nil};
- // Internal routines
- ///////////////////////////////////////////////////////////////////////////
- //
- // INL_KeyService() - Handles a keyboard interrupt (key up/down)
- //
- ///////////////////////////////////////////////////////////////////////////
- static void interrupt
- INL_KeyService(void)
- {
- static boolean special;
- byte k,c,
- temp;
- k = inportb(0x60); // Get the scan code
- // Tell the XT keyboard controller to clear the key
- outportb(0x61,(temp = inportb(0x61)) | 0x80);
- outportb(0x61,temp);
- if (k == 0xe0) // Special key prefix
- special = true;
- else if (k == 0xe1) // Handle Pause key
- Paused = true;
- else
- {
- if (k & 0x80) // Break code
- {
- k &= 0x7f;
- // DEBUG - handle special keys: ctl-alt-delete, print scrn
- Keyboard[k] = false;
- }
- else // Make code
- {
- LastCode = CurCode;
- CurCode = LastScan = k;
- Keyboard[k] = true;
- if (special)
- c = SpecialNames[k];
- else
- {
- if (k == sc_CapsLock)
- {
- CapsLock ^= true;
- // DEBUG - make caps lock light work
- }
- if (Keyboard[sc_LShift] || Keyboard[sc_RShift]) // If shifted
- {
- c = ShiftNames[k];
- if ((c >= 'A') && (c <= 'Z') && CapsLock)
- c += 'a' - 'A';
- }
- else
- {
- c = ASCIINames[k];
- if ((c >= 'a') && (c <= 'z') && CapsLock)
- c -= 'a' - 'A';
- }
- }
- if (c)
- LastASCII = c;
- }
- special = false;
- }
- if (INL_KeyHook && !special)
- INL_KeyHook();
- outportb(0x20,0x20);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // INL_GetMouseDelta() - Gets the amount that the mouse has moved from the
- // mouse driver
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- INL_GetMouseDelta(int *x,int *y)
- {
- Mouse(MDelta);
- *x = _CX;
- *y = _DX;
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // INL_GetMouseButtons() - Gets the status of the mouse buttons from the
- // mouse driver
- //
- ///////////////////////////////////////////////////////////////////////////
- static word
- INL_GetMouseButtons(void)
- {
- word buttons;
- Mouse(MButtons);
- buttons = _BX;
- return(buttons);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // IN_GetJoyAbs() - Reads the absolute position of the specified joystick
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- IN_GetJoyAbs(word joy,word *xp,word *yp)
- {
- byte xb,yb,
- xs,ys;
- word x,y;
- x = y = 0;
- xs = joy? 2 : 0; // Find shift value for x axis
- xb = 1 << xs; // Use shift value to get x bit mask
- ys = joy? 3 : 1; // Do the same for y axis
- yb = 1 << ys;
- // Read the absolute joystick values
- asm pushf // Save some registers
- asm push si
- asm push di
- asm cli // Make sure an interrupt doesn't screw the timings
- asm mov dx,0x201
- asm in al,dx
- asm out dx,al // Clear the resistors
- asm mov ah,[xb] // Get masks into registers
- asm mov ch,[yb]
- asm xor si,si // Clear count registers
- asm xor di,di
- asm xor bh,bh // Clear high byte of bx for later
- asm push bp // Don't mess up stack frame
- asm mov bp,MaxJoyValue
- loop:
- asm in al,dx // Get bits indicating whether all are finished
- asm dec bp // Check bounding register
- asm jz done // We have a silly value - abort
- asm mov bl,al // Duplicate the bits
- asm and bl,ah // Mask off useless bits (in [xb])
- asm add si,bx // Possibly increment count register
- asm mov cl,bl // Save for testing later
- asm mov bl,al
- asm and bl,ch // [yb]
- asm add di,bx
- asm add cl,bl
- asm jnz loop // If both bits were 0, drop out
- done:
- asm pop bp
- asm mov cl,[xs] // Get the number of bits to shift
- asm shr si,cl // and shift the count that many times
- asm mov cl,[ys]
- asm shr di,cl
- asm mov [x],si // Store the values into the variables
- asm mov [y],di
- asm pop di
- asm pop si
- asm popf // Restore the registers
- *xp = x;
- *yp = y;
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // INL_GetJoyDelta() - Returns the relative movement of the specified
- // joystick (from +/-127, scaled adaptively)
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- INL_GetJoyDelta(word joy,int *dx,int *dy,boolean adaptive)
- {
- word x,y;
- longword time;
- JoystickDef *def;
- static longword lasttime;
- IN_GetJoyAbs(joy,&x,&y);
- def = JoyDefs + joy;
- if (x < def->threshMinX)
- {
- if (x < def->joyMinX)
- x = def->joyMinX;
- x = -(x - def->threshMinX);
- x *= def->joyMultXL;
- x >>= JoyScaleShift;
- *dx = (x > 127)? -127 : -x;
- }
- else if (x > def->threshMaxX)
- {
- if (x > def->joyMaxX)
- x = def->joyMaxX;
- x = x - def->threshMaxX;
- x *= def->joyMultXH;
- x >>= JoyScaleShift;
- *dx = (x > 127)? 127 : x;
- }
- else
- *dx = 0;
- if (y < def->threshMinY)
- {
- if (y < def->joyMinY)
- y = def->joyMinY;
- y = -(y - def->threshMinY);
- y *= def->joyMultYL;
- y >>= JoyScaleShift;
- *dy = (y > 127)? -127 : -y;
- }
- else if (y > def->threshMaxY)
- {
- if (y > def->joyMaxY)
- y = def->joyMaxY;
- y = y - def->threshMaxY;
- y *= def->joyMultYH;
- y >>= JoyScaleShift;
- *dy = (y > 127)? 127 : y;
- }
- else
- *dy = 0;
- if (adaptive)
- {
- time = (TimeCount - lasttime) / 2;
- if (time)
- {
- if (time > 8)
- time = 8;
- *dx *= time;
- *dy *= time;
- }
- }
- lasttime = TimeCount;
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // INL_GetJoyButtons() - Returns the button status of the specified
- // joystick
- //
- ///////////////////////////////////////////////////////////////////////////
- static word
- INL_GetJoyButtons(word joy)
- {
- register word result;
- result = inportb(0x201); // Get all the joystick buttons
- result >>= joy? 6 : 4; // Shift into bits 0-1
- result &= 3; // Mask off the useless bits
- result ^= 3;
- return(result);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // IN_GetJoyButtonsDB() - Returns the de-bounced button status of the
- // specified joystick
- //
- ///////////////////////////////////////////////////////////////////////////
- word
- IN_GetJoyButtonsDB(word joy)
- {
- longword lasttime;
- word result1,result2;
- do
- {
- result1 = INL_GetJoyButtons(joy);
- lasttime = TimeCount;
- while (TimeCount == lasttime)
- ;
- result2 = INL_GetJoyButtons(joy);
- } while (result1 != result2);
- return(result1);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // INL_StartKbd() - Sets up my keyboard stuff for use
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- INL_StartKbd(void)
- {
- INL_KeyHook = 0; // Clear key hook
- IN_ClearKeysDown();
- OldKeyVect = getvect(KeyInt);
- setvect(KeyInt,INL_KeyService);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // INL_ShutKbd() - Restores keyboard control to the BIOS
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- INL_ShutKbd(void)
- {
- poke(0x40,0x17,peek(0x40,0x17) & 0xfaf0); // Clear ctrl/alt/shift flags
- setvect(KeyInt,OldKeyVect);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // INL_StartMouse() - Detects and sets up the mouse
- //
- ///////////////////////////////////////////////////////////////////////////
- static boolean
- INL_StartMouse(void)
- {
- if (getvect(MouseInt))
- {
- Mouse(MReset);
- if (_AX == 0xffff)
- return(true);
- }
- return(false);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // INL_ShutMouse() - Cleans up after the mouse
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- INL_ShutMouse(void)
- {
- }
- //
- // INL_SetJoyScale() - Sets up scaling values for the specified joystick
- //
- static void
- INL_SetJoyScale(word joy)
- {
- JoystickDef *def;
- def = &JoyDefs[joy];
- def->joyMultXL = JoyScaleMax / (def->threshMinX - def->joyMinX);
- def->joyMultXH = JoyScaleMax / (def->joyMaxX - def->threshMaxX);
- def->joyMultYL = JoyScaleMax / (def->threshMinY - def->joyMinY);
- def->joyMultYH = JoyScaleMax / (def->joyMaxY - def->threshMaxY);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // IN_SetupJoy() - Sets up thresholding values and calls INL_SetJoyScale()
- // to set up scaling values
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- IN_SetupJoy(word joy,word minx,word maxx,word miny,word maxy)
- {
- word d,r;
- JoystickDef *def;
- def = &JoyDefs[joy];
- def->joyMinX = minx;
- def->joyMaxX = maxx;
- r = maxx - minx;
- d = r / 5;
- def->threshMinX = ((r / 2) - d) + minx;
- def->threshMaxX = ((r / 2) + d) + minx;
- def->joyMinY = miny;
- def->joyMaxY = maxy;
- r = maxy - miny;
- d = r / 5;
- def->threshMinY = ((r / 2) - d) + miny;
- def->threshMaxY = ((r / 2) + d) + miny;
- INL_SetJoyScale(joy);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // INL_StartJoy() - Detects & auto-configures the specified joystick
- // The auto-config assumes the joystick is centered
- //
- ///////////////////////////////////////////////////////////////////////////
- static boolean
- INL_StartJoy(word joy)
- {
- word x,y;
- IN_GetJoyAbs(joy,&x,&y);
- if
- (
- ((x == 0) || (x > MaxJoyValue - 10))
- || ((y == 0) || (y > MaxJoyValue - 10))
- )
- return(false);
- else
- {
- IN_SetupJoy(joy,0,x * 2,0,y * 2);
- return(true);
- }
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // INL_ShutJoy() - Cleans up the joystick stuff
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- INL_ShutJoy(word joy)
- {
- JoysPresent[joy] = false;
- }
- // Public routines
- ///////////////////////////////////////////////////////////////////////////
- //
- // IN_Startup() - Starts up the Input Mgr
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- IN_Startup(void)
- {
- boolean checkjoys,checkmouse;
- word i;
- if (IN_Started)
- return;
- checkjoys = true;
- checkmouse = true;
- for (i = 1;i < _argc;i++)
- {
- switch (US_CheckParm(_argv[i],ParmStrings))
- {
- case 0:
- checkjoys = false;
- break;
- case 1:
- checkmouse = false;
- break;
- }
- }
- INL_StartKbd();
- MousePresent = checkmouse? INL_StartMouse() : false;
- for (i = 0;i < MaxJoys;i++)
- JoysPresent[i] = checkjoys? INL_StartJoy(i) : false;
- IN_Started = true;
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // IN_Default() - Sets up default conditions for the Input Mgr
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- IN_Default(boolean gotit,ControlType in)
- {
- if
- (
- (!gotit)
- || ((in == ctrl_Joystick1) && !JoysPresent[0])
- || ((in == ctrl_Joystick2) && !JoysPresent[1])
- || ((in == ctrl_Mouse) && !MousePresent)
- )
- in = ctrl_Keyboard1;
- IN_SetControlType(0,in);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // IN_Shutdown() - Shuts down the Input Mgr
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- IN_Shutdown(void)
- {
- word i;
- if (!IN_Started)
- return;
- INL_ShutMouse();
- for (i = 0;i < MaxJoys;i++)
- INL_ShutJoy(i);
- INL_ShutKbd();
- IN_Started = false;
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // IN_SetKeyHook() - Sets the routine that gets called by INL_KeyService()
- // everytime a real make/break code gets hit
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- IN_SetKeyHook(void (*hook)())
- {
- INL_KeyHook = hook;
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // IN_ClearKeyDown() - Clears the keyboard array
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- IN_ClearKeysDown(void)
- {
- int i;
- LastScan = sc_None;
- LastASCII = key_None;
- for (i = 0;i < NumCodes;i++)
- Keyboard[i] = false;
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // INL_AdjustCursor() - Internal routine of common code from IN_ReadCursor()
- //
- ///////////////////////////////////////////////////////////////////////////
- static void
- INL_AdjustCursor(CursorInfo *info,word buttons,int dx,int dy)
- {
- if (buttons & (1 << 0))
- info->button0 = true;
- if (buttons & (1 << 1))
- info->button1 = true;
- info->x += dx;
- info->y += dy;
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // IN_ReadCursor() - Reads the input devices and fills in the cursor info
- // struct
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- IN_ReadCursor(CursorInfo *info)
- {
- word i,
- buttons;
- int dx,dy;
- info->x = info->y = 0;
- info->button0 = info->button1 = false;
- if (MousePresent)
- {
- buttons = INL_GetMouseButtons();
- INL_GetMouseDelta(&dx,&dy);
- INL_AdjustCursor(info,buttons,dx,dy);
- }
- for (i = 0;i < MaxJoys;i++)
- {
- if (!JoysPresent[i])
- continue;
- buttons = INL_GetJoyButtons(i);
- INL_GetJoyDelta(i,&dx,&dy,true);
- dx /= 64;
- dy /= 64;
- INL_AdjustCursor(info,buttons,dx,dy);
- }
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // IN_ReadControl() - Reads the device associated with the specified
- // player and fills in the control info struct
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- IN_ReadControl(int player,ControlInfo *info)
- {
- boolean realdelta=false; // MDM (GAMERS EDGE)
- byte dbyte;
- word buttons;
- int dx,dy;
- Motion mx,my;
- ControlType type;
- register KeyboardDef *def;
- dx = dy = 0;
- mx = my = motion_None;
- buttons = 0;
- #if 0
- if (DemoMode == demo_Playback)
- {
- dbyte = DemoBuffer[DemoOffset + 1];
- my = (dbyte & 3) - 1;
- mx = ((dbyte >> 2) & 3) - 1;
- buttons = (dbyte >> 4) & 3;
- if (!(--DemoBuffer[DemoOffset]))
- {
- DemoOffset += 2;
- if (DemoOffset >= DemoSize)
- DemoMode = demo_PlayDone;
- }
- realdelta = false;
- }
- else if (DemoMode == demo_PlayDone)
- Quit("Demo playback exceeded");
- else
- #endif
- {
- // MDM begin (GAMERS EDGE) - added this block
- ControlTypeUsed = ctrl_None;
- // Handle mouse input...
- //
- if ((MousePresent) && (ControlTypeUsed == ctrl_None))
- {
- INL_GetMouseDelta(&dx,&dy);
- buttons = INL_GetMouseButtons();
- realdelta = true;
- if (dx || dy || buttons)
- ControlTypeUsed = ctrl_Mouse;
- }
- // Handle joystick input...
- //
- if ((JoystickCalibrated) && (ControlTypeUsed == ctrl_None))
- {
- type = ctrl_Joystick1;
- INL_GetJoyDelta(type - ctrl_Joystick,&dx,&dy,false);
- buttons = INL_GetJoyButtons(type - ctrl_Joystick);
- realdelta = true;
- if (dx || dy || buttons)
- ControlTypeUsed = ctrl_Joystick;
- }
- // Handle keyboard input...
- //
- if (ControlTypeUsed == ctrl_None)
- {
- type = ctrl_Keyboard1;
- def = &KbdDefs[type - ctrl_Keyboard];
- if (Keyboard[def->upleft])
- mx = motion_Left,my = motion_Up;
- else if (Keyboard[def->upright])
- mx = motion_Right,my = motion_Up;
- else if (Keyboard[def->downleft])
- mx = motion_Left,my = motion_Down;
- else if (Keyboard[def->downright])
- mx = motion_Right,my = motion_Down;
- if (Keyboard[def->up])
- my = motion_Up;
- else if (Keyboard[def->down])
- my = motion_Down;
- if (Keyboard[def->left])
- mx = motion_Left;
- else if (Keyboard[def->right])
- mx = motion_Right;
- if (Keyboard[def->button0])
- buttons += 1 << 0;
- if (Keyboard[def->button1])
- buttons += 1 << 1;
- realdelta = false;
- if (mx || my || buttons)
- ControlTypeUsed = ctrl_Keyboard;
- } // MDM end (GAMERS EDGE)
- }
- if (realdelta)
- {
- mx = (dx < 0)? motion_Left : ((dx > 0)? motion_Right : motion_None);
- my = (dy < 0)? motion_Up : ((dy > 0)? motion_Down : motion_None);
- }
- else
- {
- dx = mx * 127;
- dy = my * 127;
- }
- info->x = dx;
- info->xaxis = mx;
- info->y = dy;
- info->yaxis = my;
- info->button0 = buttons & (1 << 0);
- info->button1 = buttons & (1 << 1);
- info->dir = DirTable[((my + 1) * 3) + (mx + 1)];
- #if 0
- if (DemoMode == demo_Record)
- {
- // Pack the control info into a byte
- dbyte = (buttons << 4) | ((mx + 1) << 2) | (my + 1);
- if
- (
- (DemoBuffer[DemoOffset + 1] == dbyte)
- && (DemoBuffer[DemoOffset] < 255)
- )
- (DemoBuffer[DemoOffset])++;
- else
- {
- if (DemoOffset || DemoBuffer[DemoOffset])
- DemoOffset += 2;
- if (DemoOffset >= DemoSize)
- Quit("Demo buffer overflow");
- DemoBuffer[DemoOffset] = 1;
- DemoBuffer[DemoOffset + 1] = dbyte;
- }
- }
- #endif
- }
- #if 0
- ///////////////////////////////////////////////////////////////////////////
- //
- // IN_ReadControl() - Reads the device associated with the specified
- // player and fills in the control info struct
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- IN_ReadControl(int player,ControlInfo *info)
- {
- boolean realdelta;
- byte dbyte;
- word buttons;
- int dx,dy;
- Motion mx,my;
- ControlType type;
- register KeyboardDef *def;
- dx = dy = 0;
- mx = my = motion_None;
- buttons = 0;
- #if 0
- if (DemoMode == demo_Playback)
- {
- dbyte = DemoBuffer[DemoOffset + 1];
- my = (dbyte & 3) - 1;
- mx = ((dbyte >> 2) & 3) - 1;
- buttons = (dbyte >> 4) & 3;
- if (!(--DemoBuffer[DemoOffset]))
- {
- DemoOffset += 2;
- if (DemoOffset >= DemoSize)
- DemoMode = demo_PlayDone;
- }
- realdelta = false;
- }
- else if (DemoMode == demo_PlayDone)
- Quit("Demo playback exceeded");
- else
- #endif
- {
- switch (type = Controls[player])
- {
- case ctrl_Keyboard1:
- case ctrl_Keyboard2:
- def = &KbdDefs[type - ctrl_Keyboard];
- if (Keyboard[def->upleft])
- mx = motion_Left,my = motion_Up;
- else if (Keyboard[def->upright])
- mx = motion_Right,my = motion_Up;
- else if (Keyboard[def->downleft])
- mx = motion_Left,my = motion_Down;
- else if (Keyboard[def->downright])
- mx = motion_Right,my = motion_Down;
- if (Keyboard[def->up])
- my = motion_Up;
- else if (Keyboard[def->down])
- my = motion_Down;
- if (Keyboard[def->left])
- mx = motion_Left;
- else if (Keyboard[def->right])
- mx = motion_Right;
- if (Keyboard[def->button0])
- buttons += 1 << 0;
- if (Keyboard[def->button1])
- buttons += 1 << 1;
- realdelta = false;
- break;
- case ctrl_Joystick1:
- case ctrl_Joystick2:
- INL_GetJoyDelta(type - ctrl_Joystick,&dx,&dy,false);
- buttons = INL_GetJoyButtons(type - ctrl_Joystick);
- realdelta = true;
- break;
- case ctrl_Mouse:
- INL_GetMouseDelta(&dx,&dy);
- buttons = INL_GetMouseButtons();
- realdelta = true;
- break;
- }
- }
- if (realdelta)
- {
- mx = (dx < 0)? motion_Left : ((dx > 0)? motion_Right : motion_None);
- my = (dy < 0)? motion_Up : ((dy > 0)? motion_Down : motion_None);
- }
- else
- {
- dx = mx * 127;
- dy = my * 127;
- }
- info->x = dx;
- info->xaxis = mx;
- info->y = dy;
- info->yaxis = my;
- info->button0 = buttons & (1 << 0);
- info->button1 = buttons & (1 << 1);
- info->dir = DirTable[((my + 1) * 3) + (mx + 1)];
- #if 0
- if (DemoMode == demo_Record)
- {
- // Pack the control info into a byte
- dbyte = (buttons << 4) | ((mx + 1) << 2) | (my + 1);
- if
- (
- (DemoBuffer[DemoOffset + 1] == dbyte)
- && (DemoBuffer[DemoOffset] < 255)
- )
- (DemoBuffer[DemoOffset])++;
- else
- {
- if (DemoOffset || DemoBuffer[DemoOffset])
- DemoOffset += 2;
- if (DemoOffset >= DemoSize)
- Quit("Demo buffer overflow");
- DemoBuffer[DemoOffset] = 1;
- DemoBuffer[DemoOffset + 1] = dbyte;
- }
- }
- #endif
- }
- #endif
- ///////////////////////////////////////////////////////////////////////////
- //
- // IN_SetControlType() - Sets the control type to be used by the specified
- // player
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- IN_SetControlType(int player,ControlType type)
- {
- // DEBUG - check that requested type is present?
- Controls[player] = type;
- }
- #if 0
- ///////////////////////////////////////////////////////////////////////////
- //
- // IN_StartDemoRecord() - Starts the demo recording, using a buffer the
- // size passed. Returns if the buffer allocation was successful
- //
- ///////////////////////////////////////////////////////////////////////////
- boolean
- IN_StartDemoRecord(word bufsize)
- {
- if (!bufsize)
- return(false);
- MM_GetPtr((memptr *)&DemoBuffer,bufsize);
- DemoMode = demo_Record;
- DemoSize = bufsize & ~1;
- DemoOffset = 0;
- DemoBuffer[0] = DemoBuffer[1] = 0;
- return(true);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // IN_StartDemoPlayback() - Plays back the demo pointed to of the given size
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- IN_StartDemoPlayback(byte _seg *buffer,word bufsize)
- {
- DemoBuffer = buffer;
- DemoMode = demo_Playback;
- DemoSize = bufsize & ~1;
- DemoOffset = 0;
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // IN_StopDemo() - Turns off demo mode
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- IN_StopDemo(void)
- {
- if ((DemoMode == demo_Record) && DemoOffset)
- DemoOffset += 2;
- DemoMode = demo_Off;
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // IN_FreeDemoBuffer() - Frees the demo buffer, if it's been allocated
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- IN_FreeDemoBuffer(void)
- {
- if (DemoBuffer)
- MM_FreePtr((memptr *)&DemoBuffer);
- }
- #endif
- #if 0
- ///////////////////////////////////////////////////////////////////////////
- //
- // IN_GetScanName() - Returns a string containing the name of the
- // specified scan code
- //
- ///////////////////////////////////////////////////////////////////////////
- byte *
- IN_GetScanName(ScanCode scan)
- {
- byte **p;
- ScanCode far *s;
- for (s = ExtScanCodes,p = ExtScanNames;*s;p++,s++)
- if (*s == scan)
- return(*p);
- return(ScanNames[scan]);
- }
- #endif
- ///////////////////////////////////////////////////////////////////////////
- //
- // IN_WaitForKey() - Waits for a scan code, then clears LastScan and
- // returns the scan code
- //
- ///////////////////////////////////////////////////////////////////////////
- ScanCode
- IN_WaitForKey(void)
- {
- ScanCode result;
- while (!(result = LastScan))
- ;
- LastScan = 0;
- return(result);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // IN_WaitForASCII() - Waits for an ASCII char, then clears LastASCII and
- // returns the ASCII value
- //
- ///////////////////////////////////////////////////////////////////////////
- char
- IN_WaitForASCII(void)
- {
- char result;
- while (!(result = LastASCII))
- ;
- LastASCII = '\0';
- return(result);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // IN_AckBack() - Waits for either an ASCII keypress or a button press
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- IN_AckBack(void)
- {
- word i;
- while (!LastScan)
- {
- if (MousePresent)
- {
- if (INL_GetMouseButtons())
- {
- while (INL_GetMouseButtons())
- ;
- return;
- }
- }
- for (i = 0;i < MaxJoys;i++)
- {
- if (JoysPresent[i])
- {
- if (IN_GetJoyButtonsDB(i))
- {
- while (IN_GetJoyButtonsDB(i))
- ;
- return;
- }
- }
- }
- }
- IN_ClearKey(LastScan);
- LastScan = sc_None;
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // IN_Ack() - Clears user input & then calls IN_AckBack()
- //
- ///////////////////////////////////////////////////////////////////////////
- void
- IN_Ack(void)
- {
- word i;
- IN_ClearKey(LastScan);
- LastScan = sc_None;
- if (MousePresent)
- while (INL_GetMouseButtons())
- ;
- for (i = 0;i < MaxJoys;i++)
- if (JoysPresent[i])
- while (IN_GetJoyButtonsDB(i))
- ;
- IN_AckBack();
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // IN_IsUserInput() - Returns true if a key has been pressed or a button
- // is down
- //
- ///////////////////////////////////////////////////////////////////////////
- boolean
- IN_IsUserInput(void)
- {
- boolean result;
- word i;
- result = LastScan;
- if (MousePresent)
- if (INL_GetMouseButtons())
- result = true;
- for (i = 0;i < MaxJoys;i++)
- if (JoysPresent[i])
- if (INL_GetJoyButtons(i))
- result = true;
- return(result);
- }
- ///////////////////////////////////////////////////////////////////////////
- //
- // IN_UserInput() - Waits for the specified delay time (in ticks) or the
- // user pressing a key or a mouse button. If the clear flag is set, it
- // then either clears the key or waits for the user to let the mouse
- // button up.
- //
- ///////////////////////////////////////////////////////////////////////////
- boolean
- IN_UserInput(longword delay,boolean clear)
- {
- longword lasttime;
- lasttime = TimeCount;
- do
- {
- if (IN_IsUserInput())
- {
- if (clear)
- IN_AckBack();
- return(true);
- }
- } while (TimeCount - lasttime < delay);
- return(false);
- }
|