From de51889f62b7289e2eb9a7be198aacf40027e9bb Mon Sep 17 00:00:00 2001 From: TimeServ Date: Mon, 6 Sep 2004 01:18:24 +0000 Subject: [PATCH] transtable/palconvbits updates git-svn-id: https://svn.code.sf.net/p/fteqw/code/trunk@143 fc73d0e0-1445-4013-8a0c-d673dee63da5 --- engine/client/m_mp3.c | 11 +- engine/client/renderer.c | 8 +- engine/gl/glquake.h | 2 + engine/sw/d_local.h | 14 ++- engine/sw/d_part.c | 239 +++++++++++++++++++++++++++++++++--- engine/sw/d_polyse.c | 258 +++++++++++++++++++++++++++++++-------- engine/sw/d_sprite.c | 165 ++++++++++++++++++++++++- engine/sw/d_trans.c | 192 +++++++++++++++++++++++------ engine/sw/r_alias.c | 2 + engine/sw/sw_draw.c | 20 ++- 10 files changed, 788 insertions(+), 123 deletions(-) diff --git a/engine/client/m_mp3.c b/engine/client/m_mp3.c index fcaa05c10..8f062ac71 100644 --- a/engine/client/m_mp3.c +++ b/engine/client/m_mp3.c @@ -52,10 +52,10 @@ void MakeVideoPalette(void) if (strlen(r_palconvbits.string) < 3) { - // r7g7b7 is default - rs = 7; - gs = 7; - bs = 7; + // r5g6b5 is default + rs = 5; + gs = 6; + bs = 5; } else { @@ -144,7 +144,8 @@ void MakeVideoPalette(void) palshift[1] = (8 - palshift[0]) - gs; palshift[2] = palshift[1] + (8 - bs); - COM_WriteFile(filename, palxxxto8, size); + if (r_palconvwrite.value) + COM_WriteFile(filename, palxxxto8, size); } diff --git a/engine/client/renderer.c b/engine/client/renderer.c index 219f78039..199cf9aa2 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -185,7 +185,10 @@ extern cvar_t r_novis; extern cvar_t r_netgraph; cvar_t r_transtables = {"r_transtables","2"}; -cvar_t r_palconvbits = {"r_palconvbits", "777"}; +cvar_t r_transtablefull = {"r_transtablefull", "1"}; +cvar_t r_transtablewrite = {"r_transtablewrite", "1"}; +cvar_t r_palconvbits = {"r_palconvbits", "565"}; +cvar_t r_palconvwrite = {"r_palconvwrite", "1"}; extern cvar_t bul_text1; extern cvar_t bul_text2; @@ -331,7 +334,10 @@ void SWRenderer_Init(void) Cvar_Register (&r_reportsurfout, SWRENDEREROPTIONS); Cvar_Register (&r_transtables, SWRENDEREROPTIONS); + Cvar_Register (&r_transtablewrite, SWRENDEREROPTIONS); + Cvar_Register (&r_transtablefull, SWRENDEREROPTIONS); Cvar_Register (&r_palconvbits, SWRENDEREROPTIONS); + Cvar_Register (&r_palconvwrite, SWRENDEREROPTIONS); } #endif diff --git a/engine/gl/glquake.h b/engine/gl/glquake.h index 64c2b821c..1e31fae10 100644 --- a/engine/gl/glquake.h +++ b/engine/gl/glquake.h @@ -773,6 +773,8 @@ extern int r_pixbytes; #define WARP_HEIGHT 200 extern cvar_t r_palconvbits; +extern cvar_t r_palconvwrite; + extern cvar_t r_drawflat; extern int d_spanpixcount; extern int r_framecount; // sequence # of current frame since Quake diff --git a/engine/sw/d_local.h b/engine/sw/d_local.h index eeed04456..ee7ce5a0a 100644 --- a/engine/sw/d_local.h +++ b/engine/sw/d_local.h @@ -124,13 +124,23 @@ typedef qbyte tlookup[256][256]; typedef qbyte tlookupp[256]; extern tlookup *t_lookup; extern tlookupp *t_curlookupp; -extern int t_curtable; extern int t_numtables; extern int t_numtablesinv;//65546/numtables +extern int t_state; + +#define TT_REVERSE 0x1 // reverse table points +#define TT_ZERO 0x2 // zero alpha +#define TT_ONE 0x4 // full alpha +#define TT_USEHALF 0x8 // using half transtables + +// cvar defines for transtable +extern cvar_t r_transtablewrite; +extern cvar_t r_transtables; +extern cvar_t r_transtablefull; void D_InitTrans(void); #define Trans(p, p2) (t_curlookupp[p][p2]) -void Set_TransLevelI(int level); +// void Set_TransLevelI(int level); void Set_TransLevelF(float level); #endif diff --git a/engine/sw/d_part.c b/engine/sw/d_part.c index afc586bc0..37b066c68 100644 --- a/engine/sw/d_part.c +++ b/engine/sw/d_part.c @@ -360,6 +360,163 @@ void D_DrawParticle32 (particle_t *pparticle) } #define draw(x, y) x=Trans(x,(int)y) +#define rdraw(x, y) x=Trans((int)y,x) +void D_DrawParticleReverseTrans (particle_t *pparticle) +{ + vec3_t local, transformed; + float zi; + qbyte *pdest; + short *pz; + int i, izi, pix, count, u, v; + +// transform point + VectorSubtract (pparticle->org, r_origin, local); + + transformed[0] = DotProduct(local, r_pright); + transformed[1] = DotProduct(local, r_pup); + transformed[2] = DotProduct(local, r_ppn); + + if (transformed[2] < PARTICLE_Z_CLIP) + return; + +// project the point +// FIXME: preadjust xcenter and ycenter + zi = 1.0 / transformed[2]; + u = (int)(xcenter + zi * transformed[0] + 0.5); + v = (int)(ycenter - zi * transformed[1] + 0.5); + + if ((v > d_vrectbottom_particle) || + (u > d_vrectright_particle) || + (v < d_vrecty) || + (u < d_vrectx)) + { + return; + } + + pz = d_pzbuffer + (d_zwidth * v) + u; + izi = (int)(zi * 0x8000); + + pix = ((int)(izi*pparticle->scale)) >> d_pix_shift; + + if (pix < d_pix_min) + pix = d_pix_min; + else if (pix > d_pix_max) + pix = d_pix_max; + + u -= pix/2; + v -= pix/2; + if (u < 0) u = 0; + if (v < 0) v = 0; + pdest = d_viewbuffer + d_scantable[v] + u; + + switch (pix) + { + case 1: + count = 1 << d_y_aspect_shift; + + for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth) + { + if (pz[0] <= izi) + { +// pz[0] = izi; + rdraw(pdest[0], pparticle->color); + } + } + break; + + case 2: + count = 2 << d_y_aspect_shift; + + for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth) + { + if (pz[0] <= izi) + { +// pz[0] = izi; + rdraw(pdest[0], pparticle->color); + } + + if (pz[1] <= izi) + { +// pz[1] = izi; + rdraw(pdest[1], pparticle->color); + } + } + break; + + case 3: + count = 3 << d_y_aspect_shift; + + for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth) + { + if (pz[0] <= izi) + { +// pz[0] = izi; + rdraw(pdest[0], pparticle->color); + } + + if (pz[1] <= izi) + { +// pz[1] = izi; + rdraw(pdest[1], pparticle->color); + } + + if (pz[2] <= izi) + { +// pz[2] = izi; + rdraw(pdest[2], pparticle->color); + } + } + break; + + case 4: + count = 4 << d_y_aspect_shift; + + for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth) + { + if (pz[0] <= izi) + { +// pz[0] = izi; + rdraw(pdest[0], pparticle->color); + } + + if (pz[1] <= izi) + { +// pz[1] = izi; + rdraw(pdest[1], pparticle->color); + } + + if (pz[2] <= izi) + { +// pz[2] = izi; + rdraw(pdest[2], pparticle->color); + } + + if (pz[3] <= izi) + { +// pz[3] = izi; + rdraw(pdest[3], pparticle->color); + } + } + break; + + default: + count = pix << d_y_aspect_shift; + + for ( ; count ; count--, pz += d_zwidth, pdest += screenwidth) + { + for (i=0 ; icolor); + } + } + } + break; + } +} + void D_DrawParticleTrans (particle_t *pparticle) { vec3_t local, transformed; @@ -379,17 +536,22 @@ void D_DrawParticleTrans (particle_t *pparticle) return; } - if (pparticle->alpha <= 0.0) - return; + Set_TransLevelF(pparticle->alpha); + if (t_state & TT_ZERO) + return; - if (pparticle->alpha >= 0.9) + if (t_state & TT_ONE) { D_DrawParticle(pparticle); return; } - Set_TransLevelF(pparticle->alpha); + if (t_state & TT_REVERSE) + { + D_DrawParticleReverseTrans(pparticle); + return; + } // transform point VectorSubtract (pparticle->org, r_origin, local); @@ -788,11 +950,11 @@ void D_DrawSparkTrans (particle_t *pparticle) //draw a line in 3d space, 8bpp return; } - if (pparticle->alpha <= 0.0) - return; - Set_TransLevelF(pparticle->alpha); + if (t_state & TT_ZERO) + return; + speed = Length(pparticle->vel); if ((speed) < 1) { @@ -849,20 +1011,57 @@ void D_DrawSparkTrans (particle_t *pparticle) //draw a line in 3d space, 8bpp dv /= count; dz /= count; } - do - { - pz = d_pzbuffer + (d_zwidth * (v1>>16)) + (u1>>16); - if (*pz <= z1>>16) - { -// *pz = z1>>16; + if (t_state & TT_ONE) + { + do + { + pz = d_pzbuffer + (d_zwidth * (v1>>16)) + (u1>>16); - pdest = d_viewbuffer + d_scantable[v1>>16] + (u1>>16); - draw(*pdest, pparticle->color); - } + if (*pz <= z1>>16) + { + pdest = d_viewbuffer + d_scantable[v1>>16] + (u1>>16); + *pdest = pparticle->color; + } - u1 += du; - v1 += dv; - z1 += dz; - } while (count--); + u1 += du; + v1 += dv; + z1 += dz; + } while (count--); + } + else if (t_state & TT_REVERSE) + { + do + { + pz = d_pzbuffer + (d_zwidth * (v1>>16)) + (u1>>16); + + if (*pz <= z1>>16) + { + pdest = d_viewbuffer + d_scantable[v1>>16] + (u1>>16); + rdraw(*pdest, pparticle->color); + } + + u1 += du; + v1 += dv; + z1 += dz; + } while (count--); + } + else + { + do + { + pz = d_pzbuffer + (d_zwidth * (v1>>16)) + (u1>>16); + + if (*pz <= z1>>16) + { +// *pz = z1>>16; + pdest = d_viewbuffer + d_scantable[v1>>16] + (u1>>16); + draw(*pdest, pparticle->color); + } + + u1 += du; + v1 += dv; + z1 += dz; + } while (count--); + } } diff --git a/engine/sw/d_polyse.c b/engine/sw/d_polyse.c index 3243aa06d..39379872c 100644 --- a/engine/sw/d_polyse.c +++ b/engine/sw/d_polyse.c @@ -22,7 +22,9 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. //changes include stvertexes now being seperatly number from the triangles. //this allows q2 models to be supported. +#ifndef NOASM #define NOASM +#endif #include "quakedef.h" #include "r_local.h" @@ -233,6 +235,83 @@ void D_PolysetDrawFinalVerts32 (finalvert_t *fv, int numverts) } } +void D_PolysetRecursiveTriangleReverseTrans (int *lp1, int *lp2, int *lp3) +{ + int *temp; + int d; + int new[6]; + int z; + short *zbuf; + + d = lp2[0] - lp1[0]; + if (d < -1 || d > 1) + goto split; + d = lp2[1] - lp1[1]; + if (d < -1 || d > 1) + goto split; + + d = lp3[0] - lp2[0]; + if (d < -1 || d > 1) + goto split2; + d = lp3[1] - lp2[1]; + if (d < -1 || d > 1) + goto split2; + + d = lp1[0] - lp3[0]; + if (d < -1 || d > 1) + goto split3; + d = lp1[1] - lp3[1]; + if (d < -1 || d > 1) + { +split3: + temp = lp1; + lp1 = lp3; + lp3 = lp2; + lp2 = temp; + + goto split; + } + + return; // entire tri is filled + +split2: + temp = lp1; + lp1 = lp2; + lp2 = lp3; + lp3 = temp; + +split: +// split this edge + new[0] = (lp1[0] + lp2[0]) >> 1; + new[1] = (lp1[1] + lp2[1]) >> 1; + new[2] = (lp1[2] + lp2[2]) >> 1; + new[3] = (lp1[3] + lp2[3]) >> 1; + new[5] = (lp1[5] + lp2[5]) >> 1; + +// draw the point if splitting a leading edge + if (lp2[1] > lp1[1]) + goto nodraw; + if ((lp2[1] == lp1[1]) && (lp2[0] < lp1[0])) + goto nodraw; + + + z = new[5]>>16; + zbuf = zspantable[new[1]] + new[0]; + if (z >= *zbuf) + { + int pix; + + *zbuf = z; + pix = d_pcolormap[skintable[new[3]>>16][new[2]>>16]]; + d_viewbuffer[d_scantable[new[1]] + new[0]] = Trans(pix, d_viewbuffer[d_scantable[new[1]] + new[0]]); + } + +nodraw: +// recursively continue + D_PolysetRecursiveTriangleReverseTrans (lp3, lp1, new); + D_PolysetRecursiveTriangleReverseTrans (lp3, new, lp2); +} + void D_PolysetRecursiveTriangleTrans (int *lp1, int *lp2, int *lp3) { int *temp; @@ -471,6 +550,69 @@ nodraw: D_PolysetRecursiveTriangle16 (lp3, new, lp2); } +void D_PolysetDrawSpans8ReverseTrans (spanpackage_t *pspanpackage) +{ + int lcount; + qbyte *lpdest; + qbyte *lptex; + int lsfrac, ltfrac; + int llight; + int lzi; + short *lpz; + + do + { + lcount = d_aspancount - pspanpackage->count; + + errorterm += erroradjustup; + if (errorterm >= 0) + { + d_aspancount += d_countextrastep; + errorterm -= erroradjustdown; + } + else + { + d_aspancount += ubasestep; + } + + if (lcount) + { + lpdest = pspanpackage->pdest; + lptex = pspanpackage->ptex; + lpz = pspanpackage->pz; + lsfrac = pspanpackage->sfrac; + ltfrac = pspanpackage->tfrac; + llight = pspanpackage->light; + lzi = pspanpackage->zi; + + do + { + if ((lzi >> 16) >= *lpz) + { + *lpdest = Trans(((qbyte *)acolormap)[*lptex + (llight & 0xFF00)], *lpdest); +// gel mapping *lpdest = gelmap[*lpdest]; + *lpz = lzi >> 16; + } + lpdest++; + lzi += r_zistepx; + lpz++; + llight += r_lstepx; + lptex += a_ststepxwhole; + lsfrac += a_sstepxfrac; + lptex += lsfrac >> 16; + lsfrac &= 0xFFFF; + ltfrac += a_tstepxfrac; + if (ltfrac & 0x10000) + { + lptex += r_affinetridesc.skinwidth; + ltfrac &= 0xFFFF; + } + } while (--lcount); + } + + pspanpackage++; + } while (pspanpackage->count != -999999); +} void D_PolysetDrawSpans8Trans (spanpackage_t *pspanpackage) { @@ -482,6 +624,9 @@ void D_PolysetDrawSpans8Trans (spanpackage_t *pspanpackage) int lzi; short *lpz; + if (t_state & TT_REVERSE) + D_PolysetDrawSpans8ReverseTrans(pspanpackage); + do { lcount = d_aspancount - pspanpackage->count; @@ -1149,25 +1294,34 @@ void D_DrawSubdiv (void) if (currententity->alpha != 1) { Set_TransLevelF(currententity->alpha); - for (i=0 ; iv[1]-index1->v[1]) * - (index0->v[0]-index2->v[0]) - - (index0->v[0]-index1->v[0]) * - (index0->v[1]-index2->v[1])) >= 0) + for (i=0 ; iv[1]-index1->v[1]) * + (index0->v[0]-index2->v[0]) - + (index0->v[0]-index1->v[0]) * + (index0->v[1]-index2->v[1])) >= 0) + { + continue; + } + + d_pcolormap = &((qbyte *)acolormap)[index0->v[4] & 0xFF00]; + + if (t_state & TT_REVERSE) + D_PolysetRecursiveTriangleReverseTrans(index0->v, index1->v, index2->v); + else + D_PolysetRecursiveTriangleTrans(index0->v, index1->v, index2->v); } - - d_pcolormap = &((qbyte *)acolormap)[index0->v[4] & 0xFF00]; - - D_PolysetRecursiveTriangleTrans(index0->v, index1->v, index2->v); + return; } - return; } #endif @@ -1258,46 +1412,52 @@ void D_DrawNonSubdiv (void) if (currententity->alpha != 1) { Set_TransLevelF(currententity->alpha); - for (i=0 ; ixyz_index[0]; - index1 = pfv + ptri->xyz_index[1]; - index2 = pfv + ptri->xyz_index[2]; + if (t_state & TT_ZERO) + return; - d_xdenom = (index0->v[1]-index1->v[1]) * - (index0->v[0]-index2->v[0]) - - (index0->v[0]-index1->v[0])*(index0->v[1]-index2->v[1]); - - if (d_xdenom >= 0) + for (i=0 ; ixyz_index[0]; + index1 = pfv + ptri->xyz_index[1]; + index2 = pfv + ptri->xyz_index[2]; + + d_xdenom = (index0->v[1]-index1->v[1]) * + (index0->v[0]-index2->v[0]) - + (index0->v[0]-index1->v[0])*(index0->v[1]-index2->v[1]); + + if (d_xdenom >= 0) + { + continue; + } + + r_p0[0] = index0->v[0]; // u + r_p0[1] = index0->v[1]; // v + r_p0[2] = index0->v[2]; // s + r_p0[3] = index0->v[3]; // t + r_p0[4] = index0->v[4]; // light + r_p0[5] = index0->v[5]; // iz + + r_p1[0] = index1->v[0]; + r_p1[1] = index1->v[1]; + r_p1[2] = index1->v[2]; + r_p1[3] = index1->v[3]; + r_p1[4] = index1->v[4]; + r_p1[5] = index1->v[5]; + + r_p2[0] = index2->v[0]; + r_p2[1] = index2->v[1]; + r_p2[2] = index2->v[2]; + r_p2[3] = index2->v[3]; + r_p2[4] = index2->v[4]; + r_p2[5] = index2->v[5]; + + D_PolysetSetEdgeTable (); + D_RasterizeAliasPolySmoothTrans (); } - - r_p0[0] = index0->v[0]; // u - r_p0[1] = index0->v[1]; // v - r_p0[2] = index0->v[2]; // s - r_p0[3] = index0->v[3]; // t - r_p0[4] = index0->v[4]; // light - r_p0[5] = index0->v[5]; // iz - - r_p1[0] = index1->v[0]; - r_p1[1] = index1->v[1]; - r_p1[2] = index1->v[2]; - r_p1[3] = index1->v[3]; - r_p1[4] = index1->v[4]; - r_p1[5] = index1->v[5]; - - r_p2[0] = index2->v[0]; - r_p2[1] = index2->v[1]; - r_p2[2] = index2->v[2]; - r_p2[3] = index2->v[3]; - r_p2[4] = index2->v[4]; - r_p2[5] = index2->v[5]; - - D_PolysetSetEdgeTable (); - D_RasterizeAliasPolySmoothTrans (); + return; } - return; } #endif diff --git a/engine/sw/d_sprite.c b/engine/sw/d_sprite.c index 24ca4fe3e..df71e1625 100644 --- a/engine/sw/d_sprite.c +++ b/engine/sw/d_sprite.c @@ -503,6 +503,160 @@ NextSpan: } #ifdef PEXT_TRANS +void D_SpriteDrawSpansReverseTrans (sspan_t *pspan) +{ + int count, spancount, izistep; + int izi; + qbyte *pbase, *pdest; + fixed16_t s, t, snext, tnext, sstep, tstep; + float sdivz, tdivz, zi, z, du, dv, spancountminus1; + float sdivz8stepu, tdivz8stepu, zi8stepu; + qbyte btemp; + short *pz; + + sstep = 0; // keep compiler happy + tstep = 0; // ditto + + pbase = cacheblock; + + sdivz8stepu = d_sdivzstepu * 8; + tdivz8stepu = d_tdivzstepu * 8; + zi8stepu = d_zistepu * 8; + +// we count on FP exceptions being turned off to avoid range problems + izistep = (int)(d_zistepu * 0x8000 * 0x10000); + + do + { + pdest = (qbyte *)d_viewbuffer + (screenwidth * pspan->v) + pspan->u; + pz = d_pzbuffer + (d_zwidth * pspan->v) + pspan->u; + + count = pspan->count; + + if (count <= 0) + goto NextSpan; + + // calculate the initial s/z, t/z, 1/z, s, and t and clamp + du = (float)pspan->u; + dv = (float)pspan->v; + + sdivz = d_sdivzorigin + dv*d_sdivzstepv + du*d_sdivzstepu; + tdivz = d_tdivzorigin + dv*d_tdivzstepv + du*d_tdivzstepu; + zi = d_ziorigin + dv*d_zistepv + du*d_zistepu; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + // we count on FP exceptions being turned off to avoid range problems + izi = (int)(zi * 0x8000 * 0x10000); + + s = (int)(sdivz * z) + sadjust; + if (s > bbextents) + s = bbextents; + else if (s < 0) + s = 0; + + t = (int)(tdivz * z) + tadjust; + if (t > bbextentt) + t = bbextentt; + else if (t < 0) + t = 0; + + do + { + // calculate s and t at the far end of the span + if (count >= 8) + spancount = 8; + else + spancount = count; + + count -= spancount; + + if (count) + { + // calculate s/z, t/z, zi->fixed s and t at far end of span, + // calculate s and t steps across span by shifting + sdivz += sdivz8stepu; + tdivz += tdivz8stepu; + zi += zi8stepu; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 8) + snext = 8; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 8) + tnext = 8; // guard against round-off error on <0 steps + + sstep = (snext - s) >> 3; + tstep = (tnext - t) >> 3; + } + else + { + // calculate s/z, t/z, zi->fixed s and t at last pixel in span (so + // can't step off polygon), clamp, calculate s and t steps across + // span by division, biasing steps low so we don't run off the + // texture + spancountminus1 = (float)(spancount - 1); + sdivz += d_sdivzstepu * spancountminus1; + tdivz += d_tdivzstepu * spancountminus1; + zi += d_zistepu * spancountminus1; + z = (float)0x10000 / zi; // prescale to 16.16 fixed-point + snext = (int)(sdivz * z) + sadjust; + if (snext > bbextents) + snext = bbextents; + else if (snext < 8) + snext = 8; // prevent round-off error on <0 steps from + // from causing overstepping & running off the + // edge of the texture + + tnext = (int)(tdivz * z) + tadjust; + if (tnext > bbextentt) + tnext = bbextentt; + else if (tnext < 8) + tnext = 8; // guard against round-off error on <0 steps + + if (spancount > 1) + { + sstep = (snext - s) / (spancount - 1); + tstep = (tnext - t) / (spancount - 1); + } + } + + do + { + btemp = *(pbase + (s >> 16) + (t >> 16) * cachewidth); + if (btemp != 255) + { + if (*pz <= (izi >> 16)) + { + *pz = izi >> 16; + *pdest = Trans(btemp, *pdest); + } + } + + izi += izistep; + pdest++; + pz++; + s += sstep; + t += tstep; + } while (--spancount > 0); + + s = snext; + t = tnext; + + } while (count > 0); + +NextSpan: + pspan++; + + } while (pspan->count != DS_SPAN_LIST_END); +} + void D_SpriteDrawSpansTrans (sspan_t *pspan) { int count, spancount, izistep; @@ -913,12 +1067,15 @@ void D_DrawSprite (void) D_SpriteDrawSpans16 (sprite_spans); else //1 { - if (currententity->alpha>=0.9) + Set_TransLevelF(currententity->alpha); + if (t_state & TT_ONE) D_SpriteDrawSpans (sprite_spans); - else + else if (!(t_state & TT_ZERO)) { - Set_TransLevelF(currententity->alpha); - D_SpriteDrawSpansTrans (sprite_spans); + if (t_state & TT_REVERSE) + D_SpriteDrawSpansReverseTrans (sprite_spans); + else + D_SpriteDrawSpansTrans (sprite_spans); } } #endif diff --git a/engine/sw/d_trans.c b/engine/sw/d_trans.c index c43afb11d..25327e3f7 100644 --- a/engine/sw/d_trans.c +++ b/engine/sw/d_trans.c @@ -14,9 +14,23 @@ int t_curtable; int t_numtables; int t_numtablesinv;//numtables/65546 +int t_state; + #define palette host_basepal #define _abs(x) ((x)*(x)) +void R_ReverseTable(int table) +{ + int p, p2, temp; + + for (p = 0; p < 256; p++) + for (p2 = p+1; p2 < 256; p2++) + { + temp = (t_lookup[table])[p][p2]; + (t_lookup[table])[p][p2] = (t_lookup[table])[p2][p]; + (t_lookup[table])[p2][p] = temp; + } +} void R_CalcTransTable(int table, int level) { @@ -26,7 +40,7 @@ void R_CalcTransTable(int table, int level) int r, g, b, j; int i; unsigned char *pa; - int m; + int m, rvr; int dif, curdif; qbyte p1multi; @@ -38,11 +52,37 @@ void R_CalcTransTable(int table, int level) pixdivide = p1multi + p2multi; + if (level > 99) // trivial generate for p2 + { + for (p = 0; p < 256; p++) + for (p2 = 0; p2 < 256; p2++) + (t_lookup[table])[p][p2] = p2; + return; + } + + if (level < 1) // trivial generate for p + { + for (p = 0; p < 256; p++) + for (p2 = 0; p2 < 256; p2++) + (t_lookup[table])[p][p2] = p; + return; + } + + if (level > 50) + { + level = 100 - level; + rvr = 1; + } + else + rvr = 0; + COM_FOpenFile (va("data/ttable%i.dat", (int) level) , &f); //we can ignore the filesize return value if (f) { if (fread (t_lookup[table], 256, 256, f) == 256) { + if (rvr) + R_ReverseTable(table); fclose(f); return; } @@ -81,24 +121,32 @@ void R_CalcTransTable(int table, int level) } } - COM_CreatePath(va("%s/data/", com_gamedir)); -#if 1 - f = fopen (va("%s/data/ttable%i.dat", com_gamedir, (int) level), "wb"); - if (f) + if (r_transtablewrite.value) { - if (fwrite (t_lookup[table], 256, 256, f) != 256) + COM_CreatePath(va("%s/data/", com_gamedir)); +#if 1 + f = fopen (va("%s/data/ttable%i.dat", com_gamedir, (int) level), "wb"); + if (f) { - Con_Printf("Couldn't write data to \"data/ttable%i.dat\"\n", (int) level); - fclose(f); - return; + if (fwrite (t_lookup[table], 256, 256, f) != 256) + { + Con_Printf("Couldn't write data to \"data/ttable%i.dat\"\n", (int) level); + fclose(f); + if (rvr) + R_ReverseTable(table); // make sure it gets reversed if needed + return; + } + fclose(f); } - fclose(f); - } - else - Con_Printf("Couldn't write data to \"data/ttable%i.dat\"\n", (int) level); + else + Con_Printf("Couldn't write data to \"data/ttable%i.dat\"\n", (int) level); #else - COM_WriteFile(va("data/ttable%i.dat", (int)level, t_lookup[table], 256*256); + COM_WriteFile(va("data/ttable%i.dat", (int)level, t_lookup[table], 256*256); #endif + } + + if (rvr) // just reverse it here instead of having to do reversed writes + R_ReverseTable(table); } void D_InitTrans(void) @@ -111,35 +159,53 @@ void D_InitTrans(void) //no trans palette yet.. Con_SafePrintf("Making/loading transparency lookup tables\nPlease wait...\n"); -MakeVideoPalette(); + MakeVideoPalette(); + + t_numtables = 5; + + i = r_transtables.value; + if (i > 0 && i < 50) // might need a max bound sanity check here + { + t_numtables = i; + } if ((i = COM_CheckParm("-ttables")) != 0) { t_numtables = Q_atoi(com_argv[i+1]); if (t_numtables < 1) t_numtables = 1; + if (t_numtables > 50) + t_numtables = 50; } - else - t_numtables = 5; t_numtablesinv = ((float)65536/t_numtables)+1;//65546/numtables +t_state = TT_ZERO; t_curtable=0; //t_lookup = Hunk_AllocName(sizeof(tlookup)*t_numtables, "Transtables"); t_lookup = BZ_Malloc(sizeof(tlookup)*t_numtables); t_curlookupp = t_lookup[t_curtable]; - if (t_numtables == 1) - R_CalcTransTable(0, 50); - else if (t_numtables == 2) + if (r_transtablefull.value) { - R_CalcTransTable(0, 50); - R_CalcTransTable(1, 100); + t_state = TT_ZERO|TT_USEHALF; + for (table = 0; table < t_numtables; table++) + R_CalcTransTable(table, (int)floor(((table+1)/(float)(t_numtables*2+1))*100 + 0.5)); } else { - for (table = 0; table < t_numtables; table++) - R_CalcTransTable(table, 100/((float)(t_numtables-1)/table)); + if (t_numtables == 1) + R_CalcTransTable(0, 50); + else if (t_numtables == 2) + { + R_CalcTransTable(0, 33); + R_CalcTransTable(1, 67); + } + else + { + for (table = 0; table < t_numtables; table++) + R_CalcTransTable(table, (int)floor(100/((float)(t_numtables-1)/table) + 0.5)); + } } Con_Printf("Done\n"); } @@ -152,29 +218,79 @@ byte _fastcall Trans(byte p, byte p2) } #endif +/* void Set_TransLevelI(int level) { - /* - 0 =0 - 12.5 =1 - 25 =2 - 37.5 =3 - 50 =4 - 62.5 =5 - 75 =6 - 87.5 =7 - 100 =8 - */ t_curtable = level/(100.0f/(t_numtables-1)); t_curlookupp = t_lookup[t_curtable]; } +*/ + void Set_TransLevelF(float level) //MUST be between 0 and 1 { -// level+=1.0/(NUMTABLES-1); if (level>1) level = 1; - t_curtable = level*(t_numtables-1); - t_curlookupp = t_lookup[t_curtable]; + + if (t_state & TT_USEHALF) + { + t_state = TT_ZERO; + t_curtable = floor(level*(t_numtables*2+1) + 0.5); + if (t_curtable > t_numtables) + { + t_curtable = (t_numtables*2+1)-t_curtable; + t_state = TT_REVERSE|TT_ONE; + } + + if (t_curtable > 0) + { + t_state &= ~(TT_ZERO|TT_ONE); + t_curlookupp = t_lookup[t_curtable-1]; + } + + + t_state |= TT_USEHALF; + } + else if (t_numtables == 1) + { + if (level < 0.33) + t_state = TT_ZERO; + else if (level > 0.67) + t_state = TT_ONE; + else + t_state = 0; + } + else if (t_numtables == 2) + { + if (level > 0.75) + t_state = TT_ONE; + else if (level > 0.50) + { + t_state = 0; + t_curtable = 1; + t_curlookupp = t_lookup[t_curtable]; + } + else if (level > 0.25) + { + t_state = 0; + t_curtable = 0; + t_curlookupp = t_lookup[t_curtable]; + } + else + t_state = TT_ZERO; + } + else + { + t_curtable = level*t_numtables; + if (t_curtable >= t_numtables) + t_state = TT_ONE; + else if (t_curtable <= 0) + t_state = TT_ZERO; + else + { + t_state = 0; + t_curlookupp = t_lookup[t_curtable]; + } + } } #endif diff --git a/engine/sw/r_alias.c b/engine/sw/r_alias.c index 5e3283169..c1c6d7336 100644 --- a/engine/sw/r_alias.c +++ b/engine/sw/r_alias.c @@ -314,10 +314,12 @@ void R_AliasPreparePoints (void) av = pauxverts; #ifdef PEXT_TRANS +/* if (currententity->alpha != 1) { Set_TransLevelF(currententity->alpha); } +*/ #endif for (i=0 ; i