mirror of
https://github.com/scp-fs2open/fs2open.github.com.git
synced 2026-11-10 04:31:34 -10:00
Conflicts: .gitignore code/Makefile.am code/ai/ai.h code/ai/ai_profiles.cpp code/ai/ai_profiles.h code/ai/aibig.cpp code/ai/aicode.cpp code/ai/aiturret.cpp code/asteroid/asteroid.cpp code/asteroid/asteroid.h code/bmpman/bm_internal.h code/bmpman/bmpman.cpp code/bmpman/bmpman.h code/camera/camera.cpp code/camera/camera.h code/cfile/cfile.cpp code/cmdline/cmdline.cpp code/cmdline/cmdline.h code/controlconfig/controlsconfig.h code/controlconfig/controlsconfigcommon.cpp code/cutscene/movie.cpp code/cutscene/oggplayer.cpp code/debugconsole/consoleparse.cpp code/fred2/campaigneditordlg.cpp code/fred2/fred.cpp code/fred2/fred.rc code/fred2/missionsave.cpp code/fred2/resource.h code/fred2/sexp_tree.cpp code/fred2/sexp_tree.h code/fred2/shipflagsdlg.cpp code/fred2/shipflagsdlg.h code/fred2/shiptexturesdlg.cpp code/fred2/voiceactingmanager.cpp code/freespace2/freespace.cpp code/freespace2/freespace.rc code/gamehelp/contexthelp.cpp code/globalincs/alphacolors.cpp code/globalincs/alphacolors.h code/globalincs/version.h code/globalincs/vmallocator.h code/globalincs/windebug.cpp code/graphics/2d.cpp code/graphics/font.cpp code/graphics/generic.cpp code/graphics/generic.h code/graphics/grinternal.h code/graphics/gropengl.cpp code/graphics/gropengldraw.cpp code/graphics/gropenglextension.h code/graphics/gropenglpostprocessing.cpp code/graphics/gropenglstate.cpp code/graphics/gropenglstate.h code/graphics/gropengltexture.cpp code/graphics/gropengltnl.cpp code/hud/hud.cpp code/hud/hud.h code/hud/hudconfig.cpp code/hud/hudlock.cpp code/hud/hudmessage.cpp code/hud/hudparse.cpp code/hud/hudreticle.cpp code/hud/hudreticle.h code/hud/hudshield.cpp code/hud/hudsquadmsg.cpp code/hud/hudtarget.cpp code/hud/hudtarget.h code/hud/hudtargetbox.cpp code/inetfile/cftp.cpp code/inetfile/chttpget.cpp code/io/joy.cpp code/io/joy_ff.cpp code/io/key.cpp code/io/keycontrol.cpp code/io/mouse.cpp code/io/timer.cpp code/localization/localize.cpp code/localization/localize.h code/math/fvi.cpp code/math/vecmat.cpp code/menuui/credits.cpp code/menuui/mainhallmenu.cpp code/menuui/mainhallmenu.h code/menuui/optionsmenumulti.cpp code/menuui/playermenu.cpp code/mission/missionbriefcommon.cpp code/mission/missioncampaign.cpp code/mission/missiongoals.h code/mission/missionmessage.cpp code/mission/missionparse.cpp code/mission/missionparse.h code/missionui/missionbrief.cpp code/missionui/missioncmdbrief.cpp code/missionui/missiondebrief.cpp code/missionui/missionscreencommon.cpp code/missionui/missionshipchoice.cpp code/missionui/missionweaponchoice.cpp code/missionui/redalert.cpp code/missionui/redalert.h code/mod_table/mod_table.cpp code/mod_table/mod_table.h code/model/model.h code/model/modelcollide.cpp code/model/modelinterp.cpp code/model/modelread.cpp code/network/multi.cpp code/network/multi_dogfight.cpp code/network/multi_ingame.cpp code/network/multi_log.cpp code/network/multi_rate.cpp code/network/multiteamselect.cpp code/network/multiui.cpp code/network/multiutil.cpp code/network/stand_gui-unix.cpp code/object/collideshipship.cpp code/object/collideshipweapon.cpp code/object/object.cpp code/object/object.h code/object/objectsnd.cpp code/object/objectsort.cpp code/osapi/osapi.cpp code/osapi/osapi_unix.cpp code/osapi/outwnd.h code/parse/generic_log.cpp code/parse/lua.cpp code/parse/parselo.cpp code/parse/parselo.h code/parse/scripting.cpp code/parse/scripting.h code/parse/sexp.cpp code/parse/sexp.h code/physics/physics.cpp code/pilotfile/csg.cpp code/pilotfile/csg_convert.cpp code/pilotfile/pilotfile.cpp code/pilotfile/pilotfile_convert.h code/playerman/playercontrol.cpp code/radar/radardradis.cpp code/radar/radardradis.h code/radar/radarsetup.cpp code/radar/radarsetup.h code/ship/ship.cpp code/ship/ship.h code/ship/shipfx.cpp code/ship/shiphit.cpp code/sound/audiostr.cpp code/sound/ds.cpp code/sound/openal.cpp code/sound/rtvoice.cpp code/sound/sound.cpp code/sound/voicerec.cpp code/stats/medals.cpp code/stats/medals.h code/stats/scoring.cpp code/ui/ui.h code/weapon/beam.cpp code/weapon/weapon.h code/weapon/weapons.cpp code/wxfred2/aboutbox.cpp code/wxfred2/campaigneditor.cpp code/wxfred2/campaigneditor.h code/wxfred2/commandbriefingeditor.cpp code/wxfred2/debriefingeditor.cpp code/wxfred2/fredframe.cpp code/wxfred2/fredframe.h code/wxfred2/missionspecseditor.cpp code/wxfred2/missionspecseditor.h code/wxfred2/voiceactingmanagereditor.cpp code/wxfred2/wxfred.xrc code/wxfred2/wxfred2.cpp code/wxfred2/wxfred2.h configure.ac fs2open.Doxyfile jansson/LICENSE jansson/dump.c jansson/hashtable.c jansson/hashtable.h jansson/jansson.h jansson/jansson_config.h jansson/jansson_private.h jansson/load.c jansson/memory.c jansson/pack_unpack.c jansson/strbuffer.c jansson/strbuffer.h jansson/strconv.c jansson/utf.c jansson/utf.h jansson/value.c libpng/png.c libpng/png.h libpng/pngconf.h libpng/pngdebug.h libpng/pngerror.c libpng/pngget.c libpng/pnginfo.h libpng/pnglibconf.h libpng/pngmem.c libpng/pngpread.c libpng/pngpriv.h libpng/pngread.c libpng/pngrio.c libpng/pngrtran.c libpng/pngrutil.c libpng/pngset.c libpng/pngstruct.h libpng/pngtrans.c libpng/pngwio.c libpng/pngwrite.c libpng/pngwtran.c libpng/pngwutil.c projects/Eclipse/Freespace2/.project projects/MSVC_2005/Fred2.vcproj projects/MSVC_2005/Freespace2.sln projects/MSVC_2005/Freespace2.vcproj projects/MSVC_2005/code.vcproj projects/MSVC_2005/wxFRED2.vcproj projects/MSVC_2008/Fred2.vcproj projects/MSVC_2008/Freespace2.doxproj projects/MSVC_2008/Freespace2.vcproj projects/MSVC_2008/code.vcproj projects/MSVC_2010/Fred2.vcxproj projects/MSVC_2010/Freespace2.vcxproj projects/MSVC_2010/code.vcxproj projects/MSVC_2010/code.vcxproj.filters projects/MSVC_2010/wxFRED2.vcxproj projects/MSVC_2011/Fred2.vcxproj projects/MSVC_2011/Freespace2.vcxproj projects/MSVC_2011/code.vcxproj projects/MSVC_2011/code.vcxproj.filters projects/MSVC_2011/wxFRED2.vcxproj projects/MSVC_2013/Fred2.vcxproj projects/MSVC_2013/Freespace2.vcxproj projects/MSVC_2013/code.vcxproj projects/MSVC_2013/code.vcxproj.filters projects/MSVC_2013/libjpeg.vcxproj projects/MSVC_2013/liblua.vcxproj projects/MSVC_2013/libpng.vcxproj projects/MSVC_2013/wxFRED2.vcxproj projects/MSVC_2013/zlib.vcxproj projects/MSVC_6/Fred2.dsp projects/MSVC_6/Freespace2.dsp projects/MSVC_6/code.dsp projects/MSVC_6/wxFRED2.dsp projects/Xcode/English.lproj/InfoPlist.strings projects/Xcode/FS2_Open.xcodeproj/project.pbxproj projects/Xcode4/English.lproj/InfoPlist.strings projects/Xcode4/FS2_Open.xcodeproj/project.pbxproj projects/Xcode4/Frameworks.tgz projects/codeblocks/Freespace2/Freespace2.cbp zlib/adler32.c zlib/compress.c zlib/crc32.c zlib/crc32.h zlib/deflate.c zlib/deflate.h zlib/infback.c zlib/inffast.c zlib/inffixed.h zlib/inflate.c zlib/inftrees.c zlib/trees.c zlib/uncompr.c zlib/zconf.h zlib/zlib.h zlib/zutil.c zlib/zutil.h
747 lines
18 KiB
C++
747 lines
18 KiB
C++
/*
|
|
* Copyright (C) Volition, Inc. 1999. All rights reserved.
|
|
*
|
|
* All source code herein is the property of Volition, Inc. You may not sell
|
|
* or otherwise commercially exploit the source or things you created based on the
|
|
* source.
|
|
*
|
|
*/
|
|
|
|
|
|
#include "SDL.h"
|
|
|
|
#include "controlconfig/controlsconfig.h" //For textify scancode
|
|
#include "globalincs/pstypes.h"
|
|
#include "graphics/2d.h"
|
|
#include "io/key.h"
|
|
#include "math/fix.h"
|
|
#include "io/timer.h"
|
|
#include "localization/localize.h"
|
|
#include "parse/scripting.h"
|
|
#include "cmdline/cmdline.h"
|
|
|
|
#define THREADED // to use the proper set of macros
|
|
#include "osapi/osapi.h"
|
|
|
|
|
|
#define KEY_BUFFER_SIZE 16
|
|
|
|
//-------- Variable accessed by outside functions ---------
|
|
ubyte keyd_buffer_type; // 0=No buffer, 1=buffer ASCII, 2=buffer scans
|
|
ubyte keyd_repeat;
|
|
uint keyd_last_pressed;
|
|
uint keyd_last_released;
|
|
ubyte keyd_pressed[NUM_KEYS];
|
|
int keyd_time_when_last_pressed;
|
|
|
|
typedef struct keyboard {
|
|
ushort keybuffer[KEY_BUFFER_SIZE];
|
|
uint time_pressed[KEY_BUFFER_SIZE];
|
|
uint TimeKeyWentDown[NUM_KEYS];
|
|
uint TimeKeyHeldDown[NUM_KEYS];
|
|
uint TimeKeyDownChecked[NUM_KEYS];
|
|
uint NumDowns[NUM_KEYS];
|
|
uint NumUps[NUM_KEYS];
|
|
int down_check[NUM_KEYS]; // nonzero if has been pressed yet this mission
|
|
uint keyhead, keytail;
|
|
} keyboard;
|
|
|
|
keyboard key_data;
|
|
|
|
int key_inited = 0;
|
|
|
|
SDL_mutex* key_lock;
|
|
|
|
//int Backspace_debug=1; // global flag that will enable/disable the backspace key from stopping execution
|
|
// This flag was created since the backspace key is also used to correct mistakes
|
|
// when typing in your pilots callsign. This global flag is checked before execution
|
|
// is stopped.
|
|
|
|
SCP_map<int, int> SDLtoFS2;
|
|
|
|
int ascii_table[128] =
|
|
{ 255, 255, '1', '2', '3', '4', '5', '6', '7', '8', '9', '0', '-', '=',255,255,
|
|
'q', 'w', 'e', 'r', 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 255, 255,
|
|
'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', 39, '`',
|
|
255, '\\', 'z', 'x', 'c', 'v', 'b', 'n', 'm', ',', '.', '/', 255,'*',
|
|
255, ' ', 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255,255,
|
|
255, 255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
|
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
|
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
|
255,255,255,255,255,255,255,255 };
|
|
|
|
int shifted_ascii_table[128] =
|
|
{ 255, 255, '!', '@', '#', '$', '%', '^', '&', '*', '(', ')', '_', '+',255,255,
|
|
'Q', 'W', 'E', 'R', 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 255, 255,
|
|
'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', '"', '~',
|
|
255, '|', 'Z', 'X', 'C', 'V', 'B', 'N', 'M', '<', '>', '?', 255,255,
|
|
255, ' ', 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255, 255,255,255,
|
|
255, 255, 255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
|
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
|
255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,255,
|
|
255,255,255,255,255,255,255,255 };
|
|
|
|
static int Key_numlock_was_on = 0; // Flag to indicate whether NumLock is on at start
|
|
|
|
|
|
int Cheats_enabled = 0;
|
|
int Key_normal_game = 0;
|
|
|
|
void FillSDLArray ()
|
|
{
|
|
SDLtoFS2[SDL_SCANCODE_0] = KEY_0;
|
|
SDLtoFS2[SDL_SCANCODE_1] = KEY_1;
|
|
SDLtoFS2[SDL_SCANCODE_2] = KEY_2;
|
|
SDLtoFS2[SDL_SCANCODE_3] = KEY_3;
|
|
SDLtoFS2[SDL_SCANCODE_4] = KEY_4;
|
|
SDLtoFS2[SDL_SCANCODE_5] = KEY_5;
|
|
SDLtoFS2[SDL_SCANCODE_6] = KEY_6;
|
|
SDLtoFS2[SDL_SCANCODE_7] = KEY_7;
|
|
SDLtoFS2[SDL_SCANCODE_8] = KEY_8;
|
|
SDLtoFS2[SDL_SCANCODE_9] = KEY_9;
|
|
|
|
SDLtoFS2[SDL_SCANCODE_A] = KEY_A;
|
|
SDLtoFS2[SDL_SCANCODE_B] = KEY_B;
|
|
SDLtoFS2[SDL_SCANCODE_C] = KEY_C;
|
|
SDLtoFS2[SDL_SCANCODE_D] = KEY_D;
|
|
SDLtoFS2[SDL_SCANCODE_E] = KEY_E;
|
|
SDLtoFS2[SDL_SCANCODE_F] = KEY_F;
|
|
SDLtoFS2[SDL_SCANCODE_G] = KEY_G;
|
|
SDLtoFS2[SDL_SCANCODE_H] = KEY_H;
|
|
SDLtoFS2[SDL_SCANCODE_I] = KEY_I;
|
|
SDLtoFS2[SDL_SCANCODE_J] = KEY_J;
|
|
SDLtoFS2[SDL_SCANCODE_K] = KEY_K;
|
|
SDLtoFS2[SDL_SCANCODE_L] = KEY_L;
|
|
SDLtoFS2[SDL_SCANCODE_M] = KEY_M;
|
|
SDLtoFS2[SDL_SCANCODE_N] = KEY_N;
|
|
SDLtoFS2[SDL_SCANCODE_O] = KEY_O;
|
|
SDLtoFS2[SDL_SCANCODE_P] = KEY_P;
|
|
SDLtoFS2[SDL_SCANCODE_Q] = KEY_Q;
|
|
SDLtoFS2[SDL_SCANCODE_R] = KEY_R;
|
|
SDLtoFS2[SDL_SCANCODE_S] = KEY_S;
|
|
SDLtoFS2[SDL_SCANCODE_T] = KEY_T;
|
|
SDLtoFS2[SDL_SCANCODE_U] = KEY_U;
|
|
SDLtoFS2[SDL_SCANCODE_V] = KEY_V;
|
|
SDLtoFS2[SDL_SCANCODE_W] = KEY_W;
|
|
SDLtoFS2[SDL_SCANCODE_X] = KEY_X;
|
|
SDLtoFS2[SDL_SCANCODE_Y] = KEY_Y;
|
|
SDLtoFS2[SDL_SCANCODE_Z] = KEY_Z;
|
|
|
|
|
|
SDLtoFS2[SDL_SCANCODE_MINUS] = KEY_MINUS;
|
|
SDLtoFS2[SDL_SCANCODE_EQUALS] = KEY_EQUAL;
|
|
SDLtoFS2[SDL_SCANCODE_SLASH] = KEY_DIVIDE; // No idea - DDOI
|
|
SDLtoFS2[SDL_SCANCODE_BACKSLASH] = KEY_SLASH;
|
|
//SDLtoFS2[SDL_SCANCODE_BACKSLASH] = KEY_SLASH_UK; // ?
|
|
SDLtoFS2[SDL_SCANCODE_COMMA] = KEY_COMMA;
|
|
SDLtoFS2[SDL_SCANCODE_PERIOD] = KEY_PERIOD;
|
|
SDLtoFS2[SDL_SCANCODE_SEMICOLON] = KEY_SEMICOL;
|
|
|
|
SDLtoFS2[SDL_SCANCODE_LEFTBRACKET] = KEY_LBRACKET;
|
|
SDLtoFS2[SDL_SCANCODE_RIGHTBRACKET] = KEY_RBRACKET;
|
|
|
|
SDLtoFS2[SDL_SCANCODE_GRAVE] = KEY_LAPOSTRO;
|
|
SDLtoFS2[SDL_SCANCODE_APOSTROPHE] = KEY_RAPOSTRO;
|
|
|
|
|
|
SDLtoFS2[SDL_SCANCODE_ESCAPE] = KEY_ESC;
|
|
SDLtoFS2[SDL_SCANCODE_RETURN] = KEY_ENTER;
|
|
SDLtoFS2[SDL_SCANCODE_BACKSPACE] = KEY_BACKSP;
|
|
SDLtoFS2[SDL_SCANCODE_TAB] = KEY_TAB;
|
|
SDLtoFS2[SDL_SCANCODE_SPACE] = KEY_SPACEBAR;
|
|
|
|
SDLtoFS2[SDL_SCANCODE_NUMLOCKCLEAR] = KEY_NUMLOCK;
|
|
SDLtoFS2[SDL_SCANCODE_SCROLLLOCK] = KEY_SCROLLOCK;
|
|
SDLtoFS2[SDL_SCANCODE_CAPSLOCK] = KEY_CAPSLOCK;
|
|
|
|
SDLtoFS2[SDL_SCANCODE_LSHIFT] = KEY_LSHIFT;
|
|
SDLtoFS2[SDL_SCANCODE_RSHIFT] = KEY_RSHIFT;
|
|
|
|
SDLtoFS2[SDL_SCANCODE_LALT] = KEY_LALT;
|
|
SDLtoFS2[SDL_SCANCODE_RALT] = KEY_RALT;
|
|
|
|
SDLtoFS2[SDL_SCANCODE_LCTRL] = KEY_LCTRL;
|
|
SDLtoFS2[SDL_SCANCODE_RCTRL] = KEY_RCTRL;
|
|
|
|
SDLtoFS2[SDL_SCANCODE_F1] = KEY_F1;
|
|
SDLtoFS2[SDL_SCANCODE_F2] = KEY_F2;
|
|
SDLtoFS2[SDL_SCANCODE_F3] = KEY_F3;
|
|
SDLtoFS2[SDL_SCANCODE_F4] = KEY_F4;
|
|
SDLtoFS2[SDL_SCANCODE_F5] = KEY_F5;
|
|
SDLtoFS2[SDL_SCANCODE_F6] = KEY_F6;
|
|
SDLtoFS2[SDL_SCANCODE_F7] = KEY_F7;
|
|
SDLtoFS2[SDL_SCANCODE_F8] = KEY_F8;
|
|
SDLtoFS2[SDL_SCANCODE_F9] = KEY_F9;
|
|
SDLtoFS2[SDL_SCANCODE_F10] = KEY_F10;
|
|
SDLtoFS2[SDL_SCANCODE_F11] = KEY_F11;
|
|
SDLtoFS2[SDL_SCANCODE_F12] = KEY_F12;
|
|
|
|
SDLtoFS2[SDL_SCANCODE_KP_0] = KEY_PAD0;
|
|
SDLtoFS2[SDL_SCANCODE_KP_1] = KEY_PAD1;
|
|
SDLtoFS2[SDL_SCANCODE_KP_2] = KEY_PAD2;
|
|
SDLtoFS2[SDL_SCANCODE_KP_3] = KEY_PAD3;
|
|
SDLtoFS2[SDL_SCANCODE_KP_4] = KEY_PAD4;
|
|
SDLtoFS2[SDL_SCANCODE_KP_5] = KEY_PAD5;
|
|
SDLtoFS2[SDL_SCANCODE_KP_6] = KEY_PAD6;
|
|
SDLtoFS2[SDL_SCANCODE_KP_7] = KEY_PAD7;
|
|
SDLtoFS2[SDL_SCANCODE_KP_8] = KEY_PAD8;
|
|
SDLtoFS2[SDL_SCANCODE_KP_9] = KEY_PAD9;
|
|
SDLtoFS2[SDL_SCANCODE_KP_MINUS] = KEY_PADMINUS;
|
|
SDLtoFS2[SDL_SCANCODE_KP_PLUS] = KEY_PADPLUS;
|
|
SDLtoFS2[SDL_SCANCODE_KP_PERIOD] = KEY_PADPERIOD;
|
|
SDLtoFS2[SDL_SCANCODE_KP_DIVIDE] = KEY_PADDIVIDE;
|
|
SDLtoFS2[SDL_SCANCODE_KP_MULTIPLY] = KEY_PADMULTIPLY;
|
|
SDLtoFS2[SDL_SCANCODE_KP_ENTER] = KEY_PADENTER;
|
|
|
|
SDLtoFS2[SDL_SCANCODE_INSERT] = KEY_INSERT;
|
|
SDLtoFS2[SDL_SCANCODE_HOME] = KEY_HOME;
|
|
SDLtoFS2[SDL_SCANCODE_PAGEUP] = KEY_PAGEUP;
|
|
SDLtoFS2[SDL_SCANCODE_DELETE] = KEY_DELETE;
|
|
SDLtoFS2[SDL_SCANCODE_END] = KEY_END;
|
|
SDLtoFS2[SDL_SCANCODE_PAGEDOWN] = KEY_PAGEDOWN;
|
|
SDLtoFS2[SDL_SCANCODE_UP] = KEY_UP;
|
|
SDLtoFS2[SDL_SCANCODE_DOWN] = KEY_DOWN;
|
|
SDLtoFS2[SDL_SCANCODE_LEFT] = KEY_LEFT;
|
|
SDLtoFS2[SDL_SCANCODE_RIGHT] = KEY_RIGHT;
|
|
|
|
SDLtoFS2[SDL_SCANCODE_PRINTSCREEN] = KEY_PRINT_SCRN;
|
|
SDLtoFS2[SDL_SCANCODE_PAUSE] = KEY_PAUSE;
|
|
// SDLtoFS2[SDL_SCANCODE_BREAK] = KEY_BREAK;
|
|
}
|
|
|
|
int key_numlock_is_on()
|
|
{
|
|
const Uint8 *state = SDL_GetKeyboardState(NULL);
|
|
|
|
return state[SDL_SCANCODE_NUMLOCKCLEAR];
|
|
}
|
|
|
|
void key_turn_off_numlock()
|
|
{
|
|
|
|
}
|
|
|
|
void key_turn_on_numlock()
|
|
{
|
|
|
|
}
|
|
|
|
// Convert a BIOS scancode to ASCII.
|
|
// If scancode >= 127, returns 255, meaning there is no corresponding ASCII code.
|
|
// Uses ascii_table and shifted_ascii_table to translate scancode to ASCII.
|
|
int key_to_ascii(int keycode )
|
|
{
|
|
int shifted;
|
|
|
|
if ( !key_inited ) return 255;
|
|
|
|
shifted = keycode & KEY_SHIFTED;
|
|
keycode &= 0xFF;
|
|
|
|
if ( keycode>=127 )
|
|
return 255;
|
|
|
|
if (shifted)
|
|
return shifted_ascii_table[keycode];
|
|
else
|
|
return ascii_table[keycode];
|
|
}
|
|
|
|
// Flush the keyboard buffer.
|
|
// Clear the keyboard array (keyd_pressed).
|
|
void key_flush()
|
|
{
|
|
int i;
|
|
uint CurTime;
|
|
|
|
if ( !key_inited ) return;
|
|
|
|
SDL_LockMutex( key_lock );
|
|
|
|
key_data.keyhead = key_data.keytail = 0;
|
|
|
|
//Clear the keyboard buffer
|
|
for (i=0; i<KEY_BUFFER_SIZE; i++ ) {
|
|
key_data.keybuffer[i] = 0;
|
|
key_data.time_pressed[i] = 0;
|
|
}
|
|
|
|
//Clear the keyboard array
|
|
|
|
CurTime = timer_get_milliseconds();
|
|
|
|
|
|
for (i=0; i<NUM_KEYS; i++ ) {
|
|
keyd_pressed[i] = 0;
|
|
key_data.TimeKeyDownChecked[i] = CurTime;
|
|
key_data.TimeKeyWentDown[i] = CurTime;
|
|
key_data.TimeKeyHeldDown[i] = 0;
|
|
key_data.NumDowns[i]=0;
|
|
key_data.NumUps[i]=0;
|
|
}
|
|
|
|
SDL_UnlockMutex( key_lock );
|
|
}
|
|
|
|
// A nifty function which performs the function:
|
|
// n = (n+1) % KEY_BUFFER_SIZE
|
|
// (assuming positive values of n).
|
|
int add_one( int n )
|
|
{
|
|
n++;
|
|
if ( n >= KEY_BUFFER_SIZE ) n=0;
|
|
return n;
|
|
}
|
|
|
|
// Returns 1 if character waiting... 0 otherwise
|
|
int key_checkch()
|
|
{
|
|
int is_one_waiting = 0;
|
|
|
|
if ( !key_inited ) return 0;
|
|
|
|
SDL_LockMutex( key_lock );
|
|
|
|
if (key_data.keytail != key_data.keyhead){
|
|
is_one_waiting = 1;
|
|
}
|
|
|
|
SDL_UnlockMutex( key_lock );
|
|
|
|
return is_one_waiting;
|
|
}
|
|
|
|
// Return key scancode if a key has been pressed,
|
|
// else return 0.
|
|
// Reads keys out of the key buffer and updates keyhead.
|
|
|
|
//WMC - Added so scripting can get at keys.
|
|
int Current_key_down = 0;
|
|
int key_inkey()
|
|
{
|
|
int key = 0;
|
|
|
|
if ( !key_inited ) return 0;
|
|
|
|
SDL_LockMutex( key_lock );
|
|
|
|
if (key_data.keytail!=key_data.keyhead) {
|
|
key = key_data.keybuffer[key_data.keyhead];
|
|
key_data.keyhead = add_one(key_data.keyhead);
|
|
}
|
|
|
|
SDL_UnlockMutex( key_lock );
|
|
|
|
Current_key_down = key;
|
|
|
|
return key;
|
|
}
|
|
|
|
// Unget a key. Puts it back in the input queue.
|
|
void key_outkey(int key)
|
|
{
|
|
int bufp;
|
|
|
|
if ( !key_inited ) return;
|
|
|
|
SDL_LockMutex( key_lock );
|
|
|
|
bufp = key_data.keytail+1;
|
|
|
|
if (bufp >= KEY_BUFFER_SIZE){
|
|
bufp = 0;
|
|
}
|
|
|
|
key_data.keybuffer[key_data.keytail] = (unsigned short)key;
|
|
|
|
key_data.keytail = bufp;
|
|
|
|
SDL_UnlockMutex( key_lock );
|
|
}
|
|
|
|
|
|
|
|
// Return amount of time last key was held down.
|
|
// This is currently (July 17, 1996) bogus because our timing is
|
|
// not accurate.
|
|
int key_inkey_time(uint * time)
|
|
{
|
|
int key = 0;
|
|
|
|
if ( !key_inited ) {
|
|
*time = 0;
|
|
return 0;
|
|
}
|
|
|
|
SDL_LockMutex( key_lock );
|
|
|
|
if (key_data.keytail!=key_data.keyhead) {
|
|
key = key_data.keybuffer[key_data.keyhead];
|
|
*time = key_data.time_pressed[key_data.keyhead];
|
|
key_data.keyhead = add_one(key_data.keyhead);
|
|
}
|
|
|
|
SDL_UnlockMutex( key_lock );
|
|
|
|
return key;
|
|
}
|
|
|
|
|
|
// Returns scancode of last key pressed, if any (returns 0 if no key pressed)
|
|
// but does not update keyhead pointer.
|
|
int key_peekkey()
|
|
{
|
|
int key = 0;
|
|
|
|
if ( !key_inited ) return 0;
|
|
|
|
SDL_LockMutex( key_lock );
|
|
|
|
if (key_data.keytail!=key_data.keyhead) {
|
|
key = key_data.keybuffer[key_data.keyhead];
|
|
}
|
|
SDL_UnlockMutex( key_lock );
|
|
|
|
return key;
|
|
}
|
|
|
|
// If not installed, uses BIOS and returns getch();
|
|
// Else returns pending key (or waits for one if none waiting).
|
|
int key_getch()
|
|
{
|
|
int dummy=0;
|
|
int in;
|
|
|
|
if ( !key_inited ) return 0;
|
|
|
|
while (!key_checkch()){
|
|
os_poll();
|
|
|
|
dummy++;
|
|
}
|
|
in = key_inkey();
|
|
|
|
return in;
|
|
}
|
|
|
|
// Set global shift_status with modifier results (shift, ctrl, alt).
|
|
uint key_get_shift_status()
|
|
{
|
|
unsigned int shift_status = 0;
|
|
|
|
if ( !key_inited ) return 0;
|
|
|
|
SDL_LockMutex( key_lock );
|
|
|
|
if ( keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT] )
|
|
shift_status |= KEY_SHIFTED;
|
|
|
|
if ( keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT] )
|
|
shift_status |= KEY_ALTED;
|
|
|
|
if ( keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL] )
|
|
shift_status |= KEY_CTRLED;
|
|
|
|
#ifndef NDEBUG
|
|
if (keyd_pressed[KEY_DEBUG_KEY])
|
|
shift_status |= KEY_DEBUGGED;
|
|
#else
|
|
if (keyd_pressed[KEY_DEBUG_KEY]) {
|
|
mprintf(("Cheats_enabled = %i, Key_normal_game = %i\n", Cheats_enabled, Key_normal_game));
|
|
if ((Cheats_enabled) && Key_normal_game) {
|
|
mprintf(("Debug key\n"));
|
|
shift_status |= KEY_DEBUGGED1;
|
|
}
|
|
}
|
|
#endif
|
|
SDL_UnlockMutex( key_lock );
|
|
|
|
return shift_status;
|
|
}
|
|
|
|
// Returns amount of time key (specified by "code") has been down since last call.
|
|
// Returns float, unlike key_down_time() which returns a fix.
|
|
float key_down_timef(uint scancode)
|
|
{
|
|
uint time_down, time;
|
|
uint delta_time;
|
|
|
|
if ( !key_inited ) {
|
|
return 0.0f;
|
|
}
|
|
|
|
if (scancode >= NUM_KEYS) {
|
|
return 0.0f;
|
|
}
|
|
|
|
SDL_LockMutex( key_lock );
|
|
|
|
time = timer_get_milliseconds();
|
|
delta_time = time - key_data.TimeKeyDownChecked[scancode];
|
|
key_data.TimeKeyDownChecked[scancode] = time;
|
|
|
|
if ( delta_time <= 1 ) {
|
|
key_data.TimeKeyWentDown[scancode] = time;
|
|
if (keyd_pressed[scancode]) {
|
|
SDL_UnlockMutex( key_lock );
|
|
return 1.0f;
|
|
} else {
|
|
SDL_UnlockMutex( key_lock );
|
|
return 0.0f;
|
|
}
|
|
}
|
|
|
|
if ( !keyd_pressed[scancode] ) {
|
|
time_down = key_data.TimeKeyHeldDown[scancode];
|
|
key_data.TimeKeyHeldDown[scancode] = 0;
|
|
} else {
|
|
time_down = time - key_data.TimeKeyWentDown[scancode];
|
|
key_data.TimeKeyWentDown[scancode] = time;
|
|
}
|
|
|
|
SDL_UnlockMutex( key_lock );
|
|
|
|
return i2fl(time_down) / i2fl(delta_time);
|
|
}
|
|
|
|
// Returns number of times key has went from up to down since last call.
|
|
int key_down_count(int scancode)
|
|
{
|
|
int n;
|
|
|
|
if ( !key_inited ) return 0;
|
|
if ((scancode<0)|| (scancode>=NUM_KEYS)) return 0;
|
|
|
|
SDL_LockMutex( key_lock );
|
|
|
|
n = key_data.NumDowns[scancode];
|
|
key_data.NumDowns[scancode] = 0;
|
|
|
|
SDL_UnlockMutex( key_lock );
|
|
|
|
return n;
|
|
}
|
|
|
|
|
|
// Returns number of times key has went from down to up since last call.
|
|
int key_up_count(int scancode)
|
|
{
|
|
int n;
|
|
|
|
if ( !key_inited ) return 0;
|
|
if ((scancode<0)|| (scancode>=NUM_KEYS)) return 0;
|
|
|
|
SDL_LockMutex( key_lock );
|
|
|
|
n = key_data.NumUps[scancode];
|
|
key_data.NumUps[scancode] = 0;
|
|
|
|
SDL_UnlockMutex( key_lock );
|
|
|
|
return n;
|
|
}
|
|
|
|
int key_check(int key)
|
|
{
|
|
return key_data.down_check[key];
|
|
}
|
|
|
|
// Add a key up or down code to the key buffer. state=1 -> down, state=0 -> up
|
|
// latency => time difference in ms between when key was actually pressed and now
|
|
//void key_mark( uint code, int state )
|
|
void key_mark( uint code, int state, uint latency )
|
|
{
|
|
uint scancode, breakbit, temp, event_time;
|
|
ushort keycode;
|
|
|
|
if ( !key_inited ) return;
|
|
|
|
SDL_LockMutex( key_lock );
|
|
|
|
// If running in the UK, need to translate their wacky slash scancode to ours
|
|
if ( code == KEY_SLASH_UK ) {
|
|
code = KEY_SLASH;
|
|
}
|
|
|
|
Assert( code < NUM_KEYS );
|
|
|
|
event_time = timer_get_milliseconds() - latency;
|
|
// event_time = timeGetTime() - latency;
|
|
|
|
// Read in scancode
|
|
scancode = code & (NUM_KEYS-1);
|
|
breakbit = !state;
|
|
|
|
if (breakbit) {
|
|
// Key going up
|
|
keyd_last_released = scancode;
|
|
keyd_pressed[scancode] = 0;
|
|
key_data.NumUps[scancode]++;
|
|
|
|
// What is the point of this code? "temp" is never used!
|
|
temp = 0;
|
|
temp |= keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT];
|
|
temp |= keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT];
|
|
temp |= keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL];
|
|
temp |= keyd_pressed[KEY_DEBUG_KEY];
|
|
|
|
if (event_time < key_data.TimeKeyWentDown[scancode]) {
|
|
key_data.TimeKeyHeldDown[scancode] = 0;
|
|
} else {
|
|
key_data.TimeKeyHeldDown[scancode] += event_time - key_data.TimeKeyWentDown[scancode];
|
|
}
|
|
|
|
Current_key_down = scancode;
|
|
if ( keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT] ) {
|
|
Current_key_down |= KEY_SHIFTED;
|
|
}
|
|
|
|
if ( keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT] ) {
|
|
Current_key_down |= KEY_ALTED;
|
|
}
|
|
|
|
if ( keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL] ) {
|
|
Current_key_down |= KEY_CTRLED;
|
|
}
|
|
|
|
Script_system.SetHookVar("Key", 's', textify_scancode(Current_key_down));
|
|
Script_system.RunCondition(CHA_KEYRELEASED);
|
|
Script_system.RemHookVar("Key");
|
|
} else {
|
|
// Key going down
|
|
keyd_last_pressed = scancode;
|
|
keyd_time_when_last_pressed = event_time;
|
|
if (!keyd_pressed[scancode]) {
|
|
// First time down
|
|
key_data.TimeKeyWentDown[scancode] = event_time;
|
|
keyd_pressed[scancode] = 1;
|
|
key_data.NumDowns[scancode]++;
|
|
key_data.down_check[scancode]++;
|
|
|
|
//WMC - For scripting
|
|
Current_key_down = scancode;
|
|
if ( keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT] ) {
|
|
Current_key_down |= KEY_SHIFTED;
|
|
}
|
|
|
|
if ( keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT] ) {
|
|
Current_key_down |= KEY_ALTED;
|
|
}
|
|
|
|
if ( keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL] ) {
|
|
Current_key_down |= KEY_CTRLED;
|
|
}
|
|
|
|
Script_system.SetHookVar("Key", 's', textify_scancode(Current_key_down));
|
|
Script_system.RunCondition(CHA_KEYPRESSED);
|
|
Script_system.RemHookVar("Key");
|
|
} else if (!keyd_repeat) {
|
|
// Don't buffer repeating key if repeat mode is off
|
|
scancode = 0xAA;
|
|
}
|
|
|
|
if ( scancode!=0xAA ) {
|
|
keycode = (unsigned short)scancode;
|
|
|
|
if ( keyd_pressed[KEY_LSHIFT] || keyd_pressed[KEY_RSHIFT] ) {
|
|
keycode |= KEY_SHIFTED;
|
|
}
|
|
|
|
if ( keyd_pressed[KEY_LALT] || keyd_pressed[KEY_RALT] ) {
|
|
keycode |= KEY_ALTED;
|
|
}
|
|
|
|
if ( keyd_pressed[KEY_LCTRL] || keyd_pressed[KEY_RCTRL] ) {
|
|
keycode |= KEY_CTRLED;
|
|
}
|
|
|
|
#ifndef NDEBUG
|
|
if ( keyd_pressed[KEY_DEBUG_KEY] ) {
|
|
keycode |= KEY_DEBUGGED;
|
|
}
|
|
#else
|
|
if ( keyd_pressed[KEY_DEBUG_KEY] ) {
|
|
mprintf(("Cheats_enabled = %i, Key_normal_game = %i\n", Cheats_enabled, Key_normal_game));
|
|
if (Cheats_enabled && Key_normal_game) {
|
|
keycode |= KEY_DEBUGGED1;
|
|
}
|
|
}
|
|
|
|
#endif
|
|
|
|
if ( keycode ) {
|
|
temp = key_data.keytail+1;
|
|
if ( temp >= KEY_BUFFER_SIZE ) temp=0;
|
|
|
|
if (temp!=key_data.keyhead) {
|
|
key_data.keybuffer[key_data.keytail] = keycode;
|
|
key_data.time_pressed[key_data.keytail] = keyd_time_when_last_pressed;
|
|
key_data.keytail = temp;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
SDL_UnlockMutex( key_lock );
|
|
}
|
|
|
|
void key_close()
|
|
{
|
|
if ( !key_inited ) return;
|
|
|
|
if ( Key_numlock_was_on ) {
|
|
key_turn_on_numlock();
|
|
Key_numlock_was_on = 0;
|
|
}
|
|
|
|
key_inited = 0;
|
|
|
|
SDL_DestroyMutex( key_lock );
|
|
}
|
|
|
|
void key_init()
|
|
{
|
|
// Initialize queue
|
|
if ( key_inited ) return;
|
|
key_inited = 1;
|
|
|
|
key_lock = SDL_CreateMutex();
|
|
|
|
SDL_LockMutex(key_lock);
|
|
|
|
FillSDLArray();
|
|
|
|
keyd_time_when_last_pressed = timer_get_milliseconds();
|
|
keyd_buffer_type = 1;
|
|
keyd_repeat = 1;
|
|
|
|
// Clear the keyboard array
|
|
key_flush();
|
|
|
|
SDL_UnlockMutex( key_lock );
|
|
|
|
atexit(key_close);
|
|
}
|
|
|
|
void key_level_init()
|
|
{
|
|
int i;
|
|
|
|
for (i=0; i<NUM_KEYS; i++)
|
|
key_data.down_check[i] = 0;
|
|
}
|
|
|
|
void key_lost_focus()
|
|
{
|
|
if ( !key_inited ) return;
|
|
|
|
key_flush();
|
|
}
|
|
|
|
void key_got_focus()
|
|
{
|
|
if ( !key_inited ) return;
|
|
|
|
key_flush();
|
|
}
|