UFO: Alien Invasion
Loading...
Searching...
No Matches
cl_input.cpp
Go to the documentation of this file.
1
17
18/*
19All original material Copyright (C) 2002-2025 UFO: Alien Invasion.
20
21Original file from Quake 2 v3.21: quake2-2.31/client/cl_input.c
22Copyright (C) 1997-2001 Id Software, Inc.
23
24This program is free software; you can redistribute it and/or
25modify it under the terms of the GNU General Public License
26as published by the Free Software Foundation; either version 2
27of the License, or (at your option) any later version.
28
29This program is distributed in the hope that it will be useful,
30but WITHOUT ANY WARRANTY; without even the implied warranty of
31MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
32
33See the GNU General Public License for more details.
34
35You should have received a copy of the GNU General Public License
36along with this program; if not, write to the Free Software
37Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
38
39*/
40
41#include "../client.h"
42#include "cl_input.h"
43#include "cl_keys.h"
44#include "cl_joystick.h"
47#include "../cl_console.h"
48#include "../cl_screen.h"
52#include "../ui/ui_main.h"
53#include "../ui/ui_input.h"
55#include "../../shared/utf8.h"
56
58#include "../renderer/r_misc.h"
59
60/* power of two please */
61#define MAX_KEYQ 64
62
63static struct {
64 unsigned int key;
65 unsigned short unicode;
66 int down;
68
69static int keyq_head = 0;
70static int keyq_tail = 0;
71
74
78
82enum {
85};
86
87/*
88===============================================================================
89KEY BUTTONS
90===============================================================================
91*/
92
93typedef struct {
94 int down[2];
95 unsigned downtime;
96 unsigned msec;
97 int state;
98} kbutton_t;
99
105
113static void IN_KeyDown (kbutton_t* b)
114{
115 int k;
116 const char* c = Cmd_Argv(1);
117
118 if (c[0])
119 k = atoi(c);
120 else
121 /* typed manually at the console for continuous down */
122 k = -1;
123
124 /* repeating key */
125 if (k == b->down[0] || k == b->down[1])
126 return;
127
128 if (!b->down[0])
129 b->down[0] = k;
130 else if (!b->down[1])
131 b->down[1] = k;
132 else {
133 Com_Printf("Three keys down for a button!\n");
134 return;
135 }
136
137 /* still down */
138 if (b->state)
139 return;
140
141 /* save timestamp */
142 c = Cmd_Argv(2);
143 b->downtime = atoi(c);
144 if (!b->downtime)
145 b->downtime = CL_Milliseconds() - 100;
146
147 /* down */
148 b->state = 1;
149}
150
159static void IN_KeyUp (kbutton_t* b)
160{
161 int k;
162 const char* c = Cmd_Argv(1);
163
164 if (c[0])
165 k = atoi(c);
166 /* typed manually at the console, assume for unsticking, so clear all */
167 else {
168 b->down[0] = b->down[1] = 0;
169 return;
170 }
171
172 if (b->down[0] == k)
173 b->down[0] = 0;
174 else if (b->down[1] == k)
175 b->down[1] = 0;
176 /* key up without corresponding down (menu pass through) */
177 else
178 return;
179
180 /* some other key is still holding it down */
181 if (b->down[0] || b->down[1])
182 return;
183
184 /* still up (this should not happen) */
185 if (!b->state)
186 return;
187
188 /* save timestamp */
189 c = Cmd_Argv(2);
190 const unsigned uptime = atoi(c);
191 if (uptime)
192 b->msec = uptime - b->downtime;
193 else
194 b->msec = 10;
195
196 /* now up */
197 b->state = 0;
198}
199
200static void IN_TurnLeftDown_f (void)
201{
203}
204static void IN_TurnLeftUp_f (void)
205{
207}
208static void IN_TurnRightDown_f (void)
209{
211}
212static void IN_TurnRightUp_f (void)
213{
215}
216static void IN_TurnUpDown_f (void)
217{
219}
220static void IN_TurnUpUp_f (void)
221{
223}
224static void IN_TurnDownDown_f (void)
225{
227}
228static void IN_TurnDownUp_f (void)
229{
231}
232static void IN_PanTiltDown_f (void)
233{
234 if (IN_GetMouseSpace() != MS_WORLD)
235 return;
237}
238static void IN_PanTiltUp_f (void)
239{
241}
242static void IN_ShiftLeftDown_f (void)
243{
245}
246static void IN_ShiftLeftUp_f (void)
247{
249}
250static void IN_ShiftLeftUpDown_f (void)
251{
254}
255static void IN_ShiftLeftUpUp_f (void)
256{
259}
260static void IN_ShiftLeftDownDown_f (void)
261{
264}
265static void IN_ShiftLeftDownUp_f (void)
266{
269}
270static void IN_ShiftRightDown_f (void)
271{
273}
274static void IN_ShiftRightUp_f (void)
275{
277}
278static void IN_ShiftRightUpDown_f (void)
279{
282}
283static void IN_ShiftRightUpUp_f (void)
284{
287}
288static void IN_ShiftRightDownDown_f (void)
289{
292}
293static void IN_ShiftRightDownUp_f (void)
294{
297}
298static void IN_ShiftUpDown_f (void)
299{
301}
302static void IN_ShiftUpUp_f (void)
303{
305}
306static void IN_ShiftDownDown_f (void)
307{
309}
310static void IN_ShiftDownUp_f (void)
311{
313}
314static void IN_ZoomInDown_f (void)
315{
317}
318static void IN_ZoomInUp_f (void)
319{
321}
322static void IN_ZoomOutDown_f (void)
323{
325}
326static void IN_ZoomOutUp_f (void)
327{
329}
330
331
335static void CL_LevelUp_f (void)
336{
337 if (!CL_OnBattlescape())
338 return;
339 Cvar_SetValue("cl_worldlevel", (cl_worldlevel->integer < cl.mapMaxLevel - 1) ? cl_worldlevel->integer + 1 : cl.mapMaxLevel - 1);
340}
341
345static void CL_LevelDown_f (void)
346{
347 if (!CL_OnBattlescape())
348 return;
349 Cvar_SetValue("cl_worldlevel", (cl_worldlevel->integer > 0) ? cl_worldlevel->integer - 1 : 0);
350}
351
352static void CL_ZoomInQuant_f (void)
353{
355}
356
357static void CL_ZoomOutQuant_f (void)
358{
360}
361
362static void CL_WheelDown_f (void)
363{
364 UI_MouseScroll(0, 1);
365}
366
367static void CL_WheelUp_f (void)
368{
369 UI_MouseScroll(0, -1);
370}
371
385
386static void CL_SelectUp_f (void)
387{
388#ifdef ANDROID
389 /* Android input quirk - when user tries to zoom/rotate, and touches the screen with a second finger,
390 * SDL will send left mouse button up event, and right mouse button down event immediately after that,
391 * so we need to cancel the mouse click action, and let the user zoom/rotate as she wants */
392 if ((SDL_GetMouseState(nullptr, nullptr) & SDL_BUTTON(SDL_BUTTON_RIGHT)) == 0)
393#endif
398 if (IN_GetMouseSpace() == MS_UI)
399 return;
401}
402
416
420static void CL_ActionDown_f (void)
421{
422 if (!CL_OnBattlescape())
423 return;
425}
426
427static void CL_ActionUp_f (void)
428{
430 if (IN_GetMouseSpace() == MS_UI)
431 return;
432 if (in_pantilt.msec < 250)
435}
436
440static void CL_TurnDown_f (void)
441{
442 if (IN_GetMouseSpace() == MS_UI)
443 return;
444 if (IN_GetMouseSpace() == MS_WORLD)
446}
447
448static void CL_TurnUp_f (void)
449{
450 if (IN_GetMouseSpace() == MS_UI)
451 return;
453}
454
458static void CL_HudRadarDown_f (void)
459{
461 return;
462 UI_PushWindow("radarmenu");
463}
464
468static void CL_HudRadarUp_f (void)
469{
471 return;
472 UI_CloseWindow("radarmenu");
473}
474
478static void CL_RightClickDown_f (void)
479{
480 if (IN_GetMouseSpace() == MS_UI) {
482 }
483}
484
488static void CL_RightClickUp_f (void)
489{
490 if (IN_GetMouseSpace() == MS_UI) {
492 }
493}
494
498static void CL_MiddleClickDown_f (void)
499{
500 if (IN_GetMouseSpace() == MS_UI) {
502 }
503}
504
508static void CL_MiddleClickUp_f (void)
509{
510 if (IN_GetMouseSpace() == MS_UI) {
512 }
513}
514
518static void CL_LeftClickDown_f (void)
519{
520 if (IN_GetMouseSpace() == MS_UI) {
522 }
523}
524
528static void CL_LeftClickUp_f (void)
529{
530 if (IN_GetMouseSpace() == MS_UI) {
532 }
533}
534
535#define SCROLL_BORDER 4
536#define MOUSE_YAW_SCALE 0.1
537#define MOUSE_PITCH_SCALE 0.1
538
542float CL_GetKeyMouseState (int dir)
543{
544 float value;
545
546 switch (dir) {
547 case STATE_FORWARD:
548 /* sum directions, 'true' is use as '1' */
549 value = (in_shiftup.state & 1) + (mousePosY <= (viddef.y / viddef.ry) + SCROLL_BORDER) - (in_shiftdown.state & 1) - (mousePosY >= ((viddef.y + viddef.viewHeight) / viddef.ry) - SCROLL_BORDER);
550 break;
551 case STATE_RIGHT:
552 /* sum directions, 'true' is use as '1' */
553 value = (in_shiftright.state & 1) + (mousePosX >= ((viddef.x + viddef.viewWidth) / viddef.rx) - SCROLL_BORDER) - (in_shiftleft.state & 1) - (mousePosX <= (viddef.x / viddef.rx) + SCROLL_BORDER);
554 break;
555 case STATE_ZOOM:
556 value = (in_zoomin.state & 1) - (in_zoomout.state & 1);
557 break;
558 case STATE_ROT:
559 value = (in_turnleft.state & 1) - (in_turnright.state & 1);
560 if (in_pantilt.state)
561 value -= (float) (mousePosX - oldMousePosX) * MOUSE_YAW_SCALE;
562 break;
563 case STATE_TILT:
564 value = (in_turnup.state & 1) - (in_turndown.state & 1);
565 if (in_pantilt.state)
566 value += (float) (mousePosY - oldMousePosY) * MOUSE_PITCH_SCALE;
567 break;
568 default:
569 value = 0.0;
570 break;
571 }
572
573 return value;
574}
575
580static void IN_Parse (void)
581{
583
584 /* standard menu and world mouse handling */
585 if (UI_IsMouseOnWindow()) {
587 return;
588 }
589
590 if (cls.state != ca_active)
591 return;
592
593 if (!viddef.viewWidth || !viddef.viewHeight)
594 return;
595
596 if (CL_ActorMouseTrace()) {
597 /* mouse is in the world */
599 }
600}
601
605static inline void IN_PrintKey (const SDL_Event* event, int down)
606{
607 if (in_debug->integer) {
608 Com_Printf("key name: %s (down: %i)", SDL_GetKeyName(event->key.keysym.sym), down);
609 const int unicode = event->key.keysym.sym;
610 if (unicode) {
611 Com_Printf(" unicode: %x", unicode);
612 if (unicode >= '0' && unicode <= '~') /* printable? */
613 Com_Printf(" (%c)", (unsigned char)(unicode));
614 }
615 Com_Printf("\n");
616 }
617}
618
622static bool IN_TranslateKey (const unsigned int keycode, unsigned int* ascii)
623{
624 bool translated = true;
625 switch (keycode) {
626 case SDLK_PAGEUP:
627 *ascii = K_PGUP;
628 break;
629 case SDLK_KP_0:
630 *ascii = K_KP_INS;
631 translated = !Key_IsNumlock();
632 break;
633 case SDLK_KP_1:
634 *ascii = K_KP_END;
635 translated = !Key_IsNumlock();
636 break;
637 case SDLK_KP_2:
638 *ascii = K_KP_DOWNARROW;
639 translated = !Key_IsNumlock();
640 break;
641 case SDLK_KP_3:
642 *ascii = K_KP_PGDN;
643 translated = !Key_IsNumlock();
644 break;
645 case SDLK_KP_4:
646 *ascii = K_KP_LEFTARROW;
647 translated = !Key_IsNumlock();
648 break;
649 case SDLK_KP_5:
650 *ascii = K_KP_5;
651 translated = !Key_IsNumlock();
652 break;
653 case SDLK_KP_6:
654 *ascii = K_KP_RIGHTARROW;
655 translated = !Key_IsNumlock();
656 break;
657 case SDLK_KP_7:
658 *ascii = K_KP_HOME;
659 translated = !Key_IsNumlock();
660 break;
661 case SDLK_KP_8:
662 *ascii = K_KP_UPARROW;
663 translated = !Key_IsNumlock();
664 break;
665 case SDLK_KP_9:
666 *ascii = K_KP_PGUP;
667 translated = !Key_IsNumlock();
668 break;
669 case SDLK_PRINTSCREEN:
670 *ascii = K_PRINT;
671 break;
672 case SDLK_SCROLLLOCK:
673 *ascii = K_SCROLLOCK;
674 break;
675 case SDLK_PAGEDOWN:
676 *ascii = K_PGDN;
677 break;
678 case SDLK_HOME:
679 *ascii = K_HOME;
680 break;
681 case SDLK_END:
682 *ascii = K_END;
683 break;
684 case SDLK_LEFT:
685 *ascii = K_LEFTARROW;
686 break;
687 case SDLK_RIGHT:
688 *ascii = K_RIGHTARROW;
689 break;
690 case SDLK_DOWN:
691 *ascii = K_DOWNARROW;
692 break;
693 case SDLK_UP:
694 *ascii = K_UPARROW;
695 break;
696 case SDLK_ESCAPE:
697 *ascii = K_ESCAPE;
698 break;
699 case SDLK_KP_ENTER:
700 *ascii = K_KP_ENTER;
701 break;
702 case SDLK_RETURN:
703 *ascii = K_ENTER;
704 break;
705 case SDLK_TAB:
706 *ascii = K_TAB;
707 break;
708 case SDLK_F1:
709 *ascii = K_F1;
710 break;
711 case SDLK_F2:
712 *ascii = K_F2;
713 break;
714 case SDLK_F3:
715 *ascii = K_F3;
716 break;
717 case SDLK_F4:
718 *ascii = K_F4;
719 break;
720 case SDLK_F5:
721 *ascii = K_F5;
722 break;
723 case SDLK_F6:
724 *ascii = K_F6;
725 break;
726 case SDLK_F7:
727 *ascii = K_F7;
728 break;
729 case SDLK_F8:
730 *ascii = K_F8;
731 break;
732 case SDLK_F9:
733 *ascii = K_F9;
734 break;
735 case SDLK_F10:
736 *ascii = K_F10;
737 break;
738 case SDLK_F11:
739 *ascii = K_F11;
740 break;
741 case SDLK_F12:
742 *ascii = K_F12;
743 break;
744 case SDLK_F13:
745 *ascii = K_F13;
746 break;
747 case SDLK_F14:
748 *ascii = K_F14;
749 break;
750 case SDLK_F15:
751 *ascii = K_F15;
752 break;
753 case SDLK_BACKSPACE:
754 *ascii = K_BACKSPACE;
755 break;
756 case SDLK_KP_PERIOD:
757 *ascii = K_KP_DEL;
758 translated = !Key_IsNumlock();
759 break;
760 case SDLK_DELETE:
761 *ascii = K_DEL;
762 break;
763 case SDLK_PAUSE:
764 *ascii = K_PAUSE;
765 break;
766 case SDLK_LSHIFT:
767 case SDLK_RSHIFT:
768 *ascii = K_SHIFT;
769 break;
770 case SDLK_LCTRL:
771 case SDLK_RCTRL:
772 *ascii = K_CTRL;
773 break;
774 case SDLK_LALT:
775 case SDLK_RALT:
776 *ascii = K_ALT;
777 break;
778 case SDLK_INSERT:
779 *ascii = K_INS;
780 break;
781 case SDLK_KP_PLUS:
782 *ascii = K_KP_PLUS;
783 translated = !Key_IsNumlock();
784 break;
785 case SDLK_KP_MINUS:
786 *ascii = K_KP_MINUS;
787 translated = !Key_IsNumlock();
788 break;
789 case SDLK_KP_DIVIDE:
790 *ascii = K_KP_SLASH;
791 translated = !Key_IsNumlock();
792 break;
793 case SDLK_KP_MULTIPLY:
794 *ascii = K_KP_MULTIPLY;
795 translated = !Key_IsNumlock();
796 break;
797 case SDLK_MODE:
798 *ascii = K_MODE;
799 break;
800 case SDLK_HELP:
801 *ascii = K_HELP;
802 break;
803 case SDLK_SYSREQ:
804 *ascii = K_SYSREQ;
805 break;
806 case SDLK_MENU:
807 *ascii = K_MENU;
808 break;
809 case SDLK_POWER:
810 *ascii = K_POWER;
811 break;
812 case SDLK_UNDO:
813 *ascii = K_UNDO;
814 break;
815 case SDLK_CAPSLOCK:
816 *ascii = K_CAPSLOCK;
817 break;
818 case SDLK_SPACE:
819 *ascii = K_SPACE;
820 break;
821 default:
822 translated = false;
823 if (UTF8_encoded_len(keycode) == 1 && isprint(keycode))
824 *ascii = keycode;
825 else
826 *ascii = 0;
827 break;
828 }
829 return translated;
830}
831
832void IN_EventEnqueue (unsigned int keyNum, unsigned short keyUnicode, bool keyDown)
833{
834 if (keyNum > 0 || keyUnicode > 0) {
835 if (in_debug->integer)
836 Com_Printf("Enqueue: %s (%i) (down: %i)\n", Key_KeynumToString(keyNum), keyNum, keyDown);
837 keyq[keyq_head].down = keyDown;
838 keyq[keyq_head].unicode = keyUnicode;
839 keyq[keyq_head].key = keyNum;
840 keyq_head = (keyq_head + 1) & (MAX_KEYQ - 1);
841 }
842}
843
844static bool IN_ToggleFullscreen (const bool full)
845{
846 const int mask = full ? SDL_WINDOW_FULLSCREEN : SDL_WINDOW_FULLSCREEN_DESKTOP;
847 const bool isFullScreen = SDL_GetWindowFlags(cls.window) & mask;
848 SDL_SetWindowFullscreen(cls.window, isFullScreen ? 0 : mask);
849 return SDL_GetWindowFlags(cls.window) & mask;
850}
851
859void IN_Frame (void)
860{
861 int mouse_buttonstate;
862 unsigned short unicode;
863 unsigned int key;
864 SDL_Event event;
865
866 IN_Parse();
867
869
871
872 if (vid_grabmouse->modified) {
873 vid_grabmouse->modified = false;
874
875 if (!vid_grabmouse->integer) {
876 /* ungrab the pointer */
877 Com_Printf("Switch grab input off\n");
878 SDL_SetWindowGrab(cls.window, SDL_FALSE);
879 } else {
880 /* grab the pointer */
881 Com_Printf("Switch grab input on\n");
882 SDL_SetWindowGrab(cls.window, SDL_TRUE);
883 }
884 }
885
888
889 while (SDL_PollEvent(&event)) {
890 switch (event.type) {
891 case SDL_MOUSEWHEEL:
892 mouse_buttonstate = event.wheel.y < 0 ? K_MWHEELDOWN : K_MWHEELUP;
893 IN_EventEnqueue(mouse_buttonstate, 0, true);
894 break;
895 case SDL_TEXTEDITING:
897 break;
898 case SDL_TEXTINPUT: {
899 if (!SDL_IsTextInputActive())
900 break;
901
902 const char* text = event.text.text;
903 const char** str = &text;
904 for (;;) {
905 const int characterUnicode = UTF8_next(str);
906 if (characterUnicode == -1) {
907 break;
908 }
909 unicode = characterUnicode;
910 IN_TranslateKey(characterUnicode, &key);
912 IN_EventEnqueue(key, unicode, false);
913 }
914 break;
915 }
916 case SDL_MOUSEBUTTONDOWN:
917 case SDL_MOUSEBUTTONUP:
918 switch (event.button.button) {
919 case SDL_BUTTON_LEFT:
920 mouse_buttonstate = K_MOUSE1;
921 break;
922 case SDL_BUTTON_MIDDLE:
923 mouse_buttonstate = K_MOUSE3;
924 break;
925 case SDL_BUTTON_RIGHT:
926 mouse_buttonstate = K_MOUSE2;
927 break;
928 case SDL_BUTTON_X1:
929 mouse_buttonstate = K_MOUSE4;
930 break;
931 case SDL_BUTTON_X2:
932 mouse_buttonstate = K_MOUSE5;
933 break;
934 default:
935 mouse_buttonstate = K_AUX1 + (event.button.button - 8) % 16;
936 break;
937 }
938 IN_EventEnqueue(mouse_buttonstate, 0, (event.type == SDL_MOUSEBUTTONDOWN));
939 break;
940
941 case SDL_MOUSEMOTION:
942 SDL_GetMouseState(&mousePosX, &mousePosY);
943 mousePosX /= viddef.rx;
944 mousePosY /= viddef.ry;
945 break;
946
947 case SDL_KEYDOWN:
948 IN_PrintKey(&event, 1);
949 if ((event.key.keysym.mod & KMOD_ALT) && event.key.keysym.sym == SDLK_RETURN) {
950 Com_Printf("try to toggle fullscreen\n");
951 if (IN_ToggleFullscreen(false)) {
952 Cvar_SetValue("vid_fullscreen", 1);
953 /* make sure, that input grab is deactivated in fullscreen mode */
954 Cvar_SetValue("vid_grabmouse", 0);
955 } else {
956 Cvar_SetValue("vid_fullscreen", 0);
957 }
958 vid_fullscreen->modified = false; /* we just changed it with SDL. */
959 break; /* ignore this key */
960 }
961
962 if ((event.key.keysym.mod & KMOD_CTRL) && event.key.keysym.sym == SDLK_RETURN) {
963 Com_Printf("try to toggle fullscreen\n");
964 if (IN_ToggleFullscreen(true)) {
965 Cvar_SetValue("vid_fullscreen", 2);
966 } else {
967 Cvar_SetValue("vid_fullscreen", 0);
968 }
969 vid_fullscreen->modified = false; /* we just changed it with SDL. */
970 break; /* ignore this key */
971 }
972
973 if ((event.key.keysym.mod & KMOD_CTRL) && event.key.keysym.sym == SDLK_g) {
974 const bool grab = SDL_GetWindowGrab(cls.window);
975 Cvar_SetValue("vid_grabmouse", grab ? 0 : 1);
976 Com_Printf("toggled mouse grab (%s)\n", vid_grabmouse->integer == 1 ? "true" : "false");
977 break; /* ignore this key */
978 }
979
980 /* console key is hardcoded, so the user can never unbind it */
981 if ((event.key.keysym.mod & KMOD_SHIFT) && event.key.keysym.sym == SDLK_ESCAPE) {
983 break;
984 }
985
986 /* SDL_TEXTINPUT above will handle normal text for sdl2 */
987 if (IN_TranslateKey(event.key.keysym.sym, &key) || !SDL_IsTextInputActive())
988 IN_EventEnqueue(key, 0, true);
989 break;
990
991 case SDL_KEYUP:
992 IN_PrintKey(&event, 0);
993 /* SDL_TEXTINPUT above will handle normal text for sdl2 */
994 if (IN_TranslateKey(event.key.keysym.sym, &key) || !SDL_IsTextInputActive())
995 IN_EventEnqueue(key, 0, false);
996 break;
997
999 case SDL_WINDOWEVENT:
1000 switch (event.window.event) {
1001 case SDL_WINDOWEVENT_MOVED:
1002 viddef.context.left = event.window.data1;
1003 viddef.context.top = event.window.data2;
1004 Cvar_SetValue("vid_left", event.window.data1);
1005 Cvar_SetValue("vid_top", event.window.data2);
1006 break;
1007 case SDL_WINDOWEVENT_RESIZED:
1008 /* make sure that SDL_SetVideoMode is called again after we changed the size
1009 * otherwise the mouse will make problems */
1010 vid_mode->modified = true;
1011 break;
1012 case SDL_WINDOWEVENT_FOCUS_LOST:
1014 break;
1015 default:
1016 break;
1017 }
1018 break;
1019
1020 case SDL_QUIT:
1021 Cmd_ExecuteString("quit");
1022 break;
1023 }
1024 }
1025}
1026
1030static void CL_PressKey_f (void)
1031{
1032 if (Cmd_Argc() != 2) {
1033 Com_Printf("Usage: %s <key> : simulate press of a key\n", Cmd_Argv(0));
1034 return;
1035 }
1036
1037 const unsigned int keyNum = Key_StringToKeynum(Cmd_Argv(1));
1038 /* @todo unicode value is wrong */
1039 IN_EventEnqueue(keyNum, '?', true);
1040 IN_EventEnqueue(keyNum, '?', false);
1041}
1042
1043typedef struct cursorChange_s {
1047
1049
1051{
1052 if (mspace != MS_NULL) {
1053 if (mspace != cursorChange.prevSpace) {
1055 }
1056 }
1057 if (mouseSpace != MS_NULL && mouseSpace != cursorChange.prevSpace) {
1058 cursorChange.prevSpace = mouseSpace;
1059 cursorChange.cursor = Cvar_GetValue("cursor");
1060 }
1061 mouseSpace = mspace;
1062}
1063
1067void IN_Init (void)
1068{
1069 Com_Printf("\n------- input initialization -------\n");
1070
1071 /* cvars */
1072 in_debug = Cvar_Get("in_debug", "0", 0, "Show input key codes on game console");
1073 cl_isometric = Cvar_Get("r_isometric", "0", CVAR_ARCHIVE, "Draw the world in isometric mode");
1074
1075 /* commands */
1076 Cmd_AddCommand("+turnleft", IN_TurnLeftDown_f, N_("Rotate battlescape camera anti-clockwise"));
1077 Cmd_AddCommand("-turnleft", IN_TurnLeftUp_f);
1078 Cmd_AddCommand("+turnright", IN_TurnRightDown_f, N_("Rotate battlescape camera clockwise"));
1079 Cmd_AddCommand("-turnright", IN_TurnRightUp_f);
1080 Cmd_AddCommand("+turnup", IN_TurnUpDown_f, N_("Tilt battlescape camera up"));
1081 Cmd_AddCommand("-turnup", IN_TurnUpUp_f);
1082 Cmd_AddCommand("+turndown", IN_TurnDownDown_f, N_("Tilt battlescape camera down"));
1083 Cmd_AddCommand("-turndown", IN_TurnDownUp_f);
1084 Cmd_AddCommand("+pantilt", IN_PanTiltDown_f, N_("Move battlescape camera"));
1085 Cmd_AddCommand("-pantilt", IN_PanTiltUp_f);
1086 Cmd_AddCommand("+shiftleft", IN_ShiftLeftDown_f, N_("Move battlescape camera left"));
1087 Cmd_AddCommand("-shiftleft", IN_ShiftLeftUp_f);
1088 Cmd_AddCommand("+shiftleftup", IN_ShiftLeftUpDown_f, N_("Move battlescape camera top left"));
1089 Cmd_AddCommand("-shiftleftup", IN_ShiftLeftUpUp_f);
1090 Cmd_AddCommand("+shiftleftdown", IN_ShiftLeftDownDown_f, N_("Move battlescape camera bottom left"));
1091 Cmd_AddCommand("-shiftleftdown", IN_ShiftLeftDownUp_f);
1092 Cmd_AddCommand("+shiftright", IN_ShiftRightDown_f, N_("Move battlescape camera right"));
1093 Cmd_AddCommand("-shiftright", IN_ShiftRightUp_f);
1094 Cmd_AddCommand("+shiftrightup", IN_ShiftRightUpDown_f, N_("Move battlescape camera top right"));
1095 Cmd_AddCommand("-shiftrightup", IN_ShiftRightUpUp_f);
1096 Cmd_AddCommand("+shiftrightdown", IN_ShiftRightDownDown_f, N_("Move battlescape camera bottom right"));
1097 Cmd_AddCommand("-shiftrightdown", IN_ShiftRightDownUp_f);
1098 Cmd_AddCommand("+shiftup", IN_ShiftUpDown_f, N_("Move battlescape camera forward"));
1099 Cmd_AddCommand("-shiftup", IN_ShiftUpUp_f);
1100 Cmd_AddCommand("+shiftdown", IN_ShiftDownDown_f, N_("Move battlescape camera backward"));
1101 Cmd_AddCommand("-shiftdown", IN_ShiftDownUp_f);
1102 Cmd_AddCommand("+zoomin", IN_ZoomInDown_f, N_("Zoom in"));
1103 Cmd_AddCommand("-zoomin", IN_ZoomInUp_f);
1104 Cmd_AddCommand("+zoomout", IN_ZoomOutDown_f, N_("Zoom out"));
1105 Cmd_AddCommand("-zoomout", IN_ZoomOutUp_f);
1106
1107 Cmd_AddCommand("+leftmouse", CL_LeftClickDown_f, N_("Left mouse button click (menu)"));
1108 Cmd_AddCommand("-leftmouse", CL_LeftClickUp_f);
1109 Cmd_AddCommand("+middlemouse", CL_MiddleClickDown_f, N_("Middle mouse button click (menu)"));
1110 Cmd_AddCommand("-middlemouse", CL_MiddleClickUp_f);
1111 Cmd_AddCommand("+rightmouse", CL_RightClickDown_f, N_("Right mouse button click (menu)"));
1112 Cmd_AddCommand("-rightmouse", CL_RightClickUp_f);
1113 Cmd_AddCommand("wheelupmouse", CL_WheelUp_f, N_("Mouse wheel up"));
1114 Cmd_AddCommand("wheeldownmouse", CL_WheelDown_f, N_("Mouse wheel down"));
1115 Cmd_AddCommand("+select", CL_SelectDown_f, N_("Select objects/Walk to a square/In fire mode, fire etc"));
1116 Cmd_AddCommand("-select", CL_SelectUp_f);
1117 Cmd_AddCommand("+action", CL_ActionDown_f, N_("Rotate Battlescape/In fire mode, cancel action"));
1118 Cmd_AddCommand("-action", CL_ActionUp_f);
1119 Cmd_AddCommand("+turn", CL_TurnDown_f, N_("Turn soldier toward mouse pointer"));
1120 Cmd_AddCommand("-turn", CL_TurnUp_f);
1121 Cmd_AddCommand("+hudradar", CL_HudRadarDown_f, N_("Toggles the hud radar mode"));
1122 Cmd_AddCommand("-hudradar", CL_HudRadarUp_f);
1123
1124 Cmd_AddCommand("levelup", CL_LevelUp_f, N_("Slice through terrain at a higher level"));
1125 Cmd_AddCommand("leveldown", CL_LevelDown_f, N_("Slice through terrain at a lower level"));
1126 Cmd_AddCommand("zoominquant", CL_ZoomInQuant_f, N_("Zoom in"));
1127 Cmd_AddCommand("zoomoutquant", CL_ZoomOutQuant_f, N_("Zoom out"));
1128
1129 Cmd_AddCommand("press", CL_PressKey_f, "Press a key from a command");
1130
1131 mousePosX = mousePosY = 0.0;
1132
1134}
1135
1140{
1141 while (keyq_head != keyq_tail) {
1143 keyq_tail = (keyq_tail + 1) & (MAX_KEYQ - 1);
1144 }
1145}
void CL_ActorSelectMouse(void)
Selects an actor using the mouse.
void CL_ActorTurnMouse(void)
Turns the actor around without moving.
void CL_BattlescapeMouseDragging(void)
Scroll battlescape touchscreen-style, by clicking and dragging away.
bool CL_ActorMouseTrace(void)
Battlescape cursor positioning.
void CL_InitBattlescapeMouseDragging(void)
Scroll battlescape touchscreen-style, by clicking and dragging away.
void CL_ActorActionMouse(void)
initiates action with mouse.
clientBattleScape_t cl
bool CL_OnBattlescape(void)
Check whether we are in a tactical mission as server or as client. But this only means that we are ab...
bool CL_BattlescapeRunning(void)
Check whether we already have actors spawned on the battlefield.
void CL_CameraZoomIn(void)
Zooms the scene of the battlefield in.
void CL_CameraZoomOut(void)
Zooms the scene of the battlefield out.
void Con_ToggleConsole_f(void)
Console header file.
cvar_t * cl_worldlevel
Definition cl_hud.cpp:46
HUD related routines.
static void CL_LevelUp_f(void)
Switch one worldlevel up.
Definition cl_input.cpp:335
static void IN_TurnUpDown_f(void)
Definition cl_input.cpp:216
int mousePosY
Definition cl_input.cpp:76
static void IN_ShiftLeftDownUp_f(void)
Definition cl_input.cpp:265
static void IN_ShiftRightDown_f(void)
Definition cl_input.cpp:270
static void CL_ActionDown_f(void)
Middle mouse click.
Definition cl_input.cpp:420
static cvar_t * in_debug
Definition cl_input.cpp:72
static int battlescapeMouseDraggingX
Definition cl_input.cpp:79
static void IN_ShiftLeftUpDown_f(void)
Definition cl_input.cpp:250
static int keyq_tail
Definition cl_input.cpp:70
static void IN_TurnUpUp_f(void)
Definition cl_input.cpp:220
static void IN_ZoomInDown_f(void)
Definition cl_input.cpp:314
static kbutton_t in_turnleft
Definition cl_input.cpp:100
static void IN_ZoomOutDown_f(void)
Definition cl_input.cpp:322
#define MOUSE_YAW_SCALE
Definition cl_input.cpp:536
static void CL_HudRadarUp_f(void)
Definition cl_input.cpp:468
static void CL_ZoomOutQuant_f(void)
Definition cl_input.cpp:357
static kbutton_t in_shiftdown
Definition cl_input.cpp:101
static void CL_MiddleClickUp_f(void)
Middle mouse button is freed in menu.
Definition cl_input.cpp:508
static bool battlescapeMouseDraggingActive
Definition cl_input.cpp:81
static void CL_PressKey_f(void)
static void IN_ShiftUpUp_f(void)
Definition cl_input.cpp:302
static void IN_ShiftRightUp_f(void)
Definition cl_input.cpp:274
static void CL_WheelUp_f(void)
Definition cl_input.cpp:367
static void IN_PanTiltUp_f(void)
Definition cl_input.cpp:238
void IN_Frame(void)
Handle input events like key presses and joystick movement as well as window events.
Definition cl_input.cpp:859
#define MOUSE_PITCH_SCALE
Definition cl_input.cpp:537
#define MAX_KEYQ
Definition cl_input.cpp:61
float CL_GetKeyMouseState(int dir)
Definition cl_input.cpp:542
static void IN_ShiftLeftUpUp_f(void)
Definition cl_input.cpp:255
static void IN_KeyUp(kbutton_t *b)
Handles the release of a kbutton_t state.
Definition cl_input.cpp:159
static kbutton_t in_shiftright
Definition cl_input.cpp:100
static bool IN_ToggleFullscreen(const bool full)
Definition cl_input.cpp:844
static void IN_ZoomOutUp_f(void)
Definition cl_input.cpp:326
static void IN_TurnLeftUp_f(void)
Definition cl_input.cpp:204
static bool IN_TranslateKey(const unsigned int keycode, unsigned int *ascii)
Translate the keys to ufo keys.
Definition cl_input.cpp:622
static void IN_KeyDown(kbutton_t *b)
Handles the catch of a kbutton_t state.
Definition cl_input.cpp:113
static kbutton_t in_pantilt
Definition cl_input.cpp:104
mouseSpace_t mouseSpace
Definition cl_input.cpp:75
static void CL_TurnUp_f(void)
Definition cl_input.cpp:448
void IN_Init(void)
unsigned int key
Definition cl_input.cpp:64
static void CL_SelectUp_f(void)
Definition cl_input.cpp:386
static int oldMousePosX
Definition cl_input.cpp:77
#define SCROLL_BORDER
Definition cl_input.cpp:535
@ BATTLESCAPE_MOUSE_DRAGGING_TRIGGER_Y
Definition cl_input.cpp:84
@ BATTLESCAPE_MOUSE_DRAGGING_TRIGGER_X
Definition cl_input.cpp:83
static kbutton_t in_zoomout
Definition cl_input.cpp:102
static void CL_SelectDown_f(void)
Left mouse click.
Definition cl_input.cpp:375
static void IN_ShiftRightUpUp_f(void)
Definition cl_input.cpp:283
static void CL_WheelDown_f(void)
Definition cl_input.cpp:362
static void CL_LeftClickDown_f(void)
Left mouse button is hit in menu.
Definition cl_input.cpp:518
static void CL_LevelDown_f(void)
Switch one worldlevel down.
Definition cl_input.cpp:345
static void IN_TurnRightDown_f(void)
Definition cl_input.cpp:208
static void IN_ShiftRightUpDown_f(void)
Definition cl_input.cpp:278
static kbutton_t in_zoomin
Definition cl_input.cpp:102
static kbutton_t in_shiftleft
Definition cl_input.cpp:100
static void IN_ZoomInUp_f(void)
Definition cl_input.cpp:318
static void IN_TurnDownDown_f(void)
Definition cl_input.cpp:224
void IN_EventEnqueue(unsigned int keyNum, unsigned short keyUnicode, bool keyDown)
Definition cl_input.cpp:832
static void IN_ShiftLeftDownDown_f(void)
Definition cl_input.cpp:260
static void CL_RightClickDown_f(void)
Right mouse button is hit in menu.
Definition cl_input.cpp:478
static void IN_ShiftRightDownUp_f(void)
Definition cl_input.cpp:293
int down
Definition cl_input.cpp:66
static void CL_RightClickUp_f(void)
Right mouse button is freed in menu.
Definition cl_input.cpp:488
static void IN_Parse(void)
Called every frame to parse the input.
Definition cl_input.cpp:580
static void IN_ShiftDownDown_f(void)
Definition cl_input.cpp:306
static int keyq_head
Definition cl_input.cpp:69
static kbutton_t in_turnup
Definition cl_input.cpp:103
static void CL_ActionUp_f(void)
Definition cl_input.cpp:427
static void IN_TurnDownUp_f(void)
Definition cl_input.cpp:228
static struct @065014221206172263127061201106336017314171050104 keyq[MAX_KEYQ]
static void IN_ShiftRightDownDown_f(void)
Definition cl_input.cpp:288
static cursorChange_t cursorChange
static void CL_LeftClickUp_f(void)
Left mouse button is freed in menu.
Definition cl_input.cpp:528
unsigned short unicode
Definition cl_input.cpp:65
int mousePosX
Definition cl_input.cpp:76
static void IN_TurnLeftDown_f(void)
Definition cl_input.cpp:200
static void CL_HudRadarDown_f(void)
Definition cl_input.cpp:458
static void CL_ProcessMouseDragging(void)
Definition cl_input.cpp:403
static void IN_TurnRightUp_f(void)
Definition cl_input.cpp:212
void IN_SetMouseSpace(mouseSpace_t mspace)
static int oldMousePosY
Definition cl_input.cpp:77
static void CL_ZoomInQuant_f(void)
Definition cl_input.cpp:352
static void CL_MiddleClickDown_f(void)
Middle mouse button is hit in menu.
Definition cl_input.cpp:498
static kbutton_t in_turndown
Definition cl_input.cpp:103
static void IN_ShiftLeftUp_f(void)
Definition cl_input.cpp:246
static void IN_PrintKey(const SDL_Event *event, int down)
Debug function to print sdl key events.
Definition cl_input.cpp:605
static kbutton_t in_shiftup
Definition cl_input.cpp:101
static void IN_ShiftLeftDown_f(void)
Definition cl_input.cpp:242
static void CL_TurnDown_f(void)
Turn button is hit.
Definition cl_input.cpp:440
static void IN_ShiftDownUp_f(void)
Definition cl_input.cpp:310
static bool battlescapeMouseDraggingPossible
Definition cl_input.cpp:81
void IN_SendKeyEvents(void)
static int battlescapeMouseDraggingY
Definition cl_input.cpp:80
static void IN_ShiftUpDown_f(void)
Definition cl_input.cpp:298
static kbutton_t in_turnright
Definition cl_input.cpp:100
static void IN_PanTiltDown_f(void)
Definition cl_input.cpp:232
External (non-keyboard) input devices.
#define STATE_FORWARD
Definition cl_input.h:39
#define STATE_RIGHT
Definition cl_input.h:40
#define STATE_TILT
Definition cl_input.h:43
#define IN_GetMouseSpace()
Definition cl_input.h:48
mouseSpace_t
Definition cl_input.h:31
@ MS_WORLD
Definition cl_input.h:34
@ MS_UI
Definition cl_input.h:33
@ MS_NULL
Definition cl_input.h:32
#define STATE_ZOOM
Definition cl_input.h:41
#define STATE_ROT
Definition cl_input.h:42
void IN_StartupJoystick(void)
Init available joysticks.
void IN_JoystickMove(void)
static bool keyDown[K_KEY_SIZE]
Definition cl_keys.cpp:67
bool Key_IsNumlock(void)
Definition cl_keys.cpp:221
const char * Key_KeynumToString(int keynum)
Convert a given keynum to string.
Definition cl_keys.cpp:485
void Key_Event(unsigned int key, unsigned short unicode, bool down, unsigned time)
Called by the system between frames for both key up and key down events.
Definition cl_keys.cpp:841
int Key_StringToKeynum(const char *str)
Convert to given string to keynum.
Definition cl_keys.cpp:462
Header file for keyboard handler.
@ K_F2
Definition cl_keys.h:82
@ K_F1
Definition cl_keys.h:81
@ K_MOUSE4
Definition cl_keys.h:51
@ K_SHIFT
Definition cl_keys.h:97
@ K_KP_5
Definition cl_keys.h:59
@ K_F12
Definition cl_keys.h:92
@ K_KP_RIGHTARROW
Definition cl_keys.h:60
@ K_DEL
Definition cl_keys.h:44
@ K_KP_MINUS
Definition cl_keys.h:67
@ K_F6
Definition cl_keys.h:86
@ K_F4
Definition cl_keys.h:84
@ K_KP_PGDN
Definition cl_keys.h:57
@ K_MOUSE5
Definition cl_keys.h:52
@ K_KP_DEL
Definition cl_keys.h:64
@ K_KP_PGUP
Definition cl_keys.h:63
@ K_MENU
Definition cl_keys.h:160
@ K_KP_UPARROW
Definition cl_keys.h:62
@ K_KP_INS
Definition cl_keys.h:54
@ K_KP_PLUS
Definition cl_keys.h:68
@ K_ALT
Definition cl_keys.h:99
@ K_MWHEELUP
Definition cl_keys.h:50
@ K_KP_END
Definition cl_keys.h:55
@ K_F13
Definition cl_keys.h:93
@ K_ENTER
Definition cl_keys.h:40
@ K_F9
Definition cl_keys.h:89
@ K_F14
Definition cl_keys.h:94
@ K_MOUSE2
Definition cl_keys.h:47
@ K_MOUSE1
Definition cl_keys.h:46
@ K_MODE
Definition cl_keys.h:154
@ K_UPARROW
Definition cl_keys.h:72
@ K_F8
Definition cl_keys.h:88
@ K_ESCAPE
Definition cl_keys.h:42
@ K_F5
Definition cl_keys.h:85
@ K_UNDO
Definition cl_keys.h:162
@ K_POWER
Definition cl_keys.h:166
@ K_SYSREQ
Definition cl_keys.h:157
@ K_PGUP
Definition cl_keys.h:79
@ K_PAUSE
Definition cl_keys.h:41
@ K_KP_DOWNARROW
Definition cl_keys.h:56
@ K_AUX1
Definition cl_keys.h:134
@ K_BACKSPACE
Definition cl_keys.h:38
@ K_CAPSLOCK
Definition cl_keys.h:165
@ K_KP_SLASH
Definition cl_keys.h:65
@ K_HELP
Definition cl_keys.h:155
@ K_MOUSE3
Definition cl_keys.h:48
@ K_END
Definition cl_keys.h:78
@ K_F15
Definition cl_keys.h:95
@ K_SCROLLOCK
Definition cl_keys.h:158
@ K_INS
Definition cl_keys.h:96
@ K_F10
Definition cl_keys.h:90
@ K_KP_ENTER
Definition cl_keys.h:69
@ K_CTRL
Definition cl_keys.h:98
@ K_KP_LEFTARROW
Definition cl_keys.h:58
@ K_MWHEELDOWN
Definition cl_keys.h:49
@ K_F11
Definition cl_keys.h:91
@ K_KP_MULTIPLY
Definition cl_keys.h:66
@ K_SPACE
Definition cl_keys.h:43
@ K_HOME
Definition cl_keys.h:77
@ K_PRINT
Definition cl_keys.h:156
@ K_TAB
Definition cl_keys.h:39
@ K_RIGHTARROW
Definition cl_keys.h:74
@ K_F3
Definition cl_keys.h:83
@ K_F7
Definition cl_keys.h:87
@ K_DOWNARROW
Definition cl_keys.h:73
@ K_KP_HOME
Definition cl_keys.h:61
@ K_PGDN
Definition cl_keys.h:80
@ K_LEFTARROW
Definition cl_keys.h:75
client_static_t cls
Definition cl_main.cpp:83
int CL_Milliseconds(void)
Definition cl_main.cpp:1207
#define VID_NORM_WIDTH
Definition cl_renderer.h:40
#define VID_NORM_HEIGHT
Definition cl_renderer.h:41
void SCR_ChangeCursor(int cursor)
Header for certain screen operations.
#define N_(String)
Definition cl_shared.h:46
@ ca_active
Definition cl_shared.h:80
cvar_t * vid_grabmouse
Definition cl_video.cpp:39
cvar_t * vid_fullscreen
Definition cl_video.cpp:37
viddef_t viddef
Definition cl_video.cpp:34
cvar_t * vid_mode
Definition cl_video.cpp:38
cvar_t * cl_isometric
Definition cl_input.cpp:73
Primary header for client.
void Cmd_ExecuteString(const char *text,...)
A complete command line has been parsed, so try to execute it.
Definition cmd.cpp:1007
const char * Cmd_Argv(int arg)
Returns a given argument.
Definition cmd.cpp:516
int Cmd_Argc(void)
Return the number of arguments of the current command. "command parameter" will result in a argc of 2...
Definition cmd.cpp:505
void Cmd_AddCommand(const char *cmdName, xcommand_t function, const char *desc)
Add a new command to the script interface.
Definition cmd.cpp:744
void Com_Printf(const char *const fmt,...)
Definition common.cpp:428
void Cvar_SetValue(const char *varName, float value)
Expands value to a string and calls Cvar_Set.
Definition cvar.cpp:671
float Cvar_GetValue(const char *varName)
Returns the float value of a cvar.
Definition cvar.cpp:125
cvar_t * Cvar_Get(const char *var_name, const char *var_value, int flags, const char *desc)
Init or return a cvar.
Definition cvar.cpp:342
#define CVAR_ARCHIVE
Definition cvar.h:40
mouseSpace_t prevSpace
This is a cvar definition. Cvars can be user modified and used in our menus e.g.
Definition cvar.h:71
unsigned msec
Definition cl_input.cpp:96
int down[2]
Definition cl_input.cpp:94
unsigned downtime
Definition cl_input.cpp:95
Tracing functions.
void UI_MouseUp(int x, int y, int button)
Called when we are in UI mode and up a mouse button.
Definition ui_input.cpp:839
void UI_MouseScroll(int deltaX, int deltaY)
Called when we are in UI mode and scroll via mousewheel.
Definition ui_input.cpp:756
void UI_ReleaseInput(void)
Release all captured input (keyboard or mouse).
Definition ui_input.cpp:496
void UI_MouseDown(int x, int y, int button)
Called when we are in UI mode and down a mouse button.
Definition ui_input.cpp:801
uiNode_t * UI_PushWindow(const char *name, const char *parentName, linkedList_t *params)
Push a window onto the window stack.
void UI_CloseWindow(const char *name)
bool UI_IsMouseOnWindow(void)
Check if a point is over a window from the stack.
int UTF8_next(const char **str)
Get the next utf-8 character from the given string.
Definition utf8.cpp:132
int UTF8_encoded_len(int c)
Definition utf8.cpp:188