1 // Interface functions (written in C++) for
2 // Direct3D immediate mode system
3
4 // Must link to C code in main engine system
5
6 extern "C" {
7
8 // Note: INITGUID has NOT been defined here,
9 // since the definition in d3_func.cpp is amply
10 // sufficient.
11
12 #include "3dc.h"
13 #include "module.h"
14 #include "inline.h"
15 #include "stratdef.h"
16 #include "gamedef.h"
17 #include "gameplat.h"
18 #include "usr_io.h"
19 extern "C++"{
20 #include "iofocus.h"
21 };
22
23 #include "showcmds.h"
24
25 // DirectInput key down value
26 #define DikOn 0x80
27
28 // Internal DirectInput driver
29 // buffer Size for direct mouse read
30 #define DMouse_BufferSize 128
31
32 // Maximum number of buffered events retrievable
33 // from a mouse data acquisition
34 #define DMouse_RetrieveSize 128
35
36 /*
37 These are (hopefully) temporary #defines,
38 introduced as a hack because the curious
39 FIELD_OFFSET macros in the dinput.h header
40 don't appear to compile, at least in Watcom 10.6.
41 They will obviously have to be kept up to date
42 with changes in the DIMOUSESTATE structure manually.
43 */
44
45 #define DIMouseXOffset 0
46
47 #define DIMouseYOffset 4
48 #define DIMouseZOffset 8
49
50 #define DIMouseButton0Offset 12
51
52 #define DIMouseButton1Offset 13
53
54 #define DIMouseButton2Offset 14
55
56 #define DIMouseButton3Offset 15
57
58
59 /*
60 Globals
61 */
62
63
64 static LPDIRECTINPUT lpdi; // DirectInput interface
65 static LPDIRECTINPUTDEVICE lpdiKeyboard; // keyboard device interface
66 static LPDIRECTINPUTDEVICE lpdiMouse; // mouse device interface
67 static BOOL DIKeyboardOkay; // Is the keyboard acquired?
68
69 static IDirectInputDevice* g_pJoystick = NULL;
70 static IDirectInputDevice2* g_pJoystickDevice2 = NULL; // needed to poll joystick
71
72 static char bGravePressed = No;
73 // added 14/1/98 by DHM as a temporary hack to debounce the GRAVE key
74
75 /*
76 Externs for input communication
77 */
78
79 extern HINSTANCE hInst;
80 extern HWND hWndMain;
81
82 int GotMouse;
83 unsigned int MouseButton;
84 int MouseVelX;
85 int MouseVelY;
86 int MouseVelZ;
87 int MouseX;
88 int MouseY;
89 int MouseZ;
90
91 extern unsigned char KeyboardInput[];
92 extern unsigned char GotAnyKey;
93 static unsigned char LastGotAnyKey;
94 unsigned char DebouncedGotAnyKey;
95
96 int GotJoystick;
97 JOYCAPS JoystickCaps;
98 JOYINFOEX JoystickData;
99 int JoystickEnabled;
100
101 DIJOYSTATE JoystickState; // DirectInput joystick state
102
103
104 /*
105 8/4/98 DHM: A new array, analagous to KeyboardInput, except it's debounced
106 */
107 extern "C"
108 {
109 unsigned char DebouncedKeyboardInput[MAX_NUMBER_OF_INPUT_KEYS];
110 }
111
112 // Implementation of the debounced KeyboardInput
113 // There's probably a more efficient way of getting it direct from DirectInput
114 // but it's getting late and I can't face reading any more Microsoft documentation...
115 static unsigned char LastFramesKeyboardInput[MAX_NUMBER_OF_INPUT_KEYS];
116
117
118 extern int NormalFrameTime;
119
120 static char IngameKeyboardInput[256];
121 extern IngameKeyboardInput_KeyDown(unsigned char key);
122 extern IngameKeyboardInput_KeyUp(unsigned char key);
123 extern IngameKeyboardInput_ClearBuffer(void);
124
125 /*
126
127 Create DirectInput via CoCreateInstance
128
129 */
130
131
InitialiseDirectInput(void)132 BOOL InitialiseDirectInput(void)
133
134 {
135 // try to create di object
136 if (DirectInputCreate(hInst, DIRECTINPUT_VERSION, &lpdi, NULL) != DI_OK)
137 {
138 #if debug
139 ReleaseDirect3D();
140 exit(0x4111);
141 #else
142 return FALSE;
143 #endif
144 }
145
146 return TRUE;
147 }
148
149 /*
150
151 Release DirectInput object
152
153 */
154
155
ReleaseDirectInput(void)156 void ReleaseDirectInput(void)
157
158 {
159 if (lpdi!= NULL)
160 {
161 lpdi->Release();
162 lpdi = NULL;
163 }
164 }
165
166
167
168
169 // see comments below
170
171 #define UseForegroundKeyboard No
172
173 GUID guid = GUID_SysKeyboard;
InitialiseDirectKeyboard()174 BOOL InitialiseDirectKeyboard()
175
176 {
177 HRESULT hRes;
178
179 // try to create keyboard device
180 if (lpdi->CreateDevice(guid, &lpdiKeyboard, NULL) !=DI_OK)
181 {
182 #if debug
183 ReleaseDirect3D();
184 exit(0x4112);
185 #else
186 return FALSE;
187 #endif
188 }
189
190 // Tell DirectInput that we want to receive data in keyboard format
191 if (lpdiKeyboard->SetDataFormat(&c_dfDIKeyboard) != DI_OK)
192 {
193 #if debug
194 ReleaseDirect3D();
195 exit(0x4113);
196 #else
197 return FALSE;
198 #endif
199 }
200
201 // set cooperative level
202 // this level is the most likely to work across
203 // multiple hardware targets
204 // (i.e. this is probably best for a production
205 // release)
206 #if UseForegroundKeyboard
207 if (lpdiKeyboard->SetCooperativeLevel(hWndMain,
208 DISCL_NONEXCLUSIVE | DISCL_FOREGROUND) != DI_OK)
209 #else
210 // this level makes alt-tabbing multiple instances in
211 // SunWindow mode possible without receiving lots
212 // of false inputs
213 if (lpdiKeyboard->SetCooperativeLevel(hWndMain,
214 DISCL_NONEXCLUSIVE | DISCL_BACKGROUND) != DI_OK)
215 #endif
216 {
217 #if debug
218 ReleaseDirect3D();
219 exit(0x4114);
220 #else
221 return FALSE;
222 #endif
223 }
224
225 // try to acquire the keyboard
226 hRes = lpdiKeyboard->Acquire();
227 if (hRes == DI_OK)
228 {
229 // keyboard was acquired
230 DIKeyboardOkay = TRUE;
231 }
232 else
233 {
234 // keyboard was NOT acquired
235 DIKeyboardOkay = FALSE;
236 }
237
238 // if we get here, all objects were created successfully
239 return TRUE;
240 }
241
242
243
244 /*
245
246 Use DirectInput to read keyboard
247
248 PS: I know this function involves an
249 apparently unnecessary layer of translation
250 between one keyboard array and another one.
251 This is to allow people to swap from a windows
252 procedure keyboard handler to a DirectInput one
253 without having to change their IDemand functions.
254
255 I can't think of a faster way to do the translation
256 below, but given that it only runs once per frame
257 it shouldn't be too bad. BUT NOTE THAT IT DOES
258 ONLY RUN ONCE PER FRAME (FROM READUSERINPUT) AND
259 SO YOU MUST HAVE A DECENT FRAME RATE IF KEYS ARE NOT
260 TO BE MISSED.
261
262 NOTE ALSO THAT IF YOU ARE USING THIS SYSTEM YOU CAN
263 ACCESS THE KEYBOARD ARRAY IN A TIGHT LOOP WHILE CALLING
264 READUSERINPUT BUT -->NOT<-- CHECKWINDOWSMESSAGES (AS REQUIRED
265 FOR THE WINPROC HANDLER). BUT CHECKFORWINDOWSMESSAGES WON'T DO
266 ANY HARM.
267 */
268
DirectReadKeyboard(void)269 void DirectReadKeyboard(void)
270 {
271 // Local array for map of all 256 characters on
272 // keyboard
273 BYTE DiKeybd[256];
274 HRESULT hRes;
275
276 // Get keyboard state
277 hRes = lpdiKeyboard->GetDeviceState(sizeof(DiKeybd), DiKeybd);
278 if (hRes != DI_OK)
279 {
280 if (hRes == DIERR_INPUTLOST)
281 {
282 // keyboard control lost; try to reacquire
283 DIKeyboardOkay = FALSE;
284 hRes = lpdiKeyboard->Acquire();
285 if (hRes == DI_OK)
286 DIKeyboardOkay = TRUE;
287 }
288 }
289
290 // Check for error values on routine exit
291 if (hRes != DI_OK)
292 {
293 // failed to read the keyboard
294 #if debug
295 ReleaseDirect3D();
296 exit(0x999774);
297 #else
298 return;
299 #endif
300 }
301
302 // Take a copy of last frame's inputs:
303 memcpy((void*)LastFramesKeyboardInput, (void*)KeyboardInput, MAX_NUMBER_OF_INPUT_KEYS);
304 LastGotAnyKey=GotAnyKey;
305
306 // Zero current inputs (i.e. set all keys to FALSE,
307 // or not pressed)
308 memset((void*)KeyboardInput, FALSE, MAX_NUMBER_OF_INPUT_KEYS);
309 GotAnyKey = FALSE;
310
311 #if 1
312 {
313 int c;
314
315 for (c='a'; c<='z'; c++)
316 {
317 if (IngameKeyboardInput[c])
318 {
319 KeyboardInput[KEY_A + c - 'a'] = TRUE;
320 GotAnyKey = TRUE;
321 }
322 }
323 if (IngameKeyboardInput[246])
324 {
325 KeyboardInput[KEY_O_UMLAUT] = TRUE;
326 GotAnyKey = TRUE;
327 }
328 if (IngameKeyboardInput[228])
329 {
330 KeyboardInput[KEY_A_UMLAUT] = TRUE;
331 GotAnyKey = TRUE;
332 }
333 if (IngameKeyboardInput[252])
334 {
335 KeyboardInput[KEY_U_UMLAUT] = TRUE;
336 GotAnyKey = TRUE;
337 }
338 if (IngameKeyboardInput[223])
339 {
340 KeyboardInput[KEY_BETA] = TRUE;
341 GotAnyKey = TRUE;
342 }
343 if (IngameKeyboardInput['+'])
344 {
345 KeyboardInput[KEY_PLUS] = TRUE;
346 GotAnyKey = TRUE;
347 }
348 if (IngameKeyboardInput['#'])
349 {
350 KeyboardInput[KEY_HASH] = TRUE;
351 GotAnyKey = TRUE;
352 }
353 if (IngameKeyboardInput[161])
354 {
355 KeyboardInput[KEY_UPSIDEDOWNEXCLAMATION] = TRUE;
356 GotAnyKey = TRUE;
357 }
358 if (IngameKeyboardInput[231])
359 {
360 KeyboardInput[KEY_C_CEDILLA] = TRUE;
361 GotAnyKey = TRUE;
362 }
363 if (IngameKeyboardInput[241])
364 {
365 KeyboardInput[KEY_N_TILDE] = TRUE;
366 GotAnyKey = TRUE;
367 }
368 if (IngameKeyboardInput[')'])
369 {
370 KeyboardInput[KEY_RIGHTBRACKET] = TRUE;
371 GotAnyKey = TRUE;
372 }
373 if (IngameKeyboardInput['*'])
374 {
375 KeyboardInput[KEY_ASTERISK] = TRUE;
376 GotAnyKey = TRUE;
377 }
378 if (IngameKeyboardInput['$'])
379 {
380 KeyboardInput[KEY_DOLLAR] = TRUE;
381 GotAnyKey = TRUE;
382 }
383 if (IngameKeyboardInput[249])
384 {
385 KeyboardInput[KEY_U_GRAVE] = TRUE;
386 GotAnyKey = TRUE;
387 }
388 if (IngameKeyboardInput['!'])
389 {
390 KeyboardInput[KEY_EXCLAMATION] = TRUE;
391 GotAnyKey = TRUE;
392 }
393 if (IngameKeyboardInput[':'])
394 {
395 KeyboardInput[KEY_COLON] = TRUE;
396 GotAnyKey = TRUE;
397 }
398 if (IngameKeyboardInput[96])
399 {
400 KeyboardInput[KEY_DIACRITIC_GRAVE] = TRUE;
401 GotAnyKey = TRUE;
402 }
403 if (IngameKeyboardInput[180])
404 {
405 KeyboardInput[KEY_DIACRITIC_ACUTE] = TRUE;
406 GotAnyKey = TRUE;
407 }
408 if (IngameKeyboardInput[94])
409 {
410 KeyboardInput[KEY_DIACRITIC_CARET] = TRUE;
411 GotAnyKey = TRUE;
412 }
413 if (IngameKeyboardInput[168])
414 {
415 KeyboardInput[KEY_DIACRITIC_UMLAUT] = TRUE;
416 GotAnyKey = TRUE;
417 }
418 if (IngameKeyboardInput['<'])
419 {
420 KeyboardInput[KEY_LESSTHAN] = TRUE;
421 GotAnyKey = TRUE;
422 }
423 if (IngameKeyboardInput[176])
424 {
425 KeyboardInput[KEY_ORDINAL] = TRUE;
426 GotAnyKey = TRUE;
427 }
428
429
430 if (IngameKeyboardInput['['])
431 {
432 KeyboardInput[KEY_LBRACKET] = TRUE;
433 GotAnyKey = TRUE;
434 }
435 if (IngameKeyboardInput[']'])
436 {
437 KeyboardInput[KEY_RBRACKET] = TRUE;
438 GotAnyKey = TRUE;
439 }
440 if (IngameKeyboardInput[';'])
441 {
442 KeyboardInput[KEY_SEMICOLON] = TRUE;
443 GotAnyKey = TRUE;
444 }
445 if (IngameKeyboardInput['\''])
446 {
447 KeyboardInput[KEY_APOSTROPHE] = TRUE;
448 GotAnyKey = TRUE;
449 }
450 if (IngameKeyboardInput['\\'])
451 {
452 KeyboardInput[KEY_BACKSLASH] = TRUE;
453 GotAnyKey = TRUE;
454 }
455 if (IngameKeyboardInput['/'])
456 {
457 KeyboardInput[KEY_SLASH] = TRUE;
458 GotAnyKey = TRUE;
459 }
460 if (IngameKeyboardInput['-'])
461 {
462 KeyboardInput[KEY_MINUS] = TRUE;
463 GotAnyKey = TRUE;
464 }
465 if (IngameKeyboardInput['='])
466 {
467 KeyboardInput[KEY_EQUALS] = TRUE;
468 GotAnyKey = TRUE;
469 }
470 if (IngameKeyboardInput[','])
471 {
472 KeyboardInput[KEY_COMMA] = TRUE;
473 GotAnyKey = TRUE;
474 }
475 if (IngameKeyboardInput['.'])
476 {
477 KeyboardInput[KEY_FSTOP] = TRUE;
478 GotAnyKey = TRUE;
479 }
480
481 }
482
483 #endif
484
485 // Check and set keyboard array
486 // (test checks only for the moment)
487 if (DiKeybd[DIK_LEFT] & DikOn)
488 {
489 KeyboardInput[KEY_LEFT] = TRUE;
490 GotAnyKey = TRUE;
491 }
492
493 if (DiKeybd[DIK_RIGHT] & DikOn)
494 {
495 KeyboardInput[KEY_RIGHT] = TRUE;
496 GotAnyKey = TRUE;
497 }
498
499 if (DiKeybd[DIK_UP] & DikOn)
500 {
501 KeyboardInput[KEY_UP] = TRUE;
502 GotAnyKey = TRUE;
503 }
504
505 if (DiKeybd[DIK_DOWN] & DikOn)
506 {
507 KeyboardInput[KEY_DOWN] = TRUE;
508 GotAnyKey = TRUE;
509 }
510
511 if (DiKeybd[DIK_ESCAPE] & DikOn)
512 {
513 KeyboardInput[KEY_ESCAPE] = TRUE;
514 GotAnyKey = TRUE;
515 }
516
517 if (DiKeybd[DIK_RETURN] & DikOn)
518 {
519 KeyboardInput[KEY_CR] = TRUE;
520 GotAnyKey = TRUE;
521 }
522
523 if (DiKeybd[DIK_TAB] & DikOn)
524 {
525 KeyboardInput[KEY_TAB] = TRUE;
526 GotAnyKey = TRUE;
527 }
528
529 if (DiKeybd[DIK_F1] & DikOn)
530 {
531 KeyboardInput[KEY_F1] = TRUE;
532 GotAnyKey = TRUE;
533 }
534
535 if (DiKeybd[DIK_F2] & DikOn)
536 {
537 KeyboardInput[KEY_F2] = TRUE;
538 GotAnyKey = TRUE;
539 }
540
541 if (DiKeybd[DIK_F3] & DikOn)
542 {
543 KeyboardInput[KEY_F3] = TRUE;
544 GotAnyKey = TRUE;
545 }
546
547 if (DiKeybd[DIK_F4] & DikOn)
548 {
549 KeyboardInput[KEY_F4] = TRUE;
550 GotAnyKey = TRUE;
551 }
552
553 if (DiKeybd[DIK_F5] & DikOn)
554 {
555 KeyboardInput[KEY_F5] = TRUE;
556 GotAnyKey = TRUE;
557 }
558
559 if (DiKeybd[DIK_F6] & DikOn)
560 {
561 KeyboardInput[KEY_F6] = TRUE;
562 GotAnyKey = TRUE;
563 }
564
565 if (DiKeybd[DIK_F7] & DikOn)
566 {
567 KeyboardInput[KEY_F7] = TRUE;
568 GotAnyKey = TRUE;
569 }
570
571 if (DiKeybd[DIK_F8] & DikOn)
572 {
573 KeyboardInput[KEY_F8] = TRUE;
574 /* KJL 14:51:38 21/04/98 - F8 does screen shots, and so this is a hack
575 to make F8 not count in a 'press any key' situation */
576 // GotAnyKey = TRUE;
577 }
578
579 if (DiKeybd[DIK_F9] & DikOn)
580 {
581 KeyboardInput[KEY_F9] = TRUE;
582 GotAnyKey = TRUE;
583 }
584
585 if (DiKeybd[DIK_F10] & DikOn)
586 {
587 KeyboardInput[KEY_F10] = TRUE;
588 GotAnyKey = TRUE;
589 }
590
591 if (DiKeybd[DIK_F11] & DikOn)
592 {
593 KeyboardInput[KEY_F11] = TRUE;
594 GotAnyKey = TRUE;
595 }
596
597 if (DiKeybd[DIK_F12] & DikOn)
598 {
599 KeyboardInput[KEY_F12] = TRUE;
600 GotAnyKey = TRUE;
601 }
602
603 if (DiKeybd[DIK_INSERT] & DikOn)
604 {
605 KeyboardInput[KEY_INS] = TRUE;
606 GotAnyKey = TRUE;
607 }
608
609 if (DiKeybd[DIK_DELETE] & DikOn)
610 {
611 KeyboardInput[KEY_DEL] = TRUE;
612 GotAnyKey = TRUE;
613 }
614
615 if (DiKeybd[DIK_END] & DikOn)
616 {
617 KeyboardInput[KEY_END] = TRUE;
618 GotAnyKey = TRUE;
619 }
620
621 if (DiKeybd[DIK_HOME] & DikOn)
622 {
623 KeyboardInput[KEY_HOME] = TRUE;
624 GotAnyKey = TRUE;
625 }
626
627 if (DiKeybd[DIK_PRIOR] & DikOn)
628 {
629 KeyboardInput[KEY_PAGEUP] = TRUE;
630 GotAnyKey = TRUE;
631 }
632
633 if (DiKeybd[DIK_NEXT] & DikOn)
634 {
635 KeyboardInput[KEY_PAGEDOWN] = TRUE;
636 GotAnyKey = TRUE;
637 }
638
639 if (DiKeybd[DIK_BACK] & DikOn)
640 {
641 KeyboardInput[KEY_BACKSPACE] = TRUE;
642 GotAnyKey = TRUE;
643 }
644
645 if (DiKeybd[DIK_SPACE] & DikOn)
646 {
647 KeyboardInput[KEY_SPACE] = TRUE;
648 GotAnyKey = TRUE;
649 }
650
651 if (DiKeybd[DIK_LSHIFT] & DikOn)
652 {
653 KeyboardInput[KEY_LEFTSHIFT] = TRUE;
654 GotAnyKey = TRUE;
655 }
656
657 if (DiKeybd[DIK_RSHIFT] & DikOn)
658 {
659 KeyboardInput[KEY_RIGHTSHIFT] = TRUE;
660 GotAnyKey = TRUE;
661 }
662
663 if (DiKeybd[DIK_LCONTROL] & DikOn)
664 {
665 KeyboardInput[KEY_LEFTCTRL] = TRUE;
666 GotAnyKey = TRUE;
667 }
668
669 if (DiKeybd[DIK_RCONTROL] & DikOn)
670 {
671 KeyboardInput[KEY_RIGHTCTRL] = TRUE;
672 GotAnyKey = TRUE;
673 }
674
675 if (DiKeybd[DIK_CAPSLOCK] & DikOn)
676 {
677 KeyboardInput[KEY_CAPS] = TRUE;
678 GotAnyKey = TRUE;
679 }
680
681 if (DiKeybd[DIK_NUMLOCK] & DikOn)
682 {
683 KeyboardInput[KEY_NUMLOCK] = TRUE;
684 GotAnyKey = TRUE;
685 }
686
687 if (DiKeybd[DIK_SCROLL] & DikOn)
688 {
689 KeyboardInput[KEY_SCROLLOK] = TRUE;
690 GotAnyKey = TRUE;
691 }
692
693 if (DiKeybd[DIK_LMENU] & DikOn)
694 {
695 KeyboardInput[KEY_LEFTALT] = TRUE;
696 GotAnyKey = TRUE;
697 }
698
699 if (DiKeybd[DIK_RMENU] & DikOn)
700 {
701 KeyboardInput[KEY_RIGHTALT] = TRUE;
702 GotAnyKey = TRUE;
703 }
704
705 if (DiKeybd[DIK_0] & DikOn)
706 {
707 KeyboardInput[KEY_0] = TRUE;
708 GotAnyKey = TRUE;
709 }
710
711 if (DiKeybd[DIK_1] & DikOn)
712 {
713 KeyboardInput[KEY_1] = TRUE;
714 GotAnyKey = TRUE;
715 }
716
717 if (DiKeybd[DIK_2] & DikOn)
718 {
719 KeyboardInput[KEY_2] = TRUE;
720 GotAnyKey = TRUE;
721 }
722
723 if (DiKeybd[DIK_3] & DikOn)
724 {
725 KeyboardInput[KEY_3] = TRUE;
726 GotAnyKey = TRUE;
727 }
728
729 if (DiKeybd[DIK_4] & DikOn)
730 {
731 KeyboardInput[KEY_4] = TRUE;
732 GotAnyKey = TRUE;
733 }
734
735 if (DiKeybd[DIK_5] & DikOn)
736 {
737 KeyboardInput[KEY_5] = TRUE;
738 GotAnyKey = TRUE;
739 }
740
741 if (DiKeybd[DIK_6] & DikOn)
742 {
743 KeyboardInput[KEY_6] = TRUE;
744 GotAnyKey = TRUE;
745 }
746
747 if (DiKeybd[DIK_7] & DikOn)
748 {
749 KeyboardInput[KEY_7] = TRUE;
750 GotAnyKey = TRUE;
751 }
752
753 if (DiKeybd[DIK_8] & DikOn)
754 {
755 KeyboardInput[KEY_8] = TRUE;
756 GotAnyKey = TRUE;
757 }
758
759 if (DiKeybd[DIK_9] & DikOn)
760 {
761 KeyboardInput[KEY_9] = TRUE;
762 GotAnyKey = TRUE;
763 }
764
765
766 /* KJL 16:12:19 05/11/97 - numeric pad follows */
767 if (DiKeybd[DIK_NUMPAD7] & DikOn)
768 {
769 KeyboardInput[KEY_NUMPAD7] = TRUE;
770 GotAnyKey = TRUE;
771 }
772 if (DiKeybd[DIK_NUMPAD8] & DikOn)
773 {
774 KeyboardInput[KEY_NUMPAD8] = TRUE;
775 GotAnyKey = TRUE;
776 }
777 if (DiKeybd[DIK_NUMPAD9] & DikOn)
778 {
779 KeyboardInput[KEY_NUMPAD9] = TRUE;
780 GotAnyKey = TRUE;
781 }
782 if (DiKeybd[DIK_SUBTRACT] & DikOn)
783 {
784 KeyboardInput[KEY_NUMPADSUB] = TRUE;
785 GotAnyKey = TRUE;
786 }
787 if (DiKeybd[DIK_NUMPAD4] & DikOn)
788 {
789 KeyboardInput[KEY_NUMPAD4] = TRUE;
790 GotAnyKey = TRUE;
791 }
792 if (DiKeybd[DIK_NUMPAD5] & DikOn)
793 {
794 KeyboardInput[KEY_NUMPAD5] = TRUE;
795 GotAnyKey = TRUE;
796 }
797 if (DiKeybd[DIK_NUMPAD6] & DikOn)
798 {
799 KeyboardInput[KEY_NUMPAD6] = TRUE;
800 GotAnyKey = TRUE;
801 }
802 if (DiKeybd[DIK_ADD] & DikOn)
803 {
804 KeyboardInput[KEY_NUMPADADD] = TRUE;
805 GotAnyKey = TRUE;
806 }
807 if (DiKeybd[DIK_NUMPAD1] & DikOn)
808 {
809 KeyboardInput[KEY_NUMPAD1] = TRUE;
810 GotAnyKey = TRUE;
811 }
812 if (DiKeybd[DIK_NUMPAD2] & DikOn)
813 {
814 KeyboardInput[KEY_NUMPAD2] = TRUE;
815 GotAnyKey = TRUE;
816 }
817 if (DiKeybd[DIK_NUMPAD3] & DikOn)
818 {
819 KeyboardInput[KEY_NUMPAD3] = TRUE;
820 GotAnyKey = TRUE;
821 }
822 if (DiKeybd[DIK_NUMPAD0] & DikOn)
823 {
824 KeyboardInput[KEY_NUMPAD0] = TRUE;
825 GotAnyKey = TRUE;
826 }
827 if (DiKeybd[DIK_DECIMAL] & DikOn)
828 {
829 KeyboardInput[KEY_NUMPADDEL] = TRUE;
830 GotAnyKey = TRUE;
831 }
832 if (DiKeybd[DIK_NUMPADENTER] & DikOn)
833 {
834 KeyboardInput[KEY_NUMPADENTER] = TRUE;
835 GotAnyKey = TRUE;
836 }
837 if (DiKeybd[DIK_DIVIDE] & DikOn)
838 {
839 KeyboardInput[KEY_NUMPADDIVIDE] = TRUE;
840 GotAnyKey = TRUE;
841 }
842 if (DiKeybd[DIK_MULTIPLY] & DikOn)
843 {
844 KeyboardInput[KEY_NUMPADMULTIPLY] = TRUE;
845 GotAnyKey = TRUE;
846 }
847 if (DiKeybd[DIK_CAPITAL] & DikOn)
848 {
849 KeyboardInput[KEY_CAPITAL] = TRUE;
850 GotAnyKey = TRUE;
851 }
852 if (DiKeybd[DIK_LWIN] & DikOn)
853 {
854 KeyboardInput[KEY_LWIN] = TRUE;
855 GotAnyKey = TRUE;
856 }
857 if (DiKeybd[DIK_RWIN] & DikOn)
858 {
859 KeyboardInput[KEY_RWIN] = TRUE;
860 GotAnyKey = TRUE;
861 }
862 if (DiKeybd[DIK_APPS] & DikOn)
863 {
864 KeyboardInput[KEY_APPS] = TRUE;
865 GotAnyKey = TRUE;
866 }
867
868
869 #if 0
870 // Added 14/1/98 by DHM: Process the grave key (known to some as the tilde key)
871 // Done this way as a bit of a hack to avoid touching PLATFORM.H
872 // which would force big recompiles
873 if (DiKeybd[DIK_GRAVE] & DikOn)
874 {
875 if ( !bGravePressed )
876 {
877 IOFOCUS_Toggle();
878 }
879
880 bGravePressed = Yes;
881
882 GotAnyKey = TRUE;
883 }
884 else
885 {
886 bGravePressed = No;
887 }
888 #else
889 if (DiKeybd[DIK_GRAVE] & DikOn)
890 {
891 KeyboardInput[KEY_GRAVE] = TRUE;
892 }
893 #endif
894
895 /* mouse keys */
896 if (MouseButton & LeftButton)
897 {
898 KeyboardInput[KEY_LMOUSE] = TRUE;
899 GotAnyKey = TRUE;
900 }
901 if (MouseButton & MiddleButton)
902 {
903 KeyboardInput[KEY_MMOUSE] = TRUE;
904 GotAnyKey = TRUE;
905 }
906 if (MouseButton & RightButton)
907 {
908 KeyboardInput[KEY_RMOUSE] = TRUE;
909 GotAnyKey = TRUE;
910 }
911
912 /* mouse wheel - read using windows messages */
913 {
914 extern signed int MouseWheelStatus;
915 if (MouseWheelStatus>0)
916 {
917 KeyboardInput[KEY_MOUSEWHEELUP] = TRUE;
918 GotAnyKey = TRUE;
919 }
920 else if (MouseWheelStatus<0)
921 {
922 KeyboardInput[KEY_MOUSEWHEELDOWN] = TRUE;
923 GotAnyKey = TRUE;
924 }
925 }
926
927
928 /* joystick buttons */
929 if (GotJoystick)
930 {
931 unsigned int n,bit;
932
933 for (n=0,bit=1; n<16; n++,bit*=2)
934 {
935 if(JoystickData.dwButtons&bit)
936 {
937 KeyboardInput[KEY_JOYSTICK_BUTTON_1+n]=TRUE;
938 GotAnyKey = TRUE;
939 }
940 }
941
942 }
943
944
945 /* update debounced keys array */
946 {
947 for (int i=0;i<MAX_NUMBER_OF_INPUT_KEYS;i++)
948 {
949 DebouncedKeyboardInput[i] =
950 (
951 KeyboardInput[i] && !LastFramesKeyboardInput[i]
952 );
953 }
954 DebouncedGotAnyKey = GotAnyKey && !LastGotAnyKey;
955 }
956
957
958 }
959 /*
960
961 Clean up direct keyboard objects
962
963 */
964
ReleaseDirectKeyboard(void)965 void ReleaseDirectKeyboard(void)
966 {
967 if (DIKeyboardOkay)
968 {
969 lpdiKeyboard->Unacquire();
970 DIKeyboardOkay = FALSE;
971 }
972
973 if (lpdiKeyboard != NULL)
974 {
975 lpdiKeyboard->Release();
976 lpdiKeyboard = NULL;
977 }
978 }
979
980
InitialiseDirectMouse()981 BOOL InitialiseDirectMouse()
982
983 {
984 GUID guid = GUID_SysMouse;
985 HRESULT hres;
986
987 //MouseButton = 0;
988
989 // Obtain an interface to the system mouse device.
990 hres = lpdi->CreateDevice(guid, &lpdiMouse, NULL);
991 if (hres != DI_OK) return FALSE;
992
993 // Set the data format to "mouse format".
994 hres = lpdiMouse->SetDataFormat(&c_dfDIMouse);
995 if (hres != DI_OK) return FALSE;
996
997 // Set the cooperativity level.
998
999 #if debug
1000 // This level should allow the debugger to actually work
1001 // not to mention drop 'n' drag in sub-window mode
1002 hres = lpdiMouse->SetCooperativeLevel(hWndMain,
1003 DISCL_NONEXCLUSIVE | DISCL_FOREGROUND);
1004 #else
1005 // this level is the most likely to work across
1006 // multiple mouse drivers
1007 hres = lpdiMouse->SetCooperativeLevel(hWndMain,
1008 DISCL_EXCLUSIVE | DISCL_FOREGROUND);
1009 #endif
1010 if (hres != DI_OK) return FALSE;
1011
1012 // Set the buffer size for reading the mouse to
1013 // DMouse_BufferSize elements
1014 // mouse-type should be relative by default, so there
1015 // is no need to change axis mode.
1016 DIPROPDWORD dipdw =
1017 {
1018 {
1019 sizeof(DIPROPDWORD), // diph.dwSize
1020 sizeof(DIPROPHEADER), // diph.dwHeaderSize
1021 0, // diph.dwObj
1022 DIPH_DEVICE, // diph.dwHow
1023 },
1024 DMouse_BufferSize, // dwData
1025 };
1026
1027 hres = lpdiMouse->SetProperty(DIPROP_BUFFERSIZE, &dipdw.diph);
1028
1029 if (hres != DI_OK) return FALSE;
1030
1031 // try to acquire the mouse
1032 hres = lpdiMouse->Acquire();
1033
1034 return TRUE;
1035 }
1036
DirectReadMouse(void)1037 void DirectReadMouse(void)
1038 {
1039 DIDEVICEOBJECTDATA od[DMouse_RetrieveSize];
1040 DWORD dwElements = DMouse_RetrieveSize;
1041 HRESULT hres;
1042 int OldMouseX, OldMouseY, OldMouseZ;
1043
1044 GotMouse = No;
1045 MouseVelX = 0;
1046 MouseVelY = 0;
1047 MouseVelZ = 0;
1048
1049 hres = lpdiMouse->GetDeviceData(sizeof(DIDEVICEOBJECTDATA),&od[0],&dwElements, 0);
1050
1051
1052 if (hres == DIERR_INPUTLOST || hres==DIERR_NOTACQUIRED)
1053 {
1054 // We had acquisition, but lost it. Try to reacquire it.
1055 hres = lpdiMouse->Acquire();
1056 // No data this time
1057 return;
1058 }
1059
1060 // Unable to read data
1061 if (hres != DI_OK) return;
1062
1063 // Check for any data being picked up
1064 GotMouse = Yes;
1065 if (dwElements == 0) return;
1066
1067 // Save mouse x and y for velocity determination
1068 OldMouseX = MouseX;
1069 OldMouseY = MouseY;
1070 OldMouseZ = MouseZ;
1071
1072 // Process all recovered elements and
1073 // make appropriate modifications to mouse
1074 // status variables.
1075
1076 int i;
1077
1078 for (i=0; i<dwElements; i++)
1079 {
1080 // Look at the element to see what happened
1081
1082 switch (od[i].dwOfs)
1083 {
1084 // DIMOFS_X: Mouse horizontal motion
1085 case DIMouseXOffset:
1086 MouseX += od[i].dwData;
1087 break;
1088
1089 // DIMOFS_Y: Mouse vertical motion
1090 case DIMouseYOffset:
1091 MouseY += od[i].dwData;
1092 break;
1093
1094 case DIMouseZOffset:
1095 MouseZ += od[i].dwData;
1096 textprint("z info received %d\n",MouseZ);
1097 break;
1098
1099 // DIMOFS_BUTTON0: Button 0 pressed or released
1100 case DIMouseButton0Offset:
1101 if (od[i].dwData & DikOn)
1102 // Button pressed
1103 MouseButton |= LeftButton;
1104 else
1105 // Button released
1106 MouseButton &= ~LeftButton;
1107 break;
1108
1109 // DIMOFS_BUTTON1: Button 1 pressed or released
1110 case DIMouseButton1Offset:
1111 if (od[i].dwData & DikOn)
1112 // Button pressed
1113 MouseButton |= RightButton;
1114 else
1115 // Button released
1116 MouseButton &= ~RightButton;
1117 break;
1118
1119 case DIMouseButton2Offset:
1120 case DIMouseButton3Offset:
1121 if (od[i].dwData & DikOn)
1122 // Button pressed
1123 MouseButton |= MiddleButton;
1124 else
1125 // Button released
1126 MouseButton &= ~MiddleButton;
1127 break;
1128
1129 default:
1130 break;
1131 }
1132 }
1133
1134 MouseVelX = DIV_FIXED(MouseX-OldMouseX,NormalFrameTime);
1135 MouseVelY = DIV_FIXED(MouseY-OldMouseY,NormalFrameTime);
1136 //MouseVelZ = DIV_FIXED(MouseZ-OldMouseZ,NormalFrameTime);
1137
1138
1139 #if 0
1140 textprint("MouseNormalFrameTime %d\n",MouseNormalFrameTime);
1141 textprint("Got Mouse %d\n", GotMouse);
1142 textprint("Vel X %d\n", MouseVelX);
1143 textprint("Vel Y %d\n", MouseVelY);
1144 #endif
1145 }
1146
ReleaseDirectMouse(void)1147 void ReleaseDirectMouse(void)
1148
1149 {
1150 if (lpdiMouse != NULL)
1151 {
1152 lpdiMouse->Release();
1153 lpdiMouse = NULL;
1154 }
1155 }
1156
1157
1158
1159 /*KJL****************************************************************
1160 * *
1161 * JOYSTICK SUPPORT - I've moved all joystick support to here. *
1162 * *
1163 ****************************************************************KJL*/
1164
1165
1166 /* KJL 11:32:46 04/30/97 -
1167
1168 Okay, this has been changed for the sake of AvP. I know that this
1169 isn't in AvP\win95\..., but moving this file probably isn't worth
1170 the trouble.
1171
1172 This code is designed to read only one joystick.
1173
1174 */
1175
1176
1177 /*
1178 Decide which (if any) joysticks
1179 exist, access capabilities,
1180 initialise internal variables.
1181 */
1182 #if 1
InitJoysticks(void)1183 void InitJoysticks(void)
1184 {
1185 JoystickData.dwFlags = (JOY_RETURNALL | JOY_RETURNCENTERED | JOY_USEDEADZONE);
1186 JoystickData.dwSize = sizeof(JoystickData);
1187
1188 GotJoystick = CheckForJoystick();
1189 }
1190
ReadJoysticks(void)1191 void ReadJoysticks(void)
1192 {
1193 GotJoystick = ReadJoystick();
1194 }
1195
ReadJoystick(void)1196 int ReadJoystick(void)
1197 {
1198 MMRESULT joyreturn;
1199
1200 if(!JoystickControlMethods.JoystickEnabled) return No;
1201
1202 joyreturn = joyGetPosEx(JOYSTICKID1,&JoystickData);
1203
1204 if (joyreturn == JOYERR_NOERROR) return Yes;
1205
1206 return No;
1207 }
1208
CheckForJoystick(void)1209 int CheckForJoystick(void)
1210 {
1211 MMRESULT joyreturn;
1212
1213 joyreturn = joyGetDevCaps(JOYSTICKID1,
1214 &JoystickCaps,
1215 sizeof(JOYCAPS));
1216
1217 if (joyreturn == JOYERR_NOERROR) return Yes;
1218
1219 return No;
1220 }
1221 #else
1222 // Eleventh hour rewrite of joystick code, to support PantherXL trackerball.
1223 // Typical. KJL, 99/5/1
1224 BOOL CALLBACK EnumJoysticksCallback( LPCDIDEVICEINSTANCE pInst, LPVOID lpvContext );
1225
1226
InitJoysticks(void)1227 void InitJoysticks(void)
1228 {
1229 HRESULT hr;
1230 GotJoystick = No;
1231 g_pJoystick = NULL;
1232
1233 hr = lpdi->EnumDevices(DIDEVTYPE_JOYSTICK, EnumJoysticksCallback, NULL, DIEDFL_ATTACHEDONLY);
1234 if ( FAILED(hr) ) return;
1235
1236 hr = g_pJoystick->SetDataFormat( &c_dfDIJoystick );
1237 if ( FAILED(hr) ) return;
1238
1239 hr = g_pJoystick->SetCooperativeLevel( hWndMain, DISCL_EXCLUSIVE | DISCL_FOREGROUND);
1240 if ( FAILED(hr) ) return;
1241
1242 GotJoystick = Yes;
1243 }
1244
ReadJoysticks(void)1245 void ReadJoysticks(void)
1246 {
1247
1248 GotJoystick = No;
1249
1250 if(!JoystickControlMethods.JoystickEnabled || g_pJoystick==NULL)
1251 {
1252 return;
1253 }
1254
1255 HRESULT hr = DIERR_INPUTLOST;
1256
1257 // if input is lost then acquire and keep trying
1258 while ( DIERR_INPUTLOST == hr )
1259 {
1260 // poll the joystick to read the current state
1261 hr = g_pJoystickDevice2->Poll();
1262 if ( FAILED(hr) ) return;
1263
1264 // get the input's device state, and put the state in dims
1265 hr = g_pJoystick->GetDeviceState( sizeof(DIJOYSTATE), &JoystickState );
1266
1267 if ( hr == DIERR_INPUTLOST )
1268 {
1269 // DirectInput is telling us that the input stream has
1270 // been interrupted. We aren't tracking any state
1271 // between polls, so we don't have any special reset
1272 // that needs to be done. We just re-acquire and
1273 // try again.
1274 hr = g_pJoystick->Acquire();
1275 if ( FAILED(hr) ) return;
1276 }
1277 }
1278
1279 if ( FAILED(hr) ) return;
1280
1281 GotJoystick = Yes;
1282 PrintDebuggingText("%d %d\n",JoystickState.rglSlider[0],JoystickState.rglSlider[1]);
1283
1284 }
1285 //-----------------------------------------------------------------------------
1286 // Function: EnumJoysticksCallback
1287 //
1288 // Description:
1289 // Called once for each enumerated joystick. If we find one,
1290 // create a device interface on it so we can play with it.
1291 //
1292 //-----------------------------------------------------------------------------
EnumJoysticksCallback(LPCDIDEVICEINSTANCE pInst,LPVOID lpvContext)1293 BOOL CALLBACK EnumJoysticksCallback( LPCDIDEVICEINSTANCE pInst,
1294 LPVOID lpvContext )
1295 {
1296 HRESULT hr;
1297 LPDIRECTINPUTDEVICE pDevice;
1298
1299 // obtain an interface to the enumerated force feedback joystick.
1300 hr = lpdi->CreateDevice( pInst->guidInstance, &pDevice, NULL );
1301
1302 // if it failed, then we can't use this joystick for some
1303 // bizarre reason. (Maybe the user unplugged it while we
1304 // were in the middle of enumerating it.) So continue enumerating
1305 if ( FAILED(hr) )
1306 return DIENUM_CONTINUE;
1307
1308 // we successfully created an IDirectInputDevice. So stop looking
1309 // for another one.
1310 g_pJoystick = pDevice;
1311
1312 // query for IDirectInputDevice2 - we need this to poll the joystick
1313 pDevice->QueryInterface( IID_IDirectInputDevice2, (LPVOID *)&g_pJoystickDevice2 );
1314
1315 return DIENUM_STOP;
1316 }
1317 #endif
1318
1319
IngameKeyboardInput_KeyDown(unsigned char key)1320 extern IngameKeyboardInput_KeyDown(unsigned char key)
1321 {
1322 IngameKeyboardInput[key] = 1;
1323 }
1324
IngameKeyboardInput_KeyUp(unsigned char key)1325 extern IngameKeyboardInput_KeyUp(unsigned char key)
1326 {
1327 IngameKeyboardInput[key] = 0;
1328 }
1329
IngameKeyboardInput_ClearBuffer(void)1330 extern IngameKeyboardInput_ClearBuffer(void)
1331 {
1332 int i;
1333
1334 for (i=0; i<=255; i++)
1335 {
1336 IngameKeyboardInput[i] = 0;
1337 }
1338 }
1339
1340 // For extern "C"
1341 };
1342
1343
1344
1345