#include "lephisto.h" #include "log.h" #include "player.h" #include "pause.h" #include "toolkit.h" #include "menu.h" #include "board.h" #include "input.h" #define KEY_PRESS ( 1.) #define KEY_RELEASE (-1.) // Keybind structure. typedef struct Keybind_ { char* name; // Keybinding name, taken from keybindNames[] KeybindType type; // type, defined in player.h. unsigned int key; // Key/axis/button event number. double reverse; // 1. if normal, -1 if reversed, only useful for joystick axis. } Keybind; static Keybind** input_keybinds; // Contains the players keybindings. // Name of each keybinding. const char* keybindNames[] = { "accel", "left", "right", "reverse", // Movement. "primary", "target", "target_nearest", "face", "board", // Combat. "secondary", "secondary_next", // Secondary weapons. "target_planet", "land", "thyperspace", "jump", // Navigation. "mapzoomin", "mapzoomout", "screenshot", "pause", "menu", "info", // Misc. "end" }; // Must terminate at the end. // From player.c extern double player_turn; extern double player_acc; extern unsigned int player_target; // Grabbed from main.c extern int show_fps; // Set the default input keys. void input_setDefault(void) { // Movement. input_setKeybind("accel", KEYBIND_KEYBOARD, SDLK_w, 0); input_setKeybind("left", KEYBIND_KEYBOARD, SDLK_a, 0); input_setKeybind("right", KEYBIND_KEYBOARD, SDLK_d, 0); input_setKeybind("reverse", KEYBIND_KEYBOARD, SDLK_s, 0); // Combat. input_setKeybind("primary", KEYBIND_KEYBOARD, SDLK_SPACE, 0); input_setKeybind("target", KEYBIND_KEYBOARD, SDLK_TAB, 0); input_setKeybind("target_nearest", KEYBIND_KEYBOARD, SDLK_r, 0); input_setKeybind("face", KEYBIND_KEYBOARD, SDLK_f, 0); input_setKeybind("board", KEYBIND_KEYBOARD, SDLK_b, 0); // Secondary weapon. input_setKeybind("secondary", KEYBIND_KEYBOARD, SDLK_LSHIFT, 0); input_setKeybind("secondary_next", KEYBIND_KEYBOARD, SDLK_q, 0); // Space input_setKeybind("target_planet", KEYBIND_KEYBOARD, SDLK_p, 0); input_setKeybind("land", KEYBIND_KEYBOARD, SDLK_l, 0); input_setKeybind("thyperspace", KEYBIND_KEYBOARD, SDLK_h, 0); input_setKeybind("jump", KEYBIND_KEYBOARD, SDLK_j, 0); // Misc. input_setKeybind("mapzoomin", KEYBIND_KEYBOARD, SDLK_UP, 0); input_setKeybind("mapzoomout", KEYBIND_KEYBOARD, SDLK_DOWN, 0); input_setKeybind("screenshot", KEYBIND_KEYBOARD, SDLK_F12, 0); input_setKeybind("pause", KEYBIND_KEYBOARD, SDLK_F1, 0); input_setKeybind("menu", KEYBIND_KEYBOARD, SDLK_ESCAPE, 0); input_setKeybind("info", KEYBIND_KEYBOARD, SDLK_i, 0); } // Initialization/exit functions (does not assign keys). void input_init(void) { Keybind* tmp; int i; for(i = 0; strcmp(keybindNames[i], "end"); i++); // Get number of bindings. input_keybinds = malloc(i*sizeof(Keybind*)); // Create a null keybinding for each. for(i = 0; strcmp(keybindNames[i], "end"); i++) { tmp = MALLOC_L(Keybind); tmp->name = (char*)keybindNames[i]; tmp->type = KEYBIND_NULL; tmp->key = 0; tmp->reverse = 1.; input_keybinds[i] = tmp; } } void input_exit(void) { int i; for(i = 0; strcmp(keybindNames[i], "end"); i++) free(input_keybinds[i]); free(input_keybinds); } // Binds key of type [type] to action keybind. void input_setKeybind(char* keybind, KeybindType type, int key, int reverse) { int i; for(i = 0; strcmp(keybindNames[i], "end"); i++) if(strcmp(keybind, input_keybinds[i]->name)==0) { input_keybinds[i]->type = type; input_keybinds[i]->key = key; input_keybinds[i]->reverse = reverse ? -1. : 1.; return; } WARN("Unable to set keybind '%s', That command does not exist.", keybind); } // == Run input method. ================================================ // keynum : Index of the input_keybinds keybind. // value : Value of keypress (defined above). // abs : Whether or not it's an abs value (For those pesky joysticks. // ===================================================================== #define KEY(s) (strcmp(input_keybinds[keynum]->name, s)==0) static void input_key(int keynum, double value, int abs) { // Accelerating. if(KEY("accel")) { if(abs)player_acc = value; else player_acc += value; player_acc = ABS(player_acc); // Make sure value is sane. } // Turning left. else if(KEY("left")) { // Set flags for facing correction. if(value == KEY_PRESS) player_setFlag(PLAYER_TURN_LEFT); else if(value == KEY_RELEASE) player_rmFlag(PLAYER_TURN_LEFT); if(abs)player_turn = -value; else player_turn -= value; if(player_turn < -1.) player_turn = -1.; // Make sure value is sane. } // Turning right. else if(KEY("right")) { // Set flags for facing correction. if(value == KEY_PRESS) player_setFlag(PLAYER_TURN_RIGHT); else if(value == KEY_RELEASE) player_rmFlag(PLAYER_TURN_RIGHT); if(abs) player_turn = value; else player_turn += value; if(player_turn < -1.) player_turn = -1.; // Make sure value is sane. } // Turn around to face vel. else if(KEY("reverse")) { if(value == KEY_PRESS) player_setFlag(PLAYER_REVERSE); else if(value == KEY_RELEASE) { player_rmFlag(PLAYER_REVERSE); player_turn = 0; // Turning corrections. if(player_isFlag(PLAYER_TURN_LEFT)) player_turn -= 1; if(player_isFlag(PLAYER_TURN_RIGHT)) player_turn += 1; } } // Shoot primary weapon. BOOM BOOM. else if(KEY("primary") && !paused) { if(value == KEY_PRESS) player_setFlag(PLAYER_PRIMARY); else if(value == KEY_RELEASE) player_rmFlag(PLAYER_PRIMARY); } // Targetting. else if(KEY("target") && !paused) { if(value == KEY_PRESS) player_target = pilot_getNext(player_target); } else if(KEY("target_nearest")) { if(value == KEY_PRESS) player_target = pilot_getHostile(); } // Face the target. else if(KEY("face")) { if(value == KEY_PRESS) player_setFlag(PLAYER_FACE); else if(value == KEY_RELEASE) { player_rmFlag(PLAYER_FACE); // Turning corrections. player_turn = 0; if(player_isFlag(PLAYER_TURN_LEFT)) player_turn -= 1; if(player_isFlag(PLAYER_TURN_RIGHT)) player_turn += 1; } } // Board those ships. else if(KEY("board") && !paused) { if(value == KEY_PRESS) player_board(); } // Shooting secondary weapon. else if(KEY("secondary") && !paused) { if(value == KEY_PRESS) player_setFlag(PLAYER_SECONDARY); else if(value == KEY_RELEASE) player_rmFlag(PLAYER_SECONDARY); } // Selecting secondary weapon. else if(KEY("secondary_next") && !paused) { if(value == KEY_PRESS) player_secondaryNext(); } // Space. // Target planet (cycles just like target). else if(KEY("target_planet") && !paused) { if(value == KEY_PRESS) player_targetPlanet(); } // Target nearest planet or attempt to land. else if(KEY("land") && !paused) { if(value == KEY_PRESS) player_land(); } else if(KEY("thyperspace") && !paused) { if(value == KEY_PRESS) player_targetHyperspace(); } else if(KEY("jump") && !paused) { if(value == KEY_PRESS) player_jump(); } // Zoom in. else if(KEY("mapzoomin")) { if(value == KEY_PRESS) player_setRadarRel(1); } // Zoom out. else if(KEY("mapzoomout")) { if(value == KEY_PRESS) player_setRadarRel(-1); } // Take a screenshot. else if(KEY("screenshot")) { if(value == KEY_PRESS) player_screenshot(); } // Pause the game. else if(KEY("pause")) { if(value == KEY_PRESS) { if(!toolkit) { if(paused) unpause(); } else pause(); } } // Opens a menu. else if(KEY("menu")) { if(value == KEY_PRESS) menu_small(); } // Show pilot information. else if(KEY("info")) { if(value == KEY_PRESS) info_menu(); } } // --Events-- static void input_joyaxis(const unsigned int axis, const int value); static void input_joydown(const unsigned int button); static void input_joyup(const unsigned int button); static void input_keydown(SDLKey key); static void input_keyup(SDLKey key); // Joystick. // Axis. static void input_joyaxis(const unsigned int axis, const int value) { int i; for(i = 0; strcmp(keybindNames[i], "end"); i++) if(input_keybinds[i]->type == KEYBIND_JAXIS && input_keybinds[i]->key == axis) { input_key(i, -(input_keybinds[i]->reverse) * (double)value / 32767., 1); return; } } // Joystick button down. static void input_joydown(const unsigned int button) { int i; for(i = 0; strcmp(keybindNames[i], "end");i++) if(input_keybinds[i]->type == KEYBIND_JBUTTON && input_keybinds[i]->key == button) { input_key(i, KEY_RELEASE, 0); return; } } // Joystick button up. static void input_joyup(const unsigned int button) { int i; for(i = 0; strcmp(keybindNames[i], "end"); i++) if(input_keybinds[i]->type == KEYBIND_JBUTTON && input_keybinds[i]->key == button) { input_key(i, KEY_RELEASE, 0); return; } } // Keyboard. // Key down. static void input_keydown(SDLKey key) { int i; for(i = 0; strcmp(keybindNames[i], "end"); i++) if(input_keybinds[i]->type == KEYBIND_KEYBOARD && input_keybinds[i]->key == key) { input_key(i, KEY_PRESS, 0); return; } } // Key up. static void input_keyup(SDLKey key) { int i; for(i = 0; strcmp(keybindNames[i], "end"); i++) if(input_keybinds[i]->type == KEYBIND_KEYBOARD && input_keybinds[i]->key == key) { input_key(i, KEY_RELEASE, 0); return; } } // Global input. // Just seperates the event types. void input_handle(SDL_Event* event) { if(toolkit) { // Toolkit is handled seperately. toolkit_input(event); return; } switch(event->type) { case SDL_JOYAXISMOTION: input_joyaxis(event->jaxis.axis, event->jaxis.value); break; case SDL_JOYBUTTONDOWN: input_joydown(event->jbutton.button); break; case SDL_JOYBUTTONUP: input_joyup(event->jbutton.button); break; case SDL_KEYDOWN: input_keydown(event->key.keysym.sym); break; case SDL_KEYUP: input_keyup(event->key.keysym.sym); break; } }