diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index 9133292fd..e56921b3d 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -3617,7 +3617,7 @@ void Host_Init (quakeparms_t *parms) Hunk_AllocName (0, "-HOST_HUNKLEVEL-"); host_hunklevel = Hunk_LowMark (); - R_SetRenderer(-1);//set the renderer stuff to unset... + R_SetRenderer(NULL);//set the renderer stuff to unset... host_initialized = true; @@ -3696,24 +3696,7 @@ void Host_FinishInit(void) Cmd_StuffCmds(); Cbuf_Execute (); //if the server initialisation causes a problem, give it a place to abort to - - Cvar_ApplyLatches(CVAR_RENDERERLATCH); - -//-1 means 'never set' - if (qrenderer == -1 && *vid_renderer.string) - { - Cmd_ExecuteString("vid_restart\n", RESTRICT_LOCAL); - } - if (qrenderer == -1) - { //we still failed. Try again, but use the default renderer. - Cvar_Set(&vid_renderer, ""); - Cmd_ExecuteString("vid_restart\n", RESTRICT_LOCAL); - } - if (qrenderer == -1) - Sys_Error("No renderer was set!\n"); - - if (qrenderer == QR_NONE) - Con_Printf("Use the setrenderer command to use a gui\n"); + Renderer_Start(); #ifdef VM_UI UI_Init(); diff --git a/engine/client/cl_plugin.inc b/engine/client/cl_plugin.inc index 955d34788..632a8493c 100644 --- a/engine/client/cl_plugin.inc +++ b/engine/client/cl_plugin.inc @@ -13,7 +13,7 @@ static plugin_t *protocolclientplugin; qintptr_t VARGS Plug_Menu_Control(void *offset, quintptr_t mask, const qintptr_t *arg) { - if (qrenderer <= 0) + if (qrenderer == QR_NONE) return 0; switch(VM_LONG(arg[0])) @@ -56,7 +56,7 @@ qintptr_t VARGS Plug_Key_GetKeyCode(void *offset, quintptr_t mask, const qintptr qintptr_t VARGS Plug_SCR_CenterPrint(void *offset, quintptr_t mask, const qintptr_t *arg) { - if (qrenderer <= 0) + if (qrenderer == QR_NONE) return 0; SCR_CenterPrint(0, VM_POINTER(arg[0]), true); @@ -72,7 +72,7 @@ qintptr_t VARGS Plug_Media_ShowFrameRGBA_32(void *offset, quintptr_t mask, const // int width = VM_LONG(arg[5]); // int height = VM_LONG(arg[6]); - if (qrenderer <= 0) + if (qrenderer == QR_NONE) return 0; Media_ShowFrameRGBA_32(src, srcwidth, srcheight); @@ -123,7 +123,7 @@ qintptr_t VARGS Plug_Draw_LoadImage(void *offset, quintptr_t mask, const qintptr if (pluginimagearray[i].pic) return i+1; //already loaded. - if (qrenderer > 0) + if (qrenderer != QR_NONE) { if (fromwad && Draw_SafePicFromWad) pic = Draw_SafePicFromWad(name); @@ -184,7 +184,7 @@ qintptr_t VARGS Plug_Draw_Image(void *offset, quintptr_t mask, const qintptr_t * { mpic_t *pic; int i; - if (qrenderer <= 0) + if (qrenderer == QR_NONE) return 0; if (!Draw_Image) return 0; @@ -233,7 +233,7 @@ qintptr_t VARGS Plug_Draw_Line(void *offset, quintptr_t mask, const qintptr_t *a qintptr_t VARGS Plug_Draw_Character(void *offset, quintptr_t mask, const qintptr_t *arg) { int x, y; - if (qrenderer <= 0) + if (qrenderer == QR_NONE) return 0; Font_BeginString(font_conchar, arg[0], arg[1], &x, &y); Font_DrawChar(x, y, CON_WHITEMASK | 0xe000 | (unsigned int)arg[2]); @@ -244,7 +244,7 @@ void (D3D_Draw_Fill_Colours) (int x, int y, int w, int h); qintptr_t VARGS Plug_Draw_Fill(void *offset, quintptr_t mask, const qintptr_t *arg) { float x, y, width, height; - if (qrenderer <= 0) + if (qrenderer == QR_NONE) return 0; x = VM_FLOAT(arg[0]); y = VM_FLOAT(arg[1]); @@ -315,7 +315,7 @@ qintptr_t VARGS Plug_Draw_Colour4f(void *offset, quintptr_t mask, const qintptr_ qintptr_t VARGS Plug_LocalSound(void *offset, quintptr_t mask, const qintptr_t *arg) { - if (qrenderer <= 0) + if (qrenderer == QR_NONE) return false; S_LocalSound(VM_POINTER(arg[0])); @@ -335,7 +335,7 @@ qintptr_t VARGS Plug_CL_GetStats(void *offset, quintptr_t mask, const qintptr_t if (VM_OOB(arg[1], arg[2]*4)) return 0; - if (qrenderer <= 0) + if (qrenderer == QR_NONE) return false; max = pluginstats; @@ -457,7 +457,7 @@ qintptr_t VARGS Plug_Con_SubPrint(void *offset, quintptr_t mask, const qintptr_t char *text = VM_POINTER(arg[1]); console_t *con; - if (qrenderer <= 0) + if (qrenderer == QR_NONE) return false; con = Con_FindConsole(name); @@ -481,7 +481,7 @@ qintptr_t VARGS Plug_Con_RenameSub(void *offset, quintptr_t mask, const qintptr_ { char *name = VM_POINTER(arg[0]); console_t *con; - if (qrenderer <= 0) + if (qrenderer == QR_NONE) return false; con = Con_FindConsole(name); if (!con) @@ -495,7 +495,7 @@ qintptr_t VARGS Plug_Con_IsActive(void *offset, quintptr_t mask, const qintptr_t { char *name = VM_POINTER(arg[0]); console_t *con; - if (qrenderer <= 0) + if (qrenderer == QR_NONE) return false; con = Con_FindConsole(name); if (!con) @@ -507,7 +507,7 @@ qintptr_t VARGS Plug_Con_SetActive(void *offset, quintptr_t mask, const qintptr_ { char *name = VM_POINTER(arg[0]); console_t *con; - if (qrenderer <= 0) + if (qrenderer == QR_NONE) return false; con = Con_FindConsole(name); if (!con) @@ -520,7 +520,7 @@ qintptr_t VARGS Plug_Con_Destroy(void *offset, quintptr_t mask, const qintptr_t { char *name = VM_POINTER(arg[0]); console_t *con; - if (qrenderer <= 0) + if (qrenderer == QR_NONE) return false; con = Con_FindConsole(name); if (!con) @@ -536,7 +536,7 @@ qintptr_t VARGS Plug_Con_NameForNum(void *offset, quintptr_t mask, const qintptr int buffersize = VM_LONG(arg[2]); if (VM_OOB(arg[1], arg[2]) || buffersize < 1) return false; - if (qrenderer <= 0) + if (qrenderer == QR_NONE) return false; return Con_NameForNum(num, buffer, buffersize); diff --git a/engine/client/keys.c b/engine/client/keys.c index 3b8a53dc3..5695947c9 100644 --- a/engine/client/keys.c +++ b/engine/client/keys.c @@ -416,7 +416,7 @@ vec3_t sccolor; void Con_Selectioncolour_Callback(struct cvar_s *var, char *oldvalue) { - if (qrenderer != QR_NONE && qrenderer != -1) + if (qrenderer != QR_NONE) SCR_StringToRGB(var->string, sccolor, 1); } diff --git a/engine/client/m_items.c b/engine/client/m_items.c index d70e7759c..8fefb866b 100644 --- a/engine/client/m_items.c +++ b/engine/client/m_items.c @@ -689,7 +689,7 @@ menupicture_t *MC_AddSelectablePicture(menu_t *menu, int x, int y, char *picname char selname[MAX_QPATH]; menupicture_t *n; - if (!qrenderer) + if (qrenderer == QR_NONE) return NULL; Q_strncpyz(selname, picname, sizeof(selname)); @@ -715,7 +715,7 @@ menupicture_t *MC_AddSelectablePicture(menu_t *menu, int x, int y, char *picname menupicture_t *MC_AddPicture(menu_t *menu, int x, int y, int width, int height, char *picname) { menupicture_t *n; - if (!qrenderer) + if (qrenderer == QR_NONE) return NULL; Draw_SafeCachePic(picname); @@ -741,7 +741,7 @@ menupicture_t *MC_AddCenterPicture(menu_t *menu, int y, int height, char *picnam int width; mpic_t *p; - if (!qrenderer) + if (qrenderer == QR_NONE) return NULL; p = Draw_SafeCachePic(picname); if (!p) diff --git a/engine/client/merged.h b/engine/client/merged.h index 87e2ee04f..1b7b482f9 100644 --- a/engine/client/merged.h +++ b/engine/client/merged.h @@ -71,6 +71,8 @@ extern qboolean (*Draw_IsCached) (char *picname); //can be null extern void (*Draw_Image) (float x, float y, float w, float h, float s1, float t1, float s2, float t2, mpic_t *pic); //gl-style scaled/coloured/subpic extern void (*Draw_ImageColours) (float r, float g, float b, float a); +void R2D_FillBlock(int x, int y, int w, int h); +#define Draw_FillBlock R2D_FillBlock extern void (*R_Init) (void); extern void (*R_DeInit) (void); @@ -149,7 +151,7 @@ void Draw_FunStringWidth(int x, int y, const unsigned char *str, int width); -typedef struct { +typedef struct rendererinfo_s { char *description; char *name[4]; r_qrenderer_t rtype; diff --git a/engine/client/p_script.c b/engine/client/p_script.c index e2b3d6101..40775864a 100644 --- a/engine/client/p_script.c +++ b/engine/client/p_script.c @@ -465,7 +465,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn) texnums_t tn; char *defaultshader; char *namepostfix; - if (qrenderer<=0) + if (qrenderer == QR_NONE) return; /*try and load the shader, fail if we would need to generate one*/ diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index cf7b85a19..61b55c9d5 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -441,7 +441,7 @@ void skel_dodelete(void); qboolean csqc_deprecated_warned; -#define csqc_deprecated(s) do {if (!csqc_deprecated_warned){Con_Printf("deprecated feature used: %s\n", s); csqc_deprecated_warned = true;}}while(0) +#define csqc_deprecated(s) do {if (!csqc_deprecated_warned){Con_Printf("csqc warning: %s\n", s); csqc_deprecated_warned = true;}}while(0) static model_t *CSQC_GetModelForIndex(int index); @@ -530,7 +530,7 @@ static void PF_cs_remove (progfuncs_t *prinst, struct globalvars_s *pr_globals) if (ed->isfree) { - Con_DPrintf("CSQC Tried removing free entity\n"); + csqc_deprecated("Tried removing free entity"); return; } @@ -548,12 +548,12 @@ static void PF_cvar (progfuncs_t *prinst, struct globalvars_s *pr_globals) if (!strcmp(str, "vid_conwidth")) { - csqc_deprecated("vid_conwidth cvar"); + csqc_deprecated("vid_conwidth cvar used"); G_FLOAT(OFS_RETURN) = vid.width; } else if (!strcmp(str, "vid_conheight")) { - csqc_deprecated("vid_conheight cvar"); + csqc_deprecated("vid_conheight cvar used"); G_FLOAT(OFS_RETURN) = vid.height; } else @@ -709,6 +709,10 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out) cs_getframestate(in, rflags, &out->framestate); VectorCopy(in->v->origin, out->origin); + { + extern cvar_t temp1; + out->origin[2] += temp1.value; + } if (rflags & CSQCRF_USEAXIS) { VectorCopy(csqcg.forward, out->axis[0]); @@ -786,6 +790,11 @@ static void PF_R_AddEntity(progfuncs_t *prinst, struct globalvars_s *pr_globals) { csqcedict_t *in = (void*)G_EDICT(prinst, OFS_PARM0); entity_t ent; + if (in->isfree || in->entnum == 0) + { + csqc_deprecated("Tried drawing a free/removed/world entity\n"); + return; + } if (CopyCSQCEdictToEntity(in, &ent)) V_AddAxisEntity(&ent); @@ -1413,7 +1422,7 @@ static void PF_cs_getstatf(progfuncs_t *prinst, struct globalvars_s *pr_globals) float val = cl.statsf[csqc_lplayernum][stnum]; //copy float into the stat G_FLOAT(OFS_RETURN) = val; } -static void PF_cs_getstati(progfuncs_t *prinst, struct globalvars_s *pr_globals) +static void PF_cs_getstatbits(progfuncs_t *prinst, struct globalvars_s *pr_globals) { //convert an int stat into a qc float. int stnum = G_FLOAT(OFS_PARM0); @@ -4912,13 +4921,13 @@ static struct { //330 {"getstatf", PF_cs_getstatf, 330}, // #330 float(float stnum) getstatf (EXT_CSQC) - {"getstati", PF_cs_getstati, 331}, // #331 float(float stnum) getstati (EXT_CSQC) + {"getstatbits", PF_cs_getstatbits, 331}, // #331 float(float stnum) getstatbits (EXT_CSQC) {"getstats", PF_cs_getstats, 332}, // #332 string(float firststnum) getstats (EXT_CSQC) {"setmodelindex", PF_cs_SetModelIndex, 333}, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC) {"modelnameforindex", PF_cs_ModelnameForIndex, 334}, // #334 string(float mdlindex) modelnameforindex (EXT_CSQC) {"particleeffectnum", PF_cs_particleeffectnum, 335}, // #335 float(string effectname) particleeffectnum (EXT_CSQC) - {"trailparticles", PF_cs_trailparticles, 336}, // #336 void(entity ent, float effectnum, vector start, vector end) trailparticles (EXT_CSQC), + {"trailparticles", PF_cs_trailparticles, 336}, // #336 void(float effectnum, entity ent, vector start, vector end) trailparticles (EXT_CSQC), {"pointparticles", PF_cs_pointparticles, 337}, // #337 void(float effectnum, vector origin [, vector dir, float count]) pointparticles (EXT_CSQC) {"cprint", PF_cl_cprint, 338}, // #338 void(string s) cprint (EXT_CSQC) @@ -5399,7 +5408,7 @@ qboolean CSQC_Init (unsigned int checksum) if (csqcprogs) return false; - if (!qrenderer) + if (qrenderer == QR_NONE) { return false; } @@ -5415,6 +5424,7 @@ qboolean CSQC_Init (unsigned int checksum) pr_builtin[BuiltinList[i].ebfsnum] = BuiltinList[i].bifunc; } + csqc_deprecated_warned = false; skel_reset(); memset(cl.model_csqcname, 0, sizeof(cl.model_csqcname)); memset(cl.model_csqcprecache, 0, sizeof(cl.model_csqcprecache)); diff --git a/engine/client/pr_menu.c b/engine/client/pr_menu.c index 9370c82d5..9ebd42c61 100644 --- a/engine/client/pr_menu.c +++ b/engine/client/pr_menu.c @@ -278,23 +278,10 @@ void PF_CL_drawfill (progfuncs_t *prinst, struct globalvars_s *pr_globals) float *size = G_VECTOR(OFS_PARM1); float *rgb = G_VECTOR(OFS_PARM2); float alpha = G_FLOAT(OFS_PARM3); -#ifdef GLQUAKE - if (qrenderer == QR_OPENGL) - { - qglColor4f(rgb[0], rgb[1], rgb[2], alpha); - qglDisable(GL_TEXTURE_2D); + Draw_ImageColours(rgb[0], rgb[1], rgb[2], alpha); + Draw_FillBlock(pos[0], pos[1], size[0], size[1]); - qglBegin(GL_QUADS); - qglVertex2f(pos[0], pos[1]); - qglVertex2f(pos[0]+size[0], pos[1]); - qglVertex2f(pos[0]+size[0], pos[1]+size[1]); - qglVertex2f(pos[0], pos[1]+size[1]); - qglEnd(); - - qglEnable(GL_TEXTURE_2D); - } -#endif G_FLOAT(OFS_RETURN) = 1; } //void drawsetcliparea(float x, float y, float width, float height) = #458; @@ -555,7 +542,7 @@ void PF_CL_drawrawstring (progfuncs_t *prinst, struct globalvars_s *pr_globals) Font_ForceColour(rgb[0], rgb[1], rgb[2], alpha); while(*text) { - x = Font_DrawChar(x, y, 0xe000|(*text++&0xff)); + x = Font_DrawChar(x, y, CON_WHITEMASK|0xe000|(*text++&0xff)); } Font_ForceColour(1, 1, 1, 1); Font_EndString(font_conchar); @@ -1788,7 +1775,7 @@ void VARGS Menu_Abort (char *format, ...) double menutime; void MP_Init (void) { - if (!qrenderer) + if (qrenderer == QR_NONE) { return; } diff --git a/engine/client/quakedef.h b/engine/client/quakedef.h index ba270edd1..34a17bddd 100644 --- a/engine/client/quakedef.h +++ b/engine/client/quakedef.h @@ -249,6 +249,7 @@ extern double realtime; // not bounded in any way, changed at void Host_ServerFrame (void); void Host_InitCommands (void); void Host_Init (quakeparms_t *parms); +void Host_FinishInit(void); void Host_Shutdown(void); NORETURN void VARGS Host_Error (char *error, ...) LIKEPRINTF(1); NORETURN void VARGS Host_EndGame (char *message, ...) LIKEPRINTF(1); diff --git a/engine/client/r_2d.c b/engine/client/r_2d.c index 923dce122..7834d6e5d 100644 --- a/engine/client/r_2d.c +++ b/engine/client/r_2d.c @@ -6,6 +6,7 @@ texid_t missing_texture; static mpic_t *conback; static mpic_t *draw_backtile; +static mpic_t *draw_fill, *draw_fill_trans; mpic_t *draw_disc; static mesh_t draw_mesh; @@ -82,6 +83,23 @@ void R2D_Init(void) if (!draw_backtile) draw_backtile = Draw_SafeCachePic ("gfx/menu/backtile.lmp"); + draw_fill = R_RegisterShader("fill_opaque", + "{\n" + "{\n" + "map $whiteimage\n" + "rgbgen vertex\n" + "}\n" + "}\n"); + draw_fill_trans = R_RegisterShader("fill_trans", + "{\n" + "{\n" + "map $whiteimage\n" + "rgbgen vertex\n" + "alphagen vertex\n" + "blendfunc blend\n" + "}\n" + "}\n"); + Cvar_Hook(&gl_conback, R2D_Conback_Callback); } @@ -118,6 +136,16 @@ void R2D_ImageColours(float r, float g, float b, float a) Vector4Copy(draw_mesh_colors[0], draw_mesh_colors[2]); Vector4Copy(draw_mesh_colors[0], draw_mesh_colors[3]); } +void R2D_ImagePaletteColour(unsigned int i, float a) +{ + draw_mesh_colors[0][0] = host_basepal[i*3+0]/255; + draw_mesh_colors[0][1] = host_basepal[i*3+1]/255; + draw_mesh_colors[0][2] = host_basepal[i*3+2]/255; + draw_mesh_colors[0][3] = a; + Vector4Copy(draw_mesh_colors[0], draw_mesh_colors[1]); + Vector4Copy(draw_mesh_colors[0], draw_mesh_colors[2]); + Vector4Copy(draw_mesh_colors[0], draw_mesh_colors[3]); +} //awkward and weird to use void R2D_Image(float x, float y, float w, float h, float s1, float t1, float s2, float t2, mpic_t *pic) @@ -154,6 +182,27 @@ void R2D_Image(float x, float y, float w, float h, float s1, float t1, float s2, BE_DrawMeshChain(pic, &draw_mesh, NULL, &pic->defaulttextures); } +/*draws a block of the current colour on the screen*/ +void R2D_FillBlock(int x, int y, int w, int h) +{ + draw_mesh_xyz[0][0] = x; + draw_mesh_xyz[0][1] = y; + + draw_mesh_xyz[1][0] = x+w; + draw_mesh_xyz[1][1] = y; + + draw_mesh_xyz[2][0] = x+w; + draw_mesh_xyz[2][1] = y+h; + + draw_mesh_xyz[3][0] = x; + draw_mesh_xyz[3][1] = y+h; + + if (draw_mesh_colors[0][3] != 1) + BE_DrawMeshChain(draw_fill_trans, &draw_mesh, NULL, &draw_fill_trans->defaulttextures); + else + BE_DrawMeshChain(draw_fill, &draw_mesh, NULL, &draw_fill->defaulttextures); +} + void R2D_ScalePic (int x, int y, int width, int height, mpic_t *pic) { R2D_Image(x, y, width, height, 0, 0, 1, 1, pic); diff --git a/engine/client/render.h b/engine/client/render.h index f418c9d12..b2464a9a1 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -396,7 +396,7 @@ qbyte *R_CalcVis_Q1 (void); qbyte *R_MarkLeaves_Q2 (void); qbyte *R_MarkLeaves_Q3 (void); void R_SetFrustum (float projmat[16], float viewmat[16]); -void R_SetRenderer(int wanted); +void R_SetRenderer(rendererinfo_t *ri); void R_AnimateLight (void); struct texture_s *R_TextureAnimation (struct texture_s *base); void RQ_Init(void); @@ -427,6 +427,8 @@ void SaturateR8G8B8(qbyte *data, int size, float sat); void AddOcranaLEDsIndexed (qbyte *image, int h, int w); void Renderer_Init(void); +void Renderer_Start(void); +qboolean Renderer_Started(void); void R_ShutdownRenderer(void); void R_RestartRenderer_f (void);//this goes here so we can save some stack when first initing the sw renderer. diff --git a/engine/client/renderer.c b/engine/client/renderer.c index d229b23ba..a3fb9847f 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -526,10 +526,8 @@ void R_SetRenderer_f (void); void Renderer_Init(void) { - currentrendererstate.bpp = -1; //no previous. - - currentrendererstate.renderer = -1; - qrenderer = -1; + currentrendererstate.renderer = NULL; + qrenderer = QR_NONE; Cmd_AddCommand("setrenderer", R_SetRenderer_f); Cmd_AddCommand("vid_restart", R_RestartRenderer_f); @@ -671,6 +669,33 @@ void Renderer_Init(void) RQ_Init(); } +qboolean Renderer_Started(void) +{ + return !!currentrendererstate.renderer; +} + +void Renderer_Start(void) +{ + Cvar_ApplyLatches(CVAR_RENDERERLATCH); + + //renderer = none && currentrendererstate.bpp == -1 means we've never applied any mode at all + //if we currently have none, we do actually need to apply it still + if (qrenderer == QR_NONE && *vid_renderer.string) + { + Cmd_ExecuteString("vid_restart\n", RESTRICT_LOCAL); + } + if (!currentrendererstate.renderer) + { //we still failed. Try again, but use the default renderer. + Cvar_Set(&vid_renderer, ""); + Cmd_ExecuteString("vid_restart\n", RESTRICT_LOCAL); + } + if (!currentrendererstate.renderer) + Sys_Error("No renderer was set!\n"); + + if (qrenderer == QR_NONE) + Con_Printf("Use the setrenderer command to use a gui\n"); +} + mpic_t *(*Draw_SafePicFromWad) (char *name); mpic_t *(*Draw_SafeCachePic) (char *path); @@ -692,7 +717,7 @@ void (*Draw_FadeScreen) (void); void (*Draw_BeginDisc) (void); void (*Draw_EndDisc) (void); -void (*Draw_Image) (float x, float y, float w, float h, float s1, float t1, float s2, float t2, mpic_t *pic); //gl-style scaled/coloured/subpic +void (*Draw_Image) (float x, float y, float w, float h, float s1, float t1, float s2, float t2, mpic_t *pic); //gl-style scaled/coloured/subpic void (*Draw_ImageColours) (float r, float g, float b, float a); void (*R_Init) (void); @@ -750,7 +775,7 @@ char *q_renderername = "Non-Selected renderer"; rendererinfo_t dedicatedrendererinfo = { //ALL builds need a 'none' renderer, as 0. - "Dedicated server", + "No renderer", { "none", "dedicated", @@ -1210,23 +1235,15 @@ void M_Menu_Video_f (void) menu->event = CheckCustomMode; } -void R_SetRenderer(int wanted) +void R_SetRenderer(rendererinfo_t *ri) { - rendererinfo_t *ri; - - if (wanted<0) - { //-1 is used so we know when we've applied something instead of never setting anything. - wanted=0; - qrenderer = -1; - } - else - qrenderer = rendererinfo[wanted]->rtype; - - ri = rendererinfo[wanted]; + currentrendererstate.renderer = ri; + if (!ri) + ri = &dedicatedrendererinfo; + qrenderer = ri->rtype; q_renderername = ri->name[0]; - Draw_SafePicFromWad = ri->Draw_SafePicFromWad; //Not supported Draw_SafeCachePic = ri->Draw_SafeCachePic; Draw_Init = ri->Draw_Init; @@ -1348,12 +1365,14 @@ qboolean R_ApplyRenderer (rendererstate_t *newr) { if (newr->bpp == -1) return false; + if (!newr->renderer) + return false; R_ShutdownRenderer(); - if (qrenderer == QR_NONE || qrenderer==-1) + if (qrenderer == QR_NONE) { - if (newr->renderer == QR_NONE && qrenderer != -1) + if (newr->renderer->rtype == qrenderer) return true; //no point Sys_CloseTerminal (); @@ -1377,7 +1396,7 @@ qboolean R_ApplyRenderer_Load (rendererstate_t *newr) pmove.numphysent = 0; - if (qrenderer) //graphics stuff only when not dedicated + if (qrenderer != QR_NONE) //graphics stuff only when not dedicated { qbyte *data; #ifndef CLIENTONLY @@ -1755,7 +1774,7 @@ TRACE(("dbg: R_RestartRenderer_f\n")); Q_strncpyz(newr.glrenderer, gl_driver.string, sizeof(newr.glrenderer)); - newr.renderer = -1; + newr.renderer = NULL; for (i = 0; i < sizeof(rendererinfo)/sizeof(rendererinfo[0]); i++) { if (!rendererinfo[i]->description) @@ -1766,12 +1785,12 @@ TRACE(("dbg: R_RestartRenderer_f\n")); continue; if (!stricmp(rendererinfo[i]->name[j], vid_renderer.string)) { - newr.renderer = i; + newr.renderer = rendererinfo[i]; break; } } } - if (newr.renderer == -1) + if (!newr.renderer) { Con_Printf("vid_renderer unset or invalid. Using default.\n"); //gotta do this after main hunk is saved off. @@ -1784,7 +1803,7 @@ TRACE(("dbg: R_RestartRenderer_f\n")); } // use desktop settings if set to 0 and not dedicated - if (newr.renderer != QR_NONE) + if (newr.renderer->rtype != QR_NONE) { int dbpp, dheight, dwidth, drate; @@ -1849,7 +1868,7 @@ TRACE(("dbg: R_RestartRenderer_f\n")); if (failed) { - newr.renderer = QR_NONE; + newr.renderer = &dedicatedrendererinfo; if (R_ApplyRenderer(&newr)) { TRACE(("dbg: R_RestartRenderer_f going to dedicated\n")); diff --git a/engine/client/screen.h b/engine/client/screen.h index aea799ccc..459be6c43 100644 --- a/engine/client/screen.h +++ b/engine/client/screen.h @@ -105,7 +105,7 @@ void Font_BeginString(struct font_s *font, int vx, int vy, int *px, int *py); int Font_CharHeight(void); int Font_CharWidth(unsigned int charcode); int Font_DrawChar(int px, int py, unsigned int charcode); -void Font_ForceColour(float r, float g, float b, float a); +void Font_ForceColour(float r, float g, float b, float a); //This colour will be applied while the char mask remains WHITE. If you print char by char, make sure to include the mask. void Font_EndString(struct font_s *font); int Font_LineBreaks(conchar_t *start, conchar_t *end, int maxpixelwidth, int maxlines, conchar_t **starts, conchar_t **ends); extern struct font_s *font_conchar; diff --git a/engine/client/textedit.c b/engine/client/textedit.c index 25967a393..aab80257e 100644 --- a/engine/client/textedit.c +++ b/engine/client/textedit.c @@ -985,7 +985,7 @@ int QCLibEditor(progfuncs_t *prfncs, char *filename, int line, int nump, char ** if (editormodal || !developer.ival) return line; //whoops - if (!qrenderer) + if (qrenderer == QR_NONE) { int i; char buffer[8192]; diff --git a/engine/client/vid.h b/engine/client/vid.h index b14efcb6c..65db8b22c 100644 --- a/engine/client/vid.h +++ b/engine/client/vid.h @@ -36,7 +36,7 @@ typedef struct { int rate; int multisample; //for opengl antialiasing (which requires context stuff) char glrenderer[MAX_QPATH]; - r_qrenderer_t renderer; + struct rendererinfo_s *renderer; } rendererstate_t; typedef struct vrect_s diff --git a/engine/client/zqtp.c b/engine/client/zqtp.c index 74ee83582..98ec4f0f0 100644 --- a/engine/client/zqtp.c +++ b/engine/client/zqtp.c @@ -1939,7 +1939,7 @@ static void TP_TeamColor_f (void) cl_teamtopcolor = top; cl_teambottomcolor = bottom; - if (qrenderer>QR_NONE) //make sure we have the renderer initialised... + if (qrenderer != QR_NONE) //make sure we have the renderer initialised... for (i = 0; i < MAX_CLIENTS; i++) CL_NewTranslation(i); } @@ -1980,7 +1980,7 @@ static void TP_EnemyColor_f (void) cl_enemytopcolor = top; cl_enemybottomcolor = bottom; - if (qrenderer>QR_NONE) //make sure we have the renderer initialised... + if (qrenderer != QR_NONE) //make sure we have the renderer initialised... for (i = 0; i < MAX_CLIENTS; i++) CL_NewTranslation(i); } diff --git a/engine/common/com_mesh.c b/engine/common/com_mesh.c index 7ef851642..a5e21eb55 100644 --- a/engine/common/com_mesh.c +++ b/engine/common/com_mesh.c @@ -3343,7 +3343,7 @@ qboolean Mod_LoadQ3Model(model_t *mod, void *buffer) Q_strncpyz(skin->name, shadname, sizeof(skin->name)); } - if (qrenderer) + if (qrenderer != QR_NONE) { texnum->shader = R_RegisterSkin(shadname); R_BuildDefaultTexnums(texnum, texnum->shader); diff --git a/engine/common/cvar.c b/engine/common/cvar.c index a78e5a07b..8cba6edaa 100644 --- a/engine/common/cvar.c +++ b/engine/common/cvar.c @@ -605,7 +605,7 @@ cvar_t *Cvar_SetCore (cvar_t *var, const char *value, qboolean force) latch = "variable %s is latched and will be applied for the start of the next map\n"; // else if (var->flags & CVAR_LATCHFLUSH) // latch = "variable %s is latched (type flush)\n"; - else if (var->flags & CVAR_RENDERERLATCH && qrenderer) + else if (var->flags & CVAR_RENDERERLATCH && qrenderer != QR_NONE) latch = "variable %s will be changed after a vid_restart\n"; else if (var->flags & CVAR_RULESETLATCH) latch = "variable %s is latched due to current ruleset\n"; diff --git a/engine/common/fs.c b/engine/common/fs.c index 50edd3bc8..afc7f22fa 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -1215,7 +1215,7 @@ qbyte *COM_LoadFile (const char *path, int usehunk) ((qbyte *)buf)[len] = 0; #ifndef SERVERONLY - if (qrenderer) + if (qrenderer != QR_NONE) if (Draw_BeginDisc) Draw_BeginDisc (); #endif @@ -1224,7 +1224,7 @@ qbyte *COM_LoadFile (const char *path, int usehunk) VFS_CLOSE(f); #ifndef SERVERONLY - if (qrenderer) + if (qrenderer != QR_NONE) if (Draw_EndDisc) Draw_EndDisc (); #endif @@ -1755,7 +1755,7 @@ void COM_Gamedir (const char *dir) #ifndef SERVERONLY if (!isDedicated) { -// if (qrenderer>0) //only do this if we have already started the renderer +// if (qrenderer != QR_NONE) //only do this if we have already started the renderer // Cbuf_InsertText("vid_restart\n", RESTRICT_LOCAL); diff --git a/engine/common/plugin.c b/engine/common/plugin.c index 5e16257c0..0b2598d9b 100644 --- a/engine/common/plugin.c +++ b/engine/common/plugin.c @@ -356,7 +356,7 @@ int Plug_Emumerated (const char *name, int size, void *param) qintptr_t VARGS Plug_Con_Print(void *offset, quintptr_t mask, const qintptr_t *arg) { -// if (qrenderer <= 0) +// if (qrenderer == QR_NONE) // return false; Con_Printf("%s", (char*)VM_POINTER(arg[0])); return 0; diff --git a/engine/common/sys.h b/engine/common/sys.h index 7f762ccf2..b8ac9e302 100644 --- a/engine/common/sys.h +++ b/engine/common/sys.h @@ -108,6 +108,12 @@ qboolean Sys_ConditionBroadcast(void *condv); void Sys_DestroyConditional(void *condv); #endif +#ifdef NPQTV +qboolean NPQTV_Sys_Startup(int argc, char *argv[]); +void NPQTV_Sys_MainLoop(void); +void NPQTV_Sys_Shutdown(void); +#endif + #ifdef _WIN32 int StartLocalServer(int close); #endif diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index f27b461e9..ab5558be4 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -1,4 +1,9 @@ #include "quakedef.h" + +#define STATEFIXME +#define FORCESTATE + + #ifdef GLQUAKE #include "glquake.h" @@ -426,7 +431,9 @@ struct { void GL_TexEnv(GLenum mode) { +#ifndef FORCESTATE if (mode != shaderstate.texenvmode[shaderstate.currenttmu]) +#endif { qglTexEnvi(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, mode); shaderstate.texenvmode[shaderstate.currenttmu] = mode; @@ -461,7 +468,9 @@ void GL_SelectTexture(int target) void GL_SelectVBO(int vbo) { +#ifndef FORCESTATE if (shaderstate.currentvbo != vbo) +#endif { shaderstate.currentvbo = vbo; qglBindBufferARB(GL_ARRAY_BUFFER_ARB, shaderstate.currentvbo); @@ -469,7 +478,9 @@ void GL_SelectVBO(int vbo) } void GL_SelectEBO(int vbo) { +#ifndef FORCESTATE if (shaderstate.currentebo != vbo) +#endif { shaderstate.currentebo = vbo; qglBindBufferARB(GL_ELEMENT_ARRAY_BUFFER_ARB, shaderstate.currentebo); @@ -478,7 +489,9 @@ void GL_SelectEBO(int vbo) static void GL_ApplyVertexPointer(void) { +#ifndef FORCESTATE if (shaderstate.curvertexpointer != shaderstate.pendingvertexpointer || shaderstate.pendingvertexvbo != shaderstate.curvertexvbo) +#endif { shaderstate.curvertexpointer = shaderstate.pendingvertexpointer; shaderstate.curvertexvbo = shaderstate.pendingvertexvbo; @@ -491,8 +504,10 @@ void GL_MBind(int target, texid_t texnum) { GL_SelectTexture(target); +#ifndef FORCESTATE if (shaderstate.currenttextures[shaderstate.currenttmu] == texnum.num) return; +#endif shaderstate.currenttextures[shaderstate.currenttmu] = texnum.num; bindTexFunc (GL_TEXTURE_2D, texnum.num); @@ -500,8 +515,10 @@ void GL_MBind(int target, texid_t texnum) void GL_Bind(texid_t texnum) { +#ifndef FORCESTATE if (shaderstate.currenttextures[shaderstate.currenttmu] == texnum.num) return; +#endif shaderstate.currenttextures[shaderstate.currenttmu] = texnum.num; @@ -510,8 +527,10 @@ void GL_Bind(texid_t texnum) void GL_BindType(int type, texid_t texnum) { +#ifndef FORCESTATE if (shaderstate.currenttextures[shaderstate.currenttmu] == texnum.num) return; +#endif shaderstate.currenttextures[shaderstate.currenttmu] = texnum.num; bindTexFunc (type, texnum.num); @@ -519,8 +538,10 @@ void GL_BindType(int type, texid_t texnum) void GL_CullFace(unsigned int sflags) { +#ifndef FORCESTATE if (shaderstate.curcull == sflags) return; +#endif shaderstate.curcull = sflags; if (shaderstate.curcull & SHADER_CULL_FRONT) @@ -1567,8 +1588,6 @@ static void alphagen(const shaderpass_t *pass, int cnt, const avec4_t *src, avec } } -#define DVBOMETHOD 1 - static void GenerateColourMods(const shaderpass_t *pass, const mesh_t *meshlist) { if (meshlist->colors4b_array) @@ -1686,8 +1705,13 @@ static void BE_SendPassBlendAndDepth(unsigned int sbits) delta = sbits^shaderstate.shaderbits; -#pragma message("Hack to work around the fact that other bits of code change this state") +#ifdef STATEFIXME + #pragma message("Hack to work around the fact that other bits of code change this state") delta |= SBITS_MISC_NODEPTHTEST|SBITS_MISC_DEPTHEQUALONLY; +#endif +#ifdef FORCESTATE + delta |= ~0; +#endif if (!delta) return; shaderstate.shaderbits = sbits; @@ -2165,7 +2189,9 @@ static void DrawMeshChain(const mesh_t *meshlist) shaderstate.pendingvertexvbo = shaderstate.sourcevbo->vbocoord; } +#ifndef FORCESTATE if (shaderstate.curcull != (shaderstate.curshader->flags & (SHADER_CULL_FRONT|SHADER_CULL_BACK))) +#endif { shaderstate.curcull = (shaderstate.curshader->flags & (SHADER_CULL_FRONT|SHADER_CULL_BACK)); @@ -2185,7 +2211,7 @@ static void DrawMeshChain(const mesh_t *meshlist) } } - if (shaderstate.curentity != &r_worldentity) + if (shaderstate.flags & BEF_PUSHDEPTH) { /*some quake doors etc are flush with the walls that they're meant to be hidden behind, or plats the same height as the floor, etc we move them back very slightly using polygonoffset to avoid really ugly z-fighting*/ @@ -2194,7 +2220,9 @@ static void DrawMeshChain(const mesh_t *meshlist) po.factor = shaderstate.curshader->polyoffset.factor + r_polygonoffset_submodel_factor.value; po.unit = shaderstate.curshader->polyoffset.unit + r_polygonoffset_submodel_offset.value; +#ifndef FORCESTATE if (((int*)&shaderstate.curpolyoffset)[0] != ((int*)&po)[0] || ((int*)&shaderstate.curpolyoffset)[1] != ((int*)&po)[1]) +#endif { shaderstate.curpolyoffset = po; if (shaderstate.curpolyoffset.factor || shaderstate.curpolyoffset.unit) @@ -2208,7 +2236,9 @@ static void DrawMeshChain(const mesh_t *meshlist) } else { +#ifndef FORCESTATE if (*(int*)&shaderstate.curpolyoffset != *(int*)&shaderstate.curshader->polyoffset || *(int*)&shaderstate.curpolyoffset != *(int*)&shaderstate.curshader->polyoffset) +#endif { shaderstate.curpolyoffset = shaderstate.curshader->polyoffset; if (shaderstate.curpolyoffset.factor || shaderstate.curpolyoffset.unit) @@ -2587,6 +2617,7 @@ void BE_BaseEntTextures(void) { extern model_t *currentmodel; int i; + unsigned int bef; if (!r_drawentities.ival) return; @@ -2604,6 +2635,14 @@ void BE_BaseEntTextures(void) switch(currententity->model->type) { case mod_brush: + bef = BEF_PUSHDEPTH; + if (currententity->flags & Q2RF_ADDITIVE) + bef |= BEF_FORCEADDITIVE; + else if (currententity->shaderRGBAf[3] < 1) + bef |= BEF_FORCETRANSPARENT; + if (currententity->flags & RF_NODEPTHTEST) + bef |= BEF_FORCENODEPTH; + BE_SelectMode(shaderstate.mode, bef); BaseBrushTextures(currententity); break; case mod_alias: diff --git a/engine/gl/gl_draw.c b/engine/gl/gl_draw.c index d3ca23537..47b53dc45 100644 --- a/engine/gl/gl_draw.c +++ b/engine/gl/gl_draw.c @@ -149,7 +149,9 @@ extern cvar_t scr_conalpha; texid_t translate_texture; texid_t missing_texture; //texture used when one is missing. + texid_t cs_texture; // crosshair texture +shader_t *crosshair_shader; float custom_char_instep, default_char_instep; //to avoid blending issues float char_instep; @@ -387,6 +389,15 @@ TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n")); cs_texture = GL_AllocNewTexture(); + crosshair_shader = R_RegisterShader("crosshairshader", + "{\n" + "{\n" + "map $diffuse\n" + "blendfunc blend\n" + "}\n" + "}\n" + ); + missing_texture = GL_LoadTexture("no_texture", 16, 16, (unsigned char*)r_notexture_mip + r_notexture_mip->offsets[0], IF_NOALPHA|IF_NOGAMMA, 0); GL_SetupSceneProcessingTextures(); @@ -485,6 +496,17 @@ void GLCrosshair_Callback(struct cvar_s *var, char *oldvalue) #undef Pix R_Upload(cs_texture, NULL, TF_RGBA32, cs_data, 16, 16, IF_NOMIPMAP|IF_NOGAMMA); + + if (gl_smoothcrosshair.ival) + { + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + } + else + { + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + } } void GLCrosshaircolor_Callback(struct cvar_s *var, char *oldvalue) @@ -502,9 +524,10 @@ void GLDraw_Crosshair(void) { int x, y; int sc; + float sx, sy, sizex, sizey; - float x1, x2, y1, y2; float size, chc; + shader_t *shader; qboolean usingimage = false; @@ -514,89 +537,71 @@ void GLDraw_Crosshair(void) { SCR_CrosshairPosition(sc, &x, &y); Font_BeginString(font_conchar, x, y, &x, &y); - Font_DrawChar(x-4, y-4, '+' | 0xe000 | CON_WHITEMASK); + x -= Font_CharWidth('+' | 0xe000 | CON_WHITEMASK)/2; + y -= Font_CharHeight()/2; + Font_DrawChar(x, y, '+' | 0xe000 | CON_WHITEMASK); Font_EndString(font_conchar); } return; } + shader = crosshair_shader; if (*crosshairimage.string) { usingimage = true; - GL_Bind (externalhair); chc = 0; - qglEnable (GL_BLEND); - qglDisable(GL_ALPHA_TEST); + shader->defaulttextures.base = externalhair; } else if (crosshair.ival) { - GL_Bind (cs_texture); chc = 1/16.0; // force crosshair refresh with animated crosshairs - if (crosshair.value >= FIRSTANIMATEDCROSHAIR) + if (crosshair.ival >= FIRSTANIMATEDCROSHAIR) GLCrosshair_Callback(&crosshair, ""); - if (crosshairalpha.ival<1) - { - qglEnable (GL_BLEND); - qglDisable(GL_ALPHA_TEST); - } - else - { - qglDisable (GL_BLEND); - qglEnable(GL_ALPHA_TEST); - } + shader->defaulttextures.base = cs_texture; } else return; - GL_TexEnv(GL_MODULATE); - - if (usingimage) - qglColor4f(chcolor[0], chcolor[1], chcolor[2], crosshairalpha.ival); - else - qglColor4f(1, 1, 1, crosshairalpha.value); - size = crosshairsize.value; - chc = size * chc; - if (gl_smoothcrosshair.ival && (size > 16 || usingimage)) + if (size < 0) { - qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); - qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + size = -size; + sizex = size; + sizey = size; + chc = 0; } else { - qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); - qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + sizex = (size*vid.pixelwidth) / (float)vid.width; + sizey = (size*vid.pixelheight) / (float)vid.height; + chc = size * chc; } + sizex = (int)sizex; + sizex = ((sizex)*(int)vid.width) / (float)vid.pixelwidth; + + sizey = (int)sizey; + sizey = ((sizey)*(int)vid.height) / (float)vid.pixelheight; + for (sc = 0; sc < cl.splitclients; sc++) { SCR_CrosshairPosition(sc, &x, &y); - x1 = x - size - chc; - x2 = x + size - chc; - y1 = y - size - chc; - y2 = y + size - chc; - qglBegin (GL_QUADS); - qglTexCoord2f (0, 0); - qglVertex2f (x1, y1); - qglTexCoord2f (1, 0); - qglVertex2f (x2, y1); - qglTexCoord2f (1, 1); - qglVertex2f (x2, y2); - qglTexCoord2f (0, 1); - qglVertex2f (x1, y2); - qglEnd (); + //translate to pixel coord, for rounding + x = ((x-sizex-chc)*vid.pixelwidth) / (float)vid.width; + y = ((y-sizey-chc)*vid.pixelheight) / (float)vid.height; + + //translate to screen coords + sx = ((x)*(int)vid.width) / (float)vid.pixelwidth; + sy = ((y)*(int)vid.height) / (float)vid.pixelheight; + + R2D_Image(sx, sy, sizex*2, sizey*2, 0, 0, 1, 1, shader); } - -// GL_TexEnv ( GL_REPLACE ); -// GL_TexEnv ( GL_MODULATE ); - - qglColor4f(1, 1, 1, 1); } /* @@ -860,9 +865,6 @@ void GLDraw_BeginDisc (void) { if (!draw_disc || !r_drawdisk.value) return; - qglDrawBuffer (GL_FRONT); - Draw_ScalePic(vid.width - 24, 0, 24, 24, draw_disc); - qglDrawBuffer (GL_BACK); } diff --git a/engine/gl/gl_heightmap.c b/engine/gl/gl_heightmap.c index 3b9f06c9f..8ea086f95 100644 --- a/engine/gl/gl_heightmap.c +++ b/engine/gl/gl_heightmap.c @@ -761,7 +761,7 @@ qboolean GL_LoadHeightmapModel (model_t *mod, void *buffer) mod->entities = COM_LoadHunkFile(entfile); - if (qrenderer>0) + if (qrenderer != QR_NONE) { hm->detailtexture = R_LoadHiResTexture(detailtexname, "", IF_NOGAMMA); diff --git a/engine/gl/gl_model.h b/engine/gl/gl_model.h index bfd57aa0f..4f5cc324d 100644 --- a/engine/gl/gl_model.h +++ b/engine/gl/gl_model.h @@ -752,6 +752,7 @@ typedef struct model_s char name[MAX_QPATH]; qboolean needload; // bmodels and sprites don't cache normally qboolean tainted; + qboolean pushdepth; // bsp submodels have this flag set so you don't get z fighting on co-planar surfaces. modtype_t type; fromgame_t fromgame; diff --git a/engine/gl/gl_rmain.c b/engine/gl/gl_rmain.c index 38f30f923..61c8cfc1f 100644 --- a/engine/gl/gl_rmain.c +++ b/engine/gl/gl_rmain.c @@ -2037,7 +2037,7 @@ void GLR_RenderView (void) if (qglPNTrianglesiATI) { - if (gl_ati_truform_type.value) + if (gl_ati_truform_type.ival) { //linear qglPNTrianglesiATI(GL_PN_TRIANGLES_NORMAL_MODE_ATI, GL_PN_TRIANGLES_NORMAL_MODE_LINEAR_ATI); qglPNTrianglesiATI(GL_PN_TRIANGLES_POINT_MODE_ATI, GL_PN_TRIANGLES_POINT_MODE_CUBIC_ATI); diff --git a/engine/gl/shader.h b/engine/gl/shader.h index cccfac229..8ce744f8f 100644 --- a/engine/gl/shader.h +++ b/engine/gl/shader.h @@ -386,6 +386,7 @@ typedef enum #define BEF_FORCEADDITIVE 4 //blend dest = GL_ONE #define BEF_FORCETRANSPARENT 8 //texenv replace -> modulate #define BEF_FORCENODEPTH 16 //disables any and all depth. +#define BEF_PUSHDEPTH 32 //additional polygon offset //Select the current render mode and modifier flags void BE_SelectMode(backendmode_t mode, unsigned int flags); diff --git a/engine/qclib/execloop.h b/engine/qclib/execloop.h index ad40f0e5b..365c93a49 100644 --- a/engine/qclib/execloop.h +++ b/engine/qclib/execloop.h @@ -431,7 +431,7 @@ reeval: st--; goto cont; #else - PR_RunError (progfuncs, "OP_ADDRESS references invalid entity in %s", progfuncs->stringtable + pr_xfunction->s_name); + PR_RunError (progfuncs, "OP_ADDRESS references invalid entity in %s", PR_StringToNative(progfuncs, pr_xfunction->s_name)); #endif } ed = PROG_TO_EDICT(progfuncs, OPA->edict); @@ -448,7 +448,13 @@ reeval: st--; goto cont; #else - PR_RunError (progfuncs, "assignment to read-only entity in %s", progfuncs->stringtable + pr_xfunction->s_name); + { + ddef16_t *d16; + fdef_t *f; + d16 = ED_GlobalAtOfs16(progfuncs, st->a); + f = ED_FieldAtOfs(progfuncs, OPB->_int + progfuncs->fieldadjust); + PR_RunError (progfuncs, "assignment to read-only entity in %s (%s.%s)", PR_StringToNative(progfuncs, pr_xfunction->s_name), PR_StringToNative(progfuncs, d16->s_name), f?f->name:NULL); + } #endif } diff --git a/engine/qclib/qcc_pr_comp.c b/engine/qclib/qcc_pr_comp.c index 54498a23b..dec11264e 100644 --- a/engine/qclib/qcc_pr_comp.c +++ b/engine/qclib/qcc_pr_comp.c @@ -3430,6 +3430,7 @@ QCC_def_t *QCC_PR_ParseFunctionCall (QCC_def_t *func) //warning, the func could { //t = (a/%1) / (nextent(world)/%1) //a/%1 does a (int)entity to float conversion type thing + func->initialized = 1; e = QCC_PR_Expression(TOP_PRIORITY, EXPR_DISALLOW_COMMA); QCC_PR_Expect(")"); diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index dbd1f1982..b4bd05626 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -4818,7 +4818,9 @@ char *PF_infokey_Internal (int entnum, char *key) if (!strcmp(key, "ip") || !strcmp(key, "realip")) //note: FTE doesn't support mvdsv's realip stuff, so pretend that we do if the mod asks value = strcpy(ov, NET_BaseAdrToString (adr, sizeof(adr), svs.clients[entnum-1].netchan.remote_address)); else if (!strcmp(key, "ping")) - sprintf(ov, "%d", SV_CalcPing (&svs.clients[entnum-1])); + sprintf(ov, "%d", SV_CalcPing (&svs.clients[entnum-1], false)); + else if (!strcmp(key, "svping")) + sprintf(ov, "%d", SV_CalcPing (&svs.clients[entnum-1], true)); else if (!strcmp(key, "*userid")) sprintf(ov, "%d", svs.clients[entnum-1].userid); else if (!strcmp(key, "download")) diff --git a/engine/server/server.h b/engine/server/server.h index b35295109..8936dbc26 100644 --- a/engine/server/server.h +++ b/engine/server/server.h @@ -922,7 +922,7 @@ void SV_DropClient (client_t *drop); struct quakeparms_s; void SV_Init (struct quakeparms_s *parms); -int SV_CalcPing (client_t *cl); +int SV_CalcPing (client_t *cl, qboolean forcecalc); void SV_FullClientUpdate (client_t *client, sizebuf_t *buf, unsigned int ftepext); void SV_FullClientUpdateToClient (client_t *client, client_t *cl); void SVNQ_FullClientUpdate (client_t *client, sizebuf_t *buf); diff --git a/engine/server/sv_ccmds.c b/engine/server/sv_ccmds.c index 63bca4ddb..d03328803 100644 --- a/engine/server/sv_ccmds.c +++ b/engine/server/sv_ccmds.c @@ -437,7 +437,7 @@ void SV_Map_f (void) nextserver = 0; #ifndef SERVERONLY - if (qrenderer == -1) + if (!Renderer_Started()) { Cbuf_AddText(va("wait;map %s\n", Cmd_Args()), Cmd_ExecLevel); return; @@ -1445,7 +1445,7 @@ void SV_Status_f (void) } Con_Printf ("%4i %4i %5.2f\n" , (int)(1000*cl->netchan.frame_rate) - , (int)SV_CalcPing (cl) + , (int)SV_CalcPing (cl, false) , 100.0*cl->netchan.drop_count / cl->netchan.incoming_sequence); } } @@ -1485,7 +1485,7 @@ void SV_Status_f (void) else Con_Printf ("%4i %4i %5.1f %4i" , (int)(1000*cl->netchan.frame_rate) - , (int)SV_CalcPing (cl) + , (int)SV_CalcPing (cl, false) , 100.0*cl->netchan.drop_count / cl->netchan.incoming_sequence , cl->netchan.qport); if (cl->download) diff --git a/engine/server/sv_ents.c b/engine/server/sv_ents.c index a4a46160a..9fbeb197b 100644 --- a/engine/server/sv_ents.c +++ b/engine/server/sv_ents.c @@ -300,7 +300,7 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg) csqcmsgbuffer.currentbit = 0; //Ask CSQC to write a buffer for it. G_INT(OFS_PARM0) = EDICT_TO_PROG(svprogfuncs, client->edict); - G_INT(OFS_PARM1) = 0xffffff; //psudo compatibility with SendFlags (fte doesn't support properly) + G_FLOAT(OFS_PARM1) = 0xffffff; //psudo compatibility with SendFlags (fte doesn't support properly) pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent); PR_ExecuteProgram(svprogfuncs, ent->xv->SendEntity); if (G_INT(OFS_RETURN)) //0 means not to tell the client about it. @@ -2818,3 +2818,4 @@ void SV_CleanupEnts(void) needcleanup=0; } #endif + diff --git a/engine/server/sv_init.c b/engine/server/sv_init.c index 1140eac72..d4f502c5c 100644 --- a/engine/server/sv_init.c +++ b/engine/server/sv_init.c @@ -586,11 +586,11 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us int spawnflagmask; #ifndef SERVERONLY - if (!isDedicated && (!qrenderer || qrenderer == -1)) + if (!isDedicated && qrenderer == QR_NONE) { R_RestartRenderer_f(); - if (!qrenderer || qrenderer == -1) + if (qrenderer == QR_NONE) { Sys_Error("No renderer set when map restarted\n"); return; @@ -1428,3 +1428,4 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us } #endif + diff --git a/engine/server/sv_main.c b/engine/server/sv_main.c index 8d7f29e39..d689bb5fe 100644 --- a/engine/server/sv_main.c +++ b/engine/server/sv_main.c @@ -340,7 +340,7 @@ void VARGS SV_Error (char *error, ...) } #ifdef SERVERONLY -void VARGS Host_EndGame (char *error, ...) +void VARGS Host_Error (char *error, ...) { va_list argptr; char string[1024]; @@ -734,7 +734,7 @@ SV_CalcPing =================== */ -int SV_CalcPing (client_t *cl) +int SV_CalcPing (client_t *cl, qboolean forcecalc) { float ping; int i; @@ -845,7 +845,7 @@ void SV_FullClientUpdate (client_t *client, sizebuf_t *buf, unsigned int ftepext MSG_WriteByte (buf, svc_updateping); MSG_WriteByte (buf, i); - MSG_WriteShort (buf, SV_CalcPing (client)); + MSG_WriteShort (buf, SV_CalcPing (client, false)); MSG_WriteByte (buf, svc_updatepl); MSG_WriteByte (buf, i); @@ -994,7 +994,7 @@ void SVC_Status (void) bottom = atoi(Info_ValueForKey (cl->userinfo, "bottomcolor")); top = (top < 0) ? 0 : ((top > 13) ? 13 : top); bottom = (bottom < 0) ? 0 : ((bottom > 13) ? 13 : bottom); - ping = SV_CalcPing (cl); + ping = SV_CalcPing (cl, false); name = cl->name; if (!cl->state) //show bots differently. Just to be courteous. @@ -1126,7 +1126,7 @@ void SVC_GetInfo (char *challenge, int fullstatus) "%d %d \"%s\" \"%s\"\n" , cl->old_frags, - SV_CalcPing(cl), + SV_CalcPing(cl, false), cl->team, cl->name ), sizeof(response) - (resp-response)); @@ -4369,7 +4369,7 @@ void SV_Init (quakeparms_t *parms) Cbuf_Init (); Cmd_Init (); #ifndef SERVERONLY - R_SetRenderer(QR_NONE); + R_SetRenderer(NULL); #endif COM_Init (); Mod_Init (); @@ -4479,3 +4479,4 @@ void SV_Init (quakeparms_t *parms) } #endif + diff --git a/engine/server/sv_mvd.c b/engine/server/sv_mvd.c index bb247d63d..80dd9e928 100644 --- a/engine/server/sv_mvd.c +++ b/engine/server/sv_mvd.c @@ -766,7 +766,7 @@ void SV_MVDPings (void) MVDWrite_Begin (dem_all, 0, 7); MSG_WriteByte((sizebuf_t*)demo.dbuf, svc_updateping); MSG_WriteByte((sizebuf_t*)demo.dbuf, j); - MSG_WriteShort((sizebuf_t*)demo.dbuf, SV_CalcPing(client)); + MSG_WriteShort((sizebuf_t*)demo.dbuf, SV_CalcPing(client, false)); MSG_WriteByte((sizebuf_t*)demo.dbuf, svc_updatepl); MSG_WriteByte ((sizebuf_t*)demo.dbuf, j); MSG_WriteByte ((sizebuf_t*)demo.dbuf, client->lossage); @@ -1847,7 +1847,7 @@ void SV_MVD_SendInitialGamestate(mvddest_t *dest) MSG_WriteByte (&buf, svc_updateping); MSG_WriteByte (&buf, i); - MSG_WriteShort (&buf, SV_CalcPing(player)); + MSG_WriteShort (&buf, SV_CalcPing(player, false)); MSG_WriteByte (&buf, svc_updatepl); MSG_WriteByte (&buf, i); diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index 1705d7679..715eadc19 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -2801,7 +2801,7 @@ void SV_Pings_f (void) ClientReliableWrite_SZ(host_client, "pingplreport", 12); for (j = 0, client = svs.clients; j < MAX_CLIENTS; j++, client++) { - s = va(" %i %i", SV_CalcPing(client), client->lossage); + s = va(" %i %i", SV_CalcPing(client, false), client->lossage); ClientReliableWrite_SZ(host_client, s, strlen(s)); } ClientReliableWrite_Byte (host_client, '\n'); @@ -2817,7 +2817,7 @@ void SV_Pings_f (void) ClientReliableWrite_Begin (host_client, svc_updateping, 4); ClientReliableWrite_Byte (host_client, j); - ClientReliableWrite_Short (host_client, SV_CalcPing(client)); + ClientReliableWrite_Short (host_client, SV_CalcPing(client, false)); ClientReliableWrite_Begin (host_client, svc_updatepl, 4); ClientReliableWrite_Byte (host_client, j); ClientReliableWrite_Byte (host_client, client->lossage); @@ -3857,7 +3857,7 @@ void Cmd_FPSList_f(void) } if (frames) - SV_ClientPrintf(host_client, PRINT_HIGH, "%s: %ffps (min%f max %f), in: %fbps, out: %fbps\n", cl->name, ftime/frames, minf, maxf, (1000.0f*inbytes)/msecs, (1000.0f*outbytes)/msecs); + SV_ClientPrintf(host_client, PRINT_HIGH, "%s: %ffps (min%.2f max %.2f), in: %.2fbps, out: %.2fbps\n", cl->name, ftime/frames, minf, maxf, (1000.0f*inbytes)/msecs, (1000.0f*outbytes)/msecs); else SV_ClientPrintf(host_client, PRINT_HIGH, "%s: no information available\n", cl->name); } @@ -4478,7 +4478,7 @@ void SVNQ_Ping_f(void) if (!cl->state) continue; - SV_PrintToClient(host_client, PRINT_HIGH, va("%3i %s\n", SV_CalcPing (cl), cl->name)); + SV_PrintToClient(host_client, PRINT_HIGH, va("%3i %s\n", SV_CalcPing (cl, false), cl->name)); } } @@ -5075,7 +5075,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse) V_CalcRoll (sv_player->v->angles, sv_player->v->velocity)*4; } - if (SV_PlayerPhysicsQC) + if (SV_PlayerPhysicsQC && !host_client->spectator) { //csqc independant physics support pr_global_struct->frametime = host_frametime; pr_global_struct->time = sv.time; @@ -5745,7 +5745,7 @@ haveannothergo: } SV_RunCmd (&newcmd, false); - if (!SV_PlayerPhysicsQC) + if (!SV_PlayerPhysicsQC || host_client->spectator) SV_PostRunCmd(); } @@ -6536,7 +6536,7 @@ void SV_ClientThink (void) sv_player->xv->movement[2] = cmd.upmove; } - if (SV_PlayerPhysicsQC) + if (SV_PlayerPhysicsQC && !host_client->spectator) { pr_global_struct->time = sv.world.physicstime; pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);