1 /* Catacomb Apocalypse Source Code
\r
2 * Copyright (C) 1993-2014 Flat Rock Software
\r
4 * This program is free software; you can redistribute it and/or modify
\r
5 * it under the terms of the GNU General Public License as published by
\r
6 * the Free Software Foundation; either version 2 of the License, or
\r
7 * (at your option) any later version.
\r
9 * This program is distributed in the hope that it will be useful,
\r
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
\r
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
\r
12 * GNU General Public License for more details.
\r
14 * You should have received a copy of the GNU General Public License along
\r
15 * with this program; if not, write to the Free Software Foundation, Inc.,
\r
16 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
\r
21 // ID_IN.c - Input Manager
23 // By Jason Blochowiak
24 // Open Watcom port by sparky4
28 // This module handles dealing with the various input devices
30 // Depends on: Memory Mgr (for demo recording), Sound Mgr (for timing stuff),
31 // User Mgr (for command line parms)
34 // LastScan - The keyboard scan code of the last key pressed
35 // LastASCII - The ASCII value of the last key pressed
36 // DEBUG - there are more globals
39 #include "src/lib/16_in.h"
42 =============================================================================
\r
46 =============================================================================
\r
48 #ifdef __cplusplus /* Function must be declared C style */
51 static byte far ASCIINames[] = // Unshifted ASCII for scan codes
\r
53 // 0 1 2 3 4 5 6 7 8 9 A B C D E F
\r
54 0 ,27 ,'1','2','3','4','5','6','7','8','9','0','-','=',8 ,9 , // 0
\r
55 'q','w','e','r','t','y','u','i','o','p','[',']',13 ,0 ,'a','s', // 1
\r
56 'd','f','g','h','j','k','l',';',39 ,'`',0 ,92 ,'z','x','c','v', // 2
\r
57 'b','n','m',',','.','/',0 ,'*',0 ,' ',0 ,0 ,0 ,0 ,0 ,0 , // 3
\r
58 0 ,0 ,0 ,0 ,0 ,0 ,0 ,'7','8','9','-','4','5','6','+','1', // 4
\r
59 '2','3','0',127,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 5
\r
60 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 6
\r
61 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 // 7
\r
63 far ShiftNames[] = // Shifted ASCII for scan codes
\r
65 // 0 1 2 3 4 5 6 7 8 9 A B C D E F
\r
66 0 ,27 ,'!','@','#','$','%','^','&','*','(',')','_','+',8 ,9 , // 0
\r
67 'Q','W','E','R','T','Y','U','I','O','P','{','}',13 ,0 ,'A','S', // 1
\r
68 'D','F','G','H','J','K','L',':',34 ,'~',0 ,'|','Z','X','C','V', // 2
\r
69 'B','N','M','<','>','?',0 ,'*',0 ,' ',0 ,0 ,0 ,0 ,0 ,0 , // 3
\r
70 0 ,0 ,0 ,0 ,0 ,0 ,0 ,'7','8','9','-','4','5','6','+','1', // 4
\r
71 '2','3','0',127,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 5
\r
72 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 6
\r
73 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 // 7
\r
75 far SpecialNames[] = // ASCII for 0xe0 prefixed codes
\r
77 // 0 1 2 3 4 5 6 7 8 9 A B C D E F
\r
78 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 0
\r
79 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,13 ,0 ,0 ,0 , // 1
\r
80 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 2
\r
81 0 ,0 ,0 ,0 ,0 ,'/',0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 3
\r
82 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 4
\r
83 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 5
\r
84 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 , // 6
\r
85 0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 ,0 // 7
\r
87 *ScanNames[] = // Scan code names with single chars
\r
89 "?","?","1","2","3","4","5","6","7","8","9","0","-","+","?","?",
\r
90 "Q","W","E","R","T","Y","U","I","O","P","[","]","|","?","A","S",
\r
91 "D","F","G","H","J","K","L",";","\"","?","?","?","Z","X","C","V",
\r
92 "B","N","M",",",".","/","?","?","?","?","?","?","?","?","?","?",
\r
93 "?","?","?","?","?","?","?","?","\xf","?","-","\x15","5","\x11","+","?",
\r
94 "\x13","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?",
\r
95 "?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?",
\r
96 "?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?"
\r
97 }, // DEBUG - consolidate these
\r
98 far ExtScanCodes[] = // Scan codes with >1 char names
\r
100 1,0xe,0xf,0x1d,0x2a,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,
\r
101 0x3f,0x40,0x41,0x42,0x43,0x44,0x57,0x59,0x46,0x1c,0x36,
\r
102 0x37,0x38,0x47,0x49,0x4f,0x51,0x52,0x53,0x45,0x48,
\r
103 0x50,0x4b,0x4d,0x00
\r
105 *ExtScanNames[] = // Names corresponding to ExtScanCodes
\r
107 "Esc","BkSp","Tab","Ctrl","LShft","Space","CapsLk","F1","F2","F3","F4",
\r
108 "F5","F6","F7","F8","F9","F10","F11","F12","ScrlLk","Enter","RShft",
\r
109 "PrtSc","Alt","Home","PgUp","End","PgDn","Ins","Del","NumLk","Up",
\r
110 "Down","Left","Right",""
\r
113 static Direction DirTable[] = // Quick lookup for total direction
\r
118 dir_West, dir_None, dir_East,
\r
120 dir_South//,dir_SouthEast
\r
123 static boolean IN_Started;
\r
124 static boolean CapsLock;
\r
125 static ScanCode CurCode,LastCode;
127 static void (*INL_KeyHook)(void);
128 static void interrupt (*OldKeyVect)(void);
129 static char *ParmStringsIN[] = {"nojoys","nomouse",nil};
135 ///////////////////////////////////////////////////////////////////////////
137 // INL_KeyService() - Handles a keyboard interrupt (key up/down)
139 ///////////////////////////////////////////////////////////////////////////
141 INL_KeyService(inconfig *in)
143 static boolean special;
147 k = inp(0x60); // Get the scan code
149 // Tell the XT keyboard controller to clear the key
150 outp(0x61,(temp = inp(0x61)) | 0x80);
153 if (k == 0xe0) // Special key prefix
155 else if (k == 0xe1) // Handle Pause key
159 if (k & 0x80) // Break code
163 // DEBUG - handle special keys: ctl-alt-delete, print scrn
165 in->Keyboard[k] = false;
170 CurCode = in->LastScan = k;
171 in->Keyboard[k] = true;
177 if (k == sc_CapsLock)
180 // DEBUG - make caps lock light work
183 if (in->Keyboard[sc_LShift] || in->Keyboard[sc_RShift]) // If shifted
186 if ((c >= 'A') && (c <= 'Z') && CapsLock)
192 if ((c >= 'a') && (c <= 'z') && CapsLock)
203 if (INL_KeyHook && !special)
206 printf("%c %x %u\n", c, k, in->Keyboard[k]);
216 int86(MouseInt,&CPURegs,&CPURegs);
219 ///////////////////////////////////////////////////////////////////////////
221 // INL_GetMouseDelta() - Gets the amount that the mouse has moved from the
224 ///////////////////////////////////////////////////////////////////////////
226 INL_GetMouseDelta(int *x,int *y)
234 ///////////////////////////////////////////////////////////////////////////
236 // INL_GetMouseButtons() - Gets the status of the mouse buttons from the
239 ///////////////////////////////////////////////////////////////////////////
241 INL_GetMouseButtons(void)
247 buttons = CPURegs.x.bx;
251 ///////////////////////////////////////////////////////////////////////////
253 // IN_GetJoyAbs() - Reads the absolute position of the specified joystick
255 ///////////////////////////////////////////////////////////////////////////
257 IN_GetJoyAbs(word joy,word *xp,word *yp)
264 xs = joy? 2 : 0; // Find shift value for x axis
265 xb = 1 << xs; // Use shift value to get x bit mask
266 ys = joy? 3 : 1; // Do the same for y axis
269 // Read the absolute joystick values
272 pushf // Save some registers
275 cli // Make sure an interrupt doesn't screw the timings
280 out dx,al // Clear the resistors
282 mov ah,[xb] // Get masks into registers
285 xor si,si // Clear count registers
287 xor bh,bh // Clear high byte of bx for later
289 push bp // Don't mess up stack frame
293 in al,dx // Get bits indicating whether all are finished
295 dec bp // Check bounding register
296 jz done // We have a silly value - abort
298 mov bl,al // Duplicate the bits
299 and bl,ah // Mask off useless bits (in [xb])
300 add si,bx // Possibly increment count register
301 mov cl,bl // Save for testing later
308 jnz loo // If both bits were 0, drop out
313 mov cl,[xs] // Get the number of bits to shift
314 shr si,cl // and shift the count that many times
319 mov [x],si // Store the values into the variables
324 popf // Restore the registers
331 ///////////////////////////////////////////////////////////////////////////
333 // INL_GetJoyDelta() - Returns the relative movement of the specified
334 // joystick (from +/-127, scaled adaptively)
336 ///////////////////////////////////////////////////////////////////////////
338 INL_GetJoyDelta(word joy,int *dx,int *dy,boolean adaptive, inconfig *in)
342 dword TimeCount = *clockdw;
344 static dword lasttime;
346 IN_GetJoyAbs(joy,&x,&y);
347 def = in->JoyDefs + joy;
349 if (x < def->threshMinX)
351 if (x < def->joyMinX)
354 x = -(x - def->threshMinX);
357 *dx = (x > 127)? -127 : -x;
359 else if (x > def->threshMaxX)
361 if (x > def->joyMaxX)
364 x = x - def->threshMaxX;
367 *dx = (x > 127)? 127 : x;
372 if (y < def->threshMinY)
374 if (y < def->joyMinY)
377 y = -(y - def->threshMinY);
380 *dy = (y > 127)? -127 : -y;
382 else if (y > def->threshMaxY)
384 if (y > def->joyMaxY)
387 y = y - def->threshMaxY;
390 *dy = (y > 127)? 127 : y;
397 time = (TimeCount - lasttime) / 2;
406 lasttime = TimeCount;
409 ///////////////////////////////////////////////////////////////////////////
411 // INL_GetJoyButtons() - Returns the button status of the specified
414 ///////////////////////////////////////////////////////////////////////////
416 INL_GetJoyButtons(word joy)
418 register word result;
420 result = inp(0x201); // Get all the joystick buttons
421 result >>= joy? 6 : 4; // Shift into bits 0-1
422 result &= 3; // Mask off the useless bits
427 ///////////////////////////////////////////////////////////////////////////
429 // IN_GetJoyButtonsDB() - Returns the de-bounced button status of the
430 // specified joystick
432 ///////////////////////////////////////////////////////////////////////////
434 IN_GetJoyButtonsDB(word joy)
436 dword TimeCount = *clockdw;
438 word result1,result2;
442 result1 = INL_GetJoyButtons(joy);
443 lasttime = TimeCount;
444 while(TimeCount == lasttime)
445 result2 = INL_GetJoyButtons(joy);
446 } while(result1 != result2);
450 ///////////////////////////////////////////////////////////////////////////
452 // INL_StartKbd() - Sets up my keyboard stuff for use
454 ///////////////////////////////////////////////////////////////////////////
456 INL_StartKbd(inconfig *in)
458 INL_KeyHook = 0; // Clear key hook
460 IN_ClearKeysDown(in);
462 OldKeyVect = _dos_getvect(KeyInt);
463 _dos_setvect(KeyInt,INL_KeyService);
466 ///////////////////////////////////////////////////////////////////////////
468 // INL_ShutKbd() - Restores keyboard control to the BIOS
470 ///////////////////////////////////////////////////////////////////////////
474 pokeb(0x40,0x17,peekb(0x40,0x17) & 0xfaf0); // Clear ctrl/alt/shift flags
476 _dos_setvect(KeyInt,OldKeyVect);
479 ///////////////////////////////////////////////////////////////////////////
481 // INL_StartMouse() - Detects and sets up the mouse
483 ///////////////////////////////////////////////////////////////////////////
488 if(_dos_getvect(MouseInt))
491 if(CPURegs.x.ax == 0xffff)
497 ///////////////////////////////////////////////////////////////////////////
499 // INL_ShutMouse() - Cleans up after the mouse
501 ///////////////////////////////////////////////////////////////////////////
508 // INL_SetJoyScale() - Sets up scaling values for the specified joystick
511 INL_SetJoyScale(word joy, inconfig *in)
515 def = &(in->JoyDefs[joy]);
516 def->joyMultXL = JoyScaleMax / (def->threshMinX - def->joyMinX);
517 def->joyMultXH = JoyScaleMax / (def->joyMaxX - def->threshMaxX);
518 def->joyMultYL = JoyScaleMax / (def->threshMinY - def->joyMinY);
519 def->joyMultYH = JoyScaleMax / (def->joyMaxY - def->threshMaxY);
522 ///////////////////////////////////////////////////////////////////////////
524 // IN_SetupJoy() - Sets up thresholding values and calls INL_SetJoyScale()
525 // to set up scaling values
527 ///////////////////////////////////////////////////////////////////////////
529 IN_SetupJoy(word joy,word minx,word maxx,word miny,word maxy, inconfig *in)
534 def = &(in->JoyDefs[joy]);
540 def->threshMinX = ((r / 2) - d) + minx;
541 def->threshMaxX = ((r / 2) + d) + minx;
547 def->threshMinY = ((r / 2) - d) + miny;
548 def->threshMaxY = ((r / 2) + d) + miny;
550 INL_SetJoyScale(joy, in);
553 ///////////////////////////////////////////////////////////////////////////
555 // INL_StartJoy() - Detects & auto-configures the specified joystick
556 // The auto-config assumes the joystick is centered
558 ///////////////////////////////////////////////////////////////////////////
560 INL_StartJoy(word joy, inconfig *in)
564 IN_GetJoyAbs(joy,&x,&y);
568 ((x == 0) || (x > MaxJoyValue - 10))
569 || ((y == 0) || (y > MaxJoyValue - 10))
574 IN_SetupJoy(joy,0,x * 2,0,y * 2, in);
579 ///////////////////////////////////////////////////////////////////////////
581 // INL_ShutJoy() - Cleans up the joystick stuff
583 ///////////////////////////////////////////////////////////////////////////
585 INL_ShutJoy(word joy, inconfig *in)
587 in->JoysPresent[joy] = false;
592 ///////////////////////////////////////////////////////////////////////////
594 // IN_Startup() - Starts up the Input Mgr
596 ///////////////////////////////////////////////////////////////////////////
598 IN_Startup(inconfig *in)
600 boolean checkjoys,checkmouse;
610 for (i = 1;i < __argc;i++)
612 switch (US_CheckParm(__argv[i],ParmStringsIN))
624 in->MousePresent = checkmouse? INL_StartMouse() : false;
626 for (i = 0;i < MaxJoys;i++)
627 in->JoysPresent[i] = checkjoys? INL_StartJoy(i, in) : false;
633 ///////////////////////////////////////////////////////////////////////////
635 // IN_Default() - Sets up default conditions for the Input Mgr
637 ///////////////////////////////////////////////////////////////////////////
639 IN_Default(boolean gotit,player_t *player,ControlType nt, inconfig *in)
644 || ((nt == ctrl_Joystick1) && !in->JoysPresent[0])
645 || ((nt == ctrl_Joystick2) && !in->JoysPresent[1])
646 || ((nt == ctrl_Mouse) && !in->MousePresent)
647 || ((nt == ctrl_Joypad1) && !in->JoyPadPresent[0])
648 || ((nt == ctrl_Joypad2) && !in->JoyPadPresent[1])
651 IN_SetControlType(0,player,nt);
654 ///////////////////////////////////////////////////////////////////////////
656 // IN_Shutdown() - Shuts down the Input Mgr
658 ///////////////////////////////////////////////////////////////////////////
660 IN_Shutdown(inconfig *in)
670 for (i = 0;i < MaxJoys;i++)
678 ///////////////////////////////////////////////////////////////////////////
680 // IN_SetKeyHook() - Sets the routine that gets called by INL_KeyService()
681 // everytime a real make/break code gets hit
683 ///////////////////////////////////////////////////////////////////////////
685 IN_SetKeyHook(void (*hook)())
690 ///////////////////////////////////////////////////////////////////////////
692 // IN_ClearKeyDown() - Clears the keyboard array
694 ///////////////////////////////////////////////////////////////////////////
696 IN_ClearKeysDown(inconfig *in)
700 in->LastScan = sc_None;
701 in->LastASCII = key_None;
702 memset (in->Keyboard,0,sizeof(in->Keyboard));
705 ///////////////////////////////////////////////////////////////////////////
707 // INL_AdjustCursor() - Internal routine of common code from IN_ReadCursor()
709 ///////////////////////////////////////////////////////////////////////////
711 INL_AdjustCursor(CursorInfo *info,word buttons,int dx,int dy)
713 if (buttons & (1 << 0))
714 info->button0 = true;
715 if (buttons & (1 << 1))
716 info->button1 = true;
722 ///////////////////////////////////////////////////////////////////////////
724 // IN_ReadCursor() - Reads the input devices and fills in the cursor info
727 ///////////////////////////////////////////////////////////////////////////
729 IN_ReadCursor(CursorInfo *info, inconfig *in)
735 info->x = info->y = 0;
736 info->button0 = info->button1 = false;
738 if (in->MousePresent)
740 buttons = INL_GetMouseButtons();
741 INL_GetMouseDelta(&dx,&dy);
742 INL_AdjustCursor(info,buttons,dx,dy);
745 for (i = 0;i < MaxJoys;i++)
747 if (!in->JoysPresent[i])
750 buttons = INL_GetJoyButtons(i);
751 INL_GetJoyDelta(i,&dx,&dy,true, in);
754 INL_AdjustCursor(info,buttons,dx,dy);
758 ///////////////////////////////////////////////////////////////////////////
760 // IN_ReadControl() - Reads the device associated with the specified
761 // player and fills in the control info struct
763 ///////////////////////////////////////////////////////////////////////////
765 IN_ReadControl(int playnum,player_t *player, inconfig *in)
773 register KeyboardDef *def;
776 mx = my = motion_None;
780 if (DemoMode == demo_Playback)
782 dbyte = DemoBuffer[DemoOffset + 1];
783 my = (dbyte & 3) - 1;
784 mx = ((dbyte >> 2) & 3) - 1;
785 buttons = (dbyte >> 4) & 3;
787 if (!(--DemoBuffer[DemoOffset]))
790 if (DemoOffset >= DemoSize)
791 DemoMode = demo_PlayDone;
796 else if (DemoMode == demo_PlayDone)
797 Quit("Demo playback exceeded");
801 switch (type = player[playnum].Controls)
805 def = &(in->KbdDefs[type - ctrl_Keyboard]);
807 /* if (Keyboard[def->upleft])
808 mx = motion_Left,my = motion_Up;
809 else if (Keyboard[def->upright])
810 mx = motion_Right,my = motion_Up;
811 else if (Keyboard[def->downleft])
812 mx = motion_Left,my = motion_Down;
813 else if (Keyboard[def->downright])
814 mx = motion_Right,my = motion_Down;*/
816 if (in->Keyboard[def->up])
818 else if (in->Keyboard[def->down])
821 if (in->Keyboard[def->left])
823 else if (in->Keyboard[def->right])
826 if (in->Keyboard[def->button0])
828 if (in->Keyboard[def->button1])
834 INL_GetJoyDelta(type - ctrl_Joystick,&dx,&dy,false, in);
835 buttons = INL_GetJoyButtons(type - ctrl_Joystick);
839 INL_GetMouseDelta(&dx,&dy);
840 buttons = INL_GetMouseButtons();
854 mx = (dx < 0)? motion_Left : ((dx > 0)? motion_Right : motion_None);
855 my = (dy < 0)? motion_Up : ((dy > 0)? motion_Down : motion_None);
863 player[playnum].info.x = dx;
864 player[playnum].info.xaxis = mx;
865 player[playnum].info.y = dy;
866 player[playnum].info.yaxis = my;
867 player[playnum].info.button0 = buttons & (1 << 0);
868 player[playnum].info.button1 = buttons & (1 << 1);
869 player[playnum].info.button2 = buttons & (1 << 2);
870 player[playnum].info.button3 = buttons & (1 << 3);
871 player[playnum].info.dir = DirTable[((my + 1) * 3) + (mx + 1)];
874 if (DemoMode == demo_Record)
876 // Pack the control info into a byte
877 dbyte = (buttons << 4) | ((mx + 1) << 2) | (my + 1);
881 (DemoBuffer[DemoOffset + 1] == dbyte)
882 && (DemoBuffer[DemoOffset] < 255)
884 (DemoBuffer[DemoOffset])++;
887 if (DemoOffset || DemoBuffer[DemoOffset])
890 if (DemoOffset >= DemoSize)
891 Quit("Demo buffer overflow");
893 DemoBuffer[DemoOffset] = 1;
894 DemoBuffer[DemoOffset + 1] = dbyte;
900 ///////////////////////////////////////////////////////////////////////////
902 // IN_SetControlType() - Sets the control type to be used by the specified
905 ///////////////////////////////////////////////////////////////////////////
907 IN_SetControlType(word playnum,player_t *player,ControlType type)
909 // DEBUG - check that requested type is present?
910 player[playnum].Controls = type;
914 ///////////////////////////////////////////////////////////////////////////
916 // IN_StartDemoRecord() - Starts the demo recording, using a buffer the
917 // size passed. Returns if the buffer allocation was successful
919 ///////////////////////////////////////////////////////////////////////////
921 IN_StartDemoRecord(word bufsize)
926 MM_GetPtr((memptr *)&DemoBuffer,bufsize);
927 DemoMode = demo_Record;
928 DemoSize = bufsize & ~1;
930 DemoBuffer[0] = DemoBuffer[1] = 0;
935 ///////////////////////////////////////////////////////////////////////////
937 // IN_StartDemoPlayback() - Plays back the demo pointed to of the given size
939 ///////////////////////////////////////////////////////////////////////////
941 IN_StartDemoPlayback(byte /*__segment*/ *buffer,word bufsize)
944 DemoMode = demo_Playback;
945 DemoSize = bufsize & ~1;
949 ///////////////////////////////////////////////////////////////////////////
951 // IN_StopDemo() - Turns off demo mode
953 ///////////////////////////////////////////////////////////////////////////
957 if ((DemoMode == demo_Record) && DemoOffset)
963 ///////////////////////////////////////////////////////////////////////////
965 // IN_FreeDemoBuffer() - Frees the demo buffer, if it's been allocated
967 ///////////////////////////////////////////////////////////////////////////
969 IN_FreeDemoBuffer(void)
972 MM_FreePtr((memptr *)&DemoBuffer);
977 ///////////////////////////////////////////////////////////////////////////
979 // IN_GetScanName() - Returns a string containing the name of the
980 // specified scan code
982 ///////////////////////////////////////////////////////////////////////////
984 IN_GetScanName(ScanCode scan)
989 for (s = ExtScanCodes,p = ExtScanNames;*s;p++,s++)
993 return(ScanNames[scan]);
996 ///////////////////////////////////////////////////////////////////////////
998 // IN_WaitForKey() - Waits for a scan code, then clears LastScan and
999 // returns the scan code
1001 ///////////////////////////////////////////////////////////////////////////
1003 IN_WaitForKey(inconfig *in)
1007 while (!(result = in->LastScan))
1013 ///////////////////////////////////////////////////////////////////////////
1015 // IN_WaitForASCII() - Waits for an ASCII char, then clears LastASCII and
1016 // returns the ASCII value
1018 ///////////////////////////////////////////////////////////////////////////
1020 IN_WaitForASCII(inconfig *in)
1024 while (!(result = in->LastASCII))
1026 in->LastASCII = '\0';
1030 ///////////////////////////////////////////////////////////////////////////
1032 // IN_AckBack() - Waits for either an ASCII keypress or a button press
1034 ///////////////////////////////////////////////////////////////////////////
1036 IN_AckBack(inconfig *in)
1040 while (!in->LastScan)
1042 if (in->MousePresent)
1044 if (INL_GetMouseButtons())
1046 while (INL_GetMouseButtons())
1052 for (i = 0;i < MaxJoys;i++)
1054 if (in->JoysPresent[i])
1056 if (IN_GetJoyButtonsDB(i))
1058 while (IN_GetJoyButtonsDB(i))
1066 IN_ClearKey(in->LastScan, in);
1067 in->LastScan = sc_None;
1070 ///////////////////////////////////////////////////////////////////////////
1072 // IN_Ack() - Clears user input & then calls IN_AckBack()
1074 ///////////////////////////////////////////////////////////////////////////
1076 IN_Ack(inconfig *in)
1080 IN_ClearKey(in->LastScan, in);
1081 in->LastScan = sc_None;
1083 if (in->MousePresent)
1084 while (INL_GetMouseButtons())
1086 for (i = 0;i < MaxJoys;i++)
1087 if (in->JoysPresent[i])
1088 while (IN_GetJoyButtonsDB(i))
1094 ///////////////////////////////////////////////////////////////////////////
1096 // IN_IsUserInput() - Returns true if a key has been pressed or a button
1099 ///////////////////////////////////////////////////////////////////////////
1101 IN_IsUserInput(inconfig *in)
1106 result = in->LastScan;
1108 if (in->MousePresent)
1109 if (INL_GetMouseButtons())
1112 for (i = 0;i < MaxJoys;i++)
1113 if (in->JoysPresent[i])
1114 if (INL_GetJoyButtons(i))
1120 ///////////////////////////////////////////////////////////////////////////
1122 // IN_UserInput() - Waits for the specified delay time (in ticks) or the
1123 // user pressing a key or a mouse button. If the clear flag is set, it
1124 // then either clears the key or waits for the user to let the mouse
1127 ///////////////////////////////////////////////////////////////////////////
1129 IN_UserInput(dword delay,boolean clear, inconfig *in)
1131 dword TimeCount = *clockdw;
1134 lasttime = TimeCount;
1137 if (IN_IsUserInput(in))
1143 } while (TimeCount - lasttime < delay);
1147 boolean IN_KeyDown(byte code, inconfig *in)
1149 return in->Keyboard[(code)];
1152 void IN_ClearKey(byte code, inconfig *in)
1154 in->Keyboard[code] = false;
1155 if(code == in->LastScan)
1156 in->LastScan = sc_None;