polyadvent

A game engine from scratch in C
git clone git://jb55.com/polyadvent
Log | Files | Refs | README

input.c (5680B)


      1 
      2 #include "input.h"
      3 #include "util.h"
      4 #include "debug.h"
      5 #include "common.h"
      6 
      7 static void key_down(struct input *input, int scancode, u64 current_frame) {
      8     input->modifiers = SDL_GetModState();
      9 
     10     struct input_edge *edge = &input->key_edge_states[scancode];
     11 
     12     if (edge->is_down)
     13         return;
     14 
     15     edge->down_frame = current_frame;
     16     edge->is_down = 1;
     17 
     18     // might be useful to know when it was last up
     19     /* edge->up_frame = 0; */
     20 }
     21 
     22 static void key_up(struct input *input, int scancode, u64 current_frame) {
     23     input->modifiers = SDL_GetModState();
     24     struct input_edge *edge = &input->key_edge_states[scancode];
     25 
     26     edge->up_frame = current_frame;
     27     edge->is_down = 0;
     28 }
     29 
     30 static void button_up(struct input *input, SDL_JoyButtonEvent *event, u64 current_frame)
     31 {
     32     if (event->button >= SDL_CONTROLLER_BUTTON_MAX) return;
     33     /* printf("button up %d\n", event->button); */
     34     struct input_edge *edge = &input->button_edge_states[event->button];
     35 
     36     edge->up_frame = current_frame;
     37     edge->is_down = 0;
     38 }
     39 
     40 static void button_down(struct input *input, SDL_JoyButtonEvent *event, u64 current_frame)
     41 {
     42     if (event->button >= SDL_CONTROLLER_BUTTON_MAX) return;
     43     printf("button down %d\n", event->button);
     44 
     45     struct input_edge *edge = &input->button_edge_states[event->button];
     46 
     47     if (edge->is_down)
     48         return;
     49 
     50     edge->down_frame = current_frame;
     51     edge->is_down = 1;
     52 }
     53 
     54 static void axis_motion(struct input *input, SDL_JoyAxisEvent *event)
     55 {
     56     if (event->axis >= MAX_AXIS) return;
     57     input->axis[event->axis] = event->axis == 1 ? -event->value : event->value;
     58     /* printf("axis %d %d", input->axis[0], input->axis[1]); */
     59     for (int i = 0; i < MAX_AXIS; i++) {
     60         if (input->axis[i] >= -4000 && input->axis[i] <= 4000 )
     61             input->axis[i] = 0;
     62     }
     63     /* printf(" -> %d %d\n", input->axis[0], input->axis[1]); */
     64 }
     65 
     66 void process_events(struct input *input, u64 current_frame) {
     67   SDL_Event event;
     68 
     69   input->last_mx = input->mx;
     70   input->last_my = input->my;
     71 
     72   input_reset(input);
     73 
     74   while (SDL_PollEvent(&event)) {
     75     switch (event.type) {
     76     case SDL_MOUSEWHEEL:
     77         input->wheel_x = event.wheel.x;
     78         input->wheel_y = event.wheel.y;
     79         break;
     80     case SDL_KEYDOWN:
     81         key_down(input, event.key.keysym.scancode, current_frame);
     82         break;
     83     case SDL_KEYUP:
     84         key_up(input, event.key.keysym.scancode, current_frame);
     85         break;
     86     case SDL_JOYAXISMOTION:
     87         axis_motion(input, &event.jaxis);
     88         break;
     89     case SDL_JOYBUTTONUP:
     90         button_up(input, &event.jbutton, current_frame);
     91         break;
     92     case SDL_JOYBUTTONDOWN:
     93         button_down(input, &event.jbutton, current_frame);
     94         break;
     95     case SDL_MOUSEBUTTONDOWN:
     96         if (event.button.button <= MOUSE_BUTTONS)
     97             input->mbuttons[event.button.button-1] = 1;
     98 
     99         break;
    100     case SDL_MOUSEBUTTONUP:
    101         if (event.button.button <= MOUSE_BUTTONS)
    102             input->mbuttons[event.button.button-1] = 0;
    103         break;
    104     case SDL_MOUSEMOTION:
    105         input->mx = event.motion.x;
    106         input->my = event.motion.y;
    107         input->mdx += event.motion.xrel;
    108         input->mdy += event.motion.yrel;
    109         break;
    110     case SDL_WINDOWEVENT:
    111       switch (event.window.event) {
    112       case SDL_WINDOWEVENT_RESIZED:
    113           if (!event.window.data1)
    114               continue;
    115           debug("resizing %d %d\n", event.window.data1, event.window.data2);
    116           input->resized_width = event.window.data1;
    117           input->resized_height = event.window.data2;
    118           assert(input->resized_width);
    119           assert(input->resized_height);
    120         break;
    121       }
    122       break;
    123     case SDL_QUIT:
    124       SDL_Quit();
    125       exit(0);
    126     }
    127 
    128   }
    129 
    130   /* if (input->resized_width) */
    131   /*   printf("checking resize %d %d\n", input->resized_width, */
    132   /*           input->resized_height); */
    133 
    134 }
    135 
    136 void init_input(struct input *input) {
    137   /* memset(input->keys, 0, sizeof(input->keys[0]) * ARRAY_SIZE(input->keys)); */
    138   input->keystates = SDL_GetKeyboardState(NULL);
    139   assert(sizeof(input->key_edge_states) == SDL_NUM_SCANCODES * sizeof(input->key_edge_states[0]));
    140   memset(input->key_edge_states, 0, sizeof(input->key_edge_states));
    141   memset(input->button_edge_states, 0, sizeof(input->button_edge_states));
    142   memset(input->axis, 0, sizeof(input->axis));
    143   memset(input->mbuttons, 0, sizeof(input->mbuttons));
    144   input->axis_min_input = 1024;
    145   input->mx = 0;
    146   input->my = 0;
    147   input->mdx = 0;
    148   input->mdy = 0;
    149   input->wheel_x = 0;
    150   input->wheel_y = 0;
    151   input->last_mx = 0;
    152   input->last_my = 0;
    153   input->resized_height = 0;
    154   input->resized_width = 0;
    155   input->controller = 0;
    156   assert(input->keystates);
    157 }
    158 
    159 bool is_key_down_on_frame(struct input *input, u8 scancode, u64 frame) {
    160     struct input_edge *edge = &input->key_edge_states[scancode];
    161 
    162     // is_down is implied, but do it for good measure
    163     return edge->down_frame == frame && edge->is_down;
    164 }
    165 
    166 bool is_button_down_on_frame(struct input *input, SDL_GameControllerButton button, u64 frame)
    167 {
    168     struct input_edge *edge = &input->button_edge_states[button];
    169     return edge->down_frame == frame && edge->is_down;
    170 }
    171 
    172 
    173 void input_reset(struct input *input) {
    174     input->mdx = 0;
    175     input->mdy = 0;
    176     input->wheel_x = 0;
    177     input->wheel_y = 0;
    178     input->resized_height = 0;
    179     input->resized_width = 0;
    180 }
    181 
    182 int input_is_dragging(struct input *input, int mouse_button) {
    183     return input->mbuttons[mouse_button-1];
    184 }
    185 
    186 bool is_button_down(struct input *input, SDL_GameControllerButton button)
    187 {
    188     if (!input->controller) {
    189         return false;
    190     }
    191 
    192     return SDL_GameControllerGetButton(input->controller, button) == 1;
    193 }