Lephisto/src/player.c
2013-02-03 00:37:42 +00:00

190 lines
5.1 KiB
C

#include <malloc.h>
#include "def.h"
#include "pilot.h"
#include "log.h"
#include "player.h"
#define KEY_PRESS 1.
#define KEY_RELEASE -1.
// Keybind structure.
typedef struct {
char* name; // Keybinding name, taken from keybindNames[]
KeybindType type; // type, defined in player.h.
int key; // Key/axis/button event number.
double reverse; // 1. if normal, -1 if reversed, only useful for joystick axis.
} Keybind;
static Keybind** player_input; // Contains the players keybindings.
// Name of each keybinding.
const char* keybindNames[] = { "accel", "left", "right" };
Pilot* player = NULL; // extern in pilot.h
static double player_turn = 0.; // Turn velocity from input.
static double player_acc = 0.; // Accel velocity from input.
// Used in pilot.c
// Basically uses keyboard input instead of AI input.
void player_think(Pilot* player, const double dt) {
player->solid->dir_vel = 0.;
if(player_turn)
player->solid->dir_vel -= player->ship->turn * player_turn;
vect_pset(&player->solid->force, player->ship->thrust * player_acc, player->solid->dir);
}
// Initialization/exit functions (does not assign keys).
void input_init(void) {
Keybind* tmp;
int i;
for(i = 0; keybindNames[i]; i++); // Get number of bindings.
player_input = (Keybind**)malloc(i*sizeof(Keybind*));
// Create a null keybinding for each.
for(i = 0; keybindNames[i]; i++) {
tmp = MALLOC_L(Keybind);
tmp->name = (char*)keybindNames[i];
tmp->type = KEYBIND_NULL;
tmp->key = 0;
tmp->reverse = 1.;
player_input[i] = tmp;
}
}
void input_exit(void) {
int i;
for(i = 0; keybindNames[i]; i++)
free(player_input[i]);
free(player_input);
}
// Binds key of type [type] to action keybind.
void input_setKeybind(char* keybind, KeybindType type, int key, int reverse) {
int i;
for(i = 0; keybindNames[i]; i++) {
if(strcmp(keybind, player_input[i]->name)==0) {
player_input[i]->type = type;
player_input[i]->key = key;
player_input[i]->reverse = reverse ? -1. : 1.;
return;
}
}
}
// == Run input method. ================================================
// keynum : Index of the player_input keybind.
// value : Value of keypress (defined above).
// abs : Whether or not it's an abs value (For those pesky joysticks.
// =====================================================================
static void input_key(int keynum, double value, int abs) {
if(strcmp(player_input[keynum]->name, "accel")==0) {
if(abs)player_acc = value;
else player_acc += value;
}
else if(strcmp(player_input[keynum]->name, "left")==0) {
if(abs)player_turn = -value;
else player_turn -= value;
}
else if(strcmp(player_input[keynum]->name, "right")==0) {
if(abs) player_turn = value;
else player_turn += value;
}
//Make sure values are sane.
player_acc = ABS(player_acc);
if(player_acc > 1.) player_acc = 1.;
if(player_turn > 1.) player_turn = 1.;
else if(player_turn < -1.) player_turn = -1.;
}
// --Events--
static void input_joyaxis(int axis, int value);
static void input_joydown(int button);
static void input_joyup(int button);
static void input_keydown(SDLKey key);
static void input_keyup(SDLKey key);
// Joystick.
// Axis.
static void input_joyaxis(int axis, int value) {
int i;
for(i = 0; keybindNames[i]; i++)
if(player_input[i]->type == KEYBIND_JAXIS && player_input[i]->key == axis) {
input_key(i, -(player_input[i]->reverse) * (double)value / 32767., 1);
return;
}
}
// Joystick button down.
static void input_joydown(int button) {
int i;
for(i = 0; keybindNames[i]; i++)
if(player_input[i]->type == KEYBIND_JBUTTON && player_input[i]->key == button) {
input_key(i, KEY_RELEASE, 0);
return;
}
}
// Joystick button up.
static void input_joyup(int button) {
int i;
for(i = 0; keybindNames[i]; i++)
if(player_input[i]->type == KEYBIND_JBUTTON && player_input[i]->key == button) {
input_key(i, KEY_RELEASE, 0);
return;
}
}
// Keyboard.
// Key down.
static void input_keydown(SDLKey key) {
int i;
for(i = 0; keybindNames[i]; i++)
if(player_input[i]->type == KEYBIND_KEYBOARD && player_input[i]->key == key) {
input_key(i, KEY_PRESS, 0);
return;
}
// Fire Escape.
SDL_Event quit;
if(key == SDLK_ESCAPE) {
quit.type = SDL_QUIT;
SDL_PushEvent(&quit);
}
}
// Key up.
static void input_keyup(SDLKey key) {
int i;
for(i = 0; keybindNames[i]; i++)
if(player_input[i]->type == KEYBIND_KEYBOARD && player_input[i]->key == key) {
input_key(i, KEY_RELEASE, 0);
return;
}
}
// Global input.
// Just seperates the event types.
void input_handle(SDL_Event* event) {
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);
case SDL_KEYDOWN:
input_keydown(event->key.keysym.sym);
break;
case SDL_KEYUP:
input_keyup(event->key.keysym.sym);
break;
}
}