aboutsummaryrefslogtreecommitdiff
path: root/modules/libkey/libkey.c
diff options
context:
space:
mode:
Diffstat (limited to 'modules/libkey/libkey.c')
-rw-r--r--modules/libkey/libkey.c472
1 files changed, 472 insertions, 0 deletions
diff --git a/modules/libkey/libkey.c b/modules/libkey/libkey.c
new file mode 100644
index 0000000..6b3ccde
--- /dev/null
+++ b/modules/libkey/libkey.c
@@ -0,0 +1,472 @@
+/*
+ * Copyright © 2006-2016 SplinterGU (Fenix/Bennugd)
+ * Copyright © 2002-2006 Fenix Team (Fenix)
+ * Copyright © 1999-2002 José Luis Cebrián Pagüe (Fenix)
+ *
+ * This file is part of Bennu - Game Development
+ *
+ * This software is provided 'as-is', without any express or implied
+ * warranty. In no event will the authors be held liable for any damages
+ * arising from the use of this software.
+ *
+ * Permission is granted to anyone to use this software for any purpose,
+ * including commercial applications, and to alter it and redistribute it
+ * freely, subject to the following restrictions:
+ *
+ * 1. The origin of this software must not be misrepresented; you must not
+ * claim that you wrote the original software. If you use this software
+ * in a product, an acknowledgment in the product documentation would be
+ * appreciated but is not required.
+ *
+ * 2. Altered source versions must be plainly marked as such, and must not be
+ * misrepresented as being the original software.
+ *
+ * 3. This notice may not be removed or altered from any source
+ * distribution.
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+
+#include <SDL.h>
+
+#include "xctype.h"
+#include "bgddl.h"
+#include "dlvaracc.h"
+
+#define __LIBKEY
+#include "libkey.h"
+
+/* ---------------------------------------------------------------------- */
+
+#include "libkey_exports.h"
+
+/* ---------------------------------------------------------------------- */
+
+typedef struct
+{
+ SDLKey sym; /* SDL virtual keysym */
+ SDLMod mod; /* current key modifiers */
+ HOTKEY_CALLBACK callback;
+} hotkey ;
+
+static hotkey * hotkey_list = NULL ;
+static int hotkey_allocated = 0 ;
+static int hotkey_count = 0 ;
+
+/* ---------------------------------------------------------------------- */
+
+/* Publicas */
+key_equiv key_table[127] ; /* Now we have a search table with equivs */
+unsigned char * keystate = NULL; /* Pointer to key states */
+
+/* ---------------------------------------------------------------------- */
+
+static int sdl_equiv[SDLK_LAST+1] ;
+
+static int equivs[] =
+{
+ SDLK_RCTRL, 1,
+ SDLK_1, 2,
+ SDLK_KP1, 2,
+ SDLK_2, 3,
+ SDLK_KP2, 3,
+ SDLK_3, 4,
+ SDLK_KP3, 4,
+ SDLK_4, 5,
+ SDLK_KP4, 5,
+ SDLK_5, 6,
+ SDLK_KP5, 6,
+ SDLK_6, 7,
+ SDLK_KP6, 7,
+ SDLK_7, 8,
+ SDLK_KP7, 8,
+ SDLK_8, 9,
+ SDLK_KP8, 9,
+ SDLK_9, 10,
+ SDLK_KP9, 10,
+ SDLK_0, 11,
+ SDLK_KP0, 11,
+ SDLK_MINUS, 12,
+ SDLK_EQUALS, 13,
+ SDLK_BACKSPACE, 14,
+ SDLK_TAB, 15,
+ SDLK_q, 16,
+ SDLK_w, 17,
+ SDLK_e, 18,
+ SDLK_r, 19,
+ SDLK_t, 20,
+ SDLK_y, 21,
+ SDLK_u, 22,
+ SDLK_i, 23,
+ SDLK_o, 24,
+ SDLK_p, 25,
+ SDLK_LEFTBRACKET, 26,
+ SDLK_RIGHTBRACKET, 27,
+ SDLK_RETURN, 28,
+ SDLK_KP_ENTER, 28,
+ SDLK_LCTRL, 29,
+ SDLK_RCTRL, 29,
+ SDLK_LCTRL, 96,
+ SDLK_RCTRL, 94,
+ SDLK_a, 30,
+ SDLK_s, 31,
+ SDLK_d, 32,
+ SDLK_f, 33,
+ SDLK_g, 34,
+ SDLK_h, 35,
+ SDLK_j, 36,
+ SDLK_k, 37,
+ SDLK_l, 38,
+ SDLK_SEMICOLON, 39,
+ SDLK_QUOTE, 40,
+ SDLK_BACKQUOTE, 41,
+ SDLK_LSHIFT, 42,
+ SDLK_BACKSLASH, 43,
+ SDLK_z, 44,
+ SDLK_x, 45,
+ SDLK_c, 46,
+ SDLK_v, 47,
+ SDLK_b, 48,
+ SDLK_n, 49,
+ SDLK_m, 50,
+ SDLK_COMMA, 51,
+ SDLK_PERIOD, 52,
+ SDLK_KP_PERIOD, 52,
+ SDLK_SLASH, 53,
+ SDLK_KP_DIVIDE, 53,
+ SDLK_RSHIFT, 54,
+ /* SDLK_PRINT, 55,*/
+ SDLK_KP_MULTIPLY, 55,
+ SDLK_LALT, 56,
+ SDLK_RALT, 56,
+ SDLK_LALT, 95,
+ SDLK_RALT, 93,
+ SDLK_MODE, 93,
+ SDLK_MODE, 56,
+ SDLK_RMETA, 56,
+ SDLK_LMETA, 56,
+ SDLK_SPACE, 57,
+ SDLK_CAPSLOCK, 58,
+ SDLK_F1, 59,
+ SDLK_F2, 60,
+ SDLK_F3, 61,
+ SDLK_F4, 62,
+ SDLK_F5, 63,
+ SDLK_F6, 64,
+ SDLK_F7, 65,
+ SDLK_F8, 66,
+ SDLK_F9, 67,
+ SDLK_F10, 68,
+ SDLK_NUMLOCK, 69,
+ SDLK_SCROLLOCK, 70,
+ SDLK_HOME, 71,
+ SDLK_UP, 72,
+ SDLK_PAGEUP, 73,
+ SDLK_KP_MINUS, 74,
+ SDLK_LEFT, 75,
+ SDLK_RIGHT, 77,
+ SDLK_KP_PLUS, 78,
+ SDLK_END, 79,
+ SDLK_DOWN, 80,
+ SDLK_PAGEDOWN, 81,
+ SDLK_INSERT, 82,
+ SDLK_DELETE, 83,
+ SDLK_F11, 87,
+ SDLK_F12, 88,
+ SDLK_LESS, 89,
+ SDLK_PLUS, 90,
+ SDLK_GREATER, 91,
+ SDLK_QUESTION, 92,
+ SDLK_CARET, 93,
+ SDLK_SYSREQ, 55,
+ SDLK_PAUSE, 95,
+ SDLK_MENU, 97,
+ SDLK_LSUPER, 98,
+ SDLK_RSUPER, 99,
+ SDLK_COMPOSE, 99,
+ -1, -1
+} ;
+
+/* ---------------------------------------------------------------------- */
+
+enum {
+ SHIFTSTATUS = 0,
+ ASCII,
+ SCANCODE
+};
+
+/* ---------------------------------------------------------------------- */
+/* Son las variables que se desea acceder. */
+/* El interprete completa esta estructura, si la variable existe. */
+/* (usada en tiempo de ejecucion) */
+
+DLVARFIXUP __bgdexport( libkey, globals_fixup )[] =
+{
+ /* Nombre de variable global, puntero al dato, tamaño del elemento, cantidad de elementos */
+ { "shift_status" , NULL, -1, -1 },
+ { "ascii" , NULL, -1, -1 },
+ { "scan_code" , NULL, -1, -1 },
+ { NULL , NULL, -1, -1 }
+};
+
+/* ---------------------------------------------------------------------- */
+
+static void add_key_equiv( int equiv, int keyconst )
+{
+ key_equiv * curr = &key_table[keyconst] ;
+
+ if ( curr->next != NULL ) while ( curr->next != NULL ) curr = curr->next ;
+
+ if ( curr->sdlk_equiv != 0 )
+ {
+ curr->next = malloc( sizeof( key_equiv ) ) ;
+ curr = curr->next ;
+ curr->next = NULL ;
+ }
+
+ curr->sdlk_equiv = equiv ;
+}
+
+/* ---------------------------------------------------------------------- */
+
+void hotkey_add( int mod, int sym, HOTKEY_CALLBACK callback )
+{
+ if ( hotkey_count >= hotkey_allocated )
+ {
+ hotkey_allocated = hotkey_count + 5;
+ hotkey_list = realloc( hotkey_list, hotkey_allocated * sizeof( hotkey_list[0] ) );
+ }
+
+ if ( !hotkey_list )
+ {
+ fprintf( stderr, "No memory for alloc hotkey\n" );
+ exit( -1 );
+ }
+
+ hotkey_list [hotkey_count].mod = mod;
+ hotkey_list [hotkey_count].sym = sym;
+ hotkey_list [hotkey_count].callback = callback;
+ hotkey_count++;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/*
+ * FUNCTION : process_key_events
+ *
+ * Process all pending SDL events, updating all global variables
+ * and handling debug key presses and cannot be changed
+ *
+ * PARAMS :
+ * None
+ *
+ * RETURN VALUE :
+ * None
+ */
+
+static void process_key_events()
+{
+ SDL_Event e ;
+ SDLMod m ;
+ int k, asc ;
+ int pressed ;
+ key_equiv * curr ;
+ int keypress ;
+ static struct
+ {
+ int ascii ;
+ int scancode ;
+ }
+ keyring [64] ;
+ static int keyring_start = 0, keyring_tail = 0 ;
+ int ignore_key, n;
+
+ /* Actualizar eventos */
+
+ keypress = 0 ;
+ m = SDL_GetModState() ;
+
+ /* Procesa los eventos pendientes */
+ /* Reset ascii and scancode if last key was released... */
+ /* must check all the linked equivs */
+
+ pressed = 0 ;
+ if ( GLODWORD( libkey, SCANCODE ) )
+ {
+ curr = &key_table[GLODWORD( libkey, SCANCODE )] ;
+ while ( curr != NULL && pressed == 0 )
+ {
+ if ( keystate[curr->sdlk_equiv] ) pressed = 1 ;
+ curr = curr->next ;
+ }
+ }
+
+ if ( !pressed )
+ {
+ GLODWORD( libkey, ASCII ) = 0 ;
+ GLODWORD( libkey, SCANCODE ) = 0 ;
+ }
+
+ while ( SDL_PeepEvents( &e, 1, SDL_GETEVENT, SDL_EVENTMASK(SDL_KEYDOWN)|SDL_EVENTMASK(SDL_KEYUP) ) > 0 )
+ {
+ switch ( e.type )
+ {
+ case SDL_KEYDOWN:
+ ignore_key = 0;
+ /* KeyDown HotKey */
+ if ( hotkey_count )
+ for ( n = 0; n < hotkey_count; n++ )
+ {
+ if ((( hotkey_list[n].mod & e.key.keysym.mod ) == hotkey_list[n].mod ) &&
+ ( !hotkey_list[n].sym || ( hotkey_list[n].sym == e.key.keysym.sym ) ) )
+ {
+ ignore_key = hotkey_list[n].callback( e.key.keysym );
+ }
+ }
+ /* KeyDown HotKey */
+
+ if ( ignore_key ) break ;
+
+ /* Almacena la pulsación de la tecla */
+
+ k = sdl_equiv[e.key.keysym.sym];
+
+ m = e.key.keysym.mod ;
+
+ if ( !keypress )
+ {
+ GLODWORD( libkey, SCANCODE ) = k ;
+ if ( e.key.keysym.unicode )
+ {
+ asc = win_to_dos[e.key.keysym.unicode & 0xFF] ;
+
+ /* ascii mayusculas */
+ if ( asc >= 'a' && asc <= 'z' && ( m & KMOD_LSHIFT || m & KMOD_RSHIFT || keystate[SDLK_CAPSLOCK] ) )
+ asc -= 0x20 ;
+ }
+ else
+ {
+ asc = 0 ; /* NON PRINTABLE */
+ }
+
+ GLODWORD( libkey, ASCII ) = asc ;
+ keypress = 1 ;
+ }
+ else
+ {
+ keyring[keyring_tail].scancode = k ;
+ if ( e.key.keysym.unicode )
+ {
+ asc = win_to_dos[e.key.keysym.unicode & 0x7F] ;
+
+ /*ascii mayusculas */
+ if ( asc >= 'a' && asc <= 'z' && ( m & KMOD_LSHIFT || m & KMOD_RSHIFT || keystate[SDLK_CAPSLOCK] ) )
+ asc -= 0x20 ;
+ }
+ else
+ {
+ asc = 0 ; /* NON PRINTABLE */
+ }
+ keyring[keyring_tail].ascii = asc ;
+ if ( ++keyring_tail == 64 ) keyring_tail = 0 ;
+ }
+
+ break ;
+
+ case SDL_KEYUP:
+ /* Do nothing, Bennu is key_up unsensitive */
+ break ;
+ }
+ }
+
+ if ( !keypress && keyring_start != keyring_tail )
+ {
+ GLODWORD( libkey, ASCII ) = keyring[keyring_start].ascii ;
+ GLODWORD( libkey, SCANCODE ) = keyring[keyring_start].scancode ;
+ if ( ++keyring_start == 64 ) keyring_start = 0 ;
+ }
+
+ /* Now actualized every frame... */
+ GLODWORD( libkey, SHIFTSTATUS ) =
+ ( ( m & KMOD_RSHIFT ) ? STAT_RSHIFT : 0 ) |
+ ( ( m & KMOD_LSHIFT ) ? STAT_LSHIFT : 0 ) |
+
+ ( ( m & KMOD_CTRL ) ? STAT_CTRL : 0 ) |
+ ( ( m & KMOD_ALT ) ? STAT_ALT : 0 ) |
+
+ ( ( m & KMOD_RCTRL ) ? STAT_RCTRL : 0 ) |
+ ( ( m & KMOD_LCTRL ) ? STAT_LCTRL : 0 ) |
+
+ ( ( m & KMOD_RALT ) ? STAT_RALT : 0 ) |
+ ( ( m & KMOD_LALT ) ? STAT_LALT : 0 ) |
+
+ ( ( m & KMOD_NUM ) ? STAT_NUM : 0 ) |
+ ( ( m & KMOD_CAPS ) ? STAT_CAPS : 0 ) |
+ ( ( m & KMOD_SHIFT ) ? STAT_SHIFT : 0 ) ;
+}
+
+/* ---------------------------------------------------------------------- */
+
+/* Bigest priority first execute
+ Lowest priority last execute */
+
+HOOK __bgdexport( libkey, handler_hooks )[] =
+{
+ { 4900, process_key_events },
+ { 0, NULL }
+} ;
+
+/* ---------------------------------------------------------------------- */
+/* Funciones de inicializacion del modulo/plugin */
+
+void __bgdexport( libkey, module_initialize )()
+{
+ int * ptr = equivs ;
+
+ if ( !SDL_WasInit( SDL_INIT_VIDEO ) ) SDL_InitSubSystem( SDL_INIT_VIDEO );
+
+ memset( sdl_equiv, 0, sizeof( sdl_equiv ) );
+ memset( key_table, 0, sizeof( key_table ) ) ;
+
+ while ( *ptr != -1 )
+ {
+ sdl_equiv[*ptr] = ptr[1] ;
+ add_key_equiv( ptr[0], ptr[1] ) ;
+ ptr += 2 ;
+ }
+
+ if ( !keystate ) keystate = SDL_GetKeyState( NULL );
+
+ SDL_EnableUNICODE( 1 );
+}
+
+/* ---------------------------------------------------------------------- */
+
+void __bgdexport( libkey, module_finalize )()
+{
+ /* FREE used key_equivs... note base 127 equivs are static not allocated... */
+ int i ;
+ key_equiv * aux ;
+ key_equiv * curr = key_table ;
+
+ for ( i = 0;i < 127;i++ )
+ {
+ if ( curr->next != NULL )
+ {
+ curr = curr->next ;
+ while ( curr->next != NULL )
+ {
+ aux = curr ;
+ curr = curr->next;
+ free( aux ) ;
+ }
+ free( curr ) ;
+ }
+ }
+
+ if ( SDL_WasInit( SDL_INIT_VIDEO ) ) SDL_QuitSubSystem( SDL_INIT_VIDEO );
+}
+
+/* ---------------------------------------------------------------------- */