q2w bsp format support.

automatic lightmap texture scaling to retain more performance on large maps.
r_clutter preliminary implementation should probably fix up the shader still.
CSQC_Parse_Damage implemented.
finally implement q2 inventory.
fix mixer overflow crash.
glsl can now use s_diffuse etc to force inclusion of a diffuse sampler/texture, meaning shaders don't need to include them.
fix issue with writeip

git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@4841 fc73d0e0-1445-4013-8a0c-d673dee63da5
This commit is contained in:
Spoike 2015-03-03 00:14:43 +00:00
parent 02ab57490e
commit bed989f529
100 changed files with 3502 additions and 2204 deletions

View File

@ -928,14 +928,14 @@ ifeq ($(FTE_TARGET),vc)
MSVCPATH=C:/Program Files (x86)/$(MSVCDIR)/VC/BIN/amd64/
MSVCINC=-I"C:\Program Files (x86)\$(MSVCDIR)\VC\ATLMFC\INCLUDE" -I"C:\Program Files (x86)\$(MSVCDIR)\VC\INCLUDE" -I"C:\Program Files (x86)\Microsoft Visual Studio 8\VC\PlatformSDK\include" -I"C:\Program Files (x86)\Microsoft Visual Studio 8\SDK\v2.0\include"
MSVCLIB=/LIBPATH:"C:\Program Files (x86)\$(MSVCPATH)\VC\ATLMFC\LIB\amd64" /LIBPATH:"C:\Program Files (x86)\$(MSVCPATH)\VC\LIB\amd64" /LIBPATH:"$(WINDOWSSDKDIR)\lib\amd64" /LIBPATH:"C:\Program Files (x86)\$(MSVCPATH)\SDK\v2.0\LIB\AMD64"
MSVCINC=-I"C:\Program Files (x86)\$(MSVCDIR)\VC\ATLMFC\INCLUDE" -I"C:\Program Files (x86)\$(MSVCDIR)\VC\INCLUDE" -I"$(WINDOWSSDKDIR)/Include" -I"C:\Program Files (x86)\$(MSVCDIR)\VC\PlatformSDK\include" -I"C:\Program Files (x86)\$(MSVCDIR)\SDK\v2.0\include"
MSVCLIB=/LIBPATH:"C:\Program Files (x86)\$(MSVCPATH)\VC\ATLMFC\LIB\amd64" /LIBPATH:"C:\Program Files (x86)\$(MSVCDIR)\VC\LIB\amd64" /LIBPATH:"$(WINDOWSSDKDIR)\lib\amd64" /LIBPATH:"C:\Program Files (x86)\$(MSVCDIR)\SDK\v2.0\LIB\AMD64" /LIBPATH:"$(WINDOWSSDKDIR)\lib\x64"
JPEGLIB=libs/libjpeg$(BITS).lib
else
WINDRES=i686-w64-mingw32-windres
MSVCPATH=C:/Program Files (x86)/$(MSVCDIR)/VC/BIN/
MSVCINC=-I"C:\Program Files (x86)\$(MSVCDIR)\VC\ATLMFC\INCLUDE" -I"C:\Program Files (x86)\$(MSVCDIR)\VC\INCLUDE" -I"C:\Program Files (x86)\$(MSVCDIR)\VC\PlatformSDK\include" -I"C:\Program Files (x86)\$(MSVCDIR)\SDK\v2.0\include"
MSVCINC=-I"C:\Program Files (x86)\$(MSVCDIR)\VC\ATLMFC\INCLUDE" -I"C:\Program Files (x86)\$(MSVCDIR)\VC\INCLUDE" -I"$(WINDOWSSDKDIR)/Include" -I"C:\Program Files (x86)\$(MSVCDIR)\VC\PlatformSDK\include" -I"C:\Program Files (x86)\$(MSVCDIR)\SDK\v2.0\include"
MSVCLIB=/LIBPATH:"C:\Program Files (x86)\$(MSVCDIR)\VC\ATLMFC\LIB" /LIBPATH:"C:\Program Files (x86)\$(MSVCDIR)\VC\LIB" /LIBPATH:"$(WINDOWSSDKDIR)\lib" /LIBPATH:"C:\Program Files (x86)\$(MSVCDIR)\SDK\v2.0\LIB"
JPEGLIB=libs/jpeg.lib
endif
@ -943,7 +943,7 @@ ifeq ($(FTE_TARGET),vc)
STRIP=@echo strip
EXEPOSTFIX=.exe
CC="$(MSVCPATH)cl" $(SDKINC) $(MSVCINC) -D_CRT_SECURE_NO_WARNINGS
CC=PATH="C:\Program Files (x86)\$(MSVCDIR)\Common7\IDE" "$(MSVCPATH)cl" $(SDKINC) $(MSVCINC) -D_CRT_SECURE_NO_WARNINGS
DEBUG_CFLAGS ?= -Od $(CPUOPTIMIZATIONS) /fp:fast
PROFILE_CFLAGS = -O2 -Ot -Ox -GL $(CPUOPTIMISATIONS) /fp:fast
PROFILE_LDFLAGS = /LTCG:PGINSTRUMENT
@ -951,8 +951,8 @@ ifeq ($(FTE_TARGET),vc)
RELEASE_LDFLAGS = /LTCG
# /LTCG:PGOPTIMIZE
DO_CC=$(CC) /nologo $(ALL_CFLAGS) -Fo$(shell cygpath -m $@) -c $(shell cygpath -m $<)
DO_LD=$(DO_ECHO) "$(MSVCPATH)link" /nologo /out:"$(shell cygpath -m $@)" /nodefaultlib:libc.lib /LARGEADDRESSAWARE /nodefaultlib:MSVCRT $(MSVCLIB) $(SDKLIB) /manifest:no /OPT:REF wsock32.lib user32.lib kernel32.lib advapi32.lib winmm.lib libs/zlib$(BITS).lib shell32.lib
DO_CC=$(DO_ECHO) $(CC) /nologo $(ALL_CFLAGS) -Fo$(shell cygpath -m $@) -c $(shell cygpath -m $<)
DO_LD=$(DO_ECHO) PATH="C:\Program Files (x86)\$(MSVCDIR)\Common7\IDE" "$(MSVCPATH)link" /nologo /out:"$(shell cygpath -m $@)" /nodefaultlib:libc.lib /LARGEADDRESSAWARE /nodefaultlib:MSVCRT $(MSVCLIB) $(SDKLIB) /manifest:no /OPT:REF wsock32.lib user32.lib kernel32.lib advapi32.lib winmm.lib libs/zlib$(BITS).lib shell32.lib
PRECOMPHEADERS =
DEPCC=

View File

@ -471,7 +471,7 @@ void Cam_TrackCrosshairedPlayer(playerview_t *pv)
best = i;
}
}
Con_Printf("Track %i? %f\n", best, bestdot);
// Con_Printf("Track %i? %f\n", best, bestdot);
if (best != -1) //did we actually get someone?
{
pv->cam_auto++;

View File

@ -388,17 +388,44 @@ qboolean CG_GetServerCommand(int cmdnum)
typedef struct {
int firstPoint;
int numPoints;
} markFragment_t;
} q3markFragment_t;
typedef struct {
float *points;
size_t maxpoints;
size_t numpoints;
q3markFragment_t *frags;
size_t maxfrags;
size_t numfrags;
} q3markFragment_ctx_t;
static void CG_MarkFragments_Callback(q3markFragment_ctx_t *ctx, vec3_t *fte_restrict points, size_t numtris, shader_t *shader)
{
size_t i;
if (numtris > ctx->maxfrags-ctx->numfrags)
numtris = ctx->maxfrags-ctx->numfrags;
if (numtris > (ctx->maxpoints-ctx->numpoints)/3)
numtris = (ctx->maxpoints-ctx->numpoints)/3;
for (i = 0; i < numtris; i++)
{
ctx->frags[ctx->numfrags].numPoints = 3;
ctx->frags[ctx->numfrags].firstPoint = ctx->numpoints;
VectorCopy(points[0], ctx->points+3*(ctx->numpoints+0));
VectorCopy(points[1], ctx->points+3*(ctx->numpoints+1));
VectorCopy(points[2], ctx->points+3*(ctx->numpoints+2));
points += 3;
ctx->numfrags += 1;
ctx->numpoints += 3;
}
}
int CG_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projection,
int maxPoints, float *pointBuffer, int maxFragments, markFragment_t *fragmentBuffer )
int maxPoints, float *pointBuffer, int maxFragments, q3markFragment_t *fragmentBuffer )
{
vec3_t center;
vec3_t axis[3];
vec3_t p[4];
int i;
float *clippedpoints;
float radius;
int numtris;
q3markFragment_ctx_t ctx;
if (numPoints != 4)
return 0;
@ -438,27 +465,14 @@ int CG_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projecti
VectorNormalize(axis[2]);
VectorNormalize2(projection, axis[0]);
numtris = Q1BSP_ClipDecal(cl.worldmodel, center, axis[0], axis[1], axis[2], radius, &clippedpoints);
if (numtris > maxFragments)
numtris = maxFragments;
if (numtris > maxPoints/3)
numtris = maxPoints/3;
for (i = 0; i < numtris; i++)
{
fragmentBuffer[i].numPoints = 3;
fragmentBuffer[i].firstPoint = i*3;
pointBuffer[i*9+0] = clippedpoints[i*9+0];
pointBuffer[i*9+1] = clippedpoints[i*9+1];
pointBuffer[i*9+2] = clippedpoints[i*9+2];
pointBuffer[i*9+3] = clippedpoints[i*9+3];
pointBuffer[i*9+4] = clippedpoints[i*9+4];
pointBuffer[i*9+5] = clippedpoints[i*9+5];
pointBuffer[i*9+6] = clippedpoints[i*9+6];
pointBuffer[i*9+7] = clippedpoints[i*9+7];
pointBuffer[i*9+8] = clippedpoints[i*9+8];
}
return numtris;
ctx.points = pointBuffer;
ctx.maxpoints = maxPoints;
ctx.numpoints = 0;
ctx.frags = fragmentBuffer;
ctx.numfrags = 0;
ctx.maxfrags = maxFragments;
Mod_ClipDecal(cl.worldmodel, center, axis[0], axis[1], axis[2], radius, CG_MarkFragments_Callback, &ctx);
return ctx.numfrags;
}
int VM_LerpTag(void *out, model_t *model, int f1, int f2, float l2, char *tagname);

View File

@ -612,7 +612,7 @@ readnext:
else if (demotime > cls.td_lastframe)
{
cls.td_lastframe = demotime;
return 0; // already read this frame's message
return 0; // next packet starts after the previous one. draw something before parsing it.
}
if (cls.td_startframe == -1 && cls.state == ca_active)
{ //start the timer only once we are connected.
@ -841,7 +841,6 @@ readit:
demo_flushbytes(demopos);
olddemotime = demotime;
// cls.td_lastframe = host_framecount;
return 1;
}

View File

@ -2536,37 +2536,85 @@ void CLQ1_AddVisibleBBoxes(void)
}
}
typedef struct
{
scenetris_t *t;
vec4_t rgbavalue;
vec3_t axis[3];
float offset[3];
float scale[3];
} cl_adddecal_ctx_t;
static void CL_AddDecal_Callback(void *vctx, vec3_t *fte_restrict points, size_t numtris, shader_t *shader)
{
cl_adddecal_ctx_t *ctx = vctx;
scenetris_t *t = ctx->t;
size_t numpoints = numtris*3;
size_t v;
if (cl_numstrisvert + numpoints > cl_maxstrisvert)
{
cl_maxstrisvert = cl_numstrisvert + numpoints;
cl_strisvertv = BZ_Realloc(cl_strisvertv, sizeof(*cl_strisvertv)*cl_maxstrisvert);
cl_strisvertt = BZ_Realloc(cl_strisvertt, sizeof(vec2_t)*cl_maxstrisvert);
cl_strisvertc = BZ_Realloc(cl_strisvertc, sizeof(vec4_t)*cl_maxstrisvert);
}
if (cl_maxstrisidx < cl_numstrisidx+numpoints)
{
cl_maxstrisidx = cl_numstrisidx+numpoints + 64;
cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx);
}
for (v = 0; v < numpoints; v++)
{
VectorCopy(points[v], cl_strisvertv[cl_numstrisvert+v]);
cl_strisvertt[cl_numstrisvert+v][0] = (DotProduct(points[v], ctx->axis[1]) - ctx->offset[1]) * ctx->scale[1];
cl_strisvertt[cl_numstrisvert+v][1] = -(DotProduct(points[v], ctx->axis[2]) - ctx->offset[2]) * ctx->scale[2];
cl_strisvertc[cl_numstrisvert+v][0] = ctx->rgbavalue[0];
cl_strisvertc[cl_numstrisvert+v][1] = ctx->rgbavalue[1];
cl_strisvertc[cl_numstrisvert+v][2] = ctx->rgbavalue[2];
cl_strisvertc[cl_numstrisvert+v][3] = ctx->rgbavalue[3] * (1-(DotProduct(points[v], ctx->axis[0]) - ctx->offset[0]) * ctx->scale[0]);
}
for (v = 0; v < numpoints; v++)
{
cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+v - t->firstvert;
}
t->numvert += numpoints;
t->numidx += numpoints;
cl_numstrisvert += numpoints;
}
void CL_AddDecal(shader_t *shader, vec3_t origin, vec3_t up, vec3_t side, vec3_t rgbvalue, float alphavalue)
{
int num, v;
vec3_t tang;
float *verts;
float tx, ty, tz;
scenetris_t *t;
float l, s;
cl_adddecal_ctx_t ctx;
VectorNegate(up, up);
CrossProduct(up, side, tang);
VectorNegate(up, ctx.axis[0]);
VectorCopy(side, ctx.axis[2]);
CrossProduct(ctx.axis[0], ctx.axis[2], ctx.axis[1]);
s = sqrt(DotProduct(side, side));
l = sqrt(DotProduct(tang, tang));
s = sqrt(DotProduct(ctx.axis[2], ctx.axis[2]));
l = sqrt(DotProduct(ctx.axis[1], ctx.axis[1]));
VectorScale(tang, s/l, tang);
VectorScale(ctx.axis[1], s/l, ctx.axis[1]);
num = Q1BSP_ClipDecal(cl.worldmodel, origin, up, side, tang, 2, &verts);
VectorScale(ctx.axis[1], 0.5/(s*s), ctx.axis[1]);
VectorScale(ctx.axis[2], 0.5/(s*s), ctx.axis[2]);
l = sqrt(DotProduct(ctx.axis[0], ctx.axis[0]));
VectorScale(ctx.axis[0], 1/(l*l), ctx.axis[0]);
if (!num)
return;
num*=3;
ctx.offset[1] = DotProduct(origin, ctx.axis[1]) + 0.5;
ctx.offset[2] = DotProduct(origin, ctx.axis[2]) + 0.5;
ctx.offset[0] = DotProduct(origin, ctx.axis[0]);
VectorScale(tang, 0.5/(s*s), tang);
VectorScale(side, 0.5/(s*s), side);
l = sqrt(DotProduct(up, up));
VectorScale(up, 1/(l*l), up);
tx = DotProduct(origin, tang) + 0.5;
ty = DotProduct(origin, side) + 0.5;
tz = DotProduct(origin, up);
ctx.scale[1] = 1;
ctx.scale[2] = 1;
ctx.scale[0] = 1;
/*reuse the previous trigroup if its the same shader*/
if (cl_numstris && cl_stris[cl_numstris-1].shader == shader && cl_stris[cl_numstris-1].flags == (BEF_NODLIGHT|BEF_NOSHADOWS))
@ -2587,41 +2635,13 @@ void CL_AddDecal(shader_t *shader, vec3_t origin, vec3_t up, vec3_t side, vec3_t
t->firstvert = cl_numstrisvert;
}
ctx.t = t;
VectorCopy(rgbvalue, ctx.rgbavalue);
ctx.rgbavalue[3] = alphavalue;
Mod_ClipDecal(cl.worldmodel, origin, ctx.axis[0], ctx.axis[1], ctx.axis[2], 2, CL_AddDecal_Callback, &ctx);
if (cl_numstrisvert + num > cl_maxstrisvert)
{
cl_maxstrisvert = cl_numstrisvert + num;
cl_strisvertv = BZ_Realloc(cl_strisvertv, sizeof(*cl_strisvertv)*cl_maxstrisvert);
cl_strisvertt = BZ_Realloc(cl_strisvertt, sizeof(vec2_t)*cl_maxstrisvert);
cl_strisvertc = BZ_Realloc(cl_strisvertc, sizeof(vec4_t)*cl_maxstrisvert);
}
if (cl_maxstrisidx < cl_numstrisidx+num)
{
cl_maxstrisidx = cl_numstrisidx+num + 64;
cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx);
}
for (v = 0; v < num; v++)
{
VectorCopy(verts, cl_strisvertv[cl_numstrisvert+v]);
cl_strisvertt[cl_numstrisvert+v][0] = (DotProduct(verts, tang) - tx);
cl_strisvertt[cl_numstrisvert+v][1] = -(DotProduct(verts, side) - ty);
cl_strisvertc[cl_numstrisvert+v][0] = rgbvalue[0];
cl_strisvertc[cl_numstrisvert+v][1] = rgbvalue[1];
cl_strisvertc[cl_numstrisvert+v][2] = rgbvalue[2];
cl_strisvertc[cl_numstrisvert+v][3] = alphavalue * (1-(DotProduct(verts, up) - tz));
verts+=3;
}
for (v = 0; v < num; v++)
{
cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+v - t->firstvert;
}
t->numvert += num;
t->numidx += num;
cl_numstrisvert += num;
if (!t->numidx)
cl_numstris--;
}
void CLQ1_AddShadow(entity_t *ent)
@ -2629,12 +2649,10 @@ void CLQ1_AddShadow(entity_t *ent)
float radius;
vec3_t shadoworg;
vec3_t eang;
vec3_t axis[3];
float tx, ty, tz;
float *verts;
float tx, ty;
shader_t *s;
int v, num;
scenetris_t *t;
cl_adddecal_ctx_t ctx;
if (!r_shadows.value || !ent->model || ent->model->type != mod_alias)
return;
@ -2667,18 +2685,15 @@ void CLQ1_AddShadow(entity_t *ent)
eang[0] = 0;
eang[1] = ent->angles[1];
eang[2] = 0;
AngleVectors(eang, axis[0], axis[1], axis[2]);
VectorNegate(axis[2], axis[2]);
AngleVectors(eang, ctx.axis[1], ctx.axis[2], ctx.axis[0]);
VectorNegate(ctx.axis[0], ctx.axis[0]);
num = Q1BSP_ClipDecal(cl.worldmodel, shadoworg, axis[2], axis[1], axis[0], radius, &verts);
if (!num)
return;
num*=3;
tx = DotProduct(shadoworg, axis[1]) + 0.5*radius;
ty = DotProduct(shadoworg, axis[0]) + 0.5*radius;
tz = DotProduct(shadoworg, axis[2]);
ctx.offset[2] = DotProduct(shadoworg, ctx.axis[2]) + 0.5*radius;
ctx.offset[1] = DotProduct(shadoworg, ctx.axis[1]) + 0.5*radius;
ctx.offset[0] = DotProduct(shadoworg, ctx.axis[0]);
ctx.scale[1] = 1/radius;
ctx.scale[2] = 1/radius;
ctx.scale[0] = 0.5/radius;
/*reuse the previous trigroup if its the same shader*/
if (cl_numstris && cl_stris[cl_numstris-1].shader == s && cl_stris[cl_numstris-1].flags == (BEF_NODLIGHT|BEF_NOSHADOWS))
@ -2699,41 +2714,11 @@ void CLQ1_AddShadow(entity_t *ent)
t->firstvert = cl_numstrisvert;
}
if (cl_numstrisvert + num > cl_maxstrisvert)
{
cl_maxstrisvert = cl_numstrisvert + num;
cl_strisvertv = BZ_Realloc(cl_strisvertv, sizeof(*cl_strisvertv)*cl_maxstrisvert);
cl_strisvertt = BZ_Realloc(cl_strisvertt, sizeof(vec2_t)*cl_maxstrisvert);
cl_strisvertc = BZ_Realloc(cl_strisvertc, sizeof(vec4_t)*cl_maxstrisvert);
}
if (cl_maxstrisidx < cl_numstrisidx+num)
{
cl_maxstrisidx = cl_numstrisidx+num + 64;
cl_strisidx = BZ_Realloc(cl_strisidx, sizeof(*cl_strisidx)*cl_maxstrisidx);
}
for (v = 0; v < num; v++)
{
VectorCopy(verts, cl_strisvertv[cl_numstrisvert+v]);
cl_strisvertt[cl_numstrisvert+v][0] = (DotProduct(verts, axis[1]) - tx)/radius;
cl_strisvertt[cl_numstrisvert+v][1] = -(DotProduct(verts, axis[0]) - ty)/radius;
cl_strisvertc[cl_numstrisvert+v][0] = 0;
cl_strisvertc[cl_numstrisvert+v][1] = 0;
cl_strisvertc[cl_numstrisvert+v][2] = 0;
cl_strisvertc[cl_numstrisvert+v][3] = r_shadows.value * (1-((DotProduct(verts, axis[2]) - tz)/(radius/2)));
verts+=3;
}
for (v = 0; v < num; v++)
{
cl_strisidx[cl_numstrisidx++] = cl_numstrisvert+v - t->firstvert;
}
t->numvert += num;
t->numidx += num;
cl_numstrisvert += num;
ctx.t = t;
Vector4Set(ctx.rgbavalue, 0, 0, 0, r_shadows.value);
Mod_ClipDecal(cl.worldmodel, shadoworg, ctx.axis[0], ctx.axis[1], ctx.axis[2], radius, CL_AddDecal_Callback, &ctx);
if (!t->numidx)
cl_numstris--;
}
void CLQ1_AddPowerupShell(entity_t *ent, qboolean viewweap, unsigned int effects)
{
@ -4170,7 +4155,7 @@ guess_pm_type:
}
}
if (cl.worldmodel && cl.do_lerp_players)
if (cl.worldmodel && cl.do_lerp_players && cl_predict_players.ival)
{
player_state_t exact;
msec += cls.latency*1000;
@ -4180,6 +4165,7 @@ guess_pm_type:
msec = 255;
state->command.msec = msec;
//FIXME: flag these and do the pred elsewhere.
CL_SetSolidEntities();
CL_SetSolidPlayers();
CL_PredictUsercmd (0, num+1, state, &exact, &state->command); //uses player 0's maxspeed/grav...
@ -4630,7 +4616,7 @@ void CL_LinkViewModel(void)
if (cl.intermission)
return;
if (pv->stats[STAT_WEAPON] <= 0 || pv->stats[STAT_WEAPON] >= MAX_PRECACHE_MODELS)
if (pv->stats[STAT_WEAPONMODELI] <= 0 || pv->stats[STAT_WEAPONMODELI] >= MAX_PRECACHE_MODELS)
return;
if (r_drawviewmodel.value > 0 && r_drawviewmodel.value < 1)
@ -4669,7 +4655,7 @@ void CL_LinkViewModel(void)
ent.flags |= RF_TRANSLUCENT;
}
ent.model = cl.model_precache[pv->stats[STAT_WEAPON]];
ent.model = cl.model_precache[pv->stats[STAT_WEAPONMODELI]];
if (!ent.model)
return;

View File

@ -52,7 +52,7 @@ vec3_t mousemovements[MAX_SPLITS];
/*kinda a hack...*/
static int con_splitmodifier;
cvar_t cl_forcesplitclient = CVAR("in_forcesplitclient", "0");
cvar_t cl_forceseat = CVARAD("in_forceseat", "0", "in_forcesplitclient", "Overrides the device identifiers to control a specific client from any device. This can be used for debugging mods, where you only have one keyboard/mouse.");
extern cvar_t cl_splitscreen;
int CL_TargettedSplit(qboolean nowrap)
{
@ -75,8 +75,8 @@ int CL_TargettedSplit(qboolean nowrap)
if (con_splitmodifier > 0)
return (con_splitmodifier - 1) % mod;
else if (cl_forcesplitclient.ival > 0)
return (cl_forcesplitclient.ival-1) % mod;
else if (cl_forceseat.ival > 0)
return (cl_forceseat.ival-1) % mod;
else
return 0;
}
@ -638,7 +638,7 @@ void CL_ClampPitch (int pnum)
memset(pv->viewanglechange, 0, sizeof(pv->viewanglechange));
return;
}
if (pv->pmovetype == PM_6DOF)
if (pv->pmovetype == PM_6DOF)
{
// vec3_t impact;
// vec3_t norm;
@ -1960,7 +1960,7 @@ void CL_InitInput (void)
Cvar_Register (&cl_prydoncursor, inputnetworkcvargroup);
Cvar_Register (&cl_instantrotate, inputnetworkcvargroup);
Cvar_Register (&cl_forcesplitclient, inputnetworkcvargroup);
Cvar_Register (&cl_forceseat, inputnetworkcvargroup);
for (sp = 0; sp < MAX_SPLITS; sp++)
{

View File

@ -213,10 +213,10 @@ int cl_maxvisedicts;
entity_t *cl_visedicts;
scenetris_t *cl_stris;
vecV_t *cl_strisvertv;
vec4_t *cl_strisvertc;
vec2_t *cl_strisvertt;
index_t *cl_strisidx;
vecV_t *fte_restrict cl_strisvertv;
vec4_t *fte_restrict cl_strisvertc;
vec2_t *fte_restrict cl_strisvertt;
index_t *fte_restrict cl_strisidx;
unsigned int cl_numstrisidx;
unsigned int cl_maxstrisidx;
unsigned int cl_numstrisvert;
@ -328,9 +328,9 @@ CL_Quit_f
*/
void CL_Quit_f (void)
{
if (forcesaveprompt)
if (forcesaveprompt && strcmp(Cmd_Argv(1), "force"))
{
forcesaveprompt =false;
forcesaveprompt = false;
if (Cmd_Exists("menu_quit"))
{
Cmd_ExecuteString("menu_quit", RESTRICT_LOCAL);
@ -1317,6 +1317,14 @@ void CL_ClearState (void)
if (cl.particle_csname[i])
free(cl.particle_csname[i]);
}
#ifdef Q2CLIENT
for (i = 0; i < Q2MAX_IMAGES; i++)
if (cl.image_name[i])
BZ_Free(cl.image_name[i]);
for (i = 0; i < Q2MAX_ITEMS; i++)
if (cl.item_name[i])
BZ_Free(cl.item_name[i]);
#endif
{
downloadlist_t *next;
@ -3842,6 +3850,7 @@ void VARGS Host_Error (char *error, ...)
va_start (argptr,error);
vsnprintf (string,sizeof(string)-1, error,argptr);
va_end (argptr);
COM_AssertMainThread(string);
Con_TPrintf ("Host_Error: %s\n", string);
CL_Disconnect ();
@ -4521,7 +4530,8 @@ double Host_Frame (double time)
//read packets early and always, so we don't have stuff waiting for reception quite so often.
//should smooth out a few things, and increase download speeds.
CL_ReadPackets ();
if (!cls.timedemo)
CL_ReadPackets ();
if (idle && cl_idlefps.value > 0)
{

View File

@ -910,7 +910,7 @@ qboolean CL_CheckQ2BspWals(char *file)
unsigned int i, j, count;
dh = (q2dheader_t*)file;
if (LittleLong(dh->version) != Q2BSPVERSION)
if (LittleLong(dh->version) != BSPVERSION_Q2)
{
//quake3? unknown?
return false;
@ -990,7 +990,7 @@ void Model_CheckDownloads (void)
for (i = 0; i < Q2MAX_IMAGES; i++)
{
char picname[256];
if (!*cl.image_name[i])
if (!cl.image_name[i] || !*cl.image_name[i])
continue;
Q_snprintfz(picname, sizeof(picname), "pics/%s.pcx", cl.image_name[i]);
CL_CheckOrEnqueDownloadFile(picname, picname, 0);
@ -3459,7 +3459,7 @@ void CLNQ_ParseClientdata (void)
{
CL_SetStatInt(0, STAT_WEAPONFRAME, (bits & SU_WEAPONFRAME)?(unsigned short)MSG_ReadShort():0);
CL_SetStatInt(0, STAT_ARMOR, (bits & SU_ARMOR)?MSG_ReadShort():0);
CL_SetStatInt(0, STAT_WEAPON, (bits & SU_WEAPONMODEL)?MSG_ReadShort():0);
CL_SetStatInt(0, STAT_WEAPONMODELI, (bits & SU_WEAPONMODEL)?MSG_ReadShort():0);
CL_SetStatInt(0, STAT_HEALTH, MSG_ReadShort());
@ -3515,7 +3515,7 @@ void CLNQ_ParseClientdata (void)
CL_SetStatInt(0, STAT_WEAPONFRAME, weaponframe);
CL_SetStatInt(0, STAT_ARMOR, armor);
CL_SetStatInt(0, STAT_WEAPON, weaponmodel);
CL_SetStatInt(0, STAT_WEAPONMODELI, weaponmodel);
CL_SetStatInt(0, STAT_HEALTH, health);
@ -3800,41 +3800,41 @@ void CLQ2_ParseConfigString (void)
}
else if (i == Q2CS_CDTRACK)
{
// if (cl.refresh_prepped)
Media_BackgroundTrack (s, NULL);
Media_BackgroundTrack (s, NULL);
}
else if (i >= Q2CS_MODELS && i < Q2CS_MODELS+Q2MAX_MODELS)
{
// if (cl.refresh_prepped)
Q_strncpyz(cl.model_name[i-Q2CS_MODELS], s, MAX_QPATH);
if (cl.model_name[i-Q2CS_MODELS][0] == '#')
{
Q_strncpyz(cl.model_name[i-Q2CS_MODELS], s, MAX_QPATH);
if (cl.model_name[i-Q2CS_MODELS][0] == '#')
if (cl.numq2visibleweapons < Q2MAX_VISIBLE_WEAPONS)
{
if (cl.numq2visibleweapons < Q2MAX_VISIBLE_WEAPONS)
{
cl.q2visibleweapons[cl.numq2visibleweapons] = cl.model_name[i-Q2CS_MODELS]+1;
cl.numq2visibleweapons++;
}
cl.model_precache[i-Q2CS_MODELS] = NULL;
cl.q2visibleweapons[cl.numq2visibleweapons] = cl.model_name[i-Q2CS_MODELS]+1;
cl.numq2visibleweapons++;
}
else
cl.model_precache[i-Q2CS_MODELS] = Mod_ForName (cl.model_name[i-Q2CS_MODELS], MLV_WARN);
cl.model_precache[i-Q2CS_MODELS] = NULL;
}
else
cl.model_precache[i-Q2CS_MODELS] = Mod_ForName (cl.model_name[i-Q2CS_MODELS], MLV_WARN);
}
else if (i >= Q2CS_SOUNDS && i < Q2CS_SOUNDS+Q2MAX_MODELS)
else if (i >= Q2CS_SOUNDS && i < Q2CS_SOUNDS+Q2MAX_SOUNDS)
{
// if (cl.refresh_prepped)
Q_strncpyz(cl.sound_name[i-Q2CS_SOUNDS], s, MAX_QPATH);
cl.sound_precache[i-Q2CS_SOUNDS] = S_PrecacheSound (s);
cl.sound_precache[i-Q2CS_SOUNDS] = S_PrecacheSound (s);
}
else if (i >= Q2CS_IMAGES && i < Q2CS_IMAGES+Q2MAX_MODELS)
{ //ignore
Q_strncpyz(cl.image_name[i-Q2CS_IMAGES], s, MAX_QPATH);
else if (i >= Q2CS_IMAGES && i < Q2CS_IMAGES+Q2MAX_IMAGES)
{
Z_Free(cl.image_name[i-Q2CS_IMAGES]);
cl.image_name[i-Q2CS_IMAGES] = Z_StrDup(s);
}
else if (i >= Q2CS_ITEMS && i < Q2CS_ITEMS+Q2MAX_ITEMS)
{
Z_Free(cl.item_name[i-Q2CS_ITEMS]);
cl.item_name[i-Q2CS_ITEMS] = Z_StrDup(s);
}
else if (i >= Q2CS_PLAYERSKINS && i < Q2CS_PLAYERSKINS+Q2MAX_CLIENTS)
{
// if (cl.refresh_prepped && strcmp(olds, s))
CLQ2_ParseClientinfo (i-Q2CS_PLAYERSKINS, s);
CLQ2_ParseClientinfo (i-Q2CS_PLAYERSKINS, s);
}
else if (i == Q2CS_MAPCHECKSUM)
{
@ -4396,8 +4396,17 @@ void CL_NewTranslation (int slot)
skin = strchr(mod, '/');
if (skin)
*skin++ = 0;
if (!skin || !*skin)
skin = "grunt";
if (!mod || !*mod)
mod = "male";
player->model = Mod_ForName(va("players/%s/tris.md2", mod), 0);
if (player->model->loadstate == MLS_FAILED && strcmp(mod, "male"))
{ //fall back on male if the model doesn't exist. yes, sexist.
mod = "male";
player->model = Mod_ForName(va("players/male/tris.md2", mod), 0);
}
player->skinid = Mod_RegisterSkinFile(va("players/%s/%s.skin", mod,skin));
if (!player->skinid)
player->skinid = Mod_ReadSkinFile(va("players/%s/%s.skin", mod,skin), va("replace \"\" \"players/%s/%s.pcx\"", mod,skin));
@ -4621,7 +4630,7 @@ static void CL_SetStat_Internal (int pnum, int stat, int ivalue, float fvalue)
cl.playerview[pnum].item_gettime[j] = cl.time;
}
if (stat == STAT_WEAPON)
if (stat == STAT_WEAPONMODELI)
{
if (cl.playerview[pnum].stats[stat] != ivalue)
{
@ -5066,12 +5075,9 @@ void CLQ2_ParseMuzzleFlash2 (void)
void CLQ2_ParseInventory (void)
{
int i;
// TODO: finish this properly
unsigned int i;
for (i=0 ; i<Q2MAX_ITEMS ; i++)
// cl.inventory[i] = MSG_ReadShort (&net_message);
MSG_ReadShort (); // just ignore everything for now
cl.inventory[i] = MSG_ReadShort ();
}
#endif
@ -5826,6 +5832,20 @@ void CLQW_ParseServerMessage (void)
CL_ParseClientdata ();
//vanilla QW has no timing info in the client and depends upon the client for all timing.
//using the demo's timing for interpolation prevents unneccesary drift, and solves issues with demo seeking and other such things.
if (cls.demoplayback && !(cls.fteprotocolextensions & PEXT_ACCURATETIMINGS))
{
extern float demtime;
if (cl.gametime != demtime)
{
cl.oldgametime = cl.gametime;
cl.oldgametimemark = cl.gametimemark;
cl.gametime = demtime;
cl.gametimemark = realtime;
}
}
//
// parse the message
//

View File

@ -1003,14 +1003,14 @@ void CL_PredictMovePNum (int seat)
//we're only interested in inbound frames, not outbound, but its outbound frames that contain the prediction timing, so we need to look that up
//(note that in qw, inframe[i].ack==i holds true, but this code tries to be generic for unsyncronised protocols)
//(note that in nq, using outbound times means we'll skip over dupe states without noticing, and input packets with dupes should also be handled gracefully)
Con_DPrintf("in:%i:%i out:%i:%i ack:%i\n", cls.netchan.incoming_sequence, cl.validsequence, cls.netchan.outgoing_sequence,cl.movesequence, cl.ackedmovesequence);
// Con_DPrintf("in:%i:%i out:%i:%i ack:%i\n", cls.netchan.incoming_sequence, cl.validsequence, cls.netchan.outgoing_sequence,cl.movesequence, cl.ackedmovesequence);
for (i = cl.validsequence; i >= cls.netchan.incoming_sequence - UPDATE_MASK; i--)
{
int out;
//skip frames which were not received, or are otherwise invalid. yay packetloss
if (cl.inframes[i & UPDATE_MASK].frameid != i || cl.inframes[i & UPDATE_MASK].invalid)
{
Con_DPrintf("stale incoming command %i\n", i);
// Con_DPrintf("stale incoming command %i\n", i);
continue;
}
@ -1019,7 +1019,7 @@ void CL_PredictMovePNum (int seat)
backdate = &cl.outframes[out & UPDATE_MASK];
if (backdate->cmd_sequence != out)
{
Con_DPrintf("stale outgoing command %i (%i:%i:%i)\n", i, out, backdate->cmd_sequence, backdate->server_message_num);
// Con_DPrintf("stale outgoing command %i (%i:%i:%i)\n", i, out, backdate->cmd_sequence, backdate->server_message_num);
continue;
}
//okay, looks valid
@ -1039,7 +1039,7 @@ void CL_PredictMovePNum (int seat)
}
}
Con_DPrintf("sim%f, %i(%i-%i): old%f, cur%f\n", simtime, cl.ackedmovesequence, fromframe, toframe, fromtime, totime);
// Con_DPrintf("sim%f, %i(%i-%i): old%f, cur%f\n", simtime, cl.ackedmovesequence, fromframe, toframe, fromtime, totime);
if (pv->cam_locked && cl.spectator && pv->viewentity && pv->viewentity <= cl.allocated_client_slots)
{

View File

@ -67,14 +67,12 @@ void RSpeedShow(void)
memset(RQntNames, 0, sizeof(RQntNames));
RQntNames[RQUANT_MSECS] = "Microseconds";
#ifdef _DEBUG
RQntNames[RQUANT_PRIMITIVES] = "Draw Indicies";
#endif
RQntNames[RQUANT_PRIMITIVEINDICIES] = "Draw Indicies";
RQntNames[RQUANT_DRAWS] = "Draw Calls";
RQntNames[RQUANT_2DBATCHES] = "2d Batches";
RQntNames[RQUANT_WORLDBATCHES] = "World Batches";
RQntNames[RQUANT_ENTBATCHES] = "Ent Batches";
RQntNames[RQUANT_SHADOWFACES] = "Shadow Faces";
RQntNames[RQUANT_SHADOWINDICIES] = "Shadow Indicies";
RQntNames[RQUANT_SHADOWEDGES] = "Shadow Edges";
RQntNames[RQUANT_SHADOWSIDES] = "Shadowmap Sides";
RQntNames[RQUANT_LITFACES] = "Lit faces";
@ -1193,6 +1191,7 @@ void SCR_DeInit (void)
scr_initialized = false;
Cmd_RemoveCommand ("screenshot");
Cmd_RemoveCommand ("screenshot_mega");
Cmd_RemoveCommand ("sizeup");
Cmd_RemoveCommand ("sizedown");
}

View File

@ -3591,6 +3591,9 @@ void CL_UpdateBeams (void)
ent->angles[2] = rand()%360;
AngleVectors(ent->angles, ent->axis[0], ent->axis[1], ent->axis[2]);
ent->angles[0] = pitch;
ent->framestate.g[FS_REG].lerpweight[0] = 1;
ent->framestate.g[FS_REG].frame[0] = 0;
ent->framestate.g[FS_REG].frametime[0] = cl.time - (b->endtime - 0.2);
for (i=0 ; i<3 ; i++)
org[i] += dist[i]*30;

View File

@ -739,7 +739,11 @@ typedef struct
char model_name[MAX_PRECACHE_MODELS][MAX_QPATH];
char sound_name[MAX_PRECACHE_SOUNDS][MAX_QPATH];
char *particle_ssname[MAX_SSPARTICLESPRE];
char image_name[Q2MAX_IMAGES][MAX_QPATH];
#ifdef Q2CLIENT
char *image_name[Q2MAX_IMAGES];
char *item_name[Q2MAX_ITEMS];
short inventory[Q2MAX_ITEMS];
#endif
struct model_s *model_precache_vwep[MAX_VWEP_MODELS];
struct model_s *model_precache[MAX_PRECACHE_MODELS];
@ -962,10 +966,10 @@ typedef struct {
unsigned int flags;
} scenetris_t;
extern scenetris_t *cl_stris;
extern vecV_t *cl_strisvertv;
extern vec4_t *cl_strisvertc;
extern vec2_t *cl_strisvertt;
extern index_t *cl_strisidx;
extern vecV_t *fte_restrict cl_strisvertv;
extern vec4_t *fte_restrict cl_strisvertc;
extern vec2_t *fte_restrict cl_strisvertt;
extern index_t *fte_restrict cl_strisidx;
extern unsigned int cl_numstrisidx;
extern unsigned int cl_maxstrisidx;
extern unsigned int cl_numstrisvert;
@ -1220,6 +1224,7 @@ qboolean CSQC_LoadResource(char *resname, char *restype);
qboolean CSQC_ParsePrint(char *message, int printlevel);
qboolean CSQC_ParseGamePacket(void);
qboolean CSQC_CenterPrint(int lplayernum, char *cmd);
qboolean CSQC_Parse_Damage(float save, float take, vec3_t source);
void CSQC_Input_Frame(int lplayernum, usercmd_t *cmd);
void CSQC_WorldLoaded(void);
qboolean CSQC_ParseTempEntity(void);

View File

@ -765,7 +765,7 @@ void Con_PrintCon (console_t *con, char *txt, unsigned int parseflags)
oc = con->current;
if (oc->length+1 > oc->maxlength)
{
oc->maxlength = (oc->length+1)+8;
oc->maxlength = ((oc->length+1)+8)&0xffff;
if (oc->maxlength < oc->length)
oc->length = 0; //don't crash from console line overflows.
con->current = BZ_Realloc(con->current, sizeof(*con->current)+(oc->maxlength)*sizeof(conchar_t));

View File

@ -3901,7 +3901,7 @@ void Image_LoadHiResTextureWorker(void *ctx, void *data, size_t a, size_t b)
//see if we recognise the extension, and only strip it if we do.
COM_FileExtension(tex->ident, nicename, sizeof(nicename));
e = 0;
if (strcmp(nicename, "lmp"))
if (strcmp(nicename, "lmp") && strcmp(nicename, "wal"))
for (; e < tex_extensions_count; e++)
{
if (!strcmp(nicename, (*tex_extensions[e].name=='.')?tex_extensions[e].name+1:tex_extensions[e].name))
@ -4184,6 +4184,10 @@ image_t *Image_CreateTexture (const char *identifier, const char *subdir, unsign
image_t *Image_GetTexture(const char *identifier, const char *subpath, unsigned int flags, void *fallbackdata, void *fallbackpalette, int fallbackwidth, int fallbackheight, uploadfmt_t fallbackfmt)
{
image_t *tex;
qboolean dontposttoworker = (flags & (IF_NOWORKER | IF_LOADNOW));
flags &= ~IF_LOADNOW;
#ifdef LOADERTHREAD
Sys_LockMutex(com_resourcemutex);
#endif
@ -4260,7 +4264,7 @@ image_t *Image_GetTexture(const char *identifier, const char *subpath, unsigned
#endif
//FIXME: pass fallback through this way instead?
if (flags & IF_NOWORKER)
if (dontposttoworker)
Image_LoadHiResTextureWorker(tex, NULL, 0, 0);
else
COM_AddWork(1, Image_LoadHiResTextureWorker, tex, NULL, 0, 0);
@ -4361,17 +4365,68 @@ qboolean Image_UnloadTexture(image_t *tex)
}
return false;
}
//nukes an existing texture, destroying all traces. any lingering references will cause problems, so be careful about how you access these.
void Image_DestroyTexture(image_t *tex)
{
image_t **link;
if (!tex)
return;
TEXDOWAIT(tex); //just in case.
#ifdef LOADERTHREAD
Sys_LockMutex(com_resourcemutex);
#endif
Image_UnloadTexture(tex);
for (link = &imagelist; *link; link = &(*link)->next)
{
if (*link == tex)
{
*link = tex->next;
break;
}
}
#ifdef LOADERTHREAD
Sys_UnlockMutex(com_resourcemutex);
#endif
if (*tex->ident)
Hash_RemoveData(&imagetable, tex->ident, tex);
Z_Free(tex);
}
void Image_List_f(void)
{
image_t *tex;
char *status;
for (tex = imagelist; tex; tex = tex->next)
{
if (tex->status == TEX_LOADED)
status = "^2loaded";
else if (tex->status == TEX_FAILED)
status = "^1failed";
else if (tex->status == TEX_NOTLOADED)
status = "^5not loaded";
else
status = "^bloading";
if (tex->subpath)
Con_Printf("%s^h(%s)^h: %s\n", tex->ident, tex->subpath, status);
else
Con_Printf("%s: %s\n", tex->ident, status);
}
}
//may not create any images yet.
void Image_Init(void)
{
memset(imagetablebuckets, 0, sizeof(imagetablebuckets));
Hash_InitTable(&imagetable, sizeof(imagetablebuckets)/sizeof(imagetablebuckets[0]), imagetablebuckets);
Cmd_AddCommandD("image_list", Image_List_f, "Prints out a list of the currently-known textures.");
}
//destroys all textures
void Image_Shutdown(void)
{
image_t *tex;
int i = 0, j = 0;
Cmd_RemoveCommand("image_list");
while (imagelist)
{
tex = imagelist;

View File

@ -14,7 +14,6 @@ static cvar_t m_fatpressthreshold = CVARFD("m_fatpressthreshold", "0.2", CVAR_AR
static cvar_t m_touchmajoraxis = CVARFD("m_touchmajoraxis", "1", CVAR_ARCHIVE, "When using a touchscreen, use only the major axis for strafing.");
static cvar_t m_slidethreshold = CVARFD("m_slidethreshold", "10", CVAR_ARCHIVE, "How far your finger needs to move to be considered a slide event (touchscreens).");
extern cvar_t cl_forcesplitclient; //all devices claim to be a single player
extern cvar_t _windowed_mouse;
@ -320,8 +319,8 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum)
wpnum = cl.splitclients;
if (wpnum < 1)
wpnum = 1;
if (cl_forcesplitclient.ival)
wpnum = (cl_forcesplitclient.ival-1) % wpnum;
if (cl_forceseat.ival)
wpnum = (cl_forceseat.ival-1) % wpnum;
else
wpnum = mouse->qdeviceid % wpnum;
if (wpnum != pnum)
@ -561,8 +560,8 @@ void IN_MoveJoystick(struct joy_s *joy, float *movements, int pnum, float framet
wpnum = cl.splitclients;
if (wpnum < 1)
wpnum = 1;
if (cl_forcesplitclient.ival)
wpnum = (cl_forcesplitclient.ival-1) % wpnum;
if (cl_forceseat.ival)
wpnum = (cl_forceseat.ival-1) % wpnum;
else
wpnum = joy->qdeviceid % wpnum;
if (wpnum != pnum)

View File

@ -61,7 +61,6 @@ static cvar_t m_accel_noforce = CVAR("m_accel_noforce", "0");
static cvar_t m_threshold_noforce = CVAR("m_threshold_noforce", "0");
static cvar_t cl_keypad = CVAR("cl_keypad", "1");
extern cvar_t cl_forcesplitclient;
extern float multicursor_x[8], multicursor_y[8];
extern qboolean multicursor_active[8];
@ -1811,8 +1810,8 @@ static void INS_JoyMovePtr (struct wjoy_s *joy, float *movements, int pnum)
wpnum = cl.splitclients;
if (wpnum < 1)
wpnum = 1;
if (cl_forcesplitclient.ival)
wpnum = (cl_forcesplitclient.ival-1) % wpnum;
if (cl_forceseat.ival)
wpnum = (cl_forceseat.ival-1) % wpnum;
else
wpnum = joy->devid % wpnum;
if (wpnum != pnum)

View File

@ -57,3 +57,19 @@ void INS_ReInit (void);
void INS_Init (void);
void INS_Shutdown (void);
void INS_Commands (void); //final chance to call IN_MouseMove/IN_KeyEvent each frame
extern cvar_t cl_nodelta;
extern cvar_t cl_c2spps;
extern cvar_t cl_c2sImpulseBackup;
extern cvar_t cl_netfps;
extern cvar_t cl_sparemsec;
extern cvar_t cl_queueimpulses;
extern cvar_t cl_smartjump;
extern cvar_t cl_run;
extern cvar_t cl_fastaccel;
extern cvar_t cl_rollspeed;
extern cvar_t cl_prydoncursor;
extern cvar_t cl_instantrotate;
extern cvar_t in_xflip;
extern cvar_t prox_inmenu;
extern cvar_t cl_forceseat;

View File

@ -648,9 +648,7 @@ static void MenuDrawItems(int xpos, int ypos, menuoption_t *option, menu_t *menu
x += option->bind.captionwidth + 3*8;
{
extern cvar_t cl_forcesplitclient;
M_FindKeysForCommand (cl_forcesplitclient.ival, option->bind.command, keys);
M_FindKeysForCommand (cl_forceseat.ival, option->bind.command, keys);
if (bindingactive && menu->selecteditem == option)
{

View File

@ -2128,7 +2128,7 @@ void Media_ShutdownCin(cin_t *cin)
cin->shutdown(cin);
if (TEXVALID(cin->texture))
R_DestroyTexture(cin->texture);
Image_UnloadTexture(cin->texture);
if (cin->framedata)
{

View File

@ -461,7 +461,6 @@ void M_Menu_Keys_f (void)
{
int y;
menu_t *menu;
extern cvar_t cl_splitscreen, cl_forcesplitclient;
vfsfile_t *bindslist;
Key_Dest_Add(kdm_menu);
@ -491,7 +490,7 @@ void M_Menu_Keys_f (void)
break;
}
if (cl_splitscreen.ival)
if (cl_forceseat.ival)
{
static char *texts[MAX_SPLITS+2] =
{
@ -510,7 +509,7 @@ void M_Menu_Keys_f (void)
"3",
"4"
};
MC_AddCvarCombo(menu, 16, 170, y, "Force client", &cl_forcesplitclient, (const char **)texts, (const char **)values);
MC_AddCvarCombo(menu, 16, 170, y, "Force client", &cl_forceseat, (const char **)texts, (const char **)values);
y+=8;
}

View File

@ -142,6 +142,7 @@ extern struct model_s *Mod_LoadModel (struct model_s *mod, enum mlverbosity_e
extern void *Mod_Extradata (struct model_s *mod); // handles caching
extern void Mod_TouchModel (const char *name);
extern const char *Mod_FixName (const char *modname, const char *worldname); //remaps the name appropriately
char *Mod_ParseWorldspawnKey (const char *ents, const char *key, char *buffer, size_t sizeofbuffer);
extern void Mod_Think (void);
extern int Mod_SkinNumForName (struct model_s *model, const char *name);

View File

@ -74,7 +74,7 @@ typedef struct cparticle_s
#define ABSOLUTE_MIN_PARTICLES 512
#define ABSOLUTE_MAX_PARTICLES 8192
static int r_numparticles;
static cparticle_t *particles, *active_particles, *free_particles;
static cparticle_t *particles, *fte_restrict active_particles, *free_particles;
extern cvar_t r_part_density, r_part_classic_expgrav;
extern qbyte default_quakepal[]; /*for ramps more than anything else*/
@ -367,9 +367,9 @@ static void PClassic_DrawParticles(void)
dvel = 4 * frametime;
#ifdef POLYS
if (cl_numstris && cl_stris[cl_numstris-1].shader == classicshader && cl_stris[cl_numstris-1].numvert + 8 <= MAX_INDICIES)
scenetri = &cl_stris[cl_numstris-1];
else
// if (cl_numstris && cl_stris[cl_numstris-1].shader == classicshader && cl_stris[cl_numstris-1].numvert + 8 <= MAX_INDICIES)
// scenetri = &cl_stris[cl_numstris-1];
// else
{
if (cl_numstris == cl_maxstris)
{

View File

@ -3677,6 +3677,88 @@ static void PScript_EffectSpawned(part_type_t *ptype, vec3_t org, vec3_t axis[3]
Surf_AddStain(org, ptype->stain_rgb[0], ptype->stain_rgb[1], ptype->stain_rgb[2], ptype->stain_radius);
}
typedef struct
{
part_type_t *ptype;
vec3_t center;
vec3_t tangent1;
vec3_t tangent2;
float scale1;
float scale2;
float bias1;
float bias2;
} decalctx_t;
static void PScript_AddDecals(void *vctx, vec3_t *fte_restrict points, size_t numtris, shader_t *surfshader)
{
decalctx_t *ctx = vctx;
part_type_t *ptype = ctx->ptype;
clippeddecal_t *d;
unsigned int i;
vec3_t vec;
while(numtris-->0)
{
if (!free_decals)
break;
d = free_decals;
free_decals = d->next;
d->next = ptype->clippeddecals;
ptype->clippeddecals = d;
for (i = 0; i < 3; i++)
{
VectorCopy(points[i], d->vertex[i]);
VectorSubtract(d->vertex[i], ctx->center, vec);
d->texcoords[i][0] = (DotProduct(vec, ctx->tangent1)*ctx->scale1)+ctx->bias1;
d->texcoords[i][1] = (DotProduct(vec, ctx->tangent2)*ctx->scale2)+ctx->bias2;
}
points += 3;
d->die = ptype->randdie*frandom();
if (ptype->die)
d->rgba[3] = ptype->alpha + d->die*ptype->alphachange;
else
d->rgba[3] = ptype->alpha;
d->rgba[3] += ptype->alpharand*frandom();
if (ptype->colorindex >= 0)
{
int cidx;
cidx = ptype->colorrand > 0 ? rand() % ptype->colorrand : 0;
cidx = ptype->colorindex + cidx;
if (cidx > 255)
d->rgba[3] = d->rgba[3] / 2; // Hexen 2 style transparency
cidx = (cidx & 0xff) * 3;
d->rgba[0] = host_basepal[cidx] * (1/255.0);
d->rgba[1] = host_basepal[cidx+1] * (1/255.0);
d->rgba[2] = host_basepal[cidx+2] * (1/255.0);
}
else
VectorCopy(ptype->rgb, d->rgba);
vec[2] = frandom();
vec[0] = vec[2]*ptype->rgbrandsync[0] + frandom()*(1-ptype->rgbrandsync[0]);
vec[1] = vec[2]*ptype->rgbrandsync[1] + frandom()*(1-ptype->rgbrandsync[1]);
vec[2] = vec[2]*ptype->rgbrandsync[2] + frandom()*(1-ptype->rgbrandsync[2]);
d->rgba[0] += vec[0]*ptype->rgbrand[0] + ptype->rgbchange[0]*d->die;
d->rgba[1] += vec[1]*ptype->rgbrand[1] + ptype->rgbchange[1]*d->die;
d->rgba[2] += vec[2]*ptype->rgbrand[2] + ptype->rgbchange[2]*d->die;
d->die = particletime + ptype->die - d->die;
// maintain run list
if (!(ptype->state & PS_INRUNLIST))
{
ptype->nexttorun = part_run_list;
part_run_list = ptype;
ptype->state |= PS_INRUNLIST;
}
}
}
static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count, int typenum, trailstate_t **tsk)
{
part_type_t *ptype = &part_type[typenum];
@ -3765,22 +3847,17 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
if (ptype->looks.type == PT_CDECAL)
{
clippeddecal_t *d;
int decalcount;
float dist;
vec3_t tangent, t2;
vec3_t vec={0.5, 0.5, 0.5};
float *decverts;
int i;
trace_t tr;
float sb,sw,tb,tw;
vec3_t bestdir, bestorg;
decalctx_t ctx;
vec3_t bestdir;
if (!free_decals)
return 0;
VectorCopy(org, bestorg);
VectorCopy(org, ctx.center);
if (!dir || (dir[0] == 0 && dir[1] == 0 && dir[2] == 0))
{
bestdir[0] = 0;
@ -3791,26 +3868,26 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
{
if (i >= 3)
{
t2[0] = ((i&3)==0)*8;
t2[1] = ((i&3)==1)*8;
t2[2] = ((i&3)==2)*8;
ctx.tangent1[0] = ((i&3)==0)*8;
ctx.tangent1[1] = ((i&3)==1)*8;
ctx.tangent1[2] = ((i&3)==2)*8;
}
else
{
t2[0] = -((i&3)==0)*8;
t2[1] = -((i&3)==1)*8;
t2[2] = -((i&3)==2)*8;
ctx.tangent1[0] = -((i&3)==0)*8;
ctx.tangent1[1] = -((i&3)==1)*8;
ctx.tangent1[2] = -((i&3)==2)*8;
}
VectorSubtract(org, t2, tangent);
VectorAdd(org, t2, t2);
VectorSubtract(org, ctx.tangent1, ctx.tangent2);
VectorAdd(org, ctx.tangent1, ctx.tangent1);
if (cl.worldmodel && cl.worldmodel->funcs.NativeTrace (cl.worldmodel, 0, 0, NULL, tangent, t2, vec3_origin, vec3_origin, false, MASK_WORLDSOLID, &tr))
if (cl.worldmodel && cl.worldmodel->funcs.NativeTrace (cl.worldmodel, 0, 0, NULL, ctx.tangent2, ctx.tangent1, vec3_origin, vec3_origin, false, MASK_WORLDSOLID, &tr))
{
if (tr.fraction < dist)
{
dist = tr.fraction;
VectorCopy(tr.plane.normal, bestdir);
VectorCopy(tr.endpos, bestorg);
VectorCopy(tr.endpos, ctx.center);
}
}
}
@ -3820,85 +3897,21 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
VectorNormalize(dir);
VectorNormalize(vec);
CrossProduct(dir, vec, t2);
Matrix4x4_CM_Transform3(Matrix4x4_CM_NewRotation(frandom()*360, dir[0], dir[1], dir[2]), t2, tangent);
CrossProduct(dir, tangent, t2);
CrossProduct(dir, vec, ctx.tangent1);
Matrix4x4_CM_Transform3(Matrix4x4_CM_NewRotation(frandom()*360, dir[0], dir[1], dir[2]), ctx.tangent1, ctx.tangent2);
CrossProduct(dir, ctx.tangent2, ctx.tangent1);
sw = ptype->s2 - ptype->s1;
sb = ptype->s1 + sw/2;
tw = ptype->t2 - ptype->t1;
tb = ptype->t1 + tw/2;
ctx.ptype = ptype;
ctx.scale1 = ptype->s2 - ptype->s1;
ctx.bias1 = ptype->s1 + ctx.scale1/2;
ctx.scale2 = ptype->t2 - ptype->t1;
ctx.bias2 = ptype->t1 + ctx.scale2/2;
m = ptype->scale + frandom() * ptype->scalerand;
sw /= m;
tw /= m;
ctx.scale1 /= m;
ctx.scale2 /= m;
decalcount = Q1BSP_ClipDecal(cl.worldmodel, bestorg, dir, tangent, t2, m, &decverts);
while(decalcount)
{
if (!free_decals)
break;
d = free_decals;
free_decals = d->next;
d->next = ptype->clippeddecals;
ptype->clippeddecals = d;
VectorCopy((decverts+0*(sizeof(vec3_t)/sizeof(vec_t))), d->vertex[0]);
VectorCopy((decverts+1*(sizeof(vec3_t)/sizeof(vec_t))), d->vertex[1]);
VectorCopy((decverts+2*(sizeof(vec3_t)/sizeof(vec_t))), d->vertex[2]);
for (i = 0; i < 3; i++)
{
VectorSubtract(d->vertex[i], bestorg, vec);
d->texcoords[i][0] = (DotProduct(vec, t2)*sw)+sb;
d->texcoords[i][1] = (DotProduct(vec, tangent)*tw)+tb;
}
d->die = ptype->randdie*frandom();
if (ptype->die)
d->rgba[3] = ptype->alpha + d->die*ptype->alphachange;
else
d->rgba[3] = ptype->alpha;
d->rgba[3] += ptype->alpharand*frandom();
if (ptype->colorindex >= 0)
{
int cidx;
cidx = ptype->colorrand > 0 ? rand() % ptype->colorrand : 0;
cidx = ptype->colorindex + cidx;
if (cidx > 255)
d->rgba[3] = d->rgba[3] / 2; // Hexen 2 style transparency
cidx = (cidx & 0xff) * 3;
d->rgba[0] = host_basepal[cidx] * (1/255.0);
d->rgba[1] = host_basepal[cidx+1] * (1/255.0);
d->rgba[2] = host_basepal[cidx+2] * (1/255.0);
}
else
VectorCopy(ptype->rgb, d->rgba);
vec[2] = frandom();
vec[0] = vec[2]*ptype->rgbrandsync[0] + frandom()*(1-ptype->rgbrandsync[0]);
vec[1] = vec[2]*ptype->rgbrandsync[1] + frandom()*(1-ptype->rgbrandsync[1]);
vec[2] = vec[2]*ptype->rgbrandsync[2] + frandom()*(1-ptype->rgbrandsync[2]);
d->rgba[0] += vec[0]*ptype->rgbrand[0] + ptype->rgbchange[0]*d->die;
d->rgba[1] += vec[1]*ptype->rgbrand[1] + ptype->rgbchange[1]*d->die;
d->rgba[2] += vec[2]*ptype->rgbrand[2] + ptype->rgbchange[2]*d->die;
d->die = particletime + ptype->die - d->die;
decverts += (sizeof(vec3_t)/sizeof(vec_t))*3;
decalcount--;
// maintain run list
if (!(ptype->state & PS_INRUNLIST))
{
ptype->nexttorun = part_run_list;
part_run_list = ptype;
ptype->state |= PS_INRUNLIST;
}
}
//inserts decals through a callback.
Mod_ClipDecal(cl.worldmodel, ctx.center, dir, ctx.tangent2, ctx.tangent1, m, PScript_AddDecals, &ctx);
if (ptype->assoc < 0)
break;

View File

@ -107,6 +107,7 @@ extern sfx_t *cl_sfx_r_exp3;
globalfunction(parse_centerprint, "CSQC_Parse_CenterPrint"); \
globalfunction(parse_print, "CSQC_Parse_Print"); \
globalfunction(parse_event, "CSQC_Parse_Event"); \
globalfunction(parse_damage, "CSQC_Parse_Damage"); \
globalfunction(input_event, "CSQC_InputEvent"); \
globalfunction(input_frame, "CSQC_Input_Frame");/*EXT_CSQC_1*/ \
globalfunction(console_command, "CSQC_ConsoleCommand"); \
@ -270,7 +271,6 @@ static void CSQC_ChangeLocalPlayer(int seat)
static void CSQC_FindGlobals(void)
{
extern cvar_t cl_forcesplitclient;
static float csphysicsmode = 0;
#define globalfloat(name,qcname) csqcg.name = (float*)PR_FindGlobal(csqcprogs, qcname, 0, NULL);
#define globalvector(name,qcname) csqcg.name = (float*)PR_FindGlobal(csqcprogs, qcname, 0, NULL);
@ -291,7 +291,7 @@ static void CSQC_FindGlobals(void)
if (csqcg.cltime)
*csqcg.cltime = realtime;
CSQC_ChangeLocalPlayer(cl_forcesplitclient.ival?(cl_forcesplitclient.ival - 1) % cl.splitclients:0);
CSQC_ChangeLocalPlayer(cl_forceseat.ival?(cl_forceseat.ival - 1) % cl.splitclients:0);
csqc_world.g.self = csqcg.self;
csqc_world.g.other = csqcg.other;
@ -901,6 +901,17 @@ static void QCBUILTIN PF_R_DynamicLight_Set(pubprogfuncs_t *prinst, struct globa
l->rotation[2] = G_FLOAT(OFS_PARM2+2);
break;
#endif
case lfield_dietime:
l->die = G_FLOAT(OFS_PARM2);
break;
case lfield_rgbdecay:
l->channelfade[0] = G_FLOAT(OFS_PARM2+0);
l->channelfade[1] = G_FLOAT(OFS_PARM2+1);
l->channelfade[2] = G_FLOAT(OFS_PARM2+2);
break;
case lfield_radiusdecay:
l->decay = G_FLOAT(OFS_PARM2);
break;
default:
break;
}
@ -971,6 +982,17 @@ static void QCBUILTIN PF_R_DynamicLight_Get(pubprogfuncs_t *prinst, struct globa
G_FLOAT(OFS_RETURN+2) = l->rotation[2];
break;
#endif
case lfield_dietime:
G_FLOAT(OFS_RETURN) = l->die;
break;
case lfield_rgbdecay:
G_FLOAT(OFS_RETURN+0) = l->channelfade[0];
G_FLOAT(OFS_RETURN+1) = l->channelfade[1];
G_FLOAT(OFS_RETURN+2) = l->channelfade[2];
break;
case lfield_radiusdecay:
G_FLOAT(OFS_RETURN) = l->decay;
break;
default:
G_INT(OFS_RETURN) = 0;
break;
@ -1337,7 +1359,6 @@ static void QCBUILTIN PF_cs_unproject (pubprogfuncs_t *prinst, struct globalvars
//clear scene, and set up the default stuff.
static void QCBUILTIN PF_R_ClearScene (pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
extern cvar_t cl_forcesplitclient;
if (prinst->callargc > 0)
CSQC_ChangeLocalPlayer(G_FLOAT(OFS_PARM0));
@ -2724,8 +2745,6 @@ static void QCBUILTIN PF_cs_runplayerphysics (pubprogfuncs_t *prinst, struct glo
//debugging field
pmove.sequence = *csqcg.clientcommandframe;
pmove.pm_type = PM_NORMAL;
pmove.jump_msec = 0;//(cls.z_ext & Z_EXT_PM_TYPE) ? 0 : from->jump_msec;
//set up the movement command
@ -2757,6 +2776,7 @@ static void QCBUILTIN PF_cs_runplayerphysics (pubprogfuncs_t *prinst, struct glo
case MOVETYPE_NOCLIP:
pmove.pm_type = PM_SPECTATOR;
break;
case MOVETYPE_FLY_WORLDONLY:
case MOVETYPE_FLY:
pmove.pm_type = PM_FLY;
break;
@ -4396,7 +4416,6 @@ static void QCBUILTIN PF_getentity(pubprogfuncs_t *prinst, struct globalvars_s *
static void QCBUILTIN PF_V_CalcRefdef(pubprogfuncs_t *prinst, struct globalvars_s *pr_globals)
{
csqcedict_t *ent = (csqcedict_t*)G_EDICT(prinst, OFS_PARM0);
extern cvar_t cl_forcesplitclient;
Con_DPrintf("Warning: V_CalcRefdef (builtin 640) not implemented.\n");
// if (ent->xv->entnum >= 1 && ent->xv->entnum <= MAX_CLIENTS)
// CSQC_ChangeLocalPlayer(ent->xv->entnum-1);
@ -6219,7 +6238,7 @@ void CSQC_Breakpoint_f(void)
else
Con_Printf("Breakpoint has been cleared\n");
Cvar_Set(Cvar_FindVar("pr_debugger"), "1");
// Cvar_Set(Cvar_FindVar("pr_debugger"), "1");
}
static void CSQC_Poke_f(void)
@ -6334,7 +6353,6 @@ qboolean CSQC_DrawView(void)
int ticlimit = 10;
float mintic = 0.01;
double clframetime = host_frametime;
extern cvar_t cl_forcesplitclient;
csqc_resortfrags = true;
csqctime = Sys_DoubleTime();
@ -6387,7 +6405,7 @@ qboolean CSQC_DrawView(void)
host_frametime = clframetime;
//always revert to a usable default.
CSQC_ChangeLocalPlayer(cl_forcesplitclient.ival?(cl_forcesplitclient.ival - 1) % cl.splitclients:0);
CSQC_ChangeLocalPlayer(cl_forceseat.ival?(cl_forceseat.ival - 1) % cl.splitclients:0);
if (csqcg.frametime)
*csqcg.frametime = host_frametime;
@ -6683,6 +6701,23 @@ qboolean CSQC_LoadResource(char *resname, char *restype)
return !!G_FLOAT(OFS_RETURN);
}
qboolean CSQC_Parse_Damage(float save, float take, vec3_t source)
{
void *pr_globals;
if (!csqcprogs || !csqcg.parse_damage)
return false;
pr_globals = PR_globals(csqcprogs, PR_CURRENT);
((float *)pr_globals)[OFS_PARM0] = save;
((float *)pr_globals)[OFS_PARM1] = take;
((float *)pr_globals)[OFS_PARM2+0] = source[0];
((float *)pr_globals)[OFS_PARM2+1] = source[1];
((float *)pr_globals)[OFS_PARM2+2] = source[2];
PR_ExecuteProgram (csqcprogs, csqcg.parse_damage);
return G_FLOAT(OFS_RETURN);
}
qboolean CSQC_ParsePrint(char *message, int printlevel)
{
void *pr_globals;

View File

@ -181,7 +181,7 @@ void R2D_Init(void)
}
missing_texture = R_LoadHiResTexture("no_texture", NULL, IF_NEAREST|IF_NOWORKER);
if (!TEXLOADED(missing_texture))
missing_texture = R_LoadTexture8("no_texture", 16, 16, (unsigned char*)r_notexture_mip + r_notexture_mip->offsets[0], IF_NOALPHA|IF_NOGAMMA, 0);
missing_texture = R_LoadTexture8("no_texture", 16, 16, (unsigned char*)(r_notexture_mip+1), IF_NOALPHA|IF_NOGAMMA, 0);
missing_texture_gloss = R_LoadTexture("no_texture_gloss", 4, 4, TF_RGBA32, (unsigned char*)nogloss, IF_NOGAMMA);
missing_texture_normal = R_LoadTexture("no_texture_normal", 4, 4, TF_RGBA32, (unsigned char*)nonorm, IF_NOGAMMA);
translate_texture = r_nulltex;

View File

@ -25,6 +25,464 @@ float r_avertexnormals[NUMVERTEXNORMALS][3] = {
};
#include "shader.h"
#include "com_mesh.h"
//FIXME: we're likely going to want to thread the building routine at some point.
//the alias mesh stuff will need some rework as it uses statics inside.
#define DESCSPERSHADER 8
typedef struct
{
int x, y, z; //rebuilt if changed
int key;
model_t *loadingmodel; //needs rebuilding, but wait till this is loaded.
struct
{
shader_t *shader;
mesh_t mesh;
mesh_t *pmesh;
vbo_t vbo;
} soups[64];
size_t numsoups;
} cluttersector_t;
static cluttersector_t cluttersector[3*3*3];
cvar_t r_clutter_density = CVARD("r_clutter_density", "1", "Scaler for clutter counts. 0 disables clutter completely.\nClutter requires shaders with 'fte_clutter MODEL SPACING SCALEMIN SCALEMAX ZOFS ANGLEMIN ANGLEMAX' terms");
cvar_t r_clutter_distance = CVARD("r_clutter_distance", "1024", "Distance at which clutter will become invisible."); //should be used by various shaders to fade it out by here
void R_Clutter_Init(void)
{
Cvar_Register(&r_clutter_density, "Ground Clutter");
Cvar_Register(&r_clutter_distance, "Ground Clutter");
}
typedef struct
{
model_t *loadingmodel;
struct clutter_build_ctx_soup_s
{
shader_t *shader;
vecV_t *coord;
vec2_t *texcoord;
vec4_t *colour;
vec3_t *normal;
vec3_t *sdir;
vec3_t *tdir;
index_t *idx;
size_t numverts;
size_t numidx;
size_t maxverts;
size_t maxidx;
} soups[64];
unsigned int numsoups;
float area[DESCSPERSHADER]; //here so it can overflow, so large values with small surfaces actually does something. not evenly perhaps, but not much else we can do
unsigned int x, y, z, w;
} clutter_build_ctx_t;
//to make things repeatable so that people can depend upon placement.
unsigned int R_Clutter_Random(clutter_build_ctx_t *ctx)
{ //ripped from wikipedia (originally called xorshift128)
unsigned int t = ctx->x ^ (ctx->x << 11);
ctx->x = ctx->y; ctx->y = ctx->z; ctx->z = ctx->w;
return ctx->w = ctx->w ^ (ctx->w >> 19) ^ t ^ (t >> 8);
}
float R_Clutter_FRandom(clutter_build_ctx_t *ctx)
{
unsigned int r = R_Clutter_Random(ctx);
return (r & 0xffffff) / (float)0xffffff;
}
static void R_Clutter_Insert_Soup(clutter_build_ctx_t *ctx, shader_t *shader, vecV_t *fte_restrict coord, vec2_t *fte_restrict texcoord, vec3_t *fte_restrict normal, vec3_t *fte_restrict sdir, vec3_t *fte_restrict tdir, vec4_t *fte_restrict colours, size_t numverts, index_t *fte_restrict index, size_t numidx, float scale, vec3_t origin, vec3_t axis[])
{
vec3_t diffuse, ambient, ldir;
float dot;
struct clutter_build_ctx_soup_s *soup = NULL;
size_t i;
shader_t *os = shader;
shader = R_RegisterShader(va("clutter#replace=%s", os->name), SUF_NONE,
"{\n"
"program defaultsprite#MASK=0.666\n"
// "surfaceparm nodlight\n"
"surfaceparm noshadows\n"
// "cull disable\n"
"{\n"
"map $diffuse\n"
"rgbgen vertex\n"
"alphagen vertex\n"
// "alphafunc ge128\n"
"}\n"
"}\n"
);
shader->defaulttextures = os->defaulttextures;
for (i = 0, soup = ctx->soups; i < ctx->numsoups; i++, soup++)
{
if (soup->shader == shader)
if (soup->numverts + numverts <= MAX_INDICIES)
break;
}
if (i == ctx->numsoups)
{
if (i == sizeof(ctx->soups)/sizeof(ctx->soups[0]))
return; //too many different shaders or something
soup->shader = shader;
ctx->numsoups++;
}
//inject the indicies
if (soup->numidx + numidx > soup->maxidx)
{
soup->maxidx = (soup->numidx + numidx) * 2;
soup->idx = BZ_Realloc(soup->idx, sizeof(*soup->idx) * soup->maxidx);
}
for (i = 0; i < numidx; i++)
soup->idx[soup->numidx++] = soup->numverts+*index++;
cl.worldmodel->funcs.LightPointValues(cl.worldmodel, origin, diffuse, ambient, ldir);
VectorScale(ambient, 1/255.0, ambient);
VectorScale(diffuse, 1/255.0, diffuse);
//inject the verts
if (soup->numverts + numverts > soup->maxverts)
{
soup->maxverts = (soup->numverts + numverts) * 2;
soup->coord = BZ_Realloc(soup->coord, sizeof(*soup->coord) * soup->maxverts);
soup->texcoord = BZ_Realloc(soup->texcoord, sizeof(*soup->texcoord) * soup->maxverts);
soup->colour = BZ_Realloc(soup->colour, sizeof(*soup->colour) * soup->maxverts);
soup->normal = BZ_Realloc(soup->normal, sizeof(*soup->normal) * soup->maxverts);
soup->sdir = BZ_Realloc(soup->sdir, sizeof(*soup->sdir) * soup->maxverts);
soup->tdir = BZ_Realloc(soup->tdir, sizeof(*soup->tdir) * soup->maxverts);
}
for (i = 0; i < numverts; i++)
{
VectorMA(origin, scale*coord[i][0], axis[0], soup->coord[soup->numverts]);
VectorMA(soup->coord[soup->numverts], scale*coord[i][1], axis[1], soup->coord[soup->numverts]);
VectorMA(soup->coord[soup->numverts], scale*coord[i][2], axis[2], soup->coord[soup->numverts]);
Vector2Copy(texcoord[i], soup->texcoord[soup->numverts]);
VectorMA(vec3_origin, normal[i][0], axis[0], soup->normal[soup->numverts]);
VectorMA(soup->normal[soup->numverts], normal[i][1], axis[1], soup->normal[soup->numverts]);
VectorMA(soup->normal[soup->numverts], normal[i][2], axis[2], soup->normal[soup->numverts]);
VectorMA(vec3_origin, sdir[i][0], axis[0], soup->sdir[soup->numverts]);
VectorMA(soup->sdir[soup->numverts], sdir[i][1], axis[1], soup->sdir[soup->numverts]);
VectorMA(soup->sdir[soup->numverts], sdir[i][2], axis[2], soup->sdir[soup->numverts]);
VectorMA(vec3_origin, tdir[i][0], axis[0], soup->tdir[soup->numverts]);
VectorMA(soup->tdir[soup->numverts], tdir[i][1], axis[1], soup->tdir[soup->numverts]);
VectorMA(soup->tdir[soup->numverts], tdir[i][2], axis[2], soup->tdir[soup->numverts]);
// VectorCopy(ambient, soup->colour[soup->numverts]);
dot = DotProduct(ldir, soup->normal[soup->numverts]);
if (dot < 0)
dot = 0;
VectorMA(ambient, dot, diffuse, soup->colour[soup->numverts]);
if (colours) //most model formats don't have vertex colours
soup->colour[soup->numverts][3] = colours[i][3];
else
soup->colour[soup->numverts][3] = 1;
soup->numverts++;
}
}
static void R_Clutter_Insert_Mesh(clutter_build_ctx_t *ctx, model_t *mod, float scale, vec3_t origin, vec3_t axis[3])
{
mesh_t mesh;
galiasinfo_t *inf;
unsigned int surfnum = 0;
entity_t re;
unsigned int randanim = R_Clutter_Random(ctx);
unsigned int randskin = R_Clutter_Random(ctx);
if (!mod)
return;
//fill in the parts of the entity_t that Alias_GAliasBuildMesh needs.
memset(&re, 0, sizeof(re));
// memset(&re.framestate, 0, sizeof(re.framestate));
re.framestate.g[FS_REG].lerpweight[0] = 1;
re.model = mod;
inf = (galiasinfo_t*)Mod_Extradata (mod);
while(inf)
{
galiasskin_t *skins = inf->ofsskins;
re.framestate.g[FS_REG].frame[0] = randanim%inf->numanimations;
if (skins->numframes)
{
unsigned int frame = randskin%skins->numframes;
Alias_GAliasBuildMesh(&mesh, NULL, inf, surfnum, &re, false);
surfnum++;
//fixme: if shares verts, rewind the verts and don't add more somehow, while being careful with shaders
R_Clutter_Insert_Soup(ctx, skins->frame[frame].shader, mesh.xyz_array, mesh.st_array, mesh.normals_array, mesh.snormals_array, mesh.tnormals_array, mesh.colors4f_array[0], mesh.numvertexes, mesh.indexes, mesh.numindexes, scale, origin, axis);
}
inf = inf->nextsurf;
}
Alias_FlushCache(); //it got built using an entity on the stack, make sure other stuff doesn't get hurt.
}
static void R_Clutter_Insert(void *vctx, vec3_t *fte_restrict points, size_t numtris, shader_t *surface)
{
struct shader_clutter_s *clut;
unsigned int obj;
clutter_build_ctx_t *ctx = vctx;
model_t *mod[DESCSPERSHADER];
if (!surface || !surface->clutter)
return; //nothing to do.
//avoid returning on error, so the randomization is dependable when content is still loading.
for (clut = surface->clutter, obj = 0; clut && obj <= DESCSPERSHADER; clut = clut->next, obj++)
{
mod[obj] = Mod_ForName(clut->modelname, MLV_WARN);
if (mod[obj]->loadstate == MLS_LOADING)
{
if (!ctx->loadingmodel)
ctx->loadingmodel = mod[obj];
mod[obj] = NULL;
}
else if (mod[obj]->type != mod_alias)
mod[obj] = NULL;
}
while(numtris-->0)
{
vec3_t xd;
vec3_t yd;
vec3_t zd;
vec3_t norm;
vec3_t axis[3];
vec3_t org, dir;
float dot;
float triarea;
// vec3_t discard;
// unsigned int subimage;
vec_t xm, ym, zm, s;
VectorSubtract(points[1], points[0], xd);
VectorSubtract(points[2], points[0], yd);
VectorSubtract(points[2], points[1], zd);
CrossProduct(yd, xd, norm);
VectorNormalize(norm);
if (norm[2] >= 0.7)
{
//determine area of triangle
xm = Length(xd);
ym = Length(yd);
zm = Length(zd);
s = (xm+ym+zm)/2;
triarea = sqrt(s*(s-xm)*(s-ym)*(s-zm));
for (clut = surface->clutter, obj = 0; clut && obj <= DESCSPERSHADER; clut = clut->next, obj++)
{
float spacing = clut->spacing / r_clutter_density.value;
if (spacing < 1)
spacing = 1;
ctx->area[obj] += triarea;
while (ctx->area[obj] >= spacing)
{
float scale = clut->scalemin + R_Clutter_FRandom(ctx) * (clut->scalemax-clut->scalemin);
ctx->area[obj] -= spacing;
//pick a random spot
xm = R_Clutter_FRandom(ctx)*R_Clutter_FRandom(ctx);
ym = R_Clutter_FRandom(ctx) * (1-xm);
VectorMA(points[0], xm, xd, org);
VectorMA(org, ym, yd, org);
//randomize the direction
dot = clut->anglemin + R_Clutter_FRandom(ctx) * (clut->anglemax-clut->anglemin);
dir[0] = cos(dot);
dir[1] = sin(dot);
dir[2] = 0;
//figure out various directions
dot = -DotProduct(dir, norm);
VectorMA(dir, dot, norm, dir);
VectorNormalize(dir);
VectorCopy(norm, axis[2]);
CrossProduct(axis[2], dir, axis[1]);
CrossProduct(axis[1], axis[2], axis[0]);
VectorMA(org, clut->zofs*scale, axis[2], org);
R_Clutter_Insert_Mesh(ctx, mod[obj], scale, org, axis);
/*
VectorMA(org, r_clutter_size.value/2, dir, vertcoord[numverts]);
VectorMA(org, -(r_clutter_size.value/2), dir, vertcoord[numverts+1]);
VectorMA(vertcoord[numverts], r_clutter_height.value, norm, vertcoord[numverts+2]);
VectorMA(vertcoord[numverts+1], r_clutter_height.value, norm, vertcoord[numverts+3]);
subimage = R_Clutter_Random(ctx);
Vector2Set(texcoord[numverts], subimage%r_clutter_atlaswidth.ival, (subimage/r_clutter_atlaswidth.ival)%r_clutter_atlasheight.ival);
texcoord[numverts][0] *= 1/r_clutter_atlaswidth.value;
texcoord[numverts][1] *= 1/r_clutter_atlasheight.value;
Vector2Set(texcoord[numverts+1], texcoord[numverts][0]+(1/r_clutter_atlaswidth.value), texcoord[numverts][1]);
Vector2Set(texcoord[numverts+2], texcoord[numverts][0] , texcoord[numverts][1]);
Vector2Set(texcoord[numverts+3], texcoord[numverts][0]+(1/r_clutter_atlaswidth.value), texcoord[numverts][1]);
texcoord[numverts+0][1]+=(1/r_clutter_atlasheight.value);
texcoord[numverts+1][1]+=(1/r_clutter_atlasheight.value);
Vector4Set(colours[numverts+0], 1, 1, 1, 1);
VectorMA(org, 1/8.0, norm, org);//push away from the surface to avoid precision issues with lighting on slopes
cl.worldmodel->funcs.LightPointValues(cl.worldmodel, org, colours[numverts+0], discard, discard);
VectorScale(colours[numverts+0], 1/512.0, colours[numverts+0]);
Vector4Copy(colours[numverts+0], colours[numverts+1]);
Vector4Copy(colours[numverts+0], colours[numverts+2]);
Vector4Copy(colours[numverts+1], colours[numverts+3]);
indexes[numidx+0] = numverts+0;
indexes[numidx+1] = numverts+2;
indexes[numidx+2] = numverts+1;
indexes[numidx+3] = numverts+2;
indexes[numidx+4] = numverts+3;
indexes[numidx+5] = numverts+1;
numverts += 4;
numidx += 6;
*/
}
}
}
points += 3;
}
}
void R_Clutter_Emit(batch_t **batches)
{
const float cluttersize = r_clutter_distance.value;
int vx, vy, vz;
int x, y, z, key, i;
cluttersector_t *sect;
batch_t *b;
qboolean rebuildlimit = false;
if (!cl.worldmodel || cl.worldmodel->loadstate != MLS_LOADED || r_clutter_density.value <= 0)
return;
if (qrenderer != QR_OPENGL) //vbo only!
return;
//rebuild if any of the cvars changes.
key = r_clutter_density.modified + r_clutter_distance.modified;
vx = floor((r_refdef.vieworg[0] / cluttersize));
vy = floor((r_refdef.vieworg[1] / cluttersize));
vz = floor((r_refdef.vieworg[2] / cluttersize));
for (z = vz-1; z <= vz+1; z++)
for (y = vy-1; y <= vy+1; y++)
for (x = vx-1; x <= vx+1; x++)
{
int ix = x%3;
int iy = y%3;
int iz = z%3;
if (ix < 0)
ix += 3;
if (iy < 0)
iy += 3;
if (iz < 0)
iz += 3;
sect = &cluttersector[ix + (iy*3) + (iz*3*3)];
if (sect->loadingmodel && sect->loadingmodel->loadstate != MLS_LOADING)
{
sect->loadingmodel = NULL;
sect->key-=1; //rebuild even if failed, this covers multiple models.
}
if (sect->x != x || sect->y != y || sect->z != z || sect->key != key)
{
vbobctx_t vctx;
clutter_build_ctx_t cctx;
vec3_t org = {x*cluttersize+(cluttersize/2),y*cluttersize+(cluttersize/2),z*cluttersize+(cluttersize/2)};
vec3_t down = {0, 0, -1};
vec3_t forward = {1, 0, 0};
vec3_t right = {0, 1, 0};
if (r_refdef.recurse) //FIXME
continue;
if (rebuildlimit)
continue;
rebuildlimit = true;
sect->x = x;
sect->y = y;
sect->z = z;
sect->key = key;
//make sure any old state is gone
for (i = 0; i < sect->numsoups; i++)
{
BE_VBO_Destroy(&sect->soups[i].vbo.coord);
BE_VBO_Destroy(&sect->soups[i].vbo.indicies);
}
sect->numsoups = 0;
memset(&cctx, 0, sizeof(cctx));
cctx.x = x;
cctx.y = y;
cctx.z = z;
cctx.w = (sect-cluttersector)+1;
Mod_ClipDecal(cl.worldmodel, org, down, forward, right, cluttersize, R_Clutter_Insert, &cctx);
sect->loadingmodel = cctx.loadingmodel;
for (i = 0; i < cctx.numsoups; i++)
{
if (cctx.soups[i].numverts)
{
sect->soups[sect->numsoups].shader = cctx.soups[i].shader;
sect->soups[sect->numsoups].pmesh = &sect->soups[sect->numsoups].mesh;
BE_VBO_Begin(&vctx, (sizeof(cctx.soups[i].coord[0]) + sizeof(cctx.soups[i].texcoord[0]) + sizeof(cctx.soups[i].colour[0]) + 3*sizeof(vec3_t))*cctx.soups[i].numverts);
BE_VBO_Data(&vctx, cctx.soups[i].coord, sizeof(cctx.soups[i].coord[0])*cctx.soups[i].numverts, &sect->soups[sect->numsoups].vbo.coord);
BE_VBO_Data(&vctx, cctx.soups[i].texcoord, sizeof(cctx.soups[i].texcoord[0])*cctx.soups[i].numverts, &sect->soups[sect->numsoups].vbo.texcoord);
BE_VBO_Data(&vctx, cctx.soups[i].colour, sizeof(cctx.soups[i].colour[0])*cctx.soups[i].numverts, &sect->soups[sect->numsoups].vbo.colours[0]);
BE_VBO_Data(&vctx, cctx.soups[i].normal, sizeof(cctx.soups[i].normal[0])*cctx.soups[i].numverts, &sect->soups[sect->numsoups].vbo.normals);
BE_VBO_Data(&vctx, cctx.soups[i].sdir, sizeof(cctx.soups[i].sdir[0])*cctx.soups[i].numverts, &sect->soups[sect->numsoups].vbo.svector);
BE_VBO_Data(&vctx, cctx.soups[i].tdir, sizeof(cctx.soups[i].tdir[0])*cctx.soups[i].numverts, &sect->soups[sect->numsoups].vbo.tvector);
BE_VBO_Finish(&vctx, cctx.soups[i].idx, sizeof(cctx.soups[i].idx[0])*cctx.soups[i].numidx, &sect->soups[sect->numsoups].vbo.indicies);
sect->soups[sect->numsoups].mesh.numindexes = sect->soups[sect->numsoups].vbo.indexcount = cctx.soups[i].numidx;
sect->soups[sect->numsoups].mesh.numvertexes = sect->soups[sect->numsoups].vbo.vertcount = cctx.soups[i].numverts;
sect->numsoups++;
}
BZ_Free(cctx.soups[i].coord);
BZ_Free(cctx.soups[i].texcoord);
BZ_Free(cctx.soups[i].colour);
BZ_Free(cctx.soups[i].normal);
BZ_Free(cctx.soups[i].sdir);
BZ_Free(cctx.soups[i].tdir);
BZ_Free(cctx.soups[i].idx);
}
}
//emit a batch if we have grassy surfaces in this block
for (i = 0; i < sect->numsoups; i++)
{
b = BE_GetTempBatch();
if (!b)
return;
memset(b, 0, sizeof(*b));
b->ent = &r_worldentity;
b->meshes = 1;
b->mesh = &sect->soups[i].pmesh;
b->vbo = &sect->soups[i].vbo;
b->shader = sect->soups[i].shader;
b->next = batches[b->shader->sort];
batches[b->shader->sort] = b;
}
}
}
void R_Clutter_Purge(void)
{
size_t i, j;
cluttersector_t *sect;
if (!qrenderer)
return;
for (i = 0; i < sizeof(cluttersector)/sizeof(cluttersector[0]); i++)
{
sect = &cluttersector[i];
for (j = 0; j < sect->numsoups; j++)
{
BE_VBO_Destroy(&sect->soups[j].vbo.coord);
BE_VBO_Destroy(&sect->soups[j].vbo.indicies);
}
memset(sect, 0, sizeof(*sect));
}
}
void R_Rockettrail_Callback(struct cvar_s *var, char *oldvalue)
{
int i;
@ -181,6 +639,8 @@ void P_InitParticleSystem(void)
Cvar_Register (&r_rockettrail, particlecvargroupname);
Cvar_Register (&r_grenadetrail, particlecvargroupname);
R_Clutter_Init();
}
void P_Shutdown(void)
@ -195,6 +655,8 @@ void P_Shutdown(void)
pe->ShutdownParticles();
}
pe = NULL;
R_Clutter_Purge();
}
//0 says hit nothing.

View File

@ -36,7 +36,7 @@ model_t *currentmodel;
int lightmap_bytes; // 1, 3 or 4
qboolean lightmap_bgra;
#define MAX_LIGHTMAP_SIZE LMBLOCK_WIDTH
#define MAX_LIGHTMAP_SIZE 1024//LMBLOCK_WIDTH
vec3_t blocknormals[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE];
unsigned blocklights[3*MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE];
@ -95,8 +95,8 @@ void Surf_StainSurf (msurface_t *surf, float *parms)
return;
lm = lightmap[surf->lightmaptexturenums[0]];
smax = (surf->extents[0]>>4)+1;
tmax = (surf->extents[1]>>4)+1;
smax = (surf->extents[0]>>surf->lmshift)+1;
tmax = (surf->extents[1]>>surf->lmshift)+1;
tex = surf->texinfo;
stainbase = lm->stainmaps;
@ -123,12 +123,12 @@ void Surf_StainSurf (msurface_t *surf, float *parms)
for (t = 0 ; t<tmax ; t++)
{
td = local[1] - t*16;
td = local[1] - (t<<surf->lmshift);
if (td < 0)
td = -td;
for (s=0 ; s<smax ; s++)
{
sd = local[0] - s*16;
sd = local[0] - (s<<surf->lmshift);
if (sd < 0)
sd = -sd;
if (sd > td)
@ -245,7 +245,7 @@ void Surf_WipeStains(void)
{
if (!lightmap[i])
break;
memset(lightmap[i]->stainmaps, 255, LMBLOCK_WIDTH*LMBLOCK_HEIGHT*3*sizeof(stmap));
memset(lightmap[i]->stainmaps, 255, lightmap[i]->width*lightmap[i]->height*3*sizeof(stmap));
}
}
@ -284,8 +284,8 @@ void Surf_LessenStains(void)
surf->cached_dlight=-1;//nice hack here...
smax = (surf->extents[0]>>4)+1;
tmax = (surf->extents[1]>>4)+1;
smax = (surf->extents[0]>>surf->lmshift)+1;
tmax = (surf->extents[1]>>surf->lmshift)+1;
stain = lm->stainmaps;
stain += (surf->light_t[0] * lm->width + surf->light_s[0]) * 3;
@ -333,8 +333,8 @@ static void Surf_AddDynamicLights (msurface_t *surf)
float a;
unsigned *bl;
smax = (surf->extents[0]>>4)+1;
tmax = (surf->extents[1]>>4)+1;
smax = (surf->extents[0]>>surf->lmshift)+1;
tmax = (surf->extents[1]>>surf->lmshift)+1;
tex = surf->texinfo;
for (lnum=rtlights_first; lnum<RTL_FIRST; lnum++)
@ -371,12 +371,12 @@ static void Surf_AddDynamicLights (msurface_t *surf)
bl = blocklights;
for (t = 0 ; t<tmax ; t++)
{
td = local[1] - t*16;
td = local[1] - (t<<surf->lmshift);
if (td < 0)
td = -td;
for (s=0 ; s<smax ; s++)
{
sd = local[0] - s*16;
sd = local[0] - (s<<surf->lmshift);
if (sd < 0)
sd = -sd;
if (sd > td)
@ -442,12 +442,12 @@ static void Surf_AddDynamicLightNorms (msurface_t *surf)
for (t = 0 ; t<tmax ; t++)
{
td = local[1] - t*16;
td = local[1] - t*surf->lmscale;
if (td < 0)
td = -td;
for (s=0 ; s<smax ; s++)
{
sd = local[0] - s*16;
sd = local[0] - s*surf->lmscale;
if (sd < 0)
sd = -sd;
if (sd > td)
@ -482,8 +482,8 @@ static void Surf_AddDynamicLightsColours (msurface_t *surf)
unsigned *bl;
vec3_t lightofs;
smax = (surf->extents[0]>>4)+1;
tmax = (surf->extents[1]>>4)+1;
smax = (surf->extents[0]>>surf->lmshift)+1;
tmax = (surf->extents[1]>>surf->lmshift)+1;
tex = surf->texinfo;
for (lnum=rtlights_first; lnum<RTL_FIRST; lnum++)
@ -521,12 +521,12 @@ static void Surf_AddDynamicLightsColours (msurface_t *surf)
{
for (t = 0 ; t<tmax ; t++)
{
td = local[1] - t*16;
td = local[1] - t*surf->lmscale;
if (td < 0)
td = -td;
for (s=0 ; s<smax ; s++)
{
sd = local[0] - s*16;
sd = local[0] - s*surf->lmscale;
if (sd < 0)
sd = -sd;
if (sd > td)
@ -547,12 +547,12 @@ static void Surf_AddDynamicLightsColours (msurface_t *surf)
bl = blocklights;
for (t = 0 ; t<tmax ; t++)
{
td = local[1] - t*16;
td = local[1] - (t<<surf->lmshift);
if (td < 0)
td = -td;
for (s=0 ; s<smax ; s++)
{
sd = local[0] - s*16;
sd = local[0] - (s<<surf->lmshift);
if (sd < 0)
sd = -sd;
if (sd > td)
@ -575,7 +575,7 @@ static void Surf_AddDynamicLightsColours (msurface_t *surf)
static void Surf_BuildDeluxMap (msurface_t *surf, qbyte *dest)
static void Surf_BuildDeluxMap (msurface_t *surf, qbyte *dest, unsigned int lmwidth)
{
int smax, tmax;
int i, j, size;
@ -587,13 +587,13 @@ static void Surf_BuildDeluxMap (msurface_t *surf, qbyte *dest)
vec_t *bnorm;
vec3_t temp;
int stride = LMBLOCK_WIDTH*lightmap_bytes;
int stride = lmwidth*lightmap_bytes;
if (!dest)
return;
smax = (surf->extents[0]>>4)+1;
tmax = (surf->extents[1]>>4)+1;
smax = (surf->extents[0]>>surf->lmshift)+1;
tmax = (surf->extents[1]>>surf->lmshift)+1;
size = smax*tmax;
lightmap = surf->samples;
@ -705,7 +705,7 @@ enum lm_mode
just unpacks the internal lightmap block into texture info ready for upload
merges stains and oversaturates overbrights.
*/
static void Surf_StoreLightmap(qbyte *dest, int smax, int tmax, unsigned int shift, enum lm_mode lm_mode, stmap *stainsrc)
static void Surf_StoreLightmap(qbyte *dest, int smax, int tmax, unsigned int shift, enum lm_mode lm_mode, stmap *stainsrc, unsigned int lmwidth)
{
int r, g, b, t, m;
unsigned int i, j;
@ -715,7 +715,7 @@ static void Surf_StoreLightmap(qbyte *dest, int smax, int tmax, unsigned int shi
switch (lm_mode)
{
case bgra4_os:
stride = LMBLOCK_WIDTH*4 - (smax<<2);
stride = lmwidth*4 - (smax<<2);
bl = blocklights;
@ -752,7 +752,7 @@ static void Surf_StoreLightmap(qbyte *dest, int smax, int tmax, unsigned int shi
dest += 4;
}
if (stainsrc)
stainsrc += (LMBLOCK_WIDTH - smax)*3;
stainsrc += (lmwidth - smax)*3;
}
break;
/*
@ -801,12 +801,12 @@ static void Surf_StoreLightmap(qbyte *dest, int smax, int tmax, unsigned int shi
dest += 4;
}
if (stainsrc)
stainsrc += (LMBLOCK_WIDTH - smax)*3;
stainsrc += (lmwidth - smax)*3;
}
break;
*/
case rgb3_os:
stride = LMBLOCK_WIDTH*3 - (smax*3);
stride = lmwidth*3 - (smax*3);
bl = blocklights;
for (i=0 ; i<tmax ; i++, dest += stride)
@ -840,11 +840,11 @@ static void Surf_StoreLightmap(qbyte *dest, int smax, int tmax, unsigned int shi
dest += 3;
}
if (stainsrc)
stainsrc += (LMBLOCK_WIDTH - smax)*3;
stainsrc += (lmwidth - smax)*3;
}
break;
case lum:
stride = LMBLOCK_WIDTH;
stride = lmwidth;
bl = blocklights;
for (i=0 ; i<tmax ; i++, dest += stride)
{
@ -870,7 +870,7 @@ R_BuildLightMap
Combine and scale multiple lightmaps into the 8.8 format in blocklights
===============
*/
static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest, stmap *stainsrc, int shift, int ambient)
static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest, stmap *stainsrc, int shift, int ambient, unsigned int lmwidth)
{
int smax, tmax;
int t;
@ -885,8 +885,8 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest,
shift += 7; // increase to base value
surf->cached_dlight = (surf->dlightframe == r_framecount);
smax = (surf->extents[0]>>4)+1;
tmax = (surf->extents[1]>>4)+1;
smax = (surf->extents[0]>>surf->lmshift)+1;
tmax = (surf->extents[1]>>surf->lmshift)+1;
size = smax*tmax;
lightmap = surf->samples;
@ -897,7 +897,7 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest,
}
if (currentmodel->deluxdata)
Surf_BuildDeluxMap(surf, deluxdest);
Surf_BuildDeluxMap(surf, deluxdest, lmwidth);
#ifdef PEXT_LIGHTSTYLECOL
if (lightmap_bytes == 4 || lightmap_bytes == 3)
@ -969,9 +969,9 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest,
{
for (j = 0; j < smax; j++)
{
bl[0] = 255*lightmap[(i*LMBLOCK_WIDTH+j)*3];
bl[1] = 255*lightmap[(i*LMBLOCK_WIDTH+j)*3+1];
bl[2] = 255*lightmap[(i*LMBLOCK_WIDTH+j)*3+2];
bl[0] = 255*lightmap[(i*lmwidth+j)*3];
bl[1] = 255*lightmap[(i*lmwidth+j)*3+1];
bl[2] = 255*lightmap[(i*lmwidth+j)*3+2];
bl+=3;
}
}
@ -1078,7 +1078,7 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest,
{
if (lightmap_bgra)
{
Surf_StoreLightmap(dest, smax, tmax, shift, bgra4_os, stainsrc);
Surf_StoreLightmap(dest, smax, tmax, shift, bgra4_os, stainsrc, lmwidth);
}
else
{
@ -1102,7 +1102,7 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest,
}
else
{
Surf_StoreLightmap(dest, smax, tmax, shift, rgb3_os, stainsrc);
Surf_StoreLightmap(dest, smax, tmax, shift, rgb3_os, stainsrc, lmwidth);
}
}
}
@ -1162,7 +1162,7 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest,
Surf_AddDynamicLights (surf);
}
Surf_StoreLightmap(dest, smax, tmax, shift, lum, stainsrc);
Surf_StoreLightmap(dest, smax, tmax, shift, lum, stainsrc, lmwidth);
}
}
@ -1226,8 +1226,8 @@ dynamic:
lm->modified = true;
smax = (fa->extents[0]>>4)+1;
tmax = (fa->extents[1]>>4)+1;
smax = (fa->extents[0]>>fa->lmshift)+1;
tmax = (fa->extents[1]>>fa->lmshift)+1;
theRect = &lm->rectchange;
if (fa->light_t[0] < theRect->t) {
@ -1267,17 +1267,17 @@ dynamic:
theRect->h = (fa->light_t[0]-theRect->t)+tmax;
luxbase = dlm->lightmaps;
luxbase += fa->light_t[0] * dlm->width * lightmap_bytes + fa->light_s[0] * lightmap_bytes;
luxbase += (fa->light_t[0] * dlm->width + fa->light_s[0]) * lightmap_bytes;
}
else
luxbase = NULL;
base = lm->lightmaps;
base += fa->light_t[0] * lm->width * lightmap_bytes + fa->light_s[0] * lightmap_bytes;
base += (fa->light_t[0] * lm->width + fa->light_s[0]) * lightmap_bytes;
stainbase = lm->stainmaps;
stainbase += (fa->light_t[0] * lm->width + fa->light_s[0]) * 3;
Surf_BuildLightMap (fa, base, luxbase, stainbase, lightmap_shift, r_ambient.value*255);
Surf_BuildLightMap (fa, base, luxbase, stainbase, lightmap_shift, r_ambient.value*255, lm->width);
RSpeedEnd(RSPEED_DYNAMIC);
}
@ -1312,8 +1312,8 @@ dynamic:
lm->modified = true;
smax = (fa->extents[0]>>4)+1;
tmax = (fa->extents[1]>>4)+1;
smax = (fa->extents[0]>>fa->lmshift)+1;
tmax = (fa->extents[1]>>fa->lmshift)+1;
theRect = &lm->rectchange;
if (fa->light_t[0] < theRect->t)
@ -1357,17 +1357,17 @@ dynamic:
theRect->h = (fa->light_t[0]-theRect->t)+tmax;
luxbase = dlm->lightmaps;
luxbase += fa->light_t[0] * dlm->width * lightmap_bytes + fa->light_s[0] * lightmap_bytes;
luxbase += (fa->light_t[0] * dlm->width + fa->light_s[0]) * lightmap_bytes;
}
else
luxbase = NULL;
base = lm->lightmaps;
base += fa->light_t[0] * lm->width * lightmap_bytes + fa->light_s[0] * lightmap_bytes;
base += (fa->light_t[0] * lm->width + fa->light_s[0]) * lightmap_bytes;
stainbase = lm->stainmaps;
stainbase += (fa->light_t[0] * lm->width + fa->light_s[0]) * 3;
Surf_BuildLightMap (fa, base, luxbase, stainbase, lightmap_shift, -1-ambient);
Surf_BuildLightMap (fa, base, luxbase, stainbase, lightmap_shift, -1-ambient, lm->width);
RSpeedEnd(RSPEED_DYNAMIC);
}
@ -2431,11 +2431,9 @@ void Surf_DeInit(void)
for (i = 0; i < numlightmaps; i++)
{
if (!lightmap[i])
break;
continue;
if (!lightmap[i]->external)
{
R_DestroyTexture(lightmap[i]->lightmap_texture);
}
Image_DestroyTexture(lightmap[i]->lightmap_texture);
BZ_Free(lightmap[i]);
lightmap[i] = NULL;
}
@ -2560,8 +2558,8 @@ int Surf_NewLightmaps(int count, int width, int height, qboolean deluxe)
lightmap[i]->rectchange.l = 0;
lightmap[i]->rectchange.t = 0;
lightmap[i]->rectchange.h = LMBLOCK_WIDTH;
lightmap[i]->rectchange.w = LMBLOCK_WIDTH;
lightmap[i]->rectchange.h = lightmap[i]->height;
lightmap[i]->rectchange.w = lightmap[i]->width;
lightmap[i]->lightmap_texture = r_nulltex;
@ -2817,7 +2815,7 @@ void Surf_BuildModelLightmaps (model_t *m)
lm->lightmaps + (surf->light_t[j] * lm->width + surf->light_s[j]) * lightmap_bytes,
deluxemap,
lm->stainmaps + (surf->light_t[j] * lm->width + surf->light_s[j]) * 3,
shift, r_ambient.value*255);
shift, r_ambient.value*255, lm->width);
}
}
}
@ -2840,20 +2838,27 @@ Groups surfaces into their respective batches (based on the lightmap number).
*/
void Surf_BuildLightmaps (void)
{
int i, j;
int i;
model_t *m;
extern model_t *mod_known;
extern int mod_numknown;
//make sure the lightstyle values are correct.
R_AnimateLight();
r_framecount = 1; // no dlightcache
for (i = 0; i < numlightmaps; i++)
while(numlightmaps > 0)
{
if (!lightmap[i])
break;
BZ_Free(lightmap[i]);
lightmap[i] = NULL;
numlightmaps--;
if (!lightmap[numlightmaps])
continue;
if (!lightmap[numlightmaps]->external)
Image_DestroyTexture(lightmap[numlightmaps]->lightmap_texture);
BZ_Free(lightmap[numlightmaps]);
lightmap[numlightmaps] = NULL;
}
Surf_LightmapMode();
@ -2862,7 +2867,6 @@ void Surf_BuildLightmaps (void)
r_oldviewleaf2 = NULL;
r_oldviewcluster = -1;
r_oldviewcluster2 = -1;
numlightmaps = 0;
//FIXME: unload stuff that's no longer relevant somehow.
for (i = 0; i < mod_numknown; i++)
@ -2887,9 +2891,6 @@ void Surf_NewMap (void)
char namebuf[MAX_QPATH];
extern cvar_t host_mapname;
int i;
for (i=0 ; i<256 ; i++)
d_lightstylevalue[i] = 264; // normal light value
memset (&r_worldentity, 0, sizeof(r_worldentity));
AngleVectors(r_worldentity.angles, r_worldentity.axis[0], r_worldentity.axis[1], r_worldentity.axis[2]);
@ -2922,6 +2923,7 @@ void Surf_NewMap (void)
if (!pe)
Cvar_ForceCallback(&r_particlesystem);
R_Clutter_Purge();
TRACE(("dbg: Surf_NewMap: clear particles\n"));
P_ClearParticles ();
TRACE(("dbg: Surf_NewMap: wiping them stains (getting the cloth out)\n"));

View File

@ -282,6 +282,9 @@ void R_LightArrays(const entity_t *entity, vecV_t *coords, vec4_t *colours, int
void R_DrawSkyChain (struct batch_s *batch); /*called from the backend, and calls back into it*/
void R_InitSky (struct texnums_s *ret, struct texture_s *mt, qbyte *src); /*generate q1 sky texnums*/
void R_Clutter_Emit(struct batch_s **batches);
void R_Clutter_Purge(void);
//r_surf.c
void Surf_NewMap (void);
void Surf_PreNewMap(void);
@ -300,9 +303,7 @@ void Surf_BuildModelLightmaps (struct model_s *m); //rebuild lightmaps for a sin
void Surf_RenderDynamicLightmaps (struct msurface_s *fa);
void Surf_RenderAmbientLightmaps (struct msurface_s *fa, int ambient);
int Surf_LightmapShift (struct model_s *model);
#ifndef LMBLOCK_WIDTH
#define LMBLOCK_WIDTH 128
#define LMBLOCK_HEIGHT 128
#define LMBLOCK_SIZE_MAX 1024 //single axis
typedef struct glRect_s {
unsigned short l,t,w,h;
} glRect_t;
@ -325,7 +326,7 @@ extern int numlightmaps;
//extern texid_t *deluxmap_textures;
extern int lightmap_bytes; // 1, 3, or 4
extern qboolean lightmap_bgra; /*true=bgra, false=rgba*/
#endif
void Surf_RebuildLightmap_Callback (struct cvar_s *var, char *oldvalue);
@ -370,6 +371,7 @@ enum imageflags
IF_TEXTYPESHIFT = 8, /*0=2d, 1=3d, 2-7=cubeface*/
IF_MIPCAP = 1<<10,
IF_PREMULTIPLYALPHA = 1<<12, //rgb *= alpha
IF_LOADNOW = 1<<25,
IF_NOPCX = 1<<26, /*block pcx format. meaning qw skins can use team colours and cropping*/
IF_TRYBUMP = 1<<27, /*attempt to load _bump if the specified _norm texture wasn't found*/
IF_RENDERTARGET = 1<<28, /*never loaded from disk, loading can't fail*/
@ -386,15 +388,14 @@ enum imageflags
image_t *Image_FindTexture (const char *identifier, const char *subpath, unsigned int flags);
image_t *Image_CreateTexture(const char *identifier, const char *subpath, unsigned int flags);
image_t *Image_GetTexture (const char *identifier, const char *subpath, unsigned int flags, void *fallbackdata, void *fallbackpalette, int fallbackwidth, int fallbackheight, uploadfmt_t fallbackfmt);
qboolean Image_UnloadTexture (image_t *tex); //true if it did something.
qboolean Image_UnloadTexture(image_t *tex); //true if it did something.
void Image_DestroyTexture (image_t *tex);
void Image_Upload (texid_t tex, uploadfmt_t fmt, void *data, void *palette, int width, int height, unsigned int flags);
void Image_Init(void);
void Image_Shutdown(void);
image_t *Image_LoadTexture (const char *identifier, int width, int height, uploadfmt_t fmt, void *data, unsigned int flags);
#define R_DestroyTexture(id) //FIXME
#ifdef D3D9QUAKE
void D3D9_UpdateFiltering (image_t *imagelist, int filtermip[3], int filterpic[3], int mipcap[2], float anis);
qboolean D3D9_LoadTextureMips (texid_t tex, struct pendingtextureinfo *mips);
@ -597,13 +598,13 @@ extern int rspeeds[RSPEED_MAX];
enum {
RQUANT_MSECS, //old r_speeds
RQUANT_PRIMITIVES,
RQUANT_PRIMITIVEINDICIES,
RQUANT_DRAWS,
RQUANT_ENTBATCHES,
RQUANT_WORLDBATCHES,
RQUANT_2DBATCHES,
RQUANT_SHADOWFACES,
RQUANT_SHADOWINDICIES,
RQUANT_SHADOWEDGES,
RQUANT_SHADOWSIDES,
RQUANT_LITFACES,

View File

@ -502,20 +502,16 @@ void R_InitTextures (void)
{
int x,y, m;
qbyte *dest;
static char r_notexture_mip_mem[(sizeof(texture_t) + 16*16+8*8+4*4+2*2)];
static char r_notexture_mip_mem[(sizeof(texture_t) + 16*16)];
// create a simple checkerboard texture for the default
r_notexture_mip = (texture_t*)r_notexture_mip_mem;
r_notexture_mip->width = r_notexture_mip->height = 16;
r_notexture_mip->offsets[0] = sizeof(texture_t);
r_notexture_mip->offsets[1] = r_notexture_mip->offsets[0] + 16*16;
r_notexture_mip->offsets[2] = r_notexture_mip->offsets[1] + 8*8;
r_notexture_mip->offsets[3] = r_notexture_mip->offsets[2] + 4*4;
for (m=0 ; m<4 ; m++)
for (m=0 ; m<1 ; m++)
{
dest = (qbyte *)r_notexture_mip + r_notexture_mip->offsets[m];
dest = (qbyte *)(r_notexture_mip+1);
for (y=0 ; y< (16>>m) ; y++)
for (x=0 ; x< (16>>m) ; x++)
{
@ -1511,33 +1507,32 @@ qboolean R_BuildRenderstate(rendererstate_t *newr, char *rendererstring)
// use desktop settings if set to 0 and not dedicated
if (newr->renderer && newr->renderer->rtype != QR_NONE)
{
int dbpp, dheight, dwidth, drate;
extern qboolean isPlugin;
if ((!newr->fullscreen && !isPlugin) || (!vid_desktopsettings.value && !isPlugin) || !Sys_GetDesktopParameters(&dwidth, &dheight, &dbpp, &drate))
{
// force default values for systems not supporting desktop parameters
dwidth = DEFAULT_WIDTH;
dheight = DEFAULT_HEIGHT;
dbpp = DEFAULT_BPP;
drate = 0;
}
if (vid_desktopsettings.value)
{
newr->width = dwidth;
newr->height = dheight;
newr->bpp = dbpp;
newr->rate = drate;
newr->width = 0;
newr->height = 0;
newr->bpp = 0;
newr->rate = 0;
}
else
if (newr->width <= 0 || newr->height <= 0 || newr->bpp <= 0)
{
if (newr->width <= 0 || newr->height <= 0)
int dbpp, dheight, dwidth, drate;
if (!newr->fullscreen || isPlugin || !Sys_GetDesktopParameters(&dwidth, &dheight, &dbpp, &drate))
{
newr->width = dwidth;
newr->height = dheight;
dwidth = DEFAULT_WIDTH;
dheight = DEFAULT_HEIGHT;
dbpp = DEFAULT_BPP;
drate = 0;
}
if (newr->width <= 0)
newr->width = dwidth;
if (newr->height <= 0)
newr->height = dheight;
if (newr->bpp <= 0)
newr->bpp = dbpp;
}
@ -1669,6 +1664,7 @@ void R_SetRenderer_f (void)
return;
}
Cvar_ApplyLatches(CVAR_RENDERERLATCH);
if (!R_BuildRenderstate(&newr, param))
{
Con_Printf("setrenderer: parameter not supported (%s)\n", param);

View File

@ -301,7 +301,9 @@ static void SCR_DrawField (float x, float y, int color, float width, int value)
char *Get_Q2ConfigString(int i)
{
if (i >= Q2CS_IMAGES && i < Q2CS_IMAGES + Q2MAX_IMAGES)
return cl.image_name [i-Q2CS_IMAGES];
return cl.image_name[i-Q2CS_IMAGES]?cl.image_name[i-Q2CS_IMAGES]:"";
if (i >= Q2CS_ITEMS && i < Q2CS_ITEMS + Q2MAX_ITEMS)
return cl.item_name[i-Q2CS_ITEMS]?cl.item_name[i-Q2CS_ITEMS]:"";
if (i == Q2CS_STATUSBAR)
return cl.q2statusbar;
@ -384,7 +386,7 @@ void Sbar_ExecuteLayoutString (char *s)
value = cl.q2frame.playerstate.stats[atoi(com_token)];
if (value >= Q2MAX_IMAGES || value < 0)
Host_EndGame ("Pic >= Q2MAX_IMAGES");
if (Get_Q2ConfigString(Q2CS_IMAGES+value))
if (*Get_Q2ConfigString(Q2CS_IMAGES+value))
{
// SCR_AddDirtyPoint (x, y);
// SCR_AddDirtyPoint (x+23, y+23);
@ -614,6 +616,55 @@ void Sbar_ExecuteLayoutString (char *s)
}
}
static void Sbar_Q2DrawInventory(void)
{
int keys[2];
char cmd[1024];
const char *boundkey;
unsigned int validlist[Q2MAX_ITEMS], rows, i, item, selected = cl.q2frame.playerstate.stats[Q2STAT_SELECTED_ITEM];
int first;
unsigned int maxrows = ((240-24*2-8*2)/8);
//draw background
float x = (vid.width - 256)/2;
float y = (vid.height - 240)/2;
R2D_ScalePic(x, y, 256, 240, Sbar_Q2CachePic("inventory"));
//move into the frame
x += 24;
y += 24;
//figure out which items we have
for (i = 0, rows = 0, first = -1; i < Q2MAX_ITEMS; i++)
{
if (!cl.inventory[i])
continue;
if (i <= selected)
first = rows;
validlist[rows++] = i;
}
first -= maxrows/2;
first = min(first, (signed)(rows-maxrows));
first = max(0, first);
rows = min(rows, first+maxrows);
//match q2, because why not.
Draw_FunString(x, y, "hotkey ### item");y+=8;
Draw_FunString(x, y, "------ --- ----");y+=8;
for (i = first; i < rows; i++)
{
item = validlist[i];
Q_snprintfz(cmd, sizeof(cmd), "use %s", Get_Q2ConfigString(Q2CS_ITEMS+item));
M_FindKeysForCommand(0, cmd, keys);
if (keys[0] == -1)
boundkey = ""; //we don't actually know which ones can be selected at all.
else
boundkey = Key_KeynumToString(keys[0]);
Q_snprintfz(cmd, sizeof(cmd), "%6s %3i %s", boundkey, cl.inventory[item], Get_Q2ConfigString(Q2CS_ITEMS+item));
Draw_FunStringWidth(x, y, cmd, 256-24*2+8, false, item != selected); y+=8;
}
}
#endif
/*
@ -2580,11 +2631,10 @@ void Sbar_Draw (playerview_t *pv)
R2D_ImageColours(1, 1, 1, 1);
if (*cl.q2statusbar)
Sbar_ExecuteLayoutString(cl.q2statusbar);
if (*cl.q2layout)
{
if (cl.q2frame.playerstate.stats[Q2STAT_LAYOUTS] & 1)
Sbar_ExecuteLayoutString(cl.q2layout);
}
if (*cl.q2layout && (cl.q2frame.playerstate.stats[Q2STAT_LAYOUTS] & 1))
Sbar_ExecuteLayoutString(cl.q2layout);
if (cl.q2frame.playerstate.stats[Q2STAT_LAYOUTS] & 2)
Sbar_Q2DrawInventory();
return;
}
#endif
@ -2669,9 +2719,12 @@ void Sbar_Draw (playerview_t *pv)
{
if (pv->cam_auto != CAM_TRACK)
{
Sbar_DrawPic (0, 0, 320, 24, sb_scorebar);
Sbar_DrawString (160-7*8,4, "SPECTATOR MODE");
Sbar_DrawString(160-14*8+4, 12, "Press [ATTACK] for AutoCamera");
if (hud_tracking_show.ival || cl_sbar.ival)
{ //this is annoying.
Sbar_DrawPic (0, 0, 320, 24, sb_scorebar);
Sbar_DrawString (160-7*8,4, "SPECTATOR MODE");
Sbar_DrawString(160-14*8+4, 12, "Press [ATTACK] for AutoCamera");
}
}
else
{

View File

@ -73,7 +73,7 @@ static void DSOUND_Restore(soundcardinfo_t *sc)
{
DWORD dwStatus;
dshandle_t *dh = sc->handle;
if (dh->pDSBuf->lpVtbl->GetStatus (dh->pDSBuf, &dwStatus) != DD_OK)
if (dh->pDSBuf->lpVtbl->GetStatus (dh->pDSBuf, &dwStatus) != ERROR_SUCCESS)
Con_Printf ("Couldn't get sound buffer status\n");
if (dwStatus & DSBSTATUS_BUFFERLOST)

View File

@ -2855,13 +2855,16 @@ int S_GetMixerTime(soundcardinfo_t *sc)
}
if (samplepos < sc->oldsamplepos)
{
int bias;
sc->buffers++; // buffer wrapped
if (sc->paintedtime > 0x40000000)
{ // time to chop things off to avoid 32 bit limits
sc->buffers = 0;
sc->paintedtime = fullsamples;
S_StopAllSounds (true);
{
//when things get too large, we push everything back to prevent overflows
bias = sc->paintedtime;
bias -= bias % fullsamples;
sc->paintedtime -= bias;
sc->buffers -= bias / fullsamples;
}
}
sc->oldsamplepos = samplepos;
@ -3298,7 +3301,6 @@ void S_RawAudio(int sourceid, qbyte *data, int speed, int samples, int channels,
c->pos = 0;
c->rate = 1<<PITCHSHIFT;
c->sfx = &s->sfx;
c->start = 0;
SND_Spatialize(si, c);
if (si->ChannelUpdate)

View File

@ -96,7 +96,6 @@ typedef struct
{
sfx_t *sfx; // sfx number
int vol[MAXSOUNDCHANNELS]; // volume, .8 fixed point.
int start; // start time in global paintsamples
int pos; // sample position in sfx, <0 means delay sound start (shifted up by 8)
int rate; // 24.8 fixed point rate scaling
int flags; // cf_ flags

View File

@ -47,6 +47,11 @@ void Sys_Vibrate(float count)
count = 0;
vibrateduration += count*10*sys_vibrate.value;
}
void Sys_Vibrate_f(void)
{
//input is in seconds, because this is quake. output is in ms.
vibrateduration += atof(Cmd_Argv(1)) * 1000;
}
JNIEXPORT jint JNICALL Java_com_fteqw_FTEDroidEngine_getvibrateduration(JNIEnv *env, jobject obj)
{
unsigned int dur = vibrateduration;
@ -393,6 +398,7 @@ void Sys_SendKeyEvents(void)
}
void Sys_Init(void)
{
Cmd_AddCommandD("sys_vibratetime", Sys_Vibrate_f, "Provides gamecode with a way to explicitly invoke the hardware vibrator in a simple way.");
Cvar_Register(&sys_vibrate, "android stuff");
Cvar_Register(&sys_osk, "android stuff");
Cvar_Register(&sys_keepscreenon, "android stuff");

View File

@ -228,7 +228,7 @@ int VARGS linuxlike_snprintf_vc8(char *buffer, int size, const char *format, ...
#include <ws2tcpip.h>
#endif
#endif
qboolean NET_StringToSockaddr2 (const char *s, int defaultport, struct sockaddr_qstorage *sadr, int *addrfamily, int *addrsize, size_t addrcount)
size_t NET_StringToSockaddr2 (const char *s, int defaultport, struct sockaddr_qstorage *sadr, int *addrfamily, int *addrsize, size_t addrcount)
{
struct addrinfo *addrinfo = NULL;
struct addrinfo *pos;
@ -248,11 +248,11 @@ qboolean NET_StringToSockaddr2 (const char *s, int defaultport, struct sockaddr_
pgetaddrinfo = (void*)GetProcAddress(lib, "getaddrinfo");
pfreeaddrinfo = (void*)GetProcAddress(lib, "freeaddrinfo");
if (!pgetaddrinfo || !pfreeaddrinfo)
return false;
return 0;
#endif
if (!(*s))
return false;
return 0;
memset (sadr, 0, sizeof(*sadr));
@ -298,7 +298,7 @@ qboolean NET_StringToSockaddr2 (const char *s, int defaultport, struct sockaddr_
}
if (error)
{
return false;
return 0;
}
((struct sockaddr*)sadr)->sa_family = 0;
for (pos = addrinfo; pos; pos = pos->ai_next)
@ -322,7 +322,7 @@ qboolean NET_StringToSockaddr2 (const char *s, int defaultport, struct sockaddr_
dblbreak:
pfreeaddrinfo (addrinfo);
if (!((struct sockaddr*)sadr)->sa_family) //none suitablefound
return false;
return 0;
if (addrfamily)
*addrfamily = ((struct sockaddr*)sadr)->sa_family;
@ -342,7 +342,7 @@ dblbreak:
*addrsize = sizeof(struct sockaddr_in6);
}
return true;
return 1;
}
char *COM_ParseType (const char *data, char *out, int outlen, com_tokentype_t *toktype)

View File

@ -290,8 +290,8 @@ int Sys_EnumerateFiles (const char *gpath, const char *match, int (QDECL *func)(
#else
#if defined(GLQUAKE) && defined(DEBUG)
#define PRINTGLARRAYS
#if defined(GLQUAKE)
//#define PRINTGLARRAYS
#endif
#if defined(_DEBUG) || defined(DEBUG)
@ -606,8 +606,8 @@ DWORD CrashExceptionHandler (qboolean iswatchdog, DWORD exceptionCode, LPEXCEPTI
}
#ifdef PRINTGLARRAYS
// if (!iswatchdog && qrenderer == QR_OPENGL)
// DumpGLState();
if (!iswatchdog && qrenderer == QR_OPENGL)
DumpGLState();
#endif
hKernel = LoadLibrary ("kernel32");

View File

@ -1330,10 +1330,11 @@ int QCLibEditor(pubprogfuncs_t *prfncs, const char *filename, int *line, int *st
if (stepasm)
{
*line = 0;
if (line)
*line = 0;
*statement = executionlinenum;
}
else
else if (line)
*line = executionlinenum;
return editorstep;
}

View File

@ -187,13 +187,13 @@ static qboolean Headless_BE_LightCullModel (vec3_t org, struct model_s *model)
{
return false;
}
static void Headless_BE_VBO_Begin (vbobctx_t *ctx, unsigned int maxsize)
static void Headless_BE_VBO_Begin (vbobctx_t *ctx, size_t maxsize)
{
}
static void Headless_BE_VBO_Data (vbobctx_t *ctx, void *data, unsigned int size, vboarray_t *varray)
static void Headless_BE_VBO_Data (vbobctx_t *ctx, void *data, size_t size, vboarray_t *varray)
{
}
static void Headless_BE_VBO_Finish (vbobctx_t *ctx, void *edata, unsigned int esize, vboarray_t *earray)
static void Headless_BE_VBO_Finish (vbobctx_t *ctx, void *edata, size_t esize, vboarray_t *earray)
{
}
static void Headless_BE_VBO_Destroy (vboarray_t *vearray)

View File

@ -392,6 +392,13 @@ void V_ParseDamage (playerview_t *pv)
for (i=0 ; i<3 ; i++)
from[i] = MSG_ReadCoord ();
pv->faceanimtime = cl.time + 0.2; // but sbar face into pain frame
#ifdef CSQC_DAT
if (CSQC_Parse_Damage(armor, blood, from))
return;
#endif
count = blood*0.5 + armor*0.5;
if (count < 10)
count = 10;
@ -404,8 +411,6 @@ void V_ParseDamage (playerview_t *pv)
if (v_damagecshift.value >= 0)
count *= v_damagecshift.value;
pv->faceanimtime = cl.time + 0.2; // but sbar face into pain frame
cl.cshifts[CSHIFT_DAMAGE].percent += 3*count;
if (cl.cshifts[CSHIFT_DAMAGE].percent < 0)
cl.cshifts[CSHIFT_DAMAGE].percent = 0;

View File

@ -657,7 +657,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
enum {
STAT_HEALTH = 0,
//STAT_FRAGS = 1,
STAT_WEAPON = 2,
STAT_WEAPONMODELI = 2,
STAT_AMMO = 3,
STAT_ARMOR = 4,
STAT_WEAPONFRAME = 5,

View File

@ -405,8 +405,12 @@ typedef struct q2miptex_s
#define IDBSPHEADER (('P'<<24)+('S'<<16)+('B'<<8)+'I')
// little-endian "IBSP"
#define Q2BSPVERSION 38
#define Q3BSPVERSION 46
#define BSPVERSION_Q2 38
#define BSPVERSION_Q2W 69
#define BSPVERSION_Q3 46
#define BSPVERSION_RTCW 47
#define BSPVERSION_RBSP 1 //also fbsp(just bigger internal lightmaps)
// upper design bounds
@ -488,7 +492,7 @@ typedef struct
{
int ident;
int version;
lump_t lumps[Q2HEADER_LUMPS];
lump_t lumps[50];
} q2dheader_t;
typedef struct

View File

@ -704,7 +704,7 @@ static float Alias_CalculateSkeletalNormals(galiasinfo_t *model)
if (bcmodnum != model->shares_bones)
{
galiasgroup_t *g;
galiasanimation_t *g;
galiasbone_t *bones = model->ofsbones;
bcmodnum = model->shares_bones;
if (model->baseframeofs)
@ -712,9 +712,9 @@ static float Alias_CalculateSkeletalNormals(galiasinfo_t *model)
else
{
//figure out the pose from frame0pose0
if (!model->groups)
if (!model->numanimations)
return 0;
g = model->groupofs;
g = model->ofsanimations;
if (g->numposes < 1)
return 0;
bonepose = Alias_ConvertBoneData(g->skeltype, g->boneofs, numbones, bones, SKEL_ABSOLUTE, absmatrix, absmatrixalt, MAX_BONES);
@ -1148,7 +1148,7 @@ static qboolean Alias_BuildSkelLerps(skellerps_t *lerps, struct framestateregion
unsigned int frame2;
float mlerp; //minor lerp, poses within a group.
int l = 0;
galiasgroup_t *g;
galiasanimation_t *g;
unsigned int b;
float totalweight = 0;
@ -1160,10 +1160,10 @@ static qboolean Alias_BuildSkelLerps(skellerps_t *lerps, struct framestateregion
{
unsigned int frame = fs->frame[b];
float time = fs->frametime[b];
if (frame >= inf->groups)
if (frame >= inf->numanimations)
continue;//frame = (unsigned)frame%inf->groups;
g = &inf->groupofs[frame];
g = &inf->ofsanimations[frame];
if (!g->numposes)
continue; //err...
@ -1238,7 +1238,7 @@ static int Alias_FindRawSkelData(galiasinfo_t *inf, framestate_t *fstate, skelle
if (endbone == cbone)
continue;
if (!inf->groups || !Alias_BuildSkelLerps(lerps, &fstate->g[bonegroup], inf->numbones, inf)) //if there's no animations in this model, use the base pose instead.
if (!inf->numanimations || !Alias_BuildSkelLerps(lerps, &fstate->g[bonegroup], inf->numbones, inf)) //if there's no animations in this model, use the base pose instead.
{
if (!inf->baseframeofs)
continue; //nope, not happening.
@ -1602,7 +1602,7 @@ void Alias_Shutdown(void)
qboolean Alias_GAliasBuildMesh(mesh_t *mesh, vbo_t **vbop, galiasinfo_t *inf, int surfnum, entity_t *e, qboolean usebones)
{
extern cvar_t r_nolerp;
galiasgroup_t *g1, *g2;
galiasanimation_t *g1, *g2;
float lerpcutoff;
int frame1;
@ -1611,7 +1611,7 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, vbo_t **vbop, galiasinfo_t *inf, in
float fg1time;
// float fg2time;
if (!inf->groups)
if (!inf->numanimations)
{
#ifdef SKELETALMODELS
if (inf->ofs_skel_xyz && !inf->ofs_skel_weight)
@ -1818,15 +1818,15 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, vbo_t **vbop, galiasinfo_t *inf, in
Con_DPrintf("Negative frame (%s)\n", e->model->name);
frame2 = frame1;
}
if (frame1 >= inf->groups)
if (frame1 >= inf->numanimations)
{
Con_DPrintf("Too high frame %i (%s)\n", frame1, e->model->name);
frame1 %= inf->groups;
frame1 %= inf->numanimations;
}
if (frame2 >= inf->groups)
if (frame2 >= inf->numanimations)
{
Con_DPrintf("Too high frame %i (%s)\n", frame2, e->model->name);
frame2 %= inf->groups;
frame2 %= inf->numanimations;
}
if (lerp <= 0)
@ -1834,8 +1834,8 @@ qboolean Alias_GAliasBuildMesh(mesh_t *mesh, vbo_t **vbop, galiasinfo_t *inf, in
else if (lerp >= 1)
frame1 = frame2;
g1 = &inf->groupofs[frame1];
g2 = &inf->groupofs[frame2];
g1 = &inf->ofsanimations[frame1];
g2 = &inf->ofsanimations[frame2];
if (g1 == g2) //lerping within group is only done if not changing group
{
@ -2102,7 +2102,7 @@ qboolean Mod_Trace_Trisoup(vecV_t *posedata, index_t *indexes, int numindexes, v
qboolean Mod_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3], vec3_t start, vec3_t end, vec3_t mins, vec3_t maxs, qboolean capsule, unsigned int contentsmask, trace_t *trace)
{
galiasinfo_t *mod = Mod_Extradata(model);
galiasgroup_t *group;
galiasanimation_t *group;
galiaspose_t *pose;
// float temp;
@ -2133,7 +2133,7 @@ qboolean Mod_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3],
{
indexes = mod->ofs_indexes;
#ifdef SKELETALMODELS
if (!mod->groups)
if (!mod->numanimations)
{
//certain models have no possibility of animation.
posedata = mod->ofs_skel_xyz;
@ -2141,7 +2141,7 @@ qboolean Mod_Trace(model_t *model, int forcehullnum, int frame, vec3_t axis[3],
else
#endif
{
group = mod->groupofs;
group = mod->ofsanimations;
pose = group[0].poseofs;
posedata = pose->ofsverts;
#ifdef SKELETALMODELS
@ -2237,7 +2237,7 @@ static void Mod_ClampModelSize(model_t *mod)
}
}
Con_DPrintf("Don't know what size to clamp \"%s\" to (size:%f).\n", mod->name, rad);
// Con_DPrintf("Don't know what size to clamp \"%s\" to (size:%f).\n", mod->name, rad);
#endif
}
@ -2371,7 +2371,7 @@ void Mod_GenerateMeshVBO(galiasinfo_t *galias)
{
#ifndef SERVERONLY
int i, p;
galiasgroup_t *group;
galiasanimation_t *group;
galiaspose_t *pose;
int vbospace = 0;
vbobctx_t vboctx;
@ -2380,7 +2380,7 @@ void Mod_GenerateMeshVBO(galiasinfo_t *galias)
if (!BE_VBO_Begin)
return;
group = galias->groupofs;
group = galias->ofsanimations;
//determine the amount of space we need for our vbos.
if (galias->ofs_st_array)
@ -2403,7 +2403,7 @@ void Mod_GenerateMeshVBO(galiasinfo_t *galias)
if (galias->ofs_skel_weight)
vbospace += sizeof(*galias->ofs_skel_weight) * galias->numverts;
#endif
for (i = 0; i < galias->groups; i++)
for (i = 0; i < galias->numanimations; i++)
{
if (group->poseofs)
vbospace += group[i].numposes * galias->numverts * (sizeof(vecV_t)+sizeof(vec3_t)*3);
@ -2430,7 +2430,7 @@ void Mod_GenerateMeshVBO(galiasinfo_t *galias)
BE_VBO_Data(&vboctx, galias->ofs_skel_weight, sizeof(*galias->ofs_skel_weight) * galias->numverts, &galias->vbo_skel_bweight);
#endif
for (i = 0; i < galias->groups; i++, group++)
for (i = 0; i < galias->numanimations; i++, group++)
{
pose = group->poseofs;
if (pose)
@ -2455,7 +2455,7 @@ void Mod_BuildTextureVectors(galiasinfo_t *galias)
{
#ifndef SERVERONLY
int i, p;
galiasgroup_t *group;
galiasanimation_t *group;
galiaspose_t *pose;
vecV_t *vc;
vec3_t *nv, *sv, *tv;
@ -2469,9 +2469,9 @@ void Mod_BuildTextureVectors(galiasinfo_t *galias)
idx = galias->ofs_indexes;
tc = galias->ofs_st_array;
group = galias->groupofs;
group = galias->ofsanimations;
for (i = 0; i < galias->groups; i++, group++)
for (i = 0; i < galias->numanimations; i++, group++)
{
pose = group->poseofs;
for (p = 0; p < group->numposes; p++, pose++)
@ -2723,7 +2723,7 @@ static void Alias_LoadPose(vecV_t *verts, vec3_t *normals, vec3_t *svec, vec3_t
static void *Alias_LoadFrameGroup (model_t *loadmodel, daliasframetype_t *pframetype, int *seamremaps, int mdltype)
{
galiaspose_t *pose;
galiasgroup_t *frame = galias->groupofs;
galiasanimation_t *frame = galias->ofsanimations;
dtrivertx_t *pinframe;
daliasframe_t *frameinfo;
int i, k;
@ -2755,7 +2755,7 @@ static void *Alias_LoadFrameGroup (model_t *loadmodel, daliasframetype_t *pframe
#endif
frame->poseofs = pose;
frame->numposes = 1;
galias->groups++;
galias->numanimations++;
if (mdltype == 1)
frame->name[0] = '\0';
@ -2798,7 +2798,7 @@ static void *Alias_LoadFrameGroup (model_t *loadmodel, daliasframetype_t *pframe
frame->poseofs = pose;
frame->loop = true;
galias->groups++;
galias->numanimations++;
intervals = (daliasinterval_t *)(ingroup+1);
sinter = LittleFloat(intervals->interval);
@ -3227,12 +3227,12 @@ qboolean QDECL Mod_LoadQ1Model (model_t *mod, void *buffer, size_t fsize)
#ifndef SERVERONLY
+ pq1inmodel->numskins*sizeof(galiasskin_t)
#endif
+ pq1inmodel->numframes*sizeof(galiasgroup_t);
+ pq1inmodel->numframes*sizeof(galiasanimation_t);
galias = ZG_Malloc(&mod->memgroup, size);
galias->groupofs = (galiasgroup_t*)(galias+1);
galias->ofsanimations = (galiasanimation_t*)(galias+1);
#ifndef SERVERONLY
galias->ofsskins = (galiasskin_t*)(galias->groupofs+pq1inmodel->numframes);
galias->ofsskins = (galiasskin_t*)(galias->ofsanimations+pq1inmodel->numframes);
#endif
galias->nextsurf = 0;
@ -3573,7 +3573,7 @@ qboolean QDECL Mod_LoadQ2Model (model_t *mod, void *buffer, size_t fsize)
vec3_t max;
galiaspose_t *pose;
galiasgroup_t *poutframe;
galiasanimation_t *poutframe;
dmd2aliasframe_t *pinframe;
int framesize;
vecV_t *verts;
@ -3617,12 +3617,12 @@ qboolean QDECL Mod_LoadQ2Model (model_t *mod, void *buffer, size_t fsize)
#ifndef SERVERONLY
+ LittleLong(pq2inmodel->num_skins)*sizeof(galiasskin_t)
#endif
+ LittleLong(pq2inmodel->num_frames)*sizeof(galiasgroup_t);
+ LittleLong(pq2inmodel->num_frames)*sizeof(galiasanimation_t);
galias = ZG_Malloc(&mod->memgroup, size);
galias->groupofs = (galiasgroup_t*)(galias+1);
galias->ofsanimations = (galiasanimation_t*)(galias+1);
#ifndef SERVERONLY
galias->ofsskins = (galiasskin_t*)(galias->groupofs + LittleLong(pq2inmodel->num_frames));
galias->ofsskins = (galiasskin_t*)(galias->ofsanimations + LittleLong(pq2inmodel->num_frames));
#endif
galias->nextsurf = 0;
@ -3677,7 +3677,7 @@ qboolean QDECL Mod_LoadQ2Model (model_t *mod, void *buffer, size_t fsize)
indremap[i] = i;
}
Con_DPrintf ( "%s: remapped %i verts to %i\n", mod->name, LittleLong(pq2inmodel->num_xyz), numverts );
// Con_DPrintf ( "%s: remapped %i verts to %i\n", mod->name, LittleLong(pq2inmodel->num_xyz), numverts );
galias->numverts = numverts;
@ -3705,7 +3705,7 @@ qboolean QDECL Mod_LoadQ2Model (model_t *mod, void *buffer, size_t fsize)
//frames
ClearBounds ( mod->mins, mod->maxs );
poutframe = galias->groupofs;
poutframe = galias->ofsanimations;
framesize = LittleLong (pq2inmodel->framesize);
for (i=0 ; i<LittleLong(pq2inmodel->num_frames) ; i++)
{
@ -3716,7 +3716,7 @@ qboolean QDECL Mod_LoadQ2Model (model_t *mod, void *buffer, size_t fsize)
pose = (galiaspose_t *)ZG_Malloc(&mod->memgroup, size);
poutframe->poseofs = pose;
poutframe->numposes = 1;
galias->groups++;
galias->numanimations++;
verts = (vecV_t *)(pose+1);
pose->ofsverts = verts;
@ -4109,7 +4109,7 @@ int Mod_TagNumForName(model_t *model, const char *name)
int Mod_FrameNumForName(model_t *model, const char *name)
{
galiasgroup_t *group;
galiasanimation_t *group;
galiasinfo_t *inf;
int i;
@ -4124,8 +4124,8 @@ int Mod_FrameNumForName(model_t *model, const char *name)
inf = Mod_Extradata(model);
group = inf->groupofs;
for (i = 0; i < inf->groups; i++, group++)
group = inf->ofsanimations;
for (i = 0; i < inf->numanimations; i++, group++)
{
if (!strcmp(group->name, name))
return i;
@ -4157,7 +4157,7 @@ int Mod_SkinNumForName(model_t *model, const char *name)
const char *Mod_FrameNameForNum(model_t *model, int num)
{
galiasgroup_t *group;
galiasanimation_t *group;
galiasinfo_t *inf;
if (!model)
@ -4167,15 +4167,15 @@ const char *Mod_FrameNameForNum(model_t *model, int num)
inf = Mod_Extradata(model);
if (num >= inf->groups)
if (num >= inf->numanimations)
return NULL;
group = inf->groupofs;
group = inf->ofsanimations;
return group[num].name;
}
qboolean Mod_FrameInfoForNum(model_t *model, int num, char **name, int *numframes, float *duration, qboolean *loop)
{
galiasgroup_t *group;
galiasanimation_t *group;
galiasinfo_t *inf;
if (!model)
@ -4185,9 +4185,9 @@ qboolean Mod_FrameInfoForNum(model_t *model, int num, char **name, int *numframe
inf = Mod_Extradata(model);
if (num >= inf->groups)
if (num >= inf->numanimations)
return false;
group = inf->groupofs;
group = inf->ofsanimations;
*name = group[num].name;
*numframes = group[num].numposes;
@ -4237,14 +4237,14 @@ const char *Mod_SkinNameForNum(model_t *model, int num)
float Mod_GetFrameDuration(model_t *model, int frameno)
{
galiasinfo_t *inf;
galiasgroup_t *group;
galiasanimation_t *group;
if (!model || model->type != mod_alias)
return 0;
inf = Mod_Extradata(model);
group = inf->groupofs;
if (frameno < 0 || frameno >= inf->groups)
group = inf->ofsanimations;
if (frameno < 0 || frameno >= inf->numanimations)
return 0;
group += frameno;
return group->numposes/group->rate;
@ -4350,7 +4350,7 @@ qboolean QDECL Mod_LoadQ3Model(model_t *mod, void *buffer, size_t fsize)
galiaspose_t *pose;
galiasinfo_t *parent, *root;
galiasgroup_t *group;
galiasanimation_t *group;
vecV_t *verts;
@ -4386,10 +4386,10 @@ qboolean QDECL Mod_LoadQ3Model(model_t *mod, void *buffer, size_t fsize)
{
if (LittleLong(surf->ident) != MD3_IDENT)
Con_Printf(CON_WARNING "Warning: md3 sub-surface doesn't match ident\n");
size = sizeof(galiasinfo_t) + sizeof(galiasgroup_t)*LittleLong(header->numFrames);
size = sizeof(galiasinfo_t) + sizeof(galiasanimation_t)*LittleLong(header->numFrames);
galias = ZG_Malloc(&mod->memgroup, size);
galias->groupofs = (galiasgroup_t*)(galias+1); //frame groups
galias->groups = LittleLong(header->numFrames);
galias->ofsanimations = (galiasanimation_t*)(galias+1); //frame groups
galias->numanimations = LittleLong(header->numFrames);
galias->numverts = LittleLong(surf->numVerts);
galias->numindexes = LittleLong(surf->numTriangles)*3;
galias->shares_verts = s;
@ -4422,7 +4422,7 @@ qboolean QDECL Mod_LoadQ3Model(model_t *mod, void *buffer, size_t fsize)
indexes[i*3+2] = LittleLong(intris[i].indexes[2]);
}
group = (galiasgroup_t *)(galias+1);
group = (galiasanimation_t *)(galias+1);
invert = (md3XyzNormal_t *)((qbyte*)surf + LittleLong(surf->ofsXyzNormals));
for (i = 0; i < LittleLong(surf->numFrames); i++)
{
@ -4662,7 +4662,7 @@ qboolean QDECL Mod_LoadZymoticModel(model_t *mod, void *buffer, size_t fsize)
int *vertbonecounts;
galiasgroup_t *grp;
galiasanimation_t *grp;
zymscene_t *inscene;
int *renderlist, count;
@ -4802,8 +4802,8 @@ qboolean QDECL Mod_LoadZymoticModel(model_t *mod, void *buffer, size_t fsize)
for (i = 0; i < header->numsurfaces; i++, surfname+=32)
{
root[i].groups = header->numscenes;
root[i].groupofs = grp;
root[i].numanimations = header->numscenes;
root[i].ofsanimations = grp;
Q_strncpyz(root[i].surfacename, surfname, sizeof(root[i].surfacename));
@ -4996,7 +4996,7 @@ qboolean QDECL Mod_LoadPSKModel(model_t *mod, void *buffer, size_t fsize)
skinframe_t *sframes;
#endif
galiasbone_t *bones;
galiasgroup_t *group;
galiasanimation_t *group;
float *animmatrix, *basematrix;
index_t *indexes;
float vrad;
@ -5401,7 +5401,7 @@ qboolean QDECL Mod_LoadPSKModel(model_t *mod, void *buffer, size_t fsize)
if (numgroups)
{
/*externally supplied listing of frames. ignore all framegroups in the model and use only the pose info*/
group = ZG_Malloc(&mod->memgroup, sizeof(galiasgroup_t)*numgroups + num_animkeys*sizeof(float)*12);
group = ZG_Malloc(&mod->memgroup, sizeof(galiasanimation_t)*numgroups + num_animkeys*sizeof(float)*12);
animmatrix = (float*)(group+numgroups);
for (j = 0; j < numgroups; j++)
{
@ -5433,7 +5433,7 @@ qboolean QDECL Mod_LoadPSKModel(model_t *mod, void *buffer, size_t fsize)
iframe = 0;
for (i = 0; i < num_animinfo; i++)
iframe += animinfo[i].numframes;
group = ZG_Malloc(&mod->memgroup, sizeof(galiasgroup_t)*iframe + num_animkeys*sizeof(float)*12);
group = ZG_Malloc(&mod->memgroup, sizeof(galiasanimation_t)*iframe + num_animkeys*sizeof(float)*12);
animmatrix = (float*)(group+iframe);
iframe = 0;
for (j = 0; j < num_animinfo; j++)
@ -5454,7 +5454,7 @@ qboolean QDECL Mod_LoadPSKModel(model_t *mod, void *buffer, size_t fsize)
else
{
/*keep each framegroup as a group*/
group = ZG_Malloc(&mod->memgroup, sizeof(galiasgroup_t)*num_animinfo + num_animkeys*sizeof(float)*12);
group = ZG_Malloc(&mod->memgroup, sizeof(galiasanimation_t)*num_animinfo + num_animkeys*sizeof(float)*12);
animmatrix = (float*)(group+num_animinfo);
for (i = 0; i < num_animinfo; i++)
{
@ -5483,7 +5483,7 @@ qboolean QDECL Mod_LoadPSKModel(model_t *mod, void *buffer, size_t fsize)
{
num_animinfo = 1;
/*build a base pose*/
group = ZG_Malloc(&mod->memgroup, sizeof(galiasgroup_t) + num_boneinfo*sizeof(float)*12);
group = ZG_Malloc(&mod->memgroup, sizeof(galiasanimation_t) + num_boneinfo*sizeof(float)*12);
animmatrix = basematrix;
group->boneofs = animmatrix;
group->numposes = 1;
@ -5515,8 +5515,8 @@ qboolean QDECL Mod_LoadPSKModel(model_t *mod, void *buffer, size_t fsize)
{
#endif
gmdl[i].groupofs = group;
gmdl[i].groups = num_animinfo;
gmdl[i].ofsanimations = group;
gmdl[i].numanimations = num_animinfo;
gmdl[i].baseframeofs = basematrix;
gmdl[i].numindexes = 0;
@ -5687,7 +5687,7 @@ qboolean QDECL Mod_LoadDarkPlacesModel(model_t *mod, void *buffer, size_t fsize)
dpmbone_t *inbone;
float *outposedata;
galiasgroup_t *outgroups;
galiasanimation_t *outgroups;
float *inposedata;
dpmframe_t *inframes;
@ -5822,7 +5822,7 @@ qboolean QDECL Mod_LoadDarkPlacesModel(model_t *mod, void *buffer, size_t fsize)
//throw away the flags.
}
outgroups = ZG_Malloc(&mod->memgroup, sizeof(galiasgroup_t)*header->num_frames + sizeof(float)*header->num_frames*header->num_bones*12);
outgroups = ZG_Malloc(&mod->memgroup, sizeof(galiasanimation_t)*header->num_frames + sizeof(float)*header->num_frames*header->num_bones*12);
outposedata = (float*)(outgroups+header->num_frames);
inframes = (dpmframe_t*)((char*)buffer + header->ofs_frames);
@ -5867,8 +5867,8 @@ qboolean QDECL Mod_LoadDarkPlacesModel(model_t *mod, void *buffer, size_t fsize)
m->ofsbones = outbone;
m->numbones = header->num_bones;
m->groups = header->num_frames;
m->groupofs = outgroups;
m->numanimations = header->num_frames;
m->ofsanimations = outgroups;
Q_strncpyz(m->surfacename, mesh->shadername, sizeof(m->surfacename));
@ -6086,7 +6086,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer, size_t fsize)
skinframe_t *skinframe=NULL;
int skinfiles;
#endif
galiasgroup_t *fgroup=NULL;
galiasanimation_t *fgroup=NULL;
galiasbone_t *bones = NULL;
index_t *idx;
float basepose[12 * MAX_BONES];
@ -6384,8 +6384,8 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer, size_t fsize)
gai[i].shares_bones = 0;
gai[i].numbones = h->num_joints;
gai[i].ofsbones = bones;
gai[i].groups = numgroups;
gai[i].groupofs = fgroup;
gai[i].numanimations = numgroups;
gai[i].ofsanimations = fgroup;
offset = LittleLong(mesh[i].first_vertex);
@ -6481,7 +6481,7 @@ galiasinfo_t *Mod_ParseIQMMeshModel(model_t *mod, char *buffer, size_t fsize)
return gai;
}
qboolean Mod_ParseIQMAnim(char *buffer, galiasinfo_t *prototype, void**poseofs, galiasgroup_t *gat)
qboolean Mod_ParseIQMAnim(char *buffer, galiasinfo_t *prototype, void**poseofs, galiasanimation_t *gat)
{
return false;
}
@ -6521,14 +6521,14 @@ qboolean QDECL Mod_LoadInterQuakeModel(model_t *mod, void *buffer, size_t fsize)
#ifdef MD5MODELS
qboolean Mod_ParseMD5Anim(model_t *mod, char *buffer, galiasinfo_t *prototype, void**poseofs, galiasgroup_t *gat)
qboolean Mod_ParseMD5Anim(model_t *mod, char *buffer, galiasinfo_t *prototype, void**poseofs, galiasanimation_t *gat)
{
#define MD5ERROR0PARAM(x) { Con_Printf(CON_ERROR x "\n"); return false; }
#define MD5ERROR1PARAM(x, y) { Con_Printf(CON_ERROR x "\n", y); return false; }
#define EXPECT(x) buffer = COM_Parse(buffer); if (strcmp(com_token, x)) MD5ERROR1PARAM("MD5ANIM: expected %s", x);
unsigned int i, j;
galiasgroup_t grp;
galiasanimation_t grp;
unsigned int parent;
unsigned int numframes;
@ -6742,7 +6742,7 @@ galiasinfo_t *Mod_ParseMD5MeshModel(model_t *mod, char *buffer, char *modname)
int i;
galiasbone_t *bones = NULL;
galiasgroup_t *pose = NULL;
galiasanimation_t *pose = NULL;
galiasinfo_t *inf, *root, *lastsurf;
float *posedata;
#ifndef SERVERONLY
@ -6774,10 +6774,10 @@ galiasinfo_t *Mod_ParseMD5MeshModel(model_t *mod, char *buffer, char *modname)
if (!strcmp(com_token, "numFrames"))
{
void *poseofs;
galiasgroup_t *grp = ZG_Malloc(&mod->memgroup, sizeof(galiasgroup_t));
galiasanimation_t *grp = ZG_Malloc(&mod->memgroup, sizeof(galiasanimation_t));
Mod_ParseMD5Anim(mod, filestart, root, &poseofs, grp);
root->groupofs = grp;
root->groups = 1;
root->ofsanimations = grp;
root->numanimations = 1;
grp->poseofs = poseofs;
return root;
}
@ -6814,7 +6814,7 @@ galiasinfo_t *Mod_ParseMD5MeshModel(model_t *mod, char *buffer, char *modname)
MD5ERROR0PARAM("MD5MESH: joints section before (or without) numjoints");
bones = ZG_Malloc(&mod->memgroup, sizeof(*bones) * numjoints);
pose = ZG_Malloc(&mod->memgroup, sizeof(galiasgroup_t));
pose = ZG_Malloc(&mod->memgroup, sizeof(galiasanimation_t));
posedata = ZG_Malloc(&mod->memgroup, sizeof(float)*12 * numjoints);
pose->skeltype = SKEL_ABSOLUTE;
pose->rate = 1;
@ -6901,8 +6901,8 @@ galiasinfo_t *Mod_ParseMD5MeshModel(model_t *mod, char *buffer, char *modname)
inf->ofsbones = bones;
inf->numbones = numjoints;
inf->groups = 1;
inf->groupofs = pose;
inf->numanimations = 1;
inf->ofsanimations = pose;
inf->baseframeofs = pose->boneofs;
#ifndef SERVERONLY
@ -7130,8 +7130,8 @@ qboolean QDECL Mod_LoadCompositeAnim(model_t *mod, void *buffer, size_t fsize)
char *file;
galiasinfo_t *root = NULL, *surf;
int numgroups = 0;
galiasgroup_t *grouplist = NULL;
galiasgroup_t *newgroup = NULL;
galiasanimation_t *grouplist = NULL;
galiasanimation_t *newgroup = NULL;
float **poseofs;
char com_token[8192];
@ -7159,12 +7159,12 @@ qboolean QDECL Mod_LoadCompositeAnim(model_t *mod, void *buffer, size_t fsize)
{
return false;
}
newgroup = root->groupofs;
newgroup = root->ofsanimations;
grouplist = BZ_Malloc(sizeof(galiasgroup_t)*(numgroups+root->groups));
memcpy(grouplist, newgroup, sizeof(galiasgroup_t)*(numgroups+root->groups));
poseofs = BZ_Malloc(sizeof(galiasgroup_t)*(numgroups+root->groups));
for (i = 0; i < root->groups; i++)
grouplist = BZ_Malloc(sizeof(galiasanimation_t)*(numgroups+root->numanimations));
memcpy(grouplist, newgroup, sizeof(galiasanimation_t)*(numgroups+root->numanimations));
poseofs = BZ_Malloc(sizeof(galiasanimation_t)*(numgroups+root->numanimations));
for (i = 0; i < root->numanimations; i++)
{
grouplist[numgroups] = newgroup[i];
poseofs[numgroups] = newgroup[i].boneofs;
@ -7185,7 +7185,7 @@ qboolean QDECL Mod_LoadCompositeAnim(model_t *mod, void *buffer, size_t fsize)
if (!strcmp(com_token, "group"))
{
grouplist = BZ_Realloc(grouplist, sizeof(galiasgroup_t)*(numgroups+1));
grouplist = BZ_Realloc(grouplist, sizeof(galiasanimation_t)*(numgroups+1));
poseofs = BZ_Realloc(poseofs, sizeof(*poseofs)*(numgroups+1));
buffer = COM_Parse(buffer);
file = COM_LoadTempMoreFile(com_token, NULL);
@ -7203,7 +7203,7 @@ qboolean QDECL Mod_LoadCompositeAnim(model_t *mod, void *buffer, size_t fsize)
}
else if (!strcmp(com_token, "clampgroup"))
{
grouplist = BZ_Realloc(grouplist, sizeof(galiasgroup_t)*(numgroups+1));
grouplist = BZ_Realloc(grouplist, sizeof(galiasanimation_t)*(numgroups+1));
poseofs = BZ_Realloc(poseofs, sizeof(*poseofs)*(numgroups+1));
buffer = COM_Parse(buffer);
file = COM_LoadTempMoreFile(com_token, NULL);
@ -7222,7 +7222,7 @@ qboolean QDECL Mod_LoadCompositeAnim(model_t *mod, void *buffer, size_t fsize)
}
else if (!strcmp(com_token, "frames"))
{
galiasgroup_t ng;
galiasanimation_t ng;
void *np;
buffer = COM_Parse(buffer);
@ -7236,7 +7236,7 @@ qboolean QDECL Mod_LoadCompositeAnim(model_t *mod, void *buffer, size_t fsize)
return false;
}
grouplist = BZ_Realloc(grouplist, sizeof(galiasgroup_t)*(numgroups+ng.numposes));
grouplist = BZ_Realloc(grouplist, sizeof(galiasanimation_t)*(numgroups+ng.numposes));
poseofs = BZ_Realloc(poseofs, sizeof(*poseofs)*(numgroups+ng.numposes));
//pull out each frame individually
@ -7262,11 +7262,11 @@ qboolean QDECL Mod_LoadCompositeAnim(model_t *mod, void *buffer, size_t fsize)
}
newgroup = grouplist;
grouplist = ZG_Malloc(&mod->memgroup, sizeof(galiasgroup_t)*numgroups);
grouplist = ZG_Malloc(&mod->memgroup, sizeof(galiasanimation_t)*numgroups);
for(surf = root;;)
{
surf->groupofs = grouplist;
surf->groups = numgroups;
surf->ofsanimations = grouplist;
surf->numanimations = numgroups;
if (!surf->nextsurf)
break;
surf = surf->nextsurf;

View File

@ -44,7 +44,7 @@ typedef struct
float rate;
galiaspose_t *poseofs;
char name[64];
} galiasgroup_t;
} galiasanimation_t;
typedef struct galiasbone_s galiasbone_t;
#ifdef SKELETALMODELS
@ -137,8 +137,8 @@ typedef struct galiasinfo_s
byte_vec4_t *ofs_rgbaub;
#endif
int groups;
galiasgroup_t *groupofs;
int numanimations;
galiasanimation_t *ofsanimations;
struct galiasinfo_s *nextsurf;

View File

@ -95,7 +95,7 @@ cvar_t com_protocolname = CVARAD("com_protocolname", NULL, "com_gamename", "The
cvar_t com_parseutf8 = CVARD("com_parseutf8", "0", "Interpret console messages/playernames/etc as UTF-8. Requires special fonts. -1=iso 8859-1. 0=quakeascii(chat uses high chars). 1=utf8, revert to ascii on decode errors. 2=utf8 ignoring errors"); //1 parse. 2 parse, but stop parsing that string if a char was malformed.
cvar_t com_parseezquake = CVARD("com_parseezquake", "0", "Treat chevron chars from configs as a per-character flag. You should use this only for compat with nquake's configs.");
cvar_t com_highlightcolor = CVARD("com_highlightcolor", STRINGIFY(COLOR_RED), "ANSI colour to be used for highlighted text, used when com_parseutf8 is active.");
cvar_t com_nogamedirnativecode = CVARFD("com_nogamedirnativecode", "1", CVAR_NOTFROMSERVER, FULLENGINENAME" blocks all downloads of files with a .dll or .so extension, however other engines (eg: ezquake and fodquake) do not - this omission can be used to trigger remote exploits in any engine (including "DISTRIBUTION") which is later run from the same gamedir.\nQuake2, Quake3(when debugging), and KTX typically run native gamecode from within gamedirs, so if you wish to run any of these games you will need to ensure this cvar is changed to 0, as well as ensure that you don't run unsafe clients.\n");
cvar_t com_nogamedirnativecode = CVARFD("com_nogamedirnativecode", "1", CVAR_NOTFROMSERVER, FULLENGINENAME" blocks all downloads of files with a .dll or .so extension, however other engines (eg: ezquake and fodquake) do not - this omission can be used to trigger delayed eremote exploits in any engine (including "DISTRIBUTION") which is later run from the same gamedir.\nQuake2, Quake3(when debugging), and KTX typically run native gamecode from within gamedirs, so if you wish to run any of these games you will need to ensure this cvar is changed to 0, as well as ensure that you don't run unsafe clients.\n");
cvar_t sys_platform = CVAR("sys_platform", PLATFORM);
qboolean com_modified; // set true if using non-id files

View File

@ -2329,7 +2329,7 @@ void COM_Gamedir (const char *dir)
FS_ChangeGame(man, cfg_reload_on_gamedir.ival);
}
#define QCFG "set allow_download_refpackages 0\n"
#define QCFG "set allow_download_refpackages 0\nmap_autoopenportals 1\n"
/*stuff that makes dp-only mods work a bit better*/
#define DPCOMPAT QCFG "set _cl_playermodel \"\"\n set dpcompat_set 1\nset dpcompat_corruptglobals 1\nset vid_pixelheight 1\n"
/*nexuiz/xonotic has a few quirks/annoyances...*/

View File

@ -52,10 +52,11 @@ extern cvar_t r_shadow_bumpscale_basetexture;
//these are in model.c (or gl_model.c)
qboolean Mod_LoadVertexes (model_t *loadmodel, qbyte *mod_base, lump_t *l);
qboolean Mod_LoadVertexNormals (model_t *loadmodel, qbyte *mod_base, lump_t *l);
qboolean Mod_LoadEdges (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean lm);
qboolean Mod_LoadMarksurfaces (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean lm);
qboolean Mod_LoadSurfedges (model_t *loadmodel, qbyte *mod_base, lump_t *l);
void Mod_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l);
void Mod_LoadLighting (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean interleaveddeluxe);
static 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, qboolean capsule, unsigned int contents, trace_t *trace);
@ -112,11 +113,11 @@ void CalcSurfaceExtents (model_t *mod, msurface_t *s)
for (i=0 ; i<2 ; i++)
{
bmins[i] = floor(mins[i]/16);
bmaxs[i] = ceil(maxs[i]/16);
bmins[i] = floor(mins[i]/(1<<s->lmshift));
bmaxs[i] = ceil(maxs[i]/(1<<s->lmshift));
s->texturemins[i] = bmins[i] * 16;
s->extents[i] = (bmaxs[i] - bmins[i]) * 16;
s->texturemins[i] = bmins[i] << s->lmshift;
s->extents[i] = (bmaxs[i] - bmins[i]) << s->lmshift;
// if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > 8176 ) //q2 uses 512. probably for skys.
// Con_Printf ("Bad surface extents (texture %s)\n", s->texinfo->texture->name);
@ -377,7 +378,7 @@ static q2mapsurface_t nullsurface;
cvar_t map_noareas = SCVAR("map_noareas", "0"); //1 for lack of mod support.
cvar_t map_noCurves = SCVARF("map_noCurves", "0", CVAR_CHEAT);
cvar_t map_autoopenportals = SCVAR("map_autoopenportals", "1"); //1 for lack of mod support.
cvar_t map_autoopenportals = CVARD("map_autoopenportals", "0", "When set to 1, force-opens all area portals. Normally these start closed and are opened by doors when they move, but this requires the gamecode to signal this."); //1 for lack of mod support.
cvar_t r_subdivisions = SCVAR("r_subdivisions", "2");
static int CM_NumInlineModels (model_t *model);
@ -1205,18 +1206,21 @@ qboolean CModQ2_LoadSurfaces (model_t *mod, qbyte *mod_base, lump_t *l)
return true;
}
#ifndef SERVERONLY
texture_t *Mod_LoadWall(model_t *loadmodel, char *mapname, char *walname, char *shadername, unsigned int imageflags)
texture_t *Mod_LoadWall(model_t *loadmodel, char *mapname, char *texname, char *shadername, unsigned int imageflags)
{
char name[MAX_QPATH];
q2miptex_t replacementwal;
texture_t *tex;
q2miptex_t *wal;
image_t *base;
wal = (void *)FS_LoadMallocFile (walname, NULL);
Q_snprintfz (name, sizeof(name), "textures/%s.wal", texname);
wal = (void *)FS_LoadMallocFile (texname, NULL);
if (!wal)
{
wal = &replacementwal;
memset(wal, 0, sizeof(*wal));
Q_strncpyz(wal->name, walname, sizeof(wal->name));
Q_strncpyz(wal->name, texname, sizeof(wal->name));
wal->width = 64;
wal->height = 64;
}
@ -1236,26 +1240,31 @@ texture_t *Mod_LoadWall(model_t *loadmodel, char *mapname, char *walname, char *
tex = ZG_Malloc(&loadmodel->memgroup, sizeof(texture_t));
tex->offsets[0] = wal->offsets[0];
tex->width = wal->width;
tex->height = wal->height;
if (wal->offsets[0])
tex->texnums.base = R_LoadReplacementTexture(wal->name, "bmodels", imageflags, (qbyte *)wal+wal->offsets[0], wal->width, wal->height, TF_SOLID8);
if (!tex->width || !tex->height || wal == &replacementwal)
{
imageflags |= IF_LOADNOW; //make sure the size is known BEFORE it returns.
if (wal->offsets[0])
base = R_LoadReplacementTexture(wal->name, "bmodels", imageflags, (qbyte *)wal+wal->offsets[0], wal->width, wal->height, TF_SOLID8);
else
base = R_LoadReplacementTexture(wal->name, "bmodels", imageflags, NULL, 0, 0, TF_INVALID);
}
else
tex->texnums.base = R_LoadReplacementTexture(wal->name, "bmodels", imageflags, NULL, 0, 0, TF_INVALID);
base = NULL;
if (wal == &replacementwal)
{
/* FIXME: worker needs the texture to have already been loaded. it can't sync with itself however.
if (tex->texnums.base->status == TEX_LOADING)
COM_WorkerPartialSync(tex, &tex->texnums.base->status, TEX_LOADING);
if (tex->texnums.base->status == TEX_LOADED)
if (base)
{
tex->width = tex->texnums.base->width;
tex->height = tex->texnums.base->height;
if (base->status == TEX_LOADED||base->status==TEX_LOADING)
{
tex->width = base->width;
tex->height = base->height;
}
}
*/
}
else
BZ_Free(wal);
@ -1270,7 +1279,6 @@ qboolean CModQ2_LoadTexInfo (model_t *mod, qbyte *mod_base, lump_t *l, char *map
int i, j, count;
char name[MAX_QPATH], *lwr;
char sname[MAX_QPATH];
float len1, len2;
int texcount;
in = (void *)(mod_base + l->fileofs);
@ -1288,6 +1296,18 @@ qboolean CModQ2_LoadTexInfo (model_t *mod, qbyte *mod_base, lump_t *l, char *map
mod->texinfo = out;
mod->numtexinfo = count;
if (in[0].nexttexinfo != -1)
{
for (i = 1; i < count && in[i].nexttexinfo == in[0].nexttexinfo; i++)
;
if (i == count)
{
Con_Printf("WARNING: invalid texture animations in \"%s\"\n", mod->name);
for (i = 0; i < count; i++)
in[i].nexttexinfo = -1;
}
}
for ( i=0 ; i<count ; i++, in++, out++)
{
out->flags = LittleLong (in->flags);
@ -1296,28 +1316,31 @@ qboolean CModQ2_LoadTexInfo (model_t *mod, qbyte *mod_base, lump_t *l, char *map
out->vecs[0][j] = LittleFloat (in->vecs[0][j]);
for (j=0 ; j<4 ; j++)
out->vecs[1][j] = LittleFloat (in->vecs[1][j]);
len1 = Length (out->vecs[0]);
len2 = Length (out->vecs[1]);
len1 = (len1 + len2)/2;
if (len1 < 0.32)
out->mipadjust = 4;
else if (len1 < 0.49)
out->mipadjust = 3;
else if (len1 < 0.99)
out->mipadjust = 2;
else
out->mipadjust = 1;
out->vecscale[0] = 1.0/Length (out->vecs[0]);
out->vecscale[1] = 1.0/Length (out->vecs[1]);
if (out->flags & TI_SKY)
snprintf(sname, sizeof(sname), "sky/%s%s", in->texture, in->nexttexinfo==-1?"":"#ANIMLOOP");
else if (out->flags & (TI_WARP|TI_TRANS33|TI_TRANS66))
snprintf(sname, sizeof(sname), "%s/%s#ALPHA=%s%s", ((out->flags&TI_WARP)?"warp":"trans"), in->texture, ((out->flags&TI_TRANS66)?"0.66":(out->flags&TI_TRANS33?"0.33":"1")), in->nexttexinfo==-1?"":"#ANIMLOOP");
Q_snprintfz(sname, sizeof(sname), "sky/%s", in->texture);
else if (out->flags & (TI_WARP|TI_FLOWING))
Q_snprintfz(sname, sizeof(sname), "warp/%s", in->texture);
else if (out->flags & (TI_TRANS33|TI_TRANS66))
Q_snprintfz(sname, sizeof(sname), "trans/%s", in->texture);
else
snprintf(sname, sizeof(sname), "wall/%s%s", in->texture, in->nexttexinfo==-1?"":"#ANIMLOOP");
Q_snprintfz(sname, sizeof(sname), "wall/%s", in->texture);
if (out->flags & TI_FLOWING)
Q_strncatz(sname, "#FLOW", sizeof(sname));
if (out->flags & TI_TRANS66)
Q_strncatz(sname, "#ALPHA=0.66", sizeof(sname));
else if (out->flags & TI_TRANS33)
Q_strncatz(sname, "#ALPHA=0.33", sizeof(sname));
else if (out->flags & (TI_WARP|TI_FLOWING))
Q_strncatz(sname, "#ALPHA=1", sizeof(sname));
if (in->nexttexinfo != -1) //used to ensure non-looping and looping don't conflict and get confused.
Q_strncatz(sname, "#ANIMLOOP", sizeof(sname));
//in q2, 'TEX_SPECIAL' is TI_LIGHT, and that conflicts.
out->flags &= ~TI_LIGHT;
if (out->flags & (TI_SKY|TI_TRANS33|TI_TRANS66|TI_WARP))
if (out->flags & (TI_SKY|TI_TRANS33|TI_TRANS66|TI_WARP|TI_FLOWING))
out->flags |= TEX_SPECIAL;
//compact the textures.
@ -1336,9 +1359,7 @@ qboolean CModQ2_LoadTexInfo (model_t *mod, qbyte *mod_base, lump_t *l, char *map
if (*lwr >= 'A' && *lwr <= 'Z')
*lwr = *lwr - 'A' + 'a';
}
snprintf (name, sizeof(name), "textures/%s.wal", in->texture);
out->texture = Mod_LoadWall (mod, mapname, name, sname, (out->flags&TEX_SPECIAL)?0:IF_NOALPHA);
out->texture = Mod_LoadWall (mod, mapname, in->texture, sname, (out->flags&TEX_SPECIAL)?0:IF_NOALPHA);
if (!out->texture || !out->texture->width || !out->texture->height)
{
out->texture = ZG_Malloc(&mod->memgroup, sizeof(texture_t) + 16*16+8*8+4*4+2*2);
@ -1352,10 +1373,10 @@ qboolean CModQ2_LoadTexInfo (model_t *mod, qbyte *mod_base, lump_t *l, char *map
mod->textures[texcount++] = out->texture;
}
if (in->nexttexinfo != -1)
{
Con_DPrintf("FIXME: %s should animate to %s\n", in->texture, (in->nexttexinfo+(q2texinfo_t *)(mod_base + l->fileofs))->texture);
}
// if (in->nexttexinfo != -1)
// {
// Con_DPrintf("FIXME: %s should animate to %s\n", in->texture, (in->nexttexinfo+(q2texinfo_t *)(mod_base + l->fileofs))->texture);
// }
}
in = (void *)(mod_base + l->fileofs);
@ -1372,7 +1393,7 @@ qboolean CModQ2_LoadTexInfo (model_t *mod, qbyte *mod_base, lump_t *l, char *map
continue;
out[i].texture->anim_total = 1;
for (tex = out[i].texture->anim_next ; tex && tex != out[i].texture ; tex=tex->anim_next)
for (tex = out[i].texture->anim_next ; tex && tex != out[i].texture && out[i].texture->anim_total < 100; tex=tex->anim_next)
out[i].texture->anim_total++;
}
@ -1430,14 +1451,13 @@ void CalcSurfaceExtents (msurface_t *s)
}
}*/
/*
=================
Mod_LoadFaces
=================
*/
#ifndef SERVERONLY
qboolean CModQ2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l)
qboolean CModQ2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l, qboolean lightofsisdouble)
{
dsface_t *in;
msurface_t *out;
@ -1445,6 +1465,18 @@ qboolean CModQ2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l)
int planenum, side;
int ti;
unsigned short lmshift, lmscale;
char buf[64];
lmscale = atoi(Mod_ParseWorldspawnKey(mod->entities, "lightmap_scale", buf, sizeof(buf)));
if (!lmscale)
lmshift = LMSHIFT_DEFAULT;
else
{
for(lmshift = 0; lmscale > 1; lmshift++)
lmscale >>= 1;
}
in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in))
{
@ -1460,17 +1492,17 @@ qboolean CModQ2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l)
for ( surfnum=0 ; surfnum<count ; surfnum++, in++, out++)
{
out->firstedge = LittleLong(in->firstedge);
out->numedges = LittleShort(in->numedges);
out->numedges = (unsigned short)LittleShort(in->numedges);
out->flags = 0;
planenum = LittleShort(in->planenum);
side = LittleShort(in->side);
planenum = (unsigned short)LittleShort(in->planenum);
side = (unsigned short)LittleShort(in->side);
if (side)
out->flags |= SURF_PLANEBACK;
out->plane = mod->planes + planenum;
ti = LittleShort (in->texinfo);
ti = (unsigned short)LittleShort (in->texinfo);
if (ti < 0 || ti >= mod->numtexinfo)
{
Con_Printf (CON_ERROR "MOD_LoadBmodel: bad texinfo number\n");
@ -1489,6 +1521,7 @@ qboolean CModQ2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l)
}
#endif
out->lmshift = lmshift;
CalcSurfaceExtents (mod, out);
// lighting info
@ -1498,6 +1531,8 @@ qboolean CModQ2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l)
i = LittleLong(in->lightofs);
if (i == -1)
out->samples = NULL;
else if (lightofsisdouble)
out->samples = mod->lightdata + (i/2);
else
out->samples = mod->lightdata + i;
@ -1577,8 +1612,8 @@ qboolean CModQ2_LoadNodes (model_t *mod, qbyte *mod_base, lump_t *l)
out->plane = mod->planes + LittleLong(in->planenum);
out->firstsurface = LittleShort (in->firstface);
out->numsurfaces = LittleShort (in->numfaces);
out->firstsurface = (unsigned short)LittleShort (in->firstface);
out->numsurfaces = (unsigned short)LittleShort (in->numfaces);
out->contents = -1; // differentiate from leafs
for (j=0 ; j<2 ; j++)
@ -1694,7 +1729,7 @@ qboolean CModQ2_LoadLeafs (model_t *mod, qbyte *mod_base, lump_t *l)
if (out->cluster == 0xffff)
out->cluster = -1;
out->area = LittleShort (in->area);
out->area = (unsigned short)LittleShort (in->area);
out->firstleafbrush = (unsigned short)LittleShort (in->firstleafbrush);
out->numleafbrushes = (unsigned short)LittleShort (in->numleafbrushes);
@ -1820,7 +1855,7 @@ CMod_LoadBrushSides
qboolean CModQ2_LoadBrushSides (model_t *mod, qbyte *mod_base, lump_t *l)
{
cminfo_t *prv = (cminfo_t*)mod->meshinfo;
int i, j;
unsigned int i, j;
q2cbrushside_t *out;
q2dbrushside_t *in;
int count;
@ -1846,15 +1881,13 @@ qboolean CModQ2_LoadBrushSides (model_t *mod, qbyte *mod_base, lump_t *l)
for ( i=0 ; i<count ; i++, in++, out++)
{
num = LittleShort (in->planenum);
num = (unsigned short)LittleShort (in->planenum);
out->plane = &mod->planes[num];
j = LittleShort (in->texinfo);
j = (unsigned short)LittleShort (in->texinfo);
if (j >= mod->numtexinfo)
{
Con_Printf (CON_ERROR "Bad brushside texinfo\n");
return false;
}
out->surface = &prv->surfaces[j];
out->surface = &nullsurface;
else
out->surface = &prv->surfaces[j];
}
return true;
@ -2840,8 +2873,9 @@ qboolean CModQ3_LoadRFaces (model_t *mod, qbyte *mod_base, lump_t *l)
out->styles[sty] = 255;
out->lightmaptexturenums[sty] = -1;
}
out->extents[0] = (LittleLong(in->lightmap_width)-1)<<4;
out->extents[1] = (LittleLong(in->lightmap_height)-1)<<4;
out->lmshift = LMSHIFT_DEFAULT;
out->extents[0] = (LittleLong(in->lightmap_width)-1)<<out->lmshift;
out->extents[1] = (LittleLong(in->lightmap_height)-1)<<out->lmshift;
out->samples=NULL;
if (mod->lightmaps.count < out->lightmaptexturenums[0]+1)
@ -2952,8 +2986,9 @@ qboolean CModRBSP_LoadRFaces (model_t *mod, qbyte *mod_base, lump_t *l)
if (mod->lightmaps.count < out->lightmaptexturenums[j]+1)
mod->lightmaps.count = out->lightmaptexturenums[j]+1;
}
out->extents[0] = (LittleLong(in->lightmap_width)-1)<<4;
out->extents[1] = (LittleLong(in->lightmap_height)-1)<<4;
out->lmshift = LMSHIFT_DEFAULT;
out->extents[0] = (LittleLong(in->lightmap_width)-1)<<out->lmshift;
out->extents[1] = (LittleLong(in->lightmap_height)-1)<<out->lmshift;
out->samples=NULL;
fv = LittleLong(in->firstvertex);
@ -3858,35 +3893,35 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
header.ident = LittleLong(header.ident);
header.version = LittleLong(header.version);
if (header.ident == (('F'<<0)+('B'<<8)+('S'<<16)+('P'<<24)))
{
mod->lightmaps.width = 512;
mod->lightmaps.height = 512;
}
else
{
mod->lightmaps.width = 128;
mod->lightmaps.height = 128;
}
ClearBounds(mod->mins, mod->maxs);
switch(header.version)
{
default:
Con_Printf (CON_ERROR "Quake 2 or Quake 3 based BSP with unknown header (%s: %i should be %i or %i)\n"
, mod->name, header.version, Q2BSPVERSION, Q3BSPVERSION);
, mod->name, header.version, BSPVERSION_Q2, BSPVERSION_Q3);
return NULL;
break;
#ifdef Q3BSPS
case 1: //rbsp/fbsp
case Q3BSPVERSION+1: //rtcw
case Q3BSPVERSION:
case BSPVERSION_RBSP: //rbsp/fbsp
case BSPVERSION_RTCW: //rtcw
case BSPVERSION_Q3:
if (header.ident == (('F'<<0)+('B'<<8)+('S'<<16)+('P'<<24)))
{
mod->lightmaps.width = 512;
mod->lightmaps.height = 512;
}
else
{
mod->lightmaps.width = 128;
mod->lightmaps.height = 128;
}
prv->mapisq3 = true;
mod->fromgame = fg_quake3;
for (i=0 ; i<Q3LUMPS_TOTAL ; i++)
{
if (i == RBSPLUMP_LIGHTINDEXES && header.version != 1)
if (i == RBSPLUMP_LIGHTINDEXES && header.version != BSPVERSION_RBSP)
{
header.lumps[i].filelen = 0;
header.lumps[i].fileofs = 0;
@ -3938,7 +3973,7 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
prv->mapisq3 = true;
noerrors = noerrors && CModQ3_LoadShaders (mod, mod_base, &header.lumps[Q3LUMP_SHADERS]);
noerrors = noerrors && CModQ3_LoadPlanes (mod, mod_base, &header.lumps[Q3LUMP_PLANES]);
if (header.version == 1)
if (header.version == BSPVERSION_RBSP)
{
noerrors = noerrors && CModRBSP_LoadBrushSides (mod, mod_base, &header.lumps[Q3LUMP_BRUSHSIDES]);
noerrors = noerrors && CModRBSP_LoadVertexes (mod, mod_base, &header.lumps[Q3LUMP_DRAWVERTS]);
@ -3957,19 +3992,19 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
#ifndef SERVERONLY
if (qrenderer != QR_NONE)
{
if (header.version == 1)
if (header.version == BSPVERSION_RBSP)
noerrors = noerrors && CModRBSP_LoadLightgrid (mod, mod_base, &header.lumps[Q3LUMP_LIGHTGRID], &header.lumps[RBSPLUMP_LIGHTINDEXES]);
else
noerrors = noerrors && CModQ3_LoadLightgrid (mod, mod_base, &header.lumps[Q3LUMP_LIGHTGRID]);
noerrors = noerrors && CModQ3_LoadIndexes (mod, mod_base, &header.lumps[Q3LUMP_DRAWINDEXES]);
if (header.version != Q3BSPVERSION+1)
if (header.version != BSPVERSION_RTCW)
noerrors = noerrors && CModQ3_LoadFogs (mod, mod_base, &header.lumps[Q3LUMP_FOGS]);
else
mod->numfogs = 0;
facedata = (void *)(mod_base + header.lumps[Q3LUMP_SURFACES].fileofs);
if (header.version == 1)
if (header.version == BSPVERSION_RBSP)
{
noerrors = noerrors && CModRBSP_LoadRFaces (mod, mod_base, &header.lumps[Q3LUMP_SURFACES]);
buildmeshes = CModRBSP_BuildSurfMesh;
@ -4067,7 +4102,11 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
BZ_Free(map_faces);
break;
#endif
case Q2BSPVERSION:
case BSPVERSION_Q2:
case BSPVERSION_Q2W:
mod->lightmaps.width = LMBLOCK_SIZE_MAX;
mod->lightmaps.height = LMBLOCK_SIZE_MAX;
prv->mapisq3 = false;
mod->engineflags |= MDLF_NEEDOVERBRIGHT;
for (i=0 ; i<Q2HEADER_LUMPS ; i++)
@ -4075,8 +4114,13 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
header.lumps[i].filelen = LittleLong (header.lumps[i].filelen);
header.lumps[i].fileofs = LittleLong (header.lumps[i].fileofs);
}
Q1BSPX_Setup(mod, mod_base, filelen, header.lumps, Q2HEADER_LUMPS);
if (header.version == BSPVERSION_Q2W)
{
header.lumps[i].filelen = LittleLong (header.lumps[i].filelen);
header.lumps[i].fileofs = LittleLong (header.lumps[i].fileofs);
i++;
}
Q1BSPX_Setup(mod, mod_base, filelen, header.lumps, i);
#ifndef SERVERONLY
if (CM_GetQ2Palette())
@ -4115,25 +4159,23 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
mod->funcs.NativeContents = CM_NativeContents;
break;
#if defined(GLQUAKE) || defined(D3DQUAKE)
case QR_DIRECT3D9:
case QR_DIRECT3D11:
case QR_OPENGL:
#ifndef SERVERONLY
default:
// load into heap
#ifndef SERVERONLY
noerrors = noerrors && Mod_LoadVertexes (mod, mod_base, &header.lumps[Q2LUMP_VERTEXES]);
if (header.version == BSPVERSION_Q2W)
/*noerrors = noerrors &&*/ Mod_LoadVertexNormals(mod, mod_base, &header.lumps[19]);
noerrors = noerrors && Mod_LoadEdges (mod, mod_base, &header.lumps[Q2LUMP_EDGES], false);
noerrors = noerrors && Mod_LoadSurfedges (mod, mod_base, &header.lumps[Q2LUMP_SURFEDGES]);
if (noerrors)
Mod_LoadLighting (mod, mod_base, &header.lumps[Q2LUMP_LIGHTING]);
#endif
Mod_LoadLighting (mod, mod_base, &header.lumps[Q2LUMP_LIGHTING], header.version == BSPVERSION_Q2W);
noerrors = noerrors && CModQ2_LoadSurfaces (mod, mod_base, &header.lumps[Q2LUMP_TEXINFO]);
noerrors = noerrors && CModQ2_LoadPlanes (mod, mod_base, &header.lumps[Q2LUMP_PLANES]);
#ifndef SERVERONLY
noerrors = noerrors && CModQ2_LoadTexInfo (mod, mod_base, &header.lumps[Q2LUMP_TEXINFO], loadname);
noerrors = noerrors && CModQ2_LoadFaces (mod, mod_base, &header.lumps[Q2LUMP_FACES]);
if (noerrors)
CMod_LoadEntityString (mod, mod_base, &header.lumps[Q2LUMP_ENTITIES]);
noerrors = noerrors && CModQ2_LoadFaces (mod, mod_base, &header.lumps[Q2LUMP_FACES], header.version == BSPVERSION_Q2W);
noerrors = noerrors && Mod_LoadMarksurfaces (mod, mod_base, &header.lumps[Q2LUMP_LEAFFACES], false);
#endif
noerrors = noerrors && CModQ2_LoadVisibility (mod, mod_base, &header.lumps[Q2LUMP_VISIBILITY]);
noerrors = noerrors && CModQ2_LoadBrushSides (mod, mod_base, &header.lumps[Q2LUMP_BRUSHSIDES]);
noerrors = noerrors && CModQ2_LoadBrushes (mod, mod_base, &header.lumps[Q2LUMP_BRUSHES]);
@ -4143,8 +4185,6 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
noerrors = noerrors && CModQ2_LoadSubmodels (mod, mod_base, &header.lumps[Q2LUMP_MODELS]);
noerrors = noerrors && CModQ2_LoadAreas (mod, mod_base, &header.lumps[Q2LUMP_AREAS]);
noerrors = noerrors && CModQ2_LoadAreaPortals (mod, mod_base, &header.lumps[Q2LUMP_AREAPORTALS]);
if (noerrors)
CMod_LoadEntityString (mod, mod_base, &header.lumps[Q2LUMP_ENTITIES]);
if (!noerrors)
{
@ -4165,9 +4205,6 @@ static cmodel_t *CM_LoadMap (model_t *mod, qbyte *filein, size_t filelen, qboole
mod->funcs.NativeContents = CM_NativeContents;
break;
#endif
default:
return NULL;
Sys_Error("Bad internal renderer on q2 map load\n");
}
}
@ -6148,7 +6185,8 @@ static void FloodArea_r (cminfo_t *prv, q2carea_t *area, int floodnum)
{
if (area->floodnum == floodnum)
return;
Host_Error ("FloodArea_r: reflooded");
Con_Printf ("FloodArea_r: reflooded\n");
return;
}
area->floodnum = floodnum;

View File

@ -786,7 +786,6 @@ static void ICE_Destroy(struct icestate_s *con)
void ICE_Tick(void)
{
struct icestate_s *con;
unsigned int curtime = Sys_Milliseconds();
for (con = icelist; con; con = con->next)
{
@ -809,6 +808,8 @@ void ICE_Tick(void)
case ICEM_ICE:
if (con->state == ICE_CONNECTING || con->state == ICE_FAILED)
{
unsigned int curtime = Sys_Milliseconds();
if (con->stunretry < curtime && con->pubstunserver.type != NA_INVALID)
{
ICE_ToStunServer(con);

View File

@ -51,28 +51,28 @@ typedef struct plugin_s {
int blockcloses;
void *inputptr;
unsigned int inputbytes;
size_t inputbytes;
int tick;
int executestring;
qintptr_t tick;
qintptr_t executestring;
#ifndef SERVERONLY
int consolelink;
int consolelinkmouseover;
int conexecutecommand;
int menufunction;
int sbarlevel[3]; //0 - main sbar, 1 - supplementry sbar sections (make sure these can be switched off), 2 - overlays (scoreboard). menus kill all.
int reschange;
qintptr_t consolelink;
qintptr_t consolelinkmouseover;
qintptr_t conexecutecommand;
qintptr_t menufunction;
qintptr_t sbarlevel[3]; //0 - main sbar, 1 - supplementry sbar sections (make sure these can be switched off), 2 - overlays (scoreboard). menus kill all.
qintptr_t reschange;
//protocol-in-a-plugin
int connectionlessclientpacket;
qintptr_t connectionlessclientpacket;
//called to discolour console input text if they spelt it wrongly
int spellcheckmaskedtext;
qintptr_t spellcheckmaskedtext;
#endif
int svmsgfunction;
int chatmsgfunction;
int centerprintfunction;
int shutdown;
qintptr_t svmsgfunction;
qintptr_t chatmsgfunction;
qintptr_t centerprintfunction;
qintptr_t shutdown;
struct plugin_s *next;
} plugin_t;
@ -372,7 +372,7 @@ static qintptr_t VARGS Plug_Sys_CloseLibrary(void *offset, quintptr_t mask, cons
static qintptr_t VARGS Plug_ExportToEngine(void *offset, quintptr_t mask, const qintptr_t *arg)
{
char *name = (char*)VM_POINTER(arg[0]);
unsigned int functionid = VM_LONG(arg[1]);
quintptr_t functionid = arg[1];
if (!strcmp(name, "Tick")) //void(int realtime)
currentplug->tick = functionid;

View File

@ -665,7 +665,10 @@ enum lightfield_e
lfield_ambientscale=10,
lfield_diffusescale=11,
lfield_specularscale=12,
lfield_rotation=13
lfield_rotation=13,
lfield_dietime=14,
lfield_rgbdecay=15,
lfield_radiusdecay=16
};
enum csqc_input_event
{

View File

@ -1079,10 +1079,10 @@ void Q1BSP_MarkLights (dlight_t *light, int bit, mnode_t *node)
// clamp center of light to corner and check brightness
l = DotProduct (impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0];
s = l+0.5;if (s < 0) s = 0;else if (s > surf->extents[0]) s = surf->extents[0];
s = l - s;
s = (l - s)*surf->texinfo->vecscale[0];
l = DotProduct (impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3] - surf->texturemins[1];
t = l+0.5;if (t < 0) t = 0;else if (t > surf->extents[1]) t = surf->extents[1];
t = l - t;
t = (l - t)*surf->texinfo->vecscale[1];
// compare to minimum light
if ((s*s+t*t+dist*dist) < maxdist)
{
@ -1116,7 +1116,9 @@ struct fragmentdecal_s
int numplanes;
vec_t radius;
int numtris;
void (*callback)(void *ctx, vec3_t *fte_restrict points, size_t numpoints, shader_t *shader);
void *ctx;
};
typedef struct fragmentdecal_s fragmentdecal_t;
@ -1289,7 +1291,7 @@ static void Fragment_ClipTriangle(fragmentdecal_t *dec, float *a, float *b, floa
#else
void Fragment_ClipPoly(fragmentdecal_t *dec, int numverts, float *inverts)
void Fragment_ClipPoly(fragmentdecal_t *dec, int numverts, float *inverts, shader_t *surfshader)
{
//emit the triangle, and clip it's fragments.
int p;
@ -1298,18 +1300,17 @@ void Fragment_ClipPoly(fragmentdecal_t *dec, int numverts, float *inverts)
float *cverts;
int flip;
vec3_t d1, d2, n;
size_t numtris;
if (numverts > MAXFRAGMENTTRIS)
return;
if (dec->numtris == MAXFRAGMENTTRIS)
return; //don't bother
VectorSubtract(inverts+C*1, inverts+C*0, d1);
VectorSubtract(inverts+C*2, inverts+C*0, d2);
CrossProduct(d1, d2, n);
VectorNormalizeFast(n);
if (DotProduct(n, dec->normal) > 0.1)
return; //faces too far way from the normal
// if (DotProduct(n, dec->normal) > 0.1)
// return; //faces too far way from the normal
//clip to the first plane specially, so we don't have extra copys
numverts = Fragment_ClipPolyToPlane(inverts, verts, numverts, dec->planenorm[0], dec->planedist[0]);
@ -1335,24 +1336,29 @@ void Fragment_ClipPoly(fragmentdecal_t *dec, int numverts, float *inverts)
//decompose the resultant polygon into triangles.
while(numverts>2)
numtris = 0;
while(numverts-->2)
{
if (dec->numtris == MAXFRAGMENTTRIS)
return;
if (numtris == MAXFRAGMENTTRIS)
{
dec->callback(dec->ctx, decalfragmentverts, numtris, NULL);
numtris = 0;
break;
}
numverts--;
VectorCopy((cverts+C*0), decalfragmentverts[dec->numtris*3+0]);
VectorCopy((cverts+C*(numverts-1)), decalfragmentverts[dec->numtris*3+1]);
VectorCopy((cverts+C*numverts), decalfragmentverts[dec->numtris*3+2]);
dec->numtris++;
VectorCopy((cverts+C*0), decalfragmentverts[numtris*3+0]);
VectorCopy((cverts+C*(numverts-1)), decalfragmentverts[numtris*3+1]);
VectorCopy((cverts+C*numverts), decalfragmentverts[numtris*3+2]);
numtris++;
}
if (numtris)
dec->callback(dec->ctx, decalfragmentverts, numtris, surfshader);
}
#endif
//this could be inlined, but I'm lazy.
static void Fragment_Mesh (fragmentdecal_t *dec, mesh_t *mesh)
static void Fragment_Mesh (fragmentdecal_t *dec, mesh_t *mesh, shader_t *surfshader)
{
int i;
@ -1361,7 +1367,7 @@ static void Fragment_Mesh (fragmentdecal_t *dec, mesh_t *mesh)
/*if its a triangle fan/poly/quad then we can just submit the entire thing without generating extra fragments*/
if (mesh->istrifan)
{
Fragment_ClipPoly(dec, mesh->numvertexes, mesh->xyz_array[0]);
Fragment_ClipPoly(dec, mesh->numvertexes, mesh->xyz_array[0], surfshader);
return;
}
@ -1370,13 +1376,10 @@ static void Fragment_Mesh (fragmentdecal_t *dec, mesh_t *mesh)
/*otherwise it goes in and out in weird places*/
for (i = 0; i < mesh->numindexes; i+=3)
{
if (dec->numtris == MAXFRAGMENTTRIS)
break;
VectorCopy(mesh->xyz_array[mesh->indexes[i+0]], verts[0]);
VectorCopy(mesh->xyz_array[mesh->indexes[i+1]], verts[1]);
VectorCopy(mesh->xyz_array[mesh->indexes[i+2]], verts[2]);
Fragment_ClipPoly(dec, 3, verts[0]);
Fragment_ClipPoly(dec, 3, verts[0], surfshader);
}
}
@ -1418,7 +1421,7 @@ static void Q1BSP_ClipDecalToNodes (model_t *mod, fragmentdecal_t *dec, mnode_t
if (DotProduct(surf->plane->normal, dec->normal) > -0.5)
continue;
}
Fragment_Mesh(dec, surf->mesh);
Fragment_Mesh(dec, surf->mesh, surf->texinfo->texture->shader);
}
Q1BSP_ClipDecalToNodes (mod, dec, node->children[0]);
@ -1454,7 +1457,7 @@ static void Q3BSP_ClipDecalToNodes (fragmentdecal_t *dec, mnode_t *node)
continue;
surf->shadowframe = sh_shadowframe;
Fragment_Mesh(dec, surf->mesh);
Fragment_Mesh(dec, surf->mesh, surf->texinfo->texture->shader);
}
return;
}
@ -1477,8 +1480,7 @@ static void Q3BSP_ClipDecalToNodes (fragmentdecal_t *dec, mnode_t *node)
}
#endif
//returns trisoup within a 3d volume.
int Q1BSP_ClipDecal(model_t *mod, vec3_t center, vec3_t normal, vec3_t tangent1, vec3_t tangent2, float size, float **out)
void Mod_ClipDecal(struct model_s *mod, vec3_t center, vec3_t normal, vec3_t tangent1, vec3_t tangent2, float size, void (*callback)(void *ctx, vec3_t *fte_restrict points, size_t numpoints, shader_t *shader), void *ctx)
{ //quad marks a full, independant quad
int p;
float r;
@ -1486,8 +1488,9 @@ int Q1BSP_ClipDecal(model_t *mod, vec3_t center, vec3_t normal, vec3_t tangent1,
VectorCopy(center, dec.center);
VectorCopy(normal, dec.normal);
dec.numtris = 0;
dec.radius = 0;
dec.callback = callback;
dec.ctx = ctx;
VectorCopy(tangent1, dec.planenorm[0]);
VectorNegate(tangent1, dec.planenorm[1]);
@ -1522,9 +1525,6 @@ int Q1BSP_ClipDecal(model_t *mod, vec3_t center, vec3_t normal, vec3_t tangent1,
if (cl.worldmodel && cl.worldmodel->terrain)
Terrain_ClipDecal(&dec, center, dec.radius, mod);
#endif
*out = (float *)decalfragmentverts;
return dec.numtris;
}
#endif

View File

@ -2611,8 +2611,8 @@ static void BE_UploadLightmaps(qboolean force)
{
lightmap[i]->rectchange.l = 0;
lightmap[i]->rectchange.t = 0;
lightmap[i]->rectchange.w = LMBLOCK_WIDTH;
lightmap[i]->rectchange.h = LMBLOCK_HEIGHT;
lightmap[i]->rectchange.w = lightmap[i]->width;
lightmap[i]->rectchange.h = lightmap[i]->height;
lightmap[i]->modified = true;
}
@ -3486,13 +3486,13 @@ void D3D11BE_DrawWorld (qboolean drawworld, qbyte *vis)
BE_RotateForEntity(&r_worldentity, NULL);
}
void D3D11BE_VBO_Begin(vbobctx_t *ctx, unsigned int maxsize)
void D3D11BE_VBO_Begin(vbobctx_t *ctx, size_t maxsize)
{
}
void D3D11BE_VBO_Data(vbobctx_t *ctx, void *data, unsigned int size, vboarray_t *varray)
void D3D11BE_VBO_Data(vbobctx_t *ctx, void *data, size_t size, vboarray_t *varray)
{
}
void D3D11BE_VBO_Finish(vbobctx_t *ctx, void *edata, unsigned int esize, vboarray_t *earray)
void D3D11BE_VBO_Finish(vbobctx_t *ctx, void *edata, size_t esize, vboarray_t *earray)
{
}
void D3D11BE_VBO_Destroy(vboarray_t *vearray)

View File

@ -7,6 +7,8 @@
#include <d3d11.h>
extern ID3D11Device *pD3DDev11;
//#include <D3D11Shader.h> //apparently requires win8 sdk, despite being a win7 thing.
#ifndef IID_ID3DBlob
//microsoft can be such a pain sometimes.
@ -47,6 +49,67 @@ extern ID3D11Device *pD3DDev11;
#define ID3DBlob_Release(b) b->lpVtbl->Release(b)
#define ID3DBlob_GetBufferSize(b) b->lpVtbl->GetBufferSize(b)
#define D3D11_SHADER_VARIABLE_DESC void
typedef unsigned int D3D_SHADER_INPUT_TYPE;
typedef unsigned int D3D_RESOURCE_RETURN_TYPE;
typedef unsigned int D3D_SRV_DIMENSION;
typedef struct D3D11_SHADER_INPUT_BIND_DESC {
LPCSTR Name;
D3D_SHADER_INPUT_TYPE Type;
UINT BindPoint;
UINT BindCount;
UINT uFlags;
D3D_RESOURCE_RETURN_TYPE ReturnType;
D3D_SRV_DIMENSION Dimension;
UINT NumSamples;
} D3D11_SHADER_INPUT_BIND_DESC;
#define ID3D11ShaderReflectionConstantBuffer void
#define ID3D11ShaderReflectionType void
#define INTERFACE ID3D11ShaderReflectionVariable
DECLARE_INTERFACE(ID3D11ShaderReflectionVariable)
{
STDMETHOD(GetDesc)(THIS_ D3D11_SHADER_VARIABLE_DESC *pDesc) PURE;
STDMETHOD_(ID3D11ShaderReflectionType*, GetType)(THIS) PURE;
STDMETHOD_(ID3D11ShaderReflectionConstantBuffer*, GetBuffer)(THIS) PURE;
STDMETHOD_(UINT, GetInterfaceSlot)(THIS_ UINT uArrayIndex) PURE;
};
#undef INTERFACE
#define D3D11_SHADER_DESC void
#define D3D11_SIGNATURE_PARAMETER_DESC void
const GUID IID_ID3D11ShaderReflection = {0x8d536ca1, 0x0cca, 0x4956, 0xa8, 0x37, 0x78, 0x69, 0x63, 0x75, 0x55, 0x84};
#define INTERFACE ID3D11ShaderReflection
DECLARE_INTERFACE_(INTERFACE, IUnknown)
{
STDMETHOD(QueryInterface)(THIS_ REFIID iid, LPVOID *ppv) PURE;
STDMETHOD_(ULONG, AddRef)(THIS) PURE;
STDMETHOD_(ULONG, Release)(THIS) PURE;
STDMETHOD(GetDesc)(THIS_ D3D11_SHADER_DESC *pDesc) PURE;
STDMETHOD_(ID3D11ShaderReflectionConstantBuffer*, GetConstantBufferByIndex)(THIS_ UINT Index) PURE;
STDMETHOD_(ID3D11ShaderReflectionConstantBuffer*, GetConstantBufferByName)(THIS_ LPCSTR Name) PURE;
STDMETHOD(GetResourceBindingDesc)(THIS_ UINT ResourceIndex,
D3D11_SHADER_INPUT_BIND_DESC *pDesc) PURE;
STDMETHOD(GetInputParameterDesc)(THIS_ UINT ParameterIndex,
D3D11_SIGNATURE_PARAMETER_DESC *pDesc) PURE;
STDMETHOD(GetOutputParameterDesc)(THIS_ UINT ParameterIndex,
D3D11_SIGNATURE_PARAMETER_DESC *pDesc) PURE;
STDMETHOD(GetPatchConstantParameterDesc)(THIS_ UINT ParameterIndex,
D3D11_SIGNATURE_PARAMETER_DESC *pDesc) PURE;
STDMETHOD_(ID3D11ShaderReflectionVariable*, GetVariableByName)(THIS_ LPCSTR Name) PURE;
STDMETHOD(GetResourceBindingDescByName)(THIS_ LPCSTR Name, D3D11_SHADER_INPUT_BIND_DESC *pDesc) PURE;
//more stuff
};
#define ID3D11ShaderReflection_GetVariableByName(r,v) r->lpVtbl->GetVariableByName(r,v)
#define ID3D11ShaderReflection_Release IUnknown_Release
#undef INTERFACE
HRESULT (WINAPI *pD3DCompile) (
LPCVOID pSrcData,
SIZE_T SrcDataSize,
@ -60,6 +123,14 @@ HRESULT (WINAPI *pD3DCompile) (
ID3DBlob **ppCode,
ID3DBlob **ppErrorMsgs
);
HRESULT (WINAPI *pD3DReflect)(
LPCVOID pSrcData,
SIZE_T SrcDataSize,
REFIID pInterface,
void **ppReflector
);
static dllhandle_t *shaderlib;
@ -327,6 +398,29 @@ static qboolean D3D11Shader_LoadBlob(program_t *prog, const char *name, unsigned
qboolean D3D11Shader_CreateProgram (program_t *prog, const char *name, unsigned int permu, int ver, const char **precompilerconstants, const char *vert, const char *hull, const char *domain, const char *frag, qboolean silenterrors, vfsfile_t *blobfile)
{
static const char *defaultsamplers[] =
{
"s_diffuse",
"s_normalmap",
"s_specular",
"s_upper",
"s_lower",
"s_fullbright",
"s_paletted",
"s_shadowmap",
"s_projectionmap",
"s_lightmap",
"s_deluxmap"
#if MAXRLIGHTMAPS > 1
,"s_lightmap1"
,"s_lightmap2"
,"s_lightmap3"
,"s_deluxmap1"
,"s_deluxmap2"
,"s_deluxmap3"
#endif
};
char *vsformat;
char *hsformat = NULL;
char *dsformat = NULL;
@ -334,6 +428,8 @@ qboolean D3D11Shader_CreateProgram (program_t *prog, const char *name, unsigned
D3D_SHADER_MACRO defines[64];
ID3DBlob *vcode = NULL, *hcode = NULL, *dcode = NULL, *fcode = NULL, *errors = NULL;
qboolean success = false;
ID3D11ShaderReflection *freflect;
int i;
if (d3dfeaturelevel >= D3D_FEATURE_LEVEL_11_0) //and 11.1
{
@ -508,6 +604,35 @@ qboolean D3D11Shader_CreateProgram (program_t *prog, const char *name, unsigned
VFS_WRITE(blobfile, ID3DBlob_GetBufferPointer(fcode), sz);
}
if (fcode)
{
pD3DReflect(ID3DBlob_GetBufferPointer(fcode), ID3DBlob_GetBufferSize(fcode), &IID_ID3D11ShaderReflection, (void**)&freflect);
if (freflect)
{
int tmu;
D3D11_SHADER_INPUT_BIND_DESC bdesc = {0};
for (i = prog->numsamplers; i < 8; i++)
{
if (SUCCEEDED(freflect->lpVtbl->GetResourceBindingDescByName(freflect, va("t_%i", i), &bdesc)))
prog->numsamplers = i+1;
}
tmu = prog->numsamplers;
for (i = 0; i < sizeof(defaultsamplers)/sizeof(defaultsamplers[0]); i++)
{
// if (prog->defaulttextures & (1u<<i))
// continue;
if (SUCCEEDED(freflect->lpVtbl->GetResourceBindingDescByName(freflect, va("t%s", defaultsamplers[i]+1), &bdesc)))
prog->defaulttextures |= (1u<<i);
if (!(prog->defaulttextures & (1u<<i)))
continue;
tmu++;
}
ID3D11ShaderReflection_Release(freflect);
}
}
if (vcode)
ID3DBlob_Release(vcode);
if (hcode)
@ -527,11 +652,13 @@ qboolean D3D11Shader_Init(unsigned int flevel)
dllfunction_t funcsold[] =
{
{(void**)&pD3DCompile, "D3DCompileFromMemory"},
{(void**)&pD3DReflect, "D3DReflect"},
{NULL,NULL}
};
dllfunction_t funcsnew[] =
{
{(void**)&pD3DCompile, "D3DCompile"},
{(void**)&pD3DReflect, "D3DReflect"},
{NULL,NULL}
};

View File

@ -3216,13 +3216,13 @@ void D3D9BE_DrawWorld (qboolean drawworld, qbyte *vis)
BE_RotateForEntity(&r_worldentity, NULL);
}
void D3D9BE_VBO_Begin(vbobctx_t *ctx, unsigned int maxsize)
void D3D9BE_VBO_Begin(vbobctx_t *ctx, size_t maxsize)
{
}
void D3D9BE_VBO_Data(vbobctx_t *ctx, void *data, unsigned int size, vboarray_t *varray)
void D3D9BE_VBO_Data(vbobctx_t *ctx, void *data, size_t size, vboarray_t *varray)
{
}
void D3D9BE_VBO_Finish(vbobctx_t *ctx, void *edata, unsigned int esize, vboarray_t *earray)
void D3D9BE_VBO_Finish(vbobctx_t *ctx, void *edata, size_t esize, vboarray_t *earray)
{
}
void D3D9BE_VBO_Destroy(vboarray_t *vearray)

View File

@ -213,19 +213,19 @@ static qboolean D3D9Shader_CreateProgram (program_t *prog, const char *sname, un
return success;
}
static int D3D9Shader_FindUniform_(LPD3DXCONSTANTTABLE ct, char *name)
static int D3D9Shader_FindUniform_(LPD3DXCONSTANTTABLE ct, const char *name)
{
if (ct)
{
UINT dc = 1;
D3DXCONSTANT_DESC d;
if (!FAILED(ct->lpVtbl->GetConstantDesc(ct, name, &d, &dc)))
if (!FAILED(ct->lpVtbl->GetConstantDesc(ct, (void*)name, &d, &dc)))
return d.RegisterIndex;
}
return -1;
}
static int D3D9Shader_FindUniform(union programhandle_u *h, int type, char *name)
static int D3D9Shader_FindUniform(union programhandle_u *h, int type, const char *name)
{
int offs;
@ -253,6 +253,29 @@ static void D3D9Shader_ProgAutoFields(program_t *prog, char **cvarnames, int *cv
char tmpname[128];
cvar_t *cvar;
static const char *defaultsamplers[] =
{
"s_diffuse",
"s_normalmap",
"s_specular",
"s_upper",
"s_lower",
"s_fullbright",
"s_paletted",
"s_shadowmap",
"s_projectionmap",
"s_lightmap",
"s_deluxmap"
#if MAXRLIGHTMAPS > 1
,"s_lightmap1"
,"s_lightmap2"
,"s_lightmap3"
,"s_deluxmap1"
,"s_deluxmap2"
,"s_deluxmap3"
#endif
};
prog->numparams = 0;
prog->nofixedcompat = true;
@ -314,6 +337,51 @@ static void D3D9Shader_ProgAutoFields(program_t *prog, char **cvarnames, int *cv
int v[4] = {i};
IDirect3DDevice9_SetPixelShader(pD3DDev9, prog->permu[p].handle.hlsl.frag);
IDirect3DDevice9_SetPixelShaderConstantI(pD3DDev9, 0, v, 1);
if (prog->numsamplers < i+1)
prog->numsamplers = i+1;
}
}
for (i = 0; i < sizeof(defaultsamplers)/sizeof(defaultsamplers[0]); i++)
{
//figure out which ones are needed.
if (prog->defaulttextures & (1u<<i))
continue; //don't spam
uniformloc = D3D9Shader_FindUniform(&prog->permu[p].handle, 2, defaultsamplers[i]);
if (uniformloc != -1)
prog->defaulttextures |= (1u<<i);
}
}
//multiple lightmaps is kinda hacky. if any are set, all must be.
if (prog->defaulttextures & ((1u<<11) | (1u<<12) | (1u<<13)))
prog->defaulttextures |=((1u<<11) | (1u<<12) | (1u<<13));
if (prog->defaulttextures & ((1u<<14) | (1u<<15) | (1u<<16)))
prog->defaulttextures |=((1u<<14) | (1u<<15) | (1u<<16));
if (prog->defaulttextures)
{
unsigned int sampnum;
/*set default texture uniforms*/
for (p = 0; p < PERMUTATIONS; p++)
{
if (!prog->permu[p].handle.glsl.handle)
continue;
sampnum = prog->numsamplers;
for (i = 0; i < sizeof(defaultsamplers)/sizeof(defaultsamplers[0]); i++)
{
if (prog->defaulttextures & (1u<<i))
{
uniformloc = D3D9Shader_FindUniform(&prog->permu[p].handle, 2, defaultsamplers[i]);
if (uniformloc != -1)
{
int v[4] = {sampnum};
IDirect3DDevice9_SetPixelShader(pD3DDev9, prog->permu[p].handle.hlsl.frag);
IDirect3DDevice9_SetPixelShaderConstantI(pD3DDev9, 0, v, 1);
}
sampnum++;
}
}
}
}

View File

@ -736,6 +736,8 @@ static qboolean D3D9_VID_Init(rendererstate_t *info, unsigned char *palette)
static void (D3D9_VID_DeInit) (void)
{
Image_Shutdown();
/*final shutdown, kill the video stuff*/
if (pD3DDev9)
{
@ -854,6 +856,12 @@ void D3D9_Set2D (void)
vport.MinZ = 0;
vport.MaxZ = 1;
IDirect3DDevice9_SetViewport(pD3DDev9, &vport);
vid.fbvwidth = vid.width;
vid.fbvheight = vid.height;
vid.fbpwidth = vid.pixelwidth;
vid.fbpheight = vid.pixelheight;
}
static int d3d9error(int i)

View File

@ -990,6 +990,7 @@ static qboolean D3D11_VID_Init(rendererstate_t *info, unsigned char *palette)
static void (D3D11_VID_DeInit) (void)
{
D3D11BE_Shutdown();
Image_Shutdown();
/*we cannot shut down cleanly while in fullscreen, supposedly*/
if(d3dswapchain)
@ -1150,8 +1151,14 @@ void D3D11_Set2D (void)
vport.MinDepth = 0;
vport.MaxDepth = 1;
ID3D11DeviceContext_RSSetViewports(d3ddevctx, 1, &vport);
ID3D11DeviceContext_RSSetViewports(d3ddevctx, 1, &vport);
D3D11BE_SetupViewCBuffer();
vid.fbvwidth = vid.width;
vid.fbvheight = vid.height;
vid.fbpwidth = vid.pixelwidth;
vid.fbpheight = vid.pixelheight;
}
static void (D3D11_SCR_UpdateScreen) (void)

View File

@ -22030,6 +22030,10 @@
/>
</FileConfiguration>
</File>
<File
RelativePath="..\gl\gl_shadow.c"
>
</File>
<File
RelativePath="..\gl\gl_warp.c"
>
@ -24320,10 +24324,6 @@
/>
</FileConfiguration>
</File>
<File
RelativePath="..\gl\gl_shadow.c"
>
</File>
<File
RelativePath="..\gl\gl_vidcommon.c"
>

View File

@ -90,7 +90,7 @@ void Mod_WipeSkin(skinid_t id)
for (i = 0; i < sk->nummappings; i++)
{
if (sk->mappings[i].needsfree)
R_DestroyTexture(sk->mappings[i].texnums.base);
Image_UnloadTexture(sk->mappings[i].texnums.base);
R_UnloadShader(sk->mappings[i].shader);
}
Z_Free(registeredskins[id]);
@ -2492,6 +2492,8 @@ void BE_GenModelBatches(batch_t **batches, const dlight_t *dl, unsigned int bemo
Terr_DrawTerrainModel(batches, &r_worldentity);
#endif
R_Clutter_Emit(batches);
if (!r_drawentities.ival)
return;

View File

@ -30,6 +30,12 @@ extern cvar_t gl_ati_truform;
extern cvar_t r_wireframe;
extern cvar_t r_refract_fbo;
extern texid_t missing_texture;
extern texid_t missing_texture_gloss;
extern texid_t missing_texture_normal;
extern texid_t scenepp_postproc_cube;
extern texid_t r_whiteimage;
static const char LIGHTPASS_SHADER[] = "\
{\n\
program rtlight%s\n\
@ -894,7 +900,8 @@ void GLBE_RenderShadowBuffer(unsigned int numverts, int vbo, vecV_t *verts, unsi
GL_SelectEBO(ibo);
qglDrawRangeElements(GL_TRIANGLES, 0, numverts, numindicies, GL_INDEX_TYPE, indicies);
}
RQuantAdd(RQUANT_SHADOWFACES, numindicies/3);
RQuantAdd(RQUANT_DRAWS, 1);
RQuantAdd(RQUANT_SHADOWINDICIES, numindicies);
shaderstate.dummyvbo.indicies.gl.vbo = 0;
shaderstate.sourcevbo = NULL;
}
@ -924,22 +931,18 @@ void GL_CullFace(unsigned int sflags)
}
}
void R_FetchTopColour(int *retred, int *retgreen, int *retblue)
void R_FetchPlayerColour(unsigned int cv, vec3_t rgb)
{
int i;
unsigned int cv = shaderstate.curentity->topcolour;
if (cv >= 16)
{
*retred = (((cv&0xff0000)>>16)**((unsigned char*)&d_8to24rgbtable[15]+0))>>8;
*retgreen = (((cv&0x00ff00)>>8)**((unsigned char*)&d_8to24rgbtable[15]+1))>>8;
*retblue = (((cv&0x0000ff)>>0)**((unsigned char*)&d_8to24rgbtable[15]+2))>>8;
rgb[0] = (((cv&0xff0000)>>16)**((unsigned char*)&d_8to24rgbtable[15]+0)) / (256.0*256);
rgb[1] = (((cv&0x00ff00)>>8)**((unsigned char*)&d_8to24rgbtable[15]+1)) / (256.0*256);
rgb[2] = (((cv&0x0000ff)>>0)**((unsigned char*)&d_8to24rgbtable[15]+2)) / (256.0*256);
return;
}
if (cv >= 0)
i = cv;
else
i = TOP_RANGE>>4;
i = cv;
if (i >= 8)
{
i<<=4;
@ -950,45 +953,9 @@ void R_FetchTopColour(int *retred, int *retgreen, int *retblue)
i+=15;
}
i*=3;
*retred = host_basepal[i+0];
*retgreen = host_basepal[i+1];
*retblue = host_basepal[i+2];
/* if (!gammaworks)
{
*retred = gammatable[*retred];
*retgreen = gammatable[*retgreen];
*retblue = gammatable[*retblue];
}*/
}
void R_FetchBottomColour(int *retred, int *retgreen, int *retblue)
{
int i;
unsigned int cv = shaderstate.curentity->bottomcolour;
if (cv >= 16)
{
*retred = (((cv&0xff0000)>>16)**((unsigned char*)&d_8to24rgbtable[15]+0))>>8;
*retgreen = (((cv&0x00ff00)>>8)**((unsigned char*)&d_8to24rgbtable[15]+1))>>8;
*retblue = (((cv&0x0000ff)>>0)**((unsigned char*)&d_8to24rgbtable[15]+2))>>8;
return;
}
if (cv >= 0)
i = cv;
else
i = BOTTOM_RANGE>>4;
if (i >= 8)
{
i<<=4;
}
else
{
i<<=4;
i+=15;
}
i*=3;
*retred = host_basepal[i+0];
*retgreen = host_basepal[i+1];
*retblue = host_basepal[i+2];
rgb[0] = host_basepal[i+0] / 255.0;
rgb[1] = host_basepal[i+1] / 255.0;
rgb[2] = host_basepal[i+2] / 255.0;
/* if (!gammaworks)
{
*retred = gammatable[*retred];
@ -1126,11 +1093,7 @@ static void T_Gen_CurrentRender(int tmu)
static void Shader_BindTextureForPass(int tmu, const shaderpass_t *pass)
{
extern texid_t missing_texture;
extern texid_t missing_texture_gloss;
extern texid_t missing_texture_normal;
extern texid_t scenepp_postproc_cube;
extern texid_t r_whiteimage;
extern cvar_t gl_specular_fallback;
texid_t t;
switch(pass->texgen)
@ -1175,6 +1138,8 @@ static void Shader_BindTextureForPass(int tmu, const shaderpass_t *pass)
case T_GEN_SPECULAR:
if (shaderstate.curtexnums && TEXLOADED(shaderstate.curtexnums->specular))
t = shaderstate.curtexnums->specular;
else if (gl_specular_fallback.value<0 && shaderstate.curtexnums && TEXLOADED(shaderstate.curtexnums->base))
t = shaderstate.curtexnums->base;
else
t = missing_texture_gloss;
break;
@ -1379,22 +1344,22 @@ void GLBE_DestroyFBOs(void)
if (shaderstate.tex_reflection)
{
R_DestroyTexture(shaderstate.tex_reflection);
Image_DestroyTexture(shaderstate.tex_reflection);
shaderstate.tex_reflection = r_nulltex;
}
if (shaderstate.tex_refraction)
{
R_DestroyTexture(shaderstate.tex_refraction);
Image_DestroyTexture(shaderstate.tex_refraction);
shaderstate.tex_refraction = r_nulltex;
}
if (shaderstate.tex_refractiondepth)
{
R_DestroyTexture(shaderstate.tex_refractiondepth);
Image_DestroyTexture(shaderstate.tex_refractiondepth);
shaderstate.tex_refractiondepth = r_nulltex;
}
if (shaderstate.temptexture)
{
R_DestroyTexture(shaderstate.temptexture);
Image_DestroyTexture(shaderstate.temptexture);
shaderstate.temptexture = r_nulltex;
}
}
@ -1985,11 +1950,7 @@ static void colourgen(const shaderpass_t *pass, int cnt, vec4_t *src, vec4_t *ds
case RGB_GEN_TOPCOLOR:
if (cnt)
{
int r, g, b;
R_FetchTopColour(&r, &g, &b);
dst[0][0] = r/255.0f;
dst[0][1] = g/255.0f;
dst[0][2] = b/255.0f;
R_FetchPlayerColour(shaderstate.curentity->topcolour, dst[0]);
while((cnt)--)
{
dst[cnt][0] = dst[0][0];
@ -2001,11 +1962,7 @@ static void colourgen(const shaderpass_t *pass, int cnt, vec4_t *src, vec4_t *ds
case RGB_GEN_BOTTOMCOLOR:
if (cnt)
{
int r, g, b;
R_FetchBottomColour(&r, &g, &b);
dst[0][0] = r/255.0f;
dst[0][1] = g/255.0f;
dst[0][2] = b/255.0f;
R_FetchPlayerColour(shaderstate.curentity->bottomcolour, dst[0]);
while((cnt)--)
{
dst[cnt][0] = dst[0][0];
@ -2738,7 +2695,7 @@ static void BE_SubmitMeshChain(qboolean usetesselation)
mesh = shaderstate.meshes[0];
qglDrawRangeElements(batchtype, mesh->vbofirstvert, mesh->vbofirstvert+mesh->numvertexes, mesh->numindexes, GL_INDEX_TYPE, (index_t*)shaderstate.sourcevbo->indicies.gl.addr + mesh->vbofirstelement);
RQuantAdd(RQUANT_DRAWS, 1);
RQuantAdd(RQUANT_PRIMITIVES, mesh->numindexes);
RQuantAdd(RQUANT_PRIMITIVEINDICIES, mesh->numindexes);
return;
}
else
@ -2771,7 +2728,7 @@ static void BE_SubmitMeshChain(qboolean usetesselation)
}
qglDrawRangeElements(batchtype, startv, endv, endi, GL_INDEX_TYPE, ilst);
RQuantAdd(RQUANT_DRAWS, 1);
RQuantAdd(RQUANT_PRIMITIVES, endi);
RQuantAdd(RQUANT_PRIMITIVEINDICIES, endi);
}
return;
}
@ -2822,7 +2779,7 @@ static void BE_SubmitMeshChain(qboolean usetesselation)
}
qglDrawRangeElements(batchtype, startv, endv, endi-starti, GL_INDEX_TYPE, (index_t*)shaderstate.sourcevbo->indicies.gl.addr + starti);
RQuantAdd(RQUANT_DRAWS, 1);
RQuantAdd(RQUANT_PRIMITIVES, endi-starti);
RQuantAdd(RQUANT_PRIMITIVEINDICIES, endi-starti);
}
/*
if (qglUnlockArraysEXT)
@ -2957,7 +2914,7 @@ static void DrawPass(const shaderpass_t *pass)
static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm, qboolean entunchanged)
{
vec4_t param4;
int r, g, b;
int r, g;//, b;
int i;
unsigned int ph;
const shaderprogparm_t *p;
@ -2975,6 +2932,93 @@ static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm,
switch(p->type)
{
/*
case SP_UBO_ENTITYINFO:
struct
{
vec2_t blendweights;
vec2_t pad1;
vec3_t glowmod;
vec_t pad2;
vec3_t origin;
vec_t pad3;
vec4_t colormod;
vec3_t glowmod;
vec_t pad4;
vec3_t uppercolour;
vec_t pad5;
vec3_t lowercolour;
vec_t pad6;
vec3_t fogcolours;
vec_t fogalpha;
vec3_t vlightdir;
vec_t fogdensity;
vec3_t vlightmul;
vec_t fogdepthbias;
vec3_t vlightadd;
vec_t time;
} u_entityinfo;
Vector2Copy(shaderstate.meshes[0]->xyz_blendw, u_entityinfo.blendweights);
VectorCopy(shaderstate.curentity->glowmod, u_entityinfo.glowmod);
VectorCopy(shaderstate.curentity->origin, u_entityinfo.origin);
Vector4Copy(shaderstate.curentity->shaderRGBAf, u_entityinfo.colormod);
R_FetchPlayerColour(shaderstate.curentity->topcolour, u_entityinfo.uppercolour);
R_FetchPlayerColour(shaderstate.curentity->bottomcolour, u_entityinfo.lowercolour);
Vector3Copy(r_refdef.globalfog.colour, u_entityinfo.fogcolours);
u_entityinfo.fogalpha = r_refdef.globalfog.alpha;
u_entityinfo.fogdensity = r_refdef.globalfog.density;
u_entityinfo.fogdepthbias = r_refdef.globalfog.depthbias;
u_entityinfo.time = shaderstate.curtime;
Vector3Copy(shaderstate.curentity->light_dir, u_entityinfo.vlightdir);
Vector3Copy(shaderstate.curentity->light_range, u_entityinfo.vlightmul);
Vector3Copy(shaderstate.curentity->light_avg, u_entityinfo.vlightadd);
break;
*/
/*
case SP_UBO_LIGHTINFO:
struct
{
vec3_t toscreen;
vec_t lightradius;
vec3_t lightcolours;
vec_t pad1;
vec3_t lightcolourscale;
vec_t pad2;
vec3_t lightorigin_modelspace;
vec_t pad3;
matrix4x4_t lightcubematrix;
vec4_t lightshadowmapproj;
vec2_t lightshadowmapscale;
vec2_t pad4;
} u_lightinfo;
{
float v[4], tempv[4];
v[0] = shaderstate.lightorg[0];
v[1] = shaderstate.lightorg[1];
v[2] = shaderstate.lightorg[2];
v[3] = 1;
Matrix4x4_CM_Transform4(shaderstate.modelviewmatrix, v, tempv);
Matrix4x4_CM_Transform4(r_refdef.m_projection, tempv, v);
v[3] *= 2;
u_lightinfo.toscreen[0] = (v[0]/v[3]) + 0.5;
u_lightinfo.toscreen[1] = (v[1]/v[3]) + 0.5;
u_lightinfo.toscreen[2] = (v[2]/v[3]) + 0.5;
}
u_lightinfo.lightradius = shaderstate.lightradius;
Vector3Copy(shaderstate.lightcolours, u_lightinfo.lightcolours);
Matrix4x4_CM_Transform3(shaderstate.modelmatrixinv, shaderstate.lightorg, u_lightinfo.lightorigin_modelspace);
Vector3Copy(shaderstate.lightcolourscale, u_lightinfo.lightcolourscale);
Matrix4_Multiply(shaderstate.lightprojmatrix, shaderstate.modelmatrix, u_lightinfo.lightcubematrix);
Vector4Copy(shaderstate.lightshadowmapproj, u_lightinfo.lightshadowmapproj);
Vector2Copy(shaderstate.lightshadowmapscale, u_lightinfo.lightshadowmapscale);
break;
*/
case SP_M_VIEW:
qglUniformMatrix4fvARB(ph, 1, false, r_refdef.m_view);
break;
@ -3130,17 +3174,11 @@ static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm,
qglUniform4fARB(ph, 1, 1, 1, shaderstate.curentity->shaderRGBAf[3]);
break;
case SP_E_TOPCOLOURS:
R_FetchTopColour(&r, &g, &b);
param4[0] = r/255.0f;
param4[1] = g/255.0f;
param4[2] = b/255.0f;
R_FetchPlayerColour(shaderstate.curentity->topcolour, param4);
qglUniform3fvARB(ph, 1, param4);
break;
case SP_E_BOTTOMCOLOURS:
R_FetchBottomColour(&r, &g, &b);
param4[0] = r/255.0f;
param4[1] = g/255.0f;
param4[2] = b/255.0f;
R_FetchPlayerColour(shaderstate.curentity->bottomcolour, param4);
qglUniform3fvARB(ph, 1, param4);
break;
@ -3155,11 +3193,11 @@ static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm,
r = 1;
g = 1;
while (r < vid.pixelwidth)
r *= 2;
param4[0] *= 2;
while (g < vid.pixelheight)
g *= 2;
param4[0] = vid.pixelwidth/(float)r;
param4[1] = vid.pixelheight/(float)g;
param4[1] *= 2;
param4[0] = vid.pixelwidth/param4[0];
param4[1] = vid.pixelheight/param4[1];
}
param4[2] = 0;
param4[3] = 0;
@ -3351,27 +3389,17 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas
#if MAXRLIGHTMAPS > 1
if (perm & PERMUTATION_LIGHTSTYLES)
{
GL_LazyBind(i++, GL_TEXTURE_2D, shaderstate.curbatch->lightmap[1] >= 0?lightmap[shaderstate.curbatch->lightmap[1]]->lightmap_texture:r_nulltex);
GL_LazyBind(i++, GL_TEXTURE_2D, shaderstate.curbatch->lightmap[2] >= 0?lightmap[shaderstate.curbatch->lightmap[2]]->lightmap_texture:r_nulltex);
GL_LazyBind(i++, GL_TEXTURE_2D, shaderstate.curbatch->lightmap[3] >= 0?lightmap[shaderstate.curbatch->lightmap[3]]->lightmap_texture:r_nulltex);
//we need this loop to fix up fixed-function stuff
for (; i < shaderstate.lastpasstmus; i++)
{
GL_LazyBind(i, 0, r_nulltex);
}
shaderstate.lastpasstmus = pass->numMergedPasses+3;
GL_LazyBind(i++, GL_TEXTURE_2D, shaderstate.curbatch->lightmap[1]>=0?lightmap[shaderstate.curbatch->lightmap[1]]->lightmap_texture:r_nulltex);
GL_LazyBind(i++, GL_TEXTURE_2D, shaderstate.curbatch->lightmap[2]>=0?lightmap[shaderstate.curbatch->lightmap[2]]->lightmap_texture:r_nulltex);
GL_LazyBind(i++, GL_TEXTURE_2D, shaderstate.curbatch->lightmap[3]>=0?lightmap[shaderstate.curbatch->lightmap[3]]->lightmap_texture:r_nulltex);
GL_LazyBind(i++, GL_TEXTURE_2D, (shaderstate.curbatch->lightmap[1]>=0&&lightmap[shaderstate.curbatch->lightmap[1]]->hasdeluxe)?lightmap[shaderstate.curbatch->lightmap[1]+1]->lightmap_texture:missing_texture_normal);
GL_LazyBind(i++, GL_TEXTURE_2D, (shaderstate.curbatch->lightmap[2]>=0&&lightmap[shaderstate.curbatch->lightmap[2]]->hasdeluxe)?lightmap[shaderstate.curbatch->lightmap[2]+1]->lightmap_texture:missing_texture_normal);
GL_LazyBind(i++, GL_TEXTURE_2D, (shaderstate.curbatch->lightmap[3]>=0&&lightmap[shaderstate.curbatch->lightmap[3]]->hasdeluxe)?lightmap[shaderstate.curbatch->lightmap[3]+1]->lightmap_texture:missing_texture_normal);
}
else
#endif
{
//we need this loop to fix up fixed-function stuff
for (; i < shaderstate.lastpasstmus; i++)
{
GL_LazyBind(i, 0, r_nulltex);
}
shaderstate.lastpasstmus = pass->numMergedPasses;
}
while (shaderstate.lastpasstmus > i)
GL_LazyBind(--shaderstate.lastpasstmus, 0, r_nulltex);
shaderstate.lastpasstmus = i; //in case it was already lower
}
BE_SubmitMeshChain(p->permu[perm].handle.glsl.usetesselation);
}
@ -3503,12 +3531,6 @@ void GLBE_SelectMode(backendmode_t mode)
shaderstate.crepskyshader = R_RegisterShader("crepuscular_sky", SUF_NONE,
"{\n"
"program crepuscular_sky\n"
"{\n"
"map $diffuse\n"
"}\n"
"{\n"
"map $fullbright\n"
"}\n"
"}\n"
);
}
@ -4649,8 +4671,8 @@ static void BE_UpdateLightmaps(void)
lm->width, lm->rectchange.h, glformat, gltype,
lm->lightmaps+(lm->rectchange.t) *lm->width*lightmap_bytes);
}
lm->rectchange.l = LMBLOCK_WIDTH;
lm->rectchange.t = LMBLOCK_HEIGHT;
lm->rectchange.l = lm->width;
lm->rectchange.t = lm->height;
lm->rectchange.h = 0;
lm->rectchange.w = 0;
}
@ -5259,7 +5281,7 @@ void GLBE_DrawWorld (qboolean drawworld, qbyte *vis)
TRACE(("GLBE_DrawWorld: drawn everything\n"));
}
void GLBE_VBO_Begin(vbobctx_t *ctx, unsigned int maxsize)
void GLBE_VBO_Begin(vbobctx_t *ctx, size_t maxsize)
{
COM_AssertMainThread("GLBE_VBO_Begin");
@ -5278,7 +5300,7 @@ void GLBE_VBO_Begin(vbobctx_t *ctx, unsigned int maxsize)
else
ctx->fallback = BZ_Malloc(maxsize);
}
void GLBE_VBO_Data(vbobctx_t *ctx, void *data, unsigned int size, vboarray_t *varray)
void GLBE_VBO_Data(vbobctx_t *ctx, void *data, size_t size, vboarray_t *varray)
{
if (ctx->fallback)
{
@ -5295,7 +5317,7 @@ void GLBE_VBO_Data(vbobctx_t *ctx, void *data, unsigned int size, vboarray_t *va
ctx->pos += size;
}
void GLBE_VBO_Finish(vbobctx_t *ctx, void *edata, unsigned int esize, vboarray_t *earray)
void GLBE_VBO_Finish(vbobctx_t *ctx, void *edata, size_t esize, vboarray_t *earray)
{
if (ctx->pos > ctx->maxsize)
Sys_Error("BE_VBO_Finish: too much data given\n");
@ -5317,8 +5339,12 @@ void GLBE_VBO_Finish(vbobctx_t *ctx, void *edata, unsigned int esize, vboarray_t
void GLBE_VBO_Destroy(vboarray_t *vearray)
{
if (vearray->gl.vbo)
{
qglDeleteBuffersARB(1, &vearray->gl.vbo);
vearray->gl.vbo = 0;
}
else
BZ_Free(vearray->gl.addr);
vearray->gl.addr = NULL;
}
#endif

View File

@ -321,6 +321,18 @@ qboolean GL_LoadTextureMips(texid_t tex, struct pendingtextureinfo *mips)
qglTexParameteri(targ, GL_TEXTURE_WRAP_R, GL_REPEAT);
}
//make sure the texture is complete even if the mips are not.
//note that some drivers will just ignore levels that are not valid.
//this means that we can't make this setting dynamic, so we might as well let the drivers know BEFORE we do the uploads, to be kind to those that are buggy..
if (!gl_config.gles)
{
if (targ != GL_TEXTURE_CUBE_MAP_ARB && (tex->flags & IF_MIPCAP))
{
qglTexParameteri(targ, GL_TEXTURE_BASE_LEVEL, min(mips->mipcount-1, gl_mipcap_min));
qglTexParameteri(targ, GL_TEXTURE_MAX_LEVEL, min(mips->mipcount-1, gl_mipcap_max));
}
}
tex->width = mips->mip[0].width;
tex->height = mips->mip[0].height;
GL_Texturemode_Apply(targ, tex->flags);
@ -443,14 +455,6 @@ qboolean GL_LoadTextureMips(texid_t tex, struct pendingtextureinfo *mips)
Z_Free(mips->mip[i].data);
}
}
if (!gl_config.gles) //make sure the texture is complete even if the mips are not.
{
if (targ != GL_TEXTURE_CUBE_MAP_ARB && (tex->flags & IF_MIPCAP))
{
qglTexParameteri(targ, GL_TEXTURE_BASE_LEVEL, min(mips->mipcount-1, gl_mipcap_min));
qglTexParameteri(targ, GL_TEXTURE_MAX_LEVEL, min(mips->mipcount-1, gl_mipcap_max));
}
}
if (mips->extrafree)
Z_Free(mips->extrafree);

View File

@ -3063,9 +3063,6 @@ void Terr_DrawTerrainModel (batch_t **batches, entity_t *e)
Terr_DrawInBounds(&tdibctx, bounds[0], bounds[2], bounds[1]-bounds[0], bounds[3]-bounds[2]);
}
typedef struct fragmentdecal_s fragmentdecal_t;
void Fragment_ClipPoly(fragmentdecal_t *dec, int numverts, float *inverts);
void Terrain_ClipDecal(fragmentdecal_t *dec, float *center, float radius, model_t *model)
{
int min[2], max[2], mint[2], maxt[2];
@ -3145,8 +3142,9 @@ void Terrain_ClipDecal(fragmentdecal_t *dec, float *center, float radius, model_
vert[5][2] = s->heights[(tx+1) + (ty+1)*SECTHEIGHTSIZE];
}
Fragment_ClipPoly(dec, 3, &vert[0][0]);
Fragment_ClipPoly(dec, 3, &vert[3][0]);
//fixme: per-section shaders for clutter info. this kinda sucks.
Fragment_ClipPoly(dec, 3, &vert[0][0], hm->shader);
Fragment_ClipPoly(dec, 3, &vert[3][0], hm->shader);
}
}
}
@ -4660,6 +4658,7 @@ void Terr_FinishTerrain(model_t *mod)
"map $diffuse\n"
"blendfunc add\n"
"}\n"
//FIXME: these maps are a legacy thing, and could be removed if third-party glsl properly contains s_diffuse
"{\n"
"map $upperoverlay\n"
"}\n"
@ -4697,6 +4696,7 @@ void Terr_FinishTerrain(model_t *mod)
"}\n"
"}\n"
//FIXME: these maps are a legacy thing, and could be removed if third-party glsl properly contains s_diffuse
"{\n"
"map $diffuse\n"
"}\n"

File diff suppressed because it is too large Load Diff

View File

@ -282,16 +282,14 @@ typedef struct texture_s
char name[64];
unsigned width, height;
qbyte alphaed; //gl_blend needed on this surface.
struct shader_s *shader;
texnums_t texnums;
int anim_total; // total tenths in sequence ( 0 = no)
int anim_min, anim_max; // time for this frame min <=time< max
struct texture_s *anim_next; // in the animation sequence
struct texture_s *alternate_anims; // bmodels in frmae 1 use these
unsigned offsets[MIPLEVELS]; // four mip maps stored
qbyte *mips[4]; //the different mipmap levels.
} texture_t;
/*
typedef struct
@ -327,7 +325,7 @@ typedef struct
typedef struct mtexinfo_s
{
float vecs[2][4];
float mipadjust;
float vecscale[2];
texture_t *texture;
int flags;
@ -354,15 +352,16 @@ typedef struct mfog_s
mplane_t **planes;
} mfog_t;
#define LMSHIFT_DEFAULT 4
typedef struct msurface_s
{
mplane_t *plane;
int flags;
int firstedge; // look up in model->surfedges[], negative numbers
int numedges; // are backwards edges
unsigned short numedges; // are backwards edges
unsigned short lmshift; //texels>>lmshift = lightmap samples.
short texturemins[2];
short extents[2];
@ -497,7 +496,9 @@ void Q1BSP_Init(void);
void *Q1BSPX_FindLump(char *lumpname, int *lumpsize);
void Q1BSPX_Setup(struct model_s *mod, char *filebase, unsigned int filelen, lump_t *lumps, int numlumps);
int Q1BSP_ClipDecal(struct model_s *mod, vec3_t center, vec3_t normal, vec3_t tangent1, vec3_t tangent2, float size, float **out);
typedef struct fragmentdecal_s fragmentdecal_t;
void Fragment_ClipPoly(fragmentdecal_t *dec, int numverts, float *inverts, shader_t *surfshader);
void Mod_ClipDecal(struct model_s *mod, vec3_t center, vec3_t normal, vec3_t tangent1, vec3_t tangent2, float size, void (*callback)(void *ctx, vec3_t *fte_restrict points, size_t numpoints, shader_t *shader), void *ctx);
void Q1BSP_MarkLights (dlight_t *light, int bit, mnode_t *node);
void GLQ1BSP_LightPointValues(struct model_s *model, vec3_t point, vec3_t res_diffuse, vec3_t res_ambient, vec3_t res_dir);
@ -887,6 +888,7 @@ typedef struct model_s
int numvertexes;
mvertex_t *vertexes;
vec3_t *normals;
int numedges;
medge_t *edges;

View File

@ -74,7 +74,7 @@ void R_AnimateLight (void)
int v1, v2, vd;
if (!cl_lightstyle[j].length)
{
d_lightstylevalue[j] = 256;
d_lightstylevalue[j] = ('m'-'a')*22;
continue;
}
@ -1246,8 +1246,8 @@ int GLRecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
if (!surf->samples)
return 0;
ds >>= 4;
dt >>= 4;
ds >>= surf->lmshift;
dt >>= surf->lmshift;
lightmap = surf->samples;
r = 0;
@ -1255,29 +1255,27 @@ int GLRecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
{
if (cl.worldmodel->engineflags & MDLF_RGBLIGHTING)
{
lightmap += (dt * ((surf->extents[0]>>4)+1) + ds)*3;
lightmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)*3;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++)
{
scale = d_lightstylevalue[surf->styles[maps]];
r += (lightmap[0]+lightmap[1]+lightmap[2]) * scale / 3;
lightmap += ((surf->extents[0]>>4)+1) *
((surf->extents[1]>>4)+1)*3;
lightmap += ((surf->extents[0]>>surf->lmshift)+1) * ((surf->extents[1]>>surf->lmshift)+1)*3;
}
}
else
{
lightmap += dt * ((surf->extents[0]>>4)+1) + ds;
lightmap += dt * ((surf->extents[0]>>surf->lmshift)+1) + ds;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++)
{
scale = d_lightstylevalue[surf->styles[maps]];
r += *lightmap * scale;
lightmap += ((surf->extents[0]>>4)+1) *
((surf->extents[1]>>4)+1);
lightmap += ((surf->extents[0]>>surf->lmshift)+1) * ((surf->extents[1]>>surf->lmshift)+1);
}
}
@ -1406,8 +1404,8 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
return l;
}
ds >>= 4;
dt >>= 4;
ds >>= surf->lmshift;
dt >>= surf->lmshift;
lightmap = surf->samples;
l[0]=0;l[1]=0;l[2]=0;
@ -1421,8 +1419,8 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
{
deluxmap = surf->samples - cl.worldmodel->lightdata + cl.worldmodel->deluxdata;
lightmap += (dt * ((surf->extents[0]>>4)+1) + ds)*3;
deluxmap += (dt * ((surf->extents[0]>>4)+1) + ds)*3;
lightmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)*3;
deluxmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)*3;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++)
{
@ -1436,10 +1434,10 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
l[4] += (deluxmap[1]-127)*scale;
l[5] += (deluxmap[2]-127)*scale;
lightmap += ((surf->extents[0]>>4)+1) *
((surf->extents[1]>>4)+1) * 3;
deluxmap += ((surf->extents[0]>>4)+1) *
((surf->extents[1]>>4)+1) * 3;
lightmap += ((surf->extents[0]>>surf->lmshift)+1) *
((surf->extents[1]>>surf->lmshift)+1) * 3;
deluxmap += ((surf->extents[0]>>surf->lmshift)+1) *
((surf->extents[1]>>surf->lmshift)+1) * 3;
}
}
@ -1447,8 +1445,8 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
{
deluxmap = (surf->samples - cl.worldmodel->lightdata)*3 + cl.worldmodel->deluxdata;
lightmap += (dt * ((surf->extents[0]>>4)+1) + ds);
deluxmap += (dt * ((surf->extents[0]>>4)+1) + ds)*3;
lightmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds);
deluxmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)*3;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++)
{
@ -1462,10 +1460,10 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
l[4] += deluxmap[1]*scale;
l[5] += deluxmap[2]*scale;
lightmap += ((surf->extents[0]>>4)+1) *
((surf->extents[1]>>4)+1);
deluxmap += ((surf->extents[0]>>4)+1) *
((surf->extents[1]>>4)+1) * 3;
lightmap += ((surf->extents[0]>>surf->lmshift)+1) *
((surf->extents[1]>>surf->lmshift)+1);
deluxmap += ((surf->extents[0]>>surf->lmshift)+1) *
((surf->extents[1]>>surf->lmshift)+1) * 3;
}
}
@ -1474,7 +1472,7 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
{
if (cl.worldmodel->engineflags & MDLF_RGBLIGHTING)
{
lightmap += (dt * ((surf->extents[0]>>4)+1) + ds)*3;
lightmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)*3;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++)
{
@ -1484,14 +1482,14 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
l[1] += lightmap[1] * scale * cl_lightstyle[surf->styles[maps]].colours[1];
l[2] += lightmap[2] * scale * cl_lightstyle[surf->styles[maps]].colours[2];
lightmap += ((surf->extents[0]>>4)+1) *
((surf->extents[1]>>4)+1) * 3;
lightmap += ((surf->extents[0]>>surf->lmshift)+1) *
((surf->extents[1]>>surf->lmshift)+1) * 3;
}
}
else
{
lightmap += (dt * ((surf->extents[0]>>4)+1) + ds);
lightmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds);
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++)
{
@ -1501,8 +1499,8 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
l[1] += *lightmap * scale * cl_lightstyle[surf->styles[maps]].colours[1];
l[2] += *lightmap * scale * cl_lightstyle[surf->styles[maps]].colours[2];
lightmap += ((surf->extents[0]>>4)+1) *
((surf->extents[1]>>4)+1);
lightmap += ((surf->extents[0]>>surf->lmshift)+1) *
((surf->extents[1]>>surf->lmshift)+1);
}
}
}

View File

@ -31,11 +31,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include <ctype.h>
#ifdef D3D9QUAKE
#include <d3d9.h>
extern LPDIRECT3DDEVICE9 pD3DDev9;
#endif
extern texid_t missing_texture;
texid_t r_whiteimage;
static qboolean shader_reload_needed;
@ -214,6 +209,7 @@ typedef struct shaderkey_s
{
char *keyword;
void (*func)( shader_t *shader, shaderpass_t *pass, char **ptr );
char *prefix;
} shaderkey_t;
typedef struct shadercachefile_s {
char *data;
@ -412,13 +408,13 @@ static char *Shader_ParseSensString(char **ptr)
return token;
}
static float Shader_ParseFloat(shader_t *shader, char **ptr)
static float Shader_ParseFloat(shader_t *shader, char **ptr, float defaultval)
{
char *token;
if (!ptr || !(*ptr))
return 0;
return defaultval;
if (!**ptr || **ptr == '}')
return 0;
return defaultval;
token = COM_ParseExt(ptr, false, true);
if (*token == '$')
@ -432,9 +428,16 @@ static float Shader_ParseFloat(shader_t *shader, char **ptr)
cvar_t *var;
var = Cvar_FindVar(token+1);
if (var)
return var->value;
{
if (*var->string)
return var->value;
else
return defaultval;
}
}
}
if (!*token)
return defaultval;
return atof(token);
}
@ -592,10 +595,10 @@ static void Shader_ParseFunc (shader_t *shader, char **ptr, shaderfunc_t *func)
else if (!Q_stricmp (token, "noise"))
func->type = SHADER_FUNC_NOISE;
func->args[0] = Shader_ParseFloat (shader, ptr);
func->args[1] = Shader_ParseFloat (shader, ptr);
func->args[2] = Shader_ParseFloat (shader, ptr);
func->args[3] = Shader_ParseFloat (shader, ptr);
func->args[0] = Shader_ParseFloat (shader, ptr, 0);
func->args[1] = Shader_ParseFloat (shader, ptr, 0);
func->args[2] = Shader_ParseFloat (shader, ptr, 0);
func->args[3] = Shader_ParseFloat (shader, ptr, 0);
}
//===========================================================================
@ -742,7 +745,7 @@ static void Shader_DeformVertexes ( shader_t *shader, shaderpass_t *pass, char *
if ( !Q_stricmp (token, "wave") )
{
deformv->type = DEFORMV_WAVE;
deformv->args[0] = Shader_ParseFloat (shader, ptr);
deformv->args[0] = Shader_ParseFloat (shader, ptr, 0);
if (deformv->args[0])
deformv->args[0] = 1.0f / deformv->args[0];
Shader_ParseFunc (shader, ptr, &deformv->func );
@ -750,13 +753,13 @@ static void Shader_DeformVertexes ( shader_t *shader, shaderpass_t *pass, char *
else if ( !Q_stricmp (token, "normal") )
{
deformv->type = DEFORMV_NORMAL;
deformv->args[0] = Shader_ParseFloat (shader, ptr );
deformv->args[1] = Shader_ParseFloat (shader, ptr );
deformv->args[0] = Shader_ParseFloat (shader, ptr, 0);
deformv->args[1] = Shader_ParseFloat (shader, ptr, 0);
}
else if ( !Q_stricmp (token, "bulge") )
{
deformv->type = DEFORMV_BULGE;
Shader_ParseVector (shader, ptr, deformv->args );
Shader_ParseVector (shader, ptr, deformv->args);
shader->flags |= SHADER_DEFORMV_BULGE;
}
else if ( !Q_stricmp (token, "move") )
@ -783,6 +786,24 @@ static void Shader_DeformVertexes ( shader_t *shader, shaderpass_t *pass, char *
shader->numdeforms++;
}
static void Shader_ClutterParms(shader_t *shader, shaderpass_t *pass, char **ptr)
{
struct shader_clutter_s *clut;
char *modelname;
modelname = Shader_ParseString(ptr);
clut = Z_Malloc(sizeof(*clut) + strlen(modelname));
strcpy(clut->modelname, modelname);
clut->spacing = Shader_ParseFloat(shader, ptr, 1000);
clut->scalemin = Shader_ParseFloat(shader, ptr, 1);
clut->scalemax = Shader_ParseFloat(shader, ptr, 1);
clut->zofs = Shader_ParseFloat(shader, ptr, 0);
clut->anglemin = Shader_ParseFloat(shader, ptr, 0) * M_PI * 2 / 360.;
clut->anglemax = Shader_ParseFloat(shader, ptr, 360) * M_PI * 2 / 360.;
clut->next = shader->clutter;
shader->clutter = clut;
}
static void Shader_SkyParms(shader_t *shader, shaderpass_t *pass, char **ptr)
{
@ -801,11 +822,7 @@ static void Shader_SkyParms(shader_t *shader, shaderpass_t *pass, char **ptr)
boxname = Shader_ParseString(ptr);
Shader_ParseSkySides(shader->name, boxname, skydome->farbox_textures);
skyheight = Shader_ParseFloat(shader, ptr);
if (!skyheight)
{
skyheight = 512.0f;
}
skyheight = Shader_ParseFloat(shader, ptr, 512);
boxname = Shader_ParseString(ptr);
Shader_ParseSkySides(shader->name, boxname, skydome->nearbox_textures);
@ -832,7 +849,7 @@ static void Shader_FogParms ( shader_t *shader, shaderpass_t *pass, char **ptr )
shader->fog_color[1] = FloatToByte ( fcolor[1] );
shader->fog_color[2] = FloatToByte ( fcolor[2] );
shader->fog_color[3] = 255;
shader->fog_dist = Shader_ParseFloat (shader, ptr );
shader->fog_dist = Shader_ParseFloat (shader, ptr, 128);
if ( shader->fog_dist <= 0.0f ) {
shader->fog_dist = 128.0f;
@ -960,6 +977,8 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
cvarnames[cvarcount] = NULL;
prog->nofixedcompat = true;
prog->numsamplers = 0;
prog->defaulttextures = 0;
for(;;)
{
while (*script == ' ' || *script == '\r' || *script == '\n' || *script == '\t')
@ -968,15 +987,11 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
{
prog->nofixedcompat = false;
script += 7;
while (*script && *script != '\n')
script++;
}
else if (!strncmp(script, "!!tess", 6))
{
tess = true;
script += 6;
while (*script && *script != '\n')
script++;
}
else if (!strncmp(script, "!!cvardf", 8))
{
@ -1063,7 +1078,13 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
}
}
if (!permutationname[p])
Con_DPrintf("Unknown pemutation in glsl program %s\n", name);
{
//we 'recognise' ones that are force-defined, despite not being actual permutations.
if (strncmp("SPECULAR", script, end - script))
if (strncmp("OFFSETMAPPING", script, end - script))
if (strncmp("RELIEFMAPPING", script, end - script))
Con_DPrintf("Unknown pemutation in glsl program %s\n", name);
}
script = end;
}
else if (!strncmp(script, "!!ver", 5))
@ -1077,8 +1098,16 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
ver = strtol(script, NULL, 0);
script = end;
}
else if (!strncmp(script, "//", 2))
{
script += 2;
while (*script == ' ' || *script == '\t')
script++;
}
else
break;
while (*script && *script != '\n')
script++;
};
if (sh_config.pLoadBlob && blobfilename && *blobfilename)
@ -2020,36 +2049,37 @@ static shaderkey_t shaderkeys[] =
{"entitymergable", Shader_EntityMergable},
//fte extensions
{"lpp_light", Shader_Prelight},
{"glslprogram", Shader_GLSLProgramName},
{"program", Shader_ProgramName}, //gl or d3d
{"hlslprogram", Shader_HLSL9ProgramName}, //for d3d
{"hlsl11program", Shader_HLSL11ProgramName}, //for d3d
{"param", Shader_ProgramParam}, //legacy
{"clutter", Shader_ClutterParms, "fte"},
{"lpp_light", Shader_Prelight, "fte"},
{"glslprogram", Shader_GLSLProgramName, "fte"},
{"program", Shader_ProgramName, "fte"}, //gl or d3d
{"hlslprogram", Shader_HLSL9ProgramName, "fte"}, //for d3d
{"hlsl11program", Shader_HLSL11ProgramName, "fte"}, //for d3d
{"param", Shader_ProgramParam, "fte"}, //legacy
{"bemode", Shader_BEMode},
{"bemode", Shader_BEMode, "fte"},
//dp compat
{"dp_camera", Shader_DP_Camera},
{"camera", Shader_DP_Camera, "dp"},
/*doom3 compat*/
{"diffusemap", Shader_DiffuseMap}, //macro for "{\nstage diffusemap\nmap <map>\n}"
{"bumpmap", Shader_BumpMap}, //macro for "{\nstage bumpmap\nmap <map>\n}"
{"specularmap", Shader_SpecularMap},//macro for "{\nstage specularmap\nmap <map>\n}"
{"fullbrightmap", Shader_FullbrightMap},//macro for "{\nstage specularmap\nmap <map>\n}"
{"uppermap", Shader_UpperMap},//macro for "{\nstage specularmap\nmap <map>\n}"
{"lowermap", Shader_LowerMap},//macro for "{\nstage specularmap\nmap <map>\n}"
{"discrete", NULL},
{"nonsolid", NULL},
{"noimpact", NULL},
{"translucent", Shader_Translucent},
{"noshadows", NULL},
{"nooverlays", NULL},
{"nofragment", NULL},
{"diffusemap", Shader_DiffuseMap, "doom3"}, //macro for "{\nstage diffusemap\nmap <map>\n}"
{"bumpmap", Shader_BumpMap, "doom3"}, //macro for "{\nstage bumpmap\nmap <map>\n}"
{"specularmap", Shader_SpecularMap, "doom3"},//macro for "{\nstage specularmap\nmap <map>\n}"
{"fullbrightmap", Shader_FullbrightMap, "doom3"},//macro for "{\nstage specularmap\nmap <map>\n}"
{"uppermap", Shader_UpperMap, "doom3"},//macro for "{\nstage specularmap\nmap <map>\n}"
{"lowermap", Shader_LowerMap, "doom3"},//macro for "{\nstage specularmap\nmap <map>\n}"
{"discrete", NULL, "doom3"},
{"nonsolid", NULL, "doom3"},
{"noimpact", NULL, "doom3"},
{"translucent", Shader_Translucent, "doom3"},
{"noshadows", NULL, "doom3"},
{"nooverlays", NULL, "doom3"},
{"nofragment", NULL, "doom3"},
/*simpler parsing for fte shaders*/
{"progblendfunc", Shader_ProgBlendFunc},
{"progmap", Shader_ProgMap},
{"progblendfunc", Shader_ProgBlendFunc, "fte"},
{"progmap", Shader_ProgMap, "fte"},
{NULL, NULL}
};
@ -2223,7 +2253,7 @@ static void Shaderpass_AnimMap (shader_t *shader, shaderpass_t *pass, char **ptr
pass->tcgen = TC_GEN_BASE;
pass->flags |= SHADER_PASS_ANIMMAP;
pass->texgen = T_GEN_ANIMMAP;
pass->anim_fps = (int)Shader_ParseFloat (shader, ptr);
pass->anim_fps = (int)Shader_ParseFloat (shader, ptr, 0);
pass->anim_numframes = 0;
for ( ; ; )
@ -2370,7 +2400,7 @@ static void Shaderpass_AlphaGen (shader_t *shader, shaderpass_t *pass, char **pt
if (!Q_stricmp (token, "portal"))
{
pass->alphagen = ALPHA_GEN_PORTAL;
shader->portaldist = Shader_ParseFloat(shader, ptr);
shader->portaldist = Shader_ParseFloat(shader, ptr, 256);
if (!shader->portaldist)
shader->portaldist = 256;
shader->flags |= SHADER_AGEN_PORTAL;
@ -2397,7 +2427,7 @@ static void Shaderpass_AlphaGen (shader_t *shader, shaderpass_t *pass, char **pt
{
pass->alphagen = ALPHA_GEN_CONST;
pass->alphagen_func.type = SHADER_FUNC_CONSTANT;
pass->alphagen_func.args[0] = fabs(Shader_ParseFloat(shader, ptr));
pass->alphagen_func.args[0] = fabs(Shader_ParseFloat(shader, ptr, 0));
}
}
static void Shaderpass_AlphaShift (shader_t *shader, shaderpass_t *pass, char **ptr) //for alienarena
@ -2414,9 +2444,9 @@ static void Shaderpass_AlphaShift (shader_t *shader, shaderpass_t *pass, char **
//arg2 = timeshift
//arg3 = timescale
speed = Shader_ParseFloat(shader, ptr);
min = Shader_ParseFloat(shader, ptr);
max = Shader_ParseFloat(shader, ptr);
speed = Shader_ParseFloat(shader, ptr, 0);
min = Shader_ParseFloat(shader, ptr, 0);
max = Shader_ParseFloat(shader, ptr, 0);
pass->alphagen_func.args[0] = min + (max - min)/2;
pass->alphagen_func.args[1] = (max - min)/2;
@ -2584,7 +2614,7 @@ static void Shaderpass_TcMod (shader_t *shader, shaderpass_t *pass, char **ptr)
token = Shader_ParseString (ptr);
if (!Q_stricmp (token, "rotate"))
{
tcmod->args[0] = -Shader_ParseFloat(shader, ptr) / 360.0f;
tcmod->args[0] = -Shader_ParseFloat(shader, ptr, 0) / 360.0f;
if (!tcmod->args[0])
{
return;
@ -2594,14 +2624,14 @@ static void Shaderpass_TcMod (shader_t *shader, shaderpass_t *pass, char **ptr)
}
else if ( !Q_stricmp (token, "scale") )
{
tcmod->args[0] = Shader_ParseFloat (shader, ptr);
tcmod->args[1] = Shader_ParseFloat (shader, ptr);
tcmod->args[0] = Shader_ParseFloat (shader, ptr, 0);
tcmod->args[1] = Shader_ParseFloat (shader, ptr, 0);
tcmod->type = SHADER_TCMOD_SCALE;
}
else if ( !Q_stricmp (token, "scroll") )
{
tcmod->args[0] = Shader_ParseFloat (shader, ptr);
tcmod->args[1] = Shader_ParseFloat (shader, ptr);
tcmod->args[0] = Shader_ParseFloat (shader, ptr, 0);
tcmod->args[1] = Shader_ParseFloat (shader, ptr, 0);
tcmod->type = SHADER_TCMOD_SCROLL;
}
else if (!Q_stricmp(token, "stretch"))
@ -2618,13 +2648,13 @@ static void Shaderpass_TcMod (shader_t *shader, shaderpass_t *pass, char **ptr)
else if (!Q_stricmp (token, "transform"))
{
for (i = 0; i < 6; ++i)
tcmod->args[i] = Shader_ParseFloat (shader, ptr);
tcmod->args[i] = Shader_ParseFloat (shader, ptr, 0);
tcmod->type = SHADER_TCMOD_TRANSFORM;
}
else if (!Q_stricmp (token, "turb"))
{
for (i = 0; i < 4; i++)
tcmod->args[i] = Shader_ParseFloat (shader, ptr);
tcmod->args[i] = Shader_ParseFloat (shader, ptr, 0);
tcmod->type = SHADER_TCMOD_TURB;
}
else
@ -2648,7 +2678,7 @@ static void Shaderpass_Scale ( shader_t *shader, shaderpass_t *pass, char **ptr
token = Shader_ParseString (ptr);
if (!strcmp(token, "static"))
{
tcmod->args[0] = Shader_ParseFloat (shader, ptr);
tcmod->args[0] = Shader_ParseFloat (shader, ptr, 0);
}
else
{
@ -2663,7 +2693,7 @@ static void Shaderpass_Scale ( shader_t *shader, shaderpass_t *pass, char **ptr
token = Shader_ParseString (ptr);
if (!strcmp(token, "static"))
{
tcmod->args[1] = Shader_ParseFloat (shader, ptr);
tcmod->args[1] = Shader_ParseFloat (shader, ptr, 0);
}
else
{
@ -2685,7 +2715,7 @@ static void Shaderpass_Scroll (shader_t *shader, shaderpass_t *pass, char **ptr)
if (!strcmp(token, "static"))
{
tcmod->type = SHADER_TCMOD_SCROLL;
tcmod->args[0] = Shader_ParseFloat (shader, ptr );
tcmod->args[0] = Shader_ParseFloat (shader, ptr, 0);
}
else
{
@ -2697,7 +2727,7 @@ static void Shaderpass_Scroll (shader_t *shader, shaderpass_t *pass, char **ptr)
if (!strcmp(token, "static"))
{
tcmod->type = SHADER_TCMOD_SCROLL;
tcmod->args[1] = Shader_ParseFloat (shader, ptr );
tcmod->args[1] = Shader_ParseFloat (shader, ptr, 0);
}
else
{
@ -2754,22 +2784,22 @@ static void Shaderpass_NoLightMap ( shader_t *shader, shaderpass_t *pass, char *
static void Shaderpass_Red(shader_t *shader, shaderpass_t *pass, char **ptr)
{
pass->rgbgen = RGB_GEN_CONST;
pass->rgbgen_func.args[0] = Shader_ParseFloat(shader, ptr);
pass->rgbgen_func.args[0] = Shader_ParseFloat(shader, ptr, 0);
}
static void Shaderpass_Green(shader_t *shader, shaderpass_t *pass, char **ptr)
{
pass->rgbgen = RGB_GEN_CONST;
pass->rgbgen_func.args[1] = Shader_ParseFloat(shader, ptr);
pass->rgbgen_func.args[1] = Shader_ParseFloat(shader, ptr, 0);
}
static void Shaderpass_Blue(shader_t *shader, shaderpass_t *pass, char **ptr)
{
pass->rgbgen = RGB_GEN_CONST;
pass->rgbgen_func.args[2] = Shader_ParseFloat(shader, ptr);
pass->rgbgen_func.args[2] = Shader_ParseFloat(shader, ptr, 0);
}
static void Shaderpass_Alpha(shader_t *shader, shaderpass_t *pass, char **ptr)
{
pass->alphagen = ALPHA_GEN_CONST;
pass->alphagen_func.args[0] = Shader_ParseFloat(shader, ptr);
pass->alphagen_func.args[0] = Shader_ParseFloat(shader, ptr, 0);
}
static void Shaderpass_MaskColor(shader_t *shader, shaderpass_t *pass, char **ptr)
{
@ -2793,7 +2823,7 @@ static void Shaderpass_MaskAlpha(shader_t *shader, shaderpass_t *pass, char **pt
}
static void Shaderpass_AlphaTest(shader_t *shader, shaderpass_t *pass, char **ptr)
{
if (Shader_ParseFloat(shader, ptr) == 0.5)
if (Shader_ParseFloat(shader, ptr, 0) == 0.5)
pass->shaderbits |= SBITS_ATEST_GE128;
else
Con_Printf("unsupported alphatest value\n");
@ -2850,30 +2880,30 @@ static shaderkey_t shaderpasskeys[] =
{"clampmap", Shaderpass_ClampMap },
{"videomap", Shaderpass_VideoMap },
{"tcgen", Shaderpass_TcGen },
{"envmap", Shaderpass_EnvMap },//for alienarena
{"nolightmap", Shaderpass_NoLightMap },//for alienarena
{"scale", Shaderpass_Scale },//for alienarena
{"scroll", Shaderpass_Scroll },//for alienarena
{"alphagen", Shaderpass_AlphaGen },
{"alphashift", Shaderpass_AlphaShift },//for alienarena
{"alphamask", Shaderpass_AlphaMask },//for alienarena
{"detail", Shaderpass_Detail },
{"envmap", Shaderpass_EnvMap, "rscript"},//for alienarena
{"nolightmap", Shaderpass_NoLightMap, "rscript"},//for alienarena
{"scale", Shaderpass_Scale, "rscript"},//for alienarena
{"scroll", Shaderpass_Scroll, "rscript"},//for alienarena
{"alphagen", Shaderpass_AlphaGen, "rscript"},
{"alphashift", Shaderpass_AlphaShift, "rscript"},//for alienarena
{"alphamask", Shaderpass_AlphaMask, "rscript"},//for alienarena
{"detail", Shaderpass_Detail, "rscript"},
/*doom3 compat*/
{"blend", Shaderpass_BlendFunc},
{"maskcolor", Shaderpass_MaskColor},
{"maskred", Shaderpass_MaskRed},
{"maskgreen", Shaderpass_MaskGreen},
{"maskblue", Shaderpass_MaskBlue},
{"maskalpha", Shaderpass_MaskAlpha},
{"alphatest", Shaderpass_AlphaTest},
{"texgen", Shaderpass_TexGen},
{"cubemap", Shaderpass_CubeMap}, //one of these is wrong
{"cameracubemap",Shaderpass_CubeMap}, //one of these is wrong
{"red", Shaderpass_Red},
{"green", Shaderpass_Green},
{"blue", Shaderpass_Blue},
{"alpha", Shaderpass_Alpha},
{"blend", Shaderpass_BlendFunc, "doom3"},
{"maskcolor", Shaderpass_MaskColor, "doom3"},
{"maskred", Shaderpass_MaskRed, "doom3"},
{"maskgreen", Shaderpass_MaskGreen, "doom3"},
{"maskblue", Shaderpass_MaskBlue, "doom3"},
{"maskalpha", Shaderpass_MaskAlpha, "doom3"},
{"alphatest", Shaderpass_AlphaTest, "doom3"},
{"texgen", Shaderpass_TexGen, "doom3"},
{"cubemap", Shaderpass_CubeMap, "doom3"}, //one of these is wrong
{"cameracubemap",Shaderpass_CubeMap, "doom3"}, //one of these is wrong
{"red", Shaderpass_Red, "doom3"},
{"green", Shaderpass_Green, "doom3"},
{"blue", Shaderpass_Blue, "doom3"},
{"alpha", Shaderpass_Alpha, "doom3"},
{NULL, NULL}
};
@ -2908,8 +2938,12 @@ void Shader_Free (shader_t *shader)
shader->prog = NULL;
if (shader->skydome)
{
Z_Free (shader->skydome);
while (shader->clutter)
{
void *t = shader->clutter;
shader->clutter = shader->clutter->next;
Z_Free(t);
}
pass = shader->passes;
@ -3168,8 +3202,6 @@ void Shader_Shutdown (void)
int i;
shader_t *shader;
Image_Shutdown();
if (!r_shaders)
return; /*nothing needs freeing yet*/
for (i = 0; i < r_numshaders; i++)
@ -3431,19 +3463,35 @@ void Shader_Readpass (shader_t *shader, char **ptr)
static qboolean Shader_Parsetok (shader_t *shader, shaderpass_t *pass, shaderkey_t *keys, char *token, char **ptr)
{
shaderkey_t *key;
char *prefix;
//handle known prefixes.
if (!Q_strncasecmp(token, "fte", 3)) {prefix = token; token += 3; }
else if (!Q_strncasecmp(token, "dp", 2)) {prefix = token; token += 2; }
else if (!Q_strncasecmp(token, "doom3", 5)) {prefix = token; token += 5; }
else if (!Q_strncasecmp(token, "rscript", 7)) {prefix = token; token += 7; }
else prefix = NULL;
if (prefix && *token == '_')
token++;
for (key = keys; key->keyword != NULL; key++)
{
if (!Q_stricmp (token, key->keyword))
{
if (key->func)
key->func ( shader, pass, ptr );
if (!prefix || (prefix && key->prefix && !Q_strncasecmp(prefix, key->prefix, strlen(key->prefix))))
{
if (key->func)
key->func ( shader, pass, ptr );
return ( ptr && *ptr && **ptr == '}' );
return ( ptr && *ptr && **ptr == '}' );
}
}
}
// Con_Printf("Unknown shader directive: \"%s\"\n", token);
if (prefix)
Con_DPrintf("Unknown shader directive: \"%s_%s\"\n", prefix, token);
else
Con_DPrintf("Unknown shader directive: \"%s\"\n", token);
// Next Line
while (ptr)
@ -3606,25 +3654,6 @@ void Shader_Programify (shader_t *s)
s->numpasses = 0;
s->passes[s->numpasses++].texgen = T_GEN_DIFFUSE;
s->flags |= SHADER_HASDIFFUSE;
if (modellighting)
{
s->passes[s->numpasses++].texgen = T_GEN_LOWEROVERLAY;
s->passes[s->numpasses++].texgen = T_GEN_UPPEROVERLAY;
s->passes[s->numpasses++].texgen = T_GEN_FULLBRIGHT;
s->passes[s->numpasses++].texgen = T_GEN_NORMALMAP;
s->passes[s->numpasses++].texgen = T_GEN_SPECULAR;
s->flags |= SHADER_HASTOPBOTTOM | SHADER_HASFULLBRIGHT | SHADER_HASNORMALMAP | SHADER_HASGLOSS;
}
else if (lightmap)
{
s->passes[s->numpasses++].texgen = T_GEN_LIGHTMAP;
s->passes[s->numpasses++].texgen = T_GEN_NORMALMAP;
s->passes[s->numpasses++].texgen = T_GEN_DELUXMAP;
s->passes[s->numpasses++].texgen = T_GEN_FULLBRIGHT;
s->passes[s->numpasses++].texgen = T_GEN_SPECULAR;
s->flags |= SHADER_HASFULLBRIGHT | SHADER_HASNORMALMAP | SHADER_HASGLOSS;
}
}
void Shader_Finish (shader_t *s)
@ -3665,7 +3694,19 @@ void Shader_Finish (shader_t *s)
}
}
if (!s->numpasses && s->sort != SHADER_SORT_PORTAL && !(s->flags & (SHADER_NODRAW|SHADER_SKY)) && !s->fog_dist && !s->prog)
if (s->prog && !s->numpasses)
{
pass = &s->passes[s->numpasses++];
pass->tcgen = TC_GEN_BASE;
pass->texgen = T_GEN_DIFFUSE;
pass->shaderbits |= SBITS_MISC_DEPTHWRITE;
pass->rgbgen = RGB_GEN_IDENTITY;
pass->alphagen = ALPHA_GEN_IDENTITY;
pass->numMergedPasses = 1;
Shader_SetBlendmode(pass);
}
if (!s->numpasses && s->sort != SHADER_SORT_PORTAL && !(s->flags & (SHADER_NODRAW|SHADER_SKY)) && !s->fog_dist)
{
pass = &s->passes[s->numpasses++];
pass = &s->passes[0];
@ -3974,6 +4015,46 @@ done:;
if (s->prog)
{
struct
{
int gen;
unsigned int flags;
} defaulttgen[] =
{
{T_GEN_DIFFUSE, SHADER_HASDIFFUSE},
{T_GEN_NORMALMAP, SHADER_HASNORMALMAP},
{T_GEN_SPECULAR, SHADER_HASGLOSS},
{T_GEN_UPPEROVERLAY, SHADER_HASTOPBOTTOM},
{T_GEN_LOWEROVERLAY, SHADER_HASTOPBOTTOM},
{T_GEN_FULLBRIGHT, SHADER_HASFULLBRIGHT},
{T_GEN_PALETTED, SHADER_HASPALETTED},
{T_GEN_SHADOWMAP, 0},
{T_GEN_LIGHTCUBEMAP, 0},
// {T_GEN_REFLECTION, SHADER_HASREFLECT},
// {T_GEN_REFRACTION, SHADER_HASREFRACT},
// {T_GEN_REFRACTIONDEPTH, SHADER_HASREFRACTDEPTH},
// {T_GEN_RIPPLEMAP, SHADER_HASRIPPLEMAP},
{T_GEN_LIGHTMAP, SHADER_HASLIGHTMAP},
{T_GEN_DELUXMAP, 0},
};
//if the glsl doesn't specify all samplers, just trim them.
s->numpasses = s->prog->numsamplers;
//if the glsl has specific textures listed, be sure to provide a pass for them.
for (i = 0; i < sizeof(defaulttgen)/sizeof(defaulttgen[0]); i++)
{
if (s->prog->defaulttextures & (1u<<i))
{
s->passes[s->numpasses].flags &= ~SHADER_PASS_DEPTHCMP;
if (defaulttgen[i].gen == T_GEN_SHADOWMAP)
s->passes[s->numpasses].flags |= SHADER_PASS_DEPTHCMP;
s->passes[s->numpasses].texgen = defaulttgen[i].gen;
s->numpasses++;
s->flags |= defaulttgen[i].flags;
}
}
//must have at least one texture.
if (!s->numpasses)
{
s->passes[0].texgen = T_GEN_DIFFUSE;
@ -4054,6 +4135,11 @@ void QDECL R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader)
h = strchr(imagename, '#');
if (h)
*h = 0;
if (*imagename == '/' || strchr(imagename, ':'))
{ //this is not security. this is anti-spam for the verbose security in the filesystem code.
Con_Printf("Warning: shader has absolute path: %s\n", shader->name);
*imagename = 0;
}
//skins can use an alternative path in certain cases, to work around dodgy models.
if (shader->generator == Shader_DefaultSkin)
@ -4148,6 +4234,109 @@ void QDECL R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader)
}
}
//call this with some fallback textures to directly load some textures
void QDECL R_BuildLegacyTexnums(shader_t *shader, const char *subpath, unsigned int loadflags, uploadfmt_t basefmt, size_t width, size_t height, qbyte *mipdata[4], qbyte *palette)
{
char *h;
char imagename[MAX_QPATH];
texnums_t *tex = &shader->defaulttextures;
unsigned int imageflags;
qbyte *dontcrashme[4] = {NULL};
if (!mipdata)
mipdata = dontcrashme;
strcpy(imagename, shader->name);
h = strchr(imagename, '#');
if (h)
*h = 0;
if (*imagename == '/' || strchr(imagename, ':'))
{ //this is not security. this is anti-spam for the verbose security in the filesystem code.
Con_Printf("Warning: shader has absolute path: %s\n", shader->name);
*imagename = 0;
}
loadflags &= shader->flags;
//skins can use an alternative path in certain cases, to work around dodgy models.
if (shader->generator == Shader_DefaultSkin)
subpath = shader->genargs;
//make sure the noalpha thing is set properly.
imageflags = (basefmt==TF_SOLID8)?IF_NOALPHA:0;
imageflags |= IF_MIPCAP;
COM_StripExtension(imagename, imagename, sizeof(imagename));
/*dlights/realtime lighting needs some stuff*/
if (loadflags & SHADER_HASDIFFUSE)
{
if (!TEXVALID(tex->base) && *shader->mapname)
tex->base = R_LoadHiResTexture(shader->mapname, NULL, imageflags);
if (!TEXVALID(tex->base))
tex->base = Image_GetTexture(imagename, subpath, imageflags, mipdata[0], palette, width, height, basefmt);
}
if (loadflags & SHADER_HASPALETTED)
{
if (!TEXVALID(tex->paletted) && *shader->mapname)
tex->paletted = R_LoadHiResTexture(va("%s_pal", shader->mapname), NULL, imageflags|IF_NEAREST);
if (!TEXVALID(tex->paletted))
tex->paletted = Image_GetTexture(va("%s_pal", imagename), subpath, imageflags|IF_NEAREST, mipdata[0], palette, width, height, TF_LUM8);
}
//all the rest need/want an alpha channel in some form.
imageflags &= ~IF_NOALPHA;
imageflags |= IF_NOGAMMA;
if (loadflags & SHADER_HASNORMALMAP)
{
extern cvar_t r_shadow_bumpscale_basetexture;
if (!TEXVALID(tex->bump) && *shader->mapname)
tex->bump = R_LoadHiResTexture(va("%s_norm", shader->mapname), NULL, imageflags|IF_TRYBUMP);
if (!TEXVALID(tex->bump))
tex->bump = Image_GetTexture(va("%s_norm", imagename), subpath, imageflags|IF_TRYBUMP, r_shadow_bumpscale_basetexture.ival?mipdata[0]:NULL, palette, width, height, TF_HEIGHT8PAL);
}
if (loadflags & SHADER_HASTOPBOTTOM)
{
if (!TEXVALID(tex->loweroverlay) && *shader->mapname)
tex->loweroverlay = R_LoadHiResTexture(va("%s_pants", shader->mapname), NULL, imageflags);
if (!TEXVALID(tex->loweroverlay))
tex->loweroverlay = Image_GetTexture(va("%s_pants", imagename), subpath, imageflags, NULL, palette, width, height, 0);
}
if (loadflags & SHADER_HASTOPBOTTOM)
{
if (!TEXVALID(tex->upperoverlay) && *shader->mapname)
tex->upperoverlay = R_LoadHiResTexture(va("%s_shirt", shader->mapname), NULL, imageflags);
if (!TEXVALID(tex->upperoverlay))
tex->upperoverlay = Image_GetTexture(va("%s_shirt", imagename), subpath, imageflags, NULL, palette, width, height, 0);
}
if (loadflags & SHADER_HASGLOSS)
{
if (!TEXVALID(tex->specular) && *shader->mapname)
tex->specular = R_LoadHiResTexture(va("%s_gloss", shader->mapname), NULL, imageflags);
if (!TEXVALID(tex->specular))
tex->specular = Image_GetTexture(va("%s_gloss", imagename), subpath, imageflags, NULL, palette, width, height, 0);
}
if (loadflags & SHADER_HASFULLBRIGHT)
{
if (!TEXVALID(tex->fullbright) && *shader->mapname)
tex->fullbright = R_LoadHiResTexture(va("%s_luma", shader->mapname), NULL, imageflags);
if (!TEXVALID(tex->fullbright))
{
int s=-1;
if (mipdata[0])
for(s = width*height; s-->0; )
{
if (mipdata[0][s] >= 256-vid.fullbright)
break;
}
tex->fullbright = Image_GetTexture(va("%s_luma", imagename), subpath, imageflags, (s>=0)?mipdata[0]:NULL, palette, width, height, TF_TRANS8_FULLBRIGHT);
}
}
}
void Shader_DefaultScript(const char *shortname, shader_t *s, const void *args)
{
const char *f = args;
@ -4176,65 +4365,7 @@ void Shader_DefaultBSPLM(const char *shortname, shader_t *s, const void *args)
"}\n"
"}\n"
);
#ifdef D3D11QUAKE
if (qrenderer == QR_DIRECT3D11)
{
if (!builtin)
builtin = (
"{\n"
"program defaultwall\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"
"map $specular\n"
"}\n"
"}\n"
);
}
#endif
#if 0//def D3D9QUAKE
if (qrenderer == QR_DIRECT3D9)
{
if (!builtin)
builtin = (
"{\n"
"program defaultwall\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"
"map $specular\n"
"}\n"
"}\n"
);
}
#endif
#ifdef GLQUAKE
if (qrenderer == QR_OPENGL)
@ -4247,29 +4378,17 @@ void Shader_DefaultBSPLM(const char *shortname, shader_t *s, const void *args)
"{\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)
{
builtin = (
}
#endif
if (!builtin && ((sh_config.progs_supported && qrenderer == QR_OPENGL) || sh_config.progs_required))
{
builtin = (
"{\n"
"program defaultwall\n"
//FIXME: these maps are a legacy thing, and could be removed if third-party glsl properly contains s_diffuse
"{\n"
"map $diffuse\n"
"}\n"
@ -4290,9 +4409,7 @@ void Shader_DefaultBSPLM(const char *shortname, shader_t *s, const void *args)
"}\n"
"}\n"
);
}
}
#endif
if (!builtin)
builtin = (
"{\n"
@ -4389,9 +4506,9 @@ char *Shader_DefaultBSPWater(shader_t *s, const char *shortname)
else if (r_fastturb.ival)
wstyle = 0;
#ifdef GLQUAKE
else if (qrenderer == QR_OPENGL && gl_config.arb_shader_objects && *stylevars[type]->string)
else if (qrenderer == QR_OPENGL && sh_config.progs_supported && *stylevars[type]->string)
wstyle = stylevars[type]->ival;
else if (qrenderer == QR_OPENGL && gl_config.arb_shader_objects && stylevars[0]->ival > 0)
else if (qrenderer == QR_OPENGL && sh_config.progs_supported && stylevars[0]->ival > 0)
wstyle = stylevars[0]->ival;
#endif
else
@ -4456,14 +4573,14 @@ char *Shader_DefaultBSPWater(shader_t *s, const char *shortname)
"map $refraction\n"
"}\n"
"{\n"
"map $normalmap\n"
"map $null\n"//$reflection
"}\n"
"{\n"
"map $diffuse\n"
"map $null\n"//$ripplemap
"}\n"
"{\n"
"map $null\n"//$refractiondepth
"}\n"
// "{\n"
// "map $refractiondepth\n"
// "}\n"
"program altwater#FRESNEL=4\n"
"}\n"
);
@ -4474,15 +4591,15 @@ char *Shader_DefaultBSPWater(shader_t *s, const char *shortname)
"{\n"
"map $refraction\n"
"}\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n"
"map $reflection\n"
"}\n"
// "{\n"
// "map $refractiondepth\n"
// "}\n"
"{\n"
"map $null\n"//$ripplemap
"}\n"
"{\n"
"map $null\n"//$refractiondepth
"}\n"
"program altwater#REFLECT#FRESNEL=4\n"
"}\n"
);
@ -4494,17 +4611,14 @@ char *Shader_DefaultBSPWater(shader_t *s, const char *shortname)
"map $refraction\n"
"}\n"
"{\n"
"map $normalmap\n"
"map $null\n"//$reflection
"}\n"
"{\n"
"map $diffuse\n"
"}\n"
// "{\n"
// "map $refractiondepth\n"
// "}\n"
"{\n"
"map $ripplemap\n"
"}\n"
"{\n"
"map $null\n"//$refractiondepth
"}\n"
"program altwater#RIPPLEMAP#FRESNEL=4\n"
"}\n"
);
@ -4515,18 +4629,15 @@ char *Shader_DefaultBSPWater(shader_t *s, const char *shortname)
"{\n"
"map $refraction\n"
"}\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n"
"map $reflection\n"
"}\n"
// "{\n"
// "map $refractiondepth\n"
// "}\n"
"{\n"
"map $ripplemap\n"
"}\n"
"{\n"
"map $null\n"//$refractiondepth
"}\n"
"program altwater#REFLECT#RIPPLEMAP#FRESNEL=4\n"
"}\n"
);
@ -4715,22 +4826,7 @@ void Shader_DefaultBSPQ1(const char *shortname, shader_t *s, const void *args)
"{\n"
"program defaultwall#EIGHTBIT\n"
"{\n"
"map $paletted\n"//$diffuse\n"
"}\n"
"{\n"
"map $lightmap\n"
"}\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n"
"map $deluxmap\n"
"}\n"
"{\n"
"map $colourmap\n"//$fullbright\n"
"}\n"
"{\n"
"map $specular\n"
"map $colourmap\n"
"}\n"
"}\n"
);
@ -4841,14 +4937,6 @@ void Shader_DefaultSkin(const char *shortname, shader_t *s, const void *args)
"map $fullbright\n"
"blendfunc add\n"
"}\n"
"if $haveprogram\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n"
"map $specular\n"
"}\n"
"endif\n"
"}\n"
);
}

View File

@ -89,17 +89,17 @@ void Sh_Reset(void)
}
if (shadowmap[0])
{
R_DestroyTexture(shadowmap[0]);
Image_DestroyTexture(shadowmap[0]);
shadowmap[0] = r_nulltex;
}
if (shadowmap[1])
{
R_DestroyTexture(shadowmap[1]);
Image_DestroyTexture(shadowmap[1]);
shadowmap[1] = r_nulltex;
}
if (crepuscular_texture_id)
{
R_DestroyTexture(crepuscular_texture_id);
Image_DestroyTexture(crepuscular_texture_id);
crepuscular_texture_id = r_nulltex;
}
GLBE_FBO_Destroy(&crepuscular_fbo);
@ -700,10 +700,10 @@ static void SHM_RecursiveWorldNodeQ1_r (dlight_t *dl, mnode_t *node)
// clamp center of light to corner and check brightness
l = DotProduct (impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0];
s = l+0.5;if (s < 0) s = 0;else if (s > surf->extents[0]) s = surf->extents[0];
s = l - s;
s = (l - s)*surf->texinfo->vecscale[0];
l = DotProduct (impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3] - surf->texturemins[1];
t = l+0.5;if (t < 0) t = 0;else if (t > surf->extents[1]) t = surf->extents[1];
t = l - t;
t = (l - t)*surf->texinfo->vecscale[1];
// compare to minimum light
if ((s*s+t*t+dot*dot) < maxdist)
{
@ -894,11 +894,11 @@ static void SHM_RecursiveWorldNodeQ2_r (dlight_t *dl, mnode_t *node)
// clamp center of light to corner and check brightness
l = DotProduct (impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0];
s = l+0.5;if (s < 0) s = 0;else if (s > surf->extents[0]) s = surf->extents[0];
s = l - s;
s = l;if (s < 0) s = 0;else if (s > surf->extents[0]) s = surf->extents[0];
s = (l - s)*surf->texinfo->vecscale[0];
l = DotProduct (impact, surf->texinfo->vecs[1]) + surf->texinfo->vecs[1][3] - surf->texturemins[1];
t = l+0.5;if (t < 0) t = 0;else if (t > surf->extents[1]) t = surf->extents[1];
t = l - t;
t = l;if (t < 0) t = 0;else if (t > surf->extents[1]) t = surf->extents[1];
t = (l - t)*surf->texinfo->vecscale[1];
// compare to minimum light
if ((s*s+t*t+dot*dot) < maxdist)
{
@ -2690,7 +2690,7 @@ static void Sh_DrawBrushModelShadow(dlight_t *dl, entity_t *e)
qglVertexPointer(3, GL_FLOAT, sizeof(vecV_t), surf->mesh->xyz_array);
qglDrawArrays(GL_POLYGON, 0, surf->mesh->numvertexes);
// qglDrawRangeElements(GL_TRIANGLES, 0, surf->mesh->numvertexes, surf->mesh->numindexes, GL_INDEX_TYPE, surf->mesh->indexes);
RQuantAdd(RQUANT_SHADOWFACES, surf->mesh->numvertexes);
RQuantAdd(RQUANT_SHADOWINDICIES, surf->mesh->numvertexes);
for (v = 0; v < surf->mesh->numvertexes; v++)
{

View File

@ -1074,14 +1074,159 @@ void GL_CheckExtensions (void *(*getglfunction) (char *name))
static const char *glsl_hdrs[] =
{
"sys/defs.h",
"#define DEFS_DEFINED\n"
"#ifdef VERTEX_SHADER\n"
// "attribute vec3 v_position1;\n" //defined elsewhere, depending on fixed function availability
// "attribute vec3 v_position2;\n"
"attribute vec4 v_colour;\n"
"attribute vec2 v_texcoord;\n"
"attribute vec2 v_lmcoord;\n"
"attribute vec3 v_normal;\n"
"attribute vec3 v_svector;\n"
"attribute vec3 v_tvector;\n"
"attribute vec4 v_bone;\n" //fixme: make ints
"attribute vec4 v_weight;\n"
#if MAXRLIGHTMAPS > 1
"#define v_lmcoord1 v_lmcoord\n"
"attribute vec2 v_lmcoord2;\n"
"attribute vec2 v_lmcoord3;\n"
"attribute vec2 v_lmcoord4;\n"
"#define v_colour1 v_colour\n"
"attribute vec4 v_colour2;\n"
"attribute vec4 v_colour3;\n"
"attribute vec4 v_colour4;\n"
#endif
"#endif\n"
"uniform sampler2D s_diffuse;\n"
"uniform sampler2D s_normalmap;\n"
"uniform sampler2D s_specular;\n"
"uniform sampler2D s_upper;\n"
"uniform sampler2D s_lower;\n"
"uniform sampler2D s_fullbright;\n"
"uniform sampler2D s_paletted;\n"
"uniform sampler2D s_shadowmap;\n"
"uniform samplerCube s_projectionmap;\n"
"uniform sampler2D s_lightmap;\n"
"uniform sampler2D s_deluxmap;\n"
#if MAXRLIGHTMAPS > 1
"#define s_lightmap0 s_lightmap\n"
"uniform sampler2D s_lightmap1;\n"
"uniform sampler2D s_lightmap2;\n"
"uniform sampler2D s_lightmap3;\n"
"#define s_deluxmap0 s_deluxmap\n"
"uniform sampler2D s_deluxmap1;\n"
"uniform sampler2D s_deluxmap2;\n"
"uniform sampler2D s_deluxmap3;\n"
#endif
"#ifdef USEUBOS\n"
"layout(std140) uniform u_lightinfo\n"
"{\n"
"vec3 l_lightscreen;\n"
"float l_lightradius;\n"
"vec3 l_lightcolour;\n"
"float l_pad1;\n"
"vec3 l_lightcolourscale;\n"
"float l_pad2;\n"
"vec3 l_lightposition;\n"
"float l_pad3;\n"
"mat4 l_cubematrix;\n"
"vec4 l_shadowmapproj;\n"
"vec2 l_shadowmapscale;\n"
"vec2 l_pad4;\n"
"\n"
"};\n"
"layout(std140) uniform u_entityinfo\n"
"{\n"
"vec2 e_vblend;\n"
"vec2 e_pad1;\n"
"vec3 e_glowmod;\n"
"float e_pad2;\n"
"vec3 e_origin;\n"
"float e_pad3;\n"
"vec4 colormod;\n"
"vec3 e_glowmod;\n"
"float e_pad4;\n"
"vec3 e_uppercolour;\n"
"float e_pad5;\n"
"vec3 e_lowercolour;\n"
"float e_pad6;\n"
"vec3 w_fogcolour;\n"
"float w_fogalpha;\n"
"vec3 e_light_dir;\n"
"float w_fogdensity;\n"
"vec3 e_light_mul;\n"
"float w_fogdepthbias;\n"
"vec3 e_light_ambient;\n"
"float e_time;\n"
"};\n"
"layout(std140) unform u_bones\n"
"{\n"
"mat3x4 m_bones["STRINGIFY(MAX_GPU_BONES)"]\n"
"};\n"
"#else\n"
"uniform mat4 m_model;\n"
"uniform mat4 m_view;\n"
"uniform mat4 m_modelview;\n"
"uniform mat4 m_projection;\n"
// "uniform mat4 m_modelviewprojection;\n"
"uniform mat4 m_bones["STRINGIFY(MAX_GPU_BONES)"];\n"
"uniform mat4 m_invviewprojection;\n"
"uniform mat4 m_invmodelviewprojection;\n"
/*viewer properties*/
"uniform vec3 v_eyepos;\n"
"uniform vec4 w_fog[2];\n"
"#define w_fogcolour w_fog[0].rgb\n"
"#define w_fogalpha w_fog[0].a\n"
"#define w_fogdensity w_fog[1].x\n"
"#define w_fogdepthbias w_fog[1].y\n"
/*ent properties*/
//"uniform vec2 e_vblend;\n"
"#ifdef LIGHTSTYLED\n"
"uniform vec4 e_lmscale[4];\n"
"#else\n"
"uniform vec4 e_lmscale;\n"
"#endif\n"
"uniform vec3 e_origin;\n"
"uniform float e_time;\n"
"uniform vec3 e_eyepos;\n"
"uniform vec4 e_colour;\n"
"uniform vec4 e_colourident;\n"
"uniform vec3 e_glowmod;\n"
"uniform vec3 e_uppercolour;\n"
"uniform vec3 e_lowercolour;\n"
"uniform vec3 e_light_dir;\n"
"uniform vec3 e_light_mul;\n"
"uniform vec3 e_light_ambient;\n"
/*rtlight properties, use with caution*/
"uniform vec2 l_lightscreen;\n"
"uniform float l_lightradius;\n"
"uniform vec3 l_lightcolour;\n"
"uniform vec3 l_lightposition;\n"
"uniform vec3 l_lightcolourscale;\n"
"uniform mat4 l_cubematrix;\n"
"uniform vec4 l_shadowmapproj;\n"
"uniform vec2 l_shadowmapscale;\n"
"uniform vec2 e_rendertexturescale;\n"
"#endif\n"
,
"sys/skeletal.h",
"#ifndef DEFS_DEFINED\n"
"attribute vec3 v_normal;\n"
"attribute vec3 v_svector;\n"
"attribute vec3 v_tvector;\n"
"#endif\n"
"#ifdef SKELETAL\n"
"attribute vec4 v_bone;"
"attribute vec4 v_weight;"
"uniform mat3x4 m_bones["STRINGIFY(MAX_GPU_BONES)"];\n"
"#ifndef DEFS_DEFINED\n"
"attribute vec4 v_bone;"
"attribute vec4 v_weight;"
"uniform mat3x4 m_bones["STRINGIFY(MAX_GPU_BONES)"];\n"
"#endif\n"
"vec4 skeletaltransform()"
"{"
@ -1154,27 +1299,34 @@ static const char *glsl_hdrs[] =
"sys/fog.h",
"#ifdef FRAGMENT_SHADER\n"
"#ifdef FOG\n"
"#ifndef DEFS_DEFINED\n"
"uniform vec4 w_fog[2];\n"
"#define w_fogcolour w_fog[0].rgb\n"
"#define w_fogalpha w_fog[0].a\n"
"#define w_fogdensity w_fog[1].x\n"
"#define w_fogdepthbias w_fog[1].y\n"
"#endif\n"
"vec3 fog3(in vec3 regularcolour)"
"{"
"float z = w_fog[1].x * gl_FragCoord.z / gl_FragCoord.w;\n"
"z = max(0.0,z-w_fog[1].y);\n"
"float z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;\n"
"z = max(0.0,z-w_fogdepthbias);\n"
"#if #include \"cvar/r_fog_exp2\"\n"
"z *= z;\n"
"#endif\n"
"float fac = exp2(-(z * 1.442695));\n"
"fac = (1.0-w_fog[0].a) + (clamp(fac, 0.0, 1.0)*w_fog[0].a);\n"
"return mix(w_fog[0].rgb, regularcolour, fac);\n"
"fac = (1.0-w_fogalpha) + (clamp(fac, 0.0, 1.0)*w_fogalpha);\n"
"return mix(w_fogcolour, regularcolour, fac);\n"
"}\n"
"vec3 fog3additive(in vec3 regularcolour)"
"{"
"float z = w_fog[1].x * gl_FragCoord.z / gl_FragCoord.w;\n"
"z = max(0.0,z-w_fog[1].y);\n"
"float z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;\n"
"z = max(0.0,z-w_fogdepthbias);\n"
"#if #include \"cvar/r_fog_exp2\"\n"
"z *= z;\n"
"#endif\n"
"float fac = exp2(-(z * 1.442695));\n"
"fac = (1.0-w_fog[0].a) + (clamp(fac, 0.0, 1.0)*w_fog[0].a);\n"
"fac = (1.0-w_fogalpha) + (clamp(fac, 0.0, 1.0)*w_fogalpha);\n"
"return regularcolour * fac;\n"
"}\n"
"vec4 fog4(in vec4 regularcolour)"
@ -1183,24 +1335,24 @@ static const char *glsl_hdrs[] =
"}\n"
"vec4 fog4additive(in vec4 regularcolour)"
"{"
"float z = w_fog[1].x * gl_FragCoord.z / gl_FragCoord.w;\n"
"z = max(0.0,z-w_fog[1].y);\n"
"float z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;\n"
"z = max(0.0,z-w_fogdepthbias);\n"
"#if #include \"cvar/r_fog_exp2\"\n"
"z *= z;\n"
"#endif\n"
"float fac = exp2(-(z * 1.442695));\n"
"fac = (1.0-w_fog[0].a) + (clamp(fac, 0.0, 1.0)*w_fog[0].a);\n"
"fac = (1.0-w_fogalpha) + (clamp(fac, 0.0, 1.0)*w_fogalpha);\n"
"return regularcolour * vec4(fac, fac, fac, 1.0);\n"
"}\n"
"vec4 fog4blend(in vec4 regularcolour)"
"{"
"float z = w_fog[1].x * gl_FragCoord.z / gl_FragCoord.w;\n"
"z = max(0.0,z-w_fog[1].y);\n"
"float z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;\n"
"z = max(0.0,z-w_fogdepthbias);\n"
"#if #include \"cvar/r_fog_exp2\"\n"
"z *= z;\n"
"#endif\n"
"float fac = exp2(-(z * 1.442695));\n"
"fac = (1.0-w_fog[0].a) + (clamp(fac, 0.0, 1.0)*w_fog[0].a);\n"
"fac = (1.0-w_fogalpha) + (clamp(fac, 0.0, 1.0)*w_fogalpha);\n"
"return regularcolour * vec4(1.0, 1.0, 1.0, fac);\n"
"}\n"
"#else\n"
@ -1252,8 +1404,10 @@ static const char *glsl_hdrs[] =
"#undef r_glsl_pcf\n"
"#define r_glsl_pcf 9\n"
"#endif\n"
"#ifndef DEFS_DEFINED\n"
"uniform vec4 l_shadowmapproj;\n" //light projection matrix info
"uniform vec2 l_shadowmapscale;\n" //xy are the texture scale, z is 1, w is the scale.
"#endif\n"
"vec3 ShadowmapCoord(void)\n"
"{\n"
"#ifdef SPOT\n"
@ -1360,9 +1514,12 @@ qboolean GLSlang_GenerateIncludes(int maxstrings, int *strings, const GLchar *pr
return false;
/*emit up to the include*/
prstrings[*strings] = shadersource;
length[*strings] = incline - shadersource;
*strings += 1;
if (incline - shadersource)
{
prstrings[*strings] = shadersource;
length[*strings] = incline - shadersource;
*strings += 1;
}
incline += 8;
incline = COM_ParseOut (incline, incname, sizeof(incname));
@ -1474,6 +1631,7 @@ static GLhandleARB GLSlang_CreateShader (const char *name, int ver, const char *
//length[strings] = strlen(prstrings[strings]);
//strings++;
switch (shadertype)
{
case GL_FRAGMENT_SHADER_ARB:
@ -1654,8 +1812,20 @@ static GLhandleARB GLSlang_FinishShader(GLhandleARB shader, const char *name, GL
if (developer.ival)
{
unsigned int line;
char *eol, *start;
qglGetShaderSource(shader, sizeof(str), NULL, str);
Con_Printf("Shader \"%s\" source:\n%s", name, str);
Con_Printf("Shader \"%s\" source:\n", name, str);
for(start = str, line = 1; ;line++)
{
eol = strchr(start, '\n');
if (eol)
*eol=0;
Con_Printf("%3u: %s\n", line, start);
if (!eol)
break;
start = eol+1;
}
}
}
qglDeleteShaderObject_(shader);
@ -1901,6 +2071,29 @@ static void GLSlang_DeleteProg(program_t *prog, unsigned int permu)
static void GLSlang_ProgAutoFields(program_t *prog, char **cvarnames, int *cvartypes)
{
static const char *defaultsamplers[] =
{
"s_diffuse",
"s_normalmap",
"s_specular",
"s_upper",
"s_lower",
"s_fullbright",
"s_paletted",
"s_shadowmap",
"s_projectionmap",
"s_lightmap",
"s_deluxmap"
#if MAXRLIGHTMAPS > 1
,"s_lightmap1"
,"s_lightmap2"
,"s_lightmap3"
,"s_deluxmap1"
,"s_deluxmap2"
,"s_deluxmap3"
#endif
};
unsigned int i, p;
qboolean found;
int uniformloc;
@ -1997,6 +2190,9 @@ static void GLSlang_ProgAutoFields(program_t *prog, char **cvarnames, int *cvart
if (found)
prog->numparams++;
}
prog->numsamplers = 0;
prog->defaulttextures = 0;
/*set texture uniforms*/
for (p = 0; p < PERMUTATIONS; p++)
{
@ -2010,7 +2206,49 @@ static void GLSlang_ProgAutoFields(program_t *prog, char **cvarnames, int *cvart
Q_snprintfz(tmpname, sizeof(tmpname), "s_t%i", i);
uniformloc = qglGetUniformLocationARB(prog->permu[p].handle.glsl.handle, tmpname);
if (uniformloc != -1)
{
qglUniform1iARB(uniformloc, i);
if (prog->numsamplers < i+1)
prog->numsamplers = i+1;
}
}
for (i = 0; i < sizeof(defaultsamplers)/sizeof(defaultsamplers[0]); i++)
{
//figure out which ones are needed.
if (prog->defaulttextures & (1u<<i))
continue; //don't spam
uniformloc = qglGetUniformLocationARB(prog->permu[p].handle.glsl.handle, defaultsamplers[i]);
if (uniformloc != -1)
prog->defaulttextures |= (1u<<i);
}
}
//multiple lightmaps is kinda hacky. if any are set, all must be.
if (prog->defaulttextures & ((1u<<11) | (1u<<12) | (1u<<13)))
prog->defaulttextures |=((1u<<11) | (1u<<12) | (1u<<13));
if (prog->defaulttextures & ((1u<<14) | (1u<<15) | (1u<<16)))
prog->defaulttextures |=((1u<<14) | (1u<<15) | (1u<<16));
if (prog->defaulttextures)
{
unsigned int sampnum;
/*set default texture uniforms*/
for (p = 0; p < PERMUTATIONS; p++)
{
if (!prog->permu[p].handle.glsl.handle)
continue;
sampnum = prog->numsamplers;
GLSlang_UseProgram(prog->permu[p].handle.glsl.handle);
for (i = 0; i < sizeof(defaultsamplers)/sizeof(defaultsamplers[0]); i++)
{
if (prog->defaulttextures & (1u<<i))
{
uniformloc = qglGetUniformLocationARB(prog->permu[p].handle.glsl.handle, defaultsamplers[i]);
if (uniformloc != -1)
qglUniform1iARB(uniformloc, sampnum);
sampnum++;
}
}
}
}
}

View File

@ -400,6 +400,7 @@ HDC (WINAPI *qwglGetCurrentDC)(VOID);
PROC (WINAPI *qwglGetProcAddress)(LPCSTR);
BOOL (WINAPI *qwglMakeCurrent)(HDC, HGLRC);
BOOL (WINAPI *qSwapBuffers)(HDC);
BOOL (WINAPI *qwglSwapLayerBuffers)(HDC, UINT);
int (WINAPI *qChoosePixelFormat)(HDC, CONST PIXELFORMATDESCRIPTOR *);
BOOL (WINAPI *qSetPixelFormat)(HDC, int, CONST PIXELFORMATDESCRIPTOR *);
int (WINAPI *qDescribePixelFormat)(HDC, int, UINT, LPPIXELFORMATDESCRIPTOR);
@ -429,6 +430,23 @@ HGLRC (APIENTRY *qwglCreateContextAttribsARB)(HDC hDC, HGLRC hShareContext, cons
#define WGL_NO_RESET_NOTIFICATION_ARB 0x8261
#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252
//pixel format stuff
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
#define WGL_ACCELERATION_ARB 0x2003
#define WGL_SWAP_LAYER_BUFFERS_ARB 0x2006
#define WGL_SUPPORT_OPENGL_ARB 0x2010
#define WGL_DOUBLE_BUFFER_ARB 0x2011
#define WGL_STEREO_ARB 0x2012
#define WGL_COLOR_BITS_ARB 0x2014
#define WGL_ALPHA_BITS_ARB 0x201B
#define WGL_DEPTH_BITS_ARB 0x2022
#define WGL_STENCIL_BITS_ARB 0x2023
#define WGL_FULL_ACCELERATION_ARB 0x2027
qboolean shouldforcepixelformat;
int forcepixelformat;
int currentpixelformat;
qboolean GLInitialise (char *renderer)
{
if (!hInstGL || strcmp(reqminidriver, renderer))
@ -500,6 +518,7 @@ qboolean GLInitialise (char *renderer)
if (usingminidriver)
{
qwglSwapLayerBuffers = NULL;
qSwapBuffers = (void *)getglfunc("wglSwapBuffers");
qChoosePixelFormat = (void *)getglfunc("wglChoosePixelFormat");
qSetPixelFormat = (void *)getglfunc("wglSetPixelFormat");
@ -507,6 +526,7 @@ qboolean GLInitialise (char *renderer)
}
else
{
qwglSwapLayerBuffers = (void *)getwglfunc("wglSwapLayerBuffers");
qSwapBuffers = SwapBuffers;
qChoosePixelFormat = ChoosePixelFormat;
qSetPixelFormat = SetPixelFormat;
@ -1569,7 +1589,13 @@ void VID_WndAlpha_Override_Callback(struct cvar_s *var, char *oldvalue)
void GLVID_SwapBuffers (void)
{
qSwapBuffers(maindc);
if (qwglSwapLayerBuffers)
{
if (!qwglSwapLayerBuffers(maindc, WGL_SWAP_MAIN_PLANE))
qwglSwapLayerBuffers = NULL;
}
else
qSwapBuffers(maindc);
// handle the mouse state when windowed if that's changed
@ -1673,25 +1699,13 @@ void GLVID_Shutdown (void)
gammaworks = false;
GLBE_Shutdown();
Image_Shutdown();
VID_UnSetMode();
}
//==========================================================================
#define WGL_DRAW_TO_WINDOW_ARB 0x2001
#define WGL_ACCELERATION_ARB 0x2003
#define WGL_SUPPORT_OPENGL_ARB 0x2010
#define WGL_DOUBLE_BUFFER_ARB 0x2011
#define WGL_STEREO_ARB 0x2012
#define WGL_COLOR_BITS_ARB 0x2014
#define WGL_ALPHA_BITS_ARB 0x201B
#define WGL_DEPTH_BITS_ARB 0x2022
#define WGL_STENCIL_BITS_ARB 0x2023
#define WGL_FULL_ACCELERATION_ARB 0x2027
qboolean shouldforcepixelformat;
int forcepixelformat;
BOOL CheckForcePixelFormat(rendererstate_t *info)
{
if (qwglChoosePixelFormatARB && (info->multisample || info->srgb))
@ -1838,7 +1852,6 @@ BOOL bSetupPixelFormat(HDC hDC, rendererstate_t *info)
0, // reserved
0, 0, 0 // layer masks ignored
};
int pixelformat;
TRACE(("dbg: bSetupPixelFormat: ChoosePixelFormat\n"));
@ -1850,18 +1863,18 @@ BOOL bSetupPixelFormat(HDC hDC, rendererstate_t *info)
if (shouldforcepixelformat && qwglChoosePixelFormatARB) //the extra && is paranoia
{
shouldforcepixelformat = false;
pixelformat = forcepixelformat;
currentpixelformat = forcepixelformat;
}
else
{
if ((pixelformat = qChoosePixelFormat(hDC, &pfd)))
if ((currentpixelformat = qChoosePixelFormat(hDC, &pfd)))
{
TRACE(("dbg: ChoosePixelFormat 1: worked\n"));
if (qSetPixelFormat(hDC, pixelformat, &pfd))
if (qSetPixelFormat(hDC, currentpixelformat, &pfd))
{
TRACE(("dbg: bSetupPixelFormat: we can use the stencil buffer. woot\n"));
qDescribePixelFormat(hDC, pixelformat, sizeof(pfd), &pfd);
qDescribePixelFormat(hDC, currentpixelformat, sizeof(pfd), &pfd);
FixPaletteInDescriptor(hDC, &pfd);
if ((pfd.dwFlags & PFD_GENERIC_FORMAT) && !(pfd.dwFlags & PFD_GENERIC_ACCELERATED))
@ -1877,16 +1890,16 @@ BOOL bSetupPixelFormat(HDC hDC, rendererstate_t *info)
pfd.cStencilBits = 0;
if ( (pixelformat = qChoosePixelFormat(hDC, &pfd)) == 0 )
if ( (currentpixelformat = qChoosePixelFormat(hDC, &pfd)) == 0 )
{
Con_Printf("bSetupPixelFormat: ChoosePixelFormat failed (%i)\n", (int)GetLastError());
return FALSE;
}
}
qDescribePixelFormat(hDC, pixelformat, sizeof(pfd), &pfd);
qDescribePixelFormat(hDC, currentpixelformat, sizeof(pfd), &pfd);
if (qSetPixelFormat(hDC, pixelformat, &pfd) == FALSE)
if (qSetPixelFormat(hDC, currentpixelformat, &pfd) == FALSE)
{
Con_Printf("bSetupPixelFormat: SetPixelFormat failed (%i)\n", (int)GetLastError());
return FALSE;

View File

@ -119,16 +119,17 @@ void LightLoadEntities(char *entstring)
#define DEFAULTLIGHTLEVEL 300
mentity_t *mapent;
char key[1024];
char value[1024];
int i;
int switchedstyle=32;
num_entities = 0;
while(1)
{
entstring = COM_Parse(entstring);
if (!entstring || !*com_token)
entstring = COM_ParseOut(entstring, key, sizeof(key));
if (!entstring || !*key)
break;
if (strcmp(com_token, "{"))
if (strcmp(key, "{"))
{ //someone messed up. Stop parsing.
Con_Printf("token wasn't an open brace\n");
break;
@ -141,12 +142,11 @@ void LightLoadEntities(char *entstring)
mapent->colour[2] = 0;
while(1)
{
entstring = COM_Parse(entstring);
if (!strcmp(com_token, "}"))
entstring = COM_ParseOut(entstring, key, sizeof(key));
if (!strcmp(key, "}"))
break;
strcpy(key, com_token);
entstring = COM_Parse(entstring);
ParseEpair(mapent, key, com_token);
entstring = COM_ParseOut(entstring, value, sizeof(value));
ParseEpair(mapent, key, value);
}
if (!mapent->colour[0] && !mapent->colour[1] && !mapent->colour[2])
{
@ -677,9 +677,9 @@ static void SingleLightFace (mentity_t *light, llightinfo_t *l)
lightsamp[c][1] += add*light->colour[1];
lightsamp[c][2] += add*light->colour[2];
norms[c][0] -= add * incoming[0]; //Quake doesn't make sence some times.
norms[c][1] -= add * incoming[1];
norms[c][2] -= add * incoming[2];
norms[c][0] += add * incoming[0]; //Quake doesn't make sence some times.
norms[c][1] += add * incoming[1];
norms[c][2] += add * incoming[2];
if (add > 1) // ignore real tiny lights
hit = true;
@ -939,12 +939,17 @@ void LightFace (int surfnum)
temp[0] = DotProduct(wnorm, svector);
temp[1] = DotProduct(wnorm, tvector);
temp[2] = DotProduct(wnorm, l.facenormal);
VectorNormalize(temp);
temp[2] += 0.5;
VectorNormalize(temp);
*dulout++ = (-temp[0]+1)*128;
*dulout++ = (-temp[1]+1)*128;
*dulout++ = (-temp[2]+1)*128;
if (!temp[0] && !temp[1] && !temp[2])
VectorSet(temp, 0, 0, 1);
else
{
VectorNormalize(temp);
// temp[2] += 0.5;
VectorNormalize(temp);
}
*dulout++ = (temp[0]+1)*128;
*dulout++ = (temp[1]+1)*128;
*dulout++ = (temp[2]+1)*128;
}
}
}

View File

@ -47,19 +47,16 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"#define s_refract s_t0\n"
"#define s_reflect s_t1\n"
"#define s_ripplemap s_t2\n"
"#define s_refractdepth s_t3\n"
"uniform float cvar_r_glsl_turbscale;\n"
"uniform sampler2D s_t0; //refract\n"
"uniform sampler2D s_t1; //normalmap\n"
"uniform sampler2D s_t2; //diffuse/reflection\n"
"#ifdef DEPTH\n"
"uniform sampler2D s_t3; //refraction depth\n"
"#define s_ripplemap s_t4\n"
"#else\n"
"#define s_ripplemap s_t3\n"
"#endif\n"
"#ifdef RIPPLEMAP\n"
"uniform sampler2D s_refract; //refract\n"
"uniform sampler2D s_reflect; //reflection\n"
"uniform sampler2D s_refractdepth; //refraction depth\n"
"uniform sampler2D s_ripplemap; //ripplemap\n"
"#endif\n"
"uniform float e_time;\n"
"void main (void)\n"
@ -77,8 +74,8 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"ntc.t = tc.t + sin(tc.s+e_time)*0.125;\n"
//generate the two wave patterns from the normalmap
"n = (texture2D(s_t1, TXSCALE*tc + vec2(e_time*0.1, 0.0)).xyz);\n"
"n += (texture2D(s_t1, TXSCALE*tc - vec2(0, e_time*0.097)).xyz);\n"
"n = (texture2D(s_normalmap, TXSCALE*tc + vec2(e_time*0.1, 0.0)).xyz);\n"
"n += (texture2D(s_normalmap, TXSCALE*tc - vec2(0, e_time*0.097)).xyz);\n"
"n -= 1.0 - 4.0/256.0;\n"
"#ifdef RIPPLEMAP\n"
@ -97,7 +94,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"sdepth = mix(near, far, sdepth);\n"
//get depth value at the ground beyond the surface.
"float gdepth = texture2D(s_t3, stc).x;\n"
"float gdepth = texture2D(s_refractdepth, stc).x;\n"
"gdepth = (2.0*near) / (far + near - gdepth * (far - near));\n"
"if (gdepth >= 0.5)\n"
"{\n"
@ -119,16 +116,16 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
//refraction image (and water fog, if possible)
"refr = texture2D(s_t0, stc + n.st*STRENGTH*cvar_r_glsl_turbscale).rgb * TINT;\n"
"refr = texture2D(s_refract, stc + n.st*STRENGTH*cvar_r_glsl_turbscale).rgb * TINT;\n"
"#ifdef DEPTH\n"
"refr = mix(refr, FOGTINT, min(depth/4096.0, 1.0));\n"
"#endif\n"
//reflection/diffuse
"#ifdef REFLECT\n"
"refl = texture2D(s_t2, stc - n.st*STRENGTH*cvar_r_glsl_turbscale).rgb;\n"
"refl = texture2D(s_reflect, stc - n.st*STRENGTH*cvar_r_glsl_turbscale).rgb;\n"
"#else\n"
"refl = texture2D(s_t2, ntc).xyz;\n"
"refl = texture2D(s_diffuse, ntc).xyz;\n"
"#endif\n"
//FIXME: add specular
@ -570,6 +567,8 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"!!cvarf r_glsl_offsetmapping_scale\n"
"!!cvarf gl_specular\n"
"#include \"sys/defs.h\"\n"
//standard shader used for models.
//must support skeletal and 2-way vertex blending or Bad Things Will Happen.
//the vertex shader is responsible for calculating lighting values.
@ -585,13 +584,6 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#ifdef VERTEX_SHADER\n"
"#include \"sys/skeletal.h\"\n"
"attribute vec2 v_texcoord;\n"
"uniform vec3 e_light_dir;\n"
"uniform vec3 e_light_mul;\n"
"uniform vec3 e_light_ambient;\n"
"#if defined(SPECULAR) || defined(OFFSETMAPPING)\n"
"uniform vec3 e_eyepos;\n"
"#endif\n"
"void main ()\n"
"{\n"
"#if defined(SPECULAR)||defined(OFFSETMAPPING)\n"
@ -615,25 +607,8 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"#include \"sys/fog.h\"\n"
"uniform sampler2D s_t0;\n"
"#ifdef LOWER\n"
"uniform sampler2D s_t1;\n"
"uniform vec3 e_lowercolour;\n"
"#endif\n"
"#ifdef UPPER\n"
"uniform sampler2D s_t2;\n"
"uniform vec3 e_uppercolour;\n"
"#endif\n"
"#ifdef FULLBRIGHT\n"
"uniform sampler2D s_t3;\n"
"#endif\n"
"#if defined(BUMP)\n"
"uniform sampler2D s_t4;\n"
"#endif\n"
"#if defined(SPECULAR)\n"
"uniform sampler2D s_t5;\n"
"uniform float cvar_gl_specular;\n"
"#endif\n"
@ -641,31 +616,28 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#include \"sys/offsetmapping.h\"\n"
"#endif\n"
"uniform vec4 e_colourident;\n"
"void main ()\n"
"{\n"
"vec4 col, sp;\n"
"#ifdef OFFSETMAPPING\n"
"vec2 tcoffsetmap = offsetmap(s_t4, tc, eyevector);\n"
"vec2 tcoffsetmap = offsetmap(s_normalmap, tc, eyevector);\n"
"#define tc tcoffsetmap\n"
"#endif\n"
"col = texture2D(s_t0, tc);\n"
"col = texture2D(s_diffuse, tc);\n"
"#ifdef UPPER\n"
"vec4 uc = texture2D(s_t2, tc);\n"
"vec4 uc = texture2D(s_upper, tc);\n"
"col.rgb += uc.rgb*e_uppercolour*uc.a;\n"
"#endif\n"
"#ifdef LOWER\n"
"vec4 lc = texture2D(s_t1, tc);\n"
"vec4 lc = texture2D(s_lower, tc);\n"
"col.rgb += lc.rgb*e_lowercolour*lc.a;\n"
"#endif\n"
"#if defined(BUMP) && defined(SPECULAR)\n"
"vec3 bumps = normalize(vec3(texture2D(s_t4, tc)) - 0.5);\n"
"vec4 specs = texture2D(s_t5, tc);\n"
"vec3 bumps = normalize(vec3(texture2D(s_normalmap, tc)) - 0.5);\n"
"vec4 specs = texture2D(s_specular, tc);\n"
"vec3 halfdir = normalize(normalize(eyevector) + vec3(0.0, 0.0, 1.0));\n"
"float spec = pow(max(dot(halfdir, bumps), 0.0), 32.0 * specs.a);\n"
@ -675,7 +647,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"col.rgb *= light;\n"
"#ifdef FULLBRIGHT\n"
"vec4 fb = texture2D(s_t3, tc);\n"
"vec4 fb = texture2D(s_fullbright, tc);\n"
// col.rgb = mix(col.rgb, fb.rgb, fb.a);
"col.rgb += fb.rgb * fb.a;\n"
"#endif\n"
@ -823,9 +795,8 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"float3 l_lightcolour;\n"
"float3 l_lightposition;\n"
"sampler s_t0; /*diffuse*/\n"
"sampler s_t1; /*normal*/\n"
"sampler s_t2; /*specular*/\n"
"sampler s_diffuse; /*diffuse*/\n"
"sampler s_fullbright; /*normal*/\n"
"float4 main (v2f inp) : COLOR0\n"
"{\n"
"float2 tccoord;\n"
@ -836,10 +807,10 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"dir.xy /= 0.5*length(dir);\n"
"tccoord = (dir.xy + e_time*0.03125);\n"
"float4 solid = tex2D(s_t0, tccoord);\n"
"float4 solid = tex2D(s_diffuse, tccoord);\n"
"tccoord = (dir.xy + e_time*0.0625);\n"
"float4 clouds = tex2D(s_t1, tccoord);\n"
"float4 clouds = tex2D(s_fullbright, tccoord);\n"
"return float4((solid.rgb*(1.0-clouds.a)) + (clouds.a*clouds.rgb), 1);\n"
"}\n"
@ -1045,6 +1016,8 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"!!cvarf r_glsl_offsetmapping_scale\n"
"!!cvarf gl_specular\n"
"#include \"sys/defs.h\"\n"
//this is what normally draws all of your walls, even with rtlights disabled
//note that the '286' preset uses drawflat_walls instead.
@ -1063,19 +1036,6 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"attribute vec2 v_lmcoord;\n"
"#ifdef LIGHTSTYLED\n"
"attribute vec2 v_lmcoord2;\n"
"attribute vec2 v_lmcoord3;\n"
"attribute vec2 v_lmcoord4;\n"
"#endif\n"
"#if defined(OFFSETMAPPING) || defined(SPECULAR)\n"
"uniform vec3 e_eyepos;\n"
"attribute vec3 v_normal;\n"
"attribute vec3 v_svector;\n"
"attribute vec3 v_tvector;\n"
"#endif\n"
"void main ()\n"
"{\n"
"#if defined(OFFSETMAPPING) || defined(SPECULAR)\n"
@ -1099,50 +1059,9 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#ifdef FRAGMENT_SHADER\n"
//samplers
"#define s_diffuse s_t0\n"
"#define s_lightmap0 s_t1\n"
"#define s_normalmap s_t2\n"
"#define s_delux0 s_t3\n"
"#define s_fullbright s_t4\n"
"#define s_specular s_t5\n"
"#define s_lightmap1 s_t6\n"
"#define s_lightmap2 s_t7\n"
"#define s_lightmap3 s_t8\n"
"#define s_delux1 s_t9\n"
"#define s_delux2 s_t10\n"
"#define s_delux3 s_t11\n"
"#define s_paletted s_diffuse\n"
"#define s_colourmap s_fullbright\n"
"#define s_colourmap s_t0\n"
"uniform sampler2D s_colourmap;\n"
"uniform sampler2D s_diffuse;\n"
"uniform sampler2D s_lightmap0;\n"
"#if defined(BUMP) && (defined(OFFSETMAPPING) || defined(DELUXE) || defined(SPECULAR))\n"
"uniform sampler2D s_normalmap;\n"
"#endif\n"
"#ifdef DELUXE\n"
"uniform sampler2D s_delux0;\n"
"#endif\n"
"#if defined(FULLBRIGHT) || defined(EIGHTBIT)\n"
"uniform sampler2D s_fullbright;\n"
"#endif\n"
"#ifdef SPECULAR\n"
"uniform sampler2D s_specular;\n"
"#endif\n"
"#ifdef LIGHTSTYLED\n"
"uniform sampler2D s_lightmap1;\n"
"uniform sampler2D s_lightmap2;\n"
"uniform sampler2D s_lightmap3;\n"
"uniform sampler2D s_delux1;\n"
"uniform sampler2D s_delux2;\n"
"uniform sampler2D s_delux3;\n"
"#endif\n"
"#ifdef LIGHTSTYLED\n"
"uniform vec4 e_lmscale[4];\n"
"#else\n"
"uniform vec4 e_lmscale;\n"
"#endif\n"
"uniform vec4 e_colourident;\n"
"#ifdef SPECULAR\n"
"uniform float cvar_gl_specular;\n"
"#endif\n"
@ -1179,10 +1098,10 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#ifdef LIGHTSTYLED\n"
"vec3 lightmaps;\n"
"#ifdef DELUXE\n"
"lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb * dot(norm, 2.0*texture2D(s_delux0, lm0).rgb-0.5);\n"
"lightmaps += texture2D(s_lightmap1, lm1).rgb * e_lmscale[1].rgb * dot(norm, 2.0*texture2D(s_delux1, lm1).rgb-0.5);\n"
"lightmaps += texture2D(s_lightmap2, lm2).rgb * e_lmscale[2].rgb * dot(norm, 2.0*texture2D(s_delux2, lm2).rgb-0.5);\n"
"lightmaps += texture2D(s_lightmap3, lm3).rgb * e_lmscale[3].rgb * dot(norm, 2.0*texture2D(s_delux3, lm3).rgb-0.5);\n"
"lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb * dot(norm, 2.0*texture2D(s_deluxmap0, lm0).rgb-0.5);\n"
"lightmaps += texture2D(s_lightmap1, lm1).rgb * e_lmscale[1].rgb * dot(norm, 2.0*texture2D(s_deluxmap1, lm1).rgb-0.5);\n"
"lightmaps += texture2D(s_lightmap2, lm2).rgb * e_lmscale[2].rgb * dot(norm, 2.0*texture2D(s_deluxmap2, lm2).rgb-0.5);\n"
"lightmaps += texture2D(s_lightmap3, lm3).rgb * e_lmscale[3].rgb * dot(norm, 2.0*texture2D(s_deluxmap3, lm3).rgb-0.5);\n"
"#else\n"
"lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb;\n"
"lightmaps += texture2D(s_lightmap1, lm1).rgb * e_lmscale[1].rgb;\n"
@ -1190,10 +1109,12 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"lightmaps += texture2D(s_lightmap3, lm3).rgb * e_lmscale[3].rgb;\n"
"#endif\n"
"#else\n"
"vec3 lightmaps = (texture2D(s_lightmap0, lm0) * e_lmscale).rgb;\n"
"vec3 lightmaps = (texture2D(s_lightmap, lm0) * e_lmscale).rgb;\n"
//modulate by the bumpmap dot light
"#ifdef DELUXE\n"
"lightmaps *= dot(norm, 2.0*(texture2D(s_delux0, lm0).rgb-0.5));\n"
"vec3 delux = 2.0*(texture2D(s_deluxmap, lm0).rgb-0.5);\n"
"lightmaps *= 1.0 / max(0.25, delux.z); //counter the darkening from deluxmaps\n"
"lightmaps *= dot(norm, delux);\n"
"#endif\n"
"#endif\n"
@ -1202,7 +1123,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"vec4 specs = texture2D(s_specular, tc);\n"
"#ifdef DELUXE\n"
//not lightstyled...
"vec3 halfdir = normalize(normalize(eyevector) + 2.0*(texture2D(s_delux0, lm0).rgb-0.5)); //this norm should be the deluxemap info instead\n"
"vec3 halfdir = normalize(normalize(eyevector) + 2.0*(texture2D(s_deluxmap0, lm0).rgb-0.5)); //this norm should be the deluxemap info instead\n"
"#else\n"
"vec3 halfdir = normalize(normalize(eyevector) + vec3(0.0, 0.0, 1.0)); //this norm should be the deluxemap info instead\n"
"#endif\n"
@ -1217,7 +1138,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#ifdef EIGHTBIT //FIXME: with this extra flag, half the permutations are redundant.\n"
"lightmaps *= 0.5; //counter the fact that the colourmap contains overbright values and logically ranges from 0 to 2 intead of to 1.\n"
"float pal = texture2D(s_diffuse, tc).r; //the palette index. hopefully not interpolated.\n"
"float pal = texture2D(s_paletted, tc).r; //the palette index. hopefully not interpolated.\n"
"lightmaps -= 1.0 / 128.0; //software rendering appears to round down, so make sure we favour the lower values instead of rounding to the nearest\n"
"gl_FragColor.r = texture2D(s_colourmap, vec2(pal, 1.0-lightmaps.r)).r; //do 3 lookups. this is to cope with lit files, would be a waste to not support those.\n"
"gl_FragColor.g = texture2D(s_colourmap, vec2(pal, 1.0-lightmaps.g)).g; //its not very softwarey, but re-palettizing is ugly.\n"
@ -1298,8 +1219,10 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
#endif
#ifdef GLQUAKE
{QR_OPENGL, 110, "defaultwarp",
"!!cvarf r_wateralpha\n"
"!!permu FOG\n"
"!!cvarf r_wateralpha\n"
"#include \"sys/defs.h\"\n"
//this is the shader that's responsible for drawing default q1 turbulant water surfaces
//this is expected to be moderately fast.
@ -1307,16 +1230,16 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#include \"sys/fog.h\"\n"
"varying vec2 tc;\n"
"#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"void main ()\n"
"{\n"
"tc = v_texcoord.st;\n"
"#ifdef FLOW\n"
"tc.s += e_time * -0.5;\n"
"#endif\n"
"gl_Position = ftetransform();\n"
"}\n"
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"uniform float e_time;\n"
"#ifndef ALPHA\n"
"uniform float cvar_r_wateralpha;\n"
"#define USEALPHA cvar_r_wateralpha\n"
@ -1328,7 +1251,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"vec2 ntc;\n"
"ntc.s = tc.s + sin(tc.t+e_time)*0.125;\n"
"ntc.t = tc.t + sin(tc.s+e_time)*0.125;\n"
"vec3 ts = vec3(texture2D(s_t0, ntc));\n"
"vec3 ts = vec3(texture2D(s_diffuse, ntc));\n"
"gl_FragColor = fog4(vec4(ts, USEALPHA));\n"
"}\n"
"#endif\n"
@ -1361,13 +1284,13 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#ifdef FRAGMENT_SHADER\n"
"float cvar_r_wateralpha;\n"
"float e_time;\n"
"sampler s_t0;\n"
"sampler s_diffuse;\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"
"float3 ts = tex2D(s_diffuse, ntc).xyz;\n"
"return float4(ts, cvar_r_wateralpha);\n"
"}\n"
@ -2108,15 +2031,14 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n"
"#ifdef FRAGMENT_SHADER\n"
"sampler s_t0;\n"
"sampler s_t1;\n"
"sampler s_diffuse;\n"
"float l_lightradius;\n"
"float3 l_lightcolour;\n"
"float4 main (v2f inp) : COLOR0\n"
"{\n"
"float3 col = l_lightcolour;\n"
"col *= max(1.0 - dot(inp.lpos, inp.lpos)/(l_lightradius*l_lightradius), 0.0);\n"
"float3 diff = tex2D(s_t0, inp.tc);\n"
"float3 diff = tex2D(s_diffuse, inp.tc);\n"
"return float4(diff * col, 1);\n"
"}\n"
"#endif\n"

View File

@ -451,11 +451,14 @@ typedef struct programshared_s
{
int refs;
qboolean nofixedcompat;
int numparams;
unsigned short numparams;
unsigned short numsamplers; //shader system can strip any passes above this
unsigned int defaulttextures; //diffuse etc
shaderprogparm_t parm[SHADER_PROGPARMS_MAX];
struct {
union programhandle_u handle;
unsigned int attrmask;
unsigned int texmask; //'standard' textures that are in use
unsigned int parm[SHADER_PROGPARMS_MAX];
} permu[PERMUTATIONS];
} program_t;
@ -558,6 +561,18 @@ struct shader_s
shader_gen_t *generator;
char *genargs;
struct shader_clutter_s
{
struct shader_clutter_s *next;
float scalemin;
float scalemax;
float anglemin;
float anglemax;
float spacing;
float zofs;
char modelname[1];
} *clutter;
// meshfeatures_t features;
bucket_t bucket;
};
@ -578,7 +593,9 @@ shader_t *R_RegisterShader_Vertex (const char *name);
shader_t *R_RegisterShader_Flare (const char *name);
shader_t *QDECL R_RegisterSkin (const char *shadername, const char *modname);
shader_t *R_RegisterCustom (const char *name, unsigned int usageflags, shader_gen_t *defaultgen, const void *args);
//once loaded, most shaders should have one of the following two calls used upon it
void QDECL R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader);
void QDECL R_BuildLegacyTexnums(shader_t *shader, const char *subpath, unsigned int loadflags, uploadfmt_t basefmt, size_t width, size_t height, qbyte *mipdata[4], qbyte *palette);
void R_RemapShader(const char *sourcename, const char *destname, float timeoffset);
cin_t *R_ShaderGetCinematic(shader_t *s);
@ -691,9 +708,9 @@ void GLBE_Scissor(srect_t *rect);
void GLBE_SubmitMeshes (qboolean drawworld, int start, int stop);
//void GLBE_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destcol, texid_t destdepth, qboolean usedepth);
void GLBE_RenderToTextureUpdate2d(qboolean destchanged);
void GLBE_VBO_Begin(vbobctx_t *ctx, unsigned int maxsize);
void GLBE_VBO_Data(vbobctx_t *ctx, void *data, unsigned int size, vboarray_t *varray);
void GLBE_VBO_Finish(vbobctx_t *ctx, void *edata, unsigned int esize, vboarray_t *earray);
void GLBE_VBO_Begin(vbobctx_t *ctx, size_t maxsize);
void GLBE_VBO_Data(vbobctx_t *ctx, void *data, size_t size, vboarray_t *varray);
void GLBE_VBO_Finish(vbobctx_t *ctx, void *edata, size_t esize, vboarray_t *earray);
void GLBE_VBO_Destroy(vboarray_t *vearray);
void GLBE_FBO_Sources(texid_t sourcecolour, texid_t sourcedepth);

View File

@ -18,6 +18,13 @@
/* Define this if you get warnings about undefined structures. */
/* #undef INCOMPLETE_TYPES_BROKEN */
/* Define "boolean" as unsigned char, not int, on Windows systems. */
#ifdef _WIN32
#ifndef __RPCNDR_H__ /* don't conflict if rpcndr.h already read */
typedef unsigned char boolean;
#endif
#define HAVE_BOOLEAN /* prevent jmorecfg.h from redefining it */
#endif
#ifdef JPEG_INTERNALS

View File

@ -2,7 +2,7 @@
* jerror.h
*
* Copyright (C) 1994-1997, Thomas G. Lane.
* Modified 1997-2009 by Guido Vollbeding.
* Modified 1997-2012 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@ -106,11 +106,11 @@ JMESSAGE(JERR_QUANT_COMPONENTS,
"Cannot quantize more than %d color components")
JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors")
JMESSAGE(JERR_QUANT_MANY_COLORS, "Cannot quantize to more than %d colors")
JMESSAGE(JERR_SOF_BEFORE, "Invalid JPEG file structure: %s before SOF")
JMESSAGE(JERR_SOF_DUPLICATE, "Invalid JPEG file structure: two SOF markers")
JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker")
JMESSAGE(JERR_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x")
JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers")
JMESSAGE(JERR_SOS_NO_SOF, "Invalid JPEG file structure: SOS before SOF")
JMESSAGE(JERR_TFILE_CREATE, "Failed to create temporary file %s")
JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file")
JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file")

View File

@ -2,7 +2,7 @@
* jmorecfg.h
*
* Copyright (C) 1991-1997, Thomas G. Lane.
* Modified 1997-2009 by Guido Vollbeding.
* Modified 1997-2012 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@ -150,6 +150,24 @@ typedef unsigned short UINT16;
typedef unsigned int UINT16;
#endif /* HAVE_UNSIGNED_SHORT */
/* INT16 must hold at least the values -32768..32767. */
#ifndef XMD_H /* X11/xmd.h correctly defines INT16 */
typedef short INT16;
#endif
/* INT32 must hold at least signed 32-bit values. */
#ifndef XMD_H /* X11/xmd.h correctly defines INT32 */
#ifndef _BASETSD_H_ /* Microsoft defines it in basetsd.h */
#ifndef _BASETSD_H /* MinGW is slightly different */
#ifndef QGLOBAL_H /* Qt defines it in qglobal.h */
typedef long INT32;
#endif
#endif
#endif
#endif
/* Datatype used for image dimensions. The JPEG standard only supports
* images up to 64K*64K due to 16-bit fields in SOF markers. Therefore
* "unsigned int" is sufficient on all machines. However, if you need to
@ -192,6 +210,26 @@ typedef unsigned int JDIMENSION;
#endif
/* The noreturn type identifier is used to declare functions
* which cannot return.
* Compilers can thus create more optimized code and perform
* better checks for warnings and errors.
* Static analyzer tools can make improved inferences about
* execution paths and are prevented from giving false alerts.
*
* Unfortunately, the proposed specifications of corresponding
* extensions in the Dec 2011 ISO C standard revision (C11),
* GCC, MSVC, etc. are not viable.
* Thus we introduce a user defined type to declare noreturn
* functions at least for clarity. A proper compiler would
* have a suitable noreturn type to match in place of void.
*/
#ifndef HAVE_NORETURN_T
typedef void noreturn_t;
#endif
/* Here is the pseudo-keyword for declaring pointers that must be "far"
* on 80x86 machines. Most of the specialized coding for 80x86 is handled
* by just saying "FAR *" where such a pointer is needed. In a few places
@ -207,9 +245,23 @@ typedef unsigned int JDIMENSION;
#endif
typedef unsigned char JPEG_boolean;
#define JPEG_FALSE 0
#define JPEG_TRUE 1
/*
* On a few systems, type boolean and/or its values FALSE, TRUE may appear
* in standard header files. Or you may have conflicts with application-
* specific header files that you want to include together with these files.
* Defining HAVE_BOOLEAN before including jpeglib.h should make it work.
*/
#ifdef HAVE_BOOLEAN
#ifndef FALSE /* in case these macros already exist */
#define FALSE 0 /* values of boolean */
#endif
#ifndef TRUE
#define TRUE 1
#endif
#else
typedef enum { FALSE = 0, TRUE = 1 } boolean;
#endif
/*
@ -281,9 +333,7 @@ typedef unsigned char JPEG_boolean;
* the offsets will also change the order in which colormap data is organized.
* RESTRICTIONS:
* 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats.
* 2. These macros only affect RGB<=>YCbCr color conversion, so they are not
* useful if you are using JPEG color spaces other than YCbCr or grayscale.
* 3. The color quantizer modules will not behave desirably if RGB_PIXELSIZE
* 2. The color quantizer modules will not behave desirably if RGB_PIXELSIZE
* is not 3 (they don't understand about dummy color components!). So you
* can't use color quantization if you change that value.
*/

View File

@ -2,7 +2,7 @@
* jpeglib.h
*
* Copyright (C) 1991-1998, Thomas G. Lane.
* Modified 2002-2009 by Guido Vollbeding.
* Modified 2002-2012 by Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
@ -14,8 +14,6 @@
#ifndef JPEGLIB_H
#define JPEGLIB_H
#include <stdio.h>
/*
* First we include the configuration files that record how this
* installation of the JPEG library is set up. jconfig.h can be
@ -35,11 +33,13 @@ extern "C" {
#endif
#endif
/* Version ID for the JPEG library.
* Might be useful for tests like "#if JPEG_LIB_VERSION >= 80".
/* Version IDs for the JPEG library.
* Might be useful for tests like "#if JPEG_LIB_VERSION >= 90".
*/
#define JPEG_LIB_VERSION 80 /* Version 8.0 */
#define JPEG_LIB_VERSION 90 /* Compatibility version 9.0 */
#define JPEG_LIB_VERSION_MAJOR 9
#define JPEG_LIB_VERSION_MINOR 0
/* Various constants determining the sizes of things.
@ -47,7 +47,7 @@ extern "C" {
* if you want to be compatible.
*/
#define DCTSIZE 8 /* The basic DCT block is 8x8 samples */
#define DCTSIZE 8 /* The basic DCT block is 8x8 coefficients */
#define DCTSIZE2 64 /* DCTSIZE squared; # of elements in a block */
#define NUM_QUANT_TBLS 4 /* Quantization tables are numbered 0..3 */
#define NUM_HUFF_TBLS 4 /* Huffman tables are numbered 0..3 */
@ -95,12 +95,12 @@ typedef struct {
* CAUTION: IJG versions prior to v6a kept this array in zigzag order.
*/
UINT16 quantval[DCTSIZE2]; /* quantization step for each coefficient */
/* This field is used only during compression. It's initialized JPEG_FALSE when
* the table is created, and set JPEG_TRUE when it's been output to the file.
* You could suppress output of a table by setting this to JPEG_TRUE.
/* This field is used only during compression. It's initialized FALSE when
* the table is created, and set TRUE when it's been output to the file.
* You could suppress output of a table by setting this to TRUE.
* (See jpeg_suppress_tables for an example.)
*/
JPEG_boolean sent_table; /* JPEG_TRUE when table has been output */
boolean sent_table; /* TRUE when table has been output */
} JQUANT_TBL;
@ -111,12 +111,12 @@ typedef struct {
UINT8 bits[17]; /* bits[k] = # of symbols with codes of */
/* length k bits; bits[0] is unused */
UINT8 huffval[256]; /* The symbols, in order of incr code length */
/* This field is used only during compression. It's initialized JPEG_FALSE when
* the table is created, and set JPEG_TRUE when it's been output to the file.
* You could suppress output of a table by setting this to JPEG_TRUE.
/* This field is used only during compression. It's initialized FALSE when
* the table is created, and set TRUE when it's been output to the file.
* You could suppress output of a table by setting this to TRUE.
* (See jpeg_suppress_tables for an example.)
*/
JPEG_boolean sent_table; /* JPEG_TRUE when table has been output */
boolean sent_table; /* TRUE when table has been output */
} JHUFF_TBL;
@ -166,7 +166,7 @@ typedef struct {
* components will be ignored (eg grayscale output from YCbCr image),
* we can skip most computations for the unused components.
*/
JPEG_boolean component_needed; /* do we need the value of this component? */
boolean component_needed; /* do we need the value of this component? */
/* These values are computed before starting a scan of the component. */
/* The decompressor output side may not use these variables. */
@ -221,6 +221,13 @@ typedef enum {
JCS_YCCK /* Y/Cb/Cr/K */
} J_COLOR_SPACE;
/* Supported color transforms. */
typedef enum {
JCT_NONE = 0,
JCT_SUBTRACT_GREEN = 1
} J_COLOR_TRANSFORM;
/* DCT/IDCT algorithm options. */
typedef enum {
@ -252,7 +259,7 @@ typedef enum {
struct jpeg_memory_mgr * mem; /* Memory manager module */\
struct jpeg_progress_mgr * progress; /* Progress monitor, or NULL if none */\
void * client_data; /* Available for use by application */\
JPEG_boolean is_decompressor; /* So common code can tell which is which */\
boolean is_decompressor; /* So common code can tell which is which */\
int global_state /* For checking call sequence validity */
/* Routines that are to be used by both halves of the library are declared
@ -340,11 +347,11 @@ struct jpeg_compress_struct {
* set num_scans and scan_info to point to an array of scan definitions.
*/
JPEG_boolean raw_data_in; /* JPEG_TRUE=caller supplies downsampled data */
JPEG_boolean arith_code; /* JPEG_TRUE=arithmetic coding, JPEG_FALSE=Huffman */
JPEG_boolean optimize_coding; /* JPEG_TRUE=optimize entropy encoding parms */
JPEG_boolean CCIR601_sampling; /* JPEG_TRUE=first samples are cosited */
JPEG_boolean do_fancy_downsampling; /* JPEG_TRUE=apply fancy downsampling */
boolean raw_data_in; /* TRUE=caller supplies downsampled data */
boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */
boolean optimize_coding; /* TRUE=optimize entropy encoding parms */
boolean CCIR601_sampling; /* TRUE=first samples are cosited */
boolean do_fancy_downsampling; /* TRUE=apply fancy downsampling */
int smoothing_factor; /* 1..100, or 0 for no input smoothing */
J_DCT_METHOD dct_method; /* DCT algorithm selector */
@ -358,7 +365,7 @@ struct jpeg_compress_struct {
/* Parameters controlling emission of special markers. */
JPEG_boolean write_JFIF_header; /* should a JFIF marker be written? */
boolean write_JFIF_header; /* should a JFIF marker be written? */
UINT8 JFIF_major_version; /* What to write for the JFIF version number */
UINT8 JFIF_minor_version;
/* These three values are not used by the JPEG code, merely copied */
@ -368,8 +375,11 @@ struct jpeg_compress_struct {
UINT8 density_unit; /* JFIF code for pixel size units */
UINT16 X_density; /* Horizontal pixel density */
UINT16 Y_density; /* Vertical pixel density */
JPEG_boolean write_Adobe_marker; /* should an Adobe marker be written? */
boolean write_Adobe_marker; /* should an Adobe marker be written? */
J_COLOR_TRANSFORM color_transform;
/* Color transform identifier, writes LSE marker if nonzero */
/* State variable: index of next scanline to be written to
* jpeg_write_scanlines(). Application may use this to control its
* processing loop, e.g., "while (next_scanline < image_height)".
@ -384,7 +394,7 @@ struct jpeg_compress_struct {
/*
* These fields are computed during compression startup
*/
JPEG_boolean progressive_mode; /* JPEG_TRUE if scan script uses progressive mode */
boolean progressive_mode; /* TRUE if scan script uses progressive mode */
int max_h_samp_factor; /* largest h_samp_factor */
int max_v_samp_factor; /* largest v_samp_factor */
@ -464,22 +474,22 @@ struct jpeg_decompress_struct {
double output_gamma; /* image gamma wanted in output */
JPEG_boolean buffered_image; /* JPEG_TRUE=multiple output passes */
JPEG_boolean raw_data_out; /* JPEG_TRUE=downsampled data wanted */
boolean buffered_image; /* TRUE=multiple output passes */
boolean raw_data_out; /* TRUE=downsampled data wanted */
J_DCT_METHOD dct_method; /* IDCT algorithm selector */
JPEG_boolean do_fancy_upsampling; /* JPEG_TRUE=apply fancy upsampling */
JPEG_boolean do_block_smoothing; /* JPEG_TRUE=apply interblock smoothing */
boolean do_fancy_upsampling; /* TRUE=apply fancy upsampling */
boolean do_block_smoothing; /* TRUE=apply interblock smoothing */
JPEG_boolean quantize_colors; /* JPEG_TRUE=colormapped output wanted */
boolean quantize_colors; /* TRUE=colormapped output wanted */
/* the following are ignored if not quantize_colors: */
J_DITHER_MODE dither_mode; /* type of color dithering to use */
JPEG_boolean two_pass_quantize; /* JPEG_TRUE=use two-pass color quantization */
boolean two_pass_quantize; /* TRUE=use two-pass color quantization */
int desired_number_of_colors; /* max # colors to use in created colormap */
/* these are significant only in buffered-image mode: */
JPEG_boolean enable_1pass_quant; /* enable future use of 1-pass quantizer */
JPEG_boolean enable_external_quant;/* enable future use of external colormap */
JPEG_boolean enable_2pass_quant; /* enable future use of 2-pass quantizer */
boolean enable_1pass_quant; /* enable future use of 1-pass quantizer */
boolean enable_external_quant;/* enable future use of external colormap */
boolean enable_2pass_quant; /* enable future use of 2-pass quantizer */
/* Description of actual output image that will be returned to application.
* These fields are computed by jpeg_start_decompress().
@ -566,9 +576,9 @@ struct jpeg_decompress_struct {
jpeg_component_info * comp_info;
/* comp_info[i] describes component that appears i'th in SOF */
JPEG_boolean is_baseline; /* JPEG_TRUE if Baseline SOF0 encountered */
JPEG_boolean progressive_mode; /* JPEG_TRUE if SOFn specifies progressive mode */
JPEG_boolean arith_code; /* JPEG_TRUE=arithmetic coding, JPEG_FALSE=Huffman */
boolean is_baseline; /* TRUE if Baseline SOF0 encountered */
boolean progressive_mode; /* TRUE if SOFn specifies progressive mode */
boolean arith_code; /* TRUE=arithmetic coding, FALSE=Huffman */
UINT8 arith_dc_L[NUM_ARITH_TBLS]; /* L values for DC arith-coding tables */
UINT8 arith_dc_U[NUM_ARITH_TBLS]; /* U values for DC arith-coding tables */
@ -579,17 +589,20 @@ struct jpeg_decompress_struct {
/* These fields record data obtained from optional markers recognized by
* the JPEG library.
*/
JPEG_boolean saw_JFIF_marker; /* JPEG_TRUE iff a JFIF APP0 marker was found */
/* Data copied from JFIF marker; only valid if saw_JFIF_marker is JPEG_TRUE: */
boolean saw_JFIF_marker; /* TRUE iff a JFIF APP0 marker was found */
/* Data copied from JFIF marker; only valid if saw_JFIF_marker is TRUE: */
UINT8 JFIF_major_version; /* JFIF version number */
UINT8 JFIF_minor_version;
UINT8 density_unit; /* JFIF code for pixel size units */
UINT16 X_density; /* Horizontal pixel density */
UINT16 Y_density; /* Vertical pixel density */
JPEG_boolean saw_Adobe_marker; /* JPEG_TRUE iff an Adobe APP14 marker was found */
boolean saw_Adobe_marker; /* TRUE iff an Adobe APP14 marker was found */
UINT8 Adobe_transform; /* Color transform code from Adobe marker */
JPEG_boolean CCIR601_sampling; /* JPEG_TRUE=first samples are cosited */
J_COLOR_TRANSFORM color_transform;
/* Color transform identifier derived from LSE marker, otherwise zero */
boolean CCIR601_sampling; /* TRUE=first samples are cosited */
/* Aside from the specific data retained from APPn markers known to the
* library, the uninterpreted contents of any or all APPn and COM markers
@ -681,7 +694,7 @@ struct jpeg_decompress_struct {
struct jpeg_error_mgr {
/* Error exit handler: does not return to caller */
JMETHOD(void, error_exit, (j_common_ptr cinfo));
JMETHOD(noreturn_t, error_exit, (j_common_ptr cinfo));
/* Conditionally emit a trace or warning message */
JMETHOD(void, emit_message, (j_common_ptr cinfo, int msg_level));
/* Routine that actually outputs a trace or error message */
@ -754,7 +767,7 @@ struct jpeg_destination_mgr {
size_t free_in_buffer; /* # of byte spaces remaining in buffer */
JMETHOD(void, init_destination, (j_compress_ptr cinfo));
JMETHOD(JPEG_boolean, empty_output_buffer, (j_compress_ptr cinfo));
JMETHOD(boolean, empty_output_buffer, (j_compress_ptr cinfo));
JMETHOD(void, term_destination, (j_compress_ptr cinfo));
};
@ -766,9 +779,9 @@ struct jpeg_source_mgr {
size_t bytes_in_buffer; /* # of bytes remaining in buffer */
JMETHOD(void, init_source, (j_decompress_ptr cinfo));
JMETHOD(JPEG_boolean, fill_input_buffer, (j_decompress_ptr cinfo));
JMETHOD(boolean, fill_input_buffer, (j_decompress_ptr cinfo));
JMETHOD(void, skip_input_data, (j_decompress_ptr cinfo, long num_bytes));
JMETHOD(JPEG_boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired));
JMETHOD(boolean, resync_to_restart, (j_decompress_ptr cinfo, int desired));
JMETHOD(void, term_source, (j_decompress_ptr cinfo));
};
@ -806,13 +819,13 @@ struct jpeg_memory_mgr {
JDIMENSION numrows));
JMETHOD(jvirt_sarray_ptr, request_virt_sarray, (j_common_ptr cinfo,
int pool_id,
JPEG_boolean pre_zero,
boolean pre_zero,
JDIMENSION samplesperrow,
JDIMENSION numrows,
JDIMENSION maxaccess));
JMETHOD(jvirt_barray_ptr, request_virt_barray, (j_common_ptr cinfo,
int pool_id,
JPEG_boolean pre_zero,
boolean pre_zero,
JDIMENSION blocksperrow,
JDIMENSION numrows,
JDIMENSION maxaccess));
@ -821,12 +834,12 @@ struct jpeg_memory_mgr {
jvirt_sarray_ptr ptr,
JDIMENSION start_row,
JDIMENSION num_rows,
JPEG_boolean writable));
boolean writable));
JMETHOD(JBLOCKARRAY, access_virt_barray, (j_common_ptr cinfo,
jvirt_barray_ptr ptr,
JDIMENSION start_row,
JDIMENSION num_rows,
JPEG_boolean writable));
boolean writable));
JMETHOD(void, free_pool, (j_common_ptr cinfo, int pool_id));
JMETHOD(void, self_destruct, (j_common_ptr cinfo));
@ -845,7 +858,7 @@ struct jpeg_memory_mgr {
/* Routine signature for application-supplied marker processing methods.
* Need not pass marker code since it is stored in cinfo->unread_marker.
*/
typedef JMETHOD(JPEG_boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
typedef JMETHOD(boolean, jpeg_marker_parser_method, (j_decompress_ptr cinfo));
/* Declarations for routines called by application.
@ -969,26 +982,26 @@ EXTERN(void) jpeg_set_colorspace JPP((j_compress_ptr cinfo,
J_COLOR_SPACE colorspace));
EXTERN(void) jpeg_default_colorspace JPP((j_compress_ptr cinfo));
EXTERN(void) jpeg_set_quality JPP((j_compress_ptr cinfo, int quality,
JPEG_boolean force_baseline));
boolean force_baseline));
EXTERN(void) jpeg_set_linear_quality JPP((j_compress_ptr cinfo,
int scale_factor,
JPEG_boolean force_baseline));
boolean force_baseline));
EXTERN(void) jpeg_default_qtables JPP((j_compress_ptr cinfo,
JPEG_boolean force_baseline));
boolean force_baseline));
EXTERN(void) jpeg_add_quant_table JPP((j_compress_ptr cinfo, int which_tbl,
const unsigned int *basic_table,
int scale_factor,
JPEG_boolean force_baseline));
boolean force_baseline));
EXTERN(int) jpeg_quality_scaling JPP((int quality));
EXTERN(void) jpeg_simple_progression JPP((j_compress_ptr cinfo));
EXTERN(void) jpeg_suppress_tables JPP((j_compress_ptr cinfo,
JPEG_boolean suppress));
boolean suppress));
EXTERN(JQUANT_TBL *) jpeg_alloc_quant_table JPP((j_common_ptr cinfo));
EXTERN(JHUFF_TBL *) jpeg_alloc_huff_table JPP((j_common_ptr cinfo));
/* Main entry points for compression */
EXTERN(void) jpeg_start_compress JPP((j_compress_ptr cinfo,
JPEG_boolean write_all_tables));
boolean write_all_tables));
EXTERN(JDIMENSION) jpeg_write_scanlines JPP((j_compress_ptr cinfo,
JSAMPARRAY scanlines,
JDIMENSION num_lines));
@ -1017,23 +1030,23 @@ EXTERN(void) jpeg_write_tables JPP((j_compress_ptr cinfo));
/* Decompression startup: read start of JPEG datastream to see what's there */
EXTERN(int) jpeg_read_header JPP((j_decompress_ptr cinfo,
JPEG_boolean require_image));
boolean require_image));
/* Return value is one of: */
#define JPEG_SUSPENDED 0 /* Suspended due to lack of input data */
#define JPEG_HEADER_OK 1 /* Found valid image datastream */
#define JPEG_HEADER_TABLES_ONLY 2 /* Found valid table-specs-only datastream */
/* If you pass require_image = JPEG_TRUE (normal case), you need not check for
/* If you pass require_image = TRUE (normal case), you need not check for
* a TABLES_ONLY return code; an abbreviated file will cause an error exit.
* JPEG_SUSPENDED is only possible if you use a data source module that can
* give a suspension return (the stdio source module doesn't).
*/
/* Main entry points for decompression */
EXTERN(JPEG_boolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo));
EXTERN(boolean) jpeg_start_decompress JPP((j_decompress_ptr cinfo));
EXTERN(JDIMENSION) jpeg_read_scanlines JPP((j_decompress_ptr cinfo,
JSAMPARRAY scanlines,
JDIMENSION max_lines));
EXTERN(JPEG_boolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo));
EXTERN(boolean) jpeg_finish_decompress JPP((j_decompress_ptr cinfo));
/* Replaces jpeg_read_scanlines when reading raw downsampled data. */
EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo,
@ -1041,11 +1054,11 @@ EXTERN(JDIMENSION) jpeg_read_raw_data JPP((j_decompress_ptr cinfo,
JDIMENSION max_lines));
/* Additional entry points for buffered-image mode. */
EXTERN(JPEG_boolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo));
EXTERN(JPEG_boolean) jpeg_start_output JPP((j_decompress_ptr cinfo,
EXTERN(boolean) jpeg_has_multiple_scans JPP((j_decompress_ptr cinfo));
EXTERN(boolean) jpeg_start_output JPP((j_decompress_ptr cinfo,
int scan_number));
EXTERN(JPEG_boolean) jpeg_finish_output JPP((j_decompress_ptr cinfo));
EXTERN(JPEG_boolean) jpeg_input_complete JPP((j_decompress_ptr cinfo));
EXTERN(boolean) jpeg_finish_output JPP((j_decompress_ptr cinfo));
EXTERN(boolean) jpeg_input_complete JPP((j_decompress_ptr cinfo));
EXTERN(void) jpeg_new_colormap JPP((j_decompress_ptr cinfo));
EXTERN(int) jpeg_consume_input JPP((j_decompress_ptr cinfo));
/* Return value is one of: */
@ -1092,7 +1105,7 @@ EXTERN(void) jpeg_abort JPP((j_common_ptr cinfo));
EXTERN(void) jpeg_destroy JPP((j_common_ptr cinfo));
/* Default restart-marker-resync procedure for use by data source modules */
EXTERN(JPEG_boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo,
EXTERN(boolean) jpeg_resync_to_restart JPP((j_decompress_ptr cinfo,
int desired));

View File

@ -1,14 +1,14 @@
/*
* jversion.h
*
* Copyright (C) 1991-2010, Thomas G. Lane, Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains software version identification.
*/
#define JVERSION "8b 16-May-2010"
#define JCOPYRIGHT "Copyright (C) 2010, Thomas G. Lane, Guido Vollbeding"
/*
* jversion.h
*
* Copyright (C) 1991-2013, Thomas G. Lane, Guido Vollbeding.
* This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file.
*
* This file contains software version identification.
*/
#define JVERSION "9 13-Jan-2013"
#define JCOPYRIGHT "Copyright (C) 2013, Thomas G. Lane, Guido Vollbeding"

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -1,5 +1,5 @@
/* zconf.h -- configuration of the zlib compression library
* Copyright (C) 1995-2010 Jean-loup Gailly.
* Copyright (C) 1995-2013 Jean-loup Gailly.
* For conditions of distribution and use, see copyright notice in zlib.h
*/
@ -15,11 +15,13 @@
* this permanently in zconf.h using "./configure --zprefix".
*/
#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
# define Z_PREFIX_SET
/* all linked symbols */
# define _dist_code z__dist_code
# define _length_code z__length_code
# define _tr_align z__tr_align
# define _tr_flush_bits z__tr_flush_bits
# define _tr_flush_block z__tr_flush_block
# define _tr_init z__tr_init
# define _tr_stored_block z__tr_stored_block
@ -27,9 +29,11 @@
# define adler32 z_adler32
# define adler32_combine z_adler32_combine
# define adler32_combine64 z_adler32_combine64
# define compress z_compress
# define compress2 z_compress2
# define compressBound z_compressBound
# ifndef Z_SOLO
# define compress z_compress
# define compress2 z_compress2
# define compressBound z_compressBound
# endif
# define crc32 z_crc32
# define crc32_combine z_crc32_combine
# define crc32_combine64 z_crc32_combine64
@ -40,44 +44,53 @@
# define deflateInit2_ z_deflateInit2_
# define deflateInit_ z_deflateInit_
# define deflateParams z_deflateParams
# define deflatePending z_deflatePending
# define deflatePrime z_deflatePrime
# define deflateReset z_deflateReset
# define deflateResetKeep z_deflateResetKeep
# define deflateSetDictionary z_deflateSetDictionary
# define deflateSetHeader z_deflateSetHeader
# define deflateTune z_deflateTune
# define deflate_copyright z_deflate_copyright
# define get_crc_table z_get_crc_table
# define gz_error z_gz_error
# define gz_intmax z_gz_intmax
# define gz_strwinerror z_gz_strwinerror
# define gzbuffer z_gzbuffer
# define gzclearerr z_gzclearerr
# define gzclose z_gzclose
# define gzclose_r z_gzclose_r
# define gzclose_w z_gzclose_w
# define gzdirect z_gzdirect
# define gzdopen z_gzdopen
# define gzeof z_gzeof
# define gzerror z_gzerror
# define gzflush z_gzflush
# define gzgetc z_gzgetc
# define gzgets z_gzgets
# define gzoffset z_gzoffset
# define gzoffset64 z_gzoffset64
# define gzopen z_gzopen
# define gzopen64 z_gzopen64
# define gzprintf z_gzprintf
# define gzputc z_gzputc
# define gzputs z_gzputs
# define gzread z_gzread
# define gzrewind z_gzrewind
# define gzseek z_gzseek
# define gzseek64 z_gzseek64
# define gzsetparams z_gzsetparams
# define gztell z_gztell
# define gztell64 z_gztell64
# define gzungetc z_gzungetc
# define gzwrite z_gzwrite
# ifndef Z_SOLO
# define gz_error z_gz_error
# define gz_intmax z_gz_intmax
# define gz_strwinerror z_gz_strwinerror
# define gzbuffer z_gzbuffer
# define gzclearerr z_gzclearerr
# define gzclose z_gzclose
# define gzclose_r z_gzclose_r
# define gzclose_w z_gzclose_w
# define gzdirect z_gzdirect
# define gzdopen z_gzdopen
# define gzeof z_gzeof
# define gzerror z_gzerror
# define gzflush z_gzflush
# define gzgetc z_gzgetc
# define gzgetc_ z_gzgetc_
# define gzgets z_gzgets
# define gzoffset z_gzoffset
# define gzoffset64 z_gzoffset64
# define gzopen z_gzopen
# define gzopen64 z_gzopen64
# ifdef _WIN32
# define gzopen_w z_gzopen_w
# endif
# define gzprintf z_gzprintf
# define gzvprintf z_gzvprintf
# define gzputc z_gzputc
# define gzputs z_gzputs
# define gzread z_gzread
# define gzrewind z_gzrewind
# define gzseek z_gzseek
# define gzseek64 z_gzseek64
# define gzsetparams z_gzsetparams
# define gztell z_gztell
# define gztell64 z_gztell64
# define gzungetc z_gzungetc
# define gzwrite z_gzwrite
# endif
# define inflate z_inflate
# define inflateBack z_inflateBack
# define inflateBackEnd z_inflateBackEnd
@ -92,16 +105,22 @@
# define inflateReset z_inflateReset
# define inflateReset2 z_inflateReset2
# define inflateSetDictionary z_inflateSetDictionary
# define inflateGetDictionary z_inflateGetDictionary
# define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint
# define inflateUndermine z_inflateUndermine
# define inflateResetKeep z_inflateResetKeep
# define inflate_copyright z_inflate_copyright
# define inflate_fast z_inflate_fast
# define inflate_table z_inflate_table
# define uncompress z_uncompress
# ifndef Z_SOLO
# define uncompress z_uncompress
# endif
# define zError z_zError
# define zcalloc z_zcalloc
# define zcfree z_zcfree
# ifndef Z_SOLO
# define zcalloc z_zcalloc
# define zcfree z_zcfree
# endif
# define zlibCompileFlags z_zlibCompileFlags
# define zlibVersion z_zlibVersion
@ -111,7 +130,9 @@
# define alloc_func z_alloc_func
# define charf z_charf
# define free_func z_free_func
# define gzFile z_gzFile
# ifndef Z_SOLO
# define gzFile z_gzFile
# endif
# define gz_header z_gz_header
# define gz_headerp z_gz_headerp
# define in_func z_in_func
@ -197,6 +218,12 @@
# endif
#endif
#if defined(ZLIB_CONST) && !defined(z_const)
# define z_const const
#else
# define z_const
#endif
/* Some Mac compilers merge all .h files incorrectly: */
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
# define NO_DUMMY_DECL
@ -243,6 +270,14 @@
# endif
#endif
#ifndef Z_ARG /* function prototypes for stdarg */
# if defined(STDC) || defined(Z_HAVE_STDARG_H)
# define Z_ARG(args) args
# else
# define Z_ARG(args) ()
# endif
#endif
/* The following definitions for FAR are needed only for MSDOS mixed
* model programming (small or medium model with some far allocations).
* This was tested only with MSC; for other MSDOS compilers you may have
@ -356,12 +391,47 @@ typedef uLong FAR uLongf;
typedef Byte *voidp;
#endif
#ifdef HAVE_UNISTD_H /* may be set to #if 1 by ./configure */
#if !defined(Z_U4) && !defined(Z_SOLO) && defined(STDC)
# include <limits.h>
# if (UINT_MAX == 0xffffffffUL)
# define Z_U4 unsigned
# elif (ULONG_MAX == 0xffffffffUL)
# define Z_U4 unsigned long
# elif (USHRT_MAX == 0xffffffffUL)
# define Z_U4 unsigned short
# endif
#endif
#ifdef Z_U4
typedef Z_U4 z_crc_t;
#else
typedef unsigned long z_crc_t;
#endif
#if 1 /* was set to #if 1 by ./configure */
# define Z_HAVE_UNISTD_H
#endif
#if 1 /* was set to #if 1 by ./configure */
# define Z_HAVE_STDARG_H
#endif
#ifdef STDC
# include <sys/types.h> /* for off_t */
# ifndef Z_SOLO
# include <sys/types.h> /* for off_t */
# endif
#endif
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
# ifndef Z_SOLO
# include <stdarg.h> /* for va_list */
# endif
#endif
#ifdef _WIN32
# ifndef Z_SOLO
# include <stddef.h> /* for wchar_t */
# endif
#endif
/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and
@ -370,21 +440,38 @@ typedef uLong FAR uLongf;
* both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
* equivalently requesting no 64-bit operations
*/
#if -_LARGEFILE64_SOURCE - -1 == 1
#if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
# undef _LARGEFILE64_SOURCE
#endif
#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
# include <unistd.h> /* for SEEK_* and off_t */
# ifdef VMS
# include <unixio.h> /* for off_t */
# endif
# ifndef z_off_t
# define z_off_t off_t
#if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
# define Z_HAVE_UNISTD_H
#endif
#ifndef Z_SOLO
# if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
# include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
# ifdef VMS
# include <unixio.h> /* for off_t */
# endif
# ifndef z_off_t
# define z_off_t off_t
# endif
# endif
#endif
#ifndef SEEK_SET
#if defined(_LFS64_LARGEFILE) && _LFS64_LARGEFILE-0
# define Z_LFS64
#endif
#if defined(_LARGEFILE64_SOURCE) && defined(Z_LFS64)
# define Z_LARGE64
#endif
#if defined(_FILE_OFFSET_BITS) && _FILE_OFFSET_BITS-0 == 64 && defined(Z_LFS64)
# define Z_WANT64
#endif
#if !defined(SEEK_SET) && !defined(Z_SOLO)
# define SEEK_SET 0 /* Seek from beginning of file. */
# define SEEK_CUR 1 /* Seek from current position. */
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
@ -394,18 +481,14 @@ typedef uLong FAR uLongf;
# define z_off_t long
#endif
#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
#if !defined(_WIN32) && defined(Z_LARGE64)
# define z_off64_t off64_t
#else
# define z_off64_t z_off_t
#endif
#if defined(__OS400__)
# define NO_vsnprintf
#endif
#if defined(__MVS__)
# define NO_vsnprintf
# if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
# define z_off64_t __int64
# else
# define z_off64_t z_off_t
# endif
#endif
/* MVS linker does not support external names larger than 8 bytes */

View File

@ -1,7 +1,7 @@
/* zlib.h -- interface of the 'zlib' general purpose compression library
version 1.2.5, April 19th, 2010
version 1.2.8, April 28th, 2013
Copyright (C) 1995-2010 Jean-loup Gailly and Mark Adler
Copyright (C) 1995-2013 Jean-loup Gailly and Mark Adler
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@ -24,8 +24,8 @@
The data format used by the zlib library is described by RFCs (Request for
Comments) 1950 to 1952 in the files http://www.ietf.org/rfc/rfc1950.txt
(zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format).
Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
(zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
*/
#ifndef ZLIB_H
@ -37,11 +37,11 @@
extern "C" {
#endif
#define ZLIB_VERSION "1.2.5"
#define ZLIB_VERNUM 0x1250
#define ZLIB_VERSION "1.2.8"
#define ZLIB_VERNUM 0x1280
#define ZLIB_VER_MAJOR 1
#define ZLIB_VER_MINOR 2
#define ZLIB_VER_REVISION 5
#define ZLIB_VER_REVISION 8
#define ZLIB_VER_SUBREVISION 0
/*
@ -83,15 +83,15 @@ typedef void (*free_func) OF((voidpf opaque, voidpf address));
struct internal_state;
typedef struct z_stream_s {
Bytef *next_in; /* next input byte */
z_const Bytef *next_in; /* next input byte */
uInt avail_in; /* number of bytes available at next_in */
uLong total_in; /* total nb of input bytes read so far */
uLong total_in; /* total number of input bytes read so far */
Bytef *next_out; /* next output byte should be put there */
uInt avail_out; /* remaining free space at next_out */
uLong total_out; /* total nb of bytes output so far */
uLong total_out; /* total number of bytes output so far */
char *msg; /* last error message, NULL if no error */
z_const char *msg; /* last error message, NULL if no error */
struct internal_state FAR *state; /* not visible by applications */
alloc_func zalloc; /* used to allocate the internal state */
@ -327,8 +327,9 @@ ZEXTERN int ZEXPORT deflate OF((z_streamp strm, int flush));
Z_FINISH can be used immediately after deflateInit if all the compression
is to be done in a single step. In this case, avail_out must be at least the
value returned by deflateBound (see below). If deflate does not return
Z_STREAM_END, then it must be called again as described above.
value returned by deflateBound (see below). Then deflate is guaranteed to
return Z_STREAM_END. If not enough output space is provided, deflate will
not return Z_STREAM_END, and it must be called again as described above.
deflate() sets strm->adler to the adler32 checksum of all input read
so far (that is, total_in bytes).
@ -451,23 +452,29 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
error. However if all decompression is to be performed in a single step (a
single call of inflate), the parameter flush should be set to Z_FINISH. In
this case all pending input is processed and all pending output is flushed;
avail_out must be large enough to hold all the uncompressed data. (The size
of the uncompressed data may have been saved by the compressor for this
purpose.) The next operation on this stream must be inflateEnd to deallocate
the decompression state. The use of Z_FINISH is never required, but can be
used to inform inflate that a faster approach may be used for the single
inflate() call.
avail_out must be large enough to hold all of the uncompressed data for the
operation to complete. (The size of the uncompressed data may have been
saved by the compressor for this purpose.) The use of Z_FINISH is not
required to perform an inflation in one step. However it may be used to
inform inflate that a faster approach can be used for the single inflate()
call. Z_FINISH also informs inflate to not maintain a sliding window if the
stream completes, which reduces inflate's memory footprint. If the stream
does not complete, either because not all of the stream is provided or not
enough output space is provided, then a sliding window will be allocated and
inflate() can be called again to continue the operation as if Z_NO_FLUSH had
been used.
In this implementation, inflate() always flushes as much output as
possible to the output buffer, and always uses the faster approach on the
first call. So the only effect of the flush parameter in this implementation
is on the return value of inflate(), as noted below, or when it returns early
because Z_BLOCK or Z_TREES is used.
first call. So the effects of the flush parameter in this implementation are
on the return value of inflate() as noted below, when inflate() returns early
when Z_BLOCK or Z_TREES is used, and when inflate() avoids the allocation of
memory for a sliding window when Z_FINISH is used.
If a preset dictionary is needed after this call (see inflateSetDictionary
below), inflate sets strm->adler to the adler32 checksum of the dictionary
below), inflate sets strm->adler to the Adler-32 checksum of the dictionary
chosen by the compressor and returns Z_NEED_DICT; otherwise it sets
strm->adler to the adler32 checksum of all output produced so far (that is,
strm->adler to the Adler-32 checksum of all output produced so far (that is,
total_out bytes) and returns Z_OK, Z_STREAM_END or an error code as described
below. At the end of the stream, inflate() checks that its computed adler32
checksum is equal to that saved by the compressor and returns Z_STREAM_END
@ -478,7 +485,9 @@ ZEXTERN int ZEXPORT inflate OF((z_streamp strm, int flush));
initializing with inflateInit2(). Any information contained in the gzip
header is not retained, so applications that need that information should
instead use raw inflate, see inflateInit2() below, or inflateBack() and
perform their own processing of the gzip header and trailer.
perform their own processing of the gzip header and trailer. When processing
gzip-wrapped deflate data, strm->adler32 is set to the CRC-32 of the output
producted so far. The CRC-32 is checked against the gzip trailer.
inflate() returns Z_OK if some progress has been made (more input processed
or more output produced), Z_STREAM_END if the end of the compressed data has
@ -580,10 +589,15 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
uInt dictLength));
/*
Initializes the compression dictionary from the given byte sequence
without producing any compressed output. This function must be called
immediately after deflateInit, deflateInit2 or deflateReset, before any call
of deflate. The compressor and decompressor must use exactly the same
dictionary (see inflateSetDictionary).
without producing any compressed output. When using the zlib format, this
function must be called immediately after deflateInit, deflateInit2 or
deflateReset, and before any call of deflate. When doing raw deflate, this
function must be called either before any call of deflate, or immediately
after the completion of a deflate block, i.e. after all input has been
consumed and all output has been delivered when using any of the flush
options Z_BLOCK, Z_PARTIAL_FLUSH, Z_SYNC_FLUSH, or Z_FULL_FLUSH. The
compressor and decompressor must use exactly the same dictionary (see
inflateSetDictionary).
The dictionary should consist of strings (byte sequences) that are likely
to be encountered later in the data to be compressed, with the most commonly
@ -610,8 +624,8 @@ ZEXTERN int ZEXPORT deflateSetDictionary OF((z_streamp strm,
deflateSetDictionary returns Z_OK if success, or Z_STREAM_ERROR if a
parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
inconsistent (for example if deflate has already been called for this stream
or if the compression method is bsort). deflateSetDictionary does not
perform any compression: this will be done by deflate().
or if not at a block boundary for raw deflate). deflateSetDictionary does
not perform any compression: this will be done by deflate().
*/
ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest,
@ -688,9 +702,29 @@ ZEXTERN uLong ZEXPORT deflateBound OF((z_streamp strm,
deflation of sourceLen bytes. It must be called after deflateInit() or
deflateInit2(), and after deflateSetHeader(), if used. This would be used
to allocate an output buffer for deflation in a single pass, and so would be
called before deflate().
called before deflate(). If that first deflate() call is provided the
sourceLen input bytes, an output buffer allocated to the size returned by
deflateBound(), and the flush value Z_FINISH, then deflate() is guaranteed
to return Z_STREAM_END. Note that it is possible for the compressed size to
be larger than the value returned by deflateBound() if flush options other
than Z_FINISH or Z_NO_FLUSH are used.
*/
ZEXTERN int ZEXPORT deflatePending OF((z_streamp strm,
unsigned *pending,
int *bits));
/*
deflatePending() returns the number of bytes and bits of output that have
been generated, but not yet provided in the available output. The bytes not
provided would be due to the available output space having being consumed.
The number of bits of output not provided are between 0 and 7, where they
await more bits to join them in order to fill out a full byte. If pending
or bits are Z_NULL, then those values are not set.
deflatePending returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent.
*/
ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
int bits,
int value));
@ -703,8 +737,9 @@ ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
than or equal to 16, and that many of the least significant bits of value
will be inserted in the output.
deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source
stream state was inconsistent.
deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough
room in the internal buffer to insert the bits, or Z_STREAM_ERROR if the
source stream state was inconsistent.
*/
ZEXTERN int ZEXPORT deflateSetHeader OF((z_streamp strm,
@ -790,10 +825,11 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
if that call returned Z_NEED_DICT. The dictionary chosen by the compressor
can be determined from the adler32 value returned by that call of inflate.
The compressor and decompressor must use exactly the same dictionary (see
deflateSetDictionary). For raw inflate, this function can be called
immediately after inflateInit2() or inflateReset() and before any call of
inflate() to set the dictionary. The application must insure that the
dictionary that was used for compression is provided.
deflateSetDictionary). For raw inflate, this function can be called at any
time to set the dictionary. If the provided dictionary is smaller than the
window and there is already data in the window, then the provided dictionary
will amend what's there. The application must insure that the dictionary
that was used for compression is provided.
inflateSetDictionary returns Z_OK if success, Z_STREAM_ERROR if a
parameter is invalid (e.g. dictionary being Z_NULL) or the stream state is
@ -803,19 +839,38 @@ ZEXTERN int ZEXPORT inflateSetDictionary OF((z_streamp strm,
inflate().
*/
ZEXTERN int ZEXPORT inflateGetDictionary OF((z_streamp strm,
Bytef *dictionary,
uInt *dictLength));
/*
Returns the sliding dictionary being maintained by inflate. dictLength is
set to the number of bytes in the dictionary, and that many bytes are copied
to dictionary. dictionary must have enough space, where 32768 bytes is
always enough. If inflateGetDictionary() is called with dictionary equal to
Z_NULL, then only the dictionary length is returned, and nothing is copied.
Similary, if dictLength is Z_NULL, then it is not set.
inflateGetDictionary returns Z_OK on success, or Z_STREAM_ERROR if the
stream state is inconsistent.
*/
ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
/*
Skips invalid compressed data until a full flush point (see above the
description of deflate with Z_FULL_FLUSH) can be found, or until all
Skips invalid compressed data until a possible full flush point (see above
for the description of deflate with Z_FULL_FLUSH) can be found, or until all
available input is skipped. No output is provided.
inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR
if no more input was provided, Z_DATA_ERROR if no flush point has been
found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the
success case, the application may save the current current value of total_in
which indicates where valid compressed data was found. In the error case,
the application may repeatedly call inflateSync, providing more input each
time, until success or end of the input data.
inflateSync searches for a 00 00 FF FF pattern in the compressed data.
All full flush points have this pattern, but not all occurrences of this
pattern are full flush points.
inflateSync returns Z_OK if a possible full flush point has been found,
Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
has been found, or Z_STREAM_ERROR if the stream structure was inconsistent.
In the success case, the application may save the current current value of
total_in which indicates where valid compressed data was found. In the
error case, the application may repeatedly call inflateSync, providing more
input each time, until success or end of the input data.
*/
ZEXTERN int ZEXPORT inflateCopy OF((z_streamp dest,
@ -962,12 +1017,13 @@ ZEXTERN int ZEXPORT inflateBackInit OF((z_streamp strm, int windowBits,
See inflateBack() for the usage of these routines.
inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of
the paramaters are invalid, Z_MEM_ERROR if the internal state could not be
the parameters are invalid, Z_MEM_ERROR if the internal state could not be
allocated, or Z_VERSION_ERROR if the version of the library does not match
the version of the header file.
*/
typedef unsigned (*in_func) OF((void FAR *, unsigned char FAR * FAR *));
typedef unsigned (*in_func) OF((void FAR *,
z_const unsigned char FAR * FAR *));
typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
@ -975,11 +1031,12 @@ ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm,
out_func out, void FAR *out_desc));
/*
inflateBack() does a raw inflate with a single call using a call-back
interface for input and output. This is more efficient than inflate() for
file i/o applications in that it avoids copying between the output and the
sliding window by simply making the window itself the output buffer. This
function trusts the application to not change the output buffer passed by
the output function, at least until inflateBack() returns.
interface for input and output. This is potentially more efficient than
inflate() for file i/o applications, in that it avoids copying between the
output and the sliding window by simply making the window itself the output
buffer. inflate() can be faster on modern CPUs when used with large
buffers. inflateBack() trusts the application to not change the output
buffer passed by the output function, at least until inflateBack() returns.
inflateBackInit() must be called first to allocate the internal state
and to initialize the state with the user-provided window buffer.
@ -1088,6 +1145,7 @@ ZEXTERN uLong ZEXPORT zlibCompileFlags OF((void));
27-31: 0 (reserved)
*/
#ifndef Z_SOLO
/* utility functions */
@ -1149,10 +1207,11 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
uncompress returns Z_OK if success, Z_MEM_ERROR if there was not
enough memory, Z_BUF_ERROR if there was not enough room in the output
buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete.
buffer, or Z_DATA_ERROR if the input data was corrupted or incomplete. In
the case where there is not enough room, uncompress() will fill the output
buffer with the uncompressed data up to that point.
*/
/* gzip file access functions */
/*
@ -1162,7 +1221,7 @@ ZEXTERN int ZEXPORT uncompress OF((Bytef *dest, uLongf *destLen,
wrapper, documented in RFC 1952, wrapped around a deflate stream.
*/
typedef voidp gzFile; /* opaque gzip file descriptor */
typedef struct gzFile_s *gzFile; /* semi-opaque gzip file descriptor */
/*
ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
@ -1172,13 +1231,28 @@ ZEXTERN gzFile ZEXPORT gzopen OF((const char *path, const char *mode));
a strategy: 'f' for filtered data as in "wb6f", 'h' for Huffman-only
compression as in "wb1h", 'R' for run-length encoding as in "wb1R", or 'F'
for fixed code compression as in "wb9F". (See the description of
deflateInit2 for more information about the strategy parameter.) Also "a"
can be used instead of "w" to request that the gzip stream that will be
written be appended to the file. "+" will result in an error, since reading
and writing to the same gzip file is not supported.
deflateInit2 for more information about the strategy parameter.) 'T' will
request transparent writing or appending with no compression and not using
the gzip format.
"a" can be used instead of "w" to request that the gzip stream that will
be written be appended to the file. "+" will result in an error, since
reading and writing to the same gzip file is not supported. The addition of
"x" when writing will create the file exclusively, which fails if the file
already exists. On systems that support it, the addition of "e" when
reading or writing will set the flag to close the file on an execve() call.
These functions, as well as gzip, will read and decode a sequence of gzip
streams in a file. The append function of gzopen() can be used to create
such a file. (Also see gzflush() for another way to do this.) When
appending, gzopen does not test whether the file begins with a gzip stream,
nor does it look for the end of the gzip streams to begin appending. gzopen
will simply append a gzip stream to the existing file.
gzopen can be used to read a file which is not in gzip format; in this
case gzread will directly read from the file without decompression.
case gzread will directly read from the file without decompression. When
reading, this will be detected automatically by looking for the magic two-
byte gzip header.
gzopen returns NULL if the file could not be opened, if there was
insufficient memory to allocate the gzFile state, or if an invalid mode was
@ -1197,7 +1271,11 @@ ZEXTERN gzFile ZEXPORT gzdopen OF((int fd, const char *mode));
descriptor fd, just like fclose(fdopen(fd, mode)) closes the file descriptor
fd. If you want to keep fd open, use fd = dup(fd_keep); gz = gzdopen(fd,
mode);. The duplicated descriptor should be saved to avoid a leak, since
gzdopen does not close fd if it fails.
gzdopen does not close fd if it fails. If you are using fileno() to get the
file descriptor from a FILE *, then you will have to use dup() to avoid
double-close()ing the file descriptor. Both gzclose() and fclose() will
close the associated file descriptor, so they need to have different file
descriptors.
gzdopen returns NULL if there was insufficient memory to allocate the
gzFile state, if an invalid mode was specified (an 'r', 'w', or 'a' was not
@ -1235,14 +1313,26 @@ ZEXTERN int ZEXPORT gzsetparams OF((gzFile file, int level, int strategy));
ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
/*
Reads the given number of uncompressed bytes from the compressed file. If
the input file was not in gzip format, gzread copies the given number of
bytes into the buffer.
the input file is not in gzip format, gzread copies the given number of
bytes into the buffer directly from the file.
After reaching the end of a gzip stream in the input, gzread will continue
to read, looking for another gzip stream, or failing that, reading the rest
of the input file directly without decompression. The entire input file
will be read if gzread is called until it returns less than the requested
len.
to read, looking for another gzip stream. Any number of gzip streams may be
concatenated in the input file, and will all be decompressed by gzread().
If something other than a gzip stream is encountered after a gzip stream,
that remaining trailing garbage is ignored (and no error is returned).
gzread can be used to read a gzip file that is being concurrently written.
Upon reaching the end of the input, gzread will return with the available
data. If the error code returned by gzerror is Z_OK or Z_BUF_ERROR, then
gzclearerr can be used to clear the end of file indicator in order to permit
gzread to be tried again. Z_OK indicates that a gzip stream was completed
on the last gzread. Z_BUF_ERROR indicates that the input file ended in the
middle of a gzip stream. Note that gzread does not return -1 in the event
of an incomplete gzip stream. This error is deferred until gzclose(), which
will return Z_BUF_ERROR if the last gzread ended in the middle of a gzip
stream. Alternatively, gzerror can be used before gzclose to detect this
case.
gzread returns the number of uncompressed bytes actually read, less than
len for end of file, or -1 for error.
@ -1256,7 +1346,7 @@ ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
error.
*/
ZEXTERN int ZEXPORTVA gzprintf OF((gzFile file, const char *format, ...));
ZEXTERN int ZEXPORTVA gzprintf Z_ARG((gzFile file, const char *format, ...));
/*
Converts, formats, and writes the arguments to the compressed file under
control of the format string, as in fprintf. gzprintf returns the number of
@ -1301,7 +1391,10 @@ ZEXTERN int ZEXPORT gzputc OF((gzFile file, int c));
ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
/*
Reads one byte from the compressed file. gzgetc returns this byte or -1
in case of end of file or error.
in case of end of file or error. This is implemented as a macro for speed.
As such, it does not do all of the checking the other functions do. I.e.
it does not check to see if file is NULL, nor whether the structure file
points to has been clobbered or not.
*/
ZEXTERN int ZEXPORT gzungetc OF((int c, gzFile file));
@ -1397,9 +1490,7 @@ ZEXTERN int ZEXPORT gzeof OF((gzFile file));
ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
/*
Returns true (1) if file is being copied directly while reading, or false
(0) if file is a gzip stream being decompressed. This state can change from
false to true while reading the input file if the end of a gzip stream is
reached, but is followed by data that is not another gzip stream.
(0) if file is a gzip stream being decompressed.
If the input file is empty, gzdirect() will return true, since the input
does not contain a gzip stream.
@ -1408,6 +1499,13 @@ ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
cause buffers to be allocated to allow reading the file to determine if it
is a gzip file. Therefore if gzbuffer() is used, it should be called before
gzdirect().
When writing, gzdirect() returns true (1) if transparent writing was
requested ("wT" for the gzopen() mode), or false (0) otherwise. (Note:
gzdirect() is not needed when writing. Transparent writing must be
explicitly requested, so the application already knows the answer. When
linking statically, using gzdirect() will include all of the zlib code for
gzip file reading and decompression, which may not be desired.)
*/
ZEXTERN int ZEXPORT gzclose OF((gzFile file));
@ -1419,7 +1517,8 @@ ZEXTERN int ZEXPORT gzclose OF((gzFile file));
must not be called more than once on the same allocation.
gzclose will return Z_STREAM_ERROR if file is not valid, Z_ERRNO on a
file operation error, or Z_OK on success.
file operation error, Z_MEM_ERROR if out of memory, Z_BUF_ERROR if the
last read ended in the middle of a gzip stream, or Z_OK on success.
*/
ZEXTERN int ZEXPORT gzclose_r OF((gzFile file));
@ -1457,6 +1556,7 @@ ZEXTERN void ZEXPORT gzclearerr OF((gzFile file));
file that is being written concurrently.
*/
#endif /* !Z_SOLO */
/* checksum functions */
@ -1492,16 +1592,17 @@ ZEXTERN uLong ZEXPORT adler32_combine OF((uLong adler1, uLong adler2,
Combine two Adler-32 checksums into one. For two sequences of bytes, seq1
and seq2 with lengths len1 and len2, Adler-32 checksums were calculated for
each, adler1 and adler2. adler32_combine() returns the Adler-32 checksum of
seq1 and seq2 concatenated, requiring only adler1, adler2, and len2.
seq1 and seq2 concatenated, requiring only adler1, adler2, and len2. Note
that the z_off_t type (like off_t) is a signed integer. If len2 is
negative, the result has no meaning or utility.
*/
ZEXTERN uLong ZEXPORT crc32 OF((uLong crc, const Bytef *buf, uInt len));
/*
Update a running CRC-32 with the bytes buf[0..len-1] and return the
updated CRC-32. If buf is Z_NULL, this function returns the required
initial value for the for the crc. Pre- and post-conditioning (one's
complement) is performed within this function so it shouldn't be done by the
application.
initial value for the crc. Pre- and post-conditioning (one's complement) is
performed within this function so it shouldn't be done by the application.
Usage example:
@ -1544,17 +1645,42 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
const char *version,
int stream_size));
#define deflateInit(strm, level) \
deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream))
deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
#define inflateInit(strm) \
inflateInit_((strm), ZLIB_VERSION, sizeof(z_stream))
inflateInit_((strm), ZLIB_VERSION, (int)sizeof(z_stream))
#define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
(strategy), ZLIB_VERSION, sizeof(z_stream))
(strategy), ZLIB_VERSION, (int)sizeof(z_stream))
#define inflateInit2(strm, windowBits) \
inflateInit2_((strm), (windowBits), ZLIB_VERSION, sizeof(z_stream))
inflateInit2_((strm), (windowBits), ZLIB_VERSION, \
(int)sizeof(z_stream))
#define inflateBackInit(strm, windowBits, window) \
inflateBackInit_((strm), (windowBits), (window), \
ZLIB_VERSION, sizeof(z_stream))
ZLIB_VERSION, (int)sizeof(z_stream))
#ifndef Z_SOLO
/* gzgetc() macro and its supporting function and exposed data structure. Note
* that the real internal state is much larger than the exposed structure.
* This abbreviated structure exposes just enough for the gzgetc() macro. The
* user should not mess with these exposed elements, since their names or
* behavior could change in the future, perhaps even capriciously. They can
* only be used by the gzgetc() macro. You have been warned.
*/
struct gzFile_s {
unsigned have;
unsigned char *next;
z_off64_t pos;
};
ZEXTERN int ZEXPORT gzgetc_ OF((gzFile file)); /* backward compatibility */
#ifdef Z_PREFIX_SET
# undef z_gzgetc
# define z_gzgetc(g) \
((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
#else
# define gzgetc(g) \
((g)->have ? ((g)->have--, (g)->pos++, *((g)->next)++) : gzgetc(g))
#endif
/* provide 64-bit offset functions if _LARGEFILE64_SOURCE defined, and/or
* change the regular functions to 64 bits if _FILE_OFFSET_BITS is 64 (if
@ -1562,7 +1688,7 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
* functions are changed to 64 bits) -- in case these are set on systems
* without large file support, _LFS64_LARGEFILE must also be true
*/
#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0
#ifdef Z_LARGE64
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
ZEXTERN z_off64_t ZEXPORT gzseek64 OF((gzFile, z_off64_t, int));
ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile));
@ -1571,14 +1697,23 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
#endif
#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0
# define gzopen gzopen64
# define gzseek gzseek64
# define gztell gztell64
# define gzoffset gzoffset64
# define adler32_combine adler32_combine64
# define crc32_combine crc32_combine64
# ifdef _LARGEFILE64_SOURCE
#if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
# ifdef Z_PREFIX_SET
# define z_gzopen z_gzopen64
# define z_gzseek z_gzseek64
# define z_gztell z_gztell64
# define z_gzoffset z_gzoffset64
# define z_adler32_combine z_adler32_combine64
# define z_crc32_combine z_crc32_combine64
# else
# define gzopen gzopen64
# define gzseek gzseek64
# define gztell gztell64
# define gzoffset gzoffset64
# define adler32_combine adler32_combine64
# define crc32_combine crc32_combine64
# endif
# ifndef Z_LARGE64
ZEXTERN gzFile ZEXPORT gzopen64 OF((const char *, const char *));
ZEXTERN z_off_t ZEXPORT gzseek64 OF((gzFile, z_off_t, int));
ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile));
@ -1595,6 +1730,13 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
#endif
#else /* Z_SOLO */
ZEXTERN uLong ZEXPORT adler32_combine OF((uLong, uLong, z_off_t));
ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
#endif /* !Z_SOLO */
/* hack for buggy compilers */
#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
struct internal_state {int dummy;};
@ -1603,8 +1745,21 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
/* undocumented functions */
ZEXTERN const char * ZEXPORT zError OF((int));
ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp));
ZEXTERN const uLongf * ZEXPORT get_crc_table OF((void));
ZEXTERN const z_crc_t FAR * ZEXPORT get_crc_table OF((void));
ZEXTERN int ZEXPORT inflateUndermine OF((z_streamp, int));
ZEXTERN int ZEXPORT inflateResetKeep OF((z_streamp));
ZEXTERN int ZEXPORT deflateResetKeep OF((z_streamp));
#if defined(_WIN32) && !defined(Z_SOLO)
ZEXTERN gzFile ZEXPORT gzopen_w OF((const wchar_t *path,
const char *mode));
#endif
#if defined(STDC) || defined(Z_HAVE_STDARG_H)
# ifndef Z_SOLO
ZEXTERN int ZEXPORTVA gzvprintf Z_ARG((gzFile file,
const char *format,
va_list va));
# endif
#endif
#ifdef __cplusplus
}

View File

@ -1066,7 +1066,7 @@ void PR_Compile_f(void)
Q_SetProgsParms(true);
killondone = true;
}
if (PR_StartCompile(svprogfuncs, argc, argv))
if (svprogfuncs->StartCompile && PR_StartCompile(svprogfuncs, argc, argv))
while(PR_ContinueCompile(svprogfuncs));
if (killondone)
@ -1148,7 +1148,7 @@ void PR_BreakPoint_f(void)
else
Con_Printf("Breakpoint has been cleared\n");
Cvar_Set(Cvar_FindVar("debugger"), "1");
// Cvar_Set(Cvar_FindVar("debugger"), "1");
}
void PR_WatchPoint_f(void)
{
@ -1185,7 +1185,7 @@ void PR_WatchPoint_f(void)
Con_Printf("Watchpoint cleared\n");
pr_global_struct->self = oldself;
Cvar_Set(Cvar_FindVar("debugger"), "1");
// Cvar_Set(Cvar_FindVar("debugger"), "1");
}
static void PR_SSProfile_f(void)
@ -1246,6 +1246,7 @@ void PR_Init(void)
Cmd_AddCommand ("breakpoint", PR_BreakPoint_f);
Cmd_AddCommand ("watchpoint", PR_WatchPoint_f);
Cmd_AddCommand ("watchpoint_ssqc", PR_WatchPoint_f);
Cmd_AddCommand ("decompile", PR_Decompile_f);
Cmd_AddCommand ("compile", PR_Compile_f);
Cmd_AddCommand ("applycompile", PR_ApplyCompilation_f);
@ -8638,9 +8639,9 @@ static void QCBUILTIN PF_runclientphys(pubprogfuncs_t *prinst, struct globalvars
edict_t *ent = G_EDICT(prinst, OFS_PARM0);
edict_t *touched;
if (ent->readonly)
if (!ent || ent->readonly)
{
Con_Printf("runplayerphysics called on read-only entity");
Con_Printf("runplayerphysics called on read-only entity\n");
return;
}
@ -8648,16 +8649,14 @@ static void QCBUILTIN PF_runclientphys(pubprogfuncs_t *prinst, struct globalvars
pmove.sequence = *pr_global_ptrs->clientcommandframe;
else
pmove.sequence = 0;
if (host_client && host_client->edict == ent)
pmove.pm_type = SV_PMTypeForClient(host_client);
else
pmove.pm_type = PM_NORMAL;
pmove.pm_type = SV_PMTypeForClient((host_client && host_client->edict == ent)?host_client:NULL, ent);
pmove.jump_msec = 0;
pmove.jump_held = ((int)ent->xv->pmove_flags)&PMF_JUMP_HELD;
if (progstype != PROG_QW) //this is just annoying.
pmove.waterjumptime = sv_player->v->teleport_time - sv.time;
pmove.waterjumptime = ent->v->teleport_time - sv.time;
else
pmove.waterjumptime = ent->v->teleport_time;
@ -8729,7 +8728,7 @@ static void QCBUILTIN PF_runclientphys(pubprogfuncs_t *prinst, struct globalvars
ent->xv->pmove_flags += ((int)pmove.jump_held?PMF_JUMP_HELD:0);
ent->xv->pmove_flags += ((int)pmove.onladder?PMF_LADDER:0);
if (progstype != PROG_QW) //this is just annoying.
sv_player->v->teleport_time = sv.time + pmove.waterjumptime;
ent->v->teleport_time = sv.time + pmove.waterjumptime;
else
ent->v->teleport_time = pmove.waterjumptime;
VectorCopy(pmove.origin, ent->v->origin);
@ -8737,7 +8736,7 @@ static void QCBUILTIN PF_runclientphys(pubprogfuncs_t *prinst, struct globalvars
VectorCopy(pmove.velocity, ent->v->velocity);
VectorCopy(pmove.angles, sv_player->v->v_angle);
VectorCopy(pmove.angles, ent->v->v_angle);
ent->v->waterlevel = pmove.waterlevel;
@ -8757,7 +8756,7 @@ static void QCBUILTIN PF_runclientphys(pubprogfuncs_t *prinst, struct globalvars
if (pmove.onground)
{
ent->v->flags = (int)sv_player->v->flags | FL_ONGROUND;
ent->v->flags = (int)ent->v->flags | FL_ONGROUND;
ent->v->groundentity = EDICT_TO_PROG(svprogfuncs, EDICT_NUM(svprogfuncs, pmove.physents[pmove.groundent].info));
}
else
@ -10588,6 +10587,7 @@ void PR_DumpPlatform_f(void)
{"CSQC_UpdateViewLoading", "noref void(float vwidth, float vheight, float notmenu)", CS, "Alternative to CSQC_UpdateView, called when the engine thinks there should be a loading screen. If present, will inhibit the engine's normal loading screen, deferring to qc to draw it."},
{"CSQC_Parse_StuffCmd", "noref void(string msg)", CS, "Gives the CSQC a chance to intercept stuffcmds. Use the tokenize builtin to parse the message. Unrecognised commands would normally be localcmded, but its probably better to drop unrecognised stuffcmds completely."},
{"CSQC_Parse_CenterPrint", "noref float(string msg)", CS, "Gives the CSQC a chance to intercept centerprints. Return true if you wish the engine to otherwise ignore the centerprint."},
{"CSQC_Parse_Damage", "noref float(float save, float take, vector inflictororg)", CS, "Called as a result of player.dmg_save or player.dmg_take being set on the server.\nReturn true to completely inhibit the engine's colour shift and damage rolls, allowing you to do your own thing.\nYou can use punch_roll += (normalize(inflictororg-player.origin)*v_right)*(take+save)*autocvar_v_kickroll; as a modifier for the roll angle should the player be hit from the side, and slowly fade it away over time."},
{"CSQC_Parse_Print", "noref void(string printmsg, float printlvl)", CS, "Gives the CSQC a chance to intercept sprint/bprint builtin calls. CSQC should filter by the client's current msg setting and then pass the message on to the print command, or handle them itself."},
{"CSQC_Parse_Event", "noref void()", CS, "Called when the client receives an SVC_CGAMEPACKET. The csqc should read the data or call the error builtin if it does not recognise the message."},
{"CSQC_InputEvent", "noref float(float evtype, float scanx, float chary, float devid)", CS, "Called whenever a key is pressed, the mouse is moved, etc. evtype will be one of the IE_* constants. The other arguments vary depending on the evtype. Key presses are not guarenteed to have both scan and unichar values set at the same time."},
@ -10603,6 +10603,9 @@ void PR_DumpPlatform_f(void)
{"GameCommand", "noref void(string cmdtext)", CS|MENU},
{"init", "noref void()", QW|NQ|CS, "Part of FTE_MULTIPROGS. Called as soon as a progs is loaded, called at a time when entities are not valid. This is the only time when it is safe to call addprogs without field assignment. As it is also called as part of addprogs, this also gives you a chance to hook functions in modules that are already loaded (via externget+externget)."},
{"initents", "noref void()", QW|NQ|CS, "Part of FTE_MULTIPROGS. Called after fields have been finalized. This is the first point at which it is safe to call spawn(), and is called before any entity fields have been parsed. You can use this entrypoint to send notifications to other modules."},
{"m_init", "void()", MENU},
{"m_shutdown", "void()", MENU},
{"m_draw", "void()", MENU},
@ -10868,24 +10871,26 @@ void PR_DumpPlatform_f(void)
{"gamestate", "hashtable", ALL, "Special hash table index for hash_add and hash_get. Entries in this table will persist over map changes (and doesn't need to be created/deleted).", 0},
{"HASH_REPLACE", "const float", ALL, "Used with hash_add. Attempts to remove the old value instead of adding two values for a single key.", 256},
{"STAT_HEALTH", "const float", CS, NULL, STAT_HEALTH},
{"STAT_WEAPON", "const float", CS, NULL, STAT_WEAPON},
{"STAT_AMMO", "const float", CS, NULL, STAT_AMMO},
{"STAT_HEALTH", "const float", CS, "Player's health.", STAT_HEALTH},
{"STAT_WEAPONMODELI", "const float", CS, "This is the modelindex of the current viewmodel (renamed from the original name 'STAT_WEAPON' due to confusions).", STAT_WEAPONMODELI},
{"STAT_AMMO", "const float", CS, "player.currentammo", STAT_AMMO},
{"STAT_ARMOR", "const float", CS, NULL, STAT_ARMOR},
{"STAT_WEAPONFRAME", "const float", CS, NULL, STAT_WEAPONFRAME},
{"STAT_SHELLS", "const float", CS, NULL, STAT_SHELLS},
{"STAT_NAILS", "const float", CS, NULL, STAT_NAILS},
{"STAT_ROCKETS", "const float", CS, NULL, STAT_ROCKETS},
{"STAT_CELLS", "const float", CS, NULL, STAT_CELLS},
{"STAT_ACTIVEWEAPON", "const float", CS, NULL, STAT_ACTIVEWEAPON},
{"STAT_ACTIVEWEAPON", "const float", CS, "player.weapon", STAT_ACTIVEWEAPON},
{"STAT_TOTALSECRETS", "const float", CS, NULL, STAT_TOTALSECRETS},
{"STAT_TOTALMONSTERS", "const float", CS, NULL, STAT_TOTALMONSTERS},
{"STAT_FOUNDSECRETS", "const float", CS, NULL, STAT_SECRETS},
{"STAT_KILLEDMONSTERS", "const float", CS, NULL, STAT_MONSTERS},
{"STAT_ITEMS", "const float", CS, NULL, STAT_ITEMS},
{"STAT_VIEWHEIGHT", "const float", CS, NULL, STAT_VIEWHEIGHT},
{"STAT_ITEMS", "const float", CS, "self.items | (self.items2<<23). In order to decode this stat properly, you need to use getstatbits(STAT_ITEMS,0,23) to read self.items, and getstatbits(STAT_ITEMS,23,11) to read self.items2 or getstatbits(STAT_ITEMS,28,4) to read the visible part of serverflags, whichever is applicable.", STAT_ITEMS},
{"STAT_VIEWHEIGHT", "const float", CS, "player.view_ofs_z", STAT_VIEWHEIGHT},
{"STAT_VIEW2", "const float", CS, "This stat contains the number of the entity in the server's .view2 field.", STAT_VIEW2},
{"STAT_VIEWZOOM", "const float", CS, NULL, STAT_VIEWZOOM},
{"STAT_VIEWZOOM", "const float", CS, "Scales fov and sensitiity. Part of DP_VIEWZOOM.", STAT_VIEWZOOM},
{"STAT_USER", "const float", QW|NQ|CS, "Custom user stats start here (lower values are reserved for engine use).", 32},
{"VF_MIN", "const float", CS|MENU, "The top-left of the 3d viewport in screenspace. The VF_ values are used via the setviewprop/getviewprop builtins.", VF_MIN},
{"VF_MIN_X", "const float", CS|MENU, NULL, VF_MIN_X},
@ -10980,6 +10985,9 @@ void PR_DumpPlatform_f(void)
{"LFIELD_DIFFUSESCALE", "const float", CS, NULL, lfield_diffusescale},
{"LFIELD_SPECULARSCALE","const float", CS, NULL, lfield_specularscale},
{"LFIELD_ROTATION", "const float", CS, NULL, lfield_rotation},
{"LFIELD_DIETIME", "const float", CS, NULL, lfield_dietime},
{"LFIELD_RGBDECAY", "const float", CS, NULL, lfield_rgbdecay},
{"LFIELD_RADIUSDECAY", "const float", CS, NULL, lfield_radiusdecay},
{"LFLAG_NORMALMODE", "const float", CS, NULL, LFLAG_NORMALMODE},
{"LFLAG_REALTIMEMODE", "const float", CS, NULL, LFLAG_REALTIMEMODE},

View File

@ -878,6 +878,7 @@ typedef struct
#define MOVETYPE_H2PUSHPULL 13 // pushable/pullable object
#define MOVETYPE_H2SWIM 14 // should keep the object in water
#define MOVETYPE_PHYSICS 32
#define MOVETYPE_FLY_WORLDONLY 33
// edict->solid values
#define SOLID_NOT 0 // no interaction with other objects
@ -1145,7 +1146,7 @@ void SVNQ_ExecuteClientMessage (client_t *cl);
qboolean SV_UserInfoIsBasic(char *infoname); //standard message.
void SV_ExecuteClientMessage (client_t *cl);
void SVQ2_ExecuteClientMessage (client_t *cl);
int SV_PMTypeForClient (client_t *cl);
int SV_PMTypeForClient (client_t *cl, edict_t *ent);
void SV_UserInit (void);
qboolean SV_TogglePause (client_t *cl);

View File

@ -1430,11 +1430,11 @@ static void SV_WriteIP_f (void)
}
}
if (bi->reason[0])
s = va("%s %s %llu \"%s\"\n", banflags, NET_AdrToStringMasked(adr, sizeof(adr), &bi->adr, &bi->adrmask), (unsigned long long) bi->expiretime, bi->reason);
s = va("addip %s %s %llu \"%s\"\n", NET_AdrToStringMasked(adr, sizeof(adr), &bi->adr, &bi->adrmask), banflags, (unsigned long long) bi->expiretime, bi->reason);
else if (bi->expiretime)
s = va("%s %s %llu\n", banflags, NET_AdrToStringMasked(adr, sizeof(adr), &bi->adr, &bi->adrmask), (unsigned long long) bi->expiretime);
s = va("addip %s %s %llu\n", NET_AdrToStringMasked(adr, sizeof(adr), &bi->adr, &bi->adrmask), banflags, (unsigned long long) bi->expiretime);
else
s = va("%s %s\n", banflags, NET_AdrToStringMasked(adr, sizeof(adr), &bi->adr, &bi->adrmask));
s = va("addip %s %s\n", NET_AdrToStringMasked(adr, sizeof(adr), &bi->adr, &bi->adrmask), banflags);
VFS_WRITE(f, s, strlen(s));
bi = bi->next;
}

View File

@ -1941,7 +1941,7 @@ void SV_WritePlayerToClient(sizebuf_t *msg, clstate_t *ent)
if (ent->cl->viewent)
pm_type = PMC_NONE;
else
pm_type = SV_PMTypeForClient (ent->cl);
pm_type = SV_PMTypeForClient (ent->cl, ent->cl->edict);
switch (pm_type)
{
case PM_NORMAL: // Z_EXT_PM_TYPE protocol extension

View File

@ -2121,6 +2121,7 @@ void WPhys_RunEntity (world_t *w, wedict_t *ent)
case MOVETYPE_FOLLOW:
WPhys_Physics_Follow (w, ent);
break;
case MOVETYPE_FLY_WORLDONLY:
case MOVETYPE_FLY:
case MOVETYPE_H2SWIM:
case MOVETYPE_TOSS:

View File

@ -1771,9 +1771,9 @@ void SV_CalcClientStats(client_t *client, int statsi[MAX_CL_STATS], float statsf
#endif
{
statsf[STAT_HEALTH] = ent->v->health; //sorry, but mneh
statsi[STAT_WEAPON] = SV_ModelIndex(PR_GetString(svprogfuncs, ent->v->weaponmodel));
if ((unsigned)statsi[STAT_WEAPON] >= client->maxmodels)
statsi[STAT_WEAPON] = 0; //play it safe, try not to crash unsuspecting clients
statsi[STAT_WEAPONMODELI] = SV_ModelIndex(PR_GetString(svprogfuncs, ent->v->weaponmodel));
if ((unsigned)statsi[STAT_WEAPONMODELI] >= client->maxmodels)
statsi[STAT_WEAPONMODELI] = 0; //play it safe, try not to crash unsuspecting clients
statsf[STAT_AMMO] = ent->v->currentammo;
statsf[STAT_ARMOR] = ent->v->armorvalue;
statsf[STAT_SHELLS] = ent->v->ammo_shells;

View File

@ -259,7 +259,7 @@ void SV_New_f (void)
gamedir = Info_ValueForKey (svs.info, "*gamedir");
if (!gamedir[0])
{
if (ISQWCLIENT(host_client))
if (ISQWCLIENT(host_client) || ISQ2CLIENT(host_client))
gamedir = FS_GetGamedir(true);
else
gamedir = "";
@ -5780,7 +5780,7 @@ void AddAllEntsToPmove (edict_t *player)
}
}
int SV_PMTypeForClient (client_t *cl)
int SV_PMTypeForClient (client_t *cl, edict_t *ent)
{
#ifdef SERVER_DEMO_PLAYBACK
if (sv.demostatevalid)
@ -5793,23 +5793,23 @@ int SV_PMTypeForClient (client_t *cl)
if (sv_brokenmovetypes.value) //this is to mimic standard qw servers, which don't support movetypes other than MOVETYPE_FLY.
{ //it prevents bugs from being visible in unsuspecting mods.
if (cl->spectator)
if (cl && cl->spectator)
{
if (cl->zquake_extensions & Z_EXT_PM_TYPE_NEW)
return PM_SPECTATOR;
return PM_OLD_SPECTATOR;
}
if (cl->edict->v->health <= 0)
if (ent->v->health <= 0)
return PM_DEAD;
return PM_NORMAL;
}
switch((int)cl->edict->v->movetype)
switch((int)ent->v->movetype)
{
case MOVETYPE_NOCLIP:
/*older/vanilla clients have a b0rked spectator mode that we don't want to break*/
if (cl->zquake_extensions & Z_EXT_PM_TYPE_NEW)
if (cl && cl->zquake_extensions & Z_EXT_PM_TYPE_NEW)
return PM_SPECTATOR;
return PM_OLD_SPECTATOR;
@ -5819,6 +5819,7 @@ int SV_PMTypeForClient (client_t *cl)
case MOVETYPE_6DOF:
return PM_6DOF;
case MOVETYPE_FLY_WORLDONLY:
case MOVETYPE_FLY:
return PM_FLY;
@ -5827,7 +5828,7 @@ int SV_PMTypeForClient (client_t *cl)
case MOVETYPE_WALK:
default:
if (cl->edict->v->health <= 0)
if (ent->v->health <= 0)
return PM_DEAD;
return PM_NORMAL;
@ -6192,7 +6193,7 @@ void SV_RunCmd (usercmd_t *ucmd, qboolean recurse)
VectorCopy (sv_player->v->velocity, pmove.velocity);
VectorCopy (sv_player->v->v_angle, pmove.angles);
pmove.pm_type = SV_PMTypeForClient (host_client);
pmove.pm_type = SV_PMTypeForClient (host_client, sv_player);
pmove.jump_held = host_client->jump_held;
pmove.jump_msec = 0;
if (progstype != PROG_QW) //this is just annoying.

View File

@ -71,7 +71,7 @@ void *SVQ2_GetGameAPI (void *parms)
Q_snprintfz(name, sizeof(name), "%slibgame_%s"ARCH_DL_POSTFIX, host_parms.binarydir, gamepath);
}
else
{
{ //gamedir paths as specified above.
if (com_nogamedirnativecode.ival)
continue;
Q_snprintfz(name, sizeof(name), "%s%s", syspath, gamename[o]);

View File

@ -1039,6 +1039,8 @@ qboolean World_TransformedTrace (struct model_s *model, int hulloverride, int fr
result = Q1BSP_RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, start_l, end_l, trace);
VectorAdd (trace->endpos, origin, trace->endpos);
}
else
result = false;
return result;
}

View File

@ -40,19 +40,16 @@ void main (void)
}
#endif
#ifdef FRAGMENT_SHADER
#define s_refract s_t0
#define s_reflect s_t1
#define s_ripplemap s_t2
#define s_refractdepth s_t3
uniform float cvar_r_glsl_turbscale;
uniform sampler2D s_t0; //refract
uniform sampler2D s_t1; //normalmap
uniform sampler2D s_t2; //diffuse/reflection
#ifdef DEPTH
uniform sampler2D s_t3; //refraction depth
#define s_ripplemap s_t4
#else
#define s_ripplemap s_t3
#endif
#ifdef RIPPLEMAP
uniform sampler2D s_refract; //refract
uniform sampler2D s_reflect; //reflection
uniform sampler2D s_refractdepth; //refraction depth
uniform sampler2D s_ripplemap; //ripplemap
#endif
uniform float e_time;
void main (void)
@ -70,8 +67,8 @@ void main (void)
ntc.t = tc.t + sin(tc.s+e_time)*0.125;
//generate the two wave patterns from the normalmap
n = (texture2D(s_t1, TXSCALE*tc + vec2(e_time*0.1, 0.0)).xyz);
n += (texture2D(s_t1, TXSCALE*tc - vec2(0, e_time*0.097)).xyz);
n = (texture2D(s_normalmap, TXSCALE*tc + vec2(e_time*0.1, 0.0)).xyz);
n += (texture2D(s_normalmap, TXSCALE*tc - vec2(0, e_time*0.097)).xyz);
n -= 1.0 - 4.0/256.0;
#ifdef RIPPLEMAP
@ -90,7 +87,7 @@ void main (void)
sdepth = mix(near, far, sdepth);
//get depth value at the ground beyond the surface.
float gdepth = texture2D(s_t3, stc).x;
float gdepth = texture2D(s_refractdepth, stc).x;
gdepth = (2.0*near) / (far + near - gdepth * (far - near));
if (gdepth >= 0.5)
{
@ -112,16 +109,16 @@ void main (void)
//refraction image (and water fog, if possible)
refr = texture2D(s_t0, stc + n.st*STRENGTH*cvar_r_glsl_turbscale).rgb * TINT;
refr = texture2D(s_refract, stc + n.st*STRENGTH*cvar_r_glsl_turbscale).rgb * TINT;
#ifdef DEPTH
refr = mix(refr, FOGTINT, min(depth/4096.0, 1.0));
#endif
//reflection/diffuse
#ifdef REFLECT
refl = texture2D(s_t2, stc - n.st*STRENGTH*cvar_r_glsl_turbscale).rgb;
refl = texture2D(s_reflect, stc - n.st*STRENGTH*cvar_r_glsl_turbscale).rgb;
#else
refl = texture2D(s_t2, ntc).xyz;
refl = texture2D(s_diffuse, ntc).xyz;
#endif
//FIXME: add specular

View File

@ -7,6 +7,8 @@
!!cvarf r_glsl_offsetmapping_scale
!!cvarf gl_specular
#include "sys/defs.h"
//standard shader used for models.
//must support skeletal and 2-way vertex blending or Bad Things Will Happen.
//the vertex shader is responsible for calculating lighting values.
@ -22,13 +24,6 @@ varying vec3 eyevector;
#ifdef VERTEX_SHADER
#include "sys/skeletal.h"
attribute vec2 v_texcoord;
uniform vec3 e_light_dir;
uniform vec3 e_light_mul;
uniform vec3 e_light_ambient;
#if defined(SPECULAR) || defined(OFFSETMAPPING)
uniform vec3 e_eyepos;
#endif
void main ()
{
#if defined(SPECULAR)||defined(OFFSETMAPPING)
@ -52,25 +47,8 @@ void main ()
#endif
#ifdef FRAGMENT_SHADER
#include "sys/fog.h"
uniform sampler2D s_t0;
#ifdef LOWER
uniform sampler2D s_t1;
uniform vec3 e_lowercolour;
#endif
#ifdef UPPER
uniform sampler2D s_t2;
uniform vec3 e_uppercolour;
#endif
#ifdef FULLBRIGHT
uniform sampler2D s_t3;
#endif
#if defined(BUMP)
uniform sampler2D s_t4;
#endif
#if defined(SPECULAR)
uniform sampler2D s_t5;
uniform float cvar_gl_specular;
#endif
@ -78,31 +56,28 @@ uniform float cvar_gl_specular;
#include "sys/offsetmapping.h"
#endif
uniform vec4 e_colourident;
void main ()
{
vec4 col, sp;
#ifdef OFFSETMAPPING
vec2 tcoffsetmap = offsetmap(s_t4, tc, eyevector);
vec2 tcoffsetmap = offsetmap(s_normalmap, tc, eyevector);
#define tc tcoffsetmap
#endif
col = texture2D(s_t0, tc);
col = texture2D(s_diffuse, tc);
#ifdef UPPER
vec4 uc = texture2D(s_t2, tc);
vec4 uc = texture2D(s_upper, tc);
col.rgb += uc.rgb*e_uppercolour*uc.a;
#endif
#ifdef LOWER
vec4 lc = texture2D(s_t1, tc);
vec4 lc = texture2D(s_lower, tc);
col.rgb += lc.rgb*e_lowercolour*lc.a;
#endif
#if defined(BUMP) && defined(SPECULAR)
vec3 bumps = normalize(vec3(texture2D(s_t4, tc)) - 0.5);
vec4 specs = texture2D(s_t5, tc);
vec3 bumps = normalize(vec3(texture2D(s_normalmap, tc)) - 0.5);
vec4 specs = texture2D(s_specular, tc);
vec3 halfdir = normalize(normalize(eyevector) + vec3(0.0, 0.0, 1.0));
float spec = pow(max(dot(halfdir, bumps), 0.0), 32.0 * specs.a);
@ -112,7 +87,7 @@ void main ()
col.rgb *= light;
#ifdef FULLBRIGHT
vec4 fb = texture2D(s_t3, tc);
vec4 fb = texture2D(s_fullbright, tc);
// col.rgb = mix(col.rgb, fb.rgb, fb.a);
col.rgb += fb.rgb * fb.a;
#endif

View File

@ -7,6 +7,8 @@
!!cvarf r_glsl_offsetmapping_scale
!!cvarf gl_specular
#include "sys/defs.h"
//this is what normally draws all of your walls, even with rtlights disabled
//note that the '286' preset uses drawflat_walls instead.
@ -25,19 +27,6 @@ varying vec2 lm0;
#endif
#ifdef VERTEX_SHADER
attribute vec2 v_texcoord;
attribute vec2 v_lmcoord;
#ifdef LIGHTSTYLED
attribute vec2 v_lmcoord2;
attribute vec2 v_lmcoord3;
attribute vec2 v_lmcoord4;
#endif
#if defined(OFFSETMAPPING) || defined(SPECULAR)
uniform vec3 e_eyepos;
attribute vec3 v_normal;
attribute vec3 v_svector;
attribute vec3 v_tvector;
#endif
void main ()
{
#if defined(OFFSETMAPPING) || defined(SPECULAR)
@ -61,50 +50,9 @@ void main ()
#ifdef FRAGMENT_SHADER
//samplers
#define s_diffuse s_t0
#define s_lightmap0 s_t1
#define s_normalmap s_t2
#define s_delux0 s_t3
#define s_fullbright s_t4
#define s_specular s_t5
#define s_lightmap1 s_t6
#define s_lightmap2 s_t7
#define s_lightmap3 s_t8
#define s_delux1 s_t9
#define s_delux2 s_t10
#define s_delux3 s_t11
#define s_paletted s_diffuse
#define s_colourmap s_fullbright
#define s_colourmap s_t0
uniform sampler2D s_colourmap;
uniform sampler2D s_diffuse;
uniform sampler2D s_lightmap0;
#if defined(BUMP) && (defined(OFFSETMAPPING) || defined(DELUXE) || defined(SPECULAR))
uniform sampler2D s_normalmap;
#endif
#ifdef DELUXE
uniform sampler2D s_delux0;
#endif
#if defined(FULLBRIGHT) || defined(EIGHTBIT)
uniform sampler2D s_fullbright;
#endif
#ifdef SPECULAR
uniform sampler2D s_specular;
#endif
#ifdef LIGHTSTYLED
uniform sampler2D s_lightmap1;
uniform sampler2D s_lightmap2;
uniform sampler2D s_lightmap3;
uniform sampler2D s_delux1;
uniform sampler2D s_delux2;
uniform sampler2D s_delux3;
#endif
#ifdef LIGHTSTYLED
uniform vec4 e_lmscale[4];
#else
uniform vec4 e_lmscale;
#endif
uniform vec4 e_colourident;
#ifdef SPECULAR
uniform float cvar_gl_specular;
#endif
@ -141,10 +89,10 @@ void main ()
#ifdef LIGHTSTYLED
vec3 lightmaps;
#ifdef DELUXE
lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb * dot(norm, 2.0*texture2D(s_delux0, lm0).rgb-0.5);
lightmaps += texture2D(s_lightmap1, lm1).rgb * e_lmscale[1].rgb * dot(norm, 2.0*texture2D(s_delux1, lm1).rgb-0.5);
lightmaps += texture2D(s_lightmap2, lm2).rgb * e_lmscale[2].rgb * dot(norm, 2.0*texture2D(s_delux2, lm2).rgb-0.5);
lightmaps += texture2D(s_lightmap3, lm3).rgb * e_lmscale[3].rgb * dot(norm, 2.0*texture2D(s_delux3, lm3).rgb-0.5);
lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb * dot(norm, 2.0*texture2D(s_deluxmap0, lm0).rgb-0.5);
lightmaps += texture2D(s_lightmap1, lm1).rgb * e_lmscale[1].rgb * dot(norm, 2.0*texture2D(s_deluxmap1, lm1).rgb-0.5);
lightmaps += texture2D(s_lightmap2, lm2).rgb * e_lmscale[2].rgb * dot(norm, 2.0*texture2D(s_deluxmap2, lm2).rgb-0.5);
lightmaps += texture2D(s_lightmap3, lm3).rgb * e_lmscale[3].rgb * dot(norm, 2.0*texture2D(s_deluxmap3, lm3).rgb-0.5);
#else
lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb;
lightmaps += texture2D(s_lightmap1, lm1).rgb * e_lmscale[1].rgb;
@ -152,10 +100,12 @@ void main ()
lightmaps += texture2D(s_lightmap3, lm3).rgb * e_lmscale[3].rgb;
#endif
#else
vec3 lightmaps = (texture2D(s_lightmap0, lm0) * e_lmscale).rgb;
vec3 lightmaps = (texture2D(s_lightmap, lm0) * e_lmscale).rgb;
//modulate by the bumpmap dot light
#ifdef DELUXE
lightmaps *= dot(norm, 2.0*(texture2D(s_delux0, lm0).rgb-0.5));
vec3 delux = 2.0*(texture2D(s_deluxmap, lm0).rgb-0.5);
lightmaps *= 1.0 / max(0.25, delux.z); //counter the darkening from deluxmaps
lightmaps *= dot(norm, delux);
#endif
#endif
@ -164,7 +114,7 @@ void main ()
vec4 specs = texture2D(s_specular, tc);
#ifdef DELUXE
//not lightstyled...
vec3 halfdir = normalize(normalize(eyevector) + 2.0*(texture2D(s_delux0, lm0).rgb-0.5)); //this norm should be the deluxemap info instead
vec3 halfdir = normalize(normalize(eyevector) + 2.0*(texture2D(s_deluxmap0, lm0).rgb-0.5)); //this norm should be the deluxemap info instead
#else
vec3 halfdir = normalize(normalize(eyevector) + vec3(0.0, 0.0, 1.0)); //this norm should be the deluxemap info instead
#endif
@ -179,7 +129,7 @@ void main ()
#ifdef EIGHTBIT //FIXME: with this extra flag, half the permutations are redundant.
lightmaps *= 0.5; //counter the fact that the colourmap contains overbright values and logically ranges from 0 to 2 intead of to 1.
float pal = texture2D(s_diffuse, tc).r; //the palette index. hopefully not interpolated.
float pal = texture2D(s_paletted, tc).r; //the palette index. hopefully not interpolated.
lightmaps -= 1.0 / 128.0; //software rendering appears to round down, so make sure we favour the lower values instead of rounding to the nearest
gl_FragColor.r = texture2D(s_colourmap, vec2(pal, 1.0-lightmaps.r)).r; //do 3 lookups. this is to cope with lit files, would be a waste to not support those.
gl_FragColor.g = texture2D(s_colourmap, vec2(pal, 1.0-lightmaps.g)).g; //its not very softwarey, but re-palettizing is ugly.

View File

@ -1,5 +1,7 @@
!!cvarf r_wateralpha
!!permu FOG
!!cvarf r_wateralpha
#include "sys/defs.h"
//this is the shader that's responsible for drawing default q1 turbulant water surfaces
//this is expected to be moderately fast.
@ -7,16 +9,16 @@
#include "sys/fog.h"
varying vec2 tc;
#ifdef VERTEX_SHADER
attribute vec2 v_texcoord;
void main ()
{
tc = v_texcoord.st;
#ifdef FLOW
tc.s += e_time * -0.5;
#endif
gl_Position = ftetransform();
}
#endif
#ifdef FRAGMENT_SHADER
uniform sampler2D s_t0;
uniform float e_time;
#ifndef ALPHA
uniform float cvar_r_wateralpha;
#define USEALPHA cvar_r_wateralpha
@ -28,7 +30,7 @@ void main ()
vec2 ntc;
ntc.s = tc.s + sin(tc.t+e_time)*0.125;
ntc.t = tc.t + sin(tc.s+e_time)*0.125;
vec3 ts = vec3(texture2D(s_t0, ntc));
vec3 ts = vec3(texture2D(s_diffuse, ntc));
gl_FragColor = fog4(vec4(ts, USEALPHA));
}
#endif

View File

@ -29,9 +29,8 @@
float3 l_lightcolour;
float3 l_lightposition;
sampler s_t0; /*diffuse*/
sampler s_t1; /*normal*/
sampler s_t2; /*specular*/
sampler s_diffuse; /*diffuse*/
sampler s_fullbright; /*normal*/
float4 main (v2f inp) : COLOR0
{
float2 tccoord;
@ -42,10 +41,10 @@
dir.xy /= 0.5*length(dir);
tccoord = (dir.xy + e_time*0.03125);
float4 solid = tex2D(s_t0, tccoord);
float4 solid = tex2D(s_diffuse, tccoord);
tccoord = (dir.xy + e_time*0.0625);
float4 clouds = tex2D(s_t1, tccoord);
float4 clouds = tex2D(s_fullbright, tccoord);
return float4((solid.rgb*(1.0-clouds.a)) + (clouds.a*clouds.rgb), 1);
}

View File

@ -23,13 +23,13 @@ struct v2f {
#ifdef FRAGMENT_SHADER
float cvar_r_wateralpha;
float e_time;
sampler s_t0;
sampler s_diffuse;
float4 main (v2f inp) : COLOR0
{
float2 ntc;
ntc.x = inp.tc.x + sin(inp.tc.y+e_time)*0.125;
ntc.y = inp.tc.y + sin(inp.tc.x+e_time)*0.125;
float3 ts = tex2D(s_t0, ntc).xyz;
float3 ts = tex2D(s_diffuse, ntc).xyz;
return float4(ts, cvar_r_wateralpha);
}

View File

@ -48,15 +48,14 @@
#endif
#ifdef FRAGMENT_SHADER
sampler s_t0;
sampler s_t1;
sampler s_diffuse;
float l_lightradius;
float3 l_lightcolour;
float4 main (v2f inp) : COLOR0
{
float3 col = l_lightcolour;
col *= max(1.0 - dot(inp.lpos, inp.lpos)/(l_lightradius*l_lightradius), 0.0);
float3 diff = tex2D(s_t0, inp.tc);
float3 diff = tex2D(s_diffuse, inp.tc);
return float4(diff * col, 1);
}
#endif

View File

@ -761,6 +761,8 @@ qboolean SW_VID_Init(rendererstate_t *info, unsigned char *palette)
}
void SW_VID_DeInit(void)
{
Image_Shutdown();
DIB_Shutdown();
DestroyWindow(mainwindow);