Couple of changes.

D3D now supports hlsl shaders. Much functionality is still missing, but sky and water surfaces are in.
IQM models now supported.
Engine physics code is now potentially callable from csqc, but there are some issues which need to be resolved before its enabled.
FTEQCC has had some pointer/struct/array functionality improved. Complex trees can now be navigated properly.
added r_dumpshaders command to dump internal glsl scripts for editing.

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@3896 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2011-09-03 03:49:43 +00:00
parent 30cb0af30f
commit e8c1f669cc
65 changed files with 3067 additions and 1477 deletions

View File

@ -208,7 +208,7 @@ int demo_preparsedemo(unsigned char *buffer, int bytes)
net_message.cursize = length;
memcpy(net_message.data, buffer+ofs, length);
MSG_BeginReading(cls.netchan.netprim);
CL_ParseServerMessage();
CLQW_ParseServerMessage();
}
parsed += ofs+length;

View File

@ -1334,7 +1334,7 @@ void V_AddAxisEntity(entity_t *in)
if (cl_numvisedicts == MAX_VISEDICTS)
{
Con_Printf("Visedict list is full!\n");
Con_DPrintf("Visedict list is full!\n");
return; // object list is full
}
ent = &cl_visedicts[cl_numvisedicts];
@ -1348,7 +1348,7 @@ entity_t *V_AddEntity(entity_t *in)
if (cl_numvisedicts == MAX_VISEDICTS)
{
Con_Printf("Visedict list is full!\n");
Con_DPrintf("Visedict list is full!\n");
return NULL; // object list is full
}
ent = &cl_visedicts[cl_numvisedicts];
@ -3447,8 +3447,6 @@ Made up of: clients, packet_entities, nails, and tents
*/
void CL_SwapEntityLists(void)
{
cl_visedicts = cl_visedicts_list;
cl_numvisedicts = 0;
cl_numstrisidx = 0;
cl_numstrisvert = 0;

View File

@ -199,8 +199,7 @@ int rtlights_first, rtlights_max;
// this is double buffered so the last frame
// can be scanned for oldorigins of trailing objects
int cl_numvisedicts;
entity_t *cl_visedicts;
entity_t cl_visedicts_list[MAX_VISEDICTS];
entity_t cl_visedicts[MAX_VISEDICTS];
scenetris_t *cl_stris;
vecV_t *cl_strisvertv;
@ -2719,7 +2718,7 @@ void CL_ReadPackets (void)
cls.netchan.outgoing_sequence = cls.netchan.incoming_sequence;
}
MSG_ChangePrimitives(cls.netchan.netprim);
CL_ParseServerMessage ();
CLQW_ParseServerMessage ();
break;
case CP_UNKNOWN:
break;

View File

@ -943,13 +943,8 @@ int CL_LoadModels(int stage, qboolean dontactuallyload)
if (anycsqc || *s || cls.demoplayback) //only allow csqc if the server says so, and the 'checksum' matches.
{
unsigned int chksum = anycsqc?0:strtoul(s, NULL, 0);
if (CSQC_Init(chksum))
if (!CSQC_Init(chksum))
{
CL_SendClientCommand(true, "enablecsqc");
}
else
{
CL_SendClientCommand(true, "disablecsqc");
Sbar_Start(); //try and start this before we're actually on the server,
//this'll stop the mod from sending so much stuffed data at us, whilst we're frozen while trying to load.
//hopefully this'll make it more robust.
@ -1092,6 +1087,19 @@ int CL_LoadModels(int stage, qboolean dontactuallyload)
endstage();
}
if (atstage())
{
if (CSQC_Inited())
{
CL_SendClientCommand(true, "enablecsqc");
}
else
{
CL_SendClientCommand(true, "disablecsqc");
}
endstage();
}
return stage;
}
@ -1631,7 +1639,7 @@ int CL_RequestADownloadChunk(void)
CL_SendClientCommand(true, "stopdownload");
CL_DownloadFinished();
Con_Printf("Download took %i seconds (%i more)\n", (int)(Sys_DoubleTime() - downloadstarttime), CL_CountQueuedDownloads());
Con_DPrintf("Download took %i seconds (%i more)\n", (int)(Sys_DoubleTime() - downloadstarttime), CL_CountQueuedDownloads());
*cls.downloadlocalname = '\0';
*cls.downloadremotename = '\0';
@ -1776,7 +1784,7 @@ void CL_ParseDownload (void)
cls.downloadqw = NULL;
cls.downloadpercent = 0;
Con_Printf("Download took %i seconds\n", (int)(Sys_DoubleTime() - downloadstarttime));
Con_DPrintf("Download took %i seconds\n", (int)(Sys_DoubleTime() - downloadstarttime));
// get another file if needed
@ -1916,7 +1924,7 @@ void CLDP_ParseDownloadFinished(char *s)
cls.downloadqw = NULL;
cls.downloadpercent = 0;
Con_Printf("Download took %i seconds\n", (int)(Sys_DoubleTime() - downloadstarttime));
Con_DPrintf("Download took %i seconds\n", (int)(Sys_DoubleTime() - downloadstarttime));
// get another file if needed
@ -2488,7 +2496,7 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
}
else if (protover == H2_PROTOCOL_VERSION)
{
Host_EndGame ("\nUnable to connect to Hexen2 servers.\n");
Host_EndGame ("\nUnable to connect to standard Hexen2 servers. Host the game with "DISTRIBUTION"\n");
}
else if (protover != NQ_PROTOCOL_VERSION)
{
@ -2587,6 +2595,10 @@ void CLNQ_ParseServerData(void) //Doesn't change gamedir - use with caution.
//allow some things by default that quakeworld bans by default
Info_SetValueForStarKey(cl.serverinfo, "watervis", "1", sizeof(cl.serverinfo));
Info_SetValueForStarKey(cl.serverinfo, "mirrors", "1", sizeof(cl.serverinfo));
//prohibit some things that QW/FTE has enabled by default
Info_SetValueForStarKey(cl.serverinfo, "fbskins", "0", sizeof(cl.serverinfo));
//pretend it came from the server, and update cheat/permissions/etc
CL_CheckServerInfo();
@ -4843,7 +4855,7 @@ CL_ParseServerMessage
=====================
*/
int received_framecount;
void CL_ParseServerMessage (void)
void CLQW_ParseServerMessage (void)
{
int cmd;
char *s;

View File

@ -848,7 +848,10 @@ fixedorg:
from = &cl.frames[cl.oldvalidsequence & UPDATE_MASK];
//figure out the lerp factor
f = (cl.gametime-cl.servertime)/(cl.gametime-cl.oldgametime);//f = (cl.time-cl.lerpents[state->number].lerptime)/cl.lerpents[state->number].lerprate;
if (cl.gametime == cl.servertime)
f = 0;
else
f = (cl.gametime-cl.servertime)/(cl.gametime-cl.oldgametime);//f = (cl.time-cl.lerpents[state->number].lerptime)/cl.lerpents[state->number].lerprate;
if (f<0)
f=0;
if (f>1)

View File

@ -377,8 +377,6 @@ int VMQ3_StringToHandle(char *str)
void VQ3_AddEntity(const q3refEntity_t *q3)
{
entity_t ent;
if (!cl_visedicts)
cl_visedicts = cl_visedicts_list;
memset(&ent, 0, sizeof(ent));
ent.model = VM_FROMMHANDLE(q3->hModel);
ent.framestate.g[FS_REG].frame[0] = q3->frame;

View File

@ -787,10 +787,9 @@ void CL_SetInfo (int pnum, char *key, char *value);
void CL_BeginServerConnect(int port);
char *CL_TryingToConnect(void);
#define MAX_VISEDICTS 1024
#define MAX_VISEDICTS 2048
extern int cl_numvisedicts;
extern entity_t *cl_visedicts;
extern entity_t cl_visedicts_list[MAX_VISEDICTS];
extern entity_t cl_visedicts[];
/*these are for q3 really*/
typedef struct {
@ -924,7 +923,7 @@ int CL_CalcNet (void);
void CL_ClearParseState(void);
void CL_DumpPacket(void);
void CL_ParseEstablished(void);
void CL_ParseServerMessage (void);
void CLQW_ParseServerMessage (void);
void CLNQ_ParseServerMessage (void);
#ifdef Q2CLIENT
void CLQ2_ParseServerMessage (void);
@ -1031,6 +1030,7 @@ char *CG_GetConfigString(int num);
//pr_csqc.c
//
#ifdef CSQC_DAT
qboolean CSQC_Inited(void);
qboolean CSQC_Init (unsigned int checksum);
void CSQC_RegisterCvarsAndThings(void);
qboolean CSQC_DrawView(void);
@ -1046,6 +1046,7 @@ qboolean CSQC_ParseTempEntity(unsigned char firstbyte);
qboolean CSQC_ConsoleCommand(char *cmd);
qboolean CSQC_KeyPress(int key, int unicode, qboolean down);
qboolean CSQC_MouseMove(float xdelta, float ydelta);
qboolean CSQC_MousePosition(float xabs, float yabs);
int CSQC_StartSound(int entnum, int channel, char *soundname, vec3_t pos, float vol, float attenuation);
void CSQC_ParseEntities(void);
qboolean CSQC_SettingListener(void);

View File

@ -1912,9 +1912,6 @@ void CLQ2_AddEntities (void)
r_refdef.currentplayernum = 0;
cl_visedicts = cl_visedicts_list;
cl_numvisedicts = 0;
cl_numstrisidx = 0;
cl_numstrisvert = 0;

View File

@ -1328,16 +1328,23 @@ static void ProcessMouse(mouse_t *mouse, float *movements, int pnum)
mousecursor_y = vid.height - 1;
mx=my=0;
}
#ifdef VM_UI
else
{
#ifdef VM_UI
if (UI_MousePosition(mx, my))
{
mx = 0;
my = 0;
}
}
#endif
#ifdef PEXT_CSQC
if (CSQC_MousePosition(mx, my))
{
mx = 0;
my = 0;
}
#endif
}
#ifdef PEXT_CSQC
if (mx || my)

View File

@ -167,6 +167,7 @@ typedef enum backendmode_e
BEM_DEPTHONLY, //just a quick depth pass. textures used only for alpha test (shadowmaps).
BEM_STENCIL, //used for drawing shadow volumes to the stencil buffer.
BEM_DEPTHDARK, //a quick depth pass. textures used only for alpha test. additive textures still shown as normal.
BEM_DEPTHNORM, //all opaque stuff drawn using 'depthnorm' shader
BEM_LIGHT, //we have a valid light
BEM_SMAPLIGHTSPOT, //we have a spot light using a shadowmap
BEM_SMAPLIGHT, //we have a light using a shadowmap

View File

@ -634,6 +634,7 @@ static float Classic_ParticleTrail (vec3_t start, vec3_t end, float leftover, ef
goto done;
VectorScale(delta, 1 / len, dir); //unit vector in direction of trail
VectorMA(point, -leftover, dir, point);
len += leftover;
rlen = len;
@ -647,16 +648,12 @@ static float Classic_ParticleTrail (vec3_t start, vec3_t end, float leftover, ef
scale = 3; break;
}
leftover = scale - leftover;
VectorMA(point, leftover, delta, point);
VectorScale (dir, scale, dir);
len /= scale;
leftover = rlen - ((int)(len) * scale);
if (!(num_particles = (int) len))
goto done;
VectorScale (delta, scale, delta);
num_particles = (int) len;
for (i = 0; i < num_particles && free_particles; i++)
{
@ -735,7 +732,7 @@ static float Classic_ParticleTrail (vec3_t start, vec3_t end, float leftover, ef
p->org[j] = point[j] + ((rand() % 6) - 3);
break;
}
VectorAdd (point, delta, point);
VectorAdd (point, dir, point);
}
done:
return leftover;

View File

@ -276,8 +276,6 @@ typedef struct part_type_s {
#define PS_INRUNLIST 0x1 // particle type is currently in execution list
} part_type_t;
static void PScript_DrawParticleTypes (void (*texturedparticles)(int count, particle_t **,plooks_t*), void (*sparklineparticles)(int count, particle_t **,plooks_t*), void (*sparkfanparticles)(int count, particle_t **,plooks_t*), void (*sparktexturedparticles)(int count, particle_t **,plooks_t*), void (*beamparticles)(int count, beamseg_t**,plooks_t*), void (*drawdecalparticles)(int count, clippeddecal_t**,plooks_t*));
#ifndef TYPESONLY
//triangle fan sparks use these. // defined but not used
@ -3972,8 +3970,12 @@ static void GL_DrawClippedDecal(int count, clippeddecal_t **dlist, plooks_t *typ
}
}
static void PScript_DrawParticleTypes (void (*texturedparticles)(int count, particle_t **,plooks_t*), void (*sparklineparticles)(int count, particle_t **,plooks_t*), void (*sparkfanparticles)(int count, particle_t **,plooks_t*), void (*sparktexturedparticles)(int count, particle_t **,plooks_t*), void (*beamparticles)(int count, beamseg_t**,plooks_t*), void (*drawdecalparticles)(int count, clippeddecal_t**,plooks_t*))
static void PScript_DrawParticleTypes (void)
{
void (*sparklineparticles)(int count, particle_t **,plooks_t*)=GL_DrawLineSparkParticle;
void (*sparkfanparticles)(int count, particle_t **,plooks_t*)=GL_DrawTrifanParticle;
void (*sparktexturedparticles)(int count, particle_t **,plooks_t*)=GL_DrawTexturedSparkParticle;
qboolean (*tr) (vec3_t start, vec3_t end, vec3_t impact, vec3_t normal);
void *pdraw, *bdraw;
@ -4031,11 +4033,6 @@ static void PScript_DrawParticleTypes (void (*texturedparticles)(int count, part
kill_list = kill_first = NULL;
if (r_part_beams.ival < 0)
beamparticles = NULL;
else if (!r_part_beams.ival)
beamparticles = NULL;
if (r_part_sparks_textured.ival < 0)
sparktexturedparticles = NULL;
else if (!r_part_sparks_textured.ival)
@ -4113,7 +4110,7 @@ static void PScript_DrawParticleTypes (void (*texturedparticles)(int count, part
d->rgba[3] += pframetime*type->alphachange;
}
drawdecalparticles(1, &d, &type->looks);
GL_DrawClippedDecal(1, &d, &type->looks);
}
}
@ -4125,12 +4122,15 @@ static void PScript_DrawParticleTypes (void (*texturedparticles)(int count, part
switch(type->looks.type)
{
case PT_BEAM:
bdraw = beamparticles;
if (r_part_beams.ival <= 0)
bdraw = NULL;
else
bdraw = GL_DrawParticleBeam;
break;
case PT_DECAL:
break;
case PT_NORMAL:
pdraw = texturedparticles;
pdraw = GL_DrawTexturedParticle;
break;
case PT_SPARK:
pdraw = sparklineparticles;
@ -4532,7 +4532,7 @@ static void PScript_DrawParticles (void)
{
P_AddRainParticles();
PScript_DrawParticleTypes(GL_DrawTexturedParticle, GL_DrawLineSparkParticle, GL_DrawTrifanParticle, GL_DrawTexturedSparkParticle, GL_DrawParticleBeam, GL_DrawClippedDecal);
PScript_DrawParticleTypes();
if (fallback)
fallback->DrawParticles();

View File

@ -53,7 +53,7 @@ static qboolean csqc_isdarkplaces;
static char csqc_printbuffer[8192];
#define CSQCPROGSGROUP "CSQC progs control"
cvar_t pr_csqc_maxedicts = CVAR("pr_csqc_maxedicts", "3072"); //not tied to protocol nor server.
cvar_t pr_csqc_maxedicts = CVAR("pr_csqc_maxedicts", "8192"); //not tied to protocol nor server.
cvar_t pr_csqc_memsize = CVAR("pr_csqc_memsize", "-1");
cvar_t cl_csqcdebug = CVAR("cl_csqcdebug", "0"); //prints entity numbers which arrive (so I can tell people not to apply it to players...)
cvar_t cl_nocsqc = CVAR("cl_nocsqc", "0");
@ -287,6 +287,13 @@ static void CSQC_FindGlobals(void)
CSQC_ChangeLocalPlayer(0);
csqc_world.g.self = csqcg.self;
csqc_world.g.other = csqcg.other;
csqc_world.g.force_retouch = (float*)PR_FindGlobal(csqcprogs, "force_retouch", 0, NULL);
csqc_world.g.frametime = csqcg.frametime;
csqc_world.g.newmis = (int*)PR_FindGlobal(csqcprogs, "newmis", 0, NULL);
csqc_world.g.time = csqcg.svtime;
if (csqcg.maxclients)
*csqcg.maxclients = cl.allocated_client_slots;
}
@ -333,6 +340,7 @@ static void QCBUILTIN PF_cs_gettime (progfuncs_t *prinst, struct globalvars_s *p
\
comfieldfloat(drawmask); /*So that the qc can specify all rockets at once or all bannanas at once*/ \
comfieldfunction(predraw); /*If present, is called just before it's drawn.*/ \
comfieldvector(glowmod); \
\
comfieldfloat(ideal_pitch);\
comfieldfloat(pitch_speed);\
@ -696,15 +704,10 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out)
AngleVectors(out->angles, out->axis[0], out->axis[1], out->axis[2]);
VectorInverse(out->axis[1]);
if (!in->xv->scale || in->xv->scale == 1.0f)
if (!in->xv->scale)
out->scale = 1;
else
{
VectorScale(out->axis[0], in->xv->scale, out->axis[0]);
VectorScale(out->axis[1], in->xv->scale, out->axis[1]);
VectorScale(out->axis[2], in->xv->scale, out->axis[2]);
out->scale = in->xv->scale;
}
}
ival = in->v->colormap;
@ -714,9 +717,18 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out)
}
// TODO: DP COLORMAP extension?
out->shaderRGBAf[0] = 1;
out->shaderRGBAf[1] = 1;
out->shaderRGBAf[2] = 1;
if (!in->xv->colormod[0] && !in->xv->colormod[1] && !in->xv->colormod[2])
{
out->shaderRGBAf[0] = 1;
out->shaderRGBAf[1] = 1;
out->shaderRGBAf[2] = 1;
}
else
{
out->shaderRGBAf[0] = in->xv->colormod[0];
out->shaderRGBAf[1] = in->xv->colormod[1];
out->shaderRGBAf[2] = in->xv->colormod[2];
}
if (!in->xv->alpha || in->xv->alpha == 1)
{
out->shaderRGBAf[3] = 1.0f;
@ -727,6 +739,8 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out)
out->shaderRGBAf[3] = in->xv->alpha;
}
VectorCopy(in->xv->glowmod, out->glowmod);
out->skinnum = in->v->skin;
out->fatness = in->xv->fatness;
ival = in->xv->forceshader;
@ -5116,14 +5130,17 @@ pbool CSQC_EntFree (struct edict_s *e)
{
struct csqcedict_s *ent = (csqcedict_t*)e;
ent->v->solid = SOLID_NOT;
ent->xv->drawmask = 0;
ent->v->movetype = 0;
ent->v->modelindex = 0;
ent->v->think = 0;
ent->v->nextthink = 0;
ent->xv->predraw = 0;
ent->xv->drawmask = 0;
ent->xv->renderflags = 0;
#ifdef USEODE
World_Physics_RemoveFromEntity(&csqc_world, (wedict_t*)ent);
World_Physics_RemoveJointFromEntity(&csqc_world, (wedict_t*)ent);
World_ODE_RemoveFromEntity(&csqc_world, (wedict_t*)ent);
World_ODE_RemoveJointFromEntity(&csqc_world, (wedict_t*)ent);
#endif
return true;
@ -5143,6 +5160,14 @@ void CSQC_Event_Touch(world_t *w, wedict_t *s, wedict_t *o)
*csqcg.other = oother;
}
void CSQC_Event_Think(world_t *w, wedict_t *s)
{
*csqcg.self = EDICT_TO_PROG(w->progs, (edict_t*)s);
*csqcg.other = EDICT_TO_PROG(w->progs, (edict_t*)w->edicts);
PR_ExecuteProgram (w->progs, s->v->think);
}
model_t *CSQC_World_ModelForIndex(world_t *w, int modelindex)
{
return CSQC_GetModelForIndex(modelindex);
@ -5162,7 +5187,7 @@ void CSQC_Shutdown(void)
csqcprogs = NULL;
#ifdef USEODE
World_Physics_End(&csqc_world);
World_ODE_End(&csqc_world);
#endif
Z_Free(csqcdelta_pack_new.e);
@ -5291,6 +5316,13 @@ int CSQC_PRFileSize (const char *path)
return COM_FileSize(path);
}
qboolean CSQC_Inited(void)
{
if (csqcprogs)
return true;
return false;
}
double csqctime;
qboolean CSQC_Init (unsigned int checksum)
{
@ -5373,6 +5405,7 @@ qboolean CSQC_Init (unsigned int checksum)
PR_Configure(csqcprogs, pr_csqc_memsize.ival, 16);
csqc_world.worldmodel = cl.worldmodel;
csqc_world.Event_Touch = CSQC_Event_Touch;
csqc_world.Event_Think = CSQC_Event_Think;
csqc_world.GetCModel = CSQC_World_ModelForIndex;
World_ClearWorld(&csqc_world);
CSQC_InitFields(); //let the qclib know the field order that the engine needs.
@ -5462,7 +5495,7 @@ void CSQC_WorldLoaded(void)
csqc_world.worldmodel = cl.worldmodel;
#ifdef USEODE
World_Physics_Start(&csqc_world);
World_ODE_Start(&csqc_world);
#endif
worldent = (csqcedict_t *)EDICT_NUM(csqcprogs, 0);
@ -5689,7 +5722,9 @@ qboolean CSQC_DrawView(void)
ft = mintic;
csqc_world.physicstime += ft;
World_Physics_Frame(&csqc_world, ft, 800);
World_ODE_Frame(&csqc_world, ft, 800);
//World_Physics_Frame(&csqc_world);
}
#else
csqc_world.physicstime = cl.servertime;
@ -5749,6 +5784,22 @@ qboolean CSQC_KeyPress(int key, int unicode, qboolean down)
return G_FLOAT(OFS_RETURN);
}
qboolean CSQC_MousePosition(float xabs, float yabs)
{
void *pr_globals;
if (!csqcprogs || !csqcg.input_event)
return false;
pr_globals = PR_globals(csqcprogs, PR_CURRENT);
G_FLOAT(OFS_PARM0) = 3;
G_FLOAT(OFS_PARM1) = xabs;
G_FLOAT(OFS_PARM2) = yabs;
PR_ExecuteProgram (csqcprogs, csqcg.input_event);
return G_FLOAT(OFS_RETURN);
}
qboolean CSQC_MouseMove(float xdelta, float ydelta)
{
void *pr_globals;
@ -6030,7 +6081,7 @@ void CSQC_ParseEntities(void)
if (!csqcprogs)
Host_EndGame("CSQC needs to be initialized for this server.\n");
if (!csqcg.ent_update || !csqcg.self)
if (!csqcg.ent_update || !csqcg.self || !csqc_world.worldmodel || csqc_world.worldmodel->needload)
Host_EndGame("CSQC is unable to parse entities\n");
pr_globals = PR_globals(csqcprogs, PR_CURRENT);

View File

@ -395,35 +395,30 @@ void QCBUILTIN PF_CL_drawcolouredstring (progfuncs_t *prinst, struct globalvars_
void QCBUILTIN PF_CL_stringwidth(progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
conchar_t buffer[2048], *end;
float px, py;
char *text = PR_GetStringOfs(prinst, OFS_PARM0);
int usecolours = G_FLOAT(OFS_PARM1);
float fontsize;
if (*prinst->callargc > 2)
fontsize = G_FLOAT(OFS_PARM2);
fontsize = G_FLOAT(OFS_PARM2+1);
else
fontsize = 1;
fontsize = 8;
if (mp_globs.drawfontscale)
fontsize *= mp_globs.drawfontscale[1];
if (usecolours)
{
conchar_t buffer[2048], *end;
float px, py;
end = COM_ParseFunString(CON_WHITEMASK, text, buffer, sizeof(buffer), false);
Font_BeginScaledString(font_conchar, 0, 0, &px, &py);
px = Font_LineWidth(buffer, end);
Font_EndString(font_conchar);
end = COM_ParseFunString(CON_WHITEMASK, text, buffer, sizeof(buffer), !usecolours);
if (mp_globs.drawfontscale)
px *= mp_globs.drawfontscale[1];
Font_BeginScaledString(font_conchar, 0, 0, &px, &py);
fontsize /= Font_CharHeight();
px = Font_LineWidth(buffer, end);
Font_EndString(font_conchar);
G_FLOAT(OFS_RETURN) = px;
}
else
{
G_FLOAT(OFS_RETURN) = strlen(text)*fontsize;
}
if (mp_globs.drawfontscale)
px *= mp_globs.drawfontscale[1];
G_FLOAT(OFS_RETURN) = px * fontsize;
}
#define DRAWFLAG_NORMAL 0
@ -442,7 +437,7 @@ static unsigned int PF_SelectDPDrawFlag(int flag)
if (flag == 1)
return BEF_FORCEADDITIVE;
else
return BEF_FORCETRANSPARENT;
return 0;
}
//float drawpic(vector position, string pic, vector size, vector rgb, float alpha, float flag) = #456;

View File

@ -2447,7 +2447,10 @@ static void Surf_CreateSurfaceLightmap (msurface_t *surf, int shift)
}
if (currentmodel->fromgame == fg_quake3)
{
Surf_LM_FillBlock(surf->lightmaptexturenum, smax, tmax, surf->light_s, surf->light_t);
return;
}
else
surf->lightmaptexturenum = Surf_LM_AllocBlock (smax, tmax, &surf->light_s, &surf->light_t, surf->texinfo->texture->shader);
base = lightmap[surf->lightmaptexturenum]->lightmaps;

View File

@ -83,11 +83,12 @@ typedef struct entity_s
vec3_t angles;
vec3_t axis[3];
vec4_t shaderRGBAf;
float shaderTime;
vec4_t shaderRGBAf; /*colormod+alpha, available for shaders to mix*/
float shaderTime; /*timestamp, for syncing shader times to spawns*/
vec3_t glowmod; /*meant to be a multiplier for the fullbrights*/
int light_known;
vec3_t light_avg; /*midpoint level*/
int light_known; /*bsp lighting has been caled*/
vec3_t light_avg; /*midpoint level*/
vec3_t light_range; /*avg + this = max, avg - this = min*/
vec3_t light_dir;
@ -435,13 +436,14 @@ extern cvar_t r_netgraph;
extern cvar_t r_xflip;
#endif
extern cvar_t r_lightprepass;
extern cvar_t gl_maxdist;
extern cvar_t r_clear;
extern cvar_t gl_poly;
extern cvar_t gl_affinemodels;
extern cvar_t gl_nohwblend;
extern cvar_t gl_reporttjunctions;
extern cvar_t r_flashblend;
extern cvar_t r_flashblend, r_flashblendscale;
extern cvar_t r_lightstylesmooth;
extern cvar_t r_lightstylesmooth_limit;
extern cvar_t r_lightstylespeed;

View File

@ -2,6 +2,7 @@
#include "winquake.h"
#include "pr_common.h"
#include "gl_draw.h"
#include "shader.h"
#include <string.h>
@ -89,6 +90,8 @@ cvar_t r_skin_overlays = SCVARF ("r_skin_overlays", "1",
CVAR_SEMICHEAT|CVAR_RENDERERLATCH);
cvar_t r_flashblend = SCVARF ("gl_flashblend", "0",
CVAR_ARCHIVE);
cvar_t r_flashblendscale = SCVARF ("gl_flashblendscale", "0.35",
CVAR_ARCHIVE);
cvar_t r_floorcolour = SCVARF ("r_floorcolour", "255 255 255",
CVAR_RENDERERCALLBACK|CVAR_SHADERSYSTEM);
cvar_t r_floortexture = SCVARF ("r_floortexture", "",
@ -295,6 +298,7 @@ cvar_t r_noaliasshadows = SCVARF ("r_noaliasshadows", "0",
CVAR_ARCHIVE);
cvar_t r_shadows = SCVARF ("r_shadows", "0",
CVAR_ARCHIVE);
cvar_t r_lightprepass = CVARFD("r_lightprepass", "0", CVAR_SHADERSYSTEM, "Experimental. Attempt to use a different lighting mechanism.");
cvar_t r_shadow_bumpscale_basetexture = SCVAR ("r_shadow_bumpscale_basetexture", "4");
cvar_t r_shadow_bumpscale_bumpmap = SCVAR ("r_shadow_bumpscale_bumpmap", "10");
@ -352,6 +356,7 @@ void GLRenderer_Init(void)
Cvar_Register (&gl_affinemodels, GLRENDEREROPTIONS);
Cvar_Register (&gl_nohwblend, GLRENDEREROPTIONS);
Cvar_Register (&r_flashblend, GLRENDEREROPTIONS);
Cvar_Register (&r_flashblendscale, GLRENDEREROPTIONS);
Cvar_Register (&gl_nocolors, GLRENDEREROPTIONS);
Cvar_Register (&gl_finish, GLRENDEREROPTIONS);
Cvar_Register (&gl_lateswap, GLRENDEREROPTIONS);
@ -483,6 +488,8 @@ void Renderer_Init(void)
Cmd_AddCommand("setrenderer", R_SetRenderer_f);
Cmd_AddCommand("vid_restart", R_RestartRenderer_f);
Cmd_AddCommand("r_dumpshaders", Shader_WriteOutGenerics_f);
#if defined(GLQUAKE) || defined(D3DQUAKE)
GLD3DRenderer_Init();
#endif
@ -531,6 +538,7 @@ void Renderer_Init(void)
Cvar_Register(&r_stains, GRAPHICALNICETIES);
Cvar_Register(&r_stainfadetime, GRAPHICALNICETIES);
Cvar_Register(&r_stainfadeammount, GRAPHICALNICETIES);
Cvar_Register(&r_lightprepass, GRAPHICALNICETIES);
Cvar_Register(&scr_viewsize, SCREENOPTIONS);
Cvar_Register(&scr_fov, SCREENOPTIONS);

View File

@ -639,7 +639,9 @@ static int SNDDMA_Init(soundcardinfo_t *sc, int *cardnum, int *drivernum)
memset(sc, 0, sizeof(*sc));
// set requested rate
if (!snd_khz.ival)
if (snd_khz.ival >= 1000)
sc->sn.speed = snd_khz.ival;
else if (snd_khz.ival <= 0)
sc->sn.speed = 22050;
/* else if (snd_khz.ival >= 195)
sc->sn.speed = 200000;
@ -1064,10 +1066,14 @@ void S_Init (void)
}
p = COM_CheckParm ("-soundspeed");
if (!p)
p = COM_CheckParm ("-sspeed");
if (!p)
p = COM_CheckParm ("-sndspeed");
if (p)
{
if (p < com_argc-1)
Cvar_SetValue(&snd_khz, atof(com_argv[p+1])/1000);
Cvar_SetValue(&snd_khz, atof(com_argv[p+1]));
else
Sys_Error ("S_Init: you must specify a speed in KB after -soundspeed");
}

View File

@ -215,6 +215,7 @@ static void GenMatrixPosQuat4Scale(vec3_t pos, vec4_t quat, vec3_t scale, float
{
float xx, xy, xz, xw, yy, yz, yw, zz, zw;
float x2, y2, z2;
float s;
x2 = quat[0] + quat[0];
y2 = quat[1] + quat[1];
z2 = quat[2] + quat[2];
@ -223,17 +224,20 @@ static void GenMatrixPosQuat4Scale(vec3_t pos, vec4_t quat, vec3_t scale, float
yy = quat[1] * y2; yz = quat[1] * z2; zz = quat[2] * z2;
xw = quat[3] * x2; yw = quat[3] * y2; zw = quat[3] * z2;
result[0*4+0] = 1.0f - (yy + zz);
result[1*4+0] = xy + zw;
result[2*4+0] = xz - yw;
s = scale[0];
result[0*4+0] = s*(1.0f - (yy + zz));
result[1*4+0] = s*(xy + zw);
result[2*4+0] = s*(xz - yw);
result[0*4+1] = xy - zw;
result[1*4+1] = 1.0f - (xx + zz);
result[2*4+1] = yz + xw;
s = scale[1];
result[0*4+1] = s*(xy - zw);
result[1*4+1] = s*(1.0f - (xx + zz));
result[2*4+1] = s*(yz + xw);
result[0*4+2] = xz + yw;
result[1*4+2] = yz - xw;
result[2*4+2] = 1.0f - (xx + yy);
s = scale[2];
result[0*4+2] = s*(xz + yw);
result[1*4+2] = s*(yz - xw);
result[2*4+2] = s*(1.0f - (xx + yy));
result[0*4+3] = pos[0];
result[1*4+3] = pos[1];
@ -727,6 +731,7 @@ static int Alias_BuildLerps(float plerp[4], float *pose[4], int numbones, galias
frame1=(frame1>g1->numposes-1)?g1->numposes-1:frame1;
frame2=(frame2>g1->numposes-1)?g1->numposes-1:frame2;
}
if (frame1 == frame2)
mlerp = 0;
plerp[l] = (1-mlerp)*(1-lerpfrac);
@ -1468,7 +1473,7 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, int surfnum, ent
{
meshcache.usebonepose = Alias_GetBonePositions(inf, &e->framestate, meshcache.bonepose, MAX_BONES);
if (1)//e->fatness || !inf->ofs_skel_idx || !usebones)
if (e->fatness || !inf->ofs_skel_idx || !usebones)
{
Alias_BuildSkeletalMesh(mesh, meshcache.usebonepose, inf);
@ -1487,7 +1492,9 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, galiasinfo_t *inf, int surfnum, ent
#ifdef GLQUAKE
if (!inf->numswtransforms && qrenderer == QR_OPENGL)
{
Alias_GLDrawSkeletalBones((galiasbone_t*)((char*)inf + inf->ofsbones), (float *)meshcache.usebonepose, inf->numbones);
}
#endif
meshcache.usebonepose = NULL;
}
@ -3789,6 +3796,7 @@ qboolean Mod_LoadQ3Model(model_t *mod, void *buffer)
galias->groups = LittleLong(header->numFrames);
galias->numverts = LittleLong(surf->numVerts);
galias->numindexes = LittleLong(surf->numTriangles)*3;
galias->shares_verts = s;
if (parent)
parent->nextsurf = (qbyte *)galias - (qbyte *)parent;
else
@ -4931,7 +4939,7 @@ qboolean Mod_LoadPSKModel(model_t *mod, void *buffer)
gmdl[i].numindexes = 0;
for (j = 0; j < num_face; j++)
{
if (face[j].mattindex == i)
if (face[j].mattindex%num_matt == i)
{
indexes[gmdl[i].numindexes+0] = face[j].vtxwindex[0];
indexes[gmdl[i].numindexes+1] = face[j].vtxwindex[1];
@ -5525,6 +5533,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
vec4_t *oweight;
byte_vec4_t *oindex;
float *opose;
vec2_t *otcoords;
galiasinfo_t *gai;
@ -5601,13 +5610,14 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
sizeof(*skin)*h->num_meshes + sizeof(*texnum)*h->num_meshes +
#endif
sizeof(*fgroup)*h->num_anims + sizeof(float)*12*h->num_poses*h->num_frames + sizeof(*bones)*h->num_joints +
(sizeof(*opos) + sizeof(*onorm) + sizeof(*oweight) + sizeof(*oindex)) * h->num_vertexes);
(sizeof(*opos) + sizeof(*onorm) + sizeof(*oweight) + sizeof(*otcoords) + sizeof(*oindex)) * h->num_vertexes);
bones = (galiasbone_t*)(gai + h->num_meshes);
opos = (vecV_t*)(bones + h->num_joints);
onorm = (vec3_t*)(opos + h->num_vertexes);
oindex = (byte_vec4_t*)(onorm + h->num_vertexes);
oweight = (vec4_t*)(oindex + h->num_vertexes);
fgroup = (galiasgroup_t*)(oweight + h->num_vertexes);
otcoords = (vec2_t*)(oweight + h->num_vertexes);
fgroup = (galiasgroup_t*)(otcoords + h->num_vertexes);
opose = (float*)(fgroup + h->num_anims);
#ifndef SERVERONLY
skin = (galiasskin_t*)(opose + 12*h->num_poses*h->num_frames);
@ -5625,6 +5635,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
vec3_t pos;
vec4_t quat;
vec3_t scale;
float mat[12], mat2[12];
for (i = 0; i < h->num_joints; i++)
{
@ -5632,25 +5643,42 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
bones[i].parent = ijoint[i].parent;
GenMatrixPosQuat4Scale(ijoint[i].translate, ijoint[i].rotate, ijoint[i].scale, &basepose[i*12]);
Matrix3x4_Invert(&basepose[i*12], &invbasepose[12*i]);
if (ijoint[i].parent >= 0)
{
Matrix3x4_Multiply(&basepose[i*12], &basepose[ijoint[i].parent*12], mat);
memcpy(&basepose[i*12], mat, sizeof(mat));
Matrix3x4_Multiply(&invbasepose[ijoint[i].parent*12], &invbasepose[i*12], mat);
memcpy(&invbasepose[i*12], mat, sizeof(mat));
}
}
for (i = 0; i < h->num_frames; i++)
{
for (j = 0, p = ipose; j < h->num_poses; j++, p++)
{
pos[0] = p->channeloffset[0]; if (p->mask & 1) pos[0] += *framedata++ + p->channelscale[0];
pos[1] = p->channeloffset[1]; if (p->mask & 2) pos[1] += *framedata++ + p->channelscale[1];
pos[2] = p->channeloffset[2]; if (p->mask & 4) pos[2] += *framedata++ + p->channelscale[2];
quat[0] = p->channeloffset[3]; if (p->mask & 8) quat[0] += *framedata++ + p->channelscale[3];
quat[1] = p->channeloffset[4]; if (p->mask & 16) quat[1] += *framedata++ + p->channelscale[4];
quat[2] = p->channeloffset[5]; if (p->mask & 32) quat[2] += *framedata++ + p->channelscale[5];
scale[0] = p->channeloffset[6]; if (p->mask & 64) scale[0] += *framedata++ + p->channelscale[6];
scale[1] = p->channeloffset[7]; if (p->mask & 128) scale[1] += *framedata++ + p->channelscale[7];
scale[2] = p->channeloffset[8]; if (p->mask & 256) scale[2] += *framedata++ + p->channelscale[8];
pos[0] = p->channeloffset[0]; if (p->mask & 1) pos[0] += *framedata++ * p->channelscale[0];
pos[1] = p->channeloffset[1]; if (p->mask & 2) pos[1] += *framedata++ * p->channelscale[1];
pos[2] = p->channeloffset[2]; if (p->mask & 4) pos[2] += *framedata++ * p->channelscale[2];
quat[0] = p->channeloffset[3]; if (p->mask & 8) quat[0] += *framedata++ * p->channelscale[3];
quat[1] = p->channeloffset[4]; if (p->mask & 16) quat[1] += *framedata++ * p->channelscale[4];
quat[2] = p->channeloffset[5]; if (p->mask & 32) quat[2] += *framedata++ * p->channelscale[5];
scale[0] = p->channeloffset[6]; if (p->mask & 64) scale[0] += *framedata++ * p->channelscale[6];
scale[1] = p->channeloffset[7]; if (p->mask & 128) scale[1] += *framedata++ * p->channelscale[7];
scale[2] = p->channeloffset[8]; if (p->mask & 256) scale[2] += *framedata++ * p->channelscale[8];
quat[3] = -sqrt(max(1.0 - pow(VectorLength(quat),2), 0.0));
GenMatrixPosQuat4Scale(pos, quat, scale, opose + (i*h->num_poses+j)*12);
if (ijoint[j].parent >= 0)
{
Matrix3x4_Multiply(mat, &basepose[ijoint[j].parent*12], mat2);
Matrix3x4_Multiply(&invbasepose[j*12], mat2, &opose[(i*h->num_poses+j)*12]);
}
else
Matrix3x4_Multiply(&invbasepose[j*12], mat, &opose[(i*h->num_poses+j)*12]);
}
}
}
@ -5661,7 +5689,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
vec3_t pos;
vec4_t quat;
vec3_t scale;
float mat[12];
float mat[12], mat2[12];
for (i = 0; i < h->num_joints; i++)
{
@ -5670,31 +5698,44 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
GenMatrixPosQuat4Scale(ijoint[i].translate, ijoint[i].rotate, ijoint[i].scale, &basepose[i*12]);
// Mod_Skel_Invert(bones, basepose, h->num_joints, invbonepose);
Matrix3x4_Invert(&basepose[i*12], &invbasepose[12*i]);
if (ijoint[i].parent >= 0)
{
Matrix3x4_Multiply(&basepose[i*12], &basepose[ijoint[i].parent*12], mat);
memcpy(&basepose[i*12], mat, sizeof(mat));
Matrix3x4_Multiply(&invbasepose[ijoint[i].parent*12], &invbasepose[i*12], mat);
memcpy(&invbasepose[i*12], mat, sizeof(mat));
}
}
for (i = 0; i < h->num_frames; i++)
{
for (j = 0, p = ipose; j < h->num_poses; j++, p++)
{
pos[0] = p->channeloffset[0]; if (p->mask & 1) pos[0] += *framedata++ + p->channelscale[0];
pos[1] = p->channeloffset[1]; if (p->mask & 2) pos[1] += *framedata++ + p->channelscale[1];
pos[2] = p->channeloffset[2]; if (p->mask & 4) pos[2] += *framedata++ + p->channelscale[2];
quat[0] = p->channeloffset[3]; if (p->mask & 8) quat[0] += *framedata++ + p->channelscale[3];
quat[1] = p->channeloffset[4]; if (p->mask & 16) quat[1] += *framedata++ + p->channelscale[4];
quat[2] = p->channeloffset[5]; if (p->mask & 32) quat[2] += *framedata++ + p->channelscale[5];
quat[3] = p->channeloffset[6]; if (p->mask & 64) quat[3] += *framedata++ + p->channelscale[6];
scale[0] = p->channeloffset[7]; if (p->mask & 128) scale[0] += *framedata++ + p->channelscale[7];
scale[1] = p->channeloffset[8]; if (p->mask & 256) scale[1] += *framedata++ + p->channelscale[8];
scale[2] = p->channeloffset[9]; if (p->mask & 512) scale[2] += *framedata++ + p->channelscale[9];
pos[0] = p->channeloffset[0]; if (p->mask & 1) pos[0] += *framedata++ * p->channelscale[0];
pos[1] = p->channeloffset[1]; if (p->mask & 2) pos[1] += *framedata++ * p->channelscale[1];
pos[2] = p->channeloffset[2]; if (p->mask & 4) pos[2] += *framedata++ * p->channelscale[2];
quat[0] = p->channeloffset[3]; if (p->mask & 8) quat[0] += *framedata++ * p->channelscale[3];
quat[1] = p->channeloffset[4]; if (p->mask & 16) quat[1] += *framedata++ * p->channelscale[4];
quat[2] = p->channeloffset[5]; if (p->mask & 32) quat[2] += *framedata++ * p->channelscale[5];
quat[3] = p->channeloffset[6]; if (p->mask & 64) quat[3] += *framedata++ * p->channelscale[6];
scale[0] = p->channeloffset[7]; if (p->mask & 128) scale[0] += *framedata++ * p->channelscale[7];
scale[1] = p->channeloffset[8]; if (p->mask & 256) scale[1] += *framedata++ * p->channelscale[8];
scale[2] = p->channeloffset[9]; if (p->mask & 512) scale[2] += *framedata++ * p->channelscale[9];
GenMatrixPosQuat4Scale(pos, quat, scale, &opose[(i*h->num_poses+j)*12]);
GenMatrixPosQuat4Scale(pos, quat, scale, mat);
if (ijoint[j].parent >= 0)
{
Matrix3x4_Multiply(mat, &basepose[ijoint[j].parent*12], mat2);
Matrix3x4_Multiply(&invbasepose[j*12], mat2, &opose[(i*h->num_poses+j)*12]);
}
else
Matrix3x4_Multiply(&invbasepose[j*12], mat, &opose[(i*h->num_poses+j)*12]);
}
}
}
// Mod_Skel_PreSkin(basepose, invbonepose
/*load the framegroup info*/
anim = (struct iqmanim*)(buffer + h->ofs_anims);
for (i = 0; i < h->num_anims; i++)
@ -5715,7 +5756,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
gai[i].shares_bones = 0;
gai[i].numbones = h->num_joints;
gai[i].ofsbones = (char*)bones - (char*)&gai[i];
gai[i].groups = h->num_frames;
gai[i].groups = h->num_anims;
gai[i].groupofs = (char*)fgroup - (char*)&gai[i];
#ifndef SERVERONLY
@ -5730,6 +5771,9 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
skin[i].texnums = 1;
skin[i].ofstexnums = (char*)&texnum[i] - (char*)&skin[i];
texnum[i].shader = R_RegisterSkin(skin[i].name, mod->name);
R_BuildDefaultTexnums(&texnum[i], texnum[i].shader);
if (texnum[i].shader->flags & SHADER_NOIMAGE)
Con_Printf("Unable to load texture for shader \"%s\" for model \"%s\"\n", texnum[i].shader->name, loadmodel->name);
#endif
offset = LittleLong(mesh[i].first_vertex);
@ -5742,11 +5786,12 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
gai[i].ofs_indexes = (char*)idx - (char*)&gai[i];
for (t = 0; t < nt; t++)
{
*idx++ = LittleShort(tris[t].vertex[0]);
*idx++ = LittleShort(tris[t].vertex[1]);
*idx++ = LittleShort(tris[t].vertex[2]);
*idx++ = LittleShort(tris[t].vertex[0]) - offset;
*idx++ = LittleShort(tris[t].vertex[1]) - offset;
*idx++ = LittleShort(tris[t].vertex[2]) - offset;
}
gai[i].ofs_st_array = (char*)(otcoords+offset) - (char*)&gai[i];
/*verts*/
gai[i].shares_verts = i;
gai[i].numverts = LittleLong(mesh[i].num_vertexes);
@ -5759,10 +5804,11 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer)
}
for (i = 0; i < h->num_vertexes; i++)
{
Vector2Copy(tcoord+i*2, otcoords[i]);
VectorCopy(vpos+i*3, opos[i]);
VectorCopy(vnorm+i*4, onorm[i]);
VectorCopy(vbone+i*4, oindex[i]);
VectorCopy(vweight+i*4, oweight[i]);
Vector4Copy(vbone+i*4, oindex[i]);
Vector4Scale(vweight+i*4, 1/255.0, oweight[i]);
}
return gai;
}

View File

@ -1162,7 +1162,7 @@ static dllfunction_t odefuncs[] =
dllhandle_t ode_dll = NULL;
#endif
void World_Physics_Init(void)
void World_ODE_Init(void)
{
#ifdef ODE_DYNAMIC
const char* dllname =
@ -1230,7 +1230,7 @@ void World_Physics_Init(void)
#endif
}
void World_Physics_Shutdown(void)
void World_ODE_Shutdown(void)
{
#ifdef ODE_DYNAMIC
if (ode_dll)
@ -1244,7 +1244,7 @@ void World_Physics_Shutdown(void)
}
}
static void World_Physics_EnableODE(world_t *world)
static void World_ODE_Enable(world_t *world)
{
dVector3 center, extents;
if (world->ode.ode)
@ -1271,14 +1271,14 @@ static void World_Physics_EnableODE(world_t *world)
// dWorldSetAutoDisableFlag (world->ode.ode_world, true);
}
void World_Physics_Start(world_t *world)
void World_ODE_Start(world_t *world)
{
if (world->ode.ode)
return;
World_Physics_EnableODE(world);
World_ODE_Enable(world);
}
void World_Physics_End(world_t *world)
void World_ODE_End(world_t *world)
{
if (world->ode.ode)
{
@ -1289,7 +1289,7 @@ void World_Physics_End(world_t *world)
}
}
void World_Physics_RemoveJointFromEntity(world_t *world, wedict_t *ed)
void World_ODE_RemoveJointFromEntity(world_t *world, wedict_t *ed)
{
ed->ode.ode_joint_type = 0;
if(ed->ode.ode_joint)
@ -1297,7 +1297,7 @@ void World_Physics_RemoveJointFromEntity(world_t *world, wedict_t *ed)
ed->ode.ode_joint = NULL;
}
void World_Physics_RemoveFromEntity(world_t *world, wedict_t *ed)
void World_ODE_RemoveFromEntity(world_t *world, wedict_t *ed)
{
if (!ed->ode.ode_physics)
return;
@ -1347,7 +1347,7 @@ void World_Physics_RemoveFromEntity(world_t *world, wedict_t *ed)
ed->ode.ode_massbuf = NULL;
}
static void World_Physics_Frame_BodyToEntity(world_t *world, wedict_t *ed)
static void World_ODE_Frame_BodyToEntity(world_t *world, wedict_t *ed)
{
model_t *model;
const dReal *avel;
@ -1444,7 +1444,7 @@ static void World_Physics_Frame_BodyToEntity(world_t *world, wedict_t *ed)
World_LinkEdict(world, ed, true);
}
static void World_Physics_Frame_JointFromEntity(world_t *world, wedict_t *ed)
static void World_ODE_Frame_JointFromEntity(world_t *world, wedict_t *ed)
{
dJointID j = 0;
dBodyID b1 = 0;
@ -1729,7 +1729,7 @@ static qboolean GenerateCollisionMesh(world_t *world, model_t *mod, wedict_t *ed
return true;
}
static void World_Physics_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
static void World_ODE_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
{
dBodyID body = (dBodyID)ed->ode.ode_body;
dMass mass;
@ -1803,7 +1803,7 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
break;
default:
if (ed->ode.ode_physics)
World_Physics_RemoveFromEntity(world, ed);
World_ODE_RemoveFromEntity(world, ed);
return;
}
@ -1812,7 +1812,7 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
{
// we don't allow point-size physics objects...
if (ed->ode.ode_physics)
World_Physics_RemoveFromEntity(world, ed);
World_ODE_RemoveFromEntity(world, ed);
return;
}
@ -1827,7 +1827,7 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
|| ed->ode.ode_modelindex != modelindex)
{
modified = true;
World_Physics_RemoveFromEntity(world, ed);
World_ODE_RemoveFromEntity(world, ed);
ed->ode.ode_physics = true;
VectorCopy(entmins, ed->ode.ode_mins);
VectorCopy(entmaxs, ed->ode.ode_maxs);
@ -1853,13 +1853,13 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
{
Con_Printf("entity %i (classname %s) has no model\n", NUM_FOR_EDICT(world->progs, (edict_t*)ed), PR_GetString(world->progs, ed->v->classname));
if (ed->ode.ode_physics)
World_Physics_RemoveFromEntity(world, ed);
World_ODE_RemoveFromEntity(world, ed);
return;
}
if (!GenerateCollisionMesh(world, model, ed, geomcenter))
{
if (ed->ode.ode_physics)
World_Physics_RemoveFromEntity(world, ed);
World_ODE_RemoveFromEntity(world, ed);
return;
}
@ -1909,7 +1909,7 @@ static void World_Physics_Frame_BodyFromEntity(world_t *world, wedict_t *ed)
dMassSetCapsuleTotal(&mass, massval, axisindex+1, radius, length);
break;
default:
Sys_Error("World_Physics_BodyFromEntity: unrecognized solid value %i was accepted by filter\n", solid);
Sys_Error("World_ODE_BodyFromEntity: unrecognized solid value %i was accepted by filter\n", solid);
}
Matrix3x4_InvertTo4x4_Simple(ed->ode.ode_offsetmatrix, ed->ode.ode_offsetimatrix);
ed->ode.ode_massbuf = BZ_Malloc(sizeof(dMass));
@ -2259,7 +2259,7 @@ static void VARGS nearCallback (void *data, dGeomID o1, dGeomID o2)
}
}
void World_Physics_Frame(world_t *world, double frametime, double gravity)
void World_ODE_Frame(world_t *world, double frametime, double gravity)
{
if (world->ode.ode)
{
@ -2275,14 +2275,14 @@ void World_Physics_Frame(world_t *world, double frametime, double gravity)
{
ed = (wedict_t*)EDICT_NUM(world->progs, i);
if (!ed->isfree)
World_Physics_Frame_BodyFromEntity(world, ed);
World_ODE_Frame_BodyFromEntity(world, ed);
}
// oh, and it must be called after all bodies were created
for (i = 0;i < world->num_edicts;i++)
{
ed = (wedict_t*)EDICT_NUM(world->progs, i);
if (!ed->isfree)
World_Physics_Frame_JointFromEntity(world, ed);
World_ODE_Frame_JointFromEntity(world, ed);
}
for (i = 0;i < world->ode.ode_iterations;i++)
@ -2313,7 +2313,7 @@ void World_Physics_Frame(world_t *world, double frametime, double gravity)
{
ed = (wedict_t*)EDICT_NUM(world->progs, i);
if (!ed->isfree)
World_Physics_Frame_BodyToEntity(world, ed);
World_ODE_Frame_BodyToEntity(world, ed);
}
}
}

View File

@ -114,27 +114,6 @@ void COM_Locate_f (void);
qboolean standard_quake = true, rogue, hipnotic;
// this graphic needs to be in the pak file to use registered features
unsigned short pop[] =
{
0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000,0x0000
,0x0000,0x0000,0x6600,0x0000,0x0000,0x0000,0x6600,0x0000
,0x0000,0x0066,0x0000,0x0000,0x0000,0x0000,0x0067,0x0000
,0x0000,0x6665,0x0000,0x0000,0x0000,0x0000,0x0065,0x6600
,0x0063,0x6561,0x0000,0x0000,0x0000,0x0000,0x0061,0x6563
,0x0064,0x6561,0x0000,0x0000,0x0000,0x0000,0x0061,0x6564
,0x0064,0x6564,0x0000,0x6469,0x6969,0x6400,0x0064,0x6564
,0x0063,0x6568,0x6200,0x0064,0x6864,0x0000,0x6268,0x6563
,0x0000,0x6567,0x6963,0x0064,0x6764,0x0063,0x6967,0x6500
,0x0000,0x6266,0x6769,0x6a68,0x6768,0x6a69,0x6766,0x6200
,0x0000,0x0062,0x6566,0x6666,0x6666,0x6666,0x6562,0x0000
,0x0000,0x0000,0x0062,0x6364,0x6664,0x6362,0x0000,0x0000
,0x0000,0x0000,0x0000,0x0062,0x6662,0x0000,0x0000,0x0000
,0x0000,0x0000,0x0000,0x0061,0x6661,0x0000,0x0000,0x0000
,0x0000,0x0000,0x0000,0x0000,0x6500,0x0000,0x0000,0x0000
,0x0000,0x0000,0x0000,0x0000,0x6400,0x0000,0x0000,0x0000
};
/*
@ -3003,33 +2982,14 @@ being registered.
void COM_CheckRegistered (void)
{
vfsfile_t *h;
unsigned short check[128];
int i;
h = FS_OpenVFS("gfx/pop.lmp", "rb", FS_GAME);
static_registered = false;
if (!h)
{
Con_TPrintf (TL_SHAREWAREVERSION);
#if 0//ndef SERVERONLY
// FIXME DEBUG -- only temporary
if (com_modified)
Sys_Error ("You must have the registered version to play QuakeWorld");
#endif
return;
}
VFS_READ(h, check, sizeof(check));
VFS_CLOSE(h);
for (i=0 ; i<128 ; i++)
if (pop[i] != (unsigned short)BigShort (check[i]))
{
Con_TPrintf (TL_SHAREWAREVERSION);
return;
}
static_registered = true;
Con_TPrintf (TL_REGISTEREDVERSION);
}

View File

@ -1639,7 +1639,7 @@ void COM_Gamedir (const char *dir)
/*some modern non-compat settings*/
#define DMFCFG "set com_parseutf8 1\npm_airstep 1\nsv_demoExtensions 1\n"
/*set some stuff so our regular qw client appears more like hexen2*/
#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"
#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\nsv_sound_land \"fx/thngland.wav\"\n"
/*Q3's ui doesn't like empty model/headmodel/handicap cvars, even if the gamecode copes*/
#define Q3CFG "seta model sarge\nseta headmodel sarge\nseta handicap 100\n"
@ -2307,21 +2307,24 @@ void COM_InitFilesystem (void)
fclose(f);
break;
}
if (autobasedir)
{
#ifdef _WIN32
if (Sys_FindGameData(gamemode_info[i].poshname, gamemode_info[i].exename, com_quakedir, sizeof(com_quakedir)))
{
if (com_quakedir[strlen(com_quakedir)-1] == '\\')
com_quakedir[strlen(com_quakedir)-1] = '/';
else if (com_quakedir[strlen(com_quakedir)-1] != '/')
if (Sys_FindGameData(gamemode_info[i].poshname, gamemode_info[i].exename, com_quakedir, sizeof(com_quakedir)))
{
com_quakedir[strlen(com_quakedir)+1] = '\0';
com_quakedir[strlen(com_quakedir)] = '/';
if (com_quakedir[strlen(com_quakedir)-1] == '\\')
com_quakedir[strlen(com_quakedir)-1] = '/';
else if (com_quakedir[strlen(com_quakedir)-1] != '/')
{
com_quakedir[strlen(com_quakedir)+1] = '\0';
com_quakedir[strlen(com_quakedir)] = '/';
}
}
}
else
else
#endif
{
Con_Printf("Couldn't find the gamedata for this game mode!\n");
{
Con_Printf("Couldn't find the gamedata for this game mode!\n");
}
}
break;
}

View File

@ -3444,7 +3444,7 @@ void CMQ3_CalcPHS (void)
count++;
}
Con_Printf ("Average clusters visible / hearable / total: %i / %i / %i\n"
Con_DPrintf ("Average clusters visible / hearable / total: %i / %i / %i\n"
, vcount/numclusters, count/numclusters, numclusters);
}
#endif
@ -5186,7 +5186,10 @@ trace_t CM_BoxTrace (model_t *mod, vec3_t start, vec3_t end,
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);
if (maxs[0] - mins[0])
*trace = CM_BoxTrace(model, start, end, mins, maxs, MASK_PLAYERSOLID);
else
*trace = CM_BoxTrace(model, start, end, mins, maxs, MASK_SOLID);
return trace->fraction != 1;
}
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)

View File

@ -622,6 +622,24 @@ void R_ConcatTransforms (float in1[3][4], float in2[3][4], float out[3][4])
in1[2][2] * in2[2][3] + in1[2][3];
}
void Matrix3x4_Multiply(const float *a, const float *b, float *out)
{
out[0] = a[0] * b[0] + a[4] * b[1] + a[8] * b[2];
out[1] = a[1] * b[0] + a[5] * b[1] + a[9] * b[2];
out[2] = a[2] * b[0] + a[6] * b[1] + a[10] * b[2];
out[3] = a[3] * b[0] + a[7] * b[1] + a[11] * b[2] + b[3];
out[4] = a[0] * b[4] + a[4] * b[5] + a[8] * b[6];
out[5] = a[1] * b[4] + a[5] * b[5] + a[9] * b[6];
out[6] = a[2] * b[4] + a[6] * b[5] + a[10] * b[6];
out[7] = a[3] * b[4] + a[7] * b[5] + a[11] * b[6] + b[7];
out[8] = a[0] * b[8] + a[4] * b[9] + a[8] * b[10];
out[9] = a[1] * b[8] + a[5] * b[9] + a[9] * b[10];
out[10] = a[2] * b[8] + a[6] * b[9] + a[10] * b[10];
out[11] = a[3] * b[8] + a[7] * b[9] + a[11] * b[10] + b[11];
}
void R_ConcatRotationsPad (float in1[3][4], float in2[3][4], float out[3][4])
{
out[0][0] = in1[0][0] * in2[0][0] + in1[0][1] * in2[1][0] +
@ -1537,6 +1555,25 @@ void Matrix3x3_RM_Invert_Simple (const vec3_t in1[3], vec3_t out[3])
out[2][2] = in1[2][2] * scale;
}
void Matrix3x4_Invert (const float *in1, float *out)
{
vec3_t a, b, c, trans;
VectorSet (a, in1[0], in1[4], in1[8]);
VectorSet (b, in1[1], in1[5], in1[9]);
VectorSet (c, in1[2], in1[6], in1[10]);
VectorScale (a, 1 / DotProduct (a, a), a);
VectorScale (b, 1 / DotProduct (b, b), b);
VectorScale (c, 1 / DotProduct (c, c), c);
VectorSet (trans, in1[3], in1[7], in1[11]);
Vector4Set (out+0, a[0], a[1], a[2], -DotProduct (a, trans));
Vector4Set (out+4, b[0], b[1], b[2], -DotProduct (b, trans));
Vector4Set (out+8, c[0], c[1], c[2], -DotProduct (c, trans));
}
void Matrix3x4_Invert_Simple (const float *in1, float *out)
{
// we only support uniform scaling, so assume the first row is enough

View File

@ -82,6 +82,7 @@ extern vec3_t vec3_origin;
#define Vector4Copy(a,b) do{(b)[0]=(a)[0];(b)[1]=(a)[1];(b)[2]=(a)[2];(b)[3]=(a)[3];}while(0)
#define Vector4Scale(in,scale,out) ((out)[0]=(in)[0]*scale,(out)[1]=(in)[1]*scale,(out)[2]=(in)[2]*scale,(out)[3]=(in)[3]*scale)
#define Vector4Add(a,b,c) ((c)[0]=(((a[0])+(b[0]))),(c)[1]=(((a[1])+(b[1]))),(c)[2]=(((a[2])+(b[2]))),(c)[3]=(((a[3])+(b[3]))))
#define Vector4Set(r,x,y,z,w) {(r)[0] = x; (r)[1] = y;(r)[2] = z;(r)[3]=w;}
typedef float matrix3x4[3][4];
typedef float matrix3x3[3][3];
@ -140,6 +141,7 @@ mat3x4 is always row-major (and functions can accept many RM mat4x4)
void Matrix3_Multiply (vec3_t *in1, vec3_t *in2, vec3_t *out);
void Matrix4x4_Identity(float *outm);
qboolean Matrix4_Invert(const float *m, float *out);
void Matrix3x4_Invert (const float *in1, float *out);
void Matrix3x4_Invert_Simple (const float *in1, float *out);
void Matrix3x4_InvertTo4x4_Simple (const float *in1, float *out);
void Matrix3x3_RM_Invert_Simple(const vec3_t in[3], vec3_t out[3]);
@ -151,6 +153,7 @@ void Matrix4x4_CM_ModelViewMatrix (float *modelview, const vec3_t viewangles, c
void Matrix4x4_CM_ModelViewMatrixFromAxis (float *modelview, const vec3_t pn, const vec3_t right, const vec3_t up, const vec3_t vieworg);
void Matrix4_CreateFromQuakeEntity (float *matrix, float x, float y, float z, float pitch, float yaw, float roll, float scale);
void Matrix4_Multiply (const float *a, const float *b, float *out);
void Matrix3x4_Multiply(const float *a, const float *b, float *out);
void Matrix4x4_CM_Project (const vec3_t in, vec3_t out, const vec3_t viewangles, const vec3_t vieworg, float fovx, float fovy);
void Matrix4x4_CM_Transform3 (const float *matrix, const float *vector, float *product);
void Matrix4x4_CM_Transform4 (const float *matrix, const float *vector, float *product);

View File

@ -310,6 +310,20 @@ pbool ED_CanFree (edict_t *ed);
#endif
#define MOVETYPE_NONE 0 // never moves
#define MOVETYPE_ANGLENOCLIP 1
#define MOVETYPE_ANGLECLIP 2
#define MOVETYPE_WALK 3 // gravity
#define MOVETYPE_STEP 4 // gravity, special edge handling
#define MOVETYPE_FLY 5
#define MOVETYPE_TOSS 6 // gravity
#define MOVETYPE_PUSH 7 // no clip to world, push and crush
#define MOVETYPE_NOCLIP 8
#define MOVETYPE_FLYMISSILE 9 // extra size to monsters
#define MOVETYPE_BOUNCE 10
#define MOVETYPE_BOUNCEMISSILE 11 // bounce w/o gravity
#define MOVETYPE_FOLLOW 12 // track movement of aiment
#define MOVETYPE_H2PUSHPULL 13 // pushable/pullable object
#define MOVETYPE_H2SWIM 14 // should keep the object in water
#define MOVETYPE_PHYSICS 32
// edict->solid values
@ -318,8 +332,8 @@ pbool ED_CanFree (edict_t *ed);
#define SOLID_BBOX 2 // touch on edge, block
#define SOLID_SLIDEBOX 3 // touch on edge, but not an onground
#define SOLID_BSP 4 // bsp clip, touch on edge, block
#define SOLID_PHASEH2 5
#define SOLID_CORPSE 5
#define SOLID_PHASEH2 5 // hexen2 flag - these ents can be freely walked through or something
#define SOLID_CORPSE 5 // non-solid to solid_slidebox entities and itself.
#define SOLID_LADDER 20 //dmw. touch on edge, not blocking. Touching players have different physics. Otherwise a SOLID_TRIGGER
#define SOLID_PHYSICS_BOX 32 ///< physics object (mins, maxs, mass, origin, axis_forward, axis_left, axis_up, velocity, spinvelocity)
#define SOLID_PHYSICS_SPHERE 33 ///< physics object (mins, maxs, mass, origin, axis_forward, axis_left, axis_up, velocity, spinvelocity)

View File

@ -93,6 +93,7 @@ typedef struct q2trace_s
#define MOVE_TRIGGERS 16 //triggers must be marked with FINDABLE_NONSOLID (an alternative to solid-corpse)
#define MOVE_EVERYTHING 32 //can return triggers and non-solid items if they're marked with FINDABLE_NONSOLID (works even if the items are not properly linked)
#define MOVE_LAGGED 64 //trace touches current last-known-state, instead of actual ents (just affects players for now)
#define MOVE_ENTCHAIN 128 //chain of impacted ents, otherwise result shows only world
typedef struct areanode_s
{
@ -107,6 +108,8 @@ typedef struct areanode_s
#define EDICT_FROM_AREA(l) STRUCT_FROM_LINK(l,wedict_t,area)
typedef struct wedict_s wedict_t;
#define PROG_TO_WEDICT (wedict_t*)PROG_TO_EDICT
#define WEDICT_NUM (wedict_t *)EDICT_NUM
typedef struct
{
@ -117,9 +120,10 @@ typedef struct
struct world_s
{
void (*Event_Touch)(struct world_s *w, wedict_t *s, wedict_t *o);
void (*Event_Think)(struct world_s *w, wedict_t *s);
void (*Event_Sound) (wedict_t *entity, int channel, char *sample, int volume, float attenuation, int pitchadj);
model_t *(*GetCModel)(struct world_s *w, int modelindex);
int *global_self;
unsigned int max_edicts; //limiting factor... 1024 fields*4*MAX_EDICTS == a heck of a lot.
unsigned int num_edicts; // increases towards MAX_EDICTS
/*FTE_DEPRECATED*/ unsigned int edict_size; //still used in copyentity
@ -138,6 +142,15 @@ struct world_s
laggedentinfo_t *lagents;
unsigned int maxlagents;
struct {
int *self;
int *other;
int *newmis;
float *time;
float *frametime;
float *force_retouch;
} g;
#ifdef USEODE
worldode_t ode;
#endif
@ -145,13 +158,13 @@ struct world_s
typedef struct world_s world_t;
#ifdef USEODE
void World_Physics_RemoveFromEntity(world_t *world, wedict_t *ed);
void World_Physics_RemoveJointFromEntity(world_t *world, wedict_t *ed);
void World_Physics_Frame(world_t *world, double frametime, double gravity);
void World_Physics_Init(void);
void World_Physics_Start(world_t *world);
void World_Physics_End(world_t *world);
void World_Physics_Shutdown(void);
void World_ODE_RemoveFromEntity(world_t *world, wedict_t *ed);
void World_ODE_RemoveJointFromEntity(world_t *world, wedict_t *ed);
void World_ODE_Frame(world_t *world, double frametime, double gravity);
void World_ODE_Init(void);
void World_ODE_Start(world_t *world);
void World_ODE_End(world_t *world);
void World_ODE_Shutdown(void);
#endif
void World_ClearWorld (world_t *w);

View File

@ -15,6 +15,8 @@ extern LPDIRECT3DDEVICE9 pD3DDev9;
#define MAX_TMUS 4
extern float d3d_trueprojection[16];
/*========================================== tables for deforms =====================================*/
#define frand() (rand()*(1.0/RAND_MAX))
#define FTABLE_SIZE 1024
@ -126,6 +128,7 @@ typedef struct
unsigned int curcull;
float depthbias;
float depthfactor;
float m_model[16];
unsigned int lastpasscount;
texid_t curtex[MAX_TMUS];
@ -169,13 +172,26 @@ extern int be_maxpasses;
enum
{
D3D_VDEC_COL4B = 1<<0,
//D3D_VDEC_NORMS = 1<<1,
D3D_VDEC_ST0 = 1<<1,
D3D_VDEC_ST1 = 1<<2,
D3D_VDEC_ST2 = 1<<3,
D3D_VDEC_ST3 = 1<<4,
D3D_VDEC_MAX = 1<<5
D3D_VDEC_NORM = 1<<5,
D3D_VDEC_SKEL = 1<<6,
D3D_VDEC_MAX = 1<<7
};
#define STRM_VERT 0
#define STRM_COL 1
#define STRM_TC0 2
#define STRM_TC1 3
#define STRM_TC2 4
#define STRM_TC3 5
#define STRM_NORM 6
#define STRM_NORMS 7
#define STRM_NORMT 8
#define STRM_BONENUM 9
#define STRM_BONEWEIGHT 10
#define STRM_MAX 11
IDirect3DVertexDeclaration9 *vertexdecls[D3D_VDEC_MAX];
static void BE_ApplyTMUState(unsigned int tu, unsigned int flags)
@ -355,7 +371,7 @@ void D3DBE_Reset(qboolean before)
{
IDirect3DDevice9_SetVertexDeclaration(pD3DDev9, NULL);
shaderstate.curvertdecl = 0;
for (i = 0; i < 5+MAX_TMUS; i++)
for (i = 0; i < STRM_MAX; i++)
IDirect3DDevice9_SetStreamSource(pD3DDev9, i, NULL, 0, 0);
IDirect3DDevice9_SetIndices(pD3DDev9, NULL);
@ -384,13 +400,13 @@ void D3DBE_Reset(qboolean before)
}
else
{
D3DVERTEXELEMENT9 decl[8], declend=D3DDECL_END();
D3DVERTEXELEMENT9 decl[13], declend=D3DDECL_END();
int elements;
for (i = 0; i < D3D_VDEC_MAX; i++)
{
elements = 0;
decl[elements].Stream = 0;
decl[elements].Stream = STRM_VERT;
decl[elements].Offset = 0;
decl[elements].Type = D3DDECLTYPE_FLOAT3;
decl[elements].Method = D3DDECLMETHOD_DEFAULT;
@ -400,7 +416,7 @@ void D3DBE_Reset(qboolean before)
if (i & D3D_VDEC_COL4B)
{
decl[elements].Stream = 1;
decl[elements].Stream = STRM_COL;
decl[elements].Offset = 0;
decl[elements].Type = D3DDECLTYPE_D3DCOLOR;
decl[elements].Method = D3DDECLMETHOD_DEFAULT;
@ -409,38 +425,38 @@ void D3DBE_Reset(qboolean before)
elements++;
}
/* if (i & D3D_VDEC_NORMS)
if (i & D3D_VDEC_NORM)
{
decl[elements].Stream = 2;
decl[elements].Stream = STRM_NORM;
decl[elements].Offset = 0;
decl[elements].Type = D3DDECLTYPE_FLOAT2;
decl[elements].Type = D3DDECLTYPE_FLOAT3;
decl[elements].Method = D3DDECLMETHOD_DEFAULT;
decl[elements].Usage = D3DDECLUSAGE_TEXCOORD;
decl[elements].UsageIndex = 1;
decl[elements].Usage = D3DDECLUSAGE_NORMAL;
decl[elements].UsageIndex = 0;
elements++;
decl[elements].Stream = 3;
decl[elements].Stream = STRM_NORMS;
decl[elements].Offset = 0;
decl[elements].Type = D3DDECLTYPE_FLOAT2;
decl[elements].Type = D3DDECLTYPE_FLOAT3;
decl[elements].Method = D3DDECLMETHOD_DEFAULT;
decl[elements].Usage = D3DDECLUSAGE_TEXCOORD;
decl[elements].UsageIndex = 1;
decl[elements].Usage = D3DDECLUSAGE_TANGENT;
decl[elements].UsageIndex = 0;
elements++;
decl[elements].Stream = 4;
decl[elements].Stream = STRM_NORMT;
decl[elements].Offset = 0;
decl[elements].Type = D3DDECLTYPE_FLOAT2;
decl[elements].Type = D3DDECLTYPE_FLOAT3;
decl[elements].Method = D3DDECLMETHOD_DEFAULT;
decl[elements].Usage = D3DDECLUSAGE_TEXCOORD;
decl[elements].UsageIndex = 1;
decl[elements].Usage = D3DDECLUSAGE_BINORMAL;
decl[elements].UsageIndex = 0;
elements++;
}
*/
for (tmu = 0; tmu < MAX_TMUS; tmu++)
{
if (i & (D3D_VDEC_ST0<<tmu))
{
decl[elements].Stream = 5+tmu;
decl[elements].Stream = STRM_TC0+tmu;
decl[elements].Offset = 0;
decl[elements].Type = D3DDECLTYPE_FLOAT2;
decl[elements].Method = D3DDECLMETHOD_DEFAULT;
@ -450,6 +466,25 @@ void D3DBE_Reset(qboolean before)
}
}
if (i & D3D_VDEC_SKEL)
{
decl[elements].Stream = STRM_BONEWEIGHT;
decl[elements].Offset = 0;
decl[elements].Type = D3DDECLTYPE_FLOAT3;
decl[elements].Method = D3DDECLMETHOD_DEFAULT;
decl[elements].Usage = D3DDECLUSAGE_BLENDWEIGHT;
decl[elements].UsageIndex = 0;
elements++;
decl[elements].Stream = STRM_BONENUM;
decl[elements].Offset = 0;
decl[elements].Type = D3DDECLTYPE_FLOAT3;
decl[elements].Method = D3DDECLMETHOD_DEFAULT;
decl[elements].Usage = D3DDECLUSAGE_BLENDINDICES;
decl[elements].UsageIndex = 0;
elements++;
}
decl[elements] = declend;
elements++;
@ -940,7 +975,7 @@ static unsigned int BE_GenerateColourMods(unsigned int vertcount, const shaderpa
colourgenbyte(pass, 1, (byte_vec4_t*)&shaderstate.passcolour, (byte_vec4_t*)&shaderstate.passcolour, m);
alphagenbyte(pass, 1, (byte_vec4_t*)&shaderstate.passcolour, (byte_vec4_t*)&shaderstate.passcolour, m);
/*FIXME: just because there's no rgba set, there's no reason to assume it should be a single colour (unshaded ents)*/
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, 1, NULL, 0, 0));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_COL, NULL, 0, 0));
}
else
{
@ -1005,7 +1040,7 @@ static unsigned int BE_GenerateColourMods(unsigned int vertcount, const shaderpa
}
}
d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dyncol_buff));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, 1, shaderstate.dyncol_buff, shaderstate.dyncol_offs - vertcount*sizeof(D3DCOLOR), sizeof(D3DCOLOR)));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_COL, shaderstate.dyncol_buff, shaderstate.dyncol_offs - vertcount*sizeof(D3DCOLOR), sizeof(D3DCOLOR)));
}
return ret;
}
@ -1478,13 +1513,13 @@ static qboolean BE_DrawMeshChain_SetupPass(shaderpass_t *pass, unsigned int vert
allocvertexbuffer(shaderstate.dynst_buff[tmu], shaderstate.dynst_size, &shaderstate.dynst_offs[tmu], &map, vertcount*sizeof(vec2_t));
GenerateTCMods(pass+passno, map);
d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dynst_buff[tmu]));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, 5+tmu, shaderstate.dynst_buff[tmu], shaderstate.dynst_offs[tmu] - vertcount*sizeof(vec2_t), sizeof(vec2_t)));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0+tmu, shaderstate.dynst_buff[tmu], shaderstate.dynst_offs[tmu] - vertcount*sizeof(vec2_t), sizeof(vec2_t)));
tmu++;
}
/*deactivate any extras*/
for (; tmu < shaderstate.lastpasscount; )
{
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, 5+tmu, NULL, 0, 0));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0+tmu, NULL, 0, 0));
BindTexture(tmu, NULL);
d3dcheck(IDirect3DDevice9_SetTextureStageState(pD3DDev9, tmu, D3DTSS_COLOROP, D3DTOP_DISABLE));
tmu++;
@ -1506,13 +1541,193 @@ static qboolean BE_DrawMeshChain_SetupPass(shaderpass_t *pass, unsigned int vert
return true;
}
static void BE_ApplyUniforms(program_t *prog, int permu)
{
int i;
IDirect3DDevice9_SetVertexShader(pD3DDev9, prog->handle[permu].hlsl.vert);
IDirect3DDevice9_SetPixelShader(pD3DDev9, prog->handle[permu].hlsl.frag);
for (i = 0; i < prog->numparams; i++)
{
switch (prog->parm[i].type)
{
case SP_M_PROJECTION:
IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, prog->parm[i].handle[permu], d3d_trueprojection, 4);
break;
case SP_M_VIEW:
IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, prog->parm[i].handle[permu], r_refdef.m_view, 4);
break;
// case SP_M_MODEL:
// IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, prog->parm[i].handle[permu], r_refdef.m_view, 4);
// break;
case SP_V_EYEPOS:
IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, prog->parm[i].handle[permu], r_origin, 1);
break;
case SP_E_EYEPOS:
{
vec4_t t2;
float m16[16];
Matrix4x4_CM_ModelMatrixFromAxis(m16, shaderstate.curentity->axis[0], shaderstate.curentity->axis[1], shaderstate.curentity->axis[2], shaderstate.curentity->origin);
Matrix4x4_CM_Transform3(m16, r_origin, t2);
IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, prog->parm[i].handle[permu], t2, 1);
}
break;
case SP_E_TIME:
{
vec4_t t1 = {shaderstate.curtime};
IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, prog->parm[i].handle[permu], t1, 1);
}
break;
case SP_M_MODELVIEWPROJECTION:
{
float mv[16], mvp[16];
Matrix4_Multiply(r_refdef.m_view, shaderstate.m_model, mv);
Matrix4_Multiply(d3d_trueprojection, mv, mvp);
IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, prog->parm[i].handle[permu], mvp, 4);
}
break;
case SP_E_COLOURS:
case SP_E_COLOURSIDENT:
case SP_E_TOPCOLOURS:
case SP_E_BOTTOMCOLOURS:
case SP_E_L_DIR:
case SP_E_L_MUL:
case SP_E_L_AMBIENT:
case SP_M_ENTBONES:
case SP_M_MODEL:
case SP_M_MODELVIEW:
case SP_RENDERTEXTURESCALE:
case SP_LIGHTRADIUS:
case SP_LIGHTCOLOUR:
case SP_LIGHTPOSITION:
case SP_FIRSTIMMEDIATE:
case SP_CONSTI:
case SP_CONSTF:
case SP_CVARI:
case SP_CVARF:
case SP_CVAR3F:
case SP_TEXTURE:
Con_Printf("shader property %i not implemented\n", prog->parm[i].type);
break;
}
}
}
static void BE_RenderMeshProgram(unsigned int vertcount, unsigned int idxfirst, unsigned int idxcount)
{
int vdec = D3D_VDEC_ST0;
int passno;
shader_t *s = shaderstate.curshader;
//shaderpass_t *pass = s->passes; //unused variable
IDirect3DDevice9_SetVertexShader(pD3DDev9, s->prog->handle[0].hlsl.vert);
IDirect3DDevice9_SetPixelShader(pD3DDev9, s->prog->handle[0].hlsl.frag);
D3DBE_ApplyShaderBits(shaderstate.curshader->passes->shaderbits);
BE_ApplyUniforms(s->prog, 0);
/*activate tmus*/
for (passno = 0; passno < s->numpasses; passno++)
{
SelectPassTexture(passno, s->passes+passno);
}
/*deactivate any extras*/
for (; passno < shaderstate.lastpasscount; passno++)
{
BindTexture(passno, NULL);
d3dcheck(IDirect3DDevice9_SetTextureStageState(pD3DDev9, passno, D3DTSS_COLOROP, D3DTOP_DISABLE));
}
shaderstate.lastpasscount = passno;
/*colours*/
if (vdec & D3D_VDEC_COL4B)
{
int mno,v;
void *map;
mesh_t *m;
allocvertexbuffer(shaderstate.dynst_buff[0], shaderstate.dynst_size, &shaderstate.dynst_offs[0], &map, vertcount*sizeof(byte_vec4_t));
for (mno = 0, vertcount = 0; mno < shaderstate.nummeshes; mno++)
{
byte_vec4_t *dest = (byte_vec4_t*)((char*)map+vertcount*sizeof(byte_vec4_t));
m = shaderstate.meshlist[mno];
if (m->colors4f_array)
{
for (v = 0; v < m->numvertexes; v++)
{
dest[v][0] = bound(0, m->colors4f_array[v][0] * 255, 255);
dest[v][1] = bound(0, m->colors4f_array[v][1] * 255, 255);
dest[v][2] = bound(0, m->colors4f_array[v][2] * 255, 255);
dest[v][3] = bound(0, m->colors4f_array[v][3] * 255, 255);
}
}
else if (m->colors4b_array)
memcpy(dest, m->colors4b_array, m->numvertexes*sizeof(byte_vec4_t));
else
memset(dest, 0, m->numvertexes*sizeof(byte_vec4_t));
vertcount += m->numvertexes;
}
d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dynst_buff[0]));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0, shaderstate.dynst_buff[0], shaderstate.dynst_offs[0] - vertcount*sizeof(byte_vec4_t), sizeof(byte_vec4_t)));
}
/*texture coords*/
if (vdec & D3D_VDEC_ST0)
{
int mno;
void *map;
mesh_t *m;
allocvertexbuffer(shaderstate.dynst_buff[0], shaderstate.dynst_size, &shaderstate.dynst_offs[0], &map, vertcount*sizeof(vec2_t));
for (mno = 0, vertcount = 0; mno < shaderstate.nummeshes; mno++)
{
vec2_t *dest = (vec2_t*)((char*)map+vertcount*sizeof(vec2_t));
m = shaderstate.meshlist[mno];
memcpy(dest, m->st_array, m->numvertexes*sizeof(vec2_t));
vertcount += m->numvertexes;
}
d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dynst_buff[0]));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0, shaderstate.dynst_buff[0], shaderstate.dynst_offs[0] - vertcount*sizeof(vec2_t), sizeof(vec2_t)));
}
/*lm coords*/
if (vdec & D3D_VDEC_ST1)
{
int mno;
void *map;
mesh_t *m;
allocvertexbuffer(shaderstate.dynst_buff[1], shaderstate.dynst_size, &shaderstate.dynst_offs[1], &map, vertcount*sizeof(vec2_t));
for (mno = 0, vertcount = 0; mno < shaderstate.nummeshes; mno++)
{
vec2_t *dest = (vec2_t*)((char*)map+vertcount*sizeof(vec2_t));
m = shaderstate.meshlist[mno];
memcpy(dest, m->lmst_array, m->numvertexes*sizeof(vec2_t));
vertcount += m->numvertexes;
}
d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dynst_buff[1]));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0, shaderstate.dynst_buff[1], shaderstate.dynst_offs[1] - vertcount*sizeof(vec2_t), sizeof(vec2_t)));
}
/*normals/tangents/bitangents*/
if (vdec & D3D_VDEC_NORM)
{
/*FIXME*/
vdec &= ~D3D_VDEC_NORM;
}
/*bone weights+indexes*/
if (vdec & D3D_VDEC_SKEL)
{
/*FIXME*/
vdec &= ~D3D_VDEC_NORM;
}
if (vdec != shaderstate.curvertdecl)
{
shaderstate.curvertdecl = vdec;
d3dcheck(IDirect3DDevice9_SetVertexDeclaration(pD3DDev9, vertexdecls[shaderstate.curvertdecl]));
}
// IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9,
d3dcheck(IDirect3DDevice9_DrawIndexedPrimitive(pD3DDev9, D3DPT_TRIANGLELIST, 0, 0, vertcount, idxfirst, idxcount/3));
@ -1597,7 +1812,7 @@ static void BE_DrawMeshChain_Internal(void)
vertcount += m->numvertexes;
}
d3dcheck(IDirect3DVertexBuffer9_Unlock(shaderstate.dynxyz_buff));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, 0, shaderstate.dynxyz_buff, shaderstate.dynxyz_offs - vertcount*sizeof(vecV_t), sizeof(vecV_t)));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_VERT, shaderstate.dynxyz_buff, shaderstate.dynxyz_offs - vertcount*sizeof(vecV_t), sizeof(vecV_t)));
/*so are index buffers*/
idxfirst = allocindexbuffer(&map, idxcount);
@ -1626,7 +1841,7 @@ static void BE_DrawMeshChain_Internal(void)
/*deactivate any extras*/
for (passno = 0; passno < shaderstate.lastpasscount; )
{
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, 5+passno, NULL, 0, 0));
d3dcheck(IDirect3DDevice9_SetStreamSource(pD3DDev9, STRM_TC0+passno, NULL, 0, 0));
BindTexture(passno, NULL);
d3dcheck(IDirect3DDevice9_SetTextureStageState(pD3DDev9, passno, D3DTSS_COLOROP, D3DTOP_DISABLE));
passno++;
@ -1900,7 +2115,7 @@ batch_t *D3DBE_GetTempBatch(void)
static void BE_RotateForEntity (const entity_t *e, const model_t *mod)
{
float mv[16];
float m[16];
float *m = shaderstate.m_model;
shaderstate.curentity = e;
@ -2072,9 +2287,12 @@ static void BE_SubmitMeshesSortList(batch_t *sortlist)
if (batch->shader->flags & SHADER_SKY)
{
if (shaderstate.mode == BEM_STANDARD)
R_DrawSkyChain (batch);
continue;
if (!batch->shader->prog)
{
if (shaderstate.mode == BEM_STANDARD)
R_DrawSkyChain (batch);
continue;
}
}
BE_SubmitBatch(batch);
@ -2209,7 +2427,7 @@ static void TransformDir(vec3_t in, vec3_t planea[3], vec3_t viewa[3], vec3_t re
}
static void R_RenderScene(void)
{
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_PROJECTION, (D3DMATRIX*)r_refdef.m_projection);
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_PROJECTION, (D3DMATRIX*)d3d_trueprojection);
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_VIEW, (D3DMATRIX*)r_refdef.m_view);
R_SetFrustum (r_refdef.m_projection, r_refdef.m_view);
Surf_DrawWorld();
@ -2320,7 +2538,7 @@ static void R_DrawPortal(batch_t *batch, batch_t **blist)
AngleVectors (r_refdef.viewangles, vpn, vright, vup);
VectorCopy (r_refdef.vieworg, r_origin);
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_PROJECTION, (D3DMATRIX*)r_refdef.m_projection);
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_PROJECTION, (D3DMATRIX*)d3d_trueprojection);
IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_VIEW, (D3DMATRIX*)r_refdef.m_view);
R_SetFrustum (r_refdef.m_projection, r_refdef.m_view);
}

View File

@ -15,8 +15,8 @@ typedef struct {
LPCSTR Definition;
} D3DXMACRO;
#define D3DXHANDLE void *
#define LPD3DXINCLUDE void *
#define LPD3DXCONSTANTTABLE void *
#undef INTERFACE
#define INTERFACE d3dxbuffer
@ -31,6 +31,96 @@ DECLARE_INTERFACE_(d3dxbuffer,IUnknown)
};
typedef struct d3dxbuffer *LPD3DXBUFFER;
typedef enum _D3DXREGISTER_SET
{
D3DXRS_BOOL,
D3DXRS_INT4,
D3DXRS_FLOAT4,
D3DXRS_SAMPLER,
D3DXRS_FORCE_DWORD = 0x7fffffff
} D3DXREGISTER_SET, *LPD3DXREGISTER_SET;
typedef enum _D3DXPARAMETER_CLASS
{
D3DXPC_SCALAR,
D3DXPC_VECTOR,
D3DXPC_MATRIX_ROWS,
D3DXPC_MATRIX_COLUMNS,
D3DXPC_OBJECT,
D3DXPC_STRUCT,
D3DXPC_FORCE_DWORD = 0x7fffffff
} D3DXPARAMETER_CLASS, *LPD3DXPARAMETER_CLASS;
typedef enum _D3DXPARAMETER_TYPE
{
D3DXPT_VOID,
D3DXPT_BOOL,
D3DXPT_INT,
D3DXPT_FLOAT,
D3DXPT_STRING,
D3DXPT_TEXTURE,
D3DXPT_TEXTURE1D,
D3DXPT_TEXTURE2D,
D3DXPT_TEXTURE3D,
D3DXPT_TEXTURECUBE,
D3DXPT_SAMPLER,
D3DXPT_SAMPLER1D,
D3DXPT_SAMPLER2D,
D3DXPT_SAMPLER3D,
D3DXPT_SAMPLERCUBE,
D3DXPT_PIXELSHADER,
D3DXPT_VERTEXSHADER,
D3DXPT_PIXELFRAGMENT,
D3DXPT_VERTEXFRAGMENT,
} D3DXPARAMETER_TYPE, *LPD3DXPARAMETER_TYPE;
typedef struct _D3DXCONSTANT_DESC
{
LPCSTR Name; // Constant name
D3DXREGISTER_SET RegisterSet; // Register set
UINT RegisterIndex; // Register index
UINT RegisterCount; // Number of registers occupied
D3DXPARAMETER_CLASS Class; // Class
D3DXPARAMETER_TYPE Type; // Component type
UINT Rows; // Number of rows
UINT Columns; // Number of columns
UINT Elements; // Number of array elements
UINT StructMembers; // Number of structure member sub-parameters
UINT Bytes; // Data size, in bytes
LPCVOID DefaultValue; // Pointer to default value
} D3DXCONSTANT_DESC, *LPD3DXCONSTANT_DESC;
typedef struct _D3DXCONSTANTTABLE_DESC
{
LPCSTR Creator; // Creator string
DWORD Version; // Shader version
UINT Constants; // Number of constants
} D3DXCONSTANTTABLE_DESC, *LPD3DXCONSTANTTABLE_DESC;
#undef INTERFACE
#define INTERFACE d3dxconstanttable
DECLARE_INTERFACE_(d3dxconstanttable,IUnknown)
{
STDMETHOD(QueryInterface)(THIS_ REFIID,PVOID*) PURE;
STDMETHOD_(ULONG,AddRef)(THIS) PURE;
STDMETHOD_(ULONG,Release)(THIS) PURE;
STDMETHOD_(LPVOID,GetBufferPointer)(THIS) PURE;
STDMETHOD_(SIZE_T,GetBufferSize)(THIS) PURE;
STDMETHOD(GetDesc)(THIS_ D3DXCONSTANTTABLE_DESC *pDesc) PURE;
STDMETHOD(GetConstantDesc)(THIS_ D3DXHANDLE hConstant, D3DXCONSTANT_DESC *pConstantDesc, UINT *pCount) PURE;
STDMETHOD_(D3DXHANDLE, GetConstant)(THIS_ D3DXHANDLE hConstant, UINT Index) PURE;
STDMETHOD_(D3DXHANDLE, GetConstantByName)(THIS_ D3DXHANDLE hConstant, LPCSTR pName) PURE;
STDMETHOD_(D3DXHANDLE, GetConstantElement)(THIS_ D3DXHANDLE hConstant, UINT Index) PURE;
/*more stuff not included here cos I don't need it*/
};
typedef struct d3dxconstanttable *LPD3DXCONSTANTTABLE;
HRESULT (WINAPI *pD3DXCompileShader) (
LPCSTR pSrcData,
@ -58,29 +148,36 @@ void D3DShader_Init(void)
if (!shaderlib)
shaderlib = Sys_LoadLibrary("d3dx9_32", funcs);
if (!shaderlib)
shaderlib = Sys_LoadLibrary("d3dx9_34", funcs);
if (!shaderlib)
return;
}
union programhandle_u D3DShader_CreateProgram (char **precompilerconstants, char *vert, char *frag)
void D3DShader_CreateProgram (program_t *prog, int permu, char **precompilerconstants, char *vert, char *frag)
{
union programhandle_u ret;
int i, j, k;
D3DXMACRO defines[64];
LPD3DXBUFFER code = NULL, errors = NULL;
memset(&ret, 0, sizeof(ret));
D3DXCONSTANTTABLE_DESC ctd;
D3DXHANDLE ch;
D3DXCONSTANT_DESC d;
UINT dc;
prog->handle[permu].hlsl.vert = NULL;
prog->handle[permu].hlsl.frag = NULL;
if (pD3DXCompileShader)
{
int consts;
for (consts = 2; precompilerconstants[consts]; consts++)
{
}
;
if (consts >= sizeof(defines) / sizeof(defines[0]))
return ret;
return;
consts = 0;
defines[consts].Name = NULL;
defines[consts].Name = NULL; /*shader type*/
defines[consts].Definition = "1";
consts++;
@ -99,9 +196,9 @@ union programhandle_u D3DShader_CreateProgram (char **precompilerconstants, char
defines[consts].Definition = NULL;
defines[0].Name = "VERTEX_SHADER";
if (!FAILED(pD3DXCompileShader(vert, strlen(vert), defines, NULL, "main", "vs_2_0", 0, &code, &errors, NULL)))
if (!FAILED(pD3DXCompileShader(vert, strlen(vert), defines, NULL, "main", "vs_2_0", 0, &code, &errors, (LPD3DXCONSTANTTABLE*)&prog->handle[permu].hlsl.ctabv)))
{
IDirect3DDevice9_CreateVertexShader(pD3DDev9, code->lpVtbl->GetBufferPointer(code), (IDirect3DVertexShader9**)&ret.hlsl.vert);
IDirect3DDevice9_CreateVertexShader(pD3DDev9, code->lpVtbl->GetBufferPointer(code), (IDirect3DVertexShader9**)&prog->handle[permu].hlsl.vert);
code->lpVtbl->Release(code);
}
if (errors)
@ -112,9 +209,9 @@ union programhandle_u D3DShader_CreateProgram (char **precompilerconstants, char
}
defines[0].Name = "FRAGMENT_SHADER";
if (!FAILED(pD3DXCompileShader(frag, strlen(frag), defines, NULL, "main", "ps_2_0", 0, &code, &errors, NULL)))
if (!FAILED(pD3DXCompileShader(frag, strlen(frag), defines, NULL, "main", "ps_2_0", 0, &code, &errors, (LPD3DXCONSTANTTABLE*)&prog->handle[permu].hlsl.ctabf)))
{
IDirect3DDevice9_CreatePixelShader(pD3DDev9, code->lpVtbl->GetBufferPointer(code), (IDirect3DPixelShader9**)&ret.hlsl.frag);
IDirect3DDevice9_CreatePixelShader(pD3DDev9, code->lpVtbl->GetBufferPointer(code), (IDirect3DPixelShader9**)&prog->handle[permu].hlsl.frag);
code->lpVtbl->Release(code);
}
if (errors)
@ -124,7 +221,37 @@ union programhandle_u D3DShader_CreateProgram (char **precompilerconstants, char
errors->lpVtbl->Release(errors);
}
}
}
return ret;
static int D3DShader_FindUniform_(LPD3DXCONSTANTTABLE ct, char *name)
{
if (ct)
{
UINT dc = 1;
D3DXCONSTANT_DESC d;
if (!FAILED(ct->lpVtbl->GetConstantDesc(ct, name, &d, &dc)))
return d.RegisterIndex;
}
return -1;
}
int D3DShader_FindUniform(union programhandle_u *h, int type, char *name)
{
int offs;
if (!type || type == 1)
{
offs = D3DShader_FindUniform_(h->hlsl.ctabv, name);
if (offs >= 0)
return offs;
}
if (!type || type == 2)
{
offs = D3DShader_FindUniform_(h->hlsl.ctabf, name);
if (offs >= 0)
return offs;
}
return -1;
}
#endif

View File

@ -58,6 +58,7 @@ static void resetD3D9(void);
static LPDIRECT3D9 pD3D;
LPDIRECT3DDEVICE9 pD3DDev9;
static D3DPRESENT_PARAMETERS d3dpp;
float d3d_trueprojection[16];
static qboolean vid_initializing;
@ -1180,8 +1181,8 @@ static void D3D9_SetupViewPort(void)
d3d9error(IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_VIEW, (D3DMATRIX*)r_refdef.m_view));
/*d3d projection matricies scale depth to 0 to 1*/
Matrix4x4_CM_Projection_Inf(r_refdef.m_projection, fov_x, fov_y, gl_mindist.value/2);
d3d9error(IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_PROJECTION, (D3DMATRIX*)r_refdef.m_projection));
Matrix4x4_CM_Projection_Inf(d3d_trueprojection, fov_x, fov_y, gl_mindist.value/2);
d3d9error(IDirect3DDevice9_SetTransform(pD3DDev9, D3DTS_PROJECTION, (D3DMATRIX*)d3d_trueprojection));
/*ogl projection matricies scale depth to -1 to 1, and I would rather my code used consistant culling*/
Matrix4x4_CM_Projection_Inf(r_refdef.m_projection, fov_x, fov_y, gl_mindist.value);
}

View File

@ -709,6 +709,7 @@
/>
<Tool
Name="VCManifestTool"
EmbedManifest="false"
UseFAT32Workaround="true"
/>
<Tool
@ -12971,194 +12972,6 @@
/>
</FileConfiguration>
</File>
<File
RelativePath="..\client\renderer.c"
>
<FileConfiguration
Name="MinGLDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<File
RelativePath="..\client\renderque.c"
>
@ -28386,6 +28199,194 @@
RelativePath="..\client\r_surf.c"
>
</File>
<File
RelativePath="..\client\renderer.c"
>
<FileConfiguration
Name="MinGLDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MinGLRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Release Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|Win32"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="Debug Dedicated Server|x64"
ExcludedFromBuild="true"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MDebug|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="MDebug|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="GLRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DRelease|Win32"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
<FileConfiguration
Name="D3DRelease|x64"
>
<Tool
Name="VCCLCompilerTool"
AdditionalIncludeDirectories=""
PreprocessorDefinitions=""
/>
</FileConfiguration>
</File>
<Filter
Name="gl"
>

View File

@ -1027,7 +1027,7 @@ void R_GAlias_GenerateBatches(entity_t *e, batch_t **batches)
if (e->flags & Q2RF_TRANSLUCENT)
{
b->flags |= BEF_FORCETRANSPARENT;
if (sort < SHADER_SORT_BLEND)
if (SHADER_SORT_PORTAL < sort && sort < SHADER_SORT_BLEND)
sort = SHADER_SORT_BLEND;
}
if (e->flags & RF_NODEPTHTEST)
@ -1821,7 +1821,7 @@ static void R_Sprite_GenerateBatch(entity_t *e, batch_t **batches, void (*drawfu
if (e->flags & Q2RF_TRANSLUCENT || (gl_blendsprites.ival && drawfunc == R_DB_Sprite))
{
b->flags |= BEF_FORCETRANSPARENT;
if (sort < SHADER_SORT_BLEND)
if (SHADER_SORT_PORTAL < sort && sort < SHADER_SORT_BLEND)
sort = SHADER_SORT_BLEND;
}
if (e->flags & RF_NODEPTHTEST)

View File

@ -30,7 +30,7 @@ uniform mat4 entmatrix;\n\
#define LIGHTPASS_GLSL_VERTEX "\
#ifdef VERTEX_SHADER\n\
\
uniform vec3 lightposition;\n\
uniform vec3 l_lightposition;\n\
\
#if defined(SPECULAR) || defined(OFFSETMAPPING)\n\
uniform vec3 eyeposition;\n\
@ -47,7 +47,7 @@ void main (void)\n\
\
tcbase = v_texcoord; //pass the texture coords straight through\n\
\
vec3 lightminusvertex = lightposition - v_position.xyz;\n\
vec3 lightminusvertex = l_lightposition - v_position.xyz;\n\
lightvector.x = dot(lightminusvertex, v_svector.xyz);\n\
lightvector.y = dot(lightminusvertex, v_tvector.xyz);\n\
lightvector.z = dot(lightminusvertex, v_normal.xyz);\n\
@ -59,7 +59,7 @@ void main (void)\n\
eyevector.z = dot(eyeminusvertex, v_normal.xyz);\n\
#endif\n\
#if defined(PCF) || defined(SPOT) || defined(PROJECTION)\n\
vshadowcoord = gl_TextureMatrix[7] * (entmatrix*v_position);\n\
vshadowcoord = gl_TextureMatrix[7] * (entmatrix*vec4(v_position.xyz, 1.0));\n\
#endif\n\
}\n\
#endif\n\
@ -68,8 +68,8 @@ void main (void)\n\
/*this is full 4*4 PCF, with an added attempt at prenumbra*/
/*the offset consts are 1/(imagesize*2) */
#define PCF16P(f) "\
float xPixelOffset = (1.0+shadowcoord.b/lightradius)/texx;\
float yPixelOffset = (1.0+shadowcoord.b/lightradius)/texy;\
float xPixelOffset = (1.0+shadowcoord.b/l_lightradius)/texx;\
float yPixelOffset = (1.0+shadowcoord.b/l_lightradius)/texy;\
float s = 0.0;\n\
s += "f"Proj(shadowmap, shadowcoord + vec4(-1.5 * xPixelOffset * shadowcoord.w, -1.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
s += "f"Proj(shadowmap, shadowcoord + vec4(-1.5 * xPixelOffset * shadowcoord.w, -0.5 * yPixelOffset * shadowcoord.w, 0.05, 0.0)).r;\n\
@ -153,8 +153,8 @@ uniform sampler2DShadow shadowmap;\n\
#endif\n\
\
\
uniform float lightradius;\n\
uniform vec3 lightcolour;\n\
uniform float l_lightradius;\n\
uniform vec3 l_lightcolour;\n\
\
#ifdef OFFSETMAPPING\n\
uniform float offsetmapping_scale;\n\
@ -188,7 +188,7 @@ void main (void)\n\
#endif\n\
\
vec3 nl = normalize(lightvector);\n\
float colorscale = max(1.0 - dot(lightvector, lightvector)/(lightradius*lightradius), 0.0);\n\
float colorscale = max(1.0 - dot(lightvector, lightvector)/(l_lightradius*l_lightradius), 0.0);\n\
\
#ifdef BUMP\n\
vec3 diff;\n\
@ -224,10 +224,10 @@ if (shadowcoord.w < 0.0) discard;\n\
vec2 spot = ((shadowcoord.st)/shadowcoord.w - 0.5)*2.0;colorscale*=1.0-(dot(spot,spot));\n\
#endif\n\
#if defined(PROJECTION)\n\
lightcolour *= texture2d(projected, shadowcoord);\n\
l_lightcolour *= texture2d(projected, shadowcoord);\n\
#endif\n\
\n\
gl_FragColor.rgb = diff*colorscale*lightcolour;\n\
gl_FragColor.rgb = diff*colorscale*l_lightcolour;\n\
}\n\
\
#endif\n\
@ -257,11 +257,6 @@ static const char LIGHTPASS_SHADER[] = "\
param texture 0 baset\n\
param opt texture 1 bumpt\n\
param opt texture 2 speculart\n\
\
//light info\n\
param lightpos lightposition\n\
param lightradius lightradius\n\
param lightcolour lightcolour\n\
\
param opt cvarf r_glsl_offsetmapping_bias offsetmapping_bias\n\
param opt cvarf r_glsl_offsetmapping_scale offsetmapping_scale\n\
@ -301,11 +296,6 @@ static const char PCFPASS_SHADER[] = "\
param texture 1 baset\n\
param opt texture 2 bumpt\n\
param opt texture 3 speculart\n\
\
//light info\n\
param lightpos lightposition\n\
param lightradius lightradius\n\
param lightcolour lightcolour\n\
\
param opt cvarf r_glsl_offsetmapping_scale offsetmapping_scale\n\
\
@ -354,6 +344,14 @@ struct {
qboolean initedspotpasses;
const shader_t *spotpassshader;
qboolean initeddepthnorm;
const shader_t *depthnormshader;
texid_t tex_normals;
texid_t tex_diffuse;
int fbo_diffuse;
texid_t tex_sourcecol; /*this is used by $sourcecolour tgen*/
texid_t tex_sourcedepth;
qboolean force2d;
int currenttmu;
int blendmode[SHADER_PASS_MAX];
@ -923,6 +921,13 @@ static void Shader_BindTextureForPass(int tmu, const shaderpass_t *pass, qboolea
case T_GEN_CURRENTRENDER:
T_Gen_CurrentRender(tmu);
return;
case T_GEN_SOURCECOLOUR:
t = shaderstate.tex_sourcecol;
break;
case T_GEN_SOURCEDEPTH:
t = shaderstate.tex_sourcedepth;
break;
}
GL_LazyBind(tmu, GL_TEXTURE_2D, t, useclientarray);
}
@ -1100,6 +1105,16 @@ void GLBE_Init(void)
shaderstate.fogtexture = r_nulltex;
//make sure the world draws correctly
r_worldentity.shaderRGBAf[0] = 1;
r_worldentity.shaderRGBAf[1] = 1;
r_worldentity.shaderRGBAf[2] = 1;
r_worldentity.shaderRGBAf[3] = 1;
r_worldentity.axis[0][0] = 1;
r_worldentity.axis[1][1] = 1;
r_worldentity.axis[2][2] = 1;
}
//end tables
@ -2358,14 +2373,20 @@ static unsigned int BE_Program_Set_Attribute(const shaderprogparm_t *p, unsigned
qglVertexAttribPointer(p->handle[perm], 2, GL_FLOAT, GL_FALSE, sizeof(vec2_t), shaderstate.sourcevbo->lmcoord);
return 1u<<p->handle[perm];
case SP_ATTR_NORMALS:
if (!shaderstate.sourcevbo->normals)
return 0;
GL_SelectVBO(shaderstate.sourcevbo->vbonormals);
qglVertexAttribPointer(p->handle[perm], 3, GL_FLOAT, GL_FALSE, sizeof(vec3_t), shaderstate.sourcevbo->normals);
return 1u<<p->handle[perm];
case SP_ATTR_SNORMALS:
if (!shaderstate.sourcevbo->normals)
return 0;
GL_SelectVBO(shaderstate.sourcevbo->vbosvector);
qglVertexAttribPointer(p->handle[perm], 3, GL_FLOAT, GL_FALSE, sizeof(vec3_t), shaderstate.sourcevbo->svector);
return 1u<<p->handle[perm];
case SP_ATTR_TNORMALS:
if (!shaderstate.sourcevbo->normals)
return 0;
GL_SelectVBO(shaderstate.sourcevbo->vbotvector);
qglVertexAttribPointer(p->handle[perm], 3, GL_FLOAT, GL_FALSE, sizeof(vec3_t), shaderstate.sourcevbo->tvector);
return 1u<<p->handle[perm];
@ -2378,20 +2399,31 @@ static unsigned int BE_Program_Set_Attribute(const shaderprogparm_t *p, unsigned
qglVertexAttribPointer(p->handle[perm], 4, GL_FLOAT, GL_FALSE, sizeof(vec4_t), shaderstate.sourcevbo->boneweights);
return 1u<<p->handle[perm];
case SP_VIEWMATRIX:
case SP_M_VIEW:
qglUniformMatrix4fvARB(p->handle[perm], 1, false, r_refdef.m_view);
break;
case SP_PROJECTIONMATRIX:
case SP_M_PROJECTION:
qglUniformMatrix4fvARB(p->handle[perm], 1, false, r_refdef.m_projection);
break;
case SP_MODELVIEWMATRIX:
case SP_M_MODELVIEW:
qglUniformMatrix4fvARB(p->handle[perm], 1, false, shaderstate.modelviewmatrix);
break;
case SP_MODELVIEWPROJECTIONMATRIX:
// qglUniformMatrix4fvARB(p->handle[perm], 1, false, r_refdef.);
case SP_M_MODELVIEWPROJECTION:
{
float m16[16];
Matrix4_Multiply(r_refdef.m_projection, shaderstate.modelviewmatrix, m16);
qglUniformMatrix4fvARB(p->handle[perm], 1, false, m16);
}
break;
case SP_MODELMATRIX:
case SP_ENTMATRIX:
case SP_M_INVMODELVIEWPROJECTION:
{
float m16[16], inv[16];
Matrix4_Multiply(r_refdef.m_projection, shaderstate.modelviewmatrix, m16);
Matrix4_Invert(m16, inv);
qglUniformMatrix4fvARB(p->handle[perm], 1, false, inv);
}
break;
case SP_M_MODEL:
{
float m16[16];
Matrix4x4_CM_ModelMatrixFromAxis(m16, shaderstate.curentity->axis[0], shaderstate.curentity->axis[1], shaderstate.curentity->axis[2], shaderstate.curentity->origin);
@ -2407,29 +2439,43 @@ static unsigned int BE_Program_Set_Attribute(const shaderprogparm_t *p, unsigned
qglUniformMatrix4fvARB(p->handle[perm], 1, false, m16);
}
break;
case SP_ENTBONEMATRICIES:
case SP_M_ENTBONES:
{
qglUniformMatrix3x4fv(p->handle[perm], shaderstate.sourcevbo->numbones, false, shaderstate.sourcevbo->bones);
}
break;
case SP_M_INVVIEWPROJECTION:
{
float m16[16], inv[16];
Matrix4_Multiply(r_refdef.m_projection, r_refdef.m_view, m16);
Matrix4_Invert(m16, inv);
qglUniformMatrix4fvARB(p->handle[perm], 1, false, inv);
}
break;
case SP_ENTCOLOURS:
case SP_E_GLOWMOD:
qglUniform3fvARB(p->handle[perm], 1, (GLfloat*)shaderstate.curentity->glowmod);
break;
case SP_E_ORIGIN:
qglUniform3fvARB(p->handle[perm], 1, (GLfloat*)shaderstate.curentity->origin);
break;
case SP_E_COLOURS:
qglUniform4fvARB(p->handle[perm], 1, (GLfloat*)shaderstate.curentity->shaderRGBAf);
break;
case SP_ENTCOLOURSIDENT:
case SP_E_COLOURSIDENT:
if (shaderstate.flags & BEF_FORCECOLOURMOD)
qglUniform4fvARB(p->handle[perm], 1, (GLfloat*)shaderstate.curentity->shaderRGBAf);
else
qglUniform4fARB(p->handle[perm], 1, 1, 1, shaderstate.curentity->shaderRGBAf[3]);
break;
case SP_TOPCOLOURS:
case SP_E_TOPCOLOURS:
R_FetchTopColour(&r, &g, &b);
param3[0] = r/255.0f;
param3[1] = g/255.0f;
param3[2] = b/255.0f;
qglUniform3fvARB(p->handle[perm], 1, param3);
break;
case SP_BOTTOMCOLOURS:
case SP_E_BOTTOMCOLOURS:
R_FetchBottomColour(&r, &g, &b);
param3[0] = r/255.0f;
param3[1] = g/255.0f;
@ -2464,7 +2510,10 @@ static unsigned int BE_Program_Set_Attribute(const shaderprogparm_t *p, unsigned
case SP_LIGHTCOLOUR:
qglUniform3fvARB(p->handle[perm], 1, shaderstate.lightcolours);
break;
case SP_EYEPOS:
case SP_V_EYEPOS:
qglUniform3fvARB(p->handle[perm], 1, r_origin);
break;
case SP_E_EYEPOS:
{
float m16[16];
#ifdef _MSC_VER
@ -2498,7 +2547,17 @@ static unsigned int BE_Program_Set_Attribute(const shaderprogparm_t *p, unsigned
qglUniform3fvARB(p->handle[perm], 1, t2);
}
break;
case SP_TIME:
case SP_E_L_DIR:
qglUniform3fvARB(p->handle[perm], 1, (float*)shaderstate.curentity->light_dir);
break;
case SP_E_L_MUL:
qglUniform3fvARB(p->handle[perm], 1, (float*)shaderstate.curentity->light_range);
break;
case SP_E_L_AMBIENT:
qglUniform3fvARB(p->handle[perm], 1, (float*)shaderstate.curentity->light_avg);
break;
case SP_E_TIME:
qglUniform1fARB(p->handle[perm], shaderstate.curtime);
break;
case SP_CONSTI:
@ -2527,15 +2586,6 @@ static unsigned int BE_Program_Set_Attribute(const shaderprogparm_t *p, unsigned
qglUniform3fvARB(p->handle[perm], 1, param3);
}
break;
case SP_E_L_DIR:
qglUniform3fvARB(p->handle[perm], 1, (float*)shaderstate.curentity->light_dir);
break;
case SP_E_L_MUL:
qglUniform3fvARB(p->handle[perm], 1, (float*)shaderstate.curentity->light_range);
break;
case SP_E_L_AMBIENT:
qglUniform3fvARB(p->handle[perm], 1, (float*)shaderstate.curentity->light_avg);
break;
default:
Host_EndGame("Bad shader program parameter type (%i)", p->type);
@ -2934,6 +2984,9 @@ static void DrawMeshes(void)
case BEM_LIGHT:
BE_RenderMeshProgram(shaderstate.lightpassshader, shaderstate.lightpassshader->passes);
break;
case BEM_DEPTHNORM:
BE_RenderMeshProgram(shaderstate.depthnormshader, shaderstate.depthnormshader->passes);
break;
#endif
case BEM_DEPTHONLY:
GL_DeSelectProgram();
@ -3219,12 +3272,12 @@ static void BE_SubmitMeshesSortList(batch_t *sortlist)
}
}
void GLBE_SubmitMeshes (qboolean drawworld, batch_t **blist)
static void GLBE_SubmitMeshes (qboolean drawworld, batch_t **blist, int start, int stop)
{
model_t *model = cl.worldmodel;
int i;
for (i = SHADER_SORT_PORTAL; i < SHADER_SORT_COUNT; i++)
for (i = start; i <= stop; i++)
{
if (drawworld)
{
@ -3311,11 +3364,135 @@ void BE_BaseEntTextures(void)
{
batch_t *batches[SHADER_SORT_COUNT];
BE_GenModelBatches(batches);
GLBE_SubmitMeshes(false, batches);
GLBE_SubmitMeshes(false, batches, SHADER_SORT_PORTAL, SHADER_SORT_NEAREST);
BE_SelectEntity(&r_worldentity);
}
#endif
void GLBE_DrawLightPrePass(qbyte *vis, batch_t **batches)
{
extern cvar_t temp1;
if (!shaderstate.initeddepthnorm)
{
shaderstate.initeddepthnorm = true;
shaderstate.depthnormshader = R_RegisterShader("lpp_depthnorm",
"{\n"
"program lpp_depthnorm\n"
"{\n"
"map $normalmap\n"
"tcgen base\n"
"}\n"
"}\n"
);
}
if (!shaderstate.depthnormshader)
{
Con_Printf("%s requires content support\n", r_lightprepass.name);
r_lightprepass.ival = 0;
return;
}
/*do portals*/
BE_SelectMode(BEM_STANDARD);
GLBE_SubmitMeshes(true, batches, SHADER_SORT_PORTAL, SHADER_SORT_PORTAL);
BE_SelectMode(BEM_DEPTHNORM);
if (!shaderstate.depthnormshader)
{
BE_SelectMode(BEM_STANDARD);
return;
}
#define GL_RGBA16F_ARB 0x881A
#define GL_RGBA32F_ARB 0x8814
if (!TEXVALID(shaderstate.tex_normals))
{
shaderstate.tex_normals = GL_AllocNewTexture(vid.pixelwidth, vid.pixelheight);
r_lightprepass.modified = true;
}
if (r_lightprepass.modified)
{
GL_MTBind(0, GL_TEXTURE_2D, shaderstate.tex_normals);
qglTexImage2D(GL_TEXTURE_2D, 0, (r_lightprepass.ival==2)?GL_RGBA32F_ARB:GL_RGBA16F_ARB, vid.pixelwidth, vid.pixelheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
r_lightprepass.modified = false;
}
if (!TEXVALID(shaderstate.tex_diffuse))
{
int drb;
shaderstate.tex_diffuse = GL_AllocNewTexture(vid.pixelwidth, vid.pixelheight);
GL_MTBind(0, GL_TEXTURE_2D, shaderstate.tex_diffuse);
qglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, vid.pixelwidth, vid.pixelheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
GL_MTBind(0, GL_TEXTURE_2D, shaderstate.tex_normals);
qglTexImage2D(GL_TEXTURE_2D, 0, (r_lightprepass.ival==2)?GL_RGBA32F_ARB:GL_RGBA16F_ARB, vid.pixelwidth, vid.pixelheight, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
r_lightprepass.modified = false;
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
qglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
qglGenFramebuffersEXT(1, &shaderstate.fbo_diffuse);
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shaderstate.fbo_diffuse);
qglGenRenderbuffersEXT(1, &drb);
qglBindRenderbufferEXT(GL_RENDERBUFFER_EXT, drb);
qglRenderbufferStorageEXT(GL_RENDERBUFFER_EXT, GL_DEPTH_COMPONENT24_ARB, vid.pixelwidth, vid.pixelheight);
qglFramebufferRenderbufferEXT(GL_FRAMEBUFFER_EXT, GL_DEPTH_ATTACHMENT_EXT, GL_RENDERBUFFER_EXT, drb);
qglDrawBuffer(GL_COLOR_ATTACHMENT0_EXT);
// qglReadBuffer(GL_NONE);
}
else
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shaderstate.fbo_diffuse);
/*set the FB up to draw surface info*/
qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, shaderstate.tex_normals.num, 0);
qglClear(GL_DEPTH_BUFFER_BIT);
if (GL_FRAMEBUFFER_COMPLETE_EXT != qglCheckFramebufferStatusEXT(GL_FRAMEBUFFER_EXT))
{
Con_Printf("Bad framebuffer\n");
return;
}
/*draw surfaces that can be drawn this way*/
GLBE_SubmitMeshes(true, batches, SHADER_SORT_OPAQUE, SHADER_SORT_OPAQUE);
/*reconfigure - now drawing diffuse light info using the previous fb image as a source image*/
shaderstate.tex_sourcecol = shaderstate.tex_normals;
qglFramebufferTexture2DEXT(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D, shaderstate.tex_diffuse.num, 0);
BE_SelectMode(BEM_STANDARD);
qglClearColor (0,0,0,0);
qglClear(GL_COLOR_BUFFER_BIT);
BE_SelectEntity(&r_worldentity);
/*now draw the prelights*/
GLBE_SubmitMeshes(true, batches, SHADER_SORT_PRELIGHT, SHADER_SORT_PRELIGHT);
/*final reconfigure - now drawing final surface data onto true framebuffer*/
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, 0);
shaderstate.tex_sourcecol = shaderstate.tex_diffuse;
qglDrawBuffer(GL_BACK);
/*now draw the postlight passes (this includes blended stuff which will NOT be lit)*/
BE_SelectEntity(&r_worldentity);
GLBE_SubmitMeshes(true, batches, SHADER_SORT_SKY, SHADER_SORT_NEAREST);
/*regular lighting now*/
Sh_DrawLights(vis);
shaderstate.tex_sourcecol = r_nulltex;
shaderstate.tex_sourcedepth = r_nulltex;
qglClearColor (1,0,0,1);
}
void GLBE_DrawWorld (qbyte *vis)
{
extern cvar_t r_shadow_realtime_world, r_shadow_realtime_world_lightmaps;
@ -3328,9 +3505,9 @@ void GLBE_DrawWorld (qbyte *vis)
if (!r_refdef.recurse)
{
if (shaderstate.wbatch > shaderstate.maxwbatches)
if (shaderstate.wbatch + 50 > shaderstate.maxwbatches)
{
int newm = shaderstate.wbatch;
int newm = shaderstate.wbatch + 100;
shaderstate.wbatches = BZ_Realloc(shaderstate.wbatches, newm * sizeof(*shaderstate.wbatches));
memset(shaderstate.wbatches + shaderstate.maxwbatches, 0, (newm - shaderstate.maxwbatches) * sizeof(*shaderstate.wbatches));
shaderstate.maxwbatches = newm;
@ -3339,101 +3516,75 @@ void GLBE_DrawWorld (qbyte *vis)
shaderstate.wbatch = 0;
}
BE_GenModelBatches(batches);
R_GenDlightBatches(batches);
shaderstate.curentity = &r_worldentity;
shaderstate.updatetime = cl.servertime;
BE_SelectEntity(&r_worldentity);
#if 0
{int i;
for (i = 0; i < SHADER_SORT_COUNT; i++)
batches[i] = NULL;
}
#endif
BE_UpdateLightmaps();
//make sure the world draws correctly
r_worldentity.shaderRGBAf[0] = 1;
r_worldentity.shaderRGBAf[1] = 1;
r_worldentity.shaderRGBAf[2] = 1;
r_worldentity.shaderRGBAf[3] = 1;
r_worldentity.axis[0][0] = 1;
r_worldentity.axis[1][1] = 1;
r_worldentity.axis[2][2] = 1;
if (gl_overbright.modified)
if (vis)
{
int i;
gl_overbright.modified = false;
if (gl_overbright.ival > 2)
gl_overbright.ival = 2;
BE_UpdateLightmaps();
for (i = 0; i < SHADER_PASS_MAX; i++)
shaderstate.blendmode[i] = -1;
}
if (gl_overbright.modified)
{
int i;
gl_overbright.modified = false;
if (gl_overbright.ival > 2)
gl_overbright.ival = 2;
for (i = 0; i < SHADER_PASS_MAX; i++)
shaderstate.blendmode[i] = -1;
}
#ifdef RTLIGHTS
if (r_shadow_realtime_world.value && gl_config.arb_shader_objects)
shaderstate.identitylighting = r_shadow_realtime_world_lightmaps.value;
else
if (r_shadow_realtime_world.value && gl_config.arb_shader_objects)
shaderstate.identitylighting = r_shadow_realtime_world_lightmaps.value;
else
#endif
shaderstate.identitylighting = 1;
// shaderstate.identitylighting /= 1<<gl_overbright.ival;
if (shaderstate.identitylighting == 0)
BE_SelectMode(BEM_DEPTHDARK);
else
BE_SelectMode(BEM_STANDARD);
RSpeedRemark();
GLBE_SubmitMeshes(true, batches);
RSpeedEnd(RSPEED_WORLD);
shaderstate.identitylighting = 1;
// shaderstate.identitylighting /= 1<<gl_overbright.ival;
#ifdef RTLIGHTS
RSpeedRemark();
BE_SelectEntity(&r_worldentity);
Sh_DrawLights(vis);
RSpeedEnd(RSPEED_STENCILSHADOWS);
if (r_lightprepass.ival)
{
GLBE_DrawLightPrePass(vis, batches);
}
else
#endif
{
if (shaderstate.identitylighting == 0)
BE_SelectMode(BEM_DEPTHDARK);
else
BE_SelectMode(BEM_STANDARD);
RSpeedRemark();
GLBE_SubmitMeshes(true, batches, SHADER_SORT_PORTAL, SHADER_SORT_NEAREST);
RSpeedEnd(RSPEED_WORLD);
}
#ifdef RTLIGHTS
RSpeedRemark();
BE_SelectEntity(&r_worldentity);
Sh_DrawLights(vis);
RSpeedEnd(RSPEED_STENCILSHADOWS);
#endif
if (r_refdef.gfog_alpha)
if (r_refdef.gfog_alpha)
{
BE_SelectMode(BEM_FOG);
BE_SelectFog(r_refdef.gfog_rgb, r_refdef.gfog_alpha, r_refdef.gfog_density);
GLBE_SubmitMeshes(true, batches, SHADER_SORT_PORTAL, SHADER_SORT_NEAREST);
}
}
else
{
BE_SelectMode(BEM_FOG);
BE_SelectFog(r_refdef.gfog_rgb, r_refdef.gfog_alpha, r_refdef.gfog_density);
GLBE_SubmitMeshes(true, batches);
GLBE_SubmitMeshes(false, batches, SHADER_SORT_PORTAL, SHADER_SORT_NEAREST);
}
BE_SelectEntity(&r_worldentity);
shaderstate.updatetime = realtime;
shaderstate.curtime = shaderstate.updatetime = realtime;
checkglerror();
}
void BE_DrawNonWorld (void)
{
batch_t *batches[SHADER_SORT_COUNT];
checkglerror();
if (shaderstate.wbatch > shaderstate.maxwbatches)
{
int newm = shaderstate.wbatch;
shaderstate.wbatches = BZ_Realloc(shaderstate.wbatches, newm * sizeof(*shaderstate.wbatches));
memset(shaderstate.wbatches + shaderstate.maxwbatches, 0, (newm - shaderstate.maxwbatches) * sizeof(*shaderstate.wbatches));
shaderstate.maxwbatches = newm;
}
shaderstate.wbatch = 0;
BE_GenModelBatches(batches);
shaderstate.updatetime = cl.servertime;
GLBE_SubmitMeshes(false, batches);
BE_SelectEntity(&r_worldentity);
shaderstate.updatetime = realtime;
checkglerror();
}
#endif

View File

@ -32,6 +32,7 @@ struct world_s;
typedef enum {
SHADER_SORT_NONE,
SHADER_SORT_PRELIGHT,
SHADER_SORT_PORTAL,
SHADER_SORT_SKY,
SHADER_SORT_OPAQUE,

View File

@ -121,8 +121,11 @@ avec4_t flashblend_colours[FLASHBLEND_VERTS+1];
vecV_t flashblend_vcoords[FLASHBLEND_VERTS+1];
vec2_t flashblend_tccoords[FLASHBLEND_VERTS+1];
index_t flashblend_indexes[FLASHBLEND_VERTS*3];
index_t flashblend_fsindexes[6] = {0, 1, 2, 0, 2, 3};
mesh_t flashblend_mesh;
mesh_t flashblend_fsmesh;
shader_t *flashblend_shader;
shader_t *lpplight_shader;
void R_InitFlashblends(void)
{
int i;
@ -143,6 +146,14 @@ void R_InitFlashblends(void)
flashblend_mesh.numindexes = FLASHBLEND_VERTS*3;
flashblend_mesh.istrifan = true;
flashblend_fsmesh.numvertexes = 4;
flashblend_fsmesh.xyz_array = flashblend_vcoords;
flashblend_fsmesh.st_array = flashblend_tccoords;
flashblend_fsmesh.colors4f_array = flashblend_colours;
flashblend_fsmesh.indexes = flashblend_fsindexes;
flashblend_fsmesh.numindexes = 6;
flashblend_fsmesh.istrifan = true;
flashblend_shader = R_RegisterShader("flashblend",
"{\n"
"{\n"
@ -153,9 +164,10 @@ void R_InitFlashblends(void)
"}\n"
"}\n"
);
lpplight_shader = NULL;
}
void R_RenderDlight (dlight_t *light, unsigned int beflags)
static qboolean R_BuildDlightMesh(dlight_t *light, float radscale, qboolean expand)
{
int i, j;
// float a;
@ -163,11 +175,11 @@ void R_RenderDlight (dlight_t *light, unsigned int beflags)
float rad;
float *bub_sin, *bub_cos;
vec3_t colour;
extern cvar_t gl_mindist;
bub_sin = bubble_sintable;
bub_cos = bubble_costable;
rad = light->radius * 0.35;
rad = 16;
rad = light->radius * radscale;
VectorCopy(light->color, colour);
@ -182,19 +194,17 @@ void R_RenderDlight (dlight_t *light, unsigned int beflags)
}
VectorSubtract (light->origin, r_origin, v);
if (Length (v) < rad)
if (Length (v) < rad + gl_mindist.value*2)
{ // view is inside the dlight
AddLightBlend (colour[0]*5, colour[1]*5, colour[2]*5, light->radius * 0.0003);
return;
return false;
}
flashblend_colours[0][0] = colour[0]*2;
flashblend_colours[0][1] = colour[1]*2;
flashblend_colours[0][2] = colour[2]*2;
flashblend_colours[0][3] = 1;
for (i=0 ; i<3 ; i++)
flashblend_vcoords[0][i] = light->origin[i] - vpn[i]*rad/1.5;
VectorCopy(light->origin, flashblend_vcoords[0]);
for (i=16 ; i>0 ; i--)
{
for (j=0 ; j<3 ; j++)
@ -203,8 +213,17 @@ void R_RenderDlight (dlight_t *light, unsigned int beflags)
bub_sin++;
bub_cos++;
}
BE_DrawMesh_Single(flashblend_shader, &flashblend_mesh, NULL, &flashblend_shader->defaulttextures, beflags);
if (!expand)
VectorMA(flashblend_vcoords[0], -rad/1.5, vpn, flashblend_vcoords[0]);
else
{
vec3_t diff;
VectorSubtract(r_origin, light->origin, diff);
VectorNormalize(diff);
for (i=0 ; i<=16 ; i++)
VectorMA(flashblend_vcoords[i], rad, diff, flashblend_vcoords[i]);
}
return true;
}
/*
@ -251,7 +270,88 @@ void GLR_RenderDlights (void)
if (TraceLineN(r_refdef.vieworg, l->origin, waste1, waste2))
continue;
}
R_RenderDlight (l, beflags);
if (!R_BuildDlightMesh (l, r_flashblendscale.value, false))
AddLightBlend (l->color[0]*5, l->color[1]*5, l->color[2]*5, l->radius * 0.0003);
else
BE_DrawMesh_Single(flashblend_shader, &flashblend_mesh, NULL, &flashblend_shader->defaulttextures, beflags);
}
}
void R_GenDlightMesh(struct batch_s *batch)
{
static mesh_t *meshptr;
dlight_t *l = cl_dlights + batch->surf_first;
BE_SelectDLight(l, l->color);
if (!R_BuildDlightMesh (l, 1, true))
{
int i;
static vec2_t s[4] = {{1, -1}, {-1, -1}, {-1, 1}, {1, 1}};
batch->flags |= BEF_FORCENODEPTH;
for (i = 0; i < 4; i++)
{
VectorMA(r_origin, 32, vpn, flashblend_vcoords[i]);
VectorMA(flashblend_vcoords[i], s[i][0]*320, vright, flashblend_vcoords[i]);
VectorMA(flashblend_vcoords[i], s[i][1]*320, vup, flashblend_vcoords[i]);
}
meshptr = &flashblend_fsmesh;
}
else
{
meshptr = &flashblend_mesh;
}
batch->mesh = &meshptr;
}
void R_GenDlightBatches(batch_t *batches[])
{
int i, sort;
dlight_t *l;
batch_t *b;
if (!lpplight_shader)
lpplight_shader = R_RegisterShader("lpp_light",
"{\n"
"program lpp_light\n"
"{\n"
"map $sourcecolour\n"
"blendfunc gl_one gl_one\n"
"}\n"
"surfaceparm nodlight\n"
"lpp_light\n"
"}\n"
);
l = cl_dlights+rtlights_first;
for (i=rtlights_first; i<rtlights_max; i++, l++)
{
if (!l->radius)
continue;
if (R_CullSphere(l->origin, l->radius))
continue;
b = BE_GetTempBatch();
if (!b)
return;
b->flags = 0;
sort = lpplight_shader->sort;
b->buildmeshes = R_GenDlightMesh;
b->ent = &r_worldentity;
b->mesh = NULL;
b->firstmesh = 0;
b->meshes = 1;
b->skin = &lpplight_shader->defaulttextures;
b->texture = NULL;
b->shader = lpplight_shader;
b->lightmap = -1;
b->surf_first = i;
b->flags |= BEF_NOSHADOWS;
b->vbo = 0;
b->next = batches[sort];
batches[sort] = b;
}
}

View File

@ -208,7 +208,7 @@ void GL_InitFisheyeFov(void)
void main(void)\
{\
texcoord = gl_MultiTexCoord0.xy;\
gl_Position = gl_ModelViewProjectionMatrix * gl_Vertex;\
gl_Position = ftetransform();\
}";
char *fisheyefshader = "\
uniform samplerCube source;\
@ -600,7 +600,7 @@ void R_RenderScene (void)
Surf_DrawWorld (); // adds static entities to the list
}
else
BE_DrawNonWorld();
BE_DrawWorld(NULL);
S_ExtraUpdate (); // don't let sound get messed up if going slow

View File

@ -31,6 +31,11 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <ctype.h>
#ifdef D3DQUAKE
#include <d3d9.h>
extern LPDIRECT3DDEVICE9 pD3DDev9;
#endif
extern texid_t missing_texture;
static qboolean shader_reload_needed;
static qboolean shader_rescan_needed;
@ -218,7 +223,9 @@ static qboolean Shader_EvaluateCondition(char **ptr)
{
extern cvar_t gl_bump;
token++;
if (!Q_stricmp(token, "lightmap"))
if (!Q_stricmp(token, "lpp"))
conditiontrue = conditiontrue == !r_lightprepass.ival;
else if (!Q_stricmp(token, "lightmap"))
conditiontrue = conditiontrue == !r_fullbright.value;
else if (!Q_stricmp(token, "deluxmap") )
conditiontrue = conditiontrue == (r_deluxemapping.value && gl_bump.value);
@ -697,34 +704,41 @@ static void Shader_Sort ( shader_t *shader, shaderpass_t *pass, char **ptr )
{
char *token;
token = Shader_ParseString ( ptr );
if ( !Q_stricmp( token, "portal" ) ) {
if ( !Q_stricmp( token, "portal" ) )
shader->sort = SHADER_SORT_PORTAL;
} else if( !Q_stricmp( token, "sky" ) ) {
else if( !Q_stricmp( token, "sky" ) )
shader->sort = SHADER_SORT_SKY;
} else if( !Q_stricmp( token, "opaque" ) ) {
else if( !Q_stricmp( token, "opaque" ) )
shader->sort = SHADER_SORT_OPAQUE;
} else if( !Q_stricmp( token, "decal" ) ) {
else if( !Q_stricmp( token, "decal" ) )
shader->sort = SHADER_SORT_DECAL;
} else if( !Q_stricmp( token, "seethrough" ) ) {
else if( !Q_stricmp( token, "seethrough" ) )
shader->sort = SHADER_SORT_SEETHROUGH;
} else if( !Q_stricmp( token, "banner" ) ) {
else if( !Q_stricmp( token, "banner" ) )
shader->sort = SHADER_SORT_BANNER;
} else if( !Q_stricmp( token, "additive" ) ) {
else if( !Q_stricmp( token, "additive" ) )
shader->sort = SHADER_SORT_ADDITIVE;
} else if( !Q_stricmp( token, "underwater" ) ) {
else if( !Q_stricmp( token, "underwater" ) )
shader->sort = SHADER_SORT_UNDERWATER;
} else if( !Q_stricmp( token, "nearest" ) ) {
else if( !Q_stricmp( token, "nearest" ) )
shader->sort = SHADER_SORT_NEAREST;
} else if( !Q_stricmp( token, "blend" ) ) {
else if( !Q_stricmp( token, "blend" ) )
shader->sort = SHADER_SORT_BLEND;
} else {
else if ( !Q_stricmp( token, "lpp_light" ) )
shader->sort = SHADER_SORT_PRELIGHT;
else
{
shader->sort = atoi ( token );
clamp ( shader->sort, SHADER_SORT_NONE, SHADER_SORT_NEAREST );
}
}
static void Shader_Prelight ( shader_t *shader, shaderpass_t *pass, char **ptr )
{
shader->sort = SHADER_SORT_PRELIGHT;
}
static void Shader_Portal ( shader_t *shader, shaderpass_t *pass, char **ptr )
{
shader->sort = SHADER_SORT_PORTAL;
@ -856,7 +870,7 @@ static void Shader_LoadPermutations(char *name, program_t *prog, char *script, i
permutationdefines[pn++] = permutationname[n];
}
permutationdefines[pn++] = NULL;
prog->handle[p] = D3DShader_CreateProgram(permutationdefines, script, script);
D3DShader_CreateProgram(prog, p, permutationdefines, script, script);
}
#endif
}
@ -1123,7 +1137,7 @@ struct sbuiltin_s
"}\n"
"#endif\n"
},
/* {QR_OPENGL, 110, "defaultsky",
{QR_OPENGL, 110, "defaultsky",
"#ifdef VERTEX_SHADER\n"
"varying vec3 pos;\n"
@ -1160,7 +1174,6 @@ struct sbuiltin_s
"}\n"
"#endif\n"
},
*/
/*draws a model. there's lots of extra stuff for light shading calcs and upper/lower textures*/
{QR_OPENGL/*ES*/, 100, "defaultskin",
"!!permu FULLBRIGHT\n"
@ -1284,26 +1297,180 @@ struct sbuiltin_s
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "lpp_depthnorm",
"!!permu BUMP\n"
"varying vec2 pos;\n"
"varying vec3 norm, tang, bitang;\n"
"#if defined(BUMP)\n"
"varying vec2 tc;\n"
"#endif\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"attribute vec3 v_normal;\n"
"attribute vec3 v_svector;\n"
"attribute vec3 v_tvector;\n"
"uniform mat4 m_modelviewprojection;\n"
"void main(void)\n"
"{\n"
"gl_Position = ftetransform();\n"
"pos = gl_Position.zw;\n"
"norm = v_normal;\n"
"#if defined(BUMP)\n"
"tang = v_svector;\n"
"bitang = v_tvector;\n"
"tc = v_texcoord;\n"
"#endif\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"#if defined(BUMP)\n"
"uniform sampler2D s_t0;\n"
"#endif\n"
"void main(void)\n"
"{\n"
"vec3 onorm;\n"
"#if defined(BUMP)\n"
/*transform by the normalmap*/
"vec3 bm = 2.0*texture2D(s_t0, tc).xyz - 1.0;\n"
"onorm = normalize(bm.x * tang + bm.y * bitang + bm.z * norm);\n"
"#else\n"
"onorm = norm;\n"
"#endif\n"
"gl_FragColor = vec4(onorm.xyz, pos.x/pos.y);\n"
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "lpp_light",
"varying vec4 tf;\n"
"#ifdef VERTEX_SHADER\n"
"void main(void)\n"
"{\n"
"gl_Position = tf = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"uniform vec3 l_lightposition;\n"
"uniform mat4 m_invviewprojection;\n"
"uniform vec3 l_lightcolour;\n"
"uniform float l_lightradius;\n"
"vec3 calcLightWorldPos(vec2 screenPos, float depth)\n"
"{\n"
"vec4 pos;\n"
"pos.x = screenPos.x;\n"
"pos.y = screenPos.y;\n"
"pos.z = depth;\n"
"pos.w = 1.0;\n"
"pos = m_invviewprojection * pos;\n"
"return pos.xyz / pos.w;\n"
"}\n"
"void main (void)\n"
"{\n"
"vec3 lightColour = l_lightcolour.rgb;\n"
"float lightIntensity = 1.0;\n"
"float lightAttenuation = l_lightradius;\n" // fixme: just use the light radius for now, use better near/far att math separately once working
"float radiusFar = l_lightradius;\n"
"float radiusNear = l_lightradius*0.5;\n"
"vec2 fc;\n"
"fc = tf.xy / tf.w;\n"
"vec4 data = texture2D(s_t0, (1.0 + fc) / 2.0);\n"
"float depth = data.a;\n"
"vec3 norm = data.xyz;\n"
/* calc where the wall that generated this sample came from */
"vec3 worldPos = calcLightWorldPos(fc, depth);\n"
/*calc diffuse lighting term*/
"vec3 lightDir = l_lightposition - worldPos;\n"
"float zdiff = 1.0 - saturate( length(lightDir) / lightAttenuation );\n"
"float atten = (radiusFar * zdiff) / (radiusFar - radiusNear);\n"
"atten = pow(atten, 2.0);\n"
"lightDir = normalize(lightDir);\n"
"float nDotL = dot(norm, lightDir) * atten;\n"
"float lightDiffuse = max(0.0, nDotL);\n"
/*calc specular term*/
// todo: specular term in its own buffer for full coloured specular
"gl_FragColor = vec4(lightDiffuse * (lightColour * lightIntensity), 1.0);\n"
// gl_FragColor = vec4(normalize(lightDir), 0.0);
"}\n"
"#endif\n"
},
{QR_OPENGL, 110, "lpp_wall",
"!!cvarf gl_overbright\n"
"varying vec2 tc, lm;\n"
"varying vec4 tf;\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"attribute vec2 v_lmcoord;\n"
"void main (void)\n"
"{\n"
"tc = v_texcoord;\n"
"lm = v_lmcoord;\n"
"gl_Position = tf = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n" /*lpp lighting*/
"uniform sampler2D s_t1;\n" /*tex_diffuse*/
"uniform sampler2D s_t2;\n" /*tex_lightmap*/
//"uniform sampler2D s_t3;\n" /*tex_normalmap*/
//"uniform sampler2D s_t4;\n" /*tex_deluxmap*/
//"uniform sampler2D s_t5;\n" /*tex_fullbright*/
"uniform float cvar_gl_overbright;\n"
"void main (void)\n"
"{\n"
"float lmscale = exp2(floor(clamp(cvar_gl_overbright, 0.0, 2.0)));\n"
//"gl_FragColor = texture2D(s_t0, tc) * texture2D(s_t1, lm) * vec4(scale, scale, scale, 1.0);\n"
"vec2 nst;\n"
"nst = tf.xy / tf.w;\n"
"nst = (1.0 + nst) / 2.0;\n"
"vec4 l = texture2D(s_t0, nst)*5.0;\n"
"vec4 c = texture2D(s_t1, tc);\n"
"vec3 lmsamp = texture2D(s_t2, lm).rgb*lmscale;\n"
"vec3 diff = l.rgb;\n"
"vec3 chrom = diff / (0.001 + dot(diff, vec3(0.3, 0.59, 0.11)));\n"
"vec3 spec = chrom * l.a;\n"
"gl_FragColor = vec4((diff + lmsamp) * c.xyz, 1.0);\n" // + 0.6 * spec, 1.0);
"}\n"
"#endif\n"
},
#endif
#if 0//def D3DQUAKE
{QR_DIRECT3D, 9, "defaultsky",
#ifdef D3DQUAKE
{QR_DIRECT3D, 9, "defaultsky",
"struct a2v {\n"
"float4 pos: POSITION;\n"
"};\n"
"struct v2f {\n"
"#ifdef VERTEX_SHADER\n"
"#ifndef FRAGMENT_SHADER\n"
"float4 pos: POSITION;\n"
"#endif\n"
"float3 vpos: COLOR;\n"
"#endif\n"
"float3 vpos: TEXCOORD0;\n"
"};\n"
"#ifdef VERTEX_SHADER\n"
"float4x4 ModelViewProj;\n"
"float4x4 m_modelviewprojection;\n"
"v2f main (a2v inp)\n"
"{\n"
" v2f outp;\n"
" outp.pos = mul(inp.pos, ModelViewProj);\n"
" outp.pos = mul(m_modelviewprojection, inp.pos);\n"
" outp.vpos = inp.pos;\n"
" return outp;\n"
"}\n"
@ -1312,8 +1479,8 @@ struct sbuiltin_s
"#ifdef FRAGMENT_SHADER\n"
"float e_time;\n"
"float3 e_eyepos;\n"
"sampler2D s_t0;\n"
"sampler2D s_t1;\n"
"sampler s_t0;\n"
"sampler s_t1;\n"
"float4 main (v2f inp) : COLOR0\n"
"{\n"
" float2 tccoord;\n"
@ -1330,7 +1497,46 @@ struct sbuiltin_s
" float4 clouds = tex2D(s_t1, tccoord);\n"
" return float4((solid.rgb*(1.0-clouds.a)) + (clouds.a*clouds.rgb), 1);\n"
// " return solid.rgb;/*gl_FragColor.g = clouds.r;*/gl_FragColor.b = clouds.a;\n"
// " return float4(solid.rgb, 1);"///*gl_FragColor.g = clouds.r;*/gl_FragColor.b = clouds.a;\n"
"}\n"
"#endif\n"
},
{QR_DIRECT3D, 9, "defaultwarp",
"!!cvarf r_wateralpha\n"
"struct a2v {\n"
"float4 pos: POSITION;\n"
"float2 tc: TEXCOORD0;\n"
"};\n"
"struct v2f {\n"
"#ifndef FRAGMENT_SHADER\n"
"float4 pos: POSITION;\n"
"#endif\n"
"float2 tc: TEXCOORD0;\n"
"};\n"
"#ifdef VERTEX_SHADER\n"
"float4x4 m_modelviewprojection;\n"
"v2f main (a2v inp)\n"
"{\n"
" v2f outp;\n"
" outp.pos = mul(m_modelviewprojection, inp.pos);\n"
" outp.tc = inp.tc;\n"
" return outp;\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"float cvar_r_wateralpha;\n"
"float e_time;\n"
"sampler s_t0;\n"
"float4 main (v2f inp) : COLOR0\n"
"{\n"
" float2 ntc;\n"
" ntc.x = inp.tc.x + sin(inp.tc.y+e_time)*0.125;\n"
" ntc.y = inp.tc.y + sin(inp.tc.x+e_time)*0.125;\n"
" float3 ts = tex2D(s_t0, ntc).xyz;\n"
" return float4(ts, cvar_r_wateralpha);\n"
"}\n"
"#endif\n"
},
@ -1399,9 +1605,24 @@ static program_t *Shader_LoadGeneric(char *name, int qrtype)
g->prog.refs = 1;
FS_LoadFile(name, &file);
if (strchr(name, '/') || strchr(name, '.'))
FS_LoadFile(name, &file);
else if (qrenderer == QR_DIRECT3D)
FS_LoadFile(va("hlsl/%s.hlsl", name), &file);
else if (qrenderer == QR_OPENGL)
{
#ifdef GLQUAKE
if (gl_config.gles)
FS_LoadFile(va("gles/%s.glsl", name), &file);
else
#endif
FS_LoadFile(va("glsl/%s.glsl", name), &file);
}
else
file = NULL;
if (file)
{
Con_DPrintf("Loaded %s from disk\n", name);
Shader_LoadPermutations(name, &g->prog, file, qrtype, 0);
FS_FreeFile(file);
@ -1437,6 +1658,92 @@ static program_t *Shader_LoadGeneric(char *name, int qrtype)
return NULL;
}
void Shader_WriteOutGenerics_f(void)
{
int i;
char *name;
for (i = 0; *sbuiltins[i].name; i++)
{
name = NULL;
if (sbuiltins[i].qrtype == QR_OPENGL)
{
if (sbuiltins[i].apiver == 100)
name = va("gles/%s.glsl", sbuiltins[i].name);
else
name = va("glsl/%s.glsl", sbuiltins[i].name);
}
else if (sbuiltins[i].qrtype == QR_DIRECT3D)
name = va("hlsl/%s.hlsl", sbuiltins[i].name);
if (name)
{
vfsfile_t *f = FS_OpenVFS(name, "rb", FS_GAMEONLY);
if (f)
{
int len = VFS_GETLEN(f);
char *buf = Hunk_TempAlloc(len);
VFS_READ(f, buf, len);
if (len != strlen(sbuiltins[i].body) || memcmp(buf, sbuiltins[i].body, len))
Con_Printf("Not writing %s - modified version in the way\n", name);
else
Con_Printf("%s is unmodified\n", name);
VFS_CLOSE(f);
}
else
{
Con_Printf("Writing %s\n", name);
FS_WriteFile(name, sbuiltins[i].body, strlen(sbuiltins[i].body), FS_GAMEONLY);
}
}
}
}
struct shader_field_names_s shader_field_names[] =
{
/*vertex attributes*/
{"v_position", SP_ATTR_VERTEX},
{"v_colour", SP_ATTR_COLOUR},
{"v_texcoord", SP_ATTR_TEXCOORD},
{"v_lmcoord", SP_ATTR_LMCOORD},
{"v_normal", SP_ATTR_NORMALS},
{"v_svector", SP_ATTR_SNORMALS},
{"v_tvector", SP_ATTR_TNORMALS},
{"v_bone", SP_ATTR_BONENUMS},
{"v_weight", SP_ATTR_BONEWEIGHTS},
/*matricies*/
{"m_model", SP_M_MODEL},
{"m_view", SP_M_VIEW},
{"m_modelview", SP_M_MODELVIEW},
{"m_projection", SP_M_PROJECTION},
{"m_modelviewprojection", SP_M_MODELVIEWPROJECTION},
{"m_bones", SP_M_ENTBONES},
{"m_invviewprojection", SP_M_INVVIEWPROJECTION},
{"m_invmodelviewprojection",SP_M_INVMODELVIEWPROJECTION},
/*viewer properties*/
{"v_eyepos", SP_V_EYEPOS},
/*ent properties*/
{"e_origin", SP_E_ORIGIN},
{"e_time", SP_E_TIME},
{"e_eyepos", SP_E_EYEPOS},
{"e_colour", SP_E_COLOURS},
{"e_colourident", SP_E_COLOURSIDENT},
{"e_glowmod", SP_E_GLOWMOD},
{"e_topcolour", SP_E_TOPCOLOURS},
{"e_bottomcolour", SP_E_BOTTOMCOLOURS},
{"e_light_dir", SP_E_L_DIR},
{"e_light_mul", SP_E_L_MUL},
{"e_light_ambient", SP_E_L_AMBIENT},
/*rtlight properties, use with caution*/
{"l_lightradius", SP_LIGHTRADIUS},
{"l_lightcolour", SP_LIGHTCOLOUR},
{"l_lightposition", SP_LIGHTPOSITION},
{NULL}
};
static void Shader_ProgAutoFields(program_t *prog, char **cvarfnames)
{
unsigned int i, p;
@ -1444,43 +1751,7 @@ static void Shader_ProgAutoFields(program_t *prog, char **cvarfnames)
int uniformloc;
char tmpname[128];
cvar_t *cvar;
static struct
{
char *name;
enum shaderprogparmtype_e ptype;
} u[] =
{
/*vertex attributes*/
{"v_position", SP_ATTR_VERTEX},
{"v_colour", SP_ATTR_COLOUR},
{"v_texcoord", SP_ATTR_TEXCOORD},
{"v_lmcoord", SP_ATTR_LMCOORD},
{"v_normal", SP_ATTR_NORMALS},
{"v_svector", SP_ATTR_SNORMALS},
{"v_tvector", SP_ATTR_TNORMALS},
{"v_bone", SP_ATTR_BONENUMS},
{"v_weight", SP_ATTR_BONEWEIGHTS},
/*matricies*/
{"m_model", SP_MODELMATRIX},
{"m_view", SP_VIEWMATRIX},
{"m_modelview", SP_MODELVIEWMATRIX},
{"m_projection", SP_PROJECTIONMATRIX},
{"m_modelviewprojection", SP_MODELVIEWPROJECTIONMATRIX},
{"m_bones", SP_ENTBONEMATRICIES},
/*ent properties*/
{"e_time", SP_TIME},
{"e_eyepos", SP_EYEPOS},
{"e_colour", SP_ENTCOLOURS},
{"e_colourident", SP_ENTCOLOURSIDENT},
{"e_topcolour", SP_TOPCOLOURS},
{"e_bottomcolour", SP_BOTTOMCOLOURS},
{"e_light_dir", SP_E_L_DIR},
{"e_light_mul", SP_E_L_MUL},
{"e_light_ambient", SP_E_L_AMBIENT},
{NULL}
};
prog->numparams = 0;
#ifdef GLQUAKE
if (qrenderer == QR_OPENGL)
@ -1502,13 +1773,13 @@ static void Shader_ProgAutoFields(program_t *prog, char **cvarfnames)
{
if (!prog->handle[p].glsl)
continue;
GLSlang_UseProgram(prog->handle[p].glsl);
GL_SelectProgram(prog->handle[p].glsl);
uniformloc = qglGetUniformLocationARB(prog->handle[p].glsl, va("cvar_%s", tmpname));
if (uniformloc != -1)
qglUniform1fARB(uniformloc, cvar->value);
}
}
for (i = 0; u[i].name; i++)
for (i = 0; shader_field_names[i].name; i++)
{
found = false;
for (p = 0; p < PERMUTATIONS; p++)
@ -1516,20 +1787,20 @@ static void Shader_ProgAutoFields(program_t *prog, char **cvarfnames)
if (!prog->handle[p].glsl)
continue;
GLSlang_UseProgram(prog->handle[p].glsl);
if (u[i].ptype >= SP_FIRSTUNIFORM)
uniformloc = qglGetUniformLocationARB(prog->handle[p].glsl, u[i].name);
if (shader_field_names[i].ptype >= SP_FIRSTUNIFORM)
uniformloc = qglGetUniformLocationARB(prog->handle[p].glsl, shader_field_names[i].name);
else
uniformloc = qglGetAttribLocationARB(prog->handle[p].glsl, u[i].name);
uniformloc = qglGetAttribLocationARB(prog->handle[p].glsl, shader_field_names[i].name);
if (uniformloc != -1)
found = true;
prog->parm[prog->numparams].handle[p] = uniformloc;
}
if (found)
{
prog->parm[prog->numparams].type = u[i].ptype;
prog->parm[prog->numparams].type = shader_field_names[i].ptype;
prog->numparams++;
if (u[i].ptype < SP_FIRSTUNIFORM)
if (shader_field_names[i].ptype < SP_FIRSTUNIFORM)
prog->nofixedcompat = true;
}
}
@ -1546,7 +1817,84 @@ static void Shader_ProgAutoFields(program_t *prog, char **cvarfnames)
qglUniform1iARB(uniformloc, i);
}
}
GLSlang_UseProgram(0);
return;
}
#endif
#ifdef D3DQUAKE
if (qrenderer == QR_DIRECT3D)
{
prog->nofixedcompat = true;
/*set cvar uniforms*/
for (i = 0; cvarfnames[i]; i++)
{
for (p = 0; cvarfnames[i][p] && (unsigned char)cvarfnames[i][p] > 32 && p < sizeof(tmpname)-1; p++)
tmpname[p] = cvarfnames[i][p];
tmpname[p] = 0;
cvar = Cvar_FindVar(tmpname);
if (!cvar)
continue;
cvar->flags |= CVAR_SHADERSYSTEM;
for (p = 0; p < PERMUTATIONS; p++)
{
if (!prog->handle[p].glsl)
continue;
uniformloc = D3DShader_FindUniform(&prog->handle[p], 1, va("cvar_%s", tmpname));
if (uniformloc != -1)
{
vec4_t v = {cvar->value, 0, 0, 0};
IDirect3DDevice9_SetVertexShader(pD3DDev9, prog->handle[0].hlsl.vert);
IDirect3DDevice9_SetVertexShaderConstantF(pD3DDev9, 0, v, 1);
}
uniformloc = D3DShader_FindUniform(&prog->handle[p], 2, va("cvar_%s", tmpname));
if (uniformloc != -1)
{
vec4_t v = {cvar->value, 0, 0, 0};
IDirect3DDevice9_SetPixelShader(pD3DDev9, prog->handle[0].hlsl.vert);
IDirect3DDevice9_SetPixelShaderConstantF(pD3DDev9, 0, v, 1);
}
}
}
for (i = 0; shader_field_names[i].name; i++)
{
found = false;
for (p = 0; p < PERMUTATIONS; p++)
{
if (shader_field_names[i].ptype >= SP_FIRSTUNIFORM)
{
uniformloc = D3DShader_FindUniform(&prog->handle[p], 0, shader_field_names[i].name);
}
else
uniformloc = -1;
if (uniformloc != -1)
found = true;
prog->parm[prog->numparams].handle[p] = uniformloc;
}
if (found)
{
prog->parm[prog->numparams].type = shader_field_names[i].ptype;
prog->numparams++;
if (shader_field_names[i].ptype < SP_FIRSTUNIFORM)
prog->nofixedcompat = true;
}
}
/*set texture uniforms*/
for (p = 0; p < PERMUTATIONS; p++)
{
for (i = 0; i < 8; i++)
{
uniformloc = D3DShader_FindUniform(&prog->handle[p], 2, va("s_t%i", i));
if (uniformloc != -1)
{
int v[4] = {i};
IDirect3DDevice9_SetPixelShader(pD3DDev9, prog->handle[0].hlsl.vert);
IDirect3DDevice9_SetPixelShaderConstantI(pD3DDev9, 0, v, 1);
}
}
}
IDirect3DDevice9_SetVertexShader(pD3DDev9, NULL);
IDirect3DDevice9_SetPixelShader(pD3DDev9, NULL);
}
#endif
}
@ -1685,17 +2033,17 @@ static void Shader_ProgramParam ( shader_t *shader, shaderpass_t *pass, char **p
parmtype = SP_CVAR3F;
}
else if (!Q_stricmp(token, "time"))
parmtype = SP_TIME;
parmtype = SP_E_TIME;
else if (!Q_stricmp(token, "eyepos"))
parmtype = SP_EYEPOS;
parmtype = SP_E_EYEPOS;
else if (!Q_stricmp(token, "entmatrix"))
parmtype = SP_ENTMATRIX;
parmtype = SP_M_MODEL;
else if (!Q_stricmp(token, "colours") || !Q_stricmp(token, "colors"))
parmtype = SP_ENTCOLOURS;
parmtype = SP_E_COLOURS;
else if (!Q_stricmp(token, "upper"))
parmtype = SP_TOPCOLOURS;
parmtype = SP_E_TOPCOLOURS;
else if (!Q_stricmp(token, "lower"))
parmtype = SP_BOTTOMCOLOURS;
parmtype = SP_E_BOTTOMCOLOURS;
else if (!Q_stricmp(token, "lightradius"))
parmtype = SP_LIGHTRADIUS;
else if (!Q_stricmp(token, "lightcolour"))
@ -1805,6 +2153,7 @@ static shaderkey_t shaderkeys[] =
{"sort", Shader_Sort},
{"deformvertexes", Shader_DeformVertexes},
{"portal", Shader_Portal},
{"lpp_light", Shader_Prelight},
{"entitymergable", Shader_EntityMergable},
{"glslprogram", Shader_GLSLProgramName},
@ -1886,6 +2235,16 @@ static qboolean ShaderPass_MapGen (shader_t *shader, shaderpass_t *pass, char *t
pass->texgen = T_GEN_CURRENTRENDER;
pass->tcgen = TC_GEN_BASE; //FIXME: moo!
}
else if (!Q_stricmp (tname, "$sourcecolour"))
{
pass->texgen = T_GEN_SOURCECOLOUR;
pass->tcgen = TC_GEN_BASE; //FIXME: moo!
}
else if (!Q_stricmp (tname, "$sourcedepth"))
{
pass->texgen = T_GEN_SOURCEDEPTH;
pass->tcgen = TC_GEN_BASE; //FIXME: moo!
}
else
return false;
return true;
@ -2253,7 +2612,7 @@ static void Shaderpass_TcMod (shader_t *shader, shaderpass_t *pass, char **ptr)
tcmod_t *tcmod;
char *token;
if (pass->numtcmods >= SHADER_TCMOD_MAX)
if (pass->numtcmods >= SHADER_MAX_TC_MODS)
{
return;
}
@ -3504,6 +3863,32 @@ void Shader_DefaultBSPLM(char *shortname, shader_t *s, const void *args)
"}\n"
);
#ifdef GLQUAKE
if (!builtin && r_lightprepass.ival)
{
builtin = (
"{\n"
"program lpp_wall\n"
"{\n"
"map $sourcecolour\n"
"}\n"
"{\n"
"map $diffuse\n"
"}\n"
"{\n"
"map $lightmap\n"
"}\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n"
"map $deluxmap\n"
"}\n"
"{\n"
"map $fullbright\n"
"}\n"
"}\n"
);
}
if (!builtin && gl_config.arb_shader_objects && gl_config.nofixedfunc)
{
builtin = (
@ -3934,7 +4319,14 @@ void Shader_DefaultSkin(char *shortname, shader_t *s, const void *args)
{
Shader_DefaultScript(shortname, s,
"{\n"
"program defaultskin\n"
"if $lpp\n"
"[\n"
"program defaultskin\n"
"]\n"
"else\n"
"[\n"
"program lpp_skin\n"
"]\n"
"{\n"
"map $diffuse\n"
"rgbgen lightingDiffuse\n"

View File

@ -1218,7 +1218,7 @@ static qboolean Sh_ScissorForBox(vec3_t mins, vec3_t maxs)
return true;
// set up the scissor rectangle
qglScissor(ix1, iy1, ix2 - ix1, iy2 - iy1);
//qglEnable(GL_SCISSOR_TEST);
// qglEnable(GL_SCISSOR_TEST);
return false;
}
@ -1229,7 +1229,7 @@ void GL_BeginRenderBuffer_DepthOnly(texid_t depthtexture)
{
if (!shadow_fbo_id)
{
qglGenRenderbuffersEXT(1, &shadow_fbo_id);
qglGenFramebuffersEXT(1, &shadow_fbo_id);
qglBindFramebufferEXT(GL_FRAMEBUFFER_EXT, shadow_fbo_id);
qglDrawBuffer(GL_NONE);
qglReadBuffer(GL_NONE);
@ -1855,7 +1855,7 @@ static qboolean Sh_DrawStencilLight(dlight_t *dl, vec3_t colour, qbyte *vvis)
BE_SelectMode(BEM_STENCIL);
//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);
@ -2065,7 +2065,9 @@ void Sh_DrawLights(qbyte *vis)
extern cvar_t r_shadow_realtime_world_shadows, r_shadow_realtime_dlight_shadows;
if (!r_shadow_realtime_world.ival && !r_shadow_realtime_dlight.ival)
{
return;
}
/*no stencil?*/
if (gl_config.nofixedfunc)

View File

@ -122,6 +122,8 @@ void (APIENTRY *qglDeleteRenderbuffersEXT)(GLsizei n, const GLuint* ids);
void (APIENTRY *qglBindRenderbufferEXT)(GLenum target, GLuint id);
void (APIENTRY *qglRenderbufferStorageEXT)(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height);
void (APIENTRY *qglFramebufferTexture2DEXT)(GLenum target, GLenum attachmentPoint, GLenum textureTarget, GLuint textureId, GLint level);
void (APIENTRY *qglFramebufferRenderbufferEXT)(GLenum target, GLenum attachmentPoint, GLenum textureTarget, GLuint textureId);
GLenum (APIENTRY *qglCheckFramebufferStatusEXT)(GLenum target);
/*
PFNGLPROGRAMSTRINGARBPROC qglProgramStringARB;
@ -647,14 +649,16 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name), float ver)
if (GL_CheckExtension("GL_EXT_framebuffer_object"))
{
gl_config.ext_framebuffer_objects = true;
qglGenFramebuffersEXT = (void *)getglext("glGenFramebuffersEXT");
qglDeleteFramebuffersEXT = (void *)getglext("glDeleteFramebuffersEXT");
qglBindFramebufferEXT = (void *)getglext("glBindFramebufferEXT");
qglGenRenderbuffersEXT = (void *)getglext("glGenRenderbuffersEXT");
qglDeleteRenderbuffersEXT = (void *)getglext("glDeleteRenderbuffersEXT");
qglBindRenderbufferEXT = (void *)getglext("glBindRenderbufferEXT");
qglRenderbufferStorageEXT = (void *)getglext("glRenderbufferStorageEXT");
qglFramebufferTexture2DEXT = (void *)getglext("glFramebufferTexture2DEXT");
qglGenFramebuffersEXT = (void *)getglext("glGenFramebuffersEXT");
qglDeleteFramebuffersEXT = (void *)getglext("glDeleteFramebuffersEXT");
qglBindFramebufferEXT = (void *)getglext("glBindFramebufferEXT");
qglGenRenderbuffersEXT = (void *)getglext("glGenRenderbuffersEXT");
qglDeleteRenderbuffersEXT = (void *)getglext("glDeleteRenderbuffersEXT");
qglBindRenderbufferEXT = (void *)getglext("glBindRenderbufferEXT");
qglRenderbufferStorageEXT = (void *)getglext("glRenderbufferStorageEXT");
qglFramebufferTexture2DEXT = (void *)getglext("glFramebufferTexture2DEXT");
qglFramebufferRenderbufferEXT = (void *)getglext("glFramebufferRenderbufferEXT");
qglCheckFramebufferStatusEXT = (void *)getglext("glCheckFramebufferStatusEXT");
}
#ifdef DEBUG
@ -716,8 +720,8 @@ GLhandleARB GLSlang_CreateShader (char *name, char *versionline, char **precompi
if (gl_config.nofixedfunc)
{
prstrings[strings++] =
"#define ftetransform() (m_projection * m_modelview * vec4(v_position, 1.0))\n"
"uniform mat4 m_modelview, m_projection;\n"
"#define ftetransform() (m_modelviewprojection * vec4(v_position, 1.0))\n"
"uniform mat4 m_modelviewprojection;\n"
"attribute vec3 v_position;\n";
}
else
@ -726,9 +730,9 @@ GLhandleARB GLSlang_CreateShader (char *name, char *versionline, char **precompi
"#ifdef SKELETAL\n"
"attribute vec4 v_bone;\n"
"attribute vec4 v_weight;\n"
"uniform mat4 m_modelview, m_projection;\n"
"uniform mat4 m_modelviewprojection;\n"
"uniform mat3x4 m_bones["STRINGIFY(MAX_BONES)"];\n"
"#define v_position gl_Vertex\n"
"attribute vec3 v_position;\n"
"vec4 skeletaltransform()\n"
"{"
@ -737,7 +741,7 @@ GLhandleARB GLSlang_CreateShader (char *name, char *versionline, char **precompi
" wmat += m_bones[int(v_bone.y)] * v_weight.y;\n"
" wmat += m_bones[int(v_bone.z)] * v_weight.z;\n"
" wmat += m_bones[int(v_bone.w)] * v_weight.w;\n"
" return m_projection * m_modelview * vec4(v_position * wmat, v_position.w);\n"
" return m_modelviewprojection * vec4(vec4(v_position.xyz, 1.0) * wmat, 1.0);\n"
"}\n"
"#define ftetransform() skeletaltransform()\n"
"#else\n"

View File

@ -333,6 +333,7 @@ void R_DrawHLModel(entity_t *curent);
// gl_rlight.c
//
void GLR_RenderDlights (void);
void R_GenDlightBatches(batch_t *batches[]);
#ifdef GLQUAKE
void GLR_MarkQ2Lights (dlight_t *light, int bit, mnode_t *node);
void R_InitFlashblends (void);
@ -750,6 +751,8 @@ extern void (APIENTRY *qglDeleteRenderbuffersEXT)(GLsizei n, const GLuint* ids);
extern void (APIENTRY *qglBindRenderbufferEXT)(GLenum target, GLuint id);
extern void (APIENTRY *qglRenderbufferStorageEXT)(GLenum target, GLenum internalFormat, GLsizei width, GLsizei height);
extern void (APIENTRY *qglFramebufferTexture2DEXT)(GLenum target, GLenum attachmentPoint, GLenum textureTarget, GLuint textureId, GLint level);
extern void (APIENTRY *qglFramebufferRenderbufferEXT)(GLenum target, GLenum attachmentPoint, GLenum textureTarget, GLuint textureId);
extern GLenum (APIENTRY *qglCheckFramebufferStatusEXT)(GLenum target);
/*
extern qboolean gl_arb_fragment_program;

View File

@ -53,7 +53,6 @@ typedef struct
SHADER_TCMOD_SCROLL, //boring moving texcoords with time
SHADER_TCMOD_STRETCH, //constant factor
SHADER_TCMOD_ROTATE,
SHADER_TCMOD_MAX,
SHADER_TCMOD_TRANSFORM,
SHADER_TCMOD_TURB
} type;
@ -221,6 +220,9 @@ typedef struct shaderpass_s {
T_GEN_CURRENTRENDER,//copy the current screen to a texture, and draw that
T_GEN_SOURCECOLOUR, //used for render-to-texture targets
T_GEN_SOURCEDEPTH, //used for render-to-texture targets
T_GEN_VIDEOMAP, //use the media playback as an image source, updating each frame for which it is visible
T_GEN_SKYBOX, //use a skybox instead, otherwise T_GEN_SINGLEMAP
} texgen;
@ -275,23 +277,27 @@ typedef struct {
SP_FIRSTUNIFORM, //never set
/*entity properties*/
SP_ENTCOLOURS,
SP_ENTCOLOURSIDENT,
SP_TOPCOLOURS,
SP_BOTTOMCOLOURS,
SP_TIME,
SP_E_ORIGIN,
SP_E_COLOURS,
SP_E_COLOURSIDENT,
SP_E_GLOWMOD,
SP_E_TOPCOLOURS,
SP_E_BOTTOMCOLOURS,
SP_E_TIME,
SP_E_L_DIR, /*these light values are non-dynamic light as in classic quake*/
SP_E_L_MUL,
SP_E_L_AMBIENT,
SP_E_EYEPOS, /*viewer's eyepos, in model space*/
SP_V_EYEPOS, /*viewer's eyepos, in world space*/
SP_ENTBONEMATRICIES,
SP_EYEPOS,
SP_ENTMATRIX,
SP_VIEWMATRIX,
SP_MODELMATRIX,
SP_MODELVIEWMATRIX,
SP_PROJECTIONMATRIX,
SP_MODELVIEWPROJECTIONMATRIX,
SP_M_ENTBONES,
SP_M_VIEW,
SP_M_MODEL,
SP_M_MODELVIEW,
SP_M_PROJECTION,
SP_M_MODELVIEWPROJECTION,
SP_M_INVVIEWPROJECTION,
SP_M_INVMODELVIEWPROJECTION,
SP_RENDERTEXTURESCALE, /*multiplier for currentrender->texcoord*/
@ -325,6 +331,8 @@ union programhandle_u
{
void *vert;
void *frag;
void *ctabf;
void *ctabv;
} hlsl;
#endif
};
@ -429,6 +437,7 @@ void R_BackendInit (void);
void Shader_Shutdown (void);
qboolean Shader_Init (void);
void Shader_NeedReload(void);
void Shader_WriteOutGenerics_f(void);
mfog_t *CM_FogForOrigin(vec3_t org);
@ -470,7 +479,8 @@ void D3DBE_DrawWorld (qbyte *vis);
qboolean D3DBE_LightCullModel(vec3_t org, model_t *model);
void D3DBE_SelectEntity(entity_t *ent);
union programhandle_u D3DShader_CreateProgram (char **precompilerconstants, char *vert, char *frag);
void D3DShader_CreateProgram (program_t *prog, int permu, char **precompilerconstants, char *vert, char *frag);
int D3DShader_FindUniform(union programhandle_u *h, int type, char *name);
void D3DShader_Init(void);
#endif
@ -496,4 +506,10 @@ 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);
#endif
struct shader_field_names_s
{
char *name;
enum shaderprogparmtype_e ptype;
} shader_field_names[];
#endif

View File

@ -463,7 +463,7 @@ int IWebAuthorize(char *name, char *password)
return IWEBACC_READ;
#else
#ifndef CLIENTONLY
int id = Rank_GetPlayerID(name, atoi(password), false, true);
int id = Rank_GetPlayerID(NULL, name, atoi(password), false, true);
rankinfo_t info;
if (!id)
{

View File

@ -35,6 +35,12 @@
#error Bad cont size
#endif
#ifdef DEBUGABLE
#define OPCODE (st->op & ~0x8000)
#else
#define OPCODE (st->op)
#endif
#define ENGINEPOINTER(p) ((char*)(p) - progfuncs->stringtable)
#define QCPOINTER(p) (eval_t *)(p->_int+progfuncs->stringtable)
#define QCPOINTERM(p) (eval_t *)((p)+progfuncs->stringtable)
@ -49,11 +55,10 @@ cont: //last statement may have been a breakpoint
st = pr_statements + s;
reeval:
switch (st->op & ~0x8000)
#else
st++;
switch (st->op)
#endif
switch (OPCODE)
{
case OP_ADD_F:
OPC->_float = OPA->_float + OPB->_float;
@ -567,11 +572,10 @@ reeval:
RUNAWAYCHECK();
pr_xstatement = st-pr_statements;
if (st->op > OP_CALL8)
pr_argc = st->op - (OP_CALL1H-1);
if (OPCODE > OP_CALL8)
pr_argc = OPCODE - (OP_CALL1H-1);
else
pr_argc = st->op - OP_CALL0;
pr_argc = OPCODE - OP_CALL0;
fnum = OPA->function;
if ((fnum & ~0xff000000)==0)
{
@ -743,7 +747,7 @@ if (pr_typecurrent != 0)
//array/structure reading/writing.
case OP_GLOBALADDRESS:
OPC->_int = ENGINEPOINTER(&OPA->_int + OPB->_int);
OPC->_int = ENGINEPOINTER(&OPA->_int + OPB->_int); /*pointer arithmatic*/
break;
case OP_POINTER_ADD: //pointer to 32 bit (remember to *3 for vectors)
OPC->_int = OPA->_int + OPB->_int*4;
@ -755,7 +759,7 @@ if (pr_typecurrent != 0)
case OP_LOADA_ENT:
case OP_LOADA_S:
case OP_LOADA_FNC:
ptr = (eval_t *)(&OPA->_int + OPB->_int);
ptr = (eval_t *)(&OPA->_int + OPB->_int); /*pointer arithmatic*/
OPC->_int = ptr->_int;
break;
@ -784,7 +788,7 @@ if (pr_typecurrent != 0)
case OP_LOADP_ENT:
case OP_LOADP_S:
case OP_LOADP_FNC:
ptr = QCPOINTERM(OPA->_int + OPB->_int);
ptr = QCPOINTERM(OPA->_int + OPB->_int*p);
OPC->_int = ptr->_int;
break;
@ -859,44 +863,44 @@ if (pr_typecurrent != 0)
break;
case OP_RAND0:
G_FLOAT(OFS_RETURN) = (rand()&0x7fff)/((float)0x7fff);
OPC->_float = (rand()&0x7fff)/((float)0x7fff);
break;
case OP_RAND1:
G_FLOAT(OFS_RETURN) = (rand()&0x7fff)/((float)0x7fff)*OPA->_float;
OPC->_float = (rand()&0x7fff)/((float)0x7fff)*OPA->_float;
break;
case OP_RAND2:
if(OPA->_float < OPB->_float)
{
G_FLOAT(OFS_RETURN) = OPA->_float+((rand()&0x7fff)/((float)0x7fff)
OPC->_float = OPA->_float+((rand()&0x7fff)/((float)0x7fff)
*(OPB->_float-OPA->_float));
}
else
{
G_FLOAT(OFS_RETURN) = OPB->_float+((rand()&0x7fff)/((float)0x7fff)
OPC->_float = OPB->_float+((rand()&0x7fff)/((float)0x7fff)
*(OPA->_float-OPB->_float));
}
break;
case OP_RANDV0:
G_FLOAT(OFS_RETURN+0) = (rand()&0x7fff)/((float)0x7fff);
G_FLOAT(OFS_RETURN+1) = (rand()&0x7fff)/((float)0x7fff);
G_FLOAT(OFS_RETURN+2) = (rand()&0x7fff)/((float)0x7fff);
OPC->_vector[0] = (rand()&0x7fff)/((float)0x7fff);
OPC->_vector[1] = (rand()&0x7fff)/((float)0x7fff);
OPC->_vector[2] = (rand()&0x7fff)/((float)0x7fff);
break;
case OP_RANDV1:
G_FLOAT(OFS_RETURN+0) = (rand()&0x7fff)/((float)0x7fff)*OPA->_vector[0];
G_FLOAT(OFS_RETURN+1) = (rand()&0x7fff)/((float)0x7fff)*OPA->_vector[1];
G_FLOAT(OFS_RETURN+2) = (rand()&0x7fff)/((float)0x7fff)*OPA->_vector[2];
OPC->_vector[0] = (rand()&0x7fff)/((float)0x7fff)*OPA->_vector[0];
OPC->_vector[1] = (rand()&0x7fff)/((float)0x7fff)*OPA->_vector[1];
OPC->_vector[2] = (rand()&0x7fff)/((float)0x7fff)*OPA->_vector[2];
break;
case OP_RANDV2:
for(i = 0; i < 3; i++)
{
if(OPA->_vector[i] < OPB->_vector[i])
{
G_FLOAT(OFS_RETURN+i) = OPA->_vector[i]+((rand()&0x7fff)/((float)0x7fff)
OPC->_vector[i] = OPA->_vector[i]+((rand()&0x7fff)/((float)0x7fff)
*(OPB->_vector[i]-OPA->_vector[i]));
}
else
{
G_FLOAT(OFS_RETURN+i) = OPB->_vector[i]+(rand()*(1.0f/RAND_MAX)
OPC->_vector[i] = OPB->_vector[i]+(rand()*(1.0f/RAND_MAX)
*(OPA->_vector[i]-OPB->_vector[i]));
}
}
@ -909,7 +913,7 @@ if (pr_typecurrent != 0)
case OP_SWITCH_E:
case OP_SWITCH_FNC:
swtch = OPA;
swtchtype = st->op;
swtchtype = OPCODE;
RUNAWAYCHECK();
st += (sofs)st->b - 1; // offset the st++
break;
@ -1072,7 +1076,7 @@ if (pr_typecurrent != 0)
if ((unsigned int)OPA->_int < (unsigned int)st->c || (unsigned int)OPA->_int >= (unsigned int)st->b)
{
pr_xstatement = st-pr_statements;
PR_RunError(progfuncs, "Progs boundcheck failed. Value is %i.", OPA->_int);
PR_RunError(progfuncs, "Progs boundcheck failed. Value is %i. Must be between %u and %u", OPA->_int, st->c, st->b);
}
break;
/* case OP_PUSH:
@ -1124,6 +1128,7 @@ if (pr_typecurrent != 0)
#undef dstatement_t
#undef sofs
#undef uofs
#undef OPCODE
#undef ENGINEPOINTER
#undef QCPOINTER

View File

@ -2922,6 +2922,9 @@ retry:
break;
}
}
if (st16[i].op >= OP_RAND0 && st16[i].op <= OP_RANDV2)
if (!st16[i].c)
st16[i].c = OFS_RETURN;
}
if (hexencalling)
{
@ -2951,6 +2954,9 @@ retry:
break;
}
}
if (st16[i].op >= OP_RAND0 && st16[i].op <= OP_RANDV2)
if (!st16[i].c)
st16[i].c = OFS_RETURN;
}
if (hexencalling)
{

View File

@ -45,9 +45,9 @@ void PR_MoveParms(progfuncs_t *progfuncs, progsnum_t progs1, progsnum_t progs2)
p2 = &pr_progstate[(int)progs2];
if ((unsigned)progs1 >= maxprogs || !p1->globals)
Sys_Error("QCLIB: Bad prog type - %i", progs1);
PR_RunError(progfuncs, "QCLIB: Bad prog type - %i", progs1);
if ((unsigned)progs2 >= maxprogs || !p2->globals)
Sys_Error("QCLIB: Bad prog type - %i", progs2);
PR_RunError(progfuncs, "QCLIB: Bad prog type - %i", progs2);
//copy parms.
for (a = 0; a < MAX_PARMS;a++)

View File

@ -533,7 +533,8 @@ void QCC_PR_Lex (void);
// reads the next token into pr_token and classifies its type
QCC_type_t *QCC_PR_NewType (char *name, int basictype);
QCC_type_t *QCC_PR_ParseType (int newtype); extern pbool type_inlinefunction;
QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail);
extern pbool type_inlinefunction;
QCC_type_t *QCC_TypeForName(char *name);
QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype);
QCC_type_t *QCC_PR_ParseFunctionTypeReacc (int newtype, QCC_type_t *returntype);
@ -542,6 +543,8 @@ CompilerConstant_t *QCC_PR_DefineName(char *name);
void QCC_RemapOffsets(unsigned int firststatement, unsigned int laststatement, unsigned int min, unsigned int max, unsigned int newmin);
int QCC_PR_IntConstExpr(void);
#ifndef COMMONINLINES
pbool QCC_PR_CheckImmediate (char *string);
pbool QCC_PR_CheckToken (char *string);

File diff suppressed because it is too large Load Diff

View File

@ -2828,7 +2828,12 @@ char *QCC_PR_ParseName (void)
char *ret;
if (pr_token_type != tt_name)
QCC_PR_ParseError (ERR_NOTANAME, "\"%s\" - not a name", pr_token);
{
if (pr_token_type == tt_eof)
QCC_PR_ParseError (ERR_EOF, "unexpected EOF", pr_token);
else
QCC_PR_ParseError (ERR_NOTANAME, "\"%s\" - not a name", pr_token);
}
if (strlen(pr_token) >= MAX_NAME-1)
QCC_PR_ParseError (ERR_NAMETOOLONG, "name too long");
strcpy (ident, pr_token);
@ -3105,7 +3110,7 @@ QCC_type_t *QCC_PR_ParseFunctionType (int newtype, QCC_type_t *returntype)
break;
}
nptype = QCC_PR_ParseType(true);
nptype = QCC_PR_ParseType(true, false);
if (nptype->type == ev_void)
break;
@ -3188,7 +3193,7 @@ QCC_type_t *QCC_PR_ParseFunctionTypeReacc (int newtype, QCC_type_t *returntype)
{
name = QCC_PR_ParseName();
QCC_PR_Expect(":");
nptype = QCC_PR_ParseType(true);
nptype = QCC_PR_ParseType(true, false);
}
if (nptype->type == ev_void)
@ -3219,12 +3224,17 @@ QCC_type_t *QCC_PR_ParseFunctionTypeReacc (int newtype, QCC_type_t *returntype)
}
QCC_type_t *QCC_PR_PointerType (QCC_type_t *pointsto)
{
QCC_type_t *ptype;
char name[128];
sprintf(name, "*%s", pointsto->name);
ptype = QCC_PR_NewType(name, ev_pointer);
QCC_type_t *ptype, *e;
ptype = QCC_PR_NewType("ptr", ev_pointer);
ptype->aux_type = pointsto;
return QCC_PR_FindType (ptype);
e = QCC_PR_FindType (ptype);
if (e == ptype)
{
char name[128];
sprintf(name, "ptr to %s", pointsto->name);
e->name = strdup(name);
}
return e;
}
QCC_type_t *QCC_PR_FieldType (QCC_type_t *pointsto)
{
@ -3238,7 +3248,10 @@ QCC_type_t *QCC_PR_FieldType (QCC_type_t *pointsto)
}
pbool type_inlinefunction;
QCC_type_t *QCC_PR_ParseType (int newtype)
/*newtype=true: creates a new type always
silentfail=true: function is permitted to return NULL if it was not given a type, otherwise never returns NULL
*/
QCC_type_t *QCC_PR_ParseType (int newtype, pbool silentfail)
{
QCC_type_t *newparm;
QCC_type_t *newt;
@ -3253,7 +3266,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype)
if (QCC_PR_CheckToken ("..")) //so we don't end up with the user specifying '. .vector blah' (hexen2 added the .. token for array ranges)
{
newt = QCC_PR_NewType("FIELD TYPE", ev_field);
newt->aux_type = QCC_PR_ParseType (false);
newt->aux_type = QCC_PR_ParseType (false, false);
newt->size = newt->aux_type->size;
@ -3271,7 +3284,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype)
if (QCC_PR_CheckToken ("."))
{
newt = QCC_PR_NewType("FIELD TYPE", ev_field);
newt->aux_type = QCC_PR_ParseType (false);
newt->aux_type = QCC_PR_ParseType (false, false);
newt->size = newt->aux_type->size;
@ -3345,7 +3358,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype)
// if (QCC_PR_CheckToken(","))
// type->next = QCC_PR_NewType(type->name, type->type);
// else
newparm = QCC_PR_ParseType(true);
newparm = QCC_PR_ParseType(true, false);
if (newparm->type == ev_struct || newparm->type == ev_union) //we wouldn't be able to handle it.
QCC_PR_ParseError(ERR_INTERNAL, "Struct or union in class %s", classname);
@ -3407,7 +3420,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype)
newparm = QCC_PR_NewType(newparm->name, newparm->type);
}
else
newparm = QCC_PR_ParseType(true);
newparm = QCC_PR_ParseType(true, false);
if (!QCC_PR_CheckToken(";"))
{
@ -3415,8 +3428,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype)
QCC_PR_Lex();
if (QCC_PR_CheckToken("["))
{
newparm->size*=atoi(pr_token);
QCC_PR_Lex();
newparm->size*=QCC_PR_IntConstExpr();
QCC_PR_Expect("]");
}
QCC_PR_CheckToken(";");
@ -3454,7 +3466,7 @@ QCC_type_t *QCC_PR_ParseType (int newtype)
newparm = QCC_PR_NewType(newparm->name, newparm->type);
}
else
newparm = QCC_PR_ParseType(true);
newparm = QCC_PR_ParseType(true, false);
if (QCC_PR_CheckToken(";"))
newparm->name = QCC_CopyString("")+strings;
else
@ -3504,16 +3516,22 @@ QCC_type_t *QCC_PR_ParseType (int newtype)
type = type_function;
else
{
if (silentfail)
return NULL;
QCC_PR_ParseError (ERR_NOTATYPE, "\"%s\" is not a type", name);
type = type_float; // shut up compiler warning
}
}
QCC_PR_Lex ();
while (QCC_PR_CheckToken("*"))
type = QCC_PointerTypeTo(type);
if (QCC_PR_CheckToken ("(")) //this is followed by parameters. Must be a function.
{
type_inlinefunction = true;
return QCC_PR_ParseFunctionType(newtype, type);
type = QCC_PR_ParseFunctionType(newtype, type);
}
else
{
@ -3521,9 +3539,8 @@ QCC_type_t *QCC_PR_ParseType (int newtype)
{
type = QCC_PR_DuplicateType(type);
}
return type;
}
return type;
}
#endif

View File

@ -238,7 +238,8 @@ compiler_flag_t compiler_flag[] = {
{&flag_filetimes, 0, "filetimes", "Check Filetimes", "Recompiles the progs only if the file times are modified."},
{&flag_fasttrackarrays, FLAG_MIDCOMPILE|FLAG_ASDEFAULT,"fastarrays","fast arrays where possible", "Generates extra instructions inside array handling functions to detect engine and use extension opcodes only in supporting engines.\nAdds a global which is set by the engine if the engine supports the extra opcodes. Note that this applies to all arrays or none."},
{&flag_assume_integer, FLAG_MIDCOMPILE,"assumeint", "Assume Integers", "Numerical constants are assumed to be integers, instead of floats."},
{&pr_subscopedlocals, FLAG_MIDCOMPILE, "subscope", "Subscoped Locals", "Restrict the scope of locals to the block they are actually defined within, as in C."},
{&pr_subscopedlocals, FLAG_MIDCOMPILE,"subscope", "Subscoped Locals", "Restrict the scope of locals to the block they are actually defined within, as in C."},
{&verbose, FLAG_MIDCOMPILE,"verbose", "Verbose", "Lots of extra compiler messages."},
{NULL}
};
@ -2865,10 +2866,10 @@ void QCC_main (int argc, char **argv) //as part of the quake engine
pHash_GetNext = &Hash_GetNext;
pHash_Add = &Hash_Add;
MAX_REGS = 65536;
MAX_REGS = 1<<17;
MAX_STRINGS = 1000000;
MAX_GLOBALS = 65535;
MAX_FIELDS = 2048;
MAX_GLOBALS = 1<<17;
MAX_FIELDS = 1<<12;
MAX_STATEMENTS = 0x80000;
MAX_FUNCTIONS = 16384;
maxtypeinfos = 16384;

View File

@ -166,7 +166,7 @@ void ED_Spawned (struct edict_s *ent, int loading)
ent->xv->dimension_solid = 255;
ent->xv->dimension_hit = 255;
ent->xv->Version = sv.csqcentversion[ent->entnum]+1;
ent->xv->Version = sv.csqcentversion[ent->entnum];
ent->xv->uniquespawnid = sv.csqcentversion[ent->entnum];
}
}
@ -202,6 +202,7 @@ pbool ED_CanFree (edict_t *ed)
VectorClear (ed->v->angles);
ed->v->nextthink = 0;
ed->v->solid = 0;
ed->xv->pvsflags = 0;
ed->v->classname = 0;
@ -216,12 +217,13 @@ pbool ED_CanFree (edict_t *ed)
ed->v->think = 0;
}
ed->xv->Version+=1;
ed->xv->SendEntity = 0;
sv.csqcentversion[ed->entnum] = ed->xv->Version+1;
sv.csqcentversion[ed->entnum] += 1;
#ifdef USEODE
World_Physics_RemoveFromEntity(&sv.world, (wedict_t*)ed);
World_Physics_RemoveJointFromEntity(&sv.world, (wedict_t*)ed);
World_ODE_RemoveFromEntity(&sv.world, (wedict_t*)ed);
World_ODE_RemoveJointFromEntity(&sv.world, (wedict_t*)ed);
#endif
@ -413,17 +415,19 @@ void SVPR_Event_Touch(world_t *w, wedict_t *s, wedict_t *o)
pr_global_struct->self = EDICT_TO_PROG(w->progs, s);
pr_global_struct->other = EDICT_TO_PROG(w->progs, o);
pr_global_struct->time = w->physicstime;
#ifdef VM_Q1
if (w==&sv.world && svs.gametype == GT_Q1QVM)
Q1QVM_Touch();
else
#endif
PR_ExecuteProgram (w->progs, s->v->touch);
PR_ExecuteProgram (w->progs, s->v->touch);
pr_global_struct->self = oself;
pr_global_struct->other = oother;
}
void SVPR_Event_Think(world_t *w, wedict_t *s)
{
pr_global_struct->self = EDICT_TO_PROG(w->progs, s);
pr_global_struct->other = EDICT_TO_PROG(w->progs, w->edicts);
PR_ExecuteProgram (w->progs, s->v->think);
}
void Q_SetProgsParms(qboolean forcompiler)
{
progstype = PROG_NONE;
@ -469,6 +473,8 @@ void Q_SetProgsParms(qboolean forcompiler)
sv.world.progs = svprogfuncs = InitProgs(&svprogparms);
}
sv.world.Event_Touch = SVPR_Event_Touch;
sv.world.Event_Think = SVPR_Event_Think;
sv.world.Event_Sound = SVQ1_StartSound;
sv.world.GetCModel = SVPR_GetCModel;
PRSV_ClearThreads();
PR_fclose_progs(svprogfuncs);
@ -480,7 +486,7 @@ void Q_SetProgsParms(qboolean forcompiler)
void PR_Deinit(void)
{
#ifdef USEODE
World_Physics_End(&sv.world);
World_ODE_End(&sv.world);
#endif
#ifdef SQL
@ -678,6 +684,14 @@ void PR_LoadGlabalStruct(void)
SV_ClearQCStats();
sv.world.g.self = pr_nqglobal_struct->self;
sv.world.g.other = pr_nqglobal_struct->other;
sv.world.g.force_retouch = pr_nqglobal_struct->force_retouch;
sv.world.g.frametime = pr_nqglobal_struct->frametime;
sv.world.g.newmis = pr_nqglobal_struct->newmis;
sv.world.g.time = pr_nqglobal_struct->time;
/*Hexen2 has lots of extra stats, which I don't want special support for, so list them here and send them as for csqc*/
if (progstype == PROG_H2)
{
SV_QCStatName(ev_float, "level", STAT_H2_LEVEL);
@ -1476,7 +1490,7 @@ void Q_InitProgs(void)
SV_RegisterH2CustomTents();
#ifdef USEODE
World_Physics_Start(&sv.world);
World_ODE_Start(&sv.world);
#endif
}
@ -2819,7 +2833,7 @@ static void QCBUILTIN PF_sound (progfuncs_t *prinst, struct globalvars_s *pr_glo
if (volume > 255)
volume = 255;
SVQ1_StartSound (entity, channel, sample, volume, attenuation, pitchadj);
SVQ1_StartSound ((wedict_t*)entity, channel, sample, volume, attenuation, pitchadj);
}
//an evil one from telejano.
@ -2960,7 +2974,6 @@ static void QCBUILTIN PF_traceboxdp (progfuncs_t *prinst, struct globalvars_s *p
set_trace_globals(&trace, pr_globals);
}
extern trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore);
static void QCBUILTIN PF_TraceToss (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
trace_t trace;
@ -2972,7 +2985,7 @@ static void QCBUILTIN PF_TraceToss (progfuncs_t *prinst, struct globalvars_s *pr
Con_DPrintf("tracetoss: can not use world entity\n");
ignore = G_EDICT(prinst, OFS_PARM1);
trace = SV_Trace_Toss (ent, ignore);
trace = WPhys_Trace_Toss (&sv.world, (wedict_t*)ent, (wedict_t*)ignore);
set_trace_globals(&trace, pr_globals);
}
@ -4458,6 +4471,17 @@ void QCBUILTIN PF_WriteCoord (progfuncs_t *prinst, struct globalvars_s *pr_globa
#endif
}
void QCBUILTIN PF_WriteFloat (progfuncs_t *prinst, struct globalvars_s *pr_globals)
{
if (G_FLOAT(OFS_PARM0) == MSG_CSQC)
{ //csqc buffers are always written.
MSG_WriteFloat(&csqcmsgbuffer, G_FLOAT(OFS_PARM1));
return;
}
return;
}
void PF_WriteString_Internal (int target, char *str)
{
if (target == MSG_CSQC)
@ -6981,7 +7005,7 @@ static void QCBUILTIN PF_h2StopSound(progfuncs_t *prinst, struct globalvars_s *p
entity = G_EDICT(prinst, OFS_PARM0);
channel = G_FLOAT(OFS_PARM1);
SVQ1_StartSound (entity, channel, "", 1, 0, 0);
SVQ1_StartSound ((wedict_t*)entity, channel, "", 1, 0, 0);
}
static void QCBUILTIN PF_h2updatesoundpos(progfuncs_t *prinst, struct globalvars_s *pr_globals)
@ -8375,15 +8399,7 @@ static void QCBUILTIN PF_runclientphys(progfuncs_t *prinst, struct globalvars_s
if (!touched->v->touch || (playertouch[n/8]&(1<<(n%8))))
continue;
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, touched);
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, ent);
pr_global_struct->time = sv.time;
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_Touch();
else
#endif
PR_ExecuteProgram (svprogfuncs, touched->v->touch);
sv.world.Event_Touch(&sv.world, (wedict_t*)touched, (wedict_t*)ent);
playertouch[n/8] |= 1 << (n%8);
}
}
@ -8439,7 +8455,7 @@ qboolean SV_RunFullQCMovement(client_t *client, usercmd_t *ucmd)
sv_player->xv->movement[2] = ucmd->upmove;
}
SV_CheckVelocity(sv_player);
WPhys_CheckVelocity(&sv.world, (wedict_t*)sv_player);
//
// angles
@ -8458,7 +8474,7 @@ qboolean SV_RunFullQCMovement(client_t *client, usercmd_t *ucmd)
//prethink should be consistant with what the engine normally does
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, client->edict);
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PlayerPreThink);
SV_RunThink (client->edict);
WPhys_RunThink (&sv.world, (wedict_t*)client->edict);
@ -8472,9 +8488,18 @@ qboolean SV_RunFullQCMovement(client_t *client, usercmd_t *ucmd)
pr_global_struct->input_timelength = ucmd->msec/1000.0f;
//precision inaccuracies. :(
#define ANGLE2SHORT(x) (x) * (65536/360.0)
(pr_global_struct->input_angles)[0] = SHORT2ANGLE(ucmd->angles[0]);
(pr_global_struct->input_angles)[1] = SHORT2ANGLE(ucmd->angles[1]);
(pr_global_struct->input_angles)[2] = SHORT2ANGLE(ucmd->angles[2]);
if (sv_player->v->fixangle)
{
(pr_global_struct->input_angles)[0] = sv_player->v->v_angle[0];
(pr_global_struct->input_angles)[1] = sv_player->v->v_angle[1];
(pr_global_struct->input_angles)[2] = sv_player->v->v_angle[2];
}
else
{
(pr_global_struct->input_angles)[0] = SHORT2ANGLE(ucmd->angles[0]);
(pr_global_struct->input_angles)[1] = SHORT2ANGLE(ucmd->angles[1]);
(pr_global_struct->input_angles)[2] = SHORT2ANGLE(ucmd->angles[2]);
}
(pr_global_struct->input_movevalues)[0] = ucmd->forwardmove;
(pr_global_struct->input_movevalues)[1] = ucmd->sidemove;
@ -9117,6 +9142,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"terrain_edit", PF_sv_terrain_edit, 0, 0, 0, 278},//void(float action, vector pos, float radius, float quant) terrain_edit = #278 (??FTE_TERRAIN_EDIT??
{"touchtriggers", PF_sv_touchtriggers,0, 0, 0, 279},//void() touchtriggers = #279;
{"writefloat", PF_WriteFloat, 0, 0, 0, 280},//void(float buf, float fl) writefloat = #280;
//EXT_CSQC
// {"setmodelindex", PF_sv_SetModelIndex,0, 0, 0, 333}, // #333 void(entity e, float mdlindex) setmodelindex (EXT_CSQC)
@ -9198,7 +9224,7 @@ BuiltinList_t BuiltinList[] = { //nq qw h2 ebfs
{"getsurfacenumpoints",PF_getsurfacenumpoints,0,0, 0, 434},// #434 float(entity e, float s) getsurfacenumpoints (DP_QC_GETSURFACE)
{"getsurfacepoint",PF_getsurfacepoint, 0, 0, 0, 435},// #435 vector(entity e, float s, float n) getsurfacepoint (DP_QC_GETSURFACE)
{"getsurfacenormal",PF_getsurfacenormal,0, 0, 0, 436},// #436 vector(entity e, float s) getsurfacenormal (DP_QC_GETSURFACE)
// {"getsurfacetexture",PF_getsurfacetexture,0, 0, 0, 437},// #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
{"getsurfacetexture",PF_getsurfacetexture,0, 0, 0, 437},// #437 string(entity e, float s) getsurfacetexture (DP_QC_GETSURFACE)
{"getsurfacenearpoint",PF_getsurfacenearpoint,0,0, 0, 438},// #438 float(entity e, vector p) getsurfacenearpoint (DP_QC_GETSURFACE)
{"getsurfaceclippedpoint",PF_getsurfaceclippedpoint,0,0,0, 439},// #439 vector(entity e, float s, vector p) getsurfaceclippedpoint (DP_QC_GETSURFACE)

View File

@ -639,7 +639,7 @@ static qintptr_t syscallhandle (void *offset, quintptr_t mask, qintptr_t fn, con
case G_SOUND:
// ( int edn, int channel, char *samp, float vol, float att )
SVQ1_StartSound (Q1QVMPF_EdictNum(svprogfuncs, VM_LONG(arg[0])), VM_LONG(arg[1]), VM_POINTER(arg[2]), VM_FLOAT(arg[3])*255, VM_FLOAT(arg[4]), 0);
SVQ1_StartSound ((wedict_t*)Q1QVMPF_EdictNum(svprogfuncs, VM_LONG(arg[0])), VM_LONG(arg[1]), VM_POINTER(arg[2]), VM_FLOAT(arg[3])*255, VM_FLOAT(arg[4]), 0);
break;
case G_TRACELINE:
@ -1302,6 +1302,29 @@ void Q1QVM_Shutdown(void)
Z_FreeTags(VMFSID_Q1QVM);
}
void Q1QVM_Event_Touch(world_t *w, wedict_t *s, wedict_t *o)
{
int oself = pr_global_struct->self;
int oother = pr_global_struct->other;
pr_global_struct->self = EDICT_TO_PROG(w->progs, s);
pr_global_struct->other = EDICT_TO_PROG(w->progs, o);
pr_global_struct->time = w->physicstime;
VM_Call(q1qvm, GAME_EDICT_TOUCH);
pr_global_struct->self = oself;
pr_global_struct->other = oother;
}
void Q1QVM_Event_Think(world_t *w, wedict_t *s)
{
pr_global_struct->self = EDICT_TO_PROG(w->progs, s);
pr_global_struct->other = EDICT_TO_PROG(w->progs, w->edicts);
VM_Call(q1qvm, GAME_EDICT_THINK);
PR_ExecuteProgram (w->progs, s->v->think);
}
qboolean PR_LoadQ1QVM(void)
{
static float writable;
@ -1343,7 +1366,8 @@ qboolean PR_LoadQ1QVM(void)
q1qvmprogfuncs.StringToProgs = Q1QVMPF_StringToProgs;
q1qvmprogfuncs.StringToNative = Q1QVMPF_StringToNative;
sv.world.Event_Touch = SVPR_Event_Touch;
sv.world.Event_Touch = Q1QVM_Event_Touch;
sv.world.Event_Think = Q1QVM_Event_Think;
sv.world.GetCModel = SVPR_GetCModel;
sv.world.num_edicts = 0; //we're not ready for most of the builtins yet
@ -1549,16 +1573,6 @@ void Q1QVM_StartFrame(void)
VM_Call(q1qvm, GAME_START_FRAME, (qintptr_t)(sv.time*1000));
}
void Q1QVM_Touch(void)
{
VM_Call(q1qvm, GAME_EDICT_TOUCH);
}
void Q1QVM_Think(void)
{
VM_Call(q1qvm, GAME_EDICT_THINK);
}
void Q1QVM_Blocked(void)
{
VM_Call(q1qvm, GAME_EDICT_BLOCKED);

View File

@ -109,17 +109,17 @@ if the middle has a valid name, both left+right must have valid names too.
so the base fields are a fixed size
and the extension fields are added on the end and can have extra vm-specific stuff added on the end
*/
/*DO NOT ADD TO THIS STRUCTURE*/
/*DO NOT ADD TO THIS STRUCTURE (base-qw-compat for q1qvm)*/
#define comqcfields \
comfieldfloat(modelindex,modelindex,modelindex);\
comfieldvector(absmin,absmin,absmin);\
comfieldvector(absmax,absmax,absmax);\
comfieldfloat(ltime,_ltime,_ltime);\
comfieldfloat(lastruntime,_lastruntime,_lastruntime); /*type doesn't match the qc, we use a hidden double instead. this is dead.*/ \
comfieldfloat(ltime,ltime,_ltime);\
comfieldfloat(_lastruntime,lastruntime,_lastruntime); /*type doesn't match the qc, we use a hidden double instead. this is dead.*/ \
comfieldfloat(movetype,movetype,movetype);\
comfieldfloat(solid,solid,solid);\
comfieldvector(origin,origin,origin);\
comfieldvector(oldorigin,_oldorigin,_oldorigin);\
comfieldvector(oldorigin,oldorigin,_oldorigin);\
comfieldvector(velocity,velocity,velocity);\
comfieldvector(angles,angles,angles);\
comfieldvector(avelocity,avelocity,avelocity);\
@ -133,9 +133,9 @@ and the extension fields are added on the end and can have extra vm-specific stu
comfieldvector(size,size,size);\
comfieldfunction(touch,touch,touch);\
comfieldfunction(_use,_use,_use);\
comfieldfunction(think,_think,think);\
comfieldfunction(blocked,_blocked,_blocked);\
comfieldfloat(nextthink,_nextthink,nextthink);\
comfieldfunction(think,think,think);\
comfieldfunction(blocked,blocked,_blocked);\
comfieldfloat(nextthink,nextthink,nextthink);\
comfieldentity(groundentity,groundentity,groundentity);\
comfieldfloat(health,_health,_health);\
comfieldfloat(frags,_frags,_frags);\
@ -151,13 +151,13 @@ and the extension fields are added on the end and can have extra vm-specific stu
comfieldfloat(takedamage,_takedamage,_takedamage);\
comfieldentity(chain,chain,chain);\
comfieldfloat(_deadflag,_deadflag,_deadflag);\
comfieldvector(view_ofs,_view_ofs,_view_ofs);\
comfieldvector(view_ofs,view_ofs,_view_ofs);\
comfieldfloat(button0,_button0,_button0);\
comfieldfloat(button1,_button1,_button1); /*dead field in nq mode*/ \
comfieldfloat(button2,_button2,_button2);\
comfieldfloat(impulse,_impulse,_impulse);\
comfieldfloat(fixangle,_fixangle,_fixangle);\
comfieldvector(v_angle,_v_angle,_v_angle);\
comfieldvector(v_angle,v_angle,_v_angle);\
comfieldstring(netname,_netname,_netname);\
comfieldentity(enemy,enemy,enemy);\
comfieldfloat(flags,flags,flags);\
@ -167,8 +167,8 @@ and the extension fields are added on the end and can have extra vm-specific stu
comfieldfloat(teleport_time,_teleport_time,_teleport_time);\
comfieldfloat(_armortype,_armortype,_armortype);\
comfieldfloat(armorvalue,_armorvalue,_armorvalue);\
comfieldfloat(waterlevel,_waterlevel,_waterlevel);\
comfieldfloat(watertype,_watertype,_watertype);\
comfieldfloat(waterlevel,waterlevel,_waterlevel);\
comfieldfloat(watertype,watertype,_watertype);\
comfieldfloat(ideal_yaw,ideal_yaw,ideal_yaw);\
comfieldfloat(yaw_speed,yaw_speed,yaw_speed);\
comfieldentity(aiment,aiment,aiment);\
@ -190,13 +190,17 @@ and the extension fields are added on the end and can have extra vm-specific stu
/*DO NOT ADD TO THE ABOVE STRUCTURE*/
#define comextqcfields \
comfieldvector(punchangle); /*std in nq*/\
comfieldfloat(gravity); /*added in quake 1.09 (for hipnotic)*/\
comfieldfloat(hull);/*PEXT_HEXEN2*/\
comfieldentity(movechain);/*hexen2*/\
comfieldfunction(chainmoved);/*hexen2*/\
comfieldfloat(dimension_solid);/*EXT_DIMENSION_PHYSICS*/\
comfieldfloat(dimension_hit);/*EXT_DIMENSION_PHYSICS*/\
comfieldfloat(scale);/*DP_ENT_SCALE*/\
comfieldfloat(fatness);/*FTE_PEXT_FATNESS*/\
comfieldfloat(alpha);/*DP_ENT_ALPHA*/\
comfieldvector(colormod);\
comfieldfloat(pmove_flags);/*EXT_CSQC_1*/\
comfieldfloat(jointtype);/*DP_...PHYSICS*/\
comfieldfloat(mass);/*DP_...PHYSICS*/\
@ -206,7 +210,6 @@ and the extension fields are added on the end and can have extra vm-specific stu
#define svextqcfields \
comfieldfloat(maxspeed);/*added in quake 1.09*/\
comfieldfloat(items2); /*added in quake 1.09 (for hipnotic)*/\
comfieldvector(punchangle); /*std in nq*/\
comfieldentity(view2);/*FTE_PEXT_VIEW2*/\
comfieldvector(movement);\
comfieldfloat(vw_index);\
@ -227,7 +230,6 @@ and the extension fields are added on the end and can have extra vm-specific stu
comfieldfloat(glow_color);\
comfieldfloat(glow_trail);\
comfieldvector(color);\
comfieldvector(colormod);\
comfieldfloat(light_lev);\
comfieldfloat(style);\
comfieldfloat(pflags);\
@ -238,8 +240,6 @@ and the extension fields are added on the end and can have extra vm-specific stu
comfieldfloat(dimension_ghost_alpha);/*EXT_DIMENSION_GHOST*/\
comfieldfloat(playerclass);/*hexen2 requirements*/\
comfieldfloat(drawflags);/*hexen2*/\
comfieldentity(movechain);/*hexen2*/\
comfieldfunction(chainmoved);/*hexen2*/\
comfieldfloat(hasted);/*hexen2 uses this AS WELL as maxspeed*/\
comfieldfloat(light_level);/*hexen2's grabbing light level from client*/\
comfieldfloat(abslight);/*hexen2's force a lightlevel*/\

View File

@ -144,8 +144,6 @@ void Q1QVM_PlayerPreThink(void);
void Q1QVM_RunPlayerThink(void);
void Q1QVM_PostThink(void);
void Q1QVM_StartFrame(void);
void Q1QVM_Touch(void);
void Q1QVM_Think(void);
void Q1QVM_Blocked(void);
void Q1QVM_SetNewParms(void);
void Q1QVM_SetChangeParms(void);

View File

@ -370,7 +370,7 @@ typedef struct client_s
char *name;
char namebuf[32]; // for printing to other people
// extracted from userinfo
char guid[32];
char guid[32]; /*+2 for split+pad*/
int messagelevel; // for filtering printed messages
// the datagram is written to after every frame, but only cleared
@ -1000,13 +1000,14 @@ qboolean SVQ3_Command(void);
// sv_phys.c
//
void SV_SetMoveVars(void);
void SV_RunNewmis (void);
void WPhys_RunNewmis (world_t *w);
qboolean SV_Physics (void);
void SV_CheckVelocity (edict_t *ent);
trace_t SV_Trace_Toss (edict_t *ent, edict_t *ignore);
void World_Physics_Frame(world_t *w);
void WPhys_CheckVelocity (world_t *w, wedict_t *ent);
trace_t WPhys_Trace_Toss (world_t *w, wedict_t *ent, wedict_t *ignore);
void SV_ProgStartFrame (void);
void SV_RunEntity (edict_t *ent);
qboolean SV_RunThink (edict_t *ent);
void WPhys_RunEntity (world_t *w, wedict_t *ent);
qboolean WPhys_RunThink (world_t *w, wedict_t *ent);
//
// sv_send.c
//
@ -1024,7 +1025,7 @@ void VARGS SV_Multicast (vec3_t origin, multicast_t to);
void SV_MulticastProtExt(vec3_t origin, multicast_t to, int dimension_mask, int with, int without);
void SV_StartSound (int ent, vec3_t origin, int seenmask, int channel, char *sample, int volume, float attenuation, int pitchadj);
void SVQ1_StartSound (edict_t *entity, int channel, char *sample, int volume, float attenuation, int pitchadj);
void SVQ1_StartSound (wedict_t *entity, int channel, char *sample, int volume, float attenuation, int pitchadj);
void SV_PrintToClient(client_t *cl, int level, char *string);
void VARGS SV_ClientPrintf (client_t *cl, int level, char *fmt, ...) LIKEPRINTF(3);
void VARGS SV_ClientTPrintf (client_t *cl, int level, translation_t text, ...);
@ -1156,7 +1157,7 @@ typedef struct {
rankstats_t s;
} rankinfo_t;
int Rank_GetPlayerID(char *name, int pwd, qboolean allowcreate, qboolean requirepasswordtobeset);
int Rank_GetPlayerID(char *guid, char *name, int pwd, qboolean allowcreate, qboolean requirepasswordtobeset);
void Rank_SetPlayerStats(int id, rankstats_t *stats);
rankstats_t *Rank_GetPlayerStats(int id, rankstats_t *buffer);
rankinfo_t *Rank_GetPlayerInfo(int id, rankinfo_t *buffer);
@ -1292,6 +1293,7 @@ extern cvar_t sv_demoUseCache;
extern cvar_t sv_demoMaxSize;
extern cvar_t sv_demoMaxDirSize;
char *SV_Demo_CurrentOutput(void);
void SV_MVDInit(void);
char *SV_MVDNum(char *buffer, int bufferlen, int num);
void SV_SendMVDMessage(void);

View File

@ -1151,7 +1151,7 @@ void SV_CripplePlayer_f (void)
if (!cl->iscrippled)
{
SV_LogPlayer(cl, "crippled");
if (persist)
if (persist && cl->rankid)
{
cl->iscrippled = 2;
SV_BroadcastTPrintf (PRINT_HIGH, STL_CLIENTISCRIPPLEDPERMANENTLY, cl->name);
@ -1186,7 +1186,7 @@ void SV_Mute_f (void)
if (!cl->ismuted)
{
SV_LogPlayer(cl, "muted");
if (persist)
if (persist && cl->rankid)
{
cl->ismuted = 2;
SV_BroadcastTPrintf (PRINT_HIGH, STL_CLIENTISMUTEDPERMANENTLY, cl->name);
@ -1221,7 +1221,7 @@ void SV_Cuff_f (void)
if (!cl->iscuffed)
{
SV_LogPlayer(cl, "cuffed");
if (persist)
if (persist && cl->rankid)
{
cl->iscuffed = 2;
SV_BroadcastTPrintf (PRINT_HIGH, STL_CLIENTISCUFFEDPERMANENTLY, cl->name);
@ -1437,20 +1437,23 @@ void SV_Status_f (void)
NET_PrintAddresses(svs.sockets);
Con_Printf ("cpu utilization : %3i%%\n",(int)cpu);
Con_Printf ("avg response time: %i ms\n",(int)avg);
Con_Printf ("packets/frame : %5.2f\n", pak); //not relevent as a limit.
Con_Printf("cpu utilization : %3i%%\n",(int)cpu);
Con_Printf("avg response time: %i ms\n",(int)avg);
Con_Printf("packets/frame : %5.2f\n", pak); //not relevent as a limit.
Con_Printf("server uptime : %s\n", ShowTime(realtime));
Con_Printf("map uptime : %s\n", ShowTime(sv.world.physicstime));
//show the current map+name (but hide name if its too long or would be ugly)
if (columns >= 80 && *sv.mapname && strlen(sv.mapname) < 45 && !strchr(sv.mapname, '\n'))
Con_Printf ("current map : %s (%s)\n", sv.name, sv.mapname);
else
Con_Printf ("current map : %s\n", sv.name);
Con_Printf("map uptime : %s\n", ShowTime(sv.world.physicstime));
Con_Printf("server uptime : %s\n", ShowTime(realtime));
Con_Printf("entities : %i/%i\n", sv.world.num_edicts, sv.world.max_edicts);
Con_Printf("gamedir : %s\n", FS_GetGamedir());
if (sv.csqcdebug)
Con_Printf("csqc debug : true\n");
if (sv.mvdrecording)
Con_Printf("recording : %s\n", SV_Demo_CurrentOutput());
Con_Printf("public : %s\n", sv_public.value?"yes":"no");
Con_Printf("client types :%s%s%s%s\n", sv_listen_qw.ival?" QW":"", sv_listen_nq.ival?" NQ":"", sv_listen_dp.ival?" DP":"", sv_listen_q3.ival?" Q3":"");

View File

@ -357,10 +357,10 @@ void SV_EmitCSQCUpdate(client_t *client, sizebuf_t *msg)
for (en = 1; en < sv.world.num_edicts; en++)
{
ent = EDICT_NUM(svprogfuncs, en);
if (client->csqcentversions[en] > 0 && (client->csqcentversions[en] != sv.csqcentversion[en]) && !((int)ent->xv->pvsflags & PVSF_NOREMOVE))
if (client->csqcentversions[en] > 0 && client->csqcentversions[en] != ent->xv->Version)
{
// if (!ent->isfree)
// continue;
if (((int)ent->xv->pvsflags & PVSF_NOREMOVE))
continue;
if (msg->cursize + 5 >= msg->maxsize) //try removing next frame instead.
{
@ -2542,10 +2542,8 @@ void SV_Snapshot_BuildQ1(client_t *client, packet_entities_t *pack, qbyte *pvs,
{
if (e >= client->max_net_ents)
continue;
#ifdef PEXT_MODELDBL
if (ent->v->modelindex >= 256 && !(client->fteprotocolextensions & PEXT_MODELDBL))
if (ent->v->modelindex >= client->maxmodels)
continue;
#endif
}
#ifdef DEPTHOPTIMISE

View File

@ -736,7 +736,7 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
}
#ifdef USEODE
World_Physics_End(&sv.world);
World_ODE_End(&sv.world);
#endif
// wipe the entire per-level structure
@ -1256,10 +1256,6 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
pr_global_struct->deathmatch = deathmatch.value;
}
if (progstype == PROG_QW)
// run the frame start qc function to let progs check cvars
SV_ProgStartFrame (); //prydon gate seems to fail because of this allowance
if (svs.gametype != GT_Q1QVM) //we cannot do this with qvm
{
for (i = 0; i < svs.numprogs; i++) //do this AFTER precaches have been played with...
@ -1271,6 +1267,10 @@ void SV_SpawnServer (char *server, char *startspot, qboolean noents, qboolean us
}
}
}
if (progstype == PROG_QW)
// run the frame start qc function to let progs check cvars
SV_ProgStartFrame (); //prydon gate seems to fail because of this allowance
}
// load and spawn all other entities

View File

@ -256,7 +256,7 @@ void SV_Shutdown (void)
PR_Deinit();
#ifdef USEODE
World_Physics_Shutdown();
World_ODE_Shutdown();
#endif
if (sv.mvdrecording)
@ -2344,10 +2344,14 @@ client_t *SVC_DirectConnect(void)
}
else
{
for (i=0 ; i<NUM_RANK_SPAWN_PARMS ; i++)
newcl->spawn_parms[i] = rs.parm[i];
for (; i < NUM_SPAWN_PARMS; i++)
newcl->spawn_parms[i] = 0;
extern cvar_t rank_parms_first, rank_parms_last;
for (i=0 ; i<NUM_SPAWN_PARMS ; i++)
{
if (i < NUM_RANK_SPAWN_PARMS && i >= rank_parms_first.ival && i <= rank_parms_last.ival)
newcl->spawn_parms[i] = rs.parm[i];
else
newcl->spawn_parms[i] = 0;
}
}
if (rs.timeonserver > 3*60) //woo. Ages.
@ -2435,6 +2439,7 @@ client_t *SVC_DirectConnect(void)
temp.frameunion.frames = cl->frameunion.frames; //don't touch these.
temp.edict = cl->edict;
memcpy(cl, newcl, sizeof(client_t));
Q_strncatz(cl->guid, va("%i", clients), sizeof(cl->guid));
cl->name = cl->namebuf;
cl->team = cl->teambuf;
@ -2552,7 +2557,7 @@ void SVC_RemoteCommand (void)
{
*colon = '\0';
colon++;
rid = Rank_GetPlayerID(s, atoi(colon), false, true);
rid = Rank_GetPlayerID(NULL, s, atoi(colon), false, true);
if (rid)
{
if (!Rank_GetPlayerStats(rid, &stats))
@ -4342,9 +4347,9 @@ qboolean ReloadRanking(client_t *cl, char *newname)
int newid;
int j;
rankstats_t rs;
newid = Rank_GetPlayerID(newname, atoi(Info_ValueForKey (cl->userinfo, "_pwd")), true, false); //'_' keys are always stripped. On any server. So try and use that so persistant data won't give out the password when connecting to a different server
newid = Rank_GetPlayerID(cl->guid, newname, atoi(Info_ValueForKey (cl->userinfo, "_pwd")), true, false); //'_' keys are always stripped. On any server. So try and use that so persistant data won't give out the password when connecting to a different server
if (!newid)
newid = Rank_GetPlayerID(newname, atoi(Info_ValueForKey (cl->userinfo, "password")), true, false);
newid = Rank_GetPlayerID(cl->guid, newname, atoi(Info_ValueForKey (cl->userinfo, "password")), true, false);
if (newid)
{
if (cl->rankid && cl->state >= cs_spawned)//apply current stats
@ -4372,6 +4377,7 @@ qboolean ReloadRanking(client_t *cl, char *newname)
if (spawnparamglobals[j])
rs.parm[j] = *spawnparamglobals[j];
Rank_SetPlayerStats(cl->rankid, &rs);
cl->rankid = 0;
}
if (!Rank_GetPlayerStats(newid, &rs))
return false;
@ -4656,7 +4662,7 @@ void SV_Init (quakeparms_t *parms)
#endif
#ifdef USEODE
World_Physics_Init();
World_ODE_Init();
#endif
#ifdef SVRANKING

View File

@ -1416,7 +1416,7 @@ mvddest_t *SV_InitRecordFile (char *name)
Q_strncpyz(demo.path, ".", MAX_OSPATH);
SV_BroadcastPrintf (PRINT_CHAT, "Server starts recording (%s):\n%s\n", (dst->desttype == DEST_BUFFEREDFILE) ? "memory" : "disk", name);
Cvar_ForceSet(Cvar_Get("serverdemo", "", CVAR_NOSET, ""), demo.name);
Cvar_ForceSet(Cvar_Get("serverdemo", "", CVAR_NOSET, ""), SV_Demo_CurrentOutput());
Q_strncpyz(path, name, MAX_OSPATH);
Q_strncpyz(path + strlen(path) - 3, "txt", MAX_OSPATH - strlen(path) + 3);
@ -1447,6 +1447,17 @@ mvddest_t *SV_InitRecordFile (char *name)
return dst;
}
char *SV_Demo_CurrentOutput(void)
{
mvddest_t *d;
for (d = demo.dest; d; d = d->nextdest)
{
if (d->desttype == DEST_FILE || d->desttype == DEST_BUFFEREDFILE)
return d->name;
}
return "QTV";
}
mvddest_t *SV_InitStream(int socket)
{
mvddest_t *dst;
@ -2916,8 +2927,8 @@ void SV_MVDInit(void)
#ifdef SERVERONLY //client command would conflict otherwise.
Cmd_AddCommand ("record", SV_MVD_Record_f);
Cmd_AddCommand ("stop", SV_MVDStop_f);
Cmd_AddCommand ("cancel", SV_MVD_Cancel_f);
#endif
Cmd_AddCommand ("cancel", SV_MVD_Cancel_f);
Cmd_AddCommand ("qtvreverse", SV_MVD_QTVReverse_f);
Cmd_AddCommand ("mvdrecord", SV_MVD_Record_f);
Cmd_AddCommand ("easyrecord", SV_MVDEasyRecord_f);

File diff suppressed because it is too large Load Diff

View File

@ -26,9 +26,11 @@ typedef struct {
rankfileheader_t rankfileheader;
FILE *rankfile;
cvar_t rank_autoadd = SCVAR("rank_autoadd", "1");
cvar_t rank_needlogin = SCVAR("rank_needlogin", "0");
cvar_t rank_filename = SCVAR("rank_filename", "");
cvar_t rank_autoadd = CVARD("rank_autoadd", "1", "Automatically register players into the ranking system");
cvar_t rank_needlogin = CVARD("rank_needlogin", "0", "If set to 1, prohibits players from joining if they're not already registered.");
cvar_t rank_filename = CVARD("rank_filename", "", "Specifies which file to use as a rankings database. Enables the ranking system if set.");
cvar_t rank_parms_first = CVARD("rank_parms_first", "0", "Mod setting: first parm saved");
cvar_t rank_parms_last = CVARD("rank_parms_last", "31", "Mod setting: the index of the last parm to be saved. Clamped to 32.");
char rank_cvargroup[] = "server rankings";
#define RANKFILE_VERSION ((NUM_RANK_SPAWN_PARMS==32)?0:0x00000001)
@ -40,7 +42,7 @@ void inline READ_PLAYERSTATS(int x, rankstats_t *os)
size_t result;
fseek(rankfile, sizeof(rankfileheader_t)+sizeof(rankheader_t)+((x-1)*sizeof(rankinfo_t)), SEEK_SET);
result = fread(os, sizeof(rankstats_t), 1, rankfile);
result = fread(os, 1, sizeof(rankstats_t), rankfile);
if (result != sizeof(rankstats_t))
Con_Printf("READ_PLAYERSTATS() fread: expected %lu, result was %u (%s)\n",(long unsigned int)sizeof(rankstats_t),(unsigned int)result,strerror(errno));
@ -73,7 +75,7 @@ void inline WRITE_PLAYERSTATS(int x, rankstats_t *os)
ns.pad2 = (os->pad2);
ns.pad3 = (os->pad3);
fwrite(&ns, sizeof(rankstats_t), 1, rankfile);
fwrite(&ns, 1, sizeof(rankstats_t), rankfile);
}
void inline READ_PLAYERHEADER(int x, rankheader_t *oh)
@ -82,7 +84,7 @@ void inline READ_PLAYERHEADER(int x, rankheader_t *oh)
fseek(rankfile, sizeof(rankfileheader_t)+((x-1)*sizeof(rankinfo_t)), SEEK_SET);
result = fread(oh, sizeof(rankheader_t), 1, rankfile);
result = fread(oh, 1, sizeof(rankheader_t), rankfile);
if (result != sizeof(rankheader_t))
Con_Printf("READ_PLAYERHEADER() fread: expected %lu, result was %u (%s)\n",(long unsigned int)sizeof(rankheader_t),(unsigned int)result,strerror(errno));
@ -106,7 +108,7 @@ void inline WRITE_PLAYERHEADER(int x, rankheader_t *oh)
nh.pwd = swaplong(oh->pwd);
nh.score = swapfloat(oh->score);
fwrite(&nh, sizeof(rankheader_t), 1, rankfile);
fwrite(&nh, 1, sizeof(rankheader_t), rankfile);
}
void inline READ_PLAYERINFO(int x, rankinfo_t *inf)
@ -126,9 +128,9 @@ void inline WRITEHEADER(void)
nh.freeslot = swaplong(rankfileheader.freeslot);
fseek(rankfile, 0, SEEK_SET);
fwrite(&nh, sizeof(rankfileheader_t), 1, rankfile);
fwrite(&nh, 1, sizeof(rankfileheader_t), rankfile);
}
//#define WRITEHEADER() {fseek(rankfile, 0, SEEK_SET);fwrite(&rankfileheader, sizeof(rankfileheader_t), 1, rankfile);}
//#define WRITEHEADER() {fseek(rankfile, 0, SEEK_SET);fwrite(&rankfileheader, 1, sizeof(rankfileheader_t), rankfile);}
#define NAMECMP(saved, against) Q_strncasecmp(saved, against, 31)
@ -161,7 +163,7 @@ qboolean Rank_OpenRankings(void)
memset(&rankfileheader, 0, sizeof(rankfileheader));
fseek(rankfile, 0, SEEK_SET);
result = fread(&rankfileheader, sizeof(rankfileheader_t), 1, rankfile);
result = fread(&rankfileheader, 1, sizeof(rankfileheader_t), rankfile);
if (result != sizeof(rankfileheader_t))
Con_Printf("Rank_OpenRankings() fread: expected %lu, result was %u (%s)\n",(long unsigned int)sizeof(rankfileheader_t),(unsigned int)result,strerror(errno));
@ -388,7 +390,7 @@ void Rank_SetPlayerStats(int id, rankstats_t *stats)
}
}
int Rank_GetPlayerID(char *name, int pwd, qboolean allowadd, qboolean requirepasswordtobeset)
int Rank_GetPlayerID(char *guid, char *name, int pwd, qboolean allowadd, qboolean requirepasswordtobeset)
{
rankstats_t rs;
rankheader_t rh;
@ -902,6 +904,9 @@ void Rank_RegisterCommands(void)
Cvar_Register(&rank_autoadd, rank_cvargroup);
Cvar_Register(&rank_needlogin, rank_cvargroup);
Cvar_Register(&rank_filename, rank_cvargroup);
Cvar_Register(&rank_parms_first, rank_cvargroup);
Cvar_Register(&rank_parms_last, rank_cvargroup);
}
void Rank_Flush (void) //new game dir?
{

View File

@ -945,8 +945,9 @@ void SV_StartSound (int ent, vec3_t origin, int seenmask, int channel, char *sam
SV_MulticastProtExt(origin, reliable ? MULTICAST_ALL_R : MULTICAST_ALL, seenmask, requiredextensions, 0);
}
void SVQ1_StartSound (edict_t *entity, int channel, char *sample, int volume, float attenuation, int pitchadj)
void SVQ1_StartSound (wedict_t *wentity, int channel, char *sample, int volume, float attenuation, int pitchadj)
{
edict_t *entity = (edict_t*)wentity;
int i;
vec3_t origin;
if (entity->v->solid == SOLID_BSP)
@ -1561,7 +1562,7 @@ void SV_UpdateClientStats (client_t *client, int pnum)
SV_CalcClientStats(client, statsi, statsf, statss);
m = MAX_QW_STATS;
if (client->fteprotocolextensions & PEXT_HEXEN2)
if (client->fteprotocolextensions & (PEXT_HEXEN2|PEXT_CSQC))
m = MAX_CL_STATS;
for (i=0 ; i<m ; i++)
@ -2374,7 +2375,7 @@ void SV_SendMVDMessage(void)
msg.overflowed = false;
m = MAX_QW_STATS;
if (demo.recorder.fteprotocolextensions & PEXT_HEXEN2)
if (demo.recorder.fteprotocolextensions & (PEXT_HEXEN2|PEXT_CSQC))
m = MAX_CL_STATS;
for (i=0, c = svs.clients ; i<MAX_CLIENTS ; i++, c++)

View File

@ -44,7 +44,7 @@ cvar_t sv_spectalk = SCVAR("sv_spectalk", "1");
cvar_t sv_mapcheck = SCVAR("sv_mapcheck", "1");
cvar_t sv_antilag = CVARFD("sv_antilag", "0", CVAR_SERVERINFO, "Attempt to backdate impacts to compensate for lag.");
cvar_t sv_antilag = CVARFD("sv_antilag", "1", CVAR_SERVERINFO, "Attempt to backdate impacts to compensate for lag. 0=completely off. 1=mod-controlled. 2=forced, which might break certain uses of traceline.");
cvar_t sv_antilag_frac = CVARF("sv_antilag_frac", "1", CVAR_SERVERINFO);
cvar_t sv_cheatpc = CVAR("sv_cheatpc", "125");
cvar_t sv_cheatspeedchecktime = CVAR("sv_cheatspeedchecktime", "30");
@ -58,7 +58,7 @@ cvar_t sv_nomsec = CVARD("sv_nomsec", "0", "Ignore client msec times, runs using
cvar_t sv_edgefriction = CVARAF("sv_edgefriction", "2",
"edgefriction", 0);
cvar_t sv_brokenmovetypes = SCVAR("sv_brokenmovetypes", "0");
cvar_t sv_brokenmovetypes = CVARD("sv_brokenmovetypes", "0", "Emulate standard quakeworld movetypes. Shouldn't be used for any games other than QuakeWorld.");
cvar_t sv_chatfilter = CVAR("sv_chatfilter", "0");
@ -90,8 +90,8 @@ cvar_t sv_pushplayers = SCVAR("sv_pushplayers", "0");
//yes, realip cvars need to be fully initialised or realip will be disabled
cvar_t sv_getrealip = CVARD("sv_getrealip", "0", "Attempt to obtain a more reliable IP for clients, rather than just their proxy.");
cvar_t sv_realip_kick = SCVAR("sv_realip_kick", "0");
cvar_t sv_realiphostname_ipv4 = SCVAR("sv_realiphostname_ipv4", "");
cvar_t sv_realiphostname_ipv6 = SCVAR("sv_realiphostname_ipv6", "");
cvar_t sv_realiphostname_ipv4 = CVARD("sv_realiphostname_ipv4", "", "This is the server's public ip:port. This is needed for realip to work when the autodetected/local ip is not globally routable");
cvar_t sv_realiphostname_ipv6 = CVARD("sv_realiphostname_ipv6", "", "This is the server's public ip:port. This is needed for realip to work when the autodetected/local ip is not globally routable");
cvar_t sv_realip_timeout = SCVAR("sv_realip_timeout", "10");
#ifdef VOICECHAT
@ -5230,9 +5230,6 @@ int SV_PMTypeForClient (client_t *cl)
}
//called for common csqc/server code (supposedly)
void SV_RunEntity (edict_t *ent);
/*
===========
SV_PreRunCmd
@ -5422,7 +5419,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
sv_player->xv->movement[2] = ucmd->upmove * host_frametime;
}
SV_CheckVelocity(sv_player);
WPhys_CheckVelocity(&sv.world, (wedict_t*)sv_player);
//
// angles
@ -5442,7 +5439,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
{ //csqc independant physics support
pr_global_struct->frametime = host_frametime;
pr_global_struct->time = sv.time;
SV_RunEntity(sv_player);
WPhys_RunEntity(&sv.world, (wedict_t*)sv_player);
return;
}
@ -5489,7 +5486,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
sv_player->v->velocity[2] -= 270;
}
SV_RunThink (sv_player);
WPhys_RunThink (&sv.world, (wedict_t*)sv_player);
}
// memset(&pmove, 0, sizeof(pmove));
@ -5650,32 +5647,11 @@ if (sv_player->v->health > 0 && before && !after )
continue;
if (ent->v->touch)
{
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, ent);
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, sv_player);
pr_global_struct->time = sv.time;
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_Touch();
else
#endif
PR_ExecuteProgram (svprogfuncs, ent->v->touch);
}
sv.world.Event_Touch(&sv.world, (wedict_t*)ent, (wedict_t*)sv_player);
playertouch[n/8] |= 1 << (n%8);
if (sv_player->v->touch && !ent->isfree)
{
pr_global_struct->other = EDICT_TO_PROG(svprogfuncs, ent);
pr_global_struct->self = EDICT_TO_PROG(svprogfuncs, sv_player);
pr_global_struct->time = sv.time;
#ifdef VM_Q1
if (svs.gametype == GT_Q1QVM)
Q1QVM_Touch();
else
#endif
PR_ExecuteProgram (svprogfuncs, sv_player->v->touch);
}
sv.world.Event_Touch(&sv.world, (wedict_t*)sv_player, (wedict_t*)ent);
}
}
@ -5716,7 +5692,7 @@ void SV_PostRunCmd(void)
PR_ExecuteProgram (svprogfuncs, pr_global_struct->PlayerPostThink);
SV_RunNewmis ();
WPhys_RunNewmis (&sv.world);
}
else if (SpectatorThink)
{
@ -6466,7 +6442,7 @@ void SVNQ_ReadClientMove (usercmd_t *move)
if (host_client->last_sequence)
{
host_frametime = timesincelast;
SV_RunEntity(host_client->edict);
WPhys_RunEntity(&sv.world, (wedict_t*)host_client->edict);
host_client->isindependant = true;
}
else

View File

@ -469,10 +469,7 @@ void World_LinkEdict (world_t *w, wedict_t *ent, qboolean touch_triggers)
// link to PVS leafs
if (w->worldmodel)
{
if (ent->v->modelindex)
w->worldmodel->funcs.FindTouchedLeafs(w->worldmodel, &ent->pvsinfo, ent->v->absmin, ent->v->absmax);
else
w->worldmodel->funcs.FindTouchedLeafs(w->worldmodel, &ent->pvsinfo, NULL, NULL);
w->worldmodel->funcs.FindTouchedLeafs(w->worldmodel, &ent->pvsinfo, ent->v->absmin, ent->v->absmax);
}
if (ent->v->solid == SOLID_NOT)
@ -1445,8 +1442,16 @@ static void World_ClipToEverything (world_t *w, moveclip_t *clip)
if (trace.allsolid || trace.startsolid ||
trace.fraction < clip->trace.fraction)
{
trace.ent = touch;
clip->trace = trace;
if (clip->type & MOVE_ENTCHAIN)
{
touch->v->chain = EDICT_TO_PROG(w->progs, clip->trace.ent?clip->trace.ent:w->edicts);
clip->trace.ent = touch;
}
else
{
trace.ent = touch;
clip->trace = trace;
}
}
}
}
@ -1535,11 +1540,20 @@ static void World_ClipToLinks (world_t *w, areanode_t *node, moveclip_t *clip)
trace = World_ClipMoveToEntity (w, touch, touch->v->origin, clip->start, clip->mins2, clip->maxs2, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL);
else
trace = World_ClipMoveToEntity (w, touch, touch->v->origin, clip->start, clip->mins, clip->maxs, clip->end, clip->hullnum, clip->type & MOVE_HITMODEL);
if (trace.allsolid || trace.startsolid ||
trace.fraction < clip->trace.fraction)
{
trace.ent = touch;
clip->trace = trace;
if (clip->type & MOVE_ENTCHAIN)
{
touch->v->chain = EDICT_TO_PROG(w->progs, clip->trace.ent?clip->trace.ent:w->edicts);
clip->trace.ent = touch;
}
else
{
trace.ent = touch;
clip->trace = trace;
}
}
}
@ -1822,8 +1836,16 @@ trace_t World_Move (world_t *w, vec3_t start, vec3_t mins, vec3_t maxs, vec3_t e
if (trace.allsolid || trace.startsolid || trace.fraction < clip.trace.fraction)
{
trace.ent = touch;
clip.trace = trace;
if (clip.type & MOVE_ENTCHAIN)
{
touch->v->chain = EDICT_TO_PROG(w->progs, clip.trace.ent?clip.trace.ent:w->edicts);
clip.trace.ent = touch;
}
else
{
trace.ent = touch;
clip.trace = trace;
}
}
}
}

View File

@ -1,7 +1,7 @@
<?xml version="1.0" encoding="Windows-1252"?>
<VisualStudioProject
ProjectType="Visual C++"
Version="8,00"
Version="8.00"
Name="qtvprox"
ProjectGUID="{62669E6C-7E18-4E4D-BA54-DFBE29E7D24E}"
>
@ -220,6 +220,10 @@
RelativePath="..\forward.c"
>
</File>
<File
RelativePath="..\libqtvc\glibc_sucks.c"
>
</File>
<File
RelativePath="..\httpsv.c"
>
@ -228,10 +232,18 @@
RelativePath="..\mdfour.c"
>
</File>
<File
RelativePath="..\menu.c"
>
</File>
<File
RelativePath="..\msg.c"
>
</File>
<File
RelativePath="..\libqtvc\msvc_sucks.c"
>
</File>
<File
RelativePath="..\netchan.c"
>