setrenderer headless;vid_restart does not mess with vid_renderer cvar at all now.

add the particle debugging commands to release builds too. probably should only be the particles one and not the trails one, but whatever.
try to do something about black screens on android etc by sys_erroring if we get glsl compile errors on the default2d glsl when there's no fixed function available. this is enough to ensure that the console text+background is always visible, or they know(ish) why its not.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4660 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2014-05-17 15:25:02 +00:00
parent c0f8c28e2c
commit 7cfaa1a6ef
6 changed files with 107 additions and 82 deletions

View File

@ -4662,30 +4662,34 @@ void CL_LinkViewModel(void)
if (!CLHL_AnimateViewEntity(&ent))
#endif
{
ent.framestate.g[FS_REG].frame[0] = pv->stats[STAT_WEAPONFRAME];
ent.framestate.g[FS_REG].frame[1] = pv->oldframe;
if (ent.framestate.g[FS_REG].frame[0] != pv->prevframe)
//if the model changed, reset everything.
if (ent.model != pv->vm.oldmodel)
{
pv->oldframe = ent.framestate.g[FS_REG].frame[1] = pv->prevframe;
pv->frameduration = (realtime - pv->lerptime);
if (pv->frameduration < 0.01)//no faster than 100 times a second... to avoid divide by zero
pv->frameduration = 0.01;
if (pv->frameduration > 0.2) //no slower than 5 times a second
pv->frameduration = 0.2;
pv->lerptime = realtime;
pv->vm.oldmodel = ent.model;
pv->vm.oldframe = pv->vm.prevframe = pv->stats[STAT_WEAPONFRAME];
pv->vm.oldlerptime = pv->vm.lerptime = realtime;
pv->vm.frameduration = 0.1;
}
pv->prevframe = ent.framestate.g[FS_REG].frame[0];
if (ent.model != pv->oldmodel)
//if the frame changed, update the oldframe to lerp into the new frame
else if (pv->stats[STAT_WEAPONFRAME] != pv->vm.prevframe)
{
pv->oldmodel = ent.model;
pv->oldframe = ent.framestate.g[FS_REG].frame[1] = ent.framestate.g[FS_REG].frame[0];
pv->frameduration = 0.1;
pv->lerptime = realtime;
pv->vm.oldframe = pv->vm.prevframe;
pv->vm.prevframe = pv->stats[STAT_WEAPONFRAME];
pv->vm.oldlerptime = pv->vm.lerptime;
pv->vm.frameduration = (realtime - pv->vm.lerptime);
if (pv->vm.frameduration < 0.01)//no faster than 100 times a second... to avoid divide by zero
pv->vm.frameduration = 0.01;
if (pv->vm.frameduration > 0.2) //no slower than 5 times a second
pv->vm.frameduration = 0.2;
pv->vm.lerptime = realtime;
}
ent.framestate.g[FS_REG].lerpfrac = 1-(realtime-pv->lerptime)/pv->frameduration;
//work out the blend fraction
ent.framestate.g[FS_REG].frame[0] = pv->vm.prevframe;
ent.framestate.g[FS_REG].frame[1] = pv->vm.oldframe;
ent.framestate.g[FS_REG].frametime[0] = realtime - pv->vm.lerptime;
ent.framestate.g[FS_REG].frametime[1] = realtime - pv->vm.oldlerptime;
ent.framestate.g[FS_REG].lerpfrac = 1-(realtime-pv->vm.lerptime)/pv->vm.frameduration;
ent.framestate.g[FS_REG].lerpfrac = bound(0, ent.framestate.g[FS_REG].lerpfrac, 1);
}

View File

@ -576,11 +576,15 @@ struct playerview_s
vec3_t vw_axis[3]; //weapons should be positioned relative to this
vec3_t vw_origin; //weapons should be positioned relative to this
// entity_t viewent; // is this not utterly redundant yet?
struct model_s *oldmodel;
float lerptime;
float frameduration;
int prevframe;
int oldframe;
struct
{
struct model_s *oldmodel;
float lerptime;
float oldlerptime;
float frameduration;
int prevframe;
int oldframe;
} vm;
};
//

View File

@ -2137,7 +2137,7 @@ static void P_ExportAllEffects_f(void)
Con_Printf("Written %s\n", effect);
}
#if _DEBUG
#if 1//_DEBUG
// R_BeamInfo_f - debug junk
static void P_BeamInfo_f (void)
{
@ -2694,10 +2694,10 @@ static qboolean PScript_InitParticles (void)
Cmd_AddCommand("r_importeffectinfo", P_ImportEffectInfo_f);
Cmd_AddCommand("r_exportalleffects", P_ExportAllEffects_f);
#if _DEBUG
//#if _DEBUG
Cmd_AddCommand("r_partinfo", P_PartInfo_f);
Cmd_AddCommand("r_beaminfo", P_BeamInfo_f);
#endif
//#endif
pt_pointfile = P_AllocateParticleType("", "PT_POINTFILE");

View File

@ -1420,21 +1420,35 @@ qboolean R_BuildRenderstate(rendererstate_t *newr, char *rendererstring)
newr->renderer = NULL;
rendererstring = COM_Parse(rendererstring);
for (i = 0; i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++)
if (!*com_token)
{
if (!rendererinfo[i]->description)
continue; //not valid in this build. :(
for (j = 4-1; j >= 0; j--)
for (i = 0; i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++)
{
if (!rendererinfo[i]->name[j])
continue;
if (!stricmp(rendererinfo[i]->name[j], com_token))
if (rendererinfo[i]->name[0] && stricmp(rendererinfo[i]->name[0], "none"))
{
newr->renderer = rendererinfo[i];
break;
}
}
}
else
{
for (i = 0; i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++)
{
if (!rendererinfo[i]->description)
continue; //not valid in this build. :(
for (j = 4-1; j >= 0; j--)
{
if (!rendererinfo[i]->name[j])
continue;
if (!stricmp(rendererinfo[i]->name[j], com_token))
{
newr->renderer = rendererinfo[i];
break;
}
}
}
}
rendererstring = COM_Parse(rendererstring);
if (*com_token)
@ -1488,48 +1502,22 @@ qboolean R_BuildRenderstate(rendererstate_t *newr, char *rendererstring)
return newr->renderer != NULL;
}
void R_RestartRenderer_f (void)
void R_RestartRenderer (rendererstate_t *newr)
{
rendererstate_t oldr;
rendererstate_t newr;
if (r_blockvidrestart)
{
Con_Printf("Ignoring vid_restart from config\n");
return;
}
memset(&newr, 0, sizeof(newr));
TRACE(("dbg: R_RestartRenderer_f\n"));
Cvar_ApplyLatches(CVAR_RENDERERLATCH);
if (!R_BuildRenderstate(&newr, vid_renderer.string))
{
int i;
if (*vid_renderer.string)
Con_Printf("vid_renderer \"%s\" unsupported. Using default.\n", vid_renderer.string);
else
Con_DPrintf("vid_renderer unset. Using default.\n");
//gotta do this after main hunk is saved off.
for (i = 0; i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++)
{
if (rendererinfo[i]->name[0] && stricmp(rendererinfo[i]->name[0], "none"))
{
Cmd_ExecuteString(va("setrenderer %s\n", rendererinfo[i]->name[0]), RESTRICT_LOCAL);
break;
}
}
return;
}
M_Shutdown(false);
Media_CaptureDemoEnd();
TRACE(("dbg: R_RestartRenderer_f renderer %i\n", newr.renderer));
memcpy(&oldr, &currentrendererstate, sizeof(rendererstate_t));
if (!R_ApplyRenderer(&newr))
if (!R_ApplyRenderer(newr))
{
TRACE(("dbg: R_RestartRenderer_f failed\n"));
if (R_ApplyRenderer(&oldr))
@ -1541,36 +1529,36 @@ TRACE(("dbg: R_RestartRenderer_f\n"));
{
int i;
qboolean failed = true;
rendererinfo_t *skip = newr.renderer;
rendererinfo_t *skip = newr->renderer;
if (newr.rate != 0)
if (newr->rate != 0)
{
Con_Printf(CON_NOTICE "Trying default refresh rate\n");
newr.rate = 0;
failed = !R_ApplyRenderer(&newr);
newr->rate = 0;
failed = !R_ApplyRenderer(newr);
}
if (failed && newr.width != DEFAULT_WIDTH && newr.height != DEFAULT_HEIGHT)
if (failed && newr->width != DEFAULT_WIDTH && newr->height != DEFAULT_HEIGHT)
{
Con_Printf(CON_NOTICE "Trying %i*%i\n", DEFAULT_WIDTH, DEFAULT_HEIGHT);
newr.width = DEFAULT_WIDTH;
newr.height = DEFAULT_HEIGHT;
failed = !R_ApplyRenderer(&newr);
newr->width = DEFAULT_WIDTH;
newr->height = DEFAULT_HEIGHT;
failed = !R_ApplyRenderer(newr);
}
for (i = 0; failed && i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++)
{
newr.renderer = rendererinfo[i];
if (newr.renderer && newr.renderer != skip)
newr->renderer = rendererinfo[i];
if (newr->renderer && newr->renderer != skip)
{
Con_Printf(CON_NOTICE "Trying %s\n", newr.renderer->description);
failed = !R_ApplyRenderer(&newr);
Con_Printf(CON_NOTICE "Trying %s\n", newr->renderer->description);
failed = !R_ApplyRenderer(newr);
}
}
//if we ended up resorting to our last choice (dedicated) then print some informative message about it
//fixme: on unixy systems, we should make sure we're actually printing to something (ie: that we're not running via some x11 shortcut with our stdout redirected to /dev/nul
if (!failed && newr.renderer == &dedicatedrendererinfo)
if (!failed && newr->renderer == &dedicatedrendererinfo)
{
Con_Printf(CON_ERROR "Video mode switch failed. Console forced.\n\nPlease change the following vars to something useable, and then use the setrenderer command.\n");
Con_Printf("%s: %s\n", vid_width.name, vid_width.string);
@ -1593,6 +1581,23 @@ TRACE(("dbg: R_RestartRenderer_f\n"));
M_Reinit();
}
void R_RestartRenderer_f (void)
{
rendererstate_t newr;
Cvar_ApplyLatches(CVAR_RENDERERLATCH);
if (!R_BuildRenderstate(&newr, vid_renderer.string))
{
Con_Printf("vid_renderer \"%s\" unsupported. Using default.\n", vid_renderer.string);
//gotta do this after main hunk is saved off.
Cmd_ExecuteString("setrenderer \"\"\n", RESTRICT_LOCAL);
return;
}
R_RestartRenderer(&newr);
}
void R_SetRenderer_f (void)
{
int i;
@ -1621,10 +1626,11 @@ void R_SetRenderer_f (void)
Cvar_Set(&vid_bpp, Cmd_Argv(2));
}
Cvar_Set(&vid_renderer, param);
if (newr.renderer->rtype != QR_HEADLESS) //don't save headless in the vid_renderer cvar via the setrenderer command. 'setrenderer headless;vid_restart' can then do what is most sane.
Cvar_Set(&vid_renderer, param);
if (!r_blockvidrestart)
R_RestartRenderer_f();
R_RestartRenderer(&newr);
}

View File

@ -75,6 +75,7 @@ static void Headless_R_PreNewMap (void)
//tray icon crap, so the user can still restore the game.
LRESULT CALLBACK HeadlessWndProc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lparam)
{
extern cvar_t vid_renderer;
switch(msg)
{
case WM_USER:
@ -83,7 +84,10 @@ LRESULT CALLBACK HeadlessWndProc(HWND wnd, UINT msg, WPARAM wparam, LPARAM lpara
case WM_CONTEXTMENU:
case WM_USER+0:
case WM_RBUTTONUP:
Cbuf_AddText("vid_renderer \"\";vid_restart\n", RESTRICT_LOCAL);
if (!Q_strcasecmp(vid_renderer.string, "headless"))
Cbuf_AddText("vid_renderer \"\";vid_restart\n", RESTRICT_LOCAL);
else
Cbuf_AddText("vid_restart\n", RESTRICT_LOCAL);
break;
default:
break;

View File

@ -1530,6 +1530,7 @@ static GLhandleARB GLSlang_FinishShader(GLhandleARB shader, const char *name, GL
qglGetShaderParameteriv_(shader, GL_OBJECT_COMPILE_STATUS_ARB, &compiled);
if(!compiled)
{
char *typedesc;
char str[8192];
qglGetShaderInfoLog_(shader, sizeof(str), NULL, str);
@ -1538,15 +1539,21 @@ static GLhandleARB GLSlang_FinishShader(GLhandleARB shader, const char *name, GL
switch (shadertype)
{
case GL_FRAGMENT_SHADER_ARB:
Con_Printf("Fragment shader (%s) compilation error:\n----------\n%s----------\n", name, str);
typedesc = "Fragment";
break;
case GL_VERTEX_SHADER_ARB:
Con_Printf("Vertex shader (%s) compilation error:\n----------\n%s----------\n", name, str);
typedesc = "Vertex";
break;
default:
Con_Printf("Shader_CreateShader: This shouldn't happen ever\n");
typedesc = "???";
break;
}
Con_Printf("%s shader (%s) compilation error:\n----------\n%s----------\n", typedesc, name, str);
//if there's no fixed function then failure to compile the default2d shader should be considered fatal. this should help avoid black screens on android.
if (gl_config.nofixedfunc && !strcmp(name, "default2d"))
Sys_Error("%s shader (%s) compilation error:\n----------\n%s----------\n", typedesc, name, str);
if (developer.ival)
{
qglGetShaderSource(shader, sizeof(str), NULL, str);