From 244c08ad0441e115ee08971992db41944a9599f5 Mon Sep 17 00:00:00 2001 From: Spoike Date: Sun, 18 Jul 2010 08:42:59 +0000 Subject: [PATCH] Attempted to add support for divVerent's varlen protocol extension info. This is more silencing warnings than anything else. Also tweeked video code to remove 6 dead sw-only functions. git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3556 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/cl_main.c | 8 + engine/client/cl_parse.c | 22 +- engine/client/image.c | 2 +- engine/client/merged.h | 12 - engine/client/p_script.c | 784 +++++++++++++++++++++++++++---------- engine/client/pr_csqc.c | 8 +- engine/client/renderer.c | 18 - engine/client/sys_win.c | 6 +- engine/client/vid.h | 9 - engine/common/cmd.c | 11 +- engine/common/common.c | 31 ++ engine/common/common.h | 2 +- engine/common/cvar.h | 2 +- engine/common/fs.c | 6 +- engine/common/net_wins.c | 23 +- engine/common/particles.h | 2 +- engine/common/protocol.h | 1 + engine/gl/gl_alias.c | 115 +----- engine/gl/gl_backend.c | 48 ++- engine/gl/gl_hlmdl.c | 2 +- engine/gl/gl_rmain.c | 97 ++++- engine/gl/gl_shader.c | 21 +- engine/gl/gl_shadow.c | 7 +- engine/gl/gl_vidcommon.c | 6 - engine/gl/gl_vidlinuxglx.c | 17 - engine/gl/gl_vidmacos.c | 8 - engine/gl/gl_vidnt.c | 9 - engine/gl/gl_vidnull.c | 5 +- engine/gl/gl_vidsdl.c | 28 +- engine/gl/glquake.h | 2 +- engine/gl/shader.h | 1 + engine/qclib/pr_multi.c | 2 +- engine/qclib/progsint.h | 2 +- engine/qclib/progslib.h | 22 +- engine/qclib/qcc_pr_comp.c | 2 +- engine/qclib/qcc_pr_lex.c | 8 - engine/server/pr_cmds.c | 30 +- engine/server/sv_ents.c | 4 +- engine/server/sv_mvd.c | 4 +- engine/server/sv_sys_win.c | 138 ++++++- 40 files changed, 975 insertions(+), 550 deletions(-) diff --git a/engine/client/cl_main.c b/engine/client/cl_main.c index c59d12322..a26bc0205 100644 --- a/engine/client/cl_main.c +++ b/engine/client/cl_main.c @@ -2187,6 +2187,14 @@ void CL_ConnectionlessPacket (void) pext = MSG_ReadLong (); else if (c == PROTOCOL_VERSION_FTE2) pext2 = MSG_ReadLong (); + else if (c == PROTOCOL_VERSION_VARLENGTH) + { + int len = MSG_ReadLong(); + if (len < 0 || len > 8192) + break; + c = MSG_ReadLong();/*ident*/ + MSG_ReadSkip(len); /*payload*/ + } #ifdef HUFFNETWORK else if (c == (('H'<<0) + ('U'<<8) + ('F'<<16) + ('F' << 24))) huffcrc = MSG_ReadLong (); diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index 6acd13f41..7216c6db7 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -2051,14 +2051,32 @@ void CL_ParseServerData (void) protover = MSG_ReadLong (); if (protover == PROTOCOL_VERSION_FTE) { - cls.fteprotocolextensions = MSG_ReadLong(); + cls.fteprotocolextensions = MSG_ReadLong(); continue; } if (protover == PROTOCOL_VERSION_FTE2) { - cls.fteprotocolextensions2 = MSG_ReadLong(); + cls.fteprotocolextensions2 = MSG_ReadLong(); continue; } + if (protover == PROTOCOL_VERSION_VARLENGTH) + { + int ident; + int len; + char data[1024]; + ident = MSG_ReadLong(); + len = MSG_ReadLong(); + if (len <= sizeof(data)) + { + MSG_ReadData(data, len); + switch(ident) + { + default: + break; + } + continue; + } + } if (protover == PROTOCOL_VERSION_QW) //this ends the version info break; if (cls.demoplayback && (protover == 26 || protover == 27 || protover == 28)) //older versions, maintain demo compatability. diff --git a/engine/client/image.c b/engine/client/image.c index f4f62f70e..001e1fa72 100644 --- a/engine/client/image.c +++ b/engine/client/image.c @@ -710,7 +710,7 @@ int Image_WritePNG (char *filename, int compression, qbyte *pixels, int width, i if (!(fp = fopen (name, "wb"))) { - COM_CreatePath (name); + FS_CreatePath (filename, FS_GAMEONLY); if (!(fp = fopen (name, "wb"))) return false; } diff --git a/engine/client/merged.h b/engine/client/merged.h index a8c8fceb2..15bac139d 100644 --- a/engine/client/merged.h +++ b/engine/client/merged.h @@ -88,12 +88,6 @@ extern void (*R_LessenStains) (void); extern qboolean (*VID_Init) (rendererstate_t *info, unsigned char *palette); extern void (*VID_DeInit) (void); -extern void (*VID_LockBuffer) (void); -extern void (*VID_UnlockBuffer) (void); -extern void (*D_BeginDirectRect) (int x, int y, qbyte *pbitmap, int width, int height); -extern void (*D_EndDirectRect) (int x, int y, int width, int height); -extern void (*VID_ForceLockState) (int lk); -extern int (*VID_ForceUnlockedAndReturnState) (void); extern void (*VID_SetPalette) (unsigned char *palette); extern void (*VID_ShiftPalette) (unsigned char *palette); extern char *(*VID_GetRGBInfo) (int prepad, int *truevidwidth, int *truevidheight); @@ -213,12 +207,6 @@ typedef struct rendererinfo_s { qboolean (*VID_Init) (rendererstate_t *info, unsigned char *palette); void (*VID_DeInit) (void); - void (*VID_LockBuffer) (void); - void (*VID_UnlockBuffer) (void); - void (*D_BeginDirectRect) (int x, int y, qbyte *pbitmap, int width, int height); - void (*D_EndDirectRect) (int x, int y, int width, int height); - void (*VID_ForceLockState) (int lk); - int (*VID_ForceUnlockedAndReturnState) (void); void (*VID_SetPalette) (unsigned char *palette); void (*VID_ShiftPalette) (unsigned char *palette); char *(*VID_GetRGBInfo) (int prepad, int *truevidwidth, int *truevidheight); diff --git a/engine/client/p_script.c b/engine/client/p_script.c index ec4a98d2b..f5649beae 100644 --- a/engine/client/p_script.c +++ b/engine/client/p_script.c @@ -147,38 +147,39 @@ typedef struct { typedef struct part_type_s { char name[MAX_QPATH]; char texname[MAX_QPATH]; - vec3_t rgb; + vec3_t rgb; //initial colour float alpha; - vec3_t rgbchange; + vec3_t rgbchange; //colour delta (per second) float alphachange; - vec3_t rgbrand; - int colorindex; - int colorrand; - float rgbchangetime; - vec3_t rgbrandsync; - float scale; - float die, randdie; - float randomvel, veladd; - float orgadd; - float offsetspread; - float offsetspreadvert; - float randomvelvert; - float randscale; + vec3_t rgbrand; //random rgb colour to start with + float alpharand; + int colorindex; //get colour from a palette + int colorrand; //and add up to this amount + float rgbchangetime;//colour stops changing at this time + vec3_t rgbrandsync; //like rgbrand, but a single random value instead of separate (can mix) + float scale; //initial scale + float scalerand; //with up to this much extra + float die, randdie; //how long it lasts (plus some rand) + float randomvel, randomvelvert; //random velocity (unaligned) + float veladd; //scale the incoming velocity by this much + float orgadd; //spawn the particle this far along its velocity direction + float spawnvel, spawnvelvert; //spawn the particle with a velocity based upon its spawn type (generally so it flies outwards) - float s1, t1, s2, t2; + float s1, t1, s2, t2; //texture coords float texsstride; //addition for s for each random slot. int randsmax; //max times the stride can be added plooks_t *slooks; //shared looks, so state switches don't apply between particles so much plooks_t looks; - float spawntime; - float spawnchance; + float spawntime; //time limit for trails + float spawnchance; //if < 0, particles might not spawn so many float rotationstartmin, rotationstartrand; float rotationmin, rotationrand; float scaledelta; + int countextra; float count; float countrand; @@ -239,6 +240,7 @@ typedef struct part_type_s { #define PT_NOSTATE 0x040 // don't use trailstate for this emitter (careful with assoc...) #define PT_NOSPREADFIRST 0x080 // don't randomize org/vel for first generated particle #define PT_NOSPREADLAST 0x100 // don't randomize org/vel for last generated particle + unsigned int state; #define PS_INRUNLIST 0x1 // particle type is currently in execution list } part_type_t; @@ -364,7 +366,8 @@ static part_type_t *P_GetParticleType(char *name) if (oldlist) { - part_run_list=NULL; + if (part_run_list) + part_run_list = (part_type_t*)((char*)part_run_list - (char*)oldlist + (char*)part_type); for (i = 0; i < numparticletypes; i++) if (part_type[i].nexttorun) @@ -486,6 +489,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn) "rgbgen vertex\n" "alphagen vertex\n" "}\n" + "polygonoffset\n" "}\n" ; break; @@ -499,6 +503,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn) "rgbgen vertex\n" "alphagen vertex\n" "}\n" + "polygonoffset\n" "}\n" ; break; @@ -512,6 +517,21 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn) "rgbgen vertex\n" "alphagen vertex\n" "}\n" + "polygonoffset\n" + "}\n" + ; + break; + case BM_INVMOD: + namepostfix = "_invmod"; + defaultshader = + "{\n" + "{\n" + "map $diffuse\n" + "blendfunc GL_ZERO GL_ONE_MINUS_SRC_COLOR\n" + "rgbgen vertex\n" + "alphagen vertex\n" + "}\n" + "polygonoffset\n" "}\n" ; break; @@ -525,6 +545,7 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn) "rgbgen vertex\n" "alphagen vertex\n" "}\n" + "polygonoffset\n" "}\n" ; break; @@ -751,10 +772,10 @@ static void P_ParticleEffect_f(void) { ptype->scale = atof(value); if (Cmd_Argc()>2) - ptype->randscale = atof(Cmd_Argv(2)) - ptype->scale; + ptype->scalerand = atof(Cmd_Argv(2)) - ptype->scale; } else if (!strcmp(var, "scalerand")) - ptype->randscale = atof(value); + ptype->scalerand = atof(value); else if (!strcmp(var, "scalefactor")) ptype->looks.scalefactor = atof(value); @@ -773,6 +794,8 @@ static void P_ParticleEffect_f(void) ptype->count = atof(value); if (Cmd_Argc()>2) ptype->countrand = atof(Cmd_Argv(2)); + if (Cmd_Argc()>3) + ptype->countextra = atof(Cmd_Argv(3)); } else if (!strcmp(var, "alpha")) @@ -1032,15 +1055,15 @@ static void P_ParticleEffect_f(void) else if (!strcmp(var, "offsetspread")) { Con_DPrintf("offsetspread is deprechiated, use spawnvel\n"); - ptype->offsetspread = atof(value); + ptype->spawnvel = atof(value); } else if (!strcmp(var, "offsetspreadvert")) { Con_DPrintf("offsetspreadvert is deprechiated, use spawnvel\n"); - ptype->offsetspreadvert = atof(value); + ptype->spawnvelvert = atof(value); } - // new names + // current names else if (!strcmp(var, "spawnorg")) { ptype->areaspreadvert = ptype->areaspread = atof(value); @@ -1050,10 +1073,10 @@ static void P_ParticleEffect_f(void) } else if (!strcmp(var, "spawnvel")) { - ptype->offsetspreadvert = ptype->offsetspread = atof(value); + ptype->spawnvelvert = ptype->spawnvel = atof(value); if (Cmd_Argc()>2) - ptype->offsetspreadvert = atof(Cmd_Argv(2)); + ptype->spawnvelvert = atof(Cmd_Argv(2)); } // spawn mode param fields @@ -1176,10 +1199,10 @@ static void P_ParticleEffect_f(void) ptype->clipcount = 1; //if there is a chance that it moves - if (ptype->randomvel || ptype->gravity || ptype->veladd || ptype->offsetspread || ptype->offsetspreadvert) + if (ptype->randomvel || ptype->gravity || ptype->veladd || ptype->spawnvel || ptype->spawnvelvert) ptype->flags |= PT_VELOCITY; //if it has friction - if (ptype->friction) + if (ptype->friction[0] || ptype->friction[1] || ptype->friction[2]) ptype->flags |= PT_FRICTION; if (!settype) @@ -1323,6 +1346,7 @@ static void P_BeamInfo_f (void) static void P_PartInfo_f (void) { particle_t *p; + part_type_t *ptype; int i, j; @@ -1340,11 +1364,327 @@ static void P_PartInfo_f (void) j++; if (j) + { Con_Printf("Type %s = %i total\n", part_type[i].name, j); + if (!(part_type[i].state & PS_INRUNLIST)) + Con_Printf(" NOT RUNNING\n"); + } } + + Con_Printf("Running effects:\n"); + // maintain run list + for (ptype = part_run_list; ptype; ptype = ptype->nexttorun) + { + j = 0; + for (p = ptype->particles; p; p = p->next) + j++; + + + Con_Printf("Type %s = %i total\n", ptype->name, j); + } + Con_Printf("End of list\n"); } #endif +void FinishParticleType(part_type_t *ptype) +{ + //if there is a chance that it moves + if (ptype->randomvel || ptype->gravity || ptype->veladd || ptype->spawnvel || ptype->spawnvelvert) + ptype->flags |= PT_VELOCITY; + //if it has friction + if (ptype->friction[0] || ptype->friction[1] || ptype->friction[2]) + ptype->flags |= PT_FRICTION; + + P_LoadTexture(ptype, true); + if (ptype->die == 9999) + { + if (ptype->alphachange) + ptype->die = (ptype->alpha+ptype->alpharand)/-ptype->alphachange; + else + ptype->die = 15; + } + if (ptype->looks.scalefactor > 1 && !ptype->looks.invscalefactor) + { + ptype->scale *= ptype->looks.scalefactor; + ptype->scalerand *= ptype->looks.scalefactor; + /*too lazy to go through ramps*/ + ptype->looks.scalefactor = 1; + } +} + +static void P_ImportEffectInfo_f(void) +{ + part_type_t *ptype = NULL; + int parenttype; + char *file, *line; + char *cmd; + char arg[8][1024]; + int args = 0; + FS_LoadFile("effectinfo.txt", (void**)&file); + + if (!file) + { + Con_Printf("effectinfo.txt not found\n"); + return; + } + line = file; + for (;;) + { + if (!*line) + break; + if (args == 8) + { + Con_Printf("Too many args!\n"); + args--; + } + line = COM_StringParse(line, false, false); + Q_strncpyz(arg[args], com_token, sizeof(arg[args])); + args++; + if (*com_token == '\n') + args--; + else if (*line) + continue; + + if (args <= 0) + continue; + + cmd = arg[0]; + if (!strcmp(arg[0], "effect")) + { + char newname[64]; + int i; + + if (ptype) + { + FinishParticleType(ptype); + } + + ptype = P_GetParticleType(arg[1]); + if (ptype->loaded) + { + for (i = 0; i < 64; i++) + { + parenttype = ptype - part_type; + snprintf(newname, sizeof(newname), "%i+%s", i, arg[1]); + ptype = P_GetParticleType(newname); + if (!ptype->loaded) + { + part_type[parenttype].assoc = ptype - part_type; + break; + } + } + if (i == 64) + { + Con_Printf("Too many duplicate names, gave up\n"); + break; + } + } + ptype->loaded = true; + ptype->scale = 1; + ptype->alpha = 0; + ptype->alpharand = 1; + ptype->alphachange = -1; + ptype->die = 9999; + strcpy(ptype->texname, "particles/particlefont.tga"); + ptype->rgb[0] = 1; + ptype->rgb[1] = 1; + ptype->rgb[2] = 1; + ptype->colorindex = -1; + + ptype->spawnmode = SM_BOX; + + ptype->spawnchance = 1; + ptype->randsmax = 1; + ptype->looks.scalefactor = 2; + ptype->looks.invscalefactor = 0; + ptype->looks.type = PT_NORMAL; + ptype->looks.blendmode = BM_BLEND; + } + else if (!ptype) + { + Con_Printf("Bad effectinfo file\n"); + break; + } + else if (!strcmp(arg[0], "countabsolute") && args == 2) + ptype->countextra = atof(arg[1]); + else if (!strcmp(arg[0], "count") && args == 2) + ptype->count = atof(arg[1]); + else if (!strcmp(arg[0], "type") && args == 2) + { + if (!strcmp(arg[1], "decal")) + { + ptype->looks.type = PT_DECAL; + ptype->looks.blendmode = BM_INVMOD; + } + else if (!strcmp(arg[1], "alphastatic")) + { + ptype->looks.type = PT_NORMAL; + ptype->looks.blendmode = BM_BLEND; + } + else if (!strcmp(arg[1], "static")) + { + ptype->looks.type = PT_NORMAL; + ptype->looks.blendmode = BM_ADD; + } + else if (!strcmp(arg[1], "smoke")) + { + ptype->looks.type = PT_NORMAL; + ptype->looks.blendmode = BM_ADD; + } + else if (!strcmp(arg[1], "spark")) + { + ptype->looks.type = PT_TEXTUREDSPARK; + } + else if (!strcmp(arg[1], "bubble")) + { + ptype->looks.type = PT_NORMAL; + ptype->looks.blendmode = BM_ADD; + } + else if (!strcmp(arg[1], "blood")) + { + ptype->looks.type = PT_NORMAL; + ptype->looks.blendmode = BM_INVMOD; + } + else if (!strcmp(arg[1], "beam")) + { + ptype->looks.type = PT_BEAM; + ptype->looks.blendmode = BM_ADD; + } + else + { + Con_Printf("effectinfo type %s not supported\n", arg[1]); + } + } + else if (!strcmp(arg[0], "tex") && args == 3) + { + int mini = atoi(arg[1]); + int maxi = atoi(arg[2]); + /*number range between 0 and 63*/ + ptype->s1 = 1/8.0 * (mini & 7); + ptype->s2 = 1/8.0 * (1+(mini & 7)); + ptype->t1 = 1/8.0 * (mini>>3); + ptype->t2 = 1/8.0 * (1+(mini>>3)); + ptype->texsstride = 1/8.0; + ptype->randsmax = (maxi - mini)+1; + if (ptype->randsmax < 1) + ptype->randsmax = 1; + } + else if (!strcmp(arg[0], "size") && args == 3) + { + float s1 = atof(arg[1]), s2 = atof(arg[2]); + ptype->scale = s1; + ptype->scalerand = s2-s1; + } + else if (!strcmp(arg[0], "sizeincrease") && args == 2) + ptype->scaledelta = atof(arg[1]); + else if (!strcmp(arg[0], "color") && args == 3) + { + unsigned int rgb1 = strtoul(arg[1], NULL, 0), rgb2 = strtoul(arg[2], NULL, 0); + int i; + for (i = 0; i < 3; i++) + { + ptype->rgb[i] = ((rgb1>>(16-i*8)) & 0xff)/255.0; + ptype->rgbrandsync[i] = (((rgb2>>(16-i*8)) & 0xff) - ((rgb1>>(16-i*8)) & 0xff))/255.0; + } + } + else if (!strcmp(arg[0], "alpha") && args == 4) + { + float a1 = atof(arg[1]), a2 = atof(arg[2]), f = atof(arg[3]); + ptype->alpha = a1/255; + ptype->alpharand = (a2-a1)/255; + ptype->alphachange = -f/255; + } + else if (!strcmp(arg[0], "velocityoffset") && args == 4) + ; /*a 3d world-coord addition*/ + else if (!strcmp(arg[0], "velocityjitter") && args == 4) + { + ptype->spawnvel = (atof(arg[1]) + atof(arg[2]))*0.5; + ptype->spawnvelvert = atof(arg[3]); + } + else if (!strcmp(arg[0], "originoffset") && args == 4) + ; /*a 3d world-coord addition*/ + else if (!strcmp(arg[0], "originjitter") && args == 4) + { + ptype->areaspread = (atof(arg[1]) + atof(arg[2]))*0.5; + ptype->areaspreadvert = atof(arg[3]); + } + else if (!strcmp(arg[0], "gravity") && args == 2) + { + ptype->gravity = 800*atof(arg[1]); + } + else if (!strcmp(arg[0], "bounce") && args == 2) + { + ptype->clipbounce = atof(arg[1]); + ptype->cliptype = ptype - part_type; + } + else if (!strcmp(arg[0], "airfriction") && args == 2) + ptype->friction[2] = ptype->friction[1] = ptype->friction[0] = atof(arg[1]); + else if (!strcmp(arg[0], "liquidfriction") && args == 2) + ; + else if (!strcmp(arg[0], "underwater") && args == 1) + ; + else if (!strcmp(arg[0], "notunderwater") && args == 1) + ; + else if (!strcmp(arg[0], "velocitymultiplier") && args == 2) + ptype->veladd = atof(arg[1]); + else if (!strcmp(arg[0], "lightradius") && args == 2) + ; + else if (!strcmp(arg[0], "lightradiusfade") && args == 2) + ; + else if (!strcmp(arg[0], "lightcolor") && args == 4) + ; + else if (!strcmp(arg[0], "lighttime") && args == 2) + ; + else if (!strcmp(arg[0], "trailspacing") && args == 2) + ptype->count = 1 / atof(arg[1]); + else if (!strcmp(arg[0], "time") && args == 3) + { + ptype->die = atof(arg[1]); + ptype->randdie = atof(arg[2]) - ptype->die; + if (ptype->randdie < 0) + { + ptype->die = atof(arg[2]); + ptype->randdie = atof(arg[1]) - ptype->die; + } + } +#if 0 + else if (!strcmp(arg[0], "blend") && args == 2) + ; /*overrides blendmode*/ + else if (!strcmp(arg[0], "orientation") && args == 2) + ; /*overrides type*/ + else if (!strcmp(arg[0], "lightshadow") && args == 2) + ; + else if (!strcmp(arg[0], "lightcubemapnum") && args == 2) + ; + else if (!strcmp(arg[0], "stretchfactor") && args == 2) + ; + else if (!strcmp(arg[0], "staincolor") && args == 2) + ; + else if (!strcmp(arg[0], "stainalpha") && args == 2) + ; + else if (!strcmp(arg[0], "stainsize") && args == 2) + ; + else if (!strcmp(arg[0], "staintex") && args == 2) + ; + else if (!strcmp(arg[0], "stainless") && args == 1) + ; + else if (!strcmp(arg[0], "rotate") && args == 2) + ; +#endif + else + Con_Printf("Particle effect token not recognised, or invalid args: %s %s %s %s %s %s\n", arg[0], args<2?"":arg[1], args<3?"":arg[2], args<4?"":arg[3], args<5?"":arg[4], args<6?"":arg[5]); + args = 0; + } + + if (ptype) + { + FinishParticleType(ptype); + } + + FS_FreeFile(file); + r_plooksdirty = true; +} + /* =============== R_InitParticles @@ -1397,6 +1737,7 @@ static qboolean PScript_InitParticles (void) Cmd_AddRemCommand("r_trail", P_AssosiateTrail_f); Cmd_AddRemCommand("r_exportbuiltinparticles", P_ExportBuiltinSet_f); + Cmd_AddRemCommand("r_importeffectinfo", P_ImportEffectInfo_f); #if _DEBUG Cmd_AddRemCommand("r_partinfo", P_PartInfo_f); @@ -1450,6 +1791,7 @@ static void PScript_Shutdown (void) Cmd_RemoveCommand("r_trail"); Cmd_RemoveCommand("r_exportbuiltinparticles"); + Cmd_RemoveCommand("r_importeffectinfo"); #if _DEBUG Cmd_RemoveCommand("r_partinfo"); @@ -1551,6 +1893,8 @@ static void P_LoadParticleSet(char *name, qboolean first) //particle descriptions submitted by the server are deemed to not be cheats but game configs. if (!stricmp(name, "none")) return; + else if (!stricmp(name, "effectinfo")) + Cbuf_AddText("r_importeffectinfo\n", RESTRICT_LOCAL); else if (!stricmp(name, "faithful") || (first && !*name)) Cbuf_AddText(particle_set_faithful, RESTRICT_LOCAL); else if (!stricmp(name, "spikeset")) @@ -1583,18 +1927,13 @@ static void P_LoadParticleSet(char *name, qboolean first) } } -static void R_ParticlesDesc_Callback(struct cvar_s *var, char *oldvalue) +static void R_Particles_KillAllEffects(void) { + int i; + + model_t *mod; extern model_t mod_known[]; extern int mod_numknown; - qboolean first; - - model_t *mod; - int i; - char *c; - - if (cls.state == ca_disconnected) - return; // don't bother parsing while disconnected for (i = 0; i < numparticletypes; i++) { @@ -1605,6 +1944,9 @@ static void R_ParticlesDesc_Callback(struct cvar_s *var, char *oldvalue) BZ_Free(part_type->ramp); part_type->ramp = NULL; } +// numparticletypes = 0; +// BZ_Free(part_type); +// part_type = NULL; for (i=0 , mod=mod_known ; istring); com_token[0]; c = COM_ParseStringSet(c)) @@ -1773,7 +2127,6 @@ static void P_AddRainParticles(void) } } - static void R_Part_SkyTri(float *v1, float *v2, float *v3, msurface_t *surf) { float dot; @@ -1984,143 +2337,155 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count, else ts = NULL; - if (ptype->looks.type == PT_DECAL) - { - clippeddecal_t *d; - int decalcount; - float dist; - vec3_t tangent, t2; - vec3_t vec={0.5, 0.5, 0.5}; - float *decverts; - int i; - trace_t tr; - - vec3_t bestdir; - - if (!free_decals) - return 0; - - if (!dir) - { - bestdir[0] = 0; - bestdir[1] = 0.73; - bestdir[2] = 0.73; - dist = 1; - for (i = 0; i < 6; i++) - { - if (i >= 3) - { - t2[0] = ((i&3)==0)*8; - t2[1] = ((i&3)==1)*8; - t2[2] = ((i&3)==2)*8; - } - else - { - t2[0] = -((i&3)==0)*8; - t2[1] = -((i&3)==1)*8; - t2[2] = -((i&3)==2)*8; - } - VectorSubtract(org, t2, tangent); - VectorAdd(org, t2, t2); - - if (cl.worldmodel->funcs.Trace (cl.worldmodel, 0, 0,tangent, t2, vec3_origin, vec3_origin, &tr)) - { - if (tr.fraction < dist) - { - dist = tr.fraction; - VectorCopy(tr.plane.normal, bestdir); - } - } - } - dir = bestdir; - } - VectorInverse(dir); - VectorNormalize(dir); - - VectorNormalize(vec); - CrossProduct(dir, vec, tangent); - CrossProduct(dir, tangent, t2); - - decalcount = Q1BSP_ClipDecal(org, dir, tangent, t2, ptype->scale, &decverts); - while(decalcount) - { - if (!free_decals) - break; - - d = free_decals; - free_decals = d->next; - d->next = ptype->clippeddecals; - ptype->clippeddecals = d; - - VectorCopy((decverts+0), d->vertex[0]); - VectorCopy((decverts+3), d->vertex[1]); - VectorCopy((decverts+6), d->vertex[2]); - - for (i = 0; i < 3; i++) - { - VectorSubtract(d->vertex[i], org, vec); - d->texcoords[i][0] = (DotProduct(vec, t2)/ptype->scale)+0.5; - d->texcoords[i][1] = (DotProduct(vec, tangent)/ptype->scale)+0.5; - } - - d->die = ptype->randdie*frandom(); - - if (ptype->die) - d->rgba[3] = ptype->alpha+d->die*ptype->alphachange; - else - d->rgba[3] = ptype->alpha; - - if (ptype->colorindex >= 0) - { - int cidx; - cidx = ptype->colorrand > 0 ? rand() % ptype->colorrand : 0; - cidx = ptype->colorindex + cidx; - if (cidx > 255) - d->rgba[3] = d->rgba[3] / 2; // Hexen 2 style transparency - cidx = (cidx & 0xff) * 3; - d->rgba[0] = host_basepal[cidx] * (1/255.0); - d->rgba[1] = host_basepal[cidx+1] * (1/255.0); - d->rgba[2] = host_basepal[cidx+2] * (1/255.0); - } - else - VectorCopy(ptype->rgb, d->rgba); - - vec[2] = frandom(); - vec[0] = vec[2]*ptype->rgbrandsync[0] + frandom()*(1-ptype->rgbrandsync[0]); - vec[1] = vec[2]*ptype->rgbrandsync[1] + frandom()*(1-ptype->rgbrandsync[1]); - vec[2] = vec[2]*ptype->rgbrandsync[2] + frandom()*(1-ptype->rgbrandsync[2]); - d->rgba[0] += vec[0]*ptype->rgbrand[0] + ptype->rgbchange[0]*d->die; - d->rgba[1] += vec[1]*ptype->rgbrand[1] + ptype->rgbchange[1]*d->die; - d->rgba[2] += vec[2]*ptype->rgbrand[2] + ptype->rgbchange[2]*d->die; - - d->die = particletime + ptype->die - d->die; - - decverts += 3*3; - decalcount--; - - - // maintain run list - if (!(ptype->state & PS_INRUNLIST)) - { - ptype->nexttorun = part_run_list; - part_run_list = ptype; - ptype->state |= PS_INRUNLIST; - } - } - - return 0; - } - // get msvc to shut up j = k = l = 0; m = 0; while(ptype) { + if (ptype->looks.type == PT_DECAL) + { + clippeddecal_t *d; + int decalcount; + float dist; + vec3_t tangent, t2; + vec3_t vec={0.5, 0.5, 0.5}; + float *decverts; + int i; + trace_t tr; + float sb,sw,tb,tw; + + vec3_t bestdir; + + if (!free_decals) + return 0; + + if (!dir || (dir[0] == 0 && dir[1] == 0 && dir[2] == 0)) + { + bestdir[0] = 0; + bestdir[1] = 0.73; + bestdir[2] = 0.73; + dist = 1; + for (i = 0; i < 6; i++) + { + if (i >= 3) + { + t2[0] = ((i&3)==0)*8; + t2[1] = ((i&3)==1)*8; + t2[2] = ((i&3)==2)*8; + } + else + { + t2[0] = -((i&3)==0)*8; + t2[1] = -((i&3)==1)*8; + t2[2] = -((i&3)==2)*8; + } + VectorSubtract(org, t2, tangent); + VectorAdd(org, t2, t2); + + if (cl.worldmodel->funcs.Trace (cl.worldmodel, 0, 0,tangent, t2, vec3_origin, vec3_origin, &tr)) + { + if (tr.fraction < dist) + { + dist = tr.fraction; + VectorCopy(tr.plane.normal, bestdir); + } + } + } + dir = bestdir; + } + VectorInverse(dir); + VectorNormalize(dir); + + VectorNormalize(vec); + CrossProduct(dir, vec, tangent); + CrossProduct(dir, tangent, t2); + + sw = ptype->s2 - ptype->s1; + sb = ptype->s1 + sw/2; + tw = ptype->t2 - ptype->t1; + tb = ptype->t1 + tw/2; + sw /= ptype->scale; + tw /= ptype->scale; + + decalcount = Q1BSP_ClipDecal(org, dir, tangent, t2, ptype->scale, &decverts); + while(decalcount) + { + if (!free_decals) + break; + + d = free_decals; + free_decals = d->next; + d->next = ptype->clippeddecals; + ptype->clippeddecals = d; + + VectorCopy((decverts+0*(sizeof(vec3_t)/sizeof(vec_t))), d->vertex[0]); + VectorCopy((decverts+1*(sizeof(vec3_t)/sizeof(vec_t))), d->vertex[1]); + VectorCopy((decverts+2*(sizeof(vec3_t)/sizeof(vec_t))), d->vertex[2]); + + for (i = 0; i < 3; i++) + { + VectorSubtract(d->vertex[i], org, vec); + d->texcoords[i][0] = (DotProduct(vec, t2)*sw)+sb; + d->texcoords[i][1] = (DotProduct(vec, tangent)*tw)+tb; + } + + d->die = ptype->randdie*frandom(); + + if (ptype->die) + d->rgba[3] = ptype->alpha + d->die*ptype->alphachange; + else + d->rgba[3] = ptype->alpha; + d->rgba[3] += ptype->alpharand*frandom(); + + if (ptype->colorindex >= 0) + { + int cidx; + cidx = ptype->colorrand > 0 ? rand() % ptype->colorrand : 0; + cidx = ptype->colorindex + cidx; + if (cidx > 255) + d->rgba[3] = d->rgba[3] / 2; // Hexen 2 style transparency + cidx = (cidx & 0xff) * 3; + d->rgba[0] = host_basepal[cidx] * (1/255.0); + d->rgba[1] = host_basepal[cidx+1] * (1/255.0); + d->rgba[2] = host_basepal[cidx+2] * (1/255.0); + } + else + VectorCopy(ptype->rgb, d->rgba); + + vec[2] = frandom(); + vec[0] = vec[2]*ptype->rgbrandsync[0] + frandom()*(1-ptype->rgbrandsync[0]); + vec[1] = vec[2]*ptype->rgbrandsync[1] + frandom()*(1-ptype->rgbrandsync[1]); + vec[2] = vec[2]*ptype->rgbrandsync[2] + frandom()*(1-ptype->rgbrandsync[2]); + d->rgba[0] += vec[0]*ptype->rgbrand[0] + ptype->rgbchange[0]*d->die; + d->rgba[1] += vec[1]*ptype->rgbrand[1] + ptype->rgbchange[1]*d->die; + d->rgba[2] += vec[2]*ptype->rgbrand[2] + ptype->rgbchange[2]*d->die; + + d->die = particletime + ptype->die - d->die; + + decverts += (sizeof(vec3_t)/sizeof(vec_t))*3; + decalcount--; + + + // maintain run list + if (!(ptype->state & PS_INRUNLIST)) + { + ptype->nexttorun = part_run_list; + part_run_list = ptype; + ptype->state |= PS_INRUNLIST; + } + } + + if (ptype->assoc < 0) + break; + + ptype = &part_type[ptype->assoc]; + continue; + } // init spawn specific variables b = bfirst = NULL; spawnspc = 8; - pcount = count*(ptype->count+ptype->countrand*frandom()); + pcount = ptype->countextra + count*(ptype->count+ptype->countrand*frandom()); if (ptype->flags & PT_INVFRAMETIME) pcount /= host_frametime; if (ts) @@ -2184,6 +2549,7 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count, break; } + /*this is a hack, use countextra=1, count=0*/ if (!ptype->die && ptype->count == 1 && ptype->countrand == 0) { i = 0; @@ -2220,11 +2586,12 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count, ptype->particles = p; p->die = ptype->randdie*frandom(); - p->scale = ptype->scale+ptype->randscale*frandom(); + p->scale = ptype->scale+ptype->scalerand*frandom(); if (ptype->die) p->rgba[3] = ptype->alpha+p->die*ptype->alphachange; else p->rgba[3] = ptype->alpha; + p->rgba[3] += ptype->alpharand*frandom(); // p->color = 0; if (ptype->emittime < 0) p->state.trailstate = NULL; @@ -2413,9 +2780,9 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count, // apply arsvec+ofsvec if (dir) { - p->vel[0] += dir[0]*ptype->veladd+ofsvec[0]*ptype->offsetspread; - p->vel[1] += dir[1]*ptype->veladd+ofsvec[1]*ptype->offsetspread; - p->vel[2] += dir[2]*ptype->veladd+ofsvec[2]*ptype->offsetspreadvert; + p->vel[0] += dir[0]*ptype->veladd+ofsvec[0]*ptype->spawnvel; + p->vel[1] += dir[1]*ptype->veladd+ofsvec[1]*ptype->spawnvel; + p->vel[2] += dir[2]*ptype->veladd+ofsvec[2]*ptype->spawnvelvert; p->org[0] += dir[0]*ptype->orgadd; p->org[1] += dir[1]*ptype->orgadd; @@ -2423,9 +2790,9 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count, } else { - p->vel[0] += ofsvec[0]*ptype->offsetspread; - p->vel[1] += ofsvec[1]*ptype->offsetspread; - p->vel[2] += ofsvec[2]*ptype->offsetspreadvert - ptype->veladd; + p->vel[0] += ofsvec[0]*ptype->spawnvel; + p->vel[1] += ofsvec[1]*ptype->spawnvel; + p->vel[2] += ofsvec[2]*ptype->spawnvelvert - ptype->veladd; p->org[2] -= ptype->orgadd; } @@ -2913,11 +3280,12 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype ptype->particles = p; p->die = ptype->randdie*frandom(); - p->scale = ptype->scale+ptype->randscale*frandom(); + p->scale = ptype->scale+ptype->scalerand*frandom(); if (ptype->die) p->rgba[3] = ptype->alpha+p->die*ptype->alphachange; else p->rgba[3] = ptype->alpha; + p->rgba[3] += ptype->alpharand*frandom(); // p->color = 0; // if (ptype->spawnmode == SM_TRACER) @@ -2990,15 +3358,15 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype case SM_TRACER: if (tcount & 1) { - p->vel[0] = vec[1]*ptype->offsetspread; - p->vel[1] = -vec[0]*ptype->offsetspread; + p->vel[0] = vec[1]*ptype->spawnvel; + p->vel[1] = -vec[0]*ptype->spawnvel; p->org[0] = vec[1]*ptype->areaspread; p->org[1] = -vec[0]*ptype->areaspread; } else { - p->vel[0] = -vec[1]*ptype->offsetspread; - p->vel[1] = vec[0]*ptype->offsetspread; + p->vel[0] = -vec[1]*ptype->spawnvel; + p->vel[1] = vec[0]*ptype->spawnvel; p->org[0] = -vec[1]*ptype->areaspread; p->org[1] = vec[0]*ptype->areaspread; } @@ -3026,8 +3394,8 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype p->org[1] = start[1] + right[1]*tright + up[1]*tup; p->org[2] = start[2] + right[2]*tright + up[2]*tup; - tright = tcos*ptype->offsetspread; - tup = tsin*ptype->offsetspread; + tright = tcos*ptype->spawnvel; + tup = tsin*ptype->spawnvel; p->vel[0] = vec[0]*veladd+crandom()*randvel + right[0]*tright + up[0]*tup; p->vel[1] = vec[1]*veladd+crandom()*randvel + right[1]*tright + up[1]*tup; @@ -3042,9 +3410,9 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype VectorNormalize(p->org); VectorScale(p->org, frandom(), p->org); - p->vel[0] = vec[0]*veladd+crandom()*randvel + p->org[0]*ptype->offsetspread; - p->vel[1] = vec[1]*veladd+crandom()*randvel + p->org[1]*ptype->offsetspread; - p->vel[2] = vec[2]*veladd+crandom()*randvelvert + p->org[2]*ptype->offsetspreadvert; + p->vel[0] = vec[0]*veladd+crandom()*randvel + p->org[0]*ptype->spawnvel; + p->vel[1] = vec[1]*veladd+crandom()*randvel + p->org[1]*ptype->spawnvel; + p->vel[2] = vec[2]*veladd+crandom()*randvelvert + p->org[2]*ptype->spawnvelvert; p->org[0] = p->org[0]*ptype->areaspread + start[0]; p->org[1] = p->org[1]*ptype->areaspread + start[1]; @@ -3062,8 +3430,8 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype p->org[1] = start[1] + right[1]*tcos + up[1]*tsin + vstep[1] * (len*tdegree); p->org[2] = start[2] + right[2]*tcos + up[2]*tsin + vstep[2] * (len*tdegree)*50; - tcos = cos(len*tdegree)*ptype->offsetspread; - tsin = sin(len*tdegree)*ptype->offsetspread; + tcos = cos(len*tdegree)*ptype->spawnvel; + tsin = sin(len*tdegree)*ptype->spawnvel; p->vel[0] = vec[0]*veladd+crandom()*randvel + right[0]*tcos + up[0]*tsin; p->vel[1] = vec[1]*veladd+crandom()*randvel + right[1]*tcos + up[1]*tsin; @@ -3087,9 +3455,9 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype VectorNormalize(p->org); VectorScale(p->org, rdist, p->org); - p->vel[0] = vec[0]*veladd+crandom()*randvel + p->org[0]*ptype->offsetspread; - p->vel[1] = vec[1]*veladd+crandom()*randvel + p->org[1]*ptype->offsetspread; - p->vel[2] = vec[2]*veladd+crandom()*randvelvert + p->org[2]*ptype->offsetspreadvert; + p->vel[0] = vec[0]*veladd+crandom()*randvel + p->org[0]*ptype->spawnvel; + p->vel[1] = vec[1]*veladd+crandom()*randvel + p->org[1]*ptype->spawnvel; + p->vel[2] = vec[2]*veladd+crandom()*randvelvert + p->org[2]*ptype->spawnvelvert; p->org[0] = p->org[0]*ptype->areaspread + start[0]; p->org[1] = p->org[1]*ptype->areaspread + start[1]; @@ -3101,9 +3469,9 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype p->org[1] = crandom(); p->org[2] = crandom(); - p->vel[0] = vec[0]*veladd+crandom()*randvel + p->org[0]*ptype->offsetspread; - p->vel[1] = vec[1]*veladd+crandom()*randvel + p->org[1]*ptype->offsetspread; - p->vel[2] = vec[2]*veladd+crandom()*randvelvert + p->org[2]*ptype->offsetspreadvert; + p->vel[0] = vec[0]*veladd+crandom()*randvel + p->org[0]*ptype->spawnvel; + p->vel[1] = vec[1]*veladd+crandom()*randvel + p->org[1]*ptype->spawnvel; + p->vel[2] = vec[2]*veladd+crandom()*randvelvert + p->org[2]*ptype->spawnvelvert; p->org[0] = p->org[0]*ptype->areaspread + start[0]; p->org[1] = p->org[1]*ptype->areaspread + start[1]; @@ -3245,6 +3613,8 @@ static void GL_DrawTexturedParticle(int count, particle_t **plist, plooks_t *typ } if (type->scalefactor == 1) + scale = p->scale; + else { scale = (p->org[0] - r_origin[0])*vpn[0] + (p->org[1] - r_origin[1])*vpn[1] + (p->org[2] - r_origin[2])*vpn[2]; @@ -3254,9 +3624,7 @@ static void GL_DrawTexturedParticle(int count, particle_t **plist, plooks_t *typ else scale = 0.25 + scale * 0.001; } - else - scale = 1; - + Vector4Copy(p->rgba, pscriptcolours[pscriptmesh.numvertexes+0]); Vector4Copy(p->rgba, pscriptcolours[pscriptmesh.numvertexes+1]); Vector4Copy(p->rgba, pscriptcolours[pscriptmesh.numvertexes+2]); @@ -3521,7 +3889,6 @@ static void GL_DrawClippedDecal(int count, clippeddecal_t **dlist, plooks_t *typ Vector4Copy(d->rgba, pscriptcolours[pscripttmesh.numvertexes+0]); Vector4Copy(d->rgba, pscriptcolours[pscripttmesh.numvertexes+1]); Vector4Copy(d->rgba, pscriptcolours[pscripttmesh.numvertexes+2]); - Vector4Copy(d->rgba, pscriptcolours[pscripttmesh.numvertexes+3]); Vector2Copy(d->texcoords[0], pscripttexcoords[pscripttmesh.numvertexes+0]); Vector2Copy(d->texcoords[1], pscripttexcoords[pscripttmesh.numvertexes+1]); @@ -3531,13 +3898,13 @@ static void GL_DrawClippedDecal(int count, clippeddecal_t **dlist, plooks_t *typ VectorCopy(d->vertex[1], pscriptverts[pscripttmesh.numvertexes+1]); VectorCopy(d->vertex[2], pscriptverts[pscripttmesh.numvertexes+2]); - pscriptmesh.numvertexes += 3; + pscripttmesh.numvertexes += 3; } - if (pscriptmesh.numvertexes) + if (pscripttmesh.numvertexes) { pscripttmesh.numindexes = pscripttmesh.numvertexes; - BE_DrawMesh_Single(type->shader, &pscriptmesh, NULL, &type->shader->defaulttextures); + BE_DrawMesh_Single(type->shader, &pscripttmesh, NULL, &type->shader->defaulttextures); pscripttmesh.numvertexes = 0; } } @@ -3582,6 +3949,7 @@ static void PScript_DrawParticleTypes (void (*texturedparticles)(int count, part } } r_plooksdirty = false; + CL_RegisterParticles(); } pframetime = host_frametime; @@ -3834,7 +4202,9 @@ static void PScript_DrawParticleTypes (void (*texturedparticles)(int count, part } grav = type->gravity*pframetime; - VectorScale(type->friction, pframetime, friction); + friction[0] = 1 - type->friction[0]*pframetime; + friction[1] = 1 - type->friction[1]*pframetime; + friction[2] = 1 - type->friction[2]*pframetime; for (p=type->particles ; p ; p=p->next) { @@ -3882,9 +4252,9 @@ static void PScript_DrawParticleTypes (void (*texturedparticles)(int count, part p->org[2] += p->vel[2]*pframetime; if (type->flags & PT_FRICTION) { - p->vel[0] -= friction[0]*p->vel[0]; - p->vel[1] -= friction[1]*p->vel[1]; - p->vel[2] -= friction[2]*p->vel[2]; + p->vel[0] *= friction[0]; + p->vel[1] *= friction[1]; + p->vel[2] *= friction[2]; } p->vel[2] -= grav; } @@ -4066,11 +4436,11 @@ static void PScript_DrawParticleTypes (void (*texturedparticles)(int count, part // delete from run list if necessary if (!type->particles && !type->beams && !type->clippeddecals) { -// if (!lastvalidtype) -// part_run_list = type->nexttorun; -// else -// lastvalidtype->nexttorun = type->nexttorun; -// type->state &= ~PS_INRUNLIST; + if (!lastvalidtype) + part_run_list = type->nexttorun; + else + lastvalidtype->nexttorun = type->nexttorun; + type->state &= ~PS_INRUNLIST; } else lastvalidtype = type; diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index 6b17650a9..7c6c156f6 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -358,13 +358,7 @@ typedef struct csqcedict_s #endif /*the above is shared with qclib*/ link_t area; - int num_leafs; - short leafnums[MAX_ENT_LEAFS]; -#ifdef Q2BSPS - int areanum; //q2bsp - int areanum2; //q2bsp - int headnode; //q2bsp -#endif + pvscache_t pvsinfo; #ifdef USEODE entityode_t ode; #endif diff --git a/engine/client/renderer.c b/engine/client/renderer.c index a83bfa0f7..7a32d6961 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -736,12 +736,6 @@ float (*Mod_GetFrameDuration) (struct model_s *model, int framenum); qboolean (*VID_Init) (rendererstate_t *info, unsigned char *palette); void (*VID_DeInit) (void); -void (*VID_LockBuffer) (void); -void (*VID_UnlockBuffer) (void); -void (*D_BeginDirectRect) (int x, int y, qbyte *pbitmap, int width, int height); -void (*D_EndDirectRect) (int x, int y, int width, int height); -void (*VID_ForceLockState) (int lk); -int (*VID_ForceUnlockedAndReturnState) (void); void (*VID_SetPalette) (unsigned char *palette); void (*VID_ShiftPalette) (unsigned char *palette); char *(*VID_GetRGBInfo) (int prepad, int *truevidwidth, int *truevidheight); @@ -821,12 +815,6 @@ rendererinfo_t dedicatedrendererinfo = { NULL, //VID_Init, NULL, //VID_DeInit, - NULL, //VID_LockBuffer, - NULL, //VID_UnlockBuffer, - NULL, //D_BeginDirectRect, - NULL, //D_EndDirectRect, - NULL, //VID_ForceLockState, - NULL, //VID_ForceUnlockedAndReturnState, NULL, //VID_SetPalette, NULL, //VID_ShiftPalette, NULL, //VID_GetRGBInfo, @@ -1344,12 +1332,6 @@ void R_SetRenderer(rendererinfo_t *ri) VID_Init = ri->VID_Init; VID_DeInit = ri->VID_DeInit; - VID_LockBuffer = ri->VID_LockBuffer; - VID_UnlockBuffer = ri->VID_UnlockBuffer; - D_BeginDirectRect = ri->D_BeginDirectRect; - D_EndDirectRect = ri->D_EndDirectRect; - VID_ForceLockState = ri->VID_ForceLockState; - VID_ForceUnlockedAndReturnState = ri->VID_ForceUnlockedAndReturnState; VID_SetPalette = ri->VID_SetPalette; VID_ShiftPalette = ri->VID_ShiftPalette; VID_GetRGBInfo = ri->VID_GetRGBInfo; diff --git a/engine/client/sys_win.c b/engine/client/sys_win.c index 81a5fe5d7..6612e36e2 100644 --- a/engine/client/sys_win.c +++ b/engine/client/sys_win.c @@ -386,7 +386,8 @@ DWORD CrashExceptionHandler (DWORD exceptionCode, LPEXCEPTION_POINTERS exception } } } - MessageBox(NULL, "Kaboom! Sorry. Blame the nubs.", DISTRIBUTION " Sucks", 0); + else + MessageBox(NULL, "Kaboom! Sorry. No MiniDumpWriteDump function.", DISTRIBUTION " Sucks", 0); return EXCEPTION_EXECUTE_HANDLER; } #endif @@ -739,9 +740,6 @@ void VARGS Sys_Printf (char *fmt, ...) void Sys_Quit (void) { #ifndef SERVERONLY - if (VID_ForceUnlockedAndReturnState) - VID_ForceUnlockedAndReturnState (); - SetHookState(false); Host_Shutdown (); diff --git a/engine/client/vid.h b/engine/client/vid.h index a405583fb..42cf56775 100644 --- a/engine/client/vid.h +++ b/engine/client/vid.h @@ -52,7 +52,6 @@ typedef struct unsigned width; unsigned height; - float aspect; // width / height -- < 0 is taller than wide int numpages; int recalc_refdef; // if true, recalc vid-based stuff @@ -88,16 +87,8 @@ int GLVID_SetMode (rendererstate_t *info, unsigned char *palette); // sets the mode; only used by the Quake engine for resetting to mode 0 (the // base mode) on memory allocation failures -void GLVID_LockBuffer (void); -void GLVID_UnlockBuffer (void); - -int GLVID_ForceUnlockedAndReturnState (void); -void GLVID_ForceLockState (int lk); - qboolean GLVID_Is8bit(); -void GLD_BeginDirectRect (int x, int y, qbyte *pbitmap, int width, int height); -void GLD_EndDirectRect (int x, int y, int width, int height); char *GLVID_GetRGBInfo(int prepadbytes, int *truewidth, int *trueheight); void GLVID_SetCaption(char *caption); #endif diff --git a/engine/common/cmd.c b/engine/common/cmd.c index 9e4366216..28618e926 100644 --- a/engine/common/cmd.c +++ b/engine/common/cmd.c @@ -24,6 +24,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. cvar_t com_fs_cache = SCVARF("fs_cache", IFMINIMAL("2","1"), CVAR_ARCHIVE); cvar_t rcon_level = SCVAR("rcon_level", "20"); cvar_t cmd_maxbuffersize = SCVAR("cmd_maxbuffersize", "65536"); +cvar_t dpcompat_set = SCVAR("dpcompat_set", "0"); int Cmd_ExecLevel; void Cmd_ForwardToServer (void); @@ -2594,6 +2595,7 @@ void Cmd_set_f(void) const char *text; int forceflags = 0; qboolean docalc; + char name[256]; if (Cmd_Argc()<3) { @@ -2606,7 +2608,7 @@ void Cmd_set_f(void) else docalc = false; - var = Cvar_Get (Cmd_Argv(1), "", 0, "Custom variables"); + Q_strncpyz(name, Cmd_Argv(1), sizeof(name)); if (Cmd_FromGamecode()) //AAHHHH!!! Q2 set command is different { @@ -2619,6 +2621,11 @@ void Cmd_set_f(void) return; text = Cmd_Argv(2); } + else if (dpcompat_set.ival) + { + text = Cmd_Argv(2); + /*desc = Cmd_Argv(3)*/ + } else { Cmd_ShiftArgs(1, false); @@ -2646,6 +2653,8 @@ void Cmd_set_f(void) forceflags = 0; } + var = Cvar_Get (name, text, 0, "Custom variables"); + mark = If_Token_GetMark(); if (var) diff --git a/engine/common/common.c b/engine/common/common.c index badca233e..3409992a4 100644 --- a/engine/common/common.c +++ b/engine/common/common.c @@ -1103,6 +1103,31 @@ int MSG_ReadBits(int bits) return bitmask; } +void MSG_ReadSkip(int bytes) +{ + if (net_message.packing!=SZ_RAWBYTES) + { + while (bytes > 4) + { + MSG_ReadBits(32); + bytes-=4; + } + while (bytes > 0) + { + MSG_ReadBits(8); + bytes--; + } + } + if (msg_readcount+bytes > net_message.cursize) + { + msg_readcount = net_message.cursize; + msg_badread = true; + return; + } + msg_readcount += bytes; +} + + // returns -1 and sets msg_badread if no more characters are available int MSG_ReadChar (void) { @@ -2393,6 +2418,12 @@ skipwhite: return NULL; // end of file; data++; } + if (c == '\n') + { + com_token[len++] = c; + com_token[len] = 0; + return (char*)data+1; + } // skip // comments if (c=='/') diff --git a/engine/common/common.h b/engine/common/common.h index 391ea7f24..4fa3e6da4 100644 --- a/engine/common/common.h +++ b/engine/common/common.h @@ -168,6 +168,7 @@ float MSG_ReadAngle16 (void); void MSG_ReadDeltaUsercmd (struct usercmd_s *from, struct usercmd_s *cmd); void MSGQ2_ReadDeltaUsercmd (struct usercmd_s *from, struct usercmd_s *move); void MSG_ReadData (void *data, int len); +void MSG_ReadSkip (int len); //============================================================================ @@ -372,7 +373,6 @@ qbyte *COM_LoadTempFile (const char *path); qbyte *COM_LoadTempFile2 (const char *path); //allocates a little bit more without freeing old temp qbyte *COM_LoadHunkFile (const char *path); void COM_LoadCacheFile (const char *path, struct cache_user_s *cu); -void COM_CreatePath (char *path); void FS_ForceToPure(const char *str, const char *crcs, int seed); char *COM_GetPathInfo (int i, int *crc); char *COM_NextPath (char *prevpath); diff --git a/engine/common/cvar.h b/engine/common/cvar.h index bc876202b..9a00683d5 100644 --- a/engine/common/cvar.h +++ b/engine/common/cvar.h @@ -117,7 +117,7 @@ typedef struct cvar_group_s //freestyle #define CVAR_POINTER (1<<5) // q2 style. May be converted to q1 if needed. These are often specified on the command line and then converted into q1 when registered properly. -#define CVAR_FREEDEFAULT (1<<6) // q2 style. May be converted to q1 if needed. These are often specified on the command line and then converted into q1 when registered properly. +#define CVAR_FREEDEFAULT (1<<6) //the default string was malloced/needs to be malloced, free on unregister #define CVAR_NOTFROMSERVER (1<<7) // the console will ignore changes to cvars if set at from the server or any gamecode. This is to protect against security flaws - like qterm #define CVAR_USERCREATED (1<<8) //write a 'set' or 'seta' in front of the var name. #define CVAR_CHEAT (1<<9) //latch to the default, unless cheats are enabled. diff --git a/engine/common/fs.c b/engine/common/fs.c index 3b6455e79..bfdf7cc77 100644 --- a/engine/common/fs.c +++ b/engine/common/fs.c @@ -137,6 +137,7 @@ int fs_hash_files; static const char *FS_GetCleanPath(const char *pattern, char *outbuf, int outlen); void FS_RegisterDefaultFileSystems(void); +static void COM_CreatePath (char *path); #define ENFORCEFOPENMODE(mode) {if (strcmp(mode, "r") && strcmp(mode, "w")/* && strcmp(mode, "rw")*/)Sys_Error("fs mode %s is not permitted here\n");} @@ -351,7 +352,7 @@ COM_CreatePath Only used for CopyFile and download ============ */ -void COM_CreatePath (char *path) +static void COM_CreatePath (char *path) { char *ofs; @@ -1799,7 +1800,8 @@ void COM_Gamedir (const char *dir) #endif } -#define NEXCFG "set sv_maxairspeed \"400\"\nset sv_mintic \"0.01\"\ncl_nolerp 0\n" +#define DPCOMPAT "set dpcompat_set 1\nset dpcompat_trailparticles 1\n" +#define NEXCFG DPCOMPAT "set sv_maxairspeed \"400\"\nset sv_jumpvelocity 270\nset sv_mintic \"0.01\"\ncl_nolerp 0\nset r_particlesdesc effectinfo\n" #define DMFCFG "set com_parseutf8 1\npm_airstep 1\n" typedef struct { diff --git a/engine/common/net_wins.c b/engine/common/net_wins.c index 5ea73872d..bf478952c 100644 --- a/engine/common/net_wins.c +++ b/engine/common/net_wins.c @@ -3347,16 +3347,16 @@ void NET_InitServer(void) char *port; port = STRINGIFY(PORT_SERVER); - if (!svs.sockets) - { - svs.sockets = FTENET_CreateCollection(true); -#ifndef SERVERONLY - FTENET_AddToCollection(svs.sockets, "SVLoopback", port, FTENET_Loop_EstablishConnection, true); -#endif - } - if (sv_listen_nq.value || sv_listen_dp.value || sv_listen_qw.value || sv_listen_q3.value) { + if (!svs.sockets) + { + svs.sockets = FTENET_CreateCollection(true); + #ifndef SERVERONLY + FTENET_AddToCollection(svs.sockets, "SVLoopback", port, FTENET_Loop_EstablishConnection, true); + #endif + } + allowconnects = true; Cvar_ForceCallback(&sv_port); @@ -3374,8 +3374,15 @@ void NET_InitServer(void) #endif } else + { NET_CloseServer(); +#ifndef SERVERONLY + svs.sockets = FTENET_CreateCollection(true); + FTENET_AddToCollection(svs.sockets, "SVLoopback", port, FTENET_Loop_EstablishConnection, true); +#endif + } + // // init the message buffer diff --git a/engine/common/particles.h b/engine/common/particles.h index 9da8b8154..4f2b48625 100644 --- a/engine/common/particles.h +++ b/engine/common/particles.h @@ -77,7 +77,7 @@ typedef struct trailstate_s { #define PARTICLE_Z_CLIP 8.0 -typedef enum { BM_BLEND, BM_BLENDCOLOUR, BM_ADD, BM_SUBTRACT } blendmode_t; +typedef enum { BM_BLEND, BM_BLENDCOLOUR, BM_ADD, BM_SUBTRACT, BM_INVMOD } blendmode_t; #define frandom() (rand()*(1.0f/RAND_MAX)) #define crandom() (rand()*(2.0f/RAND_MAX)-1.0f) diff --git a/engine/common/protocol.h b/engine/common/protocol.h index 2ca41dec9..6ea5d6cef 100644 --- a/engine/common/protocol.h +++ b/engine/common/protocol.h @@ -93,6 +93,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #define PROTOCOL_VERSION_FTE (('F'<<0) + ('T'<<8) + ('E'<<16) + ('X' << 24)) //fte extensions. #define PROTOCOL_VERSION_FTE2 (('F'<<0) + ('T'<<8) + ('E'<<16) + ('2' << 24)) //fte extensions. #define PROTOCOL_VERSION_HUFFMAN (('H'<<0) + ('U'<<8) + ('F'<<16) + ('F' << 24)) //packet compression +#define PROTOCOL_VERSION_VARLENGTH (('v'<<0) + ('l'<<8) + ('e'<<16) + ('n' << 24)) //packet compression #define PROTOCOL_VERSION_QW 28 #define PROTOCOL_VERSION_Q2_MIN 31 diff --git a/engine/gl/gl_alias.c b/engine/gl/gl_alias.c index d13e380fd..8292e1968 100644 --- a/engine/gl/gl_alias.c +++ b/engine/gl/gl_alias.c @@ -883,14 +883,11 @@ void R_DrawGAliasModel (entity_t *e, unsigned int rmode) galiasinfo_t *inf; mesh_t mesh; texnums_t *skin; - float entScale; vec3_t saveorg; int surfnum; int bef; - float tmatrix[3][4]; - qboolean needrecolour; qboolean nolightdir; @@ -946,7 +943,7 @@ void R_DrawGAliasModel (entity_t *e, unsigned int rmode) bef = BEF_FORCEDEPTHTEST; if (e->flags & Q2RF_ADDITIVE) { - bef |= BEF_FORCETRANSPARENT; + bef |= BEF_FORCEADDITIVE; } else if (e->drawflags & DRF_TRANSLUCENT) { @@ -973,113 +970,7 @@ void R_DrawGAliasModel (entity_t *e, unsigned int rmode) qglPushMatrix(); - R_RotateForEntity(e); - - if (e->scale != 1 && e->scale != 0) //hexen 2 stuff - { - vec3_t scale; - vec3_t scale_origin; - float xyfact, zfact; - scale[0] = (clmodel->maxs[0]-clmodel->mins[0])/255; - scale[1] = (clmodel->maxs[1]-clmodel->mins[1])/255; - scale[2] = (clmodel->maxs[2]-clmodel->mins[2])/255; - scale_origin[0] = clmodel->mins[0]; - scale_origin[1] = clmodel->mins[1]; - scale_origin[2] = clmodel->mins[2]; - -/* qglScalef( 1/scale[0], - 1/scale[1], - 1/scale[2]); - qglTranslatef ( -scale_origin[0], - -scale_origin[1], - -scale_origin[2]); -*/ - - if(e->scale != 0 && e->scale != 1) - { - entScale = (float)e->scale; - switch(e->drawflags&SCALE_TYPE_MASKIN) - { - default: - case SCALE_TYPE_UNIFORM: - tmatrix[0][0] = scale[0]*entScale; - tmatrix[1][1] = scale[1]*entScale; - tmatrix[2][2] = scale[2]*entScale; - xyfact = zfact = (entScale-1.0)*127.95; - break; - case SCALE_TYPE_XYONLY: - tmatrix[0][0] = scale[0]*entScale; - tmatrix[1][1] = scale[1]*entScale; - tmatrix[2][2] = scale[2]; - xyfact = (entScale-1.0)*127.95; - zfact = 1.0; - break; - case SCALE_TYPE_ZONLY: - tmatrix[0][0] = scale[0]; - tmatrix[1][1] = scale[1]; - tmatrix[2][2] = scale[2]*entScale; - xyfact = 1.0; - zfact = (entScale-1.0)*127.95; - break; - } - switch(currententity->drawflags&SCALE_ORIGIN_MASKIN) - { - default: - case SCALE_ORIGIN_CENTER: - tmatrix[0][3] = scale_origin[0]-scale[0]*xyfact; - tmatrix[1][3] = scale_origin[1]-scale[1]*xyfact; - tmatrix[2][3] = scale_origin[2]-scale[2]*zfact; - break; - case SCALE_ORIGIN_BOTTOM: - tmatrix[0][3] = scale_origin[0]-scale[0]*xyfact; - tmatrix[1][3] = scale_origin[1]-scale[1]*xyfact; - tmatrix[2][3] = scale_origin[2]; - break; - case SCALE_ORIGIN_TOP: - tmatrix[0][3] = scale_origin[0]-scale[0]*xyfact; - tmatrix[1][3] = scale_origin[1]-scale[1]*xyfact; - tmatrix[2][3] = scale_origin[2]-scale[2]*zfact*2.0; - break; - } - } - else - { - tmatrix[0][0] = scale[0]; - tmatrix[1][1] = scale[1]; - tmatrix[2][2] = scale[2]; - tmatrix[0][3] = scale_origin[0]; - tmatrix[1][3] = scale_origin[1]; - tmatrix[2][3] = scale_origin[2]; - } - -/* if(clmodel->flags&EF_ROTATE) - { // Floating motion - tmatrix[2][3] += sin(currententity->origin[0] - +currententity->origin[1]+(cl.time*3))*5.5; - }*/ - - qglTranslatef (tmatrix[0][3],tmatrix[1][3],tmatrix[2][3]); - qglScalef (tmatrix[0][0],tmatrix[1][1],tmatrix[2][2]); - - qglScalef( 1/scale[0], - 1/scale[1], - 1/scale[2]); - qglTranslatef ( -scale_origin[0], - -scale_origin[1], - -scale_origin[2]); - } - else if (!strcmp(clmodel->name, "progs/eyes.mdl")) - { - // double size of eyes, since they are really hard to see in gl - qglTranslatef (0, 0, 0 - (22 + 8)); - qglScalef (2, 2, 2); - } - - if (!ruleset_allow_larger_models.ival && clmodel->clampscale != 1) - { //possibly this should be on a per-frame basis, but that's a real pain to do - Con_DPrintf("Rescaling %s by %f\n", clmodel->name, clmodel->clampscale); - qglScalef(clmodel->clampscale, clmodel->clampscale, clmodel->clampscale); - } + R_RotateForEntity(e, clmodel); inf = RMod_Extradata (clmodel); if (qglPNTrianglesfATI && gl_ati_truform.ival) @@ -1366,7 +1257,7 @@ void R_DrawGAliasShadowVolume(entity_t *e, vec3_t lightpos, float radius) return; qglPushMatrix(); - R_RotateForEntity(e); + R_RotateForEntity(e, clmodel); inf = RMod_Extradata (clmodel); diff --git a/engine/gl/gl_backend.c b/engine/gl/gl_backend.c index dbd7fe14a..a9f797ea0 100644 --- a/engine/gl/gl_backend.c +++ b/engine/gl/gl_backend.c @@ -185,7 +185,6 @@ void main (void)\n\ vec3 halfdir = (normalize(eyevector) + normalize(lightvector))/2.0;\n\ float dv = dot(halfdir, bumps);\n\ diff += pow(dv, 8.0) * specs;\n\ - diff.g = pow(dv, 8.0);\n\ #endif\n\ ""\n\ #ifdef PCF\n\ @@ -942,7 +941,7 @@ static void tcgen_environment(float *st, unsigned int numverts, float *xyz, floa RotateLightVector(shaderstate.curentity->axis, shaderstate.curentity->origin, r_origin, rorg); - for (i = 0 ; i < numverts ; i++, xyz += 3, normal += 3, st += 2 ) + for (i = 0 ; i < numverts ; i++, xyz += sizeof(vecV_t)/sizeof(vec_t), normal += 3, st += 2 ) { VectorSubtract (rorg, xyz, viewer); VectorNormalizeFast (viewer); @@ -1777,15 +1776,12 @@ static void BE_SendPassBlendAndDepth(unsigned int sbits) } if (shaderstate.flags & ~BEF_PUSHDEPTH) { - if (!(sbits & SBITS_BLEND_BITS)) - { /*only force blend bits if its not already blended*/ - if (shaderstate.flags & BEF_FORCEADDITIVE) - sbits = (sbits & ~(SBITS_MISC_DEPTHWRITE|SBITS_BLEND_BITS|SBITS_ATEST_BITS)) - | (SBITS_SRCBLEND_ONE | SBITS_DSTBLEND_ONE); - else if (shaderstate.flags & BEF_FORCETRANSPARENT) /*if transparency is forced, clear alpha test bits*/ - sbits = (sbits & ~(SBITS_MISC_DEPTHWRITE|SBITS_BLEND_BITS|SBITS_ATEST_BITS)) - | (SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA); - } + if (shaderstate.flags & BEF_FORCEADDITIVE) + sbits = (sbits & ~(SBITS_MISC_DEPTHWRITE|SBITS_BLEND_BITS|SBITS_ATEST_BITS)) + | (SBITS_SRCBLEND_ONE | SBITS_DSTBLEND_ONE); + else if ((shaderstate.flags & BEF_FORCETRANSPARENT) && !(sbits & SBITS_BLEND_BITS)) /*if transparency is forced, clear alpha test bits*/ + sbits = (sbits & ~(SBITS_MISC_DEPTHWRITE|SBITS_BLEND_BITS|SBITS_ATEST_BITS)) + | (SBITS_SRCBLEND_SRC_ALPHA | SBITS_DSTBLEND_ONE_MINUS_SRC_ALPHA); if (shaderstate.flags & BEF_FORCENODEPTH) /*EF_NODEPTHTEST dp extension*/ sbits |= SBITS_MISC_NODEPTHTEST; @@ -1908,10 +1904,25 @@ static void BE_SubmitMeshChain(void) int startv, starti, endv, endi; int m; mesh_t *mesh; + extern cvar_t temp1; + if (temp1.ival) + { + endv = 0; + startv = 0x7fffffff; + for (m = 0; m < shaderstate.meshcount; m++) + { + mesh = shaderstate.meshes[m]; + starti = mesh->vbofirstvert; + if (starti < startv) + startv = starti; + endi = mesh->vbofirstvert+mesh->numvertexes; + if (endi > endv) + endv = endi; + } + qglLockArraysEXT(startv, endv); + } - mesh = shaderstate.meshes[0]; - - for (m = 0; m < shaderstate.meshcount; ) + for (m = 0, mesh = shaderstate.meshes[0]; m < shaderstate.meshcount; ) { startv = mesh->vbofirstvert; starti = mesh->vbofirstelement; @@ -1936,6 +1947,8 @@ static void BE_SubmitMeshChain(void) qglDrawRangeElements(GL_TRIANGLES, startv, endv, endi-starti, GL_INDEX_TYPE, shaderstate.sourcevbo->indicies + starti); } + if (temp1.ival) + qglUnlockArraysEXT(); } static void DrawPass(const shaderpass_t *pass) @@ -2546,15 +2559,16 @@ static void BaseBrushTextures(entity_t *ent) batch_t batch; mesh_t *batchmeshes[64]; + model = ent->model; + #ifdef RTLIGHTS - if (BE_LightCullModel(ent->origin, ent->model)) + if (BE_LightCullModel(ent->origin, model)) return; #endif qglPushMatrix(); - R_RotateForEntity(ent); + R_RotateForEntity(ent, model); - model = ent->model; chain = NULL; // calculate dynamic lighting for bmodel if it's not an diff --git a/engine/gl/gl_hlmdl.c b/engine/gl/gl_hlmdl.c index 695ec94c4..804271434 100644 --- a/engine/gl/gl_hlmdl.c +++ b/engine/gl/gl_hlmdl.c @@ -613,7 +613,7 @@ void R_DrawHLModel(entity_t *curent) qglColor4f(difuse[0]/255+ambient[0]/255, difuse[1]/255+ambient[1]/255, difuse[2]/255+ambient[2]/255, curent->shaderRGBAf[3]); } - R_RotateForEntity (curent); + R_RotateForEntity (curent, curent->model); cbone = 0; for (bgroup = 0; bgroup < FS_COUNT; bgroup++) diff --git a/engine/gl/gl_rmain.c b/engine/gl/gl_rmain.c index 30fb11292..283f20d83 100644 --- a/engine/gl/gl_rmain.c +++ b/engine/gl/gl_rmain.c @@ -491,7 +491,7 @@ void GL_SetupSceneProcessingTextures (void) qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGB, PP_WARP_TEX_SIZE, PP_WARP_TEX_SIZE, 0, GL_RGB, GL_UNSIGNED_BYTE, pp_edge_tex); } -void R_RotateForEntity (entity_t *e) +void R_RotateForEntity (entity_t *e, model_t *mod) { float m[16]; if (e->flags & Q2RF_WEAPONMODEL && r_refdef.currentplayernum>=0) @@ -540,6 +540,101 @@ void R_RotateForEntity (entity_t *e) m[15] = 1; qglMultMatrixf(m); + + if (!mod) + return; + + if (e->scale != 1 && e->scale != 0) //hexen 2 stuff + { + float tmatrix[3][4]; + vec3_t scale; + vec3_t scale_origin; + float xyfact, zfact, entScale; + scale[0] = (mod->maxs[0]-mod->mins[0])/255; + scale[1] = (mod->maxs[1]-mod->mins[1])/255; + scale[2] = (mod->maxs[2]-mod->mins[2])/255; + scale_origin[0] = mod->mins[0]; + scale_origin[1] = mod->mins[1]; + scale_origin[2] = mod->mins[2]; + + + entScale = (float)e->scale; + switch(e->drawflags&SCALE_TYPE_MASKIN) + { + default: + case SCALE_TYPE_UNIFORM: + tmatrix[0][0] = scale[0]*entScale; + tmatrix[1][1] = scale[1]*entScale; + tmatrix[2][2] = scale[2]*entScale; + xyfact = zfact = (entScale-1.0)*127.95; + break; + case SCALE_TYPE_XYONLY: + tmatrix[0][0] = scale[0]*entScale; + tmatrix[1][1] = scale[1]*entScale; + tmatrix[2][2] = scale[2]; + xyfact = (entScale-1.0)*127.95; + zfact = 1.0; + break; + case SCALE_TYPE_ZONLY: + tmatrix[0][0] = scale[0]; + tmatrix[1][1] = scale[1]; + tmatrix[2][2] = scale[2]*entScale; + xyfact = 1.0; + zfact = (entScale-1.0)*127.95; + break; + } + switch(currententity->drawflags&SCALE_ORIGIN_MASKIN) + { + default: + case SCALE_ORIGIN_CENTER: + tmatrix[0][3] = scale_origin[0]-scale[0]*xyfact; + tmatrix[1][3] = scale_origin[1]-scale[1]*xyfact; + tmatrix[2][3] = scale_origin[2]-scale[2]*zfact; + break; + case SCALE_ORIGIN_BOTTOM: + tmatrix[0][3] = scale_origin[0]-scale[0]*xyfact; + tmatrix[1][3] = scale_origin[1]-scale[1]*xyfact; + tmatrix[2][3] = scale_origin[2]; + break; + case SCALE_ORIGIN_TOP: + tmatrix[0][3] = scale_origin[0]-scale[0]*xyfact; + tmatrix[1][3] = scale_origin[1]-scale[1]*xyfact; + tmatrix[2][3] = scale_origin[2]-scale[2]*zfact*2.0; + break; + } + /* + { + tmatrix[0][0] = scale[0]; + tmatrix[1][1] = scale[1]; + tmatrix[2][2] = scale[2]; + tmatrix[0][3] = scale_origin[0]; + tmatrix[1][3] = scale_origin[1]; + tmatrix[2][3] = scale_origin[2]; + } + */ + + qglTranslatef (tmatrix[0][3],tmatrix[1][3],tmatrix[2][3]); + qglScalef (tmatrix[0][0],tmatrix[1][1],tmatrix[2][2]); + + qglScalef( 1/scale[0], + 1/scale[1], + 1/scale[2]); + qglTranslatef ( -scale_origin[0], + -scale_origin[1], + -scale_origin[2]); + } + else if (!strcmp(mod->name, "progs/eyes.mdl")) + { + // double size of eyes, since they are really hard to see in gl + qglTranslatef (0, 0, 0 - (22 + 8)); + qglScalef (2, 2, 2); + } + + if (!ruleset_allow_larger_models.ival && mod->clampscale != 1) + { //possibly this should be on a per-frame basis, but that's a real pain to do + Con_DPrintf("Rescaling %s by %f\n", mod->name, mod->clampscale); + qglScalef(mod->clampscale, mod->clampscale, mod->clampscale); + } } /* diff --git a/engine/gl/gl_shader.c b/engine/gl/gl_shader.c index 4c4afb8aa..fd03cd470 100644 --- a/engine/gl/gl_shader.c +++ b/engine/gl/gl_shader.c @@ -1614,7 +1614,8 @@ void Shader_Free (shader_t *shader) int i; shaderpass_t *pass; - Hash_RemoveData(&shader_active_hash, shader->name, shader); + if (shader->bucket.data == shader) + Hash_RemoveData(&shader_active_hash, shader->name, shader); #ifdef GLQUAKE if (qrenderer == QR_OPENGL) @@ -2408,6 +2409,7 @@ void Shader_DefaultBSPLM(char *shortname, shader_t *s, const void *args) "{\n" "map $normalmap\n" "tcgen base\n" + "depthwrite\n" "}\n" "{\n" "map $deluxmap\n" @@ -2417,6 +2419,10 @@ void Shader_DefaultBSPLM(char *shortname, shader_t *s, const void *args) "{\n" "map $diffuse\n" "tcgen base\n" + "if $deluxmap\n" + "[\n" + "blendfunc gl_one gl_zero\n" + "]\n" "}\n" "if $lightmap\n" "[\n" @@ -2425,11 +2431,14 @@ void Shader_DefaultBSPLM(char *shortname, shader_t *s, const void *args) "blendfunc gl_dst_color gl_zero\n" "}\n" "]\n" - "{\n" - "map $fullbright\n" - "blendfunc add\n" - "depthfunc equal\n" - "}\n" + "if r_fb_bmodels\n" + "[\n" + "{\n" + "map $fullbright\n" + "blendfunc add\n" + "depthfunc equal\n" + "}\n" + "]\n" "}\n" ); diff --git a/engine/gl/gl_shadow.c b/engine/gl/gl_shadow.c index cf2e87e82..c6075d2ba 100644 --- a/engine/gl/gl_shadow.c +++ b/engine/gl/gl_shadow.c @@ -1698,11 +1698,6 @@ static void Sh_DrawEntLighting(dlight_t *light, vec3_t colour) } - -#pragma message "move to header" -void BE_PushOffsetShadow(qboolean foobar); - - #define PROJECTION_DISTANCE (float)(dl->radius*2)//0x7fffffff /*Fixme: this is brute forced*/ static void Sh_DrawBrushModelShadow(dlight_t *dl, entity_t *e) @@ -1722,7 +1717,7 @@ static void Sh_DrawBrushModelShadow(dlight_t *dl, entity_t *e) RotateLightVector(e->axis, e->origin, dl->origin, lightorg); qglPushMatrix(); - R_RotateForEntity(e); + R_RotateForEntity(e, e->model); GL_SelectVBO(0); GL_SelectEBO(0); diff --git a/engine/gl/gl_vidcommon.c b/engine/gl/gl_vidcommon.c index b5ce97fe1..28692f994 100644 --- a/engine/gl/gl_vidcommon.c +++ b/engine/gl/gl_vidcommon.c @@ -851,12 +851,6 @@ rendererinfo_t openglrendererinfo = { GLVID_Init, GLVID_DeInit, - GLVID_LockBuffer, - GLVID_UnlockBuffer, - GLD_BeginDirectRect, - GLD_EndDirectRect, - GLVID_ForceLockState, - GLVID_ForceUnlockedAndReturnState, GLVID_SetPalette, GLVID_ShiftPalette, GLVID_GetRGBInfo, diff --git a/engine/gl/gl_vidlinuxglx.c b/engine/gl/gl_vidlinuxglx.c index 0346a97a0..5427adb91 100644 --- a/engine/gl/gl_vidlinuxglx.c +++ b/engine/gl/gl_vidlinuxglx.c @@ -183,15 +183,6 @@ void *GLX_GetSymbol(char *name) return symb; } - -void GLD_BeginDirectRect (int x, int y, qbyte *pbitmap, int width, int height) -{ -} - -void GLD_EndDirectRect (int x, int y, int width, int height) -{ -} - static int XLateKey(XKeyEvent *ev, unsigned int *unicode) { @@ -951,7 +942,6 @@ qboolean GLVID_Init (rendererstate_t *info, unsigned char *palette) if (vid.width > info->width) vid.width = info->width; - vid.aspect = ((float)vid.height / (float)vid.width) * (320.0 / 240.0); vid.numpages = 2; InitSig(); // trap evil signals @@ -1121,13 +1111,6 @@ void IN_Move (float *movements, int pnum) } #endif - -void GLVID_UnlockBuffer() {} -void GLVID_LockBuffer() {} - -int GLVID_ForceUnlockedAndReturnState (void) {return 0;} -void GLVID_ForceLockState (int lk) {} - void GL_DoSwap(void) {} void GLVID_SetCaption(char *text) diff --git a/engine/gl/gl_vidmacos.c b/engine/gl/gl_vidmacos.c index dd8d2d8b2..616994c93 100644 --- a/engine/gl/gl_vidmacos.c +++ b/engine/gl/gl_vidmacos.c @@ -189,14 +189,6 @@ qboolean GLVID_IsLocked(void) return 0; } -void GLD_BeginDirectRect(int x, int y, qbyte *pbitmap, int width, int height) -{ -} - -void GLD_EndDirectRect(int x, int y, int width, int height) -{ -} - void GLVID_SetCaption(char *text) { } diff --git a/engine/gl/gl_vidnt.c b/engine/gl/gl_vidnt.c index 21f9a6b2b..4e95fed85 100644 --- a/engine/gl/gl_vidnt.c +++ b/engine/gl/gl_vidnt.c @@ -325,15 +325,6 @@ int GLVID_ForceUnlockedAndReturnState (void) return 0; } -void GLD_BeginDirectRect (int x, int y, qbyte *pbitmap, int width, int height) -{ -} - -void GLD_EndDirectRect (int x, int y, int width, int height) -{ -} - - void CenterWindow(HWND hWndCenter, int width, int height, BOOL lefttopjustify) { // RECT rect; diff --git a/engine/gl/gl_vidnull.c b/engine/gl/gl_vidnull.c index b5d7c2e10..faa2364ab 100644 --- a/engine/gl/gl_vidnull.c +++ b/engine/gl/gl_vidnull.c @@ -33,11 +33,8 @@ void GLD_EndDirectRect(int x, int y, int width, int height) { } -void GL_BeginRendering (int *x, int *y, int *width, int *height) +void GL_BeginRendering (void) { - *x = *y = 0; - *width = 640; - *height = 480; } void GL_EndRendering (void) diff --git a/engine/gl/gl_vidsdl.c b/engine/gl/gl_vidsdl.c index cbc356a85..66091e4b2 100644 --- a/engine/gl/gl_vidsdl.c +++ b/engine/gl/gl_vidsdl.c @@ -102,7 +102,7 @@ void GLVID_DeInit (void) } -void GL_BeginRendering () +void GL_BeginRendering (void) { vid.pixelwidth = glwidth; vid.pixelheight = glheight; @@ -150,32 +150,6 @@ void GL_EndRendering (void) GL_DoSwap(); } - - -void GLVID_LockBuffer (void) -{ -} - -void GLVID_UnlockBuffer (void) -{ -} - -int GLVID_ForceUnlockedAndReturnState (void) -{ - return 0; -} - -void GLD_BeginDirectRect (int x, int y, qbyte *pbitmap, int width, int height) -{ -} - -void GLD_EndDirectRect (int x, int y, int width, int height) -{ -} -void GLVID_ForceLockState (int lk) -{ -} - void GLVID_SetPalette (unsigned char *palette) { qbyte *pal; diff --git a/engine/gl/glquake.h b/engine/gl/glquake.h index 4fc155d30..84a2a4c8f 100644 --- a/engine/gl/glquake.h +++ b/engine/gl/glquake.h @@ -316,7 +316,7 @@ qboolean R_CullBox (vec3_t mins, vec3_t maxs); #ifdef GLQUAKE qboolean R_CullSphere (vec3_t origin, float radius); qboolean R_CullEntityBox(entity_t *e, vec3_t modmins, vec3_t modmaxs); -void R_RotateForEntity (entity_t *e); +void R_RotateForEntity (entity_t *e, model_t *mod); void GL_InitSceneProcessingShaders (void); void GL_SetupSceneProcessingTextures (void); diff --git a/engine/gl/shader.h b/engine/gl/shader.h index 8653f332b..eae962dc2 100644 --- a/engine/gl/shader.h +++ b/engine/gl/shader.h @@ -404,6 +404,7 @@ void BE_ClearVBO(vbo_t *vbo); void BE_UploadAllLightmaps(void); #ifdef RTLIGHTS +void BE_PushOffsetShadow(qboolean foobar); //submits the world and ents... used only by gl_shadows.c void BE_SubmitMeshes (void); //sets up gl for depth-only FIXME diff --git a/engine/qclib/pr_multi.c b/engine/qclib/pr_multi.c index e26c83d7d..64142837f 100644 --- a/engine/qclib/pr_multi.c +++ b/engine/qclib/pr_multi.c @@ -205,7 +205,7 @@ void QC_FlushProgsOffsets(progfuncs_t *progfuncs) //origionaloffs is used to track matching field offsets. fields with the same progs offset overlap //note: we probably suffer from progs with renamed system globals. -int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, size_t engineofs, size_t progsofs) +int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, signed long engineofs, signed long progsofs) { // progstate_t *p; // int pnum; diff --git a/engine/qclib/progsint.h b/engine/qclib/progsint.h index 0b2de713c..f78fac374 100644 --- a/engine/qclib/progsint.h +++ b/engine/qclib/progsint.h @@ -101,7 +101,7 @@ 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, char *stringtable); -int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, size_t requestedpos, size_t originalofs); +int QC_RegisterFieldVar(progfuncs_t *progfuncs, unsigned int type, char *name, signed long requestedpos, signed long originalofs); pbool Decompile(progfuncs_t *progfuncs, char *fname); int PR_ToggleBreakpoint(progfuncs_t *progfuncs, char *filename, int linenum, int flag); void StripExtension (char *path); diff --git a/engine/qclib/progslib.h b/engine/qclib/progslib.h index 3554f3606..635d29d4b 100644 --- a/engine/qclib/progslib.h +++ b/engine/qclib/progslib.h @@ -1,26 +1,6 @@ #ifndef PROGSLIB_H #define PROGSLIB_H -/*#define true 1 -#define false 0 - -#define PITCH 0 -#define YAW 1 -#define ROLL 2 - -typedef char bool; -//typedef float vec3_t[3]; -typedef int progsnum_t; -typedef int func_t; -#ifndef COMPILER -typedef char *string_t; -#endif -//typedef struct globalvars_s globalvars_t; -//typedef struct edict_s edict_t; -#define globalvars_t void -#define edict_t void -*/ - #ifdef _MSC_VER #define VARGS __cdecl #endif @@ -132,7 +112,7 @@ struct progfuncs_s { int lastcalledbuiltinnumber; //useful with non-implemented opcodes. - int (*RegisterFieldVar) (progfuncs_t *prinst, unsigned int type, char *name, size_t requestedpos, size_t originalofs); + int (*RegisterFieldVar) (progfuncs_t *prinst, unsigned int type, char *name, signed long requestedpos, signed long originalofs); char *tempstringbase; //for engine's use. Store your base tempstring pointer here. int tempstringnum; //for engine's use. diff --git a/engine/qclib/qcc_pr_comp.c b/engine/qclib/qcc_pr_comp.c index ca50f65fc..687bbb01c 100644 --- a/engine/qclib/qcc_pr_comp.c +++ b/engine/qclib/qcc_pr_comp.c @@ -9103,7 +9103,7 @@ void QCC_PR_ParseDefs (char *classname) def->constant = false; else def->constant = true; - if (QCC_PR_CheckImmediate("0")) + if (QCC_PR_CheckImmediate("0") || QCC_PR_CheckImmediate("0i")) { def->constant = 0; def->initialized = 1; //fake function diff --git a/engine/qclib/qcc_pr_lex.c b/engine/qclib/qcc_pr_lex.c index 7e88679d2..3befbcd3b 100644 --- a/engine/qclib/qcc_pr_lex.c +++ b/engine/qclib/qcc_pr_lex.c @@ -2385,14 +2385,6 @@ CompilerConstant_t *QCC_PR_CheckCompConstDefined(char *def) { CompilerConstant_t *c = pHash_Get(&compconstantstable, def); return c; - /*int a; - for (a = 0; a < numCompilerConstants; a++) - { - if (!strncmp(def, CompilerConstant[a].name, CompilerConstant[a].namelen+1)) - return &CompilerConstant[a]; - } - return NULL; - */ } //============================================================================ diff --git a/engine/server/pr_cmds.c b/engine/server/pr_cmds.c index 47d5f8b54..0a438cd0f 100644 --- a/engine/server/pr_cmds.c +++ b/engine/server/pr_cmds.c @@ -35,6 +35,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. void ED_Print (struct progfuncs_s *progfuncs, struct edict_s *ed); int PR_EnableEBFSBuiltin(char *name, int binum); +/*cvars for the gamecode only*/ cvar_t nomonsters = SCVAR("nomonsters", "0"); cvar_t gamecfg = SCVAR("gamecfg", "0"); cvar_t scratch1 = SCVAR("scratch1", "0"); @@ -49,10 +50,16 @@ cvar_t saved4 = SCVARF("saved4", "0", CVAR_ARCHIVE); cvar_t temp1 = SCVARF("temp1", "0", CVAR_ARCHIVE); cvar_t noexit = SCVAR("noexit", "0"); -cvar_t pr_maxedicts = SCVARF("pr_maxedicts", "2048", CVAR_LATCH); +/*cvars purely for compat with others*/ +cvar_t dpcompat_trailparticles = SCVAR("dpcompat_trailparticles", "0"); cvar_t pr_imitatemvdsv = SCVARF("pr_imitatemvdsv", "0", CVAR_LATCH); + +/*compat with frikqcc's arrays (ensures that unknown fields are at the same offsets*/ cvar_t pr_fixbrokenqccarrays = SCVARF("pr_fixbrokenqccarrays", "1", CVAR_LATCH); +/*other stuff*/ +cvar_t pr_maxedicts = SCVARF("pr_maxedicts", "2048", CVAR_LATCH); + cvar_t pr_no_playerphysics = SCVARF("pr_no_playerphysics", "0", CVAR_LATCH); cvar_t progs = SCVARF("progs", "", CVAR_ARCHIVE | CVAR_SERVERINFO | CVAR_NOTFROMSERVER); @@ -1013,9 +1020,11 @@ void PR_Init(void) Cmd_AddCommand ("svtestprogs", QCLibTest); #endif */ - Cvar_Register(&pr_maxedicts, cvargroup_progs); + Cvar_Register(&dpcompat_trailparticles, "Darkplaces compatibility"); Cvar_Register(&pr_imitatemvdsv, cvargroup_progs); Cvar_Register(&pr_fixbrokenqccarrays, cvargroup_progs); + + Cvar_Register(&pr_maxedicts, cvargroup_progs); Cvar_Register(&pr_no_playerphysics, cvargroup_progs); for (i = 0; i < MAXADDONS; i++) @@ -7228,12 +7237,23 @@ void PF_sv_particleeffectnum(progfuncs_t *prinst, struct globalvars_s *pr_global void PF_sv_trailparticles(progfuncs_t *prinst, struct globalvars_s *pr_globals) { #ifdef PEXT_CSQC -#pragma message("PF_sv_trailparticles: first two parameters differ from dp, but comply with spec") - int efnum = G_FLOAT(OFS_PARM0); - int ednum = G_EDICTNUM(prinst, OFS_PARM1); + int efnum; + int ednum; float *start = G_VECTOR(OFS_PARM2); float *end = G_VECTOR(OFS_PARM3); + /*DP gets this wrong*/ + if (dpcompat_trailparticles.ival) + { + ednum = G_EDICTNUM(prinst, OFS_PARM0); + efnum = G_FLOAT(OFS_PARM1); + } + else + { + efnum = G_FLOAT(OFS_PARM0); + ednum = G_EDICTNUM(prinst, OFS_PARM1); + } + MSG_WriteByte(&sv.multicast, svcfte_trailparticles); MSG_WriteShort(&sv.multicast, ednum); MSG_WriteShort(&sv.multicast, efnum); diff --git a/engine/server/sv_ents.c b/engine/server/sv_ents.c index c29db2b97..00428256c 100644 --- a/engine/server/sv_ents.c +++ b/engine/server/sv_ents.c @@ -2440,7 +2440,7 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs, if (ent->xv->customizeentityforclient) { pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent); - pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, clent); + pr_global_struct->other = (clent?EDICT_TO_PROG(svprogfuncs, clent):0); PR_ExecuteProgram(svprogfuncs, ent->xv->customizeentityforclient); if(!G_FLOAT(OFS_RETURN)) continue; @@ -2448,7 +2448,7 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs, if (ent->xv->viewmodelforclient) { - if (ent->xv->viewmodelforclient != EDICT_TO_PROG(svprogfuncs, host_client->edict)) + if (ent->xv->viewmodelforclient != (clent?EDICT_TO_PROG(svprogfuncs, clent):0)) continue; pvsflags = PVSF_IGNOREPVS; } diff --git a/engine/server/sv_mvd.c b/engine/server/sv_mvd.c index 40736aaf7..1192baae6 100644 --- a/engine/server/sv_mvd.c +++ b/engine/server/sv_mvd.c @@ -1963,7 +1963,7 @@ void SV_MVD_Record_f (void) COM_StripExtension(name, name, sizeof(name)); COM_DefaultExtension(name, ".mvd", sizeof(name)); - COM_CreatePath(name); + FS_CreatePath (name, FS_GAMEONLY); // // open the demo file and start recording @@ -2243,8 +2243,8 @@ void SV_MVDEasyRecord_f (void) Q_strncpyz(name, va("%s/%s", sv_demoDir.string, name), sizeof(name)); // find a filename that doesn't exist yet Q_strncpyz(name2, name, sizeof(name2)); - FS_CreatePath (sv_demoDir.string, FS_GAMEONLY); // COM_StripExtension(name2, name2); + FS_CreatePath (name2, FS_GAMEONLY); strcat (name2, ".mvd"); if ((f = FS_OpenVFS(name2, "rb", FS_GAMEONLY)) == 0) f = FS_OpenVFS(va("%s.gz", name2), "rb", FS_GAMEONLY); diff --git a/engine/server/sv_sys_win.c b/engine/server/sv_sys_win.c index 95b7568b3..bce10154b 100644 --- a/engine/server/sv_sys_win.c +++ b/engine/server/sv_sys_win.c @@ -41,6 +41,93 @@ static HANDLE hconsoleout; + +#ifdef _DEBUG +#if _MSC_VER >= 1300 +#define CATCHCRASH +#endif +#endif + + +#ifdef CATCHCRASH +#include "dbghelp.h" +typedef BOOL (WINAPI *MINIDUMPWRITEDUMP) ( + HANDLE hProcess, + DWORD ProcessId, + HANDLE hFile, + MINIDUMP_TYPE DumpType, + PMINIDUMP_EXCEPTION_INFORMATION ExceptionParam, + PMINIDUMP_USER_STREAM_INFORMATION UserStreamParam, + PMINIDUMP_CALLBACK_INFORMATION CallbackParam + ); + +DWORD CrashExceptionHandler (DWORD exceptionCode, LPEXCEPTION_POINTERS exceptionInfo) +{ + char dumpPath[1024]; + HANDLE hProc = GetCurrentProcess(); + DWORD procid = GetCurrentProcessId(); + HANDLE dumpfile; + HMODULE hDbgHelp; + MINIDUMPWRITEDUMP fnMiniDumpWriteDump; + HMODULE hKernel; + BOOL (WINAPI *pIsDebuggerPresent)(void); + + hKernel = LoadLibrary ("kernel32"); + pIsDebuggerPresent = (void*)GetProcAddress(hKernel, "IsDebuggerPresent"); + +#ifdef GLQUAKE + GLVID_Crashed(); +#endif + + if (pIsDebuggerPresent ()) + { + /*if we have a current window, minimize it to bring us out of fullscreen*/ + return EXCEPTION_CONTINUE_SEARCH; + } + + hDbgHelp = LoadLibrary ("DBGHELP"); + if (hDbgHelp) + fnMiniDumpWriteDump = (MINIDUMPWRITEDUMP)GetProcAddress (hDbgHelp, "MiniDumpWriteDump"); + else + fnMiniDumpWriteDump = NULL; + + if (fnMiniDumpWriteDump) + { + if (MessageBox(NULL, "KABOOM! We crashed!\nBlame the monkey in the corner.\nI hope you saved your work.\nWould you like to take a dump now?", DISTRIBUTION " Sucks", MB_ICONSTOP|MB_YESNO) != IDYES) + return EXCEPTION_EXECUTE_HANDLER; + + /*take a dump*/ + GetTempPath (sizeof(dumpPath)-16, dumpPath); + Q_strncatz(dumpPath, DISTRIBUTION"CrashDump.dmp", sizeof(dumpPath)); + dumpfile = CreateFile (dumpPath, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL); + if (dumpfile) + { + MINIDUMP_EXCEPTION_INFORMATION crashinfo; + crashinfo.ClientPointers = TRUE; + crashinfo.ExceptionPointers = exceptionInfo; + crashinfo.ThreadId = GetCurrentThreadId (); + if (fnMiniDumpWriteDump(hProc, procid, dumpfile, MiniDumpWithIndirectlyReferencedMemory|MiniDumpWithDataSegs, &crashinfo, NULL, NULL)) + { + CloseHandle(dumpfile); + MessageBox(NULL, va("You can find the crashdump at\n%s\nPlease send this file to someone.\n\nWarning: sensitive information (like your current user name) might be present in the dump.\nYou will probably want to compress it.", dumpPath), DISTRIBUTION " Sucks", 0); + return EXCEPTION_EXECUTE_HANDLER; + } + } + } + else + MessageBox(NULL, "Kaboom! Sorry. No MiniDumpWriteDump function.", DISTRIBUTION " Sucks", 0); + return EXCEPTION_EXECUTE_HANDLER; +} +#endif + + + + + + + + + void Sys_CloseLibrary(dllhandle_t *lib) { FreeLibrary((HMODULE)lib); @@ -1191,32 +1278,43 @@ int main (int argc, char **argv) } #endif - COM_InitArgv (argc, argv); -#ifdef USESERVICE - if (COM_CheckParm("-register")) +#ifdef CATCHCRASH + __try +#endif { - CreateSampleService(1); - return true; + COM_InitArgv (argc, argv); + #ifdef USESERVICE + if (COM_CheckParm("-register")) + { + CreateSampleService(1); + return true; + } + if (COM_CheckParm("-unregister")) + { + CreateSampleService(0); + return true; + } + #endif + + #ifndef _DEBUG + if (COM_CheckParm("-noreset")) + { + signal (SIGFPE, Signal_Error_Handler); + signal (SIGILL, Signal_Error_Handler); + signal (SIGSEGV, Signal_Error_Handler); + } + #endif + StartQuakeServer(); + + ServerMainLoop(); } - if (COM_CheckParm("-unregister")) +#ifdef CATCHCRASH + __except (CrashExceptionHandler(GetExceptionCode(), GetExceptionInformation())) { - CreateSampleService(0); - return true; + return 1; } #endif -#ifndef _DEBUG - if (COM_CheckParm("-noreset")) - { - signal (SIGFPE, Signal_Error_Handler); - signal (SIGILL, Signal_Error_Handler); - signal (SIGSEGV, Signal_Error_Handler); - } -#endif - StartQuakeServer(); - - ServerMainLoop(); - return true; }