Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision

Target

Select target project
  • STJr/SRB2
  • Sryder/SRB2
  • wolfy852/SRB2
  • Alpha2244/SRB2
  • Inuyasha/SRB2
  • yoshibot/SRB2
  • TehRealSalt/SRB2
  • PrisimaTF/SRB2
  • Hatninja/SRB2
  • SteelT/SRB2
  • james/SRB2
  • ShaderWraith/SRB2
  • SinnamonLat/SRB2
  • mazmazz_/SRB2
  • filpAM/SRB2
  • chaoloveicemdboy/SRB2
  • Whooa21/SRB2
  • Machturne/SRB2
  • Golden/SRB2
  • Tatsuru/SRB2
  • Snu/SRB2
  • Zwip-Zwap_Zapony/SRB2
  • fickleheart/SRB2
  • alphaRexJames/SRB2
  • JJK/SRB2
  • diskpoppy/SRB2
  • Hannu_Hanhi/SRB2
  • ZipperQR/SRB2
  • kays/SRB2
  • spherallic/SRB2
  • Zippy_Zolton/SRB2
  • namiishere/SRB2
  • Ors/SRB2
  • SMS_Alfredo/SRB2
  • sonic_edge/SRB2
  • lavla/SRB2
  • ashi/SRB2
  • X.organic/SRB2
  • Fafabis/SRB2
  • Meziu/SRB2
  • v-rob/SRB2
  • tertu/SRB2
  • bitten2up/SRB2
  • flarn2006/SRB2
  • Krabs/SRB2
  • clairebun/SRB2
  • Lactozilla/SRB2
  • thehackstack/SRB2
  • Spice/SRB2
  • win8linux/SRB2
  • JohnFrostFox/SRB2
  • talktoneon726/SRB2
  • Wane/SRB2
  • Lamibe/SRB2
  • spectrumuk2/srb-2
  • nerdyminer18/srb-2
  • 256nil/SRB2
  • ARJr/SRB2
  • Alam/SRB2
  • Zenya/srb-2-marathon-demos
  • Acelite/srb-2-archivedmodifications
  • MIDIMan/SRB2
  • Lach/SRB2
  • Frostiikin/bounce-tweaks
  • Jaden/SRB2
  • Tyron/SRB2
  • Astronight/SRB2
  • Mari0shi06/SRB2
  • aiire/SRB2
  • Galactice/SRB2
  • srb2-ports/srb2-dreamcast
  • sdasdas/SRB2
  • chreas/srb-2-vr
  • StarManiaKG/the-story-of-sinically-rocketing-and-botching-the-2nd
  • LoganAir/SRB2
  • NepDisk/srb-2
  • alufolie91/SRB2
  • Felicia.iso/SRB2
  • twi/SRB2
  • BarrelsOFun/SRB2
  • Speed2411/SRB2
  • Leather_Realms/SRB2
  • Ayemar/SRB2
  • Acelite/SRB2
  • VladDoc/SRB2
  • kaldrum/model-features
  • strawberryfox417/SRB2
  • Lugent/SRB2
  • Rem/SRB2
  • Refrag/SRB2
  • Henry_3230/srb-3230
  • TehPuertoRicanSpartan2/tprs-srb2
  • Leminn/srb-2-marathon-stuff
  • chromaticpipe2/SRB2
  • MiguelGustavo15/SRB2
  • Maru/srb-2-tests
  • SilicDev/SRB2
  • UnmatchedBracket/SRB2
  • HybridDog/SRB2
  • xordspar0/SRB2
  • jsjhbewfhh/SRB2
  • Fancy2209/SRB2
  • Lorsoen/SRB2
  • shindoukin/SRB2
  • GamerOfDays/SRB2
  • Craftyawesome/SRB2
  • tenshi-tensai-tennoji/SRB2
  • Scarfdudebalder/SRB2
  • luigi-budd/srb-2-fix-interplag-lockon
  • mskluesner/SRB2
  • johnpetersa19/SRB2
  • Pheazant/SRB2
  • chromaticpipe2/srb2classic
  • romoney5/SRB2
  • PAS/SRB2Classic
  • BlueStaggo/SRB2
  • Jisk/srb-2-beef-jerky
117 results
Select Git revision
Show changes
Commits on Source (33)
...@@ -38,7 +38,7 @@ ...@@ -38,7 +38,7 @@
// protos. // protos.
//======== //========
static boolean COM_Exists(const char *com_name); static boolean COM_Exists(const char *com_name);
static void COM_ExecuteString(char *com_text); static void COM_ExecuteString(UINT8 *com_text);
static void COM_Alias_f(void); static void COM_Alias_f(void);
static void COM_Echo_f(void); static void COM_Echo_f(void);
...@@ -58,8 +58,8 @@ static consvar_t *CV_FindVar(const char *name); ...@@ -58,8 +58,8 @@ static consvar_t *CV_FindVar(const char *name);
static const char *CV_StringValue(const char *var_name); static const char *CV_StringValue(const char *var_name);
static consvar_t *consvar_vars; // list of registered console variables static consvar_t *consvar_vars; // list of registered console variables
static char com_token[1024]; static UINT8 com_token[1024];
static char *COM_Parse(char *data); static UINT8 *COM_Parse(UINT8 *data);
CV_PossibleValue_t CV_OnOff[] = {{0, "Off"}, {1, "On"}, {0, NULL}}; CV_PossibleValue_t CV_OnOff[] = {{0, "Off"}, {1, "On"}, {0, NULL}};
CV_PossibleValue_t CV_YesNo[] = {{0, "No"}, {1, "Yes"}, {0, NULL}}; CV_PossibleValue_t CV_YesNo[] = {{0, "No"}, {1, "Yes"}, {0, NULL}};
...@@ -168,14 +168,14 @@ COM_BufTicker(void) ...@@ -168,14 +168,14 @@ COM_BufTicker(void)
void COM_BufExecute(void) void COM_BufExecute(void)
{ {
size_t i; size_t i;
char *ptext; UINT8 *ptext;
char line[1024] = ""; UINT8 line[1024] = "";
INT32 quotes; INT32 quotes;
while (com_text.cursize) while (com_text.cursize)
{ {
// find a '\n' or; line break // find a '\n' or; line break
ptext = (char *)com_text.data; ptext = (UINT8 *)com_text.data;
quotes = 0; quotes = 0;
for (i = 0; i < com_text.cursize; i++) for (i = 0; i < com_text.cursize; i++)
...@@ -223,17 +223,17 @@ void COM_BufExecute(void) ...@@ -223,17 +223,17 @@ void COM_BufExecute(void)
/** Executes a string immediately. Used for skirting around WAIT commands. /** Executes a string immediately. Used for skirting around WAIT commands.
*/ */
void COM_ImmedExecute(const char *ptext) void COM_ImmedExecute(const char *itext)
{ {
const UINT8 *ptext = (const UINT8 *)itext;
size_t i = 0, j = 0; size_t i = 0, j = 0;
char line[1024] = ""; UINT8 line[1024] = "";
INT32 quotes; INT32 quotes;
while (i < strlen(ptext)) while (i < HU_StringLength(ptext))
{ {
quotes = 0; quotes = 0;
for (j = 0; i < strlen(ptext); i++,j++) for (j = 0; i < HU_StringLength(ptext); i++,j++)
{ {
if (ptext[i] == '\"' && !quotes && i > 0 && ptext[i-1] != ' ') // Malformed command if (ptext[i] == '\"' && !quotes && i > 0 && ptext[i-1] != ' ') // Malformed command
return; return;
...@@ -384,7 +384,7 @@ size_t COM_FirstOption(void) ...@@ -384,7 +384,7 @@ size_t COM_FirstOption(void)
* \param ptext A null-terminated string. Does not need to be * \param ptext A null-terminated string. Does not need to be
* newline-terminated. * newline-terminated.
*/ */
static void COM_TokenizeString(char *ptext) static void COM_TokenizeString(UINT8 *ptext)
{ {
size_t i; size_t i;
...@@ -407,13 +407,13 @@ static void COM_TokenizeString(char *ptext) ...@@ -407,13 +407,13 @@ static void COM_TokenizeString(char *ptext)
break; break;
if (com_argc == 1) if (com_argc == 1)
com_args = ptext; com_args = (char *)ptext;
ptext = COM_Parse(ptext); ptext = COM_Parse(ptext);
if (ptext == NULL) if (ptext == NULL)
break; break;
com_argv[com_argc] = Z_StrDup(com_token); com_argv[com_argc] = (char *)HU_StringCopyAlloc(com_token);
com_argc++; com_argc++;
} }
} }
...@@ -541,7 +541,7 @@ const char *COM_CompleteCommand(const char *partial, INT32 skips) ...@@ -541,7 +541,7 @@ const char *COM_CompleteCommand(const char *partial, INT32 skips)
* *
* \param ptext A single line of text. * \param ptext A single line of text.
*/ */
static void COM_ExecuteString(char *ptext) static void COM_ExecuteString(UINT8 *ptext)
{ {
xcommand_t *cmd; xcommand_t *cmd;
cmdalias_t *a; cmdalias_t *a;
...@@ -2077,9 +2077,9 @@ void CV_SaveVariables(FILE *f) ...@@ -2077,9 +2077,9 @@ void CV_SaveVariables(FILE *f)
* \param data String to parse. * \param data String to parse.
* \return The data pointer after the token. NULL if no token found. * \return The data pointer after the token. NULL if no token found.
*/ */
static char *COM_Parse(char *data) static UINT8 *COM_Parse(UINT8 *data)
{ {
char c; UINT8 c;
size_t len = 0; size_t len = 0;
com_token[0] = 0; com_token[0] = 0;
......
...@@ -42,7 +42,7 @@ void COM_BufAddText(const char *btext); ...@@ -42,7 +42,7 @@ void COM_BufAddText(const char *btext);
void COM_BufInsertText(const char *btext); void COM_BufInsertText(const char *btext);
// don't bother inserting, just do immediately // don't bother inserting, just do immediately
void COM_ImmedExecute(const char *ptext); void COM_ImmedExecute(const char *itext);
// Execute commands in buffer, flush them // Execute commands in buffer, flush them
void COM_BufExecute(void); void COM_BufExecute(void);
......
...@@ -139,7 +139,7 @@ static CV_PossibleValue_t backcolor_cons_t[] = {{0, "White"}, {1, "Black"}, { ...@@ -139,7 +139,7 @@ static CV_PossibleValue_t backcolor_cons_t[] = {{0, "White"}, {1, "Black"}, {
consvar_t cons_backcolor = {"con_backcolor", "Green", CV_CALL|CV_SAVE, backcolor_cons_t, CONS_backcolor_Change, 0, NULL, NULL, 0, 0, NULL}; consvar_t cons_backcolor = {"con_backcolor", "Green", CV_CALL|CV_SAVE, backcolor_cons_t, CONS_backcolor_Change, 0, NULL, NULL, 0, 0, NULL};
static void CON_Print(char *msg); static void CON_Print(UINT8 *msg);
// //
// //
...@@ -399,7 +399,6 @@ void CON_Init(void) ...@@ -399,7 +399,6 @@ void CON_Init(void)
con_destlines = vid.height; con_destlines = vid.height;
con_curlines = vid.height; con_curlines = vid.height;
if (!dedicated) if (!dedicated)
{ {
con_started = true; con_started = true;
...@@ -518,7 +517,7 @@ static void CON_RecalcSize(void) ...@@ -518,7 +517,7 @@ static void CON_RecalcSize(void)
conw--; conw--;
string[conw+1] = '\n'; string[conw+1] = '\n';
string[conw+2] = '\0'; string[conw+2] = '\0';
CON_Print(string); CON_Print((UINT8 *)string);
} }
} }
} }
...@@ -679,8 +678,8 @@ static void CON_InputClear(void) ...@@ -679,8 +678,8 @@ static void CON_InputClear(void)
static void CON_InputSetString(const char *c) static void CON_InputSetString(const char *c)
{ {
memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS); memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS);
strcpy(inputlines[inputline], c); HU_StringCopy((UINT8 *)inputlines[inputline], (const UINT8 *)c);
input_cur = input_sel = input_len = strlen(c); input_cur = input_sel = input_len = HU_StringLength((const UINT8 *)c);
} }
static void CON_InputAddString(const char *c) static void CON_InputAddString(const char *c)
...@@ -743,6 +742,11 @@ static void CON_InputDelChar(void) ...@@ -743,6 +742,11 @@ static void CON_InputDelChar(void)
// ---- // ----
// //
boolean CON_AcceptInput(void)
{
return consoleready;
}
// Handles console key input // Handles console key input
// //
boolean CON_Responder(event_t *ev) boolean CON_Responder(event_t *ev)
...@@ -760,7 +764,7 @@ boolean CON_Responder(event_t *ev) ...@@ -760,7 +764,7 @@ boolean CON_Responder(event_t *ev)
return false; return false;
// let go keyup events, don't eat them // let go keyup events, don't eat them
if (ev->type != ev_keydown && ev->type != ev_console) if (ev->type != ev_keydown && ev->type != ev_textinput && ev->type != ev_console)
{ {
if (ev->data1 == gamecontrol[gc_console][0] || ev->data1 == gamecontrol[gc_console][1]) if (ev->data1 == gamecontrol[gc_console][0] || ev->data1 == gamecontrol[gc_console][1])
consdown = false; consdown = false;
...@@ -787,7 +791,7 @@ boolean CON_Responder(event_t *ev) ...@@ -787,7 +791,7 @@ boolean CON_Responder(event_t *ev)
// check other keys only if console prompt is active // check other keys only if console prompt is active
if (!consoleready && key < NUMINPUTS) // metzgermeister: boundary check!! if (!consoleready && key < NUMINPUTS) // metzgermeister: boundary check!!
{ {
if (bindtable[key]) if (bindtable[key] && ev->type == ev_keydown) // ev_textinput crashes the game. Why?
{ {
COM_BufAddText(bindtable[key]); COM_BufAddText(bindtable[key]);
COM_BufAddText("\n"); COM_BufAddText("\n");
...@@ -1075,33 +1079,42 @@ boolean CON_Responder(event_t *ev) ...@@ -1075,33 +1079,42 @@ boolean CON_Responder(event_t *ev)
} }
// allow people to use keypad in console (good for typing IP addresses) - Calum // allow people to use keypad in console (good for typing IP addresses) - Calum
if (key >= KEY_KEYPAD7 && key <= KEY_KPADDEL) if (!cv_textinput.value)
{ {
char keypad_translation[] = {'7','8','9','-', if (key >= KEY_KEYPAD7 && key <= KEY_KPADDEL)
'4','5','6','+', {
'1','2','3', char keypad_translation[] = {'7','8','9','-',
'0','.'}; '4','5','6','+',
'1','2','3',
'0','.'};
key = keypad_translation[key - KEY_KEYPAD7]; key = keypad_translation[key - KEY_KEYPAD7];
} }
else if (key == KEY_KPADSLASH) else if (key == KEY_KPADSLASH)
key = '/'; key = '/';
if (key >= 'a' && key <= 'z') if (key >= 'a' && key <= 'z')
{ {
if (capslock ^ shiftdown) if (capslock ^ shiftdown)
key = shiftxform[key];
}
else if (shiftdown)
key = shiftxform[key]; key = shiftxform[key];
} }
else if (shiftdown)
key = shiftxform[key]; // Lactozilla: Ignore caps lock key
// or else it turns into a printable character
if (ev->type != ev_textinput && key == KEY_CAPSLOCK)
return true;
// enter a char into the command prompt // enter a char into the command prompt
if (key < 32 || key > 127) if (key < 32 || key > 0xFF)
return true; return true;
// add key to cmd line here // add key to cmd line here
if (key >= 'A' && key <= 'Z' && !(shiftdown ^ capslock)) //this is only really necessary for dedicated servers if (!cv_textinput.value)
key = key + 'a' - 'A'; if (key >= 'A' && key <= 'Z' && !(shiftdown ^ capslock)) //this is only really necessary for dedicated servers
key = key + 'a' - 'A';
if (input_sel != input_cur) if (input_sel != input_cur)
CON_InputDelSelection(); CON_InputDelSelection();
...@@ -1128,7 +1141,7 @@ static void CON_Linefeed(void) ...@@ -1128,7 +1141,7 @@ static void CON_Linefeed(void)
} }
// Outputs text into the console text buffer // Outputs text into the console text buffer
static void CON_Print(char *msg) static void CON_Print(UINT8 *msg)
{ {
size_t l; size_t l;
INT32 controlchars = 0; // for color changing INT32 controlchars = 0; // for color changing
...@@ -1145,7 +1158,7 @@ static void CON_Print(char *msg) ...@@ -1145,7 +1158,7 @@ static void CON_Print(char *msg)
S_StartSound(NULL, sfx_radio); S_StartSound(NULL, sfx_radio);
} }
if (!(*msg & 0x80)) if (!(HU_IsColorCode(*msg)))
{ {
con_line[con_cx++] = '\x80'; con_line[con_cx++] = '\x80';
controlchars = 1; controlchars = 1;
...@@ -1156,7 +1169,7 @@ static void CON_Print(char *msg) ...@@ -1156,7 +1169,7 @@ static void CON_Print(char *msg)
// skip non-printable characters and white spaces // skip non-printable characters and white spaces
while (*msg && *msg <= ' ') while (*msg && *msg <= ' ')
{ {
if (*msg & 0x80) if (HU_IsColorCode(*msg))
{ {
color = con_line[con_cx++] = *(msg++); color = con_line[con_cx++] = *(msg++);
controlchars++; controlchars++;
...@@ -1275,7 +1288,7 @@ void CONS_Printf(const char *fmt, ...) ...@@ -1275,7 +1288,7 @@ void CONS_Printf(const char *fmt, ...)
} }
else else
// write message in con text buffer // write message in con text buffer
CON_Print(txt); CON_Print((UINT8 *)txt);
#ifndef PC_DOS #ifndef PC_DOS
CON_LogMessage(txt); CON_LogMessage(txt);
...@@ -1385,7 +1398,7 @@ void CONS_Error(const char *msg) ...@@ -1385,7 +1398,7 @@ void CONS_Error(const char *msg)
static void CON_DrawInput(void) static void CON_DrawInput(void)
{ {
INT32 charwidth = (INT32)con_scalefactor << 3; INT32 charwidth = (INT32)con_scalefactor << 3;
const char *p = inputlines[inputline]; const UINT8 *p = (UINT8 *)inputlines[inputline];
size_t c, clen, cend; size_t c, clen, cend;
UINT8 lellip = 0, rellip = 0; UINT8 lellip = 0, rellip = 0;
INT32 x, y, i; INT32 x, y, i;
...@@ -1440,32 +1453,32 @@ static void CON_DrawInput(void) ...@@ -1440,32 +1453,32 @@ static void CON_DrawInput(void)
if (input_sel < c) if (input_sel < c)
V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 77 | V_NOSCALESTART); V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 77 | V_NOSCALESTART);
for (i = 0; i < 3; ++i, x += charwidth) for (i = 0; i < 3; ++i, x += charwidth)
V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, true); V_DrawCharacter(x, y, '.', cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, true);
} }
else else
V_DrawCharacter(x-charwidth, y, CON_PROMPTCHAR | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, true); V_DrawCharacter(x-charwidth, y, CON_PROMPTCHAR, cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, true);
for (cend = c + clen; c < cend; ++c, x += charwidth) for (cend = c + clen; c < cend; ++c, x += charwidth)
{ {
if ((input_sel > c && input_cur <= c) || (input_sel <= c && input_cur > c)) if ((input_sel > c && input_cur <= c) || (input_sel <= c && input_cur > c))
{ {
V_DrawFill(x, y, charwidth, (10 * con_scalefactor), 77 | V_NOSCALESTART); V_DrawFill(x, y, charwidth, (10 * con_scalefactor), 77 | V_NOSCALESTART);
V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_YELLOWMAP | V_NOSCALESTART, true); V_DrawCharacter(x, y, p[c], cv_constextsize.value | V_YELLOWMAP | V_NOSCALESTART, true);
} }
else else
V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, true); V_DrawCharacter(x, y, p[c], cv_constextsize.value | V_NOSCALESTART, true);
if (c == input_cur && con_tick >= 4) if (c == input_cur && con_tick >= 4)
V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, true); V_DrawCharacter(x, y + (con_scalefactor*2), '_', cv_constextsize.value | V_NOSCALESTART, true);
} }
if (cend == input_cur && con_tick >= 4) if (cend == input_cur && con_tick >= 4)
V_DrawCharacter(x, y + (con_scalefactor*2), '_' | cv_constextsize.value | V_NOSCALESTART, true); V_DrawCharacter(x, y + (con_scalefactor*2), '_', cv_constextsize.value | V_NOSCALESTART, true);
if (rellip) if (rellip)
{ {
if (input_sel > cend) if (input_sel > cend)
V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 77 | V_NOSCALESTART); V_DrawFill(x, y, charwidth*3, (10 * con_scalefactor), 77 | V_NOSCALESTART);
for (i = 0; i < 3; ++i, x += charwidth) for (i = 0; i < 3; ++i, x += charwidth)
V_DrawCharacter(x, y, '.' | cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, true); V_DrawCharacter(x, y, '.', cv_constextsize.value | V_GRAYMAP | V_NOSCALESTART, true);
} }
} }
...@@ -1501,7 +1514,7 @@ static void CON_DrawHudlines(void) ...@@ -1501,7 +1514,7 @@ static void CON_DrawHudlines(void)
for (c = 0, x = 0; c < con_width; c++, x += charwidth, p++) for (c = 0, x = 0; c < con_width; c++, x += charwidth, p++)
{ {
while (*p & 0x80) // Graue 06-19-2004 while (HU_IsColorCode(*p)) // Graue 06-19-2004
{ {
charflags = (*p & 0x7f) << V_CHARCOLORSHIFT; charflags = (*p & 0x7f) << V_CHARCOLORSHIFT;
p++; p++;
...@@ -1511,11 +1524,11 @@ static void CON_DrawHudlines(void) ...@@ -1511,11 +1524,11 @@ static void CON_DrawHudlines(void)
else else
{ {
//charwidth = SHORT(hu_font['A'-HU_FONTSTART]->width) * con_scalefactor; //charwidth = SHORT(hu_font['A'-HU_FONTSTART]->width) * con_scalefactor;
V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, true); V_DrawCharacter(x, y, *p, charflags | cv_constextsize.value | V_NOSCALESTART, true);
} }
} }
//V_DrawCharacter(x, y, (p[c]&0xff) | cv_constextsize.value | V_NOSCALESTART, true); //V_DrawCharacter(x, y, (p[c]&0xff), cv_constextsize.value | V_NOSCALESTART, true);
y += charheight; y += charheight;
} }
...@@ -1581,12 +1594,12 @@ static void CON_DrawConsole(void) ...@@ -1581,12 +1594,12 @@ static void CON_DrawConsole(void)
for (c = 0, x = charwidth; c < con_width; c++, x += charwidth, p++) for (c = 0, x = charwidth; c < con_width; c++, x += charwidth, p++)
{ {
while (*p & 0x80) while (HU_IsColorCode(*p))
{ {
charflags = (*p & 0x7f) << V_CHARCOLORSHIFT; charflags = (*p & 0x7f) << V_CHARCOLORSHIFT;
p++; p++;
} }
V_DrawCharacter(x, y, (INT32)(*p) | charflags | cv_constextsize.value | V_NOSCALESTART, true); V_DrawCharacter(x, y, (INT32)(*p), charflags | cv_constextsize.value | V_NOSCALESTART, true);
} }
} }
......
...@@ -16,6 +16,7 @@ ...@@ -16,6 +16,7 @@
void CON_Init(void); void CON_Init(void);
boolean CON_Responder(event_t *ev); boolean CON_Responder(event_t *ev);
boolean CON_AcceptInput(void);
// set true when screen size has changed, to adapt console // set true when screen size has changed, to adapt console
extern boolean con_recalc; extern boolean con_recalc;
......
...@@ -1295,8 +1295,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) ...@@ -1295,8 +1295,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame; netbuffer->u.serverinfo.modifiedgame = (UINT8)modifiedgame;
netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled(); netbuffer->u.serverinfo.cheatsenabled = CV_CheatsEnabled();
netbuffer->u.serverinfo.isdedicated = (UINT8)dedicated; netbuffer->u.serverinfo.isdedicated = (UINT8)dedicated;
strncpy(netbuffer->u.serverinfo.servername, cv_servername.string, HU_StringCopyLen((UINT8 *)netbuffer->u.serverinfo.servername, (const UINT8 *)cv_servername.string, MAXSERVERNAME);
MAXSERVERNAME);
strncpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), 7); strncpy(netbuffer->u.serverinfo.mapname, G_BuildMapName(gamemap), 7);
M_Memcpy(netbuffer->u.serverinfo.mapmd5, mapmd5, 16); M_Memcpy(netbuffer->u.serverinfo.mapmd5, mapmd5, 16);
...@@ -1308,7 +1307,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime) ...@@ -1308,7 +1307,7 @@ static void SV_SendServerInfo(INT32 node, tic_t servertime)
char *read = mapheaderinfo[gamemap-1]->lvlttl, *writ = netbuffer->u.serverinfo.maptitle; char *read = mapheaderinfo[gamemap-1]->lvlttl, *writ = netbuffer->u.serverinfo.maptitle;
while (writ < (netbuffer->u.serverinfo.maptitle+32) && *read != '\0') while (writ < (netbuffer->u.serverinfo.maptitle+32) && *read != '\0')
{ {
if (!(*read & 0x80)) if (!(HU_IsColorCode(*read)))
{ {
*writ = toupper(*read); *writ = toupper(*read);
writ++; writ++;
......
...@@ -27,6 +27,7 @@ typedef enum ...@@ -27,6 +27,7 @@ typedef enum
ev_joystick, ev_joystick,
ev_mouse2, ev_mouse2,
ev_joystick2, ev_joystick2,
ev_textinput,
} evtype_t; } evtype_t;
// Event structure. // Event structure.
......
...@@ -916,8 +916,15 @@ boolean EnsurePlayerNameIsGood(char *name, INT32 playernum) ...@@ -916,8 +916,15 @@ boolean EnsurePlayerNameIsGood(char *name, INT32 playernum)
// Also, anything over 0x80 is disallowed too, since compilers love to // Also, anything over 0x80 is disallowed too, since compilers love to
// differ on whether they're printable characters or not. // differ on whether they're printable characters or not.
for (ix = 0; name[ix] != '\0'; ix++) for (ix = 0; name[ix] != '\0'; ix++)
if (!isprint(name[ix]) || name[ix] == ';' || (UINT8)(name[ix]) >= 0x80) {
int printable = isprint(name[ix]);
// Lactozilla: Apparently Unicode isn't printable.
// Oh well.
if ((UINT8)name[ix] > 0x7F)
printable = 1;
if (!printable || name[ix] == ';' || HU_IsColorCode((UINT8)(name[ix])))
return false; return false;
}
// Check if a player is currently using the name, case-insensitively. // Check if a player is currently using the name, case-insensitively.
for (ix = 0; ix < MAXPLAYERS; ix++) for (ix = 0; ix < MAXPLAYERS; ix++)
......
...@@ -2246,7 +2246,7 @@ void F_EndingDrawer(void) ...@@ -2246,7 +2246,7 @@ void F_EndingDrawer(void)
{ {
//colset(linkmap, 164, 165, 169); -- the ideal purple colour to represent a clicked in-game link, but not worth it just for a soundtest-controlled secret //colset(linkmap, 164, 165, 169); -- the ideal purple colour to represent a clicked in-game link, but not worth it just for a soundtest-controlled secret
V_DrawCenteredString(BASEVIDWIDTH/2, 8, V_ALLOWLOWERCASE|(trans<<V_ALPHASHIFT), str); V_DrawCenteredString(BASEVIDWIDTH/2, 8, V_ALLOWLOWERCASE|(trans<<V_ALPHASHIFT), str);
V_DrawCharacter(32, BASEVIDHEIGHT-16, '>'|(trans<<V_ALPHASHIFT), false); V_DrawCharacter(32, BASEVIDHEIGHT-16, '>', (trans<<V_ALPHASHIFT), false);
V_DrawString(40, ((finalecount == STOPPINGPOINT-(20+TICRATE)) ? 1 : 0)+BASEVIDHEIGHT-16, ((timesBeaten || finalecount >= STOPPINGPOINT-TICRATE) ? V_PURPLEMAP : V_BLUEMAP)|(trans<<V_ALPHASHIFT), " [S] ===>"); V_DrawString(40, ((finalecount == STOPPINGPOINT-(20+TICRATE)) ? 1 : 0)+BASEVIDHEIGHT-16, ((timesBeaten || finalecount >= STOPPINGPOINT-TICRATE) ? V_PURPLEMAP : V_BLUEMAP)|(trans<<V_ALPHASHIFT), " [S] ===>");
} }
...@@ -2262,7 +2262,7 @@ void F_EndingDrawer(void) ...@@ -2262,7 +2262,7 @@ void F_EndingDrawer(void)
else else
trans2 += 2*trans; trans2 += 2*trans;
if (trans2 < 10) if (trans2 < 10)
V_DrawCharacter(26, BASEVIDHEIGHT-33, '\x1C'|(trans2<<V_ALPHASHIFT), false); V_DrawCharacter(26, BASEVIDHEIGHT-33, '\x1C', (trans2<<V_ALPHASHIFT), false);
} }
} }
} }
......
...@@ -40,7 +40,7 @@ INT32 mouse2x, mouse2y, mlook2y; ...@@ -40,7 +40,7 @@ INT32 mouse2x, mouse2y, mlook2y;
INT32 joyxmove[JOYAXISSET], joyymove[JOYAXISSET], joy2xmove[JOYAXISSET], joy2ymove[JOYAXISSET]; INT32 joyxmove[JOYAXISSET], joyymove[JOYAXISSET], joy2xmove[JOYAXISSET], joy2ymove[JOYAXISSET];
// current state of the keys: true if pushed // current state of the keys: true if pushed
UINT8 gamekeydown[NUMINPUTS]; INT32 gamekeydown[NUMINPUTS];
// two key codes (or virtual key) per game control // two key codes (or virtual key) per game control
INT32 gamecontrol[num_gamecontrols][2]; INT32 gamecontrol[num_gamecontrols][2];
...@@ -117,7 +117,7 @@ void G_MapEventsToControls(event_t *ev) ...@@ -117,7 +117,7 @@ void G_MapEventsToControls(event_t *ev)
switch (ev->type) switch (ev->type)
{ {
case ev_keydown: case ev_keydown:
if (ev->data1 < NUMINPUTS) if (ev->data1 < NUMINPUTS || (ev->data1 & KEY_XTMASK))
gamekeydown[ev->data1] = 1; gamekeydown[ev->data1] = 1;
#ifdef PARANOIA #ifdef PARANOIA
else else
...@@ -129,7 +129,7 @@ void G_MapEventsToControls(event_t *ev) ...@@ -129,7 +129,7 @@ void G_MapEventsToControls(event_t *ev)
break; break;
case ev_keyup: case ev_keyup:
if (ev->data1 < NUMINPUTS) if (ev->data1 < NUMINPUTS || (ev->data1 & KEY_XTMASK))
gamekeydown[ev->data1] = 0; gamekeydown[ev->data1] = 0;
#ifdef PARANOIA #ifdef PARANOIA
else else
...@@ -245,13 +245,14 @@ static keyname_t keynames[] = ...@@ -245,13 +245,14 @@ static keyname_t keynames[] =
{KEY_TAB, "TAB"}, {KEY_TAB, "TAB"},
{KEY_ESCAPE, "ESCAPE"}, {KEY_ESCAPE, "ESCAPE"},
{KEY_BACKSPACE, "BACKSPACE"}, {KEY_BACKSPACE, "BACKSPACE"},
{KEY_PRTSC, "PRINTSCREEN"},
{KEY_NUMLOCK, "NUMLOCK"}, {KEY_NUMLOCK, "NUMLOCK"},
{KEY_SCROLLLOCK, "SCROLLLOCK"}, {KEY_SCROLLLOCK, "SCROLLLOCK"},
// bill gates keys // bill gates keys
{KEY_LEFTWIN, "LEFTWIN"}, {KEY_LEFTWIN, "LEFTGUI"},
{KEY_RIGHTWIN, "RIGHTWIN"}, {KEY_RIGHTWIN, "RIGHTGUI"},
{KEY_MENU, "MENU"}, {KEY_MENU, "MENU"},
{KEY_LSHIFT, "LSHIFT"}, {KEY_LSHIFT, "LSHIFT"},
...@@ -306,7 +307,7 @@ static keyname_t keynames[] = ...@@ -306,7 +307,7 @@ static keyname_t keynames[] =
{KEY_F11, "F11"}, {KEY_F11, "F11"},
{KEY_F12, "F12"}, {KEY_F12, "F12"},
// KEY_CONSOLE has an exception in the keyname code // I don't think that's a tilde
{'`', "TILDE"}, {'`', "TILDE"},
{KEY_PAUSE, "PAUSE/BREAK"}, {KEY_PAUSE, "PAUSE/BREAK"},
...@@ -637,9 +638,9 @@ const char *G_KeynumToString(INT32 keynum) ...@@ -637,9 +638,9 @@ const char *G_KeynumToString(INT32 keynum)
UINT32 j; UINT32 j;
// return a string with the ascii char if displayable // return a string with the ascii char if displayable
if (keynum > ' ' && keynum <= 'z' && keynum != KEY_CONSOLE) if (keynum > ' ' && keynum <= 0xFF && keynum != KEY_CONSOLE)
{ {
keynamestr[0] = (char)keynum; keynamestr[0] = (UINT8)keynum;
keynamestr[1] = '\0'; keynamestr[1] = '\0';
return keynamestr; return keynamestr;
} }
...@@ -656,10 +657,12 @@ const char *G_KeynumToString(INT32 keynum) ...@@ -656,10 +657,12 @@ const char *G_KeynumToString(INT32 keynum)
INT32 G_KeyStringtoNum(const char *keystr) INT32 G_KeyStringtoNum(const char *keystr)
{ {
const UINT8 *keystr_u = (const UINT8 *)keystr;
UINT32 j; UINT32 j;
if (!keystr[1] && keystr[0] > ' ' && keystr[0] <= 'z') // You can put as your strafe left key but the game won't recognize it
return keystr[0]; if (!keystr_u[1] && keystr_u[0] > ' ')
return (UINT8)keystr[0];
if (!strncmp(keystr, "KEY", 3) && keystr[3] >= '0' && keystr[3] <= '9') if (!strncmp(keystr, "KEY", 3) && keystr[3] >= '0' && keystr[3] <= '9')
return atoi(&keystr[3]); return atoi(&keystr[3]);
......
...@@ -20,7 +20,7 @@ ...@@ -20,7 +20,7 @@
// number of total 'button' inputs, include keyboard keys, plus virtual // number of total 'button' inputs, include keyboard keys, plus virtual
// keys (mousebuttons and joybuttons becomes keys) // keys (mousebuttons and joybuttons becomes keys)
#define NUMKEYS 256 #define NUMKEYS 0x200 // Needs to be at least a single bit higher KEY_XTMASK!!!!
#define MOUSEBUTTONS 8 #define MOUSEBUTTONS 8
#define JOYBUTTONS 32 // 32 buttons #define JOYBUTTONS 32 // 32 buttons
...@@ -123,7 +123,7 @@ extern INT32 mouse2x, mouse2y, mlook2y; ...@@ -123,7 +123,7 @@ extern INT32 mouse2x, mouse2y, mlook2y;
extern INT32 joyxmove[JOYAXISSET], joyymove[JOYAXISSET], joy2xmove[JOYAXISSET], joy2ymove[JOYAXISSET]; extern INT32 joyxmove[JOYAXISSET], joyymove[JOYAXISSET], joy2xmove[JOYAXISSET], joy2ymove[JOYAXISSET];
// current state of the keys: true if pushed // current state of the keys: true if pushed
extern UINT8 gamekeydown[NUMINPUTS]; extern INT32 gamekeydown[NUMINPUTS];
// two key codes (or virtual key) per game control // two key codes (or virtual key) per game control
extern INT32 gamecontrol[num_gamecontrols][2]; extern INT32 gamecontrol[num_gamecontrols][2];
......
...@@ -77,6 +77,7 @@ patch_t *nto_font[NT_FONTSIZE]; ...@@ -77,6 +77,7 @@ patch_t *nto_font[NT_FONTSIZE];
static player_t *plr; static player_t *plr;
boolean chat_on; // entering a chat message? boolean chat_on; // entering a chat message?
static tic_t chat_delay = 0;
static char w_chat[HU_MAXMSGLEN]; static char w_chat[HU_MAXMSGLEN];
static size_t c_input = 0; // let's try to make the chat input less shitty. static size_t c_input = 0; // let's try to make the chat input less shitty.
static boolean headsupactive = false; static boolean headsupactive = false;
...@@ -192,6 +193,9 @@ void HU_LoadGraphics(void) ...@@ -192,6 +193,9 @@ void HU_LoadGraphics(void)
{ {
// cache the heads-up font for entire game execution // cache the heads-up font for entire game execution
sprintf(buffer, "STCFN%.3d", j); sprintf(buffer, "STCFN%.3d", j);
if (j > 127)
sprintf(buffer, "UN%06X", j);
if (W_CheckNumForName(buffer) == LUMPERROR) if (W_CheckNumForName(buffer) == LUMPERROR)
hu_font[i] = NULL; hu_font[i] = NULL;
else else
...@@ -371,8 +375,9 @@ static UINT32 chat_maxscroll = 0; // how far can we scroll? ...@@ -371,8 +375,9 @@ static UINT32 chat_maxscroll = 0; // how far can we scroll?
//static chatmsg_t chat_mini[CHAT_BUFSIZE]; // Display the last few messages sent. //static chatmsg_t chat_mini[CHAT_BUFSIZE]; // Display the last few messages sent.
//static chatmsg_t chat_log[CHAT_BUFSIZE]; // Keep every message sent to us in memory so we can scroll n shit, it's cool. //static chatmsg_t chat_log[CHAT_BUFSIZE]; // Keep every message sent to us in memory so we can scroll n shit, it's cool.
static char chat_log[CHAT_BUFSIZE][255]; // hold the last 48 or so messages in that log. #define CHATLENGTH 255 // Why not 256?
static char chat_mini[8][255]; // display up to 8 messages that will fade away / get overwritten static char chat_log[CHAT_BUFSIZE][CHATLENGTH]; // hold the last 48 or so messages in that log.
static char chat_mini[8][CHATLENGTH]; // display up to 8 messages that will fade away / get overwritten
static tic_t chat_timers[8]; static tic_t chat_timers[8];
static boolean chat_scrollmedown = false; // force instant scroll down on the chat log. Happens when you open it / send a message. static boolean chat_scrollmedown = false; // force instant scroll down on the chat log. Happens when you open it / send a message.
...@@ -383,10 +388,10 @@ static INT16 addy = 0; // use this to make the messages scroll smoothly when one ...@@ -383,10 +388,10 @@ static INT16 addy = 0; // use this to make the messages scroll smoothly when one
static void HU_removeChatText_Mini(void) static void HU_removeChatText_Mini(void)
{ {
// MPC: Don't create new arrays, just iterate through an existing one // Lactozilla: Don't create new arrays, just iterate through an existing one
size_t i; size_t i;
for(i=0;i<chat_nummsg_min-1;i++) { for(i=0;i<chat_nummsg_min-1;i++) {
strcpy(chat_mini[i], chat_mini[i+1]); HU_StringCopy((UINT8 *)chat_mini[i], (UINT8 *)chat_mini[i+1]);
chat_timers[i] = chat_timers[i+1]; chat_timers[i] = chat_timers[i+1];
} }
chat_nummsg_min--; // lost 1 msg. chat_nummsg_min--; // lost 1 msg.
...@@ -399,10 +404,10 @@ static void HU_removeChatText_Mini(void) ...@@ -399,10 +404,10 @@ static void HU_removeChatText_Mini(void)
// same but w the log. TODO: optimize this and maybe merge in a single func? im bad at C. // same but w the log. TODO: optimize this and maybe merge in a single func? im bad at C.
static void HU_removeChatText_Log(void) static void HU_removeChatText_Log(void)
{ {
// MPC: Don't create new arrays, just iterate through an existing one // Lactozilla: Don't create new arrays, just iterate through an existing one
size_t i; size_t i;
for(i=0;i<chat_nummsg_log-1;i++) { for(i=0;i<chat_nummsg_log-1;i++) {
strcpy(chat_log[i], chat_log[i+1]); HU_StringCopy((UINT8 *)chat_log[i], (UINT8 *)chat_log[i+1]);
} }
chat_nummsg_log--; // lost 1 msg. chat_nummsg_log--; // lost 1 msg.
} }
...@@ -418,13 +423,13 @@ void HU_AddChatText(const char *text, boolean playsound) ...@@ -418,13 +423,13 @@ void HU_AddChatText(const char *text, boolean playsound)
if (chat_nummsg_log >= CHAT_BUFSIZE) // too many messages! if (chat_nummsg_log >= CHAT_BUFSIZE) // too many messages!
HU_removeChatText_Log(); HU_removeChatText_Log();
strcpy(chat_log[chat_nummsg_log], text); HU_StringCopyLen((UINT8 *)chat_log[chat_nummsg_log], (const UINT8 *)text, CHATLENGTH);
chat_nummsg_log++; chat_nummsg_log++;
if (chat_nummsg_min >= 8) if (chat_nummsg_min >= 8)
HU_removeChatText_Mini(); HU_removeChatText_Mini();
strcpy(chat_mini[chat_nummsg_min], text); HU_StringCopyLen((UINT8 *)chat_mini[chat_nummsg_min], (const UINT8 *)text, CHATLENGTH);
chat_timers[chat_nummsg_min] = TICRATE*cv_chattime.value; chat_timers[chat_nummsg_min] = TICRATE*cv_chattime.value;
chat_nummsg_min++; chat_nummsg_min++;
...@@ -438,6 +443,60 @@ void HU_AddChatText(const char *text, boolean playsound) ...@@ -438,6 +443,60 @@ void HU_AddChatText(const char *text, boolean playsound)
#endif #endif
} }
size_t HU_StringLength(const UINT8 *str)
{
UINT32 i = 0;
size_t len = 0;
while (true)
{
UINT8 ch = str[i];
if (!ch)
break;
if ((ch >= HU_FONTSTART && hu_font[ch-HU_FONTSTART]) || ch == ' ')
len++;
i++;
}
return len;
}
void HU_StringCopy(UINT8 *dest, const UINT8 *src)
{
UINT32 i = 0;
while (true)
{
dest[i] = src[i];
if (!dest[i])
{
dest[i] = '\0';
break;
}
i++;
}
}
void HU_StringCopyLen(UINT8 *dest, const UINT8 *src, size_t len)
{
UINT32 i;
for (i = 0; i < len; i++)
{
dest[i] = src[i];
if (!dest[i])
{
dest[i] = '\0';
break;
}
}
dest[len-1] = '\0';
}
UINT8 *HU_StringCopyAlloc(const UINT8 *src)
{
size_t length = HU_StringLength(src);
UINT8 *buf = Z_Malloc(length + 1, PU_STATIC, NULL);
HU_StringCopy(buf, src);
return buf;
}
#ifndef NONET #ifndef NONET
/** Runs a say command, sending an ::XD_SAY message. /** Runs a say command, sending an ::XD_SAY message.
...@@ -496,7 +555,7 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags) ...@@ -496,7 +555,7 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags)
strlcat(msg, COM_Argv(ix + usedargs), msgspace); strlcat(msg, COM_Argv(ix + usedargs), msgspace);
} }
if (strlen(msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm if (HU_StringLength((UINT8 *)msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm
{ {
// what we're gonna do now is check if the player exists // what we're gonna do now is check if the player exists
// with that logic, characters 4 and 5 are our numbers: // with that logic, characters 4 and 5 are our numbers:
...@@ -547,7 +606,7 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags) ...@@ -547,7 +606,7 @@ static void DoSayCommand(SINT8 target, size_t usedargs, UINT8 flags)
strlcpy(msg, newmsg, 252); strlcpy(msg, newmsg, 252);
} }
SendNetXCmd(XD_SAY, buf, strlen(msg) + 1 + msg-buf); SendNetXCmd(XD_SAY, buf, HU_StringLength((UINT8 *)msg) + 1 + msg-buf);
} }
/** Send a message to everyone. /** Send a message to everyone.
...@@ -669,13 +728,13 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) ...@@ -669,13 +728,13 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
return; return;
} }
//check for invalid characters (0x80 or above) //check for invalid characters (color codes)
{ {
size_t i; size_t i;
const size_t j = strlen(msg); const size_t j = HU_StringLength((UINT8 *)msg);
for (i = 0; i < j; i++) for (i = 0; i < j; i++)
{ {
if (msg[i] & 0x80) if (HU_IsColorCode(msg[i]))
{ {
CONS_Alert(CONS_WARNING, M_GetText("Illegal say command received from %s containing invalid characters\n"), player_names[playernum]); CONS_Alert(CONS_WARNING, M_GetText("Illegal say command received from %s containing invalid characters\n"), player_names[playernum]);
if (server) if (server)
...@@ -723,7 +782,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) ...@@ -723,7 +782,7 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
} }
// Handle "/me" actions, but only in messages to everyone. // Handle "/me" actions, but only in messages to everyone.
if (target == 0 && strlen(msg) > 4 && strnicmp(msg, "/me ", 4) == 0) if (target == 0 && HU_StringLength((UINT8 *)msg) > 4 && strnicmp(msg, "/me ", 4) == 0)
{ {
msg += 4; msg += 4;
action = true; action = true;
...@@ -900,13 +959,13 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) ...@@ -900,13 +959,13 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
// name, color end, and the message itself. // name, color end, and the message itself.
// '\4' makes the message yellow and beeps; '\3' just beeps. // '\4' makes the message yellow and beeps; '\3' just beeps.
if (action) if (action)
fmt2 = "* %s%s%s%s \x82%s%s"; fmt2 = "* %s%s%s%s \x82%s";
else if (target-1 == consoleplayer) // To you else if (target-1 == consoleplayer) // To you
{ {
prefix = "\x82[PM]"; prefix = "\x82[PM]";
cstart = "\x82"; cstart = "\x82";
textcolor = "\x82"; textcolor = "\x82";
fmt2 = "%s<%s%s>%s\x80 %s%s"; fmt2 = "%s<%s%s>%s\x80 %s";
} }
else if (target > 0) // By you, to another player else if (target > 0) // By you, to another player
{ {
...@@ -914,11 +973,10 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) ...@@ -914,11 +973,10 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
dispname = player_names[target-1]; dispname = player_names[target-1];
prefix = "\x82[TO]"; prefix = "\x82[TO]";
cstart = "\x82"; cstart = "\x82";
fmt2 = "%s<%s%s>%s\x80 %s%s"; fmt2 = "%s<%s%s>%s\x80 %s";
} }
else if (target == 0) // To everyone else if (target == 0) // To everyone
fmt2 = "%s<%s%s%s>\x80 %s%s"; fmt2 = "%s<%s%s%s>\x80 %s";
else // To your team else // To your team
{ {
if (players[playernum].ctfteam == 1) // red if (players[playernum].ctfteam == 1) // red
...@@ -928,10 +986,20 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) ...@@ -928,10 +986,20 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
else else
prefix = "\x83"; // makes sure this doesn't implode if you sayteam on non-team gamemodes prefix = "\x83"; // makes sure this doesn't implode if you sayteam on non-team gamemodes
fmt2 = "%s<%s%s>\x80%s %s%s"; fmt2 = "%s<%s%s>\x80%s %s";
} }
HU_AddChatText(va(fmt2, prefix, cstart, dispname, cend, textcolor, msg), cv_chatnotifications.value); // add to chat // What a mess
{
const char *formatted = va(fmt2, prefix, cstart, dispname, cend, textcolor);
size_t fullstrlen = strlen(formatted) + HU_StringLength((UINT8 *)msg) + 1;
UINT8 *fullstr = Z_Calloc(fullstrlen, PU_STATIC, NULL);
memcpy(fullstr, formatted, strlen(formatted));
memcpy(fullstr + strlen(formatted), (UINT8 *)msg, HU_StringLength((UINT8 *)msg));
fullstr[fullstrlen-1] = '\0';
HU_AddChatText((char *)fullstr, cv_chatnotifications.value); // add to chat
Z_Free(fullstr);
}
if (tempchar) if (tempchar)
Z_Free(tempchar); Z_Free(tempchar);
...@@ -948,17 +1016,20 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum) ...@@ -948,17 +1016,20 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
// Handles key input and string input // Handles key input and string input
// //
static inline boolean HU_keyInChatString(char *s, char ch) static inline boolean HU_keyInChatString(char *s, UINT8 ch)
{ {
size_t l; size_t l;
if ((ch >= HU_FONTSTART && ch <= HU_FONTEND && hu_font[ch-HU_FONTSTART]) if (chat_delay)
return false;
if ((ch >= HU_FONTSTART && hu_font[ch-HU_FONTSTART])
|| ch == ' ') // Allow spaces, of course || ch == ' ') // Allow spaces, of course
{ {
l = strlen(s); l = HU_StringLength((UINT8 *)s);
if (l < HU_MAXMSGLEN - 1) if (l < HU_MAXMSGLEN - 1)
{ {
if (c_input >= strlen(s)) // don't do anything complicated if (c_input >= HU_StringLength((UINT8*)s)) // don't do anything complicated
{ {
s[l++] = ch; s[l++] = ch;
s[l]=0; s[l]=0;
...@@ -993,9 +1064,9 @@ static inline boolean HU_keyInChatString(char *s, char ch) ...@@ -993,9 +1064,9 @@ static inline boolean HU_keyInChatString(char *s, char ch)
if (!s[i-1]) if (!s[i-1])
return false; return false;
if (i >= strlen(s)-1) if (i >= HU_StringLength((UINT8 *)s)-1)
{ {
s[strlen(s)-1] = 0; s[HU_StringLength((UINT8 *)s)-1] = 0;
c_input--; c_input--;
return false; return false;
} }
...@@ -1018,6 +1089,9 @@ static inline boolean HU_keyInChatString(char *s, char ch) ...@@ -1018,6 +1089,9 @@ static inline boolean HU_keyInChatString(char *s, char ch)
// //
void HU_Ticker(void) void HU_Ticker(void)
{ {
if (chat_delay)
chat_delay--;
if (dedicated) if (dedicated)
return; return;
...@@ -1044,7 +1118,7 @@ static boolean HU_clearChatSpaces(void) ...@@ -1044,7 +1118,7 @@ static boolean HU_clearChatSpaces(void)
char c; // current character we're iterating. char c; // current character we're iterating.
boolean nothingbutspaces = true; boolean nothingbutspaces = true;
for (; i < strlen(w_chat); i++) // iterate through message and eradicate all spaces that don't belong. for (; i < HU_StringLength((UINT8 *)w_chat); i++) // iterate through message and eradicate all spaces that don't belong.
{ {
c = w_chat[i]; c = w_chat[i];
if (!c) if (!c)
...@@ -1076,7 +1150,7 @@ static void HU_queueChatChar(char c) ...@@ -1076,7 +1150,7 @@ static void HU_queueChatChar(char c)
do { do {
c = w_chat[-2+ci++]; c = w_chat[-2+ci++];
if (!c || (c >= ' ' && !(c & 0x80))) // copy printable characters and terminating '\0' only. if (!c || (((UINT8)c >= 32) && !(HU_IsColorCode(c)))) // copy printable characters and terminating '\0' only.
buf[ci-1]=c; buf[ci-1]=c;
} while (c); } while (c);
...@@ -1092,7 +1166,7 @@ static void HU_queueChatChar(char c) ...@@ -1092,7 +1166,7 @@ static void HU_queueChatChar(char c)
return; return;
} }
if (strlen(msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm if (HU_StringLength((UINT8 *)msg) > 4 && strnicmp(msg, "/pm", 3) == 0) // used /pm
{ {
INT32 spc = 1; // used if nodenum[1] is a space. INT32 spc = 1; // used if nodenum[1] is a space.
char *nodenum = (char*) malloc(3); char *nodenum = (char*) malloc(3);
...@@ -1149,7 +1223,7 @@ static void HU_queueChatChar(char c) ...@@ -1149,7 +1223,7 @@ static void HU_queueChatChar(char c)
// we need to get rid of the /pm<node> // we need to get rid of the /pm<node>
newmsg = msg+5+spc; newmsg = msg+5+spc;
strlcpy(msg, newmsg, 255); HU_StringCopyLen((UINT8 *)msg, (const UINT8 *)newmsg, CHATLENGTH);
} }
if (ci > 3) // don't send target+flags+empty message. if (ci > 3) // don't send target+flags+empty message.
{ {
...@@ -1159,7 +1233,7 @@ static void HU_queueChatChar(char c) ...@@ -1159,7 +1233,7 @@ static void HU_queueChatChar(char c)
buf[0] = target; buf[0] = target;
buf[1] = 0; // flags buf[1] = 0; // flags
SendNetXCmd(XD_SAY, buf, 2 + strlen(&buf[2]) + 1); SendNetXCmd(XD_SAY, buf, 2 + HU_StringLength((UINT8*)&buf[2]) + 1);
} }
return; return;
} }
...@@ -1182,6 +1256,11 @@ static INT16 typelines = 1; // number of drawfill lines we need when drawing the ...@@ -1182,6 +1256,11 @@ static INT16 typelines = 1; // number of drawfill lines we need when drawing the
// It's up here since it has to be reset when we open the chat. // It's up here since it has to be reset when we open the chat.
#endif #endif
boolean HU_ChatActive(void)
{
return chat_on;
}
// //
// Returns true if key eaten // Returns true if key eaten
// //
...@@ -1191,7 +1270,7 @@ boolean HU_Responder(event_t *ev) ...@@ -1191,7 +1270,7 @@ boolean HU_Responder(event_t *ev)
INT32 c=0; INT32 c=0;
#endif #endif
if (ev->type != ev_keydown) if (!(ev->type == ev_keydown || ev->type == ev_textinput))
return false; return false;
// only KeyDown events now... // only KeyDown events now...
...@@ -1219,7 +1298,7 @@ boolean HU_Responder(event_t *ev) ...@@ -1219,7 +1298,7 @@ boolean HU_Responder(event_t *ev)
#ifndef NONET #ifndef NONET
c = (INT32)ev->data1; c = (INT32)ev->data1;
if (!chat_on) if (!chat_on && ev->type == ev_keydown)
{ {
// enter chat mode // enter chat mode
if ((ev->data1 == gamecontrol[gc_talkkey][0] || ev->data1 == gamecontrol[gc_talkkey][1]) if ((ev->data1 == gamecontrol[gc_talkkey][0] || ev->data1 == gamecontrol[gc_talkkey][1])
...@@ -1230,6 +1309,7 @@ boolean HU_Responder(event_t *ev) ...@@ -1230,6 +1309,7 @@ boolean HU_Responder(event_t *ev)
teamtalk = false; teamtalk = false;
chat_scrollmedown = true; chat_scrollmedown = true;
typelines = 1; typelines = 1;
chat_delay = 1;
return true; return true;
} }
if ((ev->data1 == gamecontrol[gc_teamkey][0] || ev->data1 == gamecontrol[gc_teamkey][1]) if ((ev->data1 == gamecontrol[gc_teamkey][0] || ev->data1 == gamecontrol[gc_teamkey][1])
...@@ -1240,12 +1320,12 @@ boolean HU_Responder(event_t *ev) ...@@ -1240,12 +1320,12 @@ boolean HU_Responder(event_t *ev)
teamtalk = G_GametypeHasTeams(); // Don't teamtalk if we don't have teams. teamtalk = G_GametypeHasTeams(); // Don't teamtalk if we don't have teams.
chat_scrollmedown = true; chat_scrollmedown = true;
typelines = 1; typelines = 1;
chat_delay = 1;
return true; return true;
} }
} }
else // if chat_on else if (chat_on) // if chat_on
{ {
// Ignore modifier keys // Ignore modifier keys
// Note that we do this here so users can still set // Note that we do this here so users can still set
// their chat keys to one of these, if they so desire. // their chat keys to one of these, if they so desire.
...@@ -1256,37 +1336,39 @@ boolean HU_Responder(event_t *ev) ...@@ -1256,37 +1336,39 @@ boolean HU_Responder(event_t *ev)
c = (INT32)ev->data1; c = (INT32)ev->data1;
// I know this looks very messy but this works. If it ain't broke, don't fix it! if (!cv_textinput.value)
// shift LETTERS to uppercase if we have capslock or are holding shift
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
{
if (shiftdown ^ capslock)
c = shiftxform[c];
}
else // if we're holding shift we should still shift non letter symbols
{ {
if (shiftdown) // I know this looks very messy but this works. If it ain't broke, don't fix it!
c = shiftxform[c]; // shift LETTERS to uppercase if we have capslock or are holding shift
if ((c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z'))
{
if (shiftdown ^ capslock)
c = shiftxform[c];
}
else // if we're holding shift we should still shift non letter symbols
{
if (shiftdown)
c = shiftxform[c];
}
} }
// pasting. pasting is cool. chat is a bit limited, though :( // pasting. pasting is cool. chat is a bit limited, though :(
if (((c == 'v' || c == 'V') && ctrldown) && !CHAT_MUTE) if (((c == 'v' || c == 'V') && ctrldown && ev->type == ev_keydown) && !CHAT_MUTE)
{ {
const char *paste = I_ClipboardPaste(); const char *paste = I_ClipboardPaste();
size_t chatlen; size_t chatlen;
size_t pastelen; size_t pastelen;
// create a dummy string real quickly // create a dummy string real quickly
if (paste == NULL) if (paste == NULL)
return true; return true;
chatlen = strlen(w_chat); chatlen = HU_StringLength((UINT8 *)w_chat);
pastelen = strlen(paste); pastelen = strlen(paste);
if (chatlen+pastelen > HU_MAXMSGLEN) if (chatlen+pastelen > HU_MAXMSGLEN)
return true; // we can't paste this!! return true; // we can't paste this!!
if (c_input >= strlen(w_chat)) // add it at the end of the string. if (c_input >= HU_StringLength((UINT8 *)w_chat)) // add it at the end of the string.
{ {
memcpy(&w_chat[chatlen], paste, pastelen); // copy all of that. memcpy(&w_chat[chatlen], paste, pastelen); // copy all of that.
c_input += pastelen; c_input += pastelen;
...@@ -1314,41 +1396,44 @@ boolean HU_Responder(event_t *ev) ...@@ -1314,41 +1396,44 @@ boolean HU_Responder(event_t *ev)
} }
} }
if (!CHAT_MUTE && HU_keyInChatString(w_chat,c)) if (!(c == KEY_CAPSLOCK && ev->type == ev_keydown))
{ if (!CHAT_MUTE && HU_keyInChatString(w_chat, c))
HU_queueChatChar(c); HU_queueChatChar(c);
}
if (c == KEY_ENTER) if (ev->type == ev_keydown)
{
chat_on = false;
c_input = 0; // reset input cursor
chat_scrollmedown = true; // you hit enter, so you might wanna autoscroll to see what you just sent. :)
}
else if (c == KEY_ESCAPE
|| ((c == gamecontrol[gc_talkkey][0] || c == gamecontrol[gc_talkkey][1]
|| c == gamecontrol[gc_teamkey][0] || c == gamecontrol[gc_teamkey][1])
&& c >= KEY_MOUSE1)) // If it's not a keyboard key, then the chat button is used as a toggle.
{
chat_on = false;
c_input = 0; // reset input cursor
}
else if ((c == KEY_UPARROW || c == KEY_MOUSEWHEELUP) && chat_scroll > 0 && !OLDCHAT) // CHAT SCROLLING YAYS!
{
chat_scroll--;
justscrolledup = true;
chat_scrolltime = 4;
}
else if ((c == KEY_DOWNARROW || c == KEY_MOUSEWHEELDOWN) && chat_scroll < chat_maxscroll && chat_maxscroll > 0 && !OLDCHAT)
{ {
chat_scroll++; if (c == KEY_ENTER)
justscrolleddown = true; {
chat_scrolltime = 4; chat_on = false;
c_input = 0; // reset input cursor
chat_scrollmedown = true; // you hit enter, so you might wanna autoscroll to see what you just sent. :)
}
else if (c == KEY_ESCAPE
|| ((c == gamecontrol[gc_talkkey][0] || c == gamecontrol[gc_talkkey][1]
|| c == gamecontrol[gc_teamkey][0] || c == gamecontrol[gc_teamkey][1])
&& c >= KEY_MOUSE1)) // If it's not a keyboard key, then the chat button is used as a toggle.
{
chat_on = false;
c_input = 0; // reset input cursor
}
else if ((c == KEY_UPARROW || c == KEY_MOUSEWHEELUP) && chat_scroll > 0 && !OLDCHAT) // CHAT SCROLLING YAYS!
{
chat_scroll--;
justscrolledup = true;
chat_scrolltime = 4;
}
else if ((c == KEY_DOWNARROW || c == KEY_MOUSEWHEELDOWN) && chat_scroll < chat_maxscroll && chat_maxscroll > 0 && !OLDCHAT)
{
chat_scroll++;
justscrolleddown = true;
chat_scrolltime = 4;
}
else if (c == KEY_LEFTARROW && c_input != 0 && !OLDCHAT) // i said go back
c_input--;
else if (c == KEY_RIGHTARROW && c_input < HU_StringLength((UINT8 *)w_chat) && !OLDCHAT) // don't need to check for admin or w/e here since the chat won't ever contain anything if it's muted.
c_input++;
return true;
} }
else if (c == KEY_LEFTARROW && c_input != 0 && !OLDCHAT) // i said go back
c_input--;
else if (c == KEY_RIGHTARROW && c_input < strlen(w_chat) && !OLDCHAT) // don't need to check for admin or w/e here since the chat won't ever contain anything if it's muted.
c_input++;
return true;
} }
#endif #endif
...@@ -1371,16 +1456,16 @@ static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string) ...@@ -1371,16 +1456,16 @@ static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
INT32 c; INT32 c;
size_t chw, i, lastusablespace = 0; size_t chw, i, lastusablespace = 0;
size_t slen; size_t slen;
char *newstring = Z_StrDup(string); UINT8 *newstring = HU_StringCopyAlloc((const UINT8 *)string); //(UINT8 *)Z_StrDup(string);
INT32 spacewidth = (vid.width < 640) ? 8 : 4, charwidth = (vid.width < 640) ? 8 : 4; INT32 spacewidth = (vid.width < 640) ? 8 : 4, charwidth = (vid.width < 640) ? 8 : 4;
slen = strlen(string); slen = HU_StringLength((const UINT8 *)string);
x = 0; x = 0;
for (i = 0; i < slen; ++i) for (i = 0; i < slen; ++i)
{ {
c = newstring[i]; c = newstring[i];
if ((UINT8)c >= 0x80 && (UINT8)c <= 0x89) //color parsing! -Inuyasha 2.16.09 if (HU_IsColorCode((UINT8)c))
continue; continue;
if (c == '\n') if (c == '\n')
...@@ -1413,7 +1498,7 @@ static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string) ...@@ -1413,7 +1498,7 @@ static char *CHAT_WordWrap(INT32 x, INT32 w, INT32 option, const char *string)
x = 0; x = 0;
} }
} }
return newstring; return (char *)newstring;
} }
...@@ -1446,13 +1531,13 @@ static void HU_drawMiniChat(void) ...@@ -1446,13 +1531,13 @@ static void HU_drawMiniChat(void)
for (; i>0; i--) for (; i>0; i--)
{ {
const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]); const UINT8 *msg = (UINT8 *)CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i-1]);
size_t j = 0; size_t j = 0;
INT32 linescount = 0; INT32 linescount = 0;
while(msg[j]) // iterate through msg while(msg[j]) // iterate through msg
{ {
if (msg[j] < HU_FONTSTART) // don't draw if ((UINT8)msg[j] < HU_FONTSTART) // don't draw
{ {
if (msg[j] == '\n') // get back down. if (msg[j] == '\n') // get back down.
{ {
...@@ -1465,14 +1550,13 @@ static void HU_drawMiniChat(void) ...@@ -1465,14 +1550,13 @@ static void HU_drawMiniChat(void)
prev_linereturn = true; prev_linereturn = true;
continue; continue;
} }
else if (msg[j] & 0x80) // stolen from video.c, nice.
{
++j;
continue;
}
++j; ++j;
} }
else if (HU_IsColorCode(msg[j])) // stolen from video.c, nice.
{
++j;
continue;
}
else else
{ {
j++; j++;
...@@ -1510,12 +1594,12 @@ static void HU_drawMiniChat(void) ...@@ -1510,12 +1594,12 @@ static void HU_drawMiniChat(void)
INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below... INT32 timer = ((cv_chattime.value*TICRATE)-chat_timers[i]) - cv_chattime.value*TICRATE+9; // see below...
INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one. INT32 transflag = (timer >= 0 && timer <= 9) ? (timer*V_10TRANS) : 0; // you can make bad jokes out of this one.
size_t j = 0; size_t j = 0;
const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it. const UINT8 *msg = (UINT8 *)CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_mini[i]); // get the current message, and word wrap it.
UINT8 *colormap = NULL; UINT8 *colormap = NULL;
while(msg[j]) // iterate through msg while(msg[j]) // iterate through msg
{ {
if (msg[j] < HU_FONTSTART) // don't draw if ((UINT8)msg[j] < HU_FONTSTART) // don't draw
{ {
if (msg[j] == '\n') // get back down. if (msg[j] == '\n') // get back down.
{ {
...@@ -1528,22 +1612,21 @@ static void HU_drawMiniChat(void) ...@@ -1528,22 +1612,21 @@ static void HU_drawMiniChat(void)
prev_linereturn = true; prev_linereturn = true;
continue; continue;
} }
else if (msg[j] & 0x80) // stolen from video.c, nice.
{
clrflag = ((msg[j] & 0x7f) << V_CHARCOLORSHIFT) & V_CHARCOLORMASK;
colormap = V_GetStringColormap(clrflag);
++j;
continue;
}
++j; ++j;
} }
else if (HU_IsColorCode(msg[j])) // stolen from video.c, nice.
{
clrflag = ((msg[j] & 0x7f) << V_CHARCOLORSHIFT) & V_CHARCOLORMASK;
colormap = V_GetStringColormap(clrflag);
++j;
continue;
}
else else
{ {
if (cv_chatbacktint.value) // on request of wolfy if (cv_chatbacktint.value) // on request of wolfy
V_DrawFillConsoleMap(x + dx + 2, y+dy, charwidth, charheight, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT); V_DrawFillConsoleMap(x + dx + 2, y+dy, charwidth, charheight, 239|V_SNAPTOBOTTOM|V_SNAPTOLEFT);
V_DrawChatCharacter(x + dx + 2, y+dy, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, !cv_allcaps.value, colormap); V_DrawChatCharacter(x + dx + 2, y+dy, (UINT8)msg[j++], V_SNAPTOBOTTOM|V_SNAPTOLEFT|transflag, !cv_allcaps.value, colormap);
} }
dx += charwidth; dx += charwidth;
...@@ -1607,11 +1690,11 @@ static void HU_drawChatLog(INT32 offset) ...@@ -1607,11 +1690,11 @@ static void HU_drawChatLog(INT32 offset)
{ {
INT32 clrflag = 0; INT32 clrflag = 0;
INT32 j = 0; INT32 j = 0;
const char *msg = CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it. const UINT8 *msg = (UINT8 *)CHAT_WordWrap(x+2, boxw-(charwidth*2), V_SNAPTOBOTTOM|V_SNAPTOLEFT|V_ALLOWLOWERCASE, chat_log[i]); // get the current message, and word wrap it.
UINT8 *colormap = NULL; UINT8 *colormap = NULL;
while(msg[j]) // iterate through msg while(msg[j]) // iterate through msg
{ {
if (msg[j] < HU_FONTSTART) // don't draw if ((UINT8)msg[j] < HU_FONTSTART) // don't draw
{ {
if (msg[j] == '\n') // get back down. if (msg[j] == '\n') // get back down.
{ {
...@@ -1620,26 +1703,25 @@ static void HU_drawChatLog(INT32 offset) ...@@ -1620,26 +1703,25 @@ static void HU_drawChatLog(INT32 offset)
dx = 0; dx = 0;
continue; continue;
} }
else if (msg[j] & 0x80) // stolen from video.c, nice.
{
clrflag = ((msg[j] & 0x7f) << V_CHARCOLORSHIFT) & V_CHARCOLORMASK;
colormap = V_GetStringColormap(clrflag);
++j;
continue;
}
++j; ++j;
} }
else if (HU_IsColorCode(msg[j])) // stolen from video.c, nice.
{
clrflag = ((msg[j] & 0x7f) << V_CHARCOLORSHIFT) & V_CHARCOLORMASK;
colormap = V_GetStringColormap(clrflag);
++j;
continue;
}
else else
{ {
if ((y+dy+2 >= chat_topy) && (y+dy < (chat_bottomy))) if ((y+dy+2 >= chat_topy) && (y+dy < (chat_bottomy)))
V_DrawChatCharacter(x + dx + 2, y+dy+2, msg[j++] |V_SNAPTOBOTTOM|V_SNAPTOLEFT, !cv_allcaps.value, colormap); V_DrawChatCharacter(x + dx + 2, y+dy+2, (UINT8)msg[j++], V_SNAPTOBOTTOM|V_SNAPTOLEFT, !cv_allcaps.value, colormap);
else else
j++; // don't forget to increment this or we'll get stuck in the limbo. j++; // don't forget to increment this or we'll get stuck in the limbo.
} }
dx += charwidth; dx += charwidth;
if (dx >= boxw-charwidth-2 && i<chat_nummsg_log && msg[j] >= HU_FONTSTART) // end of message shouldn't count, nor should invisible characters!!!! if (dx >= boxw-charwidth-2 && i<chat_nummsg_log && (UINT8)msg[j] >= HU_FONTSTART) // end of message shouldn't count, nor should invisible characters!!!!
{ {
dx = 0; dx = 0;
dy += charheight; dy += charheight;
...@@ -1689,7 +1771,7 @@ static void HU_DrawChat(void) ...@@ -1689,7 +1771,7 @@ static void HU_DrawChat(void)
INT32 charwidth = 4, charheight = 6; INT32 charwidth = 4, charheight = 6;
INT32 boxw = cv_chatwidth.value; INT32 boxw = cv_chatwidth.value;
INT32 t = 0, c = 0, y = chaty - (typelines*charheight); INT32 t = 0, c = 0, y = chaty - (typelines*charheight);
UINT32 i = 0, saylen = strlen(w_chat); // You learn new things everyday! UINT32 i = 0, saylen = HU_StringLength((UINT8 *)w_chat); // You learn new things everyday!
INT32 cflag = 0; INT32 cflag = 0;
const char *ntalk = "Say: ", *ttalk = "Team: "; const char *ntalk = "Say: ", *ttalk = "Team: ";
const char *talk = ntalk; const char *talk = ntalk;
...@@ -1727,13 +1809,13 @@ static void HU_DrawChat(void) ...@@ -1727,13 +1809,13 @@ static void HU_DrawChat(void)
V_DrawFillConsoleMap(chatx, y-1, boxw, (typelines*charheight), 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT); V_DrawFillConsoleMap(chatx, y-1, boxw, (typelines*charheight), 239 | V_SNAPTOBOTTOM | V_SNAPTOLEFT);
while (talk[i]) while ((UINT8)talk[i])
{ {
if (talk[i] < HU_FONTSTART) if ((UINT8)talk[i] < HU_FONTSTART)
++i; ++i;
else else
{ {
V_DrawChatCharacter(chatx + c + 2, y, talk[i] |V_SNAPTOBOTTOM|V_SNAPTOLEFT|cflag, !cv_allcaps.value, V_GetStringColormap(talk[i]|cflag)); V_DrawChatCharacter(chatx + c + 2, y, (UINT8)talk[i], V_SNAPTOBOTTOM|V_SNAPTOLEFT|cflag, !cv_allcaps.value, V_GetStringColormap(talk[i]|cflag));
i++; i++;
} }
...@@ -1750,10 +1832,10 @@ static void HU_DrawChat(void) ...@@ -1750,10 +1832,10 @@ static void HU_DrawChat(void)
i = 0; i = 0;
typelines = 1; typelines = 1;
if ((strlen(w_chat) == 0 || c_input == 0) && hu_tick < 4) if ((HU_StringLength((UINT8 *)w_chat) == 0 || c_input == 0) && hu_tick < 4)
V_DrawChatCharacter(chatx + 2 + c, y+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL); V_DrawChatCharacter(chatx + 2 + c, y+1, '_', V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL);
while (w_chat[i]) while ((UINT8)w_chat[i])
{ {
boolean skippedline = false; boolean skippedline = false;
if (c_input == (i+1)) if (c_input == (i+1))
...@@ -1761,7 +1843,7 @@ static void HU_DrawChat(void) ...@@ -1761,7 +1843,7 @@ static void HU_DrawChat(void)
INT32 cursorx = (c+charwidth < boxw-charwidth) ? (chatx + 2 + c+charwidth) : (chatx+1); // we may have to go down. INT32 cursorx = (c+charwidth < boxw-charwidth) ? (chatx + 2 + c+charwidth) : (chatx+1); // we may have to go down.
INT32 cursory = (cursorx != chatx+1) ? (y) : (y+charheight); INT32 cursory = (cursorx != chatx+1) ? (y) : (y+charheight);
if (hu_tick < 4) if (hu_tick < 4)
V_DrawChatCharacter(cursorx, cursory+1, '_' |V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL); V_DrawChatCharacter(cursorx, cursory+1, '_', V_SNAPTOBOTTOM|V_SNAPTOLEFT|t, !cv_allcaps.value, NULL);
if (cursorx == chatx+1 && saylen == i) // a weirdo hack if (cursorx == chatx+1 && saylen == i) // a weirdo hack
{ {
...@@ -1771,10 +1853,10 @@ static void HU_DrawChat(void) ...@@ -1771,10 +1853,10 @@ static void HU_DrawChat(void)
} }
//Hurdler: isn't it better like that? //Hurdler: isn't it better like that?
if (w_chat[i] < HU_FONTSTART) if ((UINT8)w_chat[i] < HU_FONTSTART)
++i; ++i;
else else
V_DrawChatCharacter(chatx + c + 2, y, w_chat[i++] | V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, !cv_allcaps.value, NULL); V_DrawChatCharacter(chatx + c + 2, y, (UINT8)w_chat[i++], V_SNAPTOBOTTOM|V_SNAPTOLEFT | t, !cv_allcaps.value, NULL);
c += charwidth; c += charwidth;
if (c > boxw-(charwidth*2) && !skippedline) if (c > boxw-(charwidth*2) && !skippedline)
...@@ -1888,9 +1970,9 @@ static void HU_DrawChat_Old(void) ...@@ -1888,9 +1970,9 @@ static void HU_DrawChat_Old(void)
#endif #endif
} }
while (talk[i]) while ((UINT8)talk[i])
{ {
if (talk[i] < HU_FONTSTART) if ((UINT8)talk[i] < HU_FONTSTART)
{ {
++i; ++i;
//charwidth = 4 * con_scalefactor; //charwidth = 4 * con_scalefactor;
...@@ -1898,27 +1980,27 @@ static void HU_DrawChat_Old(void) ...@@ -1898,27 +1980,27 @@ static void HU_DrawChat_Old(void)
else else
{ {
//charwidth = SHORT(hu_font[talk[i]-HU_FONTSTART]->width) * con_scalefactor; //charwidth = SHORT(hu_font[talk[i]-HU_FONTSTART]->width) * con_scalefactor;
V_DrawCharacter(HU_INPUTX + c, y, talk[i++] | cv_constextsize.value | V_NOSCALESTART, true); V_DrawCharacter(HU_INPUTX + c, y, (UINT8)talk[i++], cv_constextsize.value | V_NOSCALESTART, true);
} }
c += charwidth; c += charwidth;
} }
if ((strlen(w_chat) == 0 || c_input == 0) && hu_tick < 4) if ((HU_StringLength((UINT8 *)w_chat) == 0 || c_input == 0) && hu_tick < 4)
V_DrawCharacter(HU_INPUTX+c, y+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, !cv_allcaps.value); V_DrawCharacter(HU_INPUTX+c, y+2*con_scalefactor, '_', cv_constextsize.value | V_NOSCALESTART|t, !cv_allcaps.value);
i = 0; i = 0;
while (w_chat[i]) while ((UINT8)w_chat[i])
{ {
if (c_input == (i+1) && hu_tick < 4) if (c_input == (i+1) && hu_tick < 4)
{ {
INT32 cursorx = (HU_INPUTX+c+charwidth < vid.width) ? (HU_INPUTX + c + charwidth) : (HU_INPUTX); // we may have to go down. INT32 cursorx = (HU_INPUTX+c+charwidth < vid.width) ? (HU_INPUTX + c + charwidth) : (HU_INPUTX); // we may have to go down.
INT32 cursory = (cursorx != HU_INPUTX) ? (y) : (y+charheight); INT32 cursory = (cursorx != HU_INPUTX) ? (y) : (y+charheight);
V_DrawCharacter(cursorx, cursory+2*con_scalefactor, '_' |cv_constextsize.value | V_NOSCALESTART|t, !cv_allcaps.value); V_DrawCharacter(cursorx, cursory+2*con_scalefactor, '_', cv_constextsize.value | V_NOSCALESTART|t, !cv_allcaps.value);
} }
//Hurdler: isn't it better like that? //Hurdler: isn't it better like that?
if (w_chat[i] < HU_FONTSTART) if ((UINT8)w_chat[i] < HU_FONTSTART)
{ {
++i; ++i;
//charwidth = 4 * con_scalefactor; //charwidth = 4 * con_scalefactor;
...@@ -1926,7 +2008,7 @@ static void HU_DrawChat_Old(void) ...@@ -1926,7 +2008,7 @@ static void HU_DrawChat_Old(void)
else else
{ {
//charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor; //charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor;
V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | cv_constextsize.value | V_NOSCALESTART | t, true); V_DrawCharacter(HU_INPUTX + c, y, (UINT8)w_chat[i++], cv_constextsize.value | V_NOSCALESTART | t, true);
} }
c += charwidth; c += charwidth;
...@@ -1938,7 +2020,7 @@ static void HU_DrawChat_Old(void) ...@@ -1938,7 +2020,7 @@ static void HU_DrawChat_Old(void)
} }
if (hu_tick < 4) if (hu_tick < 4)
V_DrawCharacter(HU_INPUTX + c, y, '_' | cv_constextsize.value |V_NOSCALESTART|t, true); V_DrawCharacter(HU_INPUTX + c, y, '_', cv_constextsize.value |V_NOSCALESTART|t, true);
} }
#endif #endif
...@@ -2838,7 +2920,7 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor ...@@ -2838,7 +2920,7 @@ static void HU_Draw32TabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scor
greycheck = greycheckdef; greycheck = greycheckdef;
supercheck = supercheckdef; supercheck = supercheckdef;
strlcpy(name, tab[i].name, 7); HU_StringCopyLen((UINT8 *)name, (const UINT8 *)tab[i].name, 7);
if (!splitscreen) // don't draw it on splitscreen, if (!splitscreen) // don't draw it on splitscreen,
{ {
if (!(tab[i].num == serverplayer)) if (!(tab[i].num == serverplayer))
......
...@@ -22,7 +22,12 @@ ...@@ -22,7 +22,12 @@
// heads up font // heads up font
//------------------------------------ //------------------------------------
#define HU_FONTSTART '\x16' // the first font character #define HU_FONTSTART '\x16' // the first font character
#define HU_FONTEND '~' #define HU_FONTEND 0xFF //
#define HU_FONTEXT 0xA1 //
#define HU_COLORSTART 0x80
#define HU_COLOREND 0x8F
#define HU_IsColorCode(char) ((UINT8)char >= HU_COLORSTART && (UINT8)char <= HU_COLOREND)
#define HU_FONTSIZE (HU_FONTEND - HU_FONTSTART + 1) #define HU_FONTSIZE (HU_FONTEND - HU_FONTSTART + 1)
...@@ -75,8 +80,15 @@ typedef struct ...@@ -75,8 +80,15 @@ typedef struct
// some functions // some functions
void HU_AddChatText(const char *text, boolean playsound); void HU_AddChatText(const char *text, boolean playsound);
// Lactokaiju
size_t HU_StringLength(const UINT8 *str);
void HU_StringCopy(UINT8 *dest, const UINT8 *src);
void HU_StringCopyLen(UINT8 *dest, const UINT8 *src, size_t len);
UINT8 *HU_StringCopyAlloc(const UINT8 *src);
// set true when entering a chat message // set true when entering a chat message
extern boolean chat_on; extern boolean chat_on;
boolean HU_ChatActive(void);
extern patch_t *hu_font[HU_FONTSIZE], *tny_font[HU_FONTSIZE]; extern patch_t *hu_font[HU_FONTSIZE], *tny_font[HU_FONTSIZE];
extern patch_t *tallnum[10]; extern patch_t *tallnum[10];
......
...@@ -13,9 +13,10 @@ ...@@ -13,9 +13,10 @@
#ifndef __KEYS_H__ #ifndef __KEYS_H__
#define __KEYS_H__ #define __KEYS_H__
// These are the key codes as posted by the keyboard handler, // Lactozilla: Well, this is embarrassing
// ascii codes are 0->127, // Those key codes conflict with even Latin-1 Supplement
// scancodes are 0x80 + 0->127 // At least events are 32-bits, so I can use 0x100
#define KEY_XTMASK (0x100)
#define KEY_NULL 0 // null key, triggers nothing #define KEY_NULL 0 // null key, triggers nothing
#define KEY_BACKSPACE 8 #define KEY_BACKSPACE 8
...@@ -26,72 +27,67 @@ ...@@ -26,72 +27,67 @@
#define KEY_MINUS 45 #define KEY_MINUS 45
#define KEY_EQUALS 61 #define KEY_EQUALS 61
#define KEY_NUMLOCK (0x80+69) // Num lock and scroll lock
#define KEY_SCROLLLOCK (0x80+70) #define KEY_NUMLOCK (KEY_XTMASK+1)
#define KEY_SCROLLLOCK (KEY_XTMASK+2)
// // Keypad
// scancodes 71-83 (non-extended) #define KEY_KEYPAD7 (KEY_XTMASK+3)
// #define KEY_KEYPAD8 (KEY_XTMASK+4)
#define KEY_KEYPAD7 (0x80+71) #define KEY_KEYPAD9 (KEY_XTMASK+5)
#define KEY_KEYPAD8 (0x80+72) #define KEY_MINUSPAD (KEY_XTMASK+6)
#define KEY_KEYPAD9 (0x80+73) #define KEY_KEYPAD4 (KEY_XTMASK+7)
#define KEY_MINUSPAD (0x80+74) #define KEY_KEYPAD5 (KEY_XTMASK+8)
#define KEY_KEYPAD4 (0x80+75) #define KEY_KEYPAD6 (KEY_XTMASK+9)
#define KEY_KEYPAD5 (0x80+76) #define KEY_PLUSPAD (KEY_XTMASK+10)
#define KEY_KEYPAD6 (0x80+77) #define KEY_KEYPAD1 (KEY_XTMASK+11)
#define KEY_PLUSPAD (0x80+78) #define KEY_KEYPAD2 (KEY_XTMASK+12)
#define KEY_KEYPAD1 (0x80+79) #define KEY_KEYPAD3 (KEY_XTMASK+13)
#define KEY_KEYPAD2 (0x80+80) #define KEY_KEYPAD0 (KEY_XTMASK+14)
#define KEY_KEYPAD3 (0x80+81) #define KEY_KPADDEL (KEY_XTMASK+15)
#define KEY_KEYPAD0 (0x80+82)
#define KEY_KPADDEL (0x80+83)
// windows95 keys
#define KEY_LEFTWIN (0x80+91)
#define KEY_RIGHTWIN (0x80+92)
#define KEY_MENU (0x80+93)
// scancodes 71-83 EXTENDED are remapped to these by the keyboard handler (just add 30)
#define KEY_KPADSLASH (0x80+100) // extended scancode 53 '/' remapped
#define KEY_HOME (0x80+101)
#define KEY_UPARROW (0x80+102)
#define KEY_PGUP (0x80+103)
#define KEY_LEFTARROW (0x80+105)
#define KEY_RIGHTARROW (0x80+107)
#define KEY_END (0x80+109)
#define KEY_DOWNARROW (0x80+110)
#define KEY_PGDN (0x80+111)
#define KEY_INS (0x80+112)
#define KEY_DEL (0x80+113)
#define KEY_F1 (0x80+0x3b) // Bill Gates keys
#define KEY_F2 (0x80+0x3c) #define KEY_LEFTWIN (KEY_XTMASK+16)
#define KEY_F3 (0x80+0x3d) #define KEY_RIGHTWIN (KEY_XTMASK+17)
#define KEY_F4 (0x80+0x3e) #define KEY_MENU (KEY_XTMASK+18) // Context Menu
#define KEY_F5 (0x80+0x3f)
#define KEY_F6 (0x80+0x40)
#define KEY_F7 (0x80+0x41)
#define KEY_F8 (0x80+0x42)
#define KEY_F9 (0x80+0x43)
#define KEY_F10 (0x80+0x44)
#define KEY_F11 (0x80+0x57)
#define KEY_F12 (0x80+0x58)
#define KEY_PAUSE 255 #define KEY_KPADSLASH (KEY_XTMASK+19)
#define KEY_HOME (KEY_XTMASK+20)
#define KEY_UPARROW (KEY_XTMASK+21)
#define KEY_PGUP (KEY_XTMASK+22)
#define KEY_LEFTARROW (KEY_XTMASK+23)
#define KEY_RIGHTARROW (KEY_XTMASK+24)
#define KEY_END (KEY_XTMASK+25)
#define KEY_DOWNARROW (KEY_XTMASK+26)
#define KEY_PGDN (KEY_XTMASK+27)
#define KEY_INS (KEY_XTMASK+28)
#define KEY_DEL (KEY_XTMASK+29)
// these ones must be non-extended scancodes (rctrl, rshift, lalt) // Function keys
#define KEY_LSHIFT (0x80+54) #define KEY_F1 (KEY_XTMASK+30)
#define KEY_RSHIFT (0x80+55) #define KEY_F2 (KEY_XTMASK+31)
#define KEY_LCTRL (0x80+29) #define KEY_F3 (KEY_XTMASK+32)
#define KEY_RCTRL (0x80+30) #define KEY_F4 (KEY_XTMASK+33)
#define KEY_LALT (0x80+56) #define KEY_F5 (KEY_XTMASK+34)
#define KEY_RALT (0x80+57) #define KEY_F6 (KEY_XTMASK+35)
#define KEY_F7 (KEY_XTMASK+36)
#define KEY_F8 (KEY_XTMASK+37)
#define KEY_F9 (KEY_XTMASK+38)
#define KEY_F10 (KEY_XTMASK+39)
#define KEY_F11 (KEY_XTMASK+40)
#define KEY_F12 (KEY_XTMASK+41)
#define KEY_CAPSLOCK (0x80+58) #define KEY_CAPSLOCK (KEY_XTMASK+42)
#define KEY_CONSOLE '`' #define KEY_CONSOLE '`' // This key is problematic, I'll put it back on tilde
#define KEY_PAUSE (KEY_XTMASK+44)
#define KEY_PRTSC (KEY_XTMASK+45)
#define KEY_OPENBRACKETS // Modifiers
#define KEY_CLOSEBRACKETS #define KEY_LSHIFT (KEY_XTMASK+46)
#define KEY_RSHIFT (KEY_XTMASK+47)
#define KEY_LCTRL (KEY_XTMASK+48)
#define KEY_RCTRL (KEY_XTMASK+49)
#define KEY_LALT (KEY_XTMASK+50)
#define KEY_RALT (KEY_XTMASK+51)
#endif #endif
...@@ -199,7 +199,8 @@ static UINT8 cht_CheckCheat(cheatseq_t *cht, char key) ...@@ -199,7 +199,8 @@ static UINT8 cht_CheckCheat(cheatseq_t *cht, char key)
boolean cht_Responder(event_t *ev) boolean cht_Responder(event_t *ev)
{ {
UINT8 ret = 0, ch = 0; UINT8 ret = 0;
UINT32 ch = 0;
if (ev->type != ev_keydown) if (ev->type != ev_keydown)
return false; return false;
......
...@@ -92,6 +92,10 @@ int snprintf(char *str, size_t n, const char *fmt, ...); ...@@ -92,6 +92,10 @@ int snprintf(char *str, size_t n, const char *fmt, ...);
#define SLIDER_WIDTH 78 #define SLIDER_WIDTH 78
#define SERVERS_PER_PAGE 11 #define SERVERS_PER_PAGE 11
// Lactozilla
#define TEXTINPUTEVENT 0x80000000
#define M_KeyboardTextInput(ch) (!cv_textinput.value) ? (true) : (ch & TEXTINPUTEVENT)
typedef enum typedef enum
{ {
QUITMSG = 0, QUITMSG = 0,
...@@ -2876,8 +2880,9 @@ static boolean M_ChangeStringCvar(INT32 choice) ...@@ -2876,8 +2880,9 @@ static boolean M_ChangeStringCvar(INT32 choice)
char buf[MAXSTRINGLENGTH]; char buf[MAXSTRINGLENGTH];
size_t len; size_t len;
if (shiftdown && choice >= 32 && choice <= 127) if (!cv_textinput.value)
choice = shiftxform[choice]; if (shiftdown && choice >= 32 && choice <= 127)
choice = shiftxform[choice];
switch (choice) switch (choice)
{ {
...@@ -2891,17 +2896,21 @@ static boolean M_ChangeStringCvar(INT32 choice) ...@@ -2891,17 +2896,21 @@ static boolean M_ChangeStringCvar(INT32 choice)
} }
return true; return true;
default: default:
if (choice >= 32 && choice <= 127) if (M_KeyboardTextInput(choice) || (choice == 32)) // ev_textinput
{ {
len = strlen(cv->string); choice &= ~TEXTINPUTEVENT;
if (len < MAXSTRINGLENGTH - 1) if (choice >= 32 && choice <= 0xFF)
{ {
M_Memcpy(buf, cv->string, len); len = strlen(cv->string);
buf[len++] = (char)choice; if (len < MAXSTRINGLENGTH - 1)
buf[len] = 0; {
CV_Set(cv, buf); M_Memcpy(buf, cv->string, len);
buf[len++] = (char)choice;
buf[len] = 0;
CV_Set(cv, buf);
}
return true;
} }
return true;
} }
break; break;
} }
...@@ -2958,6 +2967,14 @@ static void Command_Manual_f(void) ...@@ -2958,6 +2967,14 @@ static void Command_Manual_f(void)
itemOn = 0; itemOn = 0;
} }
boolean M_TextInput(void)
{
// Of course return false if the menus are down...
if (!menuactive)
return false;
return ((currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_KEYHANDLER);
}
// //
// M_Responder // M_Responder
// //
...@@ -2987,7 +3004,12 @@ boolean M_Responder(event_t *ev) ...@@ -2987,7 +3004,12 @@ boolean M_Responder(event_t *ev)
} }
else if (menuactive) else if (menuactive)
{ {
if (ev->type == ev_keydown) if (ev->type == ev_textinput)
{
keydown++;
ch = ev->data1;
}
else if (ev->type == ev_keydown)
{ {
keydown++; keydown++;
ch = ev->data1; ch = ev->data1;
...@@ -3023,7 +3045,7 @@ boolean M_Responder(event_t *ev) ...@@ -3023,7 +3045,7 @@ boolean M_Responder(event_t *ev)
break; break;
} }
} }
else if (ev->type == ev_joystick && ev->data1 == 0 && joywait < I_GetTime()) else if (ev->type == ev_joystick && ev->data1 == 0 && joywait < I_GetTime())
{ {
const INT32 jdeadzone = JOYAXISRANGE/4; const INT32 jdeadzone = JOYAXISRANGE/4;
if (ev->data3 != INT32_MAX) if (ev->data3 != INT32_MAX)
...@@ -3099,9 +3121,12 @@ boolean M_Responder(event_t *ev) ...@@ -3099,9 +3121,12 @@ boolean M_Responder(event_t *ev)
else if (ev->type == ev_keyup) // Preserve event for other responders else if (ev->type == ev_keyup) // Preserve event for other responders
keydown = 0; keydown = 0;
} }
else if (ev->type == ev_keydown) // Preserve event for other responders else if (ev->type == ev_keydown || ev->type == ev_textinput) // Preserve event for other responders
ch = ev->data1; ch = ev->data1;
if (ev->type == ev_textinput)
goto textinputhandler;
if (ch == -1) if (ch == -1)
return false; return false;
else if (ch == gamecontrol[gc_systemmenu][0] || ch == gamecontrol[gc_systemmenu][1]) // allow remappable ESC key else if (ch == gamecontrol[gc_systemmenu][0] || ch == gamecontrol[gc_systemmenu][1]) // allow remappable ESC key
...@@ -3180,17 +3205,25 @@ boolean M_Responder(event_t *ev) ...@@ -3180,17 +3205,25 @@ boolean M_Responder(event_t *ev)
return false; return false;
} }
textinputhandler:
routine = currentMenu->menuitems[itemOn].itemaction; routine = currentMenu->menuitems[itemOn].itemaction;
// Handle menuitems which need a specific key handling // Handle menuitems which need a specific key handling
if (routine && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_KEYHANDLER) if (routine && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_KEYHANDLER)
{ {
if (shiftdown && ch >= 32 && ch <= 127) INT32 chbits = ((ev->type == ev_textinput) ? TEXTINPUTEVENT : 0); // Of course
ch = shiftxform[ch]; if (!cv_textinput.value)
routine(ch); {
if (shiftdown && ch >= 32 && ch <= 127)
ch = shiftxform[ch];
}
routine(ch | chbits);
return true; return true;
} }
if (ev->type == ev_textinput)
goto cvartextinputhandler;
if (currentMenu->menuitems[itemOn].status == IT_MSGHANDLER) if (currentMenu->menuitems[itemOn].status == IT_MSGHANDLER)
{ {
if (currentMenu->menuitems[itemOn].alphaKey != MM_EVENTHANDLER) if (currentMenu->menuitems[itemOn].alphaKey != MM_EVENTHANDLER)
...@@ -3221,19 +3254,24 @@ boolean M_Responder(event_t *ev) ...@@ -3221,19 +3254,24 @@ boolean M_Responder(event_t *ev)
} }
// BP: one of the more big hack i have never made // BP: one of the more big hack i have never made
cvartextinputhandler:
if (routine && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_CVAR) if (routine && (currentMenu->menuitems[itemOn].status & IT_TYPE) == IT_CVAR)
{ {
if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_STRING) if ((currentMenu->menuitems[itemOn].status & IT_CVARTYPE) == IT_CV_STRING)
{ {
if (M_ChangeStringCvar(ch)) INT32 chbits = ((ev->type == ev_textinput) ? TEXTINPUTEVENT : 0); // Of course
if (M_ChangeStringCvar(ch | chbits))
return true; return true;
else else
routine = NULL; routine = NULL;
} }
else else if (ev->type != ev_textinput)
routine = M_ChangeCvar; routine = M_ChangeCvar;
} }
if (ev->type == ev_textinput)
return false;
// Keys usable within menu // Keys usable within menu
switch (ch) switch (ch)
{ {
...@@ -3781,9 +3819,9 @@ static void M_DrawSlider(INT32 x, INT32 y, const consvar_t *cv, boolean ontop) ...@@ -3781,9 +3819,9 @@ static void M_DrawSlider(INT32 x, INT32 y, const consvar_t *cv, boolean ontop)
if (ontop) if (ontop)
{ {
V_DrawCharacter(x - 6 - (skullAnimCounter/5), y, V_DrawCharacter(x - 6 - (skullAnimCounter/5), y,
'\x1C' | V_YELLOWMAP, false); '\x1C', V_YELLOWMAP, false);
V_DrawCharacter(x+i*8 + 8 + (skullAnimCounter/5), y, V_DrawCharacter(x+i*8 + 8 + (skullAnimCounter/5), y,
'\x1D' | V_YELLOWMAP, false); '\x1D', V_YELLOWMAP, false);
} }
p = W_CachePatchName("M_SLIDER", PU_CACHE); p = W_CachePatchName("M_SLIDER", PU_CACHE);
...@@ -4080,7 +4118,7 @@ static void M_DrawGenericMenu(void) ...@@ -4080,7 +4118,7 @@ static void M_DrawGenericMenu(void)
V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string); V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string);
if (skullAnimCounter < 4 && i == itemOn) if (skullAnimCounter < 4 && i == itemOn)
V_DrawCharacter(x + 8 + V_StringWidth(cv->string, 0), y + 12, V_DrawCharacter(x + 8 + V_StringWidth(cv->string, 0), y + 12,
'_' | 0x80, false); '_', 0x80, false);
y += 16; y += 16;
break; break;
default: default:
...@@ -4089,9 +4127,9 @@ static void M_DrawGenericMenu(void) ...@@ -4089,9 +4127,9 @@ static void M_DrawGenericMenu(void)
if (i == itemOn) if (i == itemOn)
{ {
V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(cv->string, 0) - (skullAnimCounter/5), y, V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(cv->string, 0) - (skullAnimCounter/5), y,
'\x1C' | V_YELLOWMAP, false); '\x1C', V_YELLOWMAP, false);
V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y, V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y,
'\x1D' | V_YELLOWMAP, false); '\x1D', V_YELLOWMAP, false);
} }
break; break;
} }
...@@ -4241,14 +4279,14 @@ static void M_DrawGenericScrollMenu(void) ...@@ -4241,14 +4279,14 @@ static void M_DrawGenericScrollMenu(void)
V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string); V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string);
if (skullAnimCounter < 4 && i == itemOn) if (skullAnimCounter < 4 && i == itemOn)
V_DrawCharacter(x + 8 + V_StringWidth(cv->string, 0), y + 12, V_DrawCharacter(x + 8 + V_StringWidth(cv->string, 0), y + 12,
'_' | 0x80, false); '_', 0x80, false);
#else // cool new string type stuff, not ready for limelight #else // cool new string type stuff, not ready for limelight
if (i == itemOn) if (i == itemOn)
{ {
V_DrawFill(x-2, y-1, MAXSTRINGLENGTH*8 + 4, 8+3, 159); V_DrawFill(x-2, y-1, MAXSTRINGLENGTH*8 + 4, 8+3, 159);
V_DrawString(x, y, V_ALLOWLOWERCASE, cv->string); V_DrawString(x, y, V_ALLOWLOWERCASE, cv->string);
if (skullAnimCounter < 4) if (skullAnimCounter < 4)
V_DrawCharacter(x + V_StringWidth(cv->string, 0), y, '_' | 0x80, false); V_DrawCharacter(x + V_StringWidth(cv->string, 0), y, '_', 0x80, false);
} }
else else
V_DrawRightAlignedString(BASEVIDWIDTH - x, y, V_DrawRightAlignedString(BASEVIDWIDTH - x, y,
...@@ -4261,9 +4299,9 @@ static void M_DrawGenericScrollMenu(void) ...@@ -4261,9 +4299,9 @@ static void M_DrawGenericScrollMenu(void)
if (i == itemOn) if (i == itemOn)
{ {
V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(cv->string, 0) - (skullAnimCounter/5), y, V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(cv->string, 0) - (skullAnimCounter/5), y,
'\x1C' | V_YELLOWMAP, false); '\x1C', V_YELLOWMAP, false);
V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y, V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y,
'\x1D' | V_YELLOWMAP, false); '\x1D', V_YELLOWMAP, false);
} }
break; break;
} }
...@@ -4501,7 +4539,7 @@ static void M_DrawCenteredMenu(void) ...@@ -4501,7 +4539,7 @@ static void M_DrawCenteredMenu(void)
V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string); V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string);
if (skullAnimCounter < 4 && i == itemOn) if (skullAnimCounter < 4 && i == itemOn)
V_DrawCharacter(x + 8 + V_StringWidth(cv->string, 0), y + 12, V_DrawCharacter(x + 8 + V_StringWidth(cv->string, 0), y + 12,
'_' | 0x80, false); '_', 0x80, false);
y += 16; y += 16;
break; break;
default: default:
...@@ -4510,9 +4548,9 @@ static void M_DrawCenteredMenu(void) ...@@ -4510,9 +4548,9 @@ static void M_DrawCenteredMenu(void)
if (i == itemOn) if (i == itemOn)
{ {
V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(cv->string, 0) - (skullAnimCounter/5), y, V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(cv->string, 0) - (skullAnimCounter/5), y,
'\x1C' | V_YELLOWMAP, false); '\x1C', V_YELLOWMAP, false);
V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y, V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y,
'\x1D' | V_YELLOWMAP, false); '\x1D', V_YELLOWMAP, false);
} }
break; break;
} }
...@@ -5263,9 +5301,9 @@ static void M_DrawLevelPlatterRow(UINT8 row, INT32 y) ...@@ -5263,9 +5301,9 @@ static void M_DrawLevelPlatterRow(UINT8 row, INT32 y)
if (!lsrow) if (!lsrow)
{ {
V_DrawCharacter(lsbasex - 10 - (skullAnimCounter/5), y+25, V_DrawCharacter(lsbasex - 10 - (skullAnimCounter/5), y+25,
'\x1C' | V_YELLOWMAP, false); '\x1C', V_YELLOWMAP, false);
V_DrawCharacter(lsbasex+282 + 2 + (skullAnimCounter/5), y+25, V_DrawCharacter(lsbasex+282 + 2 + (skullAnimCounter/5), y+25,
'\x1D' | V_YELLOWMAP, false); '\x1D', V_YELLOWMAP, false);
} }
} }
else if (lswide(row)) else if (lswide(row))
...@@ -6163,7 +6201,7 @@ static void M_DrawAddons(void) ...@@ -6163,7 +6201,7 @@ static void M_DrawAddons(void)
V_DrawString(x - 18, y + 8, V_ALLOWLOWERCASE|V_TRANSLUCENT, "Type to search..."); V_DrawString(x - 18, y + 8, V_ALLOWLOWERCASE|V_TRANSLUCENT, "Type to search...");
if (skullAnimCounter < 4) if (skullAnimCounter < 4)
V_DrawCharacter(x - 18 + V_StringWidth(menusearch+1, 0), y + 8, V_DrawCharacter(x - 18 + V_StringWidth(menusearch+1, 0), y + 8,
'_' | 0x80, false); '_', 0x80, false);
// draw search icon // draw search icon
x -= (21 + 5 + 16); x -= (21 + 5 + 16);
...@@ -6189,7 +6227,7 @@ static void M_AddonExec(INT32 ch) ...@@ -6189,7 +6227,7 @@ static void M_AddonExec(INT32 ch)
#define len menusearch[0] #define len menusearch[0]
static boolean M_ChangeStringAddons(INT32 choice) static boolean M_ChangeStringAddons(INT32 choice)
{ {
if (shiftdown && choice >= 32 && choice <= 127) if (!cv_textinput.value)
choice = shiftxform[choice]; choice = shiftxform[choice];
switch (choice) switch (choice)
...@@ -6209,13 +6247,17 @@ static boolean M_ChangeStringAddons(INT32 choice) ...@@ -6209,13 +6247,17 @@ static boolean M_ChangeStringAddons(INT32 choice)
} }
break; break;
default: default:
if (choice >= 32 && choice <= 127) if (M_KeyboardTextInput(choice) || (choice == 32)) // ev_textinput
{ {
if (len < MAXSTRINGLENGTH - 1) choice &= ~TEXTINPUTEVENT;
if (choice >= 32 && choice <= 0xFF)
{ {
menusearch[1+len++] = (char)choice; if (len < MAXSTRINGLENGTH - 1)
menusearch[1+len] = 0; {
return true; menusearch[1+len++] = (char)choice;
menusearch[1+len] = 0;
return true;
}
} }
} }
break; break;
...@@ -7015,9 +7057,9 @@ static void M_DrawEmblemHints(void) ...@@ -7015,9 +7057,9 @@ static void M_DrawEmblemHints(void)
if (i == itemOn) if (i == itemOn)
{ {
V_DrawCharacter(BASEVIDWIDTH - currentMenu->x - 10 - V_StringWidth(cv_soundtest.string, 0) - (skullAnimCounter/5), currentMenu->y + y, V_DrawCharacter(BASEVIDWIDTH - currentMenu->x - 10 - V_StringWidth(cv_soundtest.string, 0) - (skullAnimCounter/5), currentMenu->y + y,
'\x1C' | V_YELLOWMAP, false); '\x1C', V_YELLOWMAP, false);
V_DrawCharacter(BASEVIDWIDTH - currentMenu->x + 2 + (skullAnimCounter/5), currentMenu->y + y, V_DrawCharacter(BASEVIDWIDTH - currentMenu->x + 2 + (skullAnimCounter/5), currentMenu->y + y,
'\x1D' | V_YELLOWMAP, false); '\x1D', V_YELLOWMAP, false);
} }
if (cv_soundtest.value) if (cv_soundtest.value)
V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + y + 8, V_YELLOWMAP, S_sfx[cv_soundtest.value].name); V_DrawRightAlignedString(BASEVIDWIDTH - currentMenu->x, currentMenu->y + y + 8, V_YELLOWMAP, S_sfx[cv_soundtest.value].name);
...@@ -7256,9 +7298,9 @@ static void M_DrawSoundTest(void) ...@@ -7256,9 +7298,9 @@ static void M_DrawSoundTest(void)
if (t == st_sel) if (t == st_sel)
{ {
V_DrawCharacter(x - 10 - (skullAnimCounter/5), y, V_DrawCharacter(x - 10 - (skullAnimCounter/5), y,
'\x1C' | V_YELLOWMAP, false); '\x1C', V_YELLOWMAP, false);
V_DrawCharacter(x + 2 + V_StringWidth(sfxstr, 0) + (skullAnimCounter/5), y, V_DrawCharacter(x + 2 + V_StringWidth(sfxstr, 0) + (skullAnimCounter/5), y,
'\x1D' | V_YELLOWMAP, false); '\x1D', V_YELLOWMAP, false);
} }
if (curplaying == soundtestdefs[t]) if (curplaying == soundtestdefs[t])
...@@ -7275,7 +7317,7 @@ static void M_DrawSoundTest(void) ...@@ -7275,7 +7317,7 @@ static void M_DrawSoundTest(void)
if (curplaying == soundtestdefs[t]) if (curplaying == soundtestdefs[t])
{ {
V_DrawFill(165+140-9, y-4, 8, 16, 150); V_DrawFill(165+140-9, y-4, 8, 16, 150);
//V_DrawCharacter(165+140-8, y, '\x19' | V_YELLOWMAP, false); //V_DrawCharacter(165+140-8, y, '\x19', V_YELLOWMAP, false);
V_DrawFixedPatch((165+140-9)<<FRACBITS, (y<<FRACBITS)-(bounce*4), FRACUNIT, 0, hu_font['\x19'-HU_FONTSTART], V_GetStringColormap(V_YELLOWMAP)); V_DrawFixedPatch((165+140-9)<<FRACBITS, (y<<FRACBITS)-(bounce*4), FRACUNIT, 0, hu_font['\x19'-HU_FONTSTART], V_GetStringColormap(V_YELLOWMAP));
} }
} }
...@@ -7886,7 +7928,7 @@ skiplife: ...@@ -7886,7 +7928,7 @@ skiplife:
V_DrawScaledPatch(tempx + 9, y + 2, 0, patch); V_DrawScaledPatch(tempx + 9, y + 2, 0, patch);
tempx += 16; tempx += 16;
if (savegameinfo[savetodraw].lives == INFLIVES) if (savegameinfo[savetodraw].lives == INFLIVES)
V_DrawCharacter(tempx, y + 1, '\x16', false); V_DrawCharacter(tempx, y + 1, '\x16', 0, false);
else else
V_DrawString(tempx, y, 0, va("%d", savegameinfo[savetodraw].lives)); V_DrawString(tempx, y, 0, va("%d", savegameinfo[savetodraw].lives));
...@@ -9099,9 +9141,9 @@ void M_DrawTimeAttackMenu(void) ...@@ -9099,9 +9141,9 @@ void M_DrawTimeAttackMenu(void)
if (i == itemOn) if (i == itemOn)
{ {
V_DrawCharacter(BASEVIDWIDTH - x - soffset - 10 - V_StringWidth(cv->string, 0) - (skullAnimCounter/5), y, V_DrawCharacter(BASEVIDWIDTH - x - soffset - 10 - V_StringWidth(cv->string, 0) - (skullAnimCounter/5), y,
'\x1C' | V_YELLOWMAP, false); '\x1C', V_YELLOWMAP, false);
V_DrawCharacter(BASEVIDWIDTH - x - soffset + 2 + (skullAnimCounter/5), y, V_DrawCharacter(BASEVIDWIDTH - x - soffset + 2 + (skullAnimCounter/5), y,
'\x1D' | V_YELLOWMAP, false); '\x1D', V_YELLOWMAP, false);
} }
} }
} }
...@@ -9162,9 +9204,9 @@ void M_DrawTimeAttackMenu(void) ...@@ -9162,9 +9204,9 @@ void M_DrawTimeAttackMenu(void)
/* Draw arrows !! */ /* Draw arrows !! */
y = y + 25 - 4; y = y + 25 - 4;
V_DrawCharacter(216 - 10 - (skullAnimCounter/5), y, V_DrawCharacter(216 - 10 - (skullAnimCounter/5), y,
'\x1C' | V_YELLOWMAP, false); '\x1C', V_YELLOWMAP, false);
V_DrawCharacter(216 + 80 + 2 + (skullAnimCounter/5), y, V_DrawCharacter(216 + 80 + 2 + (skullAnimCounter/5), y,
'\x1D' | V_YELLOWMAP, false); '\x1D', V_YELLOWMAP, false);
} }
// Draw press ESC to exit string on main record attack menu // Draw press ESC to exit string on main record attack menu
V_DrawString(104-72, 180, V_TRANSLUCENT, M_GetText("Press ESC to exit")); V_DrawString(104-72, 180, V_TRANSLUCENT, M_GetText("Press ESC to exit"));
...@@ -9375,9 +9417,9 @@ void M_DrawNightsAttackMenu(void) ...@@ -9375,9 +9417,9 @@ void M_DrawNightsAttackMenu(void)
if (i == itemOn) if (i == itemOn)
{ {
V_DrawCharacter(BASEVIDWIDTH - x - soffset - 10 - V_StringWidth(cv->string, 0) - (skullAnimCounter/5), y, V_DrawCharacter(BASEVIDWIDTH - x - soffset - 10 - V_StringWidth(cv->string, 0) - (skullAnimCounter/5), y,
'\x1C' | V_YELLOWMAP, false); '\x1C', V_YELLOWMAP, false);
V_DrawCharacter(BASEVIDWIDTH - x - soffset + 2 + (skullAnimCounter/5), y, V_DrawCharacter(BASEVIDWIDTH - x - soffset + 2 + (skullAnimCounter/5), y,
'\x1D' | V_YELLOWMAP, false); '\x1D', V_YELLOWMAP, false);
} }
} }
} }
...@@ -9422,9 +9464,9 @@ void M_DrawNightsAttackMenu(void) ...@@ -9422,9 +9464,9 @@ void M_DrawNightsAttackMenu(void)
/* Draw arrows !! */ /* Draw arrows !! */
y = y + 25 - 4; y = y + 25 - 4;
V_DrawCharacter(208 - 10 - (skullAnimCounter/5), y, V_DrawCharacter(208 - 10 - (skullAnimCounter/5), y,
'\x1C' | V_YELLOWMAP, false); '\x1C', V_YELLOWMAP, false);
V_DrawCharacter(208 + 80 + 2 + (skullAnimCounter/5), y, V_DrawCharacter(208 + 80 + 2 + (skullAnimCounter/5), y,
'\x1D' | V_YELLOWMAP, false); '\x1D', V_YELLOWMAP, false);
} }
// Draw press ESC to exit string on main record attack menu // Draw press ESC to exit string on main record attack menu
V_DrawString(104-72, 180, V_TRANSLUCENT, M_GetText("Press ESC to exit")); V_DrawString(104-72, 180, V_TRANSLUCENT, M_GetText("Press ESC to exit"));
...@@ -10361,7 +10403,7 @@ static void M_DrawMPMainMenu(void) ...@@ -10361,7 +10403,7 @@ static void M_DrawMPMainMenu(void)
// draw text cursor for name // draw text cursor for name
if (itemOn == 2 //0 if (itemOn == 2 //0
&& skullAnimCounter < 4) //blink cursor && skullAnimCounter < 4) //blink cursor
V_DrawCharacter(x+8+V_StringWidth(setupm_ip, V_ALLOWLOWERCASE),y+12,'_',false); V_DrawCharacter(x+8+V_StringWidth(setupm_ip, V_ALLOWLOWERCASE),y+12,'_',0,false);
} }
// Tails 11-19-2002 // Tails 11-19-2002
...@@ -10432,26 +10474,21 @@ static void M_HandleConnectIP(INT32 choice) ...@@ -10432,26 +10474,21 @@ static void M_HandleConnectIP(INT32 choice)
break; break;
default: default:
l = strlen(setupm_ip); if (M_KeyboardTextInput(choice)) // ev_textinput
if (l >= 28-1)
break;
// Rudimentary number and period enforcing - also allows letters so hostnames can be used instead
if ((choice >= '-' && choice <= ':') || (choice >= 'A' && choice <= 'Z') || (choice >= 'a' && choice <= 'z'))
{ {
S_StartSound(NULL,sfx_menu1); // Tails choice &= ~TEXTINPUTEVENT;
setupm_ip[l] = (char)choice; l = strlen(setupm_ip);
setupm_ip[l+1] = 0; if (l >= 28-1)
} break;
else if (choice >= 199 && choice <= 211 && choice != 202 && choice != 206) //numpad too!
{
char keypad_translation[] = {'7','8','9','-','4','5','6','+','1','2','3','0','.'};
choice = keypad_translation[choice - 199];
S_StartSound(NULL,sfx_menu1); // Tails
setupm_ip[l] = (char)choice;
setupm_ip[l+1] = 0;
}
// Rudimentary number and period enforcing - also allows letters so hostnames can be used instead
if ((choice >= '-' && choice <= ':') || (choice >= 'A' && choice <= 'Z') || (choice >= 'a' && choice <= 'z'))
{
S_StartSound(NULL,sfx_menu1); // Tails
setupm_ip[l] = (char)choice;
setupm_ip[l+1] = 0;
}
}
break; break;
} }
...@@ -10514,7 +10551,7 @@ static void M_DrawSetupMultiPlayerMenu(void) ...@@ -10514,7 +10551,7 @@ static void M_DrawSetupMultiPlayerMenu(void)
V_DrawString(x + 8, y + 3, V_ALLOWLOWERCASE, setupm_name); V_DrawString(x + 8, y + 3, V_ALLOWLOWERCASE, setupm_name);
if (skullAnimCounter < 4 && itemOn == 0) if (skullAnimCounter < 4 && itemOn == 0)
V_DrawCharacter(x + 8 + V_StringWidth(setupm_name, V_ALLOWLOWERCASE), y + 3, V_DrawCharacter(x + 8 + V_StringWidth(setupm_name, V_ALLOWLOWERCASE), y + 3,
'_' | 0x80, false); '_', 0x80, false);
y += 20; y += 20;
...@@ -10530,9 +10567,9 @@ static void M_DrawSetupMultiPlayerMenu(void) ...@@ -10530,9 +10567,9 @@ static void M_DrawSetupMultiPlayerMenu(void)
if (itemOn == 1 && (MP_PlayerSetupMenu[1].status & IT_TYPE) != IT_SPACE) if (itemOn == 1 && (MP_PlayerSetupMenu[1].status & IT_TYPE) != IT_SPACE)
{ {
V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(skins[setupm_fakeskin].realname, V_ALLOWLOWERCASE) - (skullAnimCounter/5), y, V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(skins[setupm_fakeskin].realname, V_ALLOWLOWERCASE) - (skullAnimCounter/5), y,
'\x1C' | V_YELLOWMAP, false); '\x1C', V_YELLOWMAP, false);
V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y, V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y,
'\x1D' | V_YELLOWMAP, false); '\x1D', V_YELLOWMAP, false);
} }
x = BASEVIDWIDTH/2; x = BASEVIDWIDTH/2;
...@@ -10607,9 +10644,9 @@ colordraw: ...@@ -10607,9 +10644,9 @@ colordraw:
if (itemOn == 2 && (MP_PlayerSetupMenu[2].status & IT_TYPE) != IT_SPACE) if (itemOn == 2 && (MP_PlayerSetupMenu[2].status & IT_TYPE) != IT_SPACE)
{ {
V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(Color_Names[setupm_fakecolor], V_ALLOWLOWERCASE) - (skullAnimCounter/5), y, V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(Color_Names[setupm_fakecolor], V_ALLOWLOWERCASE) - (skullAnimCounter/5), y,
'\x1C' | V_YELLOWMAP, false); '\x1C', V_YELLOWMAP, false);
V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y, V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y,
'\x1D' | V_YELLOWMAP, false); '\x1D', V_YELLOWMAP, false);
} }
y += 11; y += 11;
...@@ -10761,14 +10798,18 @@ static void M_HandleSetupMultiPlayer(INT32 choice) ...@@ -10761,14 +10798,18 @@ static void M_HandleSetupMultiPlayer(INT32 choice)
break; break;
default: default:
if (itemOn != 0 || choice < 32 || choice > 127) if (M_KeyboardTextInput(choice) || (choice == 32)) // ev_textinput
break;
S_StartSound(NULL,sfx_menu1); // Tails
l = strlen(setupm_name);
if (l < MAXPLAYERNAME)
{ {
setupm_name[l] = (char)choice; choice &= ~TEXTINPUTEVENT;
setupm_name[l+1] = 0; if (itemOn != 0 || choice < 32 || choice > 0xFF)
break;
S_StartSound(NULL,sfx_menu1); // Tails
l = strlen(setupm_name);
if (l < MAXPLAYERNAME)
{
setupm_name[l] = (char)choice;
setupm_name[l+1] = 0;
}
} }
break; break;
} }
...@@ -11683,7 +11724,7 @@ static void M_DrawColorMenu(void) ...@@ -11683,7 +11724,7 @@ static void M_DrawColorMenu(void)
V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string); V_DrawString(x + 8, y + 12, V_ALLOWLOWERCASE, cv->string);
if (skullAnimCounter < 4 && i == itemOn) if (skullAnimCounter < 4 && i == itemOn)
V_DrawCharacter(x + 8 + V_StringWidth(cv->string, 0), y + 12, V_DrawCharacter(x + 8 + V_StringWidth(cv->string, 0), y + 12,
'_' | 0x80, false); '_', 0x80, false);
y += 16; y += 16;
break; break;
default: default:
...@@ -11692,9 +11733,9 @@ static void M_DrawColorMenu(void) ...@@ -11692,9 +11733,9 @@ static void M_DrawColorMenu(void)
if (i == itemOn) if (i == itemOn)
{ {
V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(cv->string, 0) - (skullAnimCounter/5), y, V_DrawCharacter(BASEVIDWIDTH - x - 10 - V_StringWidth(cv->string, 0) - (skullAnimCounter/5), y,
'\x1C' | V_YELLOWMAP, false); '\x1C', V_YELLOWMAP, false);
V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y, V_DrawCharacter(BASEVIDWIDTH - x + 2 + (skullAnimCounter/5), y,
'\x1D' | V_YELLOWMAP, false); '\x1D', V_YELLOWMAP, false);
} }
break; break;
} }
...@@ -11928,7 +11969,7 @@ static void M_OGL_DrawFogMenu(void) ...@@ -11928,7 +11969,7 @@ static void M_OGL_DrawFogMenu(void)
// blink cursor on FOG_COLOR_ITEM if selected // blink cursor on FOG_COLOR_ITEM if selected
if (itemOn == FOG_COLOR_ITEM && skullAnimCounter < 4) if (itemOn == FOG_COLOR_ITEM && skullAnimCounter < 4)
V_DrawCharacter(BASEVIDWIDTH - mx, V_DrawCharacter(BASEVIDWIDTH - mx,
my + currentMenu->menuitems[FOG_COLOR_ITEM].alphaKey, '_' | 0x80,false); my + currentMenu->menuitems[FOG_COLOR_ITEM].alphaKey, '_', 0x80,false);
} }
// ===================== // =====================
......
...@@ -176,6 +176,7 @@ void M_SetMenuCurTitlePics(void); ...@@ -176,6 +176,7 @@ void M_SetMenuCurTitlePics(void);
// this can resize the view and change game parameters. // this can resize the view and change game parameters.
// Does all the real work of the menu interaction. // Does all the real work of the menu interaction.
boolean M_Responder(event_t *ev); boolean M_Responder(event_t *ev);
boolean M_TextInput(void);
// Called by main loop, only used for menu (skull cursor) animation. // Called by main loop, only used for menu (skull cursor) animation.
void M_Ticker(void); void M_Ticker(void);
......
...@@ -1579,7 +1579,7 @@ boolean M_ScreenshotResponder(event_t *ev) ...@@ -1579,7 +1579,7 @@ boolean M_ScreenshotResponder(event_t *ev)
ch = ev->data1; ch = ev->data1;
if (ch >= KEY_MOUSE1 && menuactive) // If it's not a keyboard key, then don't allow it in the menus! if (ch >= NUMKEYS && menuactive) // If it's not a keyboard key, then don't allow it in the menus!
return false; return false;
if (ch == KEY_F8 || ch == gamecontrol[gc_screenshot][0] || ch == gamecontrol[gc_screenshot][1]) // remappable F8 if (ch == KEY_F8 || ch == gamecontrol[gc_screenshot][0] || ch == gamecontrol[gc_screenshot][1]) // remappable F8
......
...@@ -148,6 +148,11 @@ extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_fu ...@@ -148,6 +148,11 @@ extern consvar_t cv_scr_width, cv_scr_height, cv_scr_depth, cv_renderview, cv_fu
// wait for page flipping to end or not // wait for page flipping to end or not
extern consvar_t cv_vidwait; extern consvar_t cv_vidwait;
// This is an annoying place to put these cvar on
extern consvar_t cv_textinput;
extern consvar_t cv_keyboardlocale;
extern consvar_t cv_forceqwerty;
// quick fix for tall/short skies, depending on bytesperpixel // quick fix for tall/short skies, depending on bytesperpixel
extern void (*walldrawerfunc)(void); extern void (*walldrawerfunc)(void);
......
...@@ -2549,7 +2549,7 @@ const char *I_ClipboardPaste(void) ...@@ -2549,7 +2549,7 @@ const char *I_ClipboardPaste(void)
} }
else if (*i == '\t') else if (*i == '\t')
*i = ' '; // Tabs become spaces *i = ' '; // Tabs become spaces
else if (*i < 32 || (unsigned)*i > 127) else if ((unsigned)*i < 32)
*i = '?'; // Nonprintable chars become question marks *i = '?'; // Nonprintable chars become question marks
++i; ++i;
} }
......
...@@ -66,6 +66,7 @@ ...@@ -66,6 +66,7 @@
#include "../d_main.h" #include "../d_main.h"
#include "../s_sound.h" #include "../s_sound.h"
#include "../i_joy.h" #include "../i_joy.h"
#include "../hu_stuff.h"
#include "../st_stuff.h" #include "../st_stuff.h"
#include "../g_game.h" #include "../g_game.h"
#include "../i_video.h" #include "../i_video.h"
...@@ -101,6 +102,11 @@ static consvar_t cv_stretch = {"stretch", "Off", CV_SAVE|CV_NOSHOWHELP, CV_OnOff ...@@ -101,6 +102,11 @@ static consvar_t cv_stretch = {"stretch", "Off", CV_SAVE|CV_NOSHOWHELP, CV_OnOff
UINT8 graphics_started = 0; // Is used in console.c and screen.c UINT8 graphics_started = 0; // Is used in console.c and screen.c
// Lactozilla: keyboard input
consvar_t cv_textinput = {"textinput", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_keyboardlocale = {"keyboardlocale", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
consvar_t cv_forceqwerty = {"forceqwerty", "On", CV_SAVE, CV_OnOff, NULL, 0, NULL, NULL, 0, 0, NULL};
// To disable fullscreen at startup; is set in VID_PrepareModeList // To disable fullscreen at startup; is set in VID_PrepareModeList
boolean allow_fullscreen = false; boolean allow_fullscreen = false;
static SDL_bool disable_fullscreen = SDL_FALSE; static SDL_bool disable_fullscreen = SDL_FALSE;
...@@ -264,92 +270,259 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen) ...@@ -264,92 +270,259 @@ static void SDLSetMode(INT32 width, INT32 height, SDL_bool fullscreen)
} }
} }
static INT32 Impl_SDL_Scancode_To_Keycode(SDL_Scancode code) static INT32 Impl_SDL_Scancode_To_Keycode(SDL_Scancode code, Uint32 type)
{ {
if (code >= SDL_SCANCODE_A && code <= SDL_SCANCODE_Z) if (cv_keyboardlocale.value)
{ {
// get lowercase ASCII SDL_Keycode keycode = SDL_GetKeyFromScancode(code);
return code - SDL_SCANCODE_A + 'a';
} // Lactozilla
if (code >= SDL_SCANCODE_1 && code <= SDL_SCANCODE_9) // Use keycodes instead of scancodes,
{ // so that non-US keyboards can work! Wow!
return code - SDL_SCANCODE_1 + '1'; switch (keycode)
} {
else if (code == SDL_SCANCODE_0) // F11 and F12 are separated from the rest of the function keys
{ case SDLK_F11: return KEY_F11;
return '0'; case SDLK_F12: return KEY_F12;
}
if (code >= SDL_SCANCODE_F1 && code <= SDL_SCANCODE_F10) case SDLK_KP_0: return KEY_KEYPAD0;
{ case SDLK_KP_1: return KEY_KEYPAD1;
return KEY_F1 + (code - SDL_SCANCODE_F1); case SDLK_KP_2: return KEY_KEYPAD2;
} case SDLK_KP_3: return KEY_KEYPAD3;
switch (code) case SDLK_KP_4: return KEY_KEYPAD4;
{ case SDLK_KP_5: return KEY_KEYPAD5;
// F11 and F12 are separated from the rest of the function keys case SDLK_KP_6: return KEY_KEYPAD6;
case SDL_SCANCODE_F11: return KEY_F11; case SDLK_KP_7: return KEY_KEYPAD7;
case SDL_SCANCODE_F12: return KEY_F12; case SDLK_KP_8: return KEY_KEYPAD8;
case SDLK_KP_9: return KEY_KEYPAD9;
case SDL_SCANCODE_KP_0: return KEY_KEYPAD0;
case SDL_SCANCODE_KP_1: return KEY_KEYPAD1; case SDLK_RETURN: return KEY_ENTER;
case SDL_SCANCODE_KP_2: return KEY_KEYPAD2; case SDLK_ESCAPE: return KEY_ESCAPE;
case SDL_SCANCODE_KP_3: return KEY_KEYPAD3; case SDLK_BACKSPACE: return KEY_BACKSPACE;
case SDL_SCANCODE_KP_4: return KEY_KEYPAD4; case SDLK_TAB: return KEY_TAB;
case SDL_SCANCODE_KP_5: return KEY_KEYPAD5; case SDLK_SPACE: return KEY_SPACE;
case SDL_SCANCODE_KP_6: return KEY_KEYPAD6; case SDLK_CAPSLOCK: return KEY_CAPSLOCK;
case SDL_SCANCODE_KP_7: return KEY_KEYPAD7; case SDLK_PRINTSCREEN: return KEY_PRTSC;
case SDL_SCANCODE_KP_8: return KEY_KEYPAD8; case SDLK_SCROLLLOCK: return KEY_SCROLLLOCK;
case SDL_SCANCODE_KP_9: return KEY_KEYPAD9; case SDLK_APPLICATION: return KEY_MENU;
case SDLK_PAUSE: return KEY_PAUSE;
case SDL_SCANCODE_RETURN: return KEY_ENTER; case SDLK_INSERT: return KEY_INS;
case SDL_SCANCODE_ESCAPE: return KEY_ESCAPE; case SDLK_HOME: return KEY_HOME;
case SDL_SCANCODE_BACKSPACE: return KEY_BACKSPACE; case SDLK_PAGEUP: return KEY_PGUP;
case SDL_SCANCODE_TAB: return KEY_TAB; case SDLK_DELETE: return KEY_DEL;
case SDL_SCANCODE_SPACE: return KEY_SPACE; case SDLK_END: return KEY_END;
case SDL_SCANCODE_MINUS: return KEY_MINUS; case SDLK_PAGEDOWN: return KEY_PGDN;
case SDL_SCANCODE_EQUALS: return KEY_EQUALS; case SDLK_RIGHT: return KEY_RIGHTARROW;
case SDL_SCANCODE_LEFTBRACKET: return '['; case SDLK_LEFT: return KEY_LEFTARROW;
case SDL_SCANCODE_RIGHTBRACKET: return ']'; case SDLK_DOWN: return KEY_DOWNARROW;
case SDL_SCANCODE_BACKSLASH: return '\\'; case SDLK_UP: return KEY_UPARROW;
case SDL_SCANCODE_NONUSHASH: return '#'; case SDLK_NUMLOCKCLEAR: return KEY_NUMLOCK;
case SDL_SCANCODE_SEMICOLON: return ';'; case SDLK_KP_DIVIDE: return KEY_KPADSLASH;
case SDL_SCANCODE_APOSTROPHE: return '\''; case SDLK_KP_MULTIPLY: return '*'; // undefined?
case SDL_SCANCODE_GRAVE: return '`'; case SDLK_KP_MINUS: return KEY_MINUSPAD;
case SDL_SCANCODE_COMMA: return ','; case SDLK_KP_PLUS: return KEY_PLUSPAD;
case SDL_SCANCODE_PERIOD: return '.'; case SDLK_KP_ENTER: return KEY_ENTER;
case SDL_SCANCODE_SLASH: return '/'; case SDLK_KP_PERIOD: return KEY_KPADDEL;
case SDL_SCANCODE_CAPSLOCK: return KEY_CAPSLOCK;
case SDL_SCANCODE_PRINTSCREEN: return 0; // undefined? case SDLK_LSHIFT: return KEY_LSHIFT;
case SDL_SCANCODE_SCROLLLOCK: return KEY_SCROLLLOCK; case SDLK_RSHIFT: return KEY_RSHIFT;
case SDL_SCANCODE_PAUSE: return KEY_PAUSE; case SDLK_LCTRL: return KEY_LCTRL;
case SDL_SCANCODE_INSERT: return KEY_INS; case SDLK_RCTRL: return KEY_RCTRL;
case SDL_SCANCODE_HOME: return KEY_HOME; case SDLK_LALT: return KEY_LALT;
case SDL_SCANCODE_PAGEUP: return KEY_PGUP; case SDLK_RALT: return KEY_RALT;
case SDL_SCANCODE_DELETE: return KEY_DEL; case SDLK_LGUI: return KEY_LEFTWIN;
case SDL_SCANCODE_END: return KEY_END; case SDLK_RGUI: return KEY_RIGHTWIN;
case SDL_SCANCODE_PAGEDOWN: return KEY_PGDN; default: break;
case SDL_SCANCODE_RIGHT: return KEY_RIGHTARROW; }
case SDL_SCANCODE_LEFT: return KEY_LEFTARROW;
case SDL_SCANCODE_DOWN: return KEY_DOWNARROW; if (keycode >= SDLK_F1 && keycode <= SDLK_F10)
case SDL_SCANCODE_UP: return KEY_UPARROW; {
case SDL_SCANCODE_NUMLOCKCLEAR: return KEY_NUMLOCK; return KEY_F1 + (keycode - SDLK_F1);
case SDL_SCANCODE_KP_DIVIDE: return KEY_KPADSLASH; }
case SDL_SCANCODE_KP_MULTIPLY: return '*'; // undefined?
case SDL_SCANCODE_KP_MINUS: return KEY_MINUSPAD; // Do send keyup events to avoid stuck movement keys
case SDL_SCANCODE_KP_PLUS: return KEY_PLUSPAD; if (type != SDL_KEYUP && (!ctrldown))
case SDL_SCANCODE_KP_ENTER: return KEY_ENTER; {
case SDL_SCANCODE_KP_PERIOD: return KEY_KPADDEL; if (cv_textinput.value)
case SDL_SCANCODE_NONUSBACKSLASH: return '\\'; {
// Lactozilla: console input
case SDL_SCANCODE_LSHIFT: return KEY_LSHIFT; if (CON_AcceptInput())
case SDL_SCANCODE_RSHIFT: return KEY_RSHIFT; return 0;
case SDL_SCANCODE_LCTRL: return KEY_LCTRL; // menu text input
case SDL_SCANCODE_RCTRL: return KEY_RCTRL; if (M_TextInput())
case SDL_SCANCODE_LALT: return KEY_LALT; return 0;
case SDL_SCANCODE_RALT: return KEY_RALT; // chat input
case SDL_SCANCODE_LGUI: return KEY_LEFTWIN; if (HU_ChatActive())
case SDL_SCANCODE_RGUI: return KEY_RIGHTWIN; return 0;
default: break; }
}
switch (keycode)
{
case SDLK_MINUS: return KEY_MINUS;
case SDLK_EQUALS: return KEY_EQUALS;
case SDLK_LEFTBRACKET: return '[';
case SDLK_RIGHTBRACKET: return ']';
case SDLK_BACKSLASH: return '\\';
case SDLK_SEMICOLON: return ';';
case SDLK_QUOTE: return '\'';
case SDLK_BACKQUOTE: return '`';
case SDLK_COMMA: return ',';
case SDLK_PERIOD: return '.';
case SDLK_SLASH: return '/';
case SDLK_AMPERSAND: return '&';
case SDLK_ASTERISK: return '*';
case SDLK_AT: return '@';
case SDLK_CARET: return '^';
case SDLK_COLON: return ':';
case SDLK_DOLLAR: return '$';
case SDLK_EXCLAIM: return '!';
case SDLK_GREATER: return '>';
case SDLK_HASH: return '#';
case SDLK_LEFTPAREN: return '(';
case SDLK_LESS: return '<';
case SDLK_PERCENT: return '%';
case SDLK_PLUS: return '+';
case SDLK_QUESTION: return '?';
case SDLK_QUOTEDBL: return '"';
case SDLK_RIGHTPAREN: return ')';
case SDLK_UNDERSCORE: return '_';
default: break;
}
// Tested by installing a French keymap
if (cv_forceqwerty.value)
{
if (code >= SDL_SCANCODE_A && code <= SDL_SCANCODE_Z)
return code - SDL_SCANCODE_A + 'a';
else if (code >= SDL_SCANCODE_1 && code <= SDL_SCANCODE_9)
return code - SDL_SCANCODE_1 + '1';
else if (code == SDL_SCANCODE_0)
return '0';
}
else
{
if (keycode >= SDLK_a && keycode <= SDLK_z)
return keycode - SDLK_a + 'a';
else if (keycode >= SDLK_1 && keycode <= SDLK_9)
return keycode - SDLK_1 + '1';
else if (keycode == SDLK_0)
return '0';
}
}
else
{
switch (code)
{
// F11 and F12 are separated from the rest of the function keys
case SDL_SCANCODE_F11: return KEY_F11;
case SDL_SCANCODE_F12: return KEY_F12;
case SDL_SCANCODE_KP_0: return KEY_KEYPAD0;
case SDL_SCANCODE_KP_1: return KEY_KEYPAD1;
case SDL_SCANCODE_KP_2: return KEY_KEYPAD2;
case SDL_SCANCODE_KP_3: return KEY_KEYPAD3;
case SDL_SCANCODE_KP_4: return KEY_KEYPAD4;
case SDL_SCANCODE_KP_5: return KEY_KEYPAD5;
case SDL_SCANCODE_KP_6: return KEY_KEYPAD6;
case SDL_SCANCODE_KP_7: return KEY_KEYPAD7;
case SDL_SCANCODE_KP_8: return KEY_KEYPAD8;
case SDL_SCANCODE_KP_9: return KEY_KEYPAD9;
case SDL_SCANCODE_RETURN: return KEY_ENTER;
case SDL_SCANCODE_ESCAPE: return KEY_ESCAPE;
case SDL_SCANCODE_BACKSPACE: return KEY_BACKSPACE;
case SDL_SCANCODE_TAB: return KEY_TAB;
case SDL_SCANCODE_SPACE: return KEY_SPACE;
case SDL_SCANCODE_CAPSLOCK: return KEY_CAPSLOCK;
case SDL_SCANCODE_PRINTSCREEN: return 0; // undefined?
case SDL_SCANCODE_SCROLLLOCK: return KEY_SCROLLLOCK;
case SDL_SCANCODE_PAUSE: return KEY_PAUSE;
case SDL_SCANCODE_INSERT: return KEY_INS;
case SDL_SCANCODE_HOME: return KEY_HOME;
case SDL_SCANCODE_PAGEUP: return KEY_PGUP;
case SDL_SCANCODE_DELETE: return KEY_DEL;
case SDL_SCANCODE_END: return KEY_END;
case SDL_SCANCODE_PAGEDOWN: return KEY_PGDN;
case SDL_SCANCODE_RIGHT: return KEY_RIGHTARROW;
case SDL_SCANCODE_LEFT: return KEY_LEFTARROW;
case SDL_SCANCODE_DOWN: return KEY_DOWNARROW;
case SDL_SCANCODE_UP: return KEY_UPARROW;
case SDL_SCANCODE_NUMLOCKCLEAR: return KEY_NUMLOCK;
case SDL_SCANCODE_KP_DIVIDE: return KEY_KPADSLASH;
case SDL_SCANCODE_KP_MULTIPLY: return '*'; // undefined?
case SDL_SCANCODE_KP_MINUS: return KEY_MINUSPAD;
case SDL_SCANCODE_KP_PLUS: return KEY_PLUSPAD;
case SDL_SCANCODE_KP_ENTER: return KEY_ENTER;
case SDL_SCANCODE_KP_PERIOD: return KEY_KPADDEL;
case SDL_SCANCODE_NONUSBACKSLASH: return '\\';
case SDL_SCANCODE_LSHIFT: return KEY_LSHIFT;
case SDL_SCANCODE_RSHIFT: return KEY_RSHIFT;
case SDL_SCANCODE_LCTRL: return KEY_LCTRL;
case SDL_SCANCODE_RCTRL: return KEY_RCTRL;
case SDL_SCANCODE_LALT: return KEY_LALT;
case SDL_SCANCODE_RALT: return KEY_RALT;
case SDL_SCANCODE_LGUI: return KEY_LEFTWIN;
case SDL_SCANCODE_RGUI: return KEY_RIGHTWIN;
default: break;
}
if (code >= SDL_SCANCODE_F1 && code <= SDL_SCANCODE_F10)
{
return KEY_F1 + (code - SDL_SCANCODE_F1);
}
// Do send keyup events to avoid stuck movement keys
if (type != SDL_KEYUP && (!ctrldown))
{
if (cv_textinput.value)
{
// Lactozilla: console input
if (CON_AcceptInput())
return 0;
// menu text input
if (M_TextInput())
return 0;
// chat input
if (HU_ChatActive())
return 0;
}
}
switch (code)
{
case SDL_SCANCODE_MINUS: return KEY_MINUS;
case SDL_SCANCODE_EQUALS: return KEY_EQUALS;
case SDL_SCANCODE_LEFTBRACKET: return '[';
case SDL_SCANCODE_RIGHTBRACKET: return ']';
case SDL_SCANCODE_BACKSLASH: return '\\';
case SDL_SCANCODE_NONUSHASH: return '#';
case SDL_SCANCODE_SEMICOLON: return ';';
case SDL_SCANCODE_APOSTROPHE: return '\'';
case SDL_SCANCODE_GRAVE: return '`';
case SDL_SCANCODE_COMMA: return ',';
case SDL_SCANCODE_PERIOD: return '.';
case SDL_SCANCODE_SLASH: return '/';
default: break;
}
// cv_forceqwerty assumed on
if (code >= SDL_SCANCODE_A && code <= SDL_SCANCODE_Z)
{
// get lowercase ASCII
return code - SDL_SCANCODE_A + 'a';
}
if (code >= SDL_SCANCODE_1 && code <= SDL_SCANCODE_9)
{
return code - SDL_SCANCODE_1 + '1';
}
else if (code == SDL_SCANCODE_0)
{
return '0';
}
} }
#ifdef HWRENDER #ifdef HWRENDER
DBG_Printf("Unknown incoming scancode: %d, represented %c\n", DBG_Printf("Unknown incoming scancode: %d, represented %c\n",
code, code,
...@@ -630,10 +803,29 @@ static void Impl_HandleKeyboardEvent(SDL_KeyboardEvent evt, Uint32 type) ...@@ -630,10 +803,29 @@ static void Impl_HandleKeyboardEvent(SDL_KeyboardEvent evt, Uint32 type)
{ {
return; return;
} }
event.data1 = Impl_SDL_Scancode_To_Keycode(evt.keysym.scancode); event.data1 = Impl_SDL_Scancode_To_Keycode(evt.keysym.scancode, type);
if (event.data1) D_PostEvent(&event); if (event.data1) D_PostEvent(&event);
} }
static void Impl_HandleTextInputEvent(char *text)
{
event_t event;
UINT16 special;
if (!cv_textinput.value)
return;
special = (text[1]+256);
if (special == 256)
event.data1 = text[0];
else
event.data1 = special+64;
event.type = ev_textinput;
if (event.data1 >= 33 && event.data1 <= 0xFF)
D_PostEvent(&event);
}
static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt) static void Impl_HandleMouseMotionEvent(SDL_MouseMotionEvent evt)
{ {
if (USE_MOUSEINPUT) if (USE_MOUSEINPUT)
...@@ -875,6 +1067,9 @@ void I_GetEvent(void) ...@@ -875,6 +1067,9 @@ void I_GetEvent(void)
case SDL_KEYDOWN: case SDL_KEYDOWN:
Impl_HandleKeyboardEvent(evt.key, evt.type); Impl_HandleKeyboardEvent(evt.key, evt.type);
break; break;
case SDL_TEXTINPUT:
Impl_HandleTextInputEvent(evt.text.text);
break;
case SDL_MOUSEMOTION: case SDL_MOUSEMOTION:
//if (!mouseMotionOnce) //if (!mouseMotionOnce)
Impl_HandleMouseMotionEvent(evt.motion); Impl_HandleMouseMotionEvent(evt.motion);
...@@ -1606,6 +1801,21 @@ void I_StartupGraphics(void) ...@@ -1606,6 +1801,21 @@ void I_StartupGraphics(void)
disable_mouse = M_CheckParm("-nomouse"); disable_mouse = M_CheckParm("-nomouse");
disable_fullscreen = M_CheckParm("-win") ? 1 : 0; disable_fullscreen = M_CheckParm("-win") ? 1 : 0;
// Lactozilla
// Small explanation from your local kaiju
// * cv_textinput allows "text input" events from SDL,
// so that console and chat is guaranteed to use
// your keyboard's locale reliably
// * When disabled, the game will fallback to using
// keycode events, still following your locale somewhat
// * If cv_keyboardlocale is disabled, input will default
// to using the US keyboard layout
// * cv_forceqwerty does what it says on the tin, but only
// if text input events were disabled
CV_RegisterVar (&cv_textinput);
CV_RegisterVar (&cv_keyboardlocale);
CV_RegisterVar (&cv_forceqwerty);
keyboard_started = true; keyboard_started = true;
#if !defined(HAVE_TTF) #if !defined(HAVE_TTF)
......