mirror of
https://git.do.srb2.org/STJr/SRB2.git
synced 2024-11-15 09:11:48 +00:00
You can now move the cursor in command prompt and chat, using left/right, ctrl+left/right, home/end, and select text with shift
This commit is contained in:
parent
51cb45cd4b
commit
2d72b2fac6
3 changed files with 498 additions and 153 deletions
213
src/console.c
213
src/console.c
|
@ -91,11 +91,13 @@ static char inputlines[32][CON_MAXPROMPTCHARS]; // hold last 32 prompt lines
|
||||||
static INT32 inputline; // current input line number
|
static INT32 inputline; // current input line number
|
||||||
static INT32 inputhist; // line number of history input line to restore
|
static INT32 inputhist; // line number of history input line to restore
|
||||||
static size_t input_cx; // position in current input line
|
static size_t input_cx; // position in current input line
|
||||||
|
static INT32 input_selection; // selection border in current input line, -1 if no selection
|
||||||
|
|
||||||
// protos.
|
// protos.
|
||||||
static void CON_InputInit(void);
|
static void CON_InputInit(void);
|
||||||
static void CON_RecalcSize(void);
|
static void CON_RecalcSize(void);
|
||||||
|
|
||||||
|
static void CON_DeleteSelectedText(void);
|
||||||
static void CONS_hudlines_Change(void);
|
static void CONS_hudlines_Change(void);
|
||||||
static void CON_DrawBackpic(patch_t *pic, INT32 startx, INT32 destwidth);
|
static void CON_DrawBackpic(patch_t *pic, INT32 startx, INT32 destwidth);
|
||||||
//static void CON_DrawBackpic2(pic_t *pic, INT32 startx, INT32 destwidth);
|
//static void CON_DrawBackpic2(pic_t *pic, INT32 startx, INT32 destwidth);
|
||||||
|
@ -394,6 +396,7 @@ static void CON_InputInit(void)
|
||||||
inputlines[i][0] = CON_PROMPTCHAR;
|
inputlines[i][0] = CON_PROMPTCHAR;
|
||||||
inputline = 0;
|
inputline = 0;
|
||||||
input_cx = 1;
|
input_cx = 1;
|
||||||
|
input_selection = -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
|
@ -618,6 +621,25 @@ void CON_Ticker(void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Deletes selected text, assuming there is, and resets selection.
|
||||||
|
// Also sets the cursor to the correct position.
|
||||||
|
//
|
||||||
|
static void CON_DeleteSelectedText(void)
|
||||||
|
{
|
||||||
|
UINT32 i, j;
|
||||||
|
char *line = inputlines[inputline];
|
||||||
|
size_t selstart = min(input_cx, input_selection);
|
||||||
|
size_t selend = max(input_cx, input_selection);
|
||||||
|
|
||||||
|
for (i = selstart, j = selend; line[j]; ++i, ++j)
|
||||||
|
line[i] = line[j];
|
||||||
|
while (line[i])
|
||||||
|
line[i++] = 0;
|
||||||
|
|
||||||
|
input_cx = selstart;
|
||||||
|
input_selection = -1;
|
||||||
|
}
|
||||||
|
|
||||||
// Handles console key input
|
// Handles console key input
|
||||||
//
|
//
|
||||||
boolean CON_Responder(event_t *ev)
|
boolean CON_Responder(event_t *ev)
|
||||||
|
@ -704,6 +726,9 @@ boolean CON_Responder(event_t *ev)
|
||||||
// command completion forward (tab) and backward (shift-tab)
|
// command completion forward (tab) and backward (shift-tab)
|
||||||
if (key == KEY_TAB)
|
if (key == KEY_TAB)
|
||||||
{
|
{
|
||||||
|
input_cx = strlen(inputlines[inputline]); // make sure the cursor is at the end of the string, in case we were inserting
|
||||||
|
input_selection = -1; // make sure there is no text selected, it would look odd
|
||||||
|
|
||||||
// show all cvars/commands that match what we have inputted
|
// show all cvars/commands that match what we have inputted
|
||||||
if (ctrldown)
|
if (ctrldown)
|
||||||
{
|
{
|
||||||
|
@ -839,21 +864,51 @@ boolean CON_Responder(event_t *ev)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (key == KEY_HOME) // oldest text in buffer
|
if (key == KEY_HOME)
|
||||||
{
|
{
|
||||||
con_scrollup = (con_totallines-((con_curlines-16)>>3));
|
if (shiftdown)
|
||||||
|
{
|
||||||
|
if (input_selection == -1)
|
||||||
|
input_selection = input_cx;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
input_selection = -1;
|
||||||
|
|
||||||
|
if (ctrldown)
|
||||||
|
con_scrollup = (con_totallines-((con_curlines-16)>>3)); // oldest text in buffer
|
||||||
|
else
|
||||||
|
input_cx = 1;
|
||||||
|
|
||||||
|
if (input_cx == input_selection)
|
||||||
|
input_selection = -1;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
else if (key == KEY_END) // most recent text in buffer
|
else if (key == KEY_END)
|
||||||
{
|
{
|
||||||
con_scrollup = 0;
|
if (shiftdown)
|
||||||
|
{
|
||||||
|
if (input_selection == -1)
|
||||||
|
input_selection = input_cx;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
input_selection = -1;
|
||||||
|
|
||||||
|
if (ctrldown)
|
||||||
|
con_scrollup = 0; // most recent text in buffer
|
||||||
|
else
|
||||||
|
input_cx = strlen(inputlines[inputline]);
|
||||||
|
|
||||||
|
if (input_cx == input_selection)
|
||||||
|
input_selection = -1;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// command enter
|
// command enter
|
||||||
if (key == KEY_ENTER)
|
if (key == KEY_ENTER)
|
||||||
{
|
{
|
||||||
if (input_cx < 2)
|
if (strlen(inputlines[inputline]) < 2)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
// push the command
|
// push the command
|
||||||
|
@ -868,18 +923,107 @@ boolean CON_Responder(event_t *ev)
|
||||||
memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS);
|
memset(inputlines[inputline], 0, CON_MAXPROMPTCHARS);
|
||||||
inputlines[inputline][0] = CON_PROMPTCHAR;
|
inputlines[inputline][0] = CON_PROMPTCHAR;
|
||||||
input_cx = 1;
|
input_cx = 1;
|
||||||
|
input_selection = -1;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
// backspace command prompt
|
// backspace command prompt or delete selected text
|
||||||
if (key == KEY_BACKSPACE)
|
if (key == KEY_BACKSPACE)
|
||||||
{
|
{
|
||||||
if (input_cx > 1)
|
if (input_selection == -1)
|
||||||
{
|
{
|
||||||
input_cx--;
|
if (input_cx > 1)
|
||||||
inputlines[inputline][input_cx] = 0;
|
{
|
||||||
|
UINT32 i, j;
|
||||||
|
char *line = inputlines[inputline];
|
||||||
|
|
||||||
|
for (i = input_cx - 1, j = input_cx; line[j]; ++i, ++j)
|
||||||
|
line[i] = line[j];
|
||||||
|
line[i] = 0;
|
||||||
|
input_cx--;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
CON_DeleteSelectedText();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// delete character under cursor or selected text
|
||||||
|
if (key == KEY_DEL)
|
||||||
|
{
|
||||||
|
if (input_selection == -1)
|
||||||
|
{
|
||||||
|
UINT32 i, j;
|
||||||
|
char *line = inputlines[inputline];
|
||||||
|
|
||||||
|
for (i = input_cx, j = input_cx + 1; line[j]; ++i, ++j)
|
||||||
|
line[i] = line[j];
|
||||||
|
line[i] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
CON_DeleteSelectedText();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == KEY_LEFTARROW)
|
||||||
|
{
|
||||||
|
if (shiftdown)
|
||||||
|
{
|
||||||
|
if (input_selection == -1)
|
||||||
|
input_selection = input_cx;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
input_selection = -1;
|
||||||
|
|
||||||
|
// move cursor to previous word
|
||||||
|
if (ctrldown)
|
||||||
|
{
|
||||||
|
char *line = inputlines[inputline];
|
||||||
|
|
||||||
|
while (input_cx > 1 && line[input_cx - 1] == ' ')
|
||||||
|
input_cx--;
|
||||||
|
while (input_cx > 1 && line[input_cx - 1] != ' ')
|
||||||
|
input_cx--;
|
||||||
|
}
|
||||||
|
// move cursor left
|
||||||
|
else if (input_cx > 1)
|
||||||
|
input_cx--;
|
||||||
|
|
||||||
|
if (input_cx == input_selection)
|
||||||
|
input_selection = -1;
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (key == KEY_RIGHTARROW)
|
||||||
|
{
|
||||||
|
if (shiftdown)
|
||||||
|
{
|
||||||
|
if (input_selection == -1)
|
||||||
|
input_selection = input_cx;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
input_selection = -1;
|
||||||
|
|
||||||
|
// move cursor to next word
|
||||||
|
if (ctrldown)
|
||||||
|
{
|
||||||
|
char *line = inputlines[inputline];
|
||||||
|
|
||||||
|
while (line[input_cx] && line[input_cx] != ' ')
|
||||||
|
input_cx++;
|
||||||
|
while (line[input_cx] && line[input_cx] == ' ')
|
||||||
|
input_cx++;
|
||||||
|
}
|
||||||
|
// move cursor right
|
||||||
|
else if (inputlines[inputline][input_cx])
|
||||||
|
input_cx++;
|
||||||
|
|
||||||
|
if (input_cx == input_selection)
|
||||||
|
input_selection = -1;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -950,13 +1094,21 @@ boolean CON_Responder(event_t *ev)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// add key to cmd line here
|
// add key to cmd line here
|
||||||
if (input_cx < CON_MAXPROMPTCHARS)
|
if (strlen(inputlines[inputline]) < CON_MAXPROMPTCHARS - 1)
|
||||||
{
|
{
|
||||||
|
INT32 i, j;
|
||||||
|
char *line = inputlines[inputline];
|
||||||
|
|
||||||
if (key >= 'A' && key <= 'Z' && !shiftdown) //this is only really necessary for dedicated servers
|
if (key >= 'A' && key <= 'Z' && !shiftdown) //this is only really necessary for dedicated servers
|
||||||
key = key + 'a' - 'A';
|
key = key + 'a' - 'A';
|
||||||
|
|
||||||
inputlines[inputline][input_cx] = (char)key;
|
if (input_selection != -1)
|
||||||
inputlines[inputline][input_cx + 1] = 0;
|
CON_DeleteSelectedText();
|
||||||
|
|
||||||
|
for (i = strlen(line), j = i + 1; j > (INT32)input_cx; --i, --j)
|
||||||
|
line[j] = line[i];
|
||||||
|
|
||||||
|
line[input_cx] = (char)key;
|
||||||
input_cx++;
|
input_cx++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1246,6 +1398,7 @@ static void CON_DrawInput(void)
|
||||||
size_t c;
|
size_t c;
|
||||||
INT32 x, y;
|
INT32 x, y;
|
||||||
INT32 charwidth = (INT32)con_scalefactor << 3;
|
INT32 charwidth = (INT32)con_scalefactor << 3;
|
||||||
|
INT32 f = cv_constextsize.value | V_NOSCALESTART;
|
||||||
|
|
||||||
// input line scrolls left if it gets too long
|
// input line scrolls left if it gets too long
|
||||||
p = inputlines[inputline];
|
p = inputlines[inputline];
|
||||||
|
@ -1254,14 +1407,44 @@ static void CON_DrawInput(void)
|
||||||
|
|
||||||
y = con_curlines - 12 * con_scalefactor;
|
y = con_curlines - 12 * con_scalefactor;
|
||||||
|
|
||||||
for (c = 0, x = charwidth; c < con_width-11; c++, x += charwidth)
|
if (input_selection == -1)
|
||||||
V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
|
{
|
||||||
|
for (c = 0, x = charwidth; c < con_width-11; c++, x += charwidth)
|
||||||
|
V_DrawCharacter(x, y, p[c] | f, !cv_allcaps.value);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t selstart = min(input_cx, input_selection);
|
||||||
|
size_t selend = max(input_cx, input_selection);
|
||||||
|
|
||||||
|
for (c = 0, x = charwidth; c < selstart && c < con_width-11; c++, x += charwidth)
|
||||||
|
V_DrawCharacter(x, y, p[c] | f, !cv_allcaps.value);
|
||||||
|
|
||||||
|
f |= V_YELLOWMAP;
|
||||||
|
for (; c < selend && c < con_width-11; c++, x += charwidth)
|
||||||
|
V_DrawCharacter(x, y, p[c] | f, !cv_allcaps.value);
|
||||||
|
f &= ~V_YELLOWMAP;
|
||||||
|
|
||||||
|
for (; c < con_width-11; c++, x += charwidth)
|
||||||
|
V_DrawCharacter(x, y, p[c] | f, !cv_allcaps.value);
|
||||||
|
}
|
||||||
|
//for (c = 0, x = charwidth; c < con_width-11; c++, x += charwidth)
|
||||||
|
//V_DrawCharacter(x, y, p[c] | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
|
||||||
|
|
||||||
// draw the blinking cursor
|
// draw the blinking cursor
|
||||||
//
|
//
|
||||||
x = ((input_cx >= con_width-11) ? (INT32)(con_width-11) : (INT32)((input_cx + 1)) * charwidth);
|
x = ((input_cx >= con_width-11) ? (INT32)(con_width-11) : (INT32)((input_cx + 1)) * charwidth);
|
||||||
if (con_tick < 4)
|
if (con_tick < 4)
|
||||||
V_DrawCharacter(x, y, '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);
|
{
|
||||||
|
if (inputlines[inputline][input_cx])
|
||||||
|
//V_DrawCharacter(x - 2 * con_scalefactor, y, '|' | f, !cv_allcaps.value);
|
||||||
|
V_DrawCharacter(x, y + 2 * con_scalefactor, '_' | f, !cv_allcaps.value);
|
||||||
|
else
|
||||||
|
V_DrawCharacter(x, y, '_' | f, !cv_allcaps.value);
|
||||||
|
}
|
||||||
|
/*x = ((input_cx >= con_width-11) ? (INT32)(con_width-11) : (INT32)((input_cx + 1)) * charwidth);
|
||||||
|
if (con_tick < 4)
|
||||||
|
V_DrawCharacter(x, y, '_' | cv_constextsize.value | V_NOSCALESTART, !cv_allcaps.value);*/
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw the last lines of console text to the top of the screen
|
// draw the last lines of console text to the top of the screen
|
||||||
|
|
437
src/hu_stuff.c
437
src/hu_stuff.c
|
@ -73,6 +73,9 @@ patch_t *cred_font[CRED_FONTSIZE];
|
||||||
static player_t *plr;
|
static player_t *plr;
|
||||||
boolean chat_on; // entering a chat message?
|
boolean chat_on; // entering a chat message?
|
||||||
static char w_chat[HU_MAXMSGLEN];
|
static char w_chat[HU_MAXMSGLEN];
|
||||||
|
static size_t chat_pos; // position of the cursor in the chat
|
||||||
|
static INT32 chat_selection; // selection border in current input line, -1 if no selection
|
||||||
|
static boolean teamtalk = false;
|
||||||
static boolean headsupactive = false;
|
static boolean headsupactive = false;
|
||||||
boolean hu_showscores; // draw rankings
|
boolean hu_showscores; // draw rankings
|
||||||
static char hu_tick;
|
static char hu_tick;
|
||||||
|
@ -106,6 +109,7 @@ static patch_t *crosshair[HU_CROSSHAIRS]; // 3 precached crosshair graphics
|
||||||
static void HU_DrawRankings(void);
|
static void HU_DrawRankings(void);
|
||||||
static void HU_DrawCoopOverlay(void);
|
static void HU_DrawCoopOverlay(void);
|
||||||
static void HU_DrawNetplayCoopOverlay(void);
|
static void HU_DrawNetplayCoopOverlay(void);
|
||||||
|
static void HU_DeleteSelectedText(void);
|
||||||
|
|
||||||
//======================================================================
|
//======================================================================
|
||||||
// KEYBOARD LAYOUTS FOR ENTERING TEXT
|
// KEYBOARD LAYOUTS FOR ENTERING TEXT
|
||||||
|
@ -621,36 +625,183 @@ static void Got_Saycmd(UINT8 **p, INT32 playernum)
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
// Deletes selected text, assuming there is, and resets selection.
|
||||||
|
// Also sets the cursor to the correct position.
|
||||||
|
//
|
||||||
|
static void HU_DeleteSelectedText(void)
|
||||||
|
{
|
||||||
|
UINT32 i, j;
|
||||||
|
size_t selstart = min(chat_pos, chat_selection);
|
||||||
|
size_t selend = max(chat_pos, chat_selection);
|
||||||
|
|
||||||
|
for (i = selstart, j = selend; w_chat[j]; ++i, ++j)
|
||||||
|
w_chat[i] = w_chat[j];
|
||||||
|
while (w_chat[i])
|
||||||
|
w_chat[i++] = 0;
|
||||||
|
|
||||||
|
chat_pos = selstart;
|
||||||
|
chat_selection = -1;
|
||||||
|
}
|
||||||
|
|
||||||
// Handles key input and string input
|
// Handles key input and string input
|
||||||
//
|
//
|
||||||
static inline boolean HU_keyInChatString(char *s, char ch)
|
static inline void HU_keyInChatString(char *s, UINT32 key, boolean shiftdown, boolean ctrldown)
|
||||||
{
|
{
|
||||||
size_t l;
|
switch (key)
|
||||||
|
|
||||||
if ((ch >= HU_FONTSTART && ch <= HU_FONTEND && hu_font[ch-HU_FONTSTART])
|
|
||||||
|| ch == ' ') // Allow spaces, of course
|
|
||||||
{
|
{
|
||||||
l = strlen(s);
|
case KEY_ESCAPE:
|
||||||
if (l < HU_MAXMSGLEN - 1)
|
chat_on = false;
|
||||||
|
break;
|
||||||
|
case KEY_ENTER:
|
||||||
|
{
|
||||||
|
// send automatically the message (no more chat char)
|
||||||
|
char buf[2+256];
|
||||||
|
size_t ci = 2;
|
||||||
|
char *cp = w_chat;
|
||||||
|
|
||||||
|
while (*cp)
|
||||||
{
|
{
|
||||||
s[l++] = ch;
|
if (*cp >= ' ' && !(*cp & 0x80))
|
||||||
s[l]=0;
|
buf[ci++] = *cp;
|
||||||
return true;
|
cp++;
|
||||||
}
|
}
|
||||||
return false;
|
buf[ci] = 0;
|
||||||
}
|
|
||||||
else if (ch == KEY_BACKSPACE)
|
|
||||||
{
|
|
||||||
l = strlen(s);
|
|
||||||
if (l)
|
|
||||||
s[--l] = 0;
|
|
||||||
else
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
else if (ch != KEY_ENTER)
|
|
||||||
return false; // did not eat key
|
|
||||||
|
|
||||||
return true; // ate the key
|
// last minute mute check
|
||||||
|
if (cv_mute.value && !(server || adminplayer == consoleplayer))
|
||||||
|
{
|
||||||
|
CONS_Alert(CONS_NOTICE, M_GetText("The chat is muted. You can't say anything at the moment.\n"));
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (ci > 2) // don't send target+flags+empty message.
|
||||||
|
{
|
||||||
|
if (teamtalk)
|
||||||
|
buf[0] = -1; // target
|
||||||
|
else
|
||||||
|
buf[0] = 0; // target
|
||||||
|
buf[1] = 0; // flags
|
||||||
|
SendNetXCmd(XD_SAY, buf, 2 + strlen(&buf[2]) + 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
chat_on = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
// cursor moving
|
||||||
|
case KEY_LEFTARROW:
|
||||||
|
case KEY_RIGHTARROW:
|
||||||
|
case KEY_HOME:
|
||||||
|
case KEY_END:
|
||||||
|
if (shiftdown)
|
||||||
|
{
|
||||||
|
if (chat_selection == -1)
|
||||||
|
chat_selection = chat_pos;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
chat_selection = -1;
|
||||||
|
|
||||||
|
switch (key)
|
||||||
|
{
|
||||||
|
case KEY_LEFTARROW:
|
||||||
|
// move cursor to previous word
|
||||||
|
if (ctrldown)
|
||||||
|
{
|
||||||
|
while (chat_pos > 0 && w_chat[chat_pos - 1] == ' ')
|
||||||
|
chat_pos--;
|
||||||
|
while (chat_pos > 0 && w_chat[chat_pos - 1] != ' ')
|
||||||
|
chat_pos--;
|
||||||
|
}
|
||||||
|
// move cursor left
|
||||||
|
else if (chat_pos > 0)
|
||||||
|
chat_pos--;
|
||||||
|
break;
|
||||||
|
case KEY_RIGHTARROW:
|
||||||
|
// move cursor to next word
|
||||||
|
if (ctrldown)
|
||||||
|
{
|
||||||
|
while (w_chat[chat_pos] && w_chat[chat_pos] != ' ')
|
||||||
|
chat_pos++;
|
||||||
|
while (w_chat[chat_pos] && w_chat[chat_pos] == ' ')
|
||||||
|
chat_pos++;
|
||||||
|
}
|
||||||
|
// move cursor right
|
||||||
|
else if (w_chat[chat_pos])
|
||||||
|
chat_pos++;
|
||||||
|
break;
|
||||||
|
case KEY_HOME:
|
||||||
|
chat_pos = 0;
|
||||||
|
break;
|
||||||
|
case KEY_END:
|
||||||
|
chat_pos = strlen(w_chat);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (chat_pos == chat_selection)
|
||||||
|
chat_selection = -1;
|
||||||
|
break;
|
||||||
|
// backspace or delete selected text
|
||||||
|
case KEY_BACKSPACE:
|
||||||
|
if (chat_selection == -1)
|
||||||
|
{
|
||||||
|
if (chat_pos > 0)
|
||||||
|
{
|
||||||
|
UINT32 i, j;
|
||||||
|
for (i = chat_pos - 1, j = chat_pos; w_chat[j]; ++i, ++j)
|
||||||
|
w_chat[i] = w_chat[j];
|
||||||
|
w_chat[i] = 0;
|
||||||
|
chat_pos--;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
HU_DeleteSelectedText();
|
||||||
|
break;
|
||||||
|
// delete character under cursor
|
||||||
|
case KEY_DEL:
|
||||||
|
if (chat_selection == -1)
|
||||||
|
{
|
||||||
|
UINT32 i, j;
|
||||||
|
|
||||||
|
for (i = chat_pos, j = chat_pos + 1; w_chat[j]; ++i, ++j)
|
||||||
|
w_chat[i] = w_chat[j];
|
||||||
|
w_chat[i] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
HU_DeleteSelectedText();
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
// allow people to use keypad in chat
|
||||||
|
if (key >= KEY_KEYPAD7 && key <= KEY_KPADDEL)
|
||||||
|
{
|
||||||
|
XBOXSTATIC char keypad_translation[] = {'7','8','9','-',
|
||||||
|
'4','5','6','+',
|
||||||
|
'1','2','3',
|
||||||
|
'0','.'};
|
||||||
|
|
||||||
|
key = keypad_translation[key - KEY_KEYPAD7];
|
||||||
|
}
|
||||||
|
else if (key == KEY_KPADSLASH)
|
||||||
|
key = '/';
|
||||||
|
|
||||||
|
// use console translations
|
||||||
|
if (shiftdown)
|
||||||
|
key = shiftxform[key];
|
||||||
|
|
||||||
|
if ((key >= HU_FONTSTART && key <= HU_FONTEND && hu_font[key-HU_FONTSTART])
|
||||||
|
|| key == ' ') // Allow spaces, of course
|
||||||
|
{
|
||||||
|
if (strlen(w_chat) < HU_MAXMSGLEN - 1)
|
||||||
|
{
|
||||||
|
UINT32 i, j;
|
||||||
|
|
||||||
|
if (chat_selection != -1)
|
||||||
|
HU_DeleteSelectedText();
|
||||||
|
|
||||||
|
for (i = strlen(w_chat), j = i + 1; j > chat_pos; --i, --j)
|
||||||
|
w_chat[j] = w_chat[i];
|
||||||
|
w_chat[chat_pos] = (char)key;
|
||||||
|
chat_pos++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//
|
//
|
||||||
|
@ -669,86 +820,9 @@ void HU_Ticker(void)
|
||||||
hu_showscores = false;
|
hu_showscores = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define QUEUESIZE 256
|
// REMOVE? Now this has become pretty useless IMO
|
||||||
|
|
||||||
static boolean teamtalk = false;
|
|
||||||
static char chatchars[QUEUESIZE];
|
|
||||||
static INT32 head = 0, tail = 0;
|
|
||||||
|
|
||||||
//
|
|
||||||
// HU_dequeueChatChar
|
|
||||||
//
|
|
||||||
char HU_dequeueChatChar(void)
|
|
||||||
{
|
|
||||||
char c;
|
|
||||||
|
|
||||||
if (head != tail)
|
|
||||||
{
|
|
||||||
c = chatchars[tail];
|
|
||||||
tail = (tail + 1) & (QUEUESIZE-1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
c = 0;
|
|
||||||
|
|
||||||
return c;
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
//
|
|
||||||
static void HU_queueChatChar(char c)
|
|
||||||
{
|
|
||||||
// send automaticly the message (no more chat char)
|
|
||||||
if (c == KEY_ENTER)
|
|
||||||
{
|
|
||||||
char buf[2+256];
|
|
||||||
size_t ci = 2;
|
|
||||||
|
|
||||||
do {
|
|
||||||
c = HU_dequeueChatChar();
|
|
||||||
if (!c || (c >= ' ' && !(c & 0x80))) // copy printable characters and terminating '\0' only.
|
|
||||||
buf[ci++]=c;
|
|
||||||
} while (c);
|
|
||||||
|
|
||||||
// last minute mute check
|
|
||||||
if (cv_mute.value && !(server || adminplayer == consoleplayer))
|
|
||||||
{
|
|
||||||
CONS_Alert(CONS_NOTICE, M_GetText("The chat is muted. You can't say anything at the moment.\n"));
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ci > 3) // don't send target+flags+empty message.
|
|
||||||
{
|
|
||||||
if (teamtalk)
|
|
||||||
buf[0] = -1; // target
|
|
||||||
else
|
|
||||||
buf[0] = 0; // target
|
|
||||||
buf[1] = 0; // flags
|
|
||||||
SendNetXCmd(XD_SAY, buf, 2 + strlen(&buf[2]) + 1);
|
|
||||||
}
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (((head + 1) & (QUEUESIZE-1)) == tail)
|
|
||||||
CONS_Printf(M_GetText("[Message unsent]\n")); // message not sent
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (c == KEY_BACKSPACE)
|
|
||||||
{
|
|
||||||
if (tail != head)
|
|
||||||
head = (head - 1) & (QUEUESIZE-1);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
chatchars[head] = c;
|
|
||||||
head = (head + 1) & (QUEUESIZE-1);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void HU_clearChatChars(void)
|
void HU_clearChatChars(void)
|
||||||
{
|
{
|
||||||
while (tail != head)
|
|
||||||
HU_queueChatChar(KEY_BACKSPACE);
|
|
||||||
chat_on = false;
|
chat_on = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -758,13 +832,19 @@ void HU_clearChatChars(void)
|
||||||
boolean HU_Responder(event_t *ev)
|
boolean HU_Responder(event_t *ev)
|
||||||
{
|
{
|
||||||
static boolean shiftdown = false;
|
static boolean shiftdown = false;
|
||||||
UINT8 c;
|
static boolean ctrldown = false;
|
||||||
|
INT32 key = ev->data1; // only valid if ev->type is a key event
|
||||||
|
|
||||||
if (ev->data1 == KEY_LSHIFT || ev->data1 == KEY_RSHIFT)
|
if (key == KEY_LSHIFT || key == KEY_RSHIFT)
|
||||||
{
|
{
|
||||||
shiftdown = (ev->type == ev_keydown);
|
shiftdown = (ev->type == ev_keydown);
|
||||||
return chat_on;
|
return chat_on;
|
||||||
}
|
}
|
||||||
|
else if (key == KEY_LCTRL || key == KEY_RCTRL)
|
||||||
|
{
|
||||||
|
ctrldown = (ev->type == ev_keydown);
|
||||||
|
return chat_on;
|
||||||
|
}
|
||||||
|
|
||||||
if (ev->type != ev_keydown)
|
if (ev->type != ev_keydown)
|
||||||
return false;
|
return false;
|
||||||
|
@ -774,42 +854,36 @@ boolean HU_Responder(event_t *ev)
|
||||||
if (!chat_on)
|
if (!chat_on)
|
||||||
{
|
{
|
||||||
// enter chat mode
|
// enter chat mode
|
||||||
if ((ev->data1 == gamecontrol[gc_talkkey][0] || ev->data1 == gamecontrol[gc_talkkey][1])
|
if ((key == gamecontrol[gc_talkkey][0] || key == gamecontrol[gc_talkkey][1])
|
||||||
&& netgame && (!cv_mute.value || server || (adminplayer == consoleplayer)))
|
&& netgame && (!cv_mute.value || server || (adminplayer == consoleplayer)))
|
||||||
{
|
{
|
||||||
if (cv_mute.value && !(server || adminplayer == consoleplayer))
|
// we already checked for this two lines before...
|
||||||
return false;
|
//if (cv_mute.value && !(server || adminplayer == consoleplayer))
|
||||||
|
//return false;
|
||||||
chat_on = true;
|
chat_on = true;
|
||||||
w_chat[0] = 0;
|
w_chat[0] = 0;
|
||||||
|
chat_pos = 0;
|
||||||
|
chat_selection = -1;
|
||||||
teamtalk = false;
|
teamtalk = false;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
if ((ev->data1 == gamecontrol[gc_teamkey][0] || ev->data1 == gamecontrol[gc_teamkey][1])
|
if ((key == gamecontrol[gc_teamkey][0] || key == gamecontrol[gc_teamkey][1])
|
||||||
&& netgame && (!cv_mute.value || server || (adminplayer == consoleplayer)))
|
&& netgame && (!cv_mute.value || server || (adminplayer == consoleplayer)))
|
||||||
{
|
{
|
||||||
if (cv_mute.value && !(server || adminplayer == consoleplayer))
|
// we already checked for this two lines before...
|
||||||
return false;
|
//if (cv_mute.value && !(server || adminplayer == consoleplayer))
|
||||||
|
//return false;
|
||||||
chat_on = true;
|
chat_on = true;
|
||||||
w_chat[0] = 0;
|
w_chat[0] = 0;
|
||||||
|
chat_pos = 0;
|
||||||
|
chat_selection = -1;
|
||||||
teamtalk = true;
|
teamtalk = true;
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else // if chat_on
|
else // if chat_on
|
||||||
{
|
{
|
||||||
c = (UINT8)ev->data1;
|
HU_keyInChatString(w_chat, key, shiftdown, ctrldown);
|
||||||
|
|
||||||
// use console translations
|
|
||||||
if (shiftdown)
|
|
||||||
c = shiftxform[c];
|
|
||||||
|
|
||||||
if (HU_keyInChatString(w_chat,c))
|
|
||||||
HU_queueChatChar(c);
|
|
||||||
if (c == KEY_ENTER)
|
|
||||||
chat_on = false;
|
|
||||||
else if (c == KEY_ESCAPE)
|
|
||||||
chat_on = false;
|
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
|
@ -826,7 +900,7 @@ boolean HU_Responder(event_t *ev)
|
||||||
//
|
//
|
||||||
static void HU_DrawChat(void)
|
static void HU_DrawChat(void)
|
||||||
{
|
{
|
||||||
INT32 t = 0, c = 0, y = HU_INPUTY;
|
INT32 t = 0, f = 0, c = 0, y = HU_INPUTY;
|
||||||
size_t i = 0;
|
size_t i = 0;
|
||||||
const char *ntalk = "Say: ", *ttalk = "Say-Team: ";
|
const char *ntalk = "Say: ", *ttalk = "Say-Team: ";
|
||||||
const char *talk = ntalk;
|
const char *talk = ntalk;
|
||||||
|
@ -844,6 +918,8 @@ static void HU_DrawChat(void)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f = cv_constextsize.value | V_NOSCALESTART;
|
||||||
|
|
||||||
while (talk[i])
|
while (talk[i])
|
||||||
{
|
{
|
||||||
if (talk[i] < HU_FONTSTART)
|
if (talk[i] < HU_FONTSTART)
|
||||||
|
@ -854,36 +930,123 @@ static void HU_DrawChat(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, !cv_allcaps.value);
|
V_DrawCharacter(HU_INPUTX + c, y, talk[i++] | f, !cv_allcaps.value);
|
||||||
}
|
}
|
||||||
c += charwidth;
|
c += charwidth;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
f |= t;
|
||||||
i = 0;
|
i = 0;
|
||||||
while (w_chat[i])
|
if (chat_selection == -1)
|
||||||
{
|
{
|
||||||
//Hurdler: isn't it better like that?
|
while (w_chat[i])
|
||||||
if (w_chat[i] < HU_FONTSTART)
|
|
||||||
{
|
{
|
||||||
++i;
|
//Hurdler: isn't it better like that?
|
||||||
//charwidth = 4 * con_scalefactor;
|
if (w_chat[i] < HU_FONTSTART)
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
//charwidth = 4 * con_scalefactor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor;
|
||||||
|
V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | f, !cv_allcaps.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
c += charwidth;
|
||||||
|
if (c >= vid.width)
|
||||||
|
{
|
||||||
|
c = 0;
|
||||||
|
y += charheight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
size_t selstart = min(chat_pos, chat_selection);
|
||||||
|
size_t selend = max(chat_pos, chat_selection);
|
||||||
|
|
||||||
|
while (i < selstart)
|
||||||
{
|
{
|
||||||
//charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor;
|
//Hurdler: isn't it better like that?
|
||||||
V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | cv_constextsize.value | V_NOSCALESTART | t, !cv_allcaps.value);
|
if (w_chat[i] < HU_FONTSTART)
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
//charwidth = 4 * con_scalefactor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor;
|
||||||
|
V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | f, !cv_allcaps.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
c += charwidth;
|
||||||
|
if (c >= vid.width)
|
||||||
|
{
|
||||||
|
c = 0;
|
||||||
|
y += charheight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
c += charwidth;
|
f &= ~t;
|
||||||
if (c >= vid.width)
|
f |= V_YELLOWMAP;
|
||||||
|
while (i < selend)
|
||||||
{
|
{
|
||||||
c = 0;
|
//Hurdler: isn't it better like that?
|
||||||
y += charheight;
|
if (w_chat[i] < HU_FONTSTART)
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
//charwidth = 4 * con_scalefactor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor;
|
||||||
|
V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | f, !cv_allcaps.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
c += charwidth;
|
||||||
|
if (c >= vid.width)
|
||||||
|
{
|
||||||
|
c = 0;
|
||||||
|
y += charheight;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
f &= ~V_YELLOWMAP;
|
||||||
|
f |= t;
|
||||||
|
|
||||||
|
while (w_chat[i])
|
||||||
|
{
|
||||||
|
//Hurdler: isn't it better like that?
|
||||||
|
if (w_chat[i] < HU_FONTSTART)
|
||||||
|
{
|
||||||
|
++i;
|
||||||
|
//charwidth = 4 * con_scalefactor;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
//charwidth = SHORT(hu_font[w_chat[i]-HU_FONTSTART]->width) * con_scalefactor;
|
||||||
|
V_DrawCharacter(HU_INPUTX + c, y, w_chat[i++] | f, !cv_allcaps.value);
|
||||||
|
}
|
||||||
|
|
||||||
|
c += charwidth;
|
||||||
|
if (c >= vid.width)
|
||||||
|
{
|
||||||
|
c = 0;
|
||||||
|
y += charheight;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hu_tick < 4)
|
if (hu_tick < 4)
|
||||||
V_DrawCharacter(HU_INPUTX + c, y, '_' | cv_constextsize.value |V_NOSCALESTART|t, !cv_allcaps.value);
|
{
|
||||||
|
if (w_chat[chat_pos])
|
||||||
|
{
|
||||||
|
i = (strlen(talk) + chat_pos) * charwidth;
|
||||||
|
c = i % vid.width;
|
||||||
|
y = HU_INPUTY + i / vid.width * charheight + 2 * con_scalefactor;
|
||||||
|
}
|
||||||
|
V_DrawCharacter(HU_INPUTX + c, y, '_' | f, !cv_allcaps.value);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -93,7 +93,6 @@ boolean HU_Responder(event_t *ev);
|
||||||
|
|
||||||
void HU_Ticker(void);
|
void HU_Ticker(void);
|
||||||
void HU_Drawer(void);
|
void HU_Drawer(void);
|
||||||
char HU_dequeueChatChar(void);
|
|
||||||
void HU_Erase(void);
|
void HU_Erase(void);
|
||||||
void HU_clearChatChars(void);
|
void HU_clearChatChars(void);
|
||||||
void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer);
|
void HU_DrawTabRankings(INT32 x, INT32 y, playersort_t *tab, INT32 scorelines, INT32 whiteplayer);
|
||||||
|
|
Loading…
Reference in a new issue