Mercurial > molko
view libmlk-core/mlk/core/event.c @ 545:27303e9402de
core: introduce mlk_alloc_expand
author | David Demelier <markand@malikania.fr> |
---|---|
date | Sun, 05 Mar 2023 22:14:02 +0100 |
parents | 95792046d3d2 |
children | f76cada0bbb2 |
line wrap: on
line source
/* * event.c -- event management * * Copyright (c) 2020-2023 David Demelier <markand@malikania.fr> * * Permission to use, copy, modify, and/or distribute this software for any * purpose with or without fee is hereby granted, provided that the above * copyright notice and this permission notice appear in all copies. * * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. */ #include <SDL.h> #include "event.h" /* Maintain with enum key constants in key.h */ static const struct { SDL_Keycode key; enum mlk_key value; } keymap[] = { { SDLK_RETURN, MLK_KEY_ENTER }, { SDLK_ESCAPE, MLK_KEY_ESCAPE }, { SDLK_BACKSPACE, MLK_KEY_BACKSPACE }, { SDLK_TAB, MLK_KEY_TAB }, { SDLK_SPACE, MLK_KEY_SPACE }, { SDLK_EXCLAIM, MLK_KEY_EXCLAIM }, { SDLK_QUOTEDBL, MLK_KEY_DOUBLE_QUOTE }, { SDLK_HASH, MLK_KEY_HASH }, { SDLK_PERCENT, MLK_KEY_PERCENT }, { SDLK_DOLLAR, MLK_KEY_DOLLAR }, { SDLK_AMPERSAND, MLK_KEY_AMPERSAND }, { SDLK_QUOTE, MLK_KEY_QUOTE }, { SDLK_LEFTPAREN, MLK_KEY_LPAREN }, { SDLK_RIGHTPAREN, MLK_KEY_RPAREN }, { SDLK_ASTERISK, MLK_KEY_ASTERISK }, { SDLK_PLUS, MLK_KEY_PLUS }, { SDLK_COMMA, MLK_KEY_COMMA }, { SDLK_MINUS, MLK_KEY_MINUS }, { SDLK_PERIOD, MLK_KEY_PERIOD }, { SDLK_SLASH, MLK_KEY_SLASH }, { SDLK_0, MLK_KEY_0 }, { SDLK_1, MLK_KEY_1 }, { SDLK_2, MLK_KEY_2 }, { SDLK_3, MLK_KEY_3 }, { SDLK_4, MLK_KEY_4 }, { SDLK_5, MLK_KEY_5 }, { SDLK_6, MLK_KEY_6 }, { SDLK_7, MLK_KEY_7 }, { SDLK_8, MLK_KEY_8 }, { SDLK_9, MLK_KEY_9 }, { SDLK_COLON, MLK_KEY_COLON }, { SDLK_SEMICOLON, MLK_KEY_SEMICOLON }, { SDLK_LESS, MLK_KEY_LESS }, { SDLK_EQUALS, MLK_KEY_EQUALS }, { SDLK_GREATER, MLK_KEY_GREATER }, { SDLK_QUESTION, MLK_KEY_QUESTION }, { SDLK_AT, MLK_KEY_AT }, { SDLK_LEFTBRACKET, MLK_KEY_LBRACKET }, { SDLK_BACKSLASH, MLK_KEY_BACKSLASH }, { SDLK_RIGHTBRACKET, MLK_KEY_RBRACKET }, { SDLK_CARET, MLK_KEY_CARET }, { SDLK_UNDERSCORE, MLK_KEY_UNDERSCORE }, { SDLK_BACKQUOTE, MLK_KEY_BACKQUOTE }, { SDLK_a, MLK_KEY_A }, { SDLK_b, MLK_KEY_B }, { SDLK_c, MLK_KEY_C }, { SDLK_d, MLK_KEY_D }, { SDLK_e, MLK_KEY_E }, { SDLK_f, MLK_KEY_F }, { SDLK_g, MLK_KEY_G }, { SDLK_h, MLK_KEY_H }, { SDLK_i, MLK_KEY_I }, { SDLK_j, MLK_KEY_J }, { SDLK_k, MLK_KEY_K }, { SDLK_l, MLK_KEY_L }, { SDLK_m, MLK_KEY_M }, { SDLK_n, MLK_KEY_N }, { SDLK_o, MLK_KEY_O }, { SDLK_p, MLK_KEY_P }, { SDLK_q, MLK_KEY_Q }, { SDLK_r, MLK_KEY_R }, { SDLK_s, MLK_KEY_S }, { SDLK_t, MLK_KEY_T }, { SDLK_u, MLK_KEY_U }, { SDLK_v, MLK_KEY_V }, { SDLK_w, MLK_KEY_W }, { SDLK_x, MLK_KEY_X }, { SDLK_y, MLK_KEY_Y }, { SDLK_z, MLK_KEY_Z }, { SDLK_CAPSLOCK, MLK_KEY_CAPSLOCK }, { SDLK_F1, MLK_KEY_F1 }, { SDLK_F2, MLK_KEY_F2 }, { SDLK_F3, MLK_KEY_F3 }, { SDLK_F4, MLK_KEY_F4 }, { SDLK_F5, MLK_KEY_F5 }, { SDLK_F6, MLK_KEY_F6 }, { SDLK_F7, MLK_KEY_F7 }, { SDLK_F8, MLK_KEY_F8 }, { SDLK_F9, MLK_KEY_F9 }, { SDLK_F10, MLK_KEY_F10 }, { SDLK_F11, MLK_KEY_F11 }, { SDLK_F12, MLK_KEY_F12 }, { SDLK_F13, MLK_KEY_F13 }, { SDLK_F14, MLK_KEY_F14 }, { SDLK_F15, MLK_KEY_F15 }, { SDLK_F16, MLK_KEY_F16 }, { SDLK_F17, MLK_KEY_F17 }, { SDLK_F18, MLK_KEY_F18 }, { SDLK_F19, MLK_KEY_F19 }, { SDLK_F20, MLK_KEY_F20 }, { SDLK_F21, MLK_KEY_F21 }, { SDLK_F22, MLK_KEY_F22 }, { SDLK_F23, MLK_KEY_F23 }, { SDLK_F24, MLK_KEY_F24 }, { SDLK_PRINTSCREEN, MLK_KEY_PRINTSCREEN }, { SDLK_SCROLLLOCK, MLK_KEY_SCROLL_LOCK }, { SDLK_PAUSE, MLK_KEY_PAUSE }, { SDLK_INSERT, MLK_KEY_INSERT }, { SDLK_HOME, MLK_KEY_HOME }, { SDLK_PAGEUP, MLK_KEY_PAGEUP }, { SDLK_DELETE, MLK_KEY_DELETE }, { SDLK_END, MLK_KEY_END }, { SDLK_PAGEDOWN, MLK_KEY_PAGEDOWN }, { SDLK_RIGHT, MLK_KEY_RIGHT }, { SDLK_LEFT, MLK_KEY_LEFT }, { SDLK_DOWN, MLK_KEY_DOWN }, { SDLK_UP, MLK_KEY_UP }, { SDLK_KP_DIVIDE, MLK_KEY_KP_DIVIDE }, { SDLK_KP_MULTIPLY, MLK_KEY_KP_MULTIPLY }, { SDLK_KP_MINUS, MLK_KEY_KP_MINUS }, { SDLK_KP_PLUS, MLK_KEY_KP_PLUS }, { SDLK_KP_ENTER, MLK_KEY_KP_ENTER }, { SDLK_KP_1, MLK_KEY_KP_1 }, { SDLK_KP_2, MLK_KEY_KP_2 }, { SDLK_KP_3, MLK_KEY_KP_3 }, { SDLK_KP_4, MLK_KEY_KP_4 }, { SDLK_KP_5, MLK_KEY_KP_5 }, { SDLK_KP_6, MLK_KEY_KP_6 }, { SDLK_KP_7, MLK_KEY_KP_7 }, { SDLK_KP_8, MLK_KEY_KP_8 }, { SDLK_KP_9, MLK_KEY_KP_9 }, { SDLK_KP_0, MLK_KEY_KP_0 }, { SDLK_KP_PERIOD, MLK_KEY_KP_PERIOD }, { SDLK_KP_COMMA, MLK_KEY_KP_COMMA }, { SDLK_MENU, MLK_KEY_MENU }, { SDLK_MUTE, MLK_KEY_MUTE }, { SDLK_VOLUMEUP, MLK_KEY_VOLUME_UP }, { SDLK_VOLUMEDOWN, MLK_KEY_VOLUME_DOWN }, { SDLK_LCTRL, MLK_KEY_LCTRL }, { SDLK_LSHIFT, MLK_KEY_LSHIFT }, { SDLK_LALT, MLK_KEY_LALT }, { SDLK_LGUI, MLK_KEY_LSUPER }, { SDLK_RCTRL, MLK_KEY_RCTRL }, { SDLK_RSHIFT, MLK_KEY_RSHIFT }, { SDLK_RALT, MLK_KEY_RALT }, { SDLK_RGUI, MLK_KEY_RSUPER }, { 0, -1 } }; /* Maintain with enum mouse_button constants in mouse.h */ static const struct { int key; enum mlk_mouse_button value; } buttons[] = { { SDL_BUTTON_LEFT, MLK_MOUSE_BUTTON_LEFT }, { SDL_BUTTON_MIDDLE, MLK_MOUSE_BUTTON_MIDDLE }, { SDL_BUTTON_RIGHT, MLK_MOUSE_BUTTON_RIGHT }, { -1, MLK_MOUSE_BUTTON_NONE } }; /* Maintain with enum mlk_gamepad_button in gamepad.h */ static const struct { int button; enum mlk_gamepad_button value; } pads[] = { { SDL_CONTROLLER_BUTTON_A, MLK_GAMEPAD_BUTTON_A }, { SDL_CONTROLLER_BUTTON_B, MLK_GAMEPAD_BUTTON_B }, { SDL_CONTROLLER_BUTTON_X, MLK_GAMEPAD_BUTTON_X }, { SDL_CONTROLLER_BUTTON_Y, MLK_GAMEPAD_BUTTON_Y }, { SDL_CONTROLLER_BUTTON_BACK, MLK_GAMEPAD_BUTTON_BACK }, { SDL_CONTROLLER_BUTTON_GUIDE, MLK_GAMEPAD_BUTTON_LOGO }, { SDL_CONTROLLER_BUTTON_START, MLK_GAMEPAD_BUTTON_START }, { SDL_CONTROLLER_BUTTON_LEFTSTICK, MLK_GAMEPAD_BUTTON_LTHUMB }, { SDL_CONTROLLER_BUTTON_RIGHTSTICK, MLK_GAMEPAD_BUTTON_RTHUMB }, { SDL_CONTROLLER_BUTTON_LEFTSHOULDER, MLK_GAMEPAD_BUTTON_LSHOULDER }, { SDL_CONTROLLER_BUTTON_RIGHTSHOULDER, MLK_GAMEPAD_BUTTON_RSHOULDER }, { SDL_CONTROLLER_BUTTON_DPAD_UP, MLK_GAMEPAD_BUTTON_UP }, { SDL_CONTROLLER_BUTTON_DPAD_DOWN, MLK_GAMEPAD_BUTTON_DOWN }, { SDL_CONTROLLER_BUTTON_DPAD_LEFT, MLK_GAMEPAD_BUTTON_LEFT }, { SDL_CONTROLLER_BUTTON_DPAD_RIGHT, MLK_GAMEPAD_BUTTON_RIGHT }, { -1, MLK_GAMEPAD_BUTTON_UNKNOWN } }; static void convert_key(const SDL_Event *event, union mlk_event *ev) { ev->type = event->type == SDL_KEYDOWN ? MLK_EVENT_KEYDOWN : MLK_EVENT_KEYUP; ev->key.key = MLK_KEY_UNKNOWN; for (size_t i = 0; keymap[i].key != 0; ++i) { if (keymap[i].key == event->key.keysym.sym) { ev->key.key = keymap[i].value; break; } } } static void convert_mouse(const SDL_Event *event, union mlk_event *ev) { ev->type = MLK_EVENT_MOUSE; ev->mouse.buttons = 0; ev->mouse.x = event->motion.x; ev->mouse.y = event->motion.y; if (event->motion.state & SDL_BUTTON_LMASK) ev->mouse.buttons |= MLK_MOUSE_BUTTON_LEFT; if (event->motion.state & SDL_BUTTON_MMASK) ev->mouse.buttons |= MLK_MOUSE_BUTTON_MIDDLE; if (event->motion.state & SDL_BUTTON_RMASK) ev->mouse.buttons |= MLK_MOUSE_BUTTON_RIGHT; } static void convert_click(const SDL_Event *event, union mlk_event *ev) { ev->type = event->type == SDL_MOUSEBUTTONDOWN ? MLK_EVENT_CLICKDOWN : MLK_EVENT_CLICKUP; ev->click.button = MLK_MOUSE_BUTTON_NONE; ev->click.x = event->button.x; ev->click.y = event->button.y; ev->click.clicks = event->button.clicks; for (size_t i = 0; buttons[i].value != MLK_MOUSE_BUTTON_NONE; ++i) { if (buttons[i].key == event->button.button) { ev->click.button = buttons[i].value; break; } } } static void convert_pad(const SDL_Event *event, union mlk_event *ev) { ev->type = event->type == SDL_CONTROLLERBUTTONDOWN ? MLK_EVENT_PADDOWN : MLK_EVENT_PADUP; for (size_t i = 0; pads[i].value != MLK_GAMEPAD_BUTTON_UNKNOWN; ++i) { if (pads[i].button == event->cbutton.button) { ev->pad.button = pads[i].value; break; } } } static const struct { int axis; enum mlk_gamepad_axis value; } axises[] = { { SDL_CONTROLLER_AXIS_LEFTX, MLK_GAMEPAD_AXIS_LX }, { SDL_CONTROLLER_AXIS_LEFTY, MLK_GAMEPAD_AXIS_LY }, { SDL_CONTROLLER_AXIS_RIGHTX, MLK_GAMEPAD_AXIS_RX }, { SDL_CONTROLLER_AXIS_RIGHTY, MLK_GAMEPAD_AXIS_RY }, { SDL_CONTROLLER_AXIS_TRIGGERLEFT, MLK_GAMEPAD_AXIS_LTRIGGER }, { SDL_CONTROLLER_AXIS_TRIGGERRIGHT, MLK_GAMEPAD_AXIS_RTRIGGER }, { -1, MLK_GAMEPAD_AXIS_UNKNOWN } }; static void convert_axis(const SDL_Event *event, union mlk_event *ev) { ev->type = MLK_EVENT_AXIS; ev->axis.value = event->caxis.value; for (size_t i = 0; axises[i].value != MLK_GAMEPAD_AXIS_UNKNOWN; ++i) { if (axises[i].axis == event->caxis.axis) { ev->axis.axis = axises[i].value; break; } } } int mlk_event_poll(union mlk_event *ev) { SDL_Event event; memset(ev, 0, sizeof (*ev)); /* * Loop until we find an event we want to report, we skip unneeded * ones. */ while (SDL_PollEvent(&event)) { switch (event.type) { case SDL_QUIT: ev->type = MLK_EVENT_QUIT; return 1; case SDL_KEYDOWN: case SDL_KEYUP: convert_key(&event, ev); return 1; case SDL_MOUSEMOTION: convert_mouse(&event, ev); return 1; case SDL_MOUSEBUTTONDOWN: case SDL_MOUSEBUTTONUP: convert_click(&event, ev); return 1; case SDL_CONTROLLERBUTTONDOWN: case SDL_CONTROLLERBUTTONUP: convert_pad(&event, ev); return 1; case SDL_CONTROLLERAXISMOTION: convert_axis(&event, ev); return 1; default: continue; } } return 0; }