mirror of
https://github.com/ZDoom/gzdoom-gles.git
synced 2024-11-24 13:11:33 +00:00
- made the chat input Unicode-capable.
Also changed this to use the console font because it is far better equipped with special characters than the small font.
This commit is contained in:
parent
d15e3391a0
commit
54cb16ad8e
1 changed files with 71 additions and 55 deletions
126
src/ct_chat.cpp
126
src/ct_chat.cpp
|
@ -39,14 +39,13 @@
|
||||||
#include "d_event.h"
|
#include "d_event.h"
|
||||||
#include "sbar.h"
|
#include "sbar.h"
|
||||||
#include "v_video.h"
|
#include "v_video.h"
|
||||||
|
#include "utf8.h"
|
||||||
|
|
||||||
#define QUEUESIZE 128
|
enum
|
||||||
#define MESSAGESIZE 128
|
{
|
||||||
#define MESSAGELEN 265
|
QUEUESIZE = 128
|
||||||
#define HU_INPUTX 0
|
};
|
||||||
#define HU_INPUTY (0 + (screen->Font->GetHeight () + 1))
|
|
||||||
|
|
||||||
void CT_PasteChat(const char *clip);
|
|
||||||
|
|
||||||
EXTERN_CVAR (Int, con_scaletext)
|
EXTERN_CVAR (Int, con_scaletext)
|
||||||
|
|
||||||
|
@ -61,19 +60,20 @@ int active_con_scaletext();
|
||||||
void CT_Init ();
|
void CT_Init ();
|
||||||
void CT_Drawer ();
|
void CT_Drawer ();
|
||||||
bool CT_Responder (event_t *ev);
|
bool CT_Responder (event_t *ev);
|
||||||
|
void CT_PasteChat(const char *clip);
|
||||||
|
|
||||||
int chatmodeon;
|
int chatmodeon;
|
||||||
|
|
||||||
// Private data
|
// Private data
|
||||||
|
|
||||||
static void CT_ClearChatMessage ();
|
static void CT_ClearChatMessage ();
|
||||||
static void CT_AddChar (char c);
|
static void CT_AddChar (int c);
|
||||||
static void CT_BackSpace ();
|
static void CT_BackSpace ();
|
||||||
static void ShoveChatStr (const char *str, uint8_t who);
|
static void ShoveChatStr (const char *str, uint8_t who);
|
||||||
static bool DoSubstitution (FString &out, const char *in);
|
static bool DoSubstitution (FString &out, const char *in);
|
||||||
|
|
||||||
static int len;
|
static int CharLen;
|
||||||
static uint8_t ChatQueue[QUEUESIZE];
|
static TArray<uint8_t> ChatQueue;
|
||||||
|
|
||||||
CVAR (String, chatmacro1, "I'm ready to kick butt!", CVAR_ARCHIVE)
|
CVAR (String, chatmacro1, "I'm ready to kick butt!", CVAR_ARCHIVE)
|
||||||
CVAR (String, chatmacro2, "I'm OK.", CVAR_ARCHIVE)
|
CVAR (String, chatmacro2, "I'm OK.", CVAR_ARCHIVE)
|
||||||
|
@ -111,9 +111,10 @@ CVAR (Bool, chat_substitution, false, CVAR_ARCHIVE)
|
||||||
|
|
||||||
void CT_Init ()
|
void CT_Init ()
|
||||||
{
|
{
|
||||||
len = 0; // initialize the queue index
|
ChatQueue.Clear();
|
||||||
|
ChatQueue.Push(0);
|
||||||
|
CharLen = 0;
|
||||||
chatmodeon = 0;
|
chatmodeon = 0;
|
||||||
ChatQueue[0] = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -141,7 +142,7 @@ bool CT_Responder (event_t *ev)
|
||||||
{
|
{
|
||||||
if (ev->data1 == '\r')
|
if (ev->data1 == '\r')
|
||||||
{
|
{
|
||||||
ShoveChatStr ((char *)ChatQueue, chatmodeon - 1);
|
ShoveChatStr ((char *)ChatQueue.Data(), chatmodeon - 1);
|
||||||
CT_Stop ();
|
CT_Stop ();
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -161,7 +162,7 @@ bool CT_Responder (event_t *ev)
|
||||||
else if (ev->data1 == 'C' && (ev->data3 & GKM_CTRL))
|
else if (ev->data1 == 'C' && (ev->data3 & GKM_CTRL))
|
||||||
#endif // __APPLE__
|
#endif // __APPLE__
|
||||||
{
|
{
|
||||||
I_PutInClipboard ((char *)ChatQueue);
|
I_PutInClipboard ((char *)ChatQueue.Data());
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
@ -183,7 +184,7 @@ bool CT_Responder (event_t *ev)
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
CT_AddChar (char(ev->data1));
|
CT_AddChar (ev->data1);
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
@ -206,16 +207,17 @@ bool CT_Responder (event_t *ev)
|
||||||
|
|
||||||
void CT_PasteChat(const char *clip)
|
void CT_PasteChat(const char *clip)
|
||||||
{
|
{
|
||||||
if (clip != NULL && *clip != '\0')
|
if (clip != nullptr && *clip != '\0')
|
||||||
{
|
{
|
||||||
|
auto p = (const uint8_t *)clip;
|
||||||
// Only paste the first line.
|
// Only paste the first line.
|
||||||
while (*clip != '\0')
|
while (auto chr = GetCharFromString(p))
|
||||||
{
|
{
|
||||||
if (*clip == '\n' || *clip == '\r' || *clip == '\b')
|
if (chr == '\n' || chr == '\r' || chr == '\b')
|
||||||
{
|
{
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
CT_AddChar (*clip++);
|
CT_AddChar (chr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -228,10 +230,11 @@ void CT_PasteChat(const char *clip)
|
||||||
|
|
||||||
void CT_Drawer (void)
|
void CT_Drawer (void)
|
||||||
{
|
{
|
||||||
|
FFont *displayfont = ConFont;
|
||||||
if (chatmodeon)
|
if (chatmodeon)
|
||||||
{
|
{
|
||||||
static const char *prompt = "Say: ";
|
static const char *prompt = "Say: ";
|
||||||
int i, x, scalex, y, promptwidth;
|
int x, scalex, y, promptwidth;
|
||||||
|
|
||||||
y = (viewactive || gamestate != GS_LEVEL) ? -10 : -30;
|
y = (viewactive || gamestate != GS_LEVEL) ? -10 : -30;
|
||||||
|
|
||||||
|
@ -243,33 +246,28 @@ void CT_Drawer (void)
|
||||||
|
|
||||||
y += ((SCREENHEIGHT == viewheight && viewactive) || gamestate != GS_LEVEL) ? screen_height : st_y;
|
y += ((SCREENHEIGHT == viewheight && viewactive) || gamestate != GS_LEVEL) ? screen_height : st_y;
|
||||||
|
|
||||||
promptwidth = SmallFont->StringWidth (prompt) * scalex;
|
promptwidth = displayfont->StringWidth (prompt) * scalex;
|
||||||
x = SmallFont->GetCharWidth ('_') * scalex * 2 + promptwidth;
|
x = displayfont->GetCharWidth (displayfont->GetCursor()) * scalex * 2 + promptwidth;
|
||||||
|
|
||||||
// figure out if the text is wider than the screen->
|
// figure out if the text is wider than the screen
|
||||||
// if so, only draw the right-most portion of it.
|
// if so, only draw the right-most portion of it.
|
||||||
for (i = len - 1; i >= 0 && x < screen_width; i--)
|
const uint8_t *textp = ChatQueue.Data();
|
||||||
|
while(*textp)
|
||||||
{
|
{
|
||||||
x += SmallFont->GetCharWidth (ChatQueue[i] & 0x7f) * scalex;
|
auto textw = displayfont->StringWidth(textp);
|
||||||
}
|
if (x + textw * scalex < screen_width) break;
|
||||||
|
GetCharFromString(textp);
|
||||||
if (i >= 0)
|
|
||||||
{
|
|
||||||
i++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
i = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// draw the prompt, text, and cursor
|
// draw the prompt, text, and cursor
|
||||||
ChatQueue[len] = SmallFont->GetCursor();
|
ChatQueue.Last() = displayfont->GetCursor();
|
||||||
ChatQueue[len+1] = '\0';
|
ChatQueue.Push(0);
|
||||||
screen->DrawText (SmallFont, CR_GREEN, 0, y, prompt,
|
screen->DrawText (displayfont, CR_GREEN, 0, y, prompt,
|
||||||
DTA_VirtualWidth, screen_width, DTA_VirtualHeight, screen_height, DTA_KeepRatio, true, TAG_DONE);
|
DTA_VirtualWidth, screen_width, DTA_VirtualHeight, screen_height, DTA_KeepRatio, true, TAG_DONE);
|
||||||
screen->DrawText (SmallFont, CR_GREY, promptwidth, y, (char *)(ChatQueue + i),
|
screen->DrawText (displayfont, CR_GREY, promptwidth, y, (const char *)textp,
|
||||||
DTA_VirtualWidth, screen_width, DTA_VirtualHeight, screen_height, DTA_KeepRatio, true, TAG_DONE);
|
DTA_VirtualWidth, screen_width, DTA_VirtualHeight, screen_height, DTA_KeepRatio, true, TAG_DONE);
|
||||||
ChatQueue[len] = '\0';
|
ChatQueue.Pop();
|
||||||
|
ChatQueue.Last() = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (players[consoleplayer].camera != NULL &&
|
if (players[consoleplayer].camera != NULL &&
|
||||||
|
@ -289,12 +287,22 @@ void CT_Drawer (void)
|
||||||
//
|
//
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
|
||||||
static void CT_AddChar (char c)
|
static void CT_AddChar (int c)
|
||||||
{
|
{
|
||||||
if (len < QUEUESIZE-2)
|
if (CharLen < QUEUESIZE-2)
|
||||||
{
|
{
|
||||||
ChatQueue[len++] = c;
|
int size;
|
||||||
ChatQueue[len] = 0;
|
uint8_t encode[4];
|
||||||
|
ChatQueue.Pop();
|
||||||
|
if (utf8_encode(c, encode, &size) == 0)
|
||||||
|
{
|
||||||
|
for (int i = 0; i < size; i++)
|
||||||
|
{
|
||||||
|
ChatQueue.Push(encode[i]);
|
||||||
|
}
|
||||||
|
CharLen++;
|
||||||
|
}
|
||||||
|
ChatQueue.Push(0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -307,9 +315,13 @@ static void CT_AddChar (char c)
|
||||||
|
|
||||||
static void CT_BackSpace ()
|
static void CT_BackSpace ()
|
||||||
{
|
{
|
||||||
if (len)
|
if (CharLen)
|
||||||
{
|
{
|
||||||
ChatQueue[--len] = 0;
|
int endpos = ChatQueue.Size() - 2;
|
||||||
|
while (endpos > 0 && ChatQueue[endpos] >= 0x80 && ChatQueue[endpos] < 0xc0) endpos--;
|
||||||
|
ChatQueue[endpos] = 0;
|
||||||
|
ChatQueue.Clamp(endpos + 1);
|
||||||
|
CharLen--;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -322,8 +334,12 @@ static void CT_BackSpace ()
|
||||||
|
|
||||||
static void CT_ClearChatMessage ()
|
static void CT_ClearChatMessage ()
|
||||||
{
|
{
|
||||||
ChatQueue[0] = 0;
|
if (ChatQueue.Size() > 1)
|
||||||
len = 0;
|
{
|
||||||
|
ChatQueue.Clamp(1);
|
||||||
|
ChatQueue[0] = 0;
|
||||||
|
CharLen = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//===========================================================================
|
//===========================================================================
|
||||||
|
@ -355,11 +371,11 @@ static void ShoveChatStr (const char *str, uint8_t who)
|
||||||
|
|
||||||
if (!chat_substitution || !DoSubstitution (substBuff, str))
|
if (!chat_substitution || !DoSubstitution (substBuff, str))
|
||||||
{
|
{
|
||||||
Net_WriteString (str);
|
Net_WriteString(MakeUTF8(str));
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Net_WriteString (substBuff);
|
Net_WriteString(MakeUTF8(substBuff));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -392,9 +408,9 @@ static bool DoSubstitution (FString &out, const char *in)
|
||||||
++b;
|
++b;
|
||||||
}
|
}
|
||||||
|
|
||||||
ptrdiff_t len = b - a;
|
ptrdiff_t ByteLen = b - a;
|
||||||
|
|
||||||
if (len == 6)
|
if (ByteLen == 6)
|
||||||
{
|
{
|
||||||
if (strnicmp(a, "health", 6) == 0)
|
if (strnicmp(a, "health", 6) == 0)
|
||||||
{
|
{
|
||||||
|
@ -412,7 +428,7 @@ static bool DoSubstitution (FString &out, const char *in)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (len == 5)
|
else if (ByteLen == 5)
|
||||||
{
|
{
|
||||||
if (strnicmp(a, "armor", 5) == 0)
|
if (strnicmp(a, "armor", 5) == 0)
|
||||||
{
|
{
|
||||||
|
@ -420,7 +436,7 @@ static bool DoSubstitution (FString &out, const char *in)
|
||||||
out.AppendFormat("%d", armor != NULL ? armor->IntVar(NAME_Amount) : 0);
|
out.AppendFormat("%d", armor != NULL ? armor->IntVar(NAME_Amount) : 0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (len == 9)
|
else if (ByteLen == 9)
|
||||||
{
|
{
|
||||||
if (strnicmp(a, "ammocount", 9) == 0)
|
if (strnicmp(a, "ammocount", 9) == 0)
|
||||||
{
|
{
|
||||||
|
@ -438,7 +454,7 @@ static bool DoSubstitution (FString &out, const char *in)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (len == 4)
|
else if (ByteLen == 4)
|
||||||
{
|
{
|
||||||
if (strnicmp(a, "ammo", 4) == 0)
|
if (strnicmp(a, "ammo", 4) == 0)
|
||||||
{
|
{
|
||||||
|
@ -456,7 +472,7 @@ static bool DoSubstitution (FString &out, const char *in)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (len == 0)
|
else if (ByteLen == 0)
|
||||||
{
|
{
|
||||||
out += '$';
|
out += '$';
|
||||||
if (*b == '$')
|
if (*b == '$')
|
||||||
|
@ -467,7 +483,7 @@ static bool DoSubstitution (FString &out, const char *in)
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
out += '$';
|
out += '$';
|
||||||
out.AppendCStrPart(a, len);
|
out.AppendCStrPart(a, ByteLen);
|
||||||
}
|
}
|
||||||
a = b;
|
a = b;
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue