A few things, first is that I removed the (rather broken) serial

networking support.

Second, I moves keys.c from qw and nq to libs/video/targets when I did
the next thing.

Existing user configs which do binds, sledge hammer. Sledge hammer,
existing user configs which do binds. *WHACK* *WHACK* *WHACK*

See, much nicer now.

Someone should document it, and fix all targets which don't use SDL for
input. (I honestly don't expect svgalib and the like to ever be fixed.)
This commit is contained in:
Zephaniah E. Hull 2001-08-16 09:19:36 +00:00
parent 0c7f011f4b
commit 20adccc9e4
21 changed files with 2043 additions and 4313 deletions

View file

@ -35,140 +35,305 @@
// these are the key numbers that should be passed to Key_Event
typedef enum {
K_TAB = 9,
K_ENTER = 13,
K_ESCAPE = 27,
K_SPACE = 32,
/* The keyboard syms have been cleverly chosen to map to ASCII */
K_UNKNOWN = 0,
K_FIRST = 0,
K_BACKSPACE = 8,
K_TAB = 9,
K_CLEAR = 12,
K_RETURN = 13,
K_PAUSE = 19,
K_ESCAPE = 27,
K_SPACE = 32,
K_EXCLAIM = 33,
K_QUOTEDBL = 34,
K_HASH = 35,
K_DOLLAR = 36,
K_AMPERSAND = 38,
K_QUOTE = 39,
K_LEFTPAREN = 40,
K_RIGHTPAREN = 41,
K_ASTERISK = 42,
K_PLUS = 43,
K_COMMA = 44,
K_MINUS = 45,
K_PERIOD = 46,
K_SLASH = 47,
K_0 = 48,
K_1 = 49,
K_2 = 50,
K_3 = 51,
K_4 = 52,
K_5 = 53,
K_6 = 54,
K_7 = 55,
K_8 = 56,
K_9 = 57,
K_COLON = 58,
K_SEMICOLON = 59,
K_LESS = 60,
K_EQUALS = 61,
K_GREATER = 62,
K_QUESTION = 63,
K_AT = 64,
/*
Skip uppercase letters
*/
K_LEFTBRACKET = 91,
K_BACKSLASH = 92,
K_RIGHTBRACKET = 93,
K_CARET = 94,
K_UNDERSCORE = 95,
K_BACKQUOTE = 96,
K_a = 97,
K_b = 98,
K_c = 99,
K_d = 100,
K_e = 101,
K_f = 102,
K_g = 103,
K_h = 104,
K_i = 105,
K_j = 106,
K_k = 107,
K_l = 108,
K_m = 109,
K_n = 110,
K_o = 111,
K_p = 112,
K_q = 113,
K_r = 114,
K_s = 115,
K_t = 116,
K_u = 117,
K_v = 118,
K_w = 119,
K_x = 120,
K_y = 121,
K_z = 122,
K_DELETE = 127,
/* End of ASCII mapped keysyms */
// normal keys should be passed as lowercased ascii
/* International keyboard syms */
K_WORLD_0 = 160, /* 0xA0 */
K_WORLD_1 = 161,
K_WORLD_2 = 162,
K_WORLD_3 = 163,
K_WORLD_4 = 164,
K_WORLD_5 = 165,
K_WORLD_6 = 166,
K_WORLD_7 = 167,
K_WORLD_8 = 168,
K_WORLD_9 = 169,
K_WORLD_10 = 170,
K_WORLD_11 = 171,
K_WORLD_12 = 172,
K_WORLD_13 = 173,
K_WORLD_14 = 174,
K_WORLD_15 = 175,
K_WORLD_16 = 176,
K_WORLD_17 = 177,
K_WORLD_18 = 178,
K_WORLD_19 = 179,
K_WORLD_20 = 180,
K_WORLD_21 = 181,
K_WORLD_22 = 182,
K_WORLD_23 = 183,
K_WORLD_24 = 184,
K_WORLD_25 = 185,
K_WORLD_26 = 186,
K_WORLD_27 = 187,
K_WORLD_28 = 188,
K_WORLD_29 = 189,
K_WORLD_30 = 190,
K_WORLD_31 = 191,
K_WORLD_32 = 192,
K_WORLD_33 = 193,
K_WORLD_34 = 194,
K_WORLD_35 = 195,
K_WORLD_36 = 196,
K_WORLD_37 = 197,
K_WORLD_38 = 198,
K_WORLD_39 = 199,
K_WORLD_40 = 200,
K_WORLD_41 = 201,
K_WORLD_42 = 202,
K_WORLD_43 = 203,
K_WORLD_44 = 204,
K_WORLD_45 = 205,
K_WORLD_46 = 206,
K_WORLD_47 = 207,
K_WORLD_48 = 208,
K_WORLD_49 = 209,
K_WORLD_50 = 210,
K_WORLD_51 = 211,
K_WORLD_52 = 212,
K_WORLD_53 = 213,
K_WORLD_54 = 214,
K_WORLD_55 = 215,
K_WORLD_56 = 216,
K_WORLD_57 = 217,
K_WORLD_58 = 218,
K_WORLD_59 = 219,
K_WORLD_60 = 220,
K_WORLD_61 = 221,
K_WORLD_62 = 222,
K_WORLD_63 = 223,
K_WORLD_64 = 224,
K_WORLD_65 = 225,
K_WORLD_66 = 226,
K_WORLD_67 = 227,
K_WORLD_68 = 228,
K_WORLD_69 = 229,
K_WORLD_70 = 230,
K_WORLD_71 = 231,
K_WORLD_72 = 232,
K_WORLD_73 = 233,
K_WORLD_74 = 234,
K_WORLD_75 = 235,
K_WORLD_76 = 236,
K_WORLD_77 = 237,
K_WORLD_78 = 238,
K_WORLD_79 = 239,
K_WORLD_80 = 240,
K_WORLD_81 = 241,
K_WORLD_82 = 242,
K_WORLD_83 = 243,
K_WORLD_84 = 244,
K_WORLD_85 = 245,
K_WORLD_86 = 246,
K_WORLD_87 = 247,
K_WORLD_88 = 248,
K_WORLD_89 = 249,
K_WORLD_90 = 250,
K_WORLD_91 = 251,
K_WORLD_92 = 252,
K_WORLD_93 = 253,
K_WORLD_94 = 254,
K_WORLD_95 = 255, /* 0xFF */
K_BACKSPACE = 127,
/* Numeric keypad */
K_KP0 = 256,
K_KP1 = 257,
K_KP2 = 258,
K_KP3 = 259,
K_KP4 = 260,
K_KP5 = 261,
K_KP6 = 262,
K_KP7 = 263,
K_KP8 = 264,
K_KP9 = 265,
K_KP_PERIOD = 266,
K_KP_DIVIDE = 267,
K_KP_MULTIPLY = 268,
K_KP_MINUS = 269,
K_KP_PLUS = 270,
K_KP_ENTER = 271,
K_KP_EQUALS = 272,
K_CAPSLOCK = 256,
K_PRNTSCR,
K_SCRLCK,
K_PAUSE,
/* Arrows + Home/End pad */
K_UP = 273,
K_DOWN = 274,
K_RIGHT = 275,
K_LEFT = 276,
K_INSERT = 277,
K_HOME = 278,
K_END = 279,
K_PAGEUP = 280,
K_PAGEDOWN = 281,
K_UPARROW,
K_DOWNARROW,
K_LEFTARROW,
K_RIGHTARROW,
/* Function keys */
K_F1 = 282,
K_F2 = 283,
K_F3 = 284,
K_F4 = 285,
K_F5 = 286,
K_F6 = 287,
K_F7 = 288,
K_F8 = 289,
K_F9 = 290,
K_F10 = 291,
K_F11 = 292,
K_F12 = 293,
K_F13 = 294,
K_F14 = 295,
K_F15 = 296,
K_ALT,
K_CTRL,
K_SHIFT,
K_F1,
K_F2,
K_F3,
K_F4,
K_F5,
K_F6,
K_F7,
K_F8,
K_F9,
K_F10,
K_F11,
K_F12,
K_INS,
K_DEL,
K_PGDN,
K_PGUP,
K_HOME,
K_END,
/* Key state modifier keys */
K_NUMLOCK = 300,
K_CAPSLOCK = 301,
K_SCROLLOCK = 302,
K_RSHIFT = 303,
K_LSHIFT = 304,
K_RCTRL = 305,
K_LCTRL = 306,
K_RALT = 307,
K_LALT = 308,
K_RMETA = 309,
K_LMETA = 310,
K_LSUPER = 311, /* Left "Windows" key */
K_RSUPER = 312, /* Right "Windows" key */
K_MODE = 313, /* "Alt Gr" key */
K_COMPOSE = 314, /* Multi-key compose key */
//
// Keypad stuff..
//
/* Miscellaneous function keys */
K_HELP = 315,
K_PRINT = 316,
K_SYSREQ = 317,
K_BREAK = 318,
K_MENU = 319,
K_POWER = 320, /* Power Macintosh power key */
K_EURO = 321, /* Some european keyboards */
KP_NUMLCK,
KP_DIVIDE,
KP_MULTIPLY,
KP_HOME,
KP_UPARROW,
KP_PGUP,
KP_MINUS,
KP_LEFTARROW,
KP_5,
KP_RIGHTARROW,
KP_PLUS,
KP_END,
KP_DOWNARROW,
KP_PGDN,
KP_INS,
KP_DEL,
KP_ENTER,
/* Add any other keys here */
//
// mouse buttons generate virtual keys
//
K_MOUSE1,
K_MOUSE2,
K_MOUSE3,
M_BUTTON1,
M_BUTTON2,
M_BUTTON3,
M_WHEEL_UP,
M_WHEEL_DOWN,
//
// joystick buttons
//
K_JOY1,
K_JOY2,
K_JOY3,
K_JOY4,
J_BUTTON1,
J_BUTTON2,
J_BUTTON3,
J_BUTTON4,
J_BUTTON5,
J_BUTTON6,
J_BUTTON7,
J_BUTTON8,
J_BUTTON9,
J_BUTTON10,
J_BUTTON11,
J_BUTTON12,
J_BUTTON13,
J_BUTTON14,
J_BUTTON15,
J_BUTTON16,
J_BUTTON17,
J_BUTTON18,
J_BUTTON19,
J_BUTTON20,
J_BUTTON21,
J_BUTTON22,
J_BUTTON23,
J_BUTTON24,
J_BUTTON25,
J_BUTTON26,
J_BUTTON27,
J_BUTTON28,
J_BUTTON29,
J_BUTTON30,
J_BUTTON31,
J_BUTTON32,
//
// aux keys are for multi-buttoned joysticks to generate so they can use
// the normal binding process
//
K_AUX1,
K_AUX2,
K_AUX3,
K_AUX4,
K_AUX5,
K_AUX6,
K_AUX7,
K_AUX8,
K_AUX9,
K_AUX10,
K_AUX11,
K_AUX12,
K_AUX13,
K_AUX14,
K_AUX15,
K_AUX16,
K_AUX17,
K_AUX18,
K_AUX19,
K_AUX20,
K_AUX21,
K_AUX22,
K_AUX23,
K_AUX24,
K_AUX25,
K_AUX26,
K_AUX27,
K_AUX28,
K_AUX29,
K_AUX30,
K_AUX31,
K_AUX32,
// JACK: Intellimouse(c) Mouse Wheel Support
K_MWHEELUP,
K_MWHEELDOWN,
K_ASC178,
K_ASC233,
K_ASC167,
K_ASC232,
K_ASC231,
K_ASC224,
// keys count
K_NUM_KEYS,
} keynum_t;
K_LAST
} knum_t;
typedef struct
{
@ -176,29 +341,54 @@ typedef struct
int state; // low bit is down state
} kbutton_t;
typedef enum {
KGT_CONSOLE,
KGT_DEFAULT,
KGT_1,
KGT_2,
KGT_3,
KGT_4,
KGT_5,
KGT_6,
KGT_7,
KGT_8,
KGT_9,
KGT_10,
KGT_11,
KGT_12,
KGT_13,
KGT_14,
KGT_15,
KGT_16,
KGT_LAST,
} kgt_t;
// key_none should, preferably, be last
typedef enum {key_game, key_console, key_message, key_menu, key_none} keydest_t;
typedef enum {key_game, key_console, key_message, key_none} keydest_t;
extern keydest_t key_dest;
extern char *keybindings[K_NUM_KEYS];
extern int key_repeats[K_NUM_KEYS];
extern int key_lastpress;
extern kgt_t game_target;
extern char *keybindings[KGT_LAST][K_LAST];
extern int keydown[K_LAST];
extern int key_lastpress;
extern char chat_buffer[];
extern int chat_bufferlen;
extern qboolean chat_team;
void Key_Event (int key, int alt, qboolean down);
void Key_Event (knum_t key, short unicode, qboolean down);
void Key_Init (void);
void Key_Init_Cvars (void);
void Key_WriteBindings (VFile *f);
void Key_SetBinding (int keynum, const char *binding);
void Key_ClearStates (void);
char *Key_GetBinding (kgt_t kgt, knum_t key);
void Key_SetBinding (kgt_t target, knum_t keynum, char *binding);
void Key_ClearTyping (void);
float Key_KeyState (kbutton_t *key);
const char *Key_KeynumToString (int keynum);
const char *Key_KeynumToString (knum_t keynum);
#endif // _KEYS_H

View file

@ -109,8 +109,11 @@ Con_ToggleChat_f (void)
if (cls.state == ca_active)
*/
key_dest = key_game;
} else
game_target = KGT_DEFAULT;
} else {
key_dest = key_console;
game_target = KGT_CONSOLE;
}
Con_ClearNotify ();
}

View file

@ -82,6 +82,7 @@ Con_ProcessInput (inputline_t *il, int ch)
int i;
switch (ch) {
/*
case K_ENTER:
if (il->enter)
il->enter (il->lines[il->edit_line] + 1);
@ -147,6 +148,7 @@ Con_ProcessInput (inputline_t *il, int ch)
case K_END:
il->linepos = strlen (il->lines[il->edit_line]);
break;
*/
default:
if (ch >= ' ' && ch < 256 && ch != 127) {
i = strlen (il->lines[il->edit_line]);

View file

@ -30,7 +30,7 @@ libQFjs.la: $(libQFjs_la_OBJECTS) $(libQFjs_la_DEPENDENCIES)
$(LINK) -rpath $(libdir) $(libQFjs_la_LDFLAGS) $(libQFjs_la_OBJECTS) $(libQFjs_la_LIBADD) $(LIBS)
EXTRA_DIST= joy.c joy_linux.c joy_null.c joy_win.c
in_common_SOURCE= in_common.c in_event.c
in_common_SOURCE= in_common.c in_event.c keys.c
# Linux FBdev
YFLAGS = -d

View file

@ -49,13 +49,11 @@
HWND mainwindow;
#endif
cvar_t *m_filter;
cvar_t *_windowed_mouse;
int old_windowed_mouse;
cvar_t *m_filter;
cvar_t *_windowed_mouse;
int old_windowed_mouse;
int modestate; // FIXME: just to avoid cross-comp.
// errors - remove later
int modestate; // FIXME: just to avoid cross-comp errors - remove later
/*
IN_SendKeyEvents
@ -66,7 +64,8 @@ IN_LL_SendKeyEvents (void)
{
SDL_Event event;
int sym, state, but;
int modstate;
knum_t ksym;
short unicode;
while (SDL_PollEvent (&event)) {
switch (event.type) {
@ -74,186 +73,711 @@ IN_LL_SendKeyEvents (void)
case SDL_KEYUP:
sym = event.key.keysym.sym;
state = event.key.state;
modstate = SDL_GetModState ();
unicode = event.key.keysym.unicode;
switch (sym) {
case SDLK_DELETE:
sym = K_DEL;
case SDLK_UNKNOWN:
ksym = K_UNKNOWN;
break;
case SDLK_BACKSPACE:
sym = K_BACKSPACE;
ksym = K_BACKSPACE;
break;
case SDLK_F1:
sym = K_F1;
case SDLK_TAB:
ksym = K_TAB;
break;
case SDLK_F2:
sym = K_F2;
case SDLK_CLEAR:
ksym = K_CLEAR;
break;
case SDLK_F3:
sym = K_F3;
case SDLK_RETURN:
ksym = K_RETURN;
break;
case SDLK_F4:
sym = K_F4;
break;
case SDLK_F5:
sym = K_F5;
break;
case SDLK_F6:
sym = K_F6;
break;
case SDLK_F7:
sym = K_F7;
break;
case SDLK_F8:
sym = K_F8;
break;
case SDLK_F9:
sym = K_F9;
break;
case SDLK_F10:
sym = K_F10;
break;
case SDLK_F11:
sym = K_F11;
break;
case SDLK_F12:
sym = K_F12;
break;
case SDLK_BREAK:
case SDLK_PAUSE:
sym = K_PAUSE;
ksym = K_PAUSE;
break;
case SDLK_UP:
sym = K_UPARROW;
case SDLK_ESCAPE:
ksym = K_ESCAPE;
break;
case SDLK_DOWN:
sym = K_DOWNARROW;
case SDLK_SPACE:
ksym = K_SPACE;
break;
case SDLK_RIGHT:
sym = K_RIGHTARROW;
case SDLK_EXCLAIM:
ksym = K_EXCLAIM;
break;
case SDLK_LEFT:
sym = K_LEFTARROW;
case SDLK_QUOTEDBL:
ksym = K_QUOTEDBL;
break;
case SDLK_INSERT:
sym = K_INS;
case SDLK_HASH:
ksym = K_HASH;
break;
case SDLK_HOME:
sym = K_HOME;
case SDLK_DOLLAR:
ksym = K_DOLLAR;
break;
case SDLK_END:
sym = K_END;
case SDLK_AMPERSAND:
ksym = K_AMPERSAND;
break;
case SDLK_PAGEUP:
sym = K_PGUP;
case SDLK_QUOTE:
ksym = K_QUOTE;
break;
case SDLK_PAGEDOWN:
sym = K_PGDN;
case SDLK_LEFTPAREN:
ksym = K_LEFTPAREN;
break;
case SDLK_RSHIFT:
case SDLK_LSHIFT:
sym = K_SHIFT;
case SDLK_RIGHTPAREN:
ksym = K_RIGHTPAREN;
break;
case SDLK_RCTRL:
case SDLK_LCTRL:
sym = K_CTRL;
case SDLK_ASTERISK:
ksym = K_ASTERISK;
break;
case SDLK_RALT:
case SDLK_LALT:
sym = K_ALT;
case SDLK_PLUS:
ksym = K_PLUS;
break;
case SDLK_CAPSLOCK:
sym = K_CAPSLOCK;
case SDLK_COMMA:
ksym = K_COMMA;
break;
case SDLK_MINUS:
ksym = K_MINUS;
break;
case SDLK_PERIOD:
ksym = K_PERIOD;
break;
case SDLK_SLASH:
ksym = K_SLASH;
break;
case SDLK_0:
ksym = K_0;
break;
case SDLK_1:
ksym = K_1;
break;
case SDLK_2:
ksym = K_2;
break;
case SDLK_3:
ksym = K_3;
break;
case SDLK_4:
ksym = K_4;
break;
case SDLK_5:
ksym = K_5;
break;
case SDLK_6:
ksym = K_6;
break;
case SDLK_7:
ksym = K_7;
break;
case SDLK_8:
ksym = K_8;
break;
case SDLK_9:
ksym = K_9;
break;
case SDLK_COLON:
ksym = K_COLON;
break;
case SDLK_SEMICOLON:
ksym = K_SEMICOLON;
break;
case SDLK_LESS:
ksym = K_LESS;
break;
case SDLK_EQUALS:
ksym = K_EQUALS;
break;
case SDLK_GREATER:
ksym = K_GREATER;
break;
case SDLK_QUESTION:
ksym = K_QUESTION;
break;
case SDLK_AT:
ksym = K_AT;
break;
case SDLK_LEFTBRACKET:
ksym = K_LEFTBRACKET;
break;
case SDLK_BACKSLASH:
ksym = K_BACKSLASH;
break;
case SDLK_RIGHTBRACKET:
ksym = K_RIGHTBRACKET;
break;
case SDLK_CARET:
ksym = K_CARET;
break;
case SDLK_UNDERSCORE:
ksym = K_UNDERSCORE;
break;
case SDLK_BACKQUOTE:
ksym = K_BACKQUOTE;
break;
case SDLK_a:
ksym = K_a;
break;
case SDLK_b:
ksym = K_b;
break;
case SDLK_c:
ksym = K_c;
break;
case SDLK_d:
ksym = K_d;
break;
case SDLK_e:
ksym = K_e;
break;
case SDLK_f:
ksym = K_f;
break;
case SDLK_g:
ksym = K_g;
break;
case SDLK_h:
ksym = K_h;
break;
case SDLK_i:
ksym = K_i;
break;
case SDLK_j:
ksym = K_j;
break;
case SDLK_k:
ksym = K_k;
break;
case SDLK_l:
ksym = K_l;
break;
case SDLK_m:
ksym = K_m;
break;
case SDLK_n:
ksym = K_n;
break;
case SDLK_o:
ksym = K_o;
break;
case SDLK_p:
ksym = K_p;
break;
case SDLK_q:
ksym = K_q;
break;
case SDLK_r:
ksym = K_r;
break;
case SDLK_s:
ksym = K_s;
break;
case SDLK_t:
ksym = K_t;
break;
case SDLK_u:
ksym = K_u;
break;
case SDLK_v:
ksym = K_v;
break;
case SDLK_w:
ksym = K_w;
break;
case SDLK_x:
ksym = K_x;
break;
case SDLK_y:
ksym = K_y;
break;
case SDLK_z:
ksym = K_z;
break;
case SDLK_DELETE:
ksym = K_DELETE;
break;
case SDLK_WORLD_0:
ksym = K_WORLD_0;
break;
case SDLK_WORLD_1:
ksym = K_WORLD_1;
break;
case SDLK_WORLD_2:
ksym = K_WORLD_2;
break;
case SDLK_WORLD_3:
ksym = K_WORLD_3;
break;
case SDLK_WORLD_4:
ksym = K_WORLD_4;
break;
case SDLK_WORLD_5:
ksym = K_WORLD_5;
break;
case SDLK_WORLD_6:
ksym = K_WORLD_6;
break;
case SDLK_WORLD_7:
ksym = K_WORLD_7;
break;
case SDLK_WORLD_8:
ksym = K_WORLD_8;
break;
case SDLK_WORLD_9:
ksym = K_WORLD_9;
break;
case SDLK_WORLD_10:
ksym = K_WORLD_10;
break;
case SDLK_WORLD_11:
ksym = K_WORLD_11;
break;
case SDLK_WORLD_12:
ksym = K_WORLD_12;
break;
case SDLK_WORLD_13:
ksym = K_WORLD_13;
break;
case SDLK_WORLD_14:
ksym = K_WORLD_14;
break;
case SDLK_WORLD_15:
ksym = K_WORLD_15;
break;
case SDLK_WORLD_16:
ksym = K_WORLD_16;
break;
case SDLK_WORLD_17:
ksym = K_WORLD_17;
break;
case SDLK_WORLD_18:
ksym = K_WORLD_18;
break;
case SDLK_WORLD_19:
ksym = K_WORLD_19;
break;
case SDLK_WORLD_20:
ksym = K_WORLD_20;
break;
case SDLK_WORLD_21:
ksym = K_WORLD_21;
break;
case SDLK_WORLD_22:
ksym = K_WORLD_22;
break;
case SDLK_WORLD_23:
ksym = K_WORLD_23;
break;
case SDLK_WORLD_24:
ksym = K_WORLD_24;
break;
case SDLK_WORLD_25:
ksym = K_WORLD_25;
break;
case SDLK_WORLD_26:
ksym = K_WORLD_26;
break;
case SDLK_WORLD_27:
ksym = K_WORLD_27;
break;
case SDLK_WORLD_28:
ksym = K_WORLD_28;
break;
case SDLK_WORLD_29:
ksym = K_WORLD_29;
break;
case SDLK_WORLD_30:
ksym = K_WORLD_30;
break;
case SDLK_WORLD_31:
ksym = K_WORLD_31;
break;
case SDLK_WORLD_32:
ksym = K_WORLD_32;
break;
case SDLK_WORLD_33:
ksym = K_WORLD_33;
break;
case SDLK_WORLD_34:
ksym = K_WORLD_34;
break;
case SDLK_WORLD_35:
ksym = K_WORLD_35;
break;
case SDLK_WORLD_36:
ksym = K_WORLD_36;
break;
case SDLK_WORLD_37:
ksym = K_WORLD_37;
break;
case SDLK_WORLD_38:
ksym = K_WORLD_38;
break;
case SDLK_WORLD_39:
ksym = K_WORLD_39;
break;
case SDLK_WORLD_40:
ksym = K_WORLD_40;
break;
case SDLK_WORLD_41:
ksym = K_WORLD_41;
break;
case SDLK_WORLD_42:
ksym = K_WORLD_42;
break;
case SDLK_WORLD_43:
ksym = K_WORLD_43;
break;
case SDLK_WORLD_44:
ksym = K_WORLD_44;
break;
case SDLK_WORLD_45:
ksym = K_WORLD_45;
break;
case SDLK_WORLD_46:
ksym = K_WORLD_46;
break;
case SDLK_WORLD_47:
ksym = K_WORLD_47;
break;
case SDLK_WORLD_48:
ksym = K_WORLD_48;
break;
case SDLK_WORLD_49:
ksym = K_WORLD_49;
break;
case SDLK_WORLD_50:
ksym = K_WORLD_50;
break;
case SDLK_WORLD_51:
ksym = K_WORLD_51;
break;
case SDLK_WORLD_52:
ksym = K_WORLD_52;
break;
case SDLK_WORLD_53:
ksym = K_WORLD_53;
break;
case SDLK_WORLD_54:
ksym = K_WORLD_54;
break;
case SDLK_WORLD_55:
ksym = K_WORLD_55;
break;
case SDLK_WORLD_56:
ksym = K_WORLD_56;
break;
case SDLK_WORLD_57:
ksym = K_WORLD_57;
break;
case SDLK_WORLD_58:
ksym = K_WORLD_58;
break;
case SDLK_WORLD_59:
ksym = K_WORLD_59;
break;
case SDLK_WORLD_60:
ksym = K_WORLD_60;
break;
case SDLK_WORLD_61:
ksym = K_WORLD_61;
break;
case SDLK_WORLD_62:
ksym = K_WORLD_62;
break;
case SDLK_WORLD_63:
ksym = K_WORLD_63;
break;
case SDLK_WORLD_64:
ksym = K_WORLD_64;
break;
case SDLK_WORLD_65:
ksym = K_WORLD_65;
break;
case SDLK_WORLD_66:
ksym = K_WORLD_66;
break;
case SDLK_WORLD_67:
ksym = K_WORLD_67;
break;
case SDLK_WORLD_68:
ksym = K_WORLD_68;
break;
case SDLK_WORLD_69:
ksym = K_WORLD_69;
break;
case SDLK_WORLD_70:
ksym = K_WORLD_70;
break;
case SDLK_WORLD_71:
ksym = K_WORLD_71;
break;
case SDLK_WORLD_72:
ksym = K_WORLD_72;
break;
case SDLK_WORLD_73:
ksym = K_WORLD_73;
break;
case SDLK_WORLD_74:
ksym = K_WORLD_74;
break;
case SDLK_WORLD_75:
ksym = K_WORLD_75;
break;
case SDLK_WORLD_76:
ksym = K_WORLD_76;
break;
case SDLK_WORLD_77:
ksym = K_WORLD_77;
break;
case SDLK_WORLD_78:
ksym = K_WORLD_78;
break;
case SDLK_WORLD_79:
ksym = K_WORLD_79;
break;
case SDLK_WORLD_80:
ksym = K_WORLD_80;
break;
case SDLK_WORLD_81:
ksym = K_WORLD_81;
break;
case SDLK_WORLD_82:
ksym = K_WORLD_82;
break;
case SDLK_WORLD_83:
ksym = K_WORLD_83;
break;
case SDLK_WORLD_84:
ksym = K_WORLD_84;
break;
case SDLK_WORLD_85:
ksym = K_WORLD_85;
break;
case SDLK_WORLD_86:
ksym = K_WORLD_86;
break;
case SDLK_WORLD_87:
ksym = K_WORLD_87;
break;
case SDLK_WORLD_88:
ksym = K_WORLD_88;
break;
case SDLK_WORLD_89:
ksym = K_WORLD_89;
break;
case SDLK_WORLD_90:
ksym = K_WORLD_90;
break;
case SDLK_WORLD_91:
ksym = K_WORLD_91;
break;
case SDLK_WORLD_92:
ksym = K_WORLD_92;
break;
case SDLK_WORLD_93:
ksym = K_WORLD_93;
break;
case SDLK_WORLD_94:
ksym = K_WORLD_94;
break;
case SDLK_WORLD_95:
ksym = K_WORLD_95;
break;
case SDLK_KP0:
if (modstate & KMOD_NUM)
sym = KP_INS;
else
sym = SDLK_0;
ksym = K_KP0;
break;
case SDLK_KP1:
if (modstate & KMOD_NUM)
sym = KP_END;
else
sym = SDLK_1;
ksym = K_KP1;
break;
case SDLK_KP2:
if (modstate & KMOD_NUM)
sym = KP_DOWNARROW;
else
sym = SDLK_2;
ksym = K_KP2;
break;
case SDLK_KP3:
if (modstate & KMOD_NUM)
sym = KP_PGDN;
else
sym = SDLK_3;
ksym = K_KP3;
break;
case SDLK_KP4:
if (modstate & KMOD_NUM)
sym = KP_LEFTARROW;
else
sym = SDLK_4;
ksym = K_KP4;
break;
case SDLK_KP5:
if (modstate & KMOD_NUM)
sym = KP_5;
else
sym = SDLK_5;
ksym = K_KP5;
break;
case SDLK_KP6:
if (modstate & KMOD_NUM)
sym = KP_RIGHTARROW;
else
sym = SDLK_6;
ksym = K_KP6;
break;
case SDLK_KP7:
if (modstate & KMOD_NUM)
sym = KP_HOME;
else
sym = SDLK_7;
ksym = K_KP7;
break;
case SDLK_KP8:
if (modstate & KMOD_NUM)
sym = KP_UPARROW;
else
sym = SDLK_8;
ksym = K_KP8;
break;
case SDLK_KP9:
if (modstate & KMOD_NUM)
sym = KP_PGUP;
else
sym = SDLK_9;
ksym = K_KP9;
break;
case SDLK_KP_PERIOD:
if (modstate & KMOD_NUM)
sym = KP_DEL;
else
sym = SDLK_PERIOD;
ksym = K_KP_PERIOD;
break;
case SDLK_KP_DIVIDE:
sym = KP_DIVIDE;
ksym = K_KP_DIVIDE;
break;
case SDLK_KP_MULTIPLY:
sym = KP_MULTIPLY;
ksym = K_KP_MULTIPLY;
break;
case SDLK_KP_MINUS:
sym = KP_MINUS;
ksym = K_KP_MINUS;
break;
case SDLK_KP_PLUS:
sym = KP_PLUS;
ksym = K_KP_PLUS;
break;
case SDLK_KP_ENTER:
sym = KP_ENTER;
ksym = K_KP_ENTER;
break;
case SDLK_KP_EQUALS:
sym = SDLK_EQUALS;
ksym = K_KP_EQUALS;
break;
case SDLK_UP:
ksym = K_UP;
break;
case SDLK_DOWN:
ksym = K_DOWN;
break;
case SDLK_RIGHT:
ksym = K_RIGHT;
break;
case SDLK_LEFT:
ksym = K_LEFT;
break;
case SDLK_INSERT:
ksym = K_INSERT;
break;
case SDLK_HOME:
ksym = K_HOME;
break;
case SDLK_END:
ksym = K_END;
break;
case SDLK_PAGEUP:
ksym = K_PAGEUP;
break;
case SDLK_PAGEDOWN:
ksym = K_PAGEDOWN;
break;
case SDLK_F1:
ksym = K_F1;
break;
case SDLK_F2:
ksym = K_F2;
break;
case SDLK_F3:
ksym = K_F3;
break;
case SDLK_F4:
ksym = K_F4;
break;
case SDLK_F5:
ksym = K_F5;
break;
case SDLK_F6:
ksym = K_F6;
break;
case SDLK_F7:
ksym = K_F7;
break;
case SDLK_F8:
ksym = K_F8;
break;
case SDLK_F9:
ksym = K_F9;
break;
case SDLK_F10:
ksym = K_F10;
break;
case SDLK_F11:
ksym = K_F11;
break;
case SDLK_F12:
ksym = K_F12;
break;
case SDLK_F13:
ksym = K_F13;
break;
case SDLK_F14:
ksym = K_F14;
break;
case SDLK_F15:
ksym = K_F15;
break;
case SDLK_NUMLOCK:
ksym = K_NUMLOCK;
break;
case SDLK_CAPSLOCK:
ksym = K_CAPSLOCK;
break;
case SDLK_SCROLLOCK:
ksym = K_SCROLLOCK;
break;
case SDLK_RSHIFT:
ksym = K_RSHIFT;
break;
case SDLK_LSHIFT:
ksym = K_LSHIFT;
break;
case SDLK_RCTRL:
ksym = K_RCTRL;
break;
case SDLK_LCTRL:
ksym = K_LCTRL;
break;
case SDLK_RALT:
ksym = K_RALT;
break;
case SDLK_LALT:
ksym = K_LALT;
break;
case SDLK_RMETA:
ksym = K_RMETA;
break;
case SDLK_LMETA:
ksym = K_LMETA;
break;
case SDLK_LSUPER:
ksym = K_LSUPER;
break;
case SDLK_RSUPER:
ksym = K_RSUPER;
break;
case SDLK_MODE:
ksym = K_MODE;
break;
case SDLK_COMPOSE:
ksym = K_COMPOSE;
break;
case SDLK_HELP:
ksym = K_HELP;
break;
case SDLK_PRINT:
ksym = K_PRINT;
break;
case SDLK_SYSREQ:
ksym = K_SYSREQ;
break;
case SDLK_BREAK:
ksym = K_BREAK;
break;
case SDLK_MENU:
ksym = K_MENU;
break;
case SDLK_POWER:
ksym = K_POWER;
break;
case SDLK_EURO:
ksym = K_EURO;
break;
case SDLK_LAST:
ksym = K_LAST;
break;
default:
ksym = K_UNKNOWN;
break;
}
// If we're not directly handled and still >= K_NUM_KEYS
// just force it to 0
if (sym >= K_NUM_KEYS)
sym = 0;
Key_Event (sym, -1, state);
if (unicode > 255)
unicode = 0;
Key_Event (sym, unicode, state);
break;
case SDL_MOUSEBUTTONDOWN:
@ -268,16 +792,16 @@ IN_LL_SendKeyEvents (void)
case 1:
case 2:
case 3:
Key_Event (K_MOUSE1 + but - 1, 0, event.type
== SDL_MOUSEBUTTONDOWN);
Key_Event (M_BUTTON1 + but - 1, 0,
event.type == SDL_MOUSEBUTTONDOWN);
break;
case 4:
Key_Event (K_MWHEELUP, 0, true);
Key_Event (K_MWHEELUP, 0, false);
Key_Event (M_WHEEL_UP, 0, true);
Key_Event (M_WHEEL_UP, 0, false);
break;
case 5:
Key_Event (K_MWHEELDOWN, 0, true);
Key_Event (K_MWHEELDOWN, 0, false);
Key_Event (M_WHEEL_DOWN, 0, true);
Key_Event (M_WHEEL_DOWN, 0, false);
break;
}
break;
@ -318,6 +842,9 @@ IN_LL_Init (void)
{
JOY_Init ();
/* Enable UNICODE translation for keyboard input */
SDL_EnableUNICODE(1);
if (COM_CheckParm ("-nomouse") && !_windowed_mouse->value)
return;

View file

@ -61,11 +61,11 @@ JOY_Read (void)
if (joy_buttons[event.number].current >
joy_buttons[event.number].old) {
Key_Event (K_AUX1 + event.number, 0, true);
Key_Event (J_BUTTON1 + event.number, 0, true);
} else {
if (joy_buttons[event.number].current <
joy_buttons[event.number].old) {
Key_Event (K_AUX1 + event.number, 0, false);
Key_Event (J_BUTTON2 + event.number, 0, false);
}
}
joy_buttons[event.number].old = joy_buttons[event.number].current;

View file

@ -170,13 +170,11 @@ JOY_Read (void)
buttonstate = ji.dwButtons;
for (i = 0; i < joy_numbuttons; i++) {
if ((buttonstate & (1 << i)) && !(joy_oldbuttonstate & (1 << i))) {
key_index = (i < 4) ? K_JOY1 : K_AUX1;
Key_Event (key_index + i, -1, true);
Key_Event (J_BUTTON1 + i, 0, true);
}
if (!(buttonstate & (1 << i)) && (joy_oldbuttonstate & (1 << i))) {
key_index = (i < 4) ? K_JOY1 : K_AUX1;
Key_Event (key_index + i, -1, false);
Key_Event (J_BUTTON1 + i, 0, false);
}
}
joy_oldbuttonstate = buttonstate;
@ -200,11 +198,11 @@ JOY_Read (void)
// each change
for (i = 0; i < 4; i++) {
if ((povstate & (1 << i)) && !(joy_oldpovstate & (1 << i))) {
Key_Event (K_AUX29 + i, -1, true);
Key_Event (J_BUTTON29 + i, -1, true);
}
if (!(povstate & (1 << i)) && (joy_oldpovstate & (1 << i))) {
Key_Event (K_AUX29 + i, -1, false);
Key_Event (J_BUTTON29 + i, -1, false);
}
}
joy_oldpovstate = povstate;

1034
libs/video/targets/keys.c Normal file

File diff suppressed because it is too large Load diff

View file

@ -132,6 +132,7 @@ VID_Init (unsigned char *palette)
// initialize the mouse
SDL_ShowCursor (0);
#ifdef WIN32
// FIXME: EVIL thing - but needed for win32 until
// SDL_sound works better - without this DirectSound fails.

View file

@ -1,41 +0,0 @@
/*
net_ser.h
@description@
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
int Serial_Init (void);
void Serial_Listen (qboolean state);
void Serial_SearchForHosts (qboolean xmit);
qsocket_t *Serial_Connect (const char *host);
qsocket_t *Serial_CheckNewConnections (void);
int Serial_GetMessage (qsocket_t *sock);
int Serial_SendMessage (qsocket_t *sock, sizebuf_t *data);
int Serial_SendUnreliableMessage (qsocket_t *sock, sizebuf_t *data);
qboolean Serial_CanSendMessage (qsocket_t *sock);
qboolean Serial_CanSendUnreliableMessage (qsocket_t *sock);
void Serial_Close (qsocket_t *sock);
void Serial_Shutdown (void);

View file

@ -71,7 +71,7 @@ client_LIB_DEPS= libqfnet.la $(ASM) $(qf_client_LIBS)
client_SOURCES= cl_cam.c cl_cmd.c cl_demo.c cl_input.c cl_main.c cl_screen.c \
cl_parse.c cl_tent.c cl_view.c \
console.c keys.c locs.c sbar.c
console.c locs.c sbar.c
server_SOURCES= host.c host_cmd.c pr_cmds.c sv_cvar.c sv_main.c \
sv_move.c sv_phys.c sv_progs.c sv_user.c

View file

@ -309,6 +309,7 @@ CL_PlayDemo_f (void)
cls.state = ca_connected;
cls.forcetrack = 0;
key_dest = key_game;
game_target = KGT_DEFAULT;
while ((c = Qgetc (cls.demofile)) != '\n')
if (c == '-')

View file

@ -286,6 +286,7 @@ CL_EstablishConnection (const char *host)
cls.signon = 0; // need all the signon messages
// before playing
key_dest = key_game;
game_target = KGT_DEFAULT;
}

View file

@ -1,893 +0,0 @@
/*
keys.c
(description)
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef _WIN32
# include <windows.h>
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "QF/cmd.h"
#include "QF/console.h"
#include "QF/cvar.h"
#include "QF/keys.h"
#include "QF/screen.h"
#include "QF/sys.h"
#include "client.h"
#include "compat.h"
/*
key up events are sent even if in console mode
*/
cvar_t *cl_chatmode;
#define MAXCMDLINE 256
char key_lines[32][MAXCMDLINE];
int key_linepos;
int key_lastpress;
int edit_line = 0;
int history_line = 0;
keydest_t key_dest = key_console;
char *keybindings[K_NUM_KEYS];
qboolean consolekeys[K_NUM_KEYS]; // if true, can't be rebound while in console
qboolean menubound[K_NUM_KEYS]; // if true, can't be rebound while in menu
int keyshift[K_NUM_KEYS]; // key to map to if shift held down in console
int key_repeats[K_NUM_KEYS]; // if > 1, it is autorepeating
qboolean keydown[K_NUM_KEYS];
typedef struct {
char *name;
int keynum;
} keyname_t;
keyname_t keynames[] = {
{"TAB", K_TAB},
{"ENTER", K_ENTER},
{"ESCAPE", K_ESCAPE},
{"SPACE", K_SPACE},
{"BACKSPACE", K_BACKSPACE},
{"CAPSLOCK", K_CAPSLOCK},
{"PRINTSCR", K_PRNTSCR},
{"SCRLCK", K_SCRLCK},
{"PAUSE", K_PAUSE},
{"UPARROW", K_UPARROW},
{"DOWNARROW", K_DOWNARROW},
{"LEFTARROW", K_LEFTARROW},
{"RIGHTARROW", K_RIGHTARROW},
{"ALT", K_ALT},
{"CTRL", K_CTRL},
{"SHIFT", K_SHIFT},
// Keypad stuff..
// These are duplicated
{"NUMLOCK", KP_NUMLCK},
{"KP_NUMLCK", KP_NUMLCK},
{"KP_NUMLOCK", KP_NUMLCK},
{"KP_SLASH", KP_DIVIDE},
{"KP_DIVIDE", KP_DIVIDE},
{"KP_STAR", KP_MULTIPLY},
{"KP_MULTIPLY", KP_MULTIPLY},
{"KP_MINUS", KP_MINUS},
{"KP_HOME", KP_HOME},
{"KP_UPARROW", KP_UPARROW},
{"KP_PGUP", KP_PGUP},
{"KP_PLUS", KP_PLUS},
{"KP_LEFTARROW", KP_LEFTARROW},
{"KP_5", KP_5},
{"KP_RIGHTARROW", KP_RIGHTARROW},
{"KP_END", KP_END},
{"KP_DOWNARROW", KP_DOWNARROW},
{"KP_PGDN", KP_PGDN},
{"KP_INS", KP_INS},
{"KP_DEL", KP_DEL},
{"KP_ENTER", KP_ENTER},
{"F1", K_F1},
{"F2", K_F2},
{"F3", K_F3},
{"F4", K_F4},
{"F5", K_F5},
{"F6", K_F6},
{"F7", K_F7},
{"F8", K_F8},
{"F9", K_F9},
{"F10", K_F10},
{"F11", K_F11},
{"F12", K_F12},
{"INS", K_INS},
{"DEL", K_DEL},
{"PGDN", K_PGDN},
{"PGUP", K_PGUP},
{"HOME", K_HOME},
{"END", K_END},
{"MOUSE1", K_MOUSE1},
{"MOUSE2", K_MOUSE2},
{"MOUSE3", K_MOUSE3},
{"JOY1", K_JOY1},
{"JOY2", K_JOY2},
{"JOY3", K_JOY3},
{"JOY4", K_JOY4},
{"AUX1", K_AUX1},
{"AUX2", K_AUX2},
{"AUX3", K_AUX3},
{"AUX4", K_AUX4},
{"AUX5", K_AUX5},
{"AUX6", K_AUX6},
{"AUX7", K_AUX7},
{"AUX8", K_AUX8},
{"AUX9", K_AUX9},
{"AUX10", K_AUX10},
{"AUX11", K_AUX11},
{"AUX12", K_AUX12},
{"AUX13", K_AUX13},
{"AUX14", K_AUX14},
{"AUX15", K_AUX15},
{"AUX16", K_AUX16},
{"AUX17", K_AUX17},
{"AUX18", K_AUX18},
{"AUX19", K_AUX19},
{"AUX20", K_AUX20},
{"AUX21", K_AUX21},
{"AUX22", K_AUX22},
{"AUX23", K_AUX23},
{"AUX24", K_AUX24},
{"AUX25", K_AUX25},
{"AUX26", K_AUX26},
{"AUX27", K_AUX27},
{"AUX28", K_AUX28},
{"AUX29", K_AUX29},
{"AUX30", K_AUX30},
{"AUX31", K_AUX31},
{"AUX32", K_AUX32},
{"MWHEELUP", K_MWHEELUP},
{"MWHEELDOWN", K_MWHEELDOWN},
{"ASC178", K_ASC178}, /* be azerty keycodes for top row */
{"ASC233", K_ASC233},
{"ASC167", K_ASC167},
{"ASC232", K_ASC232},
{"ASC231", K_ASC231},
{"ASC224", K_ASC224},
{"SEMICOLON", ';'}, // because a raw semicolon seperates commands
{"DOUBLEQUOTE", '"'}, // because a raw quote groups arguments
{NULL, 0}
};
/*
LINE TYPING INTO THE CONSOLE
*/
qboolean
CheckForCommand (void)
{
char command[128];
const char *cmd, *s;
int i;
s = key_lines[edit_line] + 1;
for (i = 0; i < 127; i++)
if (s[i] <= ' ')
break;
else
command[i] = s[i];
command[i] = 0;
cmd = Cmd_CompleteCommand (command);
if (!cmd || strcmp (cmd, command))
cmd = Cvar_CompleteVariable (command);
if (!cmd || strcmp (cmd, command))
return false; // just a chat message
return true;
}
/*
Key_Console
Interactive line editing and console scrollback
*/
void
Key_Console (int key)
{
int i;
#ifdef _WIN32
HANDLE th;
char *clipText, *textCopied;
#endif
switch (key) {
case K_ENTER:
// backslash text are commands
if (key_lines[edit_line][1] == '/'
&& key_lines[edit_line][2] == '/')
goto no_lf;
else if (key_lines[edit_line][1] == '\\'
|| key_lines[edit_line][1] == '/')
Cbuf_AddText (key_lines[edit_line] + 2); // skip the ]/
else if (cl_chatmode->int_val != 1 && CheckForCommand ())
Cbuf_AddText (key_lines[edit_line] + 1); // valid command
else if ((cls.state >= ca_connected && cl_chatmode->int_val == 2)
|| cl_chatmode->int_val == 1) {
if (cls.state < ca_connected) // can happen if cl_chatmode
// is 1
goto no_lf; // the text goes to /dev/null :)
// convert to a chat message
Cbuf_AddText ("say ");
Cbuf_AddText (key_lines[edit_line] + 1);
} else
Cbuf_AddText (key_lines[edit_line] + 1); // skip the ]
Cbuf_AddText ("\n");
no_lf:
Con_Printf ("%s\n", key_lines[edit_line]);
edit_line = (edit_line + 1) & 31;
history_line = edit_line;
key_lines[edit_line][0] = ']';
key_lines[edit_line][1] = 0;
key_linepos = 1;
if (cls.state == ca_disconnected)
CL_UpdateScreen (cl.time); // force an update, because the
// command may take some time
return;
case K_TAB:
// command completion
Con_CompleteCommandLine(); // New tab command completion
return;
case K_BACKSPACE:
if (key_linepos > 1) {
strcpy (key_lines[edit_line] + key_linepos - 1,
key_lines[edit_line] + key_linepos);
key_linepos--;
}
return;
case K_DEL:
if (key_linepos < strlen (key_lines[edit_line]))
strcpy (key_lines[edit_line] + key_linepos,
key_lines[edit_line] + key_linepos + 1);
return;
case K_RIGHTARROW:
if (key_linepos < strlen (key_lines[edit_line]))
key_linepos++;
return;
case K_LEFTARROW:
if (key_linepos > 1)
key_linepos--;
return;
case K_UPARROW:
do {
history_line = (history_line - 1) & 31;
} while (history_line != edit_line && !key_lines[history_line][1]);
if (history_line == edit_line)
history_line = (edit_line + 1) & 31;
strcpy (key_lines[edit_line], key_lines[history_line]);
key_linepos = strlen (key_lines[edit_line]);
return;
case K_DOWNARROW:
if (history_line == edit_line)
return;
do {
history_line = (history_line + 1) & 31;
} while (history_line != edit_line && !key_lines[history_line][1]);
if (history_line == edit_line) {
key_lines[edit_line][0] = ']';
key_lines[edit_line][1] = 0;
key_linepos = 1;
} else {
strcpy (key_lines[edit_line], key_lines[history_line]);
key_linepos = strlen (key_lines[edit_line]);
}
return;
case K_MWHEELUP:
case K_PGUP:
if (con->display - con->current + con->numlines > 2)
con->display -= 2;
return;
case K_MWHEELDOWN:
case K_PGDN:
con->display += 2;
if (con->display > con->current)
con->display = con->current;
return;
case K_HOME:
if (keydown[K_CTRL]) {
if (con->numlines > 10)
con->display = con->current - con->numlines + 10;
} else
key_linepos = 1;
return;
case K_END:
if (keydown[K_CTRL])
con->display = con->current;
else
key_linepos = strlen (key_lines[edit_line]);
return;
}
#ifdef _WIN32
if ((key == 'V' || key == 'v') && GetKeyState (VK_CONTROL) < 0) {
if (OpenClipboard (NULL)) {
th = GetClipboardData (CF_TEXT);
if (th) {
clipText = GlobalLock (th);
if (clipText) {
textCopied = malloc (GlobalSize (th) + 1);
strcpy (textCopied, clipText);
/* Substitutes a NULL for every token */
strtok (textCopied, "\n\r\b");
i = strlen (textCopied);
if (i + strlen (key_lines[edit_line]) > MAXCMDLINE - 1)
i = MAXCMDLINE - 1 - strlen (key_lines[edit_line]);
if (i > 0) { // insert the string
memmove (key_lines[edit_line] + key_linepos + i,
key_lines[edit_line] + key_linepos,
strlen (key_lines[edit_line]) - key_linepos +
1);
memcpy (key_lines[edit_line] + key_linepos, textCopied,
i);
key_linepos += i;
}
free (textCopied);
}
GlobalUnlock (th);
}
CloseClipboard ();
return;
}
}
#endif
if (key < 32)
return; // non printable
if (key > 127 && key != K_ASC178 && key != K_ASC233 && key != K_ASC167 && key != K_ASC232 && key != K_ASC231 && key != K_ASC224) {
//Con_Printf ("keysym: %d\n", key);
return;
}
i = strlen (key_lines[edit_line]);
if (i >= MAXCMDLINE - 1)
return;
// This also moves the ending \0
memmove (key_lines[edit_line] + key_linepos + 1,
key_lines[edit_line] + key_linepos, i - key_linepos + 1);
key_lines[edit_line][key_linepos] = key;
key_linepos++;
}
qboolean chat_team;
char chat_buffer[MAXCMDLINE];
int chat_bufferlen = 0;
void
Key_Message (int key)
{
if (key == K_ENTER) {
if (chat_team)
Cbuf_AddText ("say_team \"");
else
Cbuf_AddText ("say \"");
Cbuf_AddText (chat_buffer);
Cbuf_AddText ("\"\n");
key_dest = key_game;
chat_bufferlen = 0;
chat_buffer[0] = 0;
return;
}
if (key == K_ESCAPE) {
key_dest = key_game;
chat_bufferlen = 0;
chat_buffer[0] = 0;
return;
}
if (key < 32 || key > 127)
return; // non printable
if (key == K_BACKSPACE) {
if (chat_bufferlen) {
chat_bufferlen--;
chat_buffer[chat_bufferlen] = 0;
}
return;
}
if (chat_bufferlen == sizeof (chat_buffer) - 1)
return; // all full
chat_buffer[chat_bufferlen++] = key;
chat_buffer[chat_bufferlen] = 0;
}
/*
Key_StringToKeynum
Returns a key number to be used to index keybindings[] by looking at
the given string. Single ascii characters return themselves, while
the K_* names are matched up.
*/
int
Key_StringToKeynum (const char *str)
{
keyname_t *kn;
if (!str || !str[0])
return -1;
if (!str[1])
return str[0];
for (kn = keynames; kn->name; kn++) {
if (!strcasecmp (str, kn->name))
return kn->keynum;
}
return -1;
}
/*
Key_KeynumToString
Returns a string (either a single ascii char, or a K_* name) for the
given keynum.
FIXME: handle quote special (general escape sequence?)
*/
const char *
Key_KeynumToString (int keynum)
{
keyname_t *kn;
static char tinystr[2];
if (keynum == -1)
return "<KEY NOT FOUND>";
if (keynum > 32 && keynum < 127) { // printable ascii
tinystr[0] = keynum;
tinystr[1] = 0;
return tinystr;
}
for (kn = keynames; kn->name; kn++)
if (keynum == kn->keynum)
return kn->name;
return "<UNKNOWN KEYNUM>";
}
void
Key_SetBinding (int keynum, const char *binding)
{
char *new;
int l;
if (keynum == -1)
return;
// free old bindings
if (keybindings[keynum]) {
free (keybindings[keynum]);
keybindings[keynum] = NULL;
}
// allocate memory for new binding
l = strlen (binding);
new = malloc (l + 1);
strcpy (new, binding);
new[l] = 0;
keybindings[keynum] = new;
}
void
Key_Unbind_f (void)
{
int b;
if (Cmd_Argc () != 2) {
Con_Printf ("unbind <key> : remove commands from a key\n");
return;
}
b = Key_StringToKeynum (Cmd_Argv (1));
if (b == -1) {
Con_Printf ("\"%s\" isn't a valid key\n", Cmd_Argv (1));
return;
}
Key_SetBinding (b, "");
}
void
Key_Unbindall_f (void)
{
int i;
for (i = 0; i < K_NUM_KEYS; i++)
if (keybindings[i])
Key_SetBinding (i, "");
}
void
Key_Bind_f (void)
{
int i, c, b;
char cmd[1024];
c = Cmd_Argc ();
if (c < 2) {
Con_Printf ("bind <key> [command] : attach a command to a key\n");
return;
}
b = Key_StringToKeynum (Cmd_Argv (1));
if (b == -1) {
Con_Printf ("\"%s\" isn't a valid key\n", Cmd_Argv (1));
return;
}
if (c == 2) {
if (keybindings[b])
Con_Printf ("\"%s\" = \"%s\"\n", Cmd_Argv (1), keybindings[b]);
else
Con_Printf ("\"%s\" is not bound\n", Cmd_Argv (1));
return;
}
// copy the rest of the command line
cmd[0] = 0; // start out with a null string
for (i = 2; i < c; i++) {
strncat (cmd, Cmd_Argv (i), sizeof (cmd) - strlen (cmd));
if (i != (c - 1))
strncat (cmd, " ", sizeof (cmd) - strlen (cmd));
}
Key_SetBinding (b, cmd);
}
/*
Key_WriteBindings
Writes lines containing "bind key value"
*/
void
Key_WriteBindings (VFile *f)
{
int i;
for (i = 0; i < K_NUM_KEYS; i++)
if (keybindings[i])
Qprintf (f, "bind \"%s\" \"%s\"\n", Key_KeynumToString (i),
keybindings[i]);
// 1999-12-26 bound keys not saved in quotes fix by Maddes
}
void
Key_Init (void)
{
int i;
for (i = 0; i < 32; i++) {
key_lines[i][0] = ']';
key_lines[i][1] = 0;
}
key_linepos = 1;
// init ascii characters in console mode
for (i = 32; i < 128; i++)
consolekeys[i] = true;
consolekeys[K_ENTER] = true;
consolekeys[K_TAB] = true;
consolekeys[K_LEFTARROW] = true;
consolekeys[K_RIGHTARROW] = true;
consolekeys[K_UPARROW] = true;
consolekeys[K_DOWNARROW] = true;
consolekeys[K_BACKSPACE] = true;
consolekeys[K_DEL] = true;
consolekeys[K_HOME] = true;
consolekeys[K_END] = true;
consolekeys[K_PGUP] = true;
consolekeys[K_PGDN] = true;
consolekeys[K_SHIFT] = true;
consolekeys[K_MWHEELUP] = true;
consolekeys[K_MWHEELDOWN] = true;
consolekeys['`'] = false;
consolekeys['~'] = false;
for (i = 0; i < K_NUM_KEYS; i++)
keyshift[i] = i;
for (i = 'a'; i <= 'z'; i++)
keyshift[i] = i - 'a' + 'A';
keyshift['1'] = '!';
keyshift['2'] = '@';
keyshift['3'] = '#';
keyshift['4'] = '$';
keyshift['5'] = '%';
keyshift['6'] = '^';
keyshift['7'] = '&';
keyshift['8'] = '*';
keyshift['9'] = '(';
keyshift['0'] = ')';
keyshift['-'] = '_';
keyshift['='] = '+';
keyshift[','] = '<';
keyshift['.'] = '>';
keyshift['/'] = '?';
keyshift[';'] = ':';
keyshift['\''] = '"';
keyshift['['] = '{';
keyshift[']'] = '}';
keyshift['`'] = '~';
keyshift['\\'] = '|';
menubound[K_ESCAPE] = true;
for (i = 0; i < 12; i++)
menubound[K_F1 + i] = true;
// register our functions
Cmd_AddCommand ("bind", Key_Bind_f,
"Assign a command or a set of commands to a key.\n"
"Note: To bind multiple commands to a key, enclose the "
"commands in quotes and separate with semi-colons. \n"
"To bind to non-printable keys, use the key name.\n"
"Key Name List: Escape, F1-F12, pause, backspace, tab, "
"semicolon, enter, shift, ctrl, alt, space, ins,\n"
"home, pgup, del, end, pgdn, uparrow, downarrow, "
"leftarrow, rightarrow, mouse1-mouse3, aux1-aux9, "
"joy1-joy4,\n"
"mwheelup, mwheeldown\n"
"Special: The escape, and ~ (tilde) keys can only be "
"bound from an external configuration file.");
Cmd_AddCommand ("unbind", Key_Unbind_f,
"Remove the bind from the the selected key");
Cmd_AddCommand ("unbindall", Key_Unbindall_f,
"Remove all binds (USE CAUTIOUSLY!!!)");
}
void
Key_Init_Cvars (void)
{
cl_chatmode = Cvar_Get ("cl_chatmode", "2", CVAR_NONE, NULL,
"Controls when console text will be treated as a "
"chat message: 0 - never, 1 - always, 2 - smart");
}
/*
Key_Event
Called by the system between frames for both key up and key down events
Should NOT be called during an interrupt!
*/
void
Key_Event (int key, int alt_key, qboolean down)
{
char *kb;
char cmd[1024];
// Con_Printf ("%i : %i\n", key, down); //@@@
/* Let azerty keymaps get to the numbers in console & messagemode etc. */
if (key >= 200 && key_dest != key_game && alt_key >= 0x30 && alt_key <= 0x39)
key = alt_key;
// They don't prove it, fall back to interal MESS.
if (alt_key == -1) {
if (keydown[K_SHIFT]) {
alt_key = keyshift[key];
}
}
keydown[key] = down;
if (!down)
key_repeats[key] = 0;
key_lastpress = key;
// update auto-repeat status
if (down) {
key_repeats[key]++;
if (key_repeats[key] > 1) {
if ((key != K_BACKSPACE && key != K_DEL
&& key != K_LEFTARROW && key != K_RIGHTARROW
&& key != K_PGUP && key != K_PGDN)
|| (key_dest == key_game && cls.state == ca_active))
return; // ignore most autorepeats
}
if (key >= 200 && !keybindings[key])
Con_Printf ("%s is unbound, hit F4 to set.\n",
Key_KeynumToString (key));
}
// Exit message mode is disconnected
if (key_dest == key_message && cls.state != ca_active)
key_dest = key_console;
// handle escape specialy, so the user can never unbind it
if (key == K_ESCAPE) {
if (!down)
return;
switch (key_dest) {
case key_message:
Key_Message (key);
break;
case key_menu:
// M_Keydown (key);
break;
case key_game:
case key_console:
Con_ToggleConsole_f ();
// M_ToggleMenu_f ();
break;
default:
Sys_Error ("Bad key_dest");
}
return;
}
// key up events only generate commands if the game key binding is
// a button command (leading + sign). These will occur even in console mode,
// to keep the character from continuing an action started before a console
// switch. Button commands include the kenum as a parameter, so multiple
// downs can be matched with ups
if (!down) {
kb = keybindings[key];
if (kb && kb[0] == '+') {
snprintf (cmd, sizeof (cmd), "-%s %i\n", kb + 1, key);
Cbuf_AddText (cmd);
}
if (islower (key)) {
kb = keybindings[toupper (key)];
if (kb && kb[0] == '+') {
snprintf (cmd, sizeof (cmd), "-%s %i\n", kb + 1, key);
Cbuf_AddText (cmd);
}
}
return;
}
// during demo playback, most keys bring up the main menu
if (cls.demoplayback && down && consolekeys[key] && key_dest == key_game
&& key != K_CTRL && key != K_DEL && key != K_HOME && key != K_END
&& key != K_TAB) {
// M_ToggleMenu_f ();
Con_ToggleConsole_f ();
return;
}
// if not a consolekey, send to the interpreter no matter what mode is
if ((key_dest == key_menu && menubound[key])
|| (key_dest == key_console && !consolekeys[key])
|| (key_dest == key_game
&& (cls.state == ca_active || !consolekeys[key]))) {
kb = keybindings[key];
if (kb) {
if (kb[0] == '+') { // button commands add keynum as a
// parm
snprintf (cmd, sizeof (cmd), "%s %i\n", kb, key);
Cbuf_AddText (cmd);
} else {
Cbuf_AddText (kb);
Cbuf_AddText ("\n");
}
}
return;
}
if (!down)
return; // other systems only care about key
// down events
if (alt_key > 0)
key = alt_key;
switch (key_dest) {
case key_message:
Key_Message (key);
break;
case key_menu:
// M_Keydown (key);
break;
case key_game:
case key_console:
Key_Console (key);
break;
default:
Sys_Error ("Bad key_dest");
}
}
void
Key_ClearStates (void)
{
int i;
for (i = 0; i < K_NUM_KEYS; i++) {
if (keydown[i])
Key_Event (i, 0, false);
key_repeats[i] = false;
}
}
void
Key_ClearTyping (void)
{
key_lines[edit_line][1] = 0; // clear any typing
key_linepos = 1;
}

File diff suppressed because it is too large Load diff

View file

@ -1,947 +0,0 @@
/*
net_ser.c
@description@
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#include "net_ser.h"
#include "dosisms.h"
#include "QF/crc.h"
#include "net_comx.c"
// serial protocol
#define SERIAL_PROTOCOL_VERSION 3
// The serial protocol is message oriented. The high level message format is
// a one byte message type (MTYPE_xxx), data, and a 16-bit checksum. All
// multi-byte fields are sent in network byte order. There are currently 4
// MTYPEs defined. Their formats are as follows:
//
// MTYPE_RELIABLE sequence data_length data checksum eom
// MTYPE_UNRELIABLE sequence data_length data checksum eom
// MTYPE_ACK sequence checksum eom
// MTYPE_CONTROL data_length data checksum eom
//
// sequence is an 8-bit unsigned value starting from 0
// data_length is a 16-bit unsigned value; it is the length of the data only
// the checksum is a 16-bit value. the CRC formula used is defined in crc.h.
// the checksum covers the entire messages, excluding itself
// eom is a special 2 byte sequence used to mark the End Of Message. This is
// needed for error recovery.
//
// A lot of behavior is based on knowledge of the upper level Quake network
// layer. For example, only one reliable message can be outstanding (pending
// reception of an MTYPE_ACK) at a time.
//
// The low level routines used to communicate with the modem are not part of
// this protocol.
//
// The CONTROL messages are only used for session establishment. They are
// not reliable or sequenced.
#define MTYPE_RELIABLE 0x01
#define MTYPE_UNRELIABLE 0x02
#define MTYPE_CONTROL 0x03
#define MTYPE_ACK 0x04
#define MTYPE_CLIENT 0x80
#define ESCAPE_COMMAND 0xe0
#define ESCAPE_EOM 0x19
static qboolean listening = false;
typedef struct SerialLine_s {
struct SerialLine_s *next;
qsocket_t *sock;
int lengthStated;
int lengthFound;
int tty;
qboolean connected;
qboolean connecting;
qboolean client;
double connect_time;
unsigned short crcStated;
unsigned short crcValue;
byte currState;
byte prevState;
byte mtype;
byte sequence;
} SerialLine;
#define STATE_READY 0
#define STATE_SEQUENCE 1
#define STATE_LENGTH1 2
#define STATE_LENGTH2 3
#define STATE_DATA 4
#define STATE_CRC1 5
#define STATE_CRC2 6
#define STATE_EOM 7
#define STATE_ESCAPE 8
#define STATE_ABORT 9
SerialLine serialLine[NUM_COM_PORTS];
int myDriverLevel;
static void Serial_SendACK (SerialLine * p, byte sequence);
static void
ResetSerialLineProtocol (SerialLine * p)
{
p->connected = false;
p->connecting = false;
p->currState = STATE_READY;
p->prevState = STATE_READY;
p->lengthFound = 0;
}
static int
ProcessInQueue (SerialLine * p)
{
int b;
while (1) {
b = TTY_ReadByte (p->tty);
if (b == ERR_TTY_NODATA)
break;
if (b == ERR_TTY_LINE_STATUS) {
p->currState = STATE_ABORT;
continue;
}
if (b == ERR_TTY_MODEM_STATUS) {
p->currState = STATE_ABORT;
return -1;
}
if (b == ESCAPE_COMMAND)
if (p->currState != STATE_ESCAPE) {
p->prevState = p->currState;
p->currState = STATE_ESCAPE;
continue;
}
if (p->currState == STATE_ESCAPE) {
if (b == ESCAPE_EOM) {
if (p->prevState == STATE_ABORT) {
p->currState = STATE_READY;
p->lengthFound = 0;
continue;
}
if (p->prevState != STATE_EOM) {
p->currState = STATE_READY;
p->lengthFound = 0;
Con_DPrintf ("Serial: premature EOM\n");
continue;
}
switch (p->mtype) {
case MTYPE_RELIABLE:
Con_DPrintf ("Serial: sending ack %u\n", p->sequence);
Serial_SendACK (p, p->sequence);
if (p->sequence == p->sock->receiveSequence) {
p->sock->receiveSequence = (p->sequence + 1) & 0xff;
p->sock->receiveMessageLength += p->lengthFound;
} else
Con_DPrintf
("Serial: reliable out of order; got %u wanted %u\n",
p->sequence, p->sock->receiveSequence);
break;
case MTYPE_UNRELIABLE:
p->sock->unreliableReceiveSequence =
(p->sequence + 1) & 0xff;
p->sock->receiveMessageLength += p->lengthFound;
break;
case MTYPE_ACK:
Con_DPrintf ("Serial: got ack %u\n", p->sequence);
if (p->sequence == p->sock->sendSequence) {
p->sock->sendSequence =
(p->sock->sendSequence + 1) & 0xff;
p->sock->canSend = true;
} else
Con_DPrintf
("Serial: ack out of order; got %u wanted %u\n",
p->sequence, p->sock->sendSequence);
break;
case MTYPE_CONTROL:
p->sock->receiveMessageLength += p->lengthFound;
break;
}
p->currState = STATE_READY;
p->lengthFound = 0;
continue;
}
if (b != ESCAPE_COMMAND) {
p->currState = STATE_ABORT;
Con_DPrintf ("Serial: Bad escape sequence\n");
continue;
}
// b == ESCAPE_COMMAND
p->currState = p->prevState;
}
p->prevState = p->currState;
//DEBUG
if (p->sock->receiveMessageLength + p->lengthFound > NET_MAXMESSAGE) {
Con_DPrintf ("Serial blew out receive buffer: %u\n",
p->sock->receiveMessageLength + p->lengthFound);
p->currState = STATE_ABORT;
}
if (p->sock->receiveMessageLength + p->lengthFound == NET_MAXMESSAGE) {
Con_DPrintf ("Serial hit receive buffer limit: %u\n",
p->sock->receiveMessageLength + p->lengthFound);
p->currState = STATE_ABORT;
}
//end DEBUG
switch (p->currState) {
case STATE_READY:
CRC_Init (&p->crcValue);
CRC_ProcessByte (&p->crcValue, b);
if (p->client) {
if ((b & MTYPE_CLIENT) != 0) {
p->currState = STATE_ABORT;
Con_DPrintf ("Serial: client got own message\n");
break;
}
} else {
if ((b & MTYPE_CLIENT) == 0) {
p->currState = STATE_ABORT;
Con_DPrintf ("Serial: server got own message\n");
break;
}
b &= 0x7f;
}
p->mtype = b;
if (b != MTYPE_CONTROL)
p->currState = STATE_SEQUENCE;
else
p->currState = STATE_LENGTH1;
if (p->mtype < MTYPE_ACK) {
p->sock->receiveMessage[p->sock->receiveMessageLength] = b;
p->lengthFound++;
}
break;
case STATE_SEQUENCE:
p->sequence = b;
CRC_ProcessByte (&p->crcValue, b);
if (p->mtype != MTYPE_ACK)
p->currState = STATE_LENGTH1;
else
p->currState = STATE_CRC1;
break;
case STATE_LENGTH1:
p->lengthStated = b * 256;
CRC_ProcessByte (&p->crcValue, b);
p->currState = STATE_LENGTH2;
break;
case STATE_LENGTH2:
p->lengthStated += b;
CRC_ProcessByte (&p->crcValue, b);
if (p->mtype == MTYPE_RELIABLE && p->lengthStated > MAX_MSGLEN) {
p->currState = STATE_ABORT;
Con_DPrintf ("Serial: bad reliable message length %u\n",
p->lengthStated);
} else if (p->mtype == MTYPE_UNRELIABLE
&& p->lengthStated > MAX_DATAGRAM) {
p->currState = STATE_ABORT;
Con_DPrintf ("Serial: bad unreliable message length %u\n",
p->lengthStated);
} else {
p->currState = STATE_DATA;
if (p->mtype < MTYPE_ACK) {
*(short *) &p->sock->receiveMessage[p->sock->
receiveMessageLength +
1] = p->lengthStated;
p->lengthFound += 2;
}
}
break;
case STATE_DATA:
p->sock->receiveMessage[p->sock->receiveMessageLength +
p->lengthFound] = b;
p->lengthFound++;
CRC_ProcessByte (&p->crcValue, b);
if (p->lengthFound == p->lengthStated + 3)
p->currState = STATE_CRC1;
break;
case STATE_CRC1:
p->crcStated = b * 256;
p->currState = STATE_CRC2;
break;
case STATE_CRC2:
p->crcStated += b;
if (p->crcStated == CRC_Value (p->crcValue)) {
p->currState = STATE_EOM;
} else {
p->currState = STATE_ABORT;
Con_DPrintf ("Serial: Bad crc\n");
}
break;
case STATE_EOM:
p->currState = STATE_ABORT;
Con_DPrintf ("Serial: Bad message format\n");
break;
case STATE_ABORT:
break;
}
}
return 0;
}
int
Serial_Init (void)
{
int n;
// LATER do Win32 serial support
#ifdef _WIN32
return -1;
#endif
if (COM_CheckParm ("-nolan"))
return -1;
if (COM_CheckParm ("-noserial"))
return -1;
myDriverLevel = net_driverlevel;
if (TTY_Init ())
return -1;
for (n = 0; n < NUM_COM_PORTS; n++) {
serialLine[n].tty = TTY_Open (n);
ResetSerialLineProtocol (&serialLine[n]);
}
Con_Printf ("Serial driver initialized\n");
serialAvailable = true;
return 0;
}
void
Serial_Shutdown (void)
{
int n;
for (n = 0; n < NUM_COM_PORTS; n++) {
if (serialLine[n].connected)
Serial_Close (serialLine[n].sock);
}
TTY_Shutdown ();
}
void
Serial_Listen (qboolean state)
{
listening = state;
}
qboolean
Serial_CanSendMessage (qsocket_t * sock)
{
return sock->canSend;
}
qboolean
Serial_CanSendUnreliableMessage (qsocket_t * sock)
{
return TTY_OutputQueueIsEmpty (((SerialLine *) sock->driverdata)->tty);
}
int
Serial_SendMessage (qsocket_t * sock, sizebuf_t *message)
{
SerialLine *p;
int n;
unsigned short crc;
byte b;
p = (SerialLine *) sock->driverdata;
CRC_Init (&crc);
// message type
b = MTYPE_RELIABLE;
if (p->client)
b |= MTYPE_CLIENT;
TTY_WriteByte (p->tty, b);
CRC_ProcessByte (&crc, b);
// sequence
b = p->sock->sendSequence;
TTY_WriteByte (p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte (p->tty, b);
CRC_ProcessByte (&crc, b);
// data length
b = message->cursize >> 8;
TTY_WriteByte (p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte (p->tty, b);
CRC_ProcessByte (&crc, b);
b = message->cursize & 0xff;
TTY_WriteByte (p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte (p->tty, b);
CRC_ProcessByte (&crc, b);
// data
for (n = 0; n < message->cursize; n++) {
b = message->data[n];
TTY_WriteByte (p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte (p->tty, b);
CRC_ProcessByte (&crc, b);
}
// checksum
b = CRC_Value (crc) >> 8;
TTY_WriteByte (p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte (p->tty, b);
b = CRC_Value (crc) & 0xff;
TTY_WriteByte (p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte (p->tty, b);
// end of message
TTY_WriteByte (p->tty, ESCAPE_COMMAND);
TTY_WriteByte (p->tty, ESCAPE_EOM);
TTY_Flush (p->tty);
// mark sock as busy and save the message for possible retransmit
sock->canSend = false;
Q_memcpy (sock->sendMessage, message->data, message->cursize);
sock->sendMessageLength = message->cursize;
sock->lastSendTime = net_time;
return 1;
}
static void
ReSendMessage (qsocket_t * sock)
{
sizebuf_t temp;
Con_DPrintf ("Serial: re-sending reliable\n");
temp.data = sock->sendMessage;
temp.maxsize = sock->sendMessageLength;
temp.cursize = sock->sendMessageLength;
Serial_SendMessage (sock, &temp);
}
int
Serial_SendUnreliableMessage (qsocket_t * sock, sizebuf_t *message)
{
SerialLine *p;
int n;
unsigned short crc;
byte b;
p = (SerialLine *) sock->driverdata;
if (!TTY_OutputQueueIsEmpty (p->tty)) {
TTY_Flush (p->tty);
return 1;
}
CRC_Init (&crc);
// message type
b = MTYPE_UNRELIABLE;
if (p->client)
b |= MTYPE_CLIENT;
TTY_WriteByte (p->tty, b);
CRC_ProcessByte (&crc, b);
// sequence
b = p->sock->unreliableSendSequence;
p->sock->unreliableSendSequence = (b + 1) & 0xff;
TTY_WriteByte (p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte (p->tty, b);
CRC_ProcessByte (&crc, b);
// data length
b = message->cursize >> 8;
TTY_WriteByte (p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte (p->tty, b);
CRC_ProcessByte (&crc, b);
b = message->cursize & 0xff;
TTY_WriteByte (p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte (p->tty, b);
CRC_ProcessByte (&crc, b);
// data
for (n = 0; n < message->cursize; n++) {
b = message->data[n];
TTY_WriteByte (p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte (p->tty, b);
CRC_ProcessByte (&crc, b);
}
// checksum
b = CRC_Value (crc) >> 8;
TTY_WriteByte (p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte (p->tty, b);
b = CRC_Value (crc) & 0xff;
TTY_WriteByte (p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte (p->tty, b);
// end of message
TTY_WriteByte (p->tty, ESCAPE_COMMAND);
TTY_WriteByte (p->tty, ESCAPE_EOM);
TTY_Flush (p->tty);
return 1;
}
static void
Serial_SendACK (SerialLine * p, byte sequence)
{
unsigned short crc;
byte b;
CRC_Init (&crc);
// message type
b = MTYPE_ACK;
if (p->client)
b |= MTYPE_CLIENT;
TTY_WriteByte (p->tty, b);
CRC_ProcessByte (&crc, b);
// sequence
b = sequence;
TTY_WriteByte (p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte (p->tty, b);
CRC_ProcessByte (&crc, b);
// checksum
b = CRC_Value (crc) >> 8;
TTY_WriteByte (p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte (p->tty, b);
b = CRC_Value (crc) & 0xff;
TTY_WriteByte (p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte (p->tty, b);
// end of message
TTY_WriteByte (p->tty, ESCAPE_COMMAND);
TTY_WriteByte (p->tty, ESCAPE_EOM);
TTY_Flush (p->tty);
}
static void
Serial_SendControlMessage (SerialLine * p, sizebuf_t *message)
{
unsigned short crc;
int n;
byte b;
CRC_Init (&crc);
// message type
b = MTYPE_CONTROL;
if (p->client)
b |= MTYPE_CLIENT;
TTY_WriteByte (p->tty, b);
CRC_ProcessByte (&crc, b);
// data length
b = message->cursize >> 8;
TTY_WriteByte (p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte (p->tty, b);
CRC_ProcessByte (&crc, b);
b = message->cursize & 0xff;
TTY_WriteByte (p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte (p->tty, b);
CRC_ProcessByte (&crc, b);
// data
for (n = 0; n < message->cursize; n++) {
b = message->data[n];
TTY_WriteByte (p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte (p->tty, b);
CRC_ProcessByte (&crc, b);
}
// checksum
b = CRC_Value (crc) >> 8;
TTY_WriteByte (p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte (p->tty, b);
b = CRC_Value (crc) & 0xff;
TTY_WriteByte (p->tty, b);
if (b == ESCAPE_COMMAND)
TTY_WriteByte (p->tty, b);
// end of message
TTY_WriteByte (p->tty, ESCAPE_COMMAND);
TTY_WriteByte (p->tty, ESCAPE_EOM);
TTY_Flush (p->tty);
}
static int
_Serial_GetMessage (SerialLine * p)
{
byte ret;
short length;
if (ProcessInQueue (p))
return -1;
if (p->sock->receiveMessageLength == 0)
return 0;
ret = p->sock->receiveMessage[0];
length = *(short *) &p->sock->receiveMessage[1];
if (ret == MTYPE_CONTROL)
ret = 1;
SZ_Clear (&net_message);
SZ_Write (&net_message, &p->sock->receiveMessage[3], length);
length += 3;
p->sock->receiveMessageLength -= length;
if (p->sock->receiveMessageLength + p->lengthFound)
Q_memcpy (p->sock->receiveMessage, &p->sock->receiveMessage[length],
p->sock->receiveMessageLength + p->lengthFound);
return ret;
}
int
Serial_GetMessage (qsocket_t * sock)
{
SerialLine *p;
int ret;
p = (SerialLine *) sock->driverdata;
ret = _Serial_GetMessage (p);
if (ret == 1)
messagesReceived++;
if (!sock->canSend)
if ((net_time - sock->lastSendTime) > 1.0) {
ReSendMessage (sock);
sock->lastSendTime = net_time;
}
return ret;
}
void
Serial_Close (qsocket_t * sock)
{
SerialLine *p = (SerialLine *) sock->driverdata;
TTY_Close (p->tty);
ResetSerialLineProtocol (p);
}
char *com_types[] = { "direct", "modem" };
unsigned com_bauds[] = { 9600, 14400, 19200, 28800, 57600 };
void
Serial_SearchForHosts (qboolean xmit)
{
int n;
SerialLine *p;
if (sv.active)
return;
if (hostCacheCount == HOSTCACHESIZE)
return;
// see if we've already answered
for (n = 0; n < hostCacheCount; n++)
if (Q_strcmp (hostcache[n].cname, "#") == 0)
return;
for (n = 0; n < NUM_COM_PORTS; n++)
if (TTY_IsEnabled (n))
break;
if (n == NUM_COM_PORTS)
return;
p = &serialLine[n];
if (TTY_IsModem (p->tty))
return;
snprintf (hostcache[hostCacheCount].name,
sizeof (hostcache[hostCacheCount].name), "COM%u", n + 1);
Q_strcpy (hostcache[hostCacheCount].map, "");
hostcache[hostCacheCount].users = 0;
hostcache[hostCacheCount].maxusers = 0;
hostcache[hostCacheCount].driver = net_driverlevel;
Q_strcpy (hostcache[hostCacheCount].cname, "#");
hostCacheCount++;
return;
}
static qsocket_t *
_Serial_Connect (char *host, SerialLine * p)
{
int ret;
double start_time;
double last_time;
p->client = true;
if (TTY_Connect (p->tty, host))
return NULL;
p->sock = NET_NewQSocket ();
p->sock->driver = myDriverLevel;
if (p->sock == NULL) {
Con_Printf ("No sockets available\n");
return NULL;
}
p->sock->driverdata = p;
// send the connection request
start_time = SetNetTime ();
last_time = 0.0;
SZ_Clear (&net_message);
MSG_WriteByte (&net_message, CCREQ_CONNECT);
MSG_WriteString (&net_message, "QUAKE");
do {
SetNetTime ();
if ((net_time - last_time) >= 1.0) {
Serial_SendControlMessage (p, &net_message);
last_time = net_time;
Con_Printf ("trying...\n");
SCR_UpdateScreen (cl.time);
}
ret = _Serial_GetMessage (p);
}
while (ret == 0 && (net_time - start_time) < 5.0);
if (ret == 0) {
Con_Printf ("Unable to connect, no response\n");
goto ErrorReturn;
}
if (ret == -1) {
Con_Printf ("Connection request error\n");
goto ErrorReturn;
}
MSG_BeginReading ();
ret = MSG_ReadByte ();
if (ret == CCREP_REJECT) {
Con_Printf (MSG_ReadString ());
goto ErrorReturn;
}
if (ret != CCREP_ACCEPT) {
Con_Printf ("Unknown connection response\n");
goto ErrorReturn;
}
p->connected = true;
p->sock->lastMessageTime = net_time;
Con_Printf ("Connection accepted\n");
return p->sock;
ErrorReturn:
TTY_Disconnect (p->tty);
return NULL;
}
qsocket_t *
Serial_Connect (char *host)
{
int n;
qsocket_t *ret = NULL;
// see if this looks like a phone number
if (*host == '#')
host++;
for (n = 0; n < Q_strlen (host); n++)
if (host[n] == '.' || host[n] == ':')
return NULL;
for (n = 0; n < NUM_COM_PORTS; n++)
if (TTY_IsEnabled (n) && !serialLine[n].connected)
if ((ret = _Serial_Connect (host, &serialLine[n])))
break;
return ret;
}
static qsocket_t *
_Serial_CheckNewConnections (SerialLine * p)
{
int command;
p->client = false;
if (!TTY_CheckForConnection (p->tty))
return NULL;
if (TTY_IsModem (p->tty)) {
if (!p->connecting) {
p->connecting = true;
p->connect_time = net_time;
} else if ((net_time - p->connect_time) > 15.0) {
p->connecting = false;
TTY_Disconnect (p->tty);
return NULL;
}
}
p->sock = NET_NewQSocket ();
p->sock->driver = myDriverLevel;
if (p->sock == NULL) {
Con_Printf ("No sockets available\n");
return NULL;
}
p->sock->driverdata = p;
SZ_Clear (&net_message);
if (_Serial_GetMessage (p) != 1) {
NET_FreeQSocket (p->sock);
return NULL;
}
MSG_BeginReading ();
command = MSG_ReadByte ();
if (command == CCREQ_SERVER_INFO) {
if (Q_strcmp (MSG_ReadString (), "QUAKE") != 0)
return NULL;
if (MSG_ReadByte () != SERIAL_PROTOCOL_VERSION)
return NULL;
SZ_Clear (&net_message);
MSG_WriteByte (&net_message, CCREP_SERVER_INFO);
MSG_WriteString (&net_message, hostname->string);
MSG_WriteString (&net_message, sv.name);
MSG_WriteByte (&net_message, net_activeconnections);
MSG_WriteByte (&net_message, svs.maxclients);
Serial_SendControlMessage (p, &net_message);
SZ_Clear (&net_message);
return NULL;
}
if (command != CCREQ_CONNECT)
return NULL;
if (Q_strcmp (MSG_ReadString (), "QUAKE") != 0)
return NULL;
// send him back the info about the server connection he has been
// allocated
SZ_Clear (&net_message);
MSG_WriteByte (&net_message, CCREP_ACCEPT);
Serial_SendControlMessage (p, &net_message);
SZ_Clear (&net_message);
p->connected = true;
p->connecting = false;
p->sock->lastMessageTime = net_time;
snprintf (p->sock->address, sizeof (p->sock->address), "COM%u",
(int) ((p - serialLine) + 1));
return p->sock;
}
qsocket_t *
Serial_CheckNewConnections (void)
{
int n;
qsocket_t *ret = NULL;
for (n = 0; n < NUM_COM_PORTS; n++)
if (TTY_IsEnabled (n) && !serialLine[n].connected)
if ((ret = _Serial_CheckNewConnections (&serialLine[n])))
break;
return ret;
}

View file

@ -33,7 +33,6 @@
#include "net_loop.h"
#include "net_dgrm.h"
#include "net_ser.h"
net_driver_t net_drivers[MAX_NET_DRIVERS] = {
{

View file

@ -100,7 +100,7 @@ client_LIB_DEPS= libqfnet.la $(ASM) $(qf_client_LIBS)
client_SOURCES= cl_cam.c cl_cmd.c cl_cvar.c cl_demo.c cl_ents.c cl_input.c \
cl_main.c cl_misc.c cl_ngraph.c cl_parse.c cl_pred.c \
cl_screen.c cl_skin.c cl_slist.c cl_tent.c cl_view.c \
console.c keys.c locs.c sbar.c skin.c teamplay.c
console.c locs.c sbar.c skin.c teamplay.c
# Software-rendering clients

View file

@ -143,6 +143,7 @@ CL_PredictMove (void)
VID_SetCaption (cls.servername);
cls.state = ca_active;
key_dest = key_game;
game_target = KGT_DEFAULT;
}
if (cl_nopred->int_val) {

View file

@ -88,10 +88,14 @@ Con_ToggleConsole_f (void)
Key_ClearTyping ();
if (key_dest == key_console) {
if (cls.state == ca_active)
if (cls.state == ca_active) {
key_dest = key_game;
} else
game_target = KGT_DEFAULT;
}
} else {
key_dest = key_console;
game_target = KGT_CONSOLE;
}
Con_ClearNotify ();
}
@ -103,10 +107,14 @@ Con_ToggleChat_f (void)
Key_ClearTyping ();
if (key_dest == key_console) {
if (cls.state == ca_active)
if (cls.state == ca_active) {
key_dest = key_game;
} else
game_target = KGT_DEFAULT;
}
} else {
key_dest = key_console;
game_target = KGT_CONSOLE;
}
Con_ClearNotify ();
}

View file

@ -1,893 +0,0 @@
/*
keys.c
(description)
Copyright (C) 1996-1997 Id Software, Inc.
This program is free software; you can redistribute it and/or
modify it under the terms of the GNU General Public License
as published by the Free Software Foundation; either version 2
of the License, or (at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
See the GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to:
Free Software Foundation, Inc.
59 Temple Place - Suite 330
Boston, MA 02111-1307, USA
$Id$
*/
#ifdef HAVE_CONFIG_H
# include "config.h"
#endif
#ifdef _WIN32
# include <windows.h>
#endif
#ifdef HAVE_STRING_H
# include <string.h>
#endif
#ifdef HAVE_STRINGS_H
# include <strings.h>
#endif
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include "QF/cmd.h"
#include "QF/console.h"
#include "QF/cvar.h"
#include "QF/keys.h"
#include "QF/screen.h"
#include "QF/sys.h"
#include "client.h"
#include "compat.h"
/*
key up events are sent even if in console mode
*/
cvar_t *cl_chatmode;
#define MAXCMDLINE 256
char key_lines[32][MAXCMDLINE];
int key_linepos;
int key_lastpress;
int edit_line = 0;
int history_line = 0;
keydest_t key_dest = key_console;
char *keybindings[K_NUM_KEYS];
qboolean consolekeys[K_NUM_KEYS]; // if true, can't be rebound while in console
qboolean menubound[K_NUM_KEYS]; // if true, can't be rebound while in menu
int keyshift[K_NUM_KEYS]; // key to map to if shift held down in console
int key_repeats[K_NUM_KEYS]; // if > 1, it is autorepeating
qboolean keydown[K_NUM_KEYS];
typedef struct {
char *name;
int keynum;
} keyname_t;
keyname_t keynames[] = {
{"TAB", K_TAB},
{"ENTER", K_ENTER},
{"ESCAPE", K_ESCAPE},
{"SPACE", K_SPACE},
{"BACKSPACE", K_BACKSPACE},
{"CAPSLOCK", K_CAPSLOCK},
{"PRINTSCR", K_PRNTSCR},
{"SCRLCK", K_SCRLCK},
{"PAUSE", K_PAUSE},
{"UPARROW", K_UPARROW},
{"DOWNARROW", K_DOWNARROW},
{"LEFTARROW", K_LEFTARROW},
{"RIGHTARROW", K_RIGHTARROW},
{"ALT", K_ALT},
{"CTRL", K_CTRL},
{"SHIFT", K_SHIFT},
// Keypad stuff..
// These are duplicated
{"NUMLOCK", KP_NUMLCK},
{"KP_NUMLCK", KP_NUMLCK},
{"KP_NUMLOCK", KP_NUMLCK},
{"KP_SLASH", KP_DIVIDE},
{"KP_DIVIDE", KP_DIVIDE},
{"KP_STAR", KP_MULTIPLY},
{"KP_MULTIPLY", KP_MULTIPLY},
{"KP_MINUS", KP_MINUS},
{"KP_HOME", KP_HOME},
{"KP_UPARROW", KP_UPARROW},
{"KP_PGUP", KP_PGUP},
{"KP_PLUS", KP_PLUS},
{"KP_LEFTARROW", KP_LEFTARROW},
{"KP_5", KP_5},
{"KP_RIGHTARROW", KP_RIGHTARROW},
{"KP_END", KP_END},
{"KP_DOWNARROW", KP_DOWNARROW},
{"KP_PGDN", KP_PGDN},
{"KP_INS", KP_INS},
{"KP_DEL", KP_DEL},
{"KP_ENTER", KP_ENTER},
{"F1", K_F1},
{"F2", K_F2},
{"F3", K_F3},
{"F4", K_F4},
{"F5", K_F5},
{"F6", K_F6},
{"F7", K_F7},
{"F8", K_F8},
{"F9", K_F9},
{"F10", K_F10},
{"F11", K_F11},
{"F12", K_F12},
{"INS", K_INS},
{"DEL", K_DEL},
{"PGDN", K_PGDN},
{"PGUP", K_PGUP},
{"HOME", K_HOME},
{"END", K_END},
{"MOUSE1", K_MOUSE1},
{"MOUSE2", K_MOUSE2},
{"MOUSE3", K_MOUSE3},
{"JOY1", K_JOY1},
{"JOY2", K_JOY2},
{"JOY3", K_JOY3},
{"JOY4", K_JOY4},
{"AUX1", K_AUX1},
{"AUX2", K_AUX2},
{"AUX3", K_AUX3},
{"AUX4", K_AUX4},
{"AUX5", K_AUX5},
{"AUX6", K_AUX6},
{"AUX7", K_AUX7},
{"AUX8", K_AUX8},
{"AUX9", K_AUX9},
{"AUX10", K_AUX10},
{"AUX11", K_AUX11},
{"AUX12", K_AUX12},
{"AUX13", K_AUX13},
{"AUX14", K_AUX14},
{"AUX15", K_AUX15},
{"AUX16", K_AUX16},
{"AUX17", K_AUX17},
{"AUX18", K_AUX18},
{"AUX19", K_AUX19},
{"AUX20", K_AUX20},
{"AUX21", K_AUX21},
{"AUX22", K_AUX22},
{"AUX23", K_AUX23},
{"AUX24", K_AUX24},
{"AUX25", K_AUX25},
{"AUX26", K_AUX26},
{"AUX27", K_AUX27},
{"AUX28", K_AUX28},
{"AUX29", K_AUX29},
{"AUX30", K_AUX30},
{"AUX31", K_AUX31},
{"AUX32", K_AUX32},
{"MWHEELUP", K_MWHEELUP},
{"MWHEELDOWN", K_MWHEELDOWN},
{"ASC178", K_ASC178}, /* be azerty keycodes for top row */
{"ASC233", K_ASC233},
{"ASC167", K_ASC167},
{"ASC232", K_ASC232},
{"ASC231", K_ASC231},
{"ASC224", K_ASC224},
{"SEMICOLON", ';'}, // because a raw semicolon seperates commands
{"DOUBLEQUOTE", '"'}, // because a raw quote groups arguments
{NULL, 0}
};
/*
LINE TYPING INTO THE CONSOLE
*/
qboolean
CheckForCommand (void)
{
char command[128];
const char *cmd, *s;
int i;
s = key_lines[edit_line] + 1;
for (i = 0; i < 127; i++)
if (s[i] <= ' ')
break;
else
command[i] = s[i];
command[i] = 0;
cmd = Cmd_CompleteCommand (command);
if (!cmd || strcmp (cmd, command))
cmd = Cvar_CompleteVariable (command);
if (!cmd || strcmp (cmd, command))
return false; // just a chat message
return true;
}
/*
Key_Console
Interactive line editing and console scrollback
*/
void
Key_Console (int key)
{
int i;
#ifdef _WIN32
HANDLE th;
char *clipText, *textCopied;
#endif
switch (key) {
case K_ENTER:
// backslash text are commands
if (key_lines[edit_line][1] == '/'
&& key_lines[edit_line][2] == '/')
goto no_lf;
else if (key_lines[edit_line][1] == '\\'
|| key_lines[edit_line][1] == '/')
Cbuf_AddText (key_lines[edit_line] + 2); // skip the ]/
else if (cl_chatmode->int_val != 1 && CheckForCommand ())
Cbuf_AddText (key_lines[edit_line] + 1); // valid command
else if ((cls.state >= ca_connected && cl_chatmode->int_val == 2)
|| cl_chatmode->int_val == 1) {
if (cls.state < ca_connected) // can happen if cl_chatmode
// is 1
goto no_lf; // the text goes to /dev/null :)
// convert to a chat message
Cbuf_AddText ("say ");
Cbuf_AddText (key_lines[edit_line] + 1);
} else
Cbuf_AddText (key_lines[edit_line] + 1); // skip the ]
Cbuf_AddText ("\n");
no_lf:
Con_Printf ("%s\n", key_lines[edit_line]);
edit_line = (edit_line + 1) & 31;
history_line = edit_line;
key_lines[edit_line][0] = ']';
key_lines[edit_line][1] = 0;
key_linepos = 1;
if (cls.state == ca_disconnected)
CL_UpdateScreen (realtime); // force an update, because the
// command may take some time
return;
case K_TAB:
// command completion
Con_CompleteCommandLine(); // New tab command completion
return;
case K_BACKSPACE:
if (key_linepos > 1) {
strcpy (key_lines[edit_line] + key_linepos - 1,
key_lines[edit_line] + key_linepos);
key_linepos--;
}
return;
case K_DEL:
if (key_linepos < strlen (key_lines[edit_line]))
strcpy (key_lines[edit_line] + key_linepos,
key_lines[edit_line] + key_linepos + 1);
return;
case K_RIGHTARROW:
if (key_linepos < strlen (key_lines[edit_line]))
key_linepos++;
return;
case K_LEFTARROW:
if (key_linepos > 1)
key_linepos--;
return;
case K_UPARROW:
do {
history_line = (history_line - 1) & 31;
} while (history_line != edit_line && !key_lines[history_line][1]);
if (history_line == edit_line)
history_line = (edit_line + 1) & 31;
strcpy (key_lines[edit_line], key_lines[history_line]);
key_linepos = strlen (key_lines[edit_line]);
return;
case K_DOWNARROW:
if (history_line == edit_line)
return;
do {
history_line = (history_line + 1) & 31;
} while (history_line != edit_line && !key_lines[history_line][1]);
if (history_line == edit_line) {
key_lines[edit_line][0] = ']';
key_lines[edit_line][1] = 0;
key_linepos = 1;
} else {
strcpy (key_lines[edit_line], key_lines[history_line]);
key_linepos = strlen (key_lines[edit_line]);
}
return;
case K_MWHEELUP:
case K_PGUP:
if (con->display - con->current + con->numlines > 2)
con->display -= 2;
return;
case K_MWHEELDOWN:
case K_PGDN:
con->display += 2;
if (con->display > con->current)
con->display = con->current;
return;
case K_HOME:
if (keydown[K_CTRL]) {
if (con->numlines > 10)
con->display = con->current - con->numlines + 10;
} else
key_linepos = 1;
return;
case K_END:
if (keydown[K_CTRL])
con->display = con->current;
else
key_linepos = strlen (key_lines[edit_line]);
return;
}
#ifdef _WIN32
if ((key == 'V' || key == 'v') && GetKeyState (VK_CONTROL) < 0) {
if (OpenClipboard (NULL)) {
th = GetClipboardData (CF_TEXT);
if (th) {
clipText = GlobalLock (th);
if (clipText) {
textCopied = malloc (GlobalSize (th) + 1);
strcpy (textCopied, clipText);
/* Substitutes a NULL for every token */
strtok (textCopied, "\n\r\b");
i = strlen (textCopied);
if (i + strlen (key_lines[edit_line]) > MAXCMDLINE - 1)
i = MAXCMDLINE - 1 - strlen (key_lines[edit_line]);
if (i > 0) { // insert the string
memmove (key_lines[edit_line] + key_linepos + i,
key_lines[edit_line] + key_linepos,
strlen (key_lines[edit_line]) - key_linepos +
1);
memcpy (key_lines[edit_line] + key_linepos, textCopied,
i);
key_linepos += i;
}
free (textCopied);
}
GlobalUnlock (th);
}
CloseClipboard ();
return;
}
}
#endif
if (key < 32)
return; // non printable
if (key > 127 && key != K_ASC178 && key != K_ASC233 && key != K_ASC167 && key != K_ASC232 && key != K_ASC231 && key != K_ASC224) {
//Con_Printf ("keysym: %d\n", key);
return;
}
i = strlen (key_lines[edit_line]);
if (i >= MAXCMDLINE - 1)
return;
// This also moves the ending \0
memmove (key_lines[edit_line] + key_linepos + 1,
key_lines[edit_line] + key_linepos, i - key_linepos + 1);
key_lines[edit_line][key_linepos] = key;
key_linepos++;
}
qboolean chat_team;
char chat_buffer[MAXCMDLINE];
int chat_bufferlen = 0;
void
Key_Message (int key)
{
if (key == K_ENTER) {
if (chat_team)
Cbuf_AddText ("say_team \"");
else
Cbuf_AddText ("say \"");
Cbuf_AddText (chat_buffer);
Cbuf_AddText ("\"\n");
key_dest = key_game;
chat_bufferlen = 0;
chat_buffer[0] = 0;
return;
}
if (key == K_ESCAPE) {
key_dest = key_game;
chat_bufferlen = 0;
chat_buffer[0] = 0;
return;
}
if (key < 32 || key > 127)
return; // non printable
if (key == K_BACKSPACE) {
if (chat_bufferlen) {
chat_bufferlen--;
chat_buffer[chat_bufferlen] = 0;
}
return;
}
if (chat_bufferlen == sizeof (chat_buffer) - 1)
return; // all full
chat_buffer[chat_bufferlen++] = key;
chat_buffer[chat_bufferlen] = 0;
}
/*
Key_StringToKeynum
Returns a key number to be used to index keybindings[] by looking at
the given string. Single ascii characters return themselves, while
the K_* names are matched up.
*/
int
Key_StringToKeynum (const char *str)
{
keyname_t *kn;
if (!str || !str[0])
return -1;
if (!str[1])
return str[0];
for (kn = keynames; kn->name; kn++) {
if (!strcasecmp (str, kn->name))
return kn->keynum;
}
return -1;
}
/*
Key_KeynumToString
Returns a string (either a single ascii char, or a K_* name) for the
given keynum.
FIXME: handle quote special (general escape sequence?)
*/
const char *
Key_KeynumToString (int keynum)
{
keyname_t *kn;
static char tinystr[2];
if (keynum == -1)
return "<KEY NOT FOUND>";
if (keynum > 32 && keynum < 127) { // printable ascii
tinystr[0] = keynum;
tinystr[1] = 0;
return tinystr;
}
for (kn = keynames; kn->name; kn++)
if (keynum == kn->keynum)
return kn->name;
return "<UNKNOWN KEYNUM>";
}
void
Key_SetBinding (int keynum, const char *binding)
{
char *new;
int l;
if (keynum == -1)
return;
// free old bindings
if (keybindings[keynum]) {
free (keybindings[keynum]);
keybindings[keynum] = NULL;
}
// allocate memory for new binding
l = strlen (binding);
new = malloc (l + 1);
strcpy (new, binding);
new[l] = 0;
keybindings[keynum] = new;
}
void
Key_Unbind_f (void)
{
int b;
if (Cmd_Argc () != 2) {
Con_Printf ("unbind <key> : remove commands from a key\n");
return;
}
b = Key_StringToKeynum (Cmd_Argv (1));
if (b == -1) {
Con_Printf ("\"%s\" isn't a valid key\n", Cmd_Argv (1));
return;
}
Key_SetBinding (b, "");
}
void
Key_Unbindall_f (void)
{
int i;
for (i = 0; i < K_NUM_KEYS; i++)
if (keybindings[i])
Key_SetBinding (i, "");
}
void
Key_Bind_f (void)
{
int i, c, b;
char cmd[1024];
c = Cmd_Argc ();
if (c < 2) {
Con_Printf ("bind <key> [command] : attach a command to a key\n");
return;
}
b = Key_StringToKeynum (Cmd_Argv (1));
if (b == -1) {
Con_Printf ("\"%s\" isn't a valid key\n", Cmd_Argv (1));
return;
}
if (c == 2) {
if (keybindings[b])
Con_Printf ("\"%s\" = \"%s\"\n", Cmd_Argv (1), keybindings[b]);
else
Con_Printf ("\"%s\" is not bound\n", Cmd_Argv (1));
return;
}
// copy the rest of the command line
cmd[0] = 0; // start out with a null string
for (i = 2; i < c; i++) {
strncat (cmd, Cmd_Argv (i), sizeof (cmd) - strlen (cmd));
if (i != (c - 1))
strncat (cmd, " ", sizeof (cmd) - strlen (cmd));
}
Key_SetBinding (b, cmd);
}
/*
Key_WriteBindings
Writes lines containing "bind key value"
*/
void
Key_WriteBindings (VFile *f)
{
int i;
for (i = 0; i < K_NUM_KEYS; i++)
if (keybindings[i])
Qprintf (f, "bind \"%s\" \"%s\"\n", Key_KeynumToString (i),
keybindings[i]);
// 1999-12-26 bound keys not saved in quotes fix by Maddes
}
void
Key_Init (void)
{
int i;
for (i = 0; i < 32; i++) {
key_lines[i][0] = ']';
key_lines[i][1] = 0;
}
key_linepos = 1;
// init ascii characters in console mode
for (i = 32; i < 128; i++)
consolekeys[i] = true;
consolekeys[K_ENTER] = true;
consolekeys[K_TAB] = true;
consolekeys[K_LEFTARROW] = true;
consolekeys[K_RIGHTARROW] = true;
consolekeys[K_UPARROW] = true;
consolekeys[K_DOWNARROW] = true;
consolekeys[K_BACKSPACE] = true;
consolekeys[K_DEL] = true;
consolekeys[K_HOME] = true;
consolekeys[K_END] = true;
consolekeys[K_PGUP] = true;
consolekeys[K_PGDN] = true;
consolekeys[K_SHIFT] = true;
consolekeys[K_MWHEELUP] = true;
consolekeys[K_MWHEELDOWN] = true;
consolekeys['`'] = false;
consolekeys['~'] = false;
for (i = 0; i < K_NUM_KEYS; i++)
keyshift[i] = i;
for (i = 'a'; i <= 'z'; i++)
keyshift[i] = i - 'a' + 'A';
keyshift['1'] = '!';
keyshift['2'] = '@';
keyshift['3'] = '#';
keyshift['4'] = '$';
keyshift['5'] = '%';
keyshift['6'] = '^';
keyshift['7'] = '&';
keyshift['8'] = '*';
keyshift['9'] = '(';
keyshift['0'] = ')';
keyshift['-'] = '_';
keyshift['='] = '+';
keyshift[','] = '<';
keyshift['.'] = '>';
keyshift['/'] = '?';
keyshift[';'] = ':';
keyshift['\''] = '"';
keyshift['['] = '{';
keyshift[']'] = '}';
keyshift['`'] = '~';
keyshift['\\'] = '|';
menubound[K_ESCAPE] = true;
for (i = 0; i < 12; i++)
menubound[K_F1 + i] = true;
// register our functions
Cmd_AddCommand ("bind", Key_Bind_f,
"Assign a command or a set of commands to a key.\n"
"Note: To bind multiple commands to a key, enclose the "
"commands in quotes and separate with semi-colons. \n"
"To bind to non-printable keys, use the key name.\n"
"Key Name List: Escape, F1-F12, pause, backspace, tab, "
"semicolon, enter, shift, ctrl, alt, space, ins,\n"
"home, pgup, del, end, pgdn, uparrow, downarrow, "
"leftarrow, rightarrow, mouse1-mouse3, aux1-aux9, "
"joy1-joy4,\n"
"mwheelup, mwheeldown\n"
"Special: The escape, and ~ (tilde) keys can only be "
"bound from an external configuration file.");
Cmd_AddCommand ("unbind", Key_Unbind_f,
"Remove the bind from the the selected key");
Cmd_AddCommand ("unbindall", Key_Unbindall_f,
"Remove all binds (USE CAUTIOUSLY!!!)");
}
void
Key_Init_Cvars (void)
{
cl_chatmode = Cvar_Get ("cl_chatmode", "2", CVAR_NONE, NULL,
"Controls when console text will be treated as a "
"chat message: 0 - never, 1 - always, 2 - smart");
}
/*
Key_Event
Called by the system between frames for both key up and key down events
Should NOT be called during an interrupt!
*/
void
Key_Event (int key, int alt_key, qboolean down)
{
char *kb;
char cmd[1024];
// Con_Printf ("%i : %i\n", key, down); //@@@
/* Let azerty keymaps get to the numbers in console & messagemode etc. */
if (key >= 200 && key_dest != key_game && alt_key >= 0x30 && alt_key <= 0x39)
key = alt_key;
// They don't prove it, fall back to interal MESS.
if (alt_key == -1) {
if (keydown[K_SHIFT]) {
alt_key = keyshift[key];
}
}
keydown[key] = down;
if (!down)
key_repeats[key] = 0;
key_lastpress = key;
// update auto-repeat status
if (down) {
key_repeats[key]++;
if (key_repeats[key] > 1) {
if ((key != K_BACKSPACE && key != K_DEL
&& key != K_LEFTARROW && key != K_RIGHTARROW
&& key != K_PGUP && key != K_PGDN)
|| (key_dest == key_game && cls.state == ca_active))
return; // ignore most autorepeats
}
if (key >= 200 && !keybindings[key])
Con_Printf ("%s is unbound, hit F4 to set.\n",
Key_KeynumToString (key));
}
// Exit message mode is disconnected
if (key_dest == key_message && cls.state != ca_active)
key_dest = key_console;
// handle escape specialy, so the user can never unbind it
if (key == K_ESCAPE) {
if (!down)
return;
switch (key_dest) {
case key_message:
Key_Message (key);
break;
case key_menu:
// M_Keydown (key);
break;
case key_game:
case key_console:
Con_ToggleConsole_f ();
// M_ToggleMenu_f ();
break;
default:
Sys_Error ("Bad key_dest");
}
return;
}
// key up events only generate commands if the game key binding is
// a button command (leading + sign). These will occur even in console mode,
// to keep the character from continuing an action started before a console
// switch. Button commands include the kenum as a parameter, so multiple
// downs can be matched with ups
if (!down) {
kb = keybindings[key];
if (kb && kb[0] == '+') {
snprintf (cmd, sizeof (cmd), "-%s %i\n", kb + 1, key);
Cbuf_AddText (cmd);
}
if (islower (key)) {
kb = keybindings[toupper (key)];
if (kb && kb[0] == '+') {
snprintf (cmd, sizeof (cmd), "-%s %i\n", kb + 1, key);
Cbuf_AddText (cmd);
}
}
return;
}
// during demo playback, most keys bring up the main menu
if (cls.demoplayback && down && consolekeys[key] && key_dest == key_game
&& key != K_CTRL && key != K_DEL && key != K_HOME && key != K_END
&& key != K_TAB) {
// M_ToggleMenu_f ();
Con_ToggleConsole_f ();
return;
}
// if not a consolekey, send to the interpreter no matter what mode is
if ((key_dest == key_menu && menubound[key])
|| (key_dest == key_console && !consolekeys[key])
|| (key_dest == key_game
&& (cls.state == ca_active || !consolekeys[key]))) {
kb = keybindings[key];
if (kb) {
if (kb[0] == '+') { // button commands add keynum as a
// parm
snprintf (cmd, sizeof (cmd), "%s %i\n", kb, key);
Cbuf_AddText (cmd);
} else {
Cbuf_AddText (kb);
Cbuf_AddText ("\n");
}
}
return;
}
if (!down)
return; // other systems only care about key
// down events
if (alt_key > 0)
key = alt_key;
switch (key_dest) {
case key_message:
Key_Message (key);
break;
case key_menu:
// M_Keydown (key);
break;
case key_game:
case key_console:
Key_Console (key);
break;
default:
Sys_Error ("Bad key_dest");
}
}
void
Key_ClearStates (void)
{
int i;
for (i = 0; i < K_NUM_KEYS; i++) {
if (keydown[i])
Key_Event (i, 0, false);
key_repeats[i] = false;
}
}
void
Key_ClearTyping (void)
{
key_lines[edit_line][1] = 0; // clear any typing
key_linepos = 1;
}