naev 0.12.6
input.c
Go to the documentation of this file.
1/*
2 * See Licensing and Copyright notice in naev.h
3 */
10#include "naev.h"
11#include <ctype.h>
13
14#include "input.h"
15
16#include "board.h"
17#include "camera.h"
18#include "conf.h"
19#include "console.h"
20#include "escort.h"
21#include "gui.h"
22#include "hook.h"
23#include "info.h"
24#include "land.h"
25#include "log.h"
26#include "map.h"
27#include "map_overlay.h"
28#include "menu.h"
29#include "nstring.h"
30#include "pause.h"
31#include "pilot.h"
32#include "player.h"
33#include "player_autonav.h"
34#include "toolkit.h"
35#include "utf8.h"
36
37/* keybinding structure */
41typedef struct Keybind_ {
43 KeybindType type;
44 SDL_Keycode key;
45 SDL_Keymod mod;
46} Keybind;
47
48/* Description of each key semantic type */
49static const char *keybind_info[KST_END][3] = {
50 /* Movement */
51 [KST_ACCEL] = { N_( "Accelerate" ),
52 N_( "Makes your ship accelerate forward." ), "accel" },
53 [KST_LEFT] = { N_( "Turn Left" ), N_( "Makes your ship turn left." ),
54 "left" },
55 [KST_RIGHT] = { N_( "Turn Right" ), N_( "Makes your ship turn right." ),
56 "right" },
57 [KST_REVERSE] = { N_( "Reverse" ),
58 N_( "Makes your ship face the direction you're moving "
59 "from. Useful for braking." ),
60 "reverse" },
61 [KST_FACE] = { N_( "Face Target" ),
62 N_( "Faces the targeted ship if one is targeted, otherwise "
63 "faces targeted spob, or jump point." ),
64 "face" },
65
66 /* Gameplay modifiers */
67 [KST_STEALTH] = { N_( "Stealth" ), N_( "Tries to enter stealth mode." ),
68 "stealth" },
69 [KST_GAME_SPEED] = { N_( "Toggle Speed" ), N_( "Toggles speed modifier." ),
70 "speed" },
71 [KST_PAUSE] = { N_( "Pause" ), N_( "Pauses the game." ), "pause" },
72
73 /* Movement modifiers */
74 [KST_AUTONAV] = { N_( "Autonavigation On" ),
75 N_( "Initializes the autonavigation system." ),
76 "autonav" },
77 [KST_APPROACH] =
78 { N_( "Approach" ),
79 N_( "Attempts to approach the targeted ship or space object, "
80 "or targets the nearest landable space object. "
81 "Requests landing permission if necessary. "
82 "Prioritizes ships over space objects." ),
83 "approach" },
84 [KST_MOUSE_FLYING] = { N_( "Mouse Flight" ), N_( "Toggles mouse flying." ),
85 "mousefly" },
86 [KST_JUMP] = { N_( "Initiate Jump" ),
87 N_( "Attempts to jump via a jump point." ), "jump" },
88
89 /* Targeting */
90 [KST_TARGET_NEXT] = { N_( "Target Next" ),
91 N_( "Cycles through ship targets." ), "target_next" },
92 [KST_TARGET_PREV] = { N_( "Target Previous" ),
93 N_( "Cycles backwards through ship targets." ),
94 "target_prev" },
95 [KST_TARGET_CLOSE] = { N_( "Target Nearest" ),
96 N_( "Targets the nearest non-disabled ship." ),
97 "target_nearest" },
98 [KST_TARGET_SPOB] = { N_( "Target Spob" ),
99 N_( "Cycles through space object targets." ),
100 "target_spob" },
101 [KST_TARGET_JUMP] = { N_( "Target Jumpgate" ),
102 N_( "Cycles through jump points." ), "thyperspace" },
103
104 /* Hostile targets */
105 [KST_HTARGET_NEXT] = { N_( "Target Next Hostile" ),
106 N_( "Cycles through hostile ship targets." ),
107 "target_nextHostile" },
108 [KST_HTARGET_PREV] = { N_( "Target Previous Hostile" ),
109 N_(
110 "Cycles backwards through hostile ship targets." ),
111 "target_prevHostile" },
112 [KST_HTARGET_CLOSE] = { N_( "Target Nearest Hostile" ),
113 N_( "Targets the nearest hostile ship." ),
114 "target_hostile" },
115
116 [KST_TARGET_CLEAR] =
117 { N_( "Clear Target" ),
118 N_( "Clears the currently-targeted ship, spob or jump point." ),
119 "target_clear" },
120
121 /* Fighting */
122 [KST_FIRE_PRIMARY] = { N_( "Fire Primary Weapon" ),
123 N_( "Fires primary weapons." ), "primary" },
124 [KST_FIRE_SECONDARY] = { N_( "Fire Secondary Weapon" ),
125 N_( "Fires secondary weapons." ), "secondary" },
126 [KST_COOLDOWN] = { N_( "Active Cooldown" ), N_( "Begins active cooldown." ),
127 "cooldown" },
128
129 /* Switching tab s*/
130 [KST_WEAPSET1] = { N_( "Weapon Set 1" ), N_( "Activates weapon set 1." ),
131 "weapset1" },
132 [KST_WEAPSET2] = { N_( "Weapon Set 2" ), N_( "Activates weapon set 2." ),
133 "weapset2" },
134 [KST_WEAPSET3] = { N_( "Weapon Set 3" ), N_( "Activates weapon set 3." ),
135 "weapset3" },
136 [KST_WEAPSET4] = { N_( "Weapon Set 4" ), N_( "Activates weapon set 4." ),
137 "weapset4" },
138 [KST_WEAPSET5] = { N_( "Weapon Set 5" ), N_( "Activates weapon set 5." ),
139 "weapset5" },
140 [KST_WEAPSET6] = { N_( "Weapon Set 6" ), N_( "Activates weapon set 6." ),
141 "weapset6" },
142 [KST_WEAPSET7] = { N_( "Weapon Set 7" ), N_( "Activates weapon set 7." ),
143 "weapset7" },
144 [KST_WEAPSET8] = { N_( "Weapon Set 8" ), N_( "Activates weapon set 8." ),
145 "weapset8" },
146 [KST_WEAPSET9] = { N_( "Weapon Set 9" ), N_( "Activates weapon set 9." ),
147 "weapset9" },
148 [KST_WEAPSET0] = { N_( "Weapon Set 0" ), N_( "Activates weapon set 0." ),
149 "weapset0" },
150
151 /* Map manipulation */
152 [KST_OVERLAY_MAP] = { N_( "Overlay Map" ),
153 N_( "Opens the in-system overlay map." ), "overlay" },
154 [KST_STAR_MAP] = { N_( "Star Map" ), N_( "Opens the star map." ),
155 "starmap" },
156
157 /* Menus */
158 [KST_MENU_SMALL] = { N_( "Small Menu" ),
159 N_( "Opens the small in-game menu." ), "menu" },
160 [KST_MENU_INFO] = { N_( "Information Menu" ),
161 N_( "Opens the information menu." ), "info" },
162 [KST_CONSOLE] = { N_( "Lua Console" ), N_( "Opens the Lua console." ),
163 "console" },
164
165 /* Escorts */
166 [KST_ESCORT_NEXT] = { N_( "Target Next Escort" ),
167 N_( "Cycles through your escorts." ), "e_targetNext" },
168 [KST_ESCORT_PREV] = { N_( "Target Previous Escort" ),
169 N_( "Cycles backwards through your escorts." ),
170 "e_targetPrev" },
171 [KST_ESCORT_ATTACK] = { N_( "Escort Attack Command" ),
172 N_( "Orders escorts to attack your target." ),
173 "e_attack" },
174 [KST_ESCORT_HALT] = { N_( "Escort Hold Command" ),
175 N_( "Orders escorts to hold their formation." ),
176 "e_hold" },
177 [KST_ESCORT_RETURN] =
178 { N_( "Escort Return Command" ),
179 N_( "Orders escorts to return to your ship hangars." ), "e_return" },
180 [KST_ESCORT_CLEAR] = { N_( "Escort Clear Commands" ),
181 N_( "Clears your escorts of commands." ), "e_clear" },
182
183 /* Communication */
184 [KST_HAIL] =
185 { N_( "Hail Target" ),
186 N_( "Attempts to initialize communication with the targeted ship." ),
187 "hail" },
188 [KST_AUTOHAIL] = { N_( "Autohail" ),
189 N_( "Automatically initialize communication with a ship "
190 "that is hailing you." ),
191 "autohail" },
192 [KST_SCAN] = { N_( "Scan Target" ), N_( "Attempts to scan the target." ),
193 "scan" },
194 [KST_LOG_UP] = { N_( "Log Scroll Up" ), N_( "Scrolls the log upwards." ),
195 "log_up" },
196 [KST_LOG_DOWN] = { N_( "Log Scroll Down" ),
197 N_( "Scrolls the log downwards." ), "log_down" },
198
199 /* Display options */
200 [KST_ZOOM_IN] = { N_( "Radar Zoom In" ), N_( "Zooms in on the radar." ),
201 "mapzoomin" },
202 [KST_ZOOM_OUT] = { N_( "Radar Zoom Out" ), N_( "Zooms out on the radar." ),
203 "mapzoomout" },
204
205 [KST_FULLSCREEN] = { N_( "Toggle Fullscreen" ),
206 N_( "Toggles between windowed and fullscreen mode." ),
207 "togglefullscreen" },
208
209 [KST_SCREENSHOT] = { N_( "Screenshot" ), N_( "Takes a screenshot." ),
210 "screenshot" },
211 [KST_PASTE] = { N_( "Paste" ),
212 N_( "Paste from the operating system's clipboard." ),
213 "paste" },
214};
215
216static Keybind input_keybinds[KST_END];
217static Keybind *input_paste;
218
219/*
220 * accel hacks
221 */
222static KeySemanticType doubletap_key = KST_END;
223static unsigned int doubletap_t = 0;
224
225/*
226 * Key repeat hack.
227 */
228static int repeat_key = -1;
229static unsigned int repeat_keyTimer = 0;
230static unsigned int repeat_keyCounter = 0;
231
232/*
233 * Mouse.
234 */
235static double input_mouseTimer = 1.;
236static int input_mouseCounter = 1;
237static unsigned int input_mouseClickLast = 0;
238static const void *input_lastClicked =
239 NULL;
240
241/*
242 * from player.c
243 */
244extern double player_left;
245extern double player_right;
246
247/*
248 * Prototypes.
249 */
250static void input_key( KeySemanticType keynum, double value, double kabs,
251 int repeat );
252static void input_clickZoom( double modifier );
253static void input_clickevent( SDL_Event *event );
254static void input_mouseMove( SDL_Event *event );
255static void input_joyaxis( const SDL_Keycode axis, const int value );
256static void input_joyevent( const int event, const SDL_Keycode button );
257static void input_keyevent( const int event, const SDL_Keycode key,
258 const SDL_Keymod mod, const int repeat );
259static int input_doubleClickTest( unsigned int *time, const void **last,
260 const void *clicked );
261
267void input_setDefault( int wasd )
268{
269 /* Movement */
270 if (wasd) {
271 input_setKeybind( KST_ACCEL, KEYBIND_KEYBOARD, SDLK_w, NMOD_ANY );
272 input_setKeybind( KST_LEFT, KEYBIND_KEYBOARD, SDLK_a, NMOD_ANY );
273 input_setKeybind( KST_RIGHT, KEYBIND_KEYBOARD, SDLK_d, NMOD_ANY );
274 input_setKeybind( KST_REVERSE, KEYBIND_KEYBOARD, SDLK_s, NMOD_ANY );
275 } else {
276 input_setKeybind( KST_ACCEL, KEYBIND_KEYBOARD, SDLK_UP, NMOD_ANY );
277 input_setKeybind( KST_LEFT, KEYBIND_KEYBOARD, SDLK_LEFT, NMOD_ANY );
278 input_setKeybind( KST_RIGHT, KEYBIND_KEYBOARD, SDLK_RIGHT, NMOD_ANY );
279 input_setKeybind( KST_REVERSE, KEYBIND_KEYBOARD, SDLK_DOWN, NMOD_ANY );
280 }
281 input_setKeybind( KST_STEALTH, KEYBIND_KEYBOARD, SDLK_f, NMOD_NONE );
282
283 /* Targeting */
284 if (wasd) {
285 input_setKeybind( KST_TARGET_NEXT, KEYBIND_KEYBOARD, SDLK_e, NMOD_CTRL );
286 input_setKeybind( KST_TARGET_PREV, KEYBIND_KEYBOARD, SDLK_q, NMOD_CTRL );
287 input_setKeybind( KST_TARGET_CLOSE, KEYBIND_KEYBOARD, SDLK_t, NMOD_ANY );
288 input_setKeybind( KST_HTARGET_NEXT, KEYBIND_NULL, SDLK_UNKNOWN,
289 NMOD_NONE );
290 input_setKeybind( KST_HTARGET_PREV, KEYBIND_NULL, SDLK_UNKNOWN,
291 NMOD_NONE );
292 input_setKeybind( KST_HTARGET_CLOSE, KEYBIND_KEYBOARD, SDLK_r, NMOD_ANY );
293 input_setKeybind( KST_TARGET_CLEAR, KEYBIND_KEYBOARD, SDLK_c, NMOD_ANY );
294 } else {
295 input_setKeybind( KST_TARGET_NEXT, KEYBIND_KEYBOARD, SDLK_t, NMOD_NONE );
296 input_setKeybind( KST_TARGET_PREV, KEYBIND_KEYBOARD, SDLK_t, NMOD_CTRL );
297 input_setKeybind( KST_TARGET_CLOSE, KEYBIND_KEYBOARD, SDLK_n, NMOD_NONE );
298 input_setKeybind( KST_HTARGET_NEXT, KEYBIND_KEYBOARD, SDLK_r, NMOD_CTRL );
299 input_setKeybind( KST_HTARGET_PREV, KEYBIND_NULL, SDLK_UNKNOWN,
300 NMOD_NONE );
301 input_setKeybind( KST_HTARGET_CLOSE, KEYBIND_KEYBOARD, SDLK_r,
302 NMOD_NONE );
303 input_setKeybind( KST_TARGET_CLEAR, KEYBIND_KEYBOARD, SDLK_BACKSPACE,
304 NMOD_ANY );
305 }
306
307 /* Combat */
308 input_setKeybind( KST_FIRE_PRIMARY, KEYBIND_KEYBOARD, SDLK_SPACE, NMOD_ANY );
309
310 if (wasd)
311 input_setKeybind( KST_FACE, KEYBIND_KEYBOARD, SDLK_q, NMOD_NONE );
312 else
313 input_setKeybind( KST_FACE, KEYBIND_KEYBOARD, SDLK_a, NMOD_ANY );
314
315 /* Secondary Weapons */
316 input_setKeybind( KST_FIRE_SECONDARY, KEYBIND_KEYBOARD, SDLK_LSHIFT,
317 NMOD_ANY );
318 input_setKeybind( KST_WEAPSET1, KEYBIND_KEYBOARD, SDLK_1, NMOD_ANY );
319 input_setKeybind( KST_WEAPSET2, KEYBIND_KEYBOARD, SDLK_2, NMOD_ANY );
320 input_setKeybind( KST_WEAPSET3, KEYBIND_KEYBOARD, SDLK_3, NMOD_ANY );
321 input_setKeybind( KST_WEAPSET4, KEYBIND_KEYBOARD, SDLK_4, NMOD_ANY );
322 input_setKeybind( KST_WEAPSET5, KEYBIND_KEYBOARD, SDLK_5, NMOD_ANY );
323 input_setKeybind( KST_WEAPSET6, KEYBIND_KEYBOARD, SDLK_6, NMOD_ANY );
324 input_setKeybind( KST_WEAPSET7, KEYBIND_KEYBOARD, SDLK_7, NMOD_ANY );
325 input_setKeybind( KST_WEAPSET8, KEYBIND_KEYBOARD, SDLK_8, NMOD_ANY );
326 input_setKeybind( KST_WEAPSET9, KEYBIND_KEYBOARD, SDLK_9, NMOD_ANY );
327 input_setKeybind( KST_WEAPSET0, KEYBIND_KEYBOARD, SDLK_0, NMOD_ANY );
328 /* Escorts */
329 input_setKeybind( KST_ESCORT_NEXT, KEYBIND_NULL, SDLK_UNKNOWN, NMOD_NONE );
330 input_setKeybind( KST_ESCORT_PREV, KEYBIND_NULL, SDLK_UNKNOWN, NMOD_NONE );
331 input_setKeybind( KST_ESCORT_ATTACK, KEYBIND_KEYBOARD, SDLK_END, NMOD_ANY );
332 input_setKeybind( KST_ESCORT_HALT, KEYBIND_KEYBOARD, SDLK_INSERT, NMOD_ANY );
333 input_setKeybind( KST_ESCORT_RETURN, KEYBIND_KEYBOARD, SDLK_DELETE,
334 NMOD_ANY );
335 input_setKeybind( KST_ESCORT_CLEAR, KEYBIND_KEYBOARD, SDLK_HOME, NMOD_ANY );
336 /* Space Navigation */
337 input_setKeybind( KST_AUTONAV, KEYBIND_KEYBOARD, SDLK_j, NMOD_CTRL );
338 input_setKeybind( KST_TARGET_SPOB, KEYBIND_KEYBOARD, SDLK_p, NMOD_NONE );
339 input_setKeybind( KST_APPROACH, KEYBIND_KEYBOARD, SDLK_l, NMOD_NONE );
340 input_setKeybind( KST_TARGET_JUMP, KEYBIND_KEYBOARD, SDLK_h, NMOD_NONE );
341 input_setKeybind( KST_STAR_MAP, KEYBIND_KEYBOARD, SDLK_m, NMOD_NONE );
342 input_setKeybind( KST_JUMP, KEYBIND_KEYBOARD, SDLK_j, NMOD_NONE );
343 input_setKeybind( KST_OVERLAY_MAP, KEYBIND_KEYBOARD, SDLK_TAB, NMOD_ANY );
344 input_setKeybind( KST_MOUSE_FLYING, KEYBIND_KEYBOARD, SDLK_x, NMOD_CTRL );
345 input_setKeybind( KST_COOLDOWN, KEYBIND_KEYBOARD, SDLK_s, NMOD_CTRL );
346 /* Communication */
347 input_setKeybind( KST_HAIL, KEYBIND_KEYBOARD, SDLK_y, NMOD_NONE );
348 input_setKeybind( KST_AUTOHAIL, KEYBIND_KEYBOARD, SDLK_y, NMOD_CTRL );
349 input_setKeybind( KST_SCAN, KEYBIND_KEYBOARD, SDLK_u, NMOD_ANY ),
350 input_setKeybind( KST_LOG_UP, KEYBIND_KEYBOARD, SDLK_PAGEUP, NMOD_ANY );
351 input_setKeybind( KST_LOG_DOWN, KEYBIND_KEYBOARD, SDLK_PAGEDOWN, NMOD_ANY );
352 /* Misc. */
353 input_setKeybind( KST_ZOOM_IN, KEYBIND_KEYBOARD, SDLK_KP_PLUS, NMOD_ANY );
354 input_setKeybind( KST_ZOOM_OUT, KEYBIND_KEYBOARD, SDLK_KP_MINUS, NMOD_ANY );
355 input_setKeybind( KST_SCREENSHOT, KEYBIND_KEYBOARD, SDLK_KP_MULTIPLY,
356 NMOD_ANY );
357 input_setKeybind( KST_SCREENSHOT, KEYBIND_KEYBOARD, SDLK_F11, NMOD_ANY );
358 input_setKeybind( KST_PAUSE, KEYBIND_KEYBOARD, SDLK_PAUSE, NMOD_ANY );
359
360 input_setKeybind( KST_GAME_SPEED, KEYBIND_KEYBOARD, SDLK_BACKQUOTE,
361 NMOD_ANY );
362 input_setKeybind( KST_MENU_SMALL, KEYBIND_KEYBOARD, SDLK_ESCAPE, NMOD_ANY );
363 input_setKeybind( KST_MENU_INFO, KEYBIND_KEYBOARD, SDLK_i, NMOD_NONE );
364 input_setKeybind( KST_CONSOLE, KEYBIND_KEYBOARD, SDLK_F2, NMOD_ANY );
365 input_setKeybind( KST_PASTE, KEYBIND_KEYBOARD, SDLK_v, NMOD_CTRL );
366}
367
371void input_init( void )
372{
373 /* Window. */
374 SDL_EventState( SDL_SYSWMEVENT, SDL_DISABLE );
375
376 /* Keyboard. */
377 SDL_EventState( SDL_KEYDOWN, SDL_ENABLE );
378 SDL_EventState( SDL_KEYUP, SDL_ENABLE );
379
380 /* Mice. */
381 SDL_EventState( SDL_MOUSEMOTION, SDL_ENABLE );
382 SDL_EventState( SDL_MOUSEBUTTONDOWN, SDL_ENABLE );
383 SDL_EventState( SDL_MOUSEBUTTONUP, SDL_ENABLE );
384
385 /* Joystick, enabled in joystick.c if needed. */
386 SDL_EventState( SDL_JOYAXISMOTION, SDL_DISABLE );
387 SDL_EventState( SDL_JOYHATMOTION, SDL_DISABLE );
388 SDL_EventState( SDL_JOYBUTTONDOWN, SDL_DISABLE );
389 SDL_EventState( SDL_JOYBUTTONUP, SDL_DISABLE );
390
391 /* Quit. */
392 SDL_EventState( SDL_QUIT, SDL_ENABLE );
393
394 /* Window. */
395 SDL_EventState( SDL_WINDOWEVENT, SDL_ENABLE );
396
397 /* Keyboard. */
398 SDL_EventState( SDL_TEXTINPUT,
399 SDL_DISABLE ); /* Enabled on a per-widget basis. */
400
401 /* Mouse. */
402 SDL_EventState( SDL_MOUSEWHEEL, SDL_ENABLE );
403
404 /* Create safe null keybinding for each. */
405 for (int i = 0; i < KST_END; i++) {
406 Keybind *k = &input_keybinds[i];
407 memset( k, 0, sizeof( Keybind ) );
408 k->type = KEYBIND_NULL;
409 k->key = SDLK_UNKNOWN;
410 k->mod = NMOD_NONE;
411
412 if (i == KST_PASTE)
413 input_paste = k;
414 }
415}
416
420void input_exit( void )
421{
422}
423
427void input_enableAll( void )
428{
429 for (int i = 0; i < KST_END; i++)
430 input_keybinds[i].disabled = 0;
431}
432
437{
438 for (int i = 0; i < KST_END; i++)
439 input_keybinds[i].disabled = 1;
440}
441
445void input_toggleEnable( KeySemanticType key, int enable )
446{
447 input_keybinds[key].disabled = !enable;
448}
449
453void input_mouseShow( void )
454{
455 SDL_ShowCursor( SDL_ENABLE );
457}
458
462void input_mouseHide( void )
463{
465 if (input_mouseCounter <= 0) {
466 input_mouseTimer = MIN( input_mouseTimer, conf.mouse_hide );
468 }
469}
470
475{
476 return SDL_ShowCursor( SDL_QUERY ) == SDL_ENABLE;
477}
478
485SDL_Keycode input_keyConv( const char *name )
486{
487 SDL_Keycode k = SDL_GetKeyFromName( name );
488 if (k == SDLK_UNKNOWN)
489 WARN( _( "Keyname '%s' doesn't match any key." ), name );
490
491 return k;
492}
493
502void input_setKeybind( KeySemanticType keybind, KeybindType type,
503 SDL_Keycode key, SDL_Keymod mod )
504{
505 if (( keybind >= 0 ) && ( keybind < KST_END )) {
506 Keybind *k = &input_keybinds[keybind];
507 k->type = type;
508 k->key = key;
509 /* Non-keyboards get mod NMOD_ANY to always match. */
510 k->mod = ( type == KEYBIND_KEYBOARD ) ? mod : NMOD_ANY;
511 return;
512 }
513 WARN( _( "Unable to set keybinding '%d', that command doesn't exist" ),
514 keybind );
515}
516
525SDL_Keycode input_getKeybind( KeySemanticType keybind, KeybindType *type,
526 SDL_Keymod *mod )
527{
528 if (keybind < KST_END) {
529 if (type != NULL)
530 ( *type ) = input_keybinds[keybind].type;
531 if (mod != NULL)
532 ( *mod ) = input_keybinds[keybind].mod;
533 return input_keybinds[keybind].key;
534 }
535 WARN( _( "Unable to get keybinding '%d', that command doesn't exist" ),
536 keybind );
537 return (SDL_Keycode)-1;
538}
539
547void input_getKeybindDisplay( KeySemanticType keybind, char *buf, int len )
548{
549 /* Get the keybinding. */
550 KeybindType type = KEYBIND_NULL;
551 SDL_Keymod mod = NMOD_NONE;
552 SDL_Keycode key = input_getKeybind( keybind, &type, &mod );
553
554 /* Handle type. */
555 switch (type) {
556 case KEYBIND_NULL:
557 strncpy( buf, _( "Not bound" ), len );
558 break;
559
560 case KEYBIND_KEYBOARD: {
561 int p = 0;
562 /* Handle mod. */
563 if (( mod != NMOD_NONE ) && ( mod != NMOD_ANY ))
564 p += scnprintf( &buf[p], len - p, "%s + ", input_modToText( mod ) );
565 /* Print key. Special-case ASCII letters (use uppercase, unlike
566 * SDL_GetKeyName.). */
567 if (key < 0x100 && isalpha( key ))
568 /*p +=*/scnprintf( &buf[p], len - p, "%c", toupper( key ) );
569 else
570 /*p +=*/scnprintf( &buf[p], len - p, "%s",
571 pgettext_var( "keyname", SDL_GetKeyName( key ) ) );
572 break;
573 }
574
575 case KEYBIND_JBUTTON:
576 snprintf( buf, len, _( "joy button %d" ), key );
577 break;
578
579 case KEYBIND_JHAT_UP:
580 snprintf( buf, len, _( "joy hat %d up" ), key );
581 break;
582
583 case KEYBIND_JHAT_DOWN:
584 snprintf( buf, len, _( "joy hat %d down" ), key );
585 break;
586
587 case KEYBIND_JHAT_LEFT:
588 snprintf( buf, len, _( "joy hat %d left" ), key );
589 break;
590
591 case KEYBIND_JHAT_RIGHT:
592 snprintf( buf, len, _( "joy hat %d right" ), key );
593 break;
594
595 case KEYBIND_JAXISPOS:
596 snprintf( buf, len, _( "joy axis %d-" ), key );
597 break;
598
599 case KEYBIND_JAXISNEG:
600 snprintf( buf, len, _( "joy axis %d+" ), key );
601 break;
602 }
603}
604
611const char *input_modToText( SDL_Keymod mod )
612{
613 switch ((int)mod) {
614 case NMOD_NONE:
615 return _( "None" );
616 case NMOD_CTRL:
617 return _( "Ctrl" );
618 case NMOD_SHIFT:
619 return _( "Shift" );
620 case NMOD_ALT:
621 return _( "Alt" );
622 case NMOD_META:
623 return _( "Meta" );
624 case NMOD_ANY:
625 return _( "Any" );
626 default:
627 return _( "unknown" );
628 }
629}
630
639KeySemanticType input_keyAlreadyBound( KeybindType type, SDL_Keycode key,
640 SDL_Keymod mod )
641{
642 for (int i = 0; i < KST_END; i++) {
643 const Keybind *k = &input_keybinds[i];
644
645 /* Type must match. */
646 if (k->type != type)
647 continue;
648
649 /* Must match key. */
650 if (key != k->key)
651 continue;
652
653 /* Handle per case. */
654 switch (type) {
655 case KEYBIND_KEYBOARD:
656 if (( k->mod == NMOD_ANY ) || ( mod == NMOD_ANY ) || ( k->mod == mod ))
657 return i;
658 break;
659
660 case KEYBIND_JAXISPOS:
661 case KEYBIND_JAXISNEG:
662 case KEYBIND_JBUTTON:
663 case KEYBIND_JHAT_UP:
664 case KEYBIND_JHAT_DOWN:
665 case KEYBIND_JHAT_LEFT:
666 case KEYBIND_JHAT_RIGHT:
667 return i;
668
669 default:
670 break;
671 }
672 }
673
674 /* Not found. */
675 return -1;
676}
677
681const char *input_getKeybindBrief( KeySemanticType keybind )
682{
683 if (( keybind >= 0 ) && ( keybind < KST_END ))
684 return keybind_info[keybind][2];
685 WARN( _( "Unable to get keybinding '%d', that command doesn't exist" ),
686 keybind );
687 return NULL;
688}
689
693const char *input_getKeybindName( KeySemanticType keybind )
694{
695 if (( keybind >= 0 ) && ( keybind < KST_END ))
696 return _( keybind_info[keybind][0] );
697 WARN( _( "Unable to get keybinding '%d', that command doesn't exist" ),
698 keybind );
699 return NULL;
700}
701
708const char *input_getKeybindDescription( KeySemanticType keybind )
709{
710 if (( keybind >= 0 ) && ( keybind < KST_END ))
711 return _( keybind_info[keybind][1] );
712 WARN( _( "Unable to get keybinding '%d', that command doesn't exist" ),
713 keybind );
714 return NULL;
715}
716
723SDL_Keymod input_translateMod( SDL_Keymod mod )
724{
725 SDL_Keymod mod_filtered = 0;
726 if (mod & ( KMOD_LSHIFT | KMOD_RSHIFT ))
727 mod_filtered |= NMOD_SHIFT;
728 if (mod & ( KMOD_LCTRL | KMOD_RCTRL ))
729 mod_filtered |= NMOD_CTRL;
730 if (mod & ( KMOD_LALT | KMOD_RALT ))
731 mod_filtered |= NMOD_ALT;
732 if (mod & ( KMOD_LGUI | KMOD_RGUI ))
733 mod_filtered |= NMOD_META;
734 return mod_filtered;
735}
736
740void input_update( double dt )
741{
742 if (input_mouseTimer > 0.) {
743 input_mouseTimer -= dt;
744
745 /* Hide if necessary. */
746 if (( input_mouseTimer < 0. ) && ( input_mouseCounter <= 0 ))
747 SDL_ShowCursor( SDL_DISABLE );
748 }
749
750 /* Key repeat if applicable. */
751 if (conf.repeat_delay != 0) {
752 unsigned int t;
753
754 /* Key must be repeating. */
755 if (repeat_key == -1)
756 return;
757
758 /* Get time. */
759 t = SDL_GetTicks();
760
761 /* Should be repeating. */
762 if (repeat_keyTimer + conf.repeat_delay +
763 repeat_keyCounter * conf.repeat_freq >
764 t)
765 return;
766
767 /* Key repeat. */
769 input_key( repeat_key, KEY_PRESS, 0., 1 );
770 }
771}
772
773#define INGAME() \
774 ( !toolkit_isOpen() && \
775 ( ( value == KEY_RELEASE ) || !player_isFlag( PLAYER_CINEMATICS ) ) && \
776 ( player.p != NULL ) && \
777 !pilot_isFlag( player.p, \
778 PILOT_DEAD ) )
779#define HYP() \
780 ( ( player.p == NULL ) || pilot_isFlag( player.p, PILOT_HYP_PREP ) || \
781 pilot_isFlag( player.p, PILOT_HYP_BEGIN ) || \
782 pilot_isFlag( \
783 player.p, \
784 PILOT_HYPERSPACE ) )
785#define NOHYP() \
786 ( ( player.p != NULL ) && !pilot_isFlag( player.p, PILOT_HYP_PREP ) && \
787 !pilot_isFlag( player.p, PILOT_HYP_BEGIN ) && \
788 !pilot_isFlag( \
789 player.p, \
790 PILOT_HYPERSPACE ) )
791#define DEAD() \
792 ( ( player.p == NULL ) || \
793 pilot_isFlag( player.p, PILOT_DEAD ) )
794#define NODEAD() \
795 ( ( player.p != NULL ) && \
796 !pilot_isFlag( player.p, PILOT_DEAD ) )
797#define LAND() \
798 ( ( player.p == NULL ) || landed || \
799 pilot_isFlag( player.p, PILOT_LANDING ) )
800#define NOLAND() \
801 ( ( player.p != NULL ) && \
802 ( !landed && \
803 !pilot_isFlag( player.p, \
804 PILOT_LANDING ) ) )
805#define MAP() ( map_isOpen() )
815static void input_key( KeySemanticType keynum, double value, double kabs,
816 int repeat )
817{
818 HookParam hparam[3];
819 int isdoubletap = 0;
820
821 /* Repetition stuff. */
822 if (conf.repeat_delay != 0) {
823 if (( value == KEY_PRESS ) && !repeat) {
824 repeat_key = keynum;
825 repeat_keyTimer = SDL_GetTicks();
827 } else if (value == KEY_RELEASE) {
828 repeat_key = -1;
829 repeat_keyTimer = 0;
831 }
832 }
833
834 /* Detect if double tap. */
835 if (value == KEY_PRESS) {
836 unsigned int t = SDL_GetTicks();
837 if (( keynum == doubletap_key ) &&
838 ( t - doubletap_t <= conf.doubletap_sens ))
839 isdoubletap = 1;
840 else {
841 doubletap_key = keynum;
842 doubletap_t = t;
843 }
844 }
845
846 /*
847 * movement
848 */
849 /* accelerating */
850 switch (keynum) {
851 case KST_ACCEL:
852 if (repeat)
853 break;
854
855 if (kabs >= 0.) {
856 player_restoreControl( PINPUT_MOVEMENT, NULL );
857 player_accel( kabs );
858 } else { /* prevent it from getting stuck */
859 if (isdoubletap) {
860 if (NODEAD()) {
861 pilot_outfitLOnkeydoubletap( player.p, OUTFIT_KEY_ACCEL );
863 /* Allow keeping it on outside of weapon sets. */
864 if (player.p->afterburner != NULL) {
865 player.p->afterburner->flags |= PILOTOUTFIT_ISON_TOGGLE;
867 }
868 }
869 } else if (value == KEY_RELEASE) {
870 if (NODEAD()) {
871 pilot_outfitLOnkeyrelease( player.p, OUTFIT_KEY_ACCEL );
872 /* Make sure to release the weapon set lock. */
873 if (player.p->afterburner != NULL) {
874 player.p->afterburner->flags &= ~PILOTOUTFIT_ISON_TOGGLE;
876 }
877 }
878 }
879
880 if (value == KEY_PRESS) {
881 player_restoreControl( PINPUT_MOVEMENT, NULL );
882 player_setFlag( PLAYER_ACCEL );
883 player_accel( 1. );
884 } else if (value == KEY_RELEASE) {
885 player_rmFlag( PLAYER_ACCEL );
886 if (!player_isFlag( PLAYER_REVERSE ))
888 }
889 }
890 break;
891 /* turning left */
892 case KST_LEFT:
893 if (repeat)
894 break;
895 if (kabs >= 0.) {
896 player_restoreControl( PINPUT_MOVEMENT, NULL );
897 player_setFlag( PLAYER_TURN_LEFT );
898 player_left = kabs;
899 } else {
900 if (isdoubletap) {
901 if (NODEAD())
902 pilot_outfitLOnkeydoubletap( player.p, OUTFIT_KEY_LEFT );
903 } else if (value == KEY_RELEASE) {
904 player_rmFlag( PLAYER_TURN_LEFT );
905 player_left = 0.;
906 }
907 if (value == KEY_PRESS) {
908 player_restoreControl( PINPUT_MOVEMENT, NULL );
909 player_setFlag( PLAYER_TURN_LEFT );
910 player_left = 1.;
911 }
912 }
913 break;
914 /* turning right */
915 case KST_RIGHT:
916 if (repeat)
917 break;
918 if (kabs >= 0.) {
919 player_restoreControl( PINPUT_MOVEMENT, NULL );
920 player_setFlag( PLAYER_TURN_RIGHT );
921 player_right = kabs;
922 } else {
923 if (isdoubletap) {
924 if (NODEAD())
925 pilot_outfitLOnkeydoubletap( player.p, OUTFIT_KEY_RIGHT );
926 } else if (value == KEY_RELEASE) {
927 player_rmFlag( PLAYER_TURN_RIGHT );
928 player_right = 0.;
929 }
930 if (value == KEY_PRESS) {
931 player_restoreControl( PINPUT_MOVEMENT, NULL );
932 player_setFlag( PLAYER_TURN_RIGHT );
933 player_right = 1.;
934 }
935 }
936 break;
937 /* turn around to face vel */
938 case KST_REVERSE:
939 if (repeat)
940 break;
941 if (value == KEY_PRESS) {
942 player_restoreControl( PINPUT_MOVEMENT, NULL );
943 player_setFlag( PLAYER_REVERSE );
944 /* Double tap reverse = cooldown! */
945 if (isdoubletap)
947 } else if (( value == KEY_RELEASE ) && player_isFlag( PLAYER_REVERSE )) {
948 player_rmFlag( PLAYER_REVERSE );
949
950 if (!player_isFlag( PLAYER_ACCEL ))
952 }
953 break;
954 /* try to enter stealth mode. */
955 case KST_STEALTH:
956 if (repeat || HYP() || !INGAME())
957 break;
958 if (value == KEY_PRESS)
960 break;
961
962 /* face the target */
963 case KST_FACE:
964 if (repeat)
965 break;
966 if (value == KEY_PRESS) {
967 player_restoreControl( PINPUT_MOVEMENT, NULL );
968 player_setFlag( PLAYER_FACE );
969 } else if (( value == KEY_RELEASE ) && player_isFlag( PLAYER_FACE ))
970 player_rmFlag( PLAYER_FACE );
971 break;
972
973 /*
974 * Combat
975 */
976 /* targeting */
977 case KST_TARGET_NEXT:
978 if (!INGAME() && !MAP())
979 break;
980 if (value == KEY_PRESS) {
981 if (MAP())
982 map_cycleMissions( 1 );
983 else
985 }
986 break;
987 case KST_TARGET_PREV:
988 if (!INGAME() && !MAP())
989 break;
990 if (value == KEY_PRESS) {
991 if (MAP())
992 map_cycleMissions( -1 );
993 else
995 }
996 break;
997 case KST_TARGET_CLOSE:
998 if (!INGAME() && !MAP())
999 break;
1000 if (value == KEY_PRESS) {
1001 if (MAP())
1002 map_cycleMissions( 1 );
1003 else
1005 }
1006 break;
1007 case KST_HTARGET_NEXT:
1008 if (!INGAME())
1009 break;
1010 if (value == KEY_PRESS)
1011 player_targetNext( 1 );
1012 break;
1013 case KST_HTARGET_PREV:
1014 if (!INGAME())
1015 break;
1016 if (value == KEY_PRESS)
1017 player_targetPrev( 1 );
1018 break;
1019 case KST_HTARGET_CLOSE:
1020 if (!INGAME())
1021 break;
1022 if (value == KEY_PRESS)
1024 break;
1025 case KST_TARGET_CLEAR:
1026 if (!INGAME())
1027 break;
1028 if (value == KEY_PRESS)
1030 break;
1031
1032 /*
1033 * Escorts.
1034 */
1035 case KST_ESCORT_NEXT:
1036 if (!( INGAME() && !repeat ))
1037 break;
1038 if (value == KEY_PRESS)
1040 break;
1041 case KST_ESCORT_PREV:
1042 if (!( INGAME() && !repeat ))
1043 break;
1044 if (value == KEY_PRESS)
1046 break;
1047 case KST_ESCORT_ATTACK:
1048 if (!( INGAME() && !repeat ))
1049 break;
1050 if (value == KEY_PRESS)
1052 break;
1053 case KST_ESCORT_HALT:
1054 if (!( INGAME() && !repeat ))
1055 break;
1056 if (value == KEY_PRESS)
1057 escorts_hold( player.p );
1058 break;
1059 case KST_ESCORT_RETURN:
1060 if (!( INGAME() && !repeat ))
1061 break;
1062 if (value == KEY_PRESS)
1064 break;
1065 case KST_ESCORT_CLEAR:
1066 if (!( INGAME() && !repeat ))
1067 break;
1068 if (value == KEY_PRESS)
1069 escorts_clear( player.p );
1070 break;
1071
1072 /*
1073 * secondary weapons
1074 */
1075 /* shooting primary weapon */
1076 case KST_FIRE_PRIMARY:
1077 if (DEAD())
1078 break;
1079 player_weapSetPress( 0, value, repeat );
1080 break;
1081 /* shooting secondary weapon */
1082 case KST_FIRE_SECONDARY:
1083 if (DEAD())
1084 break;
1085 player_weapSetPress( 1, value, repeat );
1086 break;
1087 /* Weapon sets. */
1088 case KST_WEAPSET1:
1089 if (DEAD())
1090 break;
1091 player_weapSetPress( 2, value, repeat );
1092 break;
1093 case KST_WEAPSET2:
1094 if (DEAD())
1095 break;
1096 player_weapSetPress( 3, value, repeat );
1097 break;
1098 case KST_WEAPSET3:
1099 if (DEAD())
1100 break;
1101 player_weapSetPress( 4, value, repeat );
1102 break;
1103 case KST_WEAPSET4:
1104 if (DEAD())
1105 break;
1106 player_weapSetPress( 5, value, repeat );
1107 break;
1108 case KST_WEAPSET5:
1109 if (DEAD())
1110 break;
1111 player_weapSetPress( 6, value, repeat );
1112 break;
1113 case KST_WEAPSET6:
1114 if (DEAD())
1115 break;
1116 player_weapSetPress( 7, value, repeat );
1117 break;
1118 case KST_WEAPSET7:
1119 if (DEAD())
1120 break;
1121 player_weapSetPress( 8, value, repeat );
1122 break;
1123 case KST_WEAPSET8:
1124 if (DEAD())
1125 break;
1126 player_weapSetPress( 9, value, repeat );
1127 break;
1128 case KST_WEAPSET9:
1129 if (DEAD())
1130 break;
1131 player_weapSetPress( 10, value, repeat );
1132 break;
1133 case KST_WEAPSET0:
1134 if (DEAD())
1135 break;
1136 player_weapSetPress( 11, value, repeat );
1137 break;
1138
1139 /*
1140 * Space
1141 */
1142 case KST_AUTONAV:
1143 if (HYP() || DEAD())
1144 break;
1145 if (value == KEY_PRESS) {
1146 if (MAP()) {
1147 unsigned int wid = window_get( MAP_WDWNAME );
1148 player_autonavStartWindow( wid, NULL );
1149 } else if INGAME ()
1151 }
1152 break;
1153 /* target spob (cycles like target) */
1154 case KST_TARGET_SPOB:
1155 if (HYP() || LAND() || !INGAME())
1156 break;
1157 if (value == KEY_PRESS)
1159 break;
1160 /* target nearest spob or attempt to land */
1161 case KST_APPROACH:
1162 if (repeat || LAND() || HYP() || !INGAME())
1163 break;
1164 if (value == KEY_PRESS) {
1165 player_restoreControl( 0, NULL );
1167 }
1168 break;
1169 case KST_TARGET_JUMP:
1170 if (DEAD() || HYP() || LAND())
1171 break;
1172 if (value == KEY_PRESS)
1174 break;
1175 case KST_STAR_MAP:
1176 if (repeat || HYP() || DEAD())
1177 break;
1178 if (value == KEY_PRESS)
1179 map_open();
1180 break;
1181 case KST_JUMP:
1182 if (!( INGAME() && !repeat ))
1183 break;
1184 if (value == KEY_PRESS) {
1185 player_restoreControl( 0, NULL );
1186 player_jump();
1187 }
1188 break;
1189 case KST_OVERLAY_MAP:
1190 if (( repeat || !INGAME() ) && !MAP())
1191 break;
1192 if (MAP())
1193 map_toggleNotes();
1194 else
1195 ovr_key( value );
1196 break;
1197 case KST_MOUSE_FLYING:
1198 if (DEAD() || repeat)
1199 break;
1200 if (value == KEY_PRESS)
1202 break;
1203 case KST_COOLDOWN:
1204 if (repeat || DEAD() || LAND() || HYP())
1205 break;
1206 if (value == KEY_PRESS) {
1207 player_restoreControl( PINPUT_BRAKING, NULL );
1209 }
1210 break;
1211
1212 /*
1213 * Communication.
1214 */
1215 case KST_HAIL:
1216 if (repeat || !INGAME() || HYP())
1217 break;
1218 if (value == KEY_PRESS)
1219 player_hail();
1220 break;
1221 case KST_AUTOHAIL:
1222 if (repeat || !INGAME() || HYP())
1223 break;
1224 if (value == KEY_PRESS)
1226 break;
1227 case KST_SCAN:
1228 if (repeat || !INGAME() || HYP())
1229 break;
1230 if (value == KEY_PRESS)
1231 player_scan();
1232 break;
1233 case KST_LOG_UP:
1234 if (!INGAME())
1235 break;
1236 if (value == KEY_PRESS)
1238 break;
1239 case KST_LOG_DOWN:
1240 if (!INGAME())
1241 break;
1242 if (value == KEY_PRESS)
1244 break;
1245
1246 /*
1247 * misc
1248 */
1249 /* zooming in */
1250 case KST_ZOOM_IN:
1251 if (!INGAME())
1252 break;
1253 if (value == KEY_PRESS)
1254 gui_setRadarRel( -1 );
1255 break;
1256 /* zooming out */
1257 case KST_ZOOM_OUT:
1258 if (!INGAME())
1259 break;
1260 if (value == KEY_PRESS)
1261 gui_setRadarRel( 1 );
1262 break;
1263 /* take a screenshot */
1264 case KST_SCREENSHOT:
1265 if (repeat)
1266 break;
1267 if (value == KEY_PRESS)
1269 break;
1270 /* toggle fullscreen */
1271 case KST_FULLSCREEN:
1272 if (repeat)
1273 break;
1274 if (value == KEY_PRESS)
1275 naev_toggleFullscreen();
1276 break;
1277 /* pause the games */
1278 case KST_PAUSE:
1279 if (repeat)
1280 break;
1281 if (value == KEY_PRESS) {
1282 if (!toolkit_isOpen()) {
1283 if (paused)
1284 unpause_game();
1285 else
1286 pause_player();
1287 }
1288 }
1289 break;
1290 /* toggle speed mode */
1291 case KST_GAME_SPEED:
1292 if (repeat)
1293 break;
1294 if (( value == KEY_PRESS ) &&
1295 ( !player_isFlag( PLAYER_CINEMATICS_2X ) )) {
1296 if (player.speed < 4. * conf.game_speed)
1297 player.speed *= 2.;
1298 else
1299 player.speed = conf.game_speed;
1301 }
1302 break;
1303 /* opens a small menu */
1304 case KST_MENU_SMALL:
1305 if (DEAD() || repeat)
1306 break;
1307 if (value == KEY_PRESS)
1308 menu_small( 1, 1, 1, 1 );
1309 break;
1310
1311 /* shows pilot information */
1312 case KST_MENU_INFO:
1313 if (repeat || DEAD() || HYP())
1314 break;
1315 if (value == KEY_PRESS)
1316 menu_info( INFO_DEFAULT );
1317 break;
1318
1319 /* Opens the Lua console. */
1320 case KST_CONSOLE:
1321 if (DEAD() || repeat)
1322 break;
1323 if (value == KEY_PRESS)
1324 cli_open();
1325 break;
1326
1327 /* Key not used. */
1328 default:
1329 return;
1330 }
1331
1332 /* Run the hook. */
1333 hparam[0].type = HOOK_PARAM_STRING;
1334 hparam[0].u.str = input_getKeybindBrief( keynum );
1335 hparam[1].type = HOOK_PARAM_BOOL;
1336 hparam[1].u.b = ( value > 0. );
1337 hparam[2].type = HOOK_PARAM_SENTINEL;
1338 hooks_runParam( "input", hparam );
1339}
1340
1341/*
1342 * joystick
1343 */
1349static void input_joyaxis( const SDL_Keycode axis, const int value )
1350{
1351 for (int i = 0; i < KST_END; i++) {
1352 const Keybind *k = &input_keybinds[i];
1353 if (k->key != axis)
1354 continue;
1355 /* Positive axis keybinding. */
1356 if (( k->type == KEYBIND_JAXISPOS ) && ( value >= 0 )) {
1357 int press = ( value > 0 ) ? KEY_PRESS : KEY_RELEASE;
1358 if (( press == KEY_PRESS ) && k->disabled)
1359 continue;
1360 input_key( i, press, FABS( ( (double)value ) / 32767. ), 0 );
1361 }
1362
1363 /* Negative axis keybinding. */
1364 if (( k->type == KEYBIND_JAXISNEG ) && ( value <= 0 )) {
1365 int press = ( value < 0 ) ? KEY_PRESS : KEY_RELEASE;
1366 if (( press == KEY_PRESS ) && k->disabled)
1367 continue;
1368 input_key( i, press, FABS( ( (double)value ) / 32767. ), 0 );
1369 }
1370 }
1371}
1372
1377static void input_joyevent( const int event, const SDL_Keycode button )
1378{
1379 for (int i = 0; i < KST_END; i++) {
1380 const Keybind *k = &input_keybinds[i];
1381 if (( event == KEY_PRESS ) && k->disabled)
1382 continue;
1383 if (( k->type == KEYBIND_JBUTTON ) && ( k->key == button ))
1384 input_key( i, event, -1., 0 );
1385 }
1386}
1387
1393static void input_joyhatevent( const Uint8 value, const Uint8 hat )
1394{
1395 for (int i = 0; i < KST_END; i++) {
1396 const Keybind *k = &input_keybinds[i];
1397 if (k->key != hat)
1398 continue;
1399
1400 if (k->type == KEYBIND_JHAT_UP) {
1401 int event = ( value & SDL_HAT_UP ) ? KEY_PRESS : KEY_RELEASE;
1402 if (!( ( event == KEY_PRESS ) && k->disabled ))
1403 input_key( i, event, -1., 0 );
1404 } else if (k->type == KEYBIND_JHAT_DOWN) {
1405 int event = ( value & SDL_HAT_DOWN ) ? KEY_PRESS : KEY_RELEASE;
1406 if (!( ( event == KEY_PRESS ) && k->disabled ))
1407 input_key( i, event, -1., 0 );
1408 } else if (k->type == KEYBIND_JHAT_LEFT) {
1409 int event = ( value & SDL_HAT_LEFT ) ? KEY_PRESS : KEY_RELEASE;
1410 if (!( ( event == KEY_PRESS ) && k->disabled ))
1411 input_key( i, event, -1., 0 );
1412 } else if (k->type == KEYBIND_JHAT_RIGHT) {
1413 int event = ( value & SDL_HAT_RIGHT ) ? KEY_PRESS : KEY_RELEASE;
1414 if (!( ( event == KEY_PRESS ) && k->disabled ))
1415 input_key( i, event, -1., 0 );
1416 }
1417 }
1418}
1419
1420/*
1421 * keyboard
1422 */
1431static void input_keyevent( const int event, SDL_Keycode key,
1432 const SDL_Keymod mod, const int repeat )
1433{
1434 /* Filter to "Naev" modifiers. */
1435 SDL_Keymod mod_filtered = input_translateMod( mod );
1436 for (int i = 0; i < KST_END; i++) {
1437 const Keybind *k = &input_keybinds[i];
1438 if (( event == KEY_PRESS ) && k->disabled)
1439 continue;
1440 if (k->type != KEYBIND_KEYBOARD)
1441 continue;
1442 if (k->key != key)
1443 continue;
1444 /* Release always gets through. */
1445 if (( k->mod == mod_filtered ) || ( k->mod == NMOD_ANY ) ||
1446 ( event == KEY_RELEASE ))
1447 input_key( i, event, -1., repeat );
1448 /* No break since multiple keys can be bound to one symbol. */
1449 }
1450}
1451
1455static void input_clickZoom( double modifier )
1456{
1457 if (player.p != NULL)
1458 cam_setZoomTarget( cam_getZoomTarget() * modifier, conf.zoom_speed );
1459}
1460
1464static void input_mouseMove( SDL_Event *event )
1465{
1466 int mx, my;
1467 gl_windowToScreenPos( &mx, &my, event->button.x, event->button.y );
1468 player.mousex = mx;
1469 player.mousey = my;
1470}
1471
1475static void input_clickevent( SDL_Event *event )
1476{
1477 int mx, my;
1478 int res;
1479 double x, y, zoom;
1480 HookParam hparam[3];
1481
1482 /* Generate hook. */
1483 hparam[0].type = HOOK_PARAM_NUMBER;
1484 hparam[0].u.num = event->button.button;
1485 hparam[1].type = HOOK_PARAM_BOOL;
1486 hparam[1].u.b = ( event->type == SDL_MOUSEBUTTONDOWN );
1487 hparam[2].type = HOOK_PARAM_SENTINEL;
1488 hooks_runParam( "mouse", hparam );
1489
1490 /* Disable in cinematics. */
1491 if (player_isFlag( PLAYER_CINEMATICS ))
1492 return;
1493
1494 /* Player must not be NULL. */
1495 if (( player.p == NULL ) || player_isFlag( PLAYER_DESTROYED ))
1496 return;
1497
1498 /* Player must not be dead. */
1499 if (pilot_isFlag( player.p, PILOT_DEAD ))
1500 return;
1501
1502 /* Middle mouse enables mouse flying. */
1503 if (event->button.button == SDL_BUTTON_MIDDLE) {
1505 return;
1506 }
1507
1508 /* Mouse targeting only uses left and right buttons. */
1509 if (event->button.button != SDL_BUTTON_LEFT &&
1510 event->button.button != SDL_BUTTON_RIGHT)
1511 return;
1512
1513 if (gui_borderClickEvent( event ))
1514 return;
1515
1516 if (gui_radarClickEvent( event ))
1517 return;
1518
1519 /* Visual (on-screen) */
1520 gl_windowToScreenPos( &mx, &my, event->button.x, event->button.y );
1521 gl_screenToGameCoords( &x, &y, (double)mx, (double)my );
1522 zoom = res = 1. / cam_getZoom();
1523 input_clickPos( event, x, y, zoom, 10. * res, 15. * res );
1524 return;
1525}
1526
1538int input_clickPos( SDL_Event *event, double x, double y, double zoom,
1539 double minpr, double minr )
1540{
1541 unsigned int pid;
1542 double dp;
1543 int pntid, jpid, astid, fieid;
1544
1545 /* Don't allow selecting a new target with the right mouse button
1546 * (prevents pilots from getting in the way of autonav). */
1547 if (event->button.button == SDL_BUTTON_RIGHT) {
1548 pid = player.p->target;
1549 const Pilot *p = pilot_get( pid );
1550 dp = pow2( x - p->solid.pos.x ) + pow2( y - p->solid.pos.y );
1551 } else {
1552 dp = pilot_getNearestPos( player.p, &pid, x, y, 1 );
1553 }
1554
1555 system_getClosest( cur_system, &pntid, &jpid, &astid, &fieid, x, y );
1556
1557 if (pntid >= 0) { /* Spob is closer. */
1558 const Spob *spb = cur_system->spobs[pntid];
1559 double rspb = MAX( 1.5 * spb->radius * zoom, minr );
1560 double dspb = hypotf( spb->pos.x - x, spb->pos.y - y );
1561 if (dspb > rspb)
1562 pntid = -1;
1563 }
1564 if (jpid >= 0) {
1565 const JumpPoint *jmp = &cur_system->jumps[jpid];
1566 double rjmp = MAX( 1.5 * jmp->radius * zoom, minr );
1567 double djmp = hypotf( jmp->pos.x - x, jmp->pos.y - y );
1568 if (djmp > rjmp)
1569 jpid = -1;
1570 }
1571 if (astid >= 0) {
1572 const AsteroidAnchor *field = &cur_system->asteroids[fieid];
1573 const Asteroid *ast = &field->asteroids[astid];
1574 /* Recover the right gfx */
1575 double rast =
1576 MAX( MAX( ast->gfx->sw * zoom, minr ), ast->gfx->sh * zoom );
1577 double dast = hypotf( ast->sol.pos.x - x, ast->sol.pos.y - y );
1578 if (dast > rast)
1579 astid = -1;
1580 }
1581 if (pid != PLAYER_ID) {
1582 const Pilot *p = pilot_get( pid );
1583 double rp =
1584 MAX( 1.5 * PILOT_SIZE_APPROX * p->ship->size / 2 * zoom, minpr );
1585 /* Reject pilot if it's too far or a valid spob is closer. */
1586 if (dp > pow2( rp ))
1587 pid = PLAYER_ID;
1588 }
1589
1590 /* Target a pilot, spob or jump, and/or perform an appropriate action. */
1591 if (event->button.button == SDL_BUTTON_LEFT) {
1592 if (( pntid >= 0 ) && input_clickedSpob( pntid, 0, 1 ))
1593 return 1;
1594 else if (( jpid >= 0 ) && input_clickedJump( jpid, 0 ))
1595 return 1;
1596 else if (( pid != PLAYER_ID ) && input_clickedPilot( pid, 0 ))
1597 return 1;
1598 else if (( astid >= 0 ) && input_clickedAsteroid( fieid, astid ))
1599 return 1;
1600 else if (( pntid >= 0 ) && input_clickedSpob( pntid, 0, 0 ))
1601 return 1;
1602 }
1603 /* Right click only controls autonav. */
1604 else if (event->button.button == SDL_BUTTON_RIGHT) {
1605 if (( pntid >= 0 ) && input_clickedSpob( pntid, 0, 0 ))
1606 return 1;
1607 else if (( jpid >= 0 ) && input_clickedJump( jpid, 1 ))
1608 return 1;
1609 else if (( pid != PLAYER_ID ) && input_clickedPilot( pid, 1 ))
1610 return 1;
1611
1612 /* Go to position, if the position is >= 1500 px away. */
1613 if (( pow2( x - player.p->solid.pos.x ) +
1614 pow2( y - player.p->solid.pos.y ) ) >= pow2( 1500 ))
1615 player_autonavPos( x, y );
1616 return 1;
1617 }
1618
1619 return 0;
1620}
1621
1629int input_clickedJump( int jump, int autonav )
1630{
1631 const JumpPoint *jp = &cur_system->jumps[jump];
1632
1633 if (!jp_isUsable( jp ))
1634 return 0;
1635
1636 if (autonav)
1637 return 0;
1638
1639 if (player.p->nav_hyperspace != jump)
1640 map_select( jp->target, 0 );
1641
1642 static unsigned int lastclick_time = 0;
1643 static const JumpPoint *lastclick_jump = NULL;
1644 int doubleclick = input_doubleClickTest(
1645 &lastclick_time, (const void **)&lastclick_jump, jp );
1646
1647 if (jump == player.p->nav_hyperspace) {
1648 if (doubleclick) {
1649 player_targetHyperspaceSet( jump, 0 );
1650 if (space_canHyperspace( player.p ))
1651 player_jump();
1652 else
1654 return 1;
1655 } else
1656 return 0; /* Already selected, ignore. */
1657 } else
1658 player_targetHyperspaceSet( jump, 0 );
1659
1660 return 0;
1661}
1662
1671int input_clickedSpob( int spob, int autonav, int priority )
1672{
1673 Spob *pnt = cur_system->spobs[spob];
1674
1675 if (!spob_isKnown( pnt ))
1676 return 0;
1677
1678 if (autonav) {
1679 player_targetSpobSet( spob );
1680 player_autonavSpob( pnt->name, 0 );
1681 return 1;
1682 }
1683
1684 static unsigned int lastclick_time = 0;
1685 static const Spob *lastclick_spob = NULL;
1686 int doubleclick = input_doubleClickTest(
1687 &lastclick_time, (const void **)&lastclick_spob, pnt );
1688
1689 /* If not priority, ignore non-landable / uninhabited. */
1690 if (priority &&
1691 ( !spob_isFlag( pnt, SPOB_SERVICE_INHABITED ) || !pnt->can_land ))
1692 return 0;
1693
1694 if (spob == player.p->nav_spob) {
1695 if (doubleclick) {
1697 spob_updateLand( pnt );
1698 if (!spob_isFlag( pnt, SPOB_SERVICE_INHABITED ) || pnt->can_land ||
1699 ( pnt->land_override > 0 )) {
1700 int ret = player_land( 0 );
1701 if (ret == PLAYER_LAND_AGAIN) {
1702 player_autonavSpob( pnt->name, 1 );
1703 } else if (ret == PLAYER_LAND_DENIED) {
1704 player_autonavSpob( pnt->name, 0 );
1705 }
1706 } else
1708 return 1;
1709 } else
1710 return 0; /* Already selected, ignore. */
1711 } else
1712 player_targetSpobSet( spob );
1713
1714 return 1;
1715}
1716
1724int input_clickedAsteroid( int field, int asteroid )
1725{
1726 // const AsteroidAnchor *anchor = &cur_system->asteroids[field];
1727 // const Asteroid *ast = &anchor->asteroids[asteroid];
1728 player_targetAsteroidSet( field, asteroid );
1729 return 1;
1730}
1731
1739int input_clickedPilot( unsigned int pilot, int autonav )
1740{
1741 if (pilot == PLAYER_ID)
1742 return 0;
1743
1744 if (autonav) {
1745 player_targetSet( pilot );
1746 player_autonavPil( pilot );
1747 return 1;
1748 }
1749 const Pilot *p = pilot_get( pilot );
1750
1751 static unsigned int lastclick_time = 0;
1752 static const Pilot *lastclick_pilot = NULL;
1753 int doubleclick = input_doubleClickTest(
1754 &lastclick_time, (const void **)&lastclick_pilot, p );
1755
1756 if (pilot == player.p->target) {
1757 if (doubleclick) {
1758 if (pilot_isDisabled( p ) || pilot_isFlag( p, PILOT_BOARDABLE )) {
1759 if (player_tryBoard( 0 ) == PLAYER_BOARD_RETRY)
1760 player_autonavBoard( player.p->target );
1761 } else
1762 player_hail();
1763 return 1;
1764 } else
1765 return 0; /* Ignore reselection. */
1766 } else
1767 player_targetSet( pilot );
1768
1769 return 1;
1770}
1771
1776void input_clicked( const void *clicked )
1777{
1778 if (conf.mouse_doubleclick <= 0.)
1779 return;
1780
1781 input_lastClicked = clicked;
1782 input_mouseClickLast = SDL_GetTicks();
1783}
1784
1789int input_isDoubleClick( const void *clicked )
1790{
1791 unsigned int threshold;
1792
1793 if (conf.mouse_doubleclick <= 0.)
1794 return 0;
1795
1796 /* Most recent time that constitutes a valid double-click. */
1797 threshold =
1798 input_mouseClickLast + (int)floor( conf.mouse_doubleclick * 1000. );
1799
1800 if (( SDL_GetTicks() <= threshold ) && ( clicked == input_lastClicked ))
1801 return 1;
1802
1803 return 0;
1804}
1805
1806static int input_doubleClickTest( unsigned int *time, const void **last,
1807 const void *clicked )
1808{
1809 unsigned int threshold, ticks;
1810
1811 if (conf.mouse_doubleclick <= 0.)
1812 return 0;
1813
1814 /* Most recent time that constitutes a valid double-click. */
1815 threshold = *time + (int)floor( conf.mouse_doubleclick * 1000. );
1816 ticks = SDL_GetTicks();
1817
1818 if (( ticks <= threshold ) && ( *last == clicked ))
1819 return 1;
1820
1821 *last = clicked;
1822 *time = ticks;
1823 return 0;
1824}
1825
1833void input_handle( SDL_Event *event )
1834{
1835 int ismouse;
1836
1837 /* Special case mouse stuff. */
1838 if (( event->type == SDL_MOUSEMOTION ) ||
1839 ( event->type == SDL_MOUSEBUTTONDOWN ) ||
1840 ( event->type == SDL_MOUSEBUTTONUP )) {
1841 input_mouseTimer = conf.mouse_hide;
1842 SDL_ShowCursor( SDL_ENABLE );
1843 ismouse = 1;
1844 } else
1845 ismouse = 0;
1846
1847 /* Special case paste. */
1848 if (event->type == SDL_KEYDOWN && SDL_HasClipboardText() &&
1849 SDL_EventState( SDL_TEXTINPUT, SDL_QUERY ) == SDL_ENABLE) {
1850 SDL_Keymod mod = input_translateMod( event->key.keysym.mod );
1851 if (( input_paste->key == event->key.keysym.sym ) &&
1852 ( input_paste->mod & mod )) {
1853 SDL_Event evt;
1854 const char *txt = SDL_GetClipboardText();
1855 evt.type = SDL_TEXTINPUT;
1856 size_t i = 0;
1857 uint32_t ch;
1858 while (( ch = u8_nextchar( txt, &i ) )) {
1859 size_t e = u8_wc_toutf8( evt.text.text, ch );
1860 evt.text.text[e] = '\0';
1861 SDL_PushEvent( &evt );
1862 }
1863 return;
1864 }
1865 }
1866
1867 if (toolkit_isOpen()) { /* toolkit handled completely separately */
1868 if (toolkit_input( event ))
1869 return; /* we don't process it if toolkit grabs it */
1870 if (ismouse)
1871 return; /* Toolkit absorbs everything mousy. */
1872 }
1873
1874 if (ovr_isOpen())
1875 if (ovr_input( event ))
1876 return; /* Don't process if the map overlay wants it. */
1877
1878 /* GUI gets event. */
1879 if (gui_handleEvent( event ))
1880 return;
1881
1882 switch (event->type) {
1883 case SDL_JOYAXISMOTION:
1884 input_joyaxis( event->jaxis.axis, event->jaxis.value );
1885 break;
1886 case SDL_JOYBUTTONDOWN:
1887 input_joyevent( KEY_PRESS, event->jbutton.button );
1888 break;
1889 case SDL_JOYBUTTONUP:
1890 input_joyevent( KEY_RELEASE, event->jbutton.button );
1891 break;
1892 case SDL_JOYHATMOTION:
1893 input_joyhatevent( event->jhat.value, event->jhat.hat );
1894 break;
1895
1896 case SDL_KEYDOWN:
1897 if (event->key.repeat != 0)
1898 return;
1899 input_keyevent( KEY_PRESS, event->key.keysym.sym, event->key.keysym.mod,
1900 0 );
1901 break;
1902 case SDL_KEYUP:
1903 if (event->key.repeat != 0)
1904 return;
1905 input_keyevent( KEY_RELEASE, event->key.keysym.sym, event->key.keysym.mod,
1906 0 );
1907 break;
1908
1909 case SDL_MOUSEBUTTONDOWN:
1910 input_clickevent( event );
1911 break;
1912 case SDL_MOUSEWHEEL:
1913 if (event->wheel.y > 0)
1914 input_clickZoom( 1.1 );
1915 else if (event->wheel.y < 0)
1916 input_clickZoom( 0.9 );
1917 break;
1918 case SDL_MOUSEMOTION:
1919 input_mouseMove( event );
1920 break;
1921
1922 default:
1923 break;
1924 }
1925}
1926
1930KeySemanticType input_keyFromBrief( const char *target )
1931{
1932 for (int i = 0; i < KST_END; i++) {
1933 if (strcmp( input_getKeybindBrief( i ), target ) == 0)
1934 return i;
1935 }
1936 WARN( _( "Key '%s' not found!" ), target );
1937 return -1;
1938}
int player_tryBoard(int noisy)
Attempt to board the player's target.
Definition board.c:152
double cam_getZoomTarget(void)
Gets the camera zoom.
Definition camera.c:111
double cam_getZoom(void)
Gets the camera zoom.
Definition camera.c:101
void cam_setZoomTarget(double zoom, double speed)
Sets the camera zoom target.
Definition camera.c:90
void cli_open(void)
Opens the console.
Definition console.c:662
int escorts_hold(const Pilot *parent)
Have a pilot order its escorts to hold position.
Definition escort.c:344
int escorts_return(const Pilot *parent)
Have a pilot order its escorts to dock.
Definition escort.c:357
int escorts_attack(Pilot *parent)
Have a pilot order its escorts to attack its target.
Definition escort.c:305
int escorts_clear(const Pilot *parent)
Have a pilot order its escorts to clear orders.
Definition escort.c:370
const char * pgettext_var(const char *msgctxt, const char *msgid)
Definition gettext.c:346
int gui_radarClickEvent(SDL_Event *event)
Handles a click at a position in the current system.
Definition gui.c:2205
int gui_handleEvent(SDL_Event *evt)
Handles GUI events.
Definition gui.c:2295
void gui_messageScrollDown(int lines)
Scrolls down the message box.
Definition gui.c:254
int gui_borderClickEvent(SDL_Event *event)
Handles clicks on the GUI border icons.
Definition gui.c:2236
void gui_setRadarRel(int mod)
Modifies the radar resolution.
Definition gui.c:2146
void gui_messageScrollUp(int lines)
Scrolls up the message box.
Definition gui.c:223
int hooks_runParam(const char *stack, const HookParam *param)
Runs all the hooks of stack.
Definition hook.c:1029
Handles the info menu.
#define INFO_DEFAULT
Definition info.h:16
void input_init(void)
Initializes the input subsystem (does not set keys).
Definition input.c:371
static void input_mouseMove(SDL_Event *event)
Provides mouse X and Y coordinates for mouse flying.
Definition input.c:1464
static void input_joyhatevent(const Uint8 value, const Uint8 hat)
Filters a joystick hat event.
Definition input.c:1393
void input_disableAll(void)
Disables all the keybinds.
Definition input.c:436
const char * input_getKeybindBrief(KeySemanticType keybind)
Gets the brief descirption of the keybinding.
Definition input.c:681
int input_isDoubleClick(const void *clicked)
Checks whether a clicked item is the same as the last-clicked.
Definition input.c:1789
SDL_Keycode input_getKeybind(KeySemanticType keybind, KeybindType *type, SDL_Keymod *mod)
Gets the value of a keybind.
Definition input.c:525
int input_clickedPilot(unsigned int pilot, int autonav)
Performs an appropriate action when a pilot is clicked.
Definition input.c:1739
static void input_clickZoom(double modifier)
Handles zoom.
Definition input.c:1455
static unsigned int repeat_keyCounter
Definition input.c:230
void input_toggleEnable(KeySemanticType key, int enable)
Enables or disables a keybind.
Definition input.c:445
double player_right
Definition player.c:131
static void input_joyevent(const int event, const SDL_Keycode button)
Filters a joystick button event.
Definition input.c:1377
static void input_clickevent(SDL_Event *event)
Handles a click event.
Definition input.c:1475
static const void * input_lastClicked
Definition input.c:238
#define HYP()
Definition input.c:779
static unsigned int input_mouseClickLast
Definition input.c:237
SDL_Keycode input_keyConv(const char *name)
Gets the key id from its name.
Definition input.c:485
#define LAND()
Definition input.c:797
static void input_joyaxis(const SDL_Keycode axis, const int value)
Filters a joystick axis event.
Definition input.c:1349
void input_handle(SDL_Event *event)
Handles global input.
Definition input.c:1833
void input_mouseShow(void)
Shows the mouse.
Definition input.c:453
static KeySemanticType doubletap_key
Definition input.c:222
static int input_mouseCounter
Definition input.c:236
KeySemanticType input_keyAlreadyBound(KeybindType type, SDL_Keycode key, SDL_Keymod mod)
Checks to see if a key is already bound.
Definition input.c:639
void input_setDefault(int wasd)
Sets the default input keys.
Definition input.c:267
int input_clickPos(SDL_Event *event, double x, double y, double zoom, double minpr, double minr)
Handles a click at a position in the current system.
Definition input.c:1538
static void input_keyevent(const int event, const SDL_Keycode key, const SDL_Keymod mod, const int repeat)
Filters a keyboard event.
Definition input.c:1431
int input_clickedAsteroid(int field, int asteroid)
Performs an appropriate action when an asteroid is clicked.
Definition input.c:1724
const char * input_getKeybindName(KeySemanticType keybind)
Gets the name of the keybinding.
Definition input.c:693
#define INGAME()
Definition input.c:773
static unsigned int doubletap_t
Definition input.c:223
static unsigned int repeat_keyTimer
Definition input.c:229
static double input_mouseTimer
Definition input.c:235
static int repeat_key
Definition input.c:228
KeySemanticType input_keyFromBrief(const char *target)
Definition input.c:1930
void input_setKeybind(KeySemanticType keybind, KeybindType type, SDL_Keycode key, SDL_Keymod mod)
Binds key of type type to action keybind.
Definition input.c:502
void input_update(double dt)
Handles key repeating.
Definition input.c:740
void input_exit(void)
Exits the input system.
Definition input.c:420
double player_left
Definition player.c:130
int input_clickedSpob(int spob, int autonav, int priority)
Performs an appropriate action when a spob is clicked.
Definition input.c:1671
#define NODEAD()
Definition input.c:794
SDL_Keymod input_translateMod(SDL_Keymod mod)
Translates SDL modifier to Naev modifier.
Definition input.c:723
static Keybind input_keybinds[KST_END]
Definition input.c:216
const char * input_getKeybindDescription(KeySemanticType keybind)
Gets the description of the keybinding.
Definition input.c:708
int input_mouseIsShown(void)
Gets whether or not the mouse is currently shown.
Definition input.c:474
void input_enableAll(void)
Enables all the keybinds.
Definition input.c:427
int input_clickedJump(int jump, int autonav)
Performs an appropriate action when a jump point is clicked.
Definition input.c:1629
const char * input_modToText(SDL_Keymod mod)
Gets the human readable version of mod.
Definition input.c:611
void input_clicked(const void *clicked)
Sets the last-clicked item, for double-click detection.
Definition input.c:1776
void input_mouseHide(void)
Hides the mouse.
Definition input.c:462
void input_getKeybindDisplay(KeySemanticType keybind, char *buf, int len)
Gets the display name (translated and human-readable) of a keybind.
Definition input.c:547
#define DEAD()
Definition input.c:791
Handles the important game menus.
Header file with generic functions and naev-specifics.
#define MIN(x, y)
Definition naev.h:39
#define pow2(x)
Definition naev.h:53
#define FABS(x)
Definition naev.h:34
#define MAX(x, y)
Definition naev.h:37
int scnprintf(char *text, size_t maxlen, const char *fmt,...)
Like snprintf(), but returns the number of characters ACTUALLY "printed" into the buffer....
Definition nstring.c:102
void gl_windowToScreenPos(int *sx, int *sy, int wx, int wy)
Translates the window position to screen position.
Definition opengl.c:762
void gl_screenToGameCoords(double *nx, double *ny, int bx, int by)
Converts screen coordinates to in-game coordinates.
void pause_player(void)
Pauses the game and marks the pause as player-initiated.
Definition pause.c:70
int paused
Definition pause.c:18
void unpause_game(void)
Unpauses the game.
Definition pause.c:43
double pilot_getNearestPos(const Pilot *p, unsigned int *tp, double x, double y, int disabled)
Get the nearest pilot to a pilot from a certain position.
Definition pilot.c:564
Pilot * pilot_get(unsigned int id)
Pulls a pilot out of the pilot_stack based on ID.
Definition pilot.c:640
int pilot_afterburn(Pilot *p)
Activate the afterburner.
void pilot_weapSetUpdateOutfitState(Pilot *p)
Updates the local state of all the pilot's outfits based on the weapon sets.
void player_stealth(void)
Input binding for toggling stealth for the player.
Definition player.c:4824
void player_weapSetPress(int id, double value, int repeat)
Handles keyboard events involving the player's weapon-set keys. It's valid to call this while gamepla...
Definition player.c:1491
void player_autohail(void)
Automatically tries to hail a pilot that hailed the player.
Definition player.c:2521
void player_cooldownBrake(void)
Starts braking or active cooldown.
Definition player.c:2623
void player_accel(double acc)
Start accelerating.
Definition player.c:2206
void player_targetEscort(int prev)
Targets the pilot.
Definition player.c:2349
void player_targetAsteroidSet(int field, int id)
Sets the player's target asteroid.
Definition player.c:1596
void player_targetSet(unsigned int id)
Sets the player's target.
Definition player.c:2230
void player_hailSpob(void)
Opens communication with the player's spob target.
Definition player.c:2503
void player_resetSpeed(void)
Resets the player speed stuff.
Definition player.c:1521
void player_targetHyperspaceSet(int id, int nomsg)
Sets the player's hyperspace target.
Definition player.c:1905
void player_targetHyperspace(void)
Gets a hyperspace target.
Definition player.c:1940
void player_hyperspacePreempt(int preempt)
Enables or disables jump points preempting spobs in autoface and target clearing.
Definition player.c:1980
void player_toggleMouseFly(void)
Toggles mouse flying.
Definition player.c:2601
void player_targetNearest(void)
Player targets nearest pilot.
Definition player.c:2393
void player_restoreControl(int reason, const char *str)
Aborts autonav and other states that take control of the ship.
Definition player.c:1535
int player_jump(void)
Actually attempts to jump in hyperspace.
Definition player.c:2029
void player_targetSpobSet(int id)
Sets the player's target spob.
Definition player.c:1559
void player_accelOver(void)
Done accelerating.
Definition player.c:2220
int player_land(int loud)
Try to land or target closest spob if no land target.
Definition player.c:1653
Player_t player
Definition player.c:77
void player_targetPrev(int mode)
Cycles to previous target.
Definition player.c:2307
void player_targetClear(void)
Clears the player's ship, spob or hyperspace target, in that order.
Definition player.c:2315
void player_targetHostile(void)
Targets the nearest hostile enemy to the player.
Definition player.c:2258
void player_screenshot(void)
Takes a screenshot.
Definition player.c:2415
void player_approach(void)
Logic to make the player approach a target pilot to board or spob to land on.
Definition player.c:1839
void player_targetSpob(void)
Cycle through spob targets.
Definition player.c:1620
void player_targetNext(int mode)
Cycles to next target.
Definition player.c:2297
void player_hail(void)
Opens communication with the player's target.
Definition player.c:2476
void player_autonavStartWindow(unsigned int wid, const char *str)
Starts autonav and closes the window.
void player_autonavPos(double x, double y)
Starts autonav with a local position destination.
void player_autonavStart(void)
Starts autonav.
void player_autonavPil(unsigned int p)
Starts autonav with a pilot to follow.
void player_autonavBoard(unsigned int p)
Starts autonav with a pilot to board.
void player_autonavSpob(const char *name, int tryland)
Starts autonav with a spob destination.
double system_getClosest(const StarSystem *sys, int *pnt, int *jp, int *ast, int *fie, double x, double y)
Gets the closest feature to a position in the system.
Definition space.c:723
int space_canHyperspace(const Pilot *p)
Checks to make sure if pilot is far enough away to hyperspace.
Definition space.c:494
StarSystem * cur_system
Definition space.c:110
void spob_updateLand(Spob *p)
Updates the land possibilities of a spob.
Definition space.c:2031
Represents an asteroid field anchor.
Definition asteroid.h:111
Asteroid * asteroids
Definition asteroid.h:116
Represents a single asteroid.
Definition asteroid.h:88
const glTexture * gfx
Definition asteroid.h:94
Solid sol
Definition asteroid.h:98
The actual hook parameter.
Definition hook.h:40
const char * str
Definition hook.h:44
union HookParam::@114305201244257020071001257133270030317263020235 u
HookParamType type
Definition hook.h:41
double num
Definition hook.h:43
int b
Definition hook.h:45
Naev Keybinding.
Definition input.c:41
int disabled
Definition input.c:42
SDL_Keycode key
Definition input.c:44
KeybindType type
Definition input.c:43
SDL_Keymod mod
Definition input.c:45
The representation of an in-game pilot.
Definition pilot.h:263
vec2 pos
Definition physics.h:49
Represents a Space Object (SPOB), including and not limited to planets, stations, wormholes,...
Definition space.h:102
int can_land
Definition space.h:125
int land_override
Definition space.h:126
double radius
Definition space.h:110
char * name
Definition space.h:105
vec2 pos
Definition space.h:109
double sw
Definition opengl_tex.h:53
double sh
Definition opengl_tex.h:54
double y
Definition vec2.h:47
double x
Definition vec2.h:46
int toolkit_isOpen(void)
Checks to see if the toolkit is open.
Definition toolkit.c:93
static SDL_Keycode input_key
Definition toolkit.c:43
unsigned int window_get(const char *wdwname)
Gets the ID of a window.
Definition toolkit.c:662
int toolkit_input(SDL_Event *event)
Toolkit input handled here.
Definition toolkit.c:1686