From 7c418ca4239fdc58100d1de42fee3b2c6b70bb9f Mon Sep 17 00:00:00 2001 From: Spoike Date: Sun, 15 May 2005 18:49:04 +0000 Subject: [PATCH] qc string_t is now an int instead of char *, stringtable is char * instead of int. Some fixes and extra stuff for nexuiz, but it took a protocol extension, which is currently assumed instead of queried. git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@1015 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/cl_ents.c | 47 +++++++--- engine/client/cl_parse.c | 2 +- engine/client/cl_tent.c | 30 +++++- engine/client/clq2_ents.c | 4 +- engine/client/pr_csqc.c | 26 +++++- engine/client/pr_menu.c | 2 +- engine/common/cmd.c | 18 +++- engine/common/gl_q2bsp.c | 46 ++++++---- engine/common/protocol.h | 19 ++-- engine/gl/gl_alias.c | 132 ++++++++++++++++----------- engine/gl/gl_ppl.c | 31 ++++--- engine/gl/gl_rsurf.c | 14 ++- engine/gl/gl_warp.c | 11 ++- engine/qclib/initlib.c | 13 ++- engine/qclib/pr_comp.h | 2 +- engine/qclib/pr_edict.c | 171 ++++++++++++++++++----------------- engine/qclib/pr_exec.c | 12 +-- engine/qclib/pr_multi.c | 22 ++--- engine/qclib/progsint.h | 6 +- engine/qclib/progslib.h | 6 +- engine/qclib/progtype.h | 2 +- engine/qclib/qcdecomp.c | 6 +- engine/server/net_preparse.c | 8 +- engine/server/pr_cmds.c | 20 ++-- engine/server/progdefs.h | 2 + engine/server/sv_ents.c | 61 +++++++++++-- engine/server/sv_init.c | 32 ++++--- engine/server/sv_main.c | 6 +- engine/server/sv_phys.c | 58 +++++++++--- engine/server/sv_user.c | 4 +- 30 files changed, 528 insertions(+), 285 deletions(-) diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index 3d18a939..f554deac 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -276,8 +276,6 @@ void CL_ParseDelta (entity_state_t *from, entity_state_t *to, int bits, qboolean if (bits&(1<flags = bits; - #ifdef PROTOCOLEXTENSIONS if (bits & U_EVENMORE && cls.fteprotocolextensions) morebits = MSG_ReadByte (); @@ -337,7 +335,7 @@ void CL_ParseDelta (entity_state_t *from, entity_state_t *to, int bits, qboolean #endif if (morebits & U_DRAWFLAGS && cls.fteprotocolextensions & PEXT_HEXEN2) - to->drawflags = MSG_ReadByte(); + to->hexen2flags = MSG_ReadByte(); if (morebits & U_ABSLIGHT && cls.fteprotocolextensions & PEXT_HEXEN2) to->abslight = MSG_ReadByte(); @@ -348,6 +346,28 @@ void CL_ParseDelta (entity_state_t *from, entity_state_t *to, int bits, qboolean if (morebits & U_MODELDBL) to->modelindex += 256; + if (morebits & U_DPFLAGS)// && cls.fteprotocolextensions & PEXT_DPFLAGS) + { + // these are bits for the 'flags' field of the entity_state_t +#define RENDER_STEP 1 +#define RENDER_GLOWTRAIL 2 +#define RENDER_VIEWMODEL 4 +#define RENDER_EXTERIORMODEL 8 +#define RENDER_LOWPRECISION 16 // send as low precision coordinates to save bandwidth +#define RENDER_COLORMAPPED 32 +#define RENDER_SHADOW 65536 // cast shadow +#define RENDER_LIGHT 131072 // receive light +#define RENDER_TRANSPARENT 262144 // can't light during opaque stage + + + i = MSG_ReadByte(); + to->flags = 0; + if (i & RENDER_VIEWMODEL) + to->flags |= Q2RF_WEAPONMODEL|Q2RF_MINLIGHT|Q2RF_DEPTHHACK; + if (i & RENDER_EXTERIORMODEL) + to->flags |= Q2RF_EXTERNALMODEL; + } + VectorSubtract(to->origin, from->origin, move); #ifdef HALFLIFEMODELS @@ -755,7 +775,10 @@ void DP5_ParseDelta(entity_state_t *s) } if (bits & E5_FULLUPDATE) { + int num; + num = s->number; *s = defaultstate; + s->number = num; // s->active = true; } if (bits & E5_FLAGS) @@ -823,10 +846,8 @@ void DP5_ParseDelta(entity_state_t *s) s->colormap = MSG_ReadByte(); if (bits & E5_ATTACHMENT) { - MSG_ReadShort(); - MSG_ReadByte(); -// s->tagentity = (unsigned short) MSG_ReadShort(); -// s->tagindex = MSG_ReadByte(); + cl.lerpents[s->number].tagent = MSG_ReadShort(); + cl.lerpents[s->number].tagindex = MSG_ReadByte(); } if (bits & E5_LIGHT) { @@ -917,9 +938,8 @@ void CLNQ_ParseDarkPlaces5Entities(void) //the things I do.. :o( to = &pack->entities[pack->num_entities]; pack->num_entities++; memcpy(to, from, sizeof(*to)); - DP5_ParseDelta(to); - to->number = read; + DP5_ParseDelta(to); if (!from || to->modelindex != from->modelindex || to->number != from->number) //model changed... or entity changed... cl.lerpents[to->number].lerptime = -10; @@ -1282,7 +1302,8 @@ void CL_RotateAroundTag(entity_t *ent, int num, int tagent, int tagnum) } else //hrm. { -// memcpy(axis, ent->axis, sizeof(temp)); + memcpy(ent->axis, axis, sizeof(temp)); + VectorCopy(org, ent->origin); } @@ -1327,6 +1348,8 @@ void V_AddLerpEntity(entity_t *in) //a convienience function ent->origin[i] = in->origin[i]*fwds + in->oldorigin[i]*back; } + ent->lerpfrac = 1 - ent->lerpfrac; + ent->angles[0]*=-1; AngleVectors(ent->angles, ent->axis[0], ent->axis[1], ent->axis[2]); VectorInverse(ent->axis[1]); @@ -1433,7 +1456,7 @@ void CL_LinkPacketEntities (void) else ent->model = model; - ent->flags = 0; + ent->flags = s1->flags; if (s1->effects & NQEF_ADDATIVE) ent->flags |= Q2RF_ADDATIVE; @@ -1454,7 +1477,7 @@ void CL_LinkPacketEntities (void) ent->skinnum = s1->skinnum; ent->abslight = s1->abslight; - ent->drawflags = s1->drawflags; + ent->drawflags = s1->hexen2flags; // set frame ent->frame = s1->frame; diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index f12a636d..5b117dc3 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -2080,7 +2080,7 @@ void CL_ParseStatic (int version) ent->oldframe = ent->frame = es.frame; ent->colormap = vid.colormap; ent->skinnum = es.skinnum; - ent->drawflags = es.drawflags; + ent->drawflags = es.hexen2flags; #ifdef PEXT_SCALE ent->scale = es.scale; diff --git a/engine/client/cl_tent.c b/engine/client/cl_tent.c index db0b4523..121c41e5 100644 --- a/engine/client/cl_tent.c +++ b/engine/client/cl_tent.c @@ -330,16 +330,16 @@ void CL_ParseBeam (int tent) return; } default: - m = Mod_ForName("progs/bolt.mdl", true); + m = Mod_ForName("progs/bolt.mdl", false); break; case 1: if (ent < 0 && ent >= -MAX_CLIENTS) //based on the railgun concept - this adds a rogue style TE_BEAM effect. m = Mod_ForName("progs/beam.mdl", false); //remember to precache! else - m = Mod_ForName("progs/bolt2.mdl", true); + m = Mod_ForName("progs/bolt2.mdl", false); break; case 2: - m = Mod_ForName("progs/bolt3.mdl", true); + m = Mod_ForName("progs/bolt3.mdl", false); break; #ifdef Q2CLIENT case 3: @@ -840,6 +840,30 @@ void CL_ParseTEnt (void) } break; + case DPTE_BLOODSHOWER: + pos[0] = MSG_ReadCoord (); + pos[1] = MSG_ReadCoord (); + pos[2] = MSG_ReadCoord (); + + pos2[0] = MSG_ReadCoord (); + pos2[1] = MSG_ReadCoord (); + pos2[2] = MSG_ReadCoord (); + + cnt = MSG_ReadCoord (); //speed + + cnt = MSG_ReadShort (); + + { +#pragma message("CL_ParseTEnt: effect DPTE_BLOODSHOWER not implemented") +/* + extern int pt_bloodshower; + VectorAdd(pos, pos2, pos); + VectorScale(pos, 0.5, pos); + P_RunParticleEffectType(pos, NULL, cnt, pt_bloodshower); +*/ + } + break; + case DPTE_SMALLFLASH: pos[0] = MSG_ReadCoord (); pos[1] = MSG_ReadCoord (); diff --git a/engine/client/clq2_ents.c b/engine/client/clq2_ents.c index 752e2275..140eccdd 100644 --- a/engine/client/clq2_ents.c +++ b/engine/client/clq2_ents.c @@ -1533,7 +1533,7 @@ void CLQ2_AddPacketEntities (q2frame_t *frame) if (s1->number == cl.playernum[0]+1) //woo! this is us! { - ent.flags |= Q2RF_VIEWERMODEL; // only draw from mirrors + ent.flags |= Q2RF_EXTERNALMODEL; // only draw from mirrors if (effects & Q2EF_FLAG1) V_AddLight (ent.origin, 225, 0.2, 0.05, 0.05); @@ -1914,7 +1914,7 @@ void CLQ2_AddViewWeapon (q2player_state_t *ps, q2player_state_t *ops) } gun.flags = Q2RF_MINLIGHT | Q2RF_DEPTHHACK | Q2RF_WEAPONMODEL; - gun.lerpfrac = cl.lerpfrac; + gun.lerpfrac = 1-cl.lerpfrac; VectorCopy (gun.origin, gun.oldorigin); // don't lerp at all V_AddEntity (&gun); #endif diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index df812f8d..a20bce1c 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -19,11 +19,10 @@ cvar_t cl_csqcdebug = {"cl_csqcdebug", "0"}; //prints entity numbers which arriv globalfunction(init_function, "CSQC_Init"); \ globalfunction(shutdown_function, "CSQC_Shutdown"); \ globalfunction(draw_function, "CSQC_UpdateView"); \ - globalfunction(keydown_function, "CSQC_KeyDown"); \ - globalfunction(keyup_function, "CSQC_KeyUp"); \ globalfunction(parse_stuffcmd, "CSQC_Parse_StuffCmd"); \ globalfunction(parse_centerprint, "CSQC_Parse_CenterPrint"); \ globalfunction(input_event, "CSQC_InputEvent"); \ + globalfunction(console_command, "CSQC_ConsoleCommand"); \ \ globalfunction(ent_update, "CSQC_Ent_Update"); \ globalfunction(ent_remove, "CSQC_Ent_Remove"); \ @@ -191,7 +190,7 @@ csqcfields static csqcedict_t *csqcent[MAX_EDICTS]; -#define RETURN_SSTRING(s) (*(char **)&((int *)pr_globals)[OFS_RETURN] = PR_SetString(prinst, s)) //static - exe will not change it. +#define RETURN_SSTRING(s) (((int *)pr_globals)[OFS_RETURN] = PR_SetString(prinst, s)) //static - exe will not change it. char *PF_TempStr(void); static int csqcentsize; @@ -1689,6 +1688,23 @@ qboolean CSQC_KeyPress(int key, qboolean down) return true; } +qboolean CSQC_ConsoleCommand(char *cmd) +{ + void *pr_globals; + char *str; + if (!csqcprogs || !csqcg.console_command) + return false; + + str = PF_TempStr(); + Q_strncpyz(str, cmd, MAXTEMPBUFFERLEN); + + pr_globals = PR_globals(csqcprogs, PR_CURRENT); + (((string_t *)pr_globals)[OFS_PARM0] = PR_SetString(csqcprogs, str)); + + PR_ExecuteProgram (csqcprogs, csqcg.console_command); + return true; +} + qboolean CSQC_StuffCmd(char *cmd) { void *pr_globals; @@ -1700,7 +1716,7 @@ qboolean CSQC_StuffCmd(char *cmd) Q_strncpyz(str, cmd, MAXTEMPBUFFERLEN); pr_globals = PR_globals(csqcprogs, PR_CURRENT); - (*(char **)&((int *)pr_globals)[OFS_PARM0] = PR_SetString(csqcprogs, str)); + (((string_t *)pr_globals)[OFS_PARM0] = PR_SetString(csqcprogs, str)); PR_ExecuteProgram (csqcprogs, csqcg.parse_stuffcmd); return true; @@ -1716,7 +1732,7 @@ qboolean CSQC_CenterPrint(char *cmd) Q_strncpyz(str, cmd, MAXTEMPBUFFERLEN); pr_globals = PR_globals(csqcprogs, PR_CURRENT); - (*(char **)&((int *)pr_globals)[OFS_PARM0] = PR_SetString(csqcprogs, str)); + (((string_t *)pr_globals)[OFS_PARM0] = PR_SetString(csqcprogs, str)); PR_ExecuteProgram (csqcprogs, csqcg.parse_centerprint); return G_FLOAT(OFS_RETURN); diff --git a/engine/client/pr_menu.c b/engine/client/pr_menu.c index 435dfd6a..062fd8ce 100644 --- a/engine/client/pr_menu.c +++ b/engine/client/pr_menu.c @@ -17,7 +17,7 @@ typedef struct menuedict_s void *fields; } menuedict_t; -#define RETURN_SSTRING(s) (*(char **)&((int *)pr_globals)[OFS_RETURN] = PR_SetString(prinst, s)) //static - exe will not change it. +#define RETURN_SSTRING(s) (((int *)pr_globals)[OFS_RETURN] = PR_SetString(prinst, s)) //static - exe will not change it. char *PF_TempStr(void); #define MAXTEMPBUFFERLEN 4096 diff --git a/engine/common/cmd.c b/engine/common/cmd.c index 155a011c..1b87819e 100644 --- a/engine/common/cmd.c +++ b/engine/common/cmd.c @@ -1694,6 +1694,13 @@ void Cmd_ExecuteString (char *text, int level) return; #endif +#ifndef SERVERONLY +#ifdef CSQC_DAT + if (CSQC_ConsoleCommand(text)) + return; +#endif +#endif + #ifndef CLIENTONLY if (sv.state) { @@ -1704,15 +1711,16 @@ void Cmd_ExecuteString (char *text, int level) #ifdef VM_CG if (CG_Command()) - ; - else + return; #endif #ifdef Q2CLIENT - if (cls.q2server) + if (cls.q2server) + { Cmd_ForwardToServer(); - else + return; + } #endif - if (cl_warncmd.value || developer.value) + if (cl_warncmd.value || developer.value) Con_TPrintf (TL_COMMANDNOTDEFINED, Cmd_Argv(0)); } diff --git a/engine/common/gl_q2bsp.c b/engine/common/gl_q2bsp.c index 9883e6d1..918bbc11 100644 --- a/engine/common/gl_q2bsp.c +++ b/engine/common/gl_q2bsp.c @@ -750,7 +750,14 @@ void CM_CreatePatch ( q3cpatch_t *patch, int numverts, const vec3_t *verts, int VectorCopy(verts[i], pointss[i]); // fill in Patch_Evaluate ( pointss, patch_cp, step, points ); - +/* + for (i = 0; i < numverts; i++) + { + points[i][0] = (int)(points[i][0]*20)/20.0f; + points[i][1] = (int)(points[i][1]*20)/20.0f; + points[i][2] = (int)(points[i][2]*20)/20.0f; + } +*/ patch->brushes = brush = map_brushes + numbrushes; patch->numbrushes = 0; @@ -1898,20 +1905,18 @@ void CModQ3_LoadShaders (lump_t *l, qboolean useshaders) loadmodel->texinfo[i].texture->gl_texturenum = Mod_LoadHiResTexture(in->shadername, "bmodels", true, false, true); loadmodel->texinfo[i].texture->gl_texturenumfb = 0; loadmodel->texinfo[i].texture->gl_texturenumbumpmap = 0; + + if (!strncmp(in->shadername, "textures/skies/", 15)) + { + loadmodel->texinfo[i].flags |= SURF_SKY; + skytexturenum = i; + } } #endif loadmodel->textures[i] = loadmodel->texinfo[i].texture; out->c.flags = LittleLong ( in->surfflags ); out->c.value = LittleLong ( in->contents ); - -#if !defined(SERVERONLY) && defined(RGLQUAKE) - if (!strncmp(in->shadername, "textures/skies/", 15)) - { - loadmodel->texinfo[i].flags |= SURF_SKY; - skytexturenum = i; - } -#endif } } @@ -2410,6 +2415,13 @@ continue; out->texinfo->texture->shader = R_RegisterShader_Vertex (out->texinfo->texture->name); else out->texinfo->texture->shader = R_RegisterShader(out->texinfo->texture->name); + + + if (out->texinfo->texture->shader->flags & SHADER_SKY) + { + out->texinfo->flags |= SURF_SKY; + skytexturenum = out->texinfo - loadmodel->texinfo; + } } if (in->fognum == -1 || !map_numfogs) @@ -4209,7 +4221,7 @@ void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2, } else { // leave - f = (d1+DIST_EPSILON) / (d1-d2); + f = (d1/*+DIST_EPSILON*/) / (d1-d2); if (f < leavefrac) leavefrac = f; } @@ -4222,7 +4234,7 @@ void CM_ClipBoxToBrush (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2, trace->allsolid = true; return; } - if (enterfrac < leavefrac) + if (enterfrac - (1.0f / 1024.0f) < leavefrac) { if (enterfrac > -1 && enterfrac < trace->fraction) { @@ -4313,7 +4325,7 @@ void CM_ClipBoxToPatch (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2, } else { // leave - f = (d1 + DIST_EPSILON) / (d1-d2); + f = (d1 /*+ DIST_EPSILON*/) / (d1-d2); if (f < leavefrac) leavefrac = f; } @@ -4322,7 +4334,7 @@ void CM_ClipBoxToPatch (vec3_t mins, vec3_t maxs, vec3_t p1, vec3_t p2, if (!startout) return; // original point is inside the patch - if (enterfrac <= leavefrac) + if (enterfrac - (1.0f / 1024.0f) <= leavefrac) { if (leadside && leadside->surface && enterfrac < trace->fraction) @@ -4503,7 +4515,7 @@ void CM_TraceToLeaf (int leafnum) for (j = 0; j < patch->numbrushes; j++) { CM_ClipBoxToPatch (trace_mins, trace_maxs, trace_start, trace_end, &trace_trace, &patch->brushes[j]); - if (!trace_trace.fraction) + if (trace_trace.fraction<=0) return; } } @@ -4800,9 +4812,9 @@ trace_t CM_BoxTrace (vec3_t start, vec3_t end, else { trace_ispoint = false; - trace_extents[0] = -trace_mins[0] > trace_maxs[0] ? -trace_mins[0] : trace_maxs[0]; - trace_extents[1] = -trace_mins[1] > trace_maxs[1] ? -trace_mins[1] : trace_maxs[1]; - trace_extents[2] = -trace_mins[2] > trace_maxs[2] ? -trace_mins[2] : trace_maxs[2]; + trace_extents[0] = (-trace_mins[0] > trace_maxs[0] ? -trace_mins[0] : trace_maxs[0])+0.1; + trace_extents[1] = (-trace_mins[1] > trace_maxs[1] ? -trace_mins[1] : trace_maxs[1])+0.1; + trace_extents[2] = (-trace_mins[2] > trace_maxs[2] ? -trace_mins[2] : trace_maxs[2])+0.1; #if ADJ if (-mins[2] != maxs[2]) //be prepared to move the thing up to counter the different min/max { diff --git a/engine/common/protocol.h b/engine/common/protocol.h index eb40a9f9..dfab2cab 100644 --- a/engine/common/protocol.h +++ b/engine/common/protocol.h @@ -62,6 +62,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define PEXT_CSQC 0x40000000 //csqc additions #endif +#define PEXT_DPFLAGS 0x80000000 //extra flags for viewmodel/externalmodel and possible other persistant style flags. //ZQuake transparent protocol extensions. @@ -440,7 +441,8 @@ enum clcq2_ops_e #ifdef PEXT_BIGORIGINS #define U_ORIGINDBL (1<<10) //use an extra qbyte for origin parts, cos one of them is off #endif -#define U_VIEWMODEL (1<<11) //glue to the player's view + +#define U_DPFLAGS (1<<11) #endif @@ -600,6 +602,7 @@ enum { #define DPTE_BLOOD 50 #define DPTE_SPARK 51 +#define DPTE_BLOODSHOWER 52 #define DPTE_SMALLFLASH 72 #define DPTE_CUSTOMFLASH 73 #define DPTE_FLAMEJET 74 @@ -674,8 +677,9 @@ typedef struct entity_state_s float fatness; #endif - int drawflags; - int abslight; + qbyte hexen2flags; + qbyte abslight; + qbyte dpflags; } entity_state_t; #else typedef struct entity_state_s @@ -698,7 +702,6 @@ typedef struct entity_state_s int sound; //q2 int event; //q2 - int solid; #ifdef PEXT_SCALE float scale; @@ -709,8 +712,10 @@ typedef struct entity_state_s #ifdef PEXT_FATNESS float fatness; #endif - int drawflags; - int abslight; + qbyte hexen2flags; + qbyte abslight; + qbyte dpflags; + qbyte solid; } entity_state_t; #endif @@ -839,7 +844,7 @@ typedef struct q1usercmd_s // entity_state_t->renderfx flags #define Q2RF_MINLIGHT 1 // allways have some light (viewmodel) -#define Q2RF_VIEWERMODEL 2 // don't draw through eyes, only mirrors +#define Q2RF_EXTERNALMODEL 2 // don't draw through eyes, only mirrors #define Q2RF_WEAPONMODEL 4 // only draw through eyes #define Q2RF_FULLBRIGHT 8 // allways draw full intensity #define Q2RF_DEPTHHACK 16 // for view weapon Z crunching diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index 0f5ef23e..6ada1b42 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -428,6 +428,7 @@ static void R_GAliasAddDlights(mesh_t *mesh, vec3_t org, vec3_t angles) static qboolean R_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, int frame1, int frame2, float lerp, float alpha) { galiasgroup_t *g1, *g2; + if (!inf->groups) { Con_DPrintf("Model with no frames (%s)\n", currententity->model->name); @@ -481,18 +482,20 @@ static qboolean R_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, int frame1, i numTempVertexCoords = inf->numverts; } + mesh->numvertexes = inf->numverts; mesh->indexes = (index_t*)((char *)inf + inf->ofs_indexes); mesh->numindexes = inf->numindexes; + + if (inf->sharesverts) + return false; //don't generate the new vertex positions. We still have them all. + + mesh->st_array = (vec2_t*)((char *)inf + inf->ofs_st_array); mesh->lmst_array = NULL; mesh->colors_array = tempColours; mesh->xyz_array = tempVertexCoords; - mesh->numvertexes = inf->numverts; mesh->trneighbors = (int *)((char *)inf + inf->ofs_trineighbours); - if (inf->sharesverts) - return false; //don't generate the new vertex positions. We still have them all. - mesh->normals_array = tempNormals; g1 = (galiasgroup_t*)((char *)inf + inf->groupofs + sizeof(galiasgroup_t)*frame1); @@ -1874,6 +1877,73 @@ void GL_GenerateNormals(float *orgs, float *normals, int *indicies, int numtris, } +int skinfilecount; + +int GL_BuildSkinFileList(char *modelname) +{ + char skinfilename[MAX_QPATH]; + for (skinfilecount = 0; ; skinfilecount++) + { + _snprintf(skinfilename, sizeof(skinfilename)-1, "%s_%i.skin", modelname, skinfilecount); + if (!COM_FCheckExists(skinfilename)) + break; + } + + return skinfilecount; +} + +//This is a hack. It uses an assuption about q3 player models. +void GL_ParseQ3SkinFile(char *out, char *surfname, char *modelname) +{ + const char *f, *p; + char line[256]; + COM_StripExtension(modelname, line); + strcat(line, "_default.skin"); + + f = COM_LoadTempFile2(line); + while(f) + { + f = COM_ParseToken(f); + if (!f) + return; + while(*f == ' ' || *f == '\t') + f++; + if (*f == ',') + { + if (!strcmp(com_token, surfname)) + { + f++; + COM_ParseToken(f); + strcpy(out, com_token); + return; + } + } + + p = strchr(f, '\n'); + if (!p) + f = f+strlen(f); + else + f = p+1; + if (!*f) + break; + } +} + +galiasskin_t *GL_LoadSkinFile(int *count, char *shadername, int skinnumber, unsigned char *rawdata, int width, int height, unsigned char *palette) +{ + galiasskin_t *skin; + galiastexnum_t *texnums; + + skin = Hunk_Alloc(sizeof(*skin)+sizeof(*texnums)); + texnums = (galiastexnum_t *)(skin+1); //texnums is seperate for skingroups/animating skins... Which this format doesn't support. + *count = 1; + skin->ofstexnums = (char *)texnums - (char *)skin; + skin->texnums = 1; + texnums->base = Mod_LoadHiResTexture(shadername, "models", true, true, true); + + return skin; +} + //Q1 model loading #if 1 @@ -2744,43 +2814,6 @@ typedef struct { } md3Shader_t; //End of Tenebrae 'assistance' -//This is a hack. It uses an assuption about q3 player models. -void GL_ParseQ3SkinFile(char *out, char *surfname, char *modelname) -{ - const char *f, *p; - char line[256]; - COM_StripExtension(modelname, line); - strcat(line, "_default.skin"); - - f = COM_LoadTempFile2(line); - while(f) - { - f = COM_ParseToken(f); - if (!f) - return; - while(*f == ' ' || *f == '\t') - f++; - if (*f == ',') - { - if (!strcmp(com_token, surfname)) - { - f++; - COM_ParseToken(f); - strcpy(out, com_token); - return; - } - } - - p = strchr(f, '\n'); - if (!p) - f = f+strlen(f); - else - f = p+1; - if (!*f) - break; - } -} - void GL_LoadQ3Model(model_t *mod, void *buffer) { int hunkstart, hunkend, hunktotal; @@ -3026,7 +3059,9 @@ void GL_LoadQ3Model(model_t *mod, void *buffer) hunkend = Hunk_LowMark (); - mod->flags = Mod_ReadFlagsFromMD1(mod->name, 0); + mod->flags = LittleLong(header->flags); + if (!mod->flags) + mod->flags = Mod_ReadFlagsFromMD1(mod->name, 0); Hunk_Alloc(0); hunktotal = hunkend - hunkstart; @@ -3116,7 +3151,6 @@ void GLMod_LoadZymoticModel(model_t *mod, void *buffer) zymvertex_t *intrans; galiasskin_t *skin; - galiastexnum_t *texnums; galiasbone_t *bone; zymbone_t *inbone; @@ -3245,13 +3279,9 @@ void GLMod_LoadZymoticModel(model_t *mod, void *buffer) root[i].groups = header->numscenes; root[i].groupofs = (char*)grp - (char*)&root[i]; - skin = Hunk_Alloc(sizeof(*skin)+sizeof(*texnums)); - texnums = (galiastexnum_t *)(skin+1); //texnums is seperate for skingroups/animating skins... Which this format doesn't support. + skin = GL_LoadSkinFile(&root[i].numskins, shadername, i, NULL, 0, 0, NULL); + root[i].ofsskins = (char *)skin - (char *)&root[i]; - root[i].numskins = 1; - skin->ofstexnums = (char *)texnums - (char *)skin; - skin->texnums = 1; - texnums->base = Mod_LoadHiResTexture(shadername, "models", true, true, true); } @@ -3271,13 +3301,13 @@ void GLMod_LoadZymoticModel(model_t *mod, void *buffer) root[i].nextsurf = sizeof(galiasinfo_t); for (i = 1; i < header->numshaders; i++) { - root[i].sharesverts = true; root[i].numbones = root[0].numbones; - root[i].numindexes = root[0].numindexes; root[i].numverts = root[0].numverts; root[i].ofsbones = root[0].ofsbones; + + root[i-1].nextsurf = sizeof(*root); } // diff --git a/engine/gl/gl_ppl.c b/engine/gl/gl_ppl.c index aa85be69..c22c0173 100644 --- a/engine/gl/gl_ppl.c +++ b/engine/gl/gl_ppl.c @@ -1746,22 +1746,25 @@ void PPL_BaseEntTextures(void) } else { - j = currententity->keynum; - while(j) - { - - if (j == (cl.viewentity[r_refdef.currentplayernum]?cl.viewentity[r_refdef.currentplayernum]:(cl.playernum[r_refdef.currentplayernum]+1))) - break; - - j = cl.lerpents[j].tagent; - } - if (j) + if (currententity->flags & Q2RF_EXTERNALMODEL) continue; - if (cl.viewentity[r_refdef.currentplayernum] && currententity->keynum == cl.viewentity[r_refdef.currentplayernum]) - continue; - if (!Cam_DrawPlayer(0, currententity->keynum-1)) - continue; +// j = currententity->keynum; +// while(j) +// { +// +// if (j == (cl.viewentity[r_refdef.currentplayernum]?cl.viewentity[r_refdef.currentplayernum]:(cl.playernum[r_refdef.currentplayernum]+1))) +// break; +// +// j = cl.lerpents[j].tagent; +// } +// if (j) +// continue; + +// if (cl.viewentity[r_refdef.currentplayernum] && currententity->keynum == cl.viewentity[r_refdef.currentplayernum]) +// continue; +// if (!Cam_DrawPlayer(0, currententity->keynum-1)) +// continue; } if (currententity->flags & Q2RF_BEAM) diff --git a/engine/gl/gl_rsurf.c b/engine/gl/gl_rsurf.c index 79f41093..f34bb9cd 100644 --- a/engine/gl/gl_rsurf.c +++ b/engine/gl/gl_rsurf.c @@ -107,10 +107,11 @@ void GLR_StainSurf (msurface_t *surf, float *parms) - - stmap *stainbase; + if (surf->lightmaptexturenum < 0) + return; + smax = (surf->extents[0]>>4)+1; tmax = (surf->extents[1]>>4)+1; tex = surf->texinfo; @@ -1784,9 +1785,14 @@ static void DrawGLWaterPoly (mesh_t *p) DrawGLPoly ================ */ -static void DrawGLPoly (mesh_t *p) +static void DrawGLPoly (mesh_t *mesh) { - Sys_Error("DrawGLWaterPoly needs work"); +// GL_DrawAliasMesh + qglVertexPointer(3, GL_FLOAT, 0, mesh->xyz_array); + qglEnableClientState( GL_VERTEX_ARRAY ); + qglDrawElements(GL_TRIANGLES, mesh->numindexes, GL_UNSIGNED_INT, mesh->indexes); + R_IBrokeTheArrays(); + /* int i; float *v; diff --git a/engine/gl/gl_warp.c b/engine/gl/gl_warp.c index af22537c..4ee1333d 100644 --- a/engine/gl/gl_warp.c +++ b/engine/gl/gl_warp.c @@ -51,6 +51,8 @@ extern cvar_t r_fastskycolour; char defaultskybox[MAX_QPATH]; qboolean reloadskybox; +int skyboxtex[6]; + void R_DrawSkyBox (msurface_t *s); void BoundPoly (int numverts, float *verts, vec3_t mins, vec3_t maxs) { @@ -192,6 +194,14 @@ void R_DrawSkyChain (msurface_t *s) GL_DisableMultitexture(); + if (!solidskytexture&&!usingskybox) + { + int i; + if (s->texinfo->texture->shader && s->texinfo->texture->shader->skydome) + for (i = 0; i < 6; i++) + skyboxtex[i] = s->texinfo->texture->shader->skydome->farbox_textures[i]; + } + if (r_fastsky.value||(!solidskytexture&&!usingskybox)) //this is for visability only... we'd otherwise not stoop this low (and this IS low) { int fc; @@ -278,7 +288,6 @@ static char *skyname_pattern[] = { "gfx/env/%s%s" }; -int skyboxtex[6]; void R_LoadSkys (void) { int i; diff --git a/engine/qclib/initlib.c b/engine/qclib/initlib.c index 1f51a63e..3c872ae1 100644 --- a/engine/qclib/initlib.c +++ b/engine/qclib/initlib.c @@ -59,6 +59,7 @@ void *PRAddressableAlloc(progfuncs_t *progfuncs, int ammount) return &addressablehunk[addressableused-ammount]; } + void PRAddressableFlush(progfuncs_t *progfuncs, int totalammount) { addressableused = 0; @@ -255,8 +256,8 @@ char *PR_VarString (progfuncs_t *progfuncs, int first) { if (G_STRING(OFS_PARM0+i*3)) { - s=G_STRING((OFS_PARM0+i*3)); - strcat (out, G_STRING((OFS_PARM0+i*3))); + s=G_STRING((OFS_PARM0+i*3)) + progfuncs->stringtable; + strcat (out, s); //#ifdef PARANOID if (strlen(out)+1 >= sizeof(out)) @@ -448,7 +449,7 @@ __declspec(dllexport) #endif void CloseProgs(progfuncs_t *inst) { - extensionbuiltin_t *eb; +// extensionbuiltin_t *eb; void (VARGS *f) (void *); int i; @@ -468,13 +469,15 @@ void CloseProgs(progfuncs_t *inst) } PRHunkFree(inst, 0); + +/* while(inst->prinst->extensionbuiltin) { eb = inst->prinst->extensionbuiltin->prev; f(inst->prinst->extensionbuiltin); inst->prinst->extensionbuiltin = eb; } - +*/ if (inst->prinst->field) f(inst->prinst->field); if (inst->prinst->shares) @@ -485,12 +488,14 @@ void CloseProgs(progfuncs_t *inst) void RegisterBuiltin(progfuncs_t *progfuncs, char *name, builtin_t func) { +/* extensionbuiltin_t *eb; eb = memalloc(sizeof(extensionbuiltin_t)); eb->prev = progfuncs->prinst->extensionbuiltin; progfuncs->prinst->extensionbuiltin = eb; eb->name = name; eb->func = func; +*/ } #ifndef WIN32 diff --git a/engine/qclib/pr_comp.h b/engine/qclib/pr_comp.h index fa529d7c..54434a8d 100644 --- a/engine/qclib/pr_comp.h +++ b/engine/qclib/pr_comp.h @@ -361,7 +361,7 @@ typedef struct fdef_s // the variable needs to be saved in savegames unsigned int ofs; unsigned int requestedofs; - string_t s_name; + char * name; } fdef_t; typedef void *ddefXX_t; diff --git a/engine/qclib/pr_edict.c b/engine/qclib/pr_edict.c index 47da4043..2490ffd1 100644 --- a/engine/qclib/pr_edict.c +++ b/engine/qclib/pr_edict.c @@ -176,7 +176,7 @@ void ED_Free (progfuncs_t *progfuncs, struct edict_s *ed) if (e->isfree) //this happens on start.bsp where an onlyregistered trigger killtargets itself (when all of this sort die after 1 trigger anyway). { if (pr_depth) - printf("Tried to free free entity within %s\n", pr_xfunction->s_name); + printf("Tried to free free entity within %s\n", pr_xfunction->s_name+progfuncs->stringtable); else printf("Engine tried to free free entity\n"); // if (developer.value == 1) @@ -267,7 +267,7 @@ fdef_t *ED_FindField (progfuncs_t *progfuncs, char *name) for (i=0 ; inumglobaldefs ; i++) { def = &pr_globaldefs16[i]; - if (!strcmp(def->s_name,name) ) + if (!strcmp(def->s_name+progfuncs->stringtable,name) ) return def; } return NULL; @@ -300,7 +300,7 @@ ddef32_t *ED_FindGlobal32 (progfuncs_t *progfuncs, char *name) for (i=1 ; inumglobaldefs ; i++) { def = &pr_globaldefs32[i]; - if (!strcmp(def->s_name,name) ) + if (!strcmp(def->s_name+progfuncs->stringtable,name) ) return def; } return NULL; @@ -332,7 +332,7 @@ ddef16_t *ED_FindGlobalFromProgs16 (progfuncs_t *progfuncs, char *name, progsnum for (i=1 ; inumglobaldefs ; i++) { def = &pr_progstate[prnum].globaldefs16[i]; - if (!strcmp(def->s_name,name) ) + if (!strcmp(def->s_name+progfuncs->stringtable,name) ) return def; } return NULL; @@ -345,7 +345,7 @@ ddef32_t *ED_FindGlobalFromProgs32 (progfuncs_t *progfuncs, char *name, progsnum for (i=1 ; inumglobaldefs ; i++) { def = &pr_progstate[prnum].globaldefs32[i]; - if (!strcmp(def->s_name,name) ) + if (!strcmp(def->s_name+progfuncs->stringtable,name) ) return def; } return NULL; @@ -359,7 +359,7 @@ ddef16_t *ED_FindTypeGlobalFromProgs16 (progfuncs_t *progfuncs, char *name, prog for (i=1 ; inumglobaldefs ; i++) { def = &pr_progstate[prnum].globaldefs16[i]; - if (!strcmp(def->s_name,name) ) + if (!strcmp(def->s_name+progfuncs->stringtable,name) ) { if (pr_progstate[prnum].types) { @@ -383,7 +383,7 @@ ddef32_t *ED_FindTypeGlobalFromProgs32 (progfuncs_t *progfuncs, char *name, prog for (i=1 ; inumglobaldefs ; i++) { def = &pr_progstate[prnum].globaldefs32[i]; - if (!strcmp(def->s_name,name) ) + if (!strcmp(def->s_name+progfuncs->stringtable,name) ) { if (pr_progstate[prnum].types) { @@ -461,7 +461,7 @@ dfunction_t *ED_FindFunction (progfuncs_t *progfuncs, char *name, progsnum_t *pr for (i=1 ; inumfunctions ; i++) { func = &pr_progstate[pnum].functions[i]; - if (!strcmp(func->s_name,name) ) + if (!strcmp(func->s_name+progfuncs->stringtable,name) ) return func; } return NULL; @@ -511,13 +511,13 @@ char *PR_ValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val) else { f = pr_progstate[(val->function & 0xff000000)>>24].functions + (val->function & ~0xff000000); - sprintf (line, "%i:%s()", (val->function & 0xff000000)>>24, f->s_name); + sprintf (line, "%i:%s()", (val->function & 0xff000000)>>24, f->s_name+progfuncs->stringtable); } } break; case ev_field: fielddef = ED_FieldAtOfs (progfuncs, val->_int ); - sprintf (line, ".%s (%i)", fielddef->s_name, val->_int); + sprintf (line, ".%s (%i)", fielddef->name, val->_int); break; case ev_void: sprintf (line, "void type"); @@ -603,12 +603,12 @@ char *PR_UglyValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val) else { f = pr_progstate[(val->function & 0xff000000)>>24].functions + (val->function & ~0xff000000); - sprintf (line, "%i:%s", (val->function & 0xff000000)>>24, f->s_name); + sprintf (line, "%i:%s", (val->function & 0xff000000)>>24, f->s_name+progfuncs->stringtable); } break; case ev_field: fielddef = ED_FieldAtOfs (progfuncs, val->_int ); - sprintf (line, "%s", fielddef->s_name); + sprintf (line, "%s", fielddef->name); break; case ev_void: sprintf (line, "void"); @@ -666,11 +666,11 @@ char *PR_UglyOldValueString (progfuncs_t *progfuncs, etype_t type, eval_t *val) break; case ev_function: f = pr_progstate[(val->function & 0xff000000)>>24].functions + (val->function & ~0xff000000); - sprintf (line, "%s", f->s_name); + sprintf (line, "%s", f->s_name+progfuncs->stringtable); break; case ev_field: fielddef = ED_FieldAtOfs (progfuncs, val->_int ); - sprintf (line, "%s", fielddef->s_name); + sprintf (line, "%s", fielddef->name); break; case ev_void: sprintf (line, "void"); @@ -763,7 +763,7 @@ char *PR_GlobalString (progfuncs_t *progfuncs, int ofs) else { s = PR_ValueString (progfuncs, def16->type, val); - sprintf (line,"%i(%s)%s", ofs, def16->s_name, s); + sprintf (line,"%i(%s)%s", ofs, def16->s_name+progfuncs->stringtable, s); } i = strlen(line); @@ -779,7 +779,7 @@ char *PR_GlobalString (progfuncs_t *progfuncs, int ofs) else { s = PR_ValueString (progfuncs, def32->type, val); - sprintf (line,"%i(%s)%s", ofs, def32->s_name, s); + sprintf (line,"%i(%s)%s", ofs, def32->s_name+progfuncs->stringtable, s); } i = strlen(line); @@ -807,14 +807,14 @@ char *PR_GlobalStringNoContents (progfuncs_t *progfuncs, int ofs) if (!def16) sprintf (line,"%i(?""?""?)", ofs); else - sprintf (line,"%i(%s)", ofs, def16->s_name); + sprintf (line,"%i(%s)", ofs, def16->s_name+progfuncs->stringtable); break; case 32: def32 = ED_GlobalAtOfs32(progfuncs, ofs); if (!def32) sprintf (line,"%i(?""?""?)", ofs); else - sprintf (line,"%i(%s)", ofs, def32->s_name); + sprintf (line,"%i(%s)", ofs, def32->s_name+progfuncs->stringtable); break; default: Sys_Error("Bad offset size in PR_GlobalStringNoContents"); @@ -855,7 +855,7 @@ void ED_Print (progfuncs_t *progfuncs, struct edict_s *ed) for (i=1 ; is_name; + name = d->name; if (name[strlen(name)-2] == '_') continue; // skip _x, _y, _z vars @@ -992,6 +992,7 @@ pbool ED_ParseEpair (progfuncs_t *progfuncs, void *base, ddefXX_t *key, char *s, fdef_t *def; char *v, *w; void *d; + string_t st; dfunction_t *func; int type; @@ -1022,8 +1023,8 @@ pbool ED_ParseEpair (progfuncs_t *progfuncs, void *base, ddefXX_t *key, char *s, switch (type) { case ev_string: - v = ED_NewString (progfuncs, s)-progfuncs->stringtable; - *(string_t *)d = v; + st = ED_NewString (progfuncs, s)-progfuncs->stringtable; + *(string_t *)d = st; break; case ev_float: @@ -1208,7 +1209,7 @@ char *ED_WriteGlobals(progfuncs_t *progfuncs, char *buffer) //switch first. for (i=0 ; inumglobaldefs ; i++) { def16 = &pr_globaldefs16[i]; - name = def16->s_name; + name = def16->s_name + progfuncs->stringtable; len = strlen(name); if (!*name) continue; @@ -1229,9 +1230,9 @@ char *ED_WriteGlobals(progfuncs_t *progfuncs, char *buffer) //switch first. v = (int *)¤t_progstate->globals[def16->ofs]; if ((v[0]&0xff000000)>>24 == (unsigned)curprogs) //same progs { - if (!*current_progstate->functions[v[0]&0x00ffffff].s_name) + if (!progfuncs->stringtable[current_progstate->functions[v[0]&0x00ffffff].s_name]) continue; - else if (!strcmp(current_progstate->functions[v[0]&0x00ffffff].s_name, name)) //names match. Assume function is at initial value. + else if (!strcmp(current_progstate->functions[v[0]&0x00ffffff].s_name+ progfuncs->stringtable, name)) //names match. Assume function is at initial value. continue; } @@ -1239,9 +1240,9 @@ char *ED_WriteGlobals(progfuncs_t *progfuncs, char *buffer) //switch first. if ((v[0]&0xff000000)>>24 == 0) if (!ED_FindFunction(progfuncs, name, NULL, curprogs)) //defined as extern { - if (!*pr_progstate[0].functions[v[0]&0x00ffffff].s_name) + if (!progfuncs->stringtable[pr_progstate[0].functions[v[0]&0x00ffffff].s_name]) continue; - else if (!strcmp(pr_progstate[0].functions[v[0]&0x00ffffff].s_name, name)) //same name. + else if (!strcmp(pr_progstate[0].functions[v[0]&0x00ffffff].s_name + progfuncs->stringtable, name)) //same name. continue; } @@ -1273,7 +1274,7 @@ char *ED_WriteGlobals(progfuncs_t *progfuncs, char *buffer) //switch first. for (i=0 ; inumglobaldefs ; i++) { def32 = &pr_globaldefs32[i]; - name = def32->s_name; + name = def32->s_name + progfuncs->stringtable; if (name[strlen(name)-2] == '_') continue; // skip _x, _y, _z vars (vector componants, which are saved as one vector not 3 floats) @@ -1290,13 +1291,13 @@ char *ED_WriteGlobals(progfuncs_t *progfuncs, char *buffer) //switch first. { v = (int *)¤t_progstate->globals[def32->ofs]; if ((v[0]&0xff000000)>>24 == (unsigned)curprogs) //same progs - if (!strcmp(current_progstate->functions[v[0]&0x00ffffff].s_name, name)) //names match. Assume function is at initial value. + if (!strcmp(current_progstate->functions[v[0]&0x00ffffff].s_name+ progfuncs->stringtable, name)) //names match. Assume function is at initial value. continue; if (curprogs!=0) if ((v[0]&0xff000000)>>24 == 0) if (!ED_FindFunction(progfuncs, name, NULL, curprogs)) //defined as extern - if (!strcmp(pr_progstate[0].functions[v[0]&0x00ffffff].s_name, name)) //same name. + if (!strcmp(pr_progstate[0].functions[v[0]&0x00ffffff].s_name+ progfuncs->stringtable, name)) //same name. continue; //else function has been redirected externally. @@ -1342,9 +1343,9 @@ char *ED_WriteEdict(progfuncs_t *progfuncs, edictrun_t *ed, char *buffer, pbool for (i=0 ; is_name; + name = d->name; len = strlen(name); - if (name[len-2] == '_' && (name[len-1] == 'x' || name[len-1] == 'y' || name[len-1] == 'z')) + if (len>4 && (name[len-2] == '_' && (name[len-1] == 'x' || name[len-1] == 'y' || name[len-1] == 'z'))) continue; // skip _x, _y, _z vars v = (int *)((char*)ed->fields + d->ofs*4); @@ -1410,10 +1411,10 @@ char *SaveCallStack (progfuncs_t *progfuncs, char *s) sprintf(buffer, "//%i %s\n", progs, pr_progstate[progs].filename); AddS (buffer); } - if (!*f->s_file) - sprintf(buffer, "\t\"%i:%s\"\n", progs, f->s_name); + if (!f->s_file) + sprintf(buffer, "\t\"%i:%s\"\n", progs, f->s_name+progfuncs->stringtable); else - sprintf(buffer, "\t\"%i:%s\" //%s\n", progs, f->s_name, f->s_file); + sprintf(buffer, "\t\"%i:%s\" //%s\n", progs, f->s_name+progfuncs->stringtable, f->s_file+progfuncs->stringtable); AddS (buffer); AddS ("\t{\n"); @@ -1430,22 +1431,22 @@ char *SaveCallStack (progfuncs_t *progfuncs, char *s) if (local->type == ev_entity) { //go safly. int n; - sprintf(buffer, "\t\t\"%s\"\t\"entity INVALID POINTER\"\n", local->s_name); + sprintf(buffer, "\t\t\"%s\"\t\"entity INVALID POINTER\"\n", local->s_name+progfuncs->stringtable); for (n = 0; n < sv_num_edicts; n++) { if (prinst->edicttable[n] == (struct edict_s *)PROG_TO_EDICT(progfuncs, ((eval_t*)(globalbase - f->locals+arg))->edict)) { - sprintf(buffer, "\t\t\"%s\" \"entity %i\"\n", local->s_name, n); + sprintf(buffer, "\t\t\"%s\" \"entity %i\"\n", local->s_name+progfuncs->stringtable, n); break; } } } else - sprintf(buffer, "\t\t\"%s\"\t\"%s\"\n", local->s_name, PR_ValueString(progfuncs, local->type, (eval_t*)(globalbase - f->locals+arg))); + sprintf(buffer, "\t\t\"%s\"\t\"%s\"\n", local->s_name+progfuncs->stringtable, PR_ValueString(progfuncs, local->type, (eval_t*)(globalbase - f->locals+arg))); //} //__except(EXCEPTION_EXECUTE_HANDLER) //{ -// sprintf(buffer, "\t\t\"%s\" \"ILLEGAL POINTER\"\n", local->s_name); +// sprintf(buffer, "\t\t\"%s\" \"ILLEGAL POINTER\"\n", local->s_name+progfuncs->stringtable); //} if (local->type == ev_vector) arg+=2; @@ -1710,7 +1711,7 @@ int LoadEnts(progfuncs_t *progfuncs, char *file, float killonspawnflags) dfunction_t *f; if ((var = GetEdictFieldValue (progfuncs, (struct edict_s *)ed, "classname", NULL))) { - f = ED_FindFunction(progfuncs, var->string, NULL, -1); + f = ED_FindFunction(progfuncs, var->string + progfuncs->stringtable, NULL, -1); if (f) { var = (eval_t *)((int *)pr_globals + ED_FindGlobalOfs(progfuncs, "self")); @@ -2089,7 +2090,7 @@ char *SaveEnt (progfuncs_t *progfuncs, char *buf, int *size, struct edict_s *ed) for (i=0 ; is_name; + name = d->name; if (name[strlen(name)-2] == '_') continue; // skip _x, _y, _z vars @@ -2181,7 +2182,7 @@ PR_LoadProgs int PR_ReallyLoadProgs (progfuncs_t *progfuncs, char *filename, int headercrc, progstate_t *progstate, pbool complain) { unsigned int i, type; - extensionbuiltin_t *eb; +// extensionbuiltin_t *eb; // float fl; int len; // int num; @@ -2205,6 +2206,8 @@ int PR_ReallyLoadProgs (progfuncs_t *progfuncs, char *filename, int headercrc, p int reorg = prinst->reorganisefields; + int stringadjust; + current_progstate = progstate; strcpy(current_progstate->filename, filename); @@ -2419,7 +2422,7 @@ retry: if (pr_progs->blockscompressed & 16) //string table { len=sizeof(char)*pr_progs->numstrings; - s = PRAddressableAlloc(progfuncs, len); + s = PRHunkAlloc(progfuncs, len); QC_decode(progfuncs, LittleLong(*(int *)pr_strings), len, 2, (char *)(((int *)pr_strings)+1), s); pr_strings = (char *)s; @@ -2427,10 +2430,10 @@ retry: if (pr_progs->blockscompressed & 32) //globals { len=sizeof(float)*pr_progs->numglobals; - s = PRAddressableAlloc(progfuncs, len); + s = PRHunkAlloc(progfuncs, len); QC_decode(progfuncs, LittleLong(*(int *)pr_globals), len, 2, (char *)(((int *)pr_globals)+1), s); - glob = current_progstate->globals = (float *)s; + glob = pr_globals = (float *)s; } if (pr_linenums && pr_progs->blockscompressed & 64) //line numbers { @@ -2450,6 +2453,21 @@ retry: } } + len=sizeof(char)*pr_progs->numstrings; + s = PRAddressableAlloc(progfuncs, len); + memcpy(s, pr_strings, len); + pr_strings = (char *)s; + + len=sizeof(float)*pr_progs->numglobals; + s = PRAddressableAlloc(progfuncs, len); + memcpy(s, pr_globals, len); + glob = pr_globals = (float *)s; + + if (progfuncs->stringtable) + stringadjust = pr_strings - progfuncs->stringtable; + else + stringadjust = 0; + if (!pr_linenums) { unsigned int lnotype = *(unsigned int*)"LNOF"; @@ -2510,16 +2528,13 @@ retry: fnc[i].numparms = LittleLong (fnc[i].numparms); fnc[i].locals = LittleLong (fnc[i].locals); #endif - fnc[i].s_name += (int)pr_strings; - fnc[i].s_file += (int)pr_strings; - - if (!strncmp(fnc[i].s_name, "ext_", 4)) +/* if (!strncmp(fnc[i].s_name+pr_strings, "ext_", 4)) { for (eb = extensionbuiltin; eb; eb = eb->prev) { if (*eb->name == '_') { - if (!strncmp(fnc[i].s_name+4, eb->name+1, strlen(eb->name+1))) + if (!strncmp(fnc[i].s_name+pr_strings+4, eb->name+1, strlen(eb->name+1))) { fnc[i].first_statement = -0x7fffffff; *(void**)&fnc[i].profile = (void*)eb->func; @@ -2534,6 +2549,9 @@ retry: } } } +*/ + fnc[i].s_name += stringadjust; + fnc[i].s_file += stringadjust; } //actual global values @@ -2555,7 +2573,7 @@ retry: pr_types[i].size = LittleLong(current_progstate->types[i].size); pr_types[i].name = (string_t)LittleLong((long)current_progstate->types[i].name); #endif - pr_types[i].name += (int)pr_strings; + pr_types[i].name += stringadjust; } } @@ -2574,7 +2592,7 @@ retry: gd16[i].ofs = LittleShort (gd16[i].ofs); gd16[i].s_name = (string_t)LittleLong ((long)gd16[i].s_name); #endif - gd16[i].s_name += (int)pr_strings; + gd16[i].s_name += stringadjust; } //byteswap fields and fix name offets. Also register the fields (which will result in some offset adjustments in the globals segment). @@ -2585,8 +2603,6 @@ retry: fld16[i].ofs = LittleShort (fld16[i].ofs); fld16[i].s_name = (string_t)LittleLong ((long)fld16[i].s_name); #endif - fld16[i].s_name += (int)pr_strings; - if (reorg) { if (pr_types) @@ -2595,12 +2611,13 @@ retry: type = fld16[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL); if (progfuncs->fieldadjust) //we need to make sure all fields appear in thier origional place. - QC_RegisterFieldVar(progfuncs, type, fld16[i].s_name, 4*(fld16[i].ofs+progfuncs->fieldadjust), -1); + QC_RegisterFieldVar(progfuncs, type, fld16[i].s_name+pr_strings, 4*(fld16[i].ofs+progfuncs->fieldadjust), -1); else if (type == ev_vector) //emit vector vars early, so thier fields cannot be alocated before the vector itself. (useful against scramblers) { - QC_RegisterFieldVar(progfuncs, type, fld16[i].s_name, -1, -1); + QC_RegisterFieldVar(progfuncs, type, fld16[i].s_name+pr_strings, -1, -1); } } + fld16[i].s_name += stringadjust; } break; case 32: @@ -2611,7 +2628,7 @@ retry: pr_globaldefs32[i].ofs = LittleLong (pr_globaldefs32[i].ofs); pr_globaldefs32[i].s_name = (string_t)LittleLong ((long)pr_globaldefs32[i].s_name); #endif - pr_globaldefs32[i].s_name += (int)pr_strings; + pr_globaldefs32[i].s_name += stringadjust; } for (i=0 ; inumfielddefs ; i++) @@ -2621,7 +2638,6 @@ retry: pr_fielddefs32[i].ofs = LittleLong (pr_fielddefs32[i].ofs); pr_fielddefs32[i].s_name = (string_t)LittleLong ((long)pr_fielddefs32[i].s_name); #endif - pr_fielddefs32[i].s_name += (int)pr_strings; if (reorg) { @@ -2630,8 +2646,9 @@ retry: else type = pr_fielddefs32[i].type & ~(DEF_SHARED|DEF_SAVEGLOBAL); if (type == ev_vector) - QC_RegisterFieldVar(progfuncs, type, pr_fielddefs32[i].s_name, -1, -1); + QC_RegisterFieldVar(progfuncs, type, pr_fielddefs32[i].s_name+pr_strings, -1, -1); } + pr_fielddefs32[i].s_name += stringadjust; } break; default: @@ -2760,7 +2777,7 @@ retry: switch(type) { case ev_field: - QC_AddSharedFieldVar(progfuncs, i); + QC_AddSharedFieldVar(progfuncs, i, pr_strings - stringadjust); break; case ev_string: if (((unsigned int *)glob)[gd16[i].ofs]>=progstate->progs->numstrings) @@ -2769,11 +2786,11 @@ retry: { if (pr_strings[((int *)glob)[gd16[i].ofs]]) //quakec uses string tables. 0 must remain null, or 'if (s)' can break. { - ((int *)glob)[gd16[i].ofs] += (int)pr_strings-progfuncs->stringtable; + ((int *)glob)[gd16[i].ofs] += stringadjust; isfriked = false; } else - *(char **)&((int *)glob)[gd16[i].ofs] = NULL; + ((int *)glob)[gd16[i].ofs] = 0; } break; case ev_function: @@ -2807,11 +2824,6 @@ retry: s+=strlen(s)+1; } } - - eval = PR_FindGlobal(progfuncs, "thisprogs", progstype); - if (eval) - eval->prog = progstype; - break; case 32: for (i=0 ; inumglobaldefs ; i++) @@ -2832,17 +2844,14 @@ retry: switch(type) { case ev_field: - QC_AddSharedFieldVar(progfuncs, i); + QC_AddSharedFieldVar(progfuncs, i, pr_strings - stringadjust); break; case ev_string: if (pr_strings[((int *)glob)[pr_globaldefs32[i].ofs]]) //quakec uses string tables. 0 must remain null, or 'if (s)' can break. { - ((int *)glob)[pr_globaldefs32[i].ofs] += (int)pr_strings-progfuncs->stringtable; + ((int *)glob)[pr_globaldefs32[i].ofs] += stringadjust; isfriked = false; } - else if (isfriked != -1) - *(char **)&((int *)glob)[pr_globaldefs32[i].ofs] = NULL; - break; case ev_function: if (((int *)glob)[pr_globaldefs32[i].ofs]) //don't change null funcs @@ -2867,19 +2876,10 @@ retry: s+=strlen(s)+1; } } - - eval = PR_FindGlobal(progfuncs, "thisprogs", progstype); - if (eval) - eval->prog = progstype; - break; default: Sys_Error("Bad int size"); } - if (!isfriked) - pr_strings=NULL; -// else -// printf("String-Stripped support enabled.\n"); if ((isfriked && pr_typecurrent)) //friked progs only allow one file. { @@ -2888,8 +2888,15 @@ retry: pr_progs=NULL; return false; } + + pr_strings+=stringadjust; if (!progfuncs->stringtable) - progfuncs->stringtable = (int)pr_strings; + progfuncs->stringtable = pr_strings; + + eval = PR_FindGlobal(progfuncs, "thisprogs", progstype); + if (eval) + eval->prog = progstype; + return true; } diff --git a/engine/qclib/pr_exec.c b/engine/qclib/pr_exec.c index 0bbb6f5b..fde43478 100644 --- a/engine/qclib/pr_exec.c +++ b/engine/qclib/pr_exec.c @@ -110,10 +110,10 @@ void PR_StackTrace (progfuncs_t *progfuncs) printf ("<%s>\n", pr_progstate[progs].filename); } - if (!*f->s_file) + if (!f->s_file) printf ("stripped : %s\n", f->s_name); else - printf ("%12s : %s\n", f->s_file, f->s_name); + printf ("%12s : %s\n", f->s_file+progfuncs->stringtable, f->s_name+progfuncs->stringtable); #ifdef STACKTRACE @@ -127,7 +127,7 @@ void PR_StackTrace (progfuncs_t *progfuncs) } else { - printf(" %s: %s\n", local->s_name, PR_ValueString(progfuncs, local->type, (eval_t*)(globalbase - f->locals+arg))); + printf(" %s: %s\n", local->s_name+progfuncs->stringtable, PR_ValueString(progfuncs, local->type, (eval_t*)(globalbase - f->locals+arg))); if (local->type == ev_vector) arg+=2; } @@ -330,7 +330,7 @@ ddef32_t *ED_FindLocalOrGlobal(progfuncs_t *progfuncs, char *name, eval_t **val) def16 = ED_GlobalAtOfs16(progfuncs, pr_xfunction->parm_start+i); if (!def16) continue; - if (!strcmp(def16->s_name, name)) + if (!strcmp(def16->s_name+progfuncs->stringtable, name)) { *val = (eval_t *)&pr_progstate[pr_typecurrent].globals[pr_xfunction->parm_start+i]; @@ -358,7 +358,7 @@ ddef32_t *ED_FindLocalOrGlobal(progfuncs_t *progfuncs, char *name, eval_t **val) def32 = ED_GlobalAtOfs32(progfuncs, pr_xfunction->parm_start+i); if (!def32) continue; - if (!strcmp(def32->s_name, name)) + if (!strcmp(def32->s_name+progfuncs->stringtable, name)) { *val = (eval_t *)&pr_progstate[pr_typecurrent].globals[pr_xfunction->parm_start+i]; @@ -642,7 +642,7 @@ int PR_ToggleBreakpoint(progfuncs_t *progfuncs, char *filename, int linenum, int { for (f = pr_progstate[pn].functions, fl = 0; fl < pr_progstate[pn].progs->numfunctions; f++, fl++) { - if (!strcmp(f->s_name, filename)) + if (!strcmp(f->s_name+progfuncs->stringtable, filename)) { i = f->first_statement; switch(pr_progstate[pn].intsize) diff --git a/engine/qclib/pr_multi.c b/engine/qclib/pr_multi.c index c10b9aaa..23a34953 100644 --- a/engine/qclib/pr_multi.c +++ b/engine/qclib/pr_multi.c @@ -208,7 +208,7 @@ int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, i //look for an existing match for (i = 0; i < numfields; i++) { - if (!strcmp(name, field[i].s_name)) + if (!strcmp(name, field[i].name)) { if (field[i].type != type) { @@ -239,7 +239,7 @@ int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, i //try to add a new one fnum = numfields; numfields++; - field[fnum].s_name = name; + field[fnum].name = name; if (type == ev_vector) //resize with the following floats (this is where I think I went wrong) { char *n; @@ -265,7 +265,7 @@ int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, i { if (type == ev_float && field[i].type == ev_vector) //check names { - if (strncmp(field[i].s_name, name, strlen(field[i].s_name))) + if (strncmp(field[i].name, name, strlen(field[i].name))) Sys_Error("Duplicated offset"); } else @@ -294,7 +294,7 @@ int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, i //called if a global is defined as a field -void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num) +void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num, char *stringtable) { // progstate_t *p; // int pnum; @@ -323,14 +323,14 @@ void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num) case 16: for (i=1 ; inumfielddefs; i++) { - if (!strcmp(pr_fielddefs16[i].s_name, pr_globaldefs16[num].s_name)) + if (!strcmp(pr_fielddefs16[i].s_name+stringtable, pr_globaldefs16[num].s_name+stringtable)) { - *(int *)&pr_globals[pr_globaldefs16[num].ofs] = QC_RegisterFieldVar(progfuncs, pr_fielddefs16[i].type, pr_globaldefs16[num].s_name, -1, *(int *)&pr_globals[pr_globaldefs16[num].ofs])-progfuncs->fieldadjust; + *(int *)&pr_globals[pr_globaldefs16[num].ofs] = QC_RegisterFieldVar(progfuncs, pr_fielddefs16[i].type, pr_globaldefs16[num].s_name+stringtable, -1, *(int *)&pr_globals[pr_globaldefs16[num].ofs])-progfuncs->fieldadjust; return; } } - s = pr_globaldefs16[num].s_name; + s = pr_globaldefs16[num].s_name+stringtable; for (i = 0; i < numfields; i++) { @@ -349,14 +349,14 @@ void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num) case 32: for (i=1 ; inumfielddefs; i++) { - if (!strcmp(pr_fielddefs32[i].s_name, pr_globaldefs32[num].s_name)) + if (!strcmp(pr_fielddefs32[i].s_name+stringtable, pr_globaldefs32[num].s_name+stringtable)) { - *(int *)&pr_globals[pr_globaldefs32[num].ofs] = QC_RegisterFieldVar(progfuncs, pr_fielddefs32[i].type, pr_globaldefs32[num].s_name, -1, *(int *)&pr_globals[pr_globaldefs32[num].ofs])-progfuncs->fieldadjust; + *(int *)&pr_globals[pr_globaldefs32[num].ofs] = QC_RegisterFieldVar(progfuncs, pr_fielddefs32[i].type, pr_globaldefs32[num].s_name+stringtable, -1, *(int *)&pr_globals[pr_globaldefs32[num].ofs])-progfuncs->fieldadjust; return; } } - s = pr_globaldefs32[num].s_name; + s = pr_globaldefs32[num].s_name+stringtable; for (i = 0; i < numfields; i++) { @@ -370,7 +370,7 @@ void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num) //oh well, must be a parameter. if (*(int *)&pr_globals[pr_globaldefs32[num].ofs]) - Sys_Error("QCLIB: Global field var with no matching field \"%s\", from offset %i", pr_globaldefs32[num].s_name, *(int *)&pr_globals[pr_globaldefs32[num].ofs]); + Sys_Error("QCLIB: Global field var with no matching field \"%s\", from offset %i", pr_globaldefs32[num].s_name+stringtable, *(int *)&pr_globals[pr_globaldefs32[num].ofs]); return; default: Sys_Error("Bad bits"); diff --git a/engine/qclib/progsint.h b/engine/qclib/progsint.h index 2dcb5179..7770b9cc 100644 --- a/engine/qclib/progsint.h +++ b/engine/qclib/progsint.h @@ -90,7 +90,7 @@ char *VARGS qcva (char *text, ...); void QC_InitShares(progfuncs_t *progfuncs); void QC_StartShares(progfuncs_t *progfuncs); void QC_AddSharedVar(progfuncs_t *progfuncs, int num, int type); -void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num); +void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num, char *stringtable); int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, int requestedpos, int origionalofs); pbool Decompile(progfuncs_t *progfuncs, char *fname); int PR_ToggleBreakpoint(progfuncs_t *progfuncs, char *filename, int linenum, int flag); @@ -413,8 +413,8 @@ var(int, addressablesize); #define addressablesize prinst->addressablesize -var(extensionbuiltin_t *, extensionbuiltin); -#define extensionbuiltin prinst->extensionbuiltin +//var(extensionbuiltin_t *, extensionbuiltin); +//#define extensionbuiltin prinst->extensionbuiltin struct edict_s **edicttable; } prinst_t; diff --git a/engine/qclib/progslib.h b/engine/qclib/progslib.h index e07b21cb..3586f7de 100644 --- a/engine/qclib/progslib.h +++ b/engine/qclib/progslib.h @@ -112,7 +112,7 @@ struct progfuncs_s { int *callargc; //number of args of built-in call void (*RegisterBuiltin) (progfuncs_t *prinst, char *, builtin_t); - int stringtable; //qc strings are all relative. add to a qc string. this is required for support of frikqcc progs that strip string immediates. + char *stringtable; //qc strings are all relative. add to a qc string. this is required for support of frikqcc progs that strip string immediates. int fieldadjust; //FrikQCC style arrays can cause problems due to field remapping. This causes us to leave gaps but offsets identical. struct qcthread_s *(*Fork) (progfuncs_t *prinst); @@ -165,7 +165,7 @@ typedef struct progexterns_s { } progparms_t, progexterns_t; void QC_AddSharedVar(progfuncs_t *progfuncs, int start, int size); -void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num); +void QC_AddSharedFieldVar(progfuncs_t *progfuncs, int num, char *relstringtable); #if defined(QCLIBDLL_EXPORTS) __declspec(dllexport) @@ -257,7 +257,7 @@ typedef union eval_s #define G_PROG(o) (*(progsnum_t *)&((float *)pr_globals)[o]) //simply so it's nice and easy to change... #define PR_GetString(p,s) (s?s + p->stringtable:"") -#define PR_GetStringOfs(p,o) (G_INT(o)?(char *)G_INT(o) + p->stringtable:"") +#define PR_GetStringOfs(p,o) (G_INT(o)?G_INT(o) + p->stringtable:"") #define PR_SetString(p, s) ((s&&*s)?(s - p->stringtable):0) #define PR_NewString(p, s) (PR_AddString(p, s) - p->stringtable) diff --git a/engine/qclib/progtype.h b/engine/qclib/progtype.h index 62f2ebf4..18d98d2e 100644 --- a/engine/qclib/progtype.h +++ b/engine/qclib/progtype.h @@ -14,5 +14,5 @@ typedef int pbool; #endif typedef int progsnum_t; typedef int func_t; -typedef char *string_t; +typedef int string_t; diff --git a/engine/qclib/qcdecomp.c b/engine/qclib/qcdecomp.c index d71d6825..e6f600d5 100644 --- a/engine/qclib/qcdecomp.c +++ b/engine/qclib/qcdecomp.c @@ -42,8 +42,8 @@ QCC_type_t *QCC_PR_NewType (char *name, int basictype); jmp_buf decompilestatementfailure; -#if 0 -bool Decompile(progfuncs_t *progfuncs, char *fname) +#if 1 +pbool Decompile(progfuncs_t *progfuncs, char *fname) { return false; } @@ -943,7 +943,7 @@ pbool Decompile(progfuncs_t *progfuncs, char *fname) case ev_function: //wierd - WriteAsmStatements(progfuncs, &progs, ((int *)progs.globals)[pr_globaldefs16[i].ofs], f, pr_globaldefs16[i].s_name); + WriteAsmStatements(progfuncs, &progs, ((int *)progs.globals)[pr_globaldefs16[i].ofs], f, pr_globaldefs16[i].s_name+progfuncs->stringtable); break; case ev_pointer: diff --git a/engine/server/net_preparse.c b/engine/server/net_preparse.c index 85f7fdf5..c15bf772 100644 --- a/engine/server/net_preparse.c +++ b/engine/server/net_preparse.c @@ -412,7 +412,7 @@ void NPP_NQWriteByte(int dest, qbyte data) //replacement write func (nq to qw) multicasttype=MULTICAST_PHS; break; - case 74: //TE_FLAMEJET + case DPTE_FLAMEJET: //TE_FLAMEJET protocollen = sizeofcoord*6 +sizeof(qbyte)*3; multicastpos = 2; multicasttype=MULTICAST_PVS; @@ -424,6 +424,12 @@ void NPP_NQWriteByte(int dest, qbyte data) //replacement write func (nq to qw) multicasttype=MULTICAST_PHS; break; + case DPTE_SMOKE: + protocollen = sizeofcoord*6+sizeof(qbyte)*3; + multicastpos = 2; + multicasttype=MULTICAST_PHS; + break; + case 79: protocollen = sizeofcoord*6+sizeof(qbyte)*3; multicastpos = 2; diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index 76cc7114..e4e8edac 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -407,7 +407,7 @@ void PR_LoadGlabalStruct(void) nqglobalvars_t *pr_globals = pr_nqglobal_struct; #define globalfloat(need,name) ((nqglobalvars_t*)pr_nqglobal_struct)->name = (float *)PR_FindGlobal(svprogfuncs, #name, 0); if (need && !((nqglobalvars_t*)pr_globals)->name) SV_Error("Could not find \""#name"\" export in progs\n"); #define globalint(need,name) ((nqglobalvars_t*)pr_globals)->name = (int *)PR_FindGlobal(svprogfuncs, #name, 0); if (need && !((nqglobalvars_t*)pr_globals)->name) SV_Error("Could not find export \""#name"\" in progs\n"); -#define globalstring(need,name) ((nqglobalvars_t*)pr_globals)->name = (char **)PR_FindGlobal(svprogfuncs, #name, 0); if (need && !((nqglobalvars_t*)pr_globals)->name) SV_Error("Could not find export \""#name"\" in progs\n"); +#define globalstring(need,name) ((nqglobalvars_t*)pr_globals)->name = (int *)PR_FindGlobal(svprogfuncs, #name, 0); if (need && !((nqglobalvars_t*)pr_globals)->name) SV_Error("Could not find export \""#name"\" in progs\n"); #define globalvec(need,name) ((nqglobalvars_t*)pr_globals)->V_##name = (vec3_t *)PR_FindGlobal(svprogfuncs, #name, 0); if (need && !((nqglobalvars_t*)pr_globals)->V_##name) SV_Error("Could not find export \""#name"\" in progs\n"); #define globalfunc(need,name) ((nqglobalvars_t*)pr_globals)->name = (func_t *)PR_FindGlobal(svprogfuncs, #name, 0); if (need && !((nqglobalvars_t*)pr_globals)->name) SV_Error("Could not find export \""#name"\" in progs\n"); // globalint(pad); @@ -1434,10 +1434,10 @@ char *PF_VarString (progfuncs_t *prinst, int first, globalvars_t *pr_globals) //#define RETURN_EDICT(pf, e) (((int *)pr_globals)[OFS_RETURN] = EDICT_TO_PROG(pf, e)) -#define RETURN_SSTRING(s) (*(char **)&((int *)pr_globals)[OFS_RETURN] = PR_SetString(prinst, s)) //static - exe will not change it. -#define RETURN_TSTRING(s) (*(char **)&((int *)pr_globals)[OFS_RETURN] = PR_SetString(prinst, s)) //temp (static but cycle buffers?) -#define RETURN_CSTRING(s) (*(char **)&((int *)pr_globals)[OFS_RETURN] = PR_SetString(prinst, s)) //semi-permanant. (hash tables?) -#define RETURN_PSTRING(s) (*(char **)&((int *)pr_globals)[OFS_RETURN] = PR_NewString(prinst, s)) //permanant +#define RETURN_SSTRING(s) (((int *)pr_globals)[OFS_RETURN] = PR_SetString(prinst, s)) //static - exe will not change it. +#define RETURN_TSTRING(s) (((int *)pr_globals)[OFS_RETURN] = PR_SetString(prinst, s)) //temp (static but cycle buffers?) +#define RETURN_CSTRING(s) (((int *)pr_globals)[OFS_RETURN] = PR_SetString(prinst, s)) //semi-permanant. (hash tables?) +#define RETURN_PSTRING(s) (((int *)pr_globals)[OFS_RETURN] = PR_NewString(prinst, s)) //permanant /* =============================================================================== @@ -3322,7 +3322,8 @@ void PF_FindString (progfuncs_t *prinst, struct globalvars_s *pr_globals) { int e; int f; - char *s, *t; + char *s; + string_t t; edict_t *ed; e = G_EDICTNUM(prinst, OFS_PARM0); @@ -4760,7 +4761,7 @@ void PF_makestatic (progfuncs_t *prinst, struct globalvars_s *pr_globals) state->colormap = ent->v->colormap; state->skinnum = ent->v->skin; state->effects = ent->v->effects; - state->drawflags = ent->v->drawflags; + state->hexen2flags = ent->v->drawflags; state->abslight = (int)(ent->v->abslight*255) & 255; state->trans = ent->v->alpha; if (!state->trans) @@ -5659,7 +5660,7 @@ void PF_fgets (progfuncs_t *prinst, struct globalvars_s *pr_globals) if (!pr_string_temp[0] && !*s) G_INT(OFS_RETURN) = 0; //EOF else - G_INT(OFS_RETURN) = (int)pr_string_temp - prinst->stringtable; + G_INT(OFS_RETURN) = pr_string_temp - prinst->stringtable; } void PF_fputs (progfuncs_t *prinst, struct globalvars_s *pr_globals) @@ -5935,6 +5936,7 @@ lh_extension_t QSG_Extensions[] = { #endif {"DP_EF_BLUE"}, //hah!! This is QuakeWorld!!! {"DP_EF_FULLBRIGHT"}, //Rerouted to hexen2 support. + {"DP_EF_NODRAW"}, //implemented by sending it with no modelindex {"DP_EF_RED"}, {"DP_EXTRA_TEMPSTRING"}, //ftos returns 16 temp buffers. {"DP_HALFLIFE_MAP_CVAR"}, @@ -8919,6 +8921,8 @@ void PR_RegisterFields(void) //it's just easier to do it this way. //dp extra fields fieldentity(nodrawtoclient); fieldentity(drawonlytoclient); + fieldentity(viewmodelforclient); + fieldentity(exteriormodeltoclient); //UDC_EXTEFFECT... yuckie PR_RegisterFieldVar(svprogfuncs, ev_float, "fieldcolor", (int)&((entvars_t*)0)->seefcolour, -1); diff --git a/engine/server/progdefs.h b/engine/server/progdefs.h index 3c39a252..30a9f8d5 100644 --- a/engine/server/progdefs.h +++ b/engine/server/progdefs.h @@ -198,6 +198,8 @@ typedef struct entvars_s //dp extra fields int nodrawtoclient; int drawonlytoclient; + int viewmodelforclient; + int exteriormodeltoclient; //EXT_DIMENSION_VISIBLE float dimension_see; diff --git a/engine/server/sv_ents.c b/engine/server/sv_ents.c index 0e2024e6..55d3bd09 100644 --- a/engine/server/sv_ents.c +++ b/engine/server/sv_ents.c @@ -519,11 +519,14 @@ void SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qb evenmorebits |= U_FATNESS; #endif - if ( to->drawflags != from->drawflags && protext & PEXT_HEXEN2) + if ( to->hexen2flags != from->hexen2flags && protext & PEXT_HEXEN2) evenmorebits |= U_DRAWFLAGS; if ( to->abslight != from->abslight && protext & PEXT_HEXEN2) evenmorebits |= U_ABSLIGHT; + if (to->dpflags) + evenmorebits |= U_DPFLAGS; + if (evenmorebits&0xff00) evenmorebits |= U_YETMORE; if (evenmorebits&0x00ff) @@ -600,9 +603,12 @@ void SV_WriteDelta (entity_state_t *from, entity_state_t *to, sizebuf_t *msg, qb #endif if (evenmorebits & U_DRAWFLAGS) - MSG_WriteByte (msg, to->drawflags); + MSG_WriteByte (msg, to->hexen2flags); if (evenmorebits & U_ABSLIGHT) MSG_WriteByte (msg, to->abslight); + + if (evenmorebits & U_DPFLAGS) + MSG_WriteByte (msg, to->dpflags); } /* @@ -2080,7 +2086,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore state->colormap = clent->v->colormap; state->skinnum = clent->v->skin; state->effects = clent->v->effects; - state->drawflags = clent->v->drawflags; + state->hexen2flags = clent->v->drawflags; state->abslight = clent->v->abslight; #ifdef PEXT_SCALE @@ -2131,8 +2137,6 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore if (progstype != PROG_QW) { - if (progstype == PROG_H2 && (int)ent->v->effects & H2EF_NODRAW) - continue; if ((int)ent->v->effects & EF_MUZZLEFLASH) { if (needcleanup < e) @@ -2280,6 +2284,32 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore } } +// these are bits for the 'flags' field of the entity_state_t +#define RENDER_STEP 1 +#define RENDER_GLOWTRAIL 2 +#define RENDER_VIEWMODEL 4 +#define RENDER_EXTERIORMODEL 8 +#define RENDER_LOWPRECISION 16 // send as low precision coordinates to save bandwidth +#define RENDER_COLORMAPPED 32 + + state->dpflags = 0; + if (ent->v->viewmodelforclient) + { + if (ent->v->viewmodelforclient == EDICT_TO_PROG(svprogfuncs, client->edict)) + state->dpflags |= RENDER_VIEWMODEL; +// else +// { //noone else sees it. +// pack->num_entities--; +// continue; +// } + } + if (ent->v->exteriormodeltoclient) + { + if (ent->v->exteriormodeltoclient == EDICT_TO_PROG(svprogfuncs, client->edict)) + state->dpflags |= RENDER_VIEWMODEL; + //everyone else sees it normally. + } + state->number = e; state->flags = 0; VectorCopy (ent->v->origin, state->origin); @@ -2289,7 +2319,7 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore state->colormap = ent->v->colormap; state->skinnum = ent->v->skin; state->effects = ent->v->effects; - state->drawflags = ent->v->drawflags; + state->hexen2flags = ent->v->drawflags; state->abslight = (int)(ent->v->abslight*255) & 255; if ((int)ent->v->flags & FL_CLASS_DEPENDENT && client->playerclass) { @@ -2307,17 +2337,32 @@ void SV_WriteEntitiesToClient (client_t *client, sizebuf_t *msg, qboolean ignore if (state->effects & EF_FULLBRIGHT) { state->abslight = 255; - state->drawflags |= MLS_ABSLIGHT; + state->hexen2flags |= MLS_ABSLIGHT; } if (progstype != PROG_QW) //don't send extra nq effects to a qw client. + { + //EF_NODRAW doesn't draw the model. + //The client still needs to know about it though, as it might have other effects on it. + if (progstype == PROG_H2) + { + if (state->effects & H2EF_NODRAW) + state->modelindex = 0; + } + else + { + if (state->effects & NQEF_NODRAW) + state->modelindex = 0; + } + state->effects &= EF_BRIGHTLIGHT | EF_DIMLIGHT; + } #ifdef PEXT_SCALE state->scale = ent->v->scale; #endif #ifdef PEXT_TRANS state->trans = ent->v->alpha; - if (!state->trans) + if (!ent->v->alpha) state->trans = 1; //QSG_DIMENSION_PLANES - if the only shared dimensions are ghost dimensions, Set half alpha. diff --git a/engine/server/sv_init.c b/engine/server/sv_init.c index 06668c68..e452ab87 100644 --- a/engine/server/sv_init.c +++ b/engine/server/sv_init.c @@ -478,7 +478,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us func_t f; char *file; - gametype_e oldgametype; + gametype_e newgametype; edict_t *ent; #ifdef Q2SERVER @@ -724,34 +724,25 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us sv.state = ss_loading; - oldgametype = svs.gametype; + newgametype = svs.gametype; #ifdef Q3SERVER if (SVQ3_InitGame()) - svs.gametype = GT_QUAKE3; + newgametype = GT_QUAKE3; else #endif #ifdef Q2SERVER if ((sv.worldmodel->fromgame == fg_quake2 || sv.worldmodel->fromgame == fg_quake3) && !*progs.string && SVQ2_InitGameProgs()) //these are the rules for running a q2 server - svs.gametype = GT_QUAKE2; //we loaded the dll + newgametype = GT_QUAKE2; //we loaded the dll else #endif { - svs.gametype = GT_PROGS; //let's just hope this loads. + newgametype = GT_PROGS; //let's just hope this loads. Q_InitProgs(); } -#ifdef Q3SERVER - if (svs.gametype != GT_QUAKE3) - SVQ3_ShutdownGame(); -#endif -#ifdef Q2SERVER - if (svs.gametype != GT_QUAKE2) //we don't want the q2 stuff anymore. - SVQ2_ShutdownGameProgs (); -#endif - // if ((sv.worldmodel->fromgame == fg_quake2 || sv.worldmodel->fromgame == fg_quake3) && !*progs.string && SVQ2_InitGameProgs()) //full q2 dll decision in one if statement - if (oldgametype != svs.gametype) + if (newgametype != svs.gametype) { for (i=0 ; iClientDisconnect(drop->q2edict); + if (drop->isq2client==1) + if (ge) + ge->ClientDisconnect(drop->q2edict); #endif + if (drop->isq2client == 0) if (svprogfuncs) { if (drop->state == cs_spawned) diff --git a/engine/server/sv_phys.c b/engine/server/sv_phys.c index a0c557e4..71443008 100644 --- a/engine/server/sv_phys.c +++ b/engine/server/sv_phys.c @@ -254,6 +254,8 @@ int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) float time_left; int blocked; vec3_t diff; + + vec3_t startorg; numbumps = 4; @@ -264,11 +266,16 @@ int SV_FlyMove (edict_t *ent, float time, trace_t *steptrace) time_left = time; + VectorCopy (ent->v->origin, startorg); + for (bumpcount=0 ; bumpcountv->origin[i] + time_left * ent->v->velocity[i]; + if (SV_TestEntityPosition(ent)) + Con_Printf("stuck point 1a\n"); + trace = SV_Move (ent->v->origin, ent->v->mins, ent->v->maxs, end, false, ent); if (trace.startsolid) @@ -1008,6 +1015,8 @@ void SV_Physics_Toss (edict_t *ent) vec3_t move; float backoff; + vec3_t temporg; + SV_CheckVelocity (ent); // regular thinking @@ -1033,7 +1042,11 @@ void SV_Physics_Toss (edict_t *ent) // move origin VectorScale (ent->v->velocity, host_frametime, move); + VectorCopy(ent->v->origin, temporg); + VectorCopy(temporg, ent->v->origin); trace = SV_PushEntity (ent, move); + if (trace.allsolid) + trace.fraction = 0; if (trace.fraction == 1) return; if (ent->isfree) @@ -1527,11 +1540,17 @@ void SV_WalkMove (edict_t *ent) VectorCopy (ent->v->origin, start_origin); VectorCopy (ent->v->velocity, start_velocity); + if (SV_TestEntityPosition(ent)) + Con_Printf("stuck point 0\n"); + clip = SV_FlyMove (ent, host_frametime, NULL); SV_SetOnGround (ent); SV_CheckVelocity(ent); + if (SV_TestEntityPosition(ent)) + Con_Printf("stuck point 1\n"); + VectorCopy(ent->v->origin, originalmove_origin); VectorCopy(ent->v->velocity, originalmove_velocity); originalmove_clip = clip; @@ -1573,11 +1592,17 @@ void SV_WalkMove (edict_t *ent) upmove[2] = pm_stepheight; // FIXME: don't link? SV_PushEntity(ent, upmove); + + if (SV_TestEntityPosition(ent)) + Con_Printf("stuck point 2\n"); // move forward ent->v->velocity[2] = 0; clip = SV_FlyMove (ent, host_frametime, &steptrace); ent->v->velocity[2] += start_velocity[2]; + + if (SV_TestEntityPosition(ent)) + Con_Printf("stuck point 3\n"); SV_CheckVelocity(ent); @@ -1607,6 +1632,9 @@ void SV_WalkMove (edict_t *ent) // Con_Printf("wall\n"); SV_WallFriction (ent, &steptrace); } + + if (SV_TestEntityPosition(ent)) + Con_Printf("stuck point 4\n"); } else if (/*!sv_gameplayfix_stepdown.integer || */!oldonground || start_velocity[2] > 0 || ((int)ent->v->flags & FL_ONGROUND) || ent->v->waterlevel >= 2) return; @@ -1617,6 +1645,9 @@ void SV_WalkMove (edict_t *ent) // FIXME: don't link? downtrace = SV_PushEntity (ent, downmove); + if (SV_TestEntityPosition(ent)) + Con_Printf("stuck point 5\n"); + if (downtrace.fraction < 1 && downtrace.plane.normal[2] > 0.7) { // LordHavoc: disabled this check so you can walk on monsters/players @@ -1642,6 +1673,9 @@ void SV_WalkMove (edict_t *ent) SV_SetOnGround (ent); SV_CheckVelocity(ent); + + if (SV_TestEntityPosition(ent)) + Con_Printf("stuck point 6\n"); } @@ -1660,7 +1694,7 @@ From normal Quake in an attempt to fix physics in QuakeRally void SV_Physics_Client (edict_t *ent, int num) { qboolean readyforjump; -// float oldvel; + float oldvel; if ( svs.clients[num-1].state < cs_spawned ) return; // unconnected slot @@ -1698,30 +1732,30 @@ void SV_Physics_Client (edict_t *ent, int num) break; case MOVETYPE_WALK: -// oldvel = ent->v->velocity[0]; + oldvel = ent->v->velocity[0]; if (!SV_RunThink (ent)) return; if (!SV_CheckWater (ent) && ! ((int)ent->v->flags & FL_WATERJUMP) ) SV_AddGravity (ent, ent->v->gravity); -// if (fabs(oldvel - ent->v->velocity[0])> 100) -// Con_Printf("grav: %f -> %f\n", oldvel, ent->v->velocity[0]); + if (fabs(oldvel - ent->v->velocity[0])> 100) + Con_Printf("grav: %f -> %f\n", oldvel, ent->v->velocity[0]); -// if (SV_TestEntityPosition(ent)) -// Con_Printf("Player starts stuck\n"); + if (SV_TestEntityPosition(ent)) + Con_Printf("Player starts stuck\n"); SV_CheckStuck (ent); -// if (fabs(oldvel - ent->v->velocity[0])> 100) -// Con_Printf("stuck: %f -> %f\n", oldvel, ent->v->velocity[0]); + if (SV_TestEntityPosition(ent)) + Con_Printf("becomes stuck\n"); SV_WalkMove (ent); -// if (SV_TestEntityPosition(ent)) -// Con_Printf("Player ends stuck\n"); + if (SV_TestEntityPosition(ent)) + Con_Printf("Player ends stuck\n"); -// if (fabs(oldvel - ent->v->velocity[0])> 100) -// Con_Printf("walk: %f -> %f\n", oldvel, ent->v->velocity[0]); + if (fabs(oldvel - ent->v->velocity[0])> 100) + Con_Printf("walk: %f -> %f\n", oldvel, ent->v->velocity[0]); break; diff --git a/engine/server/sv_user.c b/engine/server/sv_user.c index 05e4f498..916b9169 100644 --- a/engine/server/sv_user.c +++ b/engine/server/sv_user.c @@ -1011,7 +1011,7 @@ void SV_PreSpawn_f (void) { if (sv.democausesreconnect) { - if (host_client->netchan.message.cursize+sv.signon_buffer_size[buf] < host_client->netchan.message.maxsize) + if (host_client->netchan.message.cursize+sv.signon_buffer_size[buf]+30 < host_client->netchan.message.maxsize) { SZ_Write (&host_client->netchan.message, sv.demosignon_buffers[buf], @@ -1021,7 +1021,7 @@ void SV_PreSpawn_f (void) } else { - if (host_client->netchan.message.cursize+sv.signon_buffer_size[buf] < host_client->netchan.message.maxsize) + if (host_client->netchan.message.cursize+sv.signon_buffer_size[buf]+30 < host_client->netchan.message.maxsize) { SZ_Write (&host_client->netchan.message, sv.signon_buffers[buf],