diff --git a/engine/Makefile b/engine/Makefile index 1bb9cc081..686aa0348 100644 --- a/engine/Makefile +++ b/engine/Makefile @@ -805,7 +805,7 @@ ifeq (win_SDL,$(findstring win,$(FTE_TARGET))$(findstring _SDL,$(FTE_TARGET))) SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(WINDOWSSERVERONLY_OBJS) $(BOTLIB_OBJS) $(LTO_END) resources.o $(LTO_START) SV_EXE_NAME=../fteqw_sdl_sv$(BITS)$(EXEPOSTFIX) SV_CFLAGS=$(SERVER_ONLY_CFLAGS) -DFTE_SDL - SV_LDFLAGS=$(MINGW_LIBS_DIR)/libz.a -lm -lmingw32 -lws2_32 -lwinmm + SV_LDFLAGS=$(MINGW_LIBS_DIR)/libz.a -lm -lmingw32 -lws2_32 -lwinmm `$(SDLCONFIG) --libs` MINGL_DIR=mingl_sdlwin$(BITS) MINGL_EXE_NAME=../fteqw_sdl_mingl$(BITS)$(EXEPOSTFIX) @@ -1139,15 +1139,15 @@ endif ifeq ($(FTE_TARGET),droid) BASELDFLAGS= + SV_CFLAGS= + SV_LDFLAGS= SV_DIR=sv_droid-$(DROID_ARCH) - SV_LDFLAGS=-lz SV_OBJS=$(COMMON_OBJS) $(SERVER_OBJS) $(PROGS_OBJS) $(BOTLIB_OBJS) svmodel.o sys_droid.o SV_EXE_NAME=libftedroid.so - SV_LDFLAGS= - - GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) gl_viddroid.o sys_droid.o cd_null.o snd_droid.o + GL_CFLAGS=$(GLCFLAGS) GL_LDFLAGS=$(GLLDFLAGS) + GLCL_OBJS=$(GL_OBJS) $(D3DGL_OBJS) $(GLQUAKE_OBJS) $(BOTLIB_OBJS) gl_viddroid.o sys_droid.o cd_null.o snd_droid.o GLB_DIR=gl_droid-$(DROID_ARCH) GL_EXE_NAME=libftedroid.so endif diff --git a/engine/client/cl_cg.c b/engine/client/cl_cg.c index dd7231af4..7d7f8eb42 100644 --- a/engine/client/cl_cg.c +++ b/engine/client/cl_cg.c @@ -349,6 +349,7 @@ qboolean CGQ3_GetUserCmd(int cmdNumber, q3usercmd_t *ucmd) static vm_t *cgvm; extern int keycatcher; +char bigconfigstring[65536]; qboolean CG_GetServerCommand(int cmdnum) { @@ -361,6 +362,23 @@ qboolean CG_GetServerCommand(int cmdnum) Con_DPrintf("Dispaching %s\n", str); Cmd_TokenizeString(str, false, false); + if (!strcmp(Cmd_Argv(0), "bcs0")) + { + Q_snprintfz(bigconfigstring, sizeof(bigconfigstring), "cs %s \"%s", Cmd_Argv(1), Cmd_Argv(2)); + return false; + } + if (!strcmp(Cmd_Argv(0), "bcs1")) + { + Q_strncatz(bigconfigstring, Cmd_Argv(2), sizeof(bigconfigstring)); + return false; + } + if (!strcmp(Cmd_Argv(0), "bcs2")) + { + Q_strncatz(bigconfigstring, Cmd_Argv(2), sizeof(bigconfigstring)); + Q_strncatz(bigconfigstring, "\"", sizeof(bigconfigstring)); + Cmd_TokenizeString(bigconfigstring, false, false); + } + if (!strcmp(Cmd_Argv(0), "cs")) CG_InsertIntoGameState(atoi(Cmd_Argv(1)), Cmd_Argv(2)); return true; @@ -548,6 +566,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con VM_LONG(ret) = VM_FRead(VM_POINTER(arg[0]), VM_LONG(arg[1]), VM_LONG(arg[2]), 1); break; case CG_FS_WRITE: //fwrite + Con_DPrintf("CG_FS_WRITE: not implemented\n"); break; case CG_FS_FCLOSEFILE: //fclose VM_fclose(VM_LONG(arg[0]), 1); @@ -703,6 +722,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con break; case CG_R_LOADWORLDMAP: //FTE can't distinguish. :/ + Con_DPrintf("CG_R_LOADWORLDMAP: not implemented\n"); break; //So long as noone has one collision model with a different rendering one, we'll be fine case CG_CM_LOADMAP: @@ -839,8 +859,16 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con break; case CG_S_ADDLOOPINGSOUND: + //entnum, origin, velocity, sfx +// Con_DPrintf("CG_S_ADDLOOPINGSOUND: not implemented\n"); + break; + case CG_S_ADDREALLOOPINGSOUND: + //entnum, origin, velocity, sfx +// Con_DPrintf("CG_S_ADDREALLOOPINGSOUND: not implemented\n"); break; case CG_S_STOPLOOPINGSOUND: + //entnum +// Con_DPrintf("CG_S_STOPLOOPINGSOUND: not implemented\n"); break; case CG_S_STARTBACKGROUNDTRACK: @@ -850,9 +878,13 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con Media_BackgroundTrack(NULL, NULL); return 0; case CG_S_CLEARLOOPINGSOUNDS: + //clearall + Con_DPrintf("CG_S_CLEARLOOPINGSOUNDS: not implemented\n"); break; case CG_S_UPDATEENTITYPOSITION://void trap_S_UpdateEntityPosition( int entityNum, const vec3_t origin ); + //entnum, org +// Con_DPrintf("CG_S_UPDATEENTITYPOSITION: not implemented\n"); break; case CG_S_RESPATIALIZE://void trap_S_Respatialize( int entityNum, const vec3_t origin, vec3_t axis[3], int inwater ); { @@ -870,9 +902,6 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con } break; - case CG_S_ADDREALLOOPINGSOUND: - break; - case CG_KEY_ISDOWN: { extern qboolean keydown[256]; @@ -986,6 +1015,7 @@ static qintptr_t CG_SystemCalls(void *offset, quintptr_t mask, qintptr_t fn, con break; case CG_PC_READ_TOKEN: //fixme: memory protect. + VALIDATEPOINTER(arg[1], sizeof(struct pc_token_s)); return Script_Read(arg[0], VM_POINTER(arg[1])); // standard Q3 diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 9a339ecc3..37122ac49 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -1942,10 +1942,10 @@ void CL_ParseDownload (void) } if (size == -3) { - char *localname; + char *requestedname; Q_strncpyz(name, MSG_ReadString(), sizeof(name)); - localname = MSG_ReadString(); - Con_DPrintf("Download for %s redirected to %s\n", localname, name); + requestedname = MSG_ReadString(); + Con_DPrintf("Download for %s redirected to %s\n", requestedname, name); /*quakeforge http download redirection*/ if (cls.downloadqw) { diff --git a/engine/client/cl_screen.c b/engine/client/cl_screen.c index f300f1072..5661292d9 100644 --- a/engine/client/cl_screen.c +++ b/engine/client/cl_screen.c @@ -1650,7 +1650,7 @@ void SCR_SetUpToDrawConsole (void) Key_Dest_Add(kdm_console); scr_conlines = scr_con_current = vid.height * fullscreenpercent; } - else if ((!Key_Dest_Has(~(kdm_console|kdm_game))) && SCR_GetLoadingStage() == LS_NONE && cls.state < ca_active && !Media_PlayingFullScreen() && !CSQC_UnconnectedOkay(false)) + else if (!Key_Dest_Has(kdm_menu) && (!Key_Dest_Has(~(kdm_console|kdm_game))) && SCR_GetLoadingStage() == LS_NONE && cls.state < ca_active && !Media_PlayingFullScreen() && !CSQC_UnconnectedOkay(false)) { //go fullscreen if we're not doing anything #ifdef VM_UI diff --git a/engine/client/cl_ui.c b/engine/client/cl_ui.c index db13410c6..3a68f3512 100644 --- a/engine/client/cl_ui.c +++ b/engine/client/cl_ui.c @@ -407,6 +407,8 @@ void VQ3_AddEntity(const q3refEntity_t *q3) if (q3->customSkin) ent.skinnum = Mod_SkinNumForName(ent.model, VM_FROMSTRCACHE(q3->customSkin)); + else + ent.skinnum = q3->skinNum; ent.shaderRGBAf[0] = q3->shaderRGBA[0]/255.0f; ent.shaderRGBAf[1] = q3->shaderRGBA[1]/255.0f; diff --git a/engine/client/r_surf.c b/engine/client/r_surf.c index 327a0de4f..aa61ce345 100644 --- a/engine/client/r_surf.c +++ b/engine/client/r_surf.c @@ -2430,6 +2430,7 @@ void Surf_DeInit(void) numlightmaps=0; Alias_Shutdown(); + Shader_ResetRemaps(); } void Surf_Clear(model_t *mod) diff --git a/engine/client/renderer.c b/engine/client/renderer.c index 487d6df2c..fa3c43b6c 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -333,6 +333,8 @@ cvar_t gl_texturemode2d = CVARFC("gl_texturemode2d", "GL_LINEAR", cvar_t vid_triplebuffer = CVARAFD ("vid_triplebuffer", "1", "gl_triplebuffer", CVAR_ARCHIVE, "Specifies whether the hardware is forcing tripplebuffering on us, this is the number of extra page swaps required before old data has been completely overwritten."); cvar_t r_portalrecursion = CVARD ("r_portalrecursion", "1", "The number of portals the camera is allowed to recurse through."); +cvar_t r_portaldrawplanes = CVARD ("r_portaldrawplanes", "0", "Draw front and back planes in portals. Debug feature."); +cvar_t r_portalonly = CVARD ("r_portalonly", "0", "Don't draw things which are not portals. Debug feature."); cvar_t dpcompat_psa_ungroup = SCVAR ("dpcompat_psa_ungroup", "0"); cvar_t r_noaliasshadows = SCVARF ("r_noaliasshadows", "0", CVAR_ARCHIVE); cvar_t r_shadows = CVARFD ("r_shadows", "0", CVAR_ARCHIVE, "Draw basic blob shadows underneath entities without using realtime lighting."); @@ -406,6 +408,8 @@ void GLRenderer_Init(void) Cvar_Register (&r_lerpmuzzlehack, GLRENDEREROPTIONS); Cvar_Register (&r_noframegrouplerp, GLRENDEREROPTIONS); Cvar_Register (&r_portalrecursion, GLRENDEREROPTIONS); + Cvar_Register (&r_portaldrawplanes, GLRENDEREROPTIONS); + Cvar_Register (&r_portalonly, GLRENDEREROPTIONS); Cvar_Register (&r_noaliasshadows, GLRENDEREROPTIONS); Cvar_Register (&gl_maxshadowlights, GLRENDEREROPTIONS); Cvar_Register (&r_shadow_bumpscale_basetexture, GLRENDEREROPTIONS); diff --git a/engine/common/common.c b/engine/common/common.c index ca6197dab..cc4037ca0 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -1436,7 +1436,7 @@ float MSG_ReadFloat (void) char *MSG_ReadString (void) { - static char string[2048]; + static char string[8192]; int l,c; l = 0; diff --git a/engine/common/common.h b/engine/common/common.h index 8dc79c674..b496942fb 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -261,7 +261,7 @@ void deleetstring(char *result, char *leet); //============================================================================ -extern char com_token[1024]; +extern char com_token[65536]; typedef enum {TTP_UNKNOWN, TTP_STRING, TTP_LINEENDING} com_tokentype_t; extern com_tokentype_t com_tokentype; diff --git a/engine/common/q1bsp.c b/engine/common/q1bsp.c index 99b22e016..1e29f8c1b 100644 --- a/engine/common/q1bsp.c +++ b/engine/common/q1bsp.c @@ -386,7 +386,7 @@ struct traceinfo_s vec3_t end; }; -#if 0 +#if 1 #include "shader.h" void BE_GenPolyBatches(batch_t **batches); void TestDrawPlane(float *normal, float dist, float r, float g, float b, qboolean enqueue) diff --git a/engine/common/q3common.c b/engine/common/q3common.c index e6a29b634..bf90a2735 100644 --- a/engine/common/q3common.c +++ b/engine/common/q3common.c @@ -766,7 +766,7 @@ void Netchan_TransmitQ3( netchan_t *chan, int length, const qbyte *data ) Netchan_TransmitNextFragment( chan ); if( chan->reliable_length ) { - Con_Printf( "%s: unsent fragments\n", NET_AdrToString( adr, sizeof(adr), &chan->remote_address ) ); + Con_DPrintf( "%s: unsent fragments\n", NET_AdrToString( adr, sizeof(adr), &chan->remote_address ) ); return; } /*drop the outgoing packet if we fragmented*/ diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index 9d73edb0f..cfc2ce762 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -58,7 +58,7 @@ static const char LIGHTPASS_SHADER[] = "\ }\n\ }"; -extern cvar_t r_glsl_offsetmapping, r_portalrecursion; +extern cvar_t r_glsl_offsetmapping, r_portalrecursion, r_portalonly; static void BE_SendPassBlendDepthMask(unsigned int sbits); void GLBE_SubmitBatch(batch_t *batch); @@ -1583,7 +1583,7 @@ static void tcmod(const tcmod_t *tcmod, int cnt, const float *src, float *dst, c t1 = src[0]; t2 = src[1]; dst[0] = t1 * tcmod->args[0] + t2 * tcmod->args[2] + tcmod->args[4]; - dst[1] = t2 * tcmod->args[1] + t1 * tcmod->args[3] + tcmod->args[5]; + dst[1] = t1 * tcmod->args[1] + t2 * tcmod->args[3] + tcmod->args[5]; } break; @@ -4374,8 +4374,13 @@ void GLBE_SubmitMeshes (qboolean drawworld, int start, int stop) if (drawworld) { if (i == SHADER_SORT_PORTAL && r_refdef.recurse < portaldepth) + { GLBE_SubmitMeshesPortals(model->batches, shaderstate.mbatches[i]); + if (!r_refdef.recurse && r_portalonly.ival) + return; + } + GLBE_SubmitMeshesSortList(model->batches[i]); } GLBE_SubmitMeshesSortList(shaderstate.mbatches[i]); diff --git a/engine/gl/gl_rmain.c b/engine/gl/gl_rmain.c index ea1b63ebe..137fc2a7e 100644 --- a/engine/gl/gl_rmain.c +++ b/engine/gl/gl_rmain.c @@ -77,6 +77,8 @@ extern cvar_t gl_ati_truform_type; extern cvar_t gl_ati_truform_tesselation; extern cvar_t gl_blendsprites; +extern cvar_t r_portaldrawplanes; +extern cvar_t r_portalonly; #ifdef R_XFLIP cvar_t r_xflip = SCVAR("leftisright", "0"); @@ -793,7 +795,8 @@ void R_ObliqueNearClip(float *viewmat, mplane_t *wplane) r_refdef.m_projection[10] = c[2] + 1.0F; r_refdef.m_projection[14] = c[3]; } -//void TestDrawPlane(float *normal, float dist, float r, float g, float b, qboolean enqueue); + +void TestDrawPlane(float *normal, float dist, float r, float g, float b, qboolean enqueue); void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2], int portaltype) { entity_t *view; @@ -805,6 +808,8 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2], int i; mesh_t *mesh = batch->mesh[batch->firstmesh]; qbyte newvis[(MAX_MAP_LEAFS+7)/8]; + plane_t oplane; + float ivmat[16], trmat[16]; if (r_refdef.recurse >= R_MAX_RECURSE-1) return; @@ -910,16 +915,15 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2], #ifdef CSQC_DAT if (CSQC_SetupToRenderPortal(batch->ent->keynum)) { - plane_t oplane = plane; - float ivmat[16], trmat[16]; + oplane = plane; //transform the old surface plane into the new view matrix Matrix4_Invert(r_refdef.m_view, ivmat); Matrix4x4_CM_ModelViewMatrixFromAxis(vmat, vpn, vright, vup, r_refdef.vieworg); Matrix4_Multiply(ivmat, vmat, trmat); - plane.normal[0] = (oplane.normal[0] * trmat[0] + oplane.normal[1] * trmat[4] + oplane.normal[2] * trmat[8]); - plane.normal[1] = (oplane.normal[0] * trmat[1] + oplane.normal[1] * trmat[5] + oplane.normal[2] * trmat[9]); - plane.normal[2] = (oplane.normal[0] * trmat[2] + oplane.normal[1] * trmat[6] + oplane.normal[2] * trmat[10]); + plane.normal[0] = -(oplane.normal[0] * trmat[0] + oplane.normal[1] * trmat[1] + oplane.normal[2] * trmat[2]); + plane.normal[1] = -(oplane.normal[0] * trmat[4] + oplane.normal[1] * trmat[5] + oplane.normal[2] * trmat[6]); + plane.normal[2] = -(oplane.normal[0] * trmat[8] + oplane.normal[1] * trmat[9] + oplane.normal[2] * trmat[10]); plane.dist = -oplane.dist + trmat[12]*oplane.normal[0] + trmat[13]*oplane.normal[1] + trmat[14]*oplane.normal[2]; if (Cvar_Get("temp_useplaneclip", "1", 0, "temp")->ival) @@ -938,6 +942,8 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2], for (i = 1; i < mesh->numvertexes; i++) VectorAdd(r_refdef.pvsorigin, mesh->xyz_array[i], r_refdef.pvsorigin); VectorScale(r_refdef.pvsorigin, 1.0/mesh->numvertexes, r_refdef.pvsorigin); + + portaltype = 1; } else { @@ -945,6 +951,8 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2], vec3_t paxis[3], porigin, vaxis[3], vorg; void PerpendicularVector( vec3_t dst, const vec3_t src ); + oplane = plane; + /*calculate where the surface is meant to be*/ VectorCopy(mesh->normals_array[0], paxis[0]); PerpendicularVector(paxis[1], paxis[0]); @@ -961,31 +969,59 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2], VectorCopy(vorg, r_refdef.pvsorigin); /*rotate it a bit*/ - RotatePointAroundVector(vaxis[1], vaxis[0], view->axis[1], sin(realtime)*4); - CrossProduct(vaxis[0], vaxis[1], vaxis[2]); + if (view->framestate.g[FS_REG].frame[1]) //oldframe + { + if (view->framestate.g[FS_REG].frame[0]) //newframe + d = realtime * view->framestate.g[FS_REG].frame[0]; //newframe + else + d = view->skinnum + sin(realtime)*4; + } + else + d = view->skinnum; + + if (d) + { + vec3_t rdir; + VectorCopy(vaxis[1], rdir); + RotatePointAroundVector(vaxis[1], vaxis[0], rdir, d); + CrossProduct(vaxis[0], vaxis[1], vaxis[2]); + } TransformCoord(oldrefdef.vieworg, paxis, porigin, vaxis, vorg, r_refdef.vieworg); TransformDir(vpn, paxis, vaxis, vpn); TransformDir(vright, paxis, vaxis, vright); TransformDir(vup, paxis, vaxis, vup); Matrix4x4_CM_ModelViewMatrixFromAxis(vmat, vpn, vright, vup, r_refdef.vieworg); + + + //transform the old surface plane into the new view matrix + if (Matrix4_Invert(r_refdef.m_view, ivmat)) + { + extern cvar_t temp1; + Matrix4_Multiply(ivmat, vmat, trmat); + plane.normal[0] = -(oplane.normal[0] * trmat[0] + oplane.normal[1] * trmat[1] + oplane.normal[2] * trmat[2]); + plane.normal[1] = -(oplane.normal[0] * trmat[4] + oplane.normal[1] * trmat[5] + oplane.normal[2] * trmat[6]); + plane.normal[2] = -(oplane.normal[0] * trmat[8] + oplane.normal[1] * trmat[9] + oplane.normal[2] * trmat[10]); + plane.dist = -oplane.dist + trmat[12]*oplane.normal[0] + trmat[13]*oplane.normal[1] + trmat[14]*oplane.normal[2]; + portaltype = 1; + } } break; } /*FIXME: can we get away with stenciling the screen?*/ /*Add to frustum culling instead of clip planes?*/ -/* if (qglClipPlane) +/* if (qglClipPlane && portaltype) { GLdouble glplane[4]; - glplane[0] = -plane.normal[0]; - glplane[1] = -plane.normal[1]; - glplane[2] = -plane.normal[2]; + glplane[0] = plane.normal[0]; + glplane[1] = plane.normal[1]; + glplane[2] = plane.normal[2]; glplane[3] = plane.dist; qglClipPlane(GL_CLIP_PLANE0, glplane); qglEnable(GL_CLIP_PLANE0); - }*/ - //fixme: we can probably scissor a smaller frusum + } +*/ //fixme: we can probably scissor a smaller frusum R_SetFrustum (r_refdef.m_projection, vmat); if (r_refdef.frustum_numplanes < MAXFRUSTUMPLANES) { @@ -1070,14 +1106,17 @@ void GLR_DrawPortal(batch_t *batch, batch_t **blist, batch_t *depthmasklist[2], // if (qglClipPlane) // qglDisable(GL_CLIP_PLANE0); - //the front of the plane should generally point away from the camera, and will be drawn in bright green. woo -// TestDrawPlane(plane.normal, plane.dist+0.01, 0.0, 0.5, 0.0, false); -// TestDrawPlane(plane.normal, plane.dist-0.01, 0.0, 0.5, 0.0, false); - //the back of the plane points towards the camera, and will be drawn in blue, for the luls -// VectorNegate(plane.normal, plane.normal); -// plane.dist *= -1; -// TestDrawPlane(plane.normal, plane.dist+0.01, 0.0, 0.0, 0.2, false); -// TestDrawPlane(plane.normal, plane.dist-0.01, 0.0, 0.0, 0.2, false); + if (r_portaldrawplanes.ival) + { + //the front of the plane should generally point away from the camera, and will be drawn in bright green. woo + TestDrawPlane(plane.normal, plane.dist+0.01, 0.0, 0.5, 0.0, false); + TestDrawPlane(plane.normal, plane.dist-0.01, 0.0, 0.5, 0.0, false); + //the back of the plane points towards the camera, and will be drawn in blue, for the luls + VectorNegate(plane.normal, plane.normal); + plane.dist *= -1; + TestDrawPlane(plane.normal, plane.dist+0.01, 0.0, 0.0, 0.2, false); + TestDrawPlane(plane.normal, plane.dist-0.01, 0.0, 0.0, 0.2, false); + } r_refdef = oldrefdef; diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index d9ae6450f..3db53b7f5 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -5409,6 +5409,20 @@ cin_t *R_ShaderFindCinematic(char *name) #endif } +void Shader_ResetRemaps(void) +{ + shader_t *s; + int i; + for (i = 0; i < r_numshaders; i++) + { + s = r_shaders[i]; + if (!s) + continue; + s->remapto = s; + s->remaptime = 0; + } +} + void R_RemapShader(const char *sourcename, const char *destname, float timeoffset) { shader_t *o; diff --git a/engine/gl/shader.h b/engine/gl/shader.h index 8e26ca527..8c3470ce1 100644 --- a/engine/gl/shader.h +++ b/engine/gl/shader.h @@ -570,7 +570,8 @@ void Shader_DefaultSkybox(char *shortname, shader_t *s, const void *args); void Shader_DefaultCinematic(char *shortname, shader_t *s, const void *args); void Shader_DefaultScript(char *shortname, shader_t *s, const void *args); -void Shader_DoReload(void); +void Shader_ResetRemaps(void); //called on map changes to reset remapped shaders. +void Shader_DoReload(void); //called when the shader system dies. void Shader_Shutdown (void); qboolean Shader_Init (void); void Shader_NeedReload(qboolean rescanfs); diff --git a/engine/server/svq3_game.c b/engine/server/svq3_game.c index 60f8e78bf..51f8ce0cd 100644 --- a/engine/server/svq3_game.c +++ b/engine/server/svq3_game.c @@ -384,7 +384,7 @@ static int SVQ3_EntitiesInBox(vec3_t mins, vec3_t maxs, int *list, int maxcount) #define ENTITYNUM_NONE (MAX_GENTITIES-1) #define ENTITYNUM_WORLD (MAX_GENTITIES-2) -static void SVQ3_Trace(q3trace_t *result, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int entnum, int contentmask) +static void SVQ3_Trace(q3trace_t *result, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int entnum, int contentmask, qboolean capsule) { int contactlist[128]; trace_t tr; @@ -550,20 +550,20 @@ static int SVQ3_PointContents(vec3_t pos, int entnum) return cont; } -static int SVQ3_Contact(vec3_t mins, vec3_t maxs, q3sharedEntity_t *ent) +static int SVQ3_Contact(vec3_t mins, vec3_t maxs, q3sharedEntity_t *ent, qboolean capsule) { model_t *mod; trace_t tr; - if (!ent->s.modelindex || ent->r.bmodel) - mod = CM_TempBoxModel(ent->r.mins, ent->r.maxs); - else + if (ent->r.bmodel) mod = Mod_ForName(va("*%i", ent->s.modelindex), false); + else + mod = CM_TempBoxModel(ent->r.mins, ent->r.maxs); if (mod->needload || !mod->funcs.NativeTrace) return false; - mod->funcs.NativeTrace(mod, 0, 0, NULL, vec3_origin, vec3_origin, mins, maxs, 0xffffffff, &tr); + tr = CM_TransformedBoxTrace(mod, vec3_origin, vec3_origin, mins, maxs, 0xffffffff, ent->r.currentOrigin, ent->r.currentAngles); if (tr.startsolid) return true; @@ -637,16 +637,51 @@ void SVQ3_SendServerCommand(client_t *cl, char *str) Q_strncpyz(cl->server_commands[cl->num_server_commands & TEXTCMD_MASK], str, sizeof(cl->server_commands[0])); } +void SVQ3_SendConfigString(client_t *dest, int num, char *string) +{ + int len = strlen(string); +#define CONFIGSTRING_MAXCHUNK (1024-24) + if (len > CONFIGSTRING_MAXCHUNK) + { + char *cmd; + char buf[CONFIGSTRING_MAXCHUNK+1]; + int off = 0; + for (;;) + { + int chunk = len - off; + if (chunk > CONFIGSTRING_MAXCHUNK) + chunk = CONFIGSTRING_MAXCHUNK; + //split it up into multiple commands. + if (!off) + cmd = "bcs0"; //initial chunk + else if (off + chunk == len) + cmd = "bcs2"; //terminator + else + cmd = "bcs1"; //mid chunk + memcpy(buf, string+off, chunk); + buf[chunk] = 0; + SVQ3_SendServerCommand(dest, va("%s %i \"%s\"\n", cmd, num, buf)); + off += chunk; + if (off == len) + break; + } + } + else + SVQ3_SendServerCommand(dest, va("cs %i \"%s\"\n", num, string)); +} + void SVQ3_SetConfigString(int num, char *string) { + int len; if (!string) string = ""; + len = strlen(string); if (svq3_configstrings[num]) Z_Free(svq3_configstrings[num]); - svq3_configstrings[num] = Z_Malloc(strlen(string)+1); + svq3_configstrings[num] = Z_Malloc(len+1); strcpy(svq3_configstrings[num], string); - SVQ3_SendServerCommand( NULL, va("cs %i \"%s\"\n", num, string)); + SVQ3_SendConfigString(num, string); } static int FloatAsInt(float f) @@ -869,13 +904,19 @@ static qintptr_t Q3G_SystemCalls(void *offset, unsigned int mask, qintptr_t fn, break; case G_TRACE: // ( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentmask ); VALIDATEPOINTER(arg[0], sizeof(q3trace_t)); - SVQ3_Trace(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_POINTER(arg[2]), VM_POINTER(arg[3]), VM_POINTER(arg[4]), VM_LONG(arg[5]), VM_LONG(arg[6])); + SVQ3_Trace(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_POINTER(arg[2]), VM_POINTER(arg[3]), VM_POINTER(arg[4]), VM_LONG(arg[5]), VM_LONG(arg[6]), false); + break; + case G_TRACECAPSULE: // ( trace_t *results, const vec3_t start, const vec3_t mins, const vec3_t maxs, const vec3_t end, int passEntityNum, int contentmask ); + VALIDATEPOINTER(arg[0], sizeof(q3trace_t)); + SVQ3_Trace(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_POINTER(arg[2]), VM_POINTER(arg[3]), VM_POINTER(arg[4]), VM_LONG(arg[5]), VM_LONG(arg[6]), true); break; case G_ENTITY_CONTACT: // ( const vec3_t mins, const vec3_t maxs, const gentity_t *ent ); 33 // perform an exact check against inline brush models of non-square shape - return SVQ3_Contact(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_POINTER(arg[2])); - break; + return SVQ3_Contact(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_POINTER(arg[2]), false); + case G_ENTITY_CONTACTCAPSULE: + return SVQ3_Contact(VM_POINTER(arg[0]), VM_POINTER(arg[1]), VM_POINTER(arg[2]), true); + case G_ENTITIES_IN_BOX: // ( const vec3_t mins, const vec3_t maxs, gentity_t **list, int maxcount ); 32 // EntitiesInBox will return brush models based on their bounding box, // so exact determination must still be done with EntityContact @@ -1536,7 +1577,7 @@ static char *QDECL BL_BSPEntityData(void) static void QDECL BL_Trace(bsp_trace_t *trace, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t end, int passent, int contentmask) { q3trace_t tr; - SVQ3_Trace(&tr, start, mins, maxs, end, passent, contentmask); + SVQ3_Trace(&tr, start, mins, maxs, end, passent, contentmask, false); trace->allsolid = tr.allsolid; trace->startsolid = tr.startsolid;