fix some issues with nametags.

allow skin files to force qw skin player colours.
qccgui now does a quick parse-only compile to see comments on globals, as well as populate file lists correctly with preqcc-style src. however, doesn't compile actual functions, so can fail to pick up function defs (will go to first prototype instead of the body).
try to fix seasick issue when viewing an fte-protocol mvd. needs testing.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4828 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2015-01-12 12:28:13 +00:00
parent 172532ba6d
commit f81ecbd44c
18 changed files with 145 additions and 61 deletions

View file

@ -1653,7 +1653,7 @@ void CL_PlayDemoStream(vfsfile_t *file, struct dl_download *dl, char *filename,
demtime = -bufferdelay;
cl.gametime = -bufferdelay;
cl.gametimemark = demtime;
cl.gametimemark = realtime;//demtime;
if (demtime < -0.5)
Con_Printf("Buffering for %g seconds\n", bufferdelay);
cls.netchan.last_received=demtime;

View file

@ -700,6 +700,12 @@ void CLFTE_ReadDelta(unsigned int entnum, entity_state_t *news, entity_state_t *
news->u.q1.gravitydir[0] = MSG_ReadByte();
news->u.q1.gravitydir[1] = MSG_ReadByte();
}
if (bits & UF_UNUSED2)
{
}
if (bits & UF_UNUSED1)
{
}
}
void CLFTE_ParseBaseline(entity_state_t *es, qboolean numberisimportant)
@ -3518,9 +3524,18 @@ void CL_LinkPacketEntities (void)
}
}
VectorCopy(angles, ent->angles);
if (model && model->type == mod_alias)
if (state->u.q1.pmovetype)
{
vec3_t vel;
VectorScale(state->u.q1.velocity, (1/8.0), vel);
//players get special logic, as the angles on the wire are their raw view angles
//FIXME: EGADS! VILE!
angles[0] *= 1/3.0; //fixme: gravity dir.
angles[2] += V_CalcRoll(angles, vel)*4;
}
else if (model && model->type == mod_alias)
angles[0]*=-1; //carmack screwed up when he added alias models - they pitch the wrong way.
VectorCopy(angles, ent->angles);
AngleVectors(angles, ent->axis[0], ent->axis[1], ent->axis[2]);
VectorInverse(ent->axis[1]);

View file

@ -6804,12 +6804,10 @@ void CLNQ_ParseServerMessage (void)
i=MSGCL_ReadEntity();
if (!cl.playerview[destsplit].viewentity)
{
cl.playerview[destsplit].playernum = (unsigned int)i;
if (cl.playerview[destsplit].playernum >= cl.allocated_client_slots)
{
Con_DPrintf(CON_WARNING "WARNING: Server put us in slot %i. We are not on the scoreboard.\n", i);
cl.playerview[destsplit].playernum = cl.allocated_client_slots; //pretend it's an mvd (we have that spare slot)
}
if (!i || i > cl.allocated_client_slots)
cl.playerview[destsplit].playernum = cl.allocated_client_slots; //the mvd spectator slot.
else
cl.playerview[destsplit].playernum = (unsigned int)i-1;
}
cl.playerview[destsplit].viewentity = i;
break;

View file

@ -144,6 +144,7 @@ typedef struct entity_s
} entity_t;
#define MAX_GEOMSETS 32
#define Q1UNSPECIFIED 0x00ffffff //0xffRRGGBB or 0x0000000V are both valid values. so this is an otherwise-illegal value to say its not been set.
typedef struct
{
char skinname[MAX_QPATH];
@ -152,6 +153,8 @@ typedef struct
qbyte geomset[MAX_GEOMSETS]; //allows selecting a single set of geometry from alternatives. this might be a can of worms.
char qwskinname[MAX_QPATH];
struct qwskin_s *qwskin;
unsigned int q1upper; //Q1UNSPECIFIED
unsigned int q1lower; //Q1UNSPECIFIED
struct
{
char surface[MAX_QPATH];

View file

@ -1455,6 +1455,7 @@ void R_DrawNameTags(void)
int len;
vec3_t center;
vec3_t tagcenter;
lerpents_t *le;
if (!cl.spectator && !cls.demoplayback)
return;
@ -1473,7 +1474,13 @@ void R_DrawNameTags(void)
for (i = 0; i < cl.allocated_client_slots; i++)
{
if (!nametagseen[i])
continue;
{
if (i+1 >= cl.maxlerpents || !cl.lerpentssequence || cl.lerpents[i+1].sequence != cl.lerpentssequence)
continue;
le = &cl.lerpents[i+1];
VectorCopy(le->origin, nametagorg[i]);
}
//while cl.lerpplayers exists, it tends to not be configured properly.
if (i == r_refdef.playerview->playernum)
continue; // Don't draw tag for the local player
if (cl.players[i].spectator)

View file

@ -2758,6 +2758,8 @@ static qboolean TP_IsItemVisible(item_vis_t *visitem)
if (R_CullSphere(visitem->entorg, visitem->radius))
return false;
pmove.skipent = -1;
VectorNegate (visitem->dir, v);
VectorNormalize (v);
VectorMA (visitem->entorg, visitem->radius, v, end);

View file

@ -502,7 +502,7 @@ void PM_Friction (void)
start[2] = pmove.origin[2] + pmove.player_mins[2];
stop[2] = start[2] - 34;
trace = PM_PlayerTrace (start, stop, MASK_PLAYERSOLID);
if (trace.fraction == 1)
if (trace.fraction == 1 && !trace.startsolid)
friction *= 2;
control = speed < movevars.stopspeed ? movevars.stopspeed : speed;

View file

@ -526,9 +526,9 @@ trace_t PM_PlayerTrace (vec3_t start, vec3_t end, unsigned int solidmask)
}
}
//this is needed to avoid *2 friction. some id bug.
if (total.startsolid)
total.fraction = 0;
// //this is needed to avoid *2 friction. some id bug.
// if (total.startsolid)
// total.fraction = 0;
return total;
}

View file

@ -236,6 +236,8 @@ skinid_t Mod_ReadSkinFile(const char *skinname, const char *skintext)
skin = Z_Malloc(sizeof(*skin) - sizeof(skin->mappings) + sizeof(skin->mappings[0])*4);
skin->maxmappings = 4;
Q_strncpyz(skin->skinname, skinname, sizeof(skin->skinname));
skin->q1lower = Q1UNSPECIFIED;
skin->q1upper = Q1UNSPECIFIED;
while(skintext)
{
@ -322,6 +324,22 @@ skinid_t Mod_ReadSkinFile(const char *skinname, const char *skintext)
skintext = COM_ParseToken(skintext, NULL);
Q_strncpyz(skin->qwskinname, com_token, sizeof(skin->qwskinname));
}
else if (!strcmp(com_token, "q1lower"))
{
skintext = COM_ParseToken(skintext, NULL);
if (!strncmp(com_token, "0x", 2))
skin->q1lower = 0xff000000|strtoul(com_token+2, NULL, 16);
else
skin->q1lower = atoi(com_token);
}
else if (!strcmp(com_token, "q1upper"))
{
skintext = COM_ParseToken(skintext, NULL);
if (!strncmp(com_token, "0x", 2))
skin->q1upper = 0xff000000|strtoul(com_token+2, NULL, 16);
else
skin->q1upper = atoi(com_token);
}
else
{
while(*skintext == ' ' || *skintext == '\t')
@ -540,6 +558,9 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e
qboolean forced;
qboolean generateupperlower = false;
tc = e->topcolour;
bc = e->bottomcolour;
*forcedtex = NULL;
/*q3 .skin files*/
if (e->customskin)
@ -560,6 +581,10 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e
}
if (!sk->qwskin && *sk->qwskinname)
sk->qwskin = Skin_Lookup(sk->qwskinname);
if (sk->q1lower != Q1UNSPECIFIED)
bc = sk->q1lower;
if (sk->q1upper != Q1UNSPECIFIED)
bc = sk->q1upper;
plskin = sk->qwskin;
}
}
@ -585,8 +610,6 @@ static shader_t *GL_ChooseSkin(galiasinfo_t *inf, model_t *model, int surfnum, e
if (!gl_nocolors.ival || forced)
{
tc = e->topcolour;
bc = e->bottomcolour;
if (!plskin || plskin->loadstate == SKIN_FAILED)
{
if (e->playerindex >= 0 && e->playerindex <= MAX_CLIENTS)

View file

@ -1188,7 +1188,7 @@ struct dl_download *HTTP_CL_Get(const char *url, const char *localfile, void (*N
activedownloads = newdl;
if (!cls.download)
if (!cls.download && localfile)
{
cls.download = &newdl->qdownload;
newdl->qdownload.method = DL_HTTP;

View file

@ -3,7 +3,7 @@ int Grep(char *filename, char *string);
void EditFile(char *name, int line);
void GUI_SetDefaultOpts(void);
int GUI_BuildParms(char *args, char **argv);
int GUI_BuildParms(char *args, char **argv, pbool quick);
unsigned char *PDECL QCC_ReadFile (const char *fname, void *buffer, int len, size_t *sz);
int QCC_FileSize (const char *fname);

View file

@ -528,7 +528,7 @@ extern pbool keyword_union; //you surly know what a union is!
extern pbool keywords_coexist;
extern pbool output_parms;
extern pbool autoprototype, autoprototyped;
extern pbool autoprototype, autoprototyped, parseonly;
extern pbool pr_subscopedlocals;
extern pbool flag_ifstring;
extern pbool flag_iffloat;

View file

@ -70,6 +70,7 @@ pbool keywords_coexist; //don't disable a keyword simply because a var was made
pbool output_parms; //emit some PARMX fields. confuses decompilers.
pbool autoprototype; //take two passes over the source code. First time round doesn't enter and functions or initialise variables.
pbool autoprototyped; //previously autoprototyped. no longer allowed to enable autoproto, but don't warn about it.
pbool parseonly; //parse defs and stuff, but don't bother compiling any actual code.
pbool pr_subscopedlocals; //causes locals to be valid ONLY within their statement block. (they simply can't be referenced by name outside of it)
pbool flag_ifstring; //makes if (blah) equivelent to if (blah != "") which resolves some issues in multiprogs situations.
pbool flag_iffloat; //use an op_if_f instruction instead of op_if so if(-0) evaluates to false.

View file

@ -472,7 +472,7 @@ extern char enginebinary[MAX_PATH];
extern char enginebasedir[MAX_PATH];
extern char enginecommandline[8192];
void RunCompiler(char *args);
void RunCompiler(char *args, pbool quick);
void RunEngine(void);
HINSTANCE ghInstance;
@ -3608,11 +3608,12 @@ int GUIprintf(const char *msg, ...)
*/
return args;
}
int Dummyprintf(const char *msg, ...){return 0;}
#undef Sys_Error
void Sys_Error(const char *text, ...);
void RunCompiler(char *args)
void RunCompiler(char *args, pbool quick)
{
char *argv[128];
int argc;
@ -3660,23 +3661,32 @@ void RunCompiler(char *args)
ext.ReadFile = GUIReadFile;
ext.FileSize = GUIFileSize;
ext.WriteFile = QCC_WriteFile;
ext.Printf = GUIprintf;
ext.Sys_Error = Sys_Error;
GUIprintf("");
if (quick)
ext.Printf = Dummyprintf;
else
{
ext.Printf = GUIprintf;
GUIprintf("");
}
if (logfile)
fclose(logfile);
if (fl_log)
if (fl_log && !quick)
logfile = fopen("fteqcc.log", "wb");
else
logfile = NULL;
argc = GUI_BuildParms(args, argv);
argc = GUI_BuildParms(args, argv, quick);
if (CompileParams(&funcs, true, argc, argv))
{
EngineGiveFocus();
EngineCommandf("qcresume\nmenu_restart\nrestart\n");
if (!quick)
{
EngineGiveFocus();
EngineCommandf("qcresume\nmenu_restart\nrestart\n");
}
}
if (logfile)
@ -3870,19 +3880,22 @@ void SetProgsSrc(void)
pr_file_p = QCC_COM_Parse(buffer);
if (*qcc_token == '#')
{
//aaaahhh! newstyle!
AddSourceFile("%s", progssrcname);
free(buffer); //aaaahhh! newstyle!
return;
}
pr_file_p = QCC_COM_Parse(pr_file_p); //we dont care about the produced progs.dat
AddSourceFile("%s", progssrcname);
while(pr_file_p)
else
{
AddSourceFile("%s/%s", progssrcname, qcc_token);
pr_file_p = QCC_COM_Parse(pr_file_p); //we dont care about the produced progs.dat
AddSourceFile("%s", progssrcname);
while(pr_file_p)
{
AddSourceFile("%s/%s", progssrcname, qcc_token);
pr_file_p = QCC_COM_Parse(pr_file_p); //we dont care about the produced progs.dat
}
}
free(buffer);
RunCompiler(parameters, true);
}
}
@ -3911,7 +3924,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
if(strstr(lpCmdLine, "-stdout"))
{
GUI_ParseCommandLine(lpCmdLine);
RunCompiler(lpCmdLine);
RunCompiler(lpCmdLine, false);
return 0;
}
@ -4067,7 +4080,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
if (fl_compileonstart)
{
CreateOutputWindow();
RunCompiler(lpCmdLine);
RunCompiler(lpCmdLine, false);
}
else
{
@ -4082,7 +4095,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
GUIprintf(progssrcname);
GUIprintf("\n");
RunCompiler("-?");
RunCompiler("-?", false);
}
}
@ -4166,7 +4179,7 @@ int WINAPI WinMain (HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLin
if (buttons[ID_COMPILE].washit)
{
CreateOutputWindow();
RunCompiler(parameters);
RunCompiler(parameters, false);
buttons[ID_COMPILE].washit = false;
}

View file

@ -385,7 +385,7 @@ void GUI_RevealOptions(void)
int GUI_BuildParms(char *args, char **argv)
int GUI_BuildParms(char *args, char **argv, pbool quick)
{
static char param[2048];
int paramlen = 0;
@ -397,6 +397,13 @@ int GUI_BuildParms(char *args, char **argv)
argc = 1;
argv[0] = "fteqcc";
if (quick)
{
strcpy(param+paramlen, "-Tparse");
argv[argc++] = param+paramlen;
paramlen += strlen(param+paramlen)+1;
}
while(*args)
{
while (*args <= ' '&& *args)

View file

@ -2785,15 +2785,20 @@ void QCC_PR_CommandLinePrecompilerOptions (void)
else if ( !strncmp(myargv[i], "-T", 2) || !strncmp(myargv[i], "/T", 2) )
{
p = 0;
for (p = 0; targets[p].name; p++)
if (!stricmp(myargv[i]+2, targets[p].name))
{
qcc_targetformat = targets[p].target;
break;
}
if (!strcmp("parse", myargv[i]+2))
parseonly = true;
else
{
for (p = 0; targets[p].name; p++)
if (!stricmp(myargv[i]+2, targets[p].name))
{
qcc_targetformat = targets[p].target;
break;
}
if (!targets[p].name)
QCC_PR_Warning(0, NULL, WARN_BADPARAMS, "Unrecognised target parameter (%s)", myargv[i]);
if (!targets[p].name)
QCC_PR_Warning(0, NULL, WARN_BADPARAMS, "Unrecognised target parameter (%s)", myargv[i]);
}
}
else if ( !strnicmp(myargv[i], "-W", 2) || !strnicmp(myargv[i], "/W", 2) )
@ -3190,8 +3195,9 @@ pbool QCC_main (int argc, char **argv) //as part of the quake engine
*compiler_flag[p].enabled = compiler_flag[p].flags & FLAG_ASDEFAULT;
}
autoprototyped = autoprototype = false;
parseonly = autoprototyped = autoprototype = false;
QCC_SetDefaultProperties();
autoprototype |= parseonly;
optres_shortenifnots = 0;
optres_overlaptemps = 0;
@ -3533,16 +3539,20 @@ void QCC_ContinueCompile(void)
qccmsrc = QCC_COM_Parse(qccmsrc);
if (!qccmsrc)
{
if (autoprototype)
if (parseonly)
qcc_compileactive = false;
else
{
qccmsrc = originalqccmsrc;
autoprototyped = autoprototype;
QCC_SetDefaultProperties();
autoprototype = false;
return;
if (autoprototype)
{
qccmsrc = originalqccmsrc;
autoprototyped = autoprototype;
QCC_SetDefaultProperties();
autoprototype = false;
return;
}
QCC_FinishCompile();
}
QCC_FinishCompile();
PostCompile();
if (currentsourcefile < numsourcefiles)
@ -3770,7 +3780,7 @@ void new_QCC_ContinueCompile(void)
if (pr_error_count)
QCC_Error (ERR_PARSEERRORS, "Errors have occured");
if (autoprototype)
if (autoprototype && !parseonly)
{
qccmsrc = originalqccmsrc;
pr_file_p = qccmsrc;
@ -3785,7 +3795,8 @@ void new_QCC_ContinueCompile(void)
}
else
{
QCC_FinishCompile();
if (!parseonly)
QCC_FinishCompile();
PostCompile();
if (!QCC_main(myargc, myargv))

View file

@ -9665,7 +9665,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"particleeffectquery",PF_Fixme,0, 0, 0, 374, D("string(float efnum, float body)", "Retrieves either the name or the body of the effect with the given number. The effect body is regenerated from internal state, and can be changed before being reapplied via the localcmd builtin.")},
{"adddecal", PF_Fixme, 0, 0, 0, 375, D("void(string shadername, vector origin, vector up, vector side, vector rgb, float alpha)", "Adds a temporary clipped decal shader to the scene, centered at the given point with given orientation. Will be drawn by the next renderscene call, and freed by the next clearscene call.")},
{"setcustomskin", PF_Fixme, 0, 0, 0, 376, D("void(entity e, string skinfilename, optional string skindata)", "Sets an entity's skin overrides. These are custom per-entity surface->shader lookups. The skinfilename/data should be in .skin format:\nsurfacename,shadername - makes the named surface use the named shader\nreplace \"surfacename\" \"shadername\" - same.\ncompose \"surfacename\" \"shader\" \"imagename@x,y:w,h?r,g,b,a\" - compose a skin texture from multiple images. The texture is determined to be sufficient to hold the first named image, additional images can be named as extra tokens on the same line. Use a + at the end of the line to continue reading image tokens from the next line also, the named shader must use 'map $diffuse' to read the composed texture (compatible with the defaultskin shader).")},
{"setcustomskin", PF_Fixme, 0, 0, 0, 376, D("void(entity e, string skinfilename, optional string skindata)", "Sets an entity's skin overrides. These are custom per-entity surface->shader lookups. The skinfilename/data should be in .skin format:\nsurfacename,shadername - makes the named surface use the named shader\nreplace \"surfacename\" \"shadername\" - same.\nqwskin \"foo\" - use an unmodified quakeworld player skin (including crop+repalette rules)\nq1lower 0xff0000 - specify an override for the entity's lower colour, in this case to red\nq1upper 0x0000ff - specify an override for the entity's lower colour, in this case to blue\ncompose \"surfacename\" \"shader\" \"imagename@x,y:w,h?r,g,b,a\" - compose a skin texture from multiple images.\n The texture is determined to be sufficient to hold the first named image, additional images can be named as extra tokens on the same line.\n Use a + at the end of the line to continue reading image tokens from the next line also, the named shader must use 'map $diffuse' to read the composed texture (compatible with the defaultskin shader).")},
//END EXT_CSQC
{"memalloc", PF_memalloc, 0, 0, 0, 384, D("__variant*(int size)", "Allocate an arbitary block of memory")},

View file

@ -2867,6 +2867,9 @@ void SV_Snapshot_BuildStateQ1(entity_state_t *state, edict_t *ent, client_t *cli
state->u.q1.velocity[1] = 0;
state->u.q1.velocity[2] = 0;
VectorCopy (ent->v->origin, state->origin);
VectorCopy (ent->v->angles, state->angles);
if ((state->number-1) < (unsigned int)sv.allocated_client_slots && (client == &svs.clients[state->number-1] || client == svs.clients[state->number-1].controller))
state->u.q1.weaponframe = ent->v->weaponframe;
else
@ -2895,6 +2898,9 @@ void SV_Snapshot_BuildStateQ1(entity_state_t *state, edict_t *ent, client_t *cli
state->u.q1.velocity[1] = ent->v->velocity[1] * 8;
state->u.q1.velocity[2] = ent->v->velocity[2] * 8;
}
//fixme: deal with fixangles
VectorCopy (ent->v->v_angle, state->angles);
}
if (client && client->edict && (ent->v->owner == client->edict->entnum))
@ -2941,8 +2947,6 @@ void SV_Snapshot_BuildStateQ1(entity_state_t *state, edict_t *ent, client_t *cli
if (ent->v->movetype == MOVETYPE_STEP)
state->dpflags |= RENDER_STEP;
VectorCopy (ent->v->origin, state->origin);
VectorCopy (ent->v->angles, state->angles);
state->modelindex = ent->v->modelindex;
state->modelindex2 = ent->xv->vw_index;
state->frame = ent->v->frame;