hexen2 client effects now go via the particle system, if they're supported at all. Added 'h2part' description to provide this.

Fixed svc_setangles and sv_bigcoords.
Model code is now responsible for transforming traces instead of it being generic. This fixes rotating things getting stuck in players in hexen2.
The renderer now generates a list of surfaces to draw. Backend now performs rotations/scaling per entity. This fixes sorting order, at least when not using realtime lights.
Hidden items in the hexen2 inventory that you do not have.
Added colourmapping for hexen2.
Should be easier to click on menu items for hexen2.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/branches/wip@3602 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2010-08-28 17:14:38 +00:00
parent 8cac55a8eb
commit 22bb395305
65 changed files with 3104 additions and 1569 deletions

View File

@ -566,7 +566,7 @@ static qintptr_t CG_SystemCallsEx(void *offset, quintptr_t mask, qintptr_t fn, c
if (!mod)
mod = cl.worldmodel;
if (mod)
pc = cl.worldmodel->funcs.NativeContents(mod, 0, 0, VM_POINTER(arg[0]), vec3_origin, vec3_origin);
pc = cl.worldmodel->funcs.NativeContents(mod, 0, 0, NULL, VM_POINTER(arg[0]), vec3_origin, vec3_origin);
else
pc = 1;//FTECONTENTS_SOLID;
VM_LONG(ret) = pc;//Contents_To_Q3(pc);
@ -584,10 +584,10 @@ static qintptr_t CG_SystemCallsEx(void *offset, quintptr_t mask, qintptr_t fn, c
if (!mod)
mod = cl.worldmodel;
if (mod)
{
vec3_t p_l;
vec3_t temp;
vec3_t forward, right, up;
vec3_t axis[3];
// subtract origin offset
VectorSubtract (p, origin, p_l);
@ -595,20 +595,16 @@ static qintptr_t CG_SystemCallsEx(void *offset, quintptr_t mask, qintptr_t fn, c
// rotate start and end into the models frame of reference
if (angles[0] || angles[1] || angles[2])
{
AngleVectors (angles, forward, right, up);
VectorCopy (p_l, temp);
p_l[0] = DotProduct (temp, forward);
p_l[1] = -DotProduct (temp, right);
p_l[2] = DotProduct (temp, up);
AngleVectors (angles, axis[0], axis[1], axis[2]);
VectorNegate(axis[1], axis[1]);
pc = mod->funcs.NativeContents(mod, 0, 0, axis, p_l, vec3_origin, vec3_origin);
}
if (mod)
pc = mod->funcs.NativeContents(mod, 0, 0, VM_POINTER(arg[0]), vec3_origin, vec3_origin);
else
pc = 1;//FTECONTENTS_SOLID;
pc = mod->funcs.NativeContents(mod, 0, 0, NULL, p_l, vec3_origin, vec3_origin);
}
VM_LONG(ret) = pc;//Contents_To_Q3(pc);
else
pc = Q3CONTENTS_SOLID;
VM_LONG(ret) = pc;
}
break;
@ -687,7 +683,7 @@ static qintptr_t CG_SystemCallsEx(void *offset, quintptr_t mask, qintptr_t fn, c
maxs = vec3_origin;
if (mod)
{
mod->funcs.NativeTrace(mod, 0, 0, start, end, mins, maxs, brushmask, &tr);
mod->funcs.NativeTrace(mod, 0, 0, NULL, start, end, mins, maxs, brushmask, &tr);
}
else
{

View File

@ -1794,7 +1794,7 @@ void CL_LinkPacketEntities (void)
//bots or powerup glows. items always glow, bots can be disabled
if (state->modelindex != cl_playerindex || r_powerupglow.ival)
if (state->effects & (EF_BLUE | EF_RED | EF_BRIGHTLIGHT | EF_DIMLIGHT) || state->light[3])
if (state->effects & (EF_BLUE | EF_RED | EF_BRIGHTLIGHT | EF_DIMLIGHT))
{
vec3_t colour;
float radius;
@ -1831,13 +1831,6 @@ void CL_LinkPacketEntities (void)
colour[1] += 0.05;
colour[2] += 0.05;
}
if (state->light[3])
{
radius = max(radius,state->light[3]);
colour[0] += state->light[0]/1024.0f;
colour[1] += state->light[1]/1024.0f;
colour[2] += state->light[2]/1024.0f;
}
if (radius)
{
@ -1845,6 +1838,21 @@ void CL_LinkPacketEntities (void)
CL_NewDlightRGB(state->number, state->origin, radius, 0.1, colour[0], colour[1], colour[2]);
}
}
if (state->lightpflags & PFLAGS_FULLDYNAMIC)
{
vec3_t colour;
if (!colour[0] && !colour[1] && !colour[2])
{
colour[0] = colour[1] = colour[2] = 1;
}
else
{
colour[0] = state->light[0]/1024.0f;
colour[1] = state->light[1]/1024.0f;
colour[2] = state->light[2]/1024.0f;
}
CL_NewDlightRGB(state->number, state->origin, state->light[3]?state->light[3]:350, 0.1, colour[0], colour[1], colour[2]);
}
// if set to invisible, skip
if (state->modelindex<1)
@ -1953,7 +1961,7 @@ void CL_LinkPacketEntities (void)
angles[2] = 0;
if (cl_item_bobbing.value)
ent->origin[2] += 5+sin(cl.time*3)*5; //don't let it into the ground
ent->origin[2] += 5+sin(cl.time*3+(state->origin[0]+state->origin[1]+state->origin[2]))*5.5; //don't let it into the ground
}
else
{
@ -2755,8 +2763,8 @@ void CL_LinkPlayers (void)
VectorCopy(cl.simorg[pnum], org);
if (model)
{
org[2] -= model->mins[2];
org[2] += 24;
org[2] += model->mins[2];
org[2] += 32;
}
radius += r_lightflicker.value?(rand()&31):0;
CL_NewDlightRGB(j+1, org, radius, 0.1, colour[0], colour[1], colour[2])->flags &= ~LFLAG_ALLOW_FLASH;
@ -2787,10 +2795,10 @@ void CL_LinkPlayers (void)
CL_UpdateNetFrameLerpState(false, state->frame, &cl.lerpplayers[j]);
CL_LerpNetFrameState(FS_REG, &ent->framestate, &cl.lerpplayers[j]);
if (state->modelindex == cl_playerindex)
// if (state->modelindex == cl_playerindex)
ent->scoreboard = info; // use custom skin
else
ent->scoreboard = NULL;
// else
// ent->scoreboard = NULL;
#ifdef PEXT_SCALE
ent->scale = state->scale;

View File

@ -229,6 +229,7 @@ int host_hunklevel;
qbyte *host_basepal;
qbyte *host_colormap;
qbyte *h2playertranslations;
cvar_t host_speeds = SCVAR("host_speeds","0"); // set for running times
#ifdef CRAZYDEBUGGING

View File

@ -1172,6 +1172,7 @@ void CL_RequestNextDownload (void)
if (cl.downloadlist)
{
downloadlist_t *dl;
unsigned int fl;
//download required downloads first
for (dl = cl.downloadlist; dl; dl = dl->next)
@ -1181,21 +1182,22 @@ void CL_RequestNextDownload (void)
}
if (!dl)
dl = cl.downloadlist;
if ((dl->flags & DLLF_OVERWRITE) || !COM_FCheckExists (dl->localname))
CL_SendDownloadStartRequest(dl->rname, dl->localname);
else
fl = dl->flags;
if (cls.state == ca_active || requiredownloads.value || (fl & DLLF_REQUIRED))
{
Con_Printf("Already have %s\n", dl->localname);
CL_DisenqueDownload(dl->rname);
if ((fl & DLLF_OVERWRITE) || !COM_FCheckExists (dl->localname))
CL_SendDownloadStartRequest(dl->rname, dl->localname);
else
{
Con_Printf("Already have %s\n", dl->localname);
CL_DisenqueDownload(dl->rname);
//recurse a bit.
CL_RequestNextDownload();
return;
//recurse a bit.
CL_RequestNextDownload();
return;
}
}
if (requiredownloads.value || (dl->flags & DLLF_REQUIRED))
return;
}
if (cl.sendprespawn)
@ -3648,6 +3650,13 @@ void CL_ProcessUserInfo (int slot, player_info_t *player)
*/
player->model = NULL;
/*if we're running hexen2, they have to be some class...*/
player->h2playerclass = atoi(Info_ValueForKey (player->userinfo, "cl_playerclass"));
if (player->h2playerclass > 5)
player->h2playerclass = 5;
if (player->h2playerclass < 1)
player->h2playerclass = 1;
player->colourised = TP_FindColours(player->name);
// If it's us

View File

@ -334,7 +334,7 @@ void CL_NudgePosition (void)
vec3_t base;
int x, y;
if (cl.worldmodel->funcs.PointContents (cl.worldmodel, pmove.origin) == FTECONTENTS_EMPTY)
if (cl.worldmodel->funcs.PointContents (cl.worldmodel, NULL, pmove.origin) == FTECONTENTS_EMPTY)
return;
VectorCopy (pmove.origin, base);
@ -344,7 +344,7 @@ void CL_NudgePosition (void)
{
pmove.origin[0] = base[0] + x * 1.0/8;
pmove.origin[1] = base[1] + y * 1.0/8;
if (cl.worldmodel->funcs.PointContents (cl.worldmodel, pmove.origin) == FTECONTENTS_EMPTY)
if (cl.worldmodel->funcs.PointContents (cl.worldmodel, NULL, pmove.origin) == FTECONTENTS_EMPTY)
return;
}
}

View File

@ -530,6 +530,9 @@ extern qboolean sb_showscores;
{
p = &scr_centerprint[pnum];
if (p->time_off <= 0 && !cl.intermission && !(p->flags & CPRINT_PERSIST))
continue; //'/P' prefix doesn't time out
p->time_off -= host_frametime;
if (key_dest != key_game) //don't let progs guis/centerprints interfere with the game menu
@ -538,9 +541,6 @@ extern qboolean sb_showscores;
if (sb_showscores) //this was annoying
continue;
if (p->time_off <= 0 && !cl.intermission && !(p->flags & CPRINT_PERSIST))
continue; //'/P' prefix doesn't time out
SCR_VRectForPlayer(&rect, pnum);
SCR_DrawCenterString(&rect, p);
}
@ -689,7 +689,10 @@ void SCR_ShowPic_Clear(void)
int pnum;
for (pnum = 0; pnum < MAX_SPLITS; pnum++)
{
scr_centerprint[pnum].flags = 0;
scr_centerprint[pnum].charcount = 0;
}
while((sp = showpics))
{
@ -994,8 +997,8 @@ void SCR_CalcRefdef (void)
if (cl.stats[0][STAT_VIEWZOOM])
r_refdef.fov_x *= cl.stats[0][STAT_VIEWZOOM]/255.0f;
if (r_refdef.fov_x < 10)
r_refdef.fov_x = 10;
if (r_refdef.fov_x < 1)
r_refdef.fov_x = 1;
else if (r_refdef.fov_x > 170)
r_refdef.fov_x = 170;
@ -1033,7 +1036,7 @@ void SCR_CrosshairPosition(int pnum, int *x, int *y)
memset(&tr, 0, sizeof(tr));
tr.fraction = 1;
cl.worldmodel->funcs.Trace(cl.worldmodel, 0, 0, start, end, vec3_origin, vec3_origin, &tr);
cl.worldmodel->funcs.Trace(cl.worldmodel, 0, 0, NULL, start, end, vec3_origin, vec3_origin, &tr);
start[2]-=16;
if (tr.fraction == 1)
{

View File

@ -189,11 +189,12 @@ typedef struct
beam_t cl_beams[MAX_BEAMS];
#define MAX_EXPLOSIONS 32
#define MAX_EXPLOSIONS 256
typedef struct
{
vec3_t origin;
vec3_t oldorigin;
vec3_t velocity;
int firstframe;
int numframes;
@ -631,6 +632,7 @@ void CL_ParseStream (int type)
b->model = NULL;
b->endtime = cl.time + duration;
b->alpha = 1;
b->skin = skin;
VectorCopy (start, b->start);
VectorCopy (end, b->end);
@ -671,8 +673,12 @@ void CL_ParseStream (int type)
b->particleeffect = P_FindParticleType("te_stream_sunstaff2");
R_AddStain(end, -10, -10, -10, 20);
break;
case TEH2_STREAM_COLORBEAM:
b->model = Mod_ForName("models/stclrbm.mdl", true);
b->particleeffect = P_FindParticleType("te_stream_colorbeam");
break;
default:
Con_Printf("Oh noes! type %i\n", type);
Con_Printf("CL_ParseStream: type %i\n", type);
break;
}
}
@ -1420,6 +1426,7 @@ void CL_ParseTEnt (void)
void MSG_ReadPos (vec3_t pos);
void MSG_ReadDir (vec3_t dir);
typedef struct {
char name[64];
int netstyle;
int particleeffecttype;
char stain[3];
@ -1447,6 +1454,7 @@ void CL_ParseCustomTEnt(void)
char *str;
clcustomtents_t *t;
int type = MSG_ReadByte();
qboolean failed;
if (type == 255) //255 is register
{
@ -1457,6 +1465,7 @@ void CL_ParseCustomTEnt(void)
t->netstyle = MSG_ReadByte();
str = MSG_ReadString();
Q_strncpyz(t->name, str, sizeof(t->name));
t->particleeffecttype = P_ParticleTypeForName(str);
if (t->netstyle & CTE_STAINS)
@ -1495,7 +1504,7 @@ void CL_ParseCustomTEnt(void)
{
MSG_ReadPos (pos);
MSG_ReadPos (pos2);
P_ParticleTrail(pos, pos2, t->particleeffecttype, NULL);
failed = P_ParticleTrail(pos, pos2, t->particleeffecttype, NULL);
}
else
{
@ -1507,14 +1516,24 @@ void CL_ParseCustomTEnt(void)
MSG_ReadPos (pos);
VectorCopy(pos, pos2);
if (t->netstyle & CTE_CUSTOMDIRECTION)
if (t->netstyle & CTE_CUSTOMVELOCITY)
{
dir[0] = MSG_ReadCoord();
dir[1] = MSG_ReadCoord();
dir[2] = MSG_ReadCoord();
failed = P_RunParticleEffectType(pos, dir, count, t->particleeffecttype);
}
else if (t->netstyle & CTE_CUSTOMDIRECTION)
{
MSG_ReadDir (dir);
P_RunParticleEffectType(pos, dir, 1, t->particleeffecttype);
failed = P_RunParticleEffectType(pos, dir, count, t->particleeffecttype);
}
else P_RunParticleEffectType(pos, NULL, 1, t->particleeffecttype);
else failed = P_RunParticleEffectType(pos, NULL, count, t->particleeffecttype);
}
if (failed)
Con_Printf("Failed to create effect %s\n", t->name);
if (t->netstyle & CTE_STAINS)
{ //added at pos2 - end of trail
R_AddStain(pos2, t->stain[0], t->stain[1], t->stain[2], 40);
@ -1685,7 +1704,7 @@ void CL_ParseParticleEffect4 (void)
P_RunParticleEffect4 (org, radius, color, effect, msgcount);
}
void CL_SpawnSpriteEffect(vec3_t org, model_t *model, int startframe, int framecount, int framerate)
void CL_SpawnSpriteEffect(vec3_t org, vec3_t dir, model_t *model, int startframe, int framecount, int framerate, float alpha)
{
explosion_t *ex;
@ -1696,10 +1715,16 @@ void CL_SpawnSpriteEffect(vec3_t org, model_t *model, int startframe, int framec
ex->firstframe = startframe;
ex->numframes = framecount;
ex->framerate = framerate;
ex->alpha = alpha;
ex->angles[0] = 0;
ex->angles[1] = 0;
ex->angles[2] = 0;
if (dir)
VectorCopy(dir, ex->velocity);
else
VectorClear(ex->velocity);
}
// [vector] org [byte] modelindex [byte] startframe [byte] framecount [byte] framerate
@ -1730,7 +1755,7 @@ void CL_ParseEffect (qboolean effect2)
framerate = MSG_ReadByte();
CL_SpawnSpriteEffect(org, cl.model_precache[modelindex], startframe, framecount, framerate);
CL_SpawnSpriteEffect(org, vec3_origin, cl.model_precache[modelindex], startframe, framecount, framerate, 1);
}
#ifdef Q2CLIENT
@ -2854,7 +2879,7 @@ void CL_UpdateExplosions (void)
ent = CL_NewTempEntity ();
if (!ent)
return;
VectorCopy (ex->origin, ent->origin);
VectorMA (ex->origin, f, ex->velocity, ent->origin);
VectorCopy (ex->oldorigin, ent->oldorigin);
VectorCopy (ex->angles, ent->angles);
ent->skinnum = ex->skinnum;
@ -2866,9 +2891,9 @@ void CL_UpdateExplosions (void)
ent->framestate.g[FS_REG].frame[0] = of+firstframe;
ent->framestate.g[FS_REG].lerpfrac = (f - (int)f);
if (ent->model->type == mod_sprite)
ent->shaderRGBAf[3] = 1;
ent->shaderRGBAf[3] = ex->alpha; /*sprites don't fade over time, the animation should do it*/
else
ent->shaderRGBAf[3] = 1.0 - f/(numframes);
ent->shaderRGBAf[3] = (1.0 - f/(numframes))*ex->alpha;
ent->flags = ex->flags;
}

View File

@ -172,6 +172,7 @@ typedef struct player_info_s
struct model_s *model;
unsigned short vweapindex;
unsigned char h2playerclass;
int prevcount;
@ -968,6 +969,7 @@ void CL_ParseParticleEffect4 (void);
void CLDP_ParseTrailParticles(void);
void CLDP_ParsePointParticles(qboolean compact);
void CL_SpawnSpriteEffect(vec3_t org, vec3_t dir, struct model_s *model, int startframe, int framecount, int framerate, float alpha); /*called from the particlesystem*/
//
// cl_ents.c

View File

@ -1144,8 +1144,8 @@ menubutton_t *MC_AddConsoleCommandHexen2BigFont(menu_t *menu, int x, int y, cons
n->common.iszone = true;
n->common.posx = x;
n->common.posy = y;
n->common.height = 8;
n->common.width = strlen(text)*8;
n->common.height = 20;
n->common.width = strlen(text)*20;
n->text = (char *)(n+1);
strcpy((char *)(n+1), text);
n->command = n->text + strlen(n->text)+1;

View File

@ -316,7 +316,7 @@ void MSetup_TransDraw (int x, int y, menucustom_t *option, menu_t *menu)
if (p)
Draw_ScalePic (x-12, y-8, 72, 72, p);
M_BuildTranslationTable(info->topcolour*16, info->lowercolour*16);
M_BuildTranslationTable(info->topcolour, info->lowercolour);
Draw_TransPicTranslate (x, y, info->tiwidth, info->tiheight, info->translationimage, translationTable);
}

View File

@ -1091,7 +1091,7 @@ void M_Menu_Shadow_Lighting_f (void)
#ifndef MINIMAL
extern cvar_t r_vertexlight;
#endif
extern cvar_t r_noaliasshadows, r_shadows, r_shadow_realtime_world, r_loadlits, gl_maxshadowlights, r_lightmap_saturation, r_dynamic, r_vertexdlights, r_lightstylesmooth, r_lightstylespeed, r_nolightdir, r_shadow_realtime_world_lightmaps, r_shadow_glsl_offsetmapping, r_shadow_glsl_offsetmapping_bias, r_shadow_glsl_offsetmapping_scale, r_shadow_bumpscale_basetexture, r_shadow_bumpscale_bumpmap, r_fb_bmodels, r_fb_models, gl_overbright, r_rocketlight, r_powerupglow, v_powerupshell, r_lightflicker, r_explosionlight;
extern cvar_t r_noaliasshadows, r_shadows, r_shadow_realtime_world, r_loadlits, gl_maxshadowlights, r_lightmap_saturation, r_dynamic, r_vertexdlights, r_lightstylesmooth, r_lightstylespeed, r_nolightdir, r_shadow_realtime_world_lightmaps, r_glsl_offsetmapping, r_glsl_offsetmapping_scale, r_shadow_bumpscale_basetexture, r_shadow_bumpscale_bumpmap, r_fb_bmodels, r_fb_models, gl_overbright, r_rocketlight, r_powerupglow, v_powerupshell, r_lightflicker, r_explosionlight;
static const char *loadlitoptions[] =
{
@ -1139,9 +1139,8 @@ void M_Menu_Shadow_Lighting_f (void)
MC_AddCheckBox(menu, 16, y, " Realtime World Lightmaps", &r_shadow_realtime_world_lightmaps,0); y+=8;
MC_AddCheckBox(menu, 16, y, " Realtime Dynamic Lights", &r_shadow_realtime_dlight,0); y+=8;
MC_AddCheckBox(menu, 16, y, " Realtime Dynamic Light Shadows", &r_shadow_realtime_dlight_shadows,0); y+=8;
MC_AddCheckBox(menu, 16, y, " GLSL Shadow Offsetmapping", &r_shadow_glsl_offsetmapping,0); y+=8;
MC_AddSlider(menu, 16, y, " GLSL Shadow Offsetmapping Bias", &r_shadow_glsl_offsetmapping_bias,0,1,0.01); y+=8;
MC_AddSlider(menu, 16, y, " GLSL Shadow Offsetmapping Scale", &r_shadow_glsl_offsetmapping_scale,0,-1,0.01); y+=8;
MC_AddCheckBox(menu, 16, y, " GLSL Offsetmapping", &r_glsl_offsetmapping,0); y+=8;
MC_AddSlider(menu, 16, y, " GLSL Offsetmapping Scale", &r_glsl_offsetmapping_scale,0,-1,0.01); y+=8;
MC_AddSlider(menu, 16, y, " Shadow Bumpscale Basetexture", &r_shadow_bumpscale_basetexture,0,10,1); y+=8;
MC_AddSlider(menu, 16, y, " Shadow Bumpscale Bumpmap", &r_shadow_bumpscale_bumpmap,0,50,1); y+=8;
info->loadlitcombo = MC_AddCombo(menu,16, y, " LIT Loading", loadlitoptions, currentloadlit); y+=8;

View File

@ -69,23 +69,48 @@ void M_BuildTranslationTable(int top, int bottom)
int j;
qbyte *dest, *source;
for (j = 0; j < 256; j++)
identityTable[j] = j;
dest = translationTable;
source = identityTable;
memcpy (dest, source, 256);
if (top < 128) // the artists made some backwards ranges. sigh.
memcpy (dest + TOP_RANGE, source + top, 16);
int pc = Cvar_Get("cl_playerclass", "1", 0, "foo")->value;
if (h2playertranslations && pc)
{
int i;
unsigned int color_offsets[5] = {2*14*256,0,1*14*256,2*14*256,2*14*256};
unsigned char *colorA, *colorB, *sourceA, *sourceB;
colorA = h2playertranslations + 256 + color_offsets[pc-1];
colorB = colorA + 256;
sourceA = colorB + (top * 256);
sourceB = colorB + (bottom * 256);
for(i=0;i<256;i++)
{
if (bottom > 0 && (colorB[i] != 255))
translationTable[i] = sourceB[i];
else if (top > 0 && (colorA[i] != 255))
translationTable[i] = sourceA[i];
else
translationTable[i] = i;
}
}
else
for (j=0 ; j<16 ; j++)
dest[TOP_RANGE+j] = source[top+15-j];
{
top *= 16;
bottom *= 16;
for (j = 0; j < 256; j++)
identityTable[j] = j;
dest = translationTable;
source = identityTable;
memcpy (dest, source, 256);
if (bottom < 128)
memcpy (dest + BOTTOM_RANGE, source + bottom, 16);
else
for (j=0 ; j<16 ; j++)
dest[BOTTOM_RANGE+j] = source[bottom+15-j];
if (top < 128) // the artists made some backwards ranges. sigh.
memcpy (dest + TOP_RANGE, source + top, 16);
else
for (j=0 ; j<16 ; j++)
dest[TOP_RANGE+j] = source[top+15-j];
if (bottom < 128)
memcpy (dest + BOTTOM_RANGE, source + bottom, 16);
else
for (j=0 ; j<16 ; j++)
dest[BOTTOM_RANGE+j] = source[bottom+15-j];
}
}
/*

View File

@ -45,6 +45,17 @@ extern void *d3dballtexture;
#include "r_partset.h"
struct
{
char *name;
char **data;
} partset_list[] =
{
{"none", NULL},
R_PARTSET_BUILTINS
{NULL}
};
extern qbyte *host_basepal;
static int pt_pointfile = P_INVALID;
@ -148,6 +159,14 @@ typedef struct {
typedef struct part_type_s {
char name[MAX_QPATH];
char texname[MAX_QPATH];
char modelname[MAX_QPATH];
model_t *model;
float modelframestart;
float modelframeend;
float modelframerate;
float modelalpha;
vec3_t rgb; //initial colour
float alpha;
vec3_t rgbchange; //colour delta (per second)
@ -218,7 +237,14 @@ typedef struct part_type_s {
float gravity;
vec3_t friction;
float clipbounce;
int stains;
int stainonimpact;
vec3_t dl_rgb;
float dl_radius;
float dl_time;
vec3_t dl_decay;
vec3_t stain_rgb;
float stain_radius;
enum {RAMP_NONE, RAMP_DELTA, RAMP_ABSOLUTE} rampmode;
int rampindexes;
@ -472,6 +498,8 @@ static void P_LoadTexture(part_type_t *ptype, qboolean warn)
if (qrenderer == QR_NONE)
return;
ptype->model = NULL;
if (*ptype->texname)
{
/*try and load the shader, fail if we would need to generate one*/
@ -867,6 +895,14 @@ static void P_ParticleEffect_f(void)
ptype = &part_type[pnum];
ptype->inwater = assoc;
}
else if (!strcmp(var, "model"))
{
Q_strncpyz(ptype->modelname, Cmd_Argv(1), sizeof(ptype->modelname));
ptype->modelframestart = atof(Cmd_Argv(2));
ptype->modelframeend = atof(Cmd_Argv(3));
ptype->modelframerate = atof(Cmd_Argv(4));
ptype->modelalpha = atof(Cmd_Argv(5));
}
else if (!strcmp(var, "colorindex"))
{
if (Cmd_Argc()>2)
@ -959,7 +995,7 @@ static void P_ParticleEffect_f(void)
ptype->rgbrandsync[2] = atof(value);
else if (!strcmp(var, "stains"))
ptype->stains = atoi(value);
ptype->stainonimpact = atoi(value);
else if (!strcmp(var, "blend"))
{
if (!strcmp(value, "add"))
@ -1864,77 +1900,73 @@ static void PScript_ClearParticles (void)
static void P_ExportBuiltinSet_f(void)
{
char *efname = Cmd_Argv(1);
char *file;
char *file = NULL;
int i;
if (!*efname)
{
Con_Printf("Please name the built in effect (faithful, spikeset, tsshaft, minimal or highfps)\n");
return;
}
else if (!stricmp(efname, "faithful"))
file = particle_set_faithful;
else if (!stricmp(efname, "spikeset"))
file = particle_set_spikeset;
else if (!stricmp(efname, "highfps"))
file = particle_set_highfps;
else if (!stricmp(efname, "minimal"))
file = particle_set_minimal;
else if (!stricmp(efname, "tsshaft"))
file = particle_set_tsshaft;
else
for (i = 0; partset_list[i].name; i++)
{
if (!stricmp(efname, "none"))
if (!stricmp(efname, partset_list[i].name))
{
Con_Printf("nothing to export\n");
file = *partset_list[i].data;
if (file)
{
COM_WriteFile(va("particles/%s.cfg", efname), file, strlen(file));
Con_Printf("Written particles/%s.cfg\n", efname);
}
else
Con_Printf("nothing to export\n");
return;
}
Con_Printf("'%s' is not a built in particle set\n", efname);
return;
}
COM_WriteFile(va("particles/%s.cfg", efname), file, strlen(file));
Con_Printf("Written particles/%s.cfg\n", efname);
Con_Printf("'%s' is not a built in particle set\n", efname);
}
static void P_LoadParticleSet(char *name, qboolean first)
{
char *file;
int i;
int restrictlevel = Cmd_FromGamecode() ? RESTRICT_SERVER : RESTRICT_LOCAL;
//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"))
Cbuf_AddText(particle_set_spikeset, RESTRICT_LOCAL);
else if (!stricmp(name, "highfps"))
Cbuf_AddText(particle_set_highfps, RESTRICT_LOCAL);
else if (!stricmp(name, "minimal"))
Cbuf_AddText(particle_set_minimal, RESTRICT_LOCAL);
else if (!stricmp(name, "tsshaft"))
Cbuf_AddText(particle_set_tsshaft, RESTRICT_LOCAL);
else
/*set up a default*/
if (first && !*name)
name = "faithful";
for (i = 0; partset_list[i].name; i++)
{
char *file;
FS_LoadFile(va("particles/%s.cfg", name), (void**)&file);
if (!file)
FS_LoadFile(va("%s.cfg", name), (void**)&file);
if (file)
if (!stricmp(name, partset_list[i].name))
{
Cbuf_AddText(file, restrictlevel);
Cbuf_AddText("\n", restrictlevel);
FS_FreeFile(file);
if (partset_list[i].data)
{
Cbuf_AddText(*partset_list[i].data, RESTRICT_LOCAL);
}
return;
}
else if (first)
{
Con_Printf(CON_WARNING "Couldn't find particle description %s, using spikeset\n", name);
Cbuf_AddText(particle_set_spikeset, RESTRICT_LOCAL);
}
else
Con_Printf(CON_WARNING "Couldn't find particle description %s\n", name);
}
FS_LoadFile(va("particles/%s.cfg", name), (void**)&file);
if (!file)
FS_LoadFile(va("%s.cfg", name), (void**)&file);
if (file)
{
Cbuf_AddText(file, restrictlevel);
Cbuf_AddText("\n", restrictlevel);
FS_FreeFile(file);
}
else if (first)
{
Con_Printf(CON_WARNING "Couldn't find particle description %s, using spikeset\n", name);
Cbuf_AddText(particle_set_spikeset, RESTRICT_LOCAL);
}
else
Con_Printf(CON_WARNING "Couldn't find particle description %s\n", name);
}
static void R_Particles_KillAllEffects(void)
@ -2120,7 +2152,7 @@ static void P_AddRainParticles(void)
else
VectorMA(org, 0.5, st->face->plane->normal, org);
if (!(cl.worldmodel->funcs.PointContents(cl.worldmodel, org) & FTECONTENTS_SOLID))
if (!(cl.worldmodel->funcs.PointContents(cl.worldmodel, NULL, org) & FTECONTENTS_SOLID))
{
if (st->face->flags & SURF_PLANEBACK)
{
@ -2293,6 +2325,27 @@ static vec2_t avelocities[NUMVERTEXNORMALS];
// float partstep = 0.01;
// float timescale = 0.01;
static void PScript_EffectSpawned(part_type_t *ptype, vec3_t org, vec3_t dir)
{
if (*ptype->modelname)
{
if (!ptype->model)
ptype->model = Mod_ForName(ptype->modelname, false);
if (ptype->model && !ptype->model->needload)
CL_SpawnSpriteEffect(org, dir, ptype->model, ptype->modelframestart, (ptype->modelframeend?ptype->modelframeend:(ptype->model->numframes - ptype->modelframestart)), ptype->modelframerate?ptype->modelframerate:10, ptype->modelalpha?ptype->modelalpha:1);
}
if (ptype->dl_radius)
{
dlight_t *dl = CL_NewDlightRGB(0, org, ptype->dl_radius, ptype->dl_time, ptype->dl_rgb[0], ptype->dl_rgb[1], ptype->dl_rgb[2]);
dl->channelfade[0] = ptype->dl_decay[0];
dl->channelfade[1] = ptype->dl_decay[1];
dl->channelfade[2] = ptype->dl_decay[2];
}
if (ptype->stain_radius)
R_AddStain(org, ptype->stain_rgb[0], ptype->stain_rgb[1], ptype->stain_rgb[2], ptype->stain_radius);
}
int Q1BSP_ClipDecal(vec3_t center, vec3_t normal, vec3_t tangent, vec3_t tangent2, float size, float **out);
static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count, int typenum, trailstate_t **tsk)
{
@ -2314,7 +2367,7 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
if (r_part_contentswitch.ival && ptype->inwater >= 0 && cl.worldmodel)
{
int cont;
cont = cl.worldmodel->funcs.PointContents(cl.worldmodel, org);
cont = cl.worldmodel->funcs.PointContents(cl.worldmodel, NULL, org);
if (cont & FTECONTENTS_WATER)
ptype = &part_type[ptype->inwater];
@ -2353,6 +2406,8 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
while(ptype)
{
PScript_EffectSpawned(ptype, org, dir);
if (ptype->looks.type == PT_DECAL)
{
clippeddecal_t *d;
@ -2393,7 +2448,7 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
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 (cl.worldmodel->funcs.Trace (cl.worldmodel, 0, 0, NULL, tangent, t2, vec3_origin, vec3_origin, &tr))
{
if (tr.fraction < dist)
{
@ -3159,6 +3214,8 @@ static void P_ParticleTrailDraw (vec3_t startpos, vec3_t end, part_type_t *ptype
else
ts = NULL;
PScript_EffectSpawned(ptype, start, vec3_origin);
if (ptype->assoc>=0)
{
if (ts)
@ -3592,7 +3649,7 @@ static int PScript_ParticleTrail (vec3_t startpos, vec3_t end, int type, trailst
if (r_part_contentswitch.ival && ptype->inwater >= 0)
{
int cont;
cont = cl.worldmodel->funcs.PointContents(cl.worldmodel, startpos);
cont = cl.worldmodel->funcs.PointContents(cl.worldmodel, NULL, startpos);
if (cont & FTECONTENTS_WATER)
ptype = &part_type[ptype->inwater];
@ -4116,14 +4173,14 @@ static void PScript_DrawParticleTypes (void (*texturedparticles)(int count, part
P_RunParticleEffectType(p->org, p->vel, 1, type->emit);
// make sure stain effect runs
if (type->stains && r_bloodstains.ival)
if (type->stainonimpact && r_bloodstains.ival)
{
if (traces-->0&&tr(oldorg, p->org, stop, normal))
{
R_AddStain(stop, (p->rgba[1]*-10+p->rgba[2]*-10),
(p->rgba[0]*-10+p->rgba[2]*-10),
(p->rgba[0]*-10+p->rgba[1]*-10),
30*p->rgba[3]*type->stains);
30*p->rgba[3]*type->stainonimpact);
}
}
@ -4331,7 +4388,7 @@ static void PScript_DrawParticleTypes (void (*texturedparticles)(int count, part
{
if (traces-->0&&tr(oldorg, p->org, stop, normal))
{
if (type->stains && r_bloodstains.ival)
if (type->stainonimpact && r_bloodstains.ival)
R_AddStain(stop, p->rgba[1]*-10+p->rgba[2]*-10,
p->rgba[0]*-10+p->rgba[2]*-10,
p->rgba[0]*-10+p->rgba[1]*-10,
@ -4360,14 +4417,14 @@ static void PScript_DrawParticleTypes (void (*texturedparticles)(int count, part
continue;
}
}
else if (type->stains && r_bloodstains.ival)
else if (type->stainonimpact && r_bloodstains.ival)
{
if (traces-->0&&tr(oldorg, p->org, stop, normal))
{
R_AddStain(stop, (p->rgba[1]*-10+p->rgba[2]*-10),
(p->rgba[0]*-10+p->rgba[2]*-10),
(p->rgba[0]*-10+p->rgba[1]*-10),
30*p->rgba[3]*type->stains);
30*p->rgba[3]*type->stainonimpact);
p->die = -1;
continue;
}

View File

@ -701,6 +701,9 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out)
else
rflags = 0;
if ((int)in->v->effects & EF_NODEPTHTEST)
out->flags |= RF_NODEPTHTEST;
cs_getframestate(in, rflags, &out->framestate);
VectorCopy(in->v->origin, out->origin);
@ -804,11 +807,23 @@ static void PF_R_DynamicLight_Set(progfuncs_t *prinst, struct globalvars_s *pr_g
switch (field)
{
case 0:
VectorCopy(G_VECTOR(OFS_PARM1), l->origin);
VectorCopy(G_VECTOR(OFS_PARM2), l->origin);
l->rebuildcache = true;
break;
case 1:
VectorCopy(G_VECTOR(OFS_PARM2), l->color);
break;
case 2:
l->radius = G_FLOAT(OFS_PARM2);
l->rebuildcache = true;
break;
case 3:
l->flags = G_FLOAT(OFS_PARM2);
l->rebuildcache = true;
break;
case 4:
l->style = G_FLOAT(OFS_PARM2);
break;
default:
break;
}
@ -818,10 +833,10 @@ static void PF_R_DynamicLight_Get(progfuncs_t *prinst, struct globalvars_s *pr_g
dlight_t *l;
unsigned int lno = G_FLOAT(OFS_PARM0);
int field = G_FLOAT(OFS_PARM1);
if (lno >= cl_maxdlights)
if (lno >= rtlights_max)
{
if (field == -1)
G_FLOAT(OFS_RETURN) = cl_maxdlights;
G_FLOAT(OFS_RETURN) = rtlights_max;
else
G_INT(OFS_RETURN) = 0;
return;
@ -835,6 +850,15 @@ static void PF_R_DynamicLight_Get(progfuncs_t *prinst, struct globalvars_s *pr_g
case 1:
VectorCopy(l->color, G_VECTOR(OFS_RETURN));
break;
case 2:
G_FLOAT(OFS_RETURN) = l->radius;
break;
case 3:
G_FLOAT(OFS_RETURN) = l->flags;
break;
case 4:
G_FLOAT(OFS_RETURN) = l->style;
break;
default:
G_INT(OFS_RETURN) = 0;
break;
@ -1625,7 +1649,7 @@ static int CS_PointContents(vec3_t org)
{
if (!cl.worldmodel)
return FTECONTENTS_EMPTY;
return cl.worldmodel->funcs.PointContents(cl.worldmodel, org);
return cl.worldmodel->funcs.PointContents(cl.worldmodel, NULL, org);
}
static void PF_cs_pointcontents(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
@ -2494,7 +2518,6 @@ static void PF_cs_particle4(progfuncs_t *prinst, struct globalvars_s *pr_globals
}
void CL_SpawnSpriteEffect(vec3_t org, model_t *model, int startframe, int framecount, int framerate);
void PF_cl_effect(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
float *org = G_VECTOR(OFS_PARM0);
@ -2506,7 +2529,7 @@ void PF_cl_effect(progfuncs_t *prinst, struct globalvars_s *pr_globals)
mdl = Mod_ForName(name, false);
if (mdl)
CL_SpawnSpriteEffect(org, mdl, startframe, endframe, framerate);
CL_SpawnSpriteEffect(org, NULL, mdl, startframe, endframe, framerate, 1);
else
Con_Printf("PF_cl_effect: Couldn't load model %s\n", name);
}

View File

@ -557,6 +557,8 @@ void PF_CL_drawrawstring (progfuncs_t *prinst, struct globalvars_s *pr_globals)
}
Font_BeginScaledString(font_conchar, pos[0], pos[1], &x, &y);
x = pos[0];
y = pos[1];
Font_ForceColour(rgb[0], rgb[1], rgb[2], alpha);
while(*text)
{

View File

@ -242,6 +242,7 @@ extern qboolean host_initialized; // true if into command execution
extern double host_frametime;
extern qbyte *host_basepal;
extern qbyte *host_colormap;
extern qbyte *h2playertranslations;
extern int host_framecount; // incremented every frame, never reset
extern double realtime; // not bounded in any way, changed at
// start of every frame, never reset

View File

@ -187,6 +187,7 @@ qboolean TraceLineN (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal)
vec3_t delta, ts, te;
physent_t *pe;
qboolean clipped=false;
vec3_t axis[3];
memset (&trace, 0, sizeof(trace));
@ -204,7 +205,14 @@ qboolean TraceLineN (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal)
{
VectorSubtract(start, pe->origin, ts);
VectorSubtract(end, pe->origin, te);
pe->model->funcs.Trace(pe->model, 0, 0, ts, te, vec3_origin, vec3_origin, &trace);
if (pe->angles[0] || pe->angles[1] || pe->angles[2])
{
AngleVectors(pe->angles, axis[0], axis[1], axis[2]);
VectorNegate(axis[1], axis[1]);
pe->model->funcs.Trace(pe->model, 0, 0, axis, ts, te, vec3_origin, vec3_origin, &trace);
}
else
pe->model->funcs.Trace(pe->model, 0, 0, NULL, ts, te, vec3_origin, vec3_origin, &trace);
if (trace.fraction<1)
{
VectorSubtract(trace.endpos, ts, delta);

File diff suppressed because it is too large Load Diff

View File

@ -1,6 +1,7 @@
extern char *particle_set_spikeset;
extern char *particle_set_highfps;
extern char *particle_set_faithful;
extern char *particle_set_highfps;
extern char *particle_set_minimal;
extern char *particle_set_h2part;
extern char *particle_set_tsshaft;
#define R_PARTSET_BUILTINS {"spikeset", &particle_set_spikeset},{"faithful", &particle_set_faithful},{"highfps", &particle_set_highfps},{"minimal", &particle_set_minimal},{"h2part", &particle_set_h2part},{"tsshaft", &particle_set_tsshaft},

View File

@ -467,6 +467,7 @@ static void Surf_AddDynamicLightsColours (msurface_t *surf)
// float temp;
float r, g, b;
unsigned *bl;
vec3_t lightofs;
smax = (surf->extents[0]>>4)+1;
tmax = (surf->extents[1]>>4)+1;
@ -478,7 +479,8 @@ static void Surf_AddDynamicLightsColours (msurface_t *surf)
continue; // not lit by this light
rad = cl_dlights[lnum].radius;
dist = DotProduct (cl_dlights[lnum].origin, surf->plane->normal) -
VectorSubtract(cl_dlights[lnum].origin, currententity->origin, lightofs);
dist = DotProduct (lightofs, surf->plane->normal) -
surf->plane->dist;
rad -= fabs(dist);
minlight = cl_dlights[lnum].minlight;
@ -488,7 +490,7 @@ static void Surf_AddDynamicLightsColours (msurface_t *surf)
for (i=0 ; i<3 ; i++)
{
impact[i] = cl_dlights[lnum].origin[i] -
impact[i] = lightofs[i] -
surf->plane->normal[i]*dist;
}
@ -1250,8 +1252,8 @@ void Surf_RenderDynamicLightmaps (msurface_t *fa, int shift)
// check for lightmap modification
if (!fa->samples)
{
if (d_lightstylevalue[0] != fa->cached_light[0]
|| cl_lightstyle[0].colour != fa->cached_colour[0])
if (fa->cached_light[0] != 0
|| fa->cached_colour[0] != 0)
goto dynamic;
}
else
@ -1793,17 +1795,20 @@ static void Surf_CleanChains(void)
{
model_t *model = cl.worldmodel;
batch_t *batch;
int i;
if (r_refdef.recurse)
{
for (batch = model->batches; batch; batch = batch->next)
for (i = 0; i < SHADER_SORT_COUNT; i++)
for (batch = model->batches[i]; batch; batch = batch->next)
{
batch->meshes = batch->firstmesh;
}
}
else
{
for (batch = model->batches; batch; batch = batch->next)
for (i = 0; i < SHADER_SORT_COUNT; i++)
for (batch = model->batches[i]; batch; batch = batch->next)
{
batch->meshes = batch->firstmesh;
}
@ -2336,12 +2341,16 @@ void Surf_DeInit(void)
void Surf_Clear(model_t *mod)
{
batch_t *b;
while ((b = mod->batches))
int i;
for (i = 0; i < SHADER_SORT_COUNT; i++)
{
mod->batches = b->next;
while ((b = mod->batches[i]))
{
mod->batches[i] = b->next;
BZ_Free(b->mesh);
Z_Free(b);
BZ_Free(b->mesh);
Z_Free(b);
}
}
}
@ -2362,6 +2371,7 @@ void Surf_BuildLightmaps (void)
msurface_t *surf;
batch_t *batch, *bstop;
vec3_t sn;
int sortid;
r_framecount = 1; // no dlightcache
@ -2412,7 +2422,8 @@ void Surf_BuildLightmaps (void)
{
m->textures[t]->wtexno = t;
bstop = m->batches;
sortid = m->textures[t]->shader->sort;
bstop = m->batches[sortid];
batch = NULL;
for (i=0 ; i<m->numsurfaces ; i++)
{//extra texture loop so we get slightly less texture switches
@ -2423,7 +2434,7 @@ void Surf_BuildLightmaps (void)
Surf_CreateSurfaceLightmap (surf, shift);
/*the excessive logic is to give portals separate batches for separate planes*/
if (m->textures[t]->shader->sort == SHADER_SORT_PORTAL)
if (sortid == SHADER_SORT_PORTAL)
{
if (surf->flags & SURF_PLANEBACK)
VectorNegate(surf->plane->normal, sn);
@ -2432,11 +2443,11 @@ void Surf_BuildLightmaps (void)
}
else
VectorClear(sn);
if (!batch || batch->lightmap != surf->lightmaptexturenum || (m->textures[t]->shader->sort == SHADER_SORT_PORTAL && !VectorCompare(sn, batch->normal)))
if (!batch || batch->lightmap != surf->lightmaptexturenum || (sortid == SHADER_SORT_PORTAL && !VectorCompare(sn, batch->normal)))
{
if (m->textures[t]->shader->sort == SHADER_SORT_PORTAL)
if (sortid == SHADER_SORT_PORTAL)
{
for (batch = m->batches; batch != bstop; batch = batch->next)
for (batch = m->batches[sortid]; batch != bstop; batch = batch->next)
{
if (batch->lightmap == surf->lightmaptexturenum && VectorCompare(sn, batch->normal))
break;
@ -2444,7 +2455,7 @@ void Surf_BuildLightmaps (void)
}
else
{
for (batch = m->batches; batch != bstop; batch = batch->next)
for (batch = m->batches[sortid]; batch != bstop; batch = batch->next)
{
if (batch->lightmap == surf->lightmaptexturenum)
break;
@ -2455,9 +2466,10 @@ void Surf_BuildLightmaps (void)
batch = Z_Malloc(sizeof(*batch));
batch->lightmap = surf->lightmaptexturenum;
batch->texture = m->textures[t];
batch->next = m->batches;
batch->next = m->batches[sortid];
batch->ent = &r_worldentity;
VectorCopy(sn, batch->normal);
m->batches = batch;
m->batches[sortid] = batch;
}
}
surf->sbatch = batch;
@ -2469,7 +2481,8 @@ void Surf_BuildLightmaps (void)
}
}
}
for (batch = m->batches; batch != NULL; batch = batch->next)
for (sortid = 0; sortid < SHADER_SORT_COUNT; sortid++)
for (batch = m->batches[sortid]; batch != NULL; batch = batch->next)
{
batch->mesh = BZ_Malloc(sizeof(*batch->mesh)*batch->maxmeshes*2);
}

View File

@ -163,7 +163,8 @@ extern entity_t r_worldentity;
//gl_alias.c
void R_DrawGAliasModel (entity_t *e, unsigned int rmode);
void R_GAlias_DrawBatch(struct batch_s *batch);
void R_GAlias_GenerateBatches(entity_t *e, struct batch_s **batches);
//r_surf.c
struct model_s;
@ -389,7 +390,7 @@ qbyte *R_MarkLeaves_Q3 (void);
void R_SetFrustum (float projmat[16], float viewmat[16]);
void R_SetRenderer(rendererinfo_t *ri);
void R_AnimateLight (void);
struct texture_s *R_TextureAnimation (struct texture_s *base);
struct texture_s *R_TextureAnimation (int frame, struct texture_s *base);
void RQ_Init(void);
void CLQ2_EntityEvent(entity_state_t *es);

View File

@ -317,9 +317,8 @@ cvar_t r_noaliasshadows = SCVARF ("r_noaliasshadows", "0",
cvar_t r_shadow_bumpscale_basetexture = SCVAR ("r_shadow_bumpscale_basetexture", "4");
cvar_t r_shadow_bumpscale_bumpmap = SCVAR ("r_shadow_bumpscale_bumpmap", "10");
cvar_t r_shadow_glsl_offsetmapping = SCVAR ("r_shadow_glsl_offsetmapping", "0");
cvar_t r_shadow_glsl_offsetmapping_bias = SCVAR ("r_shadow_glsl_offsetmapping_bias", "0.04");
cvar_t r_shadow_glsl_offsetmapping_scale = SCVAR ("r_shadow_glsl_offsetmapping_scale", "-0.04");
cvar_t r_glsl_offsetmapping = SCVAR ("r_glsl_offsetmapping", "0");
cvar_t r_glsl_offsetmapping_scale = SCVAR ("r_glsl_offsetmapping_scale", "0.04");
cvar_t r_shadow_realtime_world = SCVARF ("r_shadow_realtime_world", "0", CVAR_ARCHIVE);
cvar_t r_shadow_realtime_world_shadows = SCVARF ("r_shadow_realtime_world_shadows", "1", CVAR_ARCHIVE);
@ -407,9 +406,8 @@ void GLRenderer_Init(void)
Cvar_Register (&gl_smoothcrosshair, GRAPHICALNICETIES);
Cvar_Register (&gl_bump, GRAPHICALNICETIES);
Cvar_Register (&r_shadow_glsl_offsetmapping, GRAPHICALNICETIES);
Cvar_Register (&r_shadow_glsl_offsetmapping_scale, GRAPHICALNICETIES);
Cvar_Register (&r_shadow_glsl_offsetmapping_bias, GRAPHICALNICETIES);
Cvar_Register (&r_glsl_offsetmapping, GRAPHICALNICETIES);
Cvar_Register (&r_glsl_offsetmapping_scale, GRAPHICALNICETIES);
Cvar_Register (&gl_contrast, GLRENDEREROPTIONS);
#ifdef R_XFLIP
@ -1490,6 +1488,10 @@ qboolean R_ApplyRenderer_Load (rendererstate_t *newr)
}
}
if (h2playertranslations)
BZ_Free(h2playertranslations);
h2playertranslations = FS_LoadMallocFile ("gfx/player.lmp");
if (vid.fullbright < 2)
vid.fullbright = 0; //transparent colour doesn't count.
@ -2140,13 +2142,12 @@ R_TextureAnimation
Returns the proper texture for a given time and base texture
===============
*/
extern entity_t *currententity;
texture_t *R_TextureAnimation (texture_t *base)
texture_t *R_TextureAnimation (int frame, texture_t *base)
{
int reletive;
int count;
if (currententity->framestate.g[FS_REG].frame[0])
if (frame)
{
if (base->alternate_anims)
base = base->alternate_anims;

View File

@ -78,10 +78,10 @@ cvar_t sbar_teamstatus = SCVAR("sbar_teamstatus", "1");
int sb_updates; // if >= vid.numpages, no update needed
int sb_hexen2_cur_item;//hexen2 hud
qboolean sb_hexen2_extra_info;//show the extra stuff
qboolean sb_hexen2_infoplaque;
float sb_hexen2_item_time;
int sb_hexen2_cur_item[MAX_SPLITS];//hexen2 hud
qboolean sb_hexen2_extra_info[MAX_SPLITS];//show the extra stuff
qboolean sb_hexen2_infoplaque[MAX_SPLITS];
float sb_hexen2_item_time[MAX_SPLITS];
qboolean sbar_parsingteamstatuses; //so we don't eat it if its not displayed
@ -673,37 +673,58 @@ void Sbar_ShowScores (void)
void Sbar_Hexen2InvLeft_f(void)
{
sb_hexen2_item_time = realtime;
sb_hexen2_cur_item--;
if (sb_hexen2_cur_item < 0)
sb_hexen2_cur_item = 14;
int tries = 15;
int pnum = CL_TargettedSplit(false);
sb_hexen2_item_time[pnum] = realtime;
while (tries-- > 0)
{
sb_hexen2_cur_item[pnum]--;
if (sb_hexen2_cur_item[pnum] < 0)
sb_hexen2_cur_item[pnum] = 14;
if (cl.stats[pnum][STAT_H2_CNT_TORCH+sb_hexen2_cur_item[pnum]] > 0)
break;
}
}
void Sbar_Hexen2InvRight_f(void)
{
sb_hexen2_item_time = realtime;
sb_hexen2_cur_item++;
if (sb_hexen2_cur_item > 14)
sb_hexen2_cur_item = 0;
int tries = 15;
int pnum = CL_TargettedSplit(false);
sb_hexen2_item_time[pnum] = realtime;
while (tries-- > 0)
{
sb_hexen2_cur_item[pnum]++;
if (sb_hexen2_cur_item[pnum] > 14)
sb_hexen2_cur_item[pnum] = 0;
if (cl.stats[pnum][STAT_H2_CNT_TORCH+sb_hexen2_cur_item[pnum]] > 0)
break;
}
}
void Sbar_Hexen2InvUse_f(void)
{
Cbuf_AddText(va("impulse %d\n", 100+sb_hexen2_cur_item), Cmd_ExecLevel);
int pnum = CL_TargettedSplit(false);
Cmd_ExecuteString(va("impulse %d\n", 100+sb_hexen2_cur_item[pnum]), Cmd_ExecLevel);
}
void Sbar_Hexen2ShowInfo_f(void)
{
sb_hexen2_extra_info = true;
int pnum = CL_TargettedSplit(false);
sb_hexen2_extra_info[pnum] = true;
}
void Sbar_Hexen2DontShowInfo_f(void)
{
sb_hexen2_extra_info = false;
int pnum = CL_TargettedSplit(false);
sb_hexen2_extra_info[pnum] = false;
}
void Sbar_Hexen2PInfoPlaque_f(void)
{
sb_hexen2_infoplaque = true;
int pnum = CL_TargettedSplit(false);
sb_hexen2_infoplaque[pnum] = true;
}
void Sbar_Hexen2MInfoPlaque_f(void)
{
sb_hexen2_infoplaque = false;
int pnum = CL_TargettedSplit(false);
sb_hexen2_infoplaque[pnum] = false;
}
/*
@ -976,6 +997,11 @@ void Sbar_DrawString (int x, int y, char *str)
Draw_FunString (sbar_rect.x + x /*+ ((sbar_rect.width - 320)>>1) */, sbar_rect.y + y+ sbar_rect.height-SBAR_HEIGHT, str);
}
void Sbar_DrawExpandedString (int x, int y, conchar_t *str)
{
Draw_ExpandedString (sbar_rect.x + x /*+ ((sbar_rect.width - 320)>>1) */, sbar_rect.y + y+ sbar_rect.height-SBAR_HEIGHT, str);
}
void Draw_TinyString (int x, int y, const qbyte *str)
{
float xstart;
@ -1354,7 +1380,8 @@ Sbar_DrawInventory
void Sbar_DrawInventory (int pnum)
{
int i;
char num[6];
char num[6];
conchar_t numc[6];
float time;
int flashon;
qboolean headsup;
@ -1368,9 +1395,9 @@ void Sbar_DrawInventory (int pnum)
if (sbar_rogue)
{
if ( cl.stats[pnum][STAT_ACTIVEWEAPON] >= RIT_LAVA_NAILGUN )
Sbar_DrawPic (0, -24, FINDOUT, FINDOUT, rsb_invbar[0]);
Sbar_DrawPic (0, -24, 320, 24, rsb_invbar[0]);
else
Sbar_DrawPic (0, -24, FINDOUT, FINDOUT, rsb_invbar[1]);
Sbar_DrawPic (0, -24, 320, 24, rsb_invbar[1]);
}
else
Sbar_DrawPic (0, -24, 320, 24, sb_ibar);
@ -1401,7 +1428,7 @@ void Sbar_DrawInventory (int pnum)
}
else
{
Sbar_DrawPic (i*24, -16, 24, 16, sb_weapons[flashon][i]);
Sbar_DrawPic (i*24, -16, (i==6)?48:24, 16, sb_weapons[flashon][i]);
}
if (flashon > 1)
@ -1421,11 +1448,11 @@ void Sbar_DrawInventory (int pnum)
if (headsup)
{
if (sbar_rect.height>200)
Sbar_DrawSubPic ((hudswap) ? 0 : (sbar_rect.width-24),-68-(5-i)*16, FINDOUT, FINDOUT, rsb_weapons[i],0,0,FINDOUT,FINDOUT);
Sbar_DrawSubPic ((hudswap) ? 0 : (sbar_rect.width-24),-68-(5-i)*16, 24, 16, rsb_weapons[i],0,0,((i==4)?48:24),16);
}
else
Sbar_DrawPic ((i+2)*24, -16, 24, 16, rsb_weapons[i]);
Sbar_DrawPic ((i+2)*24, -16, (i==4)?48:24, 16, rsb_weapons[i]);
}
}
}
@ -1435,34 +1462,18 @@ void Sbar_DrawInventory (int pnum)
for (i=0 ; i<4 ; i++)
{
snprintf (num, sizeof(num), "%3i",cl.stats[pnum][STAT_SHELLS+i] );
if (num[0] != ' ')
num[0] += 18-'0';
if (num[1] != ' ')
num[1] += 18-'0';
if (num[2] != ' ')
num[2] += 18-'0';
numc[0] = CON_WHITEMASK|0xe000|((num[0]!=' ')?(num[0] + 18-'0'):' ');
numc[1] = CON_WHITEMASK|0xe000|((num[1]!=' ')?(num[1] + 18-'0'):' ');
numc[2] = CON_WHITEMASK|0xe000|((num[2]!=' ')?(num[2] + 18-'0'):' ');
numc[3] = 0;
if (headsup)
{
// Sbar_DrawSubPic(3, -24, sb_ibar, 3, 0, 42,11);
Sbar_DrawSubPic((hudswap) ? 0 : (sbar_rect.width-42), -24 - (4-i)*11, 42, 11, sb_ibar, 3+(i*48), 0, 320, 24);
/*
if (num[0] != ' ')
Sbar_DrawCharacter ( (hudswap) ? 3 : (sbar_rect.width-39), -24 - (4-i)*11, 18 + num[0] - '0');
if (num[1] != ' ')
Sbar_DrawCharacter ( (hudswap) ? 11 : (sbar_rect.width-31), -24 - (4-i)*11, 18 + num[1] - '0');
if (num[2] != ' ')
Sbar_DrawCharacter ( (hudswap) ? 19 : (sbar_rect.width-23), -24 - (4-i)*11, 18 + num[2] - '0');
*/
Sbar_DrawString((hudswap) ? 3 : (sbar_rect.width-39), -24 - (4-i)*11, num);
Sbar_DrawExpandedString((hudswap) ? 3 : (sbar_rect.width-39), -24 - (4-i)*11, numc);
}
else
{
if (num[0] != ' ')
Sbar_DrawCharacter ( (6*i+1)*8 - 2, -24, 18 + num[0] - '0');
if (num[1] != ' ')
Sbar_DrawCharacter ( (6*i+2)*8 - 2, -24, 18 + num[1] - '0');
if (num[2] != ' ')
Sbar_DrawCharacter ( (6*i+3)*8 - 2, -24, 18 + num[2] - '0');
Sbar_DrawExpandedString((6*i+1)*8 - 2, -24, numc);
}
}
@ -1818,25 +1829,69 @@ void Sbar_Hexen2DrawInventory(int pnum)
{
int i;
int x, y=-37;
int activeleft = 0;
int activeright = 0;
if (sb_hexen2_item_time+3 < realtime)
/*always select an artifact that we actually have whether we are drawing the full bar or not.*/
for (i = 0; i < 15; i++)
{
if (cl.stats[pnum][STAT_H2_CNT_TORCH+(i+sb_hexen2_cur_item[pnum])%15])
{
sb_hexen2_cur_item[pnum] = (sb_hexen2_cur_item[pnum] + i)%15;
break;
}
}
if (sb_hexen2_item_time[pnum]+3 < realtime)
return;
#if 1
for (i = sb_hexen2_cur_item[pnum]; i < 15; i++)
if (sb_hexen2_cur_item[pnum] == i || cl.stats[pnum][STAT_H2_CNT_TORCH+i] > 0)
activeright++;
for (i = sb_hexen2_cur_item[pnum]-1; i >= 0; i--)
if (sb_hexen2_cur_item[pnum] == i || cl.stats[pnum][STAT_H2_CNT_TORCH+i] > 0)
activeleft++;
if (activeleft > 3 + (activeright<=3?(4-activeright):0))
activeleft = 3 + (activeright<=3?(4-activeright):0);
x=320/2-114 + (activeleft-1)*33;
for (i = sb_hexen2_cur_item[pnum]-1; x>=320/2-114; i--)
{
if (!cl.stats[pnum][STAT_H2_CNT_TORCH+i])
continue;
if (i == sb_hexen2_cur_item[pnum])
Sbar_DrawPic(x+9, y-12, 11, 11, Draw_SafeCachePic("gfx/artisel.lmp"));
Sbar_Hexen2DrawItem(pnum, x, y, i);
x -= 33;
}
x=320/2-114 + activeleft*33;
for (i = sb_hexen2_cur_item[pnum]; i < 15 && x < 320/2-114+7*33; i++)
{
if (i != sb_hexen2_cur_item[pnum] && !cl.stats[pnum][STAT_H2_CNT_TORCH+i])
continue;
if (i == sb_hexen2_cur_item[pnum])
Sbar_DrawPic(x+9, y-12, 11, 11, Draw_SafeCachePic("gfx/artisel.lmp"));
Sbar_Hexen2DrawItem(pnum, x, y, i);
x+=33;
}
#elif 1
for (i = 0, x=320/2-114; i < 7; i++, x+=33)
{
if ((sb_hexen2_cur_item-3+i+30)%15 == sb_hexen2_cur_item)
if ((sb_hexen2_cur_item[pnum]-3+i+30)%15 == sb_hexen2_cur_item[pnum])
Sbar_DrawPic(x+9, y-12, 11, 11, Draw_SafeCachePic("gfx/artisel.lmp"));
Sbar_Hexen2DrawItem(pnum, x, y, (sb_hexen2_cur_item-3+i+30)%15);
Sbar_Hexen2DrawItem(pnum, x, y, (sb_hexen2_cur_item[pnum]-3+i+30)%15);
}
#else
for (i = 0, x=320/2; i < 3; i++, x+=33)
{
Sbar_Hexen2DrawItem(pnum, x, y, (sb_hexen2_cur_item+1+i)%15);
Sbar_Hexen2DrawItem(pnum, x, y, (sb_hexen2_cur_item[pnum]+1+i)%15);
}
for (i = 0, x=320/2-33; i < 3; i++, x-=33)
{
Sbar_Hexen2DrawItem(pnum, x, y, (sb_hexen2_cur_item-1-i+45)%15);
Sbar_Hexen2DrawItem(pnum, x, y, (sb_hexen2_cur_item[pnum]-1-i+45)%15);
}
#endif
}
@ -1857,7 +1912,7 @@ void Sbar_Hexen2DrawExtra (int pnum)
"Demoness"
};
if (sb_hexen2_infoplaque)
if (sb_hexen2_infoplaque[pnum])
{
int i;
Con_Printf("Objectives:\n");
@ -1866,16 +1921,16 @@ void Sbar_Hexen2DrawExtra (int pnum)
if (cl.stats[pnum][STAT_H2_OBJECTIVE1 + i/32] & (1<<(i&31)))
Con_Printf("%s\n", T_GetInfoString(i));
}
sb_hexen2_infoplaque = false;
sb_hexen2_infoplaque[pnum] = false;
}
if (!sb_hexen2_extra_info)
if (!sb_hexen2_extra_info[pnum])
{
sbar_rect.y -= 46-SBAR_HEIGHT;
return;
}
pclass = cl.stats[pnum][STAT_H2_PLAYERCLASS];
pclass = cl.players[cl.playernum[pnum]].h2playerclass;
if (pclass >= sizeof(pclassname)/sizeof(pclassname[0]))
pclass = sizeof(pclassname)/sizeof(pclassname[0]) - 1;
@ -1967,7 +2022,7 @@ int Sbar_Hexen2ArmourValue(int pnum)
};
int classno;
classno = cl.stats[pnum][STAT_H2_PLAYERCLASS];
classno = cl.players[cl.playernum[pnum]].h2playerclass;
if (classno >= 1 && classno <= 5)
{
classno--;
@ -2036,9 +2091,21 @@ void Sbar_Hexen2DrawBasic(int pnum)
Sbar_DrawPic(267, 36, 10, 10, Draw_SafeCachePic("gfx/chnrcov.lmp"));
Sbar_Hexen2DrawItem(pnum, 144, 3, sb_hexen2_cur_item);
Sbar_Hexen2DrawItem(pnum, 144, 3, sb_hexen2_cur_item[pnum]);
}
void Sbar_Hexen2DrawMinimal(int pnum)
{
int y;
y = -16;
Sbar_DrawPic(3, y, 31, 17, Draw_SafeCachePic("gfx/bmmana.lmp"));
Sbar_DrawPic(3, y+18, 31, 17, Draw_SafeCachePic("gfx/gmmana.lmp"));
Sbar_DrawTinyString(10, y+6, va("%03d", cl.stats[pnum][STAT_H2_BLUEMANA]));
Sbar_DrawTinyString(10, y+18+6, va("%03d", cl.stats[pnum][STAT_H2_GREENMANA]));
Sbar_Hexen2DrawNum(38, y+18, cl.stats[pnum][STAT_HEALTH], 3);
}
void Sbar_DrawTeamStatus(void)
@ -2223,9 +2290,14 @@ void Sbar_Draw (void)
if (sbar_hexen2)
{
Sbar_Hexen2DrawExtra(pnum);
Sbar_Hexen2DrawBasic(pnum);
Sbar_Hexen2DrawInventory(pnum);
if (sb_lines > 0)
{
Sbar_Hexen2DrawExtra(pnum);
Sbar_Hexen2DrawBasic(pnum);
Sbar_Hexen2DrawInventory(pnum);
}
else
Sbar_Hexen2DrawMinimal(pnum);
if (cl.deathmatch)
Sbar_MiniDeathmatchOverlay ();

View File

@ -97,7 +97,7 @@ static int SDL_InitCard(soundcardinfo_t *sc, int cardnum)
desired.channels = sc->sn.numchannels; //fixme!
desired.samples = 0x0100;
desired.format = AUDIO_S16SYS;
desired.callback = SSDL_Paint;
desired.callback = (void*)SSDL_Paint;
desired.userdata = sc;
memcpy(&obtained, &desired, sizeof(obtained));

View File

@ -469,27 +469,30 @@ typedef struct
// remaining contents are non-visible, and don't eat brushes
#define Q2CONTENTS_AREAPORTAL 0x8000
#define Q2CONTENTS_AREAPORTAL 0x8000
#define Q2CONTENTS_PLAYERCLIP 0x10000
#define Q2CONTENTS_PLAYERCLIP 0x10000
#define Q2CONTENTS_MONSTERCLIP 0x20000
// currents can be added to any other contents, and may be mixed
#define Q2CONTENTS_CURRENT_0 0x40000
#define Q2CONTENTS_CURRENT_90 0x80000
#define Q2CONTENTS_CURRENT_0 0x40000
#define Q2CONTENTS_CURRENT_90 0x80000
#define Q2CONTENTS_CURRENT_180 0x100000
#define Q2CONTENTS_CURRENT_270 0x200000
#define Q2CONTENTS_CURRENT_UP 0x400000
#define Q2CONTENTS_CURRENT_UP 0x400000
#define Q2CONTENTS_CURRENT_DOWN 0x800000
#define Q2CONTENTS_ORIGIN 0x1000000 // removed before bsping an entity
#define Q2CONTENTS_ORIGIN 0x1000000 // removed before bsping an entity
#define Q2CONTENTS_MONSTER 0x2000000 // should never be on a brush, only in game
#define Q2CONTENTS_DEADMONSTER 0x4000000
#define Q2CONTENTS_DETAIL 0x8000000 // brushes to be added after vis leafs
#define Q2CONTENTS_DETAIL 0x8000000 // brushes to be added after vis leafs
#define Q2CONTENTS_TRANSLUCENT 0x10000000 // auto set if any surface has trans
#define Q2CONTENTS_LADDER 0x20000000
#define Q3CONTENTS_SOLID Q2CONTENTS_SOLID // should never be on a brush, only in game
#define Q3CONTENTS_BODY 0x2000000 // should never be on a brush, only in game
#define Q3CONTENTS_TRANSLUCENT 0x20000000
#define Q2CONTENTS_LADDER 0x20000000
//Texinfo flags - warning: these mix with q3 surface flags

View File

@ -1131,7 +1131,7 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf,
R_LerpFrames(mesh, (galiaspose_t *)((char *)g1 + g1->poseofs + sizeof(galiaspose_t)*frame1),
(galiaspose_t *)((char *)g2 + g2->poseofs + sizeof(galiaspose_t)*frame2),
1-lerp, (qbyte)(alpha*255), currententity->fatness, nolightdir);
1-lerp, (qbyte)(alpha*255), e->fatness, nolightdir);
return true; //to allow the mesh to be dlighted.
}
@ -1149,7 +1149,7 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf,
//The whole reason why model loading is supported in the server.
qboolean Mod_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace)
qboolean Mod_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace)
{
galiasinfo_t *mod = Mod_Extradata(model);
galiasgroup_t *group;

View File

@ -110,6 +110,7 @@ typedef struct {
texnums_t texnum;
unsigned int tcolour;
unsigned int bcolour;
unsigned int pclass;
int skinnum;
unsigned int subframe;
bucket_t bucket;

View File

@ -1801,9 +1801,9 @@ void COM_Gamedir (const char *dir)
}
#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 NEXCFG DPCOMPAT "set r_particlesdesc effectinfo\nset 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"
#define HEX2CFG "set sv_maxspeed 640\nset watervis 1\nset r_wateralpha 0.5\nset sv_pupglow 1\n"
#define HEX2CFG "set r_particlesdesc \"spikeset tsshaft h2part\"\nset sv_maxspeed 640\nset watervis 1\nset r_wateralpha 0.5\nset sv_pupglow 1\nset cl_model_bobbing 1\n"
typedef struct {
const char *protocolname; //sent to the master server when this is the current gamemode.

View File

@ -33,10 +33,10 @@ qboolean RMod_LoadSurfedges (lump_t *l);
void RMod_LoadLighting (lump_t *l);
qboolean CM_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace);
qboolean CM_NativeTrace(model_t *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int contents, trace_t *trace);
unsigned int CM_NativeContents(struct model_s *model, int hulloverride, int frame, vec3_t p, vec3_t mins, vec3_t maxs);
unsigned int Q2BSP_PointContents(model_t *mod, vec3_t p);
qboolean CM_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace);
qboolean CM_NativeTrace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int contents, trace_t *trace);
unsigned int CM_NativeContents(struct model_s *model, int hulloverride, int frame, vec3_t axis[3], vec3_t p, vec3_t mins, vec3_t maxs);
unsigned int Q2BSP_PointContents(model_t *mod, vec3_t axis[3], vec3_t p);
@ -3691,6 +3691,13 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
else
noerrors = noerrors && CModQ3_LoadRFaces (&header.lumps[Q3LUMP_SURFACES]);
noerrors = noerrors && CModQ3_LoadMarksurfaces (&header.lumps[Q3LUMP_LEAFSURFACES]); //fixme: duplicated loading.
/*make sure all textures have a shader*/
for (i=0; i<loadmodel->numtextures; i++)
{
if (!loadmodel->textures[i]->shader)
loadmodel->textures[i]->shader = R_RegisterShader_Lightmap(loadmodel->textures[i]->name);
}
}
#endif
noerrors = noerrors && CModQ3_LoadLeafFaces (&header.lumps[Q3LUMP_LEAFSURFACES]);
@ -3929,7 +3936,7 @@ q2cmodel_t *CM_LoadMap (char *name, char *filein, qboolean clientload, unsigned
mod->hulls[0].firstclipnode = bm->headnode;
mod->hulls[j].available = true;
mod->hulls[0].available = true;
mod->nummodelsurfaces = bm->numsurfaces;
mod->firstmodelsurface = bm->firstsurface;
for (j=1 ; j<MAX_MAP_HULLSM ; j++)
@ -4313,7 +4320,7 @@ int CM_PointContents (model_t *mod, vec3_t p)
return contents;
}
unsigned int CM_NativeContents(struct model_s *model, int hulloverride, int frame, vec3_t p, vec3_t mins, vec3_t maxs)
unsigned int CM_NativeContents(struct model_s *model, int hulloverride, int frame, vec3_t axis[3], vec3_t p, vec3_t mins, vec3_t maxs)
{
int contents;
if (!DotProduct(mins, mins) && !DotProduct(maxs, maxs))
@ -5154,12 +5161,12 @@ trace_t CM_BoxTrace (model_t *mod, vec3_t start, vec3_t end,
return trace_trace;
}
qboolean CM_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace)
qboolean CM_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace)
{
*trace = CM_BoxTrace(model, start, end, mins, maxs, MASK_PLAYERSOLID);
return trace->fraction != 1;
}
qboolean CM_NativeTrace(model_t *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int contents, trace_t *trace)
qboolean CM_NativeTrace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int contents, trace_t *trace)
{
*trace = CM_BoxTrace(model, start, end, mins, maxs, contents);
return trace->fraction != 1;
@ -5668,7 +5675,7 @@ qboolean Q2BSP_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f,
return true;
return false;
}*/
unsigned int Q2BSP_PointContents(model_t *mod, vec3_t p)
unsigned int Q2BSP_PointContents(model_t *mod, vec3_t axis[3], vec3_t p)
{
int pc, ret = FTECONTENTS_EMPTY;
pc = CM_PointContents (mod, p);

View File

@ -1449,6 +1449,37 @@ qboolean Matrix4_Invert(const float *m, float *out)
#undef SWAP_ROWS
}
void Matrix3_Invert_Simple (const vec3_t in1[3], vec3_t out[3])
{
// we only support uniform scaling, so assume the first row is enough
// (note the lack of sqrt here, because we're trying to undo the scaling,
// this means multiplying by the inverse scale twice - squaring it, which
// makes the sqrt a waste of time)
#if 1
double scale = 1.0 / (in1[0][0] * in1[0][0] + in1[0][1] * in1[0][1] + in1[0][2] * in1[0][2]);
#else
double scale = 3.0 / sqrt
(in1->m[0][0] * in1->m[0][0] + in1->m[0][1] * in1->m[0][1] + in1->m[0][2] * in1->m[0][2]
+ in1->m[1][0] * in1->m[1][0] + in1->m[1][1] * in1->m[1][1] + in1->m[1][2] * in1->m[1][2]
+ in1->m[2][0] * in1->m[2][0] + in1->m[2][1] * in1->m[2][1] + in1->m[2][2] * in1->m[2][2]);
scale *= scale;
#endif
// invert the rotation by transposing and multiplying by the squared
// recipricol of the input matrix scale as described above
out[0][0] = in1[0][0] * scale;
out[0][1] = in1[1][0] * scale;
out[0][2] = in1[2][0] * scale;
out[1][0] = in1[0][1] * scale;
out[1][1] = in1[1][1] * scale;
out[1][2] = in1[2][1] * scale;
out[2][0] = in1[0][2] * scale;
out[2][1] = in1[1][2] * scale;
out[2][2] = in1[2][2] * scale;
}
void Matrix4Q_Invert_Simple (const float *in1, float *out)
{
// we only support uniform scaling, so assume the first row is enough

View File

@ -134,6 +134,7 @@ void Matrix3_Multiply (vec3_t *in1, vec3_t *in2, vec3_t *out);
void Matrix4_Identity(float *outm);
qboolean Matrix4_Invert(const float *m, float *out);
void Matrix4Q_Invert_Simple (const float *in1, float *out);
void Matrix3_Invert_Simple(const vec3_t in[3], vec3_t out[3]);
void Matrix4_CreateTranslate (float *out, float x, float y, float z);
void Matrix4Q_CreateTranslate (float *out, float x, float y, float z);
void Matrix4_ModelMatrixFromAxis (float *modelview, const vec3_t pn, const vec3_t right, const vec3_t up, const vec3_t vieworg);

View File

@ -88,21 +88,18 @@ hull_t *PM_HullForBox (vec3_t mins, vec3_t maxs)
int PM_TransformedModelPointContents (model_t *mod, vec3_t p, vec3_t origin, vec3_t angles)
{
vec3_t p_l, forward, up, right, temp;
vec3_t p_l, axis[3];
VectorSubtract (p, origin, p_l);
// rotate start and end into the models frame of reference
if (angles[0] || angles[1] || angles[2])
{
AngleVectors (angles, forward, right, up);
VectorCopy (p_l, temp);
p_l[0] = DotProduct (temp, forward);
p_l[1] = -DotProduct (temp, right);
p_l[2] = DotProduct (temp, up);
AngleVectors (angles, axis[0], axis[1], axis[2]);
VectorNegate(axis[1], axis[1]);
return mod->funcs.PointContents(mod, axis, p_l);
}
return mod->funcs.PointContents(mod, p_l);
return mod->funcs.PointContents(mod, NULL, p_l);
}
@ -123,7 +120,7 @@ int PM_PointContents (vec3_t p)
pm = pmove.physents[0].model;
if (!pm)
return FTECONTENTS_EMPTY;
pc = pm->funcs.PointContents(pm, p);
pc = pm->funcs.PointContents(pm, NULL, p);
//we need this for e2m2 - waterjumping on to plats wouldn't work otherwise.
for (num = 1; num < pmove.numphysent; num++)
{
@ -206,50 +203,24 @@ static vec3_t trace_extents;
static qboolean PM_TransformedHullCheck (model_t *model, vec3_t start, vec3_t end, trace_t *trace, vec3_t origin, vec3_t angles)
{
vec3_t start_l, end_l;
vec3_t a;
vec3_t forward, right, up;
vec3_t temp;
qboolean rotated;
int i;
vec3_t axis[3];
// subtract origin offset
VectorSubtract (start, origin, start_l);
VectorSubtract (end, origin, end_l);
// rotate start and end into the models frame of reference
if (model &&
(angles[0] || angles[1] || angles[2]) )
rotated = true;
else
rotated = false;
if (rotated)
{
AngleVectors (angles, forward, right, up);
VectorCopy (start_l, temp);
start_l[0] = DotProduct (temp, forward);
start_l[1] = -DotProduct (temp, right);
start_l[2] = DotProduct (temp, up);
VectorCopy (end_l, temp);
end_l[0] = DotProduct (temp, forward);
end_l[1] = -DotProduct (temp, right);
end_l[2] = DotProduct (temp, up);
}
// sweep the box through the model
if (model)
{
for (i = 0; i < 3; i++)
if (angles[0] || angles[1] || angles[2])
{
if (start_l[i]+player_mins[i] > model->maxs[i] && end_l[i] + player_mins[i] > model->maxs[i])
return false;
if (start_l[i]+player_maxs[i] < model->mins[i] && end_l[i] + player_maxs[i] < model->mins[i])
return false;
AngleVectors (angles, axis[0], axis[1], axis[2]);
VectorNegate(axis[1], axis[1]);
model->funcs.Trace(model, 0, 0, axis, start_l, end_l, player_mins, player_maxs, trace);
}
model->funcs.Trace(model, 0, 0, start_l, end_l, player_mins, player_maxs, trace);
else
model->funcs.Trace(model, 0, 0, NULL, start_l, end_l, player_mins, player_maxs, trace);
}
else
{
@ -264,33 +235,9 @@ static qboolean PM_TransformedHullCheck (model_t *model, vec3_t start, vec3_t en
Q1BSP_RecursiveHullCheck (&box_hull, box_hull.firstclipnode, 0, 1, start_l, end_l, trace);
}
if (rotated)
{
// FIXME: figure out how to do this with existing angles
// VectorNegate (angles, a);
if (trace->fraction != 1.0)
{
a[0] = -angles[0];
a[1] = -angles[1];
a[2] = -angles[2];
AngleVectors (a, forward, right, up);
VectorCopy (trace->plane.normal, temp);
trace->plane.normal[0] = DotProduct (temp, forward);
trace->plane.normal[1] = -DotProduct (temp, right);
trace->plane.normal[2] = DotProduct (temp, up);
}
trace->endpos[0] = start[0] + trace->fraction * (end[0] - start[0]);
trace->endpos[1] = start[1] + trace->fraction * (end[1] - start[1]);
trace->endpos[2] = start[2] + trace->fraction * (end[2] - start[2]);
}
else
{
trace->endpos[0] += origin[0];
trace->endpos[1] += origin[1];
trace->endpos[2] += origin[2];
}
trace->endpos[0] += origin[0];
trace->endpos[1] += origin[1];
trace->endpos[2] += origin[2];
return true;
}

View File

@ -367,12 +367,20 @@ int Q1BSP_HullPointContents(hull_t *hull, vec3_t p)
}
}
unsigned int Q1BSP_PointContents(model_t *model, vec3_t point)
unsigned int Q1BSP_PointContents(model_t *model, vec3_t axis[3], vec3_t point)
{
if (axis)
{
vec3_t transformed;
transformed[0] = DotProduct(point, axis[0]);
transformed[1] = DotProduct(point, axis[1]);
transformed[2] = DotProduct(point, axis[2]);
return Q1BSP_HullPointContents(&model->hulls[0], transformed);
}
return Q1BSP_HullPointContents(&model->hulls[0], point);
}
qboolean Q1BSP_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace)
qboolean Q1BSP_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace)
{
hull_t *hull;
vec3_t size;
@ -420,16 +428,51 @@ qboolean Q1BSP_Trace(model_t *model, int forcehullnum, int frame, vec3_t start,
// calculate an offset value to center the origin
VectorSubtract (hull->clip_mins, mins, offset);
VectorSubtract(start, offset, start_l);
VectorSubtract(end, offset, end_l);
Q1BSP_RecursiveHullCheck(hull, hull->firstclipnode, 0, 1, start_l, end_l, trace);
if (trace->fraction == 1)
if (axis)
{
VectorCopy (end, trace->endpos);
vec3_t tmp;
VectorSubtract(start, offset, tmp);
start_l[0] = DotProduct(tmp, axis[0]);
start_l[1] = DotProduct(tmp, axis[1]);
start_l[2] = DotProduct(tmp, axis[2]);
VectorSubtract(end, offset, tmp);
end_l[0] = DotProduct(tmp, axis[0]);
end_l[1] = DotProduct(tmp, axis[1]);
end_l[2] = DotProduct(tmp, axis[2]);
Q1BSP_RecursiveHullCheck(hull, hull->firstclipnode, 0, 1, start_l, end_l, trace);
if (trace->fraction == 1)
{
VectorCopy (end, trace->endpos);
}
else
{
vec3_t iaxis[3];
vec3_t norm;
Matrix3_Invert_Simple(axis, iaxis);
VectorCopy(trace->plane.normal, norm);
trace->plane.normal[0] = DotProduct(norm, iaxis[0]);
trace->plane.normal[1] = DotProduct(norm, iaxis[1]);
trace->plane.normal[2] = DotProduct(norm, iaxis[2]);
/*just interpolate it, its easier than inverse matrix rotations*/
VectorInterpolate(start, trace->fraction, end, trace->endpos);
}
}
else
{
VectorAdd (trace->endpos, offset, trace->endpos);
VectorSubtract(start, offset, start_l);
VectorSubtract(end, offset, end_l);
Q1BSP_RecursiveHullCheck(hull, hull->firstclipnode, 0, 1, start_l, end_l, trace);
if (trace->fraction == 1)
{
VectorCopy (end, trace->endpos);
}
else
{
VectorAdd (trace->endpos, offset, trace->endpos);
}
}
return trace->fraction != 1;

View File

@ -358,7 +358,7 @@ int VMQ3_Cvar_Update(vmcvar_t *v)
if (!c)
return 0; //that slot isn't active yet
v->integer = c->value;
v->integer = c->ival;
v->value = c->value;
v->modificationCount = c->modified;
Q_strncpyz(v->string, c->string, sizeof(v->string));

View File

@ -40,31 +40,6 @@ typedef struct
// entity_state_t->renderfx flags
#define Q2RF_MINLIGHT 1 // always have some light (viewmodel)
#define Q2RF_VIEWERMODEL 2 // don't draw through eyes, only mirrors
#define Q2RF_WEAPONMODEL 4 // only draw through eyes
#define Q2RF_FULLBRIGHT 8 // always draw full intensity
#define Q2RF_DEPTHHACK 16 // for view weapon Z crunching
#define Q2RF_TRANSLUCENT 32
#define Q2RF_FRAMELERP 64
#define Q2RF_BEAM 128
#define Q2RF_CUSTOMSKIN 256 // skin is an index in image_precache
#define Q2RF_GLOW 512 // pulse lighting for bonus items
#define Q2RF_SHELL_RED 1024
#define Q2RF_SHELL_GREEN 2048
#define Q2RF_SHELL_BLUE 4096
//ROGUE
#define Q2RF_IR_VISIBLE 0x00008000 // 32768
#define Q2RF_SHELL_DOUBLE 0x00010000 // 65536
#define Q2RF_SHELL_HALF_DAM 0x00020000
#define Q2RF_USE_DISGUISE 0x00040000
//ROGUE
extern cvar_t gl_part_flame, r_fullbrightSkins, r_fb_models;
extern cvar_t r_noaliasshadows;
void R_TorchEffect (vec3_t pos, int type);
@ -218,7 +193,7 @@ static texnums_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, int surfnum,
int frame;
unsigned int subframe;
unsigned int tc, bc;
unsigned int tc, bc, pc;
qboolean forced;
if (e->skinnum >= 100 && e->skinnum < 110)
@ -245,11 +220,13 @@ static texnums_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, int surfnum,
Skin_Find(e->scoreboard);
tc = e->scoreboard->ttopcolor;
bc = e->scoreboard->tbottomcolor;
pc = e->scoreboard->h2playerclass;
}
else
{
tc = 1;
bc = 1;
pc = 0;
}
if (forced || tc != 1 || bc != 1 || (e->scoreboard && e->scoreboard->skin))
@ -323,7 +300,7 @@ static texnums_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, int surfnum,
for (cm = Hash_Get(&skincolourmapped, skinname); cm; cm = Hash_GetNext(&skincolourmapped, skinname, cm))
{
if (cm->tcolour == tc && cm->bcolour == bc && cm->skinnum == e->skinnum && cm->subframe == subframe)
if (cm->tcolour == tc && cm->bcolour == bc && cm->skinnum == e->skinnum && cm->subframe == subframe && cm->pclass == pc)
{
return &cm->texnum;
}
@ -335,6 +312,7 @@ static texnums_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, int surfnum,
Hash_Add(&skincolourmapped, cm->name, cm, &cm->bucket);
cm->tcolour = tc;
cm->bcolour = bc;
cm->pclass = pc;
cm->skinnum = e->skinnum;
cm->subframe = subframe;
cm->texnum.fullbright = r_nulltex;
@ -469,6 +447,25 @@ static texnums_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, int surfnum,
if (scaled_height > gl_max_size.value)
scaled_height = gl_max_size.value; //whoops, we made it too big
if (h2playertranslations && pc)
{
unsigned int color_offsets[5] = {2*14*256,0,1*14*256,2*14*256,2*14*256};
unsigned char *colorA, *colorB, *sourceA, *sourceB;
colorA = h2playertranslations + 256 + color_offsets[pc-1];
colorB = colorA + 256;
sourceA = colorB + (tc * 256);
sourceB = colorB + (bc * 256);
for(i=0;i<256;i++)
{
translate32[i] = d_8to24rgbtable[i];
if (tc > 0 && (colorA[i] != 255))
translate32[i] = d_8to24rgbtable[sourceA[i]];
if (bc > 0 && (colorB[i] != 255))
translate32[i] = d_8to24rgbtable[sourceB[i]];
}
translate32[0] = 0;
}
else
{
for (i=0 ; i<256 ; i++)
translate32[i] = d_8to24rgbtable[i];
@ -526,24 +523,27 @@ static texnums_t *GL_ChooseSkin(galiasinfo_t *inf, char *modelname, int surfnum,
}
}
texnums->base = R_AllocNewTexture(scaled_width, scaled_height);
R_Upload(texnums->base, "", TF_RGBX32, pixels, NULL, scaled_width, scaled_height, IF_NOMIPMAP);
R_Upload(texnums->base, "", h2playertranslations?TF_RGBA32:TF_RGBX32, pixels, NULL, scaled_width, scaled_height, IF_NOMIPMAP);
//now do the fullbrights.
out = pixels;
fracstep = tinwidth*0x10000/scaled_width;
for (i=0 ; i<scaled_height ; i++, out += scaled_width)
if (!h2playertranslations)
{
inrow = original + inwidth*(i*inheight/scaled_height);
frac = fracstep >> 1;
for (j=0 ; j<scaled_width ; j+=1)
//now do the fullbrights.
out = pixels;
fracstep = tinwidth*0x10000/scaled_width;
for (i=0 ; i<scaled_height ; i++, out += scaled_width)
{
if (inrow[frac>>16] < 255-vid.fullbright)
((char *) (&out[j]))[3] = 0; //alpha 0
frac += fracstep;
inrow = original + inwidth*(i*inheight/scaled_height);
frac = fracstep >> 1;
for (j=0 ; j<scaled_width ; j+=1)
{
if (inrow[frac>>16] < 255-vid.fullbright)
((char *) (&out[j]))[3] = 0; //alpha 0
frac += fracstep;
}
}
texnums->fullbright = R_AllocNewTexture(scaled_width, scaled_height);
R_Upload(texnums->fullbright, "", TF_RGBA32, pixels, NULL, scaled_width, scaled_height, IF_NOMIPMAP);
}
texnums->fullbright = R_AllocNewTexture(scaled_width, scaled_height);
R_Upload(texnums->fullbright, "", TF_RGBA32, pixels, NULL, scaled_width, scaled_height, IF_NOMIPMAP);
}
else
{
@ -708,7 +708,7 @@ static void R_DrawShadowVolume(mesh_t *mesh)
#endif
//true if no shading is to be used.
static qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel, unsigned int rmode)
static qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel)
{
vec3_t lightdir;
int i;
@ -728,14 +728,6 @@ static qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel, unsigned int
return true;
}
//shortcut here, no need to test bsp lights or world lights when there's realtime lighting going on.
if (rmode == BEM_DEPTHDARK || rmode == BEM_DEPTHONLY)
{
shadelight[0] = shadelight[1] = shadelight[2] = 0;
ambientlight[0] = ambientlight[1] = ambientlight[2] = 0;
return true;
}
if (!(r_refdef.flags & Q2RDF_NOWORLDMODEL))
{
if (e->flags & Q2RF_WEAPONMODEL)
@ -895,46 +887,63 @@ static qboolean R_CalcModelLighting(entity_t *e, model_t *clmodel, unsigned int
return false;
}
static shader_t reskinnedmodelshader;
void R_DrawGAliasModel (entity_t *e, unsigned int rmode)
void R_GAlias_DrawBatch(batch_t *batch)
{
model_t *clmodel;
galiasinfo_t *inf;
mesh_t mesh;
texnums_t *skin;
entity_t *e;
vec3_t saveorg;
galiasinfo_t *inf;
model_t *clmodel;
int surfnum;
int bef;
static mesh_t mesh;
static mesh_t *meshl = &mesh;
qboolean needrecolour;
qboolean nolightdir;
shader_t *shader;
e = batch->ent;
clmodel = e->model;
// if (e->flags & Q2RF_VIEWERMODEL && e->keynum == cl.playernum[r_refdef.currentplayernum]+1)
// return;
currententity = e;
nolightdir = R_CalcModelLighting(e, clmodel);
inf = RMod_Extradata (clmodel);
memset(&mesh, 0, sizeof(mesh));
for(surfnum=0; inf; ((inf->nextsurf)?(inf = (galiasinfo_t*)((char *)inf + inf->nextsurf)):(inf=NULL)), surfnum++)
{
if (batch->lightmap == surfnum)
{
needrecolour = Alias_GAliasBuildMesh(&mesh, inf, e, e->shaderRGBAf[3], nolightdir);
batch->mesh = &meshl;
}
}
}
void R_GAlias_GenerateBatches(entity_t *e, batch_t **batches)
{
galiasinfo_t *inf;
model_t *clmodel;
shader_t *shader;
batch_t *b;
int surfnum;
texnums_t *skin;
if (r_refdef.externalview && e->flags & Q2RF_WEAPONMODEL)
return;
/*switch model if we're the player model, and the player skin says a new model*/
{
extern int cl_playerindex;
if (e->scoreboard && e->model == cl.model_precache[cl_playerindex])
{
clmodel = e->scoreboard->model;
if (!clmodel || clmodel->type != mod_alias)
clmodel = e->model;
if (clmodel && clmodel->type == mod_alias)
e->model = clmodel;
}
else
clmodel = e->model;
}
if (clmodel->tainted)
{
if (!ruleset_allow_modified_eyes.ival && !strcmp(clmodel->name, "progs/eyes.mdl"))
return;
}
clmodel = e->model;
if (!(e->flags & Q2RF_WEAPONMODEL))
{
@ -951,116 +960,37 @@ void R_DrawGAliasModel (entity_t *e, unsigned int rmode)
#endif
}
nolightdir = R_CalcModelLighting(e, clmodel, rmode);
if (gl_affinemodels.ival)
qglHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_FASTEST);
if (e->flags & Q2RF_DEPTHHACK)
qglDepthRange (gldepthmin, gldepthmin + 0.3*(gldepthmax-gldepthmin));
bef = BEF_FORCEDEPTHTEST;
if (e->flags & Q2RF_ADDITIVE)
if (clmodel->tainted)
{
bef |= BEF_FORCEADDITIVE;
if (!ruleset_allow_modified_eyes.ival && !strcmp(clmodel->name, "progs/eyes.mdl"))
return;
}
else if (e->drawflags & DRF_TRANSLUCENT) //hexen2
{
bef |= BEF_FORCETRANSPARENT;
e->shaderRGBAf[3] = r_wateralpha.value;
}
else if ((e->model->flags & EFH2_SPECIAL_TRANS)) //hexen2 flags.
{
//BEFIXME: this needs to generate the right sort of default instead
//(alpha blend+disable cull)
}
else if ((e->model->flags & EFH2_TRANSPARENT))
{
//BEFIXME: make sure the shader generator works
}
else if ((e->model->flags & EFH2_HOLEY))
{
//BEFIXME: this needs to generate the right sort of default instead
//(alpha test)
}
else if (e->shaderRGBAf[3] < 1 && cls.protocol != CP_QUAKE3)
bef |= BEF_FORCETRANSPARENT;
BE_SelectMode(rmode, bef);
qglPushMatrix();
R_RotateForEntity(e, clmodel);
inf = RMod_Extradata (clmodel);
if (qglPNTrianglesfATI && gl_ati_truform.ival)
qglEnable(GL_PN_TRIANGLES_ATI);
if (clmodel == cl.model_precache_vwep[0])
{
extern int cl_playerindex;
clmodel = cl.model_precache[cl_playerindex];
}
if (e->flags & Q2RF_WEAPONMODEL)
{
VectorCopy(currententity->origin, saveorg);
VectorCopy(r_refdef.vieworg, currententity->origin);
}
memset(&mesh, 0, sizeof(mesh));
for(surfnum=0; inf; ((inf->nextsurf)?(inf = (galiasinfo_t*)((char *)inf + inf->nextsurf)):(inf=NULL)), surfnum++)
{
needrecolour = Alias_GAliasBuildMesh(&mesh, inf, e, e->shaderRGBAf[3], nolightdir);
shader = currententity->forcedshader;
skin = GL_ChooseSkin(inf, clmodel->name, surfnum, e);
if (!shader)
shader = e->forcedshader?e->forcedshader:skin->shader;
if (shader)
{
if (skin && skin->shader)
shader = skin->shader;
else
{
shader = &reskinnedmodelshader;
skin = &shader->defaulttextures;
reskinnedmodelshader.numpasses = 1;
reskinnedmodelshader.passes[0].flags = 0;
reskinnedmodelshader.passes[0].numMergedPasses = 1;
reskinnedmodelshader.passes[0].anim_frames[0] = skin->base;
if (nolightdir || !mesh.normals_array || !mesh.colors4f_array)
{
reskinnedmodelshader.passes[0].rgbgen = RGB_GEN_IDENTITY_LIGHTING;
reskinnedmodelshader.passes[0].flags |= SHADER_PASS_NOCOLORARRAY;
}
else
reskinnedmodelshader.passes[0].rgbgen = RGB_GEN_LIGHTING_DIFFUSE;
reskinnedmodelshader.passes[0].alphagen = (e->shaderRGBAf[3]<1)?ALPHA_GEN_ENTITY:ALPHA_GEN_IDENTITY;
reskinnedmodelshader.passes[0].shaderbits |= SBITS_MISC_DEPTHWRITE;
reskinnedmodelshader.passes[0].blendmode = GL_MODULATE;
reskinnedmodelshader.passes[0].texgen = T_GEN_DIFFUSE;
b = BE_GetTempBatch();
if (!b)
break;
reskinnedmodelshader.flags = SHADER_CULL_FRONT;
}
b->buildmeshes = R_GAlias_DrawBatch;
b->ent = e;
b->mesh = NULL;
b->firstmesh = 0;
b->meshes = 1;
b->skin = skin;
b->texture = NULL;
b->shader = shader;
b->lightmap = surfnum;
b->next = batches[shader->sort];
batches[shader->sort] = b;
}
BE_DrawMesh_Single(shader, &mesh, NULL, skin);
}
if (e->flags & Q2RF_WEAPONMODEL)
VectorCopy(saveorg, currententity->origin);
if (qglPNTrianglesfATI && gl_ati_truform.ival)
qglDisable(GL_PN_TRIANGLES_ATI);
qglPopMatrix();
if (gl_affinemodels.value)
qglHint (GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);
if (e->flags & Q2RF_DEPTHHACK)
qglDepthRange (gldepthmin, gldepthmax);
BE_SelectMode(rmode, 0);
}
//returns the rotated offset of the two points in result
@ -1275,9 +1205,7 @@ void R_DrawGAliasShadowVolume(entity_t *e, vec3_t lightpos, float radius)
if (Length(lightorg) > radius + clmodel->radius)
return;
qglPushMatrix();
R_RotateForEntity(e, clmodel);
BE_SelectEntity(e);
inf = RMod_Extradata (clmodel);
while(inf)
@ -1295,8 +1223,6 @@ void R_DrawGAliasShadowVolume(entity_t *e, vec3_t lightpos, float radius)
else
inf = NULL;
}
qglPopMatrix();
}
#endif

File diff suppressed because it is too large Load Diff

View File

@ -412,7 +412,6 @@ TRACE(("dbg: GLDraw_ReInit: Allocating upload buffers\n"));
qglClearColor (1,0,0,0);
TRACE(("dbg: GLDraw_ReInit: PPL_LoadSpecularFragmentProgram\n"));
PPL_CreateShaderObjects();
GL_InitSceneProcessingShaders();
#ifdef PLUGINS

View File

@ -1251,10 +1251,10 @@ float Font_DrawScaleChar(float px, float py, float cw, float ch, unsigned int ch
if (c->texplane >= DEFAULTPLANE)
{
sx = ((px+c->left)*(int)vid.width) / (float)vid.pixelwidth;
sy = ((py+c->top)*(int)vid.height) / (float)vid.pixelheight;
sw = ((curfont->charheight*cw)*vid.width) / (float)vid.pixelwidth;
sh = ((curfont->charheight*ch)*vid.height) / (float)vid.pixelheight;
sx = ((px+c->left));//*(int)vid.width) / (float)vid.pixelwidth;
sy = ((py+c->top));//*(int)vid.height) / (float)vid.pixelheight;
sw = ((curfont->charheight*cw));//*vid.width) / (float)vid.pixelwidth;
sh = ((curfont->charheight*ch));//*vid.height) / (float)vid.pixelheight;
if (c->texplane == DEFAULTPLANE)
v = Font_BeginChar(fontplanes.defaultfont);
@ -1263,10 +1263,10 @@ float Font_DrawScaleChar(float px, float py, float cw, float ch, unsigned int ch
}
else
{
sx = ((px+c->left)*(int)vid.width) / (float)vid.pixelwidth;
sy = ((py+c->top)*(int)vid.height) / (float)vid.pixelheight;
sw = ((c->bmw*cw)*vid.width) / (float)vid.pixelwidth;
sh = ((c->bmh*ch)*vid.height) / (float)vid.pixelheight;
sx = ((px+c->left));//*(int)vid.width) / (float)vid.pixelwidth;
sy = ((py+c->top));//*(int)vid.height) / (float)vid.pixelheight;
sw = ((c->bmw*cw));//*vid.width) / (float)vid.pixelwidth;
sh = ((c->bmh*ch));//*vid.height) / (float)vid.pixelheight;
v = Font_BeginChar(fontplanes.texnum[c->texplane]);
}

View File

@ -270,12 +270,12 @@ unsigned int Heightmap_PointContentsHM(heightmap_t *hm, float clipmipsz, vec3_t
return FTECONTENTS_EMPTY;
}
unsigned int Heightmap_PointContents(model_t *model, vec3_t org)
unsigned int Heightmap_PointContents(model_t *model, vec3_t axis[3], vec3_t org)
{
heightmap_t *hm = model->terrain;
return Heightmap_PointContentsHM(hm, 0, org);
}
unsigned int Heightmap_NativeBoxContents(model_t *model, int hulloverride, int frame, vec3_t org, vec3_t mins, vec3_t maxs)
unsigned int Heightmap_NativeBoxContents(model_t *model, int hulloverride, int frame, vec3_t axis[3], vec3_t org, vec3_t mins, vec3_t maxs)
{
heightmap_t *hm = model->terrain;
return Heightmap_PointContentsHM(hm, mins[2], org);
@ -514,7 +514,7 @@ Heightmap_Trace
Traces a line through a heightmap, sampling the terrain at various different positions.
This is inprecise, only supports points (or vertical lines), and can often travel though sticky out bits of terrain.
*/
qboolean Heightmap_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace)
qboolean Heightmap_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace)
{
vec3_t org;
vec3_t dir;
@ -575,9 +575,9 @@ qboolean Heightmap_Trace(model_t *model, int forcehullnum, int frame, vec3_t sta
return trace->fraction != 1;
}
qboolean Heightmap_NativeTrace(struct model_s *model, int hulloverride, int frame, vec3_t p1, vec3_t p2, vec3_t mins, vec3_t maxs, unsigned int against, struct trace_s *trace)
qboolean Heightmap_NativeTrace(struct model_s *model, int hulloverride, int frame, vec3_t axis[3], vec3_t p1, vec3_t p2, vec3_t mins, vec3_t maxs, unsigned int against, struct trace_s *trace)
{
return Heightmap_Trace(model, hulloverride, frame, p1, p2, mins, maxs, trace);
return Heightmap_Trace(model, hulloverride, frame, axis, p1, p2, mins, maxs, trace);
}
#endif

View File

@ -497,7 +497,10 @@ model_t *RMod_LoadModel (model_t *mod, qboolean crash)
if (!strcmp(mod->name, "progs/player.mdl"))
mod->engineflags |= MDLF_PLAYER | MDLF_DOCRC;
else if (!strcmp(mod->name, "progs/flame.mdl") ||
!strcmp(mod->name, "progs/flame2.mdl"))
!strcmp(mod->name, "progs/flame2.mdl") ||
!strcmp(mod->name, "models/flame1.mdl") || //hexen2 small standing flame
!strcmp(mod->name, "models/flame2.mdl") || //hexen2 large standing flame
!strcmp(mod->name, "models/cflmtrch.mdl")) //hexen2 wall torch
mod->engineflags |= MDLF_FLAME;
else if (!strcmp(mod->name, "progs/bolt.mdl") ||
!strcmp(mod->name, "progs/bolt2.mdl") ||
@ -1114,9 +1117,9 @@ TRACE(("dbg: RMod_LoadTextures: inittexturedescs\n"));
if (gl_bump.ival<2) //set to 2 to have faster loading.
{
snprintf(altname, sizeof(altname)-1, "%s_norm", mt->name);
tn.bump = R_LoadReplacementTexture(altname, loadname, IF_NOALPHA|IF_NOGAMMA|IF_SUBDIRONLY);
tn.bump = R_LoadReplacementTexture(altname, loadname, IF_NOGAMMA|IF_SUBDIRONLY);
if (!TEXVALID(tn.bump))
tn.bump = R_LoadReplacementTexture(altname, "bmodels", IF_NOALPHA|IF_NOGAMMA);
tn.bump = R_LoadReplacementTexture(altname, "bmodels", IF_NOGAMMA);
}
if (!TEXVALID(tn.bump))
{
@ -2685,12 +2688,6 @@ static void Q1BSP_StainNode (mnode_t *node, float *parms)
#endif
}
void Q1BSP_MarkLights (dlight_t *light, int bit, mnode_t *node);
qboolean Q1BSP_Trace(model_t *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, trace_t *trace);
void GLQ1BSP_LightPointValues(model_t *model, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
void RMod_FixupNodeMinsMaxs (mnode_t *node, mnode_t *parent)
{
if (!node)
@ -3191,17 +3188,17 @@ void * RMod_LoadSpriteFrame (void * pin, mspriteframe_t **ppframe, int framenum,
{
size *= 4;
if (!TEXVALID(texnum))
texnum = R_LoadTexture32 (name, width, height, (unsigned *)(pinframe + 1), IF_NOGAMMA);
texnum = R_LoadTexture32 (name, width, height, (unsigned *)(pinframe + 1), IF_NOGAMMA|IF_CLAMP);
}
else if (version == SPRITEHL_VERSION)
{
if (!TEXVALID(texnum))
texnum = R_LoadTexture8Pal32 (name, width, height, (qbyte *)(pinframe + 1), (qbyte*)palette, IF_NOGAMMA);
texnum = R_LoadTexture8Pal32 (name, width, height, (qbyte *)(pinframe + 1), (qbyte*)palette, IF_NOGAMMA|IF_CLAMP);
}
else
{
if (!TEXVALID(texnum))
texnum = R_LoadTexture8 (name, width, height, (qbyte *)(pinframe + 1), IF_NOMIPMAP|IF_NOGAMMA, 1);
texnum = R_LoadTexture8 (name, width, height, (qbyte *)(pinframe + 1), IF_NOMIPMAP|IF_NOGAMMA|IF_CLAMP, 1);
}
Q_strncpyz(name, loadmodel->name, sizeof(name));

View File

@ -30,29 +30,22 @@ struct wedict_s;
struct model_s;
struct world_s;
typedef struct {
//deals with FTECONTENTS (assumes against solid)
void (*PurgeModel) (struct model_s *mod);
typedef enum {
SHADER_SORT_NONE,
SHADER_SORT_PORTAL,
SHADER_SORT_SKY,
SHADER_SORT_OPAQUE,
SHADER_SORT_DECAL,
SHADER_SORT_SEETHROUGH,
SHADER_SORT_BANNER,
SHADER_SORT_UNDERWATER,
SHADER_SORT_BLEND,
SHADER_SORT_ADDITIVE,
SHADER_SORT_NEAREST,
qboolean (*Trace) (struct model_s *model, int hulloverride, int frame, vec3_t p1, vec3_t p2, vec3_t mins, vec3_t maxs, struct trace_s *trace);
unsigned int (*PointContents) (struct model_s *model, vec3_t p);
unsigned int (*BoxContents) (struct model_s *model, int hulloverride, int frame, vec3_t p, vec3_t mins, vec3_t maxs);
//deals with whatever is native for the bsp (gamecode is expected to distinguish this).
qboolean (*NativeTrace) (struct model_s *model, int hulloverride, int frame, vec3_t p1, vec3_t p2, vec3_t mins, vec3_t maxs, unsigned int against, struct trace_s *trace);
unsigned int (*NativeContents)(struct model_s *model, int hulloverride, int frame, vec3_t p, vec3_t mins, vec3_t maxs);
unsigned int (*FatPVS) (struct model_s *model, vec3_t org, qbyte *pvsbuffer, unsigned int buffersize, qboolean merge);
qboolean (*EdictInFatPVS) (struct model_s *model, struct pvscache_s *edict, qbyte *pvsbuffer);
void (*FindTouchedLeafs) (struct model_s *model, struct pvscache_s *ent, vec3_t cullmins, vec3_t cullmaxs); //edict system as opposed to q2 game dll system.
void (*LightPointValues) (struct model_s *model, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
void (*StainNode) (struct mnode_s *node, float *parms);
void (*MarkLights) (struct dlight_s *light, int bit, struct mnode_s *node);
qbyte *(*LeafPVS) (struct model_s *model, int num, qbyte *buffer, unsigned int buffersize);
int (*LeafnumForPoint) (struct model_s *model, vec3_t point);
} modelfuncs_t;
SHADER_SORT_COUNT
} shadersort_t;
typedef struct mesh_s
{
@ -93,11 +86,17 @@ typedef struct batch_s
struct batch_s *next;
shader_t *shader;
struct texture_s *texture;
struct vbo_s *vbo;
int lightmap;
entity_t *ent;
struct texture_s *texture;
struct texnums_s *skin;
unsigned int maxmeshes;
vec3_t normal;
unsigned int flags;
void (*buildmeshes)(struct batch_s *b);
vec3_t normal; /*used only at load (for portal surfaces, so multiple planes are not part of the same batch)*/
} batch_t;
/*
@ -131,6 +130,32 @@ BRUSH MODELS
==============================================================================
*/
typedef struct {
//deals with FTECONTENTS (assumes against solid)
void (*PurgeModel) (struct model_s *mod);
qboolean (*Trace) (struct model_s *model, int hulloverride, int frame, vec3_t axis[3], vec3_t p1, vec3_t p2, vec3_t mins, vec3_t maxs, struct trace_s *trace);
unsigned int (*PointContents) (struct model_s *model, vec3_t axis[3], vec3_t p);
unsigned int (*BoxContents) (struct model_s *model, int hulloverride, int frame, vec3_t axis[3], vec3_t p, vec3_t mins, vec3_t maxs);
//deals with whatever is native for the bsp (gamecode is expected to distinguish this).
qboolean (*NativeTrace) (struct model_s *model, int hulloverride, int frame, vec3_t axis[3], vec3_t p1, vec3_t p2, vec3_t mins, vec3_t maxs, unsigned int against, struct trace_s *trace);
unsigned int (*NativeContents)(struct model_s *model, int hulloverride, int frame, vec3_t axis[3], vec3_t p, vec3_t mins, vec3_t maxs);
unsigned int (*FatPVS) (struct model_s *model, vec3_t org, qbyte *pvsbuffer, unsigned int buffersize, qboolean merge);
qboolean (*EdictInFatPVS) (struct model_s *model, struct pvscache_s *edict, qbyte *pvsbuffer);
void (*FindTouchedLeafs) (struct model_s *model, struct pvscache_s *ent, vec3_t cullmins, vec3_t cullmaxs); //edict system as opposed to q2 game dll system.
void (*LightPointValues) (struct model_s *model, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
void (*StainNode) (struct mnode_s *node, float *parms);
void (*MarkLights) (struct dlight_s *light, int bit, struct mnode_s *node);
qbyte *(*LeafPVS) (struct model_s *model, int num, qbyte *buffer, unsigned int buffersize);
int (*LeafnumForPoint) (struct model_s *model, vec3_t point);
} modelfuncs_t;
//
// in memory representation
@ -157,7 +182,7 @@ typedef struct mplane_s
qbyte pad[2];
} mplane_t;
typedef struct {
typedef struct texnums_s {
texid_t base;
texid_t bump;
texid_t upperoverlay;
@ -423,7 +448,9 @@ void Q1BSP_Init(void);
int Q1BSP_ClipDecal(vec3_t center, vec3_t normal, vec3_t tangent1, vec3_t tangent2, float size, float **out);
qboolean Q1BSP_Trace(struct model_s *model, int forcehullnum, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, struct trace_s *trace);
void Q1BSP_MarkLights (dlight_t *light, int bit, mnode_t *node);
void GLQ1BSP_LightPointValues(struct model_s *model, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
qboolean Q1BSP_Trace(struct model_s *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, struct trace_s *trace);
qboolean Q1BSP_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f, vec3_t p1, vec3_t p2, struct trace_s *trace);
unsigned int Q1BSP_FatPVS (struct model_s *mod, vec3_t org, qbyte *pvsbuffer, unsigned int buffersize, qboolean add);
qboolean Q1BSP_EdictInFatPVS(struct model_s *mod, struct pvscache_s *ent, qbyte *pvs);
@ -826,7 +853,7 @@ typedef struct model_s
char *entities;
void *terrain;
batch_t *batches;
batch_t *batches[SHADER_SORT_COUNT];
unsigned checksum;
unsigned checksum2;

View File

@ -37,9 +37,6 @@ extern int gl_canstencil;
FTEPFNGLCOMPRESSEDTEXIMAGE2DARBPROC qglCompressedTexImage2DARB;
FTEPFNGLGETCOMPRESSEDTEXIMAGEARBPROC qglGetCompressedTexImageARB;
#define Q2RF_WEAPONMODEL 4 // only draw through eyes
#define Q2RF_DEPTHHACK 16
entity_t r_worldentity;
vec3_t modelorg, r_entorigin;
@ -437,33 +434,10 @@ 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, model_t *mod)
void R_RotateForEntity (const entity_t *e, const model_t *mod)
{
float mv[16];
float m[16];
if (e->flags & Q2RF_WEAPONMODEL && r_refdef.currentplayernum>=0)
{ //rotate to view first
m[0] = cl.viewent[r_refdef.currentplayernum].axis[0][0];
m[1] = cl.viewent[r_refdef.currentplayernum].axis[0][1];
m[2] = cl.viewent[r_refdef.currentplayernum].axis[0][2];
m[3] = 0;
m[4] = cl.viewent[r_refdef.currentplayernum].axis[1][0];
m[5] = cl.viewent[r_refdef.currentplayernum].axis[1][1];
m[6] = cl.viewent[r_refdef.currentplayernum].axis[1][2];
m[7] = 0;
m[8] = cl.viewent[r_refdef.currentplayernum].axis[2][0];
m[9] = cl.viewent[r_refdef.currentplayernum].axis[2][1];
m[10] = cl.viewent[r_refdef.currentplayernum].axis[2][2];
m[11] = 0;
m[12] = cl.viewent[r_refdef.currentplayernum].origin[0];
m[13] = cl.viewent[r_refdef.currentplayernum].origin[1];
m[14] = cl.viewent[r_refdef.currentplayernum].origin[2];
m[15] = 1;
qglMultMatrixf(m);
}
m[0] = e->axis[0][0];
m[1] = e->axis[0][1];
@ -485,101 +459,72 @@ void R_RotateForEntity (entity_t *e, model_t *mod)
m[14] = e->origin[2];
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;
float z;
float escale;
escale = 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;
VectorScale((m+0), escale, (m+0));
VectorScale((m+4), escale, (m+4));
VectorScale((m+8), escale, (m+8));
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;
VectorScale((m+0), escale, (m+0));
VectorScale((m+4), escale, (m+4));
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;
VectorScale((m+8), escale, (m+8));
break;
}
switch(currententity->drawflags&SCALE_ORIGIN_MASKIN)
if (mod && (e->drawflags&SCALE_TYPE_MASKIN) != SCALE_TYPE_XYONLY)
{
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;
switch(e->drawflags&SCALE_ORIGIN_MASKIN)
{
case SCALE_ORIGIN_CENTER:
z = ((mod->maxs[2] + mod->mins[2]) * (1-escale))/2;
VectorMA((m+12), z, e->axis[2], (m+12));
break;
case SCALE_ORIGIN_BOTTOM:
VectorMA((m+12), mod->mins[2]*(1-escale), e->axis[2], (m+12));
break;
case SCALE_ORIGIN_TOP:
VectorMA((m+12), -mod->maxs[2], e->axis[2], (m+12));
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"))
else if (mod && !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);
/*resize eyes, to make them easier to see*/
m[14] -= (22 + 8);
VectorScale((m+0), 2, (m+0));
VectorScale((m+4), 2, (m+4));
VectorScale((m+8), 2, (m+8));
}
if (!ruleset_allow_larger_models.ival && mod->clampscale != 1)
if (mod && !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);
VectorScale((m+0), mod->clampscale, (m+0));
VectorScale((m+4), mod->clampscale, (m+4));
VectorScale((m+8), mod->clampscale, (m+8));
}
if (e->flags & Q2RF_WEAPONMODEL && r_refdef.currentplayernum>=0)
{
/*FIXME: no bob*/
float simpleview[16];
Matrix4_ModelViewMatrix(simpleview, vec3_origin, vec3_origin);
Matrix4_Multiply(simpleview, m, mv);
qglLoadMatrixf(mv);
}
else
{
Matrix4_Multiply(r_refdef.m_view, m, mv);
qglLoadMatrixf(mv);
}
}
@ -1027,8 +972,6 @@ void GLR_DrawEntitiesOnList (void)
switch (currententity->model->type)
{
case mod_alias:
if (r_refdef.flags & Q2RDF_NOWORLDMODEL || !cl.worldmodel || cl.worldmodel->type != mod_brush || cl.worldmodel->fromgame == fg_doom)
R_DrawGAliasModel (currententity, BEM_STANDARD);
break;
#ifdef HALFLIFEMODELS
@ -1038,8 +981,6 @@ void GLR_DrawEntitiesOnList (void)
#endif
case mod_brush:
if (!cl.worldmodel || cl.worldmodel->type != mod_brush || cl.worldmodel->fromgame == fg_doom)
PPL_BaseBModelTextures (currententity);
break;
case mod_sprite:
@ -1081,7 +1022,7 @@ void R_SetupGL (void)
x = r_refdef.vrect.x * vid.pixelwidth/(int)vid.width;
x2 = (r_refdef.vrect.x + r_refdef.vrect.width) * vid.pixelwidth/(int)vid.width;
y = (vid.height-r_refdef.vrect.y) * vid.pixelheight/(int)vid.height;
y2 = ((int)vid.height - (r_refdef.vrect.y + r_refdef.vrect.height)) * vid.pixelheight/(int)vid.height;
y2 = ((int)vid.height - (r_refdef.vrect.y + r_refdef.vrect.height)) * (int)vid.pixelheight/(int)vid.height;
// fudge around because of frac screen scale
if (x > 0)
@ -1186,6 +1127,8 @@ void R_RenderScene (void)
TRACE(("dbg: calling R_DrawWorld\n"));
Surf_DrawWorld (); // adds static entities to the list
}
else
BE_DrawNonWorld();
S_ExtraUpdate (); // don't let sound get messed up if going slow
@ -1333,7 +1276,7 @@ static void TransformDir(vec3_t in, vec3_t planea[3], vec3_t viewa[3], vec3_t re
VectorMA(result, d, viewa[i], result);
}
}
void R_DrawPortal(batch_t *batch)
void R_DrawPortal(batch_t *batch, batch_t *blist)
{
entity_t *view;
GLdouble glplane[4];
@ -1409,7 +1352,7 @@ void R_DrawPortal(batch_t *batch)
/*FIXME: the batch stuff should be done in renderscene*/
/*fixup the first mesh index*/
for (batch = cl.worldmodel->batches; batch; batch = batch->next)
for (batch = blist; batch; batch = batch->next)
{
batch->firstmesh = batch->meshes;
}
@ -1427,7 +1370,7 @@ void R_DrawPortal(batch_t *batch)
R_RenderScene();
qglDisable(GL_CLIP_PLANE0);
for (batch = cl.worldmodel->batches; batch; batch = batch->next)
for (batch = blist; batch; batch = batch->next)
{
batch->firstmesh = 0;
}

View File

@ -864,11 +864,11 @@ static void R_LoadRTLights(void)
VectorCopy(rgb, dl->color);
dl->die = 0;
dl->flags = flags|LFLAG_ALLOW_PPL;
if (*cubename)
/*if (*cubename)
{
dl->fov = 90;
dl->flags |= LFLAG_SHADOWMAP;
}
}*/
AngleVectors(angles, dl->axis[0], dl->axis[1], dl->axis[2]);
dl->style = style+1;

View File

@ -671,6 +671,35 @@ static void Shader_EntityMergable ( shader_t *shader, shaderpass_t *pass, char *
shader->flags |= SHADER_ENTITY_MERGABLE;
}
static void Shader_LoadProgram(shader_t *shader, char *vert, char *frag, int qrtype)
{
static char *permutationdefines[PERMUTATIONS] = {
"",
"#define BUMP\n",
"#define SPECULAR\n",
"#define SPECULAR\n#define BUMP\n",
"#define USEOFFSETMAPPING\n",
"#define USEOFFSETMAPPING\n#define BUMP\n",
"#define USEOFFSETMAPPING\n#define SPECULAR\n",
"#define USEOFFSETMAPPING\n#define SPECULAR\n#define BUMP\n"
};
int p;
if (!frag)
frag = vert;
for (p = 0; p < PERMUTATIONS; p++)
{
if (qrenderer != qrtype)
{
}
#ifdef GLQUAKE
else if (qrenderer == QR_OPENGL)
shader->programhandle[p].glsl = GLSlang_CreateProgram(permutationdefines[p], (char *)vert, (char *)frag);
#endif
}
}
static void Shader_SLProgramName (shader_t *shader, shaderpass_t *pass, char **ptr, int qrtype)
{
/*accepts:
@ -685,13 +714,6 @@ static void Shader_SLProgramName (shader_t *shader, shaderpass_t *pass, char **p
*/
void *vert, *frag;
char *token;
if (shader->programhandle.glsl)
{ //this allows fallbacks
token = Shader_ParseString ( ptr );
token = Shader_ParseString ( ptr );
return;
}
token = *ptr;
while (*token == ' ' || *token == '\t' || *token == '\r')
@ -709,7 +731,7 @@ static void Shader_SLProgramName (shader_t *shader, shaderpass_t *pass, char **p
else
{
token++;
vert = frag = token;
frag = token;
for (count = 1; *token; token++)
{
if (*token == '}')
@ -721,47 +743,39 @@ static void Shader_SLProgramName (shader_t *shader, shaderpass_t *pass, char **p
else if (*token == '{')
count++;
}
frag = BZ_Malloc(token - (char*)vert + 1);
memcpy(frag, vert, token-(char*)vert);
((char*)frag)[token-(char*)vert] = 0;
vert = frag;
vert = BZ_Malloc(token - (char*)frag + 1);
memcpy(vert, frag, token-(char*)frag);
((char*)vert)[token-(char*)frag] = 0;
frag = NULL;
*ptr = token+1;
if (qrenderer != qrtype)
{
}
#ifdef GLQUAKE
else if (qrenderer == QR_OPENGL)
shader->programhandle.glsl = GLSlang_CreateProgram("", (char *)vert, (char *)frag);
#endif
Shader_LoadProgram(shader, vert, frag, qrtype);
BZ_Free(vert);
frag = NULL;
vert = NULL;
return;
}
}
token = Shader_ParseString ( ptr );
FS_LoadFile(token, &vert);
token = Shader_ParseString ( ptr );
if (!*token)
frag = vert;
else
FS_LoadFile(token, &frag);
if (qrenderer != qrtype)
vert = Shader_ParseString(ptr);
if (!strcmp(vert, "default"))
{
extern char *defaultglsl2program;
frag = Shader_ParseString(ptr);
Shader_LoadProgram(shader, defaultglsl2program, defaultglsl2program, qrtype);
return;
}
#ifdef GLQUAKE
else if (vert && frag)
shader->programhandle.glsl = GLSlang_CreateProgram("", (char *)vert, (char *)frag);
#endif
FS_LoadFile(vert, &vert);
frag = Shader_ParseString(ptr);
if (!frag)
frag = NULL;
else
FS_LoadFile(frag, &frag);
Shader_LoadProgram(shader, vert, frag, qrtype);
if (vert)
{
if (frag == vert)
frag = NULL;
FS_FreeFile(vert);
}
if (frag)
FS_FreeFile(frag);
}
@ -777,13 +791,15 @@ static void Shader_HLSLProgramName (shader_t *shader, shaderpass_t *pass, char *
static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **ptr )
{
cvar_t *cv;
cvar_t *cv = NULL;
int specialint = 0;
float specialfloat = 0;
vec3_t specialvec = {0};
enum shaderprogparmtype_e parmtype = SP_BAD;
char *token;
qboolean silent = false;
int p;
qboolean foundone;
token = Shader_ParseString(ptr);
if (!Q_stricmp(token, "opt"))
@ -801,32 +817,24 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p
{
token = Shader_ParseSensString(ptr);
cv = Cvar_Get(token, "", 0, "GLSL Shader parameters");
if (cv)
{ //Cvar_Get returns null if the cvar is the name of a command
specialint = cv->ival;
specialfloat = cv->value;
}
if (!cv)
return;
parmtype = SP_CVARI;
}
else if (!Q_stricmp(token, "cvarf"))
{
token = Shader_ParseSensString(ptr);
cv = Cvar_Get(token, "", 0, "GLSL Shader parameters");
if (cv)
{ //Cvar_Get returns null if the cvar is the name of a command
specialint = cv->ival;
specialfloat = cv->value;
}
if (!cv)
return;
parmtype = SP_CVARF;
}
else if (!Q_stricmp(token, "cvar3f"))
{
token = Shader_ParseSensString(ptr);
cv = Cvar_Get(token, "", 0, "GLSL Shader parameters");
if (cv)
{
SCR_StringToRGB(cv->string, specialvec, 1);
}
if (!cv)
return;
parmtype = SP_CVAR3F;
}
else if (!Q_stricmp(token, "time"))
@ -858,42 +866,52 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p
if (qrenderer == QR_OPENGL)
{
unsigned int uniformloc;
if (!shader->programhandle.glsl)
if (!shader->programhandle[0].glsl)
{
Con_Printf("shader %s: param without program set\n", shader->name);
}
else if (shader->numprogparams == SHADER_PROGPARMS_MAX)
Con_Printf("shader %s: too many parms\n", shader->name);
else
{
GLSlang_UseProgram(shader->programhandle.glsl);
uniformloc = qglGetUniformLocationARB(shader->programhandle.glsl, token);
if (uniformloc == -1)
foundone = false;
shader->progparm[shader->numprogparams].type = parmtype;
for (p = 0; p < PERMUTATIONS; p++)
{
if (!silent)
Con_Printf("shader %s: param without uniform \"%s\"\n", shader->name, token);
}
else
{
switch(parmtype)
if (!shader->programhandle[p].glsl)
continue;
GLSlang_UseProgram(shader->programhandle[p].glsl);
uniformloc = qglGetUniformLocationARB(shader->programhandle[p].glsl, token);
shader->progparm[shader->numprogparams].handle[p] = uniformloc;
if (uniformloc != -1)
{
case SP_BAD:
break;
case SP_TEXTURE:
case SP_CVARI:
qglUniform1iARB(uniformloc, specialint);
break;
case SP_CVARF:
qglUniform1fARB(uniformloc, specialfloat);
break;
case SP_CVAR3F:
qglUniform3fvARB(uniformloc, 1, specialvec);
break;
default:
shader->progparm[shader->numprogparams].type = parmtype;
shader->progparm[shader->numprogparams].handle = uniformloc;
shader->numprogparams++;
break;
foundone = true;
switch(parmtype)
{
case SP_BAD:
foundone = false;
break;
case SP_TEXTURE:
shader->progparm[shader->numprogparams].ival = specialint;
break;
case SP_CVARF:
case SP_CVARI:
shader->progparm[shader->numprogparams].pval = cv;
break;
case SP_CVAR3F:
shader->progparm[shader->numprogparams].pval = cv;
qglUniform3fvARB(uniformloc, 1, specialvec);
break;
default:
break;
}
}
}
if (!foundone && !silent)
Con_Printf("shader %s: param without uniform \"%s\"\n", shader->name, token);
else
shader->numprogparams++;
GLSlang_UseProgram(0);
}
}
@ -1689,8 +1707,14 @@ void Shader_Free (shader_t *shader)
#ifdef GLQUAKE
if (qrenderer == QR_OPENGL)
if (shader->programhandle.glsl)
qglDeleteObjectARB(shader->programhandle.glsl);
{
int p;
for (p = 0; p < PERMUTATIONS; p++)
{
if (shader->programhandle[p].glsl)
GLSlang_DeleteObject(shader->programhandle[p].glsl);
}
}
#endif
memset(&shader->programhandle, 0, sizeof(shader->programhandle));
@ -2153,7 +2177,7 @@ void Shader_Finish (shader_t *s)
s->sort = SHADER_SORT_DECAL;
}
if (r_vertexlight.value && !s->programhandle.glsl)
if (r_vertexlight.value && !s->programhandle[0].glsl)
{
// do we have a lightmap pass?
pass = s->passes;
@ -2337,7 +2361,7 @@ done:;
s->flags &= ~SHADER_DEPTHWRITE;
}
if (s->programhandle.glsl)
if (s->programhandle[0].glsl)
{
if (!s->numpasses)
s->numpasses = 1;
@ -2452,6 +2476,37 @@ void Shader_DefaultBSPLM(char *shortname, shader_t *s, const void *args)
"}\n"
);
if (0&&!builtin && gl_config.arb_shader_objects)
{
builtin = (
"{\n"
"program default\n"
"param texture 0 tex_diffuse\n"
"param texture 1 tex_lightmap\n"
"param texture 2 tex_normalmap\n"
"param texture 3 tex_deluxmap\n"
"param texture 4 tex_fullbright\n"
"{\n"
"map $diffuse\n"
"tcgen base\n"
"}\n"
"{\n"
"map $lightmap\n"
"tcgen lightmap\n"
"}\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n"
"map $deluxmap\n"
"}\n"
"{\n"
"map $fullbright\n"
"}\n"
"}\n"
);
}
if (!builtin)
builtin = (
"{\n"

View File

@ -1347,7 +1347,8 @@ checkerror();
BE_DrawMesh_List(tex->shader, smesh->litsurfs[tno].count, smesh->litsurfs[tno].s, &tex->vbo, &tex->shader->defaulttextures);
}
BE_BaseEntShadowDepth();
BE_SelectMode(BEM_DEPTHONLY, 0);
BE_BaseEntTextures();
if (0)
{
@ -1621,7 +1622,6 @@ static void Sh_DrawEntLighting(dlight_t *light, vec3_t colour)
texture_t *tex;
shadowmesh_t *sm;
currententity = &r_worldentity;
sm = light->worldshadowmesh;
if (light->rebuildcache)
sm = &sh_tempshmesh;
@ -1659,8 +1659,7 @@ static void Sh_DrawBrushModelShadow(dlight_t *dl, entity_t *e)
RotateLightVector(e->axis, e->origin, dl->origin, lightorg);
qglPushMatrix();
R_RotateForEntity(e, e->model);
BE_SelectEntity(e);
GL_SelectVBO(0);
GL_SelectEBO(0);
@ -1736,7 +1735,6 @@ static void Sh_DrawBrushModelShadow(dlight_t *dl, entity_t *e)
}
qglEnd();
}
qglPopMatrix();
BE_PushOffsetShadow(false);
}
@ -1750,6 +1748,7 @@ static void Sh_DrawStencilLightShadows(dlight_t *dl, qbyte *lvis, qbyte *vvis, q
extern cvar_t gl_part_flame;
int i;
struct shadowmesh_s *sm;
entity_t *ent;
BE_PushOffsetShadow(false);
@ -1758,8 +1757,6 @@ static void Sh_DrawStencilLightShadows(dlight_t *dl, qbyte *lvis, qbyte *vvis, q
Sh_DrawBrushModelShadow(dl, &r_worldentity);
else
{
currententity = &r_worldentity;
//qglEnable(GL_POLYGON_OFFSET_FILL);
//qglPolygonOffset(shaderstate.curpolyoffset.factor, shaderstate.curpolyoffset.unit);
@ -1780,41 +1777,42 @@ static void Sh_DrawStencilLightShadows(dlight_t *dl, qbyte *lvis, qbyte *vvis, q
// draw sprites seperately, because of alpha blending
for (i=0 ; i<cl_numvisedicts ; i++)
{
currententity = &cl_visedicts[i];
ent = &cl_visedicts[i];
if (currententity->flags & (RF_NOSHADOW|Q2RF_BEAM))
if (ent->flags & (RF_NOSHADOW|Q2RF_BEAM))
continue;
{
if (currententity->keynum == dl->key && currententity->keynum)
if (ent->keynum == dl->key && ent->keynum)
continue;
}
if (!currententity->model)
if (!ent->model)
continue;
if (cls.allow_anyparticles || currententity->visframe) //allowed or static
if (cls.allow_anyparticles || ent->visframe) //allowed or static
{
if (currententity->model->engineflags & MDLF_ENGULPHS)
if (ent->model->engineflags & MDLF_ENGULPHS)
{
if (gl_part_flame.value)
continue;
}
}
switch (currententity->model->type)
switch (ent->model->type)
{
case mod_alias:
R_DrawGAliasShadowVolume (currententity, dl->origin, dl->radius);
R_DrawGAliasShadowVolume (ent, dl->origin, dl->radius);
break;
case mod_brush:
Sh_DrawBrushModelShadow (dl, currententity);
Sh_DrawBrushModelShadow (dl, ent);
break;
default:
break;
}
}
BE_SelectEntity(&r_worldentity);
}
//draws a light using stencil shadows.
@ -1881,7 +1879,7 @@ static qboolean Sh_DrawStencilLight(dlight_t *dl, vec3_t colour, qbyte *vvis)
BE_SelectMode(BEM_STENCIL, 0);
//The backend doesn't maintain scissor state.
qglEnable(GL_SCISSOR_TEST);
// qglEnable(GL_SCISSOR_TEST);
//The backend doesn't maintain stencil test state either - it needs to be active for more than just stencils, or disabled. its awkward.
qglEnable(GL_STENCIL_TEST);

View File

@ -579,7 +579,6 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
#endif
}
// glslang helper api function definitions
// type should be GL_FRAGMENT_SHADER_ARB or GL_VERTEX_SHADER_ARB
GLhandleARB GLSlang_CreateShader (char *precompilerconstants, char *shadersource, GLenum shadertype)
@ -588,34 +587,33 @@ GLhandleARB GLSlang_CreateShader (char *precompilerconstants, char *shadersource
GLint compiled;
char str[1024];
int loglen;
char *prstrings[4];
char *prstrings[3];
if (!precompilerconstants)
precompilerconstants = "";
prstrings[0] = "#define ENGINE_"DISTRIBUTION"\n";
switch (shadertype)
{
case GL_FRAGMENT_SHADER_ARB:
prstrings[0] = "#define FRAGMENT_SHADER\n";
prstrings[1] = "#define FRAGMENT_SHADER\n";
break;
case GL_VERTEX_SHADER_ARB:
prstrings[0] = "#define VERTEX_SHADER\n";
prstrings[1] = "#define VERTEX_SHADER\n";
break;
default:
prstrings[0] = "#define UNKNOWN_SHADER\n";
prstrings[1] = "#define UNKNOWN_SHADER\n";
break;
}
prstrings[1] = precompilerconstants;
prstrings[2] = shadersource;
prstrings[2] = precompilerconstants;
prstrings[3] = shadersource;
shader = qglCreateShaderObjectARB(shadertype);
qglShaderSourceARB(shader, 3, (const GLcharARB**)prstrings, NULL);
qglShaderSourceARB(shader, 4, (const GLcharARB**)prstrings, NULL);
qglCompileShaderARB(shader);
qglGetObjectParameterivARB(shader, GL_OBJECT_COMPILE_STATUS_ARB, &compiled);
if(!compiled)
{
Con_DPrintf("Shader source:\n%s%s%s\n", prstrings[0], prstrings[1], prstrings[2]);
Con_DPrintf("Shader source:\n%s%s%s\n", prstrings[0], prstrings[1], prstrings[2], prstrings[3]);
qglGetInfoLogARB(shader, sizeof(str), NULL, str);
qglDeleteObjectARB(shader);
switch (shadertype)
@ -641,7 +639,7 @@ GLhandleARB GLSlang_CreateShader (char *precompilerconstants, char *shadersource
qglGetInfoLogARB(shader, sizeof(str), NULL, str);
if (strstr(str, "WARNING"))
{
Con_Printf("Shader source:\n%s%s%s\n", prstrings[0], prstrings[1], prstrings[2]);
Con_Printf("Shader source:\n%s%s%s\n", prstrings[0], prstrings[1], prstrings[2], prstrings[3]);
Con_Printf("%s\n", str);
}
}
@ -678,24 +676,78 @@ GLhandleARB GLSlang_CreateProgramObject (GLhandleARB vert, GLhandleARB frag)
return program;
}
#if HASHPROGRAMS
struct compiledshaders_s
{
int uses;
char *consts;
char *vert;
char *frag;
GLhandleARB handle;
bucket_t buck;
};
bucket_t *compiledshadersbuckets[64];
static hashtable_t compiledshaderstable;
#endif
GLhandleARB GLSlang_CreateProgram(char *precompilerconstants, char *vert, char *frag)
{
GLhandleARB handle;
GLhandleARB vs;
GLhandleARB fs;
#if HASHPROGRAMS
unsigned int hashkey;
struct compiledshaders_s *cs;
#endif
if (!gl_config.arb_shader_objects)
return 0;
if (!precompilerconstants)
precompilerconstants = "";
#if HASHPROGRAMS
hashkey = Hash_Key(precompilerconstants, ~0) ^ Hash_Key(frag, ~0);
cs = Hash_GetKey(&compiledshaderstable, hashkey);
while(cs)
{
if (!strcmp(cs->consts, precompilerconstants))
if (!strcmp(cs->vert, vert))
if (!strcmp(cs->frag, frag))
{
cs->uses++;
return cs->handle;
}
cs = Hash_GetNextKey(&compiledshaderstable, hashkey, cs);
}
#endif
vs = GLSlang_CreateShader(precompilerconstants, vert, GL_VERTEX_SHADER_ARB);
fs = GLSlang_CreateShader(precompilerconstants, frag, GL_FRAGMENT_SHADER_ARB);
if (!vs || !fs)
{
//delete ignores 0s.
qglDeleteObjectARB(vs);
qglDeleteObjectARB(fs);
return 0;
}
return GLSlang_CreateProgramObject(vs, fs);
handle = 0;
else
handle = GLSlang_CreateProgramObject(vs, fs);
//delete ignores 0s.
qglDeleteObjectARB(vs);
qglDeleteObjectARB(fs);
#if HASHPROGRAMS
cs = Z_Malloc(sizeof(*cs) + strlen(precompilerconstants)+1+strlen(vert)+1+strlen(frag)+1);
cs->consts = (char*)(cs + 1);
cs->vert = cs->consts + strlen(precompilerconstants)+1;
cs->frag = cs->vert + strlen(vert)+1;
cs->handle = handle;
cs->uses = 1;
strcpy(cs->consts, precompilerconstants);
strcpy(cs->vert, vert);
strcpy(cs->frag, frag);
Hash_AddKey(&compiledshaderstable, hashkey, cs, &cs->buck);
#endif
return handle;
}
GLint GLSlang_GetUniformLocation (int prog, char *name)
@ -890,6 +942,10 @@ void GL_Init(void *(*getglfunction) (char *name))
if (qglDebugMessageCallbackAMD)
qglDebugMessageCallbackAMD(myGLDEBUGPROCAMD, NULL);
#endif
#if HASHPROGRAMS
Hash_InitTable(&compiledshaderstable, sizeof(compiledshadersbuckets)/Hash_BytesForBuckets(1), compiledshadersbuckets);
#endif
}
unsigned int d_8to24rgbtable[256];

View File

@ -467,6 +467,7 @@ static void GL_DrawSkySphere (batch_t *batch, shader_t *shader)
skydist=gl_skyboxdist.value;
skydist/=16;
BE_SelectEntity(&r_worldentity);
//scale sky sphere and place around view origin.
qglPushMatrix();
qglTranslatef(r_refdef.vieworg[0], r_refdef.vieworg[1], r_refdef.vieworg[2]);

View File

@ -62,9 +62,6 @@ void GLR_FrameTimeGraph (int frametime);
void GL_FlushSkinCache(void);
void GL_GAliasFlushSkinCache(void);
void PPL_CreateShaderObjects(void);
void PPL_BaseBModelTextures(entity_t *e);
// Function prototypes for the Texture Object Extension routines
typedef GLboolean (APIENTRY *ARETEXRESFUNCPTR)(GLsizei, const GLuint *,
const GLboolean *);
@ -314,7 +311,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, model_t *mod);
void R_RotateForEntity (const entity_t *e, const model_t *mod);
void GL_InitSceneProcessingShaders (void);
void GL_SetupSceneProcessingTextures (void);

View File

@ -61,7 +61,7 @@ vec_t CastRay (vec3_t p1, vec3_t p2)
trace_t trace;
vec3_t move;
lightmodel->funcs.Trace (lightmodel, 0, 0, p1, p2, vec3_origin, vec3_origin, &trace);
lightmodel->funcs.Trace (lightmodel, 0, 0, NULL, p1, p2, vec3_origin, vec3_origin, &trace);
if (trace.fraction < 1)
return -1;
@ -158,7 +158,7 @@ void LightLoadEntities(char *entstring)
for (i = 0; i < 256; i+=16)
{
v[2] = mapent->origin[2]-i;
cont = lightmodel->funcs.PointContents (lightmodel, v);
cont = lightmodel->funcs.PointContents (lightmodel, NULL, v);
if (cont & (FTECONTENTS_LAVA | FTECONTENTS_SLIME | FTECONTENTS_SOLID))
break;
}

View File

@ -18,20 +18,6 @@ typedef enum {
SHADER_2D
} shadertype_t;
typedef enum {
SHADER_SORT_NONE,
SHADER_SORT_PORTAL,
SHADER_SORT_SKY,
SHADER_SORT_OPAQUE,
SHADER_SORT_DECAL,
SHADER_SORT_SEETHROUGH,
SHADER_SORT_BANNER,
SHADER_SORT_UNDERWATER,
SHADER_SORT_BLEND,
SHADER_SORT_ADDITIVE,
SHADER_SORT_NEAREST
} shadersort_t;
typedef enum {
MF_NONE = 1<<0,
MF_NORMALS = 1<<1,
@ -243,6 +229,19 @@ typedef struct
texid_t nearbox_textures[6];
} skydome_t;
enum{
PERMUTATION_GENERIC = 0,
PERMUTATION_BUMPMAP = 1,
PERMUTATION_SPECULAR = 2,
PERMUTATION_BUMP_SPEC,
PERMUTATION_OFFSET = 4,
PERMUTATION_OFFSET_BUMP,
PERMUTATION_OFFSET_SPEC,
PERMUTATION_OFFSET_BUMP_SPEC,
PERMUTATIONS
};
typedef struct {
enum shaderprogparmtype_e {
SP_BAD,
@ -267,9 +266,15 @@ typedef struct {
SP_CVAR3F,
SP_TEXTURE
} type;
unsigned int handle;
unsigned int handle[PERMUTATIONS];
union
{
int ival;
void *pval;
};
} shaderprogparm_t;
typedef struct {
float factor;
float unit;
@ -318,7 +323,7 @@ struct shader_s
union {
int glsl;
} programhandle;
} programhandle[PERMUTATIONS];
int numprogparams;
shaderprogparm_t progparm[SHADER_PROGPARMS_MAX];
@ -393,9 +398,11 @@ void BE_SelectMode(backendmode_t mode, unsigned int flags);
Rules for using a list: Every mesh must be part of the same VBO, shader, lightmap, and must have the same pointers set*/
void BE_DrawMesh_List(shader_t *shader, int nummeshes, mesh_t **mesh, vbo_t *vbo, texnums_t *texnums);
void BE_DrawMesh_Single(shader_t *shader, mesh_t *meshchain, vbo_t *vbo, texnums_t *texnums);
batch_t *BE_GetTempBatch(void);
//Asks the backend to invoke DrawMeshChain for each surface, and to upload lightmaps as required
void BE_DrawWorld (qbyte *vis);
void BE_DrawNonWorld (void);
//called at init, force the display to the right defaults etc
void BE_Init(void);
@ -411,8 +418,6 @@ void BE_GenerateProgram(shader_t *shader);
#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
void BE_SetupForShadowMap(void);
//Called from shadowmapping code into backend
@ -424,6 +429,8 @@ void Sh_Shutdown(void);
void BE_BaseEntShadowDepth(void);
//Sets the given light+colour to be the current one that everything is to be lit/culled by.
void BE_SelectDLight(dlight_t *dl, vec3_t colour);
void BE_SelectEntity(entity_t *ent);
//Returns true if the mesh is not lit by the current light
qboolean BE_LightCullModel(vec3_t org, model_t *model);
#endif

View File

@ -0,0 +1,77 @@
#include <stdio.h>
#include <string.h>
char *effects[] =
{
"spikeset.cfg",
"faithful.cfg",
"highfps.cfg",
"minimal.cfg",
"h2part.cfg",
"tsshaft.cfg",
NULL
};
int main(void)
{
FILE *c, *h, *s;
char line[1024];
int i, j;
c = fopen("../client/r_partset.c", "wt");
h = fopen("../client/r_partset.h", "wt");
fprintf(c, "/*\nWARNING: THIS FILE IS GENERATED BY '"__FILE__"'.\nYOU SHOULD NOT EDIT THIS FILE BY HAND\n*/\n\n");
fprintf(c, "#include \"r_partset.h\"\n\n\n");
for (i = 0; effects[i]; i++)
{
s = fopen(effects[i], "rt");
*strchr(effects[i], '.') = 0;
fprintf(h, "extern char *particle_set_%s;\n", effects[i]);
if (i)
fprintf(c, "\n\n\n//////////////////////////////////////////////////////\n\n\n");
fprintf(c, "char *particle_set_%s =\n", effects[i]);
while(fgets(line, sizeof(line), s))
{
j = 0;
while (line[j] == ' ' || line[j] == '\t')
j++;
if ((line[j] == '/' && line[j] == '/') || line[j] == '\r' || line[j] == '\n')
{
while (line[j])
fputc(line[j++], c);
}
else
{
fputc('\"', c);
while (line[j] && line[j] != '\r' && line[j] != '\n')
{
if (line[j] == '\t')
fputc(' ', c);
else if (line[j] == '\"')
{
fputc('\\', c);
fputc(line[j], c);
}
else
fputc(line[j], c);
j++;
}
fputs("\\n\"\n", c);
}
}
fputs(";\n", c);
fclose(s);
}
fputs("#define R_PARTSET_BUILTINS ", h);
for (i = 0; effects[i]; i++)
{
fprintf(h, "{\"%s\", &particle_set_%s},", effects[i], effects[i]);
}
fputs("\n", h);
fclose(h);
fclose(c);
}

228
engine/partcfgs/h2part.cfg Normal file
View File

@ -0,0 +1,228 @@
r_part ce_white_smoke_05
{
model models/whtsmk1.spr 0 0 20 0.5
}
r_part ce_white_smoke_10
{
model models/whtsmk1.spr 0 0 10 0.5
}
r_part ce_white_smoke_15
{
model models/whtsmk1.spr 0 0 6.666 0.5
}
r_part ce_white_smoke_20
{
model models/whtsmk1.spr 0 0 5 0.5
}
r_part ce_white_smoke_50
{
model models/whtsmk1.spr 0 0 2 0.5
}
r_part ce_bluespark
{
model models/bspark.spr 0 0 20 1
}
r_part ce_yellowspark
{
model models/spark.spr 0 0 20 1
}
r_part ce_sm_circle_exp
{
model models/fcircle.spr 0 0 20 1
}
r_part ce_bg_circle_exp
{
model models/xplod29.spr 0 0 20 1
}
r_part ce_sm_white_flash
{
model models/sm_white.spr 0 0 20 1
}
r_part ce_white_flash
{
model models/gryspt.spr 0 0 20 0.4
}
r_part ce_yellowred_flash
{
model models/yr_flsh.spr 0 0 20 0.4
}
r_part ce_blue_flash
{
model models/bluflash.spr 0 0 20 0.4
}
r_part ce_sm_blue_flash
{
model models/sm_blue.spr 0 0 20 0.4
}
r_part ce_red_flash
{
model models/redspt.spr 0 0 20 0.4
}
r_part ce_sm_explosion
{
model models/sm_expld.spr 0 0 20 1
}
r_part ce_lg_explosion
{
model models/bg_expld.spr 0 0 20 1
}
r_part ce_floor_explosion
{
model models/fl_expld.spr 0 0 20 1
}
r_part ce_rider_death
{
}
r_part ce_blue_explosion
{
model models/xpspblue.spr 0 0 20 1
}
r_part ce_green_smoke_05
{
model models/grnsmk1.spr 0 0 20 0.5
}
r_part ce_green_smoke_10
{
model models/grnsmk1.spr 0 0 10 0.5
}
r_part ce_green_smoke_15
{
model models/grnsmk1.spr 0 0 6.666 0.5
}
r_part ce_green_smoke_20
{
model models/grnsmk1.spr 0 0 5 0.5
}
// ce_grey_smoke
r_part ce_grey_smoke_15
{
model models/grysmk1.spr 0 0 6.666 0.5
}
r_part ce_red_smoke
{
model models/redsmk1.spr 0 0 6.666 0.5
}
r_part ce_slow_white_smoke
{
model models/whtsmk1.spr 0 0 20 0.5
}
r_part ce_redspark
{
model models/rspark.spr 0 0 20 1
}
r_part ce_greenspark
{
model models/gspark.spr 0 0 20 1
}
r_part ce_telesmk1
{
model models/telesmk1.spr 0 0 15 1
}
r_part ce_telesmk2
{
model models/telesmk2.spr 0 0 15 1
}
r_part ce_icehit
{
model models/icehit.spr 0 0 20 0.5
}
r_part ce_medusa_hit
{
model models/medhit.spr 0 0 20 1
}
r_part ce_mezzo_reflect
{
model models/mezzoref.spr 0 0 20 1
}
r_part ce_floor_explosion2
{
model models/flrexpl2.spr 0 0 20 1
}
r_part ce_xbow_explosion
{
model models/xbowexpl.spr 0 0 20 1
}
r_part ce_new_explosion
{
model models/gen_expl.spr 0 0 20 1
}
r_part ce_magic_missile_explosion
{
model models/mm_explod.spr 0 0 20 1
}
// ce_ghost
r_part ce_bone_explosion
{
model models/bonexpld.spr 0 0 20 1
}
// ce_redcloud
r_part ce_teleporterpuffs
{
// model models/telesmk2.spr 0 0 20 1
}
// ce_teleporterbody
// ce_boneshard
// ce_boneshrapnel
r_part ce_flamestream
{
model models/flamestr.spr 0 0 20 1
}
// ce_snow,
// ce_gravitywell
r_part ce_bldrn_expl
{
model models/xplsn_1.spr 0 0 20 1
}
// ce_acid_muzzfl
r_part ce_acid_hit
{
model models/axplsn_2.spr 0 0 20 1
}
r_part ce_firewall_small
{
model models/firewal1.spr 0 0 20 1
}
r_part ce_firewall_medium
{
model models/firewal5.spr 0 0 20 1
}
r_part ce_firewall_large
{
model models/firewal4.spr 0 0 20 1
}
r_part ce_lball_expl
{
model models/Bluexp3.spr 0 0 20 1
}
r_part ce_acid_splat
{
model models/axplsn_1.spr 0 0 20 1
}
r_part ce_acid_expl
{
model models/axplsn_5.spr 0 0 20 1
}
r_part ce_fboom
{
model models/fboom.spr 0 0 20 1
}
// ce_chunk
r_part ce_bomb
{
model models/pow.spr 0 0 20 1
}
r_part ce_brn_bounce
{
model models/spark.spr 0 0 20 1
}
r_part ce_lshock
{
model models/vorpshok.mdl 0 0 20 1
}
// ce_flamewall
// ce_flamewall2
r_part ce_floor_explosion3
{
model models/biggy.spr 0 0 20 1
}

View File

@ -3,9 +3,27 @@
// and some others I probably forgot to mention
/////////////////////////////////////////////////
//rocket trails (derived from purplehaze's, with only minor tweeks)
r_part rocketsmoke
{
texture "particles/fteparticlefont.tga"
tcoords 97 97 191 191 256
step 8
scale 7.5
alpha 0.8
die 2
randomvel 3
rgb 10 10 10
blend modulate
spawnmode spiral
scalefactor 1
spawnvel 5
}
r_part rockettrail
{
texture "particles/smoke.tga"
texture "particles/fteparticlefont.tga"
tcoords 97 97 191 191 256
step 4
scale 30
alpha 0.3
@ -17,11 +35,13 @@ r_part rockettrail
gravity -25
scalefactor 1
assoc rocketsmoke
spawnvel 10
}
r_part t_rocket
{
texture "particles/rfire"
texture "particles/fteparticlefont.tga"
tcoords 97 97 191 191 256
step 2
scale 10
alpha 0.6
@ -34,24 +54,10 @@ r_part t_rocket
scaledelta -10
}
r_part rocketsmoke
{
texture "particles/rtrail"
step 8
scale 7.5
alpha 0.8
die 2
randomvel 3
rgb 10 10 10
blend modulate
spawnmode spiral
scalefactor 1
spawnvel 10
}
r_part rockettail
{
texture "particles/rtrail"
texture "particles/fteparticlefont.tga"
tcoords 97 97 191 191 256
step 7
scale 10
alpha 0.3
@ -65,7 +71,8 @@ r_part rockettail
r_part t_altrocket
{
texture "particles/rtrail"
texture "particles/fteparticlefont.tga"
tcoords 97 97 191 191 256
step 4
scale 10
alpha 0.3
@ -160,7 +167,8 @@ r_part te_railtrail
r_part shortfume
{
texture "particles/smoke"
texture "particles/fteparticlefont.tga"
tcoords 97 97 191 191 256
scale 15
scaledelta 20
alpha 0.5
@ -173,7 +181,8 @@ r_part shortfume
r_part t_grenade
{
texture "particles/smoke"
texture "particles/fteparticlefont.tga"
tcoords 97 97 191 191 256
step 24
scale 16
scaledelta 4
@ -191,7 +200,8 @@ r_part t_grenade
//cool's blood trails (cos they're cooler)
r_part t_gib
{
texture "particles/blood"
texture "particles/fteparticlefont.tga"
tcoords 1 1 63 63 256 2 64
step 32
scale 64
alpha 0.6
@ -209,7 +219,8 @@ r_part t_gib
r_part t_zomgib
{
texture "particles/blood"
texture "particles/fteparticlefont.tga"
tcoords 1 1 63 63 256 2 64
step 64
scale 64
alpha 0.6
@ -227,7 +238,8 @@ r_part t_zomgib
r_part t_tracer
{
texture "particles/tracer"
texture "particles/fteparticlefont.tga"
tcoords 1 97 95 191 256
scale 15
step 5
alpha 0.6
@ -241,7 +253,8 @@ r_part t_tracer
r_part t_tracer2
{
texture "particles/tracer"
texture "particles/fteparticlefont.tga"
tcoords 1 97 95 191 256
scale 15
step 5
alpha 0.6
@ -255,7 +268,8 @@ r_part t_tracer2
r_part t_tracer3
{
texture "particles/tracer"
texture "particles/fteparticlefont.tga"
tcoords 1 97 95 191 256
scale 10
scaledelta -10
step 5
@ -273,7 +287,8 @@ r_part t_tracer3
//qw blood
r_part te_lightningblood
{
texture "particles/bloodtrail"
texture "particles/fteparticlefont.tga"
tcoords 193 97 255 159 256
count 3
scale 20
alpha 0.4
@ -291,7 +306,8 @@ r_part te_lightningblood
//qw blood
r_part te_blood
{
texture "particles/blood"
texture "particles/fteparticlefont.tga"
tcoords 193 97 255 159 256
count 10
scale 10
alpha 0.3
@ -308,7 +324,8 @@ r_part te_blood
//nq blood
r_part pe_73
{
texture "particles/blood"
texture "particles/fteparticlefont.tga"
tcoords 193 97 255 159 256
count 1
scale 20
alpha 0.3
@ -327,7 +344,8 @@ r_part pe_73
r_part ember
{
count 1
texture "particles/explosion"
texture "particles/fteparticlefont.tga"
tcoords 97 97 191 191 256
rgb 255 128 76
alpha 0
scale 15
@ -338,20 +356,21 @@ r_part ember
blend add
randomvel 5
veladd 1
rampmode delta //fade it in then out.
ramp 0 0 0 -0.5 0
ramp 0 0 0 0.1 0
ramp 0 0 0 0.1 0
ramp 0 0 0 0.1 0
ramp 0 0 0 0.1 0
ramp 0 0 0 0.1 0
rampmode delta
ramp 0 0 0 -0.5 0
ramp 0 0 0 0.1 0
ramp 0 0 0 0.1 0
ramp 0 0 0 0.1 0
ramp 0 0 0 0.1 0
ramp 0 0 0 0.1 0
}
//the bits that fly off
r_part expgib
{
cliptype expgib
texture "particles/explosion"
texture "particles/fteparticlefont.tga"
tcoords 97 97 191 191 256
alpha 0
count 16
die 1
@ -366,7 +385,8 @@ r_part expgib
//the heart of the explosion
r_part te_explosion
{
texture "particles/explosion"
texture "particles/fteparticlefont.tga"
tcoords 97 97 191 191 256
count 1
scale 200
scalefactor 1
@ -380,7 +400,8 @@ r_part te_explosion
r_part gunshotsmoke
{
texture "particles/smoke"
texture "particles/fteparticlefont.tga"
tcoords 1 65 31 95 256 8 32
count 3
scale 25
scalefactor 1
@ -397,7 +418,8 @@ r_part gunshotsmoke
r_part te_gunshot
{
type texturedspark
texture "ball"
texture "particles/fteparticlefont.tga"
tcoords 1 65 31 95 256 8 32
count 3
scale 2
scalefactor 1
@ -416,7 +438,8 @@ r_part te_gunshot
r_part spikecore
{
texture "ball"
texture "particles/fteparticlefont.tga"
tcoords 1 97 95 191 256
count 1
scale 1
scalefactor 1
@ -446,7 +469,8 @@ r_part te_spike
r_part te_lavasplash
{
texture "default"
texture "particles/fteparticlefont.tga"
tcoords 129 1 191 63 256
count 654
scale 15
alpha 0.7
@ -465,7 +489,8 @@ r_part te_lavasplash
//two rings moving upwards, costs less
r_part teleportsplashdown
{
texture "textures/smoke"
texture "particles/fteparticlefont.tga"
tcoords 193 1 255 63 256
count 32
scale 32
scalefactor 1
@ -479,7 +504,8 @@ r_part teleportsplashdown
}
r_part te_teleportsplash
{
texture "textures/smoke"
texture "particles/fteparticlefont.tga"
tcoords 193 1 255 63 256
count 32
scale 32
scalefactor 1
@ -496,7 +522,8 @@ r_part te_teleportsplash
//flame effect
r_part cu_flame
{
texture "particles/flame"
texture "particles/fteparticlefont.tga"
tcoords 129 1 191 63 256
count 1024
scale 0.4
scalerand 6
@ -515,7 +542,8 @@ r_part cu_flame
//flame effect
r_part cu_torch
{
texture "particles/flame"
texture "particles/fteparticlefont.tga"
tcoords 129 1 191 63 256
count 256
scale 3
scalefactor 1
@ -532,7 +560,8 @@ r_part cu_torch
r_part explodesprite
{
texture "particles/flame"
texture "particles/fteparticlefont.tga"
tcoords 97 97 191 191 256
count 180
scale 70
scaledelta -140
@ -551,7 +580,8 @@ r_part explodesprite
//you'll probably never see this one
r_part ef_entityparticles
{
texture "j"
texture "particles/fteparticlefont.tga"
tcoords 1 97 95 191 256
count 1
scale 15
alpha 0.2
@ -564,7 +594,8 @@ r_part ef_entityparticles
// emp effect, based off of purplehaze's idea
r_part empshocktrail
{
texture "particles/spark"
texture "particles/fteparticlefont.tga"
tcoords 193 1 255 63 256
step 3.2
scale 3
alpha 0.7
@ -577,7 +608,8 @@ r_part empshocktrail
r_part empcore
{
texture "particles/flame"
texture "particles/fteparticlefont.tga"
tcoords 193 1 255 63 256
count 90
scale 55
scaledelta -110
@ -596,7 +628,8 @@ r_part empcore
r_part empflash
{
die 0.1
texture "particles/flash"
texture "particles/fteparticlefont.tga"
tcoords 193 1 255 63 256
alpha 1
count 1
scale 400
@ -610,7 +643,8 @@ r_part empflash
r_part te_tarexplosion
{
texture "particles/emp"
texture "particles/fteparticlefont.tga"
tcoords 1 97 95 191 256
count 120
scale 35
die 0.75
@ -619,11 +653,11 @@ r_part te_tarexplosion
rampmode delta
ramp -32 0 0 0
ramp -32 0 0 0
ramp -32 0 0 2
ramp -32 0 0 2
friction -0.9
blend add
spawnmode uniformcircle
spawnorg 24 0
spawnorg 24 0
spawnvel 280 0
scalefactor 1
emit empshocktrail
@ -633,7 +667,8 @@ r_part te_tarexplosion
r_part pe_default
{
texture "particles/quake"
texture "particles/fteparticlefont.tga"
tcoords 1 97 95 191 256
count 1
scale 4
veladd 15
@ -646,7 +681,8 @@ r_part pe_default
r_part pe_defaulttrail
{
texture "particles/quake"
texture "particles/fteparticlefont.tga"
tcoords 1 97 95 191 256
step 12
die 1
scale 10
@ -658,7 +694,8 @@ r_part pe_defaulttrail
r_part pe_pointfile
{
texture "particles/quake"
texture "particles/fteparticlefont.tga"
tcoords 1 97 95 191 256
count 1
scale 50
die 30

View File

@ -85,6 +85,34 @@ void *Hash_GetKey(hashtable_t *table, unsigned int key)
}
return NULL;
}
/*Does _NOT_ support items that are added with two names*/
void *Hash_GetNextKey(hashtable_t *table, unsigned int key, void *old)
{
unsigned int bucknum = key%table->numbuckets;
bucket_t *buck;
buck = table->bucket[bucknum];
while(buck)
{
if (buck->data == old) //found the old one
break;
buck = buck->next;
}
if (!buck)
return NULL;
buck = buck->next;//don't return old
while(buck)
{
if (buck->key.value == key)
return buck->data;
buck = buck->next;
}
return NULL;
}
/*Does _NOT_ support items that are added with two names*/
void *Hash_GetNext(hashtable_t *table, const char *name, void *old)
{
unsigned int bucknum = Hash_Key(name, table->numbuckets);
@ -94,12 +122,9 @@ void *Hash_GetNext(hashtable_t *table, const char *name, void *old)
while(buck)
{
if (!STRCMP(name, buck->key.string))
{
if (buck->data == old) //found the old one
if (buck->data == old) //found the old one
// if (!STRCMP(name, buck->key.string))
break;
}
buck = buck->next;
}
if (!buck)
@ -115,6 +140,7 @@ void *Hash_GetNext(hashtable_t *table, const char *name, void *old)
}
return NULL;
}
/*Does _NOT_ support items that are added with two names*/
void *Hash_GetNextInsensative(hashtable_t *table, const char *name, void *old)
{
unsigned int bucknum = Hash_KeyInsensative(name, table->numbuckets);
@ -124,9 +150,9 @@ void *Hash_GetNextInsensative(hashtable_t *table, const char *name, void *old)
while(buck)
{
if (!STRCMP(name, buck->key.string))
if (buck->data == old) //found the old one
{
if (buck->data == old) //found the old one
// if (!stricmp(name, buck->key.string))
break;
}
@ -138,7 +164,7 @@ void *Hash_GetNextInsensative(hashtable_t *table, const char *name, void *old)
buck = buck->next;//don't return old
while(buck)
{
if (!STRCMP(name, buck->key.string))
if (!stricmp(name, buck->key.string))
return buck->data;
buck = buck->next;

View File

@ -28,6 +28,7 @@ void *Hash_GetInsensative(hashtable_t *table, const char *name);
void *Hash_GetKey(hashtable_t *table, unsigned int key);
void *Hash_GetNext(hashtable_t *table, const char *name, void *old);
void *Hash_GetNextInsensative(hashtable_t *table, const char *name, void *old);
void *Hash_GetNextKey(hashtable_t *table, unsigned int key, void *old);
void *Hash_Add(hashtable_t *table, const char *name, void *data, bucket_t *buck);
void *Hash_AddInsensative(hashtable_t *table, const char *name, void *data, bucket_t *buck);
void Hash_Remove(hashtable_t *table, const char *name);

View File

@ -562,6 +562,7 @@ qboolean pp_root_decide(enum protocol_type *pt, union protocol_data *pd)
static sizebuf_t *writedest;
static client_t *cldest;
struct netprim_s *destprim;
static int majortype;
static int minortype;
static int protocollen;
@ -752,12 +753,12 @@ void NPP_NQFlush(void)
vec3_t org;
coorddata cd;
memcpy(&cd, &buffer[multicastpos+writedest->prim.coordsize*0], writedest->prim.coordsize);
org[0] = MSG_FromCoord(cd, writedest->prim.coordsize);
memcpy(&cd, &buffer[multicastpos+writedest->prim.coordsize*1], writedest->prim.coordsize);
org[1] = MSG_FromCoord(cd, writedest->prim.coordsize);
memcpy(&cd, &buffer[multicastpos+writedest->prim.coordsize*2], writedest->prim.coordsize);
org[2] = MSG_FromCoord(cd, writedest->prim.coordsize);
memcpy(&cd, &buffer[multicastpos+destprim->coordsize*0], destprim->coordsize);
org[0] = MSG_FromCoord(cd, destprim->coordsize);
memcpy(&cd, &buffer[multicastpos+destprim->coordsize*1], destprim->coordsize);
org[1] = MSG_FromCoord(cd, destprim->coordsize);
memcpy(&cd, &buffer[multicastpos+destprim->coordsize*2], destprim->coordsize);
org[2] = MSG_FromCoord(cd, destprim->coordsize);
SV_MulticastProtExt(org, multicasttype, pr_global_struct->dimension_send, requireextension, 0);
}
@ -791,7 +792,7 @@ void NPP_NQCheckDest(int dest)
NPP_NQFlush();
}
cldest = cl;
destprim = &cldest->netchan.message.prim;
}
else
{
@ -802,6 +803,7 @@ void NPP_NQCheckDest(int dest)
NPP_NQFlush();
}
writedest = ndest;
destprim = &writedest->prim;
}
}
void NPP_AddData(void *data, int len)
@ -852,7 +854,7 @@ void NPP_NQWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
case svc_temp_entity:
break;
case svc_setangle:
protocollen = sizeof(qbyte)*4;
protocollen = sizeof(qbyte) + destprim->anglesize*3;
break;
case svc_setview:
protocollen = sizeof(qbyte)*1 + sizeof(short);
@ -907,7 +909,7 @@ void NPP_NQWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
ignoreprotocol = true;
break;
case 51:
protocollen = 2;
protocollen = 3;
ignoreprotocol = true;
break;
default:
@ -922,7 +924,7 @@ void NPP_NQWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
switch(majortype)
{
case svc_sound:
protocollen = 5+writedest->prim.coordsize*3;
protocollen = 5+destprim->coordsize*3;
if (data & NQSND_VOLUME)
protocollen++;
if (data & NQSND_ATTENUATION)
@ -945,7 +947,7 @@ void NPP_NQWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
case TE_LIGHTNING3:
multicastpos=4;
multicasttype=MULTICAST_PHS;
protocollen = writedest->prim.coordsize*6+sizeof(short)+sizeof(qbyte)*2;
protocollen = destprim->coordsize*6+sizeof(short)+sizeof(qbyte)*2;
break;
case TE_GUNSHOT:
multicastpos=3;
@ -954,14 +956,14 @@ void NPP_NQWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
//emit it here and we don't need to remember to play with temp_entity later
NPP_AddData(&data, sizeof(qbyte));
data = 1;
protocollen = writedest->prim.coordsize*3+sizeof(qbyte)*3;
protocollen = destprim->coordsize*3+sizeof(qbyte)*3;
break;
case TE_EXPLOSION:
case TE_SPIKE:
case TE_SUPERSPIKE:
multicastpos=2;
multicasttype=MULTICAST_PHS_R;
protocollen = writedest->prim.coordsize*3+sizeof(qbyte)*2;
protocollen = destprim->coordsize*3+sizeof(qbyte)*2;
break;
case TE_TAREXPLOSION:
case TE_WIZSPIKE:
@ -970,25 +972,25 @@ void NPP_NQWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
case TE_TELEPORT:
multicastpos=2;
multicasttype=MULTICAST_PVS;
protocollen = writedest->prim.coordsize*3+sizeof(qbyte)*2;
protocollen = destprim->coordsize*3+sizeof(qbyte)*2;
break;
case TE_EXPLOSION3_NEH:
protocollen = sizeof(qbyte) + writedest->prim.coordsize*6;
protocollen = sizeof(qbyte) + destprim->coordsize*6;
ignoreprotocol = true;
break;
case TENQ_EXPLOSION2:
protocollen = sizeof(qbyte)*4 + writedest->prim.coordsize*3;
protocollen = sizeof(qbyte)*4 + destprim->coordsize*3;
multicastpos=2;
multicasttype=MULTICAST_PHS_R;
break;
case TE_EXPLOSIONSMALL2:
data = TE_EXPLOSION;
protocollen = sizeof(qbyte)*2 + writedest->prim.coordsize*3;
protocollen = sizeof(qbyte)*2 + destprim->coordsize*3;
multicastpos=2;
multicasttype=MULTICAST_PHS;
break;
case TE_RAILTRAIL:
protocollen = writedest->prim.coordsize*6+sizeof(qbyte)*1;
protocollen = destprim->coordsize*6+sizeof(qbyte)*1;
multicastpos=2;
multicasttype=MULTICAST_PHS;
break;
@ -1000,42 +1002,42 @@ void NPP_NQWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
case TEH2_STREAM_ICECHUNKS:
case TEH2_STREAM_GAZE:
case TEH2_STREAM_FAMINE:
protocollen = writedest->prim.coordsize*6+sizeof(short)+sizeof(qbyte)*(2+2);
protocollen = destprim->coordsize*6+sizeof(short)+sizeof(qbyte)*(2+2);
multicastpos = 8;
multicasttype=MULTICAST_PHS;
break;
case TEH2_STREAM_COLORBEAM:
protocollen = writedest->prim.coordsize*6+sizeof(short)+sizeof(qbyte)*(3+2);
protocollen = destprim->coordsize*6+sizeof(short)+sizeof(qbyte)*(3+2);
multicastpos = 8;
multicasttype=MULTICAST_PHS;
break;
case TEDP_FLAMEJET: //TE_FLAMEJET
protocollen = writedest->prim.coordsize*6 +sizeof(qbyte)*3;
protocollen = destprim->coordsize*6 +sizeof(qbyte)*3;
multicastpos = 2;
multicasttype=MULTICAST_PVS;
break;
case TEDP_TEI_G3:
protocollen = writedest->prim.coordsize*9+sizeof(qbyte)*2;
protocollen = destprim->coordsize*9+sizeof(qbyte)*2;
multicastpos = 2;
multicasttype=MULTICAST_PHS;
break;
case TEDP_SMOKE:
protocollen = writedest->prim.coordsize*6+sizeof(qbyte)*3;
protocollen = destprim->coordsize*6+sizeof(qbyte)*3;
multicastpos = 2;
multicasttype=MULTICAST_PHS;
break;
case TEDP_TEI_BIGEXPLOSION:
protocollen = writedest->prim.coordsize*3+sizeof(qbyte)*2;
protocollen = destprim->coordsize*3+sizeof(qbyte)*2;
multicastpos = 2;
multicasttype=MULTICAST_PHS;
break;
case TEDP_TEI_PLASMAHIT:
protocollen = writedest->prim.coordsize*6+sizeof(qbyte)*3;
protocollen = destprim->coordsize*6+sizeof(qbyte)*3;
multicastpos = 2;
multicasttype=MULTICAST_PHS;
break;
@ -1150,31 +1152,28 @@ void NPP_NQWriteAngle(int dest, float in) //replacement write func (nq to qw)
Con_Printf("NQWriteAngle: Messages should start with WriteByte\n");
#ifdef NQPROT
if (dest == MSG_ONE)
if (cldest)
{
client_t *cl = Write_GetClient();
if (!cl)
{
Con_Printf("msg_entity: not a client\n");
if (cldest->protocol == SCP_BAD)
return;
}
else
else if (!ISQWCLIENT(cldest))
{
if (cl->protocol == SCP_BAD)
return;
else if (!ISQWCLIENT(cl))
{
ClientReliableCheckBlock(cl, sizeof(char));
ClientReliableWrite_Angle(cl, in);
return;
}
ClientReliableCheckBlock(cldest, sizeof(char));
ClientReliableWrite_Angle(cldest, in);
return;
}
}
else
MSG_WriteAngle (NQWriteDest(dest), in);
#endif
NPP_AddData(&data, sizeof(char));
if (destprim->anglesize==2)
{
coorddata cd = MSG_ToAngle(in, destprim->anglesize);
NPP_AddData(&cd.b2, sizeof(cd.b2));
}
else
NPP_AddData(&data, sizeof(char));
NPP_NQCheckFlush();
}
void NPP_NQWriteCoord(int dest, float in) //replacement write func (nq to qw)
@ -1210,7 +1209,7 @@ void NPP_NQWriteCoord(int dest, float in) //replacement write func (nq to qw)
MSG_WriteCoord (NQWriteDest(dest), in);
#endif
if (writedest->prim.coordsize==4)
if (destprim->coordsize==4)
{
dataf = LittleFloat(dataf);
NPP_AddData(&dataf, sizeof(float));
@ -1496,7 +1495,7 @@ void NPP_QWFlush(void)
NPP_AddData(&svc, sizeof(qbyte));
for (i = 0; i < 3; i++)
{
if (writedest->prim.coordsize == 4)
if (destprim->coordsize == 4)
NPP_AddData(&org[i], sizeof(float));
else
{
@ -1554,12 +1553,12 @@ void NPP_QWFlush(void)
vec3_t org;
coorddata cd;
memcpy(&cd, &buffer[multicastpos+writedest->prim.coordsize*0], writedest->prim.coordsize);
org[0] = MSG_FromCoord(cd, writedest->prim.coordsize);
memcpy(&cd, &buffer[multicastpos+writedest->prim.coordsize*1], writedest->prim.coordsize);
org[1] = MSG_FromCoord(cd, writedest->prim.coordsize);
memcpy(&cd, &buffer[multicastpos+writedest->prim.coordsize*2], writedest->prim.coordsize);
org[2] = MSG_FromCoord(cd, writedest->prim.coordsize);
memcpy(&cd, &buffer[multicastpos+destprim->coordsize*0], destprim->coordsize);
org[0] = MSG_FromCoord(cd, destprim->coordsize);
memcpy(&cd, &buffer[multicastpos+destprim->coordsize*1], destprim->coordsize);
org[1] = MSG_FromCoord(cd, destprim->coordsize);
memcpy(&cd, &buffer[multicastpos+destprim->coordsize*2], destprim->coordsize);
org[2] = MSG_FromCoord(cd, destprim->coordsize);
qwsize = sv.multicast.cursize;
sv.multicast.cursize = 0;
@ -1608,6 +1607,7 @@ void NPP_QWCheckDest(int dest)
NPP_QWFlush();
}
writedest = ndest;
destprim = &writedest->prim;
}
}
@ -1649,7 +1649,7 @@ void NPP_QWWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
case svc_temp_entity:
break;
case svc_setangle:
protocollen = sizeof(qbyte)*4;
protocollen = sizeof(qbyte) + destprim->anglesize*3;
break;
case svc_setview:
protocollen = sizeof(qbyte)*1 + sizeof(short);
@ -1730,13 +1730,13 @@ void NPP_QWWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
case TE_LIGHTNING3:
multicastpos=4;
multicasttype=MULTICAST_PHS;
protocollen = writedest->prim.coordsize*6+sizeof(short)+sizeof(qbyte)*2;
protocollen = destprim->coordsize*6+sizeof(short)+sizeof(qbyte)*2;
break;
case TEQW_BLOOD: //needs to be converted to a particle
case TE_GUNSHOT: //needs qbyte 2 removed
multicastpos=3;
multicasttype=MULTICAST_PVS;
protocollen = writedest->prim.coordsize*3+sizeof(qbyte)*3;
protocollen = destprim->coordsize*3+sizeof(qbyte)*3;
break;
case TEQW_LIGHTNINGBLOOD:
case TE_EXPLOSION:
@ -1744,7 +1744,7 @@ void NPP_QWWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
case TE_SUPERSPIKE:
multicastpos=2;
multicasttype=MULTICAST_PHS_R;
protocollen = writedest->prim.coordsize*3+sizeof(qbyte)*2;
protocollen = destprim->coordsize*3+sizeof(qbyte)*2;
break;
case TE_TAREXPLOSION:
case TE_WIZSPIKE:
@ -1753,12 +1753,12 @@ void NPP_QWWriteByte(int dest, qbyte data) //replacement write func (nq to qw)
case TE_TELEPORT:
multicastpos=2;
multicasttype=MULTICAST_PVS;
protocollen = writedest->prim.coordsize*3+sizeof(qbyte)*2;
protocollen = destprim->coordsize*3+sizeof(qbyte)*2;
break;
case TE_RAILTRAIL:
multicastpos=1;
multicasttype=MULTICAST_PVS;
protocollen = writedest->prim.coordsize*3+sizeof(qbyte)*1;
protocollen = destprim->coordsize*3+sizeof(qbyte)*1;
break;
default:
protocollen = sizeof(buffer);
@ -1823,7 +1823,7 @@ void NPP_QWWriteLong(int dest, long data) //replacement write func (nq to qw)
}
void NPP_QWWriteAngle(int dest, float in) //replacement write func (nq to qw)
{
if (writedest->prim.anglesize==1)
if (destprim->anglesize==1)
{
char data = (int)(in*256/360) & 255;
NPP_QWWriteChar(dest, data);
@ -1836,7 +1836,7 @@ void NPP_QWWriteAngle(int dest, float in) //replacement write func (nq to qw)
}
void NPP_QWWriteCoord(int dest, float in) //replacement write func (nq to qw)
{
if (writedest->prim.coordsize==4)
if (destprim->coordsize==4)
{
NPP_QWWriteFloat(dest, in);
}

View File

@ -674,8 +674,8 @@ void PR_LoadGlabalStruct(void)
SV_QCStatName(ev_float, "cnt_invincibility", STAT_H2_CNT_INVINCIBILITY);
SV_QCStatName(ev_float, "artifact_active", STAT_H2_ARTIFACT_ACTIVE);
SV_QCStatName(ev_float, "artifact_low", STAT_H2_ARTIFACT_LOW);
SV_QCStatName(ev_float, "movetype", STAT_H2_MOVETYPE);
SV_QCStatName(ev_entity, "cameramode", STAT_H2_CAMERAMODE);
SV_QCStatName(ev_float, "movetype", STAT_H2_MOVETYPE); /*normally used to change the roll when flying*/
SV_QCStatName(ev_entity, "cameramode", STAT_H2_CAMERAMODE); /*locks view in place when set*/
SV_QCStatName(ev_float, "hasted", STAT_H2_HASTED);
SV_QCStatName(ev_float, "inventory", STAT_H2_INVENTORY);
SV_QCStatName(ev_float, "rings_active", STAT_H2_RINGS_ACTIVE);
@ -699,8 +699,7 @@ void PR_LoadGlabalStruct(void)
SV_QCStatName(ev_string, "puzzle_inv8", STAT_H2_PUZZLE8);
SV_QCStatName(ev_float, "max_health", STAT_H2_MAXHEALTH);
SV_QCStatName(ev_float, "max_mana", STAT_H2_MAXMANA);
SV_QCStatName(ev_float, "flags", STAT_H2_FLAGS);
SV_QCStatName(ev_float, "playerclass", STAT_H2_PLAYERCLASS);
SV_QCStatName(ev_float, "flags", STAT_H2_FLAGS); /*to show the special abilities on the sbar*/
SV_QCStatPtr(ev_integer, &h2infoplaque[0], STAT_H2_OBJECTIVE1);
SV_QCStatPtr(ev_integer, &h2infoplaque[1], STAT_H2_OBJECTIVE2);
@ -1073,6 +1072,7 @@ void PR_Init(void)
#endif
}
void SV_RegisterH2CustomTents(void);
void Q_InitProgs(void)
{
int i, i2;
@ -1430,6 +1430,8 @@ void Q_InitProgs(void)
sv.world.edict_size = PR_InitEnts(svprogfuncs, sv.world.max_edicts);
SV_RegisterH2CustomTents();
#ifdef USEODE
World_Physics_Start(&sv.world);
#endif
@ -1780,6 +1782,92 @@ static void SV_Effect(vec3_t org, int mdlidx, int startframe, int endframe, int
}
static int SV_CustomTEnt_Register(char *effectname, int nettype, float *stain_rgb, float stain_radius, float *dl_rgb, float dl_radius, float dl_time, float *dl_fade)
{
int i;
for (i = 0; i < 255; i++)
{
if (!*sv.customtents[i].particleeffecttype)
break;
if (!strcmp(effectname, sv.customtents[i].particleeffecttype))
break;
}
if (i == 255)
{
Con_Printf("Too many custom effects\n");
return -1;
}
Q_strncpyz(sv.customtents[i].particleeffecttype, effectname, sizeof(sv.customtents[i].particleeffecttype));
sv.customtents[i].netstyle = nettype;
if (nettype & CTE_STAINS)
{
VectorCopy(stain_rgb, sv.customtents[i].stain);
sv.customtents[i].radius = stain_radius;
}
if (nettype & CTE_GLOWS)
{
sv.customtents[i].dlightrgb[0] = dl_rgb[0]*255;
sv.customtents[i].dlightrgb[1] = dl_rgb[1]*255;
sv.customtents[i].dlightrgb[2] = dl_rgb[2]*255;
sv.customtents[i].dlightradius = dl_radius/4;
sv.customtents[i].dlighttime = dl_time*16;
if (nettype & CTE_CHANNELFADE)
{
sv.customtents[i].dlightcfade[0] = dl_fade[0]*64;
sv.customtents[i].dlightcfade[1] = dl_fade[1]*64;
sv.customtents[i].dlightcfade[2] = dl_fade[2]*64;
}
}
return i;
}
static void SV_CustomTEnt_Spawn(int index, float *org, float *org2, int count, float *dir)
{
int type;
if (index < 0 || index >= 255)
return;
MSG_WriteByte(&sv.multicast, svcfte_customtempent);
MSG_WriteByte(&sv.multicast, index);
MSG_WriteCoord(&sv.multicast, org[0]);
MSG_WriteCoord(&sv.multicast, org[1]);
MSG_WriteCoord(&sv.multicast, org[2]);
type = sv.customtents[index].netstyle;
if (type & CTE_ISBEAM)
{
MSG_WriteCoord(&sv.multicast, org2[0]);
MSG_WriteCoord(&sv.multicast, org2[1]);
MSG_WriteCoord(&sv.multicast, org2[2]);
}
else
{
if (type & CTE_CUSTOMCOUNT)
{
MSG_WriteByte(&sv.multicast, count);
}
if (type & CTE_CUSTOMVELOCITY)
{
MSG_WriteCoord(&sv.multicast, dir[0]);
MSG_WriteCoord(&sv.multicast, dir[1]);
MSG_WriteCoord(&sv.multicast, dir[2]);
}
else if (type & CTE_CUSTOMDIRECTION)
{
vec3_t norm;
VectorNormalize2(dir, norm);
MSG_WriteDir(&sv.multicast, norm);
}
}
SV_MulticastProtExt (org, MULTICAST_PVS, pr_global_struct->dimension_send, PEXT_CUSTOMTEMPEFFECTS, 0); //now send the new multicast to all that will.
}
int externcallsdepth;
void PR_MoveParms(int progs1, int progs2); //from 2 to 1
@ -2258,7 +2346,7 @@ centerprint(clientent, value)
*/
void PF_centerprint_Internal (int entnum, qboolean plaque, char *s)
{
client_t *cl, *sp;
client_t *cl;
int slen;
#ifdef SERVER_DEMO_PLAYBACK
@ -7142,8 +7230,414 @@ void PF_h2updateinfoplaque(progfuncs_t *prinst, struct globalvars_s *pr_globals)
else
h2infoplaque[idx/32] ^= 1<<(idx&31);
}
enum
{
ce_none,
ce_rain,
ce_fountain,
ce_quake,
ce_white_smoke,
ce_bluespark,
ce_yellowspark,
ce_sm_circle_exp,
ce_bg_circle_exp,
ce_sm_white_flash,
ce_white_flash = 10,
ce_yellowred_flash,
ce_blue_flash,
ce_sm_blue_flash,
ce_red_flash,
ce_sm_explosion,
ce_lg_explosion,
ce_floor_explosion,
ce_rider_death,
ce_blue_explosion,
ce_green_smoke = 20,
ce_grey_smoke,
ce_red_smoke,
ce_slow_white_smoke,
ce_redspark,
ce_greenspark,
ce_telesmk1,
ce_telesmk2,
ce_icehit,
ce_medusa_hit,
ce_mezzo_reflect = 30,
ce_floor_explosion2,
ce_xbow_explosion,
ce_new_explosion,
ce_magic_missile_explosion,
ce_ghost,
ce_bone_explosion,
ce_redcloud,
ce_teleporterpuffs,
ce_teleporterbody,
ce_boneshard = 40,
ce_boneshrapnel,
ce_flamestream,
ce_snow,
ce_gravitywell,
ce_bldrn_expl,
ce_acid_muzzfl,
ce_acid_hit,
ce_firewall_small,
ce_firewall_medium,
ce_firewall_large = 50,
ce_lball_expl,
ce_acid_splat,
ce_acid_expl,
ce_fboom,
ce_chunk,
ce_bomb,
ce_brn_bounce,
ce_lshock,
ce_flamewall,
ce_flamewall2 = 60,
ce_floor_explosion3,
ce_onfire,
/*internal effects, here for indexes*/
ce_teleporterbody_1, /*de-sheeped*/
ce_white_smoke_05,
ce_white_smoke_10,
ce_white_smoke_15,
ce_white_smoke_20,
ce_white_smoke_50,
ce_green_smoke_05,
ce_green_smoke_10,
ce_green_smoke_15,
ce_green_smoke_20,
ce_grey_smoke_15,
ce_grey_smoke_100,
ce_max
};
int h2customtents[ce_max];
void SV_RegisterH2CustomTents(void)
{
int i;
for (i = 0; i < ce_max; i++)
h2customtents[i] = -1;
if (progstype == PROG_H2)
{
// ce_rain
// ce_fountain
h2customtents[ce_quake] = SV_CustomTEnt_Register("ce_quake", 0, NULL, 0, NULL, 0, 0, NULL);
// ce_white_smoke
h2customtents[ce_bluespark] = SV_CustomTEnt_Register("ce_bluespark", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_yellowspark] = SV_CustomTEnt_Register("ce_yellowspark", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_sm_circle_exp] = SV_CustomTEnt_Register("ce_sm_circle_exp", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_bg_circle_exp] = SV_CustomTEnt_Register("ce_bg_circle_exp", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_sm_white_flash] = SV_CustomTEnt_Register("ce_sm_white_flash", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_white_flash] = SV_CustomTEnt_Register("ce_white_flash", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_yellowred_flash] = SV_CustomTEnt_Register("ce_yellowred_flash", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_blue_flash] = SV_CustomTEnt_Register("ce_blue_flash", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_sm_blue_flash] = SV_CustomTEnt_Register("ce_sm_blue_flash", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_red_flash] = SV_CustomTEnt_Register("ce_red_flash", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_sm_explosion] = SV_CustomTEnt_Register("ce_sm_explosion", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_lg_explosion] = SV_CustomTEnt_Register("ce_lg_explosion", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_floor_explosion] = SV_CustomTEnt_Register("ce_floor_explosion", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_rider_death] = SV_CustomTEnt_Register("ce_rider_death", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_blue_explosion] = SV_CustomTEnt_Register("ce_blue_explosion", 0, NULL, 0, NULL, 0, 0, NULL);
// ce_green_smoke
// ce_grey_smoke
h2customtents[ce_red_smoke] = SV_CustomTEnt_Register("ce_red_smoke", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_slow_white_smoke] = SV_CustomTEnt_Register("ce_slow_white_smoke", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_redspark] = SV_CustomTEnt_Register("ce_redspark", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_greenspark] = SV_CustomTEnt_Register("ce_greenspark", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_telesmk1] = SV_CustomTEnt_Register("ce_telesmk1", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_telesmk2] = SV_CustomTEnt_Register("ce_telesmk2", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_icehit] = SV_CustomTEnt_Register("ce_icehit", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_medusa_hit] = SV_CustomTEnt_Register("ce_medusa_hit", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_mezzo_reflect] = SV_CustomTEnt_Register("ce_mezzo_reflect", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_floor_explosion2] = SV_CustomTEnt_Register("ce_floor_explosion2", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_xbow_explosion] = SV_CustomTEnt_Register("ce_xbow_explosion", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_new_explosion] = SV_CustomTEnt_Register("ce_new_explosion", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_magic_missile_explosion] = SV_CustomTEnt_Register("ce_magic_missile_explosion", 0, NULL, 0, NULL, 0, 0, NULL);
// ce_ghost
h2customtents[ce_bone_explosion] = SV_CustomTEnt_Register("ce_bone_explosion", 0, NULL, 0, NULL, 0, 0, NULL);
// ce_redcloud
h2customtents[ce_teleporterpuffs] = SV_CustomTEnt_Register("ce_teleporterpuffs", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_teleporterbody] = SV_CustomTEnt_Register("ce_teleporterbody", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
// ce_boneshard
// ce_boneshrapnel
h2customtents[ce_flamestream] = SV_CustomTEnt_Register("ce_flamestream", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
// ce_snow,
h2customtents[ce_gravitywell] = SV_CustomTEnt_Register("ce_gravitywell", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_bldrn_expl] = SV_CustomTEnt_Register("ce_bldrn_expl", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_acid_muzzfl] = SV_CustomTEnt_Register("ce_acid_muzzfl", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_acid_hit] = SV_CustomTEnt_Register("ce_acid_hit", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_firewall_small] = SV_CustomTEnt_Register("ce_firewall_small", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_firewall_medium] = SV_CustomTEnt_Register("ce_firewall_medium", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_firewall_large] = SV_CustomTEnt_Register("ce_firewall_large", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_lball_expl] = SV_CustomTEnt_Register("ce_lball_expl", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_acid_splat] = SV_CustomTEnt_Register("ce_acid_splat", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_acid_expl] = SV_CustomTEnt_Register("ce_acid_expl", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_fboom] = SV_CustomTEnt_Register("ce_fboom", 0, NULL, 0, NULL, 0, 0, NULL);
// ce_chunk
h2customtents[ce_bomb] = SV_CustomTEnt_Register("ce_bomb", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_brn_bounce] = SV_CustomTEnt_Register("ce_brn_bounce", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_lshock] = SV_CustomTEnt_Register("ce_lshock", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_flamewall] = SV_CustomTEnt_Register("ce_flamewall", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_flamewall2] = SV_CustomTEnt_Register("ce_flamewall2", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_floor_explosion3] = SV_CustomTEnt_Register("ce_floor_explosion3", 0, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_onfire] = SV_CustomTEnt_Register("ce_onfire", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_teleporterbody_1] = SV_CustomTEnt_Register("ce_teleporterbody_1", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_white_smoke_05] = SV_CustomTEnt_Register("ce_white_smoke_05", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_white_smoke_10] = SV_CustomTEnt_Register("ce_white_smoke_10", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_white_smoke_15] = SV_CustomTEnt_Register("ce_white_smoke_15", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_white_smoke_20] = SV_CustomTEnt_Register("ce_white_smoke_20", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_white_smoke_50] = SV_CustomTEnt_Register("ce_white_smoke_50", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_green_smoke_05] = SV_CustomTEnt_Register("ce_green_smoke_05", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_green_smoke_10] = SV_CustomTEnt_Register("ce_green_smoke_10", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_green_smoke_15] = SV_CustomTEnt_Register("ce_green_smoke_15", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_green_smoke_20] = SV_CustomTEnt_Register("ce_green_smoke_20", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_grey_smoke_15] = SV_CustomTEnt_Register("ce_grey_smoke_15", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
h2customtents[ce_grey_smoke_100] = SV_CustomTEnt_Register("ce_grey_smoke_100", CTE_CUSTOMVELOCITY, NULL, 0, NULL, 0, 0, NULL);
}
}
void PF_h2starteffect(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
// float *min, *max, *angle, *size;
// float colour, wait, radius, frame, framelength, duration;
// int flags, type, skin;
float *org, *dir;
int count;
int efnum = G_FLOAT(OFS_PARM0);
G_FLOAT(OFS_RETURN) = 0;
switch(efnum)
{
case ce_rain:
//min = G_VECTOR(OFS_PARM1);
//max = G_VECTOR(OFS_PARM2);
//size = G_VECTOR(OFS_PARM3);
//dir = G_VECTOR(OFS_PARM4);
//colour = G_FLOAT(OFS_PARM5);
//count = G_FLOAT(OFS_PARM6);
//wait = G_FLOAT(OFS_PARM7);
/*FIXME: not spawned - this persistant effect is created by a map object, all attributes are custom.*/
Con_Printf("FTE-H2 FIXME: ce_rain not supported!\n", efnum);
return;
break;
case ce_snow:
//min = G_VECTOR(OFS_PARM1);
//max = G_VECTOR(OFS_PARM2);
//flags = G_FLOAT(OFS_PARM3);
//dir = G_VECTOR(OFS_PARM4);
//count = G_FLOAT(OFS_PARM5);
/*FIXME: not spawned - this persistant effect is created by a map object (might be delay-spawned), all attributes are custom.*/
Con_Printf("FTE-H2 FIXME: ce_snow not supported!\n", efnum);
return;
break;
case ce_fountain:
//org = G_VECTOR(OFS_PARM1);
//angle = G_VECTOR(OFS_PARM2);
//dir = G_VECTOR(OFS_PARM3);
//colour = G_FLOAT(OFS_PARM4);
//count = G_FLOAT(OFS_PARM5);
/*FIXME: not spawned - this persistant effect is created by a map object, all attributes are custom.*/
Con_Printf("FTE-H2 FIXME: ce_fountain not supported!\n", efnum);
return;
break;
case ce_quake:
org = G_VECTOR(OFS_PARM1);
//radius = G_FLOAT(OFS_PARM2); /*discard: always 500/3 */
if (h2customtents[efnum] != -1)
{
SV_CustomTEnt_Spawn(h2customtents[efnum], org, NULL, 1, NULL);
return;
}
break;
case ce_white_smoke: //(1,2,3,4,10)*0.05
case ce_green_smoke: //(1,2,3,4)*0.05
case ce_grey_smoke: //(3,20)*0.05
/*transform them to the correct durations*/
if (efnum == ce_white_smoke)
{
int ifl = G_FLOAT(OFS_PARM3) * 100;
if (ifl == 5)
efnum = ce_white_smoke_05;
else if (ifl == 10)
efnum = ce_white_smoke_10;
else if (ifl == 15)
efnum = ce_white_smoke_15;
else if (ifl == 20)
efnum = ce_white_smoke_20;
else if (ifl == 50)
efnum = ce_white_smoke_50;
}
else if (efnum == ce_green_smoke)
{
int ifl = G_FLOAT(OFS_PARM3) * 100;
if (ifl == 05)
efnum = ce_green_smoke_05;
else if (ifl == 10)
efnum = ce_green_smoke_10;
else if (ifl == 15)
efnum = ce_green_smoke_15;
else if (ifl == 20)
efnum = ce_green_smoke_20;
}
else
{
int ifl = G_FLOAT(OFS_PARM3) * 100;
if (ifl == 15)
efnum = ce_grey_smoke_15;
if (ifl == 100)
efnum = ce_grey_smoke_100;
}
/*fallthrough*/
case ce_red_smoke: //0.15
case ce_slow_white_smoke: //0
case ce_telesmk1: //0.15
case ce_telesmk2: //not used
case ce_ghost: //0.1
case ce_redcloud: //0.05
org = G_VECTOR(OFS_PARM1);
dir = G_VECTOR(OFS_PARM2);
//framelength = G_FLOAT(OFS_PARM3); /*FIXME: validate for the other effects?*/
if (h2customtents[efnum] != -1)
{
SV_CustomTEnt_Spawn(h2customtents[efnum], org, NULL, 1, dir);
return;
}
break;
case ce_acid_muzzfl:
case ce_flamestream:
case ce_flamewall:
case ce_flamewall2:
case ce_onfire:
org = G_VECTOR(OFS_PARM1);
dir = G_VECTOR(OFS_PARM2);
//frame = G_FLOAT(OFS_PARM3); /*discard: h2 uses a fixed value for each effect (0, except for acid_muzzfl which is 0.05)*/
if (h2customtents[efnum] != -1)
{
SV_CustomTEnt_Spawn(h2customtents[efnum], org, NULL, 1, dir);
return;
}
break;
case ce_sm_white_flash:
case ce_yellowred_flash:
case ce_bluespark:
case ce_yellowspark:
case ce_sm_circle_exp:
case ce_bg_circle_exp:
case ce_sm_explosion:
case ce_lg_explosion:
case ce_floor_explosion:
case ce_floor_explosion3:
case ce_blue_explosion:
case ce_redspark:
case ce_greenspark:
case ce_icehit:
case ce_medusa_hit:
case ce_mezzo_reflect:
case ce_floor_explosion2:
case ce_xbow_explosion:
case ce_new_explosion:
case ce_magic_missile_explosion:
case ce_bone_explosion:
case ce_bldrn_expl:
case ce_acid_hit:
case ce_acid_splat:
case ce_acid_expl:
case ce_lball_expl:
case ce_firewall_small:
case ce_firewall_medium:
case ce_firewall_large:
case ce_fboom:
case ce_bomb:
case ce_brn_bounce:
case ce_lshock:
case ce_white_flash:
case ce_blue_flash:
case ce_sm_blue_flash:
case ce_red_flash:
case ce_rider_death:
case ce_teleporterpuffs:
org = G_VECTOR(OFS_PARM1);
if (h2customtents[efnum] != -1)
{
SV_CustomTEnt_Spawn(h2customtents[efnum], org, NULL, 1, NULL);
return;
}
break;
case ce_gravitywell:
org = G_VECTOR(OFS_PARM1);
//colour = G_FLOAT(OFS_PARM2); /*discard: h2 uses a fixed random range*/
//duration = G_FLOAT(OFS_PARM3); /*discard: h2 uses a fixed time limit*/
if (h2customtents[efnum] != -1)
{
SV_CustomTEnt_Spawn(h2customtents[efnum], org, NULL, 1, NULL);
return;
}
break;
case ce_teleporterbody:
org = G_VECTOR(OFS_PARM1);
dir = G_VECTOR(OFS_PARM2);
if (G_FLOAT(OFS_PARM3)) /*alternate*/
efnum = ce_teleporterbody_1;
if (h2customtents[efnum] != -1)
{
SV_CustomTEnt_Spawn(h2customtents[efnum], org, NULL, 1, dir);
return;
}
break;
case ce_boneshard:
case ce_boneshrapnel:
org = G_VECTOR(OFS_PARM1);
dir = G_VECTOR(OFS_PARM2);
//angle = G_VECTOR(OFS_PARM3); /*discard: angle is a function of the dir*/
//avelocity = G_VECTOR(OFS_PARM4);/*discard: avelocity is a function of the dir*/
/*FIXME: persistant until removed*/
if (h2customtents[efnum] != -1)
{
SV_CustomTEnt_Spawn(h2customtents[efnum], org, NULL, 1, dir);
return;
}
break;
case ce_chunk:
org = G_VECTOR(OFS_PARM1);
//type = G_FLOAT(OFS_PARM2); /*FIXME: discarded*/
dir = G_VECTOR(OFS_PARM3);
count = G_FLOAT(OFS_PARM4);
if (h2customtents[efnum] != -1)
{
SV_CustomTEnt_Spawn(h2customtents[efnum], org, NULL, count, dir);
return;
}
Con_Printf("FTE-H2 FIXME: ce_chunk not supported!\n", efnum);
return;
break;
default:
PR_BIError (prinst, "PF_h2starteffect: bad effect");
break;
}
Con_Printf("FTE-H2 FIXME: Effect %i doesn't have an effect registered\nTell Spike!\n", efnum);
#if 0
switch((int)G_FLOAT(OFS_PARM0))
{
case 4: //white_smoke
@ -7250,6 +7744,7 @@ void PF_h2starteffect(progfuncs_t *prinst, struct globalvars_s *pr_globals)
Con_Printf("Start effect %i\n", (int)G_FLOAT(OFS_PARM0));
break;
}
#endif
}
void PF_h2endeffect(progfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -7397,9 +7892,19 @@ void PF_CustomTEnt(progfuncs_t *prinst, struct globalvars_s *pr_globals)
MSG_WriteByte(&sv.multicast, G_FLOAT(OFS_PARM0+arg*3));
arg++;
}
if (type & CTE_CUSTOMDIRECTION)
if (type & CTE_CUSTOMVELOCITY)
{
MSG_WriteDir(&sv.multicast, G_VECTOR(OFS_PARM0+arg*3));
float *vel = G_VECTOR(OFS_PARM0+arg*3);
MSG_WriteCoord(&sv.multicast, vel[0]);
MSG_WriteCoord(&sv.multicast, vel[1]);
MSG_WriteCoord(&sv.multicast, vel[2]);
arg++;
}
else if (type & CTE_CUSTOMDIRECTION)
{
vec3_t norm;
VectorNormalize2(G_VECTOR(OFS_PARM0+arg*3), norm);
MSG_WriteDir(&sv.multicast, norm);
arg++;
}
}
@ -8390,71 +8895,8 @@ void PF_ChangePic(progfuncs_t *prinst, struct globalvars_s *pr_globals)
#if 0
typedef struct {
int ident;
int version;
char name[MAX_QPATH];
int flags; //Does anyone know what these are?
int numFrames;
int numTags;
int numSurfaces;
int numSkins;
int ofsFrames;
int ofsTags;
int ofsSurfaces;
int ofsEnd;
} md3Header_t;
typedef struct {
char name[MAX_QPATH];
vec3_t org;
float ang[3][3];
} md3tag_t;
typedef struct zymlump_s
{
int start;
int length;
} zymlump_t;
typedef struct zymtype1header_s
{
char id[12]; // "ZYMOTICMODEL", length 12, no termination
int type; // 0 (vertex morph) 1 (skeletal pose) or 2 (skeletal scripted)
int filesize; // size of entire model file
float mins[3], maxs[3], radius; // for clipping uses
int numverts;
int numtris;
int numsurfaces;
int numbones; // this may be zero in the vertex morph format (undecided)
int numscenes; // 0 in skeletal scripted models
// skeletal pose header
// lump offsets are relative to the file
zymlump_t lump_scenes; // zymscene_t scene[numscenes]; // name and other information for each scene (see zymscene struct)
zymlump_t lump_poses; // float pose[numposes][numbones][6]; // animation data
zymlump_t lump_bones; // zymbone_t bone[numbones];
zymlump_t lump_vertbonecounts; // int vertbonecounts[numvertices]; // how many bones influence each vertex (separate mainly to make this compress better)
zymlump_t lump_verts; // zymvertex_t vert[numvertices]; // see vertex struct
zymlump_t lump_texcoords; // float texcoords[numvertices][2];
zymlump_t lump_render; // int renderlist[rendersize]; // sorted by shader with run lengths (int count), shaders are sequentially used, each run can be used with glDrawElements (each triangle is 3 int indices)
zymlump_t lump_surfnames; // char shadername[numsurfaces][32]; // shaders used on this model
zymlump_t lump_trizone; // byte trizone[numtris]; // see trizone explanation
} zymtype1header_t;
typedef struct zymbone_s
{
char name[32];
int flags;
int parent; // parent bone number
} zymbone_t;
#endif
int SV_TagForName(int modelindex, char *tagname)
{
#if 1
model_t *model = sv.models[modelindex];
if (!model)
model = Mod_ForName(sv.strings.model_precache[modelindex], false);
@ -8462,51 +8904,6 @@ int SV_TagForName(int modelindex, char *tagname)
return 0;
return Mod_TagNumForName(model, tagname);
#else
int i;
unsigned int *file;
file = (void*)COM_LoadTempFile(sv.model_precache[modelindex]);
if (!file)
{
Con_Printf("setattachment: \"%s\" is missing\n", sv.model_precache[modelindex]);
return 0;
}
if (*file == MD3_IDENT)
{
md3Header_t *md3 = (md3Header_t*)file;
md3tag_t *tag;
tag = (md3tag_t*)((char*)md3 + md3->ofsTags);
for (i = 0;i < md3->numTags;i++)
{
if (!strcmp(tagname, tag[i].name))
{
return i + 1;
}
}
}
else if (!strncmp((char*)file, "ZYMOTICMODEL", 12) && BigLong(file[3]) == 1)
{
zymtype1header_t *zym = (zymtype1header_t*)file;
zymbone_t *tag;
tag = (zymbone_t*)((char*)zym + BigLong(zym->lump_bones.start));
for (i = BigLong(zym->numbones)-1;i >=0;i--)
{
if (!strcmp(tagname, tag[i].name))
{
return i + 1;
}
}
}
else
Con_DPrintf("setattachment: %s not supported\n", sv.model_precache[modelindex]);
return 0;
#endif
}
void PF_setattachment(progfuncs_t *prinst, struct globalvars_s *pr_globals)

View File

@ -775,7 +775,7 @@ static qintptr_t syscallhandle (void *offset, quintptr_t mask, qintptr_t fn, con
v[0] = VM_FLOAT(arg[0]);
v[1] = VM_FLOAT(arg[1]);
v[2] = VM_FLOAT(arg[2]);
return sv.world.worldmodel->funcs.PointContents(sv.world.worldmodel, v);
return sv.world.worldmodel->funcs.PointContents(sv.world.worldmodel, NULL, v);
}
break;

View File

@ -127,7 +127,7 @@ and the extension fields are added on the end and can have extra vm-specific stu
comfieldstring(model,model,model);\
comfieldfloat(frame,frame,frame);\
comfieldfloat(skin,skin,skin);\
comfieldfloat(effects,_effects,_effects);\
comfieldfloat(effects,effects,effects);\
comfieldvector(mins,mins,mins);\
comfieldvector(maxs,maxs,maxs);\
comfieldvector(size,size,size);\

View File

@ -78,6 +78,8 @@ typedef struct {
#define CTE_STAINS 4
#define CTE_GLOWS 8
#define CTE_CHANNELFADE 16
#define CTE_CUSTOMVELOCITY 32
#define CTE_UNUSED2 64
#define CTE_ISBEAM 128
typedef struct laggedpacket_s

View File

@ -1401,7 +1401,7 @@ qboolean Cull_Traceline(edict_t *viewer, edict_t *seen)
//stage 1: check against their origin
VectorAdd(viewer->v->origin, viewer->v->view_ofs, start);
tr.fraction = 1;
if (!sv.world.worldmodel->funcs.Trace (sv.world.worldmodel, 1, 0, start, seen->v->origin, vec3_origin, vec3_origin, &tr))
if (!sv.world.worldmodel->funcs.Trace (sv.world.worldmodel, 1, 0, NULL, start, seen->v->origin, vec3_origin, vec3_origin, &tr))
return false; //wasn't blocked
//stage 2: check against their bbox
@ -1412,7 +1412,7 @@ qboolean Cull_Traceline(edict_t *viewer, edict_t *seen)
end[2] = seen->v->origin[2] + ((i&4)?seen->v->mins[2]+0.1:seen->v->maxs[2]);
tr.fraction = 1;
if (!sv.world.worldmodel->funcs.Trace (sv.world.worldmodel, 1, 0, start, end, vec3_origin, vec3_origin, &tr))
if (!sv.world.worldmodel->funcs.Trace (sv.world.worldmodel, 1, 0, NULL, start, end, vec3_origin, vec3_origin, &tr))
return false; //this trace went through, so don't cull
}
@ -2228,6 +2228,7 @@ void SV_Snapshot_BuildStateQ1(entity_state_t *state, edict_t *ent, client_t *cli
state->light[2] = ent->xv->color[2]*255;
state->light[3] = ent->xv->light_lev;
state->lightstyle = ent->xv->style;
state->lightstyle = ent->xv->style;
state->lightpflags = ent->xv->pflags;
if ((int)ent->v->flags & FL_CLASS_DEPENDENT && client->playerclass) //hexen2 wierdness.

View File

@ -1269,8 +1269,21 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
else if (coop.value)
spawnflagmask |= SPAWNFLAG_NOT_H2COOP;
else
{
cvar_t *cl_playerclass = Cvar_Get("cl_playerclass", "0", CVAR_USERINFO, 0);
spawnflagmask |= SPAWNFLAG_NOT_H2SINGLE;
if (cl_playerclass && cl_playerclass->ival == 1)
spawnflagmask |= SPAWNFLAG_NOT_H2PALADIN;
else if (cl_playerclass && cl_playerclass->ival == 2)
spawnflagmask |= SPAWNFLAG_NOT_H2CLERIC;
else if (cl_playerclass && cl_playerclass->ival == 3)
spawnflagmask |= SPAWNFLAG_NOT_H2NECROMANCER;
else if (cl_playerclass && cl_playerclass->ival == 4)
spawnflagmask |= SPAWNFLAG_NOT_H2THEIF;
else if (cl_playerclass && cl_playerclass->ival == 5)
spawnflagmask |= SPAWNFLAG_NOT_H2NECROMANCER; /*yes, I know.,. makes no sense*/
}
if (skill.value < 0.5)
spawnflagmask |= SPAWNFLAG_NOT_H2EASY;
else if (skill.value > 1.5)

View File

@ -4684,7 +4684,9 @@ void AddLinksToPmove ( edict_t *player, areanode_t *node )
continue; // player's own missile
if (check->v->solid == SOLID_BSP
|| check->v->solid == SOLID_BBOX
|| check->v->solid == SOLID_SLIDEBOX)
|| check->v->solid == SOLID_SLIDEBOX
//|| (check->v->solid == SOLID_PHASEH2 && progstype == PROG_H2) //logically matches hexen2, but I hate it
)
{
if (check == player)
continue;
@ -4744,9 +4746,14 @@ void AddLinksToPmove ( edict_t *player, areanode_t *node )
model = sv.models[(int)check->v->modelindex];
if (model)
{
vec3_t axis[3];
AngleVectors(check->v->angles, axis[0], axis[1], axis[2]);
VectorNegate(axis[1], axis[1]);
// test the point
if (model->funcs.PointContents (model, player->v->origin) == FTECONTENTS_SOLID)
player->xv->pmove_flags = (int)player->xv->pmove_flags | PMF_LADDER; //touch that ladder!
if (model->funcs.PointContents (model, axis, player->v->origin) == FTECONTENTS_SOLID)
player->xv->pmove_flags = (int)player->xv->pmove_flags | PMF_LADDER; //touch that ladder!
}
}
}

View File

@ -86,9 +86,6 @@ char *mapentspointer;
#define Q3SOLID_BMODEL 0xffffff
#define Q3CONTENTS_SOLID Q2CONTENTS_SOLID // should never be on a brush, only in game
#define Q3CONTENTS_BODY 0x2000000 // should never be on a brush, only in game
#define PS_FOR_NUM(n) ((q3playerState_t *)((qbyte *)q3playerstates + sizeofGameClient*(n)))
#define clamp(v,min,max) v = (v>max)?max:((v < min)?min:v)
@ -402,7 +399,7 @@ static void SVQ3_Trace(q3trace_t *result, vec3_t start, vec3_t mins, vec3_t maxs
if (!maxs)
maxs = vec3_origin;
sv.world.worldmodel->funcs.NativeTrace(sv.world.worldmodel, 0, 0, start, end, mins, maxs, contentmask, &tr);
sv.world.worldmodel->funcs.NativeTrace(sv.world.worldmodel, 0, 0, NULL, start, end, mins, maxs, contentmask, &tr);
result->allsolid = tr.allsolid;
result->contents = tr.contents;
VectorCopy(tr.endpos, result->endpos);
@ -504,7 +501,7 @@ static int SVQ3_PointContents(vec3_t pos, int entnum)
// sv.worldmodel->funcs.Trace(sv.worldmodel, 0, 0, pos, pos, vec3_origin, vec3_origin, &tr);
// tr = CM_BoxTrace(sv.worldmodel, pos, pos, vec3_origin, vec3_origin, 0);
cont = sv.world.worldmodel->funcs.NativeContents (sv.world.worldmodel, 0, 0, pos, vec3_origin, vec3_origin);
cont = sv.world.worldmodel->funcs.NativeContents (sv.world.worldmodel, 0, 0, NULL, pos, vec3_origin, vec3_origin);
if ((unsigned)entnum >= MAX_GENTITIES)
ourowner = -1;
@ -566,7 +563,7 @@ static int SVQ3_Contact(vec3_t mins, vec3_t maxs, q3sharedEntity_t *ent)
if (mod->needload || !mod->funcs.Trace)
return false;
mod->funcs.Trace(mod, 0, 0, vec3_origin, vec3_origin, mins, maxs, &tr);
mod->funcs.Trace(mod, 0, 0, NULL, vec3_origin, vec3_origin, mins, maxs, &tr);
if (tr.startsolid)
return true;
@ -2822,7 +2819,6 @@ void SVQ3_ParseUsercmd(client_t *client, qboolean delta)
{
if(to->servertime <= client->lastcmd.servertime)
{
Con_Printf("%i vs %i\n", to->servertime, client->lastcmd.servertime);
continue;
}
if (to->servertime-10 > sv.time*1000) //10 ms allows some server latency...

View File

@ -886,7 +886,7 @@ SV_PointContents
*/
int World_PointContents (world_t *w, vec3_t p)
{
return w->worldmodel->funcs.PointContents(w->worldmodel, p);
return w->worldmodel->funcs.PointContents(w->worldmodel, NULL, p);
}
//===========================================================================
@ -917,11 +917,8 @@ qboolean Q1BSP_RecursiveHullCheck (hull_t *hull, int num, float p1f, float p2f,
//qboolean TransformedHullCheck (hull_t *hull, vec3_t start, vec3_t end, trace_t *trace, vec3_t angles)
qboolean TransformedTrace (struct model_s *model, int hulloverride, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, struct trace_s *trace, vec3_t origin, vec3_t angles)
{
qboolean rotated;
vec3_t start_l, end_l;
vec3_t a;
vec3_t forward, right, up;
vec3_t temp;
vec3_t axis[3];
qboolean result;
memset (trace, 0, sizeof(trace_t));
@ -934,53 +931,21 @@ qboolean TransformedTrace (struct model_s *model, int hulloverride, int frame, v
// don't rotate non bsp ents. Too small to bother.
if (model)
{
rotated = (angles[0] || angles[1] || angles[2]);
if (rotated)
VectorSubtract (start, origin, start_l);
VectorSubtract (end, origin, end_l);
if (angles[0] || angles[1] || angles[2])
{
AngleVectors (angles, forward, right, up);
VectorSubtract (start, origin, temp);
start_l[0] = DotProduct (temp, forward);
start_l[1] = -DotProduct (temp, right);
start_l[2] = DotProduct (temp, up);
VectorSubtract (end, origin, temp);
end_l[0] = DotProduct (temp, forward);
end_l[1] = -DotProduct (temp, right);
end_l[2] = DotProduct (temp, up);
AngleVectors (angles, axis[0], axis[1], axis[2]);
VectorNegate(axis[1], axis[1]);
result = model->funcs.Trace (model, hulloverride, frame, axis, start_l, end_l, mins, maxs, trace);
}
else
{
VectorSubtract (start, origin, start_l);
VectorSubtract (end, origin, end_l);
result = model->funcs.Trace (model, hulloverride, frame, NULL, start_l, end_l, mins, maxs, trace);
}
result = model->funcs.Trace (model, hulloverride, frame, start_l, end_l, mins, maxs, trace);
if (rotated)
{
// FIXME: figure out how to do this with existing angles
if (trace->fraction != 1)
{
VectorNegate (angles, a);
AngleVectors (a, forward, right, up);
VectorCopy (trace->plane.normal, temp);
trace->plane.normal[0] = DotProduct (temp, forward);
trace->plane.normal[1] = -DotProduct (temp, right);
trace->plane.normal[2] = DotProduct (temp, up);
trace->endpos[0] = start[0] + trace->fraction * (end[0] - start[0]);
trace->endpos[1] = start[1] + trace->fraction * (end[1] - start[1]);
trace->endpos[2] = start[2] + trace->fraction * (end[2] - start[2]);
}
else
{
VectorCopy (end, trace->endpos);
}
}
else
VectorAdd (trace->endpos, origin, trace->endpos);
VectorAdd (trace->endpos, origin, trace->endpos);
}
else
{
@ -1002,11 +967,8 @@ qboolean TransformedTrace (struct model_s *model, int hulloverride, int frame, v
qboolean TransformedNativeTrace (struct model_s *model, int hulloverride, int frame, vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, unsigned int against, struct trace_s *trace, vec3_t origin, vec3_t angles)
{
qboolean rotated;
vec3_t start_l, end_l;
vec3_t a;
vec3_t forward, right, up;
vec3_t temp;
vec3_t axis[3];
qboolean result;
memset (trace, 0, sizeof(trace_t));
@ -1019,44 +981,17 @@ qboolean TransformedNativeTrace (struct model_s *model, int hulloverride, int fr
// don't rotate non bsp ents. Too small to bother.
if (model)
{
rotated = (angles[0] || angles[1] || angles[2]);
if (rotated)
VectorSubtract (start, origin, start_l);
VectorSubtract (end, origin, end_l);
if (angles[0] || angles[1] || angles[2])
{
AngleVectors (angles, forward, right, up);
VectorSubtract (start, origin, temp);
start_l[0] = DotProduct (temp, forward);
start_l[1] = -DotProduct (temp, right);
start_l[2] = DotProduct (temp, up);
VectorSubtract (end, origin, temp);
end_l[0] = DotProduct (temp, forward);
end_l[1] = -DotProduct (temp, right);
end_l[2] = DotProduct (temp, up);
AngleVectors (angles, axis[0], axis[1], axis[2]);
VectorNegate(axis[1], axis[1]);
result = model->funcs.NativeTrace (model, hulloverride, frame, axis, start_l, end_l, mins, maxs, against, trace);
}
else
{
VectorSubtract (start, origin, start_l);
VectorSubtract (end, origin, end_l);
}
result = model->funcs.NativeTrace (model, hulloverride, frame, start_l, end_l, mins, maxs, against, trace);
if (rotated)
{
// FIXME: figure out how to do this with existing angles
// VectorNegate (angles, a);
a[0] = -angles[0];
a[1] = -angles[1];
a[2] = -angles[2];
AngleVectors (a, forward, right, up);
VectorCopy (trace->plane.normal, temp);
trace->plane.normal[0] = DotProduct (temp, forward);
trace->plane.normal[1] = -DotProduct (temp, right);
trace->plane.normal[2] = DotProduct (temp, up);
trace->endpos[0] = start[0] + trace->fraction * (end[0] - start[0]);
trace->endpos[1] = start[1] + trace->fraction * (end[1] - start[1]);
trace->endpos[2] = start[2] + trace->fraction * (end[2] - start[2]);
result = model->funcs.NativeTrace (model, hulloverride, frame, NULL, start_l, end_l, mins, maxs, against, trace);
}
VectorAdd (trace->endpos, origin, trace->endpos);
}