mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-10 14:42:13 +00:00
in_forceseat will not break clientcmds any more.
tweak drawtextfield to understand fonts. now available to menuqc too. provide player and full server info to qc server browsers. allow qc to actually use cfg_save. I've been issuing that on quit for a while now and not noticed that it was getting denied. fix some focus issues with cwindows. tweak splitscreens to display centerprints+scoreboards in more suitable places. harder to glitch out. path command can now displays hashes (in tooltips), which can be useful for creating fmf files. fix q3game crash. fix some qcc issues with hexenc and -O0. fix some qccgui unicode issues, now preserves encoding when saving. provide easy upgrade path for qccx syntax to fteqcc: string[%1] -> string+1 (which is still potentially unsafe (tempstrings), and thus generates a compiler warning). rework xmpp plugin to use cwindows for chats and the buddylist. this should make it more intuitive and thus more userfriendly. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4865 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
57248e9f64
commit
410db5d6b0
33 changed files with 1992 additions and 695 deletions
|
@ -62,10 +62,12 @@ typedef enum
|
|||
SLKEY_ISFAVORITE,//eep!
|
||||
SLKEY_ISLOCAL,
|
||||
SLKEY_ISPROXY,
|
||||
SLKEY_SERVERINFO,
|
||||
|
||||
|
||||
SLKEY_TOOMANY,
|
||||
SLKEY_CUSTOM
|
||||
SLKEY_PLAYER0,
|
||||
SLKEY_CUSTOM = SLKEY_PLAYER0+MAX_CLIENTS
|
||||
} hostcachekey_t;
|
||||
|
||||
typedef enum
|
||||
|
|
|
@ -5729,6 +5729,8 @@ void CL_ParseStuffCmd(char *msg, int destsplit) //this protects stuffcmds from n
|
|||
#endif
|
||||
else
|
||||
{
|
||||
if (!strncmp(stufftext, "cmd ", 4))
|
||||
Cbuf_AddText (va("p%i ", destsplit+1), RESTRICT_SERVER+destsplit); //without this, in_forceseat can break directed cmds.
|
||||
Cbuf_AddText (stufftext, RESTRICT_SERVER+destsplit);
|
||||
Cbuf_AddText ("\n", RESTRICT_SERVER+destsplit);
|
||||
}
|
||||
|
|
|
@ -581,6 +581,8 @@ void SCR_DrawCenterString (vrect_t *rect, cprint_t *p, struct font_s *font)
|
|||
|
||||
for (l = 0; l < linecount; l++, y += Font_CharHeight())
|
||||
{
|
||||
if (y >= bottom)
|
||||
break;
|
||||
if (p->flags & CPRINT_RALIGN)
|
||||
{
|
||||
x = right - Font_LineWidth(line_start[l], line_end[l]);
|
||||
|
@ -609,7 +611,6 @@ void SCR_CheckDrawCenterString (void)
|
|||
extern qboolean sb_showscores;
|
||||
int pnum;
|
||||
cprint_t *p;
|
||||
vrect_t rect;
|
||||
|
||||
for (pnum = 0; pnum < cl.splitclients; pnum++)
|
||||
{
|
||||
|
@ -626,12 +627,12 @@ void SCR_CheckDrawCenterString (void)
|
|||
if (sb_showscores) //this was annoying
|
||||
continue;
|
||||
|
||||
SCR_VRectForPlayer(&rect, pnum);
|
||||
SCR_DrawCenterString(&rect, p, font_default);
|
||||
if (cl.playerview[pnum].gamerectknown == cls.framecount)
|
||||
SCR_DrawCenterString(&cl.playerview[pnum].gamerect, p, font_default);
|
||||
}
|
||||
}
|
||||
|
||||
void R_DrawTextField(int x, int y, int w, int h, const char *text, unsigned int defaultmask, unsigned int fieldflags)
|
||||
void R_DrawTextField(int x, int y, int w, int h, const char *text, unsigned int defaultmask, unsigned int fieldflags, struct font_s *font, vec2_t fontscale)
|
||||
{
|
||||
cprint_t p;
|
||||
vrect_t r;
|
||||
|
@ -647,7 +648,7 @@ void R_DrawTextField(int x, int y, int w, int h, const char *text, unsigned int
|
|||
p.time_start = cl.time;
|
||||
*p.titleimage = 0;
|
||||
|
||||
SCR_DrawCenterString(&r, &p, font_default);
|
||||
SCR_DrawCenterString(&r, &p, font);
|
||||
}
|
||||
|
||||
qboolean SCR_HardwareCursorIsActive(void)
|
||||
|
@ -2419,7 +2420,7 @@ void SCR_TileClear (void)
|
|||
{
|
||||
if (r_refdef.vrect.width < r_refdef.grect.width)
|
||||
{
|
||||
int w;
|
||||
float w;
|
||||
// left
|
||||
R2D_TileClear (r_refdef.grect.x, r_refdef.grect.y, r_refdef.vrect.x-r_refdef.grect.x, r_refdef.grect.height - sb_lines);
|
||||
// right
|
||||
|
@ -2445,7 +2446,7 @@ void SCR_TileClear (void)
|
|||
// The 2d refresh stuff.
|
||||
void SCR_DrawTwoDimensional(int uimenu, qboolean nohud)
|
||||
{
|
||||
qboolean consolefocused = !!Key_Dest_Has(kdm_console);
|
||||
qboolean consolefocused = !!Key_Dest_Has(kdm_console|kdm_cwindows);
|
||||
RSpeedMark();
|
||||
|
||||
R2D_ImageColours(1, 1, 1, 1);
|
||||
|
|
|
@ -596,6 +596,9 @@ struct playerview_s
|
|||
float driftmove;
|
||||
double laststop;
|
||||
|
||||
int gamerectknown; //equals cls.framecount if valid
|
||||
vrect_t gamerect; //position the player's main view was drawn at this frame.
|
||||
|
||||
//prediction state
|
||||
int pmovetype;
|
||||
float entgravity;
|
||||
|
|
|
@ -445,22 +445,22 @@ static void SL_SliderDraw (int x, int y, menucustom_t *ths, menu_t *menu)
|
|||
|
||||
mpic_t *pic;
|
||||
|
||||
pic = R2D_SafeCachePic("scrollbars/slidebg.png");
|
||||
pic = R2D_SafeCachePic("scrollbars/slidebg.tga");
|
||||
if (pic)
|
||||
{
|
||||
R2D_ScalePic(x + ths->common.width - 8, y+8, 8, ths->common.height-16, pic);
|
||||
|
||||
pic = R2D_SafeCachePic("scrollbars/arrow_up.png");
|
||||
pic = R2D_SafeCachePic("scrollbars/arrow_up.tga");
|
||||
R2D_ScalePic(x + ths->common.width - 8, y, 8, 8, pic);
|
||||
|
||||
pic = R2D_SafeCachePic("scrollbars/arrow_down.png");
|
||||
pic = R2D_SafeCachePic("scrollbars/arrow_down.tga");
|
||||
R2D_ScalePic(x + ths->common.width - 8, y + ths->common.height - 8, 8, 8, pic);
|
||||
|
||||
y += ((info->scrollpos) / ((float)info->numslots - info->visibleslots)) * (float)(ths->common.height-(64+16-1));
|
||||
|
||||
y += 8;
|
||||
|
||||
pic = R2D_SafeCachePic("scrollbars/slider.png");
|
||||
pic = R2D_SafeCachePic("scrollbars/slider.tga");
|
||||
R2D_ScalePic(x + ths->common.width - 8, y, 8, 64, pic);
|
||||
}
|
||||
else
|
||||
|
@ -484,7 +484,7 @@ static void SL_SliderDraw (int x, int y, menucustom_t *ths, menu_t *menu)
|
|||
|
||||
my = mousecursor_y;
|
||||
my -= ths->common.posy;
|
||||
if (R2D_SafeCachePic("scrollbars/slidebg.png"))
|
||||
if (R2D_SafeCachePic("scrollbars/slidebg.tga"))
|
||||
{
|
||||
my -= 32+8;
|
||||
my /= ths->common.height - (64+16);
|
||||
|
|
|
@ -2646,6 +2646,7 @@ static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct menu_
|
|||
entity_t ent;
|
||||
vec3_t fwd, rgt, up;
|
||||
const char *fname;
|
||||
vec2_t fs = {8,8};
|
||||
|
||||
modelview_t *mods = c->dptr;
|
||||
|
||||
|
@ -2732,7 +2733,7 @@ static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct menu_
|
|||
"end: skin+=1\n"
|
||||
"pgup: frame+=1\n"
|
||||
"pgdn: frame-=1\n"
|
||||
, CON_WHITEMASK, CPRINT_TALIGN|CPRINT_LALIGN);
|
||||
, CON_WHITEMASK, CPRINT_TALIGN|CPRINT_LALIGN, font_default, fs);
|
||||
break;
|
||||
case MV_BONES:
|
||||
#ifdef SKELETALMODELS
|
||||
|
@ -2746,7 +2747,7 @@ static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct menu_
|
|||
M_BoneDisplay(&ent, b, &y, 0, -1, 0, bonecount);
|
||||
}
|
||||
else
|
||||
R_DrawTextField(r_refdef.grect.x, r_refdef.grect.y+y, r_refdef.grect.width, r_refdef.grect.height-y, "No bones in model", CON_WHITEMASK, CPRINT_TALIGN|CPRINT_LALIGN);
|
||||
R_DrawTextField(r_refdef.grect.x, r_refdef.grect.y+y, r_refdef.grect.width, r_refdef.grect.height-y, "No bones in model", CON_WHITEMASK, CPRINT_TALIGN|CPRINT_LALIGN, font_default, fs);
|
||||
}
|
||||
#endif
|
||||
break;
|
||||
|
@ -2757,7 +2758,7 @@ static void M_ModelViewerDraw(int x, int y, struct menucustom_s *c, struct menu_
|
|||
char *body = Shader_GetShaderBody(Mod_ShaderForSkin(ent.model, mods->skingroup));
|
||||
mods->shadertext = Z_StrDup(body);
|
||||
}
|
||||
R_DrawTextField(r_refdef.grect.x, r_refdef.grect.y+16, r_refdef.grect.width, r_refdef.grect.height-16, mods->shadertext, CON_WHITEMASK, CPRINT_TALIGN|CPRINT_LALIGN);
|
||||
R_DrawTextField(r_refdef.grect.x, r_refdef.grect.y+16, r_refdef.grect.width, r_refdef.grect.height-16, mods->shadertext, CON_WHITEMASK, CPRINT_TALIGN|CPRINT_LALIGN, font_default, fs);
|
||||
|
||||
//fixme: draw the shader's textures.
|
||||
}
|
||||
|
|
|
@ -294,13 +294,16 @@ void M_ToggleMenu_f (void)
|
|||
#ifdef CSQC_DAT
|
||||
if (CSQC_ConsoleCommand("togglemenu"))
|
||||
{
|
||||
Key_Dest_Remove(kdm_console);
|
||||
Key_Dest_Remove(kdm_console|kdm_cwindows);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#ifdef MENU_DAT
|
||||
if (MP_Toggle())
|
||||
{
|
||||
Key_Dest_Remove(kdm_console|kdm_cwindows);
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
#ifdef VM_UI
|
||||
if (UI_OpenMenu())
|
||||
|
@ -314,8 +317,8 @@ void M_ToggleMenu_f (void)
|
|||
m_state = m_none;
|
||||
return;
|
||||
}
|
||||
if (Key_Dest_Has(kdm_console))
|
||||
Key_Dest_Remove(kdm_console);
|
||||
if (Key_Dest_Has(kdm_console|kdm_cwindows))
|
||||
Key_Dest_Remove(kdm_console|kdm_cwindows);
|
||||
/*
|
||||
{
|
||||
if (cls.state != ca_active)
|
||||
|
|
|
@ -10,6 +10,7 @@ struct entity_s;
|
|||
struct dlight_s;
|
||||
struct galiasbone_s;
|
||||
struct dlight_s;
|
||||
struct font_s;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
|
@ -108,7 +109,7 @@ extern void SCR_SetUpToDrawConsole (void);
|
|||
extern void SCR_EraseCenterString (void);
|
||||
extern void SCR_CenterPrint (int pnum, char *str, qboolean skipgamecode);
|
||||
|
||||
void R_DrawTextField(int x, int y, int w, int h, const char *text, unsigned int defaultmask, unsigned int fieldflags);
|
||||
void R_DrawTextField(int x, int y, int w, int h, const char *text, unsigned int defaultmask, unsigned int fieldflags, struct font_s *font, vec2_t fontscale);
|
||||
#define CPRINT_LALIGN (1<<0) //L
|
||||
#define CPRINT_TALIGN (1<<1) //T
|
||||
#define CPRINT_RALIGN (1<<2) //R
|
||||
|
|
|
@ -1052,6 +1052,17 @@ float Master_ReadKeyFloat(serverinfo_t *server, int keynum)
|
|||
return 0;
|
||||
}
|
||||
|
||||
void Master_DecodeColour(vec3_t ret, int col)
|
||||
{
|
||||
if (col < 16)
|
||||
{
|
||||
col = Sbar_ColorForMap(col);
|
||||
VectorSet(ret, host_basepal[col*3+0]/255.0, host_basepal[col*3+1]/255.0, host_basepal[col*3+2]/255.0);
|
||||
}
|
||||
else
|
||||
VectorSet(ret, ((col&0xff0000)>>16)/255.0, ((col&0x00ff00)>>8)/255.0, ((col&0x0000ff)>>0)/255.0);
|
||||
}
|
||||
|
||||
char *Master_ReadKeyString(serverinfo_t *server, int keynum)
|
||||
{
|
||||
static char adr[MAX_ADR_SIZE];
|
||||
|
@ -1059,7 +1070,41 @@ char *Master_ReadKeyString(serverinfo_t *server, int keynum)
|
|||
if (!server)
|
||||
return "";
|
||||
|
||||
if (keynum < SLKEY_CUSTOM)
|
||||
if (keynum >= SLKEY_CUSTOM)
|
||||
{
|
||||
if (server->moreinfo)
|
||||
{
|
||||
keynum -= SLKEY_CUSTOM;
|
||||
if (keynum < sizeof(slist_keyname)/sizeof(slist_keyname[0]))
|
||||
return Info_ValueForKey(server->moreinfo->info, slist_keyname[keynum]);
|
||||
}
|
||||
else if (!(server->special & SS_KEEPINFO))
|
||||
{
|
||||
server->special |= SS_KEEPINFO;
|
||||
server->sends++;
|
||||
}
|
||||
}
|
||||
else if (keynum >= SLKEY_PLAYER0)
|
||||
{
|
||||
if (server->moreinfo)
|
||||
{
|
||||
keynum -= SLKEY_PLAYER0;
|
||||
if (keynum < server->moreinfo->numplayers)
|
||||
{
|
||||
vec3_t top, bot;
|
||||
Master_DecodeColour(top, server->moreinfo->players[keynum].topc);
|
||||
Master_DecodeColour(bot, server->moreinfo->players[keynum].botc);
|
||||
|
||||
return va("%i %i %g %i \"%s\" \"%s\" '%g %g %g' '%g %g %g'", server->moreinfo->players[keynum].userid, server->moreinfo->players[keynum].frags, server->moreinfo->players[keynum].time, server->moreinfo->players[keynum].ping, server->moreinfo->players[keynum].name, server->moreinfo->players[keynum].skin, top[0],top[1],top[2], bot[0], bot[1], bot[2]);
|
||||
}
|
||||
}
|
||||
else if (!(server->special & SS_KEEPINFO))
|
||||
{
|
||||
server->special |= SS_KEEPINFO;
|
||||
server->sends++;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
switch(keynum)
|
||||
{
|
||||
|
@ -1076,6 +1121,8 @@ char *Master_ReadKeyString(serverinfo_t *server, int keynum)
|
|||
return server->modname;
|
||||
case SLKEY_QCSTATUS:
|
||||
return server->qcstatus;
|
||||
case SLKEY_SERVERINFO:
|
||||
return server->moreinfo->info;
|
||||
|
||||
default:
|
||||
{
|
||||
|
@ -1085,8 +1132,6 @@ char *Master_ReadKeyString(serverinfo_t *server, int keynum)
|
|||
}
|
||||
}
|
||||
}
|
||||
else if (server->moreinfo)
|
||||
return Info_ValueForKey(server->moreinfo->info, slist_keyname[keynum-SLKEY_CUSTOM]);
|
||||
|
||||
return "";
|
||||
}
|
||||
|
@ -1130,6 +1175,10 @@ int Master_KeyForName(const char *keyname)
|
|||
return SLKEY_ISLOCAL;
|
||||
else if (!strcmp(keyname, "isproxy"))
|
||||
return SLKEY_ISPROXY;
|
||||
else if (!strcmp(keyname, "serverinfo"))
|
||||
return SLKEY_SERVERINFO;
|
||||
else if (!strncmp(keyname, "player", 6))
|
||||
return SLKEY_PLAYER0 + atoi(keyname+6);
|
||||
|
||||
else if (slist_customkeys == SLIST_MAXKEYS)
|
||||
return SLKEY_TOOMANY;
|
||||
|
@ -2694,7 +2743,7 @@ int CL_ReadServerInfo(char *msg, enum masterprotocol_e prototype, qboolean favor
|
|||
details.players[clnum].botc = 0;
|
||||
details.players[clnum].time = 0;
|
||||
}
|
||||
else //qw responce
|
||||
else //qw response
|
||||
{
|
||||
details.players[clnum].time = atoi(token);
|
||||
msg = token;
|
||||
|
|
|
@ -232,6 +232,8 @@ static void CSQC_ChangeLocalPlayer(int seat)
|
|||
*csqcg.player_localentnum = csqc_playerview->viewentity;
|
||||
else if (cl.spectator && Cam_TrackNum(csqc_playerview) >= 0)
|
||||
*csqcg.player_localentnum = Cam_TrackNum(csqc_playerview) + 1;
|
||||
else if (csqc_playerview == &csqc_nullview)
|
||||
*csqcg.player_localentnum = 0;
|
||||
else
|
||||
*csqcg.player_localentnum = csqc_playerview->playernum+1;
|
||||
}
|
||||
|
@ -1570,8 +1572,12 @@ void QCBUILTIN PF_R_SetViewFlag(pubprogfuncs_t *prinst, struct globalvars_s *pr_
|
|||
case VF_ACTIVESEAT:
|
||||
if (prinst == csqc_world.progs)
|
||||
{
|
||||
CSQC_ChangeLocalPlayer(*p);
|
||||
V_CalcRefdef(csqc_playerview); //set up the default position+angles for the named player.
|
||||
if (csqc_playerseat != *p)
|
||||
{
|
||||
CSQC_ChangeLocalPlayer(*p);
|
||||
if (prinst->callargc < 3 || G_FLOAT(OFS_PARM2))
|
||||
V_CalcRefdef(csqc_playerview); //set up the default position+angles for the named player.
|
||||
}
|
||||
}
|
||||
break;
|
||||
case VF_VIEWENTITY:
|
||||
|
@ -2868,7 +2874,10 @@ static void QCBUILTIN PF_cs_getentitytoken (pubprogfuncs_t *prinst, struct globa
|
|||
{
|
||||
csqcmapentitydata = COM_ParseToken(csqcmapentitydata, "{}()\'\":,");
|
||||
}
|
||||
RETURN_TSTRING(com_token);
|
||||
if (!csqcmapentitydata) //hit the end
|
||||
G_INT(OFS_RETURN) = 0;
|
||||
else
|
||||
RETURN_TSTRING(com_token);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -107,12 +107,13 @@ struct font_s *PR_CL_ChooseFont(float *fontsel, float szx, float szy)
|
|||
void PR_CL_BeginString(pubprogfuncs_t *prinst, float vx, float vy, float szx, float szy, float *px, float *py)
|
||||
{
|
||||
world_t *world = prinst->parms->user;
|
||||
struct font_s *font = PR_CL_ChooseFont(world->g.drawfont, szx, szy);
|
||||
struct font_s *font;
|
||||
if (world->g.drawfontscale && (world->g.drawfontscale[0] || world->g.drawfontscale[1]))
|
||||
{
|
||||
szx *= world->g.drawfontscale[0];
|
||||
szy *= world->g.drawfontscale[1];
|
||||
}
|
||||
font = PR_CL_ChooseFont(world->g.drawfont, szx, szy);
|
||||
Font_BeginScaledString(font, vx, vy, szx, szy, px, py);
|
||||
}
|
||||
int PR_findnamedfont(const char *name, qboolean isslotname)
|
||||
|
@ -367,7 +368,17 @@ void QCBUILTIN PF_CL_DrawTextField (pubprogfuncs_t *prinst, struct globalvars_s
|
|||
unsigned int flags = G_FLOAT(OFS_PARM2);
|
||||
const char *text = PR_GetStringOfs(prinst, OFS_PARM3);
|
||||
|
||||
R_DrawTextField(pos[0], pos[1], size[0], size[1], text, CON_WHITEMASK, flags);
|
||||
world_t *world = prinst->parms->user;
|
||||
vec2_t scale = {8, 8};
|
||||
struct font_s *font;
|
||||
if (world->g.drawfontscale && (world->g.drawfontscale[0] || world->g.drawfontscale[1]))
|
||||
{
|
||||
scale[0] *= world->g.drawfontscale[0];
|
||||
scale[1] *= world->g.drawfontscale[1];
|
||||
}
|
||||
font = PR_CL_ChooseFont(world->g.drawfont, scale[0], scale[1]);
|
||||
|
||||
R_DrawTextField(pos[0], pos[1], size[0], size[1], text, CON_WHITEMASK, flags, font, scale);
|
||||
}
|
||||
|
||||
//float drawstring(vector position, string text, vector scale, float alpha, float flag) = #455;
|
||||
|
@ -2002,6 +2013,7 @@ static struct {
|
|||
{"stringwidth", PF_CL_stringwidth, 468},
|
||||
{"drawsubpic", PF_CL_drawsubpic, 469},
|
||||
{"drawrotsubpic", PF_CL_drawrotsubpic, 0},
|
||||
{"drawtextfield", PF_CL_DrawTextField, 0},
|
||||
//470
|
||||
//MERGES WITH CLIENT+SERVER BUILTIN MAPPINGS BELOW
|
||||
{"asin", PF_asin, 471},
|
||||
|
|
|
@ -254,7 +254,8 @@ static qboolean largegame = false;
|
|||
#ifdef Q2CLIENT
|
||||
static void DrawHUDString (char *string, float x, float y, int centerwidth, qboolean alt)
|
||||
{
|
||||
R_DrawTextField(x, y, centerwidth, 1024, string, alt?CON_ALTMASK:CON_WHITEMASK, CPRINT_TALIGN);
|
||||
vec2_t fontscale = {8,8};
|
||||
R_DrawTextField(x, y, centerwidth, 1024, string, alt?CON_ALTMASK:CON_WHITEMASK, CPRINT_TALIGN, font_default, fontscale);
|
||||
}
|
||||
#define STAT_MINUS 10 // num frame for '-' stats digit
|
||||
static char *q2sb_nums[2][11] =
|
||||
|
@ -3089,6 +3090,8 @@ void Sbar_DeathmatchOverlay (int start)
|
|||
int startx, rank_width;
|
||||
playerview_t *pv = r_refdef.playerview;
|
||||
|
||||
vrect_t gr = r_refdef.grect;
|
||||
|
||||
if (!pv)
|
||||
return;
|
||||
|
||||
|
@ -3124,7 +3127,7 @@ void Sbar_DeathmatchOverlay (int start)
|
|||
if (R_GetShaderSizes(pic, &w, &h, false)>0)
|
||||
{
|
||||
k = (w * 24) / h;
|
||||
R2D_ScalePic ((vid.width-k)/2, 0, k, 24, pic);
|
||||
R2D_ScalePic (gr.x + (gr.width-k)/2, gr.y, k, 24, pic);
|
||||
}
|
||||
}
|
||||
y += 24;
|
||||
|
@ -3146,11 +3149,13 @@ void Sbar_DeathmatchOverlay (int start)
|
|||
y += 8;
|
||||
}
|
||||
|
||||
y += gr.y;
|
||||
|
||||
showcolumns = 0;
|
||||
|
||||
rank_width = 0;
|
||||
|
||||
#define COLUMN(title, cwidth, code) if (rank_width+(cwidth)+8 <= vid.width) {showcolumns |= (1<<COLUMN##title); rank_width += cwidth+8;}
|
||||
#define COLUMN(title, cwidth, code) if (rank_width+(cwidth)+8 <= gr.width) {showcolumns |= (1<<COLUMN##title); rank_width += cwidth+8;}
|
||||
//columns are listed here in priority order (if the screen is too narrow, later ones will be hidden)
|
||||
COLUMN_NAME
|
||||
COLUMN_PING
|
||||
|
@ -3183,7 +3188,8 @@ void Sbar_DeathmatchOverlay (int start)
|
|||
}
|
||||
#undef COLUMN
|
||||
|
||||
startx = (vid.width-rank_width)/2;
|
||||
startx = (gr.width-rank_width)/2;
|
||||
startx += gr.x;
|
||||
|
||||
if (scr_scoreboard_newstyle.ival)
|
||||
{
|
||||
|
|
|
@ -1134,6 +1134,12 @@ void V_ApplyRefdef (void)
|
|||
|
||||
//========================================
|
||||
|
||||
if (r_refdef.playerview->gamerectknown != cls.framecount)
|
||||
{
|
||||
r_refdef.playerview->gamerectknown = cls.framecount;
|
||||
r_refdef.playerview->gamerect = r_refdef.grect;
|
||||
}
|
||||
|
||||
// intermission is always full screen
|
||||
if (cl.intermission || !r_refdef.drawsbar)
|
||||
size = 120;
|
||||
|
@ -1554,9 +1560,10 @@ void R_DrawNameTags(void)
|
|||
entstr = w->progs->saveent(w->progs, asciibuffer, &buflen, sizeof(asciibuffer), (edict_t*)e); //will save just one entities vars
|
||||
if (entstr)
|
||||
{
|
||||
vec2_t scale = {8,8};
|
||||
x = screenspace[0]*r_refdef.vrect.width+r_refdef.vrect.x;
|
||||
y = (1-screenspace[1])*r_refdef.vrect.height+r_refdef.vrect.y;
|
||||
R_DrawTextField(x, y, vid.width - x, vid.height - y, entstr, CON_WHITEMASK, CPRINT_TALIGN|CPRINT_LALIGN);
|
||||
R_DrawTextField(x, y, vid.width - x, vid.height - y, entstr, CON_WHITEMASK, CPRINT_TALIGN|CPRINT_LALIGN, font_default, scale);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -2937,7 +2937,7 @@ void Cmd_WriteConfig_f(void)
|
|||
char sysname[MAX_OSPATH];
|
||||
qboolean all = true;
|
||||
|
||||
if (Cmd_IsInsecure())
|
||||
if (Cmd_IsInsecure() && Cmd_Argc() > 1)
|
||||
{
|
||||
Con_Printf ("%s not allowed\n", Cmd_Argv(0));
|
||||
return;
|
||||
|
|
|
@ -581,12 +581,13 @@ COM_Path_f
|
|||
*/
|
||||
static void COM_PathLine(searchpath_t *s)
|
||||
{
|
||||
Con_Printf("%s %s%s%s%s%s\n", s->logicalpath,
|
||||
Con_Printf("%s %s%s%s%s%s%s\n", s->logicalpath,
|
||||
(s->flags & SPF_REFERENCED)?"^[(ref)\\tip\\Referenced\\desc\\Package will auto-download to clients^]":"",
|
||||
(s->flags & SPF_TEMPORARY)?"^[(temp)\\tip\\Temporary\\desc\\Flushed on map change^]":"",
|
||||
(s->flags & SPF_COPYPROTECTED)?"^[(c)\\tip\\Copyrighted\\desc\\Copy-Protected and is not downloadable^]":"",
|
||||
(s->flags & SPF_EXPLICIT)?"^[(e)\\tip\\Explicit\\desc\\Loaded explicitly by the gamedir^]":"",
|
||||
(s->flags & SPF_UNTRUSTED)?"^[(u)\\tip\\Untrusted\\desc\\Configs and scripts will not be given access to passwords^]":"" );
|
||||
(s->flags & SPF_UNTRUSTED)?"^[(u)\\tip\\Untrusted\\desc\\Configs and scripts will not be given access to passwords^]":"",
|
||||
(s->handle->GeneratePureCRC)?va("^[(h)\\tip\\Hash: %x^]", s->handle->GeneratePureCRC(s->handle, 0, 0)):"");
|
||||
}
|
||||
void COM_Path_f (void)
|
||||
{
|
||||
|
|
|
@ -5927,102 +5927,6 @@ static qboolean CM_NativeTrace(model_t *model, int forcehullnum, int frame, vec3
|
|||
return trace->fraction != 1;
|
||||
}
|
||||
|
||||
/*
|
||||
==================
|
||||
CM_TransformedBoxTrace
|
||||
|
||||
Handles offseting and rotation of the end points for moving and
|
||||
rotating entities
|
||||
==================
|
||||
*/
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(disable : 4748)
|
||||
#pragma optimize( "", off )
|
||||
#endif
|
||||
|
||||
trace_t CM_TransformedBoxTrace (model_t *mod, vec3_t start, vec3_t end,
|
||||
vec3_t mins, vec3_t maxs,
|
||||
int brushmask,
|
||||
vec3_t origin, vec3_t angles)
|
||||
{
|
||||
#ifdef _MSC_VER
|
||||
#pragma warning(default : 4748)
|
||||
#endif
|
||||
trace_t trace;
|
||||
vec3_t start_l, end_l;
|
||||
vec3_t a;
|
||||
vec3_t forward, right, up;
|
||||
vec3_t temp;
|
||||
qboolean rotated;
|
||||
qboolean capsule = false;
|
||||
|
||||
// subtract origin offset
|
||||
VectorSubtract (start, origin, start_l);
|
||||
VectorSubtract (end, origin, end_l);
|
||||
|
||||
// rotate start and end into the models frame of reference
|
||||
if (mod != &box_model &&
|
||||
(angles[0] || angles[1] || angles[2]) )
|
||||
rotated = true;
|
||||
else
|
||||
rotated = false;
|
||||
|
||||
if (rotated)
|
||||
{
|
||||
AngleVectors (angles, forward, right, up);
|
||||
|
||||
VectorCopy (start_l, temp);
|
||||
start_l[0] = DotProduct (temp, forward);
|
||||
start_l[1] = -DotProduct (temp, right);
|
||||
start_l[2] = DotProduct (temp, up);
|
||||
|
||||
VectorCopy (end_l, temp);
|
||||
end_l[0] = DotProduct (temp, forward);
|
||||
end_l[1] = -DotProduct (temp, right);
|
||||
end_l[2] = DotProduct (temp, up);
|
||||
|
||||
VectorSet(trace_up, forward[2], -right[2], up[2]);
|
||||
}
|
||||
else
|
||||
{
|
||||
VectorSet(trace_up, 0, 0, 1);
|
||||
}
|
||||
|
||||
// sweep the box through the model
|
||||
trace = CM_BoxTrace (mod, start_l, end_l, mins, maxs, capsule, brushmask);
|
||||
|
||||
if (rotated && trace.fraction != 1.0)
|
||||
{
|
||||
// FIXME: figure out how to do this with existing angles
|
||||
VectorNegate (angles, a);
|
||||
AngleVectors (a, forward, right, up);
|
||||
|
||||
VectorCopy (trace.plane.normal, temp);
|
||||
trace.plane.normal[0] = DotProduct (temp, forward);
|
||||
trace.plane.normal[1] = -DotProduct (temp, right);
|
||||
trace.plane.normal[2] = DotProduct (temp, up);
|
||||
}
|
||||
|
||||
if (trace.fraction == 1)
|
||||
{
|
||||
VectorCopy(end, trace.endpos);
|
||||
}
|
||||
else
|
||||
{
|
||||
trace.endpos[0] = start[0] + trace.fraction * (end[0] - start[0]);
|
||||
trace.endpos[1] = start[1] + trace.fraction * (end[1] - start[1]);
|
||||
trace.endpos[2] = start[2] + trace.fraction * (end[2] - start[2]);
|
||||
}
|
||||
|
||||
return trace;
|
||||
}
|
||||
|
||||
#ifdef _MSC_VER
|
||||
#pragma optimize( "", on )
|
||||
#endif
|
||||
|
||||
|
||||
|
||||
/*
|
||||
===============================================================================
|
||||
|
||||
|
|
|
@ -5689,7 +5689,8 @@ void QCBUILTIN PF_brush_get(pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
|
|||
|
||||
//assume the worst.
|
||||
G_INT(OFS_RETURN) = 0;
|
||||
*out_contents = 0;
|
||||
if (G_INT(OFS_PARM4))
|
||||
*out_contents = 0;
|
||||
|
||||
if (!hm)
|
||||
return;
|
||||
|
@ -5699,23 +5700,29 @@ void QCBUILTIN PF_brush_get(pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
|
|||
br = &hm->wbrushes[i];
|
||||
if (br->id == brushid)
|
||||
{
|
||||
*out_contents = br->contents;
|
||||
maxfaces = min(br->numplanes, maxfaces);
|
||||
|
||||
for (fa = 0; fa < maxfaces; fa++)
|
||||
if (G_INT(OFS_PARM4))
|
||||
*out_contents = br->contents;
|
||||
if (!G_INT(OFS_PARM2))
|
||||
G_INT(OFS_RETURN) = br->numplanes;
|
||||
else
|
||||
{
|
||||
out_faces->shadername = PR_TempString(prinst, br->faces[fa].tex->shadername);
|
||||
VectorCopy(br->planes[fa], out_faces->planenormal);
|
||||
out_faces->planedist = br->planes[fa][3];
|
||||
maxfaces = min(br->numplanes, maxfaces);
|
||||
|
||||
VectorCopy(br->faces[fa].stdir[0], out_faces->sdir);
|
||||
out_faces->sbias = br->faces[fa].stdir[0][3];
|
||||
VectorCopy(br->faces[fa].stdir[1], out_faces->tdir);
|
||||
out_faces->tbias = br->faces[fa].stdir[1][3];
|
||||
for (fa = 0; fa < maxfaces; fa++)
|
||||
{
|
||||
out_faces->shadername = PR_TempString(prinst, br->faces[fa].tex->shadername);
|
||||
VectorCopy(br->planes[fa], out_faces->planenormal);
|
||||
out_faces->planedist = br->planes[fa][3];
|
||||
|
||||
out_faces++;
|
||||
VectorCopy(br->faces[fa].stdir[0], out_faces->sdir);
|
||||
out_faces->sbias = br->faces[fa].stdir[0][3];
|
||||
VectorCopy(br->faces[fa].stdir[1], out_faces->tdir);
|
||||
out_faces->tbias = br->faces[fa].stdir[1][3];
|
||||
|
||||
out_faces++;
|
||||
}
|
||||
G_INT(OFS_RETURN) = fa;
|
||||
}
|
||||
G_INT(OFS_RETURN) = fa;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1042,7 +1042,7 @@ int CM_BoxLeafnums (struct model_s *mod, vec3_t mins, vec3_t maxs, int *list, i
|
|||
int CM_PointContents (struct model_s *mod, vec3_t p);
|
||||
int CM_TransformedPointContents (struct model_s *mod, vec3_t p, int headnode, vec3_t origin, vec3_t angles);
|
||||
int CM_HeadnodeForBox (struct model_s *mod, vec3_t mins, vec3_t maxs);
|
||||
struct trace_s CM_TransformedBoxTrace (struct model_s *mod, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int brushmask, vec3_t origin, vec3_t angles);
|
||||
//struct trace_s CM_TransformedBoxTrace (struct model_s *mod, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, int brushmask, vec3_t origin, vec3_t angles);
|
||||
struct model_s *CM_TempBoxModel(vec3_t mins, vec3_t maxs);
|
||||
|
||||
void CMQ2_SetAreaPortalState (model_t *mod, unsigned int portalnum, qboolean open);
|
||||
|
|
|
@ -419,14 +419,14 @@ void R_SetupGL (float stereooffset)
|
|||
}
|
||||
else
|
||||
{
|
||||
x = r_refdef.vrect.x * (int)vid.fbpwidth/(int)vid.width;
|
||||
x2 = (r_refdef.vrect.x + r_refdef.vrect.width) * (int)vid.fbpwidth/(int)vid.width;
|
||||
y = (r_refdef.vrect.y) * (int)vid.fbpheight/(int)vid.height;
|
||||
y2 = (r_refdef.vrect.y + r_refdef.vrect.height) * (int)vid.fbpheight/(int)vid.height;
|
||||
x = floor(r_refdef.vrect.x * (float)vid.fbpwidth/(float)vid.width);
|
||||
x2 = ceil((r_refdef.vrect.x + r_refdef.vrect.width) * (float)vid.fbpwidth/(float)vid.width);
|
||||
y = floor(r_refdef.vrect.y * (float)vid.fbpheight/(float)vid.height);
|
||||
y2 = ceil((r_refdef.vrect.y + r_refdef.vrect.height) * (float)vid.fbpheight/(float)vid.height);
|
||||
|
||||
|
||||
// fudge around because of frac screen scale
|
||||
if (x > 0)
|
||||
/* if (x > 0)
|
||||
x--;
|
||||
if (x2 < vid.fbpwidth)
|
||||
x2++;
|
||||
|
@ -434,7 +434,7 @@ void R_SetupGL (float stereooffset)
|
|||
y2++;
|
||||
if (y > 0)
|
||||
y--;
|
||||
|
||||
*/
|
||||
w = x2 - x;
|
||||
h = y2 - y;
|
||||
|
||||
|
|
|
@ -109,4 +109,15 @@ extern int qcc_eof;
|
|||
#define qcc_iswhitesameline(c) ((c) == ' ' || (c) == '\t')
|
||||
|
||||
|
||||
enum
|
||||
{
|
||||
UTF8_RAW,
|
||||
UTF8_BOM,
|
||||
UTF_ANSI,
|
||||
UTF16LE,
|
||||
UTF16BE,
|
||||
UTF32LE,
|
||||
UTF32BE,
|
||||
};
|
||||
|
||||
#endif
|
||||
|
|
|
@ -380,6 +380,7 @@ enum qcop_e {
|
|||
OP_BITCLR_F,
|
||||
OP_BITCLR_I,
|
||||
|
||||
OP_ADD_SI,
|
||||
OP_ADD_PF,
|
||||
OP_ADD_FP,
|
||||
OP_ADD_PI,
|
||||
|
|
|
@ -889,14 +889,6 @@ pbool SafeClose(int hand)
|
|||
|
||||
qcc_cachedsourcefile_t *qcc_sourcefile;
|
||||
|
||||
enum
|
||||
{
|
||||
UTF16LE,
|
||||
UTF16BE,
|
||||
UTF32LE,
|
||||
UTF32BE,
|
||||
};
|
||||
|
||||
//return 0 if the input is not valid utf-8.
|
||||
unsigned int utf8_check(const void *in, unsigned int *value)
|
||||
{
|
||||
|
@ -968,14 +960,15 @@ static char *decodeUTF(int type, unsigned char *inputf, unsigned int inbytes, un
|
|||
maxperchar = 4;
|
||||
break;
|
||||
default:
|
||||
*outlen = inbytes;
|
||||
return (char*)inputf;
|
||||
//error
|
||||
*outlen = 0;
|
||||
return NULL;
|
||||
}
|
||||
chars = inbytes / w;
|
||||
if (usemalloc)
|
||||
utf8 = start = malloc(chars * maxperchar + 2);
|
||||
utf8 = start = malloc(chars * maxperchar + 2+1);
|
||||
else
|
||||
utf8 = start = qccHunkAlloc(chars * maxperchar + 2);
|
||||
utf8 = start = qccHunkAlloc(chars * maxperchar + 2+1);
|
||||
for (i = 0; i < chars; i++)
|
||||
{
|
||||
switch(type)
|
||||
|
@ -1048,6 +1041,7 @@ static char *decodeUTF(int type, unsigned char *inputf, unsigned int inbytes, un
|
|||
}
|
||||
}
|
||||
*outlen = utf8 - start;
|
||||
*utf8 = 0;
|
||||
return start;
|
||||
}
|
||||
|
||||
|
@ -1107,6 +1101,66 @@ unsigned short *QCC_makeutf16(char *mem, unsigned int len, int *outlen)
|
|||
return outstart;
|
||||
}
|
||||
|
||||
//input is a raw file (will not be changed
|
||||
//output is utf-8 data
|
||||
char *QCC_SanitizeCharSet(char *mem, unsigned int *len, pbool *freeresult, int *origfmt)
|
||||
{
|
||||
if (freeresult)
|
||||
*freeresult = true;
|
||||
if (*len >= 4 && mem[0] == '\xff' && mem[1] == '\xfe' && mem[2] == '\x00' && mem[3] == '\x00')
|
||||
mem = decodeUTF(*origfmt=UTF32LE, (unsigned char*)mem+4, *len-4, len, !!freeresult);
|
||||
else if (*len >= 4 && mem[0] == '\x00' && mem[1] == '\x00' && mem[2] == '\xfe' && mem[3] == '\xff')
|
||||
mem = decodeUTF(*origfmt=UTF32BE, (unsigned char*)mem+4, *len-4, len, !!freeresult);
|
||||
else if (*len >= 2 && mem[0] == '\xff' && mem[1] == '\xfe')
|
||||
mem = decodeUTF(*origfmt=UTF16LE, (unsigned char*)mem+2, *len-2, len, !!freeresult);
|
||||
else if (*len >= 2 && mem[0] == '\xfe' && mem[1] == '\xff')
|
||||
mem = decodeUTF(*origfmt=UTF16BE, (unsigned char*)mem+2, *len-2, len, !!freeresult);
|
||||
//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')
|
||||
{
|
||||
*origfmt=UTF8_BOM;
|
||||
mem += 3;
|
||||
*len -= 3;
|
||||
if (freeresult)
|
||||
*freeresult = false;
|
||||
}
|
||||
else
|
||||
{
|
||||
*origfmt=UTF8_RAW;
|
||||
if (freeresult)
|
||||
*freeresult = false;
|
||||
/*
|
||||
#ifdef _WIN32
|
||||
//even if we wrote the bom, resaving with wordpad will translate the file to the system's active code page, which will fuck up any comments. thanks for that, wordpad.
|
||||
//(weirdly, notepad does the right thing)
|
||||
int wchars = MultiByteToWideChar(CP_ACP, 0, mem, *len, NULL, 0);
|
||||
|
||||
if (wchars)
|
||||
{
|
||||
BOOL failed = false;
|
||||
wchar_t *wc = malloc(wchars * sizeof(wchar_t));
|
||||
int mchars;
|
||||
MultiByteToWideChar(CP_ACP, 0, mem, *len, wc, wchars);
|
||||
mchars = WideCharToMultiByte(CP_UTF8, 0, wc, wchars, NULL, 0, NULL, NULL);
|
||||
if (mchars && !failed)
|
||||
{
|
||||
mem = (freeresult?malloc(mchars+2):qccHunkAlloc(mchars+2));
|
||||
mem[mchars] = 0;
|
||||
*len = mchars;
|
||||
if (freeresult)
|
||||
*freeresult = true;
|
||||
WideCharToMultiByte(CP_UTF8, 0, wc, wchars, mem, mchars, NULL, NULL);
|
||||
}
|
||||
free(wc);
|
||||
}
|
||||
#endif
|
||||
*/
|
||||
}
|
||||
|
||||
|
||||
return mem;
|
||||
}
|
||||
|
||||
long QCC_LoadFile (char *filename, void **bufferptr)
|
||||
{
|
||||
char *mem;
|
||||
|
@ -1114,6 +1168,7 @@ long QCC_LoadFile (char *filename, void **bufferptr)
|
|||
int flen;
|
||||
unsigned int len;
|
||||
int line;
|
||||
int orig;
|
||||
pbool warned = false;
|
||||
flen = externs->FileSize(filename);
|
||||
if (flen < 0)
|
||||
|
@ -1132,20 +1187,8 @@ long QCC_LoadFile (char *filename, void **bufferptr)
|
|||
|
||||
externs->ReadFile(filename, mem, len+2, NULL);
|
||||
|
||||
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, 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, false);
|
||||
else if (len >= 2 && mem[0] == '\xff' && mem[1] == '\xfe')
|
||||
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;
|
||||
}
|
||||
mem = QCC_SanitizeCharSet(mem, &len, NULL, &orig);
|
||||
|
||||
//actual utf-8 handling is somewhat up to the engine. the qcc can only ensure that utf8 works in symbol names etc.
|
||||
//its only in strings where it actually makes a difference, and the interpretation of those is basically entirely up to the engine.
|
||||
//that said, we could insert a utf-8 BOM into ones with utf-8 chars, but that would mess up a lot of builtins+mods, so we won't.
|
||||
|
|
|
@ -620,6 +620,7 @@ QCC_opcode_t pr_opcodes[] =
|
|||
{7, "&~", "BITCLR_F", 6, ASSOC_LEFT, &type_float, &type_float, &type_float},
|
||||
{7, "&~", "BITCLR_I", 6, ASSOC_LEFT, &type_integer, &type_integer, &type_integer},
|
||||
|
||||
{7, "+", "ADD_SI", 4, ASSOC_LEFT, &type_string, &type_integer, &type_string},
|
||||
{7, "+", "ADD_PF", 6, ASSOC_LEFT, &type_pointer, &type_float, &type_pointer},
|
||||
{7, "+", "ADD_FP", 6, ASSOC_LEFT, &type_float, &type_pointer, &type_pointer},
|
||||
{7, "+", "ADD_PI", 6, ASSOC_LEFT, &type_pointer, &type_integer, &type_pointer},
|
||||
|
@ -1600,6 +1601,8 @@ static QCC_sref_t QCC_GetTemp(QCC_type_t *type)
|
|||
|
||||
tempsinfo[u].lastfunc = pr_scope;
|
||||
tempsinfo[u].laststatement = numstatements;
|
||||
|
||||
var_c.sym->referenced = true;
|
||||
return var_c;
|
||||
}
|
||||
|
||||
|
@ -2536,7 +2539,10 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_
|
|||
{
|
||||
//you're allowed to assign 0i to anything
|
||||
if (op - pr_opcodes == OP_STORE_V) //make sure vectors get set properly.
|
||||
{
|
||||
QCC_FreeTemp(var_a);
|
||||
var_a = QCC_MakeVectorConst(0, 0, 0);
|
||||
}
|
||||
}
|
||||
/*else
|
||||
{
|
||||
|
@ -2570,7 +2576,10 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_
|
|||
{
|
||||
//you're allowed to assign 0i to anything
|
||||
if (op - pr_opcodes == OP_STOREP_V) //make sure vectors get set properly.
|
||||
{
|
||||
QCC_FreeTemp(var_a);
|
||||
var_a = QCC_MakeVectorConst(0, 0, 0);
|
||||
}
|
||||
}
|
||||
/*else
|
||||
{
|
||||
|
@ -2765,6 +2774,29 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_
|
|||
// QCC_PR_ParseWarning(0, "OP_LOADA_STRUCT: cannot emulate");
|
||||
break;
|
||||
|
||||
case OP_ADD_SF:
|
||||
var_c = QCC_PR_GetSRef(NULL, "AddStringFloat", NULL, false, 0, 0);
|
||||
if (var_c.cast)
|
||||
{
|
||||
QCC_type_t *types[2] = {type_string, type_float};
|
||||
QCC_sref_t evals[2];
|
||||
evals[0] = var_a; //stupid msvc bug
|
||||
evals[1] = var_b;
|
||||
var_a = QCC_PR_GenerateFunctionCall(nullsref, var_c, evals, types, 2);
|
||||
}
|
||||
else
|
||||
{
|
||||
QCC_PR_ParseWarning(0, "string(string,float) AddStringFloat: emulation depends upon denormals");
|
||||
var_b = QCC_SupplyConversion(var_b, ev_integer, true); //FIXME: this should be an unconditional float->int conversion
|
||||
var_c = QCC_PR_StatementFlags(&pr_opcodes[OP_ADD_F], var_a, var_b, NULL, 0);
|
||||
}
|
||||
var_c.cast = type_string;
|
||||
return var_c;
|
||||
case OP_ADD_SI:
|
||||
QCC_PR_ParseWarning(0, "OP_ADD_SI: denormals may be unsafe");
|
||||
var_c = QCC_PR_StatementFlags(&pr_opcodes[OP_ADD_F], var_a, var_b, NULL, 0);
|
||||
var_c.cast = type_string;
|
||||
return var_c;
|
||||
case OP_ADD_PF:
|
||||
case OP_ADD_FP:
|
||||
case OP_ADD_PI:
|
||||
|
@ -2933,7 +2965,9 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_
|
|||
{
|
||||
var_c = QCC_PR_GetSRef(NULL, "itof", NULL, false, 0, 0);
|
||||
if (!var_c.cast)
|
||||
{
|
||||
QCC_PR_ParseError(0, "itof function not defined: cannot emulate int -> float conversions");
|
||||
}
|
||||
var_a = QCC_PR_GenerateFunctionCall(nullsref, var_c, &var_a, &type_integer, 1);
|
||||
var_a.cast = type_float;
|
||||
}
|
||||
|
@ -2954,8 +2988,13 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_
|
|||
{
|
||||
var_c = QCC_PR_GetSRef(NULL, "ftoi", NULL, false, 0, 0);
|
||||
if (!var_c.cast)
|
||||
QCC_PR_ParseError(0, "ftoi function not defined: cannot emulate float -> int conversions");
|
||||
var_a = QCC_PR_GenerateFunctionCall(nullsref, var_c, &var_a, &type_float, 1);
|
||||
{
|
||||
//with denormals, 5 * 1i -> 5i
|
||||
QCC_PR_ParseWarning(0, "ftoi emulation: denormals have limited precision");
|
||||
var_a = QCC_PR_StatementFlags(&pr_opcodes[OP_MUL_F], var_a, QCC_MakeIntConst(1), NULL, 0);
|
||||
}
|
||||
else
|
||||
var_a = QCC_PR_GenerateFunctionCall(nullsref, var_c, &var_a, &type_float, 1);
|
||||
var_a.cast = type_integer;
|
||||
}
|
||||
if (var_b.cast)
|
||||
|
@ -3178,6 +3217,11 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_
|
|||
var_c = var_b;
|
||||
var_b = var_a;
|
||||
var_a = var_c;
|
||||
if (QCC_OPCodeValid(&pr_opcodes[OP_BITCLRSTORE_I]))
|
||||
{
|
||||
op = &pr_opcodes[OP_BITCLRSTORE_I];
|
||||
break;
|
||||
}
|
||||
//fallthrough
|
||||
case OP_BITCLRSTORE_I:
|
||||
//b = var, a = bit field.
|
||||
|
@ -3192,6 +3236,11 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_
|
|||
var_c = var_b;
|
||||
var_b = var_a;
|
||||
var_a = var_c;
|
||||
if (QCC_OPCodeValid(&pr_opcodes[OP_BITCLRSTORE_F]))
|
||||
{
|
||||
op = &pr_opcodes[OP_BITCLRSTORE_F];
|
||||
break;
|
||||
}
|
||||
//fallthrough
|
||||
case OP_BITCLRSTORE_F:
|
||||
//b = var, a = bit field.
|
||||
|
@ -3594,11 +3643,20 @@ QCC_sref_t QCC_PR_StatementFlags ( QCC_opcode_t *op, QCC_sref_t var_a, QCC_sref_
|
|||
statement->b = var_b;
|
||||
|
||||
if (var_c.cast && var_c.sym && !var_c.sym->referenced)
|
||||
printf("that wasn't referenced\n");
|
||||
if (var_b.cast && var_a.sym && !var_b.sym->referenced)
|
||||
printf("that wasn't referenced\n");
|
||||
if (var_a.cast && var_b.sym && !var_a.sym->referenced)
|
||||
printf("that wasn't referenced\n");
|
||||
{
|
||||
QCC_PR_ParseWarning(WARN_DEBUGGING, "INTERNAL: var_c was not referenced");
|
||||
QCC_PR_ParsePrintSRef(WARN_DEBUGGING, var_c);
|
||||
}
|
||||
if (var_b.cast && var_b.sym && !var_b.sym->referenced)
|
||||
{
|
||||
QCC_PR_ParseWarning(WARN_DEBUGGING, "INTERNAL: var_b was not referenced");
|
||||
QCC_PR_ParsePrintSRef(WARN_DEBUGGING, var_b);
|
||||
}
|
||||
if (var_a.cast && var_a.sym && !var_a.sym->referenced)
|
||||
{
|
||||
QCC_PR_ParseWarning(WARN_DEBUGGING, "INTERNAL: var_a was not referenced");
|
||||
QCC_PR_ParsePrintSRef(WARN_DEBUGGING, var_a);
|
||||
}
|
||||
|
||||
if (var_c.cast)
|
||||
statement->c = var_c;
|
||||
|
@ -5692,6 +5750,8 @@ static QCC_ref_t *QCC_PR_ParseField(QCC_ref_t *refbuf, QCC_ref_t *lhs)
|
|||
}
|
||||
|
||||
lhs = QCC_PR_ParseField(refbuf, lhs);
|
||||
|
||||
lhs = QCC_PR_ParseRefArrayPointer (refbuf, lhs, false, false);
|
||||
}
|
||||
else if (t->accessors && (QCC_PR_CheckToken(".") || QCC_PR_CheckToken("->")))
|
||||
{
|
||||
|
@ -9177,7 +9237,8 @@ void QCC_PR_ParseState (void)
|
|||
s1 = QCC_PR_Expression (TOP_PRIORITY, EXPR_DISALLOW_COMMA);
|
||||
s1 = QCC_SupplyConversion(s1, ev_float, true);
|
||||
|
||||
QCC_PR_Expect (",");
|
||||
if (!QCC_PR_CheckToken (","))
|
||||
QCC_PR_ParseWarning(WARN_UNEXPECTEDPUNCT, "missing comma in state definition");
|
||||
|
||||
pr_assumetermtype = type_function;
|
||||
def = QCC_PR_Expression (TOP_PRIORITY, EXPR_DISALLOW_COMMA);
|
||||
|
@ -11225,7 +11286,7 @@ QCC_sref_t QCC_PR_GetSRef (QCC_type_t *type, char *name, QCC_function_t *scope,
|
|||
return nullsref;
|
||||
}
|
||||
|
||||
QCC_def_t *QCC_PR_DummyFieldDef(QCC_type_t *type, char *name, QCC_function_t *scope, int arraysize, unsigned int *fieldofs, pbool saved)
|
||||
QCC_def_t *QCC_PR_DummyFieldDef(QCC_type_t *type, char *name, QCC_function_t *scope, int arraysize, unsigned int *fieldofs, unsigned int saved)
|
||||
{
|
||||
char array[64];
|
||||
char newname[256];
|
||||
|
@ -11326,7 +11387,7 @@ QCC_def_t *QCC_PR_DummyFieldDef(QCC_type_t *type, char *name, QCC_function_t *sc
|
|||
def = QCC_PR_GetDef(ftype, newname, scope, true, 0, saved);
|
||||
if (parttype->type == ev_function)
|
||||
def->initialized = true;
|
||||
((int *)qcc_pr_globals)[def->ofs] = *fieldofs;
|
||||
def->symboldata->_int = *fieldofs;
|
||||
*fieldofs += parttype->size;
|
||||
}
|
||||
else
|
||||
|
@ -11334,6 +11395,7 @@ QCC_def_t *QCC_PR_DummyFieldDef(QCC_type_t *type, char *name, QCC_function_t *sc
|
|||
QCC_PR_ParseWarning(WARN_CONFLICTINGUNIONMEMBER, "conflicting offsets for union/struct expansion of %s. Ignoring new def.", newname);
|
||||
QCC_PR_ParsePrintDef(WARN_CONFLICTINGUNIONMEMBER, def);
|
||||
}
|
||||
QCC_FreeDef(def);
|
||||
break;
|
||||
case ev_void:
|
||||
break;
|
||||
|
@ -11355,7 +11417,7 @@ QCC_def_t *QCC_PR_DummyFieldDef(QCC_type_t *type, char *name, QCC_function_t *sc
|
|||
void QCC_PR_ExpandUnionToFields(QCC_type_t *type, unsigned int *fields)
|
||||
{
|
||||
QCC_type_t *pass = type->aux_type;
|
||||
QCC_PR_DummyFieldDef(pass, "", pr_scope, 1, fields, true);
|
||||
QCC_PR_DummyFieldDef(pass, "", pr_scope, 1, fields, GDF_SAVED|GDF_CONST);
|
||||
}
|
||||
|
||||
void QCC_PR_ParseInitializerType(int arraysize, QCC_def_t *basedef, QCC_sref_t def)
|
||||
|
|
|
@ -234,6 +234,7 @@ typedef struct editor_s {
|
|||
int curline;
|
||||
pbool modified;
|
||||
pbool scintilla;
|
||||
int savefmt;
|
||||
time_t filemodifiedtime;
|
||||
struct editor_s *next;
|
||||
} editor_t;
|
||||
|
@ -1069,7 +1070,7 @@ void GenericMenu(WPARAM wParam)
|
|||
break;
|
||||
|
||||
case IDM_ABOUT:
|
||||
MessageBox(NULL, "FTE QuakeC Compiler ("__DATE__" "__TIME__")\nWritten by Forethought Entertainment, whoever that is.\n\n", "About", 0);
|
||||
MessageBox(NULL, "FTE QuakeC Compiler ("__DATE__" "__TIME__")\nWritten by Forethought Entertainment, whoever that is.\n\nIf you have problems with wordpad corrupting your qc files, try saving them using utf-16 encoding via notepad.", "About", 0);
|
||||
break;
|
||||
|
||||
case IDM_CASCADE:
|
||||
|
@ -1796,23 +1797,31 @@ static LRESULT CALLBACK EditorWndProc(HWND hWnd,UINT message,
|
|||
}
|
||||
|
||||
unsigned short *QCC_makeutf16(char *mem, unsigned int len, int *outlen);
|
||||
char *QCC_SanitizeCharSet(char *mem, unsigned int *len, pbool *freeresult, int *origfmt);
|
||||
static void EditorReload(editor_t *editor)
|
||||
{
|
||||
struct stat sbuf;
|
||||
int flen;
|
||||
char *rawfile;
|
||||
char *file;
|
||||
pbool dofree;
|
||||
|
||||
flen = QCC_RawFileSize(editor->filename);
|
||||
if (flen >= 0)
|
||||
{
|
||||
file = malloc(flen+1);
|
||||
rawfile = malloc(flen+1);
|
||||
|
||||
QCC_ReadFile(editor->filename, file, flen, NULL);
|
||||
QCC_ReadFile(editor->filename, rawfile, flen, NULL);
|
||||
|
||||
file[flen] = 0;
|
||||
rawfile[flen] = 0;
|
||||
}
|
||||
else
|
||||
file = NULL;
|
||||
{
|
||||
rawfile = NULL;
|
||||
flen = 0;
|
||||
}
|
||||
|
||||
file = QCC_SanitizeCharSet(rawfile, &flen, &dofree, &editor->savefmt);
|
||||
|
||||
stat(editor->filename, &sbuf);
|
||||
editor->filemodifiedtime = sbuf.st_mtime;
|
||||
|
@ -1849,7 +1858,9 @@ static void EditorReload(editor_t *editor)
|
|||
SendMessage(editor->editpane, EM_SETEVENTMASK, 0, ENM_SELCHANGE|ENM_CHANGE);
|
||||
}
|
||||
|
||||
free(file);
|
||||
if (dofree)
|
||||
free(file);
|
||||
free(rawfile);
|
||||
|
||||
editor->modified = false;
|
||||
}
|
||||
|
@ -1916,6 +1927,7 @@ void EditFile(char *name, int line, pbool setcontrol)
|
|||
neweditor->next = editors;
|
||||
editors = neweditor;
|
||||
|
||||
neweditor->savefmt = UTF8_RAW;
|
||||
strncpy(neweditor->filename, name, sizeof(neweditor->filename)-1);
|
||||
|
||||
if (!mdibox)
|
||||
|
@ -2016,24 +2028,88 @@ int EditorSave(editor_t *edit)
|
|||
int len;
|
||||
wchar_t *wfile;
|
||||
char *afile;
|
||||
BOOL failed = TRUE;
|
||||
int saved = false;
|
||||
if (edit->scintilla)
|
||||
{
|
||||
//wordpad will corrupt any embedded quake chars if we force a bom, because it'll re-save using the wrong char encoding by default.
|
||||
int bomlen = 0;
|
||||
if (edit->savefmt == UTF32BE || edit->savefmt == UTF32LE || edit->savefmt == UTF16BE)
|
||||
edit->savefmt = UTF16LE;
|
||||
|
||||
if (edit->savefmt == UTF8_BOM)
|
||||
bomlen = 3;
|
||||
else if (edit->savefmt == UTF16BE || edit->savefmt == UTF16LE)
|
||||
bomlen = 2;
|
||||
else if (edit->savefmt == UTF32BE || edit->savefmt == UTF32LE)
|
||||
bomlen = 4;
|
||||
len = SendMessage(edit->editpane, SCI_GETLENGTH, 0, 0);
|
||||
afile = malloc(len+1);
|
||||
afile = malloc(bomlen+len+1);
|
||||
if (!afile)
|
||||
{
|
||||
MessageBox(NULL, "Save failed - not enough mem", "Error", 0);
|
||||
return false;
|
||||
}
|
||||
SendMessage(edit->editpane, SCI_GETTEXT, len+1, (LPARAM)afile);
|
||||
if (!QCC_WriteFile(edit->filename, afile, len))
|
||||
if (bomlen == 3)
|
||||
memcpy(afile, "\xEF\xBB\xBF", bomlen);
|
||||
else
|
||||
memcpy(afile, "\xFF\xFE\x00\x00", bomlen); //utf-16le or utf-32le. don't bother with be
|
||||
SendMessage(edit->editpane, SCI_GETTEXT, len+1, bomlen+(LPARAM)afile);
|
||||
|
||||
//because wordpad saves in ansi by default instead of the format the file was originally saved in, we HAVE to use ansi without
|
||||
if (edit->savefmt != UTF8_BOM && edit->savefmt != UTF8_RAW)
|
||||
{
|
||||
int mchars;
|
||||
char *mc;
|
||||
int wchars = MultiByteToWideChar(CP_UTF8, 0, afile, len, NULL, 0);
|
||||
if (wchars)
|
||||
{
|
||||
wchar_t *wc = malloc(wchars * sizeof(wchar_t));
|
||||
MultiByteToWideChar(CP_UTF8, 0, afile, len, wc, wchars);
|
||||
|
||||
if (edit->savefmt == UTF_ANSI)
|
||||
{
|
||||
mchars = WideCharToMultiByte(CP_ACP, 0, wc, wchars, NULL, 0, "", &failed);
|
||||
if (mchars)
|
||||
{
|
||||
mc = malloc(mchars);
|
||||
WideCharToMultiByte(CP_ACP, 0, wc, wchars, mc, mchars, "", &failed);
|
||||
if (!failed)
|
||||
{
|
||||
if (!QCC_WriteFile(edit->filename, mc, mchars))
|
||||
saved = -1;
|
||||
else
|
||||
saved = true;
|
||||
}
|
||||
free(mc);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (!QCC_WriteFile(edit->filename, wc, wchars))
|
||||
saved = -1;
|
||||
else
|
||||
saved = true;
|
||||
}
|
||||
free(wc);
|
||||
}
|
||||
}
|
||||
|
||||
if (!saved)
|
||||
{
|
||||
if (!QCC_WriteFile(edit->filename, afile, bomlen+len))
|
||||
saved = -1;
|
||||
else
|
||||
saved = true;
|
||||
}
|
||||
free(afile);
|
||||
if (saved < 0)
|
||||
{
|
||||
free(afile);
|
||||
MessageBox(NULL, "Save failed\nCheck path and ReadOnly flags", "Failure", 0);
|
||||
return false;
|
||||
}
|
||||
SendMessage(edit->editpane, SCI_SETSAVEPOINT, 0, 0);
|
||||
free(afile);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
@ -3771,9 +3847,202 @@ void GUIPrint(HWND wnd, char *msg)
|
|||
}
|
||||
writing=false;
|
||||
}
|
||||
|
||||
unsigned int utf8_decode(int *error, const void *in, char **out)
|
||||
{
|
||||
//uc is the output unicode char
|
||||
unsigned int uc = 0xfffdu; //replacement character
|
||||
//l is the length
|
||||
unsigned int l = 1;
|
||||
const unsigned char *str = in;
|
||||
|
||||
if ((*str & 0xe0) == 0xc0)
|
||||
{
|
||||
if ((str[1] & 0xc0) == 0x80)
|
||||
{
|
||||
l = 2;
|
||||
uc = ((str[0] & 0x1f)<<6) | (str[1] & 0x3f);
|
||||
if (!uc || uc >= (1u<<7)) //allow modified utf-8
|
||||
*error = 0;
|
||||
else
|
||||
*error = 2;
|
||||
}
|
||||
else *error = 1;
|
||||
}
|
||||
else if ((*str & 0xf0) == 0xe0)
|
||||
{
|
||||
if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80)
|
||||
{
|
||||
l = 3;
|
||||
uc = ((str[0] & 0x0f)<<12) | ((str[1] & 0x3f)<<6) | ((str[2] & 0x3f)<<0);
|
||||
if (uc >= (1u<<11))
|
||||
*error = 0;
|
||||
else
|
||||
*error = 2;
|
||||
}
|
||||
else *error = 1;
|
||||
}
|
||||
else if ((*str & 0xf8) == 0xf0)
|
||||
{
|
||||
if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 && (str[3] & 0xc0) == 0x80)
|
||||
{
|
||||
l = 4;
|
||||
uc = ((str[0] & 0x07)<<18) | ((str[1] & 0x3f)<<12) | ((str[2] & 0x3f)<<6) | ((str[3] & 0x3f)<<0);
|
||||
if (uc >= (1u<<16))
|
||||
*error = 0;
|
||||
else
|
||||
*error = 2;
|
||||
}
|
||||
else *error = 1;
|
||||
}
|
||||
else if ((*str & 0xfc) == 0xf8)
|
||||
{
|
||||
if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 && (str[3] & 0xc0) == 0x80 && (str[4] & 0xc0) == 0x80)
|
||||
{
|
||||
l = 5;
|
||||
uc = ((str[0] & 0x03)<<24) | ((str[1] & 0x3f)<<18) | ((str[2] & 0x3f)<<12) | ((str[3] & 0x3f)<<6) | ((str[4] & 0x3f)<<0);
|
||||
if (uc >= (1u<<21))
|
||||
*error = 0;
|
||||
else
|
||||
*error = 2;
|
||||
}
|
||||
else *error = 1;
|
||||
}
|
||||
else if ((*str & 0xfe) == 0xfc)
|
||||
{
|
||||
//six bytes
|
||||
if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 && (str[3] & 0xc0) == 0x80 && (str[4] & 0xc0) == 0x80)
|
||||
{
|
||||
l = 6;
|
||||
uc = ((str[0] & 0x01)<<30) | ((str[1] & 0x3f)<<24) | ((str[2] & 0x3f)<<18) | ((str[3] & 0x3f)<<12) | ((str[4] & 0x3f)<<6) | ((str[5] & 0x3f)<<0);
|
||||
if (uc >= (1u<<26))
|
||||
*error = 0;
|
||||
else
|
||||
*error = 2;
|
||||
}
|
||||
else *error = 1;
|
||||
}
|
||||
//0xfe and 0xff, while plausable leading bytes, are not permitted.
|
||||
#if 0
|
||||
else if ((*str & 0xff) == 0xfe)
|
||||
{
|
||||
if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 && (str[3] & 0xc0) == 0x80 && (str[4] & 0xc0) == 0x80)
|
||||
{
|
||||
l = 7;
|
||||
uc = 0 | ((str[1] & 0x3f)<<30) | ((str[2] & 0x3f)<<24) | ((str[3] & 0x3f)<<18) | ((str[4] & 0x3f)<<12) | ((str[5] & 0x3f)<<6) | ((str[6] & 0x3f)<<0);
|
||||
if (uc >= (1u<<31))
|
||||
*error = 0;
|
||||
else
|
||||
*error = 2;
|
||||
}
|
||||
else *error = 1;
|
||||
}
|
||||
else if ((*str & 0xff) == 0xff)
|
||||
{
|
||||
if ((str[1] & 0xc0) == 0x80 && (str[2] & 0xc0) == 0x80 && (str[3] & 0xc0) == 0x80 && (str[4] & 0xc0) == 0x80)
|
||||
{
|
||||
l = 8;
|
||||
uc = 0 | ((str[1] & 0x3f)<<36) | ((str[2] & 0x3f)<<30) | ((str[3] & 0x3f)<<24) | ((str[4] & 0x3f)<<18) | ((str[5] & 0x3f)<<12) | ((str[6] & 0x3f)<<6) | ((str[7] & 0x3f)<<0);
|
||||
if (uc >= (1llu<<36))
|
||||
*error = false;
|
||||
else
|
||||
*error = 2;
|
||||
}
|
||||
else *error = 1;
|
||||
}
|
||||
#endif
|
||||
else if (*str & 0x80)
|
||||
{
|
||||
//sequence error
|
||||
*error = 1;
|
||||
uc = 0xe000u + *str;
|
||||
}
|
||||
else
|
||||
{
|
||||
//ascii char
|
||||
*error = 0;
|
||||
uc = *str;
|
||||
}
|
||||
|
||||
*out = (void*)(str + l);
|
||||
|
||||
if (!*error)
|
||||
{
|
||||
//try to deal with surrogates by decoding the low if we see a high.
|
||||
if (uc >= 0xd800u && uc < 0xdc00u)
|
||||
{
|
||||
#if 1
|
||||
//cesu-8
|
||||
char *lowend;
|
||||
unsigned int lowsur = utf8_decode(error, str + l, &lowend);
|
||||
if (*error == 4)
|
||||
{
|
||||
*out = lowend;
|
||||
uc = (((uc&0x3ffu) << 10) | (lowsur&0x3ffu)) + 0x10000;
|
||||
*error = false;
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
*error = 3; //bad - lead surrogate without tail.
|
||||
}
|
||||
}
|
||||
if (uc >= 0xdc00u && uc < 0xe000u)
|
||||
*error = 4; //bad - tail surrogate
|
||||
|
||||
//these are meant to be illegal too
|
||||
if (uc == 0xfffeu || uc == 0xffffu || uc > 0x10ffffu)
|
||||
*error = 2; //illegal code
|
||||
}
|
||||
|
||||
return uc;
|
||||
}
|
||||
//outlen is the size of out in _BYTES_.
|
||||
wchar_t *widen(wchar_t *out, size_t outbytes, const char *utf8, const char *stripchars)
|
||||
{
|
||||
size_t outlen;
|
||||
wchar_t *ret = out;
|
||||
//utf-8 to utf-16, not ucs-2.
|
||||
unsigned int codepoint;
|
||||
int error;
|
||||
outlen = outbytes/sizeof(wchar_t);
|
||||
if (!outlen)
|
||||
return L"";
|
||||
outlen--;
|
||||
while (*utf8)
|
||||
{
|
||||
if (stripchars && strchr(stripchars, *utf8))
|
||||
{ //skip certain ascii chars
|
||||
utf8++;
|
||||
continue;
|
||||
}
|
||||
codepoint = utf8_decode(&error, utf8, (void*)&utf8);
|
||||
if (error || codepoint > 0x10FFFFu)
|
||||
codepoint = 0xFFFDu;
|
||||
if (codepoint > 0xffff)
|
||||
{
|
||||
if (outlen < 2)
|
||||
break;
|
||||
outlen -= 2;
|
||||
codepoint -= 0x10000u;
|
||||
*out++ = 0xD800 | (codepoint>>10);
|
||||
*out++ = 0xDC00 | (codepoint&0x3ff);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (outlen < 1)
|
||||
break;
|
||||
outlen -= 1;
|
||||
*out++ = codepoint;
|
||||
}
|
||||
}
|
||||
*out = 0;
|
||||
return ret;
|
||||
}
|
||||
int GUIEmitOutputText(HWND wnd, int start, char *text, int len, DWORD colour)
|
||||
{
|
||||
int c, cr;
|
||||
wchar_t wc[2048];
|
||||
int c;
|
||||
CHARFORMAT cf;
|
||||
|
||||
if (!len)
|
||||
|
@ -3781,17 +4050,12 @@ int GUIEmitOutputText(HWND wnd, int start, char *text, int len, DWORD colour)
|
|||
|
||||
c = text[len];
|
||||
text[len] = '\0';
|
||||
Edit_SetSel(wnd,start,start);
|
||||
Edit_ReplaceSel(wnd,text);
|
||||
|
||||
// wc = QCC_makeutf16(text, len, &ol);
|
||||
widen(wc, sizeof(wc), text, "\r");
|
||||
text[len] = c;
|
||||
|
||||
cr = 0;
|
||||
for (c = 0; c < len; c++)
|
||||
if (text[c] == '\r')
|
||||
cr++;
|
||||
if (cr)
|
||||
len-=cr;
|
||||
Edit_SetSel(wnd,start,start);
|
||||
SendMessageW(wnd, EM_REPLACESEL, 0L, (LPARAM)wc);
|
||||
len = wcslen(wc);
|
||||
|
||||
Edit_SetSel(wnd,start,start+len);
|
||||
memset(&cf, 0, sizeof(cf));
|
||||
|
@ -3806,6 +4070,7 @@ int GUIEmitOutputText(HWND wnd, int start, char *text, int len, DWORD colour)
|
|||
}
|
||||
int outlen;
|
||||
int outstatus;
|
||||
pbool gui_doannotates;
|
||||
int GUIprintf(const char *msg, ...)
|
||||
{
|
||||
va_list argptr;
|
||||
|
@ -3847,10 +4112,13 @@ int GUIprintf(const char *msg, ...)
|
|||
outstatus = 0;
|
||||
|
||||
|
||||
for (ed = editors; ed; ed = ed->next)
|
||||
if (gui_doannotates)
|
||||
{
|
||||
if (ed->scintilla)
|
||||
SendMessage(ed->editpane, SCI_ANNOTATIONCLEARALL, 0, 0);
|
||||
for (ed = editors; ed; ed = ed->next)
|
||||
{
|
||||
if (ed->scintilla)
|
||||
SendMessage(ed->editpane, SCI_ANNOTATIONCLEARALL, 0, 0);
|
||||
}
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
@ -3891,6 +4159,7 @@ int GUIprintf(const char *msg, ...)
|
|||
outlen = GUIEmitOutputText(outputbox, outlen, rn, 1, col);
|
||||
}
|
||||
|
||||
if (gui_doannotates)
|
||||
{
|
||||
char *colon1 = strchr(st, ':');
|
||||
if (colon1)
|
||||
|
@ -4060,11 +4329,13 @@ void RunCompiler(char *args, pbool quick)
|
|||
}
|
||||
|
||||
|
||||
void CreateOutputWindow(void)
|
||||
void CreateOutputWindow(pbool doannoates)
|
||||
{
|
||||
WNDCLASS wndclass;
|
||||
MDICREATESTRUCT mcs;
|
||||
|
||||
gui_doannotates = doannoates;
|
||||
|
||||
if (!mdibox) //should already be created
|
||||
return;
|
||||
|
||||
|
@ -4149,7 +4420,7 @@ int GrepSubFiles(HTREEITEM node, char *string)
|
|||
void GrepAllFiles(char *string)
|
||||
{
|
||||
int found;
|
||||
CreateOutputWindow();
|
||||
CreateOutputWindow(false);
|
||||
GUIprintf("");
|
||||
found = GrepSubFiles(TreeView_GetChild(projecttree, TVI_ROOT), string);
|
||||
if (found)
|
||||
|
@ -4456,7 +4727,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
|
|||
|
||||
if (fl_compileonstart)
|
||||
{
|
||||
CreateOutputWindow();
|
||||
CreateOutputWindow(false);
|
||||
RunCompiler(lpCmdLine, false);
|
||||
}
|
||||
else
|
||||
|
@ -4500,7 +4771,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
|
|||
{
|
||||
if (buttons[ID_COMPILE].washit)
|
||||
{
|
||||
CreateOutputWindow();
|
||||
CreateOutputWindow(true);
|
||||
RunCompiler(parameters, false);
|
||||
|
||||
buttons[ID_COMPILE].washit = false;
|
||||
|
|
|
@ -90,9 +90,9 @@ void GoToDefinition(char *name)
|
|||
{
|
||||
//with functions, the def is the prototype.
|
||||
//we want the body, so zoom to the first statement of the function instead
|
||||
if (def->type->type == ev_function && def->constant)
|
||||
if (def->type->type == ev_function && def->constant && !def->arraysize)
|
||||
{
|
||||
fnc = &functions[((int *)qcc_pr_globals)[def->ofs]];
|
||||
fnc = &functions[def->symboldata->function];
|
||||
if (fnc->code>=0 && fnc->s_file)
|
||||
{
|
||||
EditFile(strings+fnc->s_file, statements[fnc->code].linenum-1, false);
|
||||
|
|
|
@ -815,7 +815,8 @@ void QCC_UnmarshalLocals(void)
|
|||
}
|
||||
}
|
||||
numpr_globals = biggest;
|
||||
printf("%i shared locals, %i private, %i total\n", biggest - onum, onum - eog, numpr_globals-eog);
|
||||
if (verbose)
|
||||
printf("%i shared locals, %i private, %i total\n", biggest - onum, onum - eog, numpr_globals-eog);
|
||||
}
|
||||
|
||||
|
||||
|
|
|
@ -1772,7 +1772,10 @@ void SV_ClientProtocolExtensionsChanged(client_t *client)
|
|||
{
|
||||
client->max_net_clients = NQMAX_CLIENTS;
|
||||
client->datagram.maxsize = MAX_NQDATAGRAM; //vanilla limit
|
||||
client->max_net_ents = bound(512, pr_maxedicts.ival, 600);
|
||||
if (client->protocol == SCP_PROQUAKE)
|
||||
client->max_net_ents = bound(512, pr_maxedicts.ival, 8192);
|
||||
else
|
||||
client->max_net_ents = bound(512, pr_maxedicts.ival, 600);
|
||||
}
|
||||
|
||||
if (client->fteprotocolextensions2 & PEXT2_MAXPLAYERS)
|
||||
|
|
|
@ -1538,7 +1538,7 @@ void SVQW_Spawn_f (void)
|
|||
}
|
||||
if (host_client->prespawn_stage != PRESPAWN_DONE)
|
||||
{
|
||||
Con_Printf ("client sent spawn without prespawn!\n");
|
||||
Con_Printf ("%s sent spawn without prespawn!\n", host_client->name);
|
||||
SV_New_f ();
|
||||
return;
|
||||
}
|
||||
|
|
|
@ -574,16 +574,23 @@ static int SVQ3_Contact(vec3_t mins, vec3_t maxs, q3sharedEntity_t *ent, qboolea
|
|||
{
|
||||
model_t *mod;
|
||||
trace_t tr;
|
||||
float *ang;
|
||||
|
||||
if (ent->r.bmodel)
|
||||
{
|
||||
ang = ent->r.currentAngles;
|
||||
mod = Q3G_GetCModel(ent->s.modelindex);
|
||||
}
|
||||
else
|
||||
{
|
||||
ang = vec3_origin;
|
||||
mod = CM_TempBoxModel(ent->r.mins, ent->r.maxs);
|
||||
}
|
||||
|
||||
if (!mod || !mod->funcs.NativeTrace)
|
||||
return false;
|
||||
|
||||
tr = CM_TransformedBoxTrace(mod, vec3_origin, vec3_origin, mins, maxs, 0xffffffff, ent->r.currentOrigin, ent->r.currentAngles);
|
||||
World_TransformedTrace(mod, 0, 0, vec3_origin, vec3_origin, mins, maxs, capsule, &tr, ent->r.currentOrigin, ang, 0xffffffff);
|
||||
|
||||
if (tr.startsolid)
|
||||
return true;
|
||||
|
|
File diff suppressed because it is too large
Load diff
|
@ -556,10 +556,10 @@ void JCL_Join(jclient_t *jcl, char *target, char *sid, qboolean allow, int proto
|
|||
|
||||
JCL_GenLink(jcl, convolink, sizeof(convolink), NULL, target, NULL, NULL, "%s", target);
|
||||
JCL_GenLink(jcl, hanguplink, sizeof(hanguplink), "jdeny", target, NULL, c2c->sid, "%s", "Hang Up");
|
||||
Con_SubPrintf(b->name, "%s %s %s.\n", protocol==ICEP_VOICE?"Calling":"Requesting session with", convolink, hanguplink);
|
||||
XMPP_ConversationPrintf(b->accountdomain, b->name, "%s %s %s.\n", protocol==ICEP_VOICE?"Calling":"Requesting session with", convolink, hanguplink);
|
||||
}
|
||||
else
|
||||
Con_SubPrintf(b->name, "That session has expired.\n");
|
||||
XMPP_ConversationPrintf(b->accountdomain, b->name, "That session has expired.\n");
|
||||
}
|
||||
else if (c2c->creator)
|
||||
{
|
||||
|
@ -567,16 +567,16 @@ void JCL_Join(jclient_t *jcl, char *target, char *sid, qboolean allow, int proto
|
|||
//resend initiate if they've not acked it... I dunno...
|
||||
JCL_JingleSend(jcl, c2c, "session-initiate");
|
||||
JCL_GenLink(jcl, convolink, sizeof(convolink), NULL, target, NULL, NULL, "%s", target);
|
||||
Con_SubPrintf(b->name, "Restarting session with %s.\n", convolink);
|
||||
XMPP_ConversationPrintf(b->accountdomain, b->name, "Restarting session with %s.\n", convolink);
|
||||
}
|
||||
else if (c2c->accepted)
|
||||
Con_SubPrintf(b->name, "That session was already accepted.\n");
|
||||
XMPP_ConversationPrintf(b->accountdomain, b->name, "That session was already accepted.\n");
|
||||
else
|
||||
{
|
||||
char convolink[512];
|
||||
JCL_JingleSend(jcl, c2c, "session-accept");
|
||||
JCL_GenLink(jcl, convolink, sizeof(convolink), NULL, target, NULL, NULL, "%s", target);
|
||||
Con_SubPrintf(b->name, "Accepting session from %s.\n", convolink);
|
||||
XMPP_ConversationPrintf(b->accountdomain, b->name, "Accepting session from %s.\n", convolink);
|
||||
}
|
||||
}
|
||||
else
|
||||
|
@ -586,10 +586,10 @@ void JCL_Join(jclient_t *jcl, char *target, char *sid, qboolean allow, int proto
|
|||
char convolink[512];
|
||||
JCL_JingleSend(jcl, c2c, "session-terminate");
|
||||
JCL_GenLink(jcl, convolink, sizeof(convolink), NULL, target, NULL, NULL, "%s", target);
|
||||
Con_SubPrintf(b->name, "Terminating session with %s.\n", convolink);
|
||||
XMPP_ConversationPrintf(b->accountdomain, b->name, "Terminating session with %s.\n", convolink);
|
||||
}
|
||||
else
|
||||
Con_SubPrintf(b->name, "That session has already expired.\n");
|
||||
XMPP_ConversationPrintf(b->accountdomain, b->name, "That session has already expired.\n");
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -805,7 +805,7 @@ static qboolean JCL_JingleHandleInitiate_GoogleSession(jclient_t *jcl, xmltree_t
|
|||
char convolink[512];
|
||||
JCL_JingleSend(jcl, c2c, "terminate");
|
||||
JCL_GenLink(jcl, convolink, sizeof(convolink), NULL, from, NULL, NULL, "%s", b->name);
|
||||
Con_SubPrintf(b->name, "%s does not support any compatible audio codecs, and is unable to call you.\n", convolink);
|
||||
XMPP_ConversationPrintf(b->accountdomain, b->name, "%s does not support any compatible audio codecs, and is unable to call you.\n", convolink);
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
@ -822,14 +822,14 @@ static qboolean JCL_JingleHandleInitiate_GoogleSession(jclient_t *jcl, xmltree_t
|
|||
JCL_GenLink(jcl, denylink, sizeof(denylink), "jdeny", from, NULL, sid, "%s", "Reject");
|
||||
|
||||
//show a prompt for it, send the reply when the user decides.
|
||||
Con_SubPrintf(b->name,
|
||||
XMPP_ConversationPrintf(b->accountdomain, b->name,
|
||||
"%s %s. %s %s\n", convolink, offer, authlink, denylink);
|
||||
pCon_SetActive(b->name);
|
||||
return true;
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_SubPrintf(b->name, "Auto-accepting session from %s\n", convolink);
|
||||
XMPP_ConversationPrintf(b->accountdomain, b->name, "Auto-accepting session from %s\n", convolink);
|
||||
response = "accept";
|
||||
}
|
||||
}
|
||||
|
@ -938,7 +938,7 @@ static struct c2c_s *JCL_JingleHandleInitiate(jclient_t *jcl, xmltree_t *inj, ch
|
|||
{
|
||||
char convolink[512];
|
||||
JCL_GenLink(jcl, convolink, sizeof(convolink), NULL, from, NULL, NULL, "%s", b->name);
|
||||
Con_SubPrintf(b->name, "%s does not support any compatible codecs, and is unable to call you.\n", convolink);
|
||||
XMPP_ConversationPrintf(b->accountdomain, b->name, "%s does not support any compatible codecs, and is unable to call you.\n", convolink);
|
||||
|
||||
if (c2c->content[c].ice)
|
||||
piceapi->ICE_Close(c2c->content[c].ice);
|
||||
|
@ -974,14 +974,14 @@ static qboolean JCL_JingleHandleSessionTerminate(jclient_t *jcl, xmltree_t *tree
|
|||
int c;
|
||||
if (!c2c)
|
||||
{
|
||||
Con_Printf("Received session-terminate without an active session\n");
|
||||
XMPP_ConversationPrintf(b->accountdomain, b->name, "Received session-terminate without an active session\n");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (reason && reason->child)
|
||||
Con_SubPrintf(b->name, "Session ended: %s\n", reason->child->name);
|
||||
XMPP_ConversationPrintf(b->accountdomain, b->name, "Session ended: %s\n", reason->child->name);
|
||||
else
|
||||
Con_SubPrintf(b->name, "Session ended\n");
|
||||
XMPP_ConversationPrintf(b->accountdomain, b->name, "Session ended\n");
|
||||
|
||||
//unlink it
|
||||
for (link = &jcl->c2c; *link; link = &(*link)->next)
|
||||
|
@ -1032,7 +1032,7 @@ static qboolean JCL_JingleHandleSessionAccept(jclient_t *jcl, xmltree_t *tree, c
|
|||
{
|
||||
return false;
|
||||
}
|
||||
Con_SubPrintf(b->name, "Session Accepted!\n");
|
||||
XMPP_ConversationPrintf(b->accountdomain, b->name, "Session Accepted!\n");
|
||||
// XML_ConPrintTree(tree, 0);
|
||||
|
||||
JCL_JingleParsePeerPorts(jcl, c2c, tree, from, XML_GetParameter(tree, "sid", ""));
|
||||
|
@ -1324,13 +1324,13 @@ qboolean JCL_ParseJingle(jclient_t *jcl, xmltree_t *tree, char *from, char *id)
|
|||
JCL_GenLink(jcl, denylink, sizeof(denylink), "jdeny", from, NULL, sid, "%s", "Reject");
|
||||
|
||||
//show a prompt for it, send the reply when the user decides.
|
||||
Con_SubPrintf(b->name,
|
||||
XMPP_ConversationPrintf(b->accountdomain, b->name,
|
||||
"%s %s. %s %s\n", convolink, offer, authlink, denylink);
|
||||
pCon_SetActive(b->name);
|
||||
pCon_SetActive(b->accountdomain);
|
||||
}
|
||||
else
|
||||
{
|
||||
Con_SubPrintf(b->name, "Auto-accepting session from %s\n", convolink);
|
||||
XMPP_ConversationPrintf(b->accountdomain, b->name, "Auto-accepting session from %s\n", convolink);
|
||||
JCL_Join(jcl, from, sid, true, ICEP_INVALID);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,7 +2,7 @@ typedef struct xmlparams_s
|
|||
{
|
||||
char val[256]; //FIXME: make pointer
|
||||
struct xmlparams_s *next;
|
||||
char name[64]; //FIXME: make variable sized
|
||||
char name[128]; //FIXME: make variable sized
|
||||
} xmlparams_t;
|
||||
|
||||
typedef struct subtree_s
|
||||
|
@ -34,4 +34,4 @@ xmltree_t *XML_ChildOfTreeNS(xmltree_t *t, char *xmlns, char *name, int childnum
|
|||
char *XML_GetChildBody(xmltree_t *t, char *paramname, char *def);
|
||||
void XML_ConPrintTree(xmltree_t *t, char *subconsole, int indent);
|
||||
|
||||
xmltree_t *XML_FromJSON(xmltree_t *t, char *name, char *json, int *jsonpos, int jsonlen);
|
||||
xmltree_t *XML_FromJSON(xmltree_t *t, char *name, char *json, int *jsonpos, int jsonlen);
|
||||
|
|
|
@ -9,7 +9,7 @@
|
|||
#define FILETRANSFERS //IBB only, speeds suck. autoaccept is forced on. no protection from mods stuffcmding sendfile commands. needs more extensive testing
|
||||
#define QUAKECONNECT //including quake ICE connections (depends upon jingle)
|
||||
#define VOIP //enables voice chat (depends upon jingle)
|
||||
#define VOIP_LEGACY //enables google-only voice chat compat. google have not kept up with the standardisation of jingle (aka: gingle).
|
||||
//#define VOIP_LEGACY //enables google-only voice chat compat. google have not kept up with the standardisation of jingle (aka: gingle).
|
||||
//#define VOIP_LEGACY_ONLY //disables jingle feature (advert+detection only)
|
||||
#define JINGLE //enables jingle signalling
|
||||
|
||||
|
@ -21,7 +21,7 @@
|
|||
#endif
|
||||
|
||||
|
||||
#define JCL_BUILD "3"
|
||||
#define JCL_BUILD "4"
|
||||
#define DEFAULTDOMAIN ""
|
||||
#define DEFAULTRESOURCE "Quake"
|
||||
#define QUAKEMEDIAXMLNS "http://fteqw.com/protocol/quake"
|
||||
|
@ -34,7 +34,7 @@
|
|||
|
||||
|
||||
|
||||
#define JCL_MAXMSGLEN 10000
|
||||
#define JCL_MAXMSGLEN 0x10000
|
||||
|
||||
//values are not on the wire or anything
|
||||
#define CAP_VOICE (1u<<0) //supports voice
|
||||
|
@ -60,6 +60,7 @@ typedef struct bresource_s
|
|||
char fstatus[128]; //full status
|
||||
char server[256];
|
||||
int servertype; //0=none, 1=already a client, 2=joinable
|
||||
int priority;
|
||||
|
||||
unsigned int buggycaps;
|
||||
unsigned int caps;
|
||||
|
@ -102,6 +103,7 @@ typedef struct jclient_s
|
|||
JCL_ACTIVE //we're connected, we got a buddy list and everything
|
||||
} status;
|
||||
unsigned int timeout; //reconnect/ping timer
|
||||
char errormsg[256];
|
||||
|
||||
unsigned int enabledcapabilities;
|
||||
|
||||
|
@ -260,7 +262,20 @@ typedef struct jclient_s
|
|||
int privateidseq;
|
||||
#endif
|
||||
|
||||
|
||||
//persistant achived info about buddies, to avoid spamming the server every time we connect
|
||||
//such things might result in lag mid game!
|
||||
struct buddyinfo_s
|
||||
{
|
||||
struct buddyinfo_s *next;
|
||||
char *image;
|
||||
char *imagehash;
|
||||
char *imagemime;
|
||||
char accountdomain[1];
|
||||
} *buddyinfo;
|
||||
|
||||
buddy_t *buddies;
|
||||
struct iq_s *avatarupdate; //we only grab one buddy's photo at a time, this is to avoid too much spam.
|
||||
} jclient_t;
|
||||
|
||||
|
||||
|
@ -279,7 +294,8 @@ qboolean JCL_FindBuddy(jclient_t *jcl, char *jid, buddy_t **buddy, bresource_t *
|
|||
|
||||
//quake functionality
|
||||
void JCL_GenLink(jclient_t *jcl, char *out, int outlen, char *action, char *context, char *contextres, char *sid, char *txtfmt, ...);
|
||||
void Con_SubPrintf(char *subname, char *format, ...);
|
||||
void Con_SubPrintf(const char *subname, char *format, ...);
|
||||
void XMPP_ConversationPrintf(const char *context, const char *title, char *format, ...);
|
||||
|
||||
//jingle functions
|
||||
void JCL_Join(jclient_t *jcl, char *target, char *sid, qboolean allow, int protocol);
|
||||
|
|
Loading…
Reference in a new issue