]> 4ch.mooo.com Git - 16.git/blob - src/lib/16_in.c
==== OK i removed all warnings wwww
[16.git] / src / lib / 16_in.c
1 /* Catacomb Apocalypse Source Code\r
2  * Copyright (C) 1993-2014 Flat Rock Software\r
3  *\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
8  *\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
13  *\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
17  */\r
18 \r
19 //\r
20 //      ID Engine\r
21 //      ID_IN.c - Input Manager\r
22 //      v1.0d1w\r
23 //      By Jason Blochowiak\r
24 //      Open Watcom port by sparky4\r
25 //\r
26 \r
27 //\r
28 //      This module handles dealing with the various input devices\r
29 //\r
30 //      Depends on: Memory Mgr (for demo recording), Sound Mgr (for timing stuff),\r
31 //                              User Mgr (for command line parms)\r
32 //\r
33 //      Globals:\r
34 //              LastScan - The keyboard scan code of the last key pressed\r
35 //              LastASCII - The ASCII value of the last key pressed\r
36 //      DEBUG - there are more globals\r
37 //\r
38 \r
39 #include "src/lib/16_in.h"\r
40 \r
41 #ifdef __DEBUG_InputMgr__\r
42 boolean dbg_testkeyin=0,dbg_testcontrolnoisy=0;\r
43 #endif\r
44 \r
45 static word far* clockw= (word far*) 0x046C; /* 18.2hz clock */\r
46 \r
47 /*\r
48 =============================================================================\r
49 \r
50                                         GLOBAL VARIABLES\r
51 \r
52 =============================================================================\r
53 */\r
54 struct inconfig\r
55 {\r
56         boolean                 MousePresent;\r
57         boolean                 JoysPresent[MaxJoys];\r
58         boolean         Keyboard[NumCodes];\r
59         boolean         Paused;\r
60         char            LastASCII;\r
61         ScanCode        LastScan;\r
62 \r
63         KeyboardDef     KbdDefs[MaxKbds];\r
64         JoystickDef     JoyDefs[MaxJoys];\r
65 } inpu;\r
66 \r
67 //extern inconfig inpu;\r
68 //inpu.KbdDefs = {0x1d,0x38,/*0x47,*/0x48,/*0x49,*/0x4b,0x4d,/*0x4f,*/0x50/*,0x51*/};\r
69 \r
70 /*\r
71 =============================================================================\r
72 \r
73                                         LOCAL VARIABLES\r
74 \r
75 =============================================================================\r
76 */\r
77 \r
78 #ifdef __cplusplus              /* Function must be declared C style */\r
79 extern "C" {\r
80 #endif\r
81 \r
82 static struct instat {\r
83         boolean         IN_Started;\r
84         boolean         CapsLock;\r
85         ScanCode        CurCode,LastCode;\r
86 } inst;\r
87 \r
88 static  void                    (*INL_KeyHook)(void);\r
89 static  void interrupt  (*OldKeyVect)(void);\r
90 static  char                    *ParmStringsIN[] = {"nojoys","nomouse",nil};\r
91 \r
92 static  byte        far ASCIINames[] =          // Unshifted ASCII for scan codes\r
93                                         {\r
94 //       0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F\r
95         0  ,27 ,'1','2','3','4','5','6','7','8','9','0','-','=',8  ,9  ,        // 0\r
96         'q','w','e','r','t','y','u','i','o','p','[',']',13 ,0  ,'a','s',        // 1\r
97         'd','f','g','h','j','k','l',';',39 ,'`',0  ,92 ,'z','x','c','v',        // 2\r
98         'b','n','m',',','.','/',0  ,'*',0  ,' ',0  ,0  ,0  ,0  ,0  ,0  ,        // 3\r
99         0  ,0  ,0  ,0  ,0  ,0  ,0  ,'7','8','9','-','4','5','6','+','1',        // 4\r
100         '2','3','0',127,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,        // 5\r
101         0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,        // 6\r
102         0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0           // 7\r
103                                         },\r
104                                         far ShiftNames[] =              // Shifted ASCII for scan codes\r
105                                         {\r
106 //       0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F\r
107         0  ,27 ,'!','@','#','$','%','^','&','*','(',')','_','+',8  ,9  ,        // 0\r
108         'Q','W','E','R','T','Y','U','I','O','P','{','}',13 ,0  ,'A','S',        // 1\r
109         'D','F','G','H','J','K','L',':',34 ,'~',0  ,'|','Z','X','C','V',        // 2\r
110         'B','N','M','<','>','?',0  ,'*',0  ,' ',0  ,0  ,0  ,0  ,0  ,0  ,        // 3\r
111         0  ,0  ,0  ,0  ,0  ,0  ,0  ,'7','8','9','-','4','5','6','+','1',        // 4\r
112         '2','3','0',127,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,        // 5\r
113         0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,        // 6\r
114         0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0           // 7\r
115                                         },\r
116                                         far SpecialNames[] =    // ASCII for 0xe0 prefixed codes\r
117                                         {\r
118 //       0   1   2   3   4   5   6   7   8   9   A   B   C   D   E   F\r
119         0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,        // 0\r
120         0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,13 ,0  ,0  ,0  ,        // 1\r
121         0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,        // 2\r
122         0  ,0  ,0  ,0  ,0  ,'/',0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,        // 3\r
123         0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,        // 4\r
124         0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,        // 5\r
125         0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,        // 6\r
126         0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0  ,0           // 7\r
127                                         },\r
128                                         *ScanNames[] =          // Scan code names with single chars\r
129                                         {\r
130         "?","?","1","2","3","4","5","6","7","8","9","0","-","+","?","?",\r
131         "Q","W","E","R","T","Y","U","I","O","P","[","]","|","?","A","S",\r
132         "D","F","G","H","J","K","L",";","\"","?","?","?","Z","X","C","V",\r
133         "B","N","M",",",".","/","?","?","?","?","?","?","?","?","?","?",\r
134         "?","?","?","?","?","?","?","?","\xf","?","-","\x15","5","\x11","+","?",\r
135         "\x13","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?",\r
136         "?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?",\r
137         "?","?","?","?","?","?","?","?","?","?","?","?","?","?","?","?"\r
138                                         },      // DEBUG - consolidate these\r
139                                         far ExtScanCodes[] =    // Scan codes with >1 char names\r
140                                         {\r
141         1,0xe,0xf,0x1d,0x2a,0x39,0x3a,0x3b,0x3c,0x3d,0x3e,\r
142         0x3f,0x40,0x41,0x42,0x43,0x44,0x57,0x59,0x46,0x1c,0x36,\r
143         0x37,0x38,0x47,0x49,0x4f,0x51,0x52,0x53,0x45,0x48,\r
144         0x50,0x4b,0x4d,0x00\r
145                                         },\r
146                                         *ExtScanNames[] =       // Names corresponding to ExtScanCodes\r
147                                         {\r
148         "Esc","BkSp","Tab","Ctrl","LShft","Space","CapsLk","F1","F2","F3","F4",\r
149         "F5","F6","F7","F8","F9","F10","F11","F12","ScrlLk","Enter","RShft",\r
150         "PrtSc","Alt","Home","PgUp","End","PgDn","Ins","Del","NumLk","Up",\r
151         "Down","Left","Right",""\r
152                                         };\r
153 \r
154 static  Direction       DirTable[] =            // Quick lookup for total direction\r
155                                         {\r
156                                                 //dir_Nortinest,\r
157                                                 dir_North,\r
158                                                 dir_West,\r
159                                                 dir_None,\r
160                                                 dir_East,\r
161                                                 dir_South\r
162                                                 //dir_NorthEast,\r
163                                                 //dir_Soutinest,\r
164                                                 //,dir_SouthEast\r
165                                         };\r
166 #ifdef __cplusplus\r
167 }\r
168 #endif\r
169 \r
170 //      Internal routines\r
171 \r
172 ///////////////////////////////////////////////////////////////////////////\r
173 //\r
174 //      INL_KeyService() - Handles a keyboard interrupt (key up/down)\r
175 //\r
176 ///////////////////////////////////////////////////////////////////////////\r
177 void interrupt\r
178 INL_KeyService()\r
179 {\r
180 static  boolean special;\r
181                 byte    k,c;\r
182                 register byte temp;\r
183 \r
184         k = inp(0x60);  // Get the scan code\r
185 \r
186         // Tell the XT keyboard controller to clear the key\r
187         outp(0x61,(temp = inp(0x61)) | 0x80);\r
188         outp(0x61,temp);\r
189 \r
190         if (k == 0xe0)          // Special key prefix\r
191                 special = true;\r
192         else if (k == 0xe1)     // Handle Pause key\r
193                 inpu.Paused = true;\r
194         else\r
195         {\r
196                 if (k & 0x80)   // Break code\r
197                 {\r
198                         k &= 0x7f;\r
199 \r
200 // DEBUG - handle special keys: ctl-alt-delete, print scrn\r
201 \r
202                         inpu.Keyboard[k] = false;\r
203                 }\r
204                 else                    // Make code\r
205                 {\r
206                         inst.LastCode = inst.CurCode;\r
207                         inst.CurCode = inpu.LastScan = k;\r
208                         inpu.Keyboard[k] = true;\r
209 \r
210                         if (special)\r
211                                 c = SpecialNames[k];\r
212                         else\r
213                         {\r
214                                 if (k == sc_CapsLock)\r
215                                 {\r
216                                         inst.CapsLock ^= true;\r
217                                         // DEBUG - make caps lock light work\r
218                                 }\r
219 \r
220                                 if (inpu.Keyboard[sc_LShift] || inpu.Keyboard[sc_RShift])       // If shifted\r
221                                 {\r
222                                         c = ShiftNames[k];\r
223                                         if ((c >= 'A') && (c <= 'Z') && inst.CapsLock)\r
224                                                 c += 'a' - 'A';\r
225                                 }\r
226                                 else\r
227                                 {\r
228                                         c = ASCIINames[k];\r
229                                         if ((c >= 'a') && (c <= 'z') && inst.CapsLock)\r
230                                                 c -= 'a' - 'A';\r
231                                 }\r
232                         }\r
233                         if (c)\r
234                                 inpu.LastASCII = c;\r
235                 }\r
236 \r
237                 special = false;\r
238         }\r
239 \r
240         if (INL_KeyHook && !special)\r
241                 INL_KeyHook();\r
242 #ifdef __DEBUG_InputMgr__\r
243         if(dbg_testkeyin > 0) printf("%c        %u      [0x%x %u]       %u\n", c, c, k, k, inpu.Keyboard[k]);\r
244 #endif\r
245         outp(0x20,0x20);\r
246 }\r
247 \r
248 void\r
249 Mouse(int x)\r
250 {\r
251         //union REGS CPURegs;\r
252         //x = CPURegs.x.ax;\r
253         __asm {\r
254                 mov     ax,x\r
255                 int     MouseInt\r
256         }\r
257         //int86(MouseInt,&CPURegs,&CPURegs);\r
258 }\r
259 \r
260 ///////////////////////////////////////////////////////////////////////////\r
261 //\r
262 //      INL_GetMouseDelta() - Gets the amount that the mouse has moved from the\r
263 //              mouse driver\r
264 //\r
265 ///////////////////////////////////////////////////////////////////////////\r
266 static void\r
267 INL_GetMouseDelta(int *x,int *y)\r
268 {\r
269         union REGS CPURegs;\r
270         Mouse(MDelta);\r
271         *x = CPURegs.x.cx;\r
272         *y = CPURegs.x.dx;\r
273 }\r
274 \r
275 ///////////////////////////////////////////////////////////////////////////\r
276 //\r
277 //      INL_GetMouseButtons() - Gets the status of the mouse buttons from the\r
278 //              mouse driver\r
279 //\r
280 ///////////////////////////////////////////////////////////////////////////\r
281 static word\r
282 INL_GetMouseButtons(void)\r
283 {\r
284         union REGS CPURegs;\r
285         word    buttons;\r
286 \r
287         Mouse(MButtons);\r
288         buttons = CPURegs.x.bx;\r
289         return(buttons);\r
290 }\r
291 \r
292 ///////////////////////////////////////////////////////////////////////////\r
293 //\r
294 //      IN_GetJoyAbs() - Reads the absolute position of the specified joystick\r
295 //\r
296 ///////////////////////////////////////////////////////////////////////////\r
297 void\r
298 IN_GetJoyAbs(word joy,word *xp,word *yp)\r
299 {\r
300         byte    xb,yb,\r
301                         xs,ys;\r
302         word    x,y;\r
303 \r
304         x = y = 0;\r
305         xs = joy? 2 : 0;                // Find shift value for x axis\r
306         xb = 1 << xs;                   // Use shift value to get x bit mask\r
307         ys = joy? 3 : 1;                // Do the same for y axis\r
308         yb = 1 << ys;\r
309 \r
310 // Read the absolute joystick values\r
311         __asm {\r
312                 pushf                           // Save some registers\r
313                 push    si\r
314                 push    di\r
315                 cli                                     // Make sure an interrupt doesn't screw the timings\r
316 \r
317 \r
318                 mov             dx,0x201\r
319                 in              al,dx\r
320                 out             dx,al           // Clear the resistors\r
321 \r
322                 mov             ah,[xb]         // Get masks into registers\r
323                 mov             ch,[yb]\r
324 \r
325                 xor             si,si           // Clear count registers\r
326                 xor             di,di\r
327                 xor             bh,bh           // Clear high byte of bx for later\r
328 \r
329                 push    bp                      // Don't mess up stack frame\r
330                 mov             bp,MaxJoyValue\r
331 #ifdef __BORLANDC__\r
332         }\r
333 #endif\r
334 loo:\r
335 #ifdef __BORLANDC__\r
336         __asm {\r
337 #endif\r
338                 in              al,dx           // Get bits indicating whether all are finished\r
339 \r
340                 dec             bp                      // Check bounding register\r
341                 jz              done            // We have a silly value - abort\r
342 \r
343                 mov             bl,al           // Duplicate the bits\r
344                 and             bl,ah           // Mask off useless bits (in [xb])\r
345                 add             si,bx           // Possibly increment count register\r
346                 mov             cl,bl           // Save for testing later\r
347 \r
348                 mov             bl,al\r
349                 and             bl,ch           // [yb]\r
350                 add             di,bx\r
351 \r
352                 add             cl,bl\r
353                 jnz             loo             // If both bits were 0, drop out\r
354 #ifdef __BORLANDC__\r
355         }\r
356 #endif\r
357 done:\r
358 #ifdef __BORLANDC__\r
359         __asm {\r
360 #endif\r
361                 pop             bp\r
362 \r
363                 mov             cl,[xs]         // Get the number of bits to shift\r
364                 shr             si,cl           //  and shift the count that many times\r
365 \r
366                 mov             cl,[ys]\r
367                 shr             di,cl\r
368 \r
369                 mov             [x],si          // Store the values into the variables\r
370                 mov             [y],di\r
371 \r
372                 pop             di\r
373                 pop             si\r
374                 popf                            // Restore the registers\r
375         }\r
376 \r
377         *xp = x;\r
378         *yp = y;\r
379 }\r
380 \r
381 ///////////////////////////////////////////////////////////////////////////\r
382 //\r
383 //      INL_GetJoyDelta() - Returns the relative movement of the specified\r
384 //              joystick (from +/-127, scaled adaptively)\r
385 //\r
386 ///////////////////////////////////////////////////////////////////////////\r
387 static void\r
388 INL_GetJoyDelta(word joy,int *dx,int *dy,boolean adaptive)\r
389 {\r
390         word            x,y;\r
391         word    time;\r
392         word TimeCount = *clockw;\r
393         JoystickDef     *def;\r
394 static  word    lasttime;\r
395 \r
396         IN_GetJoyAbs(joy,&x,&y);\r
397         def = inpu.JoyDefs + joy;\r
398 \r
399         if (x < def->threshMinX)\r
400         {\r
401                 if (x < def->joyMinX)\r
402                         x = def->joyMinX;\r
403 \r
404                 x = -(x - def->threshMinX);\r
405                 x *= def->joyMultXL;\r
406                 x >>= JoyScaleShift;\r
407                 *dx = (x > 127)? -127 : -x;\r
408         }\r
409         else if (x > def->threshMaxX)\r
410         {\r
411                 if (x > def->joyMaxX)\r
412                         x = def->joyMaxX;\r
413 \r
414                 x = x - def->threshMaxX;\r
415                 x *= def->joyMultXH;\r
416                 x >>= JoyScaleShift;\r
417                 *dx = (x > 127)? 127 : x;\r
418         }\r
419         else\r
420                 *dx = 0;\r
421 \r
422         if (y < def->threshMinY)\r
423         {\r
424                 if (y < def->joyMinY)\r
425                         y = def->joyMinY;\r
426 \r
427                 y = -(y - def->threshMinY);\r
428                 y *= def->joyMultYL;\r
429                 y >>= JoyScaleShift;\r
430                 *dy = (y > 127)? -127 : -y;\r
431         }\r
432         else if (y > def->threshMaxY)\r
433         {\r
434                 if (y > def->joyMaxY)\r
435                         y = def->joyMaxY;\r
436 \r
437                 y = y - def->threshMaxY;\r
438                 y *= def->joyMultYH;\r
439                 y >>= JoyScaleShift;\r
440                 *dy = (y > 127)? 127 : y;\r
441         }\r
442         else\r
443                 *dy = 0;\r
444 \r
445         if (adaptive)\r
446         {\r
447                 time = (TimeCount - lasttime) / 2;\r
448                 if (time)\r
449                 {\r
450                         if (time > 8)\r
451                                 time = 8;\r
452                         *dx *= time;\r
453                         *dy *= time;\r
454                 }\r
455         }\r
456         lasttime = TimeCount;\r
457 }\r
458 \r
459 ///////////////////////////////////////////////////////////////////////////\r
460 //\r
461 //      INL_GetJoyButtons() - Returns the button status of the specified\r
462 //              joystick\r
463 //\r
464 ///////////////////////////////////////////////////////////////////////////\r
465 static word\r
466 INL_GetJoyButtons(word joy)\r
467 {\r
468 register        word    result;\r
469 \r
470         result = inp(0x201);    // Get all the joystick buttons\r
471         result >>= joy? 6 : 4;  // Shift into bits 0-1\r
472         result &= 3;                            // Mask off the useless bits\r
473         result ^= 3;\r
474         return(result);\r
475 }\r
476 \r
477 ///////////////////////////////////////////////////////////////////////////\r
478 //\r
479 //      IN_GetJoyButtonsDB() - Returns the de-bounced button status of the\r
480 //              specified joystick\r
481 //\r
482 ///////////////////////////////////////////////////////////////////////////\r
483 word\r
484 IN_GetJoyButtonsDB(word joy)\r
485 {\r
486         word TimeCount = *clockw;\r
487         word    lasttime;\r
488         word            result1,result2;\r
489 \r
490         do\r
491         {\r
492                 result1 = INL_GetJoyButtons(joy);\r
493                 lasttime = TimeCount;\r
494                 while(TimeCount == lasttime)\r
495                 result2 = INL_GetJoyButtons(joy);\r
496         } while(result1 != result2);\r
497         return(result1);\r
498 }\r
499 \r
500 ///////////////////////////////////////////////////////////////////////////\r
501 //\r
502 //      INL_StartKbd() - Sets up my keyboard stuff for use\r
503 //\r
504 ///////////////////////////////////////////////////////////////////////////\r
505 static void\r
506 INL_StartKbd()\r
507 {\r
508         INL_KeyHook = 0;        // Clear key hook\r
509 \r
510         IN_ClearKeysDown();\r
511 \r
512         OldKeyVect = _dos_getvect(KeyInt);\r
513         _dos_setvect(KeyInt,INL_KeyService);\r
514 }\r
515 \r
516 ///////////////////////////////////////////////////////////////////////////\r
517 //\r
518 //      INL_ShutKbd() - Restores keyboard control to the BIOS\r
519 //\r
520 ///////////////////////////////////////////////////////////////////////////\r
521 static void\r
522 INL_ShutKbd(void)\r
523 {\r
524         pokeb(0x40,0x17,peekb(0x40,0x17) & 0xfaf0);     // Clear ctrl/alt/shift flags\r
525 \r
526         _dos_setvect(KeyInt,OldKeyVect);\r
527 }\r
528 \r
529 ///////////////////////////////////////////////////////////////////////////\r
530 //\r
531 //      INL_StartMouse() - Detects and sets up the mouse\r
532 //\r
533 ///////////////////////////////////////////////////////////////////////////\r
534 static boolean\r
535 INL_StartMouse(void)\r
536 {\r
537         union REGS CPURegs;\r
538         if(_dos_getvect(MouseInt))\r
539         {\r
540                 Mouse(MReset);\r
541                 if(CPURegs.x.ax == 0xffff)\r
542                         return(true);\r
543         }\r
544         return(false);\r
545 }\r
546 \r
547 ///////////////////////////////////////////////////////////////////////////\r
548 //\r
549 //      INL_ShutMouse() - Cleans up after the mouse\r
550 //\r
551 ///////////////////////////////////////////////////////////////////////////\r
552 static void\r
553 INL_ShutMouse(void)\r
554 {\r
555 }\r
556 \r
557 //\r
558 //      INL_SetJoyScale() - Sets up scaling values for the specified joystick\r
559 //\r
560 static void\r
561 INL_SetJoyScale(word joy)\r
562 {\r
563         JoystickDef     *def;\r
564 \r
565         def = &(inpu.JoyDefs[joy]);\r
566         def->joyMultXL = JoyScaleMax / (def->threshMinX - def->joyMinX);\r
567         def->joyMultXH = JoyScaleMax / (def->joyMaxX - def->threshMaxX);\r
568         def->joyMultYL = JoyScaleMax / (def->threshMinY - def->joyMinY);\r
569         def->joyMultYH = JoyScaleMax / (def->joyMaxY - def->threshMaxY);\r
570 }\r
571 \r
572 ///////////////////////////////////////////////////////////////////////////\r
573 //\r
574 //      IN_SetupJoy() - Sets up thresholding values and calls INL_SetJoyScale()\r
575 //              to set up scaling values\r
576 //\r
577 ///////////////////////////////////////////////////////////////////////////\r
578 void\r
579 IN_SetupJoy(word joy,word minx,word maxx,word miny,word maxy)\r
580 {\r
581         word            d,r;\r
582         JoystickDef     *def;\r
583 \r
584         def = &(inpu.JoyDefs[joy]);\r
585 \r
586         def->joyMinX = minx;\r
587         def->joyMaxX = maxx;\r
588         r = maxx - minx;\r
589         d = r / 3;\r
590         def->threshMinX = ((r / 2) - d) + minx;\r
591         def->threshMaxX = ((r / 2) + d) + minx;\r
592 \r
593         def->joyMinY = miny;\r
594         def->joyMaxY = maxy;\r
595         r = maxy - miny;\r
596         d = r / 3;\r
597         def->threshMinY = ((r / 2) - d) + miny;\r
598         def->threshMaxY = ((r / 2) + d) + miny;\r
599 \r
600         INL_SetJoyScale(joy);\r
601 }\r
602 \r
603 ///////////////////////////////////////////////////////////////////////////\r
604 //\r
605 //      INL_StartJoy() - Detects & auto-configures the specified joystick\r
606 //                                      The auto-config assumes the joystick is centered\r
607 //\r
608 ///////////////////////////////////////////////////////////////////////////\r
609 static boolean\r
610 INL_StartJoy(word joy)\r
611 {\r
612         word            x,y;\r
613 \r
614         IN_GetJoyAbs(joy,&x,&y);\r
615 \r
616         if\r
617         (\r
618                 ((x == 0) || (x > MaxJoyValue - 10))\r
619         ||      ((y == 0) || (y > MaxJoyValue - 10))\r
620         )\r
621                 return(false);\r
622         else\r
623         {\r
624                 IN_SetupJoy(joy,0,x * 2,0,y * 2);\r
625                 return(true);\r
626         }\r
627 }\r
628 \r
629 ///////////////////////////////////////////////////////////////////////////\r
630 //\r
631 //      INL_ShutJoy() - Cleans up the joystick stuff\r
632 //\r
633 ///////////////////////////////////////////////////////////////////////////\r
634 static void\r
635 INL_ShutJoy(word joy)\r
636 {\r
637         inpu.JoysPresent[joy] = false;\r
638 }\r
639 \r
640 //      Public routines\r
641 \r
642 ///////////////////////////////////////////////////////////////////////////\r
643 //\r
644 //      IN_Startup() - Starts up the Input Mgr\r
645 //\r
646 ///////////////////////////////////////////////////////////////////////////\r
647 void\r
648 IN_Startup()\r
649 {\r
650         boolean checkjoys,checkmouse;\r
651         word    i;\r
652 \r
653         if (inst.IN_Started)\r
654                 return;\r
655 \r
656         checkjoys = true;\r
657         checkmouse = true;\r
658         for (i = 1;i < _argc;i++)\r
659         {\r
660                 switch (US_CheckParm(_argv[i],ParmStringsIN))\r
661                 {\r
662                 case 0:\r
663                         checkjoys = false;\r
664                         break;\r
665                 case 1:\r
666                         checkmouse = false;\r
667                         break;\r
668                 }\r
669         }\r
670 \r
671         INL_StartKbd();\r
672         inpu.MousePresent = checkmouse? INL_StartMouse() : false;\r
673 \r
674         for (i = 0;i < MaxJoys;i++)\r
675                 inpu.JoysPresent[i] = checkjoys? INL_StartJoy(i) : false;\r
676 \r
677         inst.IN_Started = true;\r
678 \r
679 }\r
680 \r
681 ///////////////////////////////////////////////////////////////////////////\r
682 //\r
683 //      IN_Default() - Sets up default conditions for the Input Mgr\r
684 //\r
685 ///////////////////////////////////////////////////////////////////////////\r
686 void\r
687 IN_Default(boolean gotit,player_t *player,ControlType nt)\r
688 {\r
689         int i;\r
690         if\r
691         (\r
692                 (!gotit)\r
693         ||      ((nt == ctrl_Joystick1) && !inpu.JoysPresent[0])\r
694         ||      ((nt == ctrl_Joystick2) && !inpu.JoysPresent[1])\r
695         ||      ((nt == ctrl_Mouse) && !inpu.MousePresent)\r
696         )\r
697                 nt = ctrl_Keyboard1;\r
698         inpu.KbdDefs[0].button0 = 0x1c;\r
699         inpu.KbdDefs[0].button1 = 0x38;\r
700         //in.KbdDefs[0].upleft = 0x47;\r
701         inpu.KbdDefs[0].up = 0x48;\r
702         //in.KbdDefs[0].upright = 0x49;\r
703         inpu.KbdDefs[0].left = 0x4b;\r
704         inpu.KbdDefs[0].right = 0x4d;\r
705         //in.KbdDefs[0].downleft = 0x4f;\r
706         inpu.KbdDefs[0].down = 0x50;\r
707         //in.KbdDefs[0].downright = 0x51;\r
708         IN_SetControlType(0,player,nt);\r
709         for(i=0; i>MaxPlayers;i++)\r
710                 player[i].d=2;\r
711 }\r
712 \r
713 ///////////////////////////////////////////////////////////////////////////\r
714 //\r
715 //      IN_Shutdown() - Shuts down the Input Mgr\r
716 //\r
717 ///////////////////////////////////////////////////////////////////////////\r
718 void\r
719 IN_Shutdown()\r
720 {\r
721         word    i;\r
722 \r
723         if (!inst.IN_Started)\r
724                 return;\r
725 \r
726         INL_ShutMouse();\r
727         for (i = 0;i < MaxJoys;i++)\r
728                 INL_ShutJoy(i);\r
729         INL_ShutKbd();\r
730 \r
731         inst.IN_Started = false;\r
732 }\r
733 \r
734 ///////////////////////////////////////////////////////////////////////////\r
735 //\r
736 //      IN_SetKeyHook() - Sets the routine that gets called by INL_KeyService()\r
737 //                      everytime a real make/break code gets hit\r
738 //\r
739 ///////////////////////////////////////////////////////////////////////////\r
740 void\r
741 IN_SetKeyHook(void (*hook)())\r
742 {\r
743         INL_KeyHook = hook;\r
744 }\r
745 \r
746 ///////////////////////////////////////////////////////////////////////////\r
747 //\r
748 //      IN_ClearKeyDown() - Clears the keyboard array\r
749 //\r
750 ///////////////////////////////////////////////////////////////////////////\r
751 void\r
752 IN_ClearKeysDown()\r
753 {\r
754         //int   i;\r
755 \r
756         inpu.LastScan = sc_None;\r
757         inpu.LastASCII = key_None;\r
758         memset (inpu.Keyboard,0,sizeof(inpu.Keyboard));\r
759 }\r
760 \r
761 ///////////////////////////////////////////////////////////////////////////\r
762 //\r
763 //      INL_AdjustCursor() - Internal routine of common code from IN_ReadCursor()\r
764 //\r
765 ///////////////////////////////////////////////////////////////////////////\r
766 static void\r
767 INL_AdjustCursor(CursorInfo *info,word buttons,int dx,int dy)\r
768 {\r
769         if (buttons & (1 << 0))\r
770                 info->button0 = true;\r
771         if (buttons & (1 << 1))\r
772                 info->button1 = true;\r
773 \r
774         info->x += dx;\r
775         info->y += dy;\r
776 }\r
777 \r
778 ///////////////////////////////////////////////////////////////////////////\r
779 //\r
780 //      IN_ReadCursor() - Reads the input devices and fills in the cursor info\r
781 //              struct\r
782 //\r
783 ///////////////////////////////////////////////////////////////////////////\r
784 void\r
785 IN_ReadCursor(CursorInfo *info)\r
786 {\r
787         word    i,\r
788                         buttons;\r
789         int             dx,dy;\r
790 \r
791         info->x = info->y = 0;\r
792         info->button0 = info->button1 = false;\r
793 \r
794         if (inpu.MousePresent)\r
795         {\r
796                 buttons = INL_GetMouseButtons();\r
797                 INL_GetMouseDelta(&dx,&dy);\r
798                 INL_AdjustCursor(info,buttons,dx,dy);\r
799         }\r
800 \r
801         for (i = 0;i < MaxJoys;i++)\r
802         {\r
803                 if (!inpu.JoysPresent[i])\r
804                         continue;\r
805 \r
806                 buttons = INL_GetJoyButtons(i);\r
807                 INL_GetJoyDelta(i,&dx,&dy,true);\r
808                 dx /= 64;\r
809                 dy /= 64;\r
810                 INL_AdjustCursor(info,buttons,dx,dy);\r
811         }\r
812 }\r
813 \r
814 ///////////////////////////////////////////////////////////////////////////\r
815 //\r
816 //      IN_ReadControl() - Reads the device associated with the specified\r
817 //              player and fills in the control info struct\r
818 //\r
819 ///////////////////////////////////////////////////////////////////////////\r
820 void near\r
821 IN_ReadControl(int pn,player_t *player)\r
822 {\r
823                         boolean         realdelta;\r
824 #if DEMO0\r
825                         byte            dbyte;\r
826 #endif\r
827                         word            buttons;\r
828                         int                     dx,dy;\r
829                         Motion          mx,my;\r
830                         ControlType     type;\r
831                         sword conpee;\r
832                         byte dir=DirTable[2];\r
833 register        KeyboardDef     *def;\r
834 \r
835         dx = dy = 0;\r
836         mx = my = motion_None;\r
837         buttons = 0;\r
838 \r
839 #if DEMO0\r
840         if (DemoMode == demo_Playback)\r
841         {\r
842                 dbyte = DemoBuffer[DemoOffset + 1];\r
843                 my = (dbyte & 3) - 1;\r
844                 mx = ((dbyte >> 2) & 3) - 1;\r
845                 buttons = (dbyte >> 4) & 3;\r
846 \r
847                 if (!(--DemoBuffer[DemoOffset]))\r
848                 {\r
849                         DemoOffset += 2;\r
850                         if (DemoOffset >= DemoSize)\r
851                                 DemoMode = demo_PlayDone;\r
852                 }\r
853 \r
854                 realdelta = false;\r
855         }\r
856         else if (DemoMode == demo_PlayDone)\r
857                 Quit("Demo playback exceeded");\r
858         else\r
859         {\r
860 #endif\r
861                 switch (type = player[pn].Controls)\r
862                 {\r
863                 case ctrl_Keyboard1:\r
864                 case ctrl_Keyboard2:\r
865                         def = &(inpu.KbdDefs[type - ctrl_Keyboard]);\r
866 \r
867 /*                      if (Keyboard[def->upleft])\r
868                                 mx = motion_Left,my = motion_Up;\r
869                         else if (Keyboard[def->upright])\r
870                                 mx = motion_Right,my = motion_Up;\r
871                         else if (Keyboard[def->downleft])\r
872                                 mx = motion_Left,my = motion_Down;\r
873                         else if (Keyboard[def->downright])\r
874                                 mx = motion_Right,my = motion_Down;*/\r
875 //TODO: make this into a function that the joystick AND keyboard can use wwww\r
876                         if(DIRECTIONIFELSE)//(player[pn].info.dir == 2)\r
877                         {\r
878                         if(!inpu.Keyboard[def->left] && !inpu.Keyboard[def->right]){\r
879                                 if((inpu.Keyboard[def->up] && !inpu.Keyboard[def->down]))\r
880                                         my = motion_Up;\r
881                                 if((inpu.Keyboard[def->down] && !inpu.Keyboard[def->up]))\r
882                                         my = motion_Down;\r
883                         }else if(!inpu.Keyboard[def->up] && !inpu.Keyboard[def->down]){\r
884                                 if((inpu.Keyboard[def->left] && !inpu.Keyboard[def->right]))\r
885                                         mx = motion_Left;\r
886                                 if((inpu.Keyboard[def->right] && !inpu.Keyboard[def->left]))\r
887                                         mx = motion_Right;\r
888                         }else{  //2 keys pressed\r
889                                         switch (player[pn].pdir)\r
890                                         {\r
891                                                 case 0:\r
892                                                 case 4:\r
893                                                         if((inpu.Keyboard[def->left] && !inpu.Keyboard[def->right])){ dir = DirTable[1]; }//mx = motion_Left; }\r
894                                                         else if((inpu.Keyboard[def->right] && !inpu.Keyboard[def->left])){ dir = DirTable[3]; }//mx = motion_Right; }\r
895                                                 break;\r
896                                                 case 1:\r
897                                                 case 3:\r
898                                                         if((inpu.Keyboard[def->up] && !inpu.Keyboard[def->down])){ dir = DirTable[0]; }//my = motion_Up; }\r
899                                                         else if((inpu.Keyboard[def->down] && !inpu.Keyboard[def->up])){ dir = DirTable[4]; }//my = motion_Down; }\r
900                                                 break;\r
901                                                 default:\r
902                                                 break;\r
903                                         }\r
904 #ifdef __DEBUG_InputMgr__\r
905                                         //if(dbg_testcontrolnoisy > 0){ printf("dir=%c ", dirchar(dir)); printf("pdir=%c        ", dirchar(player[pn].pdir)); }\r
906 #endif\r
907                                 }\r
908                         }\r
909                         //input from player\r
910                         if (inpu.Keyboard[def->button0])\r
911                                 buttons += 1 << 0;\r
912                         if (inpu.Keyboard[def->button1])\r
913                                 buttons += 1 << 1;\r
914                         realdelta = false;\r
915                         break;\r
916                 case ctrl_Joystick1:\r
917                 case ctrl_Joystick2:\r
918                         INL_GetJoyDelta(type - ctrl_Joystick,&dx,&dy,false);\r
919                         buttons = INL_GetJoyButtons(type - ctrl_Joystick);\r
920                         realdelta = true;\r
921                         break;\r
922                 case ctrl_Mouse:\r
923                         INL_GetMouseDelta(&dx,&dy);\r
924                         buttons = INL_GetMouseButtons();\r
925                         realdelta = true;\r
926                         break;\r
927                 }\r
928 #ifdef DEMO0\r
929         }\r
930 #endif\r
931 \r
932         if (realdelta)\r
933         {\r
934                 mx = (dx < 0)? motion_Left : ((dx > 0)? motion_Right : motion_None);\r
935                 my = (dy < 0)? motion_Up : ((dy > 0)? motion_Down : motion_None);\r
936         }\r
937         else\r
938         {\r
939                 dx = mx;// * 127;\r
940                 dy = my;// * 127;\r
941         }\r
942 \r
943         player[pn].info.x = dx;\r
944         player[pn].info.xaxis = mx;\r
945         player[pn].info.y = dy;\r
946         player[pn].info.yaxis = my;\r
947         player[pn].info.button0 = buttons & (1 << 0);\r
948         player[pn].info.button1 = buttons & (1 << 1);\r
949         player[pn].info.button2 = buttons & (1 << 2);\r
950         player[pn].info.button3 = buttons & (1 << 3);\r
951 //      player[pn].info.dir = DirTable[((my + 1) * 3) + (mx + 1)];\r
952         conpee=(((my + 1) * 2) + (mx + 1))-1;\r
953         player[pn].info.dir = DirTable[conpee];\r
954 \r
955         if(DirTable[conpee]!=2) player[pn].pdir=DirTable[conpee];\r
956         if(player[pn].q==1 &&( dir!=2 || (mx!=motion_None || my!=motion_None)))\r
957         {\r
958                 if(dir==2) player[pn].d = player[pn].info.dir;\r
959                 else player[pn].d = DirTable[dir];\r
960         }\r
961 \r
962 #if DEMO0\r
963         if (DemoMode == demo_Record)\r
964         {\r
965                 // Pack the control info into a byte\r
966                 dbyte = (buttons << 4) | ((mx + 1) << 2) | (my + 1);\r
967 \r
968                 if\r
969                 (\r
970                         (DemoBuffer[DemoOffset + 1] == dbyte)\r
971                 &&      (DemoBuffer[DemoOffset] < 255)\r
972                 )\r
973                         (DemoBuffer[DemoOffset])++;\r
974                 else\r
975                 {\r
976                         if (DemoOffset || DemoBuffer[DemoOffset])\r
977                                 DemoOffset += 2;\r
978 \r
979                         if (DemoOffset >= DemoSize)\r
980                                 Quit("Demo buffer overflow");\r
981 \r
982                         DemoBuffer[DemoOffset] = 1;\r
983                         DemoBuffer[DemoOffset + 1] = dbyte;\r
984                 }\r
985         }\r
986 #endif\r
987 #ifdef __DEBUG_InputMgr__\r
988 if(dbg_testcontrolnoisy > 0)\r
989 if(player[pn].info.dir!=2/*(inpu.Keyboard[def->up] || inpu.Keyboard[def->down] || inpu.Keyboard[def->left] || inpu.Keyboard[def->right])*/ || player[pn].q>1)\r
990 {\r
991         //printf("b1=%u b2=%u b3=%u b4=%u       ", player[pn].info.button0, player[pn].info.button1, player[pn].info.button2, player[pn].info.button3);\r
992         //printf("q=%d ", player[pn].q);\r
993         //printf("cpee=%c ", dirchar(conpee));\r
994         printf("pdir=%c d=%c dir=%c ", dirchar(player[pn].pdir), dirchar(player[pn].d), dirchar(player[pn].info.dir));\r
995         /*if(realdelta) */printf("dx=%d dy=%d   mx=%d   my=%d", player[pn].info.x, player[pn].info.y, player[pn].info.xaxis, player[pn].info.yaxis);\r
996         //else if(!realdelta) printf("%c%d %c%d %c%d %c%d", dirchar(0), inpu.Keyboard[def->up], dirchar(4), inpu.Keyboard[def->down], dirchar(1), inpu.Keyboard[def->left], dirchar(3), inpu.Keyboard[def->right]);\r
997         printf("\n");\r
998 }\r
999 #endif\r
1000 }\r
1001 \r
1002 ///////////////////////////////////////////////////////////////////////////\r
1003 //\r
1004 //      IN_SetControlType() - Sets the control type to be used by the specified\r
1005 //              player\r
1006 //\r
1007 ///////////////////////////////////////////////////////////////////////////\r
1008 void\r
1009 IN_SetControlType(word pn,player_t *player,ControlType type)\r
1010 {\r
1011         // DEBUG - check that requested type is present?\r
1012         player[pn].Controls = type;\r
1013 }\r
1014 \r
1015 #if DEMO0\r
1016 ///////////////////////////////////////////////////////////////////////////\r
1017 //\r
1018 //      IN_StartDemoRecord() - Starts the demo recording, using a buffer the\r
1019 //              size passed. Returns if the buffer allocation was successful\r
1020 //\r
1021 ///////////////////////////////////////////////////////////////////////////\r
1022 boolean\r
1023 IN_StartDemoRecord(word bufsize)\r
1024 {\r
1025         if (!bufsize)\r
1026                 return(false);\r
1027 \r
1028         MM_GetPtr((memptr *)&DemoBuffer,bufsize);\r
1029         DemoMode = demo_Record;\r
1030         DemoSize = bufsize & ~1;\r
1031         DemoOffset = 0;\r
1032         DemoBuffer[0] = DemoBuffer[1] = 0;\r
1033 \r
1034         return(true);\r
1035 }\r
1036 \r
1037 ///////////////////////////////////////////////////////////////////////////\r
1038 //\r
1039 //      IN_StartDemoPlayback() - Plays back the demo pointed to of the given size\r
1040 //\r
1041 ///////////////////////////////////////////////////////////////////////////\r
1042 void\r
1043 IN_StartDemoPlayback(byte /*__segment*/ *buffer,word bufsize)\r
1044 {\r
1045         DemoBuffer = buffer;\r
1046         DemoMode = demo_Playback;\r
1047         DemoSize = bufsize & ~1;\r
1048         DemoOffset = 0;\r
1049 }\r
1050 \r
1051 ///////////////////////////////////////////////////////////////////////////\r
1052 //\r
1053 //      IN_StopDemo() - Turns off demo mode\r
1054 //\r
1055 ///////////////////////////////////////////////////////////////////////////\r
1056 void\r
1057 IN_StopDemo(void)\r
1058 {\r
1059         if ((DemoMode == demo_Record) && DemoOffset)\r
1060                 DemoOffset += 2;\r
1061 \r
1062         DemoMode = demo_Off;\r
1063 }\r
1064 \r
1065 ///////////////////////////////////////////////////////////////////////////\r
1066 //\r
1067 //      IN_FreeDemoBuffer() - Frees the demo buffer, if it's been allocated\r
1068 //\r
1069 ///////////////////////////////////////////////////////////////////////////\r
1070 void\r
1071 IN_FreeDemoBuffer(void)\r
1072 {\r
1073         if (DemoBuffer)\r
1074                 MM_FreePtr((memptr *)&DemoBuffer);\r
1075 }\r
1076 #endif\r
1077 \r
1078 \r
1079 ///////////////////////////////////////////////////////////////////////////\r
1080 //\r
1081 //      IN_GetScanName() - Returns a string containing the name of the\r
1082 //              specified scan code\r
1083 //\r
1084 ///////////////////////////////////////////////////////////////////////////\r
1085 byte *\r
1086 IN_GetScanName(ScanCode scan)\r
1087 {\r
1088         byte            **p;\r
1089         ScanCode        far *s;\r
1090 \r
1091         for (s = ExtScanCodes,p = ExtScanNames;*s;p++,s++)\r
1092                 if (*s == scan)\r
1093                         return(*p);\r
1094 \r
1095         return(ScanNames[scan]);\r
1096 }\r
1097 \r
1098 ///////////////////////////////////////////////////////////////////////////\r
1099 //\r
1100 //      IN_WaitForKey() - Waits for a scan code, then clears LastScan and\r
1101 //              returns the scan code\r
1102 //\r
1103 ///////////////////////////////////////////////////////////////////////////\r
1104 ScanCode\r
1105 IN_WaitForKey()\r
1106 {\r
1107         ScanCode        result;\r
1108 \r
1109         while (!(result = inpu.LastScan))\r
1110                 ;\r
1111         inpu.LastScan = 0;\r
1112         return(result);\r
1113 }\r
1114 \r
1115 ///////////////////////////////////////////////////////////////////////////\r
1116 //\r
1117 //      IN_WaitForASCII() - Waits for an ASCII char, then clears LastASCII and\r
1118 //              returns the ASCII value\r
1119 //\r
1120 ///////////////////////////////////////////////////////////////////////////\r
1121 char\r
1122 IN_WaitForASCII()\r
1123 {\r
1124         char            result;\r
1125 \r
1126         while (!(result = inpu.LastASCII))\r
1127                 ;\r
1128         inpu.LastASCII = '\0';\r
1129         return(result);\r
1130 }\r
1131 \r
1132 ///////////////////////////////////////////////////////////////////////////\r
1133 //\r
1134 //      IN_AckBack() - Waits for either an ASCII keypress or a button press\r
1135 //\r
1136 ///////////////////////////////////////////////////////////////////////////\r
1137 void\r
1138 IN_AckBack()\r
1139 {\r
1140         word    i;\r
1141 \r
1142         while (!inpu.LastScan)\r
1143         {\r
1144                 if (inpu.MousePresent)\r
1145                 {\r
1146                         if (INL_GetMouseButtons())\r
1147                         {\r
1148                                 while (INL_GetMouseButtons())\r
1149                                         ;\r
1150                                 return;\r
1151                         }\r
1152                 }\r
1153 \r
1154                 for (i = 0;i < MaxJoys;i++)\r
1155                 {\r
1156                         if (inpu.JoysPresent[i])\r
1157                         {\r
1158                                 if (IN_GetJoyButtonsDB(i))\r
1159                                 {\r
1160                                         while (IN_GetJoyButtonsDB(i))\r
1161                                                 ;\r
1162                                         return;\r
1163                                 }\r
1164                         }\r
1165                 }\r
1166         }\r
1167 \r
1168         IN_ClearKey(inpu.LastScan);\r
1169         inpu.LastScan = sc_None;\r
1170 }\r
1171 \r
1172 ///////////////////////////////////////////////////////////////////////////\r
1173 //\r
1174 //      IN_Ack() - Clears user input & then calls IN_AckBack()\r
1175 //\r
1176 ///////////////////////////////////////////////////////////////////////////\r
1177 void\r
1178 IN_Ack()\r
1179 {\r
1180         word    i;\r
1181 \r
1182         if (!inst.IN_Started)\r
1183                 return;\r
1184 \r
1185         IN_ClearKey(inpu.LastScan);\r
1186         inpu.LastScan = sc_None;\r
1187 \r
1188         if (inpu.MousePresent)\r
1189                 while (INL_GetMouseButtons())\r
1190                                         ;\r
1191         for (i = 0;i < MaxJoys;i++)\r
1192                 if (inpu.JoysPresent[i])\r
1193                         while (IN_GetJoyButtonsDB(i))\r
1194                                 ;\r
1195 \r
1196         IN_AckBack();\r
1197 }\r
1198 \r
1199 ///////////////////////////////////////////////////////////////////////////\r
1200 //\r
1201 //      IN_IsUserInput() - Returns true if a key has been pressed or a button\r
1202 //              is down\r
1203 //\r
1204 ///////////////////////////////////////////////////////////////////////////\r
1205 boolean\r
1206 IN_IsUserInput()\r
1207 {\r
1208         boolean result;\r
1209         word    i;\r
1210 \r
1211         result = inpu.LastScan;\r
1212 \r
1213         if (inpu.MousePresent)\r
1214                 if (INL_GetMouseButtons())\r
1215                         result = true;\r
1216 \r
1217         for (i = 0;i < MaxJoys;i++)\r
1218                 if (inpu.JoysPresent[i])\r
1219                         if (INL_GetJoyButtons(i))\r
1220                                 result = true;\r
1221 \r
1222         return(result);\r
1223 }\r
1224 \r
1225 ///////////////////////////////////////////////////////////////////////////\r
1226 //\r
1227 //      IN_UserInput() - Waits for the specified delay time (in ticks) or the\r
1228 //              user pressing a key or a mouse button. If the clear flag is set, it\r
1229 //              then either clears the key or waits for the user to let the mouse\r
1230 //              button up.\r
1231 //\r
1232 ///////////////////////////////////////////////////////////////////////////\r
1233 boolean\r
1234 IN_UserInput(dword delay,boolean clear)\r
1235 {\r
1236         word TimeCount = *clockw;\r
1237         word    lasttime;\r
1238 \r
1239         lasttime = TimeCount;\r
1240         do\r
1241         {\r
1242                 if (IN_IsUserInput())\r
1243                 {\r
1244                         if (clear)\r
1245                                 IN_AckBack();\r
1246                         return(true);\r
1247                 }\r
1248         } while (TimeCount - lasttime < delay);\r
1249         return(false);\r
1250 }\r
1251 \r
1252 boolean IN_KeyDown(byte code)\r
1253 {\r
1254         return inpu.Keyboard[code];\r
1255 }\r
1256 \r
1257 void IN_ClearKey(byte code)\r
1258 {\r
1259         inpu.Keyboard[code] = false;\r
1260         if(code == inpu.LastScan)\r
1261                 inpu.LastScan = sc_None;\r
1262         }\r
1263 \r
1264 boolean IN_qb(byte kee)\r
1265 {\r
1266 #ifdef __DEBUG_InputMgr__\r
1267 //      if(dbg_testkeyin > 0) printf("%u\n", inpu.Keyboard[kee]);\r
1268 #endif\r
1269         if(inpu.Keyboard[kee]==true) return 1;\r
1270         else return 0;\r
1271 }\r
1272 \r
1273 //init player!\r
1274 void IN_initplayer(player_t *player, word pn)\r
1275 {\r
1276         player[pn].x = player[pn].tx*TILEWH;\r
1277         player[pn].y = player[pn].ty*TILEWH;\r
1278         player[pn].triggerx = player[pn].tx;\r
1279         player[pn].triggery = player[pn].ty+1;\r
1280 /*      player[0].info.x = player[0].tx;\r
1281         player[0].info.xaxis = player[0].tx*TILEWH;\r
1282         player[0].info.y = player[0].ty;\r
1283         player[0].info.yaxis = player[0].ty*TILEWH;*/\r
1284         player[pn].q=1;\r
1285         player[pn].d=2;\r
1286         player[pn].hp=4;\r
1287         player[pn].speed=4;\r
1288         player[pn].persist_aniframe=0;\r
1289         player[pn].spt=(TILEWH/(player[pn].speed));     //speed per tile wwww\r
1290 }\r