1
0
Fork 0
forked from fte/fteqw

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/ 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" 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)\$(MSVCPATH)\VC\LIB\amd64" /LIBPATH:"$(WINDOWSSDKDIR)\lib\amd64" /LIBPATH:"C:\Program Files (x86)\$(MSVCPATH)\SDK\v2.0\LIB\AMD64" 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 JPEGLIB=libs/libjpeg$(BITS).lib
else else
WINDRES=i686-w64-mingw32-windres WINDRES=i686-w64-mingw32-windres
MSVCPATH=C:/Program Files (x86)/$(MSVCDIR)/VC/BIN/ 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" 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 JPEGLIB=libs/jpeg.lib
endif endif
@ -943,7 +943,7 @@ ifeq ($(FTE_TARGET),vc)
STRIP=@echo strip STRIP=@echo strip
EXEPOSTFIX=.exe 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 DEBUG_CFLAGS ?= -Od $(CPUOPTIMIZATIONS) /fp:fast
PROFILE_CFLAGS = -O2 -Ot -Ox -GL $(CPUOPTIMISATIONS) /fp:fast PROFILE_CFLAGS = -O2 -Ot -Ox -GL $(CPUOPTIMISATIONS) /fp:fast
PROFILE_LDFLAGS = /LTCG:PGINSTRUMENT PROFILE_LDFLAGS = /LTCG:PGINSTRUMENT
@ -951,8 +951,8 @@ ifeq ($(FTE_TARGET),vc)
RELEASE_LDFLAGS = /LTCG RELEASE_LDFLAGS = /LTCG
# /LTCG:PGOPTIMIZE # /LTCG:PGOPTIMIZE
DO_CC=$(CC) /nologo $(ALL_CFLAGS) -Fo$(shell cygpath -m $@) -c $(shell cygpath -m $<) DO_CC=$(DO_ECHO) $(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_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 = PRECOMPHEADERS =
DEPCC= DEPCC=

View file

@ -471,7 +471,7 @@ void Cam_TrackCrosshairedPlayer(playerview_t *pv)
best = i; 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? if (best != -1) //did we actually get someone?
{ {
pv->cam_auto++; pv->cam_auto++;

View file

@ -388,17 +388,44 @@ qboolean CG_GetServerCommand(int cmdnum)
typedef struct { typedef struct {
int firstPoint; int firstPoint;
int numPoints; 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 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 center;
vec3_t axis[3]; vec3_t axis[3];
vec3_t p[4]; vec3_t p[4];
int i; int i;
float *clippedpoints;
float radius; float radius;
int numtris; q3markFragment_ctx_t ctx;
if (numPoints != 4) if (numPoints != 4)
return 0; return 0;
@ -438,27 +465,14 @@ int CG_MarkFragments( int numPoints, const vec3_t *points, const vec3_t projecti
VectorNormalize(axis[2]); VectorNormalize(axis[2]);
VectorNormalize2(projection, axis[0]); VectorNormalize2(projection, axis[0]);
numtris = Q1BSP_ClipDecal(cl.worldmodel, center, axis[0], axis[1], axis[2], radius, &clippedpoints); ctx.points = pointBuffer;
if (numtris > maxFragments) ctx.maxpoints = maxPoints;
numtris = maxFragments; ctx.numpoints = 0;
if (numtris > maxPoints/3) ctx.frags = fragmentBuffer;
numtris = maxPoints/3; ctx.numfrags = 0;
for (i = 0; i < numtris; i++) ctx.maxfrags = maxFragments;
{ Mod_ClipDecal(cl.worldmodel, center, axis[0], axis[1], axis[2], radius, CG_MarkFragments_Callback, &ctx);
fragmentBuffer[i].numPoints = 3; return ctx.numfrags;
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;
} }
int VM_LerpTag(void *out, model_t *model, int f1, int f2, float l2, char *tagname); 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) else if (demotime > cls.td_lastframe)
{ {
cls.td_lastframe = demotime; 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) if (cls.td_startframe == -1 && cls.state == ca_active)
{ //start the timer only once we are connected. { //start the timer only once we are connected.
@ -841,7 +841,6 @@ readit:
demo_flushbytes(demopos); demo_flushbytes(demopos);
olddemotime = demotime; olddemotime = demotime;
// cls.td_lastframe = host_framecount;
return 1; 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) 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; scenetris_t *t;
float l, s; float l, s;
cl_adddecal_ctx_t ctx;
VectorNegate(up, up); VectorNegate(up, ctx.axis[0]);
CrossProduct(up, side, tang); VectorCopy(side, ctx.axis[2]);
CrossProduct(ctx.axis[0], ctx.axis[2], ctx.axis[1]);
s = sqrt(DotProduct(side, side)); s = sqrt(DotProduct(ctx.axis[2], ctx.axis[2]));
l = sqrt(DotProduct(tang, tang)); 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) ctx.offset[1] = DotProduct(origin, ctx.axis[1]) + 0.5;
return; ctx.offset[2] = DotProduct(origin, ctx.axis[2]) + 0.5;
num*=3; ctx.offset[0] = DotProduct(origin, ctx.axis[0]);
VectorScale(tang, 0.5/(s*s), tang); ctx.scale[1] = 1;
VectorScale(side, 0.5/(s*s), side); ctx.scale[2] = 1;
l = sqrt(DotProduct(up, up)); ctx.scale[0] = 1;
VectorScale(up, 1/(l*l), up);
tx = DotProduct(origin, tang) + 0.5;
ty = DotProduct(origin, side) + 0.5;
tz = DotProduct(origin, up);
/*reuse the previous trigroup if its the same shader*/ /*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)) 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; 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) if (!t->numidx)
{ cl_numstris--;
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;
} }
void CLQ1_AddShadow(entity_t *ent) void CLQ1_AddShadow(entity_t *ent)
@ -2629,12 +2649,10 @@ void CLQ1_AddShadow(entity_t *ent)
float radius; float radius;
vec3_t shadoworg; vec3_t shadoworg;
vec3_t eang; vec3_t eang;
vec3_t axis[3]; float tx, ty;
float tx, ty, tz;
float *verts;
shader_t *s; shader_t *s;
int v, num;
scenetris_t *t; scenetris_t *t;
cl_adddecal_ctx_t ctx;
if (!r_shadows.value || !ent->model || ent->model->type != mod_alias) if (!r_shadows.value || !ent->model || ent->model->type != mod_alias)
return; return;
@ -2667,18 +2685,15 @@ void CLQ1_AddShadow(entity_t *ent)
eang[0] = 0; eang[0] = 0;
eang[1] = ent->angles[1]; eang[1] = ent->angles[1];
eang[2] = 0; eang[2] = 0;
AngleVectors(eang, axis[0], axis[1], axis[2]); AngleVectors(eang, ctx.axis[1], ctx.axis[2], ctx.axis[0]);
VectorNegate(axis[2], axis[2]); VectorNegate(ctx.axis[0], ctx.axis[0]);
num = Q1BSP_ClipDecal(cl.worldmodel, shadoworg, axis[2], axis[1], axis[0], radius, &verts); ctx.offset[2] = DotProduct(shadoworg, ctx.axis[2]) + 0.5*radius;
ctx.offset[1] = DotProduct(shadoworg, ctx.axis[1]) + 0.5*radius;
if (!num) ctx.offset[0] = DotProduct(shadoworg, ctx.axis[0]);
return; ctx.scale[1] = 1/radius;
num*=3; ctx.scale[2] = 1/radius;
ctx.scale[0] = 0.5/radius;
tx = DotProduct(shadoworg, axis[1]) + 0.5*radius;
ty = DotProduct(shadoworg, axis[0]) + 0.5*radius;
tz = DotProduct(shadoworg, axis[2]);
/*reuse the previous trigroup if its the same shader*/ /*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)) 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; t->firstvert = cl_numstrisvert;
} }
ctx.t = t;
if (cl_numstrisvert + num > cl_maxstrisvert) 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);
cl_maxstrisvert = cl_numstrisvert + num; if (!t->numidx)
cl_numstris--;
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;
} }
void CLQ1_AddPowerupShell(entity_t *ent, qboolean viewweap, unsigned int effects) 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; player_state_t exact;
msec += cls.latency*1000; msec += cls.latency*1000;
@ -4180,6 +4165,7 @@ guess_pm_type:
msec = 255; msec = 255;
state->command.msec = msec; state->command.msec = msec;
//FIXME: flag these and do the pred elsewhere.
CL_SetSolidEntities(); CL_SetSolidEntities();
CL_SetSolidPlayers(); CL_SetSolidPlayers();
CL_PredictUsercmd (0, num+1, state, &exact, &state->command); //uses player 0's maxspeed/grav... 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) if (cl.intermission)
return; 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; return;
if (r_drawviewmodel.value > 0 && r_drawviewmodel.value < 1) if (r_drawviewmodel.value > 0 && r_drawviewmodel.value < 1)
@ -4669,7 +4655,7 @@ void CL_LinkViewModel(void)
ent.flags |= RF_TRANSLUCENT; 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) if (!ent.model)
return; return;

View file

@ -52,7 +52,7 @@ vec3_t mousemovements[MAX_SPLITS];
/*kinda a hack...*/ /*kinda a hack...*/
static int con_splitmodifier; 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; extern cvar_t cl_splitscreen;
int CL_TargettedSplit(qboolean nowrap) int CL_TargettedSplit(qboolean nowrap)
{ {
@ -75,8 +75,8 @@ int CL_TargettedSplit(qboolean nowrap)
if (con_splitmodifier > 0) if (con_splitmodifier > 0)
return (con_splitmodifier - 1) % mod; return (con_splitmodifier - 1) % mod;
else if (cl_forcesplitclient.ival > 0) else if (cl_forceseat.ival > 0)
return (cl_forcesplitclient.ival-1) % mod; return (cl_forceseat.ival-1) % mod;
else else
return 0; return 0;
} }
@ -638,7 +638,7 @@ void CL_ClampPitch (int pnum)
memset(pv->viewanglechange, 0, sizeof(pv->viewanglechange)); memset(pv->viewanglechange, 0, sizeof(pv->viewanglechange));
return; return;
} }
if (pv->pmovetype == PM_6DOF) if (pv->pmovetype == PM_6DOF)
{ {
// vec3_t impact; // vec3_t impact;
// vec3_t norm; // vec3_t norm;
@ -1960,7 +1960,7 @@ void CL_InitInput (void)
Cvar_Register (&cl_prydoncursor, inputnetworkcvargroup); Cvar_Register (&cl_prydoncursor, inputnetworkcvargroup);
Cvar_Register (&cl_instantrotate, inputnetworkcvargroup); Cvar_Register (&cl_instantrotate, inputnetworkcvargroup);
Cvar_Register (&cl_forcesplitclient, inputnetworkcvargroup); Cvar_Register (&cl_forceseat, inputnetworkcvargroup);
for (sp = 0; sp < MAX_SPLITS; sp++) for (sp = 0; sp < MAX_SPLITS; sp++)
{ {

View file

@ -213,10 +213,10 @@ int cl_maxvisedicts;
entity_t *cl_visedicts; entity_t *cl_visedicts;
scenetris_t *cl_stris; scenetris_t *cl_stris;
vecV_t *cl_strisvertv; vecV_t *fte_restrict cl_strisvertv;
vec4_t *cl_strisvertc; vec4_t *fte_restrict cl_strisvertc;
vec2_t *cl_strisvertt; vec2_t *fte_restrict cl_strisvertt;
index_t *cl_strisidx; index_t *fte_restrict cl_strisidx;
unsigned int cl_numstrisidx; unsigned int cl_numstrisidx;
unsigned int cl_maxstrisidx; unsigned int cl_maxstrisidx;
unsigned int cl_numstrisvert; unsigned int cl_numstrisvert;
@ -328,9 +328,9 @@ CL_Quit_f
*/ */
void CL_Quit_f (void) void CL_Quit_f (void)
{ {
if (forcesaveprompt) if (forcesaveprompt && strcmp(Cmd_Argv(1), "force"))
{ {
forcesaveprompt =false; forcesaveprompt = false;
if (Cmd_Exists("menu_quit")) if (Cmd_Exists("menu_quit"))
{ {
Cmd_ExecuteString("menu_quit", RESTRICT_LOCAL); Cmd_ExecuteString("menu_quit", RESTRICT_LOCAL);
@ -1317,6 +1317,14 @@ void CL_ClearState (void)
if (cl.particle_csname[i]) if (cl.particle_csname[i])
free(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; downloadlist_t *next;
@ -3842,6 +3850,7 @@ void VARGS Host_Error (char *error, ...)
va_start (argptr,error); va_start (argptr,error);
vsnprintf (string,sizeof(string)-1, error,argptr); vsnprintf (string,sizeof(string)-1, error,argptr);
va_end (argptr); va_end (argptr);
COM_AssertMainThread(string);
Con_TPrintf ("Host_Error: %s\n", string); Con_TPrintf ("Host_Error: %s\n", string);
CL_Disconnect (); 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. //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. //should smooth out a few things, and increase download speeds.
CL_ReadPackets (); if (!cls.timedemo)
CL_ReadPackets ();
if (idle && cl_idlefps.value > 0) if (idle && cl_idlefps.value > 0)
{ {

View file

@ -910,7 +910,7 @@ qboolean CL_CheckQ2BspWals(char *file)
unsigned int i, j, count; unsigned int i, j, count;
dh = (q2dheader_t*)file; dh = (q2dheader_t*)file;
if (LittleLong(dh->version) != Q2BSPVERSION) if (LittleLong(dh->version) != BSPVERSION_Q2)
{ {
//quake3? unknown? //quake3? unknown?
return false; return false;
@ -990,7 +990,7 @@ void Model_CheckDownloads (void)
for (i = 0; i < Q2MAX_IMAGES; i++) for (i = 0; i < Q2MAX_IMAGES; i++)
{ {
char picname[256]; char picname[256];
if (!*cl.image_name[i]) if (!cl.image_name[i] || !*cl.image_name[i])
continue; continue;
Q_snprintfz(picname, sizeof(picname), "pics/%s.pcx", cl.image_name[i]); Q_snprintfz(picname, sizeof(picname), "pics/%s.pcx", cl.image_name[i]);
CL_CheckOrEnqueDownloadFile(picname, picname, 0); 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_WEAPONFRAME, (bits & SU_WEAPONFRAME)?(unsigned short)MSG_ReadShort():0);
CL_SetStatInt(0, STAT_ARMOR, (bits & SU_ARMOR)?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()); 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_WEAPONFRAME, weaponframe);
CL_SetStatInt(0, STAT_ARMOR, armor); CL_SetStatInt(0, STAT_ARMOR, armor);
CL_SetStatInt(0, STAT_WEAPON, weaponmodel); CL_SetStatInt(0, STAT_WEAPONMODELI, weaponmodel);
CL_SetStatInt(0, STAT_HEALTH, health); CL_SetStatInt(0, STAT_HEALTH, health);
@ -3800,41 +3800,41 @@ void CLQ2_ParseConfigString (void)
} }
else if (i == Q2CS_CDTRACK) 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) 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.numq2visibleweapons < Q2MAX_VISIBLE_WEAPONS)
if (cl.model_name[i-Q2CS_MODELS][0] == '#')
{ {
if (cl.numq2visibleweapons < Q2MAX_VISIBLE_WEAPONS) cl.q2visibleweapons[cl.numq2visibleweapons] = cl.model_name[i-Q2CS_MODELS]+1;
{ cl.numq2visibleweapons++;
cl.q2visibleweapons[cl.numq2visibleweapons] = cl.model_name[i-Q2CS_MODELS]+1;
cl.numq2visibleweapons++;
}
cl.model_precache[i-Q2CS_MODELS] = NULL;
} }
else cl.model_precache[i-Q2CS_MODELS] = NULL;
cl.model_precache[i-Q2CS_MODELS] = Mod_ForName (cl.model_name[i-Q2CS_MODELS], MLV_WARN);
} }
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); 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) else if (i >= Q2CS_IMAGES && i < Q2CS_IMAGES+Q2MAX_IMAGES)
{ //ignore {
Q_strncpyz(cl.image_name[i-Q2CS_IMAGES], s, MAX_QPATH); 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) 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) else if (i == Q2CS_MAPCHECKSUM)
{ {
@ -4396,8 +4396,17 @@ void CL_NewTranslation (int slot)
skin = strchr(mod, '/'); skin = strchr(mod, '/');
if (skin) if (skin)
*skin++ = 0; *skin++ = 0;
if (!skin || !*skin)
skin = "grunt";
if (!mod || !*mod)
mod = "male";
player->model = Mod_ForName(va("players/%s/tris.md2", mod), 0); 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)); player->skinid = Mod_RegisterSkinFile(va("players/%s/%s.skin", mod,skin));
if (!player->skinid) if (!player->skinid)
player->skinid = Mod_ReadSkinFile(va("players/%s/%s.skin", mod,skin), va("replace \"\" \"players/%s/%s.pcx\"", mod,skin)); 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; cl.playerview[pnum].item_gettime[j] = cl.time;
} }
if (stat == STAT_WEAPON) if (stat == STAT_WEAPONMODELI)
{ {
if (cl.playerview[pnum].stats[stat] != ivalue) if (cl.playerview[pnum].stats[stat] != ivalue)
{ {
@ -5066,12 +5075,9 @@ void CLQ2_ParseMuzzleFlash2 (void)
void CLQ2_ParseInventory (void) void CLQ2_ParseInventory (void)
{ {
int i; unsigned int i;
// TODO: finish this properly
for (i=0 ; i<Q2MAX_ITEMS ; i++) for (i=0 ; i<Q2MAX_ITEMS ; i++)
// cl.inventory[i] = MSG_ReadShort (&net_message); cl.inventory[i] = MSG_ReadShort ();
MSG_ReadShort (); // just ignore everything for now
} }
#endif #endif
@ -5826,6 +5832,20 @@ void CLQW_ParseServerMessage (void)
CL_ParseClientdata (); 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 // 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 //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 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) //(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--) for (i = cl.validsequence; i >= cls.netchan.incoming_sequence - UPDATE_MASK; i--)
{ {
int out; int out;
//skip frames which were not received, or are otherwise invalid. yay packetloss //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) 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; continue;
} }
@ -1019,7 +1019,7 @@ void CL_PredictMovePNum (int seat)
backdate = &cl.outframes[out & UPDATE_MASK]; backdate = &cl.outframes[out & UPDATE_MASK];
if (backdate->cmd_sequence != out) 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; continue;
} }
//okay, looks valid //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) 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)); memset(RQntNames, 0, sizeof(RQntNames));
RQntNames[RQUANT_MSECS] = "Microseconds"; RQntNames[RQUANT_MSECS] = "Microseconds";
#ifdef _DEBUG RQntNames[RQUANT_PRIMITIVEINDICIES] = "Draw Indicies";
RQntNames[RQUANT_PRIMITIVES] = "Draw Indicies";
#endif
RQntNames[RQUANT_DRAWS] = "Draw Calls"; RQntNames[RQUANT_DRAWS] = "Draw Calls";
RQntNames[RQUANT_2DBATCHES] = "2d Batches"; RQntNames[RQUANT_2DBATCHES] = "2d Batches";
RQntNames[RQUANT_WORLDBATCHES] = "World Batches"; RQntNames[RQUANT_WORLDBATCHES] = "World Batches";
RQntNames[RQUANT_ENTBATCHES] = "Ent Batches"; RQntNames[RQUANT_ENTBATCHES] = "Ent Batches";
RQntNames[RQUANT_SHADOWFACES] = "Shadow Faces"; RQntNames[RQUANT_SHADOWINDICIES] = "Shadow Indicies";
RQntNames[RQUANT_SHADOWEDGES] = "Shadow Edges"; RQntNames[RQUANT_SHADOWEDGES] = "Shadow Edges";
RQntNames[RQUANT_SHADOWSIDES] = "Shadowmap Sides"; RQntNames[RQUANT_SHADOWSIDES] = "Shadowmap Sides";
RQntNames[RQUANT_LITFACES] = "Lit faces"; RQntNames[RQUANT_LITFACES] = "Lit faces";
@ -1193,6 +1191,7 @@ void SCR_DeInit (void)
scr_initialized = false; scr_initialized = false;
Cmd_RemoveCommand ("screenshot"); Cmd_RemoveCommand ("screenshot");
Cmd_RemoveCommand ("screenshot_mega");
Cmd_RemoveCommand ("sizeup"); Cmd_RemoveCommand ("sizeup");
Cmd_RemoveCommand ("sizedown"); Cmd_RemoveCommand ("sizedown");
} }

View file

@ -3591,6 +3591,9 @@ void CL_UpdateBeams (void)
ent->angles[2] = rand()%360; ent->angles[2] = rand()%360;
AngleVectors(ent->angles, ent->axis[0], ent->axis[1], ent->axis[2]); AngleVectors(ent->angles, ent->axis[0], ent->axis[1], ent->axis[2]);
ent->angles[0] = pitch; 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++) for (i=0 ; i<3 ; i++)
org[i] += dist[i]*30; org[i] += dist[i]*30;

View file

@ -739,7 +739,11 @@ typedef struct
char model_name[MAX_PRECACHE_MODELS][MAX_QPATH]; char model_name[MAX_PRECACHE_MODELS][MAX_QPATH];
char sound_name[MAX_PRECACHE_SOUNDS][MAX_QPATH]; char sound_name[MAX_PRECACHE_SOUNDS][MAX_QPATH];
char *particle_ssname[MAX_SSPARTICLESPRE]; 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_vwep[MAX_VWEP_MODELS];
struct model_s *model_precache[MAX_PRECACHE_MODELS]; struct model_s *model_precache[MAX_PRECACHE_MODELS];
@ -962,10 +966,10 @@ typedef struct {
unsigned int flags; unsigned int flags;
} scenetris_t; } scenetris_t;
extern scenetris_t *cl_stris; extern scenetris_t *cl_stris;
extern vecV_t *cl_strisvertv; extern vecV_t *fte_restrict cl_strisvertv;
extern vec4_t *cl_strisvertc; extern vec4_t *fte_restrict cl_strisvertc;
extern vec2_t *cl_strisvertt; extern vec2_t *fte_restrict cl_strisvertt;
extern index_t *cl_strisidx; extern index_t *fte_restrict cl_strisidx;
extern unsigned int cl_numstrisidx; extern unsigned int cl_numstrisidx;
extern unsigned int cl_maxstrisidx; extern unsigned int cl_maxstrisidx;
extern unsigned int cl_numstrisvert; 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_ParsePrint(char *message, int printlevel);
qboolean CSQC_ParseGamePacket(void); qboolean CSQC_ParseGamePacket(void);
qboolean CSQC_CenterPrint(int lplayernum, char *cmd); 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_Input_Frame(int lplayernum, usercmd_t *cmd);
void CSQC_WorldLoaded(void); void CSQC_WorldLoaded(void);
qboolean CSQC_ParseTempEntity(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; oc = con->current;
if (oc->length+1 > oc->maxlength) if (oc->length+1 > oc->maxlength)
{ {
oc->maxlength = (oc->length+1)+8; oc->maxlength = ((oc->length+1)+8)&0xffff;
if (oc->maxlength < oc->length) if (oc->maxlength < oc->length)
oc->length = 0; //don't crash from console line overflows. oc->length = 0; //don't crash from console line overflows.
con->current = BZ_Realloc(con->current, sizeof(*con->current)+(oc->maxlength)*sizeof(conchar_t)); 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. //see if we recognise the extension, and only strip it if we do.
COM_FileExtension(tex->ident, nicename, sizeof(nicename)); COM_FileExtension(tex->ident, nicename, sizeof(nicename));
e = 0; e = 0;
if (strcmp(nicename, "lmp")) if (strcmp(nicename, "lmp") && strcmp(nicename, "wal"))
for (; e < tex_extensions_count; e++) for (; e < tex_extensions_count; e++)
{ {
if (!strcmp(nicename, (*tex_extensions[e].name=='.')?tex_extensions[e].name+1:tex_extensions[e].name)) 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 *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; image_t *tex;
qboolean dontposttoworker = (flags & (IF_NOWORKER | IF_LOADNOW));
flags &= ~IF_LOADNOW;
#ifdef LOADERTHREAD #ifdef LOADERTHREAD
Sys_LockMutex(com_resourcemutex); Sys_LockMutex(com_resourcemutex);
#endif #endif
@ -4260,7 +4264,7 @@ image_t *Image_GetTexture(const char *identifier, const char *subpath, unsigned
#endif #endif
//FIXME: pass fallback through this way instead? //FIXME: pass fallback through this way instead?
if (flags & IF_NOWORKER) if (dontposttoworker)
Image_LoadHiResTextureWorker(tex, NULL, 0, 0); Image_LoadHiResTextureWorker(tex, NULL, 0, 0);
else else
COM_AddWork(1, Image_LoadHiResTextureWorker, tex, NULL, 0, 0); COM_AddWork(1, Image_LoadHiResTextureWorker, tex, NULL, 0, 0);
@ -4361,17 +4365,68 @@ qboolean Image_UnloadTexture(image_t *tex)
} }
return false; 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. //may not create any images yet.
void Image_Init(void) void Image_Init(void)
{ {
memset(imagetablebuckets, 0, sizeof(imagetablebuckets)); memset(imagetablebuckets, 0, sizeof(imagetablebuckets));
Hash_InitTable(&imagetable, sizeof(imagetablebuckets)/sizeof(imagetablebuckets[0]), 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 //destroys all textures
void Image_Shutdown(void) void Image_Shutdown(void)
{ {
image_t *tex; image_t *tex;
int i = 0, j = 0; int i = 0, j = 0;
Cmd_RemoveCommand("image_list");
while (imagelist) while (imagelist)
{ {
tex = 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_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)."); 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; extern cvar_t _windowed_mouse;
@ -320,8 +319,8 @@ void IN_MoveMouse(struct mouse_s *mouse, float *movements, int pnum)
wpnum = cl.splitclients; wpnum = cl.splitclients;
if (wpnum < 1) if (wpnum < 1)
wpnum = 1; wpnum = 1;
if (cl_forcesplitclient.ival) if (cl_forceseat.ival)
wpnum = (cl_forcesplitclient.ival-1) % wpnum; wpnum = (cl_forceseat.ival-1) % wpnum;
else else
wpnum = mouse->qdeviceid % wpnum; wpnum = mouse->qdeviceid % wpnum;
if (wpnum != pnum) if (wpnum != pnum)
@ -561,8 +560,8 @@ void IN_MoveJoystick(struct joy_s *joy, float *movements, int pnum, float framet
wpnum = cl.splitclients; wpnum = cl.splitclients;
if (wpnum < 1) if (wpnum < 1)
wpnum = 1; wpnum = 1;
if (cl_forcesplitclient.ival) if (cl_forceseat.ival)
wpnum = (cl_forcesplitclient.ival-1) % wpnum; wpnum = (cl_forceseat.ival-1) % wpnum;
else else
wpnum = joy->qdeviceid % wpnum; wpnum = joy->qdeviceid % wpnum;
if (wpnum != pnum) 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 m_threshold_noforce = CVAR("m_threshold_noforce", "0");
static cvar_t cl_keypad = CVAR("cl_keypad", "1"); static cvar_t cl_keypad = CVAR("cl_keypad", "1");
extern cvar_t cl_forcesplitclient;
extern float multicursor_x[8], multicursor_y[8]; extern float multicursor_x[8], multicursor_y[8];
extern qboolean multicursor_active[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; wpnum = cl.splitclients;
if (wpnum < 1) if (wpnum < 1)
wpnum = 1; wpnum = 1;
if (cl_forcesplitclient.ival) if (cl_forceseat.ival)
wpnum = (cl_forcesplitclient.ival-1) % wpnum; wpnum = (cl_forceseat.ival-1) % wpnum;
else else
wpnum = joy->devid % wpnum; wpnum = joy->devid % wpnum;
if (wpnum != pnum) if (wpnum != pnum)

View file

@ -57,3 +57,19 @@ void INS_ReInit (void);
void INS_Init (void); void INS_Init (void);
void INS_Shutdown (void); void INS_Shutdown (void);
void INS_Commands (void); //final chance to call IN_MouseMove/IN_KeyEvent each frame 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; x += option->bind.captionwidth + 3*8;
{ {
extern cvar_t cl_forcesplitclient; M_FindKeysForCommand (cl_forceseat.ival, option->bind.command, keys);
M_FindKeysForCommand (cl_forcesplitclient.ival, option->bind.command, keys);
if (bindingactive && menu->selecteditem == option) if (bindingactive && menu->selecteditem == option)
{ {

View file

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

View file

@ -461,7 +461,6 @@ void M_Menu_Keys_f (void)
{ {
int y; int y;
menu_t *menu; menu_t *menu;
extern cvar_t cl_splitscreen, cl_forcesplitclient;
vfsfile_t *bindslist; vfsfile_t *bindslist;
Key_Dest_Add(kdm_menu); Key_Dest_Add(kdm_menu);
@ -491,7 +490,7 @@ void M_Menu_Keys_f (void)
break; break;
} }
if (cl_splitscreen.ival) if (cl_forceseat.ival)
{ {
static char *texts[MAX_SPLITS+2] = static char *texts[MAX_SPLITS+2] =
{ {
@ -510,7 +509,7 @@ void M_Menu_Keys_f (void)
"3", "3",
"4" "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; 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_Extradata (struct model_s *mod); // handles caching
extern void Mod_TouchModel (const char *name); extern void Mod_TouchModel (const char *name);
extern const char *Mod_FixName (const char *modname, const char *worldname); //remaps the name appropriately 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 void Mod_Think (void);
extern int Mod_SkinNumForName (struct model_s *model, const char *name); 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_MIN_PARTICLES 512
#define ABSOLUTE_MAX_PARTICLES 8192 #define ABSOLUTE_MAX_PARTICLES 8192
static int r_numparticles; 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 cvar_t r_part_density, r_part_classic_expgrav;
extern qbyte default_quakepal[]; /*for ramps more than anything else*/ extern qbyte default_quakepal[]; /*for ramps more than anything else*/
@ -367,9 +367,9 @@ static void PClassic_DrawParticles(void)
dvel = 4 * frametime; dvel = 4 * frametime;
#ifdef POLYS #ifdef POLYS
if (cl_numstris && cl_stris[cl_numstris-1].shader == classicshader && cl_stris[cl_numstris-1].numvert + 8 <= MAX_INDICIES) // 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]; // scenetri = &cl_stris[cl_numstris-1];
else // else
{ {
if (cl_numstris == cl_maxstris) 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); 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) static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count, int typenum, trailstate_t **tsk)
{ {
part_type_t *ptype = &part_type[typenum]; 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) if (ptype->looks.type == PT_CDECAL)
{ {
clippeddecal_t *d;
int decalcount;
float dist; float dist;
vec3_t tangent, t2;
vec3_t vec={0.5, 0.5, 0.5}; vec3_t vec={0.5, 0.5, 0.5};
float *decverts;
int i; int i;
trace_t tr; trace_t tr;
float sb,sw,tb,tw; decalctx_t ctx;
vec3_t bestdir;
vec3_t bestdir, bestorg;
if (!free_decals) if (!free_decals)
return 0; return 0;
VectorCopy(org, bestorg); VectorCopy(org, ctx.center);
if (!dir || (dir[0] == 0 && dir[1] == 0 && dir[2] == 0)) if (!dir || (dir[0] == 0 && dir[1] == 0 && dir[2] == 0))
{ {
bestdir[0] = 0; bestdir[0] = 0;
@ -3791,26 +3868,26 @@ static int PScript_RunParticleEffectState (vec3_t org, vec3_t dir, float count,
{ {
if (i >= 3) if (i >= 3)
{ {
t2[0] = ((i&3)==0)*8; ctx.tangent1[0] = ((i&3)==0)*8;
t2[1] = ((i&3)==1)*8; ctx.tangent1[1] = ((i&3)==1)*8;
t2[2] = ((i&3)==2)*8; ctx.tangent1[2] = ((i&3)==2)*8;
} }
else else
{ {
t2[0] = -((i&3)==0)*8; ctx.tangent1[0] = -((i&3)==0)*8;
t2[1] = -((i&3)==1)*8; ctx.tangent1[1] = -((i&3)==1)*8;
t2[2] = -((i&3)==2)*8; ctx.tangent1[2] = -((i&3)==2)*8;
} }
VectorSubtract(org, t2, tangent); VectorSubtract(org, ctx.tangent1, ctx.tangent2);
VectorAdd(org, t2, t2); 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) if (tr.fraction < dist)
{ {
dist = tr.fraction; dist = tr.fraction;
VectorCopy(tr.plane.normal, bestdir); 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(dir);
VectorNormalize(vec); VectorNormalize(vec);
CrossProduct(dir, vec, t2); CrossProduct(dir, vec, ctx.tangent1);
Matrix4x4_CM_Transform3(Matrix4x4_CM_NewRotation(frandom()*360, dir[0], dir[1], dir[2]), t2, tangent); Matrix4x4_CM_Transform3(Matrix4x4_CM_NewRotation(frandom()*360, dir[0], dir[1], dir[2]), ctx.tangent1, ctx.tangent2);
CrossProduct(dir, tangent, t2); CrossProduct(dir, ctx.tangent2, ctx.tangent1);
sw = ptype->s2 - ptype->s1; ctx.ptype = ptype;
sb = ptype->s1 + sw/2; ctx.scale1 = ptype->s2 - ptype->s1;
tw = ptype->t2 - ptype->t1; ctx.bias1 = ptype->s1 + ctx.scale1/2;
tb = ptype->t1 + tw/2; ctx.scale2 = ptype->t2 - ptype->t1;
ctx.bias2 = ptype->t1 + ctx.scale2/2;
m = ptype->scale + frandom() * ptype->scalerand; m = ptype->scale + frandom() * ptype->scalerand;
sw /= m; ctx.scale1 /= m;
tw /= m; ctx.scale2 /= m;
decalcount = Q1BSP_ClipDecal(cl.worldmodel, bestorg, dir, tangent, t2, m, &decverts); //inserts decals through a callback.
while(decalcount) Mod_ClipDecal(cl.worldmodel, ctx.center, dir, ctx.tangent2, ctx.tangent1, m, PScript_AddDecals, &ctx);
{
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;
}
}
if (ptype->assoc < 0) if (ptype->assoc < 0)
break; break;

View file

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

View file

@ -181,7 +181,7 @@ void R2D_Init(void)
} }
missing_texture = R_LoadHiResTexture("no_texture", NULL, IF_NEAREST|IF_NOWORKER); missing_texture = R_LoadHiResTexture("no_texture", NULL, IF_NEAREST|IF_NOWORKER);
if (!TEXLOADED(missing_texture)) 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_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); missing_texture_normal = R_LoadTexture("no_texture_normal", 4, 4, TF_RGBA32, (unsigned char*)nonorm, IF_NOGAMMA);
translate_texture = r_nulltex; 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) void R_Rockettrail_Callback(struct cvar_s *var, char *oldvalue)
{ {
int i; int i;
@ -181,6 +639,8 @@ void P_InitParticleSystem(void)
Cvar_Register (&r_rockettrail, particlecvargroupname); Cvar_Register (&r_rockettrail, particlecvargroupname);
Cvar_Register (&r_grenadetrail, particlecvargroupname); Cvar_Register (&r_grenadetrail, particlecvargroupname);
R_Clutter_Init();
} }
void P_Shutdown(void) void P_Shutdown(void)
@ -195,6 +655,8 @@ void P_Shutdown(void)
pe->ShutdownParticles(); pe->ShutdownParticles();
} }
pe = NULL; pe = NULL;
R_Clutter_Purge();
} }
//0 says hit nothing. //0 says hit nothing.

View file

@ -36,7 +36,7 @@ model_t *currentmodel;
int lightmap_bytes; // 1, 3 or 4 int lightmap_bytes; // 1, 3 or 4
qboolean lightmap_bgra; 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]; vec3_t blocknormals[MAX_LIGHTMAP_SIZE*MAX_LIGHTMAP_SIZE];
unsigned blocklights[3*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; return;
lm = lightmap[surf->lightmaptexturenums[0]]; lm = lightmap[surf->lightmaptexturenums[0]];
smax = (surf->extents[0]>>4)+1; smax = (surf->extents[0]>>surf->lmshift)+1;
tmax = (surf->extents[1]>>4)+1; tmax = (surf->extents[1]>>surf->lmshift)+1;
tex = surf->texinfo; tex = surf->texinfo;
stainbase = lm->stainmaps; stainbase = lm->stainmaps;
@ -123,12 +123,12 @@ void Surf_StainSurf (msurface_t *surf, float *parms)
for (t = 0 ; t<tmax ; t++) for (t = 0 ; t<tmax ; t++)
{ {
td = local[1] - t*16; td = local[1] - (t<<surf->lmshift);
if (td < 0) if (td < 0)
td = -td; td = -td;
for (s=0 ; s<smax ; s++) for (s=0 ; s<smax ; s++)
{ {
sd = local[0] - s*16; sd = local[0] - (s<<surf->lmshift);
if (sd < 0) if (sd < 0)
sd = -sd; sd = -sd;
if (sd > td) if (sd > td)
@ -245,7 +245,7 @@ void Surf_WipeStains(void)
{ {
if (!lightmap[i]) if (!lightmap[i])
break; 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... surf->cached_dlight=-1;//nice hack here...
smax = (surf->extents[0]>>4)+1; smax = (surf->extents[0]>>surf->lmshift)+1;
tmax = (surf->extents[1]>>4)+1; tmax = (surf->extents[1]>>surf->lmshift)+1;
stain = lm->stainmaps; stain = lm->stainmaps;
stain += (surf->light_t[0] * lm->width + surf->light_s[0]) * 3; 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; float a;
unsigned *bl; unsigned *bl;
smax = (surf->extents[0]>>4)+1; smax = (surf->extents[0]>>surf->lmshift)+1;
tmax = (surf->extents[1]>>4)+1; tmax = (surf->extents[1]>>surf->lmshift)+1;
tex = surf->texinfo; tex = surf->texinfo;
for (lnum=rtlights_first; lnum<RTL_FIRST; lnum++) for (lnum=rtlights_first; lnum<RTL_FIRST; lnum++)
@ -371,12 +371,12 @@ static void Surf_AddDynamicLights (msurface_t *surf)
bl = blocklights; bl = blocklights;
for (t = 0 ; t<tmax ; t++) for (t = 0 ; t<tmax ; t++)
{ {
td = local[1] - t*16; td = local[1] - (t<<surf->lmshift);
if (td < 0) if (td < 0)
td = -td; td = -td;
for (s=0 ; s<smax ; s++) for (s=0 ; s<smax ; s++)
{ {
sd = local[0] - s*16; sd = local[0] - (s<<surf->lmshift);
if (sd < 0) if (sd < 0)
sd = -sd; sd = -sd;
if (sd > td) if (sd > td)
@ -442,12 +442,12 @@ static void Surf_AddDynamicLightNorms (msurface_t *surf)
for (t = 0 ; t<tmax ; t++) for (t = 0 ; t<tmax ; t++)
{ {
td = local[1] - t*16; td = local[1] - t*surf->lmscale;
if (td < 0) if (td < 0)
td = -td; td = -td;
for (s=0 ; s<smax ; s++) for (s=0 ; s<smax ; s++)
{ {
sd = local[0] - s*16; sd = local[0] - s*surf->lmscale;
if (sd < 0) if (sd < 0)
sd = -sd; sd = -sd;
if (sd > td) if (sd > td)
@ -482,8 +482,8 @@ static void Surf_AddDynamicLightsColours (msurface_t *surf)
unsigned *bl; unsigned *bl;
vec3_t lightofs; vec3_t lightofs;
smax = (surf->extents[0]>>4)+1; smax = (surf->extents[0]>>surf->lmshift)+1;
tmax = (surf->extents[1]>>4)+1; tmax = (surf->extents[1]>>surf->lmshift)+1;
tex = surf->texinfo; tex = surf->texinfo;
for (lnum=rtlights_first; lnum<RTL_FIRST; lnum++) 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++) for (t = 0 ; t<tmax ; t++)
{ {
td = local[1] - t*16; td = local[1] - t*surf->lmscale;
if (td < 0) if (td < 0)
td = -td; td = -td;
for (s=0 ; s<smax ; s++) for (s=0 ; s<smax ; s++)
{ {
sd = local[0] - s*16; sd = local[0] - s*surf->lmscale;
if (sd < 0) if (sd < 0)
sd = -sd; sd = -sd;
if (sd > td) if (sd > td)
@ -547,12 +547,12 @@ static void Surf_AddDynamicLightsColours (msurface_t *surf)
bl = blocklights; bl = blocklights;
for (t = 0 ; t<tmax ; t++) for (t = 0 ; t<tmax ; t++)
{ {
td = local[1] - t*16; td = local[1] - (t<<surf->lmshift);
if (td < 0) if (td < 0)
td = -td; td = -td;
for (s=0 ; s<smax ; s++) for (s=0 ; s<smax ; s++)
{ {
sd = local[0] - s*16; sd = local[0] - (s<<surf->lmshift);
if (sd < 0) if (sd < 0)
sd = -sd; sd = -sd;
if (sd > td) 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 smax, tmax;
int i, j, size; int i, j, size;
@ -587,13 +587,13 @@ static void Surf_BuildDeluxMap (msurface_t *surf, qbyte *dest)
vec_t *bnorm; vec_t *bnorm;
vec3_t temp; vec3_t temp;
int stride = LMBLOCK_WIDTH*lightmap_bytes; int stride = lmwidth*lightmap_bytes;
if (!dest) if (!dest)
return; return;
smax = (surf->extents[0]>>4)+1; smax = (surf->extents[0]>>surf->lmshift)+1;
tmax = (surf->extents[1]>>4)+1; tmax = (surf->extents[1]>>surf->lmshift)+1;
size = smax*tmax; size = smax*tmax;
lightmap = surf->samples; lightmap = surf->samples;
@ -705,7 +705,7 @@ enum lm_mode
just unpacks the internal lightmap block into texture info ready for upload just unpacks the internal lightmap block into texture info ready for upload
merges stains and oversaturates overbrights. 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; int r, g, b, t, m;
unsigned int i, j; unsigned int i, j;
@ -715,7 +715,7 @@ static void Surf_StoreLightmap(qbyte *dest, int smax, int tmax, unsigned int shi
switch (lm_mode) switch (lm_mode)
{ {
case bgra4_os: case bgra4_os:
stride = LMBLOCK_WIDTH*4 - (smax<<2); stride = lmwidth*4 - (smax<<2);
bl = blocklights; bl = blocklights;
@ -752,7 +752,7 @@ static void Surf_StoreLightmap(qbyte *dest, int smax, int tmax, unsigned int shi
dest += 4; dest += 4;
} }
if (stainsrc) if (stainsrc)
stainsrc += (LMBLOCK_WIDTH - smax)*3; stainsrc += (lmwidth - smax)*3;
} }
break; break;
/* /*
@ -801,12 +801,12 @@ static void Surf_StoreLightmap(qbyte *dest, int smax, int tmax, unsigned int shi
dest += 4; dest += 4;
} }
if (stainsrc) if (stainsrc)
stainsrc += (LMBLOCK_WIDTH - smax)*3; stainsrc += (lmwidth - smax)*3;
} }
break; break;
*/ */
case rgb3_os: case rgb3_os:
stride = LMBLOCK_WIDTH*3 - (smax*3); stride = lmwidth*3 - (smax*3);
bl = blocklights; bl = blocklights;
for (i=0 ; i<tmax ; i++, dest += stride) 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; dest += 3;
} }
if (stainsrc) if (stainsrc)
stainsrc += (LMBLOCK_WIDTH - smax)*3; stainsrc += (lmwidth - smax)*3;
} }
break; break;
case lum: case lum:
stride = LMBLOCK_WIDTH; stride = lmwidth;
bl = blocklights; bl = blocklights;
for (i=0 ; i<tmax ; i++, dest += stride) 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 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 smax, tmax;
int t; int t;
@ -885,8 +885,8 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest,
shift += 7; // increase to base value shift += 7; // increase to base value
surf->cached_dlight = (surf->dlightframe == r_framecount); surf->cached_dlight = (surf->dlightframe == r_framecount);
smax = (surf->extents[0]>>4)+1; smax = (surf->extents[0]>>surf->lmshift)+1;
tmax = (surf->extents[1]>>4)+1; tmax = (surf->extents[1]>>surf->lmshift)+1;
size = smax*tmax; size = smax*tmax;
lightmap = surf->samples; lightmap = surf->samples;
@ -897,7 +897,7 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest,
} }
if (currentmodel->deluxdata) if (currentmodel->deluxdata)
Surf_BuildDeluxMap(surf, deluxdest); Surf_BuildDeluxMap(surf, deluxdest, lmwidth);
#ifdef PEXT_LIGHTSTYLECOL #ifdef PEXT_LIGHTSTYLECOL
if (lightmap_bytes == 4 || lightmap_bytes == 3) 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++) for (j = 0; j < smax; j++)
{ {
bl[0] = 255*lightmap[(i*LMBLOCK_WIDTH+j)*3]; bl[0] = 255*lightmap[(i*lmwidth+j)*3];
bl[1] = 255*lightmap[(i*LMBLOCK_WIDTH+j)*3+1]; bl[1] = 255*lightmap[(i*lmwidth+j)*3+1];
bl[2] = 255*lightmap[(i*LMBLOCK_WIDTH+j)*3+2]; bl[2] = 255*lightmap[(i*lmwidth+j)*3+2];
bl+=3; bl+=3;
} }
} }
@ -1078,7 +1078,7 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest,
{ {
if (lightmap_bgra) if (lightmap_bgra)
{ {
Surf_StoreLightmap(dest, smax, tmax, shift, bgra4_os, stainsrc); Surf_StoreLightmap(dest, smax, tmax, shift, bgra4_os, stainsrc, lmwidth);
} }
else else
{ {
@ -1102,7 +1102,7 @@ static void Surf_BuildLightMap (msurface_t *surf, qbyte *dest, qbyte *deluxdest,
} }
else 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_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; lm->modified = true;
smax = (fa->extents[0]>>4)+1; smax = (fa->extents[0]>>fa->lmshift)+1;
tmax = (fa->extents[1]>>4)+1; tmax = (fa->extents[1]>>fa->lmshift)+1;
theRect = &lm->rectchange; theRect = &lm->rectchange;
if (fa->light_t[0] < theRect->t) { if (fa->light_t[0] < theRect->t) {
@ -1267,17 +1267,17 @@ dynamic:
theRect->h = (fa->light_t[0]-theRect->t)+tmax; theRect->h = (fa->light_t[0]-theRect->t)+tmax;
luxbase = dlm->lightmaps; 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 else
luxbase = NULL; luxbase = NULL;
base = lm->lightmaps; 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 = lm->stainmaps;
stainbase += (fa->light_t[0] * lm->width + fa->light_s[0]) * 3; 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); RSpeedEnd(RSPEED_DYNAMIC);
} }
@ -1312,8 +1312,8 @@ dynamic:
lm->modified = true; lm->modified = true;
smax = (fa->extents[0]>>4)+1; smax = (fa->extents[0]>>fa->lmshift)+1;
tmax = (fa->extents[1]>>4)+1; tmax = (fa->extents[1]>>fa->lmshift)+1;
theRect = &lm->rectchange; theRect = &lm->rectchange;
if (fa->light_t[0] < theRect->t) if (fa->light_t[0] < theRect->t)
@ -1357,17 +1357,17 @@ dynamic:
theRect->h = (fa->light_t[0]-theRect->t)+tmax; theRect->h = (fa->light_t[0]-theRect->t)+tmax;
luxbase = dlm->lightmaps; 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 else
luxbase = NULL; luxbase = NULL;
base = lm->lightmaps; 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 = lm->stainmaps;
stainbase += (fa->light_t[0] * lm->width + fa->light_s[0]) * 3; 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); RSpeedEnd(RSPEED_DYNAMIC);
} }
@ -2431,11 +2431,9 @@ void Surf_DeInit(void)
for (i = 0; i < numlightmaps; i++) for (i = 0; i < numlightmaps; i++)
{ {
if (!lightmap[i]) if (!lightmap[i])
break; continue;
if (!lightmap[i]->external) if (!lightmap[i]->external)
{ Image_DestroyTexture(lightmap[i]->lightmap_texture);
R_DestroyTexture(lightmap[i]->lightmap_texture);
}
BZ_Free(lightmap[i]); BZ_Free(lightmap[i]);
lightmap[i] = NULL; 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.l = 0;
lightmap[i]->rectchange.t = 0; lightmap[i]->rectchange.t = 0;
lightmap[i]->rectchange.h = LMBLOCK_WIDTH; lightmap[i]->rectchange.h = lightmap[i]->height;
lightmap[i]->rectchange.w = LMBLOCK_WIDTH; lightmap[i]->rectchange.w = lightmap[i]->width;
lightmap[i]->lightmap_texture = r_nulltex; 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, lm->lightmaps + (surf->light_t[j] * lm->width + surf->light_s[j]) * lightmap_bytes,
deluxemap, deluxemap,
lm->stainmaps + (surf->light_t[j] * lm->width + surf->light_s[j]) * 3, 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) void Surf_BuildLightmaps (void)
{ {
int i, j; int i;
model_t *m; model_t *m;
extern model_t *mod_known; extern model_t *mod_known;
extern int mod_numknown; extern int mod_numknown;
//make sure the lightstyle values are correct.
R_AnimateLight();
r_framecount = 1; // no dlightcache r_framecount = 1; // no dlightcache
for (i = 0; i < numlightmaps; i++) while(numlightmaps > 0)
{ {
if (!lightmap[i]) numlightmaps--;
break; if (!lightmap[numlightmaps])
BZ_Free(lightmap[i]); continue;
lightmap[i] = NULL;
if (!lightmap[numlightmaps]->external)
Image_DestroyTexture(lightmap[numlightmaps]->lightmap_texture);
BZ_Free(lightmap[numlightmaps]);
lightmap[numlightmaps] = NULL;
} }
Surf_LightmapMode(); Surf_LightmapMode();
@ -2862,7 +2867,6 @@ void Surf_BuildLightmaps (void)
r_oldviewleaf2 = NULL; r_oldviewleaf2 = NULL;
r_oldviewcluster = -1; r_oldviewcluster = -1;
r_oldviewcluster2 = -1; r_oldviewcluster2 = -1;
numlightmaps = 0;
//FIXME: unload stuff that's no longer relevant somehow. //FIXME: unload stuff that's no longer relevant somehow.
for (i = 0; i < mod_numknown; i++) for (i = 0; i < mod_numknown; i++)
@ -2887,9 +2891,6 @@ void Surf_NewMap (void)
char namebuf[MAX_QPATH]; char namebuf[MAX_QPATH];
extern cvar_t host_mapname; extern cvar_t host_mapname;
int i; int i;
for (i=0 ; i<256 ; i++)
d_lightstylevalue[i] = 264; // normal light value
memset (&r_worldentity, 0, sizeof(r_worldentity)); memset (&r_worldentity, 0, sizeof(r_worldentity));
AngleVectors(r_worldentity.angles, r_worldentity.axis[0], r_worldentity.axis[1], r_worldentity.axis[2]); 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) if (!pe)
Cvar_ForceCallback(&r_particlesystem); Cvar_ForceCallback(&r_particlesystem);
R_Clutter_Purge();
TRACE(("dbg: Surf_NewMap: clear particles\n")); TRACE(("dbg: Surf_NewMap: clear particles\n"));
P_ClearParticles (); P_ClearParticles ();
TRACE(("dbg: Surf_NewMap: wiping them stains (getting the cloth out)\n")); 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_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_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 //r_surf.c
void Surf_NewMap (void); void Surf_NewMap (void);
void Surf_PreNewMap(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_RenderDynamicLightmaps (struct msurface_s *fa);
void Surf_RenderAmbientLightmaps (struct msurface_s *fa, int ambient); void Surf_RenderAmbientLightmaps (struct msurface_s *fa, int ambient);
int Surf_LightmapShift (struct model_s *model); int Surf_LightmapShift (struct model_s *model);
#ifndef LMBLOCK_WIDTH #define LMBLOCK_SIZE_MAX 1024 //single axis
#define LMBLOCK_WIDTH 128
#define LMBLOCK_HEIGHT 128
typedef struct glRect_s { typedef struct glRect_s {
unsigned short l,t,w,h; unsigned short l,t,w,h;
} glRect_t; } glRect_t;
@ -325,7 +326,7 @@ extern int numlightmaps;
//extern texid_t *deluxmap_textures; //extern texid_t *deluxmap_textures;
extern int lightmap_bytes; // 1, 3, or 4 extern int lightmap_bytes; // 1, 3, or 4
extern qboolean lightmap_bgra; /*true=bgra, false=rgba*/ extern qboolean lightmap_bgra; /*true=bgra, false=rgba*/
#endif
void Surf_RebuildLightmap_Callback (struct cvar_s *var, char *oldvalue); 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_TEXTYPESHIFT = 8, /*0=2d, 1=3d, 2-7=cubeface*/
IF_MIPCAP = 1<<10, IF_MIPCAP = 1<<10,
IF_PREMULTIPLYALPHA = 1<<12, //rgb *= alpha 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_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_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*/ 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_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_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); 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_Upload (texid_t tex, uploadfmt_t fmt, void *data, void *palette, int width, int height, unsigned int flags);
void Image_Init(void); void Image_Init(void);
void Image_Shutdown(void); void Image_Shutdown(void);
image_t *Image_LoadTexture (const char *identifier, int width, int height, uploadfmt_t fmt, void *data, unsigned int flags); 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 #ifdef D3D9QUAKE
void D3D9_UpdateFiltering (image_t *imagelist, int filtermip[3], int filterpic[3], int mipcap[2], float anis); 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); qboolean D3D9_LoadTextureMips (texid_t tex, struct pendingtextureinfo *mips);
@ -597,13 +598,13 @@ extern int rspeeds[RSPEED_MAX];
enum { enum {
RQUANT_MSECS, //old r_speeds RQUANT_MSECS, //old r_speeds
RQUANT_PRIMITIVES, RQUANT_PRIMITIVEINDICIES,
RQUANT_DRAWS, RQUANT_DRAWS,
RQUANT_ENTBATCHES, RQUANT_ENTBATCHES,
RQUANT_WORLDBATCHES, RQUANT_WORLDBATCHES,
RQUANT_2DBATCHES, RQUANT_2DBATCHES,
RQUANT_SHADOWFACES, RQUANT_SHADOWINDICIES,
RQUANT_SHADOWEDGES, RQUANT_SHADOWEDGES,
RQUANT_SHADOWSIDES, RQUANT_SHADOWSIDES,
RQUANT_LITFACES, RQUANT_LITFACES,

View file

@ -502,20 +502,16 @@ void R_InitTextures (void)
{ {
int x,y, m; int x,y, m;
qbyte *dest; 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 // create a simple checkerboard texture for the default
r_notexture_mip = (texture_t*)r_notexture_mip_mem; r_notexture_mip = (texture_t*)r_notexture_mip_mem;
r_notexture_mip->width = r_notexture_mip->height = 16; 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 (y=0 ; y< (16>>m) ; y++)
for (x=0 ; x< (16>>m) ; x++) 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 // use desktop settings if set to 0 and not dedicated
if (newr->renderer && newr->renderer->rtype != QR_NONE) if (newr->renderer && newr->renderer->rtype != QR_NONE)
{ {
int dbpp, dheight, dwidth, drate;
extern qboolean isPlugin; 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) if (vid_desktopsettings.value)
{ {
newr->width = dwidth; newr->width = 0;
newr->height = dheight; newr->height = 0;
newr->bpp = dbpp; newr->bpp = 0;
newr->rate = drate; 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; dwidth = DEFAULT_WIDTH;
newr->height = dheight; 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) if (newr->bpp <= 0)
newr->bpp = dbpp; newr->bpp = dbpp;
} }
@ -1669,6 +1664,7 @@ void R_SetRenderer_f (void)
return; return;
} }
Cvar_ApplyLatches(CVAR_RENDERERLATCH);
if (!R_BuildRenderstate(&newr, param)) if (!R_BuildRenderstate(&newr, param))
{ {
Con_Printf("setrenderer: parameter not supported (%s)\n", 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) char *Get_Q2ConfigString(int i)
{ {
if (i >= Q2CS_IMAGES && i < Q2CS_IMAGES + Q2MAX_IMAGES) 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) if (i == Q2CS_STATUSBAR)
return cl.q2statusbar; return cl.q2statusbar;
@ -384,7 +386,7 @@ void Sbar_ExecuteLayoutString (char *s)
value = cl.q2frame.playerstate.stats[atoi(com_token)]; value = cl.q2frame.playerstate.stats[atoi(com_token)];
if (value >= Q2MAX_IMAGES || value < 0) if (value >= Q2MAX_IMAGES || value < 0)
Host_EndGame ("Pic >= Q2MAX_IMAGES"); Host_EndGame ("Pic >= Q2MAX_IMAGES");
if (Get_Q2ConfigString(Q2CS_IMAGES+value)) if (*Get_Q2ConfigString(Q2CS_IMAGES+value))
{ {
// SCR_AddDirtyPoint (x, y); // SCR_AddDirtyPoint (x, y);
// SCR_AddDirtyPoint (x+23, y+23); // 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 #endif
/* /*
@ -2580,11 +2631,10 @@ void Sbar_Draw (playerview_t *pv)
R2D_ImageColours(1, 1, 1, 1); R2D_ImageColours(1, 1, 1, 1);
if (*cl.q2statusbar) if (*cl.q2statusbar)
Sbar_ExecuteLayoutString(cl.q2statusbar); Sbar_ExecuteLayoutString(cl.q2statusbar);
if (*cl.q2layout) if (*cl.q2layout && (cl.q2frame.playerstate.stats[Q2STAT_LAYOUTS] & 1))
{ Sbar_ExecuteLayoutString(cl.q2layout);
if (cl.q2frame.playerstate.stats[Q2STAT_LAYOUTS] & 1) if (cl.q2frame.playerstate.stats[Q2STAT_LAYOUTS] & 2)
Sbar_ExecuteLayoutString(cl.q2layout); Sbar_Q2DrawInventory();
}
return; return;
} }
#endif #endif
@ -2669,9 +2719,12 @@ void Sbar_Draw (playerview_t *pv)
{ {
if (pv->cam_auto != CAM_TRACK) if (pv->cam_auto != CAM_TRACK)
{ {
Sbar_DrawPic (0, 0, 320, 24, sb_scorebar); if (hud_tracking_show.ival || cl_sbar.ival)
Sbar_DrawString (160-7*8,4, "SPECTATOR MODE"); { //this is annoying.
Sbar_DrawString(160-14*8+4, 12, "Press [ATTACK] for AutoCamera"); 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 else
{ {

View file

@ -73,7 +73,7 @@ static void DSOUND_Restore(soundcardinfo_t *sc)
{ {
DWORD dwStatus; DWORD dwStatus;
dshandle_t *dh = sc->handle; 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"); Con_Printf ("Couldn't get sound buffer status\n");
if (dwStatus & DSBSTATUS_BUFFERLOST) if (dwStatus & DSBSTATUS_BUFFERLOST)

View file

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

View file

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

View file

@ -47,6 +47,11 @@ void Sys_Vibrate(float count)
count = 0; count = 0;
vibrateduration += count*10*sys_vibrate.value; 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) JNIEXPORT jint JNICALL Java_com_fteqw_FTEDroidEngine_getvibrateduration(JNIEnv *env, jobject obj)
{ {
unsigned int dur = vibrateduration; unsigned int dur = vibrateduration;
@ -393,6 +398,7 @@ void Sys_SendKeyEvents(void)
} }
void Sys_Init(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_vibrate, "android stuff");
Cvar_Register(&sys_osk, "android stuff"); Cvar_Register(&sys_osk, "android stuff");
Cvar_Register(&sys_keepscreenon, "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> #include <ws2tcpip.h>
#endif #endif
#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 *addrinfo = NULL;
struct addrinfo *pos; struct addrinfo *pos;
@ -248,11 +248,11 @@ qboolean NET_StringToSockaddr2 (const char *s, int defaultport, struct sockaddr_
pgetaddrinfo = (void*)GetProcAddress(lib, "getaddrinfo"); pgetaddrinfo = (void*)GetProcAddress(lib, "getaddrinfo");
pfreeaddrinfo = (void*)GetProcAddress(lib, "freeaddrinfo"); pfreeaddrinfo = (void*)GetProcAddress(lib, "freeaddrinfo");
if (!pgetaddrinfo || !pfreeaddrinfo) if (!pgetaddrinfo || !pfreeaddrinfo)
return false; return 0;
#endif #endif
if (!(*s)) if (!(*s))
return false; return 0;
memset (sadr, 0, sizeof(*sadr)); memset (sadr, 0, sizeof(*sadr));
@ -298,7 +298,7 @@ qboolean NET_StringToSockaddr2 (const char *s, int defaultport, struct sockaddr_
} }
if (error) if (error)
{ {
return false; return 0;
} }
((struct sockaddr*)sadr)->sa_family = 0; ((struct sockaddr*)sadr)->sa_family = 0;
for (pos = addrinfo; pos; pos = pos->ai_next) for (pos = addrinfo; pos; pos = pos->ai_next)
@ -322,7 +322,7 @@ qboolean NET_StringToSockaddr2 (const char *s, int defaultport, struct sockaddr_
dblbreak: dblbreak:
pfreeaddrinfo (addrinfo); pfreeaddrinfo (addrinfo);
if (!((struct sockaddr*)sadr)->sa_family) //none suitablefound if (!((struct sockaddr*)sadr)->sa_family) //none suitablefound
return false; return 0;
if (addrfamily) if (addrfamily)
*addrfamily = ((struct sockaddr*)sadr)->sa_family; *addrfamily = ((struct sockaddr*)sadr)->sa_family;
@ -342,7 +342,7 @@ dblbreak:
*addrsize = sizeof(struct sockaddr_in6); *addrsize = sizeof(struct sockaddr_in6);
} }
return true; return 1;
} }
char *COM_ParseType (const char *data, char *out, int outlen, com_tokentype_t *toktype) 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 #else
#if defined(GLQUAKE) && defined(DEBUG) #if defined(GLQUAKE)
#define PRINTGLARRAYS //#define PRINTGLARRAYS
#endif #endif
#if defined(_DEBUG) || defined(DEBUG) #if defined(_DEBUG) || defined(DEBUG)
@ -606,8 +606,8 @@ DWORD CrashExceptionHandler (qboolean iswatchdog, DWORD exceptionCode, LPEXCEPTI
} }
#ifdef PRINTGLARRAYS #ifdef PRINTGLARRAYS
// if (!iswatchdog && qrenderer == QR_OPENGL) if (!iswatchdog && qrenderer == QR_OPENGL)
// DumpGLState(); DumpGLState();
#endif #endif
hKernel = LoadLibrary ("kernel32"); hKernel = LoadLibrary ("kernel32");

View file

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

View file

@ -187,13 +187,13 @@ static qboolean Headless_BE_LightCullModel (vec3_t org, struct model_s *model)
{ {
return false; 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) 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++) for (i=0 ; i<3 ; i++)
from[i] = MSG_ReadCoord (); 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; count = blood*0.5 + armor*0.5;
if (count < 10) if (count < 10)
count = 10; count = 10;
@ -404,8 +411,6 @@ void V_ParseDamage (playerview_t *pv)
if (v_damagecshift.value >= 0) if (v_damagecshift.value >= 0)
count *= v_damagecshift.value; count *= v_damagecshift.value;
pv->faceanimtime = cl.time + 0.2; // but sbar face into pain frame
cl.cshifts[CSHIFT_DAMAGE].percent += 3*count; cl.cshifts[CSHIFT_DAMAGE].percent += 3*count;
if (cl.cshifts[CSHIFT_DAMAGE].percent < 0) if (cl.cshifts[CSHIFT_DAMAGE].percent < 0)
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 { enum {
STAT_HEALTH = 0, STAT_HEALTH = 0,
//STAT_FRAGS = 1, //STAT_FRAGS = 1,
STAT_WEAPON = 2, STAT_WEAPONMODELI = 2,
STAT_AMMO = 3, STAT_AMMO = 3,
STAT_ARMOR = 4, STAT_ARMOR = 4,
STAT_WEAPONFRAME = 5, STAT_WEAPONFRAME = 5,

View file

@ -405,8 +405,12 @@ typedef struct q2miptex_s
#define IDBSPHEADER (('P'<<24)+('S'<<16)+('B'<<8)+'I') #define IDBSPHEADER (('P'<<24)+('S'<<16)+('B'<<8)+'I')
// little-endian "IBSP" // little-endian "IBSP"
#define Q2BSPVERSION 38 #define BSPVERSION_Q2 38
#define Q3BSPVERSION 46 #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 // upper design bounds
@ -488,7 +492,7 @@ typedef struct
{ {
int ident; int ident;
int version; int version;
lump_t lumps[Q2HEADER_LUMPS]; lump_t lumps[50];
} q2dheader_t; } q2dheader_t;
typedef struct typedef struct

View file

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

View file

@ -44,7 +44,7 @@ typedef struct
float rate; float rate;
galiaspose_t *poseofs; galiaspose_t *poseofs;
char name[64]; char name[64];
} galiasgroup_t; } galiasanimation_t;
typedef struct galiasbone_s galiasbone_t; typedef struct galiasbone_s galiasbone_t;
#ifdef SKELETALMODELS #ifdef SKELETALMODELS
@ -137,8 +137,8 @@ typedef struct galiasinfo_s
byte_vec4_t *ofs_rgbaub; byte_vec4_t *ofs_rgbaub;
#endif #endif
int groups; int numanimations;
galiasgroup_t *groupofs; galiasanimation_t *ofsanimations;
struct galiasinfo_s *nextsurf; 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_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_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_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); cvar_t sys_platform = CVAR("sys_platform", PLATFORM);
qboolean com_modified; // set true if using non-id files 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); 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*/ /*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" #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...*/ /*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) //these are in model.c (or gl_model.c)
qboolean Mod_LoadVertexes (model_t *loadmodel, qbyte *mod_base, lump_t *l); 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_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_LoadMarksurfaces (model_t *loadmodel, qbyte *mod_base, lump_t *l, qboolean lm);
qboolean Mod_LoadSurfedges (model_t *loadmodel, qbyte *mod_base, lump_t *l); 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); 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++) for (i=0 ; i<2 ; i++)
{ {
bmins[i] = floor(mins[i]/16); bmins[i] = floor(mins[i]/(1<<s->lmshift));
bmaxs[i] = ceil(maxs[i]/16); bmaxs[i] = ceil(maxs[i]/(1<<s->lmshift));
s->texturemins[i] = bmins[i] * 16; s->texturemins[i] = bmins[i] << s->lmshift;
s->extents[i] = (bmaxs[i] - bmins[i]) * 16; s->extents[i] = (bmaxs[i] - bmins[i]) << s->lmshift;
// if ( !(tex->flags & TEX_SPECIAL) && s->extents[i] > 8176 ) //q2 uses 512. probably for skys. // 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); // 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_noareas = SCVAR("map_noareas", "0"); //1 for lack of mod support.
cvar_t map_noCurves = SCVARF("map_noCurves", "0", CVAR_CHEAT); 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"); cvar_t r_subdivisions = SCVAR("r_subdivisions", "2");
static int CM_NumInlineModels (model_t *model); 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; return true;
} }
#ifndef SERVERONLY #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; q2miptex_t replacementwal;
texture_t *tex; texture_t *tex;
q2miptex_t *wal; 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) if (!wal)
{ {
wal = &replacementwal; wal = &replacementwal;
memset(wal, 0, sizeof(*wal)); 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->width = 64;
wal->height = 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 = ZG_Malloc(&loadmodel->memgroup, sizeof(texture_t));
tex->offsets[0] = wal->offsets[0];
tex->width = wal->width; tex->width = wal->width;
tex->height = wal->height; tex->height = wal->height;
if (wal->offsets[0]) if (!tex->width || !tex->height || wal == &replacementwal)
tex->texnums.base = R_LoadReplacementTexture(wal->name, "bmodels", imageflags, (qbyte *)wal+wal->offsets[0], wal->width, wal->height, TF_SOLID8); {
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 else
tex->texnums.base = R_LoadReplacementTexture(wal->name, "bmodels", imageflags, NULL, 0, 0, TF_INVALID); base = NULL;
if (wal == &replacementwal) if (wal == &replacementwal)
{ {
/* FIXME: worker needs the texture to have already been loaded. it can't sync with itself however. if (base)
if (tex->texnums.base->status == TEX_LOADING)
COM_WorkerPartialSync(tex, &tex->texnums.base->status, TEX_LOADING);
if (tex->texnums.base->status == TEX_LOADED)
{ {
tex->width = tex->texnums.base->width; if (base->status == TEX_LOADED||base->status==TEX_LOADING)
tex->height = tex->texnums.base->height; {
tex->width = base->width;
tex->height = base->height;
}
} }
*/
} }
else else
BZ_Free(wal); 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; int i, j, count;
char name[MAX_QPATH], *lwr; char name[MAX_QPATH], *lwr;
char sname[MAX_QPATH]; char sname[MAX_QPATH];
float len1, len2;
int texcount; int texcount;
in = (void *)(mod_base + l->fileofs); 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->texinfo = out;
mod->numtexinfo = count; 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++) for ( i=0 ; i<count ; i++, in++, out++)
{ {
out->flags = LittleLong (in->flags); 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]); out->vecs[0][j] = LittleFloat (in->vecs[0][j]);
for (j=0 ; j<4 ; j++) for (j=0 ; j<4 ; j++)
out->vecs[1][j] = LittleFloat (in->vecs[1][j]); out->vecs[1][j] = LittleFloat (in->vecs[1][j]);
len1 = Length (out->vecs[0]); out->vecscale[0] = 1.0/Length (out->vecs[0]);
len2 = Length (out->vecs[1]); out->vecscale[1] = 1.0/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;
if (out->flags & TI_SKY) if (out->flags & TI_SKY)
snprintf(sname, sizeof(sname), "sky/%s%s", in->texture, in->nexttexinfo==-1?"":"#ANIMLOOP"); Q_snprintfz(sname, sizeof(sname), "sky/%s", in->texture);
else if (out->flags & (TI_WARP|TI_TRANS33|TI_TRANS66)) else if (out->flags & (TI_WARP|TI_FLOWING))
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), "warp/%s", in->texture);
else if (out->flags & (TI_TRANS33|TI_TRANS66))
Q_snprintfz(sname, sizeof(sname), "trans/%s", in->texture);
else 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. //in q2, 'TEX_SPECIAL' is TI_LIGHT, and that conflicts.
out->flags &= ~TI_LIGHT; 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; out->flags |= TEX_SPECIAL;
//compact the textures. //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') if (*lwr >= 'A' && *lwr <= 'Z')
*lwr = *lwr - 'A' + 'a'; *lwr = *lwr - 'A' + 'a';
} }
snprintf (name, sizeof(name), "textures/%s.wal", in->texture); out->texture = Mod_LoadWall (mod, mapname, in->texture, sname, (out->flags&TEX_SPECIAL)?0:IF_NOALPHA);
out->texture = Mod_LoadWall (mod, mapname, name, sname, (out->flags&TEX_SPECIAL)?0:IF_NOALPHA);
if (!out->texture || !out->texture->width || !out->texture->height) 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); 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; mod->textures[texcount++] = out->texture;
} }
if (in->nexttexinfo != -1) // if (in->nexttexinfo != -1)
{ // {
Con_DPrintf("FIXME: %s should animate to %s\n", in->texture, (in->nexttexinfo+(q2texinfo_t *)(mod_base + l->fileofs))->texture); // 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); 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; continue;
out[i].texture->anim_total = 1; 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++; out[i].texture->anim_total++;
} }
@ -1430,14 +1451,13 @@ void CalcSurfaceExtents (msurface_t *s)
} }
}*/ }*/
/* /*
================= =================
Mod_LoadFaces Mod_LoadFaces
================= =================
*/ */
#ifndef SERVERONLY #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; dsface_t *in;
msurface_t *out; msurface_t *out;
@ -1445,6 +1465,18 @@ qboolean CModQ2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l)
int planenum, side; int planenum, side;
int ti; 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); in = (void *)(mod_base + l->fileofs);
if (l->filelen % sizeof(*in)) 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++) for ( surfnum=0 ; surfnum<count ; surfnum++, in++, out++)
{ {
out->firstedge = LittleLong(in->firstedge); out->firstedge = LittleLong(in->firstedge);
out->numedges = LittleShort(in->numedges); out->numedges = (unsigned short)LittleShort(in->numedges);
out->flags = 0; out->flags = 0;
planenum = LittleShort(in->planenum); planenum = (unsigned short)LittleShort(in->planenum);
side = LittleShort(in->side); side = (unsigned short)LittleShort(in->side);
if (side) if (side)
out->flags |= SURF_PLANEBACK; out->flags |= SURF_PLANEBACK;
out->plane = mod->planes + planenum; out->plane = mod->planes + planenum;
ti = LittleShort (in->texinfo); ti = (unsigned short)LittleShort (in->texinfo);
if (ti < 0 || ti >= mod->numtexinfo) if (ti < 0 || ti >= mod->numtexinfo)
{ {
Con_Printf (CON_ERROR "MOD_LoadBmodel: bad texinfo number\n"); 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 #endif
out->lmshift = lmshift;
CalcSurfaceExtents (mod, out); CalcSurfaceExtents (mod, out);
// lighting info // lighting info
@ -1498,6 +1531,8 @@ qboolean CModQ2_LoadFaces (model_t *mod, qbyte *mod_base, lump_t *l)
i = LittleLong(in->lightofs); i = LittleLong(in->lightofs);
if (i == -1) if (i == -1)
out->samples = NULL; out->samples = NULL;
else if (lightofsisdouble)
out->samples = mod->lightdata + (i/2);
else else
out->samples = mod->lightdata + i; 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->plane = mod->planes + LittleLong(in->planenum);
out->firstsurface = LittleShort (in->firstface); out->firstsurface = (unsigned short)LittleShort (in->firstface);
out->numsurfaces = LittleShort (in->numfaces); out->numsurfaces = (unsigned short)LittleShort (in->numfaces);
out->contents = -1; // differentiate from leafs out->contents = -1; // differentiate from leafs
for (j=0 ; j<2 ; j++) 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) if (out->cluster == 0xffff)
out->cluster = -1; out->cluster = -1;
out->area = LittleShort (in->area); out->area = (unsigned short)LittleShort (in->area);
out->firstleafbrush = (unsigned short)LittleShort (in->firstleafbrush); out->firstleafbrush = (unsigned short)LittleShort (in->firstleafbrush);
out->numleafbrushes = (unsigned short)LittleShort (in->numleafbrushes); 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) qboolean CModQ2_LoadBrushSides (model_t *mod, qbyte *mod_base, lump_t *l)
{ {
cminfo_t *prv = (cminfo_t*)mod->meshinfo; cminfo_t *prv = (cminfo_t*)mod->meshinfo;
int i, j; unsigned int i, j;
q2cbrushside_t *out; q2cbrushside_t *out;
q2dbrushside_t *in; q2dbrushside_t *in;
int count; 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++) for ( i=0 ; i<count ; i++, in++, out++)
{ {
num = LittleShort (in->planenum); num = (unsigned short)LittleShort (in->planenum);
out->plane = &mod->planes[num]; out->plane = &mod->planes[num];
j = LittleShort (in->texinfo); j = (unsigned short)LittleShort (in->texinfo);
if (j >= mod->numtexinfo) if (j >= mod->numtexinfo)
{ out->surface = &nullsurface;
Con_Printf (CON_ERROR "Bad brushside texinfo\n"); else
return false; out->surface = &prv->surfaces[j];
}
out->surface = &prv->surfaces[j];
} }
return true; return true;
@ -2840,8 +2873,9 @@ qboolean CModQ3_LoadRFaces (model_t *mod, qbyte *mod_base, lump_t *l)
out->styles[sty] = 255; out->styles[sty] = 255;
out->lightmaptexturenums[sty] = -1; out->lightmaptexturenums[sty] = -1;
} }
out->extents[0] = (LittleLong(in->lightmap_width)-1)<<4; out->lmshift = LMSHIFT_DEFAULT;
out->extents[1] = (LittleLong(in->lightmap_height)-1)<<4; out->extents[0] = (LittleLong(in->lightmap_width)-1)<<out->lmshift;
out->extents[1] = (LittleLong(in->lightmap_height)-1)<<out->lmshift;
out->samples=NULL; out->samples=NULL;
if (mod->lightmaps.count < out->lightmaptexturenums[0]+1) 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) if (mod->lightmaps.count < out->lightmaptexturenums[j]+1)
mod->lightmaps.count = out->lightmaptexturenums[j]+1; mod->lightmaps.count = out->lightmaptexturenums[j]+1;
} }
out->extents[0] = (LittleLong(in->lightmap_width)-1)<<4; out->lmshift = LMSHIFT_DEFAULT;
out->extents[1] = (LittleLong(in->lightmap_height)-1)<<4; out->extents[0] = (LittleLong(in->lightmap_width)-1)<<out->lmshift;
out->extents[1] = (LittleLong(in->lightmap_height)-1)<<out->lmshift;
out->samples=NULL; out->samples=NULL;
fv = LittleLong(in->firstvertex); 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.ident = LittleLong(header.ident);
header.version = LittleLong(header.version); 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); ClearBounds(mod->mins, mod->maxs);
switch(header.version) switch(header.version)
{ {
default: default:
Con_Printf (CON_ERROR "Quake 2 or Quake 3 based BSP with unknown header (%s: %i should be %i or %i)\n" 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; return NULL;
break; break;
#ifdef Q3BSPS #ifdef Q3BSPS
case 1: //rbsp/fbsp case BSPVERSION_RBSP: //rbsp/fbsp
case Q3BSPVERSION+1: //rtcw case BSPVERSION_RTCW: //rtcw
case Q3BSPVERSION: 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; prv->mapisq3 = true;
mod->fromgame = fg_quake3; mod->fromgame = fg_quake3;
for (i=0 ; i<Q3LUMPS_TOTAL ; i++) 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].filelen = 0;
header.lumps[i].fileofs = 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; prv->mapisq3 = true;
noerrors = noerrors && CModQ3_LoadShaders (mod, mod_base, &header.lumps[Q3LUMP_SHADERS]); noerrors = noerrors && CModQ3_LoadShaders (mod, mod_base, &header.lumps[Q3LUMP_SHADERS]);
noerrors = noerrors && CModQ3_LoadPlanes (mod, mod_base, &header.lumps[Q3LUMP_PLANES]); 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_LoadBrushSides (mod, mod_base, &header.lumps[Q3LUMP_BRUSHSIDES]);
noerrors = noerrors && CModRBSP_LoadVertexes (mod, mod_base, &header.lumps[Q3LUMP_DRAWVERTS]); 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 #ifndef SERVERONLY
if (qrenderer != QR_NONE) 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]); noerrors = noerrors && CModRBSP_LoadLightgrid (mod, mod_base, &header.lumps[Q3LUMP_LIGHTGRID], &header.lumps[RBSPLUMP_LIGHTINDEXES]);
else else
noerrors = noerrors && CModQ3_LoadLightgrid (mod, mod_base, &header.lumps[Q3LUMP_LIGHTGRID]); noerrors = noerrors && CModQ3_LoadLightgrid (mod, mod_base, &header.lumps[Q3LUMP_LIGHTGRID]);
noerrors = noerrors && CModQ3_LoadIndexes (mod, mod_base, &header.lumps[Q3LUMP_DRAWINDEXES]); 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]); noerrors = noerrors && CModQ3_LoadFogs (mod, mod_base, &header.lumps[Q3LUMP_FOGS]);
else else
mod->numfogs = 0; mod->numfogs = 0;
facedata = (void *)(mod_base + header.lumps[Q3LUMP_SURFACES].fileofs); 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]); noerrors = noerrors && CModRBSP_LoadRFaces (mod, mod_base, &header.lumps[Q3LUMP_SURFACES]);
buildmeshes = CModRBSP_BuildSurfMesh; 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); BZ_Free(map_faces);
break; break;
#endif #endif
case Q2BSPVERSION: case BSPVERSION_Q2:
case BSPVERSION_Q2W:
mod->lightmaps.width = LMBLOCK_SIZE_MAX;
mod->lightmaps.height = LMBLOCK_SIZE_MAX;
prv->mapisq3 = false; prv->mapisq3 = false;
mod->engineflags |= MDLF_NEEDOVERBRIGHT; mod->engineflags |= MDLF_NEEDOVERBRIGHT;
for (i=0 ; i<Q2HEADER_LUMPS ; i++) 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].filelen = LittleLong (header.lumps[i].filelen);
header.lumps[i].fileofs = LittleLong (header.lumps[i].fileofs); header.lumps[i].fileofs = LittleLong (header.lumps[i].fileofs);
} }
if (header.version == BSPVERSION_Q2W)
Q1BSPX_Setup(mod, mod_base, filelen, header.lumps, Q2HEADER_LUMPS); {
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 #ifndef SERVERONLY
if (CM_GetQ2Palette()) 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; mod->funcs.NativeContents = CM_NativeContents;
break; break;
#if defined(GLQUAKE) || defined(D3DQUAKE) #ifndef SERVERONLY
case QR_DIRECT3D9: default:
case QR_DIRECT3D11:
case QR_OPENGL:
// load into heap // load into heap
#ifndef SERVERONLY
noerrors = noerrors && Mod_LoadVertexes (mod, mod_base, &header.lumps[Q2LUMP_VERTEXES]); 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_LoadEdges (mod, mod_base, &header.lumps[Q2LUMP_EDGES], false);
noerrors = noerrors && Mod_LoadSurfedges (mod, mod_base, &header.lumps[Q2LUMP_SURFEDGES]); noerrors = noerrors && Mod_LoadSurfedges (mod, mod_base, &header.lumps[Q2LUMP_SURFEDGES]);
if (noerrors) if (noerrors)
Mod_LoadLighting (mod, mod_base, &header.lumps[Q2LUMP_LIGHTING]); Mod_LoadLighting (mod, mod_base, &header.lumps[Q2LUMP_LIGHTING], header.version == BSPVERSION_Q2W);
#endif
noerrors = noerrors && CModQ2_LoadSurfaces (mod, mod_base, &header.lumps[Q2LUMP_TEXINFO]); noerrors = noerrors && CModQ2_LoadSurfaces (mod, mod_base, &header.lumps[Q2LUMP_TEXINFO]);
noerrors = noerrors && CModQ2_LoadPlanes (mod, mod_base, &header.lumps[Q2LUMP_PLANES]); 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_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); 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_LoadVisibility (mod, mod_base, &header.lumps[Q2LUMP_VISIBILITY]);
noerrors = noerrors && CModQ2_LoadBrushSides (mod, mod_base, &header.lumps[Q2LUMP_BRUSHSIDES]); noerrors = noerrors && CModQ2_LoadBrushSides (mod, mod_base, &header.lumps[Q2LUMP_BRUSHSIDES]);
noerrors = noerrors && CModQ2_LoadBrushes (mod, mod_base, &header.lumps[Q2LUMP_BRUSHES]); 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_LoadSubmodels (mod, mod_base, &header.lumps[Q2LUMP_MODELS]);
noerrors = noerrors && CModQ2_LoadAreas (mod, mod_base, &header.lumps[Q2LUMP_AREAS]); noerrors = noerrors && CModQ2_LoadAreas (mod, mod_base, &header.lumps[Q2LUMP_AREAS]);
noerrors = noerrors && CModQ2_LoadAreaPortals (mod, mod_base, &header.lumps[Q2LUMP_AREAPORTALS]); noerrors = noerrors && CModQ2_LoadAreaPortals (mod, mod_base, &header.lumps[Q2LUMP_AREAPORTALS]);
if (noerrors)
CMod_LoadEntityString (mod, mod_base, &header.lumps[Q2LUMP_ENTITIES]);
if (!noerrors) 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; mod->funcs.NativeContents = CM_NativeContents;
break; break;
#endif #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) if (area->floodnum == floodnum)
return; return;
Host_Error ("FloodArea_r: reflooded"); Con_Printf ("FloodArea_r: reflooded\n");
return;
} }
area->floodnum = floodnum; area->floodnum = floodnum;

View file

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

View file

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

View file

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

View file

@ -2611,8 +2611,8 @@ static void BE_UploadLightmaps(qboolean force)
{ {
lightmap[i]->rectchange.l = 0; lightmap[i]->rectchange.l = 0;
lightmap[i]->rectchange.t = 0; lightmap[i]->rectchange.t = 0;
lightmap[i]->rectchange.w = LMBLOCK_WIDTH; lightmap[i]->rectchange.w = lightmap[i]->width;
lightmap[i]->rectchange.h = LMBLOCK_HEIGHT; lightmap[i]->rectchange.h = lightmap[i]->height;
lightmap[i]->modified = true; lightmap[i]->modified = true;
} }
@ -3486,13 +3486,13 @@ void D3D11BE_DrawWorld (qboolean drawworld, qbyte *vis)
BE_RotateForEntity(&r_worldentity, NULL); 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) void D3D11BE_VBO_Destroy(vboarray_t *vearray)

View file

@ -7,6 +7,8 @@
#include <d3d11.h> #include <d3d11.h>
extern ID3D11Device *pD3DDev11; extern ID3D11Device *pD3DDev11;
//#include <D3D11Shader.h> //apparently requires win8 sdk, despite being a win7 thing.
#ifndef IID_ID3DBlob #ifndef IID_ID3DBlob
//microsoft can be such a pain sometimes. //microsoft can be such a pain sometimes.
@ -47,6 +49,67 @@ extern ID3D11Device *pD3DDev11;
#define ID3DBlob_Release(b) b->lpVtbl->Release(b) #define ID3DBlob_Release(b) b->lpVtbl->Release(b)
#define ID3DBlob_GetBufferSize(b) b->lpVtbl->GetBufferSize(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) ( HRESULT (WINAPI *pD3DCompile) (
LPCVOID pSrcData, LPCVOID pSrcData,
SIZE_T SrcDataSize, SIZE_T SrcDataSize,
@ -60,6 +123,14 @@ HRESULT (WINAPI *pD3DCompile) (
ID3DBlob **ppCode, ID3DBlob **ppCode,
ID3DBlob **ppErrorMsgs ID3DBlob **ppErrorMsgs
); );
HRESULT (WINAPI *pD3DReflect)(
LPCVOID pSrcData,
SIZE_T SrcDataSize,
REFIID pInterface,
void **ppReflector
);
static dllhandle_t *shaderlib; 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) 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 *vsformat;
char *hsformat = NULL; char *hsformat = NULL;
char *dsformat = NULL; char *dsformat = NULL;
@ -334,6 +428,8 @@ qboolean D3D11Shader_CreateProgram (program_t *prog, const char *name, unsigned
D3D_SHADER_MACRO defines[64]; D3D_SHADER_MACRO defines[64];
ID3DBlob *vcode = NULL, *hcode = NULL, *dcode = NULL, *fcode = NULL, *errors = NULL; ID3DBlob *vcode = NULL, *hcode = NULL, *dcode = NULL, *fcode = NULL, *errors = NULL;
qboolean success = false; qboolean success = false;
ID3D11ShaderReflection *freflect;
int i;
if (d3dfeaturelevel >= D3D_FEATURE_LEVEL_11_0) //and 11.1 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); 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) if (vcode)
ID3DBlob_Release(vcode); ID3DBlob_Release(vcode);
if (hcode) if (hcode)
@ -527,11 +652,13 @@ qboolean D3D11Shader_Init(unsigned int flevel)
dllfunction_t funcsold[] = dllfunction_t funcsold[] =
{ {
{(void**)&pD3DCompile, "D3DCompileFromMemory"}, {(void**)&pD3DCompile, "D3DCompileFromMemory"},
{(void**)&pD3DReflect, "D3DReflect"},
{NULL,NULL} {NULL,NULL}
}; };
dllfunction_t funcsnew[] = dllfunction_t funcsnew[] =
{ {
{(void**)&pD3DCompile, "D3DCompile"}, {(void**)&pD3DCompile, "D3DCompile"},
{(void**)&pD3DReflect, "D3DReflect"},
{NULL,NULL} {NULL,NULL}
}; };

View file

@ -3216,13 +3216,13 @@ void D3D9BE_DrawWorld (qboolean drawworld, qbyte *vis)
BE_RotateForEntity(&r_worldentity, NULL); 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) 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; return success;
} }
static int D3D9Shader_FindUniform_(LPD3DXCONSTANTTABLE ct, char *name) static int D3D9Shader_FindUniform_(LPD3DXCONSTANTTABLE ct, const char *name)
{ {
if (ct) if (ct)
{ {
UINT dc = 1; UINT dc = 1;
D3DXCONSTANT_DESC d; 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 d.RegisterIndex;
} }
return -1; 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; int offs;
@ -253,6 +253,29 @@ static void D3D9Shader_ProgAutoFields(program_t *prog, char **cvarnames, int *cv
char tmpname[128]; char tmpname[128];
cvar_t *cvar; 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->numparams = 0;
prog->nofixedcompat = true; prog->nofixedcompat = true;
@ -314,6 +337,51 @@ static void D3D9Shader_ProgAutoFields(program_t *prog, char **cvarnames, int *cv
int v[4] = {i}; int v[4] = {i};
IDirect3DDevice9_SetPixelShader(pD3DDev9, prog->permu[p].handle.hlsl.frag); IDirect3DDevice9_SetPixelShader(pD3DDev9, prog->permu[p].handle.hlsl.frag);
IDirect3DDevice9_SetPixelShaderConstantI(pD3DDev9, 0, v, 1); 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) static void (D3D9_VID_DeInit) (void)
{ {
Image_Shutdown();
/*final shutdown, kill the video stuff*/ /*final shutdown, kill the video stuff*/
if (pD3DDev9) if (pD3DDev9)
{ {
@ -854,6 +856,12 @@ void D3D9_Set2D (void)
vport.MinZ = 0; vport.MinZ = 0;
vport.MaxZ = 1; vport.MaxZ = 1;
IDirect3DDevice9_SetViewport(pD3DDev9, &vport); 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) 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) static void (D3D11_VID_DeInit) (void)
{ {
D3D11BE_Shutdown(); D3D11BE_Shutdown();
Image_Shutdown();
/*we cannot shut down cleanly while in fullscreen, supposedly*/ /*we cannot shut down cleanly while in fullscreen, supposedly*/
if(d3dswapchain) if(d3dswapchain)
@ -1150,8 +1151,14 @@ void D3D11_Set2D (void)
vport.MinDepth = 0; vport.MinDepth = 0;
vport.MaxDepth = 1; vport.MaxDepth = 1;
ID3D11DeviceContext_RSSetViewports(d3ddevctx, 1, &vport); ID3D11DeviceContext_RSSetViewports(d3ddevctx, 1, &vport);
D3D11BE_SetupViewCBuffer(); D3D11BE_SetupViewCBuffer();
vid.fbvwidth = vid.width;
vid.fbvheight = vid.height;
vid.fbpwidth = vid.pixelwidth;
vid.fbpheight = vid.pixelheight;
} }
static void (D3D11_SCR_UpdateScreen) (void) static void (D3D11_SCR_UpdateScreen) (void)

View file

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

View file

@ -90,7 +90,7 @@ void Mod_WipeSkin(skinid_t id)
for (i = 0; i < sk->nummappings; i++) for (i = 0; i < sk->nummappings; i++)
{ {
if (sk->mappings[i].needsfree) 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); R_UnloadShader(sk->mappings[i].shader);
} }
Z_Free(registeredskins[id]); 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); Terr_DrawTerrainModel(batches, &r_worldentity);
#endif #endif
R_Clutter_Emit(batches);
if (!r_drawentities.ival) if (!r_drawentities.ival)
return; return;

View file

@ -30,6 +30,12 @@ extern cvar_t gl_ati_truform;
extern cvar_t r_wireframe; extern cvar_t r_wireframe;
extern cvar_t r_refract_fbo; 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[] = "\ static const char LIGHTPASS_SHADER[] = "\
{\n\ {\n\
program rtlight%s\n\ program rtlight%s\n\
@ -894,7 +900,8 @@ void GLBE_RenderShadowBuffer(unsigned int numverts, int vbo, vecV_t *verts, unsi
GL_SelectEBO(ibo); GL_SelectEBO(ibo);
qglDrawRangeElements(GL_TRIANGLES, 0, numverts, numindicies, GL_INDEX_TYPE, indicies); 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.dummyvbo.indicies.gl.vbo = 0;
shaderstate.sourcevbo = NULL; 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; int i;
unsigned int cv = shaderstate.curentity->topcolour;
if (cv >= 16) if (cv >= 16)
{ {
*retred = (((cv&0xff0000)>>16)**((unsigned char*)&d_8to24rgbtable[15]+0))>>8; rgb[0] = (((cv&0xff0000)>>16)**((unsigned char*)&d_8to24rgbtable[15]+0)) / (256.0*256);
*retgreen = (((cv&0x00ff00)>>8)**((unsigned char*)&d_8to24rgbtable[15]+1))>>8; rgb[1] = (((cv&0x00ff00)>>8)**((unsigned char*)&d_8to24rgbtable[15]+1)) / (256.0*256);
*retblue = (((cv&0x0000ff)>>0)**((unsigned char*)&d_8to24rgbtable[15]+2))>>8; rgb[2] = (((cv&0x0000ff)>>0)**((unsigned char*)&d_8to24rgbtable[15]+2)) / (256.0*256);
return; return;
} }
if (cv >= 0) i = cv;
i = cv;
else
i = TOP_RANGE>>4;
if (i >= 8) if (i >= 8)
{ {
i<<=4; i<<=4;
@ -950,45 +953,9 @@ void R_FetchTopColour(int *retred, int *retgreen, int *retblue)
i+=15; i+=15;
} }
i*=3; i*=3;
*retred = host_basepal[i+0]; rgb[0] = host_basepal[i+0] / 255.0;
*retgreen = host_basepal[i+1]; rgb[1] = host_basepal[i+1] / 255.0;
*retblue = host_basepal[i+2]; rgb[2] = host_basepal[i+2] / 255.0;
/* 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];
/* if (!gammaworks) /* if (!gammaworks)
{ {
*retred = gammatable[*retred]; *retred = gammatable[*retred];
@ -1126,11 +1093,7 @@ static void T_Gen_CurrentRender(int tmu)
static void Shader_BindTextureForPass(int tmu, const shaderpass_t *pass) static void Shader_BindTextureForPass(int tmu, const shaderpass_t *pass)
{ {
extern texid_t missing_texture; extern cvar_t gl_specular_fallback;
extern texid_t missing_texture_gloss;
extern texid_t missing_texture_normal;
extern texid_t scenepp_postproc_cube;
extern texid_t r_whiteimage;
texid_t t; texid_t t;
switch(pass->texgen) switch(pass->texgen)
@ -1175,6 +1138,8 @@ static void Shader_BindTextureForPass(int tmu, const shaderpass_t *pass)
case T_GEN_SPECULAR: case T_GEN_SPECULAR:
if (shaderstate.curtexnums && TEXLOADED(shaderstate.curtexnums->specular)) if (shaderstate.curtexnums && TEXLOADED(shaderstate.curtexnums->specular))
t = 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 else
t = missing_texture_gloss; t = missing_texture_gloss;
break; break;
@ -1379,22 +1344,22 @@ void GLBE_DestroyFBOs(void)
if (shaderstate.tex_reflection) if (shaderstate.tex_reflection)
{ {
R_DestroyTexture(shaderstate.tex_reflection); Image_DestroyTexture(shaderstate.tex_reflection);
shaderstate.tex_reflection = r_nulltex; shaderstate.tex_reflection = r_nulltex;
} }
if (shaderstate.tex_refraction) if (shaderstate.tex_refraction)
{ {
R_DestroyTexture(shaderstate.tex_refraction); Image_DestroyTexture(shaderstate.tex_refraction);
shaderstate.tex_refraction = r_nulltex; shaderstate.tex_refraction = r_nulltex;
} }
if (shaderstate.tex_refractiondepth) if (shaderstate.tex_refractiondepth)
{ {
R_DestroyTexture(shaderstate.tex_refractiondepth); Image_DestroyTexture(shaderstate.tex_refractiondepth);
shaderstate.tex_refractiondepth = r_nulltex; shaderstate.tex_refractiondepth = r_nulltex;
} }
if (shaderstate.temptexture) if (shaderstate.temptexture)
{ {
R_DestroyTexture(shaderstate.temptexture); Image_DestroyTexture(shaderstate.temptexture);
shaderstate.temptexture = r_nulltex; 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: case RGB_GEN_TOPCOLOR:
if (cnt) if (cnt)
{ {
int r, g, b; R_FetchPlayerColour(shaderstate.curentity->topcolour, dst[0]);
R_FetchTopColour(&r, &g, &b);
dst[0][0] = r/255.0f;
dst[0][1] = g/255.0f;
dst[0][2] = b/255.0f;
while((cnt)--) while((cnt)--)
{ {
dst[cnt][0] = dst[0][0]; 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: case RGB_GEN_BOTTOMCOLOR:
if (cnt) if (cnt)
{ {
int r, g, b; R_FetchPlayerColour(shaderstate.curentity->bottomcolour, dst[0]);
R_FetchBottomColour(&r, &g, &b);
dst[0][0] = r/255.0f;
dst[0][1] = g/255.0f;
dst[0][2] = b/255.0f;
while((cnt)--) while((cnt)--)
{ {
dst[cnt][0] = dst[0][0]; dst[cnt][0] = dst[0][0];
@ -2738,7 +2695,7 @@ static void BE_SubmitMeshChain(qboolean usetesselation)
mesh = shaderstate.meshes[0]; 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); 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_DRAWS, 1);
RQuantAdd(RQUANT_PRIMITIVES, mesh->numindexes); RQuantAdd(RQUANT_PRIMITIVEINDICIES, mesh->numindexes);
return; return;
} }
else else
@ -2771,7 +2728,7 @@ static void BE_SubmitMeshChain(qboolean usetesselation)
} }
qglDrawRangeElements(batchtype, startv, endv, endi, GL_INDEX_TYPE, ilst); qglDrawRangeElements(batchtype, startv, endv, endi, GL_INDEX_TYPE, ilst);
RQuantAdd(RQUANT_DRAWS, 1); RQuantAdd(RQUANT_DRAWS, 1);
RQuantAdd(RQUANT_PRIMITIVES, endi); RQuantAdd(RQUANT_PRIMITIVEINDICIES, endi);
} }
return; 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); qglDrawRangeElements(batchtype, startv, endv, endi-starti, GL_INDEX_TYPE, (index_t*)shaderstate.sourcevbo->indicies.gl.addr + starti);
RQuantAdd(RQUANT_DRAWS, 1); RQuantAdd(RQUANT_DRAWS, 1);
RQuantAdd(RQUANT_PRIMITIVES, endi-starti); RQuantAdd(RQUANT_PRIMITIVEINDICIES, endi-starti);
} }
/* /*
if (qglUnlockArraysEXT) 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) static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm, qboolean entunchanged)
{ {
vec4_t param4; vec4_t param4;
int r, g, b; int r, g;//, b;
int i; int i;
unsigned int ph; unsigned int ph;
const shaderprogparm_t *p; const shaderprogparm_t *p;
@ -2975,6 +2932,93 @@ static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm,
switch(p->type) 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: case SP_M_VIEW:
qglUniformMatrix4fvARB(ph, 1, false, r_refdef.m_view); qglUniformMatrix4fvARB(ph, 1, false, r_refdef.m_view);
break; 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]); qglUniform4fARB(ph, 1, 1, 1, shaderstate.curentity->shaderRGBAf[3]);
break; break;
case SP_E_TOPCOLOURS: case SP_E_TOPCOLOURS:
R_FetchTopColour(&r, &g, &b); R_FetchPlayerColour(shaderstate.curentity->topcolour, param4);
param4[0] = r/255.0f;
param4[1] = g/255.0f;
param4[2] = b/255.0f;
qglUniform3fvARB(ph, 1, param4); qglUniform3fvARB(ph, 1, param4);
break; break;
case SP_E_BOTTOMCOLOURS: case SP_E_BOTTOMCOLOURS:
R_FetchBottomColour(&r, &g, &b); R_FetchPlayerColour(shaderstate.curentity->bottomcolour, param4);
param4[0] = r/255.0f;
param4[1] = g/255.0f;
param4[2] = b/255.0f;
qglUniform3fvARB(ph, 1, param4); qglUniform3fvARB(ph, 1, param4);
break; break;
@ -3155,11 +3193,11 @@ static void BE_Program_Set_Attributes(const program_t *prog, unsigned int perm,
r = 1; r = 1;
g = 1; g = 1;
while (r < vid.pixelwidth) while (r < vid.pixelwidth)
r *= 2; param4[0] *= 2;
while (g < vid.pixelheight) while (g < vid.pixelheight)
g *= 2; param4[1] *= 2;
param4[0] = vid.pixelwidth/(float)r; param4[0] = vid.pixelwidth/param4[0];
param4[1] = vid.pixelheight/(float)g; param4[1] = vid.pixelheight/param4[1];
} }
param4[2] = 0; param4[2] = 0;
param4[3] = 0; param4[3] = 0;
@ -3351,27 +3389,17 @@ static void BE_RenderMeshProgram(const shader_t *shader, const shaderpass_t *pas
#if MAXRLIGHTMAPS > 1 #if MAXRLIGHTMAPS > 1
if (perm & PERMUTATION_LIGHTSTYLES) 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[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[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[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);
//we need this loop to fix up fixed-function stuff 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);
for (; i < shaderstate.lastpasstmus; i++) 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);
{
GL_LazyBind(i, 0, r_nulltex);
}
shaderstate.lastpasstmus = pass->numMergedPasses+3;
} }
else
#endif #endif
{ while (shaderstate.lastpasstmus > i)
//we need this loop to fix up fixed-function stuff GL_LazyBind(--shaderstate.lastpasstmus, 0, r_nulltex);
for (; i < shaderstate.lastpasstmus; i++) shaderstate.lastpasstmus = i; //in case it was already lower
{
GL_LazyBind(i, 0, r_nulltex);
}
shaderstate.lastpasstmus = pass->numMergedPasses;
}
} }
BE_SubmitMeshChain(p->permu[perm].handle.glsl.usetesselation); 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, shaderstate.crepskyshader = R_RegisterShader("crepuscular_sky", SUF_NONE,
"{\n" "{\n"
"program crepuscular_sky\n" "program crepuscular_sky\n"
"{\n"
"map $diffuse\n"
"}\n"
"{\n"
"map $fullbright\n"
"}\n"
"}\n" "}\n"
); );
} }
@ -4649,8 +4671,8 @@ static void BE_UpdateLightmaps(void)
lm->width, lm->rectchange.h, glformat, gltype, lm->width, lm->rectchange.h, glformat, gltype,
lm->lightmaps+(lm->rectchange.t) *lm->width*lightmap_bytes); lm->lightmaps+(lm->rectchange.t) *lm->width*lightmap_bytes);
} }
lm->rectchange.l = LMBLOCK_WIDTH; lm->rectchange.l = lm->width;
lm->rectchange.t = LMBLOCK_HEIGHT; lm->rectchange.t = lm->height;
lm->rectchange.h = 0; lm->rectchange.h = 0;
lm->rectchange.w = 0; lm->rectchange.w = 0;
} }
@ -5259,7 +5281,7 @@ void GLBE_DrawWorld (qboolean drawworld, qbyte *vis)
TRACE(("GLBE_DrawWorld: drawn everything\n")); 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"); COM_AssertMainThread("GLBE_VBO_Begin");
@ -5278,7 +5300,7 @@ void GLBE_VBO_Begin(vbobctx_t *ctx, unsigned int maxsize)
else else
ctx->fallback = BZ_Malloc(maxsize); 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) 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; 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) if (ctx->pos > ctx->maxsize)
Sys_Error("BE_VBO_Finish: too much data given\n"); 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) void GLBE_VBO_Destroy(vboarray_t *vearray)
{ {
if (vearray->gl.vbo) if (vearray->gl.vbo)
{
qglDeleteBuffersARB(1, &vearray->gl.vbo); qglDeleteBuffersARB(1, &vearray->gl.vbo);
vearray->gl.vbo = 0;
}
else else
BZ_Free(vearray->gl.addr); BZ_Free(vearray->gl.addr);
vearray->gl.addr = NULL;
} }
#endif #endif

View file

@ -321,6 +321,18 @@ qboolean GL_LoadTextureMips(texid_t tex, struct pendingtextureinfo *mips)
qglTexParameteri(targ, GL_TEXTURE_WRAP_R, GL_REPEAT); 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->width = mips->mip[0].width;
tex->height = mips->mip[0].height; tex->height = mips->mip[0].height;
GL_Texturemode_Apply(targ, tex->flags); 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); 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) if (mips->extrafree)
Z_Free(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]); 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) void Terrain_ClipDecal(fragmentdecal_t *dec, float *center, float radius, model_t *model)
{ {
int min[2], max[2], mint[2], maxt[2]; 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]; vert[5][2] = s->heights[(tx+1) + (ty+1)*SECTHEIGHTSIZE];
} }
Fragment_ClipPoly(dec, 3, &vert[0][0]); //fixme: per-section shaders for clutter info. this kinda sucks.
Fragment_ClipPoly(dec, 3, &vert[3][0]); 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" "map $diffuse\n"
"blendfunc add\n" "blendfunc add\n"
"}\n" "}\n"
//FIXME: these maps are a legacy thing, and could be removed if third-party glsl properly contains s_diffuse
"{\n" "{\n"
"map $upperoverlay\n" "map $upperoverlay\n"
"}\n" "}\n"
@ -4697,6 +4696,7 @@ void Terr_FinishTerrain(model_t *mod)
"}\n" "}\n"
"}\n" "}\n"
//FIXME: these maps are a legacy thing, and could be removed if third-party glsl properly contains s_diffuse
"{\n" "{\n"
"map $diffuse\n" "map $diffuse\n"
"}\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]; char name[64];
unsigned width, height; unsigned width, height;
qbyte alphaed; //gl_blend needed on this surface.
struct shader_s *shader; struct shader_s *shader;
texnums_t texnums;
int anim_total; // total tenths in sequence ( 0 = no) int anim_total; // total tenths in sequence ( 0 = no)
int anim_min, anim_max; // time for this frame min <=time< max int anim_min, anim_max; // time for this frame min <=time< max
struct texture_s *anim_next; // in the animation sequence struct texture_s *anim_next; // in the animation sequence
struct texture_s *alternate_anims; // bmodels in frmae 1 use these 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; } texture_t;
/* /*
typedef struct typedef struct
@ -327,7 +325,7 @@ typedef struct
typedef struct mtexinfo_s typedef struct mtexinfo_s
{ {
float vecs[2][4]; float vecs[2][4];
float mipadjust; float vecscale[2];
texture_t *texture; texture_t *texture;
int flags; int flags;
@ -354,15 +352,16 @@ typedef struct mfog_s
mplane_t **planes; mplane_t **planes;
} mfog_t; } mfog_t;
#define LMSHIFT_DEFAULT 4
typedef struct msurface_s typedef struct msurface_s
{ {
mplane_t *plane; mplane_t *plane;
int flags; int flags;
int firstedge; // look up in model->surfedges[], negative numbers 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 texturemins[2];
short extents[2]; short extents[2];
@ -497,7 +496,9 @@ void Q1BSP_Init(void);
void *Q1BSPX_FindLump(char *lumpname, int *lumpsize); void *Q1BSPX_FindLump(char *lumpname, int *lumpsize);
void Q1BSPX_Setup(struct model_s *mod, char *filebase, unsigned int filelen, lump_t *lumps, int numlumps); 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 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); 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; int numvertexes;
mvertex_t *vertexes; mvertex_t *vertexes;
vec3_t *normals;
int numedges; int numedges;
medge_t *edges; medge_t *edges;

View file

@ -74,7 +74,7 @@ void R_AnimateLight (void)
int v1, v2, vd; int v1, v2, vd;
if (!cl_lightstyle[j].length) if (!cl_lightstyle[j].length)
{ {
d_lightstylevalue[j] = 256; d_lightstylevalue[j] = ('m'-'a')*22;
continue; continue;
} }
@ -1246,8 +1246,8 @@ int GLRecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
if (!surf->samples) if (!surf->samples)
return 0; return 0;
ds >>= 4; ds >>= surf->lmshift;
dt >>= 4; dt >>= surf->lmshift;
lightmap = surf->samples; lightmap = surf->samples;
r = 0; r = 0;
@ -1255,29 +1255,27 @@ int GLRecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end)
{ {
if (cl.worldmodel->engineflags & MDLF_RGBLIGHTING) 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 ; for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++) maps++)
{ {
scale = d_lightstylevalue[surf->styles[maps]]; scale = d_lightstylevalue[surf->styles[maps]];
r += (lightmap[0]+lightmap[1]+lightmap[2]) * scale / 3; r += (lightmap[0]+lightmap[1]+lightmap[2]) * scale / 3;
lightmap += ((surf->extents[0]>>4)+1) * lightmap += ((surf->extents[0]>>surf->lmshift)+1) * ((surf->extents[1]>>surf->lmshift)+1)*3;
((surf->extents[1]>>4)+1)*3;
} }
} }
else 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 ; for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++) maps++)
{ {
scale = d_lightstylevalue[surf->styles[maps]]; scale = d_lightstylevalue[surf->styles[maps]];
r += *lightmap * scale; r += *lightmap * scale;
lightmap += ((surf->extents[0]>>4)+1) * lightmap += ((surf->extents[0]>>surf->lmshift)+1) * ((surf->extents[1]>>surf->lmshift)+1);
((surf->extents[1]>>4)+1);
} }
} }
@ -1406,8 +1404,8 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
return l; return l;
} }
ds >>= 4; ds >>= surf->lmshift;
dt >>= 4; dt >>= surf->lmshift;
lightmap = surf->samples; lightmap = surf->samples;
l[0]=0;l[1]=0;l[2]=0; 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; deluxmap = surf->samples - cl.worldmodel->lightdata + cl.worldmodel->deluxdata;
lightmap += (dt * ((surf->extents[0]>>4)+1) + ds)*3; lightmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)*3;
deluxmap += (dt * ((surf->extents[0]>>4)+1) + ds)*3; deluxmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)*3;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ; for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++) maps++)
{ {
@ -1436,10 +1434,10 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
l[4] += (deluxmap[1]-127)*scale; l[4] += (deluxmap[1]-127)*scale;
l[5] += (deluxmap[2]-127)*scale; l[5] += (deluxmap[2]-127)*scale;
lightmap += ((surf->extents[0]>>4)+1) * lightmap += ((surf->extents[0]>>surf->lmshift)+1) *
((surf->extents[1]>>4)+1) * 3; ((surf->extents[1]>>surf->lmshift)+1) * 3;
deluxmap += ((surf->extents[0]>>4)+1) * deluxmap += ((surf->extents[0]>>surf->lmshift)+1) *
((surf->extents[1]>>4)+1) * 3; ((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; deluxmap = (surf->samples - cl.worldmodel->lightdata)*3 + cl.worldmodel->deluxdata;
lightmap += (dt * ((surf->extents[0]>>4)+1) + ds); lightmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds);
deluxmap += (dt * ((surf->extents[0]>>4)+1) + ds)*3; deluxmap += (dt * ((surf->extents[0]>>surf->lmshift)+1) + ds)*3;
for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ; for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++) maps++)
{ {
@ -1462,10 +1460,10 @@ float *GLRecursiveLightPoint3C (mnode_t *node, vec3_t start, vec3_t end)
l[4] += deluxmap[1]*scale; l[4] += deluxmap[1]*scale;
l[5] += deluxmap[2]*scale; l[5] += deluxmap[2]*scale;
lightmap += ((surf->extents[0]>>4)+1) * lightmap += ((surf->extents[0]>>surf->lmshift)+1) *
((surf->extents[1]>>4)+1); ((surf->extents[1]>>surf->lmshift)+1);
deluxmap += ((surf->extents[0]>>4)+1) * deluxmap += ((surf->extents[0]>>surf->lmshift)+1) *
((surf->extents[1]>>4)+1) * 3; ((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) 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 ; for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++) 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[1] += lightmap[1] * scale * cl_lightstyle[surf->styles[maps]].colours[1];
l[2] += lightmap[2] * scale * cl_lightstyle[surf->styles[maps]].colours[2]; l[2] += lightmap[2] * scale * cl_lightstyle[surf->styles[maps]].colours[2];
lightmap += ((surf->extents[0]>>4)+1) * lightmap += ((surf->extents[0]>>surf->lmshift)+1) *
((surf->extents[1]>>4)+1) * 3; ((surf->extents[1]>>surf->lmshift)+1) * 3;
} }
} }
else 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 ; for (maps = 0 ; maps < MAXQ1LIGHTMAPS && surf->styles[maps] != 255 ;
maps++) 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[1] += *lightmap * scale * cl_lightstyle[surf->styles[maps]].colours[1];
l[2] += *lightmap * scale * cl_lightstyle[surf->styles[maps]].colours[2]; l[2] += *lightmap * scale * cl_lightstyle[surf->styles[maps]].colours[2];
lightmap += ((surf->extents[0]>>4)+1) * lightmap += ((surf->extents[0]>>surf->lmshift)+1) *
((surf->extents[1]>>4)+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> #include <ctype.h>
#ifdef D3D9QUAKE
#include <d3d9.h>
extern LPDIRECT3DDEVICE9 pD3DDev9;
#endif
extern texid_t missing_texture; extern texid_t missing_texture;
texid_t r_whiteimage; texid_t r_whiteimage;
static qboolean shader_reload_needed; static qboolean shader_reload_needed;
@ -214,6 +209,7 @@ typedef struct shaderkey_s
{ {
char *keyword; char *keyword;
void (*func)( shader_t *shader, shaderpass_t *pass, char **ptr ); void (*func)( shader_t *shader, shaderpass_t *pass, char **ptr );
char *prefix;
} shaderkey_t; } shaderkey_t;
typedef struct shadercachefile_s { typedef struct shadercachefile_s {
char *data; char *data;
@ -412,13 +408,13 @@ static char *Shader_ParseSensString(char **ptr)
return token; return token;
} }
static float Shader_ParseFloat(shader_t *shader, char **ptr) static float Shader_ParseFloat(shader_t *shader, char **ptr, float defaultval)
{ {
char *token; char *token;
if (!ptr || !(*ptr)) if (!ptr || !(*ptr))
return 0; return defaultval;
if (!**ptr || **ptr == '}') if (!**ptr || **ptr == '}')
return 0; return defaultval;
token = COM_ParseExt(ptr, false, true); token = COM_ParseExt(ptr, false, true);
if (*token == '$') if (*token == '$')
@ -432,9 +428,16 @@ static float Shader_ParseFloat(shader_t *shader, char **ptr)
cvar_t *var; cvar_t *var;
var = Cvar_FindVar(token+1); var = Cvar_FindVar(token+1);
if (var) if (var)
return var->value; {
if (*var->string)
return var->value;
else
return defaultval;
}
} }
} }
if (!*token)
return defaultval;
return atof(token); 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")) else if (!Q_stricmp (token, "noise"))
func->type = SHADER_FUNC_NOISE; func->type = SHADER_FUNC_NOISE;
func->args[0] = Shader_ParseFloat (shader, ptr); func->args[0] = Shader_ParseFloat (shader, ptr, 0);
func->args[1] = Shader_ParseFloat (shader, ptr); func->args[1] = Shader_ParseFloat (shader, ptr, 0);
func->args[2] = Shader_ParseFloat (shader, ptr); func->args[2] = Shader_ParseFloat (shader, ptr, 0);
func->args[3] = Shader_ParseFloat (shader, ptr); 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") ) if ( !Q_stricmp (token, "wave") )
{ {
deformv->type = DEFORMV_WAVE; deformv->type = DEFORMV_WAVE;
deformv->args[0] = Shader_ParseFloat (shader, ptr); deformv->args[0] = Shader_ParseFloat (shader, ptr, 0);
if (deformv->args[0]) if (deformv->args[0])
deformv->args[0] = 1.0f / deformv->args[0]; deformv->args[0] = 1.0f / deformv->args[0];
Shader_ParseFunc (shader, ptr, &deformv->func ); 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") ) else if ( !Q_stricmp (token, "normal") )
{ {
deformv->type = DEFORMV_NORMAL; deformv->type = DEFORMV_NORMAL;
deformv->args[0] = Shader_ParseFloat (shader, ptr ); deformv->args[0] = Shader_ParseFloat (shader, ptr, 0);
deformv->args[1] = Shader_ParseFloat (shader, ptr ); deformv->args[1] = Shader_ParseFloat (shader, ptr, 0);
} }
else if ( !Q_stricmp (token, "bulge") ) else if ( !Q_stricmp (token, "bulge") )
{ {
deformv->type = DEFORMV_BULGE; deformv->type = DEFORMV_BULGE;
Shader_ParseVector (shader, ptr, deformv->args ); Shader_ParseVector (shader, ptr, deformv->args);
shader->flags |= SHADER_DEFORMV_BULGE; shader->flags |= SHADER_DEFORMV_BULGE;
} }
else if ( !Q_stricmp (token, "move") ) else if ( !Q_stricmp (token, "move") )
@ -783,6 +786,24 @@ static void Shader_DeformVertexes ( shader_t *shader, shaderpass_t *pass, char *
shader->numdeforms++; 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) 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); boxname = Shader_ParseString(ptr);
Shader_ParseSkySides(shader->name, boxname, skydome->farbox_textures); Shader_ParseSkySides(shader->name, boxname, skydome->farbox_textures);
skyheight = Shader_ParseFloat(shader, ptr); skyheight = Shader_ParseFloat(shader, ptr, 512);
if (!skyheight)
{
skyheight = 512.0f;
}
boxname = Shader_ParseString(ptr); boxname = Shader_ParseString(ptr);
Shader_ParseSkySides(shader->name, boxname, skydome->nearbox_textures); 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[1] = FloatToByte ( fcolor[1] );
shader->fog_color[2] = FloatToByte ( fcolor[2] ); shader->fog_color[2] = FloatToByte ( fcolor[2] );
shader->fog_color[3] = 255; 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 ) { if ( shader->fog_dist <= 0.0f ) {
shader->fog_dist = 128.0f; shader->fog_dist = 128.0f;
@ -960,6 +977,8 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
cvarnames[cvarcount] = NULL; cvarnames[cvarcount] = NULL;
prog->nofixedcompat = true; prog->nofixedcompat = true;
prog->numsamplers = 0;
prog->defaulttextures = 0;
for(;;) for(;;)
{ {
while (*script == ' ' || *script == '\r' || *script == '\n' || *script == '\t') 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; prog->nofixedcompat = false;
script += 7; script += 7;
while (*script && *script != '\n')
script++;
} }
else if (!strncmp(script, "!!tess", 6)) else if (!strncmp(script, "!!tess", 6))
{ {
tess = true; tess = true;
script += 6; script += 6;
while (*script && *script != '\n')
script++;
} }
else if (!strncmp(script, "!!cvardf", 8)) else if (!strncmp(script, "!!cvardf", 8))
{ {
@ -1063,7 +1078,13 @@ static qboolean Shader_LoadPermutations(char *name, program_t *prog, char *scrip
} }
} }
if (!permutationname[p]) 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; script = end;
} }
else if (!strncmp(script, "!!ver", 5)) 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); ver = strtol(script, NULL, 0);
script = end; script = end;
} }
else if (!strncmp(script, "//", 2))
{
script += 2;
while (*script == ' ' || *script == '\t')
script++;
}
else else
break; break;
while (*script && *script != '\n')
script++;
}; };
if (sh_config.pLoadBlob && blobfilename && *blobfilename) if (sh_config.pLoadBlob && blobfilename && *blobfilename)
@ -2020,36 +2049,37 @@ static shaderkey_t shaderkeys[] =
{"entitymergable", Shader_EntityMergable}, {"entitymergable", Shader_EntityMergable},
//fte extensions //fte extensions
{"lpp_light", Shader_Prelight}, {"clutter", Shader_ClutterParms, "fte"},
{"glslprogram", Shader_GLSLProgramName}, {"lpp_light", Shader_Prelight, "fte"},
{"program", Shader_ProgramName}, //gl or d3d {"glslprogram", Shader_GLSLProgramName, "fte"},
{"hlslprogram", Shader_HLSL9ProgramName}, //for d3d {"program", Shader_ProgramName, "fte"}, //gl or d3d
{"hlsl11program", Shader_HLSL11ProgramName}, //for d3d {"hlslprogram", Shader_HLSL9ProgramName, "fte"}, //for d3d
{"param", Shader_ProgramParam}, //legacy {"hlsl11program", Shader_HLSL11ProgramName, "fte"}, //for d3d
{"param", Shader_ProgramParam, "fte"}, //legacy
{"bemode", Shader_BEMode}, {"bemode", Shader_BEMode, "fte"},
//dp compat //dp compat
{"dp_camera", Shader_DP_Camera}, {"camera", Shader_DP_Camera, "dp"},
/*doom3 compat*/ /*doom3 compat*/
{"diffusemap", Shader_DiffuseMap}, //macro for "{\nstage diffusemap\nmap <map>\n}" {"diffusemap", Shader_DiffuseMap, "doom3"}, //macro for "{\nstage diffusemap\nmap <map>\n}"
{"bumpmap", Shader_BumpMap}, //macro for "{\nstage bumpmap\nmap <map>\n}" {"bumpmap", Shader_BumpMap, "doom3"}, //macro for "{\nstage bumpmap\nmap <map>\n}"
{"specularmap", Shader_SpecularMap},//macro for "{\nstage specularmap\nmap <map>\n}" {"specularmap", Shader_SpecularMap, "doom3"},//macro for "{\nstage specularmap\nmap <map>\n}"
{"fullbrightmap", Shader_FullbrightMap},//macro for "{\nstage specularmap\nmap <map>\n}" {"fullbrightmap", Shader_FullbrightMap, "doom3"},//macro for "{\nstage specularmap\nmap <map>\n}"
{"uppermap", Shader_UpperMap},//macro for "{\nstage specularmap\nmap <map>\n}" {"uppermap", Shader_UpperMap, "doom3"},//macro for "{\nstage specularmap\nmap <map>\n}"
{"lowermap", Shader_LowerMap},//macro for "{\nstage specularmap\nmap <map>\n}" {"lowermap", Shader_LowerMap, "doom3"},//macro for "{\nstage specularmap\nmap <map>\n}"
{"discrete", NULL}, {"discrete", NULL, "doom3"},
{"nonsolid", NULL}, {"nonsolid", NULL, "doom3"},
{"noimpact", NULL}, {"noimpact", NULL, "doom3"},
{"translucent", Shader_Translucent}, {"translucent", Shader_Translucent, "doom3"},
{"noshadows", NULL}, {"noshadows", NULL, "doom3"},
{"nooverlays", NULL}, {"nooverlays", NULL, "doom3"},
{"nofragment", NULL}, {"nofragment", NULL, "doom3"},
/*simpler parsing for fte shaders*/ /*simpler parsing for fte shaders*/
{"progblendfunc", Shader_ProgBlendFunc}, {"progblendfunc", Shader_ProgBlendFunc, "fte"},
{"progmap", Shader_ProgMap}, {"progmap", Shader_ProgMap, "fte"},
{NULL, NULL} {NULL, NULL}
}; };
@ -2223,7 +2253,7 @@ static void Shaderpass_AnimMap (shader_t *shader, shaderpass_t *pass, char **ptr
pass->tcgen = TC_GEN_BASE; pass->tcgen = TC_GEN_BASE;
pass->flags |= SHADER_PASS_ANIMMAP; pass->flags |= SHADER_PASS_ANIMMAP;
pass->texgen = T_GEN_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; pass->anim_numframes = 0;
for ( ; ; ) for ( ; ; )
@ -2370,7 +2400,7 @@ static void Shaderpass_AlphaGen (shader_t *shader, shaderpass_t *pass, char **pt
if (!Q_stricmp (token, "portal")) if (!Q_stricmp (token, "portal"))
{ {
pass->alphagen = ALPHA_GEN_PORTAL; pass->alphagen = ALPHA_GEN_PORTAL;
shader->portaldist = Shader_ParseFloat(shader, ptr); shader->portaldist = Shader_ParseFloat(shader, ptr, 256);
if (!shader->portaldist) if (!shader->portaldist)
shader->portaldist = 256; shader->portaldist = 256;
shader->flags |= SHADER_AGEN_PORTAL; 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 = ALPHA_GEN_CONST;
pass->alphagen_func.type = SHADER_FUNC_CONSTANT; 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 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 //arg2 = timeshift
//arg3 = timescale //arg3 = timescale
speed = Shader_ParseFloat(shader, ptr); speed = Shader_ParseFloat(shader, ptr, 0);
min = Shader_ParseFloat(shader, ptr); min = Shader_ParseFloat(shader, ptr, 0);
max = Shader_ParseFloat(shader, ptr); max = Shader_ParseFloat(shader, ptr, 0);
pass->alphagen_func.args[0] = min + (max - min)/2; pass->alphagen_func.args[0] = min + (max - min)/2;
pass->alphagen_func.args[1] = (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); token = Shader_ParseString (ptr);
if (!Q_stricmp (token, "rotate")) 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]) if (!tcmod->args[0])
{ {
return; return;
@ -2594,14 +2624,14 @@ static void Shaderpass_TcMod (shader_t *shader, shaderpass_t *pass, char **ptr)
} }
else if ( !Q_stricmp (token, "scale") ) else if ( !Q_stricmp (token, "scale") )
{ {
tcmod->args[0] = Shader_ParseFloat (shader, ptr); tcmod->args[0] = Shader_ParseFloat (shader, ptr, 0);
tcmod->args[1] = Shader_ParseFloat (shader, ptr); tcmod->args[1] = Shader_ParseFloat (shader, ptr, 0);
tcmod->type = SHADER_TCMOD_SCALE; tcmod->type = SHADER_TCMOD_SCALE;
} }
else if ( !Q_stricmp (token, "scroll") ) else if ( !Q_stricmp (token, "scroll") )
{ {
tcmod->args[0] = Shader_ParseFloat (shader, ptr); tcmod->args[0] = Shader_ParseFloat (shader, ptr, 0);
tcmod->args[1] = Shader_ParseFloat (shader, ptr); tcmod->args[1] = Shader_ParseFloat (shader, ptr, 0);
tcmod->type = SHADER_TCMOD_SCROLL; tcmod->type = SHADER_TCMOD_SCROLL;
} }
else if (!Q_stricmp(token, "stretch")) 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")) else if (!Q_stricmp (token, "transform"))
{ {
for (i = 0; i < 6; ++i) 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; tcmod->type = SHADER_TCMOD_TRANSFORM;
} }
else if (!Q_stricmp (token, "turb")) else if (!Q_stricmp (token, "turb"))
{ {
for (i = 0; i < 4; i++) 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; tcmod->type = SHADER_TCMOD_TURB;
} }
else else
@ -2648,7 +2678,7 @@ static void Shaderpass_Scale ( shader_t *shader, shaderpass_t *pass, char **ptr
token = Shader_ParseString (ptr); token = Shader_ParseString (ptr);
if (!strcmp(token, "static")) if (!strcmp(token, "static"))
{ {
tcmod->args[0] = Shader_ParseFloat (shader, ptr); tcmod->args[0] = Shader_ParseFloat (shader, ptr, 0);
} }
else else
{ {
@ -2663,7 +2693,7 @@ static void Shaderpass_Scale ( shader_t *shader, shaderpass_t *pass, char **ptr
token = Shader_ParseString (ptr); token = Shader_ParseString (ptr);
if (!strcmp(token, "static")) if (!strcmp(token, "static"))
{ {
tcmod->args[1] = Shader_ParseFloat (shader, ptr); tcmod->args[1] = Shader_ParseFloat (shader, ptr, 0);
} }
else else
{ {
@ -2685,7 +2715,7 @@ static void Shaderpass_Scroll (shader_t *shader, shaderpass_t *pass, char **ptr)
if (!strcmp(token, "static")) if (!strcmp(token, "static"))
{ {
tcmod->type = SHADER_TCMOD_SCROLL; tcmod->type = SHADER_TCMOD_SCROLL;
tcmod->args[0] = Shader_ParseFloat (shader, ptr ); tcmod->args[0] = Shader_ParseFloat (shader, ptr, 0);
} }
else else
{ {
@ -2697,7 +2727,7 @@ static void Shaderpass_Scroll (shader_t *shader, shaderpass_t *pass, char **ptr)
if (!strcmp(token, "static")) if (!strcmp(token, "static"))
{ {
tcmod->type = SHADER_TCMOD_SCROLL; tcmod->type = SHADER_TCMOD_SCROLL;
tcmod->args[1] = Shader_ParseFloat (shader, ptr ); tcmod->args[1] = Shader_ParseFloat (shader, ptr, 0);
} }
else 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) static void Shaderpass_Red(shader_t *shader, shaderpass_t *pass, char **ptr)
{ {
pass->rgbgen = RGB_GEN_CONST; 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) static void Shaderpass_Green(shader_t *shader, shaderpass_t *pass, char **ptr)
{ {
pass->rgbgen = RGB_GEN_CONST; 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) static void Shaderpass_Blue(shader_t *shader, shaderpass_t *pass, char **ptr)
{ {
pass->rgbgen = RGB_GEN_CONST; 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) static void Shaderpass_Alpha(shader_t *shader, shaderpass_t *pass, char **ptr)
{ {
pass->alphagen = ALPHA_GEN_CONST; 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) 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) 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; pass->shaderbits |= SBITS_ATEST_GE128;
else else
Con_Printf("unsupported alphatest value\n"); Con_Printf("unsupported alphatest value\n");
@ -2850,30 +2880,30 @@ static shaderkey_t shaderpasskeys[] =
{"clampmap", Shaderpass_ClampMap }, {"clampmap", Shaderpass_ClampMap },
{"videomap", Shaderpass_VideoMap }, {"videomap", Shaderpass_VideoMap },
{"tcgen", Shaderpass_TcGen }, {"tcgen", Shaderpass_TcGen },
{"envmap", Shaderpass_EnvMap },//for alienarena {"envmap", Shaderpass_EnvMap, "rscript"},//for alienarena
{"nolightmap", Shaderpass_NoLightMap },//for alienarena {"nolightmap", Shaderpass_NoLightMap, "rscript"},//for alienarena
{"scale", Shaderpass_Scale },//for alienarena {"scale", Shaderpass_Scale, "rscript"},//for alienarena
{"scroll", Shaderpass_Scroll },//for alienarena {"scroll", Shaderpass_Scroll, "rscript"},//for alienarena
{"alphagen", Shaderpass_AlphaGen }, {"alphagen", Shaderpass_AlphaGen, "rscript"},
{"alphashift", Shaderpass_AlphaShift },//for alienarena {"alphashift", Shaderpass_AlphaShift, "rscript"},//for alienarena
{"alphamask", Shaderpass_AlphaMask },//for alienarena {"alphamask", Shaderpass_AlphaMask, "rscript"},//for alienarena
{"detail", Shaderpass_Detail }, {"detail", Shaderpass_Detail, "rscript"},
/*doom3 compat*/ /*doom3 compat*/
{"blend", Shaderpass_BlendFunc}, {"blend", Shaderpass_BlendFunc, "doom3"},
{"maskcolor", Shaderpass_MaskColor}, {"maskcolor", Shaderpass_MaskColor, "doom3"},
{"maskred", Shaderpass_MaskRed}, {"maskred", Shaderpass_MaskRed, "doom3"},
{"maskgreen", Shaderpass_MaskGreen}, {"maskgreen", Shaderpass_MaskGreen, "doom3"},
{"maskblue", Shaderpass_MaskBlue}, {"maskblue", Shaderpass_MaskBlue, "doom3"},
{"maskalpha", Shaderpass_MaskAlpha}, {"maskalpha", Shaderpass_MaskAlpha, "doom3"},
{"alphatest", Shaderpass_AlphaTest}, {"alphatest", Shaderpass_AlphaTest, "doom3"},
{"texgen", Shaderpass_TexGen}, {"texgen", Shaderpass_TexGen, "doom3"},
{"cubemap", Shaderpass_CubeMap}, //one of these is wrong {"cubemap", Shaderpass_CubeMap, "doom3"}, //one of these is wrong
{"cameracubemap",Shaderpass_CubeMap}, //one of these is wrong {"cameracubemap",Shaderpass_CubeMap, "doom3"}, //one of these is wrong
{"red", Shaderpass_Red}, {"red", Shaderpass_Red, "doom3"},
{"green", Shaderpass_Green}, {"green", Shaderpass_Green, "doom3"},
{"blue", Shaderpass_Blue}, {"blue", Shaderpass_Blue, "doom3"},
{"alpha", Shaderpass_Alpha}, {"alpha", Shaderpass_Alpha, "doom3"},
{NULL, NULL} {NULL, NULL}
}; };
@ -2908,8 +2938,12 @@ void Shader_Free (shader_t *shader)
shader->prog = NULL; shader->prog = NULL;
if (shader->skydome) if (shader->skydome)
{
Z_Free (shader->skydome); Z_Free (shader->skydome);
while (shader->clutter)
{
void *t = shader->clutter;
shader->clutter = shader->clutter->next;
Z_Free(t);
} }
pass = shader->passes; pass = shader->passes;
@ -3168,8 +3202,6 @@ void Shader_Shutdown (void)
int i; int i;
shader_t *shader; shader_t *shader;
Image_Shutdown();
if (!r_shaders) if (!r_shaders)
return; /*nothing needs freeing yet*/ return; /*nothing needs freeing yet*/
for (i = 0; i < r_numshaders; i++) 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) static qboolean Shader_Parsetok (shader_t *shader, shaderpass_t *pass, shaderkey_t *keys, char *token, char **ptr)
{ {
shaderkey_t *key; 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++) for (key = keys; key->keyword != NULL; key++)
{ {
if (!Q_stricmp (token, key->keyword)) if (!Q_stricmp (token, key->keyword))
{ {
if (key->func) if (!prefix || (prefix && key->prefix && !Q_strncasecmp(prefix, key->prefix, strlen(key->prefix))))
key->func ( shader, pass, ptr ); {
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 // Next Line
while (ptr) while (ptr)
@ -3606,25 +3654,6 @@ void Shader_Programify (shader_t *s)
s->numpasses = 0; s->numpasses = 0;
s->passes[s->numpasses++].texgen = T_GEN_DIFFUSE; s->passes[s->numpasses++].texgen = T_GEN_DIFFUSE;
s->flags |= SHADER_HASDIFFUSE; 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) 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[s->numpasses++];
pass = &s->passes[0]; pass = &s->passes[0];
@ -3974,6 +4015,46 @@ done:;
if (s->prog) 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) if (!s->numpasses)
{ {
s->passes[0].texgen = T_GEN_DIFFUSE; s->passes[0].texgen = T_GEN_DIFFUSE;
@ -4054,6 +4135,11 @@ void QDECL R_BuildDefaultTexnums(texnums_t *tn, shader_t *shader)
h = strchr(imagename, '#'); h = strchr(imagename, '#');
if (h) if (h)
*h = 0; *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. //skins can use an alternative path in certain cases, to work around dodgy models.
if (shader->generator == Shader_DefaultSkin) 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) void Shader_DefaultScript(const char *shortname, shader_t *s, const void *args)
{ {
const char *f = args; const char *f = args;
@ -4176,65 +4365,7 @@ void Shader_DefaultBSPLM(const char *shortname, shader_t *s, const void *args)
"}\n" "}\n"
"}\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 #ifdef GLQUAKE
if (qrenderer == QR_OPENGL) if (qrenderer == QR_OPENGL)
@ -4247,29 +4378,17 @@ void Shader_DefaultBSPLM(const char *shortname, shader_t *s, const void *args)
"{\n" "{\n"
"map $sourcecolour\n" "map $sourcecolour\n"
"}\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" "}\n"
); );
} }
if (!builtin && gl_config.arb_shader_objects) }
{ #endif
builtin = ( if (!builtin && ((sh_config.progs_supported && qrenderer == QR_OPENGL) || sh_config.progs_required))
{
builtin = (
"{\n" "{\n"
"program defaultwall\n" "program defaultwall\n"
//FIXME: these maps are a legacy thing, and could be removed if third-party glsl properly contains s_diffuse
"{\n" "{\n"
"map $diffuse\n" "map $diffuse\n"
"}\n" "}\n"
@ -4290,9 +4409,7 @@ void Shader_DefaultBSPLM(const char *shortname, shader_t *s, const void *args)
"}\n" "}\n"
"}\n" "}\n"
); );
}
} }
#endif
if (!builtin) if (!builtin)
builtin = ( builtin = (
"{\n" "{\n"
@ -4389,9 +4506,9 @@ char *Shader_DefaultBSPWater(shader_t *s, const char *shortname)
else if (r_fastturb.ival) else if (r_fastturb.ival)
wstyle = 0; wstyle = 0;
#ifdef GLQUAKE #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; 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; wstyle = stylevars[0]->ival;
#endif #endif
else else
@ -4456,14 +4573,14 @@ char *Shader_DefaultBSPWater(shader_t *s, const char *shortname)
"map $refraction\n" "map $refraction\n"
"}\n" "}\n"
"{\n" "{\n"
"map $normalmap\n" "map $null\n"//$reflection
"}\n" "}\n"
"{\n" "{\n"
"map $diffuse\n" "map $null\n"//$ripplemap
"}\n"
"{\n"
"map $null\n"//$refractiondepth
"}\n" "}\n"
// "{\n"
// "map $refractiondepth\n"
// "}\n"
"program altwater#FRESNEL=4\n" "program altwater#FRESNEL=4\n"
"}\n" "}\n"
); );
@ -4474,15 +4591,15 @@ char *Shader_DefaultBSPWater(shader_t *s, const char *shortname)
"{\n" "{\n"
"map $refraction\n" "map $refraction\n"
"}\n" "}\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n" "{\n"
"map $reflection\n" "map $reflection\n"
"}\n" "}\n"
// "{\n" "{\n"
// "map $refractiondepth\n" "map $null\n"//$ripplemap
// "}\n" "}\n"
"{\n"
"map $null\n"//$refractiondepth
"}\n"
"program altwater#REFLECT#FRESNEL=4\n" "program altwater#REFLECT#FRESNEL=4\n"
"}\n" "}\n"
); );
@ -4494,17 +4611,14 @@ char *Shader_DefaultBSPWater(shader_t *s, const char *shortname)
"map $refraction\n" "map $refraction\n"
"}\n" "}\n"
"{\n" "{\n"
"map $normalmap\n" "map $null\n"//$reflection
"}\n" "}\n"
"{\n"
"map $diffuse\n"
"}\n"
// "{\n"
// "map $refractiondepth\n"
// "}\n"
"{\n" "{\n"
"map $ripplemap\n" "map $ripplemap\n"
"}\n" "}\n"
"{\n"
"map $null\n"//$refractiondepth
"}\n"
"program altwater#RIPPLEMAP#FRESNEL=4\n" "program altwater#RIPPLEMAP#FRESNEL=4\n"
"}\n" "}\n"
); );
@ -4515,18 +4629,15 @@ char *Shader_DefaultBSPWater(shader_t *s, const char *shortname)
"{\n" "{\n"
"map $refraction\n" "map $refraction\n"
"}\n" "}\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n" "{\n"
"map $reflection\n" "map $reflection\n"
"}\n" "}\n"
// "{\n"
// "map $refractiondepth\n"
// "}\n"
"{\n" "{\n"
"map $ripplemap\n" "map $ripplemap\n"
"}\n" "}\n"
"{\n"
"map $null\n"//$refractiondepth
"}\n"
"program altwater#REFLECT#RIPPLEMAP#FRESNEL=4\n" "program altwater#REFLECT#RIPPLEMAP#FRESNEL=4\n"
"}\n" "}\n"
); );
@ -4715,22 +4826,7 @@ void Shader_DefaultBSPQ1(const char *shortname, shader_t *s, const void *args)
"{\n" "{\n"
"program defaultwall#EIGHTBIT\n" "program defaultwall#EIGHTBIT\n"
"{\n" "{\n"
"map $paletted\n"//$diffuse\n" "map $colourmap\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"
"}\n" "}\n"
"}\n" "}\n"
); );
@ -4841,14 +4937,6 @@ void Shader_DefaultSkin(const char *shortname, shader_t *s, const void *args)
"map $fullbright\n" "map $fullbright\n"
"blendfunc add\n" "blendfunc add\n"
"}\n" "}\n"
"if $haveprogram\n"
"{\n"
"map $normalmap\n"
"}\n"
"{\n"
"map $specular\n"
"}\n"
"endif\n"
"}\n" "}\n"
); );
} }

View file

@ -89,17 +89,17 @@ void Sh_Reset(void)
} }
if (shadowmap[0]) if (shadowmap[0])
{ {
R_DestroyTexture(shadowmap[0]); Image_DestroyTexture(shadowmap[0]);
shadowmap[0] = r_nulltex; shadowmap[0] = r_nulltex;
} }
if (shadowmap[1]) if (shadowmap[1])
{ {
R_DestroyTexture(shadowmap[1]); Image_DestroyTexture(shadowmap[1]);
shadowmap[1] = r_nulltex; shadowmap[1] = r_nulltex;
} }
if (crepuscular_texture_id) if (crepuscular_texture_id)
{ {
R_DestroyTexture(crepuscular_texture_id); Image_DestroyTexture(crepuscular_texture_id);
crepuscular_texture_id = r_nulltex; crepuscular_texture_id = r_nulltex;
} }
GLBE_FBO_Destroy(&crepuscular_fbo); 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 // clamp center of light to corner and check brightness
l = DotProduct (impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0]; 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+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]; 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+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 // compare to minimum light
if ((s*s+t*t+dot*dot) < maxdist) 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 // clamp center of light to corner and check brightness
l = DotProduct (impact, surf->texinfo->vecs[0]) + surf->texinfo->vecs[0][3] - surf->texturemins[0]; 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;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]; 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;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 // compare to minimum light
if ((s*s+t*t+dot*dot) < maxdist) 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); qglVertexPointer(3, GL_FLOAT, sizeof(vecV_t), surf->mesh->xyz_array);
qglDrawArrays(GL_POLYGON, 0, surf->mesh->numvertexes); qglDrawArrays(GL_POLYGON, 0, surf->mesh->numvertexes);
// qglDrawRangeElements(GL_TRIANGLES, 0, surf->mesh->numvertexes, surf->mesh->numindexes, GL_INDEX_TYPE, surf->mesh->indexes); // 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++) 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[] = 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", "sys/skeletal.h",
"#ifndef DEFS_DEFINED\n"
"attribute vec3 v_normal;\n" "attribute vec3 v_normal;\n"
"attribute vec3 v_svector;\n" "attribute vec3 v_svector;\n"
"attribute vec3 v_tvector;\n" "attribute vec3 v_tvector;\n"
"#endif\n"
"#ifdef SKELETAL\n" "#ifdef SKELETAL\n"
"attribute vec4 v_bone;" "#ifndef DEFS_DEFINED\n"
"attribute vec4 v_weight;" "attribute vec4 v_bone;"
"uniform mat3x4 m_bones["STRINGIFY(MAX_GPU_BONES)"];\n" "attribute vec4 v_weight;"
"uniform mat3x4 m_bones["STRINGIFY(MAX_GPU_BONES)"];\n"
"#endif\n"
"vec4 skeletaltransform()" "vec4 skeletaltransform()"
"{" "{"
@ -1154,27 +1299,34 @@ static const char *glsl_hdrs[] =
"sys/fog.h", "sys/fog.h",
"#ifdef FRAGMENT_SHADER\n" "#ifdef FRAGMENT_SHADER\n"
"#ifdef FOG\n" "#ifdef FOG\n"
"#ifndef DEFS_DEFINED\n"
"uniform vec4 w_fog[2];\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)" "vec3 fog3(in vec3 regularcolour)"
"{" "{"
"float z = w_fog[1].x * gl_FragCoord.z / gl_FragCoord.w;\n" "float z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;\n"
"z = max(0.0,z-w_fog[1].y);\n" "z = max(0.0,z-w_fogdepthbias);\n"
"#if #include \"cvar/r_fog_exp2\"\n" "#if #include \"cvar/r_fog_exp2\"\n"
"z *= z;\n" "z *= z;\n"
"#endif\n" "#endif\n"
"float fac = exp2(-(z * 1.442695));\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 mix(w_fog[0].rgb, regularcolour, fac);\n" "return mix(w_fogcolour, regularcolour, fac);\n"
"}\n" "}\n"
"vec3 fog3additive(in vec3 regularcolour)" "vec3 fog3additive(in vec3 regularcolour)"
"{" "{"
"float z = w_fog[1].x * gl_FragCoord.z / gl_FragCoord.w;\n" "float z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;\n"
"z = max(0.0,z-w_fog[1].y);\n" "z = max(0.0,z-w_fogdepthbias);\n"
"#if #include \"cvar/r_fog_exp2\"\n" "#if #include \"cvar/r_fog_exp2\"\n"
"z *= z;\n" "z *= z;\n"
"#endif\n" "#endif\n"
"float fac = exp2(-(z * 1.442695));\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" "return regularcolour * fac;\n"
"}\n" "}\n"
"vec4 fog4(in vec4 regularcolour)" "vec4 fog4(in vec4 regularcolour)"
@ -1183,24 +1335,24 @@ static const char *glsl_hdrs[] =
"}\n" "}\n"
"vec4 fog4additive(in vec4 regularcolour)" "vec4 fog4additive(in vec4 regularcolour)"
"{" "{"
"float z = w_fog[1].x * gl_FragCoord.z / gl_FragCoord.w;\n" "float z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;\n"
"z = max(0.0,z-w_fog[1].y);\n" "z = max(0.0,z-w_fogdepthbias);\n"
"#if #include \"cvar/r_fog_exp2\"\n" "#if #include \"cvar/r_fog_exp2\"\n"
"z *= z;\n" "z *= z;\n"
"#endif\n" "#endif\n"
"float fac = exp2(-(z * 1.442695));\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" "return regularcolour * vec4(fac, fac, fac, 1.0);\n"
"}\n" "}\n"
"vec4 fog4blend(in vec4 regularcolour)" "vec4 fog4blend(in vec4 regularcolour)"
"{" "{"
"float z = w_fog[1].x * gl_FragCoord.z / gl_FragCoord.w;\n" "float z = w_fogdensity * gl_FragCoord.z / gl_FragCoord.w;\n"
"z = max(0.0,z-w_fog[1].y);\n" "z = max(0.0,z-w_fogdepthbias);\n"
"#if #include \"cvar/r_fog_exp2\"\n" "#if #include \"cvar/r_fog_exp2\"\n"
"z *= z;\n" "z *= z;\n"
"#endif\n" "#endif\n"
"float fac = exp2(-(z * 1.442695));\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" "return regularcolour * vec4(1.0, 1.0, 1.0, fac);\n"
"}\n" "}\n"
"#else\n" "#else\n"
@ -1252,8 +1404,10 @@ static const char *glsl_hdrs[] =
"#undef r_glsl_pcf\n" "#undef r_glsl_pcf\n"
"#define r_glsl_pcf 9\n" "#define r_glsl_pcf 9\n"
"#endif\n" "#endif\n"
"#ifndef DEFS_DEFINED\n"
"uniform vec4 l_shadowmapproj;\n" //light projection matrix info "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. "uniform vec2 l_shadowmapscale;\n" //xy are the texture scale, z is 1, w is the scale.
"#endif\n"
"vec3 ShadowmapCoord(void)\n" "vec3 ShadowmapCoord(void)\n"
"{\n" "{\n"
"#ifdef SPOT\n" "#ifdef SPOT\n"
@ -1360,9 +1514,12 @@ qboolean GLSlang_GenerateIncludes(int maxstrings, int *strings, const GLchar *pr
return false; return false;
/*emit up to the include*/ /*emit up to the include*/
prstrings[*strings] = shadersource; if (incline - shadersource)
length[*strings] = incline - shadersource; {
*strings += 1; prstrings[*strings] = shadersource;
length[*strings] = incline - shadersource;
*strings += 1;
}
incline += 8; incline += 8;
incline = COM_ParseOut (incline, incname, sizeof(incname)); 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]); //length[strings] = strlen(prstrings[strings]);
//strings++; //strings++;
switch (shadertype) switch (shadertype)
{ {
case GL_FRAGMENT_SHADER_ARB: case GL_FRAGMENT_SHADER_ARB:
@ -1654,8 +1812,20 @@ static GLhandleARB GLSlang_FinishShader(GLhandleARB shader, const char *name, GL
if (developer.ival) if (developer.ival)
{ {
unsigned int line;
char *eol, *start;
qglGetShaderSource(shader, sizeof(str), NULL, str); 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); 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 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; unsigned int i, p;
qboolean found; qboolean found;
int uniformloc; int uniformloc;
@ -1997,6 +2190,9 @@ static void GLSlang_ProgAutoFields(program_t *prog, char **cvarnames, int *cvart
if (found) if (found)
prog->numparams++; prog->numparams++;
} }
prog->numsamplers = 0;
prog->defaulttextures = 0;
/*set texture uniforms*/ /*set texture uniforms*/
for (p = 0; p < PERMUTATIONS; p++) 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); Q_snprintfz(tmpname, sizeof(tmpname), "s_t%i", i);
uniformloc = qglGetUniformLocationARB(prog->permu[p].handle.glsl.handle, tmpname); uniformloc = qglGetUniformLocationARB(prog->permu[p].handle.glsl.handle, tmpname);
if (uniformloc != -1) if (uniformloc != -1)
{
qglUniform1iARB(uniformloc, i); 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); PROC (WINAPI *qwglGetProcAddress)(LPCSTR);
BOOL (WINAPI *qwglMakeCurrent)(HDC, HGLRC); BOOL (WINAPI *qwglMakeCurrent)(HDC, HGLRC);
BOOL (WINAPI *qSwapBuffers)(HDC); BOOL (WINAPI *qSwapBuffers)(HDC);
BOOL (WINAPI *qwglSwapLayerBuffers)(HDC, UINT);
int (WINAPI *qChoosePixelFormat)(HDC, CONST PIXELFORMATDESCRIPTOR *); int (WINAPI *qChoosePixelFormat)(HDC, CONST PIXELFORMATDESCRIPTOR *);
BOOL (WINAPI *qSetPixelFormat)(HDC, int, CONST PIXELFORMATDESCRIPTOR *); BOOL (WINAPI *qSetPixelFormat)(HDC, int, CONST PIXELFORMATDESCRIPTOR *);
int (WINAPI *qDescribePixelFormat)(HDC, int, UINT, LPPIXELFORMATDESCRIPTOR); 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_NO_RESET_NOTIFICATION_ARB 0x8261
#define WGL_LOSE_CONTEXT_ON_RESET_ARB 0x8252 #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) qboolean GLInitialise (char *renderer)
{ {
if (!hInstGL || strcmp(reqminidriver, renderer)) if (!hInstGL || strcmp(reqminidriver, renderer))
@ -500,6 +518,7 @@ qboolean GLInitialise (char *renderer)
if (usingminidriver) if (usingminidriver)
{ {
qwglSwapLayerBuffers = NULL;
qSwapBuffers = (void *)getglfunc("wglSwapBuffers"); qSwapBuffers = (void *)getglfunc("wglSwapBuffers");
qChoosePixelFormat = (void *)getglfunc("wglChoosePixelFormat"); qChoosePixelFormat = (void *)getglfunc("wglChoosePixelFormat");
qSetPixelFormat = (void *)getglfunc("wglSetPixelFormat"); qSetPixelFormat = (void *)getglfunc("wglSetPixelFormat");
@ -507,6 +526,7 @@ qboolean GLInitialise (char *renderer)
} }
else else
{ {
qwglSwapLayerBuffers = (void *)getwglfunc("wglSwapLayerBuffers");
qSwapBuffers = SwapBuffers; qSwapBuffers = SwapBuffers;
qChoosePixelFormat = ChoosePixelFormat; qChoosePixelFormat = ChoosePixelFormat;
qSetPixelFormat = SetPixelFormat; qSetPixelFormat = SetPixelFormat;
@ -1569,7 +1589,13 @@ void VID_WndAlpha_Override_Callback(struct cvar_s *var, char *oldvalue)
void GLVID_SwapBuffers (void) 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 // handle the mouse state when windowed if that's changed
@ -1673,25 +1699,13 @@ void GLVID_Shutdown (void)
gammaworks = false; gammaworks = false;
GLBE_Shutdown(); GLBE_Shutdown();
Image_Shutdown();
VID_UnSetMode(); 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) BOOL CheckForcePixelFormat(rendererstate_t *info)
{ {
if (qwglChoosePixelFormatARB && (info->multisample || info->srgb)) if (qwglChoosePixelFormatARB && (info->multisample || info->srgb))
@ -1838,7 +1852,6 @@ BOOL bSetupPixelFormat(HDC hDC, rendererstate_t *info)
0, // reserved 0, // reserved
0, 0, 0 // layer masks ignored 0, 0, 0 // layer masks ignored
}; };
int pixelformat;
TRACE(("dbg: bSetupPixelFormat: ChoosePixelFormat\n")); TRACE(("dbg: bSetupPixelFormat: ChoosePixelFormat\n"));
@ -1850,18 +1863,18 @@ BOOL bSetupPixelFormat(HDC hDC, rendererstate_t *info)
if (shouldforcepixelformat && qwglChoosePixelFormatARB) //the extra && is paranoia if (shouldforcepixelformat && qwglChoosePixelFormatARB) //the extra && is paranoia
{ {
shouldforcepixelformat = false; shouldforcepixelformat = false;
pixelformat = forcepixelformat; currentpixelformat = forcepixelformat;
} }
else else
{ {
if ((pixelformat = qChoosePixelFormat(hDC, &pfd))) if ((currentpixelformat = qChoosePixelFormat(hDC, &pfd)))
{ {
TRACE(("dbg: ChoosePixelFormat 1: worked\n")); 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")); 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); FixPaletteInDescriptor(hDC, &pfd);
if ((pfd.dwFlags & PFD_GENERIC_FORMAT) && !(pfd.dwFlags & PFD_GENERIC_ACCELERATED)) 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; pfd.cStencilBits = 0;
if ( (pixelformat = qChoosePixelFormat(hDC, &pfd)) == 0 ) if ( (currentpixelformat = qChoosePixelFormat(hDC, &pfd)) == 0 )
{ {
Con_Printf("bSetupPixelFormat: ChoosePixelFormat failed (%i)\n", (int)GetLastError()); Con_Printf("bSetupPixelFormat: ChoosePixelFormat failed (%i)\n", (int)GetLastError());
return FALSE; 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()); Con_Printf("bSetupPixelFormat: SetPixelFormat failed (%i)\n", (int)GetLastError());
return FALSE; return FALSE;

View file

@ -119,16 +119,17 @@ void LightLoadEntities(char *entstring)
#define DEFAULTLIGHTLEVEL 300 #define DEFAULTLIGHTLEVEL 300
mentity_t *mapent; mentity_t *mapent;
char key[1024]; char key[1024];
char value[1024];
int i; int i;
int switchedstyle=32; int switchedstyle=32;
num_entities = 0; num_entities = 0;
while(1) while(1)
{ {
entstring = COM_Parse(entstring); entstring = COM_ParseOut(entstring, key, sizeof(key));
if (!entstring || !*com_token) if (!entstring || !*key)
break; break;
if (strcmp(com_token, "{")) if (strcmp(key, "{"))
{ //someone messed up. Stop parsing. { //someone messed up. Stop parsing.
Con_Printf("token wasn't an open brace\n"); Con_Printf("token wasn't an open brace\n");
break; break;
@ -141,12 +142,11 @@ void LightLoadEntities(char *entstring)
mapent->colour[2] = 0; mapent->colour[2] = 0;
while(1) while(1)
{ {
entstring = COM_Parse(entstring); entstring = COM_ParseOut(entstring, key, sizeof(key));
if (!strcmp(com_token, "}")) if (!strcmp(key, "}"))
break; break;
strcpy(key, com_token); entstring = COM_ParseOut(entstring, value, sizeof(value));
entstring = COM_Parse(entstring); ParseEpair(mapent, key, value);
ParseEpair(mapent, key, com_token);
} }
if (!mapent->colour[0] && !mapent->colour[1] && !mapent->colour[2]) 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][1] += add*light->colour[1];
lightsamp[c][2] += add*light->colour[2]; lightsamp[c][2] += add*light->colour[2];
norms[c][0] -= add * incoming[0]; //Quake doesn't make sence some times. norms[c][0] += add * incoming[0]; //Quake doesn't make sence some times.
norms[c][1] -= add * incoming[1]; norms[c][1] += add * incoming[1];
norms[c][2] -= add * incoming[2]; norms[c][2] += add * incoming[2];
if (add > 1) // ignore real tiny lights if (add > 1) // ignore real tiny lights
hit = true; hit = true;
@ -939,12 +939,17 @@ void LightFace (int surfnum)
temp[0] = DotProduct(wnorm, svector); temp[0] = DotProduct(wnorm, svector);
temp[1] = DotProduct(wnorm, tvector); temp[1] = DotProduct(wnorm, tvector);
temp[2] = DotProduct(wnorm, l.facenormal); temp[2] = DotProduct(wnorm, l.facenormal);
VectorNormalize(temp); if (!temp[0] && !temp[1] && !temp[2])
temp[2] += 0.5; VectorSet(temp, 0, 0, 1);
VectorNormalize(temp); else
*dulout++ = (-temp[0]+1)*128; {
*dulout++ = (-temp[1]+1)*128; VectorNormalize(temp);
*dulout++ = (-temp[2]+1)*128; // 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" "}\n"
"#endif\n" "#endif\n"
"#ifdef FRAGMENT_SHADER\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 float cvar_r_glsl_turbscale;\n"
"uniform sampler2D s_t0; //refract\n" "uniform sampler2D s_refract; //refract\n"
"uniform sampler2D s_t1; //normalmap\n" "uniform sampler2D s_reflect; //reflection\n"
"uniform sampler2D s_t2; //diffuse/reflection\n" "uniform sampler2D s_refractdepth; //refraction depth\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_ripplemap; //ripplemap\n" "uniform sampler2D s_ripplemap; //ripplemap\n"
"#endif\n"
"uniform float e_time;\n" "uniform float e_time;\n"
"void main (void)\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" "ntc.t = tc.t + sin(tc.s+e_time)*0.125;\n"
//generate the two wave patterns from the normalmap //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_normalmap, 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(0, e_time*0.097)).xyz);\n"
"n -= 1.0 - 4.0/256.0;\n" "n -= 1.0 - 4.0/256.0;\n"
"#ifdef RIPPLEMAP\n" "#ifdef RIPPLEMAP\n"
@ -97,7 +94,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"sdepth = mix(near, far, sdepth);\n" "sdepth = mix(near, far, sdepth);\n"
//get depth value at the ground beyond the surface. //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" "gdepth = (2.0*near) / (far + near - gdepth * (far - near));\n"
"if (gdepth >= 0.5)\n" "if (gdepth >= 0.5)\n"
"{\n" "{\n"
@ -119,16 +116,16 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
//refraction image (and water fog, if possible) //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" "#ifdef DEPTH\n"
"refr = mix(refr, FOGTINT, min(depth/4096.0, 1.0));\n" "refr = mix(refr, FOGTINT, min(depth/4096.0, 1.0));\n"
"#endif\n" "#endif\n"
//reflection/diffuse //reflection/diffuse
"#ifdef REFLECT\n" "#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" "#else\n"
"refl = texture2D(s_t2, ntc).xyz;\n" "refl = texture2D(s_diffuse, ntc).xyz;\n"
"#endif\n" "#endif\n"
//FIXME: add specular //FIXME: add specular
@ -570,6 +567,8 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"!!cvarf r_glsl_offsetmapping_scale\n" "!!cvarf r_glsl_offsetmapping_scale\n"
"!!cvarf gl_specular\n" "!!cvarf gl_specular\n"
"#include \"sys/defs.h\"\n"
//standard shader used for models. //standard shader used for models.
//must support skeletal and 2-way vertex blending or Bad Things Will Happen. //must support skeletal and 2-way vertex blending or Bad Things Will Happen.
//the vertex shader is responsible for calculating lighting values. //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" "#ifdef VERTEX_SHADER\n"
"#include \"sys/skeletal.h\"\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" "void main ()\n"
"{\n" "{\n"
"#if defined(SPECULAR)||defined(OFFSETMAPPING)\n" "#if defined(SPECULAR)||defined(OFFSETMAPPING)\n"
@ -615,25 +607,8 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n" "#endif\n"
"#ifdef FRAGMENT_SHADER\n" "#ifdef FRAGMENT_SHADER\n"
"#include \"sys/fog.h\"\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" "#if defined(SPECULAR)\n"
"uniform sampler2D s_t5;\n"
"uniform float cvar_gl_specular;\n" "uniform float cvar_gl_specular;\n"
"#endif\n" "#endif\n"
@ -641,31 +616,28 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#include \"sys/offsetmapping.h\"\n" "#include \"sys/offsetmapping.h\"\n"
"#endif\n" "#endif\n"
"uniform vec4 e_colourident;\n"
"void main ()\n" "void main ()\n"
"{\n" "{\n"
"vec4 col, sp;\n" "vec4 col, sp;\n"
"#ifdef OFFSETMAPPING\n" "#ifdef OFFSETMAPPING\n"
"vec2 tcoffsetmap = offsetmap(s_t4, tc, eyevector);\n" "vec2 tcoffsetmap = offsetmap(s_normalmap, tc, eyevector);\n"
"#define tc tcoffsetmap\n" "#define tc tcoffsetmap\n"
"#endif\n" "#endif\n"
"col = texture2D(s_t0, tc);\n" "col = texture2D(s_diffuse, tc);\n"
"#ifdef UPPER\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" "col.rgb += uc.rgb*e_uppercolour*uc.a;\n"
"#endif\n" "#endif\n"
"#ifdef LOWER\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" "col.rgb += lc.rgb*e_lowercolour*lc.a;\n"
"#endif\n" "#endif\n"
"#if defined(BUMP) && defined(SPECULAR)\n" "#if defined(BUMP) && defined(SPECULAR)\n"
"vec3 bumps = normalize(vec3(texture2D(s_t4, tc)) - 0.5);\n" "vec3 bumps = normalize(vec3(texture2D(s_normalmap, tc)) - 0.5);\n"
"vec4 specs = texture2D(s_t5, tc);\n" "vec4 specs = texture2D(s_specular, tc);\n"
"vec3 halfdir = normalize(normalize(eyevector) + vec3(0.0, 0.0, 1.0));\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" "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" "col.rgb *= light;\n"
"#ifdef FULLBRIGHT\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 = mix(col.rgb, fb.rgb, fb.a);
"col.rgb += fb.rgb * fb.a;\n" "col.rgb += fb.rgb * fb.a;\n"
"#endif\n" "#endif\n"
@ -823,9 +795,8 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"float3 l_lightcolour;\n" "float3 l_lightcolour;\n"
"float3 l_lightposition;\n" "float3 l_lightposition;\n"
"sampler s_t0; /*diffuse*/\n" "sampler s_diffuse; /*diffuse*/\n"
"sampler s_t1; /*normal*/\n" "sampler s_fullbright; /*normal*/\n"
"sampler s_t2; /*specular*/\n"
"float4 main (v2f inp) : COLOR0\n" "float4 main (v2f inp) : COLOR0\n"
"{\n" "{\n"
"float2 tccoord;\n" "float2 tccoord;\n"
@ -836,10 +807,10 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"dir.xy /= 0.5*length(dir);\n" "dir.xy /= 0.5*length(dir);\n"
"tccoord = (dir.xy + e_time*0.03125);\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" "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" "return float4((solid.rgb*(1.0-clouds.a)) + (clouds.a*clouds.rgb), 1);\n"
"}\n" "}\n"
@ -1045,6 +1016,8 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"!!cvarf r_glsl_offsetmapping_scale\n" "!!cvarf r_glsl_offsetmapping_scale\n"
"!!cvarf gl_specular\n" "!!cvarf gl_specular\n"
"#include \"sys/defs.h\"\n"
//this is what normally draws all of your walls, even with rtlights disabled //this is what normally draws all of your walls, even with rtlights disabled
//note that the '286' preset uses drawflat_walls instead. //note that the '286' preset uses drawflat_walls instead.
@ -1063,19 +1036,6 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n" "#endif\n"
"#ifdef VERTEX_SHADER\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" "void main ()\n"
"{\n" "{\n"
"#if defined(OFFSETMAPPING) || defined(SPECULAR)\n" "#if defined(OFFSETMAPPING) || defined(SPECULAR)\n"
@ -1099,50 +1059,9 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#ifdef FRAGMENT_SHADER\n" "#ifdef FRAGMENT_SHADER\n"
//samplers //samplers
"#define s_diffuse s_t0\n" "#define s_colourmap s_t0\n"
"#define s_lightmap0 s_t1\n" "uniform sampler2D s_colourmap;\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"
"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" "#ifdef SPECULAR\n"
"uniform float cvar_gl_specular;\n" "uniform float cvar_gl_specular;\n"
"#endif\n" "#endif\n"
@ -1179,10 +1098,10 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#ifdef LIGHTSTYLED\n" "#ifdef LIGHTSTYLED\n"
"vec3 lightmaps;\n" "vec3 lightmaps;\n"
"#ifdef DELUXE\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_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_delux1, lm1).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_delux2, lm2).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_delux3, lm3).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" "#else\n"
"lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb;\n" "lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb;\n"
"lightmaps += texture2D(s_lightmap1, lm1).rgb * e_lmscale[1].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" "lightmaps += texture2D(s_lightmap3, lm3).rgb * e_lmscale[3].rgb;\n"
"#endif\n" "#endif\n"
"#else\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 //modulate by the bumpmap dot light
"#ifdef DELUXE\n" "#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"
"#endif\n" "#endif\n"
@ -1202,7 +1123,7 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"vec4 specs = texture2D(s_specular, tc);\n" "vec4 specs = texture2D(s_specular, tc);\n"
"#ifdef DELUXE\n" "#ifdef DELUXE\n"
//not lightstyled... //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" "#else\n"
"vec3 halfdir = normalize(normalize(eyevector) + vec3(0.0, 0.0, 1.0)); //this norm should be the deluxemap info instead\n" "vec3 halfdir = normalize(normalize(eyevector) + vec3(0.0, 0.0, 1.0)); //this norm should be the deluxemap info instead\n"
"#endif\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" "#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" "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" "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.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" "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 #endif
#ifdef GLQUAKE #ifdef GLQUAKE
{QR_OPENGL, 110, "defaultwarp", {QR_OPENGL, 110, "defaultwarp",
"!!cvarf r_wateralpha\n"
"!!permu FOG\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 the shader that's responsible for drawing default q1 turbulant water surfaces
//this is expected to be moderately fast. //this is expected to be moderately fast.
@ -1307,16 +1230,16 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#include \"sys/fog.h\"\n" "#include \"sys/fog.h\"\n"
"varying vec2 tc;\n" "varying vec2 tc;\n"
"#ifdef VERTEX_SHADER\n" "#ifdef VERTEX_SHADER\n"
"attribute vec2 v_texcoord;\n"
"void main ()\n" "void main ()\n"
"{\n" "{\n"
"tc = v_texcoord.st;\n" "tc = v_texcoord.st;\n"
"#ifdef FLOW\n"
"tc.s += e_time * -0.5;\n"
"#endif\n"
"gl_Position = ftetransform();\n" "gl_Position = ftetransform();\n"
"}\n" "}\n"
"#endif\n" "#endif\n"
"#ifdef FRAGMENT_SHADER\n" "#ifdef FRAGMENT_SHADER\n"
"uniform sampler2D s_t0;\n"
"uniform float e_time;\n"
"#ifndef ALPHA\n" "#ifndef ALPHA\n"
"uniform float cvar_r_wateralpha;\n" "uniform float cvar_r_wateralpha;\n"
"#define USEALPHA 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" "vec2 ntc;\n"
"ntc.s = tc.s + sin(tc.t+e_time)*0.125;\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" "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" "gl_FragColor = fog4(vec4(ts, USEALPHA));\n"
"}\n" "}\n"
"#endif\n" "#endif\n"
@ -1361,13 +1284,13 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#ifdef FRAGMENT_SHADER\n" "#ifdef FRAGMENT_SHADER\n"
"float cvar_r_wateralpha;\n" "float cvar_r_wateralpha;\n"
"float e_time;\n" "float e_time;\n"
"sampler s_t0;\n" "sampler s_diffuse;\n"
"float4 main (v2f inp) : COLOR0\n" "float4 main (v2f inp) : COLOR0\n"
"{\n" "{\n"
"float2 ntc;\n" "float2 ntc;\n"
"ntc.x = inp.tc.x + sin(inp.tc.y+e_time)*0.125;\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" "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" "return float4(ts, cvar_r_wateralpha);\n"
"}\n" "}\n"
@ -2108,15 +2031,14 @@ YOU SHOULD NOT EDIT THIS FILE BY HAND
"#endif\n" "#endif\n"
"#ifdef FRAGMENT_SHADER\n" "#ifdef FRAGMENT_SHADER\n"
"sampler s_t0;\n" "sampler s_diffuse;\n"
"sampler s_t1;\n"
"float l_lightradius;\n" "float l_lightradius;\n"
"float3 l_lightcolour;\n" "float3 l_lightcolour;\n"
"float4 main (v2f inp) : COLOR0\n" "float4 main (v2f inp) : COLOR0\n"
"{\n" "{\n"
"float3 col = l_lightcolour;\n" "float3 col = l_lightcolour;\n"
"col *= max(1.0 - dot(inp.lpos, inp.lpos)/(l_lightradius*l_lightradius), 0.0);\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" "return float4(diff * col, 1);\n"
"}\n" "}\n"
"#endif\n" "#endif\n"

View file

@ -451,11 +451,14 @@ typedef struct programshared_s
{ {
int refs; int refs;
qboolean nofixedcompat; 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]; shaderprogparm_t parm[SHADER_PROGPARMS_MAX];
struct { struct {
union programhandle_u handle; union programhandle_u handle;
unsigned int attrmask; unsigned int attrmask;
unsigned int texmask; //'standard' textures that are in use
unsigned int parm[SHADER_PROGPARMS_MAX]; unsigned int parm[SHADER_PROGPARMS_MAX];
} permu[PERMUTATIONS]; } permu[PERMUTATIONS];
} program_t; } program_t;
@ -558,6 +561,18 @@ struct shader_s
shader_gen_t *generator; shader_gen_t *generator;
char *genargs; 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; // meshfeatures_t features;
bucket_t bucket; 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 *R_RegisterShader_Flare (const char *name);
shader_t *QDECL R_RegisterSkin (const char *shadername, const char *modname); 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); 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_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); void R_RemapShader(const char *sourcename, const char *destname, float timeoffset);
cin_t *R_ShaderGetCinematic(shader_t *s); 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_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_RenderToTexture(texid_t sourcecol, texid_t sourcedepth, texid_t destcol, texid_t destdepth, qboolean usedepth);
void GLBE_RenderToTextureUpdate2d(qboolean destchanged); void GLBE_RenderToTextureUpdate2d(qboolean destchanged);
void GLBE_VBO_Begin(vbobctx_t *ctx, unsigned int maxsize); void GLBE_VBO_Begin(vbobctx_t *ctx, size_t 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);
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);
void GLBE_VBO_Destroy(vboarray_t *vearray); void GLBE_VBO_Destroy(vboarray_t *vearray);
void GLBE_FBO_Sources(texid_t sourcecolour, texid_t sourcedepth); 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. */ /* Define this if you get warnings about undefined structures. */
/* #undef INCOMPLETE_TYPES_BROKEN */ /* #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 #ifdef JPEG_INTERNALS

View file

@ -2,7 +2,7 @@
* jerror.h * jerror.h
* *
* Copyright (C) 1994-1997, Thomas G. Lane. * 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. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * 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") "Cannot quantize more than %d color components")
JMESSAGE(JERR_QUANT_FEW_COLORS, "Cannot quantize to fewer than %d colors") 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_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_DUPLICATE, "Invalid JPEG file structure: two SOF markers")
JMESSAGE(JERR_SOF_NO_SOS, "Invalid JPEG file structure: missing SOS marker") 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_SOF_UNSUPPORTED, "Unsupported JPEG process: SOF type 0x%02x")
JMESSAGE(JERR_SOI_DUPLICATE, "Invalid JPEG file structure: two SOI markers") 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_CREATE, "Failed to create temporary file %s")
JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file") JMESSAGE(JERR_TFILE_READ, "Read failed on temporary file")
JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file") JMESSAGE(JERR_TFILE_SEEK, "Seek failed on temporary file")

View file

@ -2,7 +2,7 @@
* jmorecfg.h * jmorecfg.h
* *
* Copyright (C) 1991-1997, Thomas G. Lane. * 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. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
@ -150,6 +150,24 @@ typedef unsigned short UINT16;
typedef unsigned int UINT16; typedef unsigned int UINT16;
#endif /* HAVE_UNSIGNED_SHORT */ #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 /* Datatype used for image dimensions. The JPEG standard only supports
* images up to 64K*64K due to 16-bit fields in SOF markers. Therefore * 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 * "unsigned int" is sufficient on all machines. However, if you need to
@ -192,6 +210,26 @@ typedef unsigned int JDIMENSION;
#endif #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" /* Here is the pseudo-keyword for declaring pointers that must be "far"
* on 80x86 machines. Most of the specialized coding for 80x86 is handled * 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 * by just saying "FAR *" where such a pointer is needed. In a few places
@ -207,9 +245,23 @@ typedef unsigned int JDIMENSION;
#endif #endif
typedef unsigned char JPEG_boolean; /*
#define JPEG_FALSE 0 * On a few systems, type boolean and/or its values FALSE, TRUE may appear
#define JPEG_TRUE 1 * 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. * the offsets will also change the order in which colormap data is organized.
* RESTRICTIONS: * RESTRICTIONS:
* 1. The sample applications cjpeg,djpeg do NOT support modified RGB formats. * 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 * 2. The color quantizer modules will not behave desirably if RGB_PIXELSIZE
* 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
* is not 3 (they don't understand about dummy color components!). So you * is not 3 (they don't understand about dummy color components!). So you
* can't use color quantization if you change that value. * can't use color quantization if you change that value.
*/ */

View file

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

View file

@ -1,14 +1,14 @@
/* /*
* jversion.h * jversion.h
* *
* Copyright (C) 1991-2010, Thomas G. Lane, Guido Vollbeding. * Copyright (C) 1991-2013, Thomas G. Lane, Guido Vollbeding.
* This file is part of the Independent JPEG Group's software. * This file is part of the Independent JPEG Group's software.
* For conditions of distribution and use, see the accompanying README file. * For conditions of distribution and use, see the accompanying README file.
* *
* This file contains software version identification. * This file contains software version identification.
*/ */
#define JVERSION "8b 16-May-2010" #define JVERSION "9 13-Jan-2013"
#define JCOPYRIGHT "Copyright (C) 2010, Thomas G. Lane, Guido Vollbeding" #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 /* 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 * For conditions of distribution and use, see copyright notice in zlib.h
*/ */
@ -15,11 +15,13 @@
* this permanently in zconf.h using "./configure --zprefix". * this permanently in zconf.h using "./configure --zprefix".
*/ */
#ifdef Z_PREFIX /* may be set to #if 1 by ./configure */ #ifdef Z_PREFIX /* may be set to #if 1 by ./configure */
# define Z_PREFIX_SET
/* all linked symbols */ /* all linked symbols */
# define _dist_code z__dist_code # define _dist_code z__dist_code
# define _length_code z__length_code # define _length_code z__length_code
# define _tr_align z__tr_align # define _tr_align z__tr_align
# define _tr_flush_bits z__tr_flush_bits
# define _tr_flush_block z__tr_flush_block # define _tr_flush_block z__tr_flush_block
# define _tr_init z__tr_init # define _tr_init z__tr_init
# define _tr_stored_block z__tr_stored_block # define _tr_stored_block z__tr_stored_block
@ -27,9 +29,11 @@
# define adler32 z_adler32 # define adler32 z_adler32
# define adler32_combine z_adler32_combine # define adler32_combine z_adler32_combine
# define adler32_combine64 z_adler32_combine64 # define adler32_combine64 z_adler32_combine64
# define compress z_compress # ifndef Z_SOLO
# define compress2 z_compress2 # define compress z_compress
# define compressBound z_compressBound # define compress2 z_compress2
# define compressBound z_compressBound
# endif
# define crc32 z_crc32 # define crc32 z_crc32
# define crc32_combine z_crc32_combine # define crc32_combine z_crc32_combine
# define crc32_combine64 z_crc32_combine64 # define crc32_combine64 z_crc32_combine64
@ -40,44 +44,53 @@
# define deflateInit2_ z_deflateInit2_ # define deflateInit2_ z_deflateInit2_
# define deflateInit_ z_deflateInit_ # define deflateInit_ z_deflateInit_
# define deflateParams z_deflateParams # define deflateParams z_deflateParams
# define deflatePending z_deflatePending
# define deflatePrime z_deflatePrime # define deflatePrime z_deflatePrime
# define deflateReset z_deflateReset # define deflateReset z_deflateReset
# define deflateResetKeep z_deflateResetKeep
# define deflateSetDictionary z_deflateSetDictionary # define deflateSetDictionary z_deflateSetDictionary
# define deflateSetHeader z_deflateSetHeader # define deflateSetHeader z_deflateSetHeader
# define deflateTune z_deflateTune # define deflateTune z_deflateTune
# define deflate_copyright z_deflate_copyright # define deflate_copyright z_deflate_copyright
# define get_crc_table z_get_crc_table # define get_crc_table z_get_crc_table
# define gz_error z_gz_error # ifndef Z_SOLO
# define gz_intmax z_gz_intmax # define gz_error z_gz_error
# define gz_strwinerror z_gz_strwinerror # define gz_intmax z_gz_intmax
# define gzbuffer z_gzbuffer # define gz_strwinerror z_gz_strwinerror
# define gzclearerr z_gzclearerr # define gzbuffer z_gzbuffer
# define gzclose z_gzclose # define gzclearerr z_gzclearerr
# define gzclose_r z_gzclose_r # define gzclose z_gzclose
# define gzclose_w z_gzclose_w # define gzclose_r z_gzclose_r
# define gzdirect z_gzdirect # define gzclose_w z_gzclose_w
# define gzdopen z_gzdopen # define gzdirect z_gzdirect
# define gzeof z_gzeof # define gzdopen z_gzdopen
# define gzerror z_gzerror # define gzeof z_gzeof
# define gzflush z_gzflush # define gzerror z_gzerror
# define gzgetc z_gzgetc # define gzflush z_gzflush
# define gzgets z_gzgets # define gzgetc z_gzgetc
# define gzoffset z_gzoffset # define gzgetc_ z_gzgetc_
# define gzoffset64 z_gzoffset64 # define gzgets z_gzgets
# define gzopen z_gzopen # define gzoffset z_gzoffset
# define gzopen64 z_gzopen64 # define gzoffset64 z_gzoffset64
# define gzprintf z_gzprintf # define gzopen z_gzopen
# define gzputc z_gzputc # define gzopen64 z_gzopen64
# define gzputs z_gzputs # ifdef _WIN32
# define gzread z_gzread # define gzopen_w z_gzopen_w
# define gzrewind z_gzrewind # endif
# define gzseek z_gzseek # define gzprintf z_gzprintf
# define gzseek64 z_gzseek64 # define gzvprintf z_gzvprintf
# define gzsetparams z_gzsetparams # define gzputc z_gzputc
# define gztell z_gztell # define gzputs z_gzputs
# define gztell64 z_gztell64 # define gzread z_gzread
# define gzungetc z_gzungetc # define gzrewind z_gzrewind
# define gzwrite z_gzwrite # 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 inflate z_inflate
# define inflateBack z_inflateBack # define inflateBack z_inflateBack
# define inflateBackEnd z_inflateBackEnd # define inflateBackEnd z_inflateBackEnd
@ -92,16 +105,22 @@
# define inflateReset z_inflateReset # define inflateReset z_inflateReset
# define inflateReset2 z_inflateReset2 # define inflateReset2 z_inflateReset2
# define inflateSetDictionary z_inflateSetDictionary # define inflateSetDictionary z_inflateSetDictionary
# define inflateGetDictionary z_inflateGetDictionary
# define inflateSync z_inflateSync # define inflateSync z_inflateSync
# define inflateSyncPoint z_inflateSyncPoint # define inflateSyncPoint z_inflateSyncPoint
# define inflateUndermine z_inflateUndermine # define inflateUndermine z_inflateUndermine
# define inflateResetKeep z_inflateResetKeep
# define inflate_copyright z_inflate_copyright # define inflate_copyright z_inflate_copyright
# define inflate_fast z_inflate_fast # define inflate_fast z_inflate_fast
# define inflate_table z_inflate_table # define inflate_table z_inflate_table
# define uncompress z_uncompress # ifndef Z_SOLO
# define uncompress z_uncompress
# endif
# define zError z_zError # define zError z_zError
# define zcalloc z_zcalloc # ifndef Z_SOLO
# define zcfree z_zcfree # define zcalloc z_zcalloc
# define zcfree z_zcfree
# endif
# define zlibCompileFlags z_zlibCompileFlags # define zlibCompileFlags z_zlibCompileFlags
# define zlibVersion z_zlibVersion # define zlibVersion z_zlibVersion
@ -111,7 +130,9 @@
# define alloc_func z_alloc_func # define alloc_func z_alloc_func
# define charf z_charf # define charf z_charf
# define free_func z_free_func # 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_header z_gz_header
# define gz_headerp z_gz_headerp # define gz_headerp z_gz_headerp
# define in_func z_in_func # define in_func z_in_func
@ -197,6 +218,12 @@
# endif # endif
#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: */ /* Some Mac compilers merge all .h files incorrectly: */
#if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__) #if defined(__MWERKS__)||defined(applec)||defined(THINK_C)||defined(__SC__)
# define NO_DUMMY_DECL # define NO_DUMMY_DECL
@ -243,6 +270,14 @@
# endif # endif
#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 /* The following definitions for FAR are needed only for MSDOS mixed
* model programming (small or medium model with some far allocations). * model programming (small or medium model with some far allocations).
* This was tested only with MSC; for other MSDOS compilers you may have * This was tested only with MSC; for other MSDOS compilers you may have
@ -356,12 +391,47 @@ typedef uLong FAR uLongf;
typedef Byte *voidp; typedef Byte *voidp;
#endif #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 # define Z_HAVE_UNISTD_H
#endif #endif
#if 1 /* was set to #if 1 by ./configure */
# define Z_HAVE_STDARG_H
#endif
#ifdef STDC #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 #endif
/* a little trick to accommodate both "#define _LARGEFILE64_SOURCE" and /* 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 * both "#undef _LARGEFILE64_SOURCE" and "#define _LARGEFILE64_SOURCE 0" as
* equivalently requesting no 64-bit operations * equivalently requesting no 64-bit operations
*/ */
#if -_LARGEFILE64_SOURCE - -1 == 1 #if defined(_LARGEFILE64_SOURCE) && -_LARGEFILE64_SOURCE - -1 == 1
# undef _LARGEFILE64_SOURCE # undef _LARGEFILE64_SOURCE
#endif #endif
#if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE) #if defined(__WATCOMC__) && !defined(Z_HAVE_UNISTD_H)
# include <unistd.h> /* for SEEK_* and off_t */ # define Z_HAVE_UNISTD_H
# ifdef VMS #endif
# include <unixio.h> /* for off_t */ #ifndef Z_SOLO
# endif # if defined(Z_HAVE_UNISTD_H) || defined(_LARGEFILE64_SOURCE)
# ifndef z_off_t # include <unistd.h> /* for SEEK_*, off_t, and _LFS64_LARGEFILE */
# define z_off_t off_t # ifdef VMS
# include <unixio.h> /* for off_t */
# endif
# ifndef z_off_t
# define z_off_t off_t
# endif
# endif # 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_SET 0 /* Seek from beginning of file. */
# define SEEK_CUR 1 /* Seek from current position. */ # define SEEK_CUR 1 /* Seek from current position. */
# define SEEK_END 2 /* Set file pointer to EOF plus "offset" */ # define SEEK_END 2 /* Set file pointer to EOF plus "offset" */
@ -394,18 +481,14 @@ typedef uLong FAR uLongf;
# define z_off_t long # define z_off_t long
#endif #endif
#if defined(_LARGEFILE64_SOURCE) && _LFS64_LARGEFILE-0 #if !defined(_WIN32) && defined(Z_LARGE64)
# define z_off64_t off64_t # define z_off64_t off64_t
#else #else
# define z_off64_t z_off_t # if defined(_WIN32) && !defined(__GNUC__) && !defined(Z_SOLO)
#endif # define z_off64_t __int64
# else
#if defined(__OS400__) # define z_off64_t z_off_t
# define NO_vsnprintf # endif
#endif
#if defined(__MVS__)
# define NO_vsnprintf
#endif #endif
/* MVS linker does not support external names larger than 8 bytes */ /* 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 /* 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 This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages 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 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 Comments) 1950 to 1952 in the files http://tools.ietf.org/html/rfc1950
(zlib format), rfc1951.txt (deflate format) and rfc1952.txt (gzip format). (zlib format), rfc1951 (deflate format) and rfc1952 (gzip format).
*/ */
#ifndef ZLIB_H #ifndef ZLIB_H
@ -37,11 +37,11 @@
extern "C" { extern "C" {
#endif #endif
#define ZLIB_VERSION "1.2.5" #define ZLIB_VERSION "1.2.8"
#define ZLIB_VERNUM 0x1250 #define ZLIB_VERNUM 0x1280
#define ZLIB_VER_MAJOR 1 #define ZLIB_VER_MAJOR 1
#define ZLIB_VER_MINOR 2 #define ZLIB_VER_MINOR 2
#define ZLIB_VER_REVISION 5 #define ZLIB_VER_REVISION 8
#define ZLIB_VER_SUBREVISION 0 #define ZLIB_VER_SUBREVISION 0
/* /*
@ -83,15 +83,15 @@ typedef void (*free_func) OF((voidpf opaque, voidpf address));
struct internal_state; struct internal_state;
typedef struct z_stream_s { 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 */ 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 */ Bytef *next_out; /* next output byte should be put there */
uInt avail_out; /* remaining free space at next_out */ 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 */ struct internal_state FAR *state; /* not visible by applications */
alloc_func zalloc; /* used to allocate the internal state */ 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 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 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 value returned by deflateBound (see below). Then deflate is guaranteed to
Z_STREAM_END, then it must be called again as described above. 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 deflate() sets strm->adler to the adler32 checksum of all input read
so far (that is, total_in bytes). 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 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 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; 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 avail_out must be large enough to hold all of the uncompressed data for the
of the uncompressed data may have been saved by the compressor for this operation to complete. (The size of the uncompressed data may have been
purpose.) The next operation on this stream must be inflateEnd to deallocate saved by the compressor for this purpose.) The use of Z_FINISH is not
the decompression state. The use of Z_FINISH is never required, but can be required to perform an inflation in one step. However it may be used to
used to inform inflate that a faster approach may be used for the single inform inflate that a faster approach can be used for the single inflate()
inflate() call. 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 In this implementation, inflate() always flushes as much output as
possible to the output buffer, and always uses the faster approach on the 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 first call. So the effects of the flush parameter in this implementation are
is on the return value of inflate(), as noted below, or when it returns early on the return value of inflate() as noted below, when inflate() returns early
because Z_BLOCK or Z_TREES is used. 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 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 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 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 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 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 initializing with inflateInit2(). Any information contained in the gzip
header is not retained, so applications that need that information should header is not retained, so applications that need that information should
instead use raw inflate, see inflateInit2() below, or inflateBack() and 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 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 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)); uInt dictLength));
/* /*
Initializes the compression dictionary from the given byte sequence Initializes the compression dictionary from the given byte sequence
without producing any compressed output. This function must be called without producing any compressed output. When using the zlib format, this
immediately after deflateInit, deflateInit2 or deflateReset, before any call function must be called immediately after deflateInit, deflateInit2 or
of deflate. The compressor and decompressor must use exactly the same deflateReset, and before any call of deflate. When doing raw deflate, this
dictionary (see inflateSetDictionary). 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 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 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 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 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 inconsistent (for example if deflate has already been called for this stream
or if the compression method is bsort). deflateSetDictionary does not or if not at a block boundary for raw deflate). deflateSetDictionary does
perform any compression: this will be done by deflate(). not perform any compression: this will be done by deflate().
*/ */
ZEXTERN int ZEXPORT deflateCopy OF((z_streamp dest, 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 deflation of sourceLen bytes. It must be called after deflateInit() or
deflateInit2(), and after deflateSetHeader(), if used. This would be used 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 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, ZEXTERN int ZEXPORT deflatePrime OF((z_streamp strm,
int bits, int bits,
int value)); 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 than or equal to 16, and that many of the least significant bits of value
will be inserted in the output. will be inserted in the output.
deflatePrime returns Z_OK if success, or Z_STREAM_ERROR if the source deflatePrime returns Z_OK if success, Z_BUF_ERROR if there was not enough
stream state was inconsistent. 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, 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 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. can be determined from the adler32 value returned by that call of inflate.
The compressor and decompressor must use exactly the same dictionary (see The compressor and decompressor must use exactly the same dictionary (see
deflateSetDictionary). For raw inflate, this function can be called deflateSetDictionary). For raw inflate, this function can be called at any
immediately after inflateInit2() or inflateReset() and before any call of time to set the dictionary. If the provided dictionary is smaller than the
inflate() to set the dictionary. The application must insure that the window and there is already data in the window, then the provided dictionary
dictionary that was used for compression is provided. 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 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 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(). 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)); ZEXTERN int ZEXPORT inflateSync OF((z_streamp strm));
/* /*
Skips invalid compressed data until a full flush point (see above the Skips invalid compressed data until a possible full flush point (see above
description of deflate with Z_FULL_FLUSH) can be found, or until all for the description of deflate with Z_FULL_FLUSH) can be found, or until all
available input is skipped. No output is provided. available input is skipped. No output is provided.
inflateSync returns Z_OK if a full flush point has been found, Z_BUF_ERROR inflateSync searches for a 00 00 FF FF pattern in the compressed data.
if no more input was provided, Z_DATA_ERROR if no flush point has been All full flush points have this pattern, but not all occurrences of this
found, or Z_STREAM_ERROR if the stream structure was inconsistent. In the pattern are full flush points.
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, inflateSync returns Z_OK if a possible full flush point has been found,
the application may repeatedly call inflateSync, providing more input each Z_BUF_ERROR if no more input was provided, Z_DATA_ERROR if no flush point
time, until success or end of the input data. 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, 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. See inflateBack() for the usage of these routines.
inflateBackInit will return Z_OK on success, Z_STREAM_ERROR if any of 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 allocated, or Z_VERSION_ERROR if the version of the library does not match
the version of the header file. 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)); typedef int (*out_func) OF((void FAR *, unsigned char FAR *, unsigned));
ZEXTERN int ZEXPORT inflateBack OF((z_streamp strm, 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)); out_func out, void FAR *out_desc));
/* /*
inflateBack() does a raw inflate with a single call using a call-back 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 interface for input and output. This is potentially more efficient than
file i/o applications in that it avoids copying between the output and the inflate() for file i/o applications, in that it avoids copying between the
sliding window by simply making the window itself the output buffer. This output and the sliding window by simply making the window itself the output
function trusts the application to not change the output buffer passed by buffer. inflate() can be faster on modern CPUs when used with large
the output function, at least until inflateBack() returns. 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 inflateBackInit() must be called first to allocate the internal state
and to initialize the state with the user-provided window buffer. 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) 27-31: 0 (reserved)
*/ */
#ifndef Z_SOLO
/* utility functions */ /* 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 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 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 */ /* 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. 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)); 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 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' 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 for fixed code compression as in "wb9F". (See the description of
deflateInit2 for more information about the strategy parameter.) Also "a" deflateInit2 for more information about the strategy parameter.) 'T' will
can be used instead of "w" to request that the gzip stream that will be request transparent writing or appending with no compression and not using
written be appended to the file. "+" will result in an error, since reading the gzip format.
and writing to the same gzip file is not supported.
"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 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 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 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 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, 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 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 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 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)); ZEXTERN int ZEXPORT gzread OF((gzFile file, voidp buf, unsigned len));
/* /*
Reads the given number of uncompressed bytes from the compressed file. If 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 the input file is not in gzip format, gzread copies the given number of
bytes into the buffer. bytes into the buffer directly from the file.
After reaching the end of a gzip stream in the input, gzread will continue 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 to read, looking for another gzip stream. Any number of gzip streams may be
of the input file directly without decompression. The entire input file concatenated in the input file, and will all be decompressed by gzread().
will be read if gzread is called until it returns less than the requested If something other than a gzip stream is encountered after a gzip stream,
len. 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 gzread returns the number of uncompressed bytes actually read, less than
len for end of file, or -1 for error. len for end of file, or -1 for error.
@ -1256,7 +1346,7 @@ ZEXTERN int ZEXPORT gzwrite OF((gzFile file,
error. 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 Converts, formats, and writes the arguments to the compressed file under
control of the format string, as in fprintf. gzprintf returns the number of 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)); ZEXTERN int ZEXPORT gzgetc OF((gzFile file));
/* /*
Reads one byte from the compressed file. gzgetc returns this byte or -1 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)); 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)); ZEXTERN int ZEXPORT gzdirect OF((gzFile file));
/* /*
Returns true (1) if file is being copied directly while reading, or false 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 (0) if file is a gzip stream being decompressed.
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.
If the input file is empty, gzdirect() will return true, since the input If the input file is empty, gzdirect() will return true, since the input
does not contain a gzip stream. 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 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 is a gzip file. Therefore if gzbuffer() is used, it should be called before
gzdirect(). 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)); 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. 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 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)); 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. file that is being written concurrently.
*/ */
#endif /* !Z_SOLO */
/* checksum functions */ /* 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 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 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 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)); 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 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 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 initial value for the crc. Pre- and post-conditioning (one's complement) is
complement) is performed within this function so it shouldn't be done by the performed within this function so it shouldn't be done by the application.
application.
Usage example: Usage example:
@ -1544,17 +1645,42 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
const char *version, const char *version,
int stream_size)); int stream_size));
#define deflateInit(strm, level) \ #define deflateInit(strm, level) \
deflateInit_((strm), (level), ZLIB_VERSION, sizeof(z_stream)) deflateInit_((strm), (level), ZLIB_VERSION, (int)sizeof(z_stream))
#define inflateInit(strm) \ #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) \ #define deflateInit2(strm, level, method, windowBits, memLevel, strategy) \
deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\ deflateInit2_((strm),(level),(method),(windowBits),(memLevel),\
(strategy), ZLIB_VERSION, sizeof(z_stream)) (strategy), ZLIB_VERSION, (int)sizeof(z_stream))
#define inflateInit2(strm, windowBits) \ #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) \ #define inflateBackInit(strm, windowBits, window) \
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 /* 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 * 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 * functions are changed to 64 bits) -- in case these are set on systems
* without large file support, _LFS64_LARGEFILE must also be true * 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 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 gzseek64 OF((gzFile, z_off64_t, int));
ZEXTERN z_off64_t ZEXPORT gztell64 OF((gzFile)); 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)); ZEXTERN uLong ZEXPORT crc32_combine64 OF((uLong, uLong, z_off64_t));
#endif #endif
#if !defined(ZLIB_INTERNAL) && _FILE_OFFSET_BITS-0 == 64 && _LFS64_LARGEFILE-0 #if !defined(ZLIB_INTERNAL) && defined(Z_WANT64)
# define gzopen gzopen64 # ifdef Z_PREFIX_SET
# define gzseek gzseek64 # define z_gzopen z_gzopen64
# define gztell gztell64 # define z_gzseek z_gzseek64
# define gzoffset gzoffset64 # define z_gztell z_gztell64
# define adler32_combine adler32_combine64 # define z_gzoffset z_gzoffset64
# define crc32_combine crc32_combine64 # define z_adler32_combine z_adler32_combine64
# ifdef _LARGEFILE64_SOURCE # 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 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 gzseek64 OF((gzFile, z_off_t, int));
ZEXTERN z_off_t ZEXPORT gztell64 OF((gzFile)); 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)); ZEXTERN uLong ZEXPORT crc32_combine OF((uLong, uLong, z_off_t));
#endif #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 */ /* hack for buggy compilers */
#if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL) #if !defined(ZUTIL_H) && !defined(NO_DUMMY_DECL)
struct internal_state {int dummy;}; struct internal_state {int dummy;};
@ -1603,8 +1745,21 @@ ZEXTERN int ZEXPORT inflateBackInit_ OF((z_streamp strm, int windowBits,
/* undocumented functions */ /* undocumented functions */
ZEXTERN const char * ZEXPORT zError OF((int)); ZEXTERN const char * ZEXPORT zError OF((int));
ZEXTERN int ZEXPORT inflateSyncPoint OF((z_streamp)); 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 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 #ifdef __cplusplus
} }

View file

@ -1066,7 +1066,7 @@ void PR_Compile_f(void)
Q_SetProgsParms(true); Q_SetProgsParms(true);
killondone = true; killondone = true;
} }
if (PR_StartCompile(svprogfuncs, argc, argv)) if (svprogfuncs->StartCompile && PR_StartCompile(svprogfuncs, argc, argv))
while(PR_ContinueCompile(svprogfuncs)); while(PR_ContinueCompile(svprogfuncs));
if (killondone) if (killondone)
@ -1148,7 +1148,7 @@ void PR_BreakPoint_f(void)
else else
Con_Printf("Breakpoint has been cleared\n"); Con_Printf("Breakpoint has been cleared\n");
Cvar_Set(Cvar_FindVar("debugger"), "1"); // Cvar_Set(Cvar_FindVar("debugger"), "1");
} }
void PR_WatchPoint_f(void) void PR_WatchPoint_f(void)
{ {
@ -1185,7 +1185,7 @@ void PR_WatchPoint_f(void)
Con_Printf("Watchpoint cleared\n"); Con_Printf("Watchpoint cleared\n");
pr_global_struct->self = oldself; pr_global_struct->self = oldself;
Cvar_Set(Cvar_FindVar("debugger"), "1"); // Cvar_Set(Cvar_FindVar("debugger"), "1");
} }
static void PR_SSProfile_f(void) static void PR_SSProfile_f(void)
@ -1246,6 +1246,7 @@ void PR_Init(void)
Cmd_AddCommand ("breakpoint", PR_BreakPoint_f); Cmd_AddCommand ("breakpoint", PR_BreakPoint_f);
Cmd_AddCommand ("watchpoint", PR_WatchPoint_f); Cmd_AddCommand ("watchpoint", PR_WatchPoint_f);
Cmd_AddCommand ("watchpoint_ssqc", PR_WatchPoint_f);
Cmd_AddCommand ("decompile", PR_Decompile_f); Cmd_AddCommand ("decompile", PR_Decompile_f);
Cmd_AddCommand ("compile", PR_Compile_f); Cmd_AddCommand ("compile", PR_Compile_f);
Cmd_AddCommand ("applycompile", PR_ApplyCompilation_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 *ent = G_EDICT(prinst, OFS_PARM0);
edict_t *touched; 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; return;
} }
@ -8648,16 +8649,14 @@ static void QCBUILTIN PF_runclientphys(pubprogfuncs_t *prinst, struct globalvars
pmove.sequence = *pr_global_ptrs->clientcommandframe; pmove.sequence = *pr_global_ptrs->clientcommandframe;
else else
pmove.sequence = 0; pmove.sequence = 0;
if (host_client && host_client->edict == ent)
pmove.pm_type = SV_PMTypeForClient(host_client); pmove.pm_type = SV_PMTypeForClient((host_client && host_client->edict == ent)?host_client:NULL, ent);
else
pmove.pm_type = PM_NORMAL;
pmove.jump_msec = 0; pmove.jump_msec = 0;
pmove.jump_held = ((int)ent->xv->pmove_flags)&PMF_JUMP_HELD; pmove.jump_held = ((int)ent->xv->pmove_flags)&PMF_JUMP_HELD;
if (progstype != PROG_QW) //this is just annoying. 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 else
pmove.waterjumptime = ent->v->teleport_time; 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.jump_held?PMF_JUMP_HELD:0);
ent->xv->pmove_flags += ((int)pmove.onladder?PMF_LADDER:0); ent->xv->pmove_flags += ((int)pmove.onladder?PMF_LADDER:0);
if (progstype != PROG_QW) //this is just annoying. 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 else
ent->v->teleport_time = pmove.waterjumptime; ent->v->teleport_time = pmove.waterjumptime;
VectorCopy(pmove.origin, ent->v->origin); 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.velocity, ent->v->velocity);
VectorCopy(pmove.angles, sv_player->v->v_angle); VectorCopy(pmove.angles, ent->v->v_angle);
ent->v->waterlevel = pmove.waterlevel; ent->v->waterlevel = pmove.waterlevel;
@ -8757,7 +8756,7 @@ static void QCBUILTIN PF_runclientphys(pubprogfuncs_t *prinst, struct globalvars
if (pmove.onground) 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)); ent->v->groundentity = EDICT_TO_PROG(svprogfuncs, EDICT_NUM(svprogfuncs, pmove.physents[pmove.groundent].info));
} }
else 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_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_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_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_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_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."}, {"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}, {"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_init", "void()", MENU},
{"m_shutdown", "void()", MENU}, {"m_shutdown", "void()", MENU},
{"m_draw", "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}, {"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}, {"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_HEALTH", "const float", CS, "Player's health.", STAT_HEALTH},
{"STAT_WEAPON", "const float", CS, NULL, STAT_WEAPON}, {"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, NULL, STAT_AMMO}, {"STAT_AMMO", "const float", CS, "player.currentammo", STAT_AMMO},
{"STAT_ARMOR", "const float", CS, NULL, STAT_ARMOR}, {"STAT_ARMOR", "const float", CS, NULL, STAT_ARMOR},
{"STAT_WEAPONFRAME", "const float", CS, NULL, STAT_WEAPONFRAME}, {"STAT_WEAPONFRAME", "const float", CS, NULL, STAT_WEAPONFRAME},
{"STAT_SHELLS", "const float", CS, NULL, STAT_SHELLS}, {"STAT_SHELLS", "const float", CS, NULL, STAT_SHELLS},
{"STAT_NAILS", "const float", CS, NULL, STAT_NAILS}, {"STAT_NAILS", "const float", CS, NULL, STAT_NAILS},
{"STAT_ROCKETS", "const float", CS, NULL, STAT_ROCKETS}, {"STAT_ROCKETS", "const float", CS, NULL, STAT_ROCKETS},
{"STAT_CELLS", "const float", CS, NULL, STAT_CELLS}, {"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_TOTALSECRETS", "const float", CS, NULL, STAT_TOTALSECRETS},
{"STAT_TOTALMONSTERS", "const float", CS, NULL, STAT_TOTALMONSTERS}, {"STAT_TOTALMONSTERS", "const float", CS, NULL, STAT_TOTALMONSTERS},
{"STAT_FOUNDSECRETS", "const float", CS, NULL, STAT_SECRETS}, {"STAT_FOUNDSECRETS", "const float", CS, NULL, STAT_SECRETS},
{"STAT_KILLEDMONSTERS", "const float", CS, NULL, STAT_MONSTERS}, {"STAT_KILLEDMONSTERS", "const float", CS, NULL, STAT_MONSTERS},
{"STAT_ITEMS", "const float", CS, NULL, STAT_ITEMS}, {"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, NULL, STAT_VIEWHEIGHT}, {"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_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", "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}, {"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_DIFFUSESCALE", "const float", CS, NULL, lfield_diffusescale},
{"LFIELD_SPECULARSCALE","const float", CS, NULL, lfield_specularscale}, {"LFIELD_SPECULARSCALE","const float", CS, NULL, lfield_specularscale},
{"LFIELD_ROTATION", "const float", CS, NULL, lfield_rotation}, {"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_NORMALMODE", "const float", CS, NULL, LFLAG_NORMALMODE},
{"LFLAG_REALTIMEMODE", "const float", CS, NULL, LFLAG_REALTIMEMODE}, {"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_H2PUSHPULL 13 // pushable/pullable object
#define MOVETYPE_H2SWIM 14 // should keep the object in water #define MOVETYPE_H2SWIM 14 // should keep the object in water
#define MOVETYPE_PHYSICS 32 #define MOVETYPE_PHYSICS 32
#define MOVETYPE_FLY_WORLDONLY 33
// edict->solid values // edict->solid values
#define SOLID_NOT 0 // no interaction with other objects #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. qboolean SV_UserInfoIsBasic(char *infoname); //standard message.
void SV_ExecuteClientMessage (client_t *cl); void SV_ExecuteClientMessage (client_t *cl);
void SVQ2_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); void SV_UserInit (void);
qboolean SV_TogglePause (client_t *cl); qboolean SV_TogglePause (client_t *cl);

View file

@ -1430,11 +1430,11 @@ static void SV_WriteIP_f (void)
} }
} }
if (bi->reason[0]) 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) 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 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)); VFS_WRITE(f, s, strlen(s));
bi = bi->next; bi = bi->next;
} }

View file

@ -1941,7 +1941,7 @@ void SV_WritePlayerToClient(sizebuf_t *msg, clstate_t *ent)
if (ent->cl->viewent) if (ent->cl->viewent)
pm_type = PMC_NONE; pm_type = PMC_NONE;
else else
pm_type = SV_PMTypeForClient (ent->cl); pm_type = SV_PMTypeForClient (ent->cl, ent->cl->edict);
switch (pm_type) switch (pm_type)
{ {
case PM_NORMAL: // Z_EXT_PM_TYPE protocol extension 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: case MOVETYPE_FOLLOW:
WPhys_Physics_Follow (w, ent); WPhys_Physics_Follow (w, ent);
break; break;
case MOVETYPE_FLY_WORLDONLY:
case MOVETYPE_FLY: case MOVETYPE_FLY:
case MOVETYPE_H2SWIM: case MOVETYPE_H2SWIM:
case MOVETYPE_TOSS: case MOVETYPE_TOSS:

View file

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

View file

@ -259,7 +259,7 @@ void SV_New_f (void)
gamedir = Info_ValueForKey (svs.info, "*gamedir"); gamedir = Info_ValueForKey (svs.info, "*gamedir");
if (!gamedir[0]) if (!gamedir[0])
{ {
if (ISQWCLIENT(host_client)) if (ISQWCLIENT(host_client) || ISQ2CLIENT(host_client))
gamedir = FS_GetGamedir(true); gamedir = FS_GetGamedir(true);
else else
gamedir = ""; 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 #ifdef SERVER_DEMO_PLAYBACK
if (sv.demostatevalid) 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. 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. { //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) if (cl->zquake_extensions & Z_EXT_PM_TYPE_NEW)
return PM_SPECTATOR; return PM_SPECTATOR;
return PM_OLD_SPECTATOR; return PM_OLD_SPECTATOR;
} }
if (cl->edict->v->health <= 0) if (ent->v->health <= 0)
return PM_DEAD; return PM_DEAD;
return PM_NORMAL; return PM_NORMAL;
} }
switch((int)cl->edict->v->movetype) switch((int)ent->v->movetype)
{ {
case MOVETYPE_NOCLIP: case MOVETYPE_NOCLIP:
/*older/vanilla clients have a b0rked spectator mode that we don't want to break*/ /*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_SPECTATOR;
return PM_OLD_SPECTATOR; return PM_OLD_SPECTATOR;
@ -5819,6 +5819,7 @@ int SV_PMTypeForClient (client_t *cl)
case MOVETYPE_6DOF: case MOVETYPE_6DOF:
return PM_6DOF; return PM_6DOF;
case MOVETYPE_FLY_WORLDONLY:
case MOVETYPE_FLY: case MOVETYPE_FLY:
return PM_FLY; return PM_FLY;
@ -5827,7 +5828,7 @@ int SV_PMTypeForClient (client_t *cl)
case MOVETYPE_WALK: case MOVETYPE_WALK:
default: default:
if (cl->edict->v->health <= 0) if (ent->v->health <= 0)
return PM_DEAD; return PM_DEAD;
return PM_NORMAL; 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->velocity, pmove.velocity);
VectorCopy (sv_player->v->v_angle, pmove.angles); 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_held = host_client->jump_held;
pmove.jump_msec = 0; pmove.jump_msec = 0;
if (progstype != PROG_QW) //this is just annoying. 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); Q_snprintfz(name, sizeof(name), "%slibgame_%s"ARCH_DL_POSTFIX, host_parms.binarydir, gamepath);
} }
else else
{ { //gamedir paths as specified above.
if (com_nogamedirnativecode.ival) if (com_nogamedirnativecode.ival)
continue; continue;
Q_snprintfz(name, sizeof(name), "%s%s", syspath, gamename[o]); 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); result = Q1BSP_RecursiveHullCheck (hull, hull->firstclipnode, 0, 1, start_l, end_l, trace);
VectorAdd (trace->endpos, origin, trace->endpos); VectorAdd (trace->endpos, origin, trace->endpos);
} }
else
result = false;
return result; return result;
} }

View file

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

View file

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

View file

@ -7,6 +7,8 @@
!!cvarf r_glsl_offsetmapping_scale !!cvarf r_glsl_offsetmapping_scale
!!cvarf gl_specular !!cvarf gl_specular
#include "sys/defs.h"
//this is what normally draws all of your walls, even with rtlights disabled //this is what normally draws all of your walls, even with rtlights disabled
//note that the '286' preset uses drawflat_walls instead. //note that the '286' preset uses drawflat_walls instead.
@ -25,19 +27,6 @@ varying vec2 lm0;
#endif #endif
#ifdef VERTEX_SHADER #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 () void main ()
{ {
#if defined(OFFSETMAPPING) || defined(SPECULAR) #if defined(OFFSETMAPPING) || defined(SPECULAR)
@ -61,50 +50,9 @@ void main ()
#ifdef FRAGMENT_SHADER #ifdef FRAGMENT_SHADER
//samplers //samplers
#define s_diffuse s_t0 #define s_colourmap s_t0
#define s_lightmap0 s_t1 uniform sampler2D s_colourmap;
#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
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 #ifdef SPECULAR
uniform float cvar_gl_specular; uniform float cvar_gl_specular;
#endif #endif
@ -141,10 +89,10 @@ void main ()
#ifdef LIGHTSTYLED #ifdef LIGHTSTYLED
vec3 lightmaps; vec3 lightmaps;
#ifdef DELUXE #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_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_delux1, lm1).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_delux2, lm2).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_delux3, lm3).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 #else
lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb; lightmaps = texture2D(s_lightmap0, lm0).rgb * e_lmscale[0].rgb;
lightmaps += texture2D(s_lightmap1, lm1).rgb * e_lmscale[1].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; lightmaps += texture2D(s_lightmap3, lm3).rgb * e_lmscale[3].rgb;
#endif #endif
#else #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 //modulate by the bumpmap dot light
#ifdef DELUXE #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
#endif #endif
@ -164,7 +114,7 @@ void main ()
vec4 specs = texture2D(s_specular, tc); vec4 specs = texture2D(s_specular, tc);
#ifdef DELUXE #ifdef DELUXE
//not lightstyled... //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 #else
vec3 halfdir = normalize(normalize(eyevector) + vec3(0.0, 0.0, 1.0)); //this norm should be the deluxemap info instead vec3 halfdir = normalize(normalize(eyevector) + vec3(0.0, 0.0, 1.0)); //this norm should be the deluxemap info instead
#endif #endif
@ -179,7 +129,7 @@ void main ()
#ifdef EIGHTBIT //FIXME: with this extra flag, half the permutations are redundant. #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. 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 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.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. 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 !!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 the shader that's responsible for drawing default q1 turbulant water surfaces
//this is expected to be moderately fast. //this is expected to be moderately fast.
@ -7,16 +9,16 @@
#include "sys/fog.h" #include "sys/fog.h"
varying vec2 tc; varying vec2 tc;
#ifdef VERTEX_SHADER #ifdef VERTEX_SHADER
attribute vec2 v_texcoord;
void main () void main ()
{ {
tc = v_texcoord.st; tc = v_texcoord.st;
#ifdef FLOW
tc.s += e_time * -0.5;
#endif
gl_Position = ftetransform(); gl_Position = ftetransform();
} }
#endif #endif
#ifdef FRAGMENT_SHADER #ifdef FRAGMENT_SHADER
uniform sampler2D s_t0;
uniform float e_time;
#ifndef ALPHA #ifndef ALPHA
uniform float cvar_r_wateralpha; uniform float cvar_r_wateralpha;
#define USEALPHA cvar_r_wateralpha #define USEALPHA cvar_r_wateralpha
@ -28,7 +30,7 @@ void main ()
vec2 ntc; vec2 ntc;
ntc.s = tc.s + sin(tc.t+e_time)*0.125; ntc.s = tc.s + sin(tc.t+e_time)*0.125;
ntc.t = tc.t + sin(tc.s+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)); gl_FragColor = fog4(vec4(ts, USEALPHA));
} }
#endif #endif

View file

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

View file

@ -23,13 +23,13 @@ struct v2f {
#ifdef FRAGMENT_SHADER #ifdef FRAGMENT_SHADER
float cvar_r_wateralpha; float cvar_r_wateralpha;
float e_time; float e_time;
sampler s_t0; sampler s_diffuse;
float4 main (v2f inp) : COLOR0 float4 main (v2f inp) : COLOR0
{ {
float2 ntc; float2 ntc;
ntc.x = inp.tc.x + sin(inp.tc.y+e_time)*0.125; 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; 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); return float4(ts, cvar_r_wateralpha);
} }

View file

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

View file

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