fixed up sort ordering to be more correct.
drawstrings now tint the string, and should now work as expected with ^3 colours. tweaked qcc's utf-8 parsing. utf-8 chars are now valid in identifiers. invalid chars (like pesky nbsp) are more verbose, and can actually be found. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4667 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
23dc0cbe21
commit
faae661e9e
8 changed files with 402 additions and 112 deletions
|
@ -138,7 +138,17 @@ static qboolean SL_TitlesKey (menucustom_t *ths, menu_t *menu, int key)
|
|||
if (sortkey == SLKEY_ADDRESS)
|
||||
return true;
|
||||
|
||||
Master_SetSortField(sortkey, Master_GetSortField()!=sortkey||!Master_GetSortDescending());
|
||||
switch(sortkey)
|
||||
{
|
||||
case SLKEY_NUMPLAYERS:
|
||||
//favour descending order (low first)
|
||||
Master_SetSortField(sortkey, Master_GetSortField()!=sortkey||!Master_GetSortDescending());
|
||||
break;
|
||||
default:
|
||||
//favour ascending order (low first)
|
||||
Master_SetSortField(sortkey, Master_GetSortField()==sortkey&&!Master_GetSortDescending());
|
||||
break;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -679,7 +689,7 @@ void M_Menu_ServerList2_f(void)
|
|||
|
||||
CalcFilters(menu);
|
||||
|
||||
Master_SetSortField(SLKEY_PING, true);
|
||||
Master_SetSortField(SLKEY_PING, false);
|
||||
|
||||
MasterInfo_Refresh();
|
||||
}
|
||||
|
|
|
@ -373,7 +373,7 @@ void Master_ShowServer(serverinfo_t *server)
|
|||
return;
|
||||
}
|
||||
|
||||
if (!decreasingorder)
|
||||
if (decreasingorder)
|
||||
{
|
||||
for (i = 0; i < numvisibleservers; i++)
|
||||
{
|
||||
|
|
|
@ -877,7 +877,12 @@ void QCBUILTIN PF_cvar_string (pubprogfuncs_t *prinst, struct globalvars_s *pr_g
|
|||
const char *str = PR_GetStringOfs(prinst, OFS_PARM0);
|
||||
cvar_t *cv = Cvar_Get(str, "", 0, "QC variables");
|
||||
if (cv)
|
||||
RETURN_CSTRING(cv->string);
|
||||
{
|
||||
if(cv->latched_string)
|
||||
RETURN_CSTRING(cv->latched_string);
|
||||
else
|
||||
RETURN_CSTRING(cv->string);
|
||||
}
|
||||
else
|
||||
G_INT(OFS_RETURN) = 0;
|
||||
}
|
||||
|
|
|
@ -253,6 +253,7 @@ static texid_t font_texture;
|
|||
static int font_colourmask;
|
||||
static byte_vec4_t font_forecolour;
|
||||
static byte_vec4_t font_backcolour;
|
||||
static vec4_t font_foretint;
|
||||
|
||||
static struct font_s *curfont;
|
||||
static float curfont_scale[2];
|
||||
|
@ -1618,14 +1619,18 @@ void Font_LineDraw(int x, int y, conchar_t *start, conchar_t *end)
|
|||
correct usage of this function thus requires calling this with 1111 before Font_EndString*/
|
||||
void Font_ForceColour(float r, float g, float b, float a)
|
||||
{
|
||||
if (font_foretint[0] == r && font_foretint[1] == b && font_foretint[2] == b && font_foretint[3] == a)
|
||||
return;
|
||||
|
||||
if (font_colourmask & CON_NONCLEARBG)
|
||||
Font_Flush();
|
||||
font_colourmask = CON_WHITEMASK;
|
||||
|
||||
font_forecolour[0] = r*255;
|
||||
font_forecolour[1] = g*255;
|
||||
font_forecolour[2] = b*255;
|
||||
font_forecolour[3] = a*255;
|
||||
font_foretint[0] = r;
|
||||
font_foretint[1] = g;
|
||||
font_foretint[2] = b;
|
||||
font_foretint[3] = a;
|
||||
Vector4Scale(font_foretint, 255, font_forecolour);
|
||||
|
||||
font_backcolour[3] = 0;
|
||||
|
||||
|
@ -1633,8 +1638,7 @@ void Font_ForceColour(float r, float g, float b, float a)
|
|||
}
|
||||
void Font_InvalidateColour(void)
|
||||
{
|
||||
Font_Flush();
|
||||
font_colourmask = ~0;
|
||||
Font_ForceColour(1,1,1,1);
|
||||
}
|
||||
|
||||
//draw a character from the current font at a pixel location.
|
||||
|
@ -1691,26 +1695,40 @@ int Font_DrawChar(int px, int py, unsigned int charcode)
|
|||
col = charcode & (CON_2NDCHARSETTEXT|CON_RICHFORECOLOUR|(0xfff<<CON_RICHBSHIFT));
|
||||
if (col != font_colourmask)
|
||||
{
|
||||
vec4_t rgba;
|
||||
if (font_colourmask & CON_NONCLEARBG)
|
||||
Font_Flush();
|
||||
font_colourmask = col;
|
||||
|
||||
font_forecolour[0] = ((col>>CON_RICHRSHIFT)&0xf)*0x11;
|
||||
font_forecolour[1] = ((col>>CON_RICHGSHIFT)&0xf)*0x11;
|
||||
font_forecolour[2] = ((col>>CON_RICHBSHIFT)&0xf)*0x11;
|
||||
font_forecolour[3] = 255;
|
||||
rgba[0] = ((col>>CON_RICHRSHIFT)&0xf)*0x11;
|
||||
rgba[1] = ((col>>CON_RICHGSHIFT)&0xf)*0x11;
|
||||
rgba[2] = ((col>>CON_RICHBSHIFT)&0xf)*0x11;
|
||||
rgba[3] = 255;
|
||||
|
||||
font_backcolour[0] = 0;
|
||||
font_backcolour[1] = 0;
|
||||
font_backcolour[2] = 0;
|
||||
font_backcolour[3] = 0;
|
||||
|
||||
if (charcode & CON_2NDCHARSETTEXT)
|
||||
{
|
||||
font_forecolour[0] = min(font_forecolour[0]*1.16, 255);
|
||||
font_forecolour[1] *= 0.54;
|
||||
font_forecolour[2] *= 0.41;
|
||||
rgba[0] *= font->alttint[0];
|
||||
rgba[1] *= font->alttint[1];
|
||||
rgba[2] *= font->alttint[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
rgba[0] *= font->tint[0];
|
||||
rgba[1] *= font->tint[1];
|
||||
rgba[2] *= font->tint[2];
|
||||
}
|
||||
rgba[0] *= font_foretint[0];
|
||||
rgba[1] *= font_foretint[1];
|
||||
rgba[2] *= font_foretint[2];
|
||||
rgba[3] *= font_foretint[3];
|
||||
font_forecolour[0] = min(rgba[0], 255);
|
||||
font_forecolour[1] = min(rgba[1], 255);
|
||||
font_forecolour[2] = min(rgba[2], 255);
|
||||
font_forecolour[3] = min(rgba[3], 255);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1718,15 +1736,16 @@ int Font_DrawChar(int px, int py, unsigned int charcode)
|
|||
col = charcode & (CON_2NDCHARSETTEXT|CON_NONCLEARBG|CON_BGMASK|CON_FGMASK|CON_HALFALPHA);
|
||||
if (col != font_colourmask)
|
||||
{
|
||||
vec4_t rgba;
|
||||
if ((col ^ font_colourmask) & CON_NONCLEARBG)
|
||||
Font_Flush();
|
||||
font_colourmask = col;
|
||||
|
||||
col = (charcode&CON_FGMASK)>>CON_FGSHIFT;
|
||||
font_forecolour[0] = consolecolours[col].fr*255;
|
||||
font_forecolour[1] = consolecolours[col].fg*255;
|
||||
font_forecolour[2] = consolecolours[col].fb*255;
|
||||
font_forecolour[3] = (charcode & CON_HALFALPHA)?127:255;
|
||||
rgba[0] = consolecolours[col].fr*255;
|
||||
rgba[1] = consolecolours[col].fg*255;
|
||||
rgba[2] = consolecolours[col].fb*255;
|
||||
rgba[3] = (charcode & CON_HALFALPHA)?127:255;
|
||||
|
||||
col = (charcode&CON_BGMASK)>>CON_BGSHIFT;
|
||||
font_backcolour[0] = consolecolours[col].fr*255;
|
||||
|
@ -1736,16 +1755,24 @@ int Font_DrawChar(int px, int py, unsigned int charcode)
|
|||
|
||||
if (charcode & CON_2NDCHARSETTEXT)
|
||||
{
|
||||
font_forecolour[0] = min(font_forecolour[0]*font->alttint[0], 255);
|
||||
font_forecolour[1] = min(font_forecolour[1]*font->alttint[1], 255);
|
||||
font_forecolour[2] = min(font_forecolour[2]*font->alttint[2], 255);
|
||||
rgba[0] *= font->alttint[0];
|
||||
rgba[1] *= font->alttint[1];
|
||||
rgba[2] *= font->alttint[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
font_forecolour[0] = min(font_forecolour[0]*font->tint[0], 255);
|
||||
font_forecolour[1] = min(font_forecolour[1]*font->tint[1], 255);
|
||||
font_forecolour[2] = min(font_forecolour[2]*font->tint[2], 255);
|
||||
rgba[0] *= font->tint[0];
|
||||
rgba[1] *= font->tint[1];
|
||||
rgba[2] *= font->tint[2];
|
||||
}
|
||||
rgba[0] *= font_foretint[0];
|
||||
rgba[1] *= font_foretint[1];
|
||||
rgba[2] *= font_foretint[2];
|
||||
rgba[3] *= font_foretint[3];
|
||||
font_forecolour[0] = min(rgba[0], 255);
|
||||
font_forecolour[1] = min(rgba[1], 255);
|
||||
font_forecolour[2] = min(rgba[2], 255);
|
||||
font_forecolour[3] = min(rgba[3], 255);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1873,14 +1900,15 @@ float Font_DrawScaleChar(float px, float py, unsigned int charcode)
|
|||
col = charcode & (CON_2NDCHARSETTEXT|CON_RICHFORECOLOUR|(0xfff<<CON_RICHBSHIFT));
|
||||
if (col != font_colourmask)
|
||||
{
|
||||
vec4_t rgba;
|
||||
if (font_backcolour[3])
|
||||
Font_Flush();
|
||||
font_colourmask = col;
|
||||
|
||||
font_forecolour[0] = ((col>>CON_RICHRSHIFT)&0xf)*0x11;
|
||||
font_forecolour[1] = ((col>>CON_RICHGSHIFT)&0xf)*0x11;
|
||||
font_forecolour[2] = ((col>>CON_RICHBSHIFT)&0xf)*0x11;
|
||||
font_forecolour[3] = 255;
|
||||
rgba[0] = ((col>>CON_RICHRSHIFT)&0xf)*0x11;
|
||||
rgba[1] = ((col>>CON_RICHGSHIFT)&0xf)*0x11;
|
||||
rgba[2] = ((col>>CON_RICHBSHIFT)&0xf)*0x11;
|
||||
rgba[3] = 255;
|
||||
|
||||
font_backcolour[0] = 0;
|
||||
font_backcolour[1] = 0;
|
||||
|
@ -1889,10 +1917,24 @@ float Font_DrawScaleChar(float px, float py, unsigned int charcode)
|
|||
|
||||
if (charcode & CON_2NDCHARSETTEXT)
|
||||
{
|
||||
font_forecolour[0] = min(font_forecolour[0]*1.16, 255);
|
||||
font_forecolour[1] *= 0.54;
|
||||
font_forecolour[2] *= 0.41;
|
||||
rgba[0] *= font->alttint[0];
|
||||
rgba[1] *= font->alttint[1];
|
||||
rgba[2] *= font->alttint[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
rgba[0] *= font->tint[0];
|
||||
rgba[1] *= font->tint[1];
|
||||
rgba[2] *= font->tint[2];
|
||||
}
|
||||
rgba[0] *= font_foretint[0];
|
||||
rgba[1] *= font_foretint[1];
|
||||
rgba[2] *= font_foretint[2];
|
||||
rgba[3] *= font_foretint[3];
|
||||
font_forecolour[0] = min(rgba[0], 255);
|
||||
font_forecolour[1] = min(rgba[1], 255);
|
||||
font_forecolour[2] = min(rgba[2], 255);
|
||||
font_forecolour[3] = min(rgba[3], 255);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -1900,15 +1942,16 @@ float Font_DrawScaleChar(float px, float py, unsigned int charcode)
|
|||
col = charcode & (CON_2NDCHARSETTEXT|CON_NONCLEARBG|CON_BGMASK|CON_FGMASK|CON_HALFALPHA);
|
||||
if (col != font_colourmask)
|
||||
{
|
||||
vec4_t rgba;
|
||||
if (font_backcolour[3] != ((charcode & CON_NONCLEARBG)?127:0))
|
||||
Font_Flush();
|
||||
font_colourmask = col;
|
||||
|
||||
col = (charcode&CON_FGMASK)>>CON_FGSHIFT;
|
||||
font_forecolour[0] = consolecolours[col].fr*255;
|
||||
font_forecolour[1] = consolecolours[col].fg*255;
|
||||
font_forecolour[2] = consolecolours[col].fb*255;
|
||||
font_forecolour[3] = (charcode & CON_HALFALPHA)?127:255;
|
||||
rgba[0] = consolecolours[col].fr*255;
|
||||
rgba[1] = consolecolours[col].fg*255;
|
||||
rgba[2] = consolecolours[col].fb*255;
|
||||
rgba[3] = (charcode & CON_HALFALPHA)?127:255;
|
||||
|
||||
col = (charcode&CON_BGMASK)>>CON_BGSHIFT;
|
||||
font_backcolour[0] = consolecolours[col].fr*255;
|
||||
|
@ -1918,16 +1961,24 @@ float Font_DrawScaleChar(float px, float py, unsigned int charcode)
|
|||
|
||||
if (charcode & CON_2NDCHARSETTEXT)
|
||||
{
|
||||
font_forecolour[0] = min(font_forecolour[0]*font->alttint[0], 255);
|
||||
font_forecolour[1] = min(font_forecolour[1]*font->alttint[1], 255);
|
||||
font_forecolour[2] = min(font_forecolour[2]*font->alttint[2], 255);
|
||||
rgba[0] *= font->alttint[0];
|
||||
rgba[1] *= font->alttint[1];
|
||||
rgba[2] *= font->alttint[2];
|
||||
}
|
||||
else
|
||||
{
|
||||
font_forecolour[0] = min(font_forecolour[0]*font->tint[0], 255);
|
||||
font_forecolour[1] = min(font_forecolour[1]*font->tint[1], 255);
|
||||
font_forecolour[2] = min(font_forecolour[2]*font->tint[2], 255);
|
||||
rgba[0] *= font->tint[0];
|
||||
rgba[1] *= font->tint[1];
|
||||
rgba[2] *= font->tint[2];
|
||||
}
|
||||
rgba[0] *= font_foretint[0];
|
||||
rgba[1] *= font_foretint[1];
|
||||
rgba[2] *= font_foretint[2];
|
||||
rgba[3] *= font_foretint[3];
|
||||
font_forecolour[0] = min(rgba[0], 255);
|
||||
font_forecolour[1] = min(rgba[1], 255);
|
||||
font_forecolour[2] = min(rgba[2], 255);
|
||||
font_forecolour[3] = min(rgba[3], 255);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -95,6 +95,8 @@ long ParseNum (char *str);
|
|||
char *QCC_COM_Parse (const char *data);
|
||||
char *QCC_COM_Parse2 (char *data);
|
||||
|
||||
unsigned int utf8_check(const void *in, unsigned int *value);
|
||||
|
||||
extern char qcc_token[1024];
|
||||
extern int qcc_eof;
|
||||
|
||||
|
|
|
@ -874,9 +874,54 @@ enum
|
|||
UTF32LE,
|
||||
UTF32BE,
|
||||
};
|
||||
|
||||
//return 0 if the input is not valid utf-8.
|
||||
unsigned int utf8_check(const void *in, unsigned int *value)
|
||||
{
|
||||
//uc is the output unicode char
|
||||
unsigned int uc = 0xfffdu; //replacement character
|
||||
const unsigned char *str = in;
|
||||
|
||||
if (!(*str & 0x80))
|
||||
{
|
||||
*value = *str;
|
||||
return 1;
|
||||
}
|
||||
else if ((*str & 0xe0) == 0xc0)
|
||||
{
|
||||
if ((str[1] & 0xc0) == 0x80)
|
||||
{
|
||||
*value = uc = ((str[0] & 0x1f)<<6) | (str[1] & 0x3f);
|
||||
if (!uc || uc >= (1u<<7)) //allow modified utf-8
|
||||
return 2;
|
||||
}
|
||||
}
|
||||
else if ((*str & 0xf0) == 0xe0)
|
||||
{
|
||||
if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80)
|
||||
{
|
||||
*value = uc = ((str[0] & 0x0f)<<12) | ((str[1] & 0x3f)<<6) | ((str[2] & 0x3f)<<0);
|
||||
if (uc >= (1u<<11))
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
else if ((*str & 0xf8) == 0xf0)
|
||||
{
|
||||
if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 && (str[3] & 0xc0) == 0x80)
|
||||
{
|
||||
*value = uc = ((str[0] & 0x07)<<18) | ((str[1] & 0x3f)<<12) | ((str[2] & 0x3f)<<6) | ((str[3] & 0x3f)<<0);
|
||||
if (uc >= (1u<<16)) //overlong
|
||||
if (uc <= 0x10ffff) //aand we're not allowed to exceed utf-16 surrogates.
|
||||
return 4;
|
||||
}
|
||||
}
|
||||
*value = 0xFFFD;
|
||||
return 0;
|
||||
}
|
||||
|
||||
//read utf-16 chars and output the 'native' utf-8.
|
||||
//we don't expect essays written in code, so we don't need much actual support for utf-8.
|
||||
static char *decodeUTF(int type, unsigned char *inputf, unsigned int inbytes, int *outlen)
|
||||
static char *decodeUTF(int type, unsigned char *inputf, unsigned int inbytes, int *outlen, pbool usemalloc)
|
||||
{
|
||||
char *utf8, *start;
|
||||
unsigned int inc;
|
||||
|
@ -905,7 +950,10 @@ static char *decodeUTF(int type, unsigned char *inputf, unsigned int inbytes, in
|
|||
return inputf;
|
||||
}
|
||||
chars = inbytes / w;
|
||||
utf8 = start = qccHunkAlloc(chars * maxperchar + 2);
|
||||
if (usemalloc)
|
||||
utf8 = start = malloc(chars * maxperchar + 2);
|
||||
else
|
||||
utf8 = start = qccHunkAlloc(chars * maxperchar + 2);
|
||||
for (i = 0; i < chars; i++)
|
||||
{
|
||||
switch(type)
|
||||
|
@ -981,6 +1029,62 @@ static char *decodeUTF(int type, unsigned char *inputf, unsigned int inbytes, in
|
|||
return start;
|
||||
}
|
||||
|
||||
//the gui is a windows program.
|
||||
//this means that its fucked.
|
||||
//on the plus side, its okay with a bom...
|
||||
unsigned short *QCC_makeutf16(char *mem, unsigned int len, int *outlen)
|
||||
{
|
||||
unsigned int code;
|
||||
int l;
|
||||
unsigned short *out, *outstart;
|
||||
//sanitise the input.
|
||||
if (len >= 4 && mem[0] == '\xff' && mem[1] == '\xfe' && mem[2] == '\x00' && mem[3] == '\x00')
|
||||
mem = decodeUTF(UTF32LE, (unsigned char*)mem+4, len-4, &len, true);
|
||||
else if (len >= 4 && mem[0] == '\x00' && mem[1] == '\x00' && mem[2] == '\xfe' && mem[3] == '\xff')
|
||||
mem = decodeUTF(UTF32BE, (unsigned char*)mem+4, len-4, &len, true);
|
||||
else if (len >= 2 && mem[0] == '\xff' && mem[1] == '\xfe')
|
||||
{
|
||||
//already utf8, just return it as-is
|
||||
out = malloc(len+3);
|
||||
memcpy(out, mem, len);
|
||||
out[len/2] = 0;
|
||||
return out;
|
||||
//mem = decodeUTF(UTF16LE, (unsigned char*)mem+2, len-2, &len, false);
|
||||
}
|
||||
else if (len >= 2 && mem[0] == '\xfe' && mem[1] == '\xff')
|
||||
mem = decodeUTF(UTF16BE, (unsigned char*)mem+2, len-2, &len, false);
|
||||
//utf-8 BOM, for compat with broken text editors (like windows notepad).
|
||||
else if (len >= 3 && mem[0] == '\xef' && mem[1] == '\xbb' && mem[2] == '\xbf')
|
||||
{
|
||||
mem += 3;
|
||||
len -= 3;
|
||||
}
|
||||
|
||||
outstart = malloc(len*2+3);
|
||||
out = outstart;
|
||||
while(len)
|
||||
{
|
||||
l = utf8_check(mem, &code);
|
||||
if (!l)
|
||||
{l = 1; code = 0xe000|(unsigned char)*mem;}//fucked up. convert to 0xe000 private-use range.
|
||||
len -= l;
|
||||
mem += l;
|
||||
|
||||
if (code > 0xffff)
|
||||
{
|
||||
code -= 0x10000;
|
||||
*out++ = 0xd800u | ((code>>10) & 0x3ff);
|
||||
// *out++ = 0xdc00u | ((code>>00) & 0x3ff);
|
||||
}
|
||||
else
|
||||
*out++ = code;
|
||||
}
|
||||
if (outlen)
|
||||
*outlen = out - outstart;
|
||||
*out++ = 0;
|
||||
return outstart;
|
||||
}
|
||||
|
||||
long QCC_LoadFile (char *filename, void **bufferptr)
|
||||
{
|
||||
char *mem;
|
||||
|
@ -1002,13 +1106,13 @@ long QCC_LoadFile (char *filename, void **bufferptr)
|
|||
externs->ReadFile(filename, mem, len+2);
|
||||
|
||||
if (len >= 4 && mem[0] == '\xff' && mem[1] == '\xfe' && mem[2] == '\x00' && mem[3] == '\x00')
|
||||
mem = decodeUTF(UTF32LE, (unsigned char*)mem+4, len-4, &len);
|
||||
mem = decodeUTF(UTF32LE, (unsigned char*)mem+4, len-4, &len, false);
|
||||
else if (len >= 4 && mem[0] == '\x00' && mem[1] == '\x00' && mem[2] == '\xfe' && mem[3] == '\xff')
|
||||
mem = decodeUTF(UTF32BE, (unsigned char*)mem+4, len-4, &len);
|
||||
mem = decodeUTF(UTF32BE, (unsigned char*)mem+4, len-4, &len, false);
|
||||
else if (len >= 2 && mem[0] == '\xff' && mem[1] == '\xfe')
|
||||
mem = decodeUTF(UTF16LE, (unsigned char*)mem+2, len-2, &len);
|
||||
mem = decodeUTF(UTF16LE, (unsigned char*)mem+2, len-2, &len, false);
|
||||
else if (len >= 2 && mem[0] == '\xfe' && mem[1] == '\xff')
|
||||
mem = decodeUTF(UTF16BE, (unsigned char*)mem+2, len-2, &len);
|
||||
mem = decodeUTF(UTF16BE, (unsigned char*)mem+2, len-2, &len, false);
|
||||
//utf-8 BOM, for compat with broken text editors (like windows notepad).
|
||||
else if (len >= 3 && mem[0] == '\xef' && mem[1] == '\xbb' && mem[2] == '\xbf')
|
||||
{
|
||||
|
|
|
@ -392,6 +392,12 @@ static void QCC_PR_SkipToEndOfLine(pbool errorifnonwhite)
|
|||
{
|
||||
handleccomments = false;
|
||||
pr_file_p += 2;
|
||||
/*while(*pr_file_p)
|
||||
{
|
||||
if (*pr_file_p == '\n')
|
||||
break;
|
||||
pr_file_p++;
|
||||
}*/
|
||||
}
|
||||
else if (*pr_file_p == '\\' && pr_file_p[1] == '\r' && pr_file_p[2] == '\n')
|
||||
{ /*windows endings*/
|
||||
|
@ -1329,6 +1335,7 @@ void QCC_PR_LexString (void)
|
|||
char *end, *cnst;
|
||||
int raw;
|
||||
char rawdelim[64];
|
||||
int code;
|
||||
|
||||
int texttype;
|
||||
pbool first = true;
|
||||
|
@ -1389,6 +1396,14 @@ void QCC_PR_LexString (void)
|
|||
if (!c)
|
||||
QCC_PR_ParseError (ERR_EOF, "EOF inside quote");
|
||||
|
||||
if (!qccwarningaction[WARN_NOTUTF8] && c < 0 && utf8_check(&pr_token[c-1], &code))
|
||||
{
|
||||
//convert 0xe000 private-use area to quake's charset (if they don't have the utf-8 warning enabled)
|
||||
//note: this may have a small false-positive risk.
|
||||
if (code >= 0xe000 && code <= 0xe0ff)
|
||||
pr_file_p += utf8_check(&pr_token[c-1], &code)-1;
|
||||
}
|
||||
|
||||
/* //these two conditions are generally part of the C preprocessor.
|
||||
if (c == '\\' && *pr_file_p == '\r' && pr_file_p[1] == '\n')
|
||||
{ //dos format
|
||||
|
@ -1651,42 +1666,15 @@ void QCC_PR_LexString (void)
|
|||
|
||||
if (qccwarningaction[WARN_NOTUTF8])
|
||||
{
|
||||
len = 0;
|
||||
//this doesn't do over-long checks.
|
||||
for (c = 0; pr_token[c]; c++)
|
||||
{
|
||||
if (len)
|
||||
len = utf8_check(&pr_token[c], &code);
|
||||
if (!len)
|
||||
{
|
||||
if ((pr_token[c] & 0xc0) != 0x80)
|
||||
break;
|
||||
len--;
|
||||
}
|
||||
else if (pr_token[c] & 0x80)
|
||||
{
|
||||
if (!(pr_token[c] & 0x40))
|
||||
{
|
||||
//error.
|
||||
len = 1;
|
||||
break;
|
||||
}
|
||||
else if (!(pr_token[c] & 0x20))
|
||||
len = 2;
|
||||
else if (!(pr_token[c] & 0x10))
|
||||
len = 3;
|
||||
else if (!(pr_token[c] & 0x08))
|
||||
len = 4;
|
||||
else if (!(pr_token[c] & 0x04))
|
||||
len = 5;
|
||||
else if (!(pr_token[c] & 0x02))
|
||||
len = 6;
|
||||
else if (!(pr_token[c] & 0x01))
|
||||
len = 7;
|
||||
else
|
||||
len = 8;
|
||||
QCC_PR_ParseWarning(WARN_NOTUTF8, "String constant is not valid utf-8");
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (len)
|
||||
QCC_PR_ParseWarning(WARN_NOTUTF8, "String constant is not valid utf-8");
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
@ -1955,15 +1943,43 @@ void QCC_PR_LexName (void)
|
|||
int len;
|
||||
|
||||
len = 0;
|
||||
c = *pr_file_p;
|
||||
do
|
||||
{
|
||||
pr_token[len] = c;
|
||||
len++;
|
||||
pr_file_p++;
|
||||
int b = utf8_check(pr_file_p, &c);
|
||||
if (!b)
|
||||
{
|
||||
unsigned char lead = *pr_file_p++;
|
||||
char *o;
|
||||
while(*pr_file_p && !utf8_check(pr_file_p, &c))
|
||||
pr_file_p++;
|
||||
o = pr_file_p;
|
||||
while (qcc_iswhite(*pr_file_p))
|
||||
{
|
||||
if (*pr_file_p == '\n')
|
||||
break;
|
||||
pr_file_p++;
|
||||
}
|
||||
if (*pr_file_p == '\n')
|
||||
QCC_PR_ParseError(ERR_NOTANAME, "Invalid UTF-8 code sequence at end of line. Lead byte was %#2x", lead);
|
||||
else
|
||||
{
|
||||
len = 0;
|
||||
while (*pr_file_p && !qcc_iswhite(*pr_file_p))
|
||||
pr_token[len++] = *pr_file_p++;
|
||||
pr_token[len++] = 0;
|
||||
pr_file_p = o;
|
||||
QCC_PR_ParseError(ERR_NOTANAME, "Invalid UTF-8 code sequence before %s. Lead byte was %#2x", pr_token, lead);
|
||||
}
|
||||
return;
|
||||
}
|
||||
while(b-->0)
|
||||
{
|
||||
pr_token[len] = *pr_file_p++;
|
||||
len++;
|
||||
}
|
||||
c = *pr_file_p;
|
||||
} while ( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_'
|
||||
|| (c >= '0' && c <= '9'));
|
||||
|| (c >= '0' && c <= '9') || c & 0x80);
|
||||
|
||||
pr_token[len] = 0;
|
||||
pr_token_type = tt_name;
|
||||
|
@ -1997,7 +2013,13 @@ void QCC_PR_LexPunctuation (void)
|
|||
}
|
||||
}
|
||||
|
||||
QCC_PR_ParseError (ERR_UNKNOWNPUCTUATION, "Unknown punctuation");
|
||||
if ((unsigned char)*pr_file_p == (unsigned char)0xa0)
|
||||
QCC_PR_ParseWarning (ERR_UNKNOWNPUCTUATION, "Unknown punctuation: '\\x%x' - non-breaking space", (unsigned char)*pr_file_p);
|
||||
else
|
||||
QCC_PR_ParseWarning (ERR_UNKNOWNPUCTUATION, "Unknown punctuation: '\\x%x'", *pr_file_p);
|
||||
pr_file_p++;
|
||||
|
||||
QCC_PR_Lex();
|
||||
}
|
||||
|
||||
|
||||
|
@ -2159,7 +2181,7 @@ pbool QCC_PR_SimpleGetToken (void)
|
|||
}
|
||||
|
||||
i = 0;
|
||||
while ((c = *pr_file_p) && !qcc_iswhite(c) && c != ',' && c != ';' && c != ')' && c != '(' && c != ']')
|
||||
while ((c = *pr_file_p) && !qcc_iswhite(c) && c != ',' && c != ';' && c != ')' && c != '(' && c != ']' && !(c == '/' && pr_file_p[1] == '/'))
|
||||
{
|
||||
if (i == sizeof(qcc_token)-1)
|
||||
QCC_Error (ERR_INTERNAL, "token exceeds %i chars", i);
|
||||
|
@ -2908,6 +2930,20 @@ int QCC_PR_CheckCompConst(void)
|
|||
|
||||
return true;
|
||||
}
|
||||
if (!strncmp(pr_file_p, "__QCCVER__", 8))
|
||||
{
|
||||
char retbuf[128];
|
||||
|
||||
time_t long_time;
|
||||
time( &long_time );
|
||||
strftime( retbuf, sizeof(retbuf),
|
||||
"\"%a %d %b %Y\"", localtime( &long_time ));
|
||||
|
||||
pr_file_p += 10;
|
||||
QCC_PR_IncludeChunkEx("FTEQCC "__DATE__","__TIME__"", true, NULL, NULL);
|
||||
|
||||
return true;
|
||||
}
|
||||
if (!strncmp(pr_file_p, "__FILE__", 8))
|
||||
{
|
||||
char retbuf[256];
|
||||
|
@ -3110,7 +3146,7 @@ void QCC_PR_Lex (void)
|
|||
return;
|
||||
}
|
||||
|
||||
if ( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' )
|
||||
if ( (c >= 'a' && c <= 'z') || (c >= 'A' && c <= 'Z') || c == '_' || (c & 0x80))
|
||||
{
|
||||
if (flag_hashonly || !QCC_PR_CheckCompConst()) //look for a macro.
|
||||
QCC_PR_LexName ();
|
||||
|
|
|
@ -79,6 +79,80 @@ int PDECL QCC_FileSize (const char *fname)
|
|||
#include "../libs/zlib.h"
|
||||
#endif
|
||||
|
||||
pbool PDECL QCC_WriteFileW (const char *name, wchar_t *data, int chars)
|
||||
{
|
||||
char *u8start = malloc(3+chars*4+1);
|
||||
char *u8 = u8start;
|
||||
int offset;
|
||||
pbool result = false;
|
||||
unsigned int inc;
|
||||
FILE *f;
|
||||
|
||||
//start with the bom
|
||||
//lets just always write a BOM when the file contains something outside ascii. it'll just be more robust when microsoft refuse to use utf8 by default.
|
||||
//its just much less likely to fuck up when people use notepad/wordpad. :s
|
||||
inc = 0xfeff;
|
||||
*u8++ = ((inc>>12) & 0xf) | 0xe0;
|
||||
*u8++ = ((inc>>6) & 0x3f) | 0x80;
|
||||
*u8++ = ((inc>>0) & 0x3f) | 0x80;
|
||||
offset = u8-u8start; //assume its not needed. will set to 0 if it is.
|
||||
|
||||
while(*data)
|
||||
{
|
||||
inc = *data++;
|
||||
//handle surrogates
|
||||
if (inc >= 0xd800u && inc < 0xdc00u)
|
||||
{
|
||||
unsigned int l = *data;
|
||||
if (l >= 0xdc00u && l < 0xe000u)
|
||||
{
|
||||
data++;
|
||||
inc = (((inc & 0x3ffu)<<10) | (l & 0x3ffu)) + 0x10000;
|
||||
}
|
||||
}
|
||||
if (inc <= 127)
|
||||
*u8++ = inc;
|
||||
else
|
||||
{
|
||||
offset = 0;
|
||||
if (inc <= 0x7ff)
|
||||
{
|
||||
*u8++ = ((inc>>6) & 0x1f) | 0xc0;
|
||||
*u8++ = ((inc>>0) & 0x3f) | 0x80;
|
||||
}
|
||||
else if (inc <= 0xffff)
|
||||
{
|
||||
*u8++ = ((inc>>12) & 0xf) | 0xe0;
|
||||
*u8++ = ((inc>>6) & 0x3f) | 0x80;
|
||||
*u8++ = ((inc>>0) & 0x3f) | 0x80;
|
||||
}
|
||||
else if (inc <= 0x1fffff)
|
||||
{
|
||||
*u8++ = ((inc>>18) & 0x07) | 0xf0;
|
||||
*u8++ = ((inc>>12) & 0x3f) | 0x80;
|
||||
*u8++ = ((inc>> 6) & 0x3f) | 0x80;
|
||||
*u8++ = ((inc>> 0) & 0x3f) | 0x80;
|
||||
}
|
||||
else
|
||||
{
|
||||
inc = 0xFFFD;
|
||||
*u8++ = ((inc>>12) & 0xf) | 0xe0;
|
||||
*u8++ = ((inc>>6) & 0x3f) | 0x80;
|
||||
*u8++ = ((inc>>0) & 0x3f) | 0x80;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
f = fopen(name, "wb");
|
||||
if (f)
|
||||
{
|
||||
result = fwrite(u8start+offset, 1, u8-(u8start+offset), f) == (u8-(u8start+offset));
|
||||
fclose(f);
|
||||
}
|
||||
free(u8start);
|
||||
return result;
|
||||
}
|
||||
|
||||
pbool PDECL QCC_WriteFile (const char *name, void *data, int len)
|
||||
{
|
||||
long length;
|
||||
|
@ -303,9 +377,9 @@ HWND CreateAnEditControl(HWND parent)
|
|||
if (!richedit)
|
||||
richedit = LoadLibrary("RICHED32.DLL");
|
||||
|
||||
newc=CreateWindowEx(WS_EX_CLIENTEDGE,
|
||||
richedit?RICHEDIT_CLASS:"EDIT",
|
||||
"",
|
||||
newc=CreateWindowExW(WS_EX_CLIENTEDGE,
|
||||
richedit?RICHEDIT_CLASSW:L"EDIT",
|
||||
L"",
|
||||
WS_CHILD /*| ES_READONLY*/ | WS_VISIBLE |
|
||||
WS_HSCROLL | WS_VSCROLL | ES_LEFT | ES_WANTRETURN |
|
||||
ES_MULTILINE | ES_AUTOVSCROLL,
|
||||
|
@ -1147,6 +1221,7 @@ int Rehighlight(editor_t *edit)
|
|||
}
|
||||
#endif
|
||||
|
||||
unsigned short *QCC_makeutf16(char *mem, unsigned int len, int *outlen);
|
||||
void EditorReload(editor_t *editor)
|
||||
{
|
||||
struct stat sbuf;
|
||||
|
@ -1157,7 +1232,10 @@ void EditorReload(editor_t *editor)
|
|||
if (flen >= 0)
|
||||
{
|
||||
file = malloc(flen+1);
|
||||
|
||||
QCC_ReadFile(editor->filename, file, flen);
|
||||
|
||||
|
||||
file[flen] = 0;
|
||||
}
|
||||
else
|
||||
|
@ -1171,14 +1249,16 @@ void EditorReload(editor_t *editor)
|
|||
|
||||
if (file)
|
||||
{
|
||||
if (!fl_autohighlight)
|
||||
char msg[1024];
|
||||
wchar_t *ch = QCC_makeutf16(file, flen, NULL);
|
||||
Edit_SetSel(editor->editpane,0,0);
|
||||
SetWindowTextW(editor->editpane, ch);
|
||||
/*if (errors)
|
||||
{
|
||||
GUIPrint(editor->editpane, file);
|
||||
}
|
||||
else
|
||||
{
|
||||
GUIFormattingPrint(editor->editpane, file);
|
||||
}
|
||||
QC_snprintfz(msg, sizeof(msg), "%s contains encoding errors. Invalid bytes have been converted to the 0xe000 private use area.", editor->filename);
|
||||
MessageBox(editor->editpane, msg, "Encoding errors.", MB_ICONWARNING);
|
||||
}*/
|
||||
free(ch);
|
||||
free(file);
|
||||
}
|
||||
|
||||
|
@ -1321,16 +1401,16 @@ int EditorSave(editor_t *edit)
|
|||
char title[2048];
|
||||
struct stat sbuf;
|
||||
int len;
|
||||
char *file;
|
||||
len = Edit_GetTextLength(edit->editpane);
|
||||
file = malloc(len+1);
|
||||
wchar_t *file;
|
||||
len = GetWindowTextLengthW(edit->editpane);
|
||||
file = malloc((len+1)*2);
|
||||
if (!file)
|
||||
{
|
||||
MessageBox(NULL, "Save failed - not enough mem", "Error", 0);
|
||||
return false;
|
||||
}
|
||||
Edit_GetText(edit->editpane, file, len+1);
|
||||
if (!QCC_WriteFile(edit->filename, file, len))
|
||||
GetWindowTextW(edit->editpane, file, len+1);
|
||||
if (!QCC_WriteFileW(edit->filename, file, len))
|
||||
{
|
||||
MessageBox(NULL, "Save failed\nCheck path and ReadOnly flags", "Failure", 0);
|
||||
return false;
|
||||
|
@ -1361,8 +1441,10 @@ char *GUIReadFile(const char *fname, void *buffer, int blen)
|
|||
{
|
||||
if (e->window && !strcmp(e->filename, fname))
|
||||
{
|
||||
int elen = Edit_GetTextLength(e->editpane);
|
||||
Edit_GetText(e->editpane, buffer, blen);
|
||||
// int elen = GetWindowTextLengthW(e->editpane);
|
||||
//our qcc itself is fine with utf-16, so long as it has a BOM.
|
||||
*(short*)buffer = 0xfeff;
|
||||
GetWindowTextW(e->editpane, (short*)buffer+1, blen);
|
||||
return buffer;
|
||||
}
|
||||
}
|
||||
|
@ -1377,7 +1459,7 @@ int GUIFileSize(const char *fname)
|
|||
{
|
||||
if (e->window && !strcmp(e->filename, fname))
|
||||
{
|
||||
int len = Edit_GetTextLength(e->editpane);
|
||||
int len = (GetWindowTextLengthW(e->editpane)+1)*2;
|
||||
return len;
|
||||
}
|
||||
}
|
||||
|
@ -1639,7 +1721,7 @@ HWND optionsmenu;
|
|||
HWND hexen2item;
|
||||
HWND nokeywords_coexistitem;
|
||||
HWND autoprototype_item;
|
||||
HWND autohighlight_item;
|
||||
//HWND autohighlight_item;
|
||||
HWND extraparmsitem;
|
||||
#ifdef EMBEDDEBUG
|
||||
HWND w_enginebinary;
|
||||
|
@ -1681,7 +1763,7 @@ static LRESULT CALLBACK OptionsWndProc(HWND hWnd,UINT message,
|
|||
else
|
||||
compiler_flag[i].flags &= ~FLAG_SETINGUI;
|
||||
}
|
||||
fl_autohighlight = Button_GetCheck(autohighlight_item);
|
||||
fl_autohighlight = false;//Button_GetCheck(autohighlight_item);
|
||||
Edit_GetText(extraparmsitem, parameters, sizeof(parameters)-1);
|
||||
#ifdef EMBEDDEBUG
|
||||
Edit_GetText(w_enginebinary, enginebinary, sizeof(enginebinary)-1);
|
||||
|
@ -2086,7 +2168,7 @@ void OptionsDialog(void)
|
|||
else
|
||||
Button_SetCheck(wnd, 0);
|
||||
|
||||
autohighlight_item = wnd = CreateWindow("BUTTON","Syntax Highlighting",
|
||||
/* autohighlight_item = wnd = CreateWindow("BUTTON","Syntax Highlighting",
|
||||
WS_CHILD | WS_VISIBLE | BS_AUTOCHECKBOX,
|
||||
408,y,200-16,16,
|
||||
optionsmenu,
|
||||
|
@ -2098,7 +2180,7 @@ void OptionsDialog(void)
|
|||
Button_SetCheck(wnd, 1);
|
||||
else
|
||||
Button_SetCheck(wnd, 0);
|
||||
|
||||
*/
|
||||
x = 408;
|
||||
my = y;
|
||||
for (i = 0; compiler_flag[i].enabled; i++)
|
||||
|
|
Loading…
Reference in a new issue