mirror of
https://github.com/nzp-team/fteqw.git
synced 2024-11-25 13:21:36 +00:00
Added pm_pground cvar for compat with mvdsv/ezquake. Do not use it with NQ mods however, as the QC will interfere with the onground state (QW mods are okay).
Added Z_EXT_PF_ONGROUND + Z_EXT_PF_SOLID for compat (not enabled serverside due to conflicts with pext - just a define away). Fixed bug with loading screens switching sizes part way through loading. Added hexen2 rain effect. Fix hexen2 model texture alphas not working. Fix potential linux crash from excessively long stdin lines. Added cl_rollalpha cvar. Fixed quirk where the player would slide along the base of steep walls/slopes. Tweaked PM_NudgePosition to be more precise, giving more reliable prediction. Fixed fread qc builtin. Tweaked random() builtin to bias slightly away from 0, so that nextthink=random()*foo; will never cause statue-monsters. Check for GL_WEBGL_depth_texture instead of just GL_OES_depth_texture, to fix compressedTex2d errors in firefox. Second attempt at blocking invariant keyword with mesa. Use xrandr for gamma where possible. This prevents reading stale XF86 gamma ramps and restoring those invalid ramps when quitting. Try to grab mouse pointers slightly faster in x11. Don't call XIFreeDeviceInfo if XIQueryDevice returned NULL. Document parm_string and startspot qc globals. Fix possible infinite loop from physics frames. QTV: stripped most of the old plugin code (because really, who has a browser that still supports either ActiveX or NPAPI). Fixed up emscripten port references. QTV: fix bug with protocol extensions not being reported to viewers. QTV: use binary websockets instead of text. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@5419 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
parent
d398af48b2
commit
6c5de8e8b1
46 changed files with 671 additions and 457 deletions
|
@ -4680,8 +4680,12 @@ void CLQW_ParsePlayerinfo (void)
|
||||||
flags = (unsigned short)MSG_ReadShort ();
|
flags = (unsigned short)MSG_ReadShort ();
|
||||||
|
|
||||||
if (cls.fteprotocolextensions & (PEXT_HULLSIZE|PEXT_TRANS|PEXT_SCALE|PEXT_FATNESS))
|
if (cls.fteprotocolextensions & (PEXT_HULLSIZE|PEXT_TRANS|PEXT_SCALE|PEXT_FATNESS))
|
||||||
|
{
|
||||||
if (flags & PF_EXTRA_PFS)
|
if (flags & PF_EXTRA_PFS)
|
||||||
flags |= MSG_ReadByte()<<16;
|
flags |= MSG_ReadByte()<<16;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
flags = (flags & 0x3fff) | ((flags & 0xc000)<<8);
|
||||||
|
|
||||||
state->flags = flags;
|
state->flags = flags;
|
||||||
|
|
||||||
|
@ -4783,15 +4787,15 @@ void CLQW_ParsePlayerinfo (void)
|
||||||
state->gravitydir[2] = -1;
|
state->gravitydir[2] = -1;
|
||||||
|
|
||||||
#ifdef PEXT_SCALE
|
#ifdef PEXT_SCALE
|
||||||
if (flags & PF_SCALE && cls.fteprotocolextensions & PEXT_SCALE)
|
if ((flags & PF_SCALE) && (cls.fteprotocolextensions & PEXT_SCALE))
|
||||||
state->scale = (float)MSG_ReadByte()/50;
|
state->scale = (float)MSG_ReadByte()/50;
|
||||||
#endif
|
#endif
|
||||||
#ifdef PEXT_TRANS
|
#ifdef PEXT_TRANS
|
||||||
if (flags & PF_TRANS && cls.fteprotocolextensions & PEXT_TRANS)
|
if ((flags & PF_TRANS) && (cls.fteprotocolextensions & PEXT_TRANS))
|
||||||
state->alpha = MSG_ReadByte();
|
state->alpha = MSG_ReadByte();
|
||||||
#endif
|
#endif
|
||||||
#ifdef PEXT_FATNESS
|
#ifdef PEXT_FATNESS
|
||||||
if (flags & PF_FATNESS && cls.fteprotocolextensions & PEXT_FATNESS)
|
if ((flags & PF_FATNESS) && (cls.fteprotocolextensions & PEXT_FATNESS))
|
||||||
state->fatness = (float)MSG_ReadChar();
|
state->fatness = (float)MSG_ReadChar();
|
||||||
#endif
|
#endif
|
||||||
#ifdef PEXT_HULLSIZE
|
#ifdef PEXT_HULLSIZE
|
||||||
|
@ -4818,8 +4822,12 @@ void CLQW_ParsePlayerinfo (void)
|
||||||
}
|
}
|
||||||
//should be passed to player move func.
|
//should be passed to player move func.
|
||||||
#endif
|
#endif
|
||||||
|
if (cls.z_ext & Z_EXT_PF_ONGROUND)
|
||||||
|
state->onground = !!(flags & PF_ONGROUND);
|
||||||
|
else
|
||||||
|
state->onground = false;
|
||||||
|
|
||||||
if (cls.fteprotocolextensions & PEXT_COLOURMOD && (flags & PF_COLOURMOD))
|
if ((cls.fteprotocolextensions & PEXT_COLOURMOD) && (flags & PF_COLOURMOD))
|
||||||
{
|
{
|
||||||
state->colourmod[0] = MSG_ReadByte();
|
state->colourmod[0] = MSG_ReadByte();
|
||||||
state->colourmod[1] = MSG_ReadByte();
|
state->colourmod[1] = MSG_ReadByte();
|
||||||
|
@ -4832,6 +4840,15 @@ void CLQW_ParsePlayerinfo (void)
|
||||||
state->colourmod[2] = 32;
|
state->colourmod[2] = 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//if we have no solidity info, guess.
|
||||||
|
if (!(cls.z_ext & Z_EXT_PF_SOLID))
|
||||||
|
{
|
||||||
|
if (cl.players[num].spectator || state->flags & PF_DEAD)
|
||||||
|
state->flags &= ~PF_SOLID;
|
||||||
|
else
|
||||||
|
state->flags |= PF_SOLID;
|
||||||
|
}
|
||||||
|
|
||||||
if (cls.z_ext & Z_EXT_PM_TYPE)
|
if (cls.z_ext & Z_EXT_PM_TYPE)
|
||||||
{
|
{
|
||||||
int pm_code;
|
int pm_code;
|
||||||
|
@ -5753,9 +5770,8 @@ void CL_SetSolidPlayers (void)
|
||||||
{
|
{
|
||||||
if (!pplayer->active)
|
if (!pplayer->active)
|
||||||
continue; // not present this frame
|
continue; // not present this frame
|
||||||
|
if (!(pplayer->flags & PF_SOLID))
|
||||||
if (pplayer->flags & PF_DEAD)
|
continue;
|
||||||
continue; // dead players aren't solid
|
|
||||||
|
|
||||||
memset(pent, 0, sizeof(physent_t));
|
memset(pent, 0, sizeof(physent_t));
|
||||||
VectorCopy(pplayer->origin, pent->origin);
|
VectorCopy(pplayer->origin, pent->origin);
|
||||||
|
|
|
@ -2259,6 +2259,7 @@ void CL_CheckServerInfo(void)
|
||||||
cl.bunnyspeedcap = Q_atof(InfoBuf_ValueForKey(&cl.serverinfo, "pm_bunnyspeedcap"));
|
cl.bunnyspeedcap = Q_atof(InfoBuf_ValueForKey(&cl.serverinfo, "pm_bunnyspeedcap"));
|
||||||
movevars.slidefix = (Q_atof(InfoBuf_ValueForKey(&cl.serverinfo, "pm_slidefix")) != 0);
|
movevars.slidefix = (Q_atof(InfoBuf_ValueForKey(&cl.serverinfo, "pm_slidefix")) != 0);
|
||||||
movevars.airstep = (Q_atof(InfoBuf_ValueForKey(&cl.serverinfo, "pm_airstep")) != 0);
|
movevars.airstep = (Q_atof(InfoBuf_ValueForKey(&cl.serverinfo, "pm_airstep")) != 0);
|
||||||
|
movevars.pground = (Q_atof(InfoBuf_ValueForKey(&cl.serverinfo, "pm_pground")) != 0);
|
||||||
movevars.stepdown = (Q_atof(InfoBuf_ValueForKey(&cl.serverinfo, "pm_stepdown")) != 0);
|
movevars.stepdown = (Q_atof(InfoBuf_ValueForKey(&cl.serverinfo, "pm_stepdown")) != 0);
|
||||||
movevars.walljump = (Q_atof(InfoBuf_ValueForKey(&cl.serverinfo, "pm_walljump")));
|
movevars.walljump = (Q_atof(InfoBuf_ValueForKey(&cl.serverinfo, "pm_walljump")));
|
||||||
movevars.ktjump = Q_atof(InfoBuf_ValueForKey(&cl.serverinfo, "pm_ktjump"));
|
movevars.ktjump = Q_atof(InfoBuf_ValueForKey(&cl.serverinfo, "pm_ktjump"));
|
||||||
|
|
|
@ -406,6 +406,7 @@ void CL_PredictUsercmd (int pnum, int entnum, player_state_t *from, player_state
|
||||||
pmove.velocity[2] = 0;
|
pmove.velocity[2] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pmove.onground = from->onground;
|
||||||
pmove.jump_msec = (cls.z_ext & Z_EXT_PM_TYPE) ? 0 : from->jump_msec;
|
pmove.jump_msec = (cls.z_ext & Z_EXT_PM_TYPE) ? 0 : from->jump_msec;
|
||||||
pmove.jump_held = from->jump_held;
|
pmove.jump_held = from->jump_held;
|
||||||
pmove.waterjumptime = from->waterjumptime;
|
pmove.waterjumptime = from->waterjumptime;
|
||||||
|
@ -778,7 +779,7 @@ static void CL_EntStateToPlayerState(player_state_t *plstate, entity_state_t *st
|
||||||
memset(plstate, 0, sizeof(*plstate));
|
memset(plstate, 0, sizeof(*plstate));
|
||||||
plstate->jump_held = jumpheld;
|
plstate->jump_held = jumpheld;
|
||||||
|
|
||||||
switch(state->u.q1.pmovetype)
|
switch(state->u.q1.pmovetype & 0x7f)
|
||||||
{
|
{
|
||||||
case MOVETYPE_NOCLIP:
|
case MOVETYPE_NOCLIP:
|
||||||
if (cls.z_ext & Z_EXT_PM_TYPE_NEW)
|
if (cls.z_ext & Z_EXT_PM_TYPE_NEW)
|
||||||
|
@ -816,7 +817,10 @@ static void CL_EntStateToPlayerState(player_state_t *plstate, entity_state_t *st
|
||||||
plstate->onground = onground;
|
plstate->onground = onground;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
{
|
||||||
VectorScale(state->u.q1.velocity, 1/8.0, plstate->velocity);
|
VectorScale(state->u.q1.velocity, 1/8.0, plstate->velocity);
|
||||||
|
plstate->onground = !!(state->u.q1.pmovetype&128);
|
||||||
|
}
|
||||||
plstate->pm_type = pmtype;
|
plstate->pm_type = pmtype;
|
||||||
|
|
||||||
plstate->viewangles[0] = SHORT2ANGLE(state->u.q1.vangle[0]);
|
plstate->viewangles[0] = SHORT2ANGLE(state->u.q1.vangle[0]);
|
||||||
|
@ -886,7 +890,7 @@ void CL_PredictEntityMovement(entity_state_t *estate, float age)
|
||||||
// cmd.forwardmove = 5000;
|
// cmd.forwardmove = 5000;
|
||||||
// cmd.msec = sin(realtime*6) * 128 + 128;
|
// cmd.msec = sin(realtime*6) * 128 + 128;
|
||||||
oldphysent = pmove.numphysent;
|
oldphysent = pmove.numphysent;
|
||||||
pmove.onground = true;
|
pmove.onground = startstate.onground;
|
||||||
CL_PredictUsercmd(0, estate->number, &startstate, &resultstate, &cmd); //uses player 0's maxspeed/grav...
|
CL_PredictUsercmd(0, estate->number, &startstate, &resultstate, &cmd); //uses player 0's maxspeed/grav...
|
||||||
pmove.numphysent = oldphysent;
|
pmove.numphysent = oldphysent;
|
||||||
|
|
||||||
|
@ -1236,6 +1240,7 @@ void CL_PredictMovePNum (int seat)
|
||||||
// Con_DPrintf(" propagate %i: %f-%f\n", cl.ackedmovesequence+i, fromtime, totime);
|
// Con_DPrintf(" propagate %i: %f-%f\n", cl.ackedmovesequence+i, fromtime, totime);
|
||||||
CL_PredictUsercmd (seat, pv->viewentity, tostate, &tmp, &of->cmd[seat]);
|
CL_PredictUsercmd (seat, pv->viewentity, tostate, &tmp, &of->cmd[seat]);
|
||||||
next = &cl.inframes[(toframe+i) & UPDATE_MASK].playerstate[pv->playernum];
|
next = &cl.inframes[(toframe+i) & UPDATE_MASK].playerstate[pv->playernum];
|
||||||
|
next->onground = tmp.onground;
|
||||||
next->jump_held = tmp.jump_held;
|
next->jump_held = tmp.jump_held;
|
||||||
next->jump_msec = tmp.jump_msec;
|
next->jump_msec = tmp.jump_msec;
|
||||||
VectorCopy(tmp.gravitydir, next->gravitydir);
|
VectorCopy(tmp.gravitydir, next->gravitydir);
|
||||||
|
|
|
@ -243,6 +243,7 @@ cvar_t scr_loadingrefresh = CVARD("scr_loadingrefresh", "0", "Force redrawing of
|
||||||
cvar_t scr_showloading = CVAR("scr_showloading", "1");
|
cvar_t scr_showloading = CVAR("scr_showloading", "1");
|
||||||
//things to configure the legacy loading screen
|
//things to configure the legacy loading screen
|
||||||
cvar_t scr_loadingscreen_picture = CVAR("scr_loadingscreen_picture", "gfx/loading");
|
cvar_t scr_loadingscreen_picture = CVAR("scr_loadingscreen_picture", "gfx/loading");
|
||||||
|
cvar_t scr_loadingscreen_aspect = CVARD("scr_loadingscreen_aspect", "0", "Controls the aspect of levelshot images.\n0: Use source image's aspect.\n1: Force 4:3 aspect (ignore image's aspect), for best q3 compat.\n2: Ignore aspect considerations and just smear it over the entire screen.");
|
||||||
cvar_t scr_loadingscreen_scale = CVAR("scr_loadingscreen_scale", "1");
|
cvar_t scr_loadingscreen_scale = CVAR("scr_loadingscreen_scale", "1");
|
||||||
cvar_t scr_loadingscreen_scale_limit = CVAR("scr_loadingscreen_scale_limit", "2");
|
cvar_t scr_loadingscreen_scale_limit = CVAR("scr_loadingscreen_scale_limit", "2");
|
||||||
|
|
||||||
|
@ -269,6 +270,7 @@ void CLSCR_Init(void)
|
||||||
Cvar_Register(&scr_loadingscreen_picture, cl_screengroup);
|
Cvar_Register(&scr_loadingscreen_picture, cl_screengroup);
|
||||||
Cvar_Register(&scr_loadingscreen_scale, cl_screengroup);
|
Cvar_Register(&scr_loadingscreen_scale, cl_screengroup);
|
||||||
Cvar_Register(&scr_loadingscreen_scale_limit, cl_screengroup);
|
Cvar_Register(&scr_loadingscreen_scale_limit, cl_screengroup);
|
||||||
|
Cvar_Register(&scr_loadingscreen_aspect, cl_screengroup);
|
||||||
Cvar_Register(&show_fps, cl_screengroup);
|
Cvar_Register(&show_fps, cl_screengroup);
|
||||||
Cvar_Register(&show_fps_x, cl_screengroup);
|
Cvar_Register(&show_fps_x, cl_screengroup);
|
||||||
Cvar_Register(&show_fps_y, cl_screengroup);
|
Cvar_Register(&show_fps_y, cl_screengroup);
|
||||||
|
@ -1998,13 +2000,8 @@ void SCR_DrawLoading (qboolean opaque)
|
||||||
//int mtype = M_GameType(); //unused variable
|
//int mtype = M_GameType(); //unused variable
|
||||||
y = vid.height/2;
|
y = vid.height/2;
|
||||||
|
|
||||||
if (*levelshotname)
|
if (R2D_DrawLevelshot())
|
||||||
{
|
;
|
||||||
pic = R2D_SafeCachePic (levelshotname);
|
|
||||||
if (!R_GetShaderSizes(pic, &w, &h, true))
|
|
||||||
w = h = 1;
|
|
||||||
R2D_Letterbox(0, 0, vid.width, vid.height, pic, w, h);
|
|
||||||
}
|
|
||||||
else if (opaque)
|
else if (opaque)
|
||||||
{
|
{
|
||||||
R2D_ImageColours(0, 0, 0, 1);
|
R2D_ImageColours(0, 0, 0, 1);
|
||||||
|
|
|
@ -59,7 +59,7 @@ char *r_defaultimageextensions =
|
||||||
;
|
;
|
||||||
static void Image_ChangeFormat(struct pendingtextureinfo *mips, unsigned int flags, uploadfmt_t origfmt);
|
static void Image_ChangeFormat(struct pendingtextureinfo *mips, unsigned int flags, uploadfmt_t origfmt);
|
||||||
static void QDECL R_ImageExtensions_Callback(struct cvar_s *var, char *oldvalue);
|
static void QDECL R_ImageExtensions_Callback(struct cvar_s *var, char *oldvalue);
|
||||||
cvar_t r_imageextensions = CVARCD("r_imageextensions", NULL, R_ImageExtensions_Callback, "The list of image file extensions which fte should attempt to load.");
|
cvar_t r_imageextensions = CVARCD("r_imageextensions", NULL, R_ImageExtensions_Callback, "The list of image file extensions which might exist on disk (note that this does not list all supported formats, only the extensions that should be searched for).");
|
||||||
cvar_t r_image_downloadsizelimit = CVARFD("r_image_downloadsizelimit", "131072", CVAR_NOTFROMSERVER, "The maximum allowed file size of images loaded from a web-based url. 0 disables completely, while empty imposes no limit.");
|
cvar_t r_image_downloadsizelimit = CVARFD("r_image_downloadsizelimit", "131072", CVAR_NOTFROMSERVER, "The maximum allowed file size of images loaded from a web-based url. 0 disables completely, while empty imposes no limit.");
|
||||||
extern cvar_t scr_sshot_compression;
|
extern cvar_t scr_sshot_compression;
|
||||||
extern cvar_t gl_lerpimages;
|
extern cvar_t gl_lerpimages;
|
||||||
|
@ -9104,7 +9104,7 @@ void Image_Init(void)
|
||||||
Hash_InitTable(&imagetable, sizeof(imagetablebuckets)/sizeof(imagetablebuckets[0]), imagetablebuckets);
|
Hash_InitTable(&imagetable, sizeof(imagetablebuckets)/sizeof(imagetablebuckets[0]), imagetablebuckets);
|
||||||
|
|
||||||
Cmd_AddCommandD("r_imagelist", Image_List_f, "Prints out a list of the currently-known textures.");
|
Cmd_AddCommandD("r_imagelist", Image_List_f, "Prints out a list of the currently-known textures.");
|
||||||
Cmd_AddCommandD("r_imageformats", Image_Formats_f, "Prints out a list of the usable texture formats.");
|
Cmd_AddCommandD("r_imageformats", Image_Formats_f, "Prints out a list of the usable hardware pixel formats.");
|
||||||
}
|
}
|
||||||
//destroys all textures
|
//destroys all textures
|
||||||
void Image_Shutdown(void)
|
void Image_Shutdown(void)
|
||||||
|
|
|
@ -109,6 +109,7 @@ void R2D_FadeScreen (void);
|
||||||
void R2D_Font_Changed(void);
|
void R2D_Font_Changed(void);
|
||||||
void R2D_ConsoleBackground (int firstline, int lastline, qboolean forceopaque);
|
void R2D_ConsoleBackground (int firstline, int lastline, qboolean forceopaque);
|
||||||
void R2D_EditorBackground (void);
|
void R2D_EditorBackground (void);
|
||||||
|
qboolean R2D_DrawLevelshot(void);
|
||||||
|
|
||||||
void R2D_Image(float x, float y, float w, float h, float s1, float t1, float s2, float t2, mpic_t *pic);
|
void R2D_Image(float x, float y, float w, float h, float s1, float t1, float s2, float t2, mpic_t *pic);
|
||||||
void R2D_Image2dQuad(vec2_t const*points, vec2_t const*texcoords, vec4_t const*rgba, mpic_t *pic);
|
void R2D_Image2dQuad(vec2_t const*points, vec2_t const*texcoords, vec4_t const*rgba, mpic_t *pic);
|
||||||
|
|
|
@ -3599,6 +3599,7 @@ static qboolean P_LoadParticleSet(char *name, qboolean implicit, qboolean showwa
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
//built-in particle effects are always favoured. This is annoying, but means the cvar value alone is enough to detect cheats.
|
||||||
for (i = 0; partset_list[i].name; i++)
|
for (i = 0; partset_list[i].name; i++)
|
||||||
{
|
{
|
||||||
if (!stricmp(name, partset_list[i].name))
|
if (!stricmp(name, partset_list[i].name))
|
||||||
|
|
|
@ -3578,6 +3578,7 @@ static void QCBUILTIN PF_cs_runplayerphysics (pubprogfuncs_t *prinst, struct glo
|
||||||
pmove.safeorigin_known = false;
|
pmove.safeorigin_known = false;
|
||||||
pmove.capsule = false; //FIXME
|
pmove.capsule = false; //FIXME
|
||||||
|
|
||||||
|
movevars.coordsize = cls.netchan.message.prim.coordsize;
|
||||||
if (ent->xv->gravity)
|
if (ent->xv->gravity)
|
||||||
movevars.entgravity = ent->xv->gravity;
|
movevars.entgravity = ent->xv->gravity;
|
||||||
else if (csqc_playerseat >= 0 && cl.playerview[csqc_playerseat].playernum+1 == ent->xv->entnum)
|
else if (csqc_playerseat >= 0 && cl.playerview[csqc_playerseat].playernum+1 == ent->xv->entnum)
|
||||||
|
@ -7428,6 +7429,7 @@ qboolean CSQC_Init (qboolean anycsqc, const char *csprogsname, unsigned int chec
|
||||||
movevars.ktjump = false;//pm_ktjump.value;
|
movevars.ktjump = false;//pm_ktjump.value;
|
||||||
movevars.slidefix = true;//(pm_slidefix.value != 0);
|
movevars.slidefix = true;//(pm_slidefix.value != 0);
|
||||||
movevars.airstep = true;//(pm_airstep.value != 0);
|
movevars.airstep = true;//(pm_airstep.value != 0);
|
||||||
|
movevars.pground = true;
|
||||||
movevars.stepdown = true;
|
movevars.stepdown = true;
|
||||||
movevars.walljump = false;//(pm_walljump.value);
|
movevars.walljump = false;//(pm_walljump.value);
|
||||||
movevars.slidyslopes = false;//(pm_slidyslopes.value!=0);
|
movevars.slidyslopes = false;//(pm_slidyslopes.value!=0);
|
||||||
|
|
|
@ -312,7 +312,7 @@ extern cvar_t com_protocolversion;
|
||||||
extern cvar_t com_nogamedirnativecode;
|
extern cvar_t com_nogamedirnativecode;
|
||||||
extern cvar_t com_parseutf8;
|
extern cvar_t com_parseutf8;
|
||||||
#ifndef NOLEGACY
|
#ifndef NOLEGACY
|
||||||
extern cvar_t com_parseezquake;
|
extern cvar_t ezcompat_markup;
|
||||||
#endif
|
#endif
|
||||||
extern cvar_t sys_ticrate;
|
extern cvar_t sys_ticrate;
|
||||||
extern cvar_t sys_nostdout;
|
extern cvar_t sys_nostdout;
|
||||||
|
|
|
@ -1440,6 +1440,46 @@ void R2D_FadeScreen (void)
|
||||||
Sbar_Changed();
|
Sbar_Changed();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
qboolean R2D_DrawLevelshot(void)
|
||||||
|
{
|
||||||
|
extern char levelshotname[];
|
||||||
|
extern cvar_t scr_loadingscreen_aspect;
|
||||||
|
if (*levelshotname)
|
||||||
|
{
|
||||||
|
shader_t *pic = R2D_SafeCachePic (levelshotname);
|
||||||
|
int w,h;
|
||||||
|
if (!R_GetShaderSizes(pic, &w, &h, true))
|
||||||
|
{
|
||||||
|
#ifdef Q3CLIENT
|
||||||
|
pic = R2D_SafeCachePic("menu/art/unkownmap");
|
||||||
|
if (!R_GetShaderSizes(pic, &w, &h, true))
|
||||||
|
#endif
|
||||||
|
w = h = 1;
|
||||||
|
}
|
||||||
|
switch(scr_loadingscreen_aspect.ival)
|
||||||
|
{
|
||||||
|
case 0: //use the source image's aspect
|
||||||
|
break;
|
||||||
|
case 1: //q3 assumed 4:3 resolutions, with power-of-two images. lame, but lets retain the aspect
|
||||||
|
w = 640;
|
||||||
|
h = 480;
|
||||||
|
break;
|
||||||
|
case 2: //just ignore aspect entirely and stretch the thing in hideous ways
|
||||||
|
w = vid.width;
|
||||||
|
h = vid.height;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
R2D_Letterbox(0, 0, vid.width, vid.height, pic, w, h);
|
||||||
|
|
||||||
|
//q3's noise.
|
||||||
|
pic = R2D_SafeCachePic("levelShotDetail");
|
||||||
|
if (R_GetShaderSizes(pic, &w, &h, true))
|
||||||
|
R2D_Image(0, 0, vid.width, vid.height, 0, 0, vid.width/256, vid.height/256, pic);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
//crosshairs
|
//crosshairs
|
||||||
#define CS_HEIGHT 8
|
#define CS_HEIGHT 8
|
||||||
#define CS_WIDTH 8
|
#define CS_WIDTH 8
|
||||||
|
|
|
@ -3386,6 +3386,24 @@ char *particle_set_h2part =
|
||||||
"flurry 32\n"
|
"flurry 32\n"
|
||||||
"}\n"
|
"}\n"
|
||||||
|
|
||||||
|
//eidolon's arena
|
||||||
|
"r_part ce_rain\n"
|
||||||
|
"{\n"
|
||||||
|
"texture \"particles/fteparticlefont.tga\"\n"
|
||||||
|
"tcoords 1 1 63 63 256 2 64\n"
|
||||||
|
"type texturedspark\n"
|
||||||
|
"count 1\n"
|
||||||
|
"scale 2\n"
|
||||||
|
"scalefactor 1\n"
|
||||||
|
"die 1\n"
|
||||||
|
"alpha 0.2\n"
|
||||||
|
"alphadelta 0\n"
|
||||||
|
"rgb 255 255 255\n"
|
||||||
|
"friction 0\n"
|
||||||
|
"blend add\n"
|
||||||
|
"veladd 1\n"
|
||||||
|
"gravity 0\n"
|
||||||
|
"}\n"
|
||||||
|
|
||||||
//this teleport effect is nothing like hexen2's. hopefully it'll be acceptable :s
|
//this teleport effect is nothing like hexen2's. hopefully it'll be acceptable :s
|
||||||
//the down ring
|
//the down ring
|
||||||
|
@ -3422,7 +3440,6 @@ char *particle_set_h2part =
|
||||||
"}\n"
|
"}\n"
|
||||||
|
|
||||||
|
|
||||||
//h2part.ce_rain was not loaded
|
|
||||||
//h2part.ce_quake was not loaded
|
//h2part.ce_quake was not loaded
|
||||||
//h2part.ce_ghost was not loaded
|
//h2part.ce_ghost was not loaded
|
||||||
//h2part.ce_teleporterbody_1 was not loaded
|
//h2part.ce_teleporterbody_1 was not loaded
|
||||||
|
|
|
@ -119,8 +119,10 @@ cvar_t r_drawflat = CVARAF ("r_drawflat", "0", "gl_textureless",
|
||||||
CVAR_ARCHIVE | CVAR_SEMICHEAT | CVAR_RENDERERCALLBACK | CVAR_SHADERSYSTEM);
|
CVAR_ARCHIVE | CVAR_SEMICHEAT | CVAR_RENDERERCALLBACK | CVAR_SHADERSYSTEM);
|
||||||
cvar_t r_lightmap = CVARF ("r_lightmap", "0",
|
cvar_t r_lightmap = CVARF ("r_lightmap", "0",
|
||||||
CVAR_ARCHIVE | CVAR_SEMICHEAT | CVAR_RENDERERCALLBACK | CVAR_SHADERSYSTEM);
|
CVAR_ARCHIVE | CVAR_SEMICHEAT | CVAR_RENDERERCALLBACK | CVAR_SHADERSYSTEM);
|
||||||
cvar_t r_wireframe = CVARFD ("r_wireframe", "0",
|
cvar_t r_wireframe = CVARAFD ("r_wireframe", "0",
|
||||||
CVAR_CHEAT, "Developer feature where everything is drawn with wireframe over the top. Only active where cheats are permitted.");
|
"r_showtris", CVAR_CHEAT, "Developer feature where everything is drawn with wireframe over the top. Only active where cheats are permitted.");
|
||||||
|
cvar_t r_outline = CVARD ("gl_outline", "0", "Draw some stylised outlines.");
|
||||||
|
cvar_t r_outline_width = CVARD ("gl_outline_width", "0", "The width of those outlines.");
|
||||||
cvar_t r_wireframe_smooth = CVAR ("r_wireframe_smooth", "0");
|
cvar_t r_wireframe_smooth = CVAR ("r_wireframe_smooth", "0");
|
||||||
cvar_t r_refract_fbo = CVARD ("r_refract_fbo", "1", "Use an fbo for refraction. If 0, just renders as a portal and uses a copy of the current framebuffer.");
|
cvar_t r_refract_fbo = CVARD ("r_refract_fbo", "1", "Use an fbo for refraction. If 0, just renders as a portal and uses a copy of the current framebuffer.");
|
||||||
cvar_t r_refractreflect_scale = CVARD ("r_refractreflect_scale", "0.5", "Use a different scale for refraction and reflection texturemaps. Because $reasons.");
|
cvar_t r_refractreflect_scale = CVARD ("r_refractreflect_scale", "0.5", "Use a different scale for refraction and reflection texturemaps. Because $reasons.");
|
||||||
|
@ -896,6 +898,8 @@ void Renderer_Init(void)
|
||||||
Cvar_Register (&r_telestyle, GRAPHICALNICETIES);
|
Cvar_Register (&r_telestyle, GRAPHICALNICETIES);
|
||||||
Cvar_Register (&r_wireframe, GRAPHICALNICETIES);
|
Cvar_Register (&r_wireframe, GRAPHICALNICETIES);
|
||||||
Cvar_Register (&r_wireframe_smooth, GRAPHICALNICETIES);
|
Cvar_Register (&r_wireframe_smooth, GRAPHICALNICETIES);
|
||||||
|
Cvar_Register (&r_outline, GRAPHICALNICETIES);
|
||||||
|
Cvar_Register (&r_outline_width, GRAPHICALNICETIES);
|
||||||
Cvar_Register (&r_refract_fbo, GRAPHICALNICETIES);
|
Cvar_Register (&r_refract_fbo, GRAPHICALNICETIES);
|
||||||
Cvar_Register (&r_refractreflect_scale, GRAPHICALNICETIES);
|
Cvar_Register (&r_refractreflect_scale, GRAPHICALNICETIES);
|
||||||
Cvar_Register (&r_postprocshader, GRAPHICALNICETIES);
|
Cvar_Register (&r_postprocshader, GRAPHICALNICETIES);
|
||||||
|
|
|
@ -868,6 +868,8 @@ char *Sys_ConsoleInput(void)
|
||||||
if (!fgets(text, sizeof(text), stdin))
|
if (!fgets(text, sizeof(text), stdin))
|
||||||
return NULL;
|
return NULL;
|
||||||
nl = strchr(text, '\n');
|
nl = strchr(text, '\n');
|
||||||
|
if (!nl) //err? wut?
|
||||||
|
return NULL;
|
||||||
*nl = 0;
|
*nl = 0;
|
||||||
|
|
||||||
//Con_Printf("console input: %s\n", text);
|
//Con_Printf("console input: %s\n", text);
|
||||||
|
@ -975,6 +977,9 @@ int main (int c, const char **v)
|
||||||
TL_InitLanguages(parms.binarydir);
|
TL_InitLanguages(parms.binarydir);
|
||||||
|
|
||||||
|
|
||||||
|
if (!isatty(STDIN_FILENO))
|
||||||
|
noconinput = !isPlugin; //don't read the stdin if its probably screwed (running in qtcreator seems to pipe stdout to stdin in an attempt to screw everything up).
|
||||||
|
else
|
||||||
noconinput = COM_CheckParm("-noconinput");
|
noconinput = COM_CheckParm("-noconinput");
|
||||||
#ifndef __DJGPP__
|
#ifndef __DJGPP__
|
||||||
if (!noconinput)
|
if (!noconinput)
|
||||||
|
|
|
@ -53,9 +53,10 @@ cvar_t vsec_scaley[SIDEVIEWS] = {CVAR("v2_scaley", "0.25"), CVAR("v3_scaley", "0
|
||||||
cvar_t vsec_yaw[SIDEVIEWS] = {CVAR("v2_yaw", "180"), CVAR("v3_yaw", "90"), CVAR("v4_yaw", "270"), CVAR("v5_yaw", "0")};
|
cvar_t vsec_yaw[SIDEVIEWS] = {CVAR("v2_yaw", "180"), CVAR("v3_yaw", "90"), CVAR("v4_yaw", "270"), CVAR("v5_yaw", "0")};
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
cvar_t cl_rollspeed = CVAR("cl_rollspeed", "200");
|
cvar_t cl_rollspeed = CVARD("cl_rollspeed", "200", "Controls the speed required to reach cl_rollangle's tilt.");
|
||||||
cvar_t cl_rollangle = CVARD("cl_rollangle", "2.0", "Controls how much the view should tilt while strafing.");
|
cvar_t cl_rollangle = CVARD("cl_rollangle", "2.0", "Controls the maximum view should tilt while strafing.");
|
||||||
cvar_t v_deathtilt = CVAR("v_deathtilt", "1");
|
cvar_t cl_rollalpha = CVARD("cl_rollalpha", "20", "Controls the speed at which the view rolls according to sideways movement.");
|
||||||
|
cvar_t v_deathtilt = CVARD("v_deathtilt", "1", "Specifies whether to tilt the view when dead.");
|
||||||
|
|
||||||
cvar_t cl_bob = CVARD("cl_bob","0.02", "Controls how much the camera position should bob up down as the player runs around.");
|
cvar_t cl_bob = CVARD("cl_bob","0.02", "Controls how much the camera position should bob up down as the player runs around.");
|
||||||
cvar_t cl_bobcycle = CVAR("cl_bobcycle","0.6");
|
cvar_t cl_bobcycle = CVAR("cl_bobcycle","0.6");
|
||||||
|
@ -76,7 +77,7 @@ cvar_t v_ipitch_cycle = CVAR("v_ipitch_cycle", "1");
|
||||||
cvar_t v_iyaw_level = CVAR("v_iyaw_level", "0.3");
|
cvar_t v_iyaw_level = CVAR("v_iyaw_level", "0.3");
|
||||||
cvar_t v_iroll_level = CVAR("v_iroll_level", "0.1");
|
cvar_t v_iroll_level = CVAR("v_iroll_level", "0.1");
|
||||||
cvar_t v_ipitch_level = CVAR("v_ipitch_level", "0.3");
|
cvar_t v_ipitch_level = CVAR("v_ipitch_level", "0.3");
|
||||||
cvar_t v_idlescale = CVAR("v_idlescale", "0");
|
cvar_t v_idlescale = CVARD("v_idlescale", "0", "Enable swishing of the view (whether idle or otherwise). Often used for concussion effects.");
|
||||||
|
|
||||||
cvar_t crosshair = CVARF("crosshair", "1", CVAR_ARCHIVE);
|
cvar_t crosshair = CVARF("crosshair", "1", CVAR_ARCHIVE);
|
||||||
cvar_t crosshaircolor = CVARF("crosshaircolor", "255 255 255", CVAR_ARCHIVE);
|
cvar_t crosshaircolor = CVARF("crosshaircolor", "255 255 255", CVAR_ARCHIVE);
|
||||||
|
@ -84,8 +85,8 @@ cvar_t crosshairsize = CVARF("crosshairsize", "8", CVAR_ARCHIVE);
|
||||||
|
|
||||||
cvar_t cl_crossx = CVARF("cl_crossx", "0", CVAR_ARCHIVE);
|
cvar_t cl_crossx = CVARF("cl_crossx", "0", CVAR_ARCHIVE);
|
||||||
cvar_t cl_crossy = CVARF("cl_crossy", "0", CVAR_ARCHIVE);
|
cvar_t cl_crossy = CVARF("cl_crossy", "0", CVAR_ARCHIVE);
|
||||||
cvar_t crosshaircorrect = CVARF("crosshaircorrect", "0", CVAR_SEMICHEAT);
|
cvar_t crosshaircorrect = CVARFD("crosshaircorrect", "0", CVAR_SEMICHEAT, "Moves the crosshair around to represent the impact point of a weapon positioned below the actual view position.");
|
||||||
cvar_t crosshairimage = CVAR("crosshairimage", "");
|
cvar_t crosshairimage = CVARD("crosshairimage", "", "Enables the use of an external/custom crosshair image");
|
||||||
cvar_t crosshairalpha = CVAR("crosshairalpha", "1");
|
cvar_t crosshairalpha = CVAR("crosshairalpha", "1");
|
||||||
|
|
||||||
cvar_t gl_cshiftpercent = CVAR("gl_cshiftpercent", "100");
|
cvar_t gl_cshiftpercent = CVAR("gl_cshiftpercent", "100");
|
||||||
|
@ -1133,12 +1134,7 @@ void V_CalcViewRoll (playerview_t *pv)
|
||||||
|
|
||||||
side = V_CalcRoll (pv->simangles, pv->simvel);
|
side = V_CalcRoll (pv->simangles, pv->simvel);
|
||||||
|
|
||||||
adjspeed = fabs(cl_rollangle.value);
|
adjspeed = cl_rollalpha.value * bound(1, fabs(cl_rollangle.value), 45);
|
||||||
if (adjspeed<1)
|
|
||||||
adjspeed=1;
|
|
||||||
if (adjspeed>45)
|
|
||||||
adjspeed = 45;
|
|
||||||
adjspeed*=20;
|
|
||||||
if (side > pv->rollangle)
|
if (side > pv->rollangle)
|
||||||
{
|
{
|
||||||
pv->rollangle += host_frametime * adjspeed;
|
pv->rollangle += host_frametime * adjspeed;
|
||||||
|
@ -2544,6 +2540,7 @@ void V_Init (void)
|
||||||
|
|
||||||
Cvar_Register (&cl_rollspeed, VIEWVARS);
|
Cvar_Register (&cl_rollspeed, VIEWVARS);
|
||||||
Cvar_Register (&cl_rollangle, VIEWVARS);
|
Cvar_Register (&cl_rollangle, VIEWVARS);
|
||||||
|
Cvar_Register (&cl_rollalpha, VIEWVARS);
|
||||||
Cvar_Register (&cl_bob, VIEWVARS);
|
Cvar_Register (&cl_bob, VIEWVARS);
|
||||||
Cvar_Register (&cl_bobcycle, VIEWVARS);
|
Cvar_Register (&cl_bobcycle, VIEWVARS);
|
||||||
Cvar_Register (&cl_bobup, VIEWVARS);
|
Cvar_Register (&cl_bobup, VIEWVARS);
|
||||||
|
|
|
@ -885,7 +885,7 @@ static void Cmd_Echo_f (void)
|
||||||
#else
|
#else
|
||||||
t = TP_ParseFunChars(t);
|
t = TP_ParseFunChars(t);
|
||||||
#ifndef NOLEGACY
|
#ifndef NOLEGACY
|
||||||
Con_PrintFlags (t, (com_parseezquake.ival?PFS_EZQUAKEMARKUP:0), 0);
|
Con_PrintFlags (t, ((ezcompat_markup.ival>=2)?PFS_EZQUAKEMARKUP:0), 0);
|
||||||
#else
|
#else
|
||||||
Con_PrintFlags (t, 0, 0);
|
Con_PrintFlags (t, 0, 0);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -126,8 +126,8 @@ cvar_t fs_gamename = CVARAFD("com_fullgamename", NULL, "fs_gamename", CVAR_NOSET
|
||||||
cvar_t com_protocolname = CVARAD("com_protocolname", NULL, "com_gamename", "The protocol game name used for dpmaster queries. For compatibility with DP, you can set this to 'DarkPlaces-Quake' in order to be listed in DP's master server, and to list DP servers.");
|
cvar_t com_protocolname = CVARAD("com_protocolname", NULL, "com_gamename", "The protocol game name used for dpmaster queries. For compatibility with DP, you can set this to 'DarkPlaces-Quake' in order to be listed in DP's master server, and to list DP servers.");
|
||||||
cvar_t com_protocolversion = CVARAD("com_protocolversion", "3", NULL, "The protocol version used for dpmaster queries."); //3 by default, for compat with DP/NQ, even if our QW protocol uses different versions entirely. really it only matters for master servers.
|
cvar_t com_protocolversion = CVARAD("com_protocolversion", "3", NULL, "The protocol version used for dpmaster queries."); //3 by default, for compat with DP/NQ, even if our QW protocol uses different versions entirely. really it only matters for master servers.
|
||||||
cvar_t com_parseutf8 = CVARD("com_parseutf8", "1", "Interpret console messages/playernames/etc as UTF-8. Requires special fonts. -1=iso 8859-1. 0=quakeascii(chat uses high chars). 1=utf8, revert to ascii on decode errors. 2=utf8 ignoring errors"); //1 parse. 2 parse, but stop parsing that string if a char was malformed.
|
cvar_t com_parseutf8 = CVARD("com_parseutf8", "1", "Interpret console messages/playernames/etc as UTF-8. Requires special fonts. -1=iso 8859-1. 0=quakeascii(chat uses high chars). 1=utf8, revert to ascii on decode errors. 2=utf8 ignoring errors"); //1 parse. 2 parse, but stop parsing that string if a char was malformed.
|
||||||
#if !defined(NOLEGACY) && defined(HAVE_CLIENT)
|
#if !defined(NOLEGACY)
|
||||||
cvar_t com_parseezquake = CVARD("com_parseezquake", "0", "Treat chevron chars from configs as a per-character flag. You should use this only for compat with nquake's configs.");
|
cvar_t ezcompat_markup = CVARD("ezcompat_markup", "1", "Attempt compatibility with ezquake's text markup.0: disabled.\n1: Handle markup ampersand markup.\n2: Handle chevron markup (only in echo commands, for config compat, because its just too unreliable otherwise).");
|
||||||
#endif
|
#endif
|
||||||
cvar_t com_highlightcolor = CVARD("com_highlightcolor", STRINGIFY(COLOR_RED), "ANSI colour to be used for highlighted text, used when com_parseutf8 is active.");
|
cvar_t com_highlightcolor = CVARD("com_highlightcolor", STRINGIFY(COLOR_RED), "ANSI colour to be used for highlighted text, used when com_parseutf8 is active.");
|
||||||
cvar_t com_nogamedirnativecode = CVARFD("com_nogamedirnativecode", "1", CVAR_NOTFROMSERVER, FULLENGINENAME" blocks all downloads of files with a .dll or .so extension, however other engines (eg: ezquake and fodquake) do not - this omission can be used to trigger delayed eremote exploits in any engine (including "DISTRIBUTION") which is later run from the same gamedir.\nQuake2, Quake3(when debugging), and KTX typically run native gamecode from within gamedirs, so if you wish to run any of these games you will need to ensure this cvar is changed to 0, as well as ensure that you don't run unsafe clients.");
|
cvar_t com_nogamedirnativecode = CVARFD("com_nogamedirnativecode", "1", CVAR_NOTFROMSERVER, FULLENGINENAME" blocks all downloads of files with a .dll or .so extension, however other engines (eg: ezquake and fodquake) do not - this omission can be used to trigger delayed eremote exploits in any engine (including "DISTRIBUTION") which is later run from the same gamedir.\nQuake2, Quake3(when debugging), and KTX typically run native gamecode from within gamedirs, so if you wish to run any of these games you will need to ensure this cvar is changed to 0, as well as ensure that you don't run unsafe clients.");
|
||||||
|
@ -3251,6 +3251,7 @@ conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t
|
||||||
conchar_t *oldout = out;
|
conchar_t *oldout = out;
|
||||||
#ifndef NOLEGACY
|
#ifndef NOLEGACY
|
||||||
extern cvar_t dpcompat_console;
|
extern cvar_t dpcompat_console;
|
||||||
|
extern cvar_t ezcompat_markup;
|
||||||
|
|
||||||
if (flags & PFS_EZQUAKEMARKUP)
|
if (flags & PFS_EZQUAKEMARKUP)
|
||||||
{
|
{
|
||||||
|
@ -3577,7 +3578,7 @@ conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#ifndef NOLEGACY
|
#ifndef NOLEGACY
|
||||||
else if (*str == '&' && str[1] == 'c' && !(flags & PFS_NOMARKUP))
|
else if (*str == '&' && str[1] == 'c' && !(flags & PFS_NOMARKUP) && ezcompat_markup.ival)
|
||||||
{
|
{
|
||||||
// ezQuake color codes
|
// ezQuake color codes
|
||||||
|
|
||||||
|
@ -3600,7 +3601,7 @@ conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (*str == '&' && str[1] == 'r' && !(flags & PFS_NOMARKUP))
|
else if (*str == '&' && str[1] == 'r' && !(flags & PFS_NOMARKUP) && ezcompat_markup.ival)
|
||||||
{
|
{
|
||||||
//ezquake revert
|
//ezquake revert
|
||||||
ext = (COLOR_WHITE << CON_FGSHIFT) | (ext&~(CON_RICHFOREMASK|CON_RICHFORECOLOUR));
|
ext = (COLOR_WHITE << CON_FGSHIFT) | (ext&~(CON_RICHFOREMASK|CON_RICHFORECOLOUR));
|
||||||
|
@ -3610,7 +3611,7 @@ conchar_t *COM_ParseFunString(conchar_t defaultflags, const char *str, conchar_t
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (str[0] == '=' && str[1] == '`' && str[2] == 'k' && str[3] == '8' && str[4] == ':' && !keepmarkup)
|
else if (str[0] == '=' && str[1] == '`' && str[2] == 'k' && str[3] == '8' && str[4] == ':' && !keepmarkup && ezcompat_markup.ival)
|
||||||
{
|
{
|
||||||
//ezquake compat: koi8 compat for crazy russian people.
|
//ezquake compat: koi8 compat for crazy russian people.
|
||||||
//we parse for compat but don't generate (they'll see utf-8 from us).
|
//we parse for compat but don't generate (they'll see utf-8 from us).
|
||||||
|
@ -5758,8 +5759,8 @@ void COM_Init (void)
|
||||||
Cvar_Register (&gameversion_max, "Gamecode");
|
Cvar_Register (&gameversion_max, "Gamecode");
|
||||||
Cvar_Register (&com_nogamedirnativecode, "Gamecode");
|
Cvar_Register (&com_nogamedirnativecode, "Gamecode");
|
||||||
Cvar_Register (&com_parseutf8, "Internationalisation");
|
Cvar_Register (&com_parseutf8, "Internationalisation");
|
||||||
#if !defined(NOLEGACY) && defined(HAVE_CLIENT)
|
#if !defined(NOLEGACY)
|
||||||
Cvar_Register (&com_parseezquake, NULL);
|
Cvar_Register (&ezcompat_markup, NULL);
|
||||||
#endif
|
#endif
|
||||||
Cvar_Register (&com_highlightcolor, "Internationalisation");
|
Cvar_Register (&com_highlightcolor, "Internationalisation");
|
||||||
com_parseutf8.ival = 1;
|
com_parseutf8.ival = 1;
|
||||||
|
|
|
@ -3150,6 +3150,8 @@ const gamemode_info_t gamemode_info[] = {
|
||||||
{"-afterquake", NULL, "FTE-Quake",{"id1/pak0.pak", "id1/quake.rc"}, QCFG,{"id1", "qw", "*fte"}, "Quake", "https://triptohell.info/downloadables.php" /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/},
|
{"-afterquake", NULL, "FTE-Quake",{"id1/pak0.pak", "id1/quake.rc"}, QCFG,{"id1", "qw", "*fte"}, "Quake", "https://triptohell.info/downloadables.php" /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/},
|
||||||
//netquake-specific quake that avoids qw/ with its nquake fuckups, and disables nqisms
|
//netquake-specific quake that avoids qw/ with its nquake fuckups, and disables nqisms
|
||||||
{"-netquake", "nq", "FTE-Quake DarkPlaces-Quake",{"id1/pak0.pak", "id1/quake.rc"},NQCFG,{"id1"}, "NetQuake", "https://triptohell.info/downloadables.php" /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/},
|
{"-netquake", "nq", "FTE-Quake DarkPlaces-Quake",{"id1/pak0.pak", "id1/quake.rc"},NQCFG,{"id1"}, "NetQuake", "https://triptohell.info/downloadables.php" /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/},
|
||||||
|
//because we can. quakespasm is hopefully close enough...
|
||||||
|
{"-fitz", NULL, "FTE-Quake DarkPlaces-Quake",{"id1/pak0.pak", "id1/quake.rc"},NQCFG"fps_preset spasm\n",{"id1"}, "NetQuake", "https://triptohell.info/downloadables.php" /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/},
|
||||||
//because we can
|
//because we can
|
||||||
{"-tenebrae", NULL, "FTE-Quake DarkPlaces-Quake",{"id1/pak0.pak", "id1/quake.rc"},QCFG"fps_preset tenebrae\n",{"id1","qw","*fte"},"Tenebrae", "https://triptohell.info/downloadables.php" /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/},
|
{"-tenebrae", NULL, "FTE-Quake DarkPlaces-Quake",{"id1/pak0.pak", "id1/quake.rc"},QCFG"fps_preset tenebrae\n",{"id1","qw","*fte"},"Tenebrae", "https://triptohell.info/downloadables.php" /*,"id1/pak0.pak|http://quakeservers.nquake.com/qsw106.zip|http://nquake.localghost.net/qsw106.zip|http://qw.quakephil.com/nquake/qsw106.zip|http://fnu.nquake.com/qsw106.zip"*/},
|
||||||
|
|
||||||
|
|
|
@ -426,8 +426,7 @@ int PM_StepSlideMove (qboolean in_air)
|
||||||
VectorCopy (trace.endpos, pmove.origin);
|
VectorCopy (trace.endpos, pmove.origin);
|
||||||
}
|
}
|
||||||
|
|
||||||
//FIXME gravitydir
|
if ((in_air || movevars.slidefix) && -DotProduct(pmove.gravitydir, original) < 0)
|
||||||
if ((in_air || movevars.slidefix) && originalvel[2] < 0)
|
|
||||||
VectorMA(pmove.velocity, -DotProduct(pmove.velocity, pmove.gravitydir), pmove.gravitydir, pmove.velocity); //z=0
|
VectorMA(pmove.velocity, -DotProduct(pmove.velocity, pmove.gravitydir), pmove.gravitydir, pmove.velocity); //z=0
|
||||||
|
|
||||||
PM_SlideMove ();
|
PM_SlideMove ();
|
||||||
|
@ -867,7 +866,7 @@ void PM_AirMove (void)
|
||||||
else
|
else
|
||||||
blocked = PM_SlideMove ();
|
blocked = PM_SlideMove ();
|
||||||
|
|
||||||
if (blocked & BLOCKED_FLOOR)
|
if (movevars.pground && (blocked & BLOCKED_FLOOR))
|
||||||
pmove.onground = true;
|
pmove.onground = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -949,9 +948,17 @@ void PM_CategorizePosition (void)
|
||||||
{
|
{
|
||||||
pmove.onground = false;
|
pmove.onground = false;
|
||||||
}
|
}
|
||||||
else
|
else if (!movevars.pground || pmove.onground)
|
||||||
{
|
{
|
||||||
trace = PM_PlayerTracePortals (pmove.origin, point, MASK_PLAYERSOLID, NULL);
|
trace = PM_PlayerTracePortals (pmove.origin, point, MASK_PLAYERSOLID, NULL);
|
||||||
|
if (!trace.startsolid && trace.fraction < 1 && -DotProduct(pmove.gravitydir, trace.plane.normal) < MIN_STEP_NORMAL)
|
||||||
|
{ //if the trace hit a slope, slide down the slope to see if we can find ground below. this should fix the 'base-of-slope-is-slide' bug.
|
||||||
|
vec3_t bounce;
|
||||||
|
PM_ClipVelocity (pmove.gravitydir, trace.plane.normal, bounce, 2);
|
||||||
|
VectorMA(trace.endpos, 1-trace.fraction, bounce, point);
|
||||||
|
trace = PM_PlayerTracePortals (trace.endpos, point, MASK_PLAYERSOLID, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
if (!trace.startsolid && (trace.fraction == 1 || -DotProduct(pmove.gravitydir, trace.plane.normal) < MIN_STEP_NORMAL))
|
if (!trace.startsolid && (trace.fraction == 1 || -DotProduct(pmove.gravitydir, trace.plane.normal) < MIN_STEP_NORMAL))
|
||||||
pmove.onground = false;
|
pmove.onground = false;
|
||||||
else
|
else
|
||||||
|
@ -1044,7 +1051,7 @@ void PM_CategorizePosition (void)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pmove.onground && pmove.pm_type != PM_FLY && pmove.waterlevel < 2)
|
if (!movevars.pground && pmove.onground && pmove.pm_type != PM_FLY && pmove.waterlevel < 2)
|
||||||
{
|
{
|
||||||
// snap to ground so that we can't jump higher than we're supposed to
|
// snap to ground so that we can't jump higher than we're supposed to
|
||||||
if (!trace.startsolid && !trace.allsolid)
|
if (!trace.startsolid && !trace.allsolid)
|
||||||
|
@ -1102,7 +1109,7 @@ static void PM_CheckJump (void)
|
||||||
|
|
||||||
// check for jump bug
|
// check for jump bug
|
||||||
// groundplane normal was set in the call to PM_CategorizePosition
|
// groundplane normal was set in the call to PM_CategorizePosition
|
||||||
if (-DotProduct(pmove.gravitydir, pmove.velocity) < 0 && DotProduct(pmove.velocity, groundplane.normal) < -0.1)
|
if (!movevars.pground && -DotProduct(pmove.gravitydir, pmove.velocity) < 0 && DotProduct(pmove.velocity, groundplane.normal) < -0.1)
|
||||||
{
|
{
|
||||||
// pmove.velocity is pointing into the ground, clip it
|
// pmove.velocity is pointing into the ground, clip it
|
||||||
PM_ClipVelocity (pmove.velocity, groundplane.normal, pmove.velocity, 1);
|
PM_ClipVelocity (pmove.velocity, groundplane.normal, pmove.velocity, 1);
|
||||||
|
@ -1121,7 +1128,6 @@ static void PM_CheckJump (void)
|
||||||
}
|
}
|
||||||
|
|
||||||
pmove.jump_held = true; // don't jump again until released
|
pmove.jump_held = true; // don't jump again until released
|
||||||
|
|
||||||
pmove.jump_msec = pmove.cmd.msec;
|
pmove.jump_msec = pmove.cmd.msec;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1215,19 +1221,21 @@ static void PM_NudgePosition (void)
|
||||||
vec3_t base;
|
vec3_t base;
|
||||||
int x, y, z;
|
int x, y, z;
|
||||||
int i;
|
int i;
|
||||||
static int sign[5] = {0, -1, 1, -2, 2};
|
static float sign[5] = {0, -1/8.0, 1/8.0, -2/8.0, 2/8.0};
|
||||||
|
|
||||||
VectorCopy (pmove.origin, base);
|
VectorCopy (pmove.origin, base);
|
||||||
|
|
||||||
for (i=0 ; i<3 ; i++)
|
if (movevars.coordsize) for (i=0 ; i<3 ; i++)
|
||||||
base[i] = MSG_FromCoord(MSG_ToCoord(base[i], 2), 2);
|
base[i] = MSG_FromCoord(MSG_ToCoord(base[i], movevars.coordsize), movevars.coordsize); //higher precision or at least with more accurate rounding
|
||||||
|
else for (i=0 ; i<3 ; i++)
|
||||||
|
base[i] = ((int) (pmove.origin[i] * 8)) * 0.125; //legacy compat, which biases towards the origin.
|
||||||
|
|
||||||
// VectorCopy (base, pmove.origin);
|
// VectorCopy (base, pmove.origin);
|
||||||
|
|
||||||
//if we're moving, allow that spot without snapping to any grid
|
//if we're moving, allow that spot without snapping to any grid
|
||||||
// if (pmove.velocity[0] || pmove.velocity[1] || pmove.velocity[2])
|
// if (pmove.velocity[0] || pmove.velocity[1] || pmove.velocity[2])
|
||||||
if (PM_TestPlayerPosition (pmove.origin, false))
|
// if (PM_TestPlayerPosition (pmove.origin, false))
|
||||||
return;
|
// return;
|
||||||
|
|
||||||
for (z=0 ; z<countof(sign) ; z++)
|
for (z=0 ; z<countof(sign) ; z++)
|
||||||
{
|
{
|
||||||
|
@ -1235,9 +1243,9 @@ static void PM_NudgePosition (void)
|
||||||
{
|
{
|
||||||
for (y=0 ; y<countof(sign) ; y++)
|
for (y=0 ; y<countof(sign) ; y++)
|
||||||
{
|
{
|
||||||
pmove.origin[0] = base[0] + (sign[x] * 1.0/8);
|
pmove.origin[0] = base[0] + sign[x];
|
||||||
pmove.origin[1] = base[1] + (sign[y] * 1.0/8);
|
pmove.origin[1] = base[1] + sign[y];
|
||||||
pmove.origin[2] = base[2] + (sign[z] * 1.0/8);
|
pmove.origin[2] = base[2] + sign[z];
|
||||||
if (PM_TestPlayerPosition (pmove.origin, false))
|
if (PM_TestPlayerPosition (pmove.origin, false))
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -1251,8 +1259,8 @@ static void PM_NudgePosition (void)
|
||||||
{
|
{
|
||||||
for (y=0 ; y<3 ; y++)
|
for (y=0 ; y<3 ; y++)
|
||||||
{
|
{
|
||||||
pmove.origin[0] = base[0] + (sign[x] * 1.0/8);
|
pmove.origin[0] = base[0] + sign[x];
|
||||||
pmove.origin[1] = base[1] + (sign[y] * 1.0/8);
|
pmove.origin[1] = base[1] + sign[y];
|
||||||
pmove.origin[2] = base[2] + z;
|
pmove.origin[2] = base[2] + z;
|
||||||
if (PM_TestPlayerPosition (pmove.origin, false))
|
if (PM_TestPlayerPosition (pmove.origin, false))
|
||||||
return;
|
return;
|
||||||
|
@ -1443,7 +1451,7 @@ void PM_PlayerMove (float gamespeed)
|
||||||
|
|
||||||
// this is to make sure landing sound is not played twice
|
// this is to make sure landing sound is not played twice
|
||||||
// and falling damage is calculated correctly
|
// and falling damage is calculated correctly
|
||||||
if (pmove.onground && -DotProduct(pmove.gravitydir, pmove.velocity) < -300
|
if (!movevars.pground && pmove.onground && -DotProduct(pmove.gravitydir, pmove.velocity) < -300
|
||||||
&& DotProduct(pmove.velocity, groundplane.normal) < -0.1)
|
&& DotProduct(pmove.velocity, groundplane.normal) < -0.1)
|
||||||
{
|
{
|
||||||
PM_ClipVelocity (pmove.velocity, groundplane.normal, pmove.velocity, 1);
|
PM_ClipVelocity (pmove.velocity, groundplane.normal, pmove.velocity, 1);
|
||||||
|
|
|
@ -117,6 +117,7 @@ typedef struct {
|
||||||
int walljump;
|
int walljump;
|
||||||
qboolean slidefix;
|
qboolean slidefix;
|
||||||
qboolean airstep;
|
qboolean airstep;
|
||||||
|
qboolean pground;
|
||||||
qboolean stepdown;
|
qboolean stepdown;
|
||||||
qboolean slidyslopes;
|
qboolean slidyslopes;
|
||||||
int stepheight;
|
int stepheight;
|
||||||
|
|
|
@ -2358,12 +2358,22 @@ static int PF_fread_internal (pubprogfuncs_t *prinst, int fnum, char *buf, size_
|
||||||
return 0; //this just isn't ours.
|
return 0; //this just isn't ours.
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (pf_fopen_files[fnum].accessmode == FRIK_FILE_READ_DELAY)
|
||||||
|
{ //on first read, convert into a regular file.
|
||||||
|
pf_fopen_files[fnum].accessmode = FRIK_FILE_READ;
|
||||||
|
pf_fopen_files[fnum].data = BZ_Malloc(pf_fopen_files[fnum].len+1);
|
||||||
|
pf_fopen_files[fnum].data[pf_fopen_files[fnum].len] = 0;
|
||||||
|
pf_fopen_files[fnum].len = pf_fopen_files[fnum].bufferlen = VFS_READ(pf_fopen_files[fnum].file, pf_fopen_files[fnum].data, pf_fopen_files[fnum].len);
|
||||||
|
VFS_CLOSE(pf_fopen_files[fnum].file);
|
||||||
|
pf_fopen_files[fnum].file = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
switch(pf_fopen_files[fnum].accessmode)
|
switch(pf_fopen_files[fnum].accessmode)
|
||||||
{
|
{
|
||||||
default:
|
default:
|
||||||
|
PF_Warningf(prinst, "PF_fread: File not opened for reading\n");
|
||||||
return 0;
|
return 0;
|
||||||
case FRIK_FILE_READ:
|
case FRIK_FILE_READ:
|
||||||
//UTF-8-FIXME: de-modify utf-8
|
|
||||||
if (pf_fopen_files[fnum].ofs + len > pf_fopen_files[fnum].len)
|
if (pf_fopen_files[fnum].ofs + len > pf_fopen_files[fnum].len)
|
||||||
len = pf_fopen_files[fnum].len - pf_fopen_files[fnum].ofs;
|
len = pf_fopen_files[fnum].len - pf_fopen_files[fnum].ofs;
|
||||||
|
|
||||||
|
@ -5050,7 +5060,9 @@ void QCBUILTIN PF_argescape(pubprogfuncs_t *prinst, struct globalvars_s *pr_glob
|
||||||
|
|
||||||
void QCBUILTIN PF_random (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
void QCBUILTIN PF_random (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||||
{
|
{
|
||||||
G_FLOAT(OFS_RETURN) = (rand ()&0x7fff) / ((float)0x8000);
|
//don't return 1 (it would break array[random()*array.length];
|
||||||
|
//don't return 0 either, it would break the self.nextthink = time+random()*foo; lines in walkmonster_start, resulting rarely in statue-monsters.
|
||||||
|
G_FLOAT(OFS_RETURN) = (rand ()&0x7fff) / ((float)0x08000) + (0.5/0x08000);
|
||||||
}
|
}
|
||||||
|
|
||||||
//float(float number, float quantity) bitshift = #218;
|
//float(float number, float quantity) bitshift = #218;
|
||||||
|
|
|
@ -753,7 +753,7 @@ typedef enum
|
||||||
#define FRIK_FILE_MMAP_READ 5 /*fgets returns a pointer. memory is not guarenteed to be released.*/
|
#define FRIK_FILE_MMAP_READ 5 /*fgets returns a pointer. memory is not guarenteed to be released.*/
|
||||||
#define FRIK_FILE_MMAP_RW 6 /*fgets returns a pointer. file is written upon close. memory is not guarenteed to be released.*/
|
#define FRIK_FILE_MMAP_RW 6 /*fgets returns a pointer. file is written upon close. memory is not guarenteed to be released.*/
|
||||||
|
|
||||||
#define FRIK_FILE_READ_DELAY (7) /*internal special mode where the file is not read until the first read. this avoids extra slowness with xonotic*/
|
#define FRIK_FILE_READ_DELAY (7) /*internal special mode where the file is not read until the first read. this avoids extra slowness with xonotic (where it uses fopen to see if (large) binary file exists, resulting in large binary files getting decompressed repeatedly then discarded without reading)*/
|
||||||
|
|
||||||
#define MASK_DELTA 1
|
#define MASK_DELTA 1
|
||||||
#define MASK_STDVIEWMODEL 2
|
#define MASK_STDVIEWMODEL 2
|
||||||
|
|
|
@ -92,15 +92,16 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#define Z_EXT_JOIN_OBSERVE (1<<5) // server: "join" and "observe" commands are supported
|
#define Z_EXT_JOIN_OBSERVE (1<<5) // server: "join" and "observe" commands are supported
|
||||||
// client: on-the-fly spectator <-> player switching supported
|
// client: on-the-fly spectator <-> player switching supported
|
||||||
|
|
||||||
//#define Z_EXT_PF_ONGROUND (1<<6) // server: PF_ONGROUND is valid for all svc_playerinfo
|
#define Z_EXT_PF_ONGROUND (1<<6) // server: PF_ONGROUND is valid for all svc_playerinfo
|
||||||
#define Z_EXT_VWEP (1<<7)
|
#define Z_EXT_VWEP (1<<7)
|
||||||
//#define Z_EXT_PF_SOLID (1<<8) //conflicts with many FTE extensions.
|
#define Z_EXT_PF_SOLID (1<<8) //conflicts with many FTE extensions.
|
||||||
|
|
||||||
#ifdef QUAKESTATS
|
#ifdef QUAKESTATS
|
||||||
#define SUPPORTED_Z_EXTENSIONS (Z_EXT_PM_TYPE|Z_EXT_PM_TYPE_NEW|Z_EXT_VIEWHEIGHT|Z_EXT_SERVERTIME|Z_EXT_PITCHLIMITS|Z_EXT_JOIN_OBSERVE|Z_EXT_VWEP)
|
#define SERVER_SUPPORTED_Z_EXTENSIONS (Z_EXT_PM_TYPE|Z_EXT_PM_TYPE_NEW|Z_EXT_VIEWHEIGHT|Z_EXT_SERVERTIME|Z_EXT_PITCHLIMITS|Z_EXT_JOIN_OBSERVE/*|Z_EXT_PF_ONGROUND*/|Z_EXT_VWEP/*|Z_EXT_PF_SOLID*/)
|
||||||
#else
|
#else
|
||||||
#define SUPPORTED_Z_EXTENSIONS (Z_EXT_PM_TYPE|Z_EXT_PM_TYPE_NEW|Z_EXT_PITCHLIMITS|Z_EXT_JOIN_OBSERVE|Z_EXT_VWEP)
|
#define SERVER_SUPPORTED_Z_EXTENSIONS (Z_EXT_PM_TYPE|Z_EXT_PM_TYPE_NEW|Z_EXT_PITCHLIMITS|Z_EXT_JOIN_OBSERVE/*|Z_EXT_PF_ONGROUND*/|Z_EXT_VWEP/*|Z_EXT_PF_SOLID*/)
|
||||||
#endif
|
#endif
|
||||||
|
#define CLIENT_SUPPORTED_Z_EXTENSIONS (SERVER_SUPPORTED_Z_EXTENSIONS|Z_EXT_PF_ONGROUND|Z_EXT_PF_SOLID)
|
||||||
|
|
||||||
|
|
||||||
#define PROTOCOL_VERSION_VARLENGTH (('v'<<0) + ('l'<<8) + ('e'<<16) + ('n' << 24)) //variable length handshake
|
#define PROTOCOL_VERSION_VARLENGTH (('v'<<0) + ('l'<<8) + ('e'<<16) + ('n' << 24)) //variable length handshake
|
||||||
|
@ -519,11 +520,9 @@ enum {
|
||||||
#define PF_GIB (1<<10) // offset the view height differently
|
#define PF_GIB (1<<10) // offset the view height differently
|
||||||
|
|
||||||
//ZQuake.
|
//ZQuake.
|
||||||
#define PF_PMC_MASK ((1<<11) +\
|
#define PF_PMC_MASK ((1<<11) | \
|
||||||
(1<<12) +\
|
(1<<12) | \
|
||||||
(1<<13))
|
(1<<13))
|
||||||
|
|
||||||
|
|
||||||
#ifdef PEXT_HULLSIZE
|
#ifdef PEXT_HULLSIZE
|
||||||
#define PF_HULLSIZE_Z (1<<14)
|
#define PF_HULLSIZE_Z (1<<14)
|
||||||
#endif
|
#endif
|
||||||
|
@ -540,8 +539,11 @@ enum {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PF_COLOURMOD (1<<19)
|
#define PF_COLOURMOD (1<<19)
|
||||||
|
//#define PF_UNUSED (1<<20) //remember to faff with zext
|
||||||
|
//#define PF_UNUSED (1<<21) //remember to faff with zext
|
||||||
//note that if you add any more, you may need to change the check in the client so more can be parsed
|
//note that if you add any more, you may need to change the check in the client so more can be parsed
|
||||||
|
#define PF_ONGROUND (1<<22) //or 14, depending on extensions... messy.
|
||||||
|
#define PF_SOLID (1<<23) //or 15, depending on extensions... messy.
|
||||||
|
|
||||||
|
|
||||||
#define PF_PMC_SHIFT 11
|
#define PF_PMC_SHIFT 11
|
||||||
|
@ -1087,7 +1089,7 @@ typedef struct entity_state_s
|
||||||
struct
|
struct
|
||||||
{
|
{
|
||||||
/*info to predict other players, so I don't get yelled at if fte were to stop supporting it*/
|
/*info to predict other players, so I don't get yelled at if fte were to stop supporting it*/
|
||||||
qbyte pmovetype;
|
qbyte pmovetype; //&128 means onground.
|
||||||
qbyte msec;
|
qbyte msec;
|
||||||
short vangle[3];
|
short vangle[3];
|
||||||
|
|
||||||
|
|
|
@ -23,6 +23,8 @@ void DumpGLState(void);
|
||||||
extern cvar_t gl_overbright;
|
extern cvar_t gl_overbright;
|
||||||
extern cvar_t r_tessellation;
|
extern cvar_t r_tessellation;
|
||||||
extern cvar_t r_wireframe;
|
extern cvar_t r_wireframe;
|
||||||
|
extern cvar_t r_outline;
|
||||||
|
extern cvar_t r_outline_width;
|
||||||
extern cvar_t r_refract_fbo;
|
extern cvar_t r_refract_fbo;
|
||||||
|
|
||||||
extern texid_t missing_texture;
|
extern texid_t missing_texture;
|
||||||
|
@ -3803,9 +3805,15 @@ static void BE_Program_Set_Attributes(const program_t *prog, struct programpermu
|
||||||
qglUniform3fvARB(ph, 1, (float*)shaderstate.curentity->light_dir);
|
qglUniform3fvARB(ph, 1, (float*)shaderstate.curentity->light_dir);
|
||||||
break;
|
break;
|
||||||
case SP_E_L_MUL:
|
case SP_E_L_MUL:
|
||||||
|
if (shaderstate.mode == BEM_DEPTHDARK)
|
||||||
|
qglUniform3fvARB(ph, 1, vec3_origin);
|
||||||
|
else
|
||||||
qglUniform3fvARB(ph, 1, (float*)shaderstate.curentity->light_range);
|
qglUniform3fvARB(ph, 1, (float*)shaderstate.curentity->light_range);
|
||||||
break;
|
break;
|
||||||
case SP_E_L_AMBIENT:
|
case SP_E_L_AMBIENT:
|
||||||
|
if (shaderstate.mode == BEM_DEPTHDARK)
|
||||||
|
qglUniform3fvARB(ph, 1, vec3_origin);
|
||||||
|
else
|
||||||
qglUniform3fvARB(ph, 1, (float*)shaderstate.curentity->light_avg);
|
qglUniform3fvARB(ph, 1, (float*)shaderstate.curentity->light_avg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -6283,6 +6291,19 @@ void GLBE_DrawWorld (batch_t **worldbatches)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (r_outline.ival && !r_wireframe.ival && qglPolygonMode && qglLineWidth)
|
||||||
|
{
|
||||||
|
shaderstate.identitylighting = 0;
|
||||||
|
shaderstate.identitylightmap = 0;
|
||||||
|
BE_SelectMode(BEM_DEPTHDARK);
|
||||||
|
qglLineWidth (bound(0.1, r_outline_width.value, 2000.0));
|
||||||
|
qglPolygonMode(GL_FRONT_AND_BACK, GL_LINE);
|
||||||
|
GLBE_SubmitMeshes(NULL, SHADER_SORT_PORTAL, SHADER_SORT_SEETHROUGH+1);
|
||||||
|
BE_SelectMode(BEM_STANDARD);
|
||||||
|
qglPolygonMode(GL_FRONT_AND_BACK, GL_FILL);
|
||||||
|
qglLineWidth (1);
|
||||||
|
}
|
||||||
|
|
||||||
shaderstate.identitylighting = 1;
|
shaderstate.identitylighting = 1;
|
||||||
|
|
||||||
RSpeedRemark();
|
RSpeedRemark();
|
||||||
|
|
|
@ -152,7 +152,13 @@ void GL_SetupFormats(void)
|
||||||
if (GL_CheckExtension("GL_OES_texture_float"))
|
if (GL_CheckExtension("GL_OES_texture_float"))
|
||||||
glfmtc(PTI_RGBA32F, GL_RGBA, GL_RGBA, GL_RGBA, GL_FLOAT, 0);
|
glfmtc(PTI_RGBA32F, GL_RGBA, GL_RGBA, GL_RGBA, GL_FLOAT, 0);
|
||||||
|
|
||||||
if (GL_CheckExtension("GL_OES_depth_texture"))
|
if (GL_CheckExtension("GL_WEBGL_depth_texture"))
|
||||||
|
{ //24bit is okay with this one.
|
||||||
|
glfmt(PTI_DEPTH16, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT);
|
||||||
|
glfmt(PTI_DEPTH24, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT_24_8);
|
||||||
|
glfmt(PTI_DEPTH32, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT);
|
||||||
|
}
|
||||||
|
else if (GL_CheckExtension("GL_OES_depth_texture") || GL_CheckExtension("GL_ANGLE_depth_texture"))
|
||||||
{ //16+32, not 24.
|
{ //16+32, not 24.
|
||||||
glfmt(PTI_DEPTH16, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT);
|
glfmt(PTI_DEPTH16, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_SHORT);
|
||||||
glfmt(PTI_DEPTH32, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT);
|
glfmt(PTI_DEPTH32, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_DEPTH_COMPONENT, GL_UNSIGNED_INT);
|
||||||
|
|
|
@ -48,7 +48,8 @@ extern int r_framecount; // used for dlight push checking
|
||||||
|
|
||||||
extern cvar_t gl_part_flame;
|
extern cvar_t gl_part_flame;
|
||||||
extern cvar_t r_bloom;
|
extern cvar_t r_bloom;
|
||||||
extern cvar_t r_wireframe_smooth;
|
extern cvar_t r_wireframe, r_wireframe_smooth;
|
||||||
|
extern cvar_t r_outline;
|
||||||
|
|
||||||
cvar_t gl_affinemodels = CVAR("gl_affinemodels","0");
|
cvar_t gl_affinemodels = CVAR("gl_affinemodels","0");
|
||||||
cvar_t gl_finish = CVAR("gl_finish","0");
|
cvar_t gl_finish = CVAR("gl_finish","0");
|
||||||
|
@ -629,7 +630,7 @@ void R_SetupGL (float stereooffset, int i)
|
||||||
if (!gl_config.gles && r_wireframe_smooth.modified)
|
if (!gl_config.gles && r_wireframe_smooth.modified)
|
||||||
{
|
{
|
||||||
r_wireframe_smooth.modified = false;
|
r_wireframe_smooth.modified = false;
|
||||||
if (r_wireframe_smooth.ival)
|
if (r_wireframe_smooth.ival || (r_outline.ival && !r_wireframe.ival))
|
||||||
{
|
{
|
||||||
qglEnable(GL_LINE_SMOOTH);
|
qglEnable(GL_LINE_SMOOTH);
|
||||||
if (qglHint)
|
if (qglHint)
|
||||||
|
@ -2047,7 +2048,13 @@ void GLR_RenderView (void)
|
||||||
vid.fbvheight = vid.fbpheight;
|
vid.fbvheight = vid.fbpheight;
|
||||||
|
|
||||||
fmt = PTI_RGBA8;
|
fmt = PTI_RGBA8;
|
||||||
if ((r_refdef.flags&RDF_SCENEGAMMA)||(vid.flags&(VID_SRGBAWARE|VID_FP16))||r_hdr_framebuffer.ival)
|
if (r_hdr_framebuffer.ival < 0)
|
||||||
|
{
|
||||||
|
fmt = -r_hdr_framebuffer.ival;
|
||||||
|
if (!sh_config.texfmt[fmt])
|
||||||
|
fmt = PTI_RGB565;
|
||||||
|
}
|
||||||
|
else if ((r_refdef.flags&RDF_SCENEGAMMA)||(vid.flags&(VID_SRGBAWARE|VID_FP16))||r_hdr_framebuffer.ival)
|
||||||
{ //gamma ramps really need higher colour precision, otherwise the entire thing looks terrible.
|
{ //gamma ramps really need higher colour precision, otherwise the entire thing looks terrible.
|
||||||
if (sh_config.texfmt[PTI_RGBA16F])
|
if (sh_config.texfmt[PTI_RGBA16F])
|
||||||
fmt = PTI_RGBA16F;
|
fmt = PTI_RGBA16F;
|
||||||
|
|
|
@ -208,11 +208,9 @@ qboolean GLSCR_UpdateScreen (void)
|
||||||
scr_con_forcedraw = false;
|
scr_con_forcedraw = false;
|
||||||
if (noworld)
|
if (noworld)
|
||||||
{
|
{
|
||||||
extern char levelshotname[];
|
|
||||||
|
|
||||||
//draw the levelshot or the conback fullscreen
|
//draw the levelshot or the conback fullscreen
|
||||||
if (*levelshotname)
|
if (R2D_DrawLevelshot())
|
||||||
R2D_ScalePic(0, 0, vid.width, vid.height, R2D_SafeCachePic (levelshotname));
|
;
|
||||||
else if (scr_con_current != vid.height)
|
else if (scr_con_current != vid.height)
|
||||||
R2D_ConsoleBackground(0, vid.height, true);
|
R2D_ConsoleBackground(0, vid.height, true);
|
||||||
else
|
else
|
||||||
|
|
|
@ -5594,16 +5594,17 @@ void QDECL R_BuildLegacyTexnums(shader_t *shader, const char *fallbackname, cons
|
||||||
//make sure the noalpha thing is set properly.
|
//make sure the noalpha thing is set properly.
|
||||||
switch(basefmt)
|
switch(basefmt)
|
||||||
{
|
{
|
||||||
|
case TF_MIP4_P8:
|
||||||
case TF_MIP4_8PAL24:
|
case TF_MIP4_8PAL24:
|
||||||
case TF_MIP4_SOLID8:
|
case TF_MIP4_SOLID8:
|
||||||
case TF_SOLID8:
|
case TF_SOLID8:
|
||||||
imageflags |= IF_NOALPHA;
|
imageflags |= IF_NOALPHA;
|
||||||
|
//fallthrough
|
||||||
|
case TF_MIP4_8PAL24_T255:
|
||||||
if (!mipdata || !mipdata[0] || !mipdata[1] || !mipdata[2] || !mipdata[3])
|
if (!mipdata || !mipdata[0] || !mipdata[1] || !mipdata[2] || !mipdata[3])
|
||||||
basefmt = TF_SOLID8;
|
basefmt = TF_SOLID8;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
if (!mipdata || !mipdata[0] || !mipdata[1] || !mipdata[2] || !mipdata[3])
|
|
||||||
basefmt = TF_SOLID8;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
imageflags |= IF_MIPCAP;
|
imageflags |= IF_MIPCAP;
|
||||||
|
|
|
@ -170,6 +170,7 @@ void (APIENTRY *qglMultMatrixf) (const GLfloat *m);
|
||||||
void (APIENTRY *qglNewList) (GLuint list, GLenum mode);
|
void (APIENTRY *qglNewList) (GLuint list, GLenum mode);
|
||||||
//void (APIENTRY *qglOrtho) (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
|
//void (APIENTRY *qglOrtho) (GLdouble left, GLdouble right, GLdouble bottom, GLdouble top, GLdouble zNear, GLdouble zFar);
|
||||||
void (APIENTRY *qglPolygonMode) (GLenum face, GLenum mode);
|
void (APIENTRY *qglPolygonMode) (GLenum face, GLenum mode);
|
||||||
|
void (APIENTRY *qglLineWidth) (GLfloat width);
|
||||||
void (APIENTRY *qglPopMatrix) (void);
|
void (APIENTRY *qglPopMatrix) (void);
|
||||||
void (APIENTRY *qglPushMatrix) (void);
|
void (APIENTRY *qglPushMatrix) (void);
|
||||||
void (APIENTRY *qglReadBuffer) (GLenum mode);
|
void (APIENTRY *qglReadBuffer) (GLenum mode);
|
||||||
|
@ -1088,7 +1089,7 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
|
||||||
if (Cvar_Get("gl_blacklist_invariant", "0", CVAR_VIDEOLATCH, "gl blacklists")->ival)
|
if (Cvar_Get("gl_blacklist_invariant", "0", CVAR_VIDEOLATCH, "gl blacklists")->ival)
|
||||||
gl_config.blacklist_invariant = true;
|
gl_config.blacklist_invariant = true;
|
||||||
else if (gl_config.arb_shader_objects && !gl_config_nofixedfunc &&
|
else if (gl_config.arb_shader_objects && !gl_config_nofixedfunc &&
|
||||||
strstr(gl_renderer, " Mesa ") && gl_config.glversion <= 3.1 && Cvar_Get("gl_blacklist_mesa_invariant", "1", CVAR_VIDEOLATCH, "gl blacklists")->ival)
|
(strstr(gl_renderer, " Mesa ") || strstr(gl_version, " Mesa ")) && gl_config.glversion <= 3.1 && Cvar_Get("gl_blacklist_mesa_invariant", "1", CVAR_VIDEOLATCH, "gl blacklists")->ival)
|
||||||
{
|
{
|
||||||
gl_config.blacklist_invariant = true;
|
gl_config.blacklist_invariant = true;
|
||||||
Con_Printf(CON_NOTICE "Mesa detected, disabling the use of glsl's invariant keyword. This will result in z-fighting. Use '+set gl_blacklist_mesa_invariant 0' on the commandline to reenable it.\n");
|
Con_Printf(CON_NOTICE "Mesa detected, disabling the use of glsl's invariant keyword. This will result in z-fighting. Use '+set gl_blacklist_mesa_invariant 0' on the commandline to reenable it.\n");
|
||||||
|
@ -3228,6 +3229,7 @@ qboolean GL_Init(rendererstate_t *info, void *(*getglfunction) (char *name))
|
||||||
qglMultMatrixf = (void *)getglcore("glMultMatrixf");
|
qglMultMatrixf = (void *)getglcore("glMultMatrixf");
|
||||||
// qglOrtho = (void *)getglcore("glOrtho");
|
// qglOrtho = (void *)getglcore("glOrtho");
|
||||||
qglPolygonMode = (void *)getglcore("glPolygonMode");
|
qglPolygonMode = (void *)getglcore("glPolygonMode");
|
||||||
|
qglLineWidth = (void *)getglcore("glLineWidth");
|
||||||
qglPopMatrix = (void *)getglcore("glPopMatrix");
|
qglPopMatrix = (void *)getglcore("glPopMatrix");
|
||||||
qglPushMatrix = (void *)getglcore("glPushMatrix");
|
qglPushMatrix = (void *)getglcore("glPushMatrix");
|
||||||
qglReadBuffer = (void *)getglcore("glReadBuffer");
|
qglReadBuffer = (void *)getglcore("glReadBuffer");
|
||||||
|
|
|
@ -879,7 +879,12 @@ static qboolean XRandR_FindOutput(const char *name)
|
||||||
{
|
{
|
||||||
XRROutputInfo *primary = NULL;
|
XRROutputInfo *primary = NULL;
|
||||||
int i;
|
int i;
|
||||||
xrandr.output = NULL;
|
if (!xrandr.canmodechange12)
|
||||||
|
return false;
|
||||||
|
if (!xrandr.res)
|
||||||
|
xrandr.res = xrandr.pGetScreenResources(vid_dpy, DefaultRootWindow(vid_dpy));
|
||||||
|
if (!xrandr.res)
|
||||||
|
return false;
|
||||||
if (!xrandr.outputs)
|
if (!xrandr.outputs)
|
||||||
{
|
{
|
||||||
xrandr.outputs = Z_Malloc(sizeof(*xrandr.outputs) * xrandr.res->noutput);
|
xrandr.outputs = Z_Malloc(sizeof(*xrandr.outputs) * xrandr.res->noutput);
|
||||||
|
@ -888,6 +893,12 @@ static qboolean XRandR_FindOutput(const char *name)
|
||||||
}
|
}
|
||||||
xrandr.output = NULL;
|
xrandr.output = NULL;
|
||||||
xrandr.crtc = None;
|
xrandr.crtc = None;
|
||||||
|
if (xrandr.origgamma)
|
||||||
|
{
|
||||||
|
xrandr.pSetCrtcGamma(vid_dpy, xrandr.crtc, xrandr.origgamma);
|
||||||
|
xrandr.pFreeGamma(xrandr.origgamma);
|
||||||
|
xrandr.origgamma = NULL;
|
||||||
|
}
|
||||||
if (xrandr.crtcinfo)
|
if (xrandr.crtcinfo)
|
||||||
xrandr.pFreeCrtcInfo(xrandr.crtcinfo);
|
xrandr.pFreeCrtcInfo(xrandr.crtcinfo);
|
||||||
xrandr.crtcinfo = NULL;
|
xrandr.crtcinfo = NULL;
|
||||||
|
@ -922,10 +933,7 @@ static qboolean XRandR_FindOutput(const char *name)
|
||||||
//(sets up crtc data
|
//(sets up crtc data
|
||||||
static qboolean XRandr_PickScreen(const char *devicename, int *x, int *y, int *width, int *height)
|
static qboolean XRandr_PickScreen(const char *devicename, int *x, int *y, int *width, int *height)
|
||||||
{
|
{
|
||||||
if (xrandr.canmodechange12)
|
if (xrandr.crtcinfo || XRandR_FindOutput(devicename))
|
||||||
{
|
|
||||||
xrandr.res = xrandr.pGetScreenResources(vid_dpy, DefaultRootWindow(vid_dpy));
|
|
||||||
if (XRandR_FindOutput(devicename))
|
|
||||||
{
|
{
|
||||||
XRRCrtcInfo *c = xrandr.crtcinfo;
|
XRRCrtcInfo *c = xrandr.crtcinfo;
|
||||||
*x = c->x;
|
*x = c->x;
|
||||||
|
@ -935,7 +943,6 @@ static qboolean XRandr_PickScreen(const char *devicename, int *x, int *y, int *w
|
||||||
Con_Printf("Found monitor %s %ix%i +%i,%i\n", xrandr.output->name, c->width, c->height, c->x, c->y);
|
Con_Printf("Found monitor %s %ix%i +%i,%i\n", xrandr.output->name, c->width, c->height, c->x, c->y);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -945,14 +952,9 @@ static void XRandR_SelectMode(const char *devicename, int *x, int *y, int *width
|
||||||
if (COM_CheckParm("-current"))
|
if (COM_CheckParm("-current"))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (xrandr.canmodechange12)
|
|
||||||
{
|
|
||||||
XRRCrtcInfo *c;
|
|
||||||
xrandr.res = xrandr.pGetScreenResources(vid_dpy, DefaultRootWindow(vid_dpy));
|
|
||||||
if (xrandr.res)
|
|
||||||
{
|
|
||||||
if (XRandR_FindOutput(devicename))
|
if (XRandR_FindOutput(devicename))
|
||||||
{
|
{
|
||||||
|
XRRCrtcInfo *c;
|
||||||
xrandr.crtcmode = XRandR_FindBestMode(*width, *height, rate);
|
xrandr.crtcmode = XRandR_FindBestMode(*width, *height, rate);
|
||||||
c = xrandr.crtcinfo;
|
c = xrandr.crtcinfo;
|
||||||
if (!*width || !*height || c->mode == xrandr.crtcmode->id)
|
if (!*width || !*height || c->mode == xrandr.crtcmode->id)
|
||||||
|
@ -972,8 +974,6 @@ static void XRandR_SelectMode(const char *devicename, int *x, int *y, int *width
|
||||||
else
|
else
|
||||||
Con_Printf("XRRSetCrtcConfig failed\n");
|
Con_Printf("XRRSetCrtcConfig failed\n");
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (xrandr.canmodechange11)
|
else if (xrandr.canmodechange11)
|
||||||
{
|
{
|
||||||
int best_fit, best_dist, best_rate, dist, x, y;
|
int best_fit, best_dist, best_rate, dist, x, y;
|
||||||
|
@ -1194,6 +1194,8 @@ static struct xidevinfo *XI2_GetDeviceInfo(int devid)
|
||||||
{
|
{
|
||||||
int devs;
|
int devs;
|
||||||
XIDeviceInfo *dev = xi2.pXIQueryDevice(vid_dpy, xi2.ndeviceinfos, &devs);
|
XIDeviceInfo *dev = xi2.pXIQueryDevice(vid_dpy, xi2.ndeviceinfos, &devs);
|
||||||
|
if (dev)
|
||||||
|
{
|
||||||
if (devs==1)
|
if (devs==1)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
|
@ -1213,6 +1215,7 @@ static struct xidevinfo *XI2_GetDeviceInfo(int devid)
|
||||||
}
|
}
|
||||||
xi2.pXIFreeDeviceInfo(dev);
|
xi2.pXIFreeDeviceInfo(dev);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
xi2.ndeviceinfos++;
|
xi2.ndeviceinfos++;
|
||||||
}
|
}
|
||||||
|
@ -2528,8 +2531,8 @@ static void UpdateGrabs(void)
|
||||||
allownullcursor = wantmgrabs; //this says whether we can possibly want it. if false then we disallow the null cursor. Yes, this might break mods that do their own sw cursors. such mods are flawed in other ways too.
|
allownullcursor = wantmgrabs; //this says whether we can possibly want it. if false then we disallow the null cursor. Yes, this might break mods that do their own sw cursors. such mods are flawed in other ways too.
|
||||||
if (Key_MouseShouldBeFree())
|
if (Key_MouseShouldBeFree())
|
||||||
wantmgrabs = false;
|
wantmgrabs = false;
|
||||||
if (modeswitchpending)
|
// if (modeswitchpending)
|
||||||
wantmgrabs = false;
|
// wantmgrabs = false;
|
||||||
|
|
||||||
if (wantmgrabs)
|
if (wantmgrabs)
|
||||||
install_grabs();
|
install_grabs();
|
||||||
|
@ -2834,6 +2837,7 @@ static void GetEvent(void)
|
||||||
{
|
{
|
||||||
modeswitchpending = 1;
|
modeswitchpending = 1;
|
||||||
modeswitchtime = Sys_Milliseconds() + 1500; /*fairly slow, to make sure*/
|
modeswitchtime = Sys_Milliseconds() + 1500; /*fairly slow, to make sure*/
|
||||||
|
UpdateGrabs();
|
||||||
}
|
}
|
||||||
|
|
||||||
if (event.xfocus.window == vid_window)
|
if (event.xfocus.window == vid_window)
|
||||||
|
@ -2853,6 +2857,10 @@ static void GetEvent(void)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_XRANDR
|
||||||
|
if (xrandr.origgamma)
|
||||||
|
xrandr.pSetCrtcGamma(vid_dpy, xrandr.crtc, xrandr.origgamma);
|
||||||
|
#endif
|
||||||
#ifdef USE_VMODE
|
#ifdef USE_VMODE
|
||||||
if (vm.originalapplied)
|
if (vm.originalapplied)
|
||||||
vm.pXF86VidModeSetGammaRamp(vid_dpy, scrnum, vm.originalrampsize, vm.originalramps[0], vm.originalramps[1], vm.originalramps[2]);
|
vm.pXF86VidModeSetGammaRamp(vid_dpy, scrnum, vm.originalrampsize, vm.originalramps[0], vm.originalramps[1], vm.originalramps[2]);
|
||||||
|
@ -3389,6 +3397,33 @@ qboolean GLVID_ApplyGammaRamps(unsigned int rampcount, unsigned short *ramps)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_XRANDR
|
||||||
|
if (xrandr.origgamma)
|
||||||
|
{ //we favour xrandr - xf86 gamma seems to cache old values which screws up gamma after having previously quit ezquake.
|
||||||
|
if (ramps && rampcount == xrandr.origgamma->size)
|
||||||
|
{
|
||||||
|
XRRCrtcGamma g;
|
||||||
|
g.size = rampcount;
|
||||||
|
g.red = &ramps[0];
|
||||||
|
g.green = &ramps[rampcount];
|
||||||
|
g.blue = &ramps[rampcount*2];
|
||||||
|
if (vid.activeapp)
|
||||||
|
{
|
||||||
|
if (gammaworks)
|
||||||
|
xrandr.pSetCrtcGamma(vid_dpy, xrandr.crtc, &g);
|
||||||
|
gammaworks = true;
|
||||||
|
return gammaworks;
|
||||||
|
}
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
else if (gammaworks)
|
||||||
|
{
|
||||||
|
xrandr.pSetCrtcGamma(vid_dpy, xrandr.crtc, xrandr.origgamma);
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef USE_VMODE
|
#ifdef USE_VMODE
|
||||||
//if we don't know the original ramps yet, don't allow changing them, because we're probably invalid anyway, and even if it worked, it'll break something later.
|
//if we don't know the original ramps yet, don't allow changing them, because we're probably invalid anyway, and even if it worked, it'll break something later.
|
||||||
if (vm.originalapplied)
|
if (vm.originalapplied)
|
||||||
|
@ -3818,6 +3853,7 @@ static qboolean X11VID_Init (rendererstate_t *info, unsigned char *palette, int
|
||||||
XRandR_Init();
|
XRandR_Init();
|
||||||
if (fullscreen && !(fullscreenflags & FULLSCREEN_ANYMODE))
|
if (fullscreen && !(fullscreenflags & FULLSCREEN_ANYMODE))
|
||||||
XRandR_SelectMode(info->devicename, &x, &y, &width, &height, rate);
|
XRandR_SelectMode(info->devicename, &x, &y, &width, &height, rate);
|
||||||
|
XRandR_FindOutput(info->devicename);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef USE_VMODE
|
#ifdef USE_VMODE
|
||||||
|
@ -3932,8 +3968,13 @@ static qboolean X11VID_Init (rendererstate_t *info, unsigned char *palette, int
|
||||||
|
|
||||||
x11.pXFlush(vid_dpy);
|
x11.pXFlush(vid_dpy);
|
||||||
|
|
||||||
|
#ifdef USE_XRANDR
|
||||||
|
if (xrandr.origgamma)
|
||||||
|
vid.gammarampsize = xrandr.origgamma->size;
|
||||||
|
else
|
||||||
|
#endif
|
||||||
#ifdef USE_VMODE
|
#ifdef USE_VMODE
|
||||||
if (vm.vmajor >= 2)
|
if (!xrandr.origgamma)
|
||||||
{
|
{
|
||||||
int rampsize = 256;
|
int rampsize = 256;
|
||||||
vm.pXF86VidModeGetGammaRampSize(vid_dpy, scrnum, &rampsize);
|
vm.pXF86VidModeGetGammaRampSize(vid_dpy, scrnum, &rampsize);
|
||||||
|
@ -3948,7 +3989,9 @@ static qboolean X11VID_Init (rendererstate_t *info, unsigned char *palette, int
|
||||||
vm.originalapplied = vm.pXF86VidModeGetGammaRamp(vid_dpy, scrnum, vm.originalrampsize, vm.originalramps[0], vm.originalramps[1], vm.originalramps[2]);
|
vm.originalapplied = vm.pXF86VidModeGetGammaRamp(vid_dpy, scrnum, vm.originalrampsize, vm.originalramps[0], vm.originalramps[1], vm.originalramps[2]);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else
|
||||||
#endif
|
#endif
|
||||||
|
vid.gammarampsize = 256;
|
||||||
|
|
||||||
switch(currentpsl)
|
switch(currentpsl)
|
||||||
{
|
{
|
||||||
|
@ -4568,6 +4611,8 @@ void INS_EnumerateDevices(void *ctx, void(*callback)(void *ctx, const char *type
|
||||||
{
|
{
|
||||||
int i, devs;
|
int i, devs;
|
||||||
XIDeviceInfo *dev = xi2.pXIQueryDevice(vid_dpy, xi2.devicegroup, &devs);
|
XIDeviceInfo *dev = xi2.pXIQueryDevice(vid_dpy, xi2.devicegroup, &devs);
|
||||||
|
if (dev)
|
||||||
|
{
|
||||||
for (i = 0; i < devs; i++)
|
for (i = 0; i < devs; i++)
|
||||||
{
|
{
|
||||||
if (!dev[i].enabled)
|
if (!dev[i].enabled)
|
||||||
|
@ -4585,6 +4630,7 @@ void INS_EnumerateDevices(void *ctx, void(*callback)(void *ctx, const char *type
|
||||||
}
|
}
|
||||||
xi2.pXIFreeDeviceInfo(dev);
|
xi2.pXIFreeDeviceInfo(dev);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -1087,6 +1087,24 @@ r_part ce_snow
|
||||||
flurry 32
|
flurry 32
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//eidolon's arena
|
||||||
|
r_part ce_rain
|
||||||
|
{
|
||||||
|
texture "particles/fteparticlefont.tga"
|
||||||
|
tcoords 1 1 63 63 256 2 64
|
||||||
|
type texturedspark
|
||||||
|
count 1
|
||||||
|
scale 2
|
||||||
|
scalefactor 1
|
||||||
|
die 1
|
||||||
|
alpha 0.2
|
||||||
|
alphadelta 0
|
||||||
|
rgb 255 255 255
|
||||||
|
friction 0
|
||||||
|
blend add
|
||||||
|
veladd 1
|
||||||
|
gravity 0
|
||||||
|
}
|
||||||
|
|
||||||
//this teleport effect is nothing like hexen2's. hopefully it'll be acceptable :s
|
//this teleport effect is nothing like hexen2's. hopefully it'll be acceptable :s
|
||||||
//the down ring
|
//the down ring
|
||||||
|
@ -1123,7 +1141,6 @@ r_part +ce_teleporterbody
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
//h2part.ce_rain was not loaded
|
|
||||||
//h2part.ce_quake was not loaded
|
//h2part.ce_quake was not loaded
|
||||||
//h2part.ce_ghost was not loaded
|
//h2part.ce_ghost was not loaded
|
||||||
//h2part.ce_teleporterbody_1 was not loaded
|
//h2part.ce_teleporterbody_1 was not loaded
|
||||||
|
|
|
@ -8222,7 +8222,7 @@ void SV_RegisterH2CustomTents(void)
|
||||||
}
|
}
|
||||||
static void QCBUILTIN PF_h2starteffect(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
static void QCBUILTIN PF_h2starteffect(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
|
||||||
{
|
{
|
||||||
float *min, *max, *size;
|
float *min, *max;//, *size;
|
||||||
// float *angle;
|
// float *angle;
|
||||||
float colour;
|
float colour;
|
||||||
// float wait, radius, frame, framelength, duration;
|
// float wait, radius, frame, framelength, duration;
|
||||||
|
@ -8239,18 +8239,29 @@ static void QCBUILTIN PF_h2starteffect(pubprogfuncs_t *prinst, struct globalvars
|
||||||
/*this effect is meant to be persistant (endeffect is never used)*/
|
/*this effect is meant to be persistant (endeffect is never used)*/
|
||||||
min = G_VECTOR(OFS_PARM1);
|
min = G_VECTOR(OFS_PARM1);
|
||||||
max = G_VECTOR(OFS_PARM2);
|
max = G_VECTOR(OFS_PARM2);
|
||||||
size = G_VECTOR(OFS_PARM3);
|
//size = G_VECTOR(OFS_PARM3); /*maxs-min, so useless*/
|
||||||
dir = G_VECTOR(OFS_PARM4);
|
dir = G_VECTOR(OFS_PARM4); /*[125,100] or [0,0]*/
|
||||||
colour = G_FLOAT(OFS_PARM5);
|
colour = G_FLOAT(OFS_PARM5); /*414 default*/
|
||||||
count = G_FLOAT(OFS_PARM6);
|
count = G_FLOAT(OFS_PARM6); /*300 default*/
|
||||||
//wait = G_FLOAT(OFS_PARM7);
|
count *= /*wait =*/ G_FLOAT(OFS_PARM7); /*0.1 default*/
|
||||||
|
|
||||||
/*FIXME: not spawned - this persistant effect is created by a map object, all attributes are custom.*/
|
/*FIXME: not spawned - this persistant effect is created by a map object, all attributes are custom.*/
|
||||||
|
|
||||||
if (colour == 0 && size == 0)
|
if (colour == 414)
|
||||||
SV_CustomTEnt_Spawn(h2customtents[efnum], min, max, count, dir);
|
efnum = h2customtents[efnum];
|
||||||
else
|
else
|
||||||
Con_Printf("FTE-H2 FIXME: ce_rain not supported!\n");
|
efnum = SV_CustomTEnt_Register(va("h2part.ce_rain_%i", (int)colour), CTE_PERSISTANT|CTE_CUSTOMVELOCITY|CTE_ISBEAM|CTE_CUSTOMCOUNT, NULL, 0, NULL, 0, 0, NULL);
|
||||||
|
|
||||||
|
{ //align to the top of the rain volume
|
||||||
|
//particles should be removed once they reach the bottom
|
||||||
|
vec3_t nmin;
|
||||||
|
vec3_t ndir;
|
||||||
|
nmin[0] = min[0];
|
||||||
|
nmin[1] = min[1];
|
||||||
|
nmin[2] = max[2];
|
||||||
|
VectorSet(ndir, dir[0], dir[1], (min[2]-max[2])/1); //divide by expected lifetime.
|
||||||
|
SV_CustomTEnt_Spawn(efnum, nmin, max, count, ndir);
|
||||||
|
}
|
||||||
return;
|
return;
|
||||||
case ce_snow:
|
case ce_snow:
|
||||||
/*this effect is meant to be persistant (endeffect is never used)*/
|
/*this effect is meant to be persistant (endeffect is never used)*/
|
||||||
|
@ -9887,7 +9898,7 @@ static void QCBUILTIN PF_runclientphys(pubprogfuncs_t *prinst, struct globalvars
|
||||||
pmove.physents[0].model = sv.world.worldmodel;
|
pmove.physents[0].model = sv.world.worldmodel;
|
||||||
|
|
||||||
pmove.onladder = false;
|
pmove.onladder = false;
|
||||||
pmove.onground = false;
|
pmove.onground = ((int)ent->v->flags & FL_ONGROUND) != 0;
|
||||||
pmove.groundent = 0;
|
pmove.groundent = 0;
|
||||||
pmove.waterlevel = 0;
|
pmove.waterlevel = 0;
|
||||||
pmove.watertype = 0;
|
pmove.watertype = 0;
|
||||||
|
@ -11853,7 +11864,7 @@ void PR_DumpPlatform_f(void)
|
||||||
{"total_monsters", "float", QW|NQ},
|
{"total_monsters", "float", QW|NQ},
|
||||||
{"found_secrets", "float", QW|NQ},
|
{"found_secrets", "float", QW|NQ},
|
||||||
{"killed_monsters", "float", QW|NQ},
|
{"killed_monsters", "float", QW|NQ},
|
||||||
{"parm1, parm2, parm3, parm4, parm5, parm6, parm7, parm8, parm9, parm10, parm11, parm12, parm13, parm14, parm15, parm16", "float", QW|NQ},
|
{"parm1, parm2, parm3, parm4, parm5, parm6, parm7, parm8, parm9, parm10, parm11, parm12, parm13, parm14, parm15, parm16", "float", QW|NQ, "Player specific mod-defined values that are transferred from one map to the next. These are set by the qc inside calls to SetNewParms and SetChangeParms, and can then be read on a per-player basis after a call to the setspawnparms builtin. They are not otherwise valid."},
|
||||||
{"intermission", "float", CS},
|
{"intermission", "float", CS},
|
||||||
{"v_forward, v_up, v_right", "vector", QW|NQ|CS},
|
{"v_forward, v_up, v_right", "vector", QW|NQ|CS},
|
||||||
{"view_angles", "vector", CS, D("+x=DOWN")},
|
{"view_angles", "vector", CS, D("+x=DOWN")},
|
||||||
|
@ -12090,9 +12101,11 @@ void PR_DumpPlatform_f(void)
|
||||||
{"m_toggle", "void(float wantmode)", MENU},
|
{"m_toggle", "void(float wantmode)", MENU},
|
||||||
{"m_consolecommand", "float(string cmd)", MENU},
|
{"m_consolecommand", "float(string cmd)", MENU},
|
||||||
|
|
||||||
{"parm17, parm18, parm19, parm20, parm21, parm22, parm23, parm24, parm25, parm26, parm27, parm28, parm29, parm30, parm31, parm32", "float", QW|NQ},
|
{"parm17, parm18, parm19, parm20, parm21, parm22, parm23, parm24, parm25, parm26, parm27, parm28, parm29, parm30, parm31, parm32", "float", QW|NQ, "Additional spawn parms, following the same parmN theme."},
|
||||||
{"parm33, parm34, parm35, parm36, parm37, parm38, parm39, parm40, parm41, parm42, parm43, parm44, parm45, parm46, parm47, parm48", "float", QW|NQ},
|
{"parm33, parm34, parm35, parm36, parm37, parm38, parm39, parm40, parm41, parm42, parm43, parm44, parm45, parm46, parm47, parm48", "float", QW|NQ},
|
||||||
{"parm49, parm50, parm51, parm52, parm53, parm54, parm55, parm56, parm57, parm58, parm59, parm60, parm61, parm62, parm63, parm64", "float", QW|NQ},
|
{"parm49, parm50, parm51, parm52, parm53, parm54, parm55, parm56, parm57, parm58, parm59, parm60, parm61, parm62, parm63, parm64", "float", QW|NQ},
|
||||||
|
{"parm_string", "string", QW|NQ, "Like the regular parmN globals, but preserves string contents."},
|
||||||
|
{"startspot", "string", QW|NQ, "Receives the value of the second argument to changelevel from the previous map."},
|
||||||
{"dimension_send", "var float", QW|NQ, "Used by multicast functionality. Multicasts (and related builtins that multicast internally) will only be sent to players where (player.dimension_see & dimension_send) is non-zero."},
|
{"dimension_send", "var float", QW|NQ, "Used by multicast functionality. Multicasts (and related builtins that multicast internally) will only be sent to players where (player.dimension_see & dimension_send) is non-zero."},
|
||||||
{"dimension_default", "//var float", QW|NQ, "Default dimension bitmask", 255},
|
{"dimension_default", "//var float", QW|NQ, "Default dimension bitmask", 255},
|
||||||
{"physics_mode", "__used var float", QW|NQ|CS, "0: original csqc - physics are not run\n1: DP-compat. Thinks occur, but not true movetypes.\n2: movetypes occur just as they do in ssqc.", 2},
|
{"physics_mode", "__used var float", QW|NQ|CS, "0: original csqc - physics are not run\n1: DP-compat. Thinks occur, but not true movetypes.\n2: movetypes occur just as they do in ssqc.", 2},
|
||||||
|
|
|
@ -232,7 +232,7 @@ and the extension fields are added on the end and can have extra vm-specific stu
|
||||||
|
|
||||||
#define comextqcfields \
|
#define comextqcfields \
|
||||||
comfieldvector(punchangle,NULL) /*std in nq*/\
|
comfieldvector(punchangle,NULL) /*std in nq*/\
|
||||||
comfieldfloat(gravity,NULL) /*added in quake 1.09 (for hipnotic)*/\
|
comfieldfloat(gravity,"Multiplier applied in addition to sv_gravity (not absolute units), to control the gravity affecting this entity specifically.") /*added in quake 1.09 (for hipnotic)*/\
|
||||||
comfieldfloat(hull,"Overrides the hull used by the entity for walkmove/movetogoal and not traceline/tracebox.")/*PEXT_HEXEN2*/\
|
comfieldfloat(hull,"Overrides the hull used by the entity for walkmove/movetogoal and not traceline/tracebox.")/*PEXT_HEXEN2*/\
|
||||||
comfieldentity(movechain,"This is a linked list of entities which will be moved whenever this entity moves, logically they are attached to this entity.")/*hexen2*/\
|
comfieldentity(movechain,"This is a linked list of entities which will be moved whenever this entity moves, logically they are attached to this entity.")/*hexen2*/\
|
||||||
comfieldfunction(chainmoved, ".void()","Called when the entity is moved as a result of being part of another entity's .movechain")/*hexen2*/\
|
comfieldfunction(chainmoved, ".void()","Called when the entity is moved as a result of being part of another entity's .movechain")/*hexen2*/\
|
||||||
|
|
|
@ -2113,6 +2113,8 @@ typedef struct {
|
||||||
int health;
|
int health;
|
||||||
int spectator; //0=send to a player. 1=non-tracked player, to a spec. 2=tracked player, to a spec(or self)
|
int spectator; //0=send to a player. 1=non-tracked player, to a spec. 2=tracked player, to a spec(or self)
|
||||||
qboolean isself;
|
qboolean isself;
|
||||||
|
qboolean onground;
|
||||||
|
qboolean solid;
|
||||||
int fteext;
|
int fteext;
|
||||||
int zext;
|
int zext;
|
||||||
int hull;
|
int hull;
|
||||||
|
@ -2251,17 +2253,24 @@ void SV_WritePlayerToClient(sizebuf_t *msg, clstate_t *ent)
|
||||||
pflags |= pm_code << PF_PMC_SHIFT;
|
pflags |= pm_code << PF_PMC_SHIFT;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pflags & 0xff0000)
|
if ((zext & Z_EXT_PF_ONGROUND) && ent->onground)
|
||||||
pflags |= PF_EXTRA_PFS;
|
pflags |= PF_ONGROUND;
|
||||||
|
if ((zext & Z_EXT_PF_SOLID) && ent->solid)
|
||||||
|
pflags |= PF_SOLID;
|
||||||
|
|
||||||
MSG_WriteByte (msg, svc_playerinfo);
|
MSG_WriteByte (msg, svc_playerinfo);
|
||||||
MSG_WriteByte (msg, ent->playernum);
|
MSG_WriteByte (msg, ent->playernum);
|
||||||
MSG_WriteShort (msg, pflags&0xffff);
|
|
||||||
|
|
||||||
if (pflags & PF_EXTRA_PFS)
|
if (ent->fteext & (PEXT_HULLSIZE|PEXT_TRANS|PEXT_SCALE|PEXT_FATNESS))
|
||||||
{
|
{
|
||||||
|
if (pflags & 0xff0000)
|
||||||
|
pflags |= PF_EXTRA_PFS;
|
||||||
|
MSG_WriteShort (msg, pflags&0xffff);
|
||||||
|
if (pflags & PF_EXTRA_PFS)
|
||||||
MSG_WriteByte(msg, (pflags&0xff0000)>>16);
|
MSG_WriteByte(msg, (pflags&0xff0000)>>16);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
MSG_WriteShort (msg, (pflags&0x3fff) | ((pflags&0xc00000)>>8));
|
||||||
//we need to tell the client that it's moved, as it's own origin might not be natural
|
//we need to tell the client that it's moved, as it's own origin might not be natural
|
||||||
|
|
||||||
for (i=0 ; i<3 ; i++)
|
for (i=0 ; i<3 ; i++)
|
||||||
|
@ -2321,9 +2330,7 @@ void SV_WritePlayerToClient(sizebuf_t *msg, clstate_t *ent)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pflags & PF_MODEL)
|
if (pflags & PF_MODEL)
|
||||||
{
|
|
||||||
MSG_WriteByte (msg, ent->modelindex);
|
MSG_WriteByte (msg, ent->modelindex);
|
||||||
}
|
|
||||||
|
|
||||||
if (pflags & PF_SKINNUM)
|
if (pflags & PF_SKINNUM)
|
||||||
MSG_WriteByte (msg, ent->skin | (((pflags & PF_MODEL)&&(ent->modelindex>=256))<<7));
|
MSG_WriteByte (msg, ent->skin | (((pflags & PF_MODEL)&&(ent->modelindex>=256))<<7));
|
||||||
|
@ -2551,6 +2558,8 @@ void SV_WritePlayersToClient (client_t *client, client_frame_t *frame, edict_t *
|
||||||
clst.zext = 0;//client->zquake_extensions;
|
clst.zext = 0;//client->zquake_extensions;
|
||||||
clst.cl = NULL;
|
clst.cl = NULL;
|
||||||
clst.vw_index = 0;
|
clst.vw_index = 0;
|
||||||
|
clst.solid = true;
|
||||||
|
clst.onground = true;
|
||||||
|
|
||||||
lerp = (realtime - olddemotime) / (nextdemotime - olddemotime);
|
lerp = (realtime - olddemotime) / (nextdemotime - olddemotime);
|
||||||
if (lerp < 0)
|
if (lerp < 0)
|
||||||
|
@ -2712,6 +2721,8 @@ void SV_WritePlayersToClient (client_t *client, client_frame_t *frame, edict_t *
|
||||||
clst.velocity = vent->v->velocity;
|
clst.velocity = vent->v->velocity;
|
||||||
clst.effects = ent->v->effects;
|
clst.effects = ent->v->effects;
|
||||||
clst.vw_index = ent->xv->vw_index;
|
clst.vw_index = ent->xv->vw_index;
|
||||||
|
clst.onground = (int)ent->v->flags & FL_ONGROUND;
|
||||||
|
clst.solid = ent->v->solid && ent->v->solid != SOLID_CORPSE && ent->v->solid != SOLID_TRIGGER;
|
||||||
|
|
||||||
if (progstype == PROG_H2 && ((int)vent->v->effects & H2EF_NODRAW))
|
if (progstype == PROG_H2 && ((int)vent->v->effects & H2EF_NODRAW))
|
||||||
{
|
{
|
||||||
|
@ -3198,6 +3209,8 @@ void SV_Snapshot_BuildStateQ1(entity_state_t *state, edict_t *ent, client_t *cli
|
||||||
if (cl->isindependant)
|
if (cl->isindependant)
|
||||||
{
|
{
|
||||||
state->u.q1.pmovetype = ent->v->movetype;
|
state->u.q1.pmovetype = ent->v->movetype;
|
||||||
|
if (state->u.q1.pmovetype && ((int)ent->v->flags & FL_ONGROUND) && (client->zquake_extensions&Z_EXT_PF_ONGROUND))
|
||||||
|
state->u.q1.pmovetype |= 0x80;
|
||||||
if (cl != client && client)
|
if (cl != client && client)
|
||||||
{ /*only generate movement values if the client doesn't already know them...*/
|
{ /*only generate movement values if the client doesn't already know them...*/
|
||||||
state->u.q1.movement[0] = ent->xv->movement[0];
|
state->u.q1.movement[0] = ent->xv->movement[0];
|
||||||
|
@ -3227,7 +3240,7 @@ void SV_Snapshot_BuildStateQ1(entity_state_t *state, edict_t *ent, client_t *cli
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)
|
if (client->fteprotocolextensions2 & PEXT2_REPLACEMENTDELTAS)
|
||||||
if (state->u.q1.pmovetype && (state->u.q1.pmovetype != MOVETYPE_TOSS && state->u.q1.pmovetype != MOVETYPE_BOUNCE))
|
if (state->u.q1.pmovetype && ((state->u.q1.pmovetype&0x7f) != MOVETYPE_TOSS && (state->u.q1.pmovetype&0x7f) != MOVETYPE_BOUNCE))
|
||||||
{
|
{
|
||||||
state->angles[0] = ent->v->v_angle[0]/-3.0;
|
state->angles[0] = ent->v->v_angle[0]/-3.0;
|
||||||
state->angles[1] = ent->v->v_angle[1];
|
state->angles[1] = ent->v->v_angle[1];
|
||||||
|
@ -4048,7 +4061,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
|
||||||
// on client side doesn't stray too far off
|
// on client side doesn't stray too far off
|
||||||
if (ISQWCLIENT(client))
|
if (ISQWCLIENT(client))
|
||||||
{
|
{
|
||||||
if (client->fteprotocolextensions & PEXT_ACCURATETIMINGS && sv.world.physicstime - client->nextservertimeupdate > 0)
|
if ((client->fteprotocolextensions & PEXT_ACCURATETIMINGS )&& sv.world.physicstime - client->nextservertimeupdate > 0)
|
||||||
{ //the fte pext causes the server to send out accurate timings, allowing for perfect interpolation.
|
{ //the fte pext causes the server to send out accurate timings, allowing for perfect interpolation.
|
||||||
MSG_WriteByte (msg, svcqw_updatestatlong);
|
MSG_WriteByte (msg, svcqw_updatestatlong);
|
||||||
MSG_WriteByte (msg, STAT_TIME);
|
MSG_WriteByte (msg, STAT_TIME);
|
||||||
|
@ -4056,7 +4069,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore
|
||||||
|
|
||||||
client->nextservertimeupdate = sv.world.physicstime;
|
client->nextservertimeupdate = sv.world.physicstime;
|
||||||
}
|
}
|
||||||
else if (client->zquake_extensions & Z_EXT_SERVERTIME && sv.world.physicstime - client->nextservertimeupdate > 0)
|
else if ((client->zquake_extensions & Z_EXT_SERVERTIME) && sv.world.physicstime - client->nextservertimeupdate > 0)
|
||||||
{ //the zquake ext causes the server to send out peridoic timings, allowing for moderatly accurate game time.
|
{ //the zquake ext causes the server to send out peridoic timings, allowing for moderatly accurate game time.
|
||||||
MSG_WriteByte (msg, svcqw_updatestatlong);
|
MSG_WriteByte (msg, svcqw_updatestatlong);
|
||||||
MSG_WriteByte (msg, STAT_TIME);
|
MSG_WriteByte (msg, STAT_TIME);
|
||||||
|
|
|
@ -37,6 +37,23 @@ int host_hunklevel;
|
||||||
|
|
||||||
client_t *host_client; // current client
|
client_t *host_client; // current client
|
||||||
|
|
||||||
|
void CvarPostfixKMG(cvar_t *v, char *oldval)
|
||||||
|
{
|
||||||
|
double k = 1000; //scientific units are in thousands. 10ki is 10*1024.
|
||||||
|
char *end;
|
||||||
|
double f = strtod(v->string, &end);
|
||||||
|
if (*end && end[1]=='i')
|
||||||
|
k = 1024; //kibi
|
||||||
|
if (*end == 'k' || *end == 'K')
|
||||||
|
f *= k;
|
||||||
|
if (*end == 'm' || *end == 'M')
|
||||||
|
f *= k*k;
|
||||||
|
if (*end == 'b' || *end == 'B' || *end == 'g' || *end == 'G')
|
||||||
|
f *= k*k*k;
|
||||||
|
v->ival = f;
|
||||||
|
v->value = f;
|
||||||
|
}
|
||||||
|
|
||||||
// bound the size of the physics time tic
|
// bound the size of the physics time tic
|
||||||
#ifdef SERVERONLY
|
#ifdef SERVERONLY
|
||||||
cvar_t sv_mintic = CVARD("sv_mintic","0.013", "The minimum interval between running physics frames.");
|
cvar_t sv_mintic = CVARD("sv_mintic","0.013", "The minimum interval between running physics frames.");
|
||||||
|
@ -100,9 +117,9 @@ extern cvar_t net_enable_dtls;
|
||||||
cvar_t sv_reportheartbeats = CVARD("sv_reportheartbeats", "2", "Print a notice each time a heartbeat is sent to a master server. When set to 2, the message will be displayed once.");
|
cvar_t sv_reportheartbeats = CVARD("sv_reportheartbeats", "2", "Print a notice each time a heartbeat is sent to a master server. When set to 2, the message will be displayed once.");
|
||||||
cvar_t sv_heartbeat_interval = CVARD("sv_heartbeat_interval", "110", "Interval between heartbeats. Low values are abusive, high values may cause NAT/ghost issues.");
|
cvar_t sv_heartbeat_interval = CVARD("sv_heartbeat_interval", "110", "Interval between heartbeats. Low values are abusive, high values may cause NAT/ghost issues.");
|
||||||
cvar_t sv_highchars = CVAR("sv_highchars", "1");
|
cvar_t sv_highchars = CVAR("sv_highchars", "1");
|
||||||
cvar_t sv_maxrate = CVARD("sv_maxrate", "50000", "This controls the maximum number of bytes any indivual player may receive (when not downloading). The individual user's rate will also be controlled by the user's rate cvar.");
|
cvar_t sv_maxrate = CVARCD("sv_maxrate", "50k", CvarPostfixKMG, "This controls the maximum number of bytes any indivual player may receive (when not downloading). The individual user's rate will also be controlled by the user's rate cvar.");
|
||||||
cvar_t sv_maxdrate = CVARAFD("sv_maxdrate", "500000",
|
cvar_t sv_maxdrate = CVARAFCD("sv_maxdrate", "500k",
|
||||||
"sv_maxdownloadrate", 0, "This cvar controls the maximum number of bytes sent to each player per second while that player is downloading.\nIf this cvar is set to 0, there will be NO CAP for download rates (if the user's drate is empty/0 too, then expect really fast+abusive downloads that could potentially be considered denial of service attacks)");
|
"sv_maxdownloadrate", 0, CvarPostfixKMG, "This cvar controls the maximum number of bytes sent to each player per second while that player is downloading.\nIf this cvar is set to 0, there will be NO CAP for download rates (if the user's drate is empty/0 too, then expect really fast+abusive downloads that could potentially be considered denial of service attacks)");
|
||||||
cvar_t sv_minping = CVARFD("sv_minping", "", CVAR_SERVERINFO, "Simulate fake lag for any players with a ping under the value specified here. Value is in milliseconds.");
|
cvar_t sv_minping = CVARFD("sv_minping", "", CVAR_SERVERINFO, "Simulate fake lag for any players with a ping under the value specified here. Value is in milliseconds.");
|
||||||
|
|
||||||
cvar_t sv_bigcoords = CVARFD("sv_bigcoords", "1", 0, "Uses floats for coordinates instead of 16bit values.\nAlso boosts angle precision, so can be useful even on small maps.\nAffects clients thusly:\nQW: enforces a mandatory protocol extension\nDP: enables DPP7 protocol support\nNQ: uses RMQ protocol (protocol 999).");
|
cvar_t sv_bigcoords = CVARFD("sv_bigcoords", "1", 0, "Uses floats for coordinates instead of 16bit values.\nAlso boosts angle precision, so can be useful even on small maps.\nAffects clients thusly:\nQW: enforces a mandatory protocol extension\nDP: enables DPP7 protocol support\nNQ: uses RMQ protocol (protocol 999).");
|
||||||
|
@ -123,7 +140,7 @@ cvar_t sv_masterport = CVAR("sv_masterport", "0");
|
||||||
cvar_t pext_ezquake_nochunks = CVARD("pext_ezquake_nochunks", "0", "Prevents ezquake clients from being able to use the chunked download extension. This sidesteps numerous ezquake issues, and will make downloads slower but more robust.");
|
cvar_t pext_ezquake_nochunks = CVARD("pext_ezquake_nochunks", "0", "Prevents ezquake clients from being able to use the chunked download extension. This sidesteps numerous ezquake issues, and will make downloads slower but more robust.");
|
||||||
|
|
||||||
cvar_t sv_gamespeed = CVARAF("sv_gamespeed", "1", "slowmo", 0);
|
cvar_t sv_gamespeed = CVARAF("sv_gamespeed", "1", "slowmo", 0);
|
||||||
cvar_t sv_csqcdebug = CVAR("sv_csqcdebug", "0");
|
cvar_t sv_csqcdebug = CVARD("sv_csqcdebug", "0", "Inject packet size information for data directed to csqc.");
|
||||||
cvar_t sv_csqc_progname = CVAR("sv_csqc_progname", "csprogs.dat");
|
cvar_t sv_csqc_progname = CVAR("sv_csqc_progname", "csprogs.dat");
|
||||||
cvar_t pausable = CVAR("pausable", "");
|
cvar_t pausable = CVAR("pausable", "");
|
||||||
cvar_t sv_banproxies = CVARD("sv_banproxies", "0", "If enabled, anyone connecting via known proxy software will be refused entry. This should aid with blocking aimbots, but is only reliable for certain public proxies.");
|
cvar_t sv_banproxies = CVARD("sv_banproxies", "0", "If enabled, anyone connecting via known proxy software will be refused entry. This should aid with blocking aimbots, but is only reliable for certain public proxies.");
|
||||||
|
@ -3060,7 +3077,9 @@ client_t *SVC_DirectConnect(void)
|
||||||
//its causing far far far too many connectivity issues. seriously. its beyond a joke. I cannot stress that enough.
|
//its causing far far far too many connectivity issues. seriously. its beyond a joke. I cannot stress that enough.
|
||||||
//as the client needs to listen for the serverinfo to know which extensions will actually be used (yay demos), we can just forget that it supports svc-level extensions, at least for anything that isn't spammed via clc_move etc before the serverinfo.
|
//as the client needs to listen for the serverinfo to know which extensions will actually be used (yay demos), we can just forget that it supports svc-level extensions, at least for anything that isn't spammed via clc_move etc before the serverinfo.
|
||||||
s = InfoBuf_ValueForKey(&newcl->userinfo, "*client");
|
s = InfoBuf_ValueForKey(&newcl->userinfo, "*client");
|
||||||
if (!strncmp(s, "ezQuake", 7) && (newcl->fteprotocolextensions & PEXT_CHUNKEDDOWNLOADS))
|
if (!strncmp(s, "ezQuake", 7))
|
||||||
|
{
|
||||||
|
if (newcl->fteprotocolextensions & PEXT_CHUNKEDDOWNLOADS)
|
||||||
{
|
{
|
||||||
if (pext_ezquake_nochunks.ival)
|
if (pext_ezquake_nochunks.ival)
|
||||||
{
|
{
|
||||||
|
@ -3068,6 +3087,19 @@ client_t *SVC_DirectConnect(void)
|
||||||
Con_TPrintf("%s: ignoring ezquake chunked downloads extension.\n", NET_AdrToString (adrbuf, sizeof(adrbuf), &adr));
|
Con_TPrintf("%s: ignoring ezquake chunked downloads extension.\n", NET_AdrToString (adrbuf, sizeof(adrbuf), &adr));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (newcl->zquake_extensions & (Z_EXT_PF_SOLID|Z_EXT_PF_ONGROUND))
|
||||||
|
{
|
||||||
|
if (newcl->fteprotocolextensions & PEXT_HULLSIZE)
|
||||||
|
Con_TPrintf("%s: ignoring ezquake hullsize extension (conflicts with z_ext_pf_onground).\n", NET_AdrToString (adrbuf, sizeof(adrbuf), &adr));
|
||||||
|
if (newcl->fteprotocolextensions & PEXT_SCALE)
|
||||||
|
Con_TPrintf("%s: ignoring ezquake scale extension (conflicts with z_ext_pf_solid).\n", NET_AdrToString (adrbuf, sizeof(adrbuf), &adr));
|
||||||
|
if (newcl->fteprotocolextensions & PEXT_FATNESS)
|
||||||
|
Con_TPrintf("%s: ignoring ezquake fatness extension (conflicts with z_ext_pf_solid).\n", NET_AdrToString (adrbuf, sizeof(adrbuf), &adr));
|
||||||
|
if (newcl->fteprotocolextensions & PEXT_TRANS)
|
||||||
|
Con_TPrintf("%s: ignoring ezquake transparency extension (buggy on players, conflicts with z_ext_pf_solid).\n", NET_AdrToString (adrbuf, sizeof(adrbuf), &adr));
|
||||||
|
newcl->fteprotocolextensions &= ~(PEXT_HULLSIZE|PEXT_TRANS|PEXT_SCALE|PEXT_FATNESS);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
Netchan_Setup (NS_SERVER, &newcl->netchan, &adr, qport);
|
Netchan_Setup (NS_SERVER, &newcl->netchan, &adr, qport);
|
||||||
|
|
||||||
|
@ -5104,6 +5136,7 @@ void SV_InitLocal (void)
|
||||||
extern cvar_t pm_ktjump;
|
extern cvar_t pm_ktjump;
|
||||||
extern cvar_t pm_slidefix;
|
extern cvar_t pm_slidefix;
|
||||||
extern cvar_t pm_airstep;
|
extern cvar_t pm_airstep;
|
||||||
|
extern cvar_t pm_pground;
|
||||||
extern cvar_t pm_stepdown;
|
extern cvar_t pm_stepdown;
|
||||||
extern cvar_t pm_walljump;
|
extern cvar_t pm_walljump;
|
||||||
extern cvar_t pm_slidyslopes;
|
extern cvar_t pm_slidyslopes;
|
||||||
|
@ -5163,6 +5196,7 @@ void SV_InitLocal (void)
|
||||||
Cvar_Register (&pm_slidefix, cvargroup_serverphysics);
|
Cvar_Register (&pm_slidefix, cvargroup_serverphysics);
|
||||||
Cvar_Register (&pm_slidyslopes, cvargroup_serverphysics);
|
Cvar_Register (&pm_slidyslopes, cvargroup_serverphysics);
|
||||||
Cvar_Register (&pm_airstep, cvargroup_serverphysics);
|
Cvar_Register (&pm_airstep, cvargroup_serverphysics);
|
||||||
|
Cvar_Register (&pm_pground, cvargroup_serverphysics);
|
||||||
Cvar_Register (&pm_stepdown, cvargroup_serverphysics);
|
Cvar_Register (&pm_stepdown, cvargroup_serverphysics);
|
||||||
Cvar_Register (&pm_walljump, cvargroup_serverphysics);
|
Cvar_Register (&pm_walljump, cvargroup_serverphysics);
|
||||||
Cvar_Register (&pm_edgefriction, cvargroup_serverphysics);
|
Cvar_Register (&pm_edgefriction, cvargroup_serverphysics);
|
||||||
|
@ -5243,6 +5277,8 @@ void SV_InitLocal (void)
|
||||||
|
|
||||||
Cvar_Register (&sv_maxrate, cvargroup_servercontrol);
|
Cvar_Register (&sv_maxrate, cvargroup_servercontrol);
|
||||||
Cvar_Register (&sv_maxdrate, cvargroup_servercontrol);
|
Cvar_Register (&sv_maxdrate, cvargroup_servercontrol);
|
||||||
|
Cvar_ForceCallback(&sv_maxrate);
|
||||||
|
Cvar_ForceCallback(&sv_maxdrate);
|
||||||
Cvar_Register (&sv_minping, cvargroup_servercontrol);
|
Cvar_Register (&sv_minping, cvargroup_servercontrol);
|
||||||
|
|
||||||
Cvar_Register (&sv_nailhack, cvargroup_servercontrol);
|
Cvar_Register (&sv_nailhack, cvargroup_servercontrol);
|
||||||
|
|
|
@ -70,12 +70,13 @@ cvar_t pm_ktjump = CVARF("pm_ktjump", "", CVAR_SERVERINFO);
|
||||||
cvar_t pm_bunnyspeedcap = CVARFD("pm_bunnyspeedcap", "", CVAR_SERVERINFO, "0 or 1, ish. If the player is traveling faster than this speed while turning, their velocity will be gracefully reduced to match their current maxspeed. You can still rocket-jump to gain high velocity, but turning will reduce your speed back to the max. This can be used to disable bunny hopping.");
|
cvar_t pm_bunnyspeedcap = CVARFD("pm_bunnyspeedcap", "", CVAR_SERVERINFO, "0 or 1, ish. If the player is traveling faster than this speed while turning, their velocity will be gracefully reduced to match their current maxspeed. You can still rocket-jump to gain high velocity, but turning will reduce your speed back to the max. This can be used to disable bunny hopping.");
|
||||||
cvar_t pm_watersinkspeed = CVARFD("pm_watersinkspeed", "", CVAR_SERVERINFO, "This is the speed that players will sink at while inactive in water. Empty means 60.");
|
cvar_t pm_watersinkspeed = CVARFD("pm_watersinkspeed", "", CVAR_SERVERINFO, "This is the speed that players will sink at while inactive in water. Empty means 60.");
|
||||||
cvar_t pm_flyfriction = CVARFD("pm_flyfriction", "", CVAR_SERVERINFO, "Amount of friction that applies in fly or 6dof mode. Empty means 4.");
|
cvar_t pm_flyfriction = CVARFD("pm_flyfriction", "", CVAR_SERVERINFO, "Amount of friction that applies in fly or 6dof mode. Empty means 4.");
|
||||||
cvar_t pm_slidefix = CVARF("pm_slidefix", "", CVAR_SERVERINFO);
|
cvar_t pm_slidefix = CVARFD("pm_slidefix", "", CVAR_SERVERINFO, "Fixes an issue when jumping down slopes (ie: they act more like slopes and not steps)");
|
||||||
cvar_t pm_slidyslopes = CVARF("pm_slidyslopes", "", CVAR_SERVERINFO);
|
cvar_t pm_slidyslopes = CVARFD("pm_slidyslopes", "", CVAR_SERVERINFO, "Replicates NQ behaviour, where players will slowly slide down ramps");
|
||||||
cvar_t pm_airstep = CVARAF("pm_airstep", "", "sv_jumpstep", CVAR_SERVERINFO);
|
cvar_t pm_airstep = CVARAFD("pm_airstep", "", /*dp*/"sv_jumpstep", CVAR_SERVERINFO, "Allows players to step up while jumping. This makes stairs more graceful but also increases potential jump heights.");
|
||||||
cvar_t pm_stepdown = CVARF("pm_stepdown", "", CVAR_SERVERINFO);
|
cvar_t pm_pground = CVARFD("pm_pground", "", CVAR_SERVERINFO, "Use persisten onground state instead of recalculating every frame."CON_WARNING"Do NOT use with nq mods, as most nq mods will interfere with onground state, resulting in glitches.");
|
||||||
cvar_t pm_walljump = CVARF("pm_walljump", "", CVAR_SERVERINFO);
|
cvar_t pm_stepdown = CVARFD("pm_stepdown", "", CVAR_SERVERINFO, "Causes physics to stick to the ground, instead of constantly losing traction whiloe going down steps.");
|
||||||
cvar_t pm_edgefriction = CVARAFD("pm_edgefriction", "", "edgefriction", CVAR_SERVERINFO, "Default value of 2"); //alternative name (without prefix) for compat with dp
|
cvar_t pm_walljump = CVARFD("pm_walljump", "", CVAR_SERVERINFO, "Allows the player to bounce off walls while arborne.");
|
||||||
|
cvar_t pm_edgefriction = CVARAFD("pm_edgefriction", "", /*dp*/"edgefriction", CVAR_SERVERINFO, "Default value of 2");
|
||||||
|
|
||||||
#define cvargroup_serverphysics "server physics variables"
|
#define cvargroup_serverphysics "server physics variables"
|
||||||
void WPhys_Init(void)
|
void WPhys_Init(void)
|
||||||
|
|
|
@ -106,6 +106,7 @@ extern cvar_t pm_ktjump;
|
||||||
extern cvar_t pm_slidefix;
|
extern cvar_t pm_slidefix;
|
||||||
extern cvar_t pm_slidyslopes;
|
extern cvar_t pm_slidyslopes;
|
||||||
extern cvar_t pm_airstep;
|
extern cvar_t pm_airstep;
|
||||||
|
extern cvar_t pm_pground;
|
||||||
extern cvar_t pm_stepdown;
|
extern cvar_t pm_stepdown;
|
||||||
extern cvar_t pm_walljump;
|
extern cvar_t pm_walljump;
|
||||||
extern cvar_t pm_watersinkspeed;
|
extern cvar_t pm_watersinkspeed;
|
||||||
|
@ -6981,6 +6982,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
|
||||||
movevars.ktjump = pm_ktjump.value;
|
movevars.ktjump = pm_ktjump.value;
|
||||||
movevars.slidefix = (pm_slidefix.value != 0);
|
movevars.slidefix = (pm_slidefix.value != 0);
|
||||||
movevars.airstep = (pm_airstep.value != 0);
|
movevars.airstep = (pm_airstep.value != 0);
|
||||||
|
movevars.pground = (pm_pground.value != 0);
|
||||||
movevars.stepdown = (pm_stepdown.value != 0);
|
movevars.stepdown = (pm_stepdown.value != 0);
|
||||||
movevars.walljump = (pm_walljump.value);
|
movevars.walljump = (pm_walljump.value);
|
||||||
movevars.slidyslopes = (pm_slidyslopes.value!=0);
|
movevars.slidyslopes = (pm_slidyslopes.value!=0);
|
||||||
|
@ -7154,7 +7156,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
|
||||||
}
|
}
|
||||||
|
|
||||||
{
|
{
|
||||||
float ptime = sv.world.physicstime;
|
double ptime = sv.world.physicstime;
|
||||||
sv.world.physicstime = sv.time; //urgh, WPhys_RunThink uses the wrong time base
|
sv.world.physicstime = sv.time; //urgh, WPhys_RunThink uses the wrong time base
|
||||||
WPhys_RunThink (&sv.world, (wedict_t*)sv_player);
|
WPhys_RunThink (&sv.world, (wedict_t*)sv_player);
|
||||||
sv.world.physicstime = ptime;
|
sv.world.physicstime = ptime;
|
||||||
|
@ -7206,6 +7208,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
|
||||||
VectorCopy (sv_player->v->v_angle, pmove.angles);
|
VectorCopy (sv_player->v->v_angle, pmove.angles);
|
||||||
|
|
||||||
pmove.pm_type = SV_PMTypeForClient (host_client, sv_player);
|
pmove.pm_type = SV_PMTypeForClient (host_client, sv_player);
|
||||||
|
pmove.onground = ((int)sv_player->v->flags & FL_ONGROUND) != 0;
|
||||||
pmove.jump_held = host_client->jump_held;
|
pmove.jump_held = host_client->jump_held;
|
||||||
pmove.jump_msec = 0;
|
pmove.jump_msec = 0;
|
||||||
if (progstype != PROG_QW) //this is just annoying.
|
if (progstype != PROG_QW) //this is just annoying.
|
||||||
|
@ -7224,6 +7227,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
|
||||||
movevars.ktjump = pm_ktjump.value;
|
movevars.ktjump = pm_ktjump.value;
|
||||||
movevars.slidefix = (pm_slidefix.value != 0);
|
movevars.slidefix = (pm_slidefix.value != 0);
|
||||||
movevars.airstep = (pm_airstep.value != 0);
|
movevars.airstep = (pm_airstep.value != 0);
|
||||||
|
movevars.pground = (pm_pground.value != 0);
|
||||||
movevars.stepdown = (pm_stepdown.value != 0);
|
movevars.stepdown = (pm_stepdown.value != 0);
|
||||||
movevars.walljump = (pm_walljump.value);
|
movevars.walljump = (pm_walljump.value);
|
||||||
movevars.slidyslopes = (pm_slidyslopes.value!=0);
|
movevars.slidyslopes = (pm_slidyslopes.value!=0);
|
||||||
|
|
|
@ -2404,6 +2404,7 @@ qboolean SV_AntiKnockBack(world_t *w, client_t *client)
|
||||||
VectorCopy(frame->pmorigin, pmove.origin);
|
VectorCopy(frame->pmorigin, pmove.origin);
|
||||||
VectorCopy(frame->pmvelocity, pmove.velocity);
|
VectorCopy(frame->pmvelocity, pmove.velocity);
|
||||||
pmove.pm_type = frame->pmtype;
|
pmove.pm_type = frame->pmtype;
|
||||||
|
pmove.onground = true;//FIXME
|
||||||
pmove.jump_held = frame->pmjumpheld;
|
pmove.jump_held = frame->pmjumpheld;
|
||||||
pmove.waterjumptime = frame->pmwaterjumptime;
|
pmove.waterjumptime = frame->pmwaterjumptime;
|
||||||
pmove.onladder = frame->pmonladder;
|
pmove.onladder = frame->pmonladder;
|
||||||
|
|
|
@ -3091,7 +3091,13 @@ static void VK_PaintScreen(void)
|
||||||
|
|
||||||
//draw the levelshot or the conback fullscreen
|
//draw the levelshot or the conback fullscreen
|
||||||
if (*levelshotname)
|
if (*levelshotname)
|
||||||
R2D_ScalePic(0, 0, vid.width, vid.height, R2D_SafeCachePic (levelshotname));
|
{
|
||||||
|
shader_t *pic = R2D_SafeCachePic (levelshotname);
|
||||||
|
int w,h;
|
||||||
|
if (!R_GetShaderSizes(pic, &w, &h, true))
|
||||||
|
w = h = 1;
|
||||||
|
R2D_Letterbox(0, 0, vid.width, vid.height, pic, w, h);
|
||||||
|
}
|
||||||
else if (scr_con_current != vid.height)
|
else if (scr_con_current != vid.height)
|
||||||
R2D_ConsoleBackground(0, vid.height, true);
|
R2D_ConsoleBackground(0, vid.height, true);
|
||||||
else
|
else
|
||||||
|
|
|
@ -541,14 +541,14 @@ mergeInto(LibraryManager.library,
|
||||||
FTEC.vrDisplay.getFrameData(FTEC.vrframeData);
|
FTEC.vrDisplay.getFrameData(FTEC.vrframeData);
|
||||||
}
|
}
|
||||||
|
|
||||||
// try
|
try //this try is needed to handle Host_EndGame properly.
|
||||||
// {
|
{
|
||||||
dovsync = Runtime.dynCall('i', fnc, []);
|
dovsync = Runtime.dynCall('i', fnc, []);
|
||||||
// }
|
}
|
||||||
// catch(err)
|
catch(err)
|
||||||
// {
|
{
|
||||||
// console.log(err);
|
console.log(err);
|
||||||
// }
|
}
|
||||||
if (vr)
|
if (vr)
|
||||||
FTEC.vrDisplay.submitFrame();
|
FTEC.vrDisplay.submitFrame();
|
||||||
if (dovsync)
|
if (dovsync)
|
||||||
|
@ -771,7 +771,7 @@ mergeInto(LibraryManager.library,
|
||||||
s.ws.onopen = function(event) {s.con = 1;};
|
s.ws.onopen = function(event) {s.con = 1;};
|
||||||
s.ws.onmessage = function(event)
|
s.ws.onmessage = function(event)
|
||||||
{
|
{
|
||||||
assert(typeof event.data !== 'string' && event.data.byteLength);
|
assert(typeof event.data !== 'string' && event.data.byteLength, 'websocket data is not usable');
|
||||||
s.inq.push(new Uint8Array(event.data));
|
s.inq.push(new Uint8Array(event.data));
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -1088,7 +1088,7 @@ console.log("onerror: " + _url);
|
||||||
return;
|
return;
|
||||||
buf = buf - 1;
|
buf = buf - 1;
|
||||||
|
|
||||||
var ctx = AL.currentContext;
|
var ctx = AL.currentContext || AL.currentCtx;
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
//its async, so it needs its own copy of an arraybuffer
|
//its async, so it needs its own copy of an arraybuffer
|
||||||
|
|
|
@ -243,8 +243,13 @@ void Net_ProxySend(cluster_t *cluster, oproxy_t *prox, void *buffer, int length)
|
||||||
{
|
{
|
||||||
unsigned int c;
|
unsigned int c;
|
||||||
int enclen = 0;
|
int enclen = 0;
|
||||||
|
int datatype = 2; //1=utf-8, 2=binary
|
||||||
|
|
||||||
/*work out how much buffer space we'll need*/
|
/*work out how much buffer space we'll need*/
|
||||||
|
if (datatype == 2)
|
||||||
|
enclen += length;
|
||||||
|
else
|
||||||
|
{
|
||||||
for (c = 0; c < length; c++)
|
for (c = 0; c < length; c++)
|
||||||
{
|
{
|
||||||
if (((unsigned char*)buffer)[c] == 0 || ((unsigned char*)buffer)[c] >= 0x80)
|
if (((unsigned char*)buffer)[c] == 0 || ((unsigned char*)buffer)[c] >= 0x80)
|
||||||
|
@ -252,6 +257,7 @@ void Net_ProxySend(cluster_t *cluster, oproxy_t *prox, void *buffer, int length)
|
||||||
else
|
else
|
||||||
enclen += 1;
|
enclen += 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (prox->buffersize-prox->bufferpos + (enclen+4) > MAX_PROXY_BUFFER)
|
if (prox->buffersize-prox->bufferpos + (enclen+4) > MAX_PROXY_BUFFER)
|
||||||
{
|
{
|
||||||
|
@ -269,16 +275,23 @@ void Net_ProxySend(cluster_t *cluster, oproxy_t *prox, void *buffer, int length)
|
||||||
|
|
||||||
if (enclen >= 126)
|
if (enclen >= 126)
|
||||||
{
|
{
|
||||||
prox->buffer[prox->buffersize++&(MAX_PROXY_BUFFER-1)] = 0x81;
|
prox->buffer[prox->buffersize++&(MAX_PROXY_BUFFER-1)] = 0x80|datatype;
|
||||||
prox->buffer[prox->buffersize++&(MAX_PROXY_BUFFER-1)] = 126;
|
prox->buffer[prox->buffersize++&(MAX_PROXY_BUFFER-1)] = 126;
|
||||||
prox->buffer[prox->buffersize++&(MAX_PROXY_BUFFER-1)] = enclen>>8;
|
prox->buffer[prox->buffersize++&(MAX_PROXY_BUFFER-1)] = enclen>>8;
|
||||||
prox->buffer[prox->buffersize++&(MAX_PROXY_BUFFER-1)] = enclen;
|
prox->buffer[prox->buffersize++&(MAX_PROXY_BUFFER-1)] = enclen;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
prox->buffer[prox->buffersize++&(MAX_PROXY_BUFFER-1)] = 0x81;
|
prox->buffer[prox->buffersize++&(MAX_PROXY_BUFFER-1)] = 0x80|datatype;
|
||||||
prox->buffer[prox->buffersize++&(MAX_PROXY_BUFFER-1)] = enclen;
|
prox->buffer[prox->buffersize++&(MAX_PROXY_BUFFER-1)] = enclen;
|
||||||
}
|
}
|
||||||
|
if (datatype == 2)
|
||||||
|
{
|
||||||
|
for(; length-->0; buffer = (char*)buffer+1)
|
||||||
|
prox->buffer[prox->buffersize++&(MAX_PROXY_BUFFER-1)] = *(unsigned char*)buffer;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{ //utf-8 (or really just bytes with upper bits truncated. sue me.
|
||||||
while(length-->0)
|
while(length-->0)
|
||||||
{
|
{
|
||||||
c = *(unsigned char*)buffer;
|
c = *(unsigned char*)buffer;
|
||||||
|
@ -293,6 +306,7 @@ void Net_ProxySend(cluster_t *cluster, oproxy_t *prox, void *buffer, int length)
|
||||||
else
|
else
|
||||||
prox->buffer[prox->buffersize++&(MAX_PROXY_BUFFER-1)] = c;
|
prox->buffer[prox->buffersize++&(MAX_PROXY_BUFFER-1)] = c;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
Net_TryFlushProxyBuffer(cluster, prox); //try flushing in a desperate attempt to reduce bugs in google chrome.
|
Net_TryFlushProxyBuffer(cluster, prox); //try flushing in a desperate attempt to reduce bugs in google chrome.
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
233
fteqtv/httpsv.c
233
fteqtv/httpsv.c
|
@ -202,32 +202,6 @@ static void HTTPSV_SendHTMLHeader(cluster_t *cluster, oproxy_t *dest, char *titl
|
||||||
);
|
);
|
||||||
|
|
||||||
Net_ProxySend(cluster, dest, buffer, strlen(buffer));
|
Net_ProxySend(cluster, dest, buffer, strlen(buffer));
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (plugin)
|
|
||||||
{
|
|
||||||
s =
|
|
||||||
"<script>"
|
|
||||||
"if (!parent.getplug || parent.getplug().plugver == undefined || parent.getplug().plugver < "MINPLUGVER")"
|
|
||||||
"{"
|
|
||||||
"if (!parent.getplug || parent.getplug().plugver == undefined)"
|
|
||||||
"{"
|
|
||||||
"document.write(\"You need a plugin! Get one here!\");"
|
|
||||||
"}"
|
|
||||||
"else"
|
|
||||||
"{"
|
|
||||||
"document.write(\"Update your plugin!\");"
|
|
||||||
"}"
|
|
||||||
"document.write(\"<br/>"
|
|
||||||
"<a href=\\\"npfte.xpi\\\">Firefox (open with firefox itself)</a><br/>"
|
|
||||||
"<a href=\\\"iefte.exe\\\">Internet Explorer</a><br/>"
|
|
||||||
"<a href=\\\"npfte.exe\\\">Others</a><br/>"
|
|
||||||
"\");"
|
|
||||||
"}"
|
|
||||||
"</script>";
|
|
||||||
Net_ProxySend(cluster, dest, s, strlen(s));
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void HTTPSV_SendHTMLFooter(cluster_t *cluster, oproxy_t *dest)
|
static void HTTPSV_SendHTMLFooter(cluster_t *cluster, oproxy_t *dest)
|
||||||
|
@ -239,12 +213,6 @@ static void HTTPSV_SendHTMLFooter(cluster_t *cluster, oproxy_t *dest)
|
||||||
snprintf(buffer, sizeof(buffer), "<br/>Server Version: "QTV_VERSION_STRING" <a href=\""PROXYWEBSITE"\" target=\"_blank\">"PROXYWEBSITE"</a>");
|
snprintf(buffer, sizeof(buffer), "<br/>Server Version: "QTV_VERSION_STRING" <a href=\""PROXYWEBSITE"\" target=\"_blank\">"PROXYWEBSITE"</a>");
|
||||||
Net_ProxySend(cluster, dest, buffer, strlen(buffer));
|
Net_ProxySend(cluster, dest, buffer, strlen(buffer));
|
||||||
|
|
||||||
#if 0
|
|
||||||
/*Plugin version*/
|
|
||||||
s = "<script>if (parent.getplug != null) document.write(\"<br/>Plugin Version: \" + parent.getplug().build + parent.getplug().server);</script>";
|
|
||||||
Net_ProxySend(cluster, dest, s, strlen(s));
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/*terminate html page*/
|
/*terminate html page*/
|
||||||
s = "</body>\n"
|
s = "</body>\n"
|
||||||
"</html>\n";
|
"</html>\n";
|
||||||
|
@ -347,8 +315,11 @@ static void HTTPSV_GenerateCSSFile(cluster_t *cluster, oproxy_t *dest)
|
||||||
HTTPSV_SendHTTPHeader(cluster, dest, "200", "text/css", false);
|
HTTPSV_SendHTTPHeader(cluster, dest, "200", "text/css", false);
|
||||||
|
|
||||||
HTMLPRINT("* { font-family: Verdana, Helvetica, sans-serif; }");
|
HTMLPRINT("* { font-family: Verdana, Helvetica, sans-serif; }");
|
||||||
HTMLPRINT("body { color: #000; background-color: #fff; padding: 0 40px; }");
|
HTMLPRINT("body { color: #000; background-color: #fff; padding: 0 0px; }");
|
||||||
HTMLPRINT("a { color: #00f; }");
|
HTMLPRINT("a { color: #00f; }");
|
||||||
|
HTMLPRINT("div.topdiv { display:flex; align-items: stretch; position: absolute; top: 0; right: 0; bottom: 0; left: 0; }");
|
||||||
|
HTMLPRINT("div.left { resize: horizontal; overflow: auto; flex 0 0 25%;}");
|
||||||
|
HTMLPRINT("div.right { padding:0; margin: 0; flex: auto; }");
|
||||||
HTMLPRINT("a.qtvfile { font-weight: bold; }");
|
HTMLPRINT("a.qtvfile { font-weight: bold; }");
|
||||||
HTMLPRINT("a:visited { color: #00f; }");
|
HTMLPRINT("a:visited { color: #00f; }");
|
||||||
HTMLPRINT("a:hover { background-color: black; color: yellow; }");
|
HTMLPRINT("a:hover { background-color: black; color: yellow; }");
|
||||||
|
@ -357,6 +328,7 @@ static void HTTPSV_GenerateCSSFile(cluster_t *cluster, oproxy_t *dest)
|
||||||
HTMLPRINT("dl.nowplaying dt { margin: 1em 0 0 0; font-size: 1.1em; font-weight: bold; }");
|
HTMLPRINT("dl.nowplaying dt { margin: 1em 0 0 0; font-size: 1.1em; font-weight: bold; }");
|
||||||
HTMLPRINT("dl.nowplaying li { list-style: none; margin: 0 0 0 1em; padding: 0; }");
|
HTMLPRINT("dl.nowplaying li { list-style: none; margin: 0 0 0 1em; padding: 0; }");
|
||||||
HTMLPRINT("dl.nowplaying ul { margin: 0 0 0 1em; padding: 0; }");
|
HTMLPRINT("dl.nowplaying ul { margin: 0 0 0 1em; padding: 0; }");
|
||||||
|
HTMLPRINT("canvas.emscripten { border: 0px none; padding:0; margin: 0; width: 100%; height: 100%;}");
|
||||||
HTMLPRINT("#navigation { background-color: #eef; }");
|
HTMLPRINT("#navigation { background-color: #eef; }");
|
||||||
HTMLPRINT("#navigation li { display: inline; list-style: none; margin: 0 3em; }");
|
HTMLPRINT("#navigation li { display: inline; list-style: none; margin: 0 3em; }");
|
||||||
}
|
}
|
||||||
|
@ -788,154 +760,66 @@ static void HTTPSV_GeneratePlugin(cluster_t *cluster, oproxy_t *dest)
|
||||||
html = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n"
|
html = "<!DOCTYPE HTML PUBLIC \"-//W3C//DTD HTML 4.01 Transitional//EN\" \"http://www.w3.org/TR/html4/loose.dtd\">\n"
|
||||||
"<HTML><HEAD><TITLE>QuakeTV With Plugin</TITLE>"
|
"<HTML><HEAD><TITLE>QuakeTV With Plugin</TITLE>"
|
||||||
" <link rel=\"StyleSheet\" href=\"/style.css\" type=\"text/css\" />\n"
|
" <link rel=\"StyleSheet\" href=\"/style.css\" type=\"text/css\" />\n"
|
||||||
|
"<meta charset='utf-8' />"
|
||||||
"</HEAD><body>"
|
"</HEAD><body>"
|
||||||
"<div id=optdiv style='position:fixed; left:0%; width:50%; top:0%; height:100%;'>"
|
"<div class='topdiv'>"
|
||||||
|
"<div class='left' id=optdiv>"
|
||||||
"<iframe frameborder=0 src=\"nowplaying.html?p\" width=\"100%\" height=\"100%\">"
|
"<iframe frameborder=0 src=\"nowplaying.html?p\" width=\"100%\" height=\"100%\">"
|
||||||
"oh dear. your browser doesn't support this site"
|
"oh dear. your browser doesn't support this site"
|
||||||
"</iframe>"
|
"</iframe>"
|
||||||
"</div>"
|
"</div>"
|
||||||
"<div id=plugdiv style='position:fixed; left:50%; width:50%; top:0%; height:100%;'>"
|
"<div class='right' id=plugdiv>"
|
||||||
|
"<canvas class='emscripten' id='canvas' oncontextmenu='event.preventDefault()'>Canvas not supported</canvas>"
|
||||||
#if 1
|
|
||||||
#define EMBEDDEDWEBGLORIGIN "http://86.191.129.12:80"//127.0.0.1:80"
|
|
||||||
#define EMBEDDEDWEBGLURL EMBEDDEDWEBGLORIGIN"/ftewebgl.html"
|
|
||||||
#else
|
|
||||||
#define EMBEDDEDWEBGLORIGIN "http://triptohell.info"
|
|
||||||
#define EMBEDDEDWEBGLURL EMBEDDEDWEBGLORIGIN"/moodles/web/ftewebgl.html"
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#if 1
|
|
||||||
"<iframe frameborder=0 allowfullscreen=1 name=\"webgl\" src=\""EMBEDDEDWEBGLURL"\" width=\"100%\" height=\"100%\">"
|
|
||||||
"oh dear. your browser doesn't support this site"
|
|
||||||
"</iframe>"
|
|
||||||
#else
|
|
||||||
/*once for IE*/
|
|
||||||
"<object name=\"ieplug\""
|
|
||||||
" type=\"text/x-quaketvident\""
|
|
||||||
" classid=\"clsid:7d676c9f-fb84-40b6-b3ff-e10831557eeb\""
|
|
||||||
//" codebase=\""PROXYWEBSITE"/test.cab\""
|
|
||||||
" width=100%"
|
|
||||||
" height=100%"
|
|
||||||
" >"
|
|
||||||
"<param name=\"splash\" value=\"http://"
|
|
||||||
;
|
|
||||||
Net_ProxySend(cluster, dest, html, strlen(html));
|
|
||||||
Net_ProxySend(cluster, dest, hostname, strlen(hostname));
|
|
||||||
html =
|
|
||||||
"/qtvsplash.jpg\">"
|
|
||||||
"<param name=\"availver\" value=\""MINPLUGVER"\">"
|
|
||||||
"<param name=\"game\" value=\"q1\">"
|
|
||||||
"<param name=\"dataDownload\" value='";
|
|
||||||
Net_ProxySend(cluster, dest, html, strlen(html));
|
|
||||||
Net_ProxySend(cluster, dest, cluster->plugindatasource, strlen(cluster->plugindatasource));
|
|
||||||
html =
|
|
||||||
"'>"
|
|
||||||
/*once again for firefox and similar friends*/
|
|
||||||
"<object name=\"npplug\""
|
|
||||||
" type=\"text/x-quaketvident\""
|
|
||||||
" width=100%"
|
|
||||||
" height=100%"
|
|
||||||
" >"
|
|
||||||
"<param name=\"splash\" value=\"http://"
|
|
||||||
;
|
|
||||||
Net_ProxySend(cluster, dest, html, strlen(html));
|
|
||||||
Net_ProxySend(cluster, dest, hostname, strlen(hostname));
|
|
||||||
html =
|
|
||||||
"/qtvsplash.jpg\">"
|
|
||||||
"<param name=\"availver\" value=\""MINPLUGVER"\">"
|
|
||||||
"<param name=\"game\" value=\"q1\">"
|
|
||||||
"<param name=\"dataDownload\" value='";
|
|
||||||
Net_ProxySend(cluster, dest, html, strlen(html));
|
|
||||||
Net_ProxySend(cluster, dest, cluster->plugindatasource, strlen(cluster->plugindatasource));
|
|
||||||
html =
|
|
||||||
"'>"
|
|
||||||
"Plugin failed to load"
|
|
||||||
"</object>"
|
|
||||||
"</object>"
|
|
||||||
#endif
|
|
||||||
"</div>"
|
"</div>"
|
||||||
|
"</div>"
|
||||||
"<script>"
|
"<script type='text/javascript'>"
|
||||||
#if 0
|
"var Module = {"
|
||||||
"function getplugnp(d)\n"
|
"canvas: document.getElementById('canvas'),"
|
||||||
"{\n"
|
"print: function(msg)"
|
||||||
"return document.npplug;\n"
|
"{"
|
||||||
"}\n"
|
"console.log(msg);"
|
||||||
"function getplugie(d)\n"
|
"},"
|
||||||
"{\n"
|
"printErr: function(text)"
|
||||||
"return document.ieplug;\n"
|
"{"
|
||||||
"}\n"
|
"if (text.substr(0, 28) == 'Cannot enlarge memory arrays')"
|
||||||
"parent.host = \""
|
"alert('Memory full/fragmented. Please reload the page.');"
|
||||||
;
|
"else "
|
||||||
Net_ProxySend(cluster, dest, html, strlen(html));
|
"console.log(text);"
|
||||||
Net_ProxySend(cluster, dest, hostname, strlen(hostname));
|
"},"
|
||||||
html =
|
"arguments: ["
|
||||||
"\";\n"
|
"'-nohome',"
|
||||||
|
"'-manifest',"
|
||||||
"if (getplugie() != undefined && getplugie().plugver != undefined)\n"
|
"'http://triptohell.info/demo.fmf',"
|
||||||
"{\nparent.getplug = getplugie;\n}\n"
|
"'+connect',"
|
||||||
"else\n"
|
"window.location.host"
|
||||||
"{\nparent.getplug = getplugnp;\n}\n"
|
"]"
|
||||||
|
"};"
|
||||||
"function joinserver(d)\n"
|
|
||||||
"{\n"
|
//create the script object
|
||||||
"getplug().mapsrc = \""
|
"var s = document.createElement('script');"
|
||||||
;
|
// set it up
|
||||||
Net_ProxySend(cluster, dest, html, strlen(html));
|
"s.setAttribute('src','http://triptohell.info/ftewebgl.js');"
|
||||||
Net_ProxySend(cluster, dest, cluster->plugindatasource, strlen(cluster->plugindatasource));
|
"s.setAttribute('type','text/javascript');"
|
||||||
html =
|
"s.setAttribute('charset','utf-8');"
|
||||||
"\";\n"
|
"s.addEventListener('error', function() {alert('Error loading game script.');}, false);"
|
||||||
"getplug().server = d;\n"
|
// add to DOM
|
||||||
"getplug().running = 1;\n"
|
"document.head.appendChild(s);"
|
||||||
"}\n"
|
|
||||||
|
//set up some functions that the embedded stuff can use
|
||||||
"function playdemo(d)\n"
|
"parent.joinserver = function(d)"
|
||||||
"{\n"
|
|
||||||
// "getplug().mapsrc = \"http://bigfoot.morphos-team.net/misc/quakemaps/\";\n"
|
|
||||||
"getplug().stream = \"file:\"+d+\"@"
|
|
||||||
;
|
|
||||||
Net_ProxySend(cluster, dest, html, strlen(html));
|
|
||||||
Net_ProxySend(cluster, dest, hostname, strlen(hostname));
|
|
||||||
html =
|
|
||||||
"\";\n"
|
|
||||||
"getplug().running = 1;\n"
|
|
||||||
"}\n"
|
|
||||||
#else
|
|
||||||
"function joinserver(d)"
|
|
||||||
"{"
|
"{"
|
||||||
// "webgl.postMessage({cmd:'mapsrc',url:\""
|
|
||||||
// ;
|
|
||||||
// Net_ProxySend(cluster, dest, html, strlen(html));
|
|
||||||
// Net_ProxySend(cluster, dest, cluster->plugindatasource, strlen(cluster->plugindatasource));
|
|
||||||
// html =
|
|
||||||
// "\"}, \""EMBEDDEDWEBGLORIGIN"\");"
|
|
||||||
"webgl.postMessage({'cmd':'observeurl','url':'ws://86.191.129.12:27500'}, \""EMBEDDEDWEBGLORIGIN"\");"
|
|
||||||
"}\n"
|
"}\n"
|
||||||
|
|
||||||
"function playdemo(d)"
|
"parent.playdemo = function(d)"
|
||||||
"{"
|
"{"
|
||||||
// "parent.webgl.postMessage({cmd:'mapsrc',url:\""
|
|
||||||
// ;
|
|
||||||
// Net_ProxySend(cluster, dest, html, strlen(html));
|
|
||||||
// Net_ProxySend(cluster, dest, cluster->plugindatasource, strlen(cluster->plugindatasource));
|
|
||||||
// html =
|
|
||||||
// "\"}, \""EMBEDDEDWEBGLORIGIN"\");"
|
|
||||||
"parent.webgl.postMessage({cmd:'demourl',url:d}, \""EMBEDDEDWEBGLORIGIN"\");"
|
|
||||||
"}\n"
|
"}\n"
|
||||||
#endif
|
|
||||||
|
|
||||||
"parent.joinserver = joinserver;\n"
|
|
||||||
"parent.playdemo = playdemo;\n"
|
|
||||||
|
|
||||||
/* "if (getplug().plugver == undefined)"
|
|
||||||
"{"
|
|
||||||
"document.getElementById('plugdiv').style.left = '75%';"
|
|
||||||
"document.getElementById('optdiv').style.width = '25%';"
|
|
||||||
"document.getElementById('plugdiv').style.width = '0';"
|
|
||||||
"parent.getplug = null;"
|
|
||||||
"}"
|
|
||||||
*/
|
|
||||||
"</script>"
|
"</script>"
|
||||||
|
"<noscript>"
|
||||||
|
"It looks like you have javascript disabled.<br/>"
|
||||||
|
"If you want to run a javascript port of a game engine, it helps to have javascript enabled. Just saying.<br/>"
|
||||||
|
"<br/>"
|
||||||
|
"</noscript>"
|
||||||
|
|
||||||
"</body></HTML>";
|
"</body></HTML>";
|
||||||
Net_ProxySend(cluster, dest, html, strlen(html));
|
Net_ProxySend(cluster, dest, html, strlen(html));
|
||||||
|
@ -1171,7 +1055,7 @@ void HTTPSV_GetMethod(cluster_t *cluster, oproxy_t *pend)
|
||||||
uriend = s;
|
uriend = s;
|
||||||
urilen = uriend - uri;
|
urilen = uriend - uri;
|
||||||
|
|
||||||
if (!pend->websocket.websocket && HTTPSV_GetHeaderField((char*)pend->inbuffer, "Connection", connection, sizeof(connection)) && !stricmp(connection, "Upgrade"))
|
if (!pend->websocket.websocket && HTTPSV_GetHeaderField((char*)pend->inbuffer, "Connection", connection, sizeof(connection)) && strstr(connection, "Upgrade"))
|
||||||
{
|
{
|
||||||
if (HTTPSV_GetHeaderField((char*)pend->inbuffer, "Upgrade", upgrade, sizeof(upgrade)) && !stricmp(upgrade, "websocket"))
|
if (HTTPSV_GetHeaderField((char*)pend->inbuffer, "Upgrade", upgrade, sizeof(upgrade)) && !stricmp(upgrade, "websocket"))
|
||||||
{
|
{
|
||||||
|
@ -1252,16 +1136,7 @@ void HTTPSV_GetMethod(cluster_t *cluster, oproxy_t *pend)
|
||||||
#endif
|
#endif
|
||||||
else REDIRECTIF("/", "/nowplaying.html")
|
else REDIRECTIF("/", "/nowplaying.html")
|
||||||
else REDIRECTIF("/about.html", PROXYWEBSITE)
|
else REDIRECTIF("/about.html", PROXYWEBSITE)
|
||||||
#if 0
|
else REDIRECTIF("/favicon.ico", "http://triptohell.info/favicon.ico")
|
||||||
else REDIRECTIF("/qtvsplash.jpg", "/file/qtvsplash.jpg") /*lame, very lame*/
|
|
||||||
#if defined(_DEBUG) || defined(DEBUG)
|
|
||||||
else REDIRECTIF("/npfte.xpi", "/file/npfte_dbg.xpi") /*lame, very lame*/
|
|
||||||
#else
|
|
||||||
else REDIRECTIF("/npfte.xpi", "/file/npfte.xpi") /*lame, very lame*/
|
|
||||||
#endif
|
|
||||||
else REDIRECTIF("/npfte.exe", "/file/npfte.exe") /*lame, very lame*/
|
|
||||||
else REDIRECTIF("/iefte.exe", "/file/iefte.exe") /*lame, very lame*/
|
|
||||||
#endif
|
|
||||||
else if (uriargmatch(uri, "/demos.html", urilen, &args))
|
else if (uriargmatch(uri, "/demos.html", urilen, &args))
|
||||||
{
|
{
|
||||||
HTTPSV_GenerateDemoListing(cluster, pend, args);
|
HTTPSV_GenerateDemoListing(cluster, pend, args);
|
||||||
|
|
|
@ -24,7 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
|
||||||
#define curtime Sys_Milliseconds()
|
#define curtime Sys_Milliseconds()
|
||||||
|
|
||||||
|
|
||||||
void NET_InitUDPSocket(cluster_t *cluster, int port, qboolean ipv6)
|
void NET_InitUDPSocket(cluster_t *cluster, int port, int socketid)
|
||||||
{
|
{
|
||||||
int sock;
|
int sock;
|
||||||
|
|
||||||
|
@ -38,39 +38,42 @@ void NET_InitUDPSocket(cluster_t *cluster, int port, qboolean ipv6)
|
||||||
unsigned long v6only = false;
|
unsigned long v6only = false;
|
||||||
|
|
||||||
#pragma message("fixme")
|
#pragma message("fixme")
|
||||||
if (ipv6)
|
switch(socketid)
|
||||||
{
|
{
|
||||||
|
case SG_IPV6:
|
||||||
pf = PF_INET6;
|
pf = PF_INET6;
|
||||||
memset(&address6, 0, sizeof(address6));
|
memset(&address6, 0, sizeof(address6));
|
||||||
address6.sin6_family = AF_INET6;
|
address6.sin6_family = AF_INET6;
|
||||||
address6.sin6_port = htons((u_short)port);
|
address6.sin6_port = htons((u_short)port);
|
||||||
address = (struct sockaddr*)&address6;
|
address = (struct sockaddr*)&address6;
|
||||||
addrlen = sizeof(address6);
|
addrlen = sizeof(address6);
|
||||||
}
|
break;
|
||||||
else
|
case SG_IPV4:
|
||||||
{
|
|
||||||
pf = PF_INET;
|
pf = PF_INET;
|
||||||
address4.sin_family = AF_INET;
|
address4.sin_family = AF_INET;
|
||||||
address4.sin_addr.s_addr = INADDR_ANY;
|
address4.sin_addr.s_addr = INADDR_ANY;
|
||||||
address4.sin_port = htons((u_short)port);
|
address4.sin_port = htons((u_short)port);
|
||||||
address = (struct sockaddr*)&address4;
|
address = (struct sockaddr*)&address4;
|
||||||
addrlen = sizeof(address4);
|
addrlen = sizeof(address4);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
return; //erk
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!ipv6 && !v6only && cluster->qwdsocket[1] != INVALID_SOCKET)
|
if (socketid == SG_IPV4 && !v6only && cluster->qwdsocket[SG_IPV6] != INVALID_SOCKET)
|
||||||
{
|
{
|
||||||
int sz = sizeof(v6only);
|
int sz = sizeof(v6only);
|
||||||
if (getsockopt(cluster->qwdsocket[1], IPPROTO_IPV6, IPV6_V6ONLY, (char *)&v6only, &sz) == 0 && !v6only)
|
if (getsockopt(cluster->qwdsocket[SG_IPV6], IPPROTO_IPV6, IPV6_V6ONLY, (char *)&v6only, &sz) == 0 && !v6only)
|
||||||
port = 0;
|
port = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!port)
|
if (!port)
|
||||||
{
|
{
|
||||||
if (cluster->qwdsocket[ipv6] != INVALID_SOCKET)
|
if (cluster->qwdsocket[socketid] != INVALID_SOCKET)
|
||||||
{
|
{
|
||||||
closesocket(cluster->qwdsocket[ipv6]);
|
closesocket(cluster->qwdsocket[socketid]);
|
||||||
cluster->qwdsocket[ipv6] = INVALID_SOCKET;
|
cluster->qwdsocket[socketid] = INVALID_SOCKET;
|
||||||
Sys_Printf(cluster, "closed udp%i port\n", ipv6?6:4);
|
Sys_Printf(cluster, "closed udp%i port\n", socketid?6:4);
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -97,14 +100,14 @@ void NET_InitUDPSocket(cluster_t *cluster, int port, qboolean ipv6)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (cluster->qwdsocket[ipv6] != INVALID_SOCKET)
|
if (cluster->qwdsocket[socketid] != INVALID_SOCKET)
|
||||||
{
|
{
|
||||||
closesocket(cluster->qwdsocket[ipv6]);
|
closesocket(cluster->qwdsocket[socketid]);
|
||||||
Sys_Printf(cluster, "closed udp%i port\n", ipv6?6:4);
|
Sys_Printf(cluster, "closed udp%i port\n", socketid?6:4);
|
||||||
}
|
}
|
||||||
cluster->qwdsocket[ipv6] = sock;
|
cluster->qwdsocket[socketid] = sock;
|
||||||
if (v6only)
|
if (v6only)
|
||||||
Sys_Printf(cluster, "opened udp%i port %i\n", ipv6?6:4, port);
|
Sys_Printf(cluster, "opened udp%i port %i\n", socketid?6:4, port);
|
||||||
else
|
else
|
||||||
Sys_Printf(cluster, "opened udp port %i\n", port);
|
Sys_Printf(cluster, "opened udp port %i\n", port);
|
||||||
}
|
}
|
||||||
|
@ -115,9 +118,9 @@ SOCKET NET_ChooseSocket(SOCKET sock[2], netadr_t *toadr, netadr_t ina)
|
||||||
if (((struct sockaddr *)ina.sockaddr)->sa_family == AF_INET6)
|
if (((struct sockaddr *)ina.sockaddr)->sa_family == AF_INET6)
|
||||||
{
|
{
|
||||||
*toadr = ina;
|
*toadr = ina;
|
||||||
return sock[1];
|
return sock[SG_IPV6];
|
||||||
}
|
}
|
||||||
if (sock[0] == INVALID_SOCKET && sock[1] != INVALID_SOCKET)
|
if (sock[0] == INVALID_SOCKET && sock[SG_IPV6] != INVALID_SOCKET)
|
||||||
{
|
{
|
||||||
struct sockaddr_in6 *out = (struct sockaddr_in6*)toadr->sockaddr;
|
struct sockaddr_in6 *out = (struct sockaddr_in6*)toadr->sockaddr;
|
||||||
struct sockaddr_in *in = (struct sockaddr_in*)ina.sockaddr;
|
struct sockaddr_in *in = (struct sockaddr_in*)ina.sockaddr;
|
||||||
|
@ -128,11 +131,11 @@ SOCKET NET_ChooseSocket(SOCKET sock[2], netadr_t *toadr, netadr_t ina)
|
||||||
*(short*)&out->sin6_addr.s6_addr[10] = 0xffff;
|
*(short*)&out->sin6_addr.s6_addr[10] = 0xffff;
|
||||||
*(int*)&out->sin6_addr.s6_addr[12] = in->sin_addr.s_addr;
|
*(int*)&out->sin6_addr.s6_addr[12] = in->sin_addr.s_addr;
|
||||||
out->sin6_port = in->sin_port;
|
out->sin6_port = in->sin_port;
|
||||||
return sock[1];
|
return sock[SG_IPV6];
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
*toadr = ina;
|
*toadr = ina;
|
||||||
return sock[0];
|
return sock[SG_IPV4];
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef LIBQTV
|
#ifdef LIBQTV
|
||||||
|
@ -172,7 +175,13 @@ void NET_SendPacket(cluster_t *cluster, SOCKET sock, int length, void *data, net
|
||||||
|
|
||||||
if (dest->websocket.websocket)
|
if (dest->websocket.websocket)
|
||||||
{
|
{
|
||||||
|
int datatype = 2; //1=utf-8, 2=binary
|
||||||
int enclen = 0, c;
|
int enclen = 0, c;
|
||||||
|
|
||||||
|
if (datatype == 2)
|
||||||
|
enclen = length;
|
||||||
|
else
|
||||||
|
{
|
||||||
for (c = 0; c < length; c++)
|
for (c = 0; c < length; c++)
|
||||||
{
|
{
|
||||||
if (((unsigned char*)data)[c] == 0 || ((unsigned char*)data)[c] >= 0x80)
|
if (((unsigned char*)data)[c] == 0 || ((unsigned char*)data)[c] >= 0x80)
|
||||||
|
@ -180,21 +189,29 @@ void NET_SendPacket(cluster_t *cluster, SOCKET sock, int length, void *data, net
|
||||||
else
|
else
|
||||||
enclen += 1;
|
enclen += 1;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (dest->outbuffersize + 4+enclen < sizeof(dest->outbuffer))
|
if (dest->outbuffersize + 4+enclen < sizeof(dest->outbuffer))
|
||||||
{
|
{
|
||||||
if (enclen >= 126)
|
if (enclen >= 126)
|
||||||
{
|
{
|
||||||
dest->outbuffer[dest->outbuffersize++] = 0x81;
|
dest->outbuffer[dest->outbuffersize++] = 0x80|datatype;
|
||||||
dest->outbuffer[dest->outbuffersize++] = 126;
|
dest->outbuffer[dest->outbuffersize++] = 126;
|
||||||
dest->outbuffer[dest->outbuffersize++] = enclen>>8;
|
dest->outbuffer[dest->outbuffersize++] = enclen>>8;
|
||||||
dest->outbuffer[dest->outbuffersize++] = enclen;
|
dest->outbuffer[dest->outbuffersize++] = enclen;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
dest->outbuffer[dest->outbuffersize++] = 0x81;
|
dest->outbuffer[dest->outbuffersize++] = 0x80|datatype;
|
||||||
dest->outbuffer[dest->outbuffersize++] = enclen;
|
dest->outbuffer[dest->outbuffersize++] = enclen;
|
||||||
}
|
}
|
||||||
|
if (datatype == 2)
|
||||||
|
{
|
||||||
|
memcpy(dest->outbuffer+dest->outbuffersize, data, enclen);
|
||||||
|
dest->outbuffersize += enclen;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
while(length-->0)
|
while(length-->0)
|
||||||
{
|
{
|
||||||
c = *(unsigned char*)data;
|
c = *(unsigned char*)data;
|
||||||
|
@ -211,6 +228,7 @@ void NET_SendPacket(cluster_t *cluster, SOCKET sock, int length, void *data, net
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (dest->outbuffersize + length < sizeof(dest->outbuffer))
|
if (dest->outbuffersize + length < sizeof(dest->outbuffer))
|
||||||
|
|
|
@ -469,6 +469,7 @@ typedef struct viewer_s {
|
||||||
qboolean thinksitsconnected;
|
qboolean thinksitsconnected;
|
||||||
qboolean conmenussupported;
|
qboolean conmenussupported;
|
||||||
qboolean isproxy;
|
qboolean isproxy;
|
||||||
|
unsigned int pext1, pext2;
|
||||||
|
|
||||||
int servercount;
|
int servercount;
|
||||||
|
|
||||||
|
@ -926,7 +927,7 @@ void PM_PlayerMove (pmove_t *pmove);
|
||||||
void Netchan_Setup (SOCKET sock, netchan_t *chan, netadr_t adr, int qport, qboolean isclient);
|
void Netchan_Setup (SOCKET sock, netchan_t *chan, netadr_t adr, int qport, qboolean isclient);
|
||||||
void Netchan_OutOfBandPrint (cluster_t *cluster, netadr_t adr, char *format, ...) PRINTFWARNING(3);
|
void Netchan_OutOfBandPrint (cluster_t *cluster, netadr_t adr, char *format, ...) PRINTFWARNING(3);
|
||||||
//int Netchan_IsLocal (netadr_t adr);
|
//int Netchan_IsLocal (netadr_t adr);
|
||||||
void NET_InitUDPSocket(cluster_t *cluster, int port, qboolean ipv6);
|
void NET_InitUDPSocket(cluster_t *cluster, int port, int socketid);
|
||||||
void NET_SendPacket(cluster_t *cluster, SOCKET sock, int length, void *data, netadr_t adr);
|
void NET_SendPacket(cluster_t *cluster, SOCKET sock, int length, void *data, netadr_t adr);
|
||||||
SOCKET NET_ChooseSocket(SOCKET sock[], netadr_t *toadr, netadr_t in);
|
SOCKET NET_ChooseSocket(SOCKET sock[], netadr_t *toadr, netadr_t in);
|
||||||
qboolean Net_CompareAddress(netadr_t *s1, netadr_t *s2, int qp1, int qp2);
|
qboolean Net_CompareAddress(netadr_t *s1, netadr_t *s2, int qp1, int qp2);
|
||||||
|
|
29
fteqtv/qw.c
29
fteqtv/qw.c
|
@ -158,6 +158,16 @@ void BuildServerData(sv_t *tv, netmsg_t *msg, int servercount, viewer_t *viewer)
|
||||||
{
|
{
|
||||||
movevars_t movevars;
|
movevars_t movevars;
|
||||||
WriteByte(msg, svc_serverdata);
|
WriteByte(msg, svc_serverdata);
|
||||||
|
if (viewer->pext1)
|
||||||
|
{
|
||||||
|
WriteLong(msg, PROTOCOL_VERSION_FTE);
|
||||||
|
WriteLong(msg, viewer->pext1);
|
||||||
|
}
|
||||||
|
if (viewer->pext2)
|
||||||
|
{
|
||||||
|
WriteLong(msg, PROTOCOL_VERSION_FTE2);
|
||||||
|
WriteLong(msg, viewer->pext2);
|
||||||
|
}
|
||||||
WriteLong(msg, PROTOCOL_VERSION);
|
WriteLong(msg, PROTOCOL_VERSION);
|
||||||
WriteLong(msg, servercount);
|
WriteLong(msg, servercount);
|
||||||
|
|
||||||
|
@ -319,6 +329,14 @@ void SendServerData(sv_t *tv, viewer_t *viewer)
|
||||||
|
|
||||||
InitNetMsg(&msg, buffer, viewer->netchan.maxreliablelen);
|
InitNetMsg(&msg, buffer, viewer->netchan.maxreliablelen);
|
||||||
|
|
||||||
|
if (tv)
|
||||||
|
{
|
||||||
|
viewer->pext1 = tv->pext1;
|
||||||
|
viewer->pext2 = tv->pext2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
viewer->pext1 = viewer->pext2 = 0;
|
||||||
|
|
||||||
if (tv && (tv->controller == viewer || !tv->controller))
|
if (tv && (tv->controller == viewer || !tv->controller))
|
||||||
viewer->thisplayer = tv->map.thisplayer;
|
viewer->thisplayer = tv->map.thisplayer;
|
||||||
else
|
else
|
||||||
|
@ -2642,7 +2660,7 @@ I've removed the following from this function as it covered the menu (~Moodles):
|
||||||
|
|
||||||
"conmenu menucallback\n"
|
"conmenu menucallback\n"
|
||||||
|
|
||||||
"menuedit 48 36 \"Óåòöåòº\" \"_server\"\n"
|
"menuedit 48 36 \"^aServer:\" \"_server\"\n"
|
||||||
|
|
||||||
"menutext 48 52 \"Demos\" DEMOS\n"
|
"menutext 48 52 \"Demos\" DEMOS\n"
|
||||||
|
|
||||||
|
@ -2672,7 +2690,8 @@ I've removed the following from this function as it covered the menu (~Moodles):
|
||||||
if (!shownheader)
|
if (!shownheader)
|
||||||
{
|
{
|
||||||
shownheader = true;
|
shownheader = true;
|
||||||
QW_StuffcmdToViewer(v, "menutext 72 %i \"Áãôéöå Çáíåóº\"\n", y);
|
|
||||||
|
QW_StuffcmdToViewer(v, "menutext 72 %i \"^aActive Games:\"\n", y);
|
||||||
y+=8;
|
y+=8;
|
||||||
}
|
}
|
||||||
QW_StuffcmdToViewer(v, "menutext 32 %i \"%30s\" \"stream %i\"\n", y, *sv->map.hostname?sv->map.hostname:sv->server, sv->streamid);
|
QW_StuffcmdToViewer(v, "menutext 32 %i \"%30s\" \"stream %i\"\n", y, *sv->map.hostname?sv->map.hostname:sv->server, sv->streamid);
|
||||||
|
@ -4041,9 +4060,9 @@ void ParseQWC(cluster_t *cluster, sv_t *qtv, viewer_t *v, netmsg_t *m)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case clc_tmove:
|
case clc_tmove:
|
||||||
v->origin[0] = ((signed short)ReadShort(m))/8.0f;
|
v->origin[0] = ReadCoord(m, v->pext1);
|
||||||
v->origin[1] = ((signed short)ReadShort(m))/8.0f;
|
v->origin[1] = ReadCoord(m, v->pext1);
|
||||||
v->origin[2] = ((signed short)ReadShort(m))/8.0f;
|
v->origin[2] = ReadCoord(m, v->pext1);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case clc_upload:
|
case clc_upload:
|
||||||
|
|
|
@ -402,8 +402,8 @@ void Cmd_Master(cmdctxt_t *ctx)
|
||||||
void Cmd_UDPPort(cmdctxt_t *ctx)
|
void Cmd_UDPPort(cmdctxt_t *ctx)
|
||||||
{
|
{
|
||||||
int newp = atoi(Cmd_Argv(ctx, 1));
|
int newp = atoi(Cmd_Argv(ctx, 1));
|
||||||
NET_InitUDPSocket(ctx->cluster, newp, true);
|
NET_InitUDPSocket(ctx->cluster, newp, SG_IPV6);
|
||||||
NET_InitUDPSocket(ctx->cluster, newp, false);
|
NET_InitUDPSocket(ctx->cluster, newp, SG_IPV4);
|
||||||
}
|
}
|
||||||
void Cmd_AdminPassword(cmdctxt_t *ctx)
|
void Cmd_AdminPassword(cmdctxt_t *ctx)
|
||||||
{
|
{
|
||||||
|
|
|
@ -473,7 +473,7 @@ static size_t JSON_ReadBody(json_t *t, char *out, size_t outsize)
|
||||||
//glTF 1.0 and 2.0 differ in that 1 uses names and 2 uses indexes. There's also some significant differences with materials.
|
//glTF 1.0 and 2.0 differ in that 1 uses names and 2 uses indexes. There's also some significant differences with materials.
|
||||||
//we only support 2.0
|
//we only support 2.0
|
||||||
|
|
||||||
//FTE does not support articulated models. we might be able to convert them to skeletal though.
|
//articulated models are handled by loading them as skeletal (should probably optimise the engine for this usecase)
|
||||||
//we don't support skeletal models either right now.
|
//we don't support skeletal models either right now.
|
||||||
|
|
||||||
//buffers are raw blobs that can come from multiple different sources
|
//buffers are raw blobs that can come from multiple different sources
|
||||||
|
@ -560,6 +560,7 @@ static void GLTF_RelativePath(const char *base, const char *relative, char *out,
|
||||||
out += t;
|
out += t;
|
||||||
outsize -= t;
|
outsize -= t;
|
||||||
|
|
||||||
|
//FIXME: uris should be percent-decoded here.
|
||||||
t = strlen(relative);
|
t = strlen(relative);
|
||||||
if (t > outsize)
|
if (t > outsize)
|
||||||
t = outsize;
|
t = outsize;
|
||||||
|
@ -611,6 +612,8 @@ static struct gltf_buffer *GLTF_GetBufferData(gltf_t *gltf, int bufferidx)
|
||||||
VFS_READ(f, out->data, length);
|
VFS_READ(f, out->data, length);
|
||||||
VFS_CLOSE(f);
|
VFS_CLOSE(f);
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
Con_Printf(CON_WARNING"%s: Unable to read buffer file %s\n", gltf->mod->name, filename);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return out->data?out:NULL;
|
return out->data?out:NULL;
|
||||||
|
@ -1891,8 +1894,10 @@ static qboolean GLTF_LoadModel(struct model_s *mod, char *json, size_t jsonsize,
|
||||||
gltf.buffers[0].length = buffersize;
|
gltf.buffers[0].length = buffersize;
|
||||||
gltf.warnlimit = 5;
|
gltf.warnlimit = 5;
|
||||||
|
|
||||||
//asset.version must exist, supposedly.
|
//asset.version must exist, supposedly. so default to something b0rked
|
||||||
gltfver = JSON_GetFloat(gltf.r, "asset.version", 2.0);
|
gltfver = JSON_GetFloat(gltf.r, "asset.minVersion", 0.0);
|
||||||
|
if (gltfver != 2.0)
|
||||||
|
gltfver = JSON_GetFloat(gltf.r, "asset.version", 0.0);
|
||||||
if (gltfver == 2.0)
|
if (gltfver == 2.0)
|
||||||
{
|
{
|
||||||
JSON_FlagAsUsed(gltf.r, "asset.copyright");
|
JSON_FlagAsUsed(gltf.r, "asset.copyright");
|
||||||
|
@ -2042,9 +2047,7 @@ static qboolean GLTF_LoadModel(struct model_s *mod, char *json, size_t jsonsize,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//TODO: make a guess at the number of frames+framerate
|
//TODO: make a guess at the framerate according to sampler intervals
|
||||||
//(input samplers have min+max values).
|
|
||||||
|
|
||||||
fg->rate = 30;
|
fg->rate = 30;
|
||||||
fg->numposes = max(1, maxtime*fg->rate);
|
fg->numposes = max(1, maxtime*fg->rate);
|
||||||
if (maxtime)
|
if (maxtime)
|
||||||
|
|
Loading…
Reference in a new issue