diff --git a/doc/040_cvarlist.md b/doc/040_cvarlist.md index 6d608651..c54fa253 100644 --- a/doc/040_cvarlist.md +++ b/doc/040_cvarlist.md @@ -424,6 +424,7 @@ it's `+set busywait 0` (setting the `busywait` cvar) and `-portable` custom gun field of view is used. Defaults to `8`, which is more or less optimal for the default gun field of view of 80. +* **sw_colorlight**: enable experimental color lighting. ## cvar operations diff --git a/src/client/refresh/soft/header/local.h b/src/client/refresh/soft/header/local.h index 012571bf..6faa8c68 100644 --- a/src/client/refresh/soft/header/local.h +++ b/src/client/refresh/soft/header/local.h @@ -77,6 +77,7 @@ typedef unsigned char pixel_t; typedef int shift20_t; typedef int zvalue_t; typedef unsigned int light_t; +typedef int light3_t[3]; // xyz-prescale to 16.16 fixed-point #define SHIFT16XYZ 16 @@ -92,10 +93,15 @@ typedef enum rserr_unknown } rserr_t; +/* 64 light grades available */ +#define LIGHTMASK 0x3F00 + extern viddef_t vid; extern pixel_t *vid_buffer; // invisible buffer extern pixel_t *vid_colormap; // 256 * VID_GRADES size extern pixel_t *vid_alphamap; // 256 * 256 translucency map +extern byte *vid_lightmap; // 64 light grades for 256 colors +extern light_t vid_lightthreshold; // full light distance maximum extern char shift_size; // shift size in fixed-point typedef struct @@ -200,14 +206,17 @@ typedef struct ** if you change this structure be sure to change the #defines ** listed after it! */ -typedef struct finalvert_s { +typedef struct compactvert_s { int u, v, s, t; - int l; + light3_t l; // full color light zvalue_t zi; - int flags; - float xyz[3]; // eye space -} finalvert_t; +} compactvert_t; +typedef struct finalvert_s { + compactvert_t cv; // reuse compacted type + int flags; + float xyz[3]; // eye space +} finalvert_t; typedef struct { @@ -228,12 +237,6 @@ typedef struct int surfheight; // in mipmapped texels } drawsurf_t; -typedef struct { - int ambientlight; - int shadelight; - float *plightvec; -} alight_t; - // clipped bmodel edges typedef struct bedge_s { @@ -432,6 +435,7 @@ extern cvar_t *r_lefthand; extern cvar_t *r_gunfov; extern cvar_t *r_farsee; extern cvar_t *r_lightmap; +extern cvar_t *r_colorlight; extern cvar_t *r_drawworld; extern cvar_t *r_lerpmodels; extern cvar_t *r_lightlevel; @@ -502,7 +506,8 @@ extern edge_t **removeedges; typedef struct { int u, v, count; pixel_t *ptex; - int sfrac, tfrac, light; + int sfrac, tfrac; + light3_t light; zvalue_t zi; } spanpackage_t; extern spanpackage_t *triangle_spans, *triangles_max; @@ -583,12 +588,14 @@ void RE_Draw_FadeScreen (void); void LoadPCX (char *filename, byte **pic, byte **palette, int *width, int *height); +extern byte d_8to24table[256 * 4]; void R_InitImages(void); void R_ShutdownImages(void); image_t *R_FindImage(char *name, imagetype_t type); byte *Get_BestImageSize(const image_t *image, int *req_width, int *req_height); void R_FreeUnusedImages(void); qboolean R_ImageHasFreeSpace(void); +pixel_t R_ApplyLight(pixel_t pix, const light3_t light); void R_InitSkyBox(model_t *loadmodel); void R_IMFlatShadedQuad( const vec3_t a, const vec3_t b, const vec3_t c, const vec3_t d, int color, float alpha ); diff --git a/src/client/refresh/soft/header/model.h b/src/client/refresh/soft/header/model.h index a812386d..ec2faea7 100644 --- a/src/client/refresh/soft/header/model.h +++ b/src/client/refresh/soft/header/model.h @@ -95,7 +95,7 @@ typedef struct msurface_s // lighting info byte styles[MAXLIGHTMAPS]; - byte *samples; // [numstyles*surfsize] + byte *samples; // [numstyles*surfsize*3] struct msurface_s *nextalphasurface; } msurface_t; diff --git a/src/client/refresh/soft/sw_aclip.c b/src/client/refresh/soft/sw_aclip.c index e252871d..df6d3a06 100644 --- a/src/client/refresh/soft/sw_aclip.c +++ b/src/client/refresh/soft/sw_aclip.c @@ -34,6 +34,7 @@ static void R_Alias_clip_z (const finalvert_t *pfv0, const finalvert_t *pfv1, finalvert_t *out) { float scale; + int i; scale = (ALIAS_Z_CLIP_PLANE - pfv0->xyz[2]) / (pfv1->xyz[2] - pfv0->xyz[2]); @@ -42,39 +43,49 @@ R_Alias_clip_z (const finalvert_t *pfv0, const finalvert_t *pfv1, finalvert_t *o out->xyz[1] = pfv0->xyz[1] + (pfv1->xyz[1] - pfv0->xyz[1]) * scale; out->xyz[2] = ALIAS_Z_CLIP_PLANE; - out->s = pfv0->s + (pfv1->s - pfv0->s) * scale; - out->t = pfv0->t + (pfv1->t - pfv0->t) * scale; - out->l = pfv0->l + (pfv1->l - pfv0->l) * scale; + out->cv.s = pfv0->cv.s + (pfv1->cv.s - pfv0->cv.s) * scale; + out->cv.t = pfv0->cv.t + (pfv1->cv.t - pfv0->cv.t) * scale; + + for(i=0; i<3; i++) + out->cv.l[i] = pfv0->cv.l[i] + (pfv1->cv.l[i] - pfv0->cv.l[i]) * scale; R_AliasProjectAndClipTestFinalVert (out); } +static void +R_Alias_clip_scale (const finalvert_t *pfv0, const finalvert_t *pfv1, float scale, finalvert_t *out) +{ + int i; + + out->cv.u = pfv1->cv.u + ( pfv0->cv.u - pfv1->cv.u ) * scale + 0.5; + out->cv.v = pfv1->cv.v + ( pfv0->cv.v - pfv1->cv.v ) * scale + 0.5; + out->cv.s = pfv1->cv.s + ( pfv0->cv.s - pfv1->cv.s ) * scale + 0.5; + out->cv.t = pfv1->cv.t + ( pfv0->cv.t - pfv1->cv.t ) * scale + 0.5; + + for(i=0; i<3; i++) + out->cv.l[i] = pfv1->cv.l[i] + ( pfv0->cv.l[i] - pfv1->cv.l[i] ) * scale + 0.5; + + out->cv.zi = pfv1->cv.zi + ( pfv0->cv.zi - pfv1->cv.zi) * scale + 0.5; +} + static void R_Alias_clip_left (const finalvert_t *pfv0, const finalvert_t *pfv1, finalvert_t *out) { float scale; - if (pfv0->v >= pfv1->v ) + if (pfv0->cv.v >= pfv1->cv.v ) { - scale = (float)(r_refdef.aliasvrect.x - pfv0->u) / - (pfv1->u - pfv0->u); - out->u = pfv0->u + ( pfv1->u - pfv0->u ) * scale + 0.5; - out->v = pfv0->v + ( pfv1->v - pfv0->v ) * scale + 0.5; - out->s = pfv0->s + ( pfv1->s - pfv0->s ) * scale + 0.5; - out->t = pfv0->t + ( pfv1->t - pfv0->t ) * scale + 0.5; - out->l = pfv0->l + ( pfv1->l - pfv0->l ) * scale + 0.5; - out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5; + scale = (float)(r_refdef.aliasvrect.x - pfv0->cv.u) / + (pfv1->cv.u - pfv0->cv.u); + + R_Alias_clip_scale (pfv1, pfv0, scale, out); } else { - scale = (float)(r_refdef.aliasvrect.x - pfv1->u) / - (pfv0->u - pfv1->u); - out->u = pfv1->u + ( pfv0->u - pfv1->u ) * scale + 0.5; - out->v = pfv1->v + ( pfv0->v - pfv1->v ) * scale + 0.5; - out->s = pfv1->s + ( pfv0->s - pfv1->s ) * scale + 0.5; - out->t = pfv1->t + ( pfv0->t - pfv1->t ) * scale + 0.5; - out->l = pfv1->l + ( pfv0->l - pfv1->l ) * scale + 0.5; - out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5; + scale = (float)(r_refdef.aliasvrect.x - pfv1->cv.u) / + (pfv0->cv.u - pfv1->cv.u); + + R_Alias_clip_scale (pfv0, pfv1, scale, out); } } @@ -83,27 +94,19 @@ R_Alias_clip_right (const finalvert_t *pfv0, const finalvert_t *pfv1, finalvert_ { float scale; - if ( pfv0->v >= pfv1->v ) + if ( pfv0->cv.v >= pfv1->cv.v ) { - scale = (float)(r_refdef.aliasvrectright - pfv0->u ) / - (pfv1->u - pfv0->u ); - out->u = pfv0->u + ( pfv1->u - pfv0->u ) * scale + 0.5; - out->v = pfv0->v + ( pfv1->v - pfv0->v ) * scale + 0.5; - out->s = pfv0->s + ( pfv1->s - pfv0->s ) * scale + 0.5; - out->t = pfv0->t + ( pfv1->t - pfv0->t ) * scale + 0.5; - out->l = pfv0->l + ( pfv1->l - pfv0->l ) * scale + 0.5; - out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5; + scale = (float)(r_refdef.aliasvrectright - pfv0->cv.u ) / + (pfv1->cv.u - pfv0->cv.u ); + + R_Alias_clip_scale (pfv1, pfv0, scale, out); } else { - scale = (float)(r_refdef.aliasvrectright - pfv1->u ) / - (pfv0->u - pfv1->u ); - out->u = pfv1->u + ( pfv0->u - pfv1->u ) * scale + 0.5; - out->v = pfv1->v + ( pfv0->v - pfv1->v ) * scale + 0.5; - out->s = pfv1->s + ( pfv0->s - pfv1->s ) * scale + 0.5; - out->t = pfv1->t + ( pfv0->t - pfv1->t ) * scale + 0.5; - out->l = pfv1->l + ( pfv0->l - pfv1->l ) * scale + 0.5; - out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5; + scale = (float)(r_refdef.aliasvrectright - pfv1->cv.u ) / + (pfv0->cv.u - pfv1->cv.u ); + + R_Alias_clip_scale (pfv0, pfv1, scale, out); } } @@ -112,27 +115,19 @@ R_Alias_clip_top (const finalvert_t *pfv0, const finalvert_t *pfv1, finalvert_t { float scale; - if (pfv0->v >= pfv1->v) + if (pfv0->cv.v >= pfv1->cv.v) { - scale = (float)(r_refdef.aliasvrect.y - pfv0->v) / - (pfv1->v - pfv0->v); - out->u = pfv0->u + ( pfv1->u - pfv0->u ) * scale + 0.5; - out->v = pfv0->v + ( pfv1->v - pfv0->v ) * scale + 0.5; - out->s = pfv0->s + ( pfv1->s - pfv0->s ) * scale + 0.5; - out->t = pfv0->t + ( pfv1->t - pfv0->t ) * scale + 0.5; - out->l = pfv0->l + ( pfv1->l - pfv0->l ) * scale + 0.5; - out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5; + scale = (float)(r_refdef.aliasvrect.y - pfv0->cv.v) / + (pfv1->cv.v - pfv0->cv.v); + + R_Alias_clip_scale (pfv1, pfv0, scale, out); } else { - scale = (float)(r_refdef.aliasvrect.y - pfv1->v) / - (pfv0->v - pfv1->v); - out->u = pfv1->u + ( pfv0->u - pfv1->u ) * scale + 0.5; - out->v = pfv1->v + ( pfv0->v - pfv1->v ) * scale + 0.5; - out->s = pfv1->s + ( pfv0->s - pfv1->s ) * scale + 0.5; - out->t = pfv1->t + ( pfv0->t - pfv1->t ) * scale + 0.5; - out->l = pfv1->l + ( pfv0->l - pfv1->l ) * scale + 0.5; - out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5; + scale = (float)(r_refdef.aliasvrect.y - pfv1->cv.v) / + (pfv0->cv.v - pfv1->cv.v); + + R_Alias_clip_scale (pfv0, pfv1, scale, out); } } @@ -142,29 +137,19 @@ R_Alias_clip_bottom (const finalvert_t *pfv0, const finalvert_t *pfv1, finalvert { float scale; - if (pfv0->v >= pfv1->v) + if (pfv0->cv.v >= pfv1->cv.v) { - scale = (float)(r_refdef.aliasvrectbottom - pfv0->v) / - (pfv1->v - pfv0->v); + scale = (float)(r_refdef.aliasvrectbottom - pfv0->cv.v) / + (pfv1->cv.v - pfv0->cv.v); - out->u = pfv0->u + ( pfv1->u - pfv0->u ) * scale + 0.5; - out->v = pfv0->v + ( pfv1->v - pfv0->v ) * scale + 0.5; - out->s = pfv0->s + ( pfv1->s - pfv0->s ) * scale + 0.5; - out->t = pfv0->t + ( pfv1->t - pfv0->t ) * scale + 0.5; - out->l = pfv0->l + ( pfv1->l - pfv0->l ) * scale + 0.5; - out->zi = pfv0->zi + ( pfv1->zi - pfv0->zi) * scale + 0.5; + R_Alias_clip_scale (pfv1, pfv0, scale, out); } else { - scale = (float)(r_refdef.aliasvrectbottom - pfv1->v) / - (pfv0->v - pfv1->v); + scale = (float)(r_refdef.aliasvrectbottom - pfv1->cv.v) / + (pfv0->cv.v - pfv1->cv.v); - out->u = pfv1->u + ( pfv0->u - pfv1->u ) * scale + 0.5; - out->v = pfv1->v + ( pfv0->v - pfv1->v ) * scale + 0.5; - out->s = pfv1->s + ( pfv0->s - pfv1->s ) * scale + 0.5; - out->t = pfv1->t + ( pfv0->t - pfv1->t ) * scale + 0.5; - out->l = pfv1->l + ( pfv0->l - pfv1->l ) * scale + 0.5; - out->zi = pfv1->zi + ( pfv0->zi - pfv1->zi) * scale + 0.5; + R_Alias_clip_scale (pfv0, pfv1, scale, out); } } @@ -193,13 +178,13 @@ R_AliasClip (const finalvert_t *in, finalvert_t *out, int flag, int count, { clip (&in[j], &in[i], &out[k]); out[k].flags = 0; - if (out[k].u < r_refdef.aliasvrect.x) + if (out[k].cv.u < r_refdef.aliasvrect.x) out[k].flags |= ALIAS_LEFT_CLIP; - if (out[k].v < r_refdef.aliasvrect.y) + if (out[k].cv.v < r_refdef.aliasvrect.y) out[k].flags |= ALIAS_TOP_CLIP; - if (out[k].u > r_refdef.aliasvrectright) + if (out[k].cv.u > r_refdef.aliasvrectright) out[k].flags |= ALIAS_RIGHT_CLIP; - if (out[k].v > r_refdef.aliasvrectbottom) + if (out[k].cv.v > r_refdef.aliasvrectbottom) out[k].flags |= ALIAS_BOTTOM_CLIP; k++; } @@ -225,7 +210,7 @@ R_AliasClipTriangle(const entity_t *currententity, const finalvert_t *index0, co { int i, k, pingpong; unsigned clipflags; - finalvert_t fv[2][8]; + finalvert_t fv[2][8]; // copy vertexes and fix seam texture coordinates fv[0][0] = *index0; @@ -292,15 +277,15 @@ R_AliasClipTriangle(const entity_t *currententity, const finalvert_t *index0, co for (i=0 ; i r_refdef.aliasvrectright) - fv[pingpong][i].u = r_refdef.aliasvrectright; + if (fv[pingpong][i].cv.u < r_refdef.aliasvrect.x) + fv[pingpong][i].cv.u = r_refdef.aliasvrect.x; + else if (fv[pingpong][i].cv.u > r_refdef.aliasvrectright) + fv[pingpong][i].cv.u = r_refdef.aliasvrectright; - if (fv[pingpong][i].v < r_refdef.aliasvrect.y) - fv[pingpong][i].v = r_refdef.aliasvrect.y; - else if (fv[pingpong][i].v > r_refdef.aliasvrectbottom) - fv[pingpong][i].v = r_refdef.aliasvrectbottom; + if (fv[pingpong][i].cv.v < r_refdef.aliasvrect.y) + fv[pingpong][i].cv.v = r_refdef.aliasvrect.y; + else if (fv[pingpong][i].cv.v > r_refdef.aliasvrectbottom) + fv[pingpong][i].cv.v = r_refdef.aliasvrectbottom; fv[pingpong][i].flags = 0; } diff --git a/src/client/refresh/soft/sw_alias.c b/src/client/refresh/soft/sw_alias.c index 346bdfec..076fd6b4 100644 --- a/src/client/refresh/soft/sw_alias.c +++ b/src/client/refresh/soft/sw_alias.c @@ -35,9 +35,9 @@ affinetridesc_t r_affinetridesc; static vec3_t r_plightvec; static vec3_t r_lerp_frontv, r_lerp_backv, r_lerp_move; -static int r_ambientlight; +static light3_t r_ambientlight; int r_aliasblendcolor; -static float r_shadelight; +static vec3_t r_shadelight; static daliasframe_t *r_thisframe, *r_lastframe; @@ -257,14 +257,14 @@ R_AliasPreparePoints (const entity_t *currententity, finalvert_t *verts, const f continue; // completely clipped // insert s/t coordinates - pfv[0]->s = pstverts[ptri->index_st[0]].s << SHIFT16XYZ; - pfv[0]->t = pstverts[ptri->index_st[0]].t << SHIFT16XYZ; + pfv[0]->cv.s = pstverts[ptri->index_st[0]].s << SHIFT16XYZ; + pfv[0]->cv.t = pstverts[ptri->index_st[0]].t << SHIFT16XYZ; - pfv[1]->s = pstverts[ptri->index_st[1]].s << SHIFT16XYZ; - pfv[1]->t = pstverts[ptri->index_st[1]].t << SHIFT16XYZ; + pfv[1]->cv.s = pstverts[ptri->index_st[1]].s << SHIFT16XYZ; + pfv[1]->cv.t = pstverts[ptri->index_st[1]].t << SHIFT16XYZ; - pfv[2]->s = pstverts[ptri->index_st[2]].s << SHIFT16XYZ; - pfv[2]->t = pstverts[ptri->index_st[2]].t << SHIFT16XYZ; + pfv[2]->cv.s = pstverts[ptri->index_st[2]].s << SHIFT16XYZ; + pfv[2]->cv.t = pstverts[ptri->index_st[2]].t << SHIFT16XYZ; if ( ! (pfv[0]->flags | pfv[1]->flags | pfv[2]->flags) ) { @@ -289,14 +289,14 @@ R_AliasPreparePoints (const entity_t *currententity, finalvert_t *verts, const f continue; // completely clipped // insert s/t coordinates - pfv[0]->s = pstverts[ptri->index_st[0]].s << SHIFT16XYZ; - pfv[0]->t = pstverts[ptri->index_st[0]].t << SHIFT16XYZ; + pfv[0]->cv.s = pstverts[ptri->index_st[0]].s << SHIFT16XYZ; + pfv[0]->cv.t = pstverts[ptri->index_st[0]].t << SHIFT16XYZ; - pfv[1]->s = pstverts[ptri->index_st[1]].s << SHIFT16XYZ; - pfv[1]->t = pstverts[ptri->index_st[1]].t << SHIFT16XYZ; + pfv[1]->cv.s = pstverts[ptri->index_st[1]].s << SHIFT16XYZ; + pfv[1]->cv.t = pstverts[ptri->index_st[1]].t << SHIFT16XYZ; - pfv[2]->s = pstverts[ptri->index_st[2]].s << SHIFT16XYZ; - pfv[2]->t = pstverts[ptri->index_st[2]].t << SHIFT16XYZ; + pfv[2]->cv.s = pstverts[ptri->index_st[2]].s << SHIFT16XYZ; + pfv[2]->cv.t = pstverts[ptri->index_st[2]].t << SHIFT16XYZ; if ( ! (pfv[0]->flags | pfv[1]->flags | pfv[2]->flags) ) { @@ -399,7 +399,6 @@ R_AliasTransformFinalVerts(const entity_t *currententity, int numpoints, finalve for ( i = 0; i < numpoints; i++, fv++, oldv++, newv++ ) { - int temp; float lightcos; const float *plightnormal; vec3_t lerped_vert; @@ -426,19 +425,29 @@ R_AliasTransformFinalVerts(const entity_t *currententity, int numpoints, finalve // lighting lightcos = DotProduct (plightnormal, r_plightvec); - temp = r_ambientlight; if (lightcos < 0) { - temp += (int)(r_shadelight * lightcos); + int j; - // clamp; because we limited the minimum ambient and shading light, we - // don't have to clamp low light, just bright - if (temp < 0) - temp = 0; + for(j=0; j<3; j++) + { + int temp; + + temp = r_ambientlight[j]; + + temp += (r_shadelight[j] * lightcos); + + // clamp; because we limited the minimum ambient and shading light, we + // don't have to clamp low light, just bright + if (temp < 0) + temp = 0; + + fv->cv.l[j] = temp; + } } - - fv->l = temp; + else + memcpy(fv->cv.l, r_ambientlight, sizeof(light3_t)); if ( fv->xyz[2] < ALIAS_Z_CLIP_PLANE ) { @@ -469,18 +478,18 @@ R_AliasProjectAndClipTestFinalVert( finalvert_t *fv ) z = fv->xyz[2]; zi = 1.0 / z; - fv->zi = zi * s_ziscale; + fv->cv.zi = zi * s_ziscale; - fv->u = (x * aliasxscale * zi) + aliasxcenter; - fv->v = (y * aliasyscale * zi) + aliasycenter; + fv->cv.u = (x * aliasxscale * zi) + aliasxcenter; + fv->cv.v = (y * aliasyscale * zi) + aliasycenter; - if (fv->u < r_refdef.aliasvrect.x) + if (fv->cv.u < r_refdef.aliasvrect.x) fv->flags |= ALIAS_LEFT_CLIP; - if (fv->v < r_refdef.aliasvrect.y) + if (fv->cv.v < r_refdef.aliasvrect.y) fv->flags |= ALIAS_TOP_CLIP; - if (fv->u > r_refdef.aliasvrectright) + if (fv->cv.u > r_refdef.aliasvrectright) fv->flags |= ALIAS_RIGHT_CLIP; - if (fv->v > r_refdef.aliasvrectbottom) + if (fv->cv.v > r_refdef.aliasvrectbottom) fv->flags |= ALIAS_BOTTOM_CLIP; } @@ -534,10 +543,9 @@ R_AliasSetupLighting static void R_AliasSetupLighting(entity_t *currententity) { - alight_t lighting; - float lightvec[3] = {-1, 0, 0}; + const vec3_t lightvec = {-1, 0, 0}; vec3_t light; - int i, j; + int i; // all components of light should be identical in software if ( currententity->flags & RF_FULLBRIGHT ) @@ -578,39 +586,45 @@ R_AliasSetupLighting(entity_t *currententity) } } - j = (light[0] + light[1] + light[2]) * 0.3333 * 255; + if(r_colorlight->value < 2) + { + float temp = (light[0] + light[1] + light[2]) / 3.0; - lighting.ambientlight = j; - lighting.shadelight = j; + light[0] = light[1] = light[2] = temp; + } - lighting.plightvec = lightvec; + for(i=0; i<3; i++) + { + int j; - // clamp lighting so it doesn't overbright as much - if (lighting.ambientlight > 128) - lighting.ambientlight = 128; - if (lighting.ambientlight + lighting.shadelight > 192) - lighting.shadelight = 192 - lighting.ambientlight; + j = light[i] * 255; - // guarantee that no vertex will ever be lit below LIGHT_MIN, so we don't have - // to clamp off the bottom - r_ambientlight = lighting.ambientlight; + r_ambientlight[i] = j; + r_shadelight[i] = j; - if (r_ambientlight < LIGHT_MIN) - r_ambientlight = LIGHT_MIN; + // clamp lighting so it doesn't overbright as much + if (r_ambientlight[i] > 128) + r_ambientlight[i] = 128; + if (r_ambientlight[i] + r_shadelight[i] > 192) + r_shadelight[i] = 192 - r_ambientlight[i]; - r_ambientlight = (255 - r_ambientlight) << VID_CBITS; + // guarantee that no vertex will ever be lit below LIGHT_MIN, so we don't have + // to clamp off the bottom + if (r_ambientlight[i] < LIGHT_MIN) + r_ambientlight[i] = LIGHT_MIN; - r_shadelight = lighting.shadelight; + r_ambientlight[i] = (255 - r_ambientlight[i]) << VID_CBITS; - if (r_shadelight < 0) - r_shadelight = 0; + if (r_shadelight[i] < 0) + r_shadelight[i] = 0; - r_shadelight *= VID_GRADES; + r_shadelight[i] *= VID_GRADES; + } // rotate the lighting vector into the model's frame of reference - r_plightvec[0] = DotProduct( lighting.plightvec, s_alias_forward ); - r_plightvec[1] = -DotProduct( lighting.plightvec, s_alias_right ); - r_plightvec[2] = DotProduct( lighting.plightvec, s_alias_up ); + r_plightvec[0] = DotProduct( lightvec, s_alias_forward ); + r_plightvec[1] = -DotProduct( lightvec, s_alias_right ); + r_plightvec[2] = DotProduct( lightvec, s_alias_up ); } diff --git a/src/client/refresh/soft/sw_image.c b/src/client/refresh/soft/sw_image.c index 8e80f38c..3c37615d 100644 --- a/src/client/refresh/soft/sw_image.c +++ b/src/client/refresh/soft/sw_image.c @@ -215,11 +215,12 @@ R_LoadPic (char *name, byte *pic, int width, int realwidth, int height, int real size_t data_size, imagetype_t type) { image_t *image; - size_t i, size, full_size; + size_t size, full_size; size = width * height; - if (!pic || data_size <= 0 || width <= 0 || height <= 0 || size <= 0) + /* data_size/size are unsigned */ + if (!pic || data_size == 0 || width <= 0 || height <= 0 || size == 0) return NULL; image = R_FindFreeImage(); @@ -246,6 +247,8 @@ R_LoadPic (char *name, byte *pic, int width, int realwidth, int height, int real image->transparent = false; if (type != it_wall) { + size_t i; + for (i=0 ; iheight); ofs = LittleLong(mt->offsets[0]); - if ((ofs <= 0) || (width <= 0) || (height <= 0) || + /* width/height are unsigned */ + if ((ofs <= 0) || (width == 0) || (height == 0) || ((file_size - ofs) / width < height)) { R_Printf(PRINT_ALL, "%s: can't load %s, small body\n", __func__, name); @@ -323,7 +327,54 @@ R_LoadWal (char *name, imagetype_t type) return image; } -static unsigned char *d_16to8table = NULL; // 16 to 8 bit conversion table +static byte *d_16to8table = NULL; // 16 to 8 bit conversion table + +/* + * Apply color light to texture pixel + * + * TODO: -22% fps lost + */ +pixel_t +R_ApplyLight(pixel_t pix, const light3_t light) +{ + byte b_r, b_g, b_b; + int i_c; + light3_t light_masked; + + light_masked[0] = light[0] & LIGHTMASK; + light_masked[1] = light[1] & LIGHTMASK; + light_masked[2] = light[2] & LIGHTMASK; + + /* same light or colorlight == 0 */ + if (light_masked[0] == light_masked[1] && light_masked[0] == light_masked[2]) + return vid_colormap[pix + light_masked[0]]; + + /* full light, code could skip light processing */ + if ((light_masked[0] | light_masked[1] | light_masked[2]) <= vid_lightthreshold) + return pix; + + /* get color component for each component */ + b_r = d_8to24table[pix * 4 + 0]; + b_g = d_8to24table[pix * 4 + 1]; + b_b = d_8to24table[pix * 4 + 2]; + + /* scale by light */ + b_r = vid_lightmap[light_masked[0] + b_r]; + b_g = vid_lightmap[light_masked[1] + b_g]; + b_b = vid_lightmap[light_masked[2] + b_b]; + + /* + * convert back to indexed color (value reshifted >> 2) + * look to R_Convert32To8bit + */ + b_r = ( b_r >> 1 ); // & 31; + b_g = ( b_g >> 0 ); // & 63; + b_b = ( b_b >> 1 ); // & 31; + + i_c = b_r | ( b_g << 5 ) | ( b_b << 11 ); + + return d_16to8table[i_c & 0xFFFF]; +} static void R_Convert32To8bit(const unsigned char* pic_in, pixel_t* pic_out, size_t size) @@ -677,7 +728,7 @@ R_FindImage(char *name, imagetype_t type) } /* just return white image if show lighmap only */ - if (type == it_wall && r_lightmap->value) + if ((type == it_wall || type == it_skin) && r_lightmap->value) { return r_whitetexture_mip; } diff --git a/src/client/refresh/soft/sw_light.c b/src/client/refresh/soft/sw_light.c index 05e7f5ee..a6c2aa81 100644 --- a/src/client/refresh/soft/sw_light.c +++ b/src/client/refresh/soft/sw_light.c @@ -49,7 +49,7 @@ R_MarkLights (dlight_t *light, int bit, mnode_t *node, int r_dlightframecount) dist = DotProduct (light->origin, splitplane->normal) - splitplane->dist; i = light->intensity; - if( i< 0) + if (i < 0) i = -i; if (dist > i) // (dist > light->intensity) @@ -57,6 +57,7 @@ R_MarkLights (dlight_t *light, int bit, mnode_t *node, int r_dlightframecount) R_MarkLights (light, bit, node->children[0], r_dlightframecount); return; } + if (dist < -i) // (dist < -light->intensity) { R_MarkLights (light, bit, node->children[1], r_dlightframecount); @@ -107,12 +108,8 @@ LIGHT SAMPLING ============================================================================= */ - -static vec3_t pointcolor; -static vec3_t lightspot; - static int -RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end) +RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end, vec3_t pointcolor) { float front, back, frac; qboolean side; @@ -122,10 +119,7 @@ RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end) int s, t, ds, dt; int i; mtexinfo_t *tex; - byte *lightmap; - float *scales; int maps; - float samp; int r; if (node->contents != -1) @@ -140,7 +134,7 @@ RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end) side = front < 0; if ( (back < 0) == side) - return RecursiveLightPoint (node->children[side], start, end); + return RecursiveLightPoint (node->children[side], start, end, pointcolor); frac = front / (front-back); mid[0] = start[0] + (end[0] - start[0])*frac; @@ -150,16 +144,16 @@ RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end) mid[plane->type] = plane->dist; // go down front side - r = RecursiveLightPoint (node->children[side], start, mid); + r = RecursiveLightPoint (node->children[side], start, mid, pointcolor); if (r >= 0) return r; // hit something // check for impact on this node - VectorCopy (mid, lightspot); - surf = r_worldmodel->surfaces + node->firstsurface; for (i=0 ; inumsurfaces ; i++, surf++) { + byte *lightmap; + if (surf->flags&(SURF_DRAWTURB|SURF_DRAWSKY)) continue; // no lightmaps @@ -185,23 +179,35 @@ RecursiveLightPoint (mnode_t *node, vec3_t start, vec3_t end) lightmap = surf->samples; VectorCopy (vec3_origin, pointcolor); - lightmap += dt * ((surf->extents[0]>>4)+1) + ds; + + lightmap += 3 * (dt * ((surf->extents[0] >> 4) + 1) + ds); for (maps = 0 ; maps < MAXLIGHTMAPS && surf->styles[maps] != 255 ; maps++) { - samp = *lightmap * r_modulate->value * (1.0/255); // adjust for gl scale - scales = r_newrefdef.lightstyles[surf->styles[maps]].rgb; - VectorMA (pointcolor, samp, scales, pointcolor); - lightmap += ((surf->extents[0]>>4)+1) * - ((surf->extents[1]>>4)+1); + const float *rgb; + int j; + + rgb = r_newrefdef.lightstyles[surf->styles[maps]].rgb; + + /* Apply light level to models */ + for (j = 0; j < 3; j++) + { + float scale; + + scale = rgb[j] * r_modulate->value; + pointcolor[j] += lightmap[j] * scale * (1.0 / 255); + } + + lightmap += 3 * ((surf->extents[0] >> 4) + 1) * + ((surf->extents[1] >> 4) + 1); } return 1; } // go down back side - return RecursiveLightPoint (node->children[!side], mid, end); + return RecursiveLightPoint (node->children[!side], mid, end, pointcolor); } /* @@ -217,6 +223,7 @@ R_LightPoint (const entity_t *currententity, vec3_t p, vec3_t color) int lnum; dlight_t *dl; vec3_t dist; + vec3_t pointcolor; if (!r_worldmodel->lightdata) { @@ -228,7 +235,7 @@ R_LightPoint (const entity_t *currententity, vec3_t p, vec3_t color) end[1] = p[1]; end[2] = p[2] - 2048; - r = RecursiveLightPoint (r_worldmodel->nodes, p, end); + r = RecursiveLightPoint (r_worldmodel->nodes, p, end, pointcolor); if (r == -1) { @@ -274,36 +281,47 @@ R_AddDynamicLights (drawsurf_t* drawsurf) { msurface_t *surf; int lnum; - int sd, td; - float dist, rad, minlight; - vec3_t impact, local; - int s, t; - int i; int smax, tmax; mtexinfo_t *tex; - dlight_t *dl; - int negativeLight; surf = drawsurf->surf; smax = (surf->extents[0]>>4)+1; tmax = (surf->extents[1]>>4)+1; tex = surf->texinfo; - if (blocklight_max <= blocklights + smax*tmax) + if (blocklight_max <= blocklights + smax*tmax*3) { r_outoflights = true; return; } - for (lnum=0 ; lnumdlightbits & (1<intensity; + if(r_colorlight->value == 0) + { + for(i=0; i<3; i++) + color[i] = 256; + } + else + { + for(i=0; i<3; i++) + color[i] = 256 * dl->color[i]; + } + //===== negativeLight = 0; if(rad < 0) @@ -335,11 +353,15 @@ R_AddDynamicLights (drawsurf_t* drawsurf) for (t = 0 ; t>1); - //==== - if(!negativeLight) + for (i=0; i<3; i++) { - if (dist < minlight) - *plightdest += (rad - dist)*256; + //==== + if(!negativeLight) + { + if (dist < minlight) + *plightdest += (rad - dist) * color[i]; + + } + else + { + if (dist < minlight) + *plightdest -= (rad - dist) * color[i]; + if(*plightdest < minlight) + *plightdest = minlight; + } + //==== + plightdest ++; } - else - { - if (dist < minlight) - *plightdest -= (rad - dist)*256; - if(*plightdest < minlight) - *plightdest = minlight; - } - //==== - plightdest ++; } } } @@ -379,7 +405,7 @@ void R_BuildLightMap (drawsurf_t* drawsurf) { int smax, tmax; - int i, size; + int size; byte *lightmap; msurface_t *surf; @@ -387,22 +413,22 @@ R_BuildLightMap (drawsurf_t* drawsurf) smax = (surf->extents[0]>>4)+1; tmax = (surf->extents[1]>>4)+1; - size = smax*tmax; + size = smax*tmax*3; + if (blocklight_max <= blocklights + size) { r_outoflights = true; return; } - if (r_fullbright->value || !r_worldmodel->lightdata) - { - memset(blocklights, 0, size * sizeof(light_t)); - return; - } - // clear to no light memset(blocklights, 0, size * sizeof(light_t)); + if (r_fullbright->value || !r_worldmodel->lightdata) + { + return; + } + // add all the lightmaps lightmap = surf->samples; if (lightmap) @@ -413,11 +439,48 @@ R_BuildLightMap (drawsurf_t* drawsurf) maps++) { unsigned scale; + light_t *curr_light, *max_light; + + curr_light = blocklights; + max_light = blocklights + size; scale = drawsurf->lightadj[maps]; // 8.8 fraction - for (i=0 ; ivalue == 0) + { + do + { + light_t light; + + light = lightmap[0]; + if (light < lightmap[1]) + light = lightmap[1]; + if (light < lightmap[2]) + light = lightmap[2]; + + light *= scale; + + *curr_light += light; + curr_light++; + *curr_light += light; + curr_light++; + *curr_light += light; + curr_light++; + + lightmap += 3; /* skip to next lightmap */ + } + while(curr_light < max_light); + } + else + { + do + { + *curr_light += *lightmap * scale; + curr_light++; + lightmap ++; /* skip to next lightmap */ + } + while(curr_light < max_light); + } } } @@ -426,18 +489,28 @@ R_BuildLightMap (drawsurf_t* drawsurf) R_AddDynamicLights (drawsurf); // bound, invert, and shift - for (i=0 ; i> (8 - VID_CBITS); + curr_light = blocklights; + max_light = blocklights + size; - if (t < (1 << 6)) - t = (1 << 6); + do + { + int t; - blocklights[i] = t; + t = (int)*curr_light; + + if (t < 0) + t = 0; + t = (255*256 - t) >> (8 - VID_CBITS); + + if (t < (1 << 6)) + t = (1 << 6); + + *curr_light = t; + curr_light++; + } + while(curr_light < max_light); } } diff --git a/src/client/refresh/soft/sw_main.c b/src/client/refresh/soft/sw_main.c index cba0ffbb..1ce75dd3 100644 --- a/src/client/refresh/soft/sw_main.c +++ b/src/client/refresh/soft/sw_main.c @@ -40,6 +40,8 @@ static int swap_current = 0; espan_t *vid_polygon_spans = NULL; pixel_t *vid_colormap = NULL; pixel_t *vid_alphamap = NULL; +byte *vid_lightmap = NULL; +light_t vid_lightthreshold = 0; static int vid_minu, vid_minv, vid_maxu, vid_maxv; static int vid_zminu, vid_zminv, vid_zmaxu, vid_zmaxv; @@ -51,7 +53,7 @@ static qboolean palette_changed; refimport_t ri; -static unsigned d_8to24table[256]; +byte d_8to24table[256 * 4]; char skyname[MAX_QPATH]; vec3_t skyaxis; @@ -135,6 +137,7 @@ cvar_t *r_lefthand; cvar_t *r_gunfov; cvar_t *r_farsee; cvar_t *r_lightmap; +cvar_t *r_colorlight; static cvar_t *sw_aliasstats; cvar_t *sw_clearcolor; cvar_t *sw_drawflat; @@ -396,6 +399,7 @@ R_RegisterVariables (void) r_gunfov = ri.Cvar_Get( "r_gunfov", "80", CVAR_ARCHIVE ); r_farsee = ri.Cvar_Get("r_farsee", "0", CVAR_LATCH | CVAR_ARCHIVE); r_lightmap = ri.Cvar_Get("r_lightmap", "0", 0); + r_colorlight = ri.Cvar_Get("sw_colorlight", "0", CVAR_ARCHIVE); r_speeds = ri.Cvar_Get ("r_speeds", "0", 0); r_fullbright = ri.Cvar_Get ("r_fullbright", "0", 0); r_drawentities = ri.Cvar_Get ("r_drawentities", "1", 0); @@ -510,6 +514,14 @@ RE_Shutdown (void) free (vid_colormap); vid_colormap = NULL; } + + /* free lightmap */ + if (vid_lightmap) + { + free (vid_lightmap); + vid_lightmap = NULL; + } + R_UnRegister (); Mod_FreeAll (); R_ShutdownImages (); @@ -1230,7 +1242,7 @@ R_CalcPalette (void) if (modified) { // set back to default modified = false; - R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table ); + R_GammaCorrectAndSetPalette( d_8to24table ); return; } return; @@ -1246,7 +1258,7 @@ R_CalcPalette (void) one_minus_alpha = (1.0 - alpha); - in = (byte *)d_8to24table; + in = d_8to24table; out = palette[0]; for (i=0 ; i<256 ; i++, in+=4, out+=4) { @@ -1439,7 +1451,7 @@ R_InitGraphics( int width, int height ) R_InitCaches(); - R_GammaCorrectAndSetPalette((const unsigned char *)d_8to24table); + R_GammaCorrectAndSetPalette(d_8to24table); } static rserr_t SWimp_SetMode(int *pwidth, int *pheight, int mode, int fullscreen); @@ -1466,7 +1478,7 @@ RE_BeginFrame( float camera_separation ) if ( vid_gamma->modified || sw_overbrightbits->modified ) { Draw_BuildGammaTable(); - R_GammaCorrectAndSetPalette((const unsigned char * )d_8to24table); + R_GammaCorrectAndSetPalette(d_8to24table); // we need redraw everything VID_WholeDamageBuffer(); // and backbuffer should be zeroed @@ -1602,7 +1614,7 @@ RE_SetPalette(const unsigned char *palette) } else { - R_GammaCorrectAndSetPalette((const unsigned char *)d_8to24table); + R_GammaCorrectAndSetPalette(d_8to24table); } } @@ -1752,14 +1764,16 @@ Draw_GetPalette (void) { byte *pal, *out; int i; + int white = 0; - // get the palette and colormap + + /* get the palette and colormap */ LoadPCX ("pics/colormap.pcx", &vid_colormap, &pal, NULL, NULL); if (!vid_colormap) ri.Sys_Error (ERR_FATAL, "Couldn't load pics/colormap.pcx"); vid_alphamap = vid_colormap + 64*256; - out = (byte *)d_8to24table; + out = d_8to24table; for (i=0 ; i<256 ; i++, out+=4) { int r, g, b; @@ -1771,9 +1785,34 @@ Draw_GetPalette (void) out[0] = r; out[1] = g; out[2] = b; + + if (r == 255 && g == 255 && b == 255) + white = i; } free (pal); + + R_Printf(PRINT_ALL,"white color in palete: %d\n", white); + + /* generate lightmap */ + vid_lightmap = malloc(64 * 256 * sizeof(byte)); + for (i=0; i < 64; i++) + { + int j, scale; + + scale = ( + d_8to24table[vid_colormap[i * 256 + white] * 4 + 0] + + d_8to24table[vid_colormap[i * 256 + white] * 4 + 1] + + d_8to24table[vid_colormap[i * 256 + white] * 4 + 2] + ) / 3; + + /* full light distance maximum */ + if (scale == 255) + vid_lightthreshold = i * 256; + + for(j=0; j < 256; j++) + vid_lightmap[i * 256 + j] = ((j * scale / 255) >> 2) & 63; + } } /* @@ -2409,7 +2448,7 @@ SWimp_CreateRender(int width, int height) memset(sw_state.currentpalette, 0, sizeof(sw_state.currentpalette)); - R_GammaCorrectAndSetPalette( ( const unsigned char * ) d_8to24table ); + R_GammaCorrectAndSetPalette( d_8to24table ); } // this is only here so the functions in q_shared.c and q_shwin.c can link diff --git a/src/client/refresh/soft/sw_model.c b/src/client/refresh/soft/sw_model.c index c5fc8be9..917d3e47 100644 --- a/src/client/refresh/soft/sw_model.c +++ b/src/client/refresh/soft/sw_model.c @@ -257,8 +257,7 @@ by taking the brightest component static void Mod_LoadLighting (model_t *loadmodel, byte *mod_base, lump_t *l) { - int i, size; - pixel_t *in; + int size; if (!l->filelen) { @@ -266,18 +265,9 @@ Mod_LoadLighting (model_t *loadmodel, byte *mod_base, lump_t *l) return; } - size = l->filelen/3; + size = l->filelen; loadmodel->lightdata = Hunk_Alloc(size); - in = mod_base + l->fileofs; - for (i=0 ; i in[1] && in[0] > in[2]) - loadmodel->lightdata[i] = in[0]; - else if (in[1] > in[0] && in[1] > in[2]) - loadmodel->lightdata[i] = in[1]; - else - loadmodel->lightdata[i] = in[2]; - } + memcpy(loadmodel->lightdata, mod_base + l->fileofs, size); } @@ -665,9 +655,13 @@ Mod_LoadFaces (model_t *loadmodel, byte *mod_base, lump_t *l) out->styles[i] = in->styles[i]; i = LittleLong(in->lightofs); if (i == -1) + { out->samples = NULL; + } else - out->samples = loadmodel->lightdata + i/3; + { + out->samples = loadmodel->lightdata + i; + } // set the drawing flags flag @@ -1012,8 +1006,9 @@ Mod_LoadBrushModel(model_t *mod, void *buffer, int modfilelen) // lighting is a special case, because we keep only 1 byte out of 3 // (=> no colored lighting in soft renderer by default) { - int size = header->lumps[LUMP_LIGHTING].filelen/3; + int size = header->lumps[LUMP_LIGHTING].filelen; size = (size + 31) & ~31; + /* save color data */ hunkSize += size; } diff --git a/src/client/refresh/soft/sw_polyset.c b/src/client/refresh/soft/sw_polyset.c index 66c07f51..0f77c7da 100644 --- a/src/client/refresh/soft/sw_polyset.c +++ b/src/client/refresh/soft/sw_polyset.c @@ -26,41 +26,42 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. typedef struct { int isflattop; int numleftedges; - int *pleftedgevert0; - int *pleftedgevert1; - int *pleftedgevert2; + compactvert_t *pleftedgevert0; + compactvert_t *pleftedgevert1; + compactvert_t *pleftedgevert2; int numrightedges; - int *prightedgevert0; - int *prightedgevert1; - int *prightedgevert2; + compactvert_t *prightedgevert0; + compactvert_t *prightedgevert1; + compactvert_t *prightedgevert2; } edgetable; static int ubasestep, errorterm, erroradjustup, erroradjustdown; -static int r_p0[6], r_p1[6], r_p2[6]; +static compactvert_t r_p0, r_p1, r_p2; static int d_xdenom; static edgetable *pedgetable; static edgetable edgetables[12] = { - {0, 1, r_p0, r_p2, NULL, 2, r_p0, r_p1, r_p2}, - {0, 2, r_p1, r_p0, r_p2, 1, r_p1, r_p2, NULL}, - {1, 1, r_p0, r_p2, NULL, 1, r_p1, r_p2, NULL}, - {0, 1, r_p1, r_p0, NULL, 2, r_p1, r_p2, r_p0}, - {0, 2, r_p0, r_p2, r_p1, 1, r_p0, r_p1, NULL}, - {0, 1, r_p2, r_p1, NULL, 1, r_p2, r_p0, NULL}, - {0, 1, r_p2, r_p1, NULL, 2, r_p2, r_p0, r_p1}, - {0, 2, r_p2, r_p1, r_p0, 1, r_p2, r_p0, NULL}, - {0, 1, r_p1, r_p0, NULL, 1, r_p1, r_p2, NULL}, - {1, 1, r_p2, r_p1, NULL, 1, r_p0, r_p1, NULL}, - {1, 1, r_p1, r_p0, NULL, 1, r_p2, r_p0, NULL}, - {0, 1, r_p0, r_p2, NULL, 1, r_p0, r_p1, NULL}, + {0, 1, &r_p0, &r_p2, NULL, 2, &r_p0, &r_p1, &r_p2}, + {0, 2, &r_p1, &r_p0, &r_p2, 1, &r_p1, &r_p2, NULL}, + {1, 1, &r_p0, &r_p2, NULL, 1, &r_p1, &r_p2, NULL}, + {0, 1, &r_p1, &r_p0, NULL, 2, &r_p1, &r_p2, &r_p0}, + {0, 2, &r_p0, &r_p2, &r_p1, 1, &r_p0, &r_p1, NULL}, + {0, 1, &r_p2, &r_p1, NULL, 1, &r_p2, &r_p0, NULL}, + {0, 1, &r_p2, &r_p1, NULL, 2, &r_p2, &r_p0, &r_p1}, + {0, 2, &r_p2, &r_p1, &r_p0, 1, &r_p2, &r_p0, NULL}, + {0, 1, &r_p1, &r_p0, NULL, 1, &r_p1, &r_p2, NULL}, + {1, 1, &r_p2, &r_p1, NULL, 1, &r_p0, &r_p1, NULL}, + {1, 1, &r_p1, &r_p0, NULL, 1, &r_p2, &r_p0, NULL}, + {0, 1, &r_p0, &r_p2, NULL, 1, &r_p0, &r_p1, NULL}, }; // FIXME: some of these can become statics -static int a_sstepxfrac, a_tstepxfrac, r_lstepx, a_ststepxwhole; -static int r_sstepx, r_tstepx, r_lstepy, r_sstepy, r_tstepy; +static int a_sstepxfrac, a_tstepxfrac, a_ststepxwhole; +static int r_sstepx, r_tstepx, r_sstepy, r_tstepy; +static light3_t r_lstepx, r_lstepy; static zvalue_t r_zistepx, r_zistepy; static int d_aspancount; @@ -68,11 +69,12 @@ static spanpackage_t *d_pedgespanpackage; spanpackage_t *triangle_spans, *triangles_max; -static int d_sfrac, d_tfrac, d_light; +static int d_sfrac, d_tfrac; +static light3_t d_light; static zvalue_t d_zi; static int d_ptexextrastep, d_sfracextrastep; -static int d_tfracextrastep, d_lightextrastep; -static int d_lightbasestep, d_ptexbasestep; +static int d_tfracextrastep, d_ptexbasestep; +static light3_t d_lightbasestep, d_lightextrastep; static int d_sfracbasestep, d_tfracbasestep; static zvalue_t d_ziextrastep, d_zibasestep; @@ -169,14 +171,14 @@ R_DrawTriangle(const entity_t *currententity, const finalvert_t *a, const finalv ( a->v[0] - b->v[0] ) * ( a->v[1] - c->v[1] ); */ - dv0_ab = a->u - b->u; - dv1_ab = a->v - b->v; + dv0_ab = a->cv.u - b->cv.u; + dv1_ab = a->cv.v - b->cv.v; if ( !( dv0_ab | dv1_ab ) ) return; - dv0_ac = a->u - c->u; - dv1_ac = a->v - c->v; + dv0_ac = a->cv.u - c->cv.u; + dv1_ac = a->cv.v - c->cv.v; if ( !( dv0_ac | dv1_ac ) ) return; @@ -185,26 +187,9 @@ R_DrawTriangle(const entity_t *currententity, const finalvert_t *a, const finalv if ( d_xdenom < 0 ) { - r_p0[0] = a->u; // u - r_p0[1] = a->v; // v - r_p0[2] = a->s; // s - r_p0[3] = a->t; // t - r_p0[4] = a->l; // light - r_p0[5] = a->zi; // iz - - r_p1[0] = b->u; - r_p1[1] = b->v; - r_p1[2] = b->s; - r_p1[3] = b->t; - r_p1[4] = b->l; - r_p1[5] = b->zi; - - r_p2[0] = c->u; - r_p2[1] = c->v; - r_p2[2] = c->s; - r_p2[3] = c->t; - r_p2[4] = c->l; - r_p2[5] = c->zi; + memcpy(&r_p0, &a->cv, sizeof(compactvert_t)); + memcpy(&r_p1, &b->cv, sizeof(compactvert_t)); + memcpy(&r_p2, &c->cv, sizeof(compactvert_t)); R_PolysetSetEdgeTable (); R_RasterizeAliasPolySmooth(currententity); @@ -213,7 +198,7 @@ R_DrawTriangle(const entity_t *currententity, const finalvert_t *a, const finalv static void R_PushEdgesSpan(int u, int v, int count, - pixel_t* d_ptex, int d_sfrac, int d_tfrac, int d_light, zvalue_t d_zi) + pixel_t* d_ptex, int d_sfrac, int d_tfrac, light3_t d_light, zvalue_t d_zi) { if (d_pedgespanpackage >= triangles_max) { @@ -231,7 +216,7 @@ R_PushEdgesSpan(int u, int v, int count, d_pedgespanpackage->tfrac = d_tfrac; // FIXME: need to clamp l, s, t, at both ends? - d_pedgespanpackage->light = d_light; + memcpy(d_pedgespanpackage->light, d_light, sizeof(light3_t)); d_pedgespanpackage->zi = d_zi; d_pedgespanpackage++; @@ -257,6 +242,8 @@ R_PolysetScanLeftEdge_C(int height, pixel_t *d_ptex, int u, int v) errorterm += erroradjustup; if (errorterm >= 0) { + int i; + // addtional step for compensate error u ++; d_aspancount ++; @@ -272,12 +259,17 @@ R_PolysetScanLeftEdge_C(int height, pixel_t *d_ptex, int u, int v) d_ptex += r_affinetridesc.skinwidth; d_tfrac &= 0xFFFF; } - d_light += d_lightextrastep; + + for(i=0; i<3; i++) + d_light[i] += d_lightextrastep[i]; + d_zi += d_ziextrastep; errorterm -= erroradjustdown; } else { + int i; + d_ptex += d_ptexbasestep; d_sfrac += d_sfracbasestep; d_ptex += d_sfrac >> SHIFT16XYZ; @@ -288,7 +280,10 @@ R_PolysetScanLeftEdge_C(int height, pixel_t *d_ptex, int u, int v) d_ptex += r_affinetridesc.skinwidth; d_tfrac &= 0xFFFF; } - d_light += d_lightbasestep; + + for(i=0; i<3; i++) + d_light[i] += d_lightbasestep[i]; + d_zi += d_zibasestep; } } while (--height); @@ -371,11 +366,12 @@ R_PolysetCalcGradients (int skinwidth) { float xstepdenominv, ystepdenominv, t0, t1; float p01_minus_p21, p11_minus_p21, p00_minus_p20, p10_minus_p20; + int i; - p00_minus_p20 = r_p0[0] - r_p2[0]; - p01_minus_p21 = r_p0[1] - r_p2[1]; - p10_minus_p20 = r_p1[0] - r_p2[0]; - p11_minus_p21 = r_p1[1] - r_p2[1]; + p00_minus_p20 = r_p0.u - r_p2.u; + p01_minus_p21 = r_p0.v - r_p2.v; + p10_minus_p20 = r_p1.u - r_p2.u; + p11_minus_p21 = r_p1.v - r_p2.v; xstepdenominv = 1.0 / (float)d_xdenom; @@ -384,29 +380,32 @@ R_PolysetCalcGradients (int skinwidth) // ceil () for light so positive steps are exaggerated, negative steps // diminished, pushing us away from underflow toward overflow. Underflow is // very visible, overflow is very unlikely, because of ambient lighting - t0 = r_p0[4] - r_p2[4]; - t1 = r_p1[4] - r_p2[4]; - r_lstepx = (int) - ceil((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv); - r_lstepy = (int) - ceil((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv); + for (i=0; i<3; i++) + { + t0 = r_p0.l[i] - r_p2.l[i]; + t1 = r_p1.l[i] - r_p2.l[i]; + r_lstepx[i] = (int) + ceil((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv); + r_lstepy[i] = (int) + ceil((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv); + } - t0 = r_p0[2] - r_p2[2]; - t1 = r_p1[2] - r_p2[2]; + t0 = r_p0.s - r_p2.s; + t1 = r_p1.s - r_p2.s; r_sstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv); r_sstepy = (int)((t1 * p00_minus_p20 - t0* p10_minus_p20) * ystepdenominv); - t0 = r_p0[3] - r_p2[3]; - t1 = r_p1[3] - r_p2[3]; + t0 = r_p0.t - r_p2.t; + t1 = r_p1.t - r_p2.t; r_tstepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv); r_tstepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) * ystepdenominv); - t0 = r_p0[5] - r_p2[5]; - t1 = r_p1[5] - r_p2[5]; + t0 = r_p0.zi - r_p2.zi; + t1 = r_p1.zi - r_p2.zi; r_zistepx = (int)((t1 * p01_minus_p21 - t0 * p11_minus_p21) * xstepdenominv); r_zistepy = (int)((t1 * p00_minus_p20 - t0 * p10_minus_p20) * @@ -432,7 +431,7 @@ R_PolysetDrawSpans8_33(const entity_t *currententity, spanpackage_t *pspanpackag pixel_t *lpdest; pixel_t *lptex; int lsfrac, ltfrac; - int llight; + light3_t llight; zvalue_t lzi; zvalue_t *lpz; @@ -461,21 +460,24 @@ R_PolysetDrawSpans8_33(const entity_t *currententity, spanpackage_t *pspanpackag lptex = pspanpackage->ptex; lsfrac = pspanpackage->sfrac; ltfrac = pspanpackage->tfrac; - llight = pspanpackage->light; + memcpy(llight, pspanpackage->light, sizeof(light3_t)); lzi = pspanpackage->zi; do { + int i; + if ((lzi >> SHIFT16XYZ) >= *lpz) { - int temp = vid_colormap[*lptex + ( llight & 0xFF00 )]; + int temp = R_ApplyLight(*lptex, llight); *lpdest = vid_alphamap[temp + *lpdest*256]; } lpdest++; lzi += r_zistepx; lpz++; - llight += r_lstepx; + for(i=0; i<3; i++) + llight[i] += r_lstepx[i]; lptex += a_ststepxwhole; lsfrac += a_sstepxfrac; lptex += lsfrac >> SHIFT16XYZ; @@ -546,7 +548,7 @@ R_PolysetDrawSpans8_66(const entity_t *currententity, spanpackage_t *pspanpackag pixel_t *lpdest; pixel_t *lptex; int lsfrac, ltfrac; - int llight; + light3_t llight; zvalue_t lzi; zvalue_t *lpz; @@ -576,14 +578,16 @@ R_PolysetDrawSpans8_66(const entity_t *currententity, spanpackage_t *pspanpackag lptex = pspanpackage->ptex; lsfrac = pspanpackage->sfrac; ltfrac = pspanpackage->tfrac; - llight = pspanpackage->light; + memcpy(llight, pspanpackage->light, sizeof(light3_t)); lzi = pspanpackage->zi; do { + int i; + if ((lzi >> SHIFT16XYZ) >= *lpz) { - int temp = vid_colormap[*lptex + ( llight & 0xFF00 )]; + int temp = R_ApplyLight(*lptex, llight); *lpdest = vid_alphamap[temp*256 + *lpdest]; *lpz = lzi >> SHIFT16XYZ; @@ -592,7 +596,8 @@ R_PolysetDrawSpans8_66(const entity_t *currententity, spanpackage_t *pspanpackag lpdest++; lzi += r_zistepx; lpz++; - llight += r_lstepx; + for(i=0; i<3; i++) + llight[i] += r_lstepx[i]; lptex += a_ststepxwhole; lsfrac += a_sstepxfrac; lptex += lsfrac >> SHIFT16XYZ; @@ -700,7 +705,7 @@ R_PolysetDrawSpans8_Opaque (const entity_t *currententity, spanpackage_t *pspanp int lsfrac, ltfrac; pixel_t *lpdest; pixel_t *lptex; - int llight; + light3_t llight; zvalue_t lzi; zvalue_t *lpz; int pos_shift = (pspanpackage->v * vid_buffer_width) + pspanpackage->u; @@ -712,28 +717,28 @@ R_PolysetDrawSpans8_Opaque (const entity_t *currententity, spanpackage_t *pspanp lptex = pspanpackage->ptex; lsfrac = pspanpackage->sfrac; ltfrac = pspanpackage->tfrac; - llight = pspanpackage->light; + memcpy(llight, pspanpackage->light, sizeof(light3_t)); lzi = pspanpackage->zi; do { + int i; + if ((lzi >> SHIFT16XYZ) >= *lpz) { - int color_value; - if(r_newrefdef.rdflags & RDF_IRGOGGLES && currententity->flags & RF_IR_VISIBLE) - color_value = irtable[*lptex]; + *lpdest = vid_colormap[irtable[*lptex]]; else - color_value = *lptex + (llight & 0xFF00); + *lpdest = R_ApplyLight(*lptex, llight); - *lpdest = vid_colormap[color_value]; *lpz = lzi >> SHIFT16XYZ; zdamaged = true; } lpdest++; lzi += r_zistepx; lpz++; - llight += r_lstepx; + for(i=0; i<3; i++) + llight[i] += r_lstepx[i]; lptex += a_ststepxwhole; lsfrac += a_sstepxfrac; lptex += lsfrac >> SHIFT16XYZ; @@ -769,8 +774,9 @@ static void R_RasterizeAliasPolySmooth(const entity_t *currententity) { int initialleftheight, initialrightheight; - int *plefttop, *prighttop, *pleftbottom, *prightbottom; - int working_lstepx, originalcount; + compactvert_t *plefttop, *prighttop, *pleftbottom, *prightbottom; + light3_t working_lstepx; + int originalcount; int u, v; pixel_t *d_ptex; @@ -780,8 +786,8 @@ R_RasterizeAliasPolySmooth(const entity_t *currententity) pleftbottom = pedgetable->pleftedgevert1; prightbottom = pedgetable->prightedgevert1; - initialleftheight = pleftbottom[1] - plefttop[1]; - initialrightheight = prightbottom[1] - prighttop[1]; + initialleftheight = pleftbottom->v - plefttop->v; + initialrightheight = prightbottom->v - prighttop->v; // // set the s, t, and light gradients, which are consistent across the triangle @@ -797,18 +803,18 @@ R_RasterizeAliasPolySmooth(const entity_t *currententity) // d_pedgespanpackage = triangle_spans; - u = plefttop[0]; - v = plefttop[1]; - d_aspancount = plefttop[0] - prighttop[0]; + u = plefttop->u; + v = plefttop->v; + d_aspancount = plefttop->u - prighttop->u; - d_ptex = r_affinetridesc.pskin + (plefttop[2] >> SHIFT16XYZ) + - (plefttop[3] >> SHIFT16XYZ) * r_affinetridesc.skinwidth; + d_ptex = r_affinetridesc.pskin + (plefttop->s >> SHIFT16XYZ) + + (plefttop->t >> SHIFT16XYZ) * r_affinetridesc.skinwidth; { - d_sfrac = plefttop[2] & 0xFFFF; - d_tfrac = plefttop[3] & 0xFFFF; + d_sfrac = plefttop->s & 0xFFFF; + d_tfrac = plefttop->t & 0xFFFF; } - d_light = plefttop[4]; - d_zi = plefttop[5]; + memcpy(d_light, plefttop->l, sizeof(light3_t)); + d_zi = plefttop->zi; if (initialleftheight == 1) { @@ -817,8 +823,10 @@ R_RasterizeAliasPolySmooth(const entity_t *currententity) } else { - R_PolysetSetUpForLineScan(plefttop[0], plefttop[1], - pleftbottom[0], pleftbottom[1]); + int i; + + R_PolysetSetUpForLineScan(plefttop->u, plefttop->v, + pleftbottom->u, pleftbottom->v); // TODO: can reuse partial expressions here @@ -826,9 +834,12 @@ R_RasterizeAliasPolySmooth(const entity_t *currententity) // underflow (sort of turning the floor () we did in the gradient calcs into // ceil (), but plus a little bit) if (ubasestep < 0) - working_lstepx = r_lstepx - 1; + { + for(i=0; i<3; i++) + working_lstepx[i] = r_lstepx[i] - 1; + } else - working_lstepx = r_lstepx; + memcpy(working_lstepx, r_lstepx, sizeof(light3_t)); d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> SHIFT16XYZ) + ((r_tstepy + r_tstepx * ubasestep) >> SHIFT16XYZ) * @@ -837,7 +848,9 @@ R_RasterizeAliasPolySmooth(const entity_t *currententity) d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF; d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF; - d_lightbasestep = r_lstepy + working_lstepx * ubasestep; + for(i=0; i<3; i++) + d_lightbasestep[i] = r_lstepy[i] + working_lstepx[i] * ubasestep; + d_zibasestep = r_zistepy + r_zistepx * ubasestep; d_ptexextrastep = ((r_sstepy + r_sstepx * (ubasestep + 1)) >> SHIFT16XYZ) + @@ -847,7 +860,9 @@ R_RasterizeAliasPolySmooth(const entity_t *currententity) d_sfracextrastep = (r_sstepy + r_sstepx*(ubasestep + 1)) & 0xFFFF; d_tfracextrastep = (r_tstepy + r_tstepx*(ubasestep + 1)) & 0xFFFF; - d_lightextrastep = d_lightbasestep + working_lstepx; + for(i=0; i<3; i++) + d_lightextrastep[i] = d_lightbasestep[i] + working_lstepx[i]; + d_ziextrastep = d_zibasestep + r_zistepx; R_PolysetScanLeftEdge_C(initialleftheight, d_ptex, u, v); @@ -863,18 +878,18 @@ R_RasterizeAliasPolySmooth(const entity_t *currententity) plefttop = pleftbottom; pleftbottom = pedgetable->pleftedgevert2; - height = pleftbottom[1] - plefttop[1]; + height = pleftbottom->v - plefttop->v; // TODO: make this a function; modularize this function in general - u = plefttop[0]; - v = plefttop[1]; - d_aspancount = plefttop[0] - prighttop[0]; - d_ptex = r_affinetridesc.pskin + (plefttop[2] >> SHIFT16XYZ) + - (plefttop[3] >> SHIFT16XYZ) * r_affinetridesc.skinwidth; + u = plefttop->u; + v = plefttop->v; + d_aspancount = plefttop->u - prighttop->u; + d_ptex = r_affinetridesc.pskin + (plefttop->s >> SHIFT16XYZ) + + (plefttop->t >> SHIFT16XYZ) * r_affinetridesc.skinwidth; d_sfrac = 0; d_tfrac = 0; - d_light = plefttop[4]; - d_zi = plefttop[5]; + memcpy(d_light, plefttop->l, sizeof(light3_t)); + d_zi = plefttop->zi; if (height == 1) { @@ -883,13 +898,18 @@ R_RasterizeAliasPolySmooth(const entity_t *currententity) } else { - R_PolysetSetUpForLineScan(plefttop[0], plefttop[1], - pleftbottom[0], pleftbottom[1]); + int i; + + R_PolysetSetUpForLineScan(plefttop->u, plefttop->v, + pleftbottom->u, pleftbottom->v); if (ubasestep < 0) - working_lstepx = r_lstepx - 1; + { + for(i=0; i<3; i++) + working_lstepx[i] = r_lstepx[i] - 1; + } else - working_lstepx = r_lstepx; + memcpy(working_lstepx, r_lstepx, sizeof(light3_t)); d_ptexbasestep = ((r_sstepy + r_sstepx * ubasestep) >> SHIFT16XYZ) + ((r_tstepy + r_tstepx * ubasestep) >> SHIFT16XYZ) * @@ -898,7 +918,9 @@ R_RasterizeAliasPolySmooth(const entity_t *currententity) d_sfracbasestep = (r_sstepy + r_sstepx * ubasestep) & 0xFFFF; d_tfracbasestep = (r_tstepy + r_tstepx * ubasestep) & 0xFFFF; - d_lightbasestep = r_lstepy + working_lstepx * ubasestep; + for(i=0; i<3; i++) + d_lightbasestep[i] = r_lstepy[i] + working_lstepx[i] * ubasestep; + d_zibasestep = r_zistepy + r_zistepx * ubasestep; d_ptexextrastep = ((r_sstepy + r_sstepx * (ubasestep + 1)) >> SHIFT16XYZ) + @@ -908,7 +930,8 @@ R_RasterizeAliasPolySmooth(const entity_t *currententity) d_sfracextrastep = (r_sstepy+r_sstepx*(ubasestep + 1)) & 0xFFFF; d_tfracextrastep = (r_tstepy+r_tstepx*(ubasestep + 1)) & 0xFFFF; - d_lightextrastep = d_lightbasestep + working_lstepx; + for(i=0; i<3; i++) + d_lightextrastep[i] = d_lightbasestep[i] + working_lstepx[i]; d_ziextrastep = d_zibasestep + r_zistepx; R_PolysetScanLeftEdge_C(height, d_ptex, u, v); @@ -917,8 +940,8 @@ R_RasterizeAliasPolySmooth(const entity_t *currententity) // scan out the top (and possibly only) part of the right edge, updating the // count field - R_PolysetSetUpForLineScan(prighttop[0], prighttop[1], - prightbottom[0], prightbottom[1]); + R_PolysetSetUpForLineScan(prighttop->u, prighttop->v, + prightbottom->u, prightbottom->v); d_aspancount = 0; if ((triangle_spans + initialrightheight) >= triangles_max) { @@ -939,15 +962,15 @@ R_RasterizeAliasPolySmooth(const entity_t *currententity) pstart = triangle_spans + initialrightheight; pstart->count = originalcount; - d_aspancount = prightbottom[0] - prighttop[0]; + d_aspancount = prightbottom->u - prighttop->u; prighttop = prightbottom; prightbottom = pedgetable->prightedgevert2; - height = prightbottom[1] - prighttop[1]; + height = prightbottom->v - prighttop->v; - R_PolysetSetUpForLineScan(prighttop[0], prighttop[1], - prightbottom[0], prightbottom[1]); + R_PolysetSetUpForLineScan(prighttop->u, prighttop->v, + prightbottom->u, prightbottom->v); if ((triangle_spans + initialrightheight + height) >= triangles_max) { @@ -978,11 +1001,11 @@ R_PolysetSetEdgeTable (void) // determine which edges are right & left, and the order in which // to rasterize them // - if (r_p0[1] >= r_p1[1]) + if (r_p0.v >= r_p1.v) { - if (r_p0[1] == r_p1[1]) + if (r_p0.v == r_p1.v) { - if (r_p0[1] < r_p2[1]) + if (r_p0.v < r_p2.v) pedgetable = &edgetables[2]; else pedgetable = &edgetables[5]; @@ -995,7 +1018,7 @@ R_PolysetSetEdgeTable (void) } } - if (r_p0[1] == r_p2[1]) + if (r_p0.v == r_p2.v) { if (edgetableindex) pedgetable = &edgetables[8]; @@ -1004,7 +1027,7 @@ R_PolysetSetEdgeTable (void) return; } - else if (r_p1[1] == r_p2[1]) + else if (r_p1.v == r_p2.v) { if (edgetableindex) pedgetable = &edgetables[10]; @@ -1014,10 +1037,10 @@ R_PolysetSetEdgeTable (void) return; } - if (r_p0[1] > r_p2[1]) + if (r_p0.v > r_p2.v) edgetableindex += 2; - if (r_p1[1] > r_p2[1]) + if (r_p1.v > r_p2.v) edgetableindex += 4; pedgetable = &edgetables[edgetableindex]; diff --git a/src/client/refresh/soft/sw_surf.c b/src/client/refresh/soft/sw_surf.c index 16085e4b..c86340de 100644 --- a/src/client/refresh/soft/sw_surf.c +++ b/src/client/refresh/soft/sw_surf.c @@ -64,6 +64,24 @@ R_TextureAnimation (const entity_t *currententity, mtexinfo_t *tex) return tex->image; } +/* + * Light apply is not required + */ +static qboolean +R_SameLight(size_t size, const light3_t lightstep, const light3_t light) +{ + int i; + + if (((light[0] | light[1] | light[2]) & LIGHTMASK) > vid_lightthreshold) + return false; + + for (i=0; i<3; i++) + { + if (((size * lightstep[i] + light[i]) & LIGHTMASK) > vid_lightthreshold) + return false; + } + return true; +} /* ================ @@ -73,8 +91,8 @@ R_DrawSurfaceBlock8_anymip static void R_DrawSurfaceBlock8_anymip (int level, int surfrowbytes) { - int v, i, b, lightstep, lighttemp, light, size; - unsigned char pix, *psource, *prowdest; + int v, i, size; + unsigned char *psource, *prowdest; size = 1 << level; psource = pbasesource; @@ -82,34 +100,62 @@ R_DrawSurfaceBlock8_anymip (int level, int surfrowbytes) for (v=0 ; v> level; - lightrightstep = (r_lightptr[1] - lightright) >> level; + memcpy(lightleft, r_lightptr, sizeof(light3_t)); + memcpy(lightright, r_lightptr + 3, sizeof(light3_t)); + r_lightptr += r_lightwidth * 3; + for(i=0; i<3; i++) + { + lightleftstep[i] = (r_lightptr[i] - lightleft[i]) >> level; + lightrightstep[i] = (r_lightptr[i + 3] - lightright[i]) >> level; + } for (i=0 ; i> level; + light3_t lightstep, light; + int j; - light = lightright; - - for (b=(size-1); b>=0; b--) + for(j=0; j<3; j++) { - pix = psource[b]; - prowdest[b] = ((unsigned char *)vid_colormap) - [(light & 0xFF00) + pix]; - light += lightstep; + int lighttemp; + + lighttemp = lightleft[j] - lightright[j]; + lightstep[j] = lighttemp >> level; + } + + memcpy(light, lightright, sizeof(light3_t)); + + if (R_SameLight(size, lightstep, light)) + { + /* just copy without light apply */ + memcpy(prowdest, psource, size * sizeof(pixel_t)); + } + else + { + int b; + + for (b=(size-1); b>=0; b--) + { + pixel_t pix; + pix = psource[b]; + prowdest[b] = R_ApplyLight(pix, light); + + for(j=0; j<3; j++) + light[j] += lightstep[j]; + } } psource += sourcetstep; - lightright += lightrightstep; - lightleft += lightleftstep; + + for(j=0; j<3; j++) + { + lightright[j] += lightrightstep[j]; + lightleft[j] += lightleftstep[j]; + } + prowdest += surfrowbytes; } @@ -176,7 +222,7 @@ R_DrawSurface (drawsurf_t *drawsurf) for (u=0 ; u= blocklight_max) { diff --git a/src/common/header/shared.h b/src/common/header/shared.h index 23e4af26..8d3b12b1 100644 --- a/src/common/header/shared.h +++ b/src/common/header/shared.h @@ -65,7 +65,7 @@ typedef unsigned char byte; // must be used as prefix (YQ2_ATTR_NORETURN void bla();)! #define YQ2_ATTR_NORETURN __attribute__ ((noreturn)) #elif defined(_MSC_VER) - // Note: We prefer VS2019 16.8 or newer in C11 mode (/std:c11), + // Note: We prefer VS2019 16.8 or newer in C11 mode (/std:c11), // then the __STDC_VERSION__ >= 201112L case above is used #define YQ2_ALIGNAS_SIZE(SIZE) __declspec(align(SIZE)) @@ -148,7 +148,7 @@ typedef unsigned char byte; #ifdef _MSC_VER #define PRINTF_ATTR(FMT, VARGS) #else // at least GCC/mingw and clang support this - #define PRINTF_ATTR(FMT, VARGS) __attribute__((format(printf, FMT , VARGS ))); + #define PRINTF_ATTR(FMT, VARGS) __attribute__((format(printf, FMT , VARGS ))) #endif /* per-level limits */