From ea1947ffcc606d757357398b24e74a3f4ecefa07 Mon Sep 17 00:00:00 2001 From: neonloop Date: Wed, 20 Oct 2021 14:54:27 +0000 Subject: Initial commit from steward-fu release --- modules/libkey/libkey.c | 472 ++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 472 insertions(+) create mode 100644 modules/libkey/libkey.c (limited to 'modules/libkey/libkey.c') 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 +#include + +#include + +#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 ); +} + +/* ---------------------------------------------------------------------- */ -- cgit v1.2.3