diff --git a/engine/client/cl_ents.c b/engine/client/cl_ents.c index 1f3d72373..fcae8eada 100644 --- a/engine/client/cl_ents.c +++ b/engine/client/cl_ents.c @@ -1627,12 +1627,13 @@ void CL_LinkPacketEntities (void) if (state->colormap && (state->colormap <= MAX_CLIENTS) && (gl_nocolors.value == -1 || (ent->model/* && state->modelindex == cl_playerindex*/))) { - ent->colormap = cl.players[state->colormap-1].translations; + // TODO: DP colormap/colormod extension? + ent->palremap = cl.players[state->colormap-1].palremap; ent->scoreboard = &cl.players[state->colormap-1]; } else { - ent->colormap = vid.colormap; + ent->palremap = D_IdentityRemap(); ent->scoreboard = NULL; } @@ -2196,7 +2197,7 @@ void CL_LinkProjectiles (void) ent->skinnum = 0; ent->frame = 0; ent->flags = 0; - ent->colormap = vid.colormap; + ent->palremap = D_IdentityRemap(); ent->scoreboard = NULL; #ifdef PEXT_SCALE ent->scale = 1; @@ -2717,7 +2718,7 @@ void CL_LinkPlayers (void) else ent->lerpfrac = 0; - ent->colormap = info->translations; + ent->palremap = info->palremap; if (state->modelindex == cl_playerindex) ent->scoreboard = info; // use custom skin else diff --git a/engine/client/cl_parse.c b/engine/client/cl_parse.c index bca2504e2..1b65fca8f 100644 --- a/engine/client/cl_parse.c +++ b/engine/client/cl_parse.c @@ -2230,7 +2230,7 @@ void CL_ParseStatic (int version) // copy it to the current state ent->model = cl.model_precache[es.modelindex]; ent->oldframe = ent->frame = es.frame; - ent->colormap = vid.colormap; + ent->palremap = D_IdentityRemap(); ent->skinnum = es.skinnum; ent->drawflags = es.hexen2flags; @@ -2560,38 +2560,17 @@ void CL_NewTranslation (int slot) } } + if (top > 13 || top < 0) + top = 13; + if (bottom > 13 || bottom < 0) + bottom = 13; if (player->_topcolor != top || player->_bottomcolor != bottom || !player->skin) { player->_topcolor = top; player->_bottomcolor = bottom; - - dest = player->translations; - source = vid.colormap; - memcpy (dest, vid.colormap, sizeof(player->translations)); -// top = player->topcolor; - if (top > 13 || top < 0) - top = 13; - top *= 16; -// bottom = player->bottomcolor; - if (bottom > 13 || bottom < 0) - bottom = 13; - bottom *= 16; - - for (i=0 ; ipalremap); + player->palremap = D_GetPaletteRemap(255, 255, 255, false, true, top, bottom); } } else diff --git a/engine/client/cl_tent.c b/engine/client/cl_tent.c index 7a4e2ae2c..fb9081fb8 100644 --- a/engine/client/cl_tent.c +++ b/engine/client/cl_tent.c @@ -2311,7 +2311,7 @@ entity_t *CL_NewTempEntity (void) memset (ent, 0, sizeof(*ent)); - ent->colormap = vid.colormap; + ent->palremap = D_IdentityRemap(); #ifdef PEXT_SCALE ent->scale = 1; #endif diff --git a/engine/client/client.h b/engine/client/client.h index ed5a71524..882887317 100644 --- a/engine/client/client.h +++ b/engine/client/client.h @@ -21,7 +21,6 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. #include "particles.h" - typedef struct { char name[16]; @@ -152,8 +151,9 @@ typedef struct player_info_s int _topcolor; int _bottomcolor; + struct palremap_s *palremap; + int spectator; - qbyte translations[VID_GRADES*256]; skin_t *skin; struct model_s *model; diff --git a/engine/client/pr_csqc.c b/engine/client/pr_csqc.c index 0ad982b54..acc22cfc4 100644 --- a/engine/client/pr_csqc.c +++ b/engine/client/pr_csqc.c @@ -716,9 +716,9 @@ static qboolean CopyCSQCEdictToEntity(csqcedict_t *in, entity_t *out) if (in->v->colormap > 0 && in->v->colormap <= MAX_CLIENTS) { - out->colormap = cl.players[(int)in->v->colormap-1].translations; + out->palremap = cl.players[(int)in->v->colormap-1].palremap; out->scoreboard = &cl.players[(int)in->v->colormap-1]; - } + } // TODO: DP COLORMAP extension? if (!in->v->alpha) out->alpha = 1; diff --git a/engine/client/render.h b/engine/client/render.h index f382bbb72..b2cd47d8b 100644 --- a/engine/client/render.h +++ b/engine/client/render.h @@ -20,8 +20,12 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. // refresh.h -- public interface to refresh functions -#define TOP_RANGE 16 // soldier uniform colors -#define BOTTOM_RANGE 96 +// default soldier colors +#define TOP_DEFAULT 1 +#define BOTTOM_DEFAULT 6 + +#define TOP_RANGE (TOP_DEFAULT<<4) +#define BOTTOM_RANGE (BOTTOM_DEFAULT<<4) struct msurface_s; @@ -63,7 +67,7 @@ typedef struct entity_s struct model_s *model; // NULL = no model int frame; - qbyte *colormap; + struct palremap_s *palremap; int skinnum; // for Alias models struct player_info_s *scoreboard; // identify player @@ -382,7 +386,8 @@ extern cvar_t gl_finish; extern cvar_t gl_max_size; extern cvar_t gl_playermip; -extern cvar_t r_palconvwrite; +extern cvar_t d_palconvwrite; +extern cvar_t d_palremapsize; extern cvar_t r_lightmap_saturation; diff --git a/engine/client/renderer.c b/engine/client/renderer.c index 6ec5f3aa1..1cbc18c86 100644 --- a/engine/client/renderer.c +++ b/engine/client/renderer.c @@ -198,7 +198,8 @@ cvar_t r_drawflat = {"r_drawflat","0", NULL, CVAR_SEMICHEAT}; cvar_t r_wallcolour = {"r_wallcolour","0 0 1"}; cvar_t r_floorcolour = {"r_floorcolour","0.5 0.5 1"}; -cvar_t r_palconvwrite = {"r_palconvwrite", "1"}; +cvar_t d_palconvwrite = {"d_palconvwrite", "1"}; +cvar_t d_palremapsize = {"d_palremapsize", "64", NULL, CVAR_RENDERERLATCH}; cvar_t r_lightmap_saturation = {"r_lightmap_saturation", "1"}; @@ -388,7 +389,8 @@ void SWRenderer_Init(void) Cvar_Register (&r_ambient, SWRENDEREROPTIONS); Cvar_Register (&r_reportsurfout, SWRENDEREROPTIONS); - Cvar_Register (&r_palconvwrite, SWRENDEREROPTIONS); + Cvar_Register (&d_palconvwrite, SWRENDEREROPTIONS); + Cvar_Register (&d_palremapsize, SWRENDEREROPTIONS); } #endif @@ -1659,7 +1661,7 @@ TRACE(("dbg: R_ApplyRenderer: efrags\n")); for (i = 0; i < cl.num_statics; i++) //make the static entities reappear. { cl_static_entities[i].model = cl.model_precache[staticmodelindex[i]]; - cl_static_entities[i].colormap = vid.colormap; + cl_static_entities[i].palremap = D_IdentityRemap(); if (staticmodelindex[i]) //make sure it's worthwhile. { R_AddEfrags(&cl_static_entities[i]); diff --git a/engine/client/view.c b/engine/client/view.c index c16a79fd8..ef52286ee 100644 --- a/engine/client/view.c +++ b/engine/client/view.c @@ -1184,7 +1184,7 @@ void V_CalcRefdef (int pnum) else view->model = cl.model_precache[cl.stats[pnum][STAT_WEAPON]]; view->frame = view_message?view_message->weaponframe:0; - view->colormap = vid.colormap; + view->palremap = D_IdentityRemap(); // set up the refresh position r_refdef.viewangles[PITCH] += cl.punchangle[pnum]; diff --git a/engine/common/quakeasm.h b/engine/common/quakeasm.h index cc02062e1..6b955eaa4 100644 --- a/engine/common/quakeasm.h +++ b/engine/common/quakeasm.h @@ -167,6 +167,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. .extern C(r_affinetridesc) .extern C(acolormap) .extern C(d_pcolormap) + .extern C(apalremap) .extern C(r_affinetridesc) .extern C(d_sfrac) .extern C(d_ptex) diff --git a/engine/gl/glquake.h b/engine/gl/glquake.h index ccfb87bd8..e165f6dc7 100644 --- a/engine/gl/glquake.h +++ b/engine/gl/glquake.h @@ -790,8 +790,8 @@ extern int r_pixbytes; #define WARP_WIDTH 320 #define WARP_HEIGHT 200 -extern cvar_t r_palconvbits; -extern cvar_t r_palconvwrite; +extern cvar_t d_palconvwrite; +extern cvar_t d_palremapsize; extern cvar_t r_drawflat; extern int d_spanpixcount; diff --git a/engine/qclib/pr_edict.c b/engine/qclib/pr_edict.c index cb59859e3..6b89ead85 100644 --- a/engine/qclib/pr_edict.c +++ b/engine/qclib/pr_edict.c @@ -2098,9 +2098,12 @@ char *SaveEnt (progfuncs_t *progfuncs, char *buf, int *size, struct edict_s *ed) for (i=0 ; iname; - if (name[strlen(name)-2] == '_') + len = strlen(name); // should we skip vars with no name? + if (len > 2 && name[len-2] == '_') continue; // skip _x, _y, _z vars v = (int*)((edictrun_t*)ed)->fields + d->ofs; diff --git a/engine/sw/d_iface.h b/engine/sw/d_iface.h index df99603c5..1249a0fa1 100644 --- a/engine/sw/d_iface.h +++ b/engine/sw/d_iface.h @@ -132,7 +132,7 @@ extern int d_con_indirect; // if 0, Quake will draw console directly extern vec3_t r_pright, r_pup, r_ppn; -void D_Aff8Patch (void *pcolormap); +void D_Aff8Patch (void *pcolormap, qbyte *ppalremap); void GLD_BeginDirectRect (int x, int y, qbyte *pbitmap, int width, int height); void SWD_BeginDirectRect (int x, int y, qbyte *pbitmap, int width, int height); void D_DisableBackBufferAccess (void); @@ -180,6 +180,7 @@ extern qbyte *r_skysource; #define TRANSPARENT_COLOR 0xFF extern void *acolormap; // FIXME: should go away +extern qbyte *apalremap; //=======================================================================// diff --git a/engine/sw/d_init.c b/engine/sw/d_init.c index e7b127f5b..aa60f76c0 100644 --- a/engine/sw/d_init.c +++ b/engine/sw/d_init.c @@ -44,6 +44,10 @@ void D_DrawSpans32 (espan_t *pspan); void D_DrawSpans32From8 (espan_t *pspan); void D_DrawSpans32_Smooth (espan_t *pspan); +void D_Shutdown (void) +{ + D_ShutdownTrans(); +} /* =============== diff --git a/engine/sw/d_local.h b/engine/sw/d_local.h index 491398952..b5d60d529 100644 --- a/engine/sw/d_local.h +++ b/engine/sw/d_local.h @@ -125,12 +125,37 @@ extern void (*d_drawspans) (espan_t *pspan); #define TRANS_UPPER_CAP (TRANS_MAX / (TRANS_LEVELS + 0.0)) #define TRANS_LOWER_CAP (1.0 / TRANS_LEVELS) +#define REMAP_MAX 64 + #ifdef _fastcall #define FASTCALL _fastcall #else #define FASTCALL #endif +// palette remap cache +typedef struct palremap_s { + int r; + int g; + int b; + int key; + int references; + qbyte pal[256]; +} palremap_t; + +palremap_t *palremaps; +int palremapsize; + +#define fbremapidx(x) palremaps[1].pal[x] + +#define identityremap palremaps[0] +#define fullbrightremap palremaps[1] + +palremap_t *D_GetPaletteRemap(int red, int green, int blue, qboolean desaturate, qboolean fullbrights, int topcolor, int bottomcolor); +qbyte *D_GetMenuTintPal(void); +extern palremap_t *D_IdentityRemap(void); +extern void D_DereferenceRemap(palremap_t *palremap); + void D_InitTrans(void); // void Set_TransLevelI(int level); void D_SetTransLevel(float level, blendmode_t blend); diff --git a/engine/sw/d_polysa.s b/engine/sw/d_polysa.s index 319897936..c568475b2 100644 --- a/engine/sw/d_polysa.s +++ b/engine/sw/d_polysa.s @@ -17,6 +17,7 @@ along with this program; if not, write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ + // // d_polysa.s // x86 assembly-language polygon model drawing code @@ -683,7 +684,7 @@ LDraw: // *zbuf = z; movw %dx,(%eax,%ebp,2) -// pix = d_pcolormap[skintable[new[3]>>16][new[2]>>16]]; +// pix = d_pcolormap[apalremap[skintable[new[3]>>16][new[2]>>16]]]; movl 12(%esp),%eax sarl $16,%eax @@ -696,6 +697,8 @@ LDraw: movl 4(%esp),%ebp movb (%eax,%edx,),%cl + + movb C(apalremap)(%ecx),%cl movl C(d_pcolormap),%edx movb (%edx,%ecx,),%dl @@ -871,8 +874,10 @@ LDraw8: cmpw (%ecx),%bp jl Lp1 xorl %eax,%eax - movb %dh,%ah movb (%esi),%al + movb 0x12345678(%eax),%al +PPatch8: + movb %dh,%ah movw %bp,(%ecx) movb 0x12345678(%eax),%al LPatch8: @@ -889,8 +894,10 @@ LDraw7: cmpw 2(%ecx),%bp jl Lp2 xorl %eax,%eax - movb %dh,%ah movb (%esi),%al + movb 0x12345678(%eax),%al +PPatch7: + movb %dh,%ah movw %bp,2(%ecx) movb 0x12345678(%eax),%al LPatch7: @@ -907,8 +914,10 @@ LDraw6: cmpw 4(%ecx),%bp jl Lp3 xorl %eax,%eax - movb %dh,%ah movb (%esi),%al + movb 0x12345678(%eax),%al +PPatch6: + movb %dh,%ah movw %bp,4(%ecx) movb 0x12345678(%eax),%al LPatch6: @@ -925,8 +934,10 @@ LDraw5: cmpw 6(%ecx),%bp jl Lp4 xorl %eax,%eax - movb %dh,%ah movb (%esi),%al + movb 0x12345678(%eax),%al +PPatch5: + movb %dh,%ah movw %bp,6(%ecx) movb 0x12345678(%eax),%al LPatch5: @@ -943,8 +954,10 @@ LDraw4: cmpw 8(%ecx),%bp jl Lp5 xorl %eax,%eax - movb %dh,%ah movb (%esi),%al + movb 0x12345678(%eax),%al +PPatch4: + movb %dh,%ah movw %bp,8(%ecx) movb 0x12345678(%eax),%al LPatch4: @@ -961,8 +974,10 @@ LDraw3: cmpw 10(%ecx),%bp jl Lp6 xorl %eax,%eax - movb %dh,%ah movb (%esi),%al + movb 0x12345678(%eax),%al +PPatch3: + movb %dh,%ah movw %bp,10(%ecx) movb 0x12345678(%eax),%al LPatch3: @@ -979,8 +994,10 @@ LDraw2: cmpw 12(%ecx),%bp jl Lp7 xorl %eax,%eax - movb %dh,%ah movb (%esi),%al + movb 0x12345678(%eax),%al +PPatch2: + movb %dh,%ah movw %bp,12(%ecx) movb 0x12345678(%eax),%al LPatch2: @@ -997,8 +1014,10 @@ LDraw1: cmpw 14(%ecx),%bp jl Lp8 xorl %eax,%eax - movb %dh,%ah movb (%esi),%al + movb 0x12345678(%eax),%al +PPatch1: + movb %dh,%ah movw %bp,14(%ecx) movb 0x12345678(%eax),%al LPatch1: @@ -1045,10 +1064,12 @@ LExactlyOneLong: cmpw (%ecx),%bp jl LNextSpan xorl %eax,%eax + movb (%ebx),%al + movb 0x12345678(%eax),%al +PPatch9: movl spanpackage_t_pdest(%esi),%edi movb spanpackage_t_light+1(%esi),%ah addl $(spanpackage_t_size),%esi // point to next span - movb (%ebx),%al movw %bp,(%ecx) movb 0x12345678(%eax),%al LPatch9: @@ -1061,6 +1082,7 @@ C(D_PolysetAff8End): #define pcolormap 4 +#define ppalremap 8 .globl C(D_Aff8Patch) C(D_Aff8Patch): @@ -1074,6 +1096,16 @@ C(D_Aff8Patch): movl %eax,LPatch7-4 movl %eax,LPatch8-4 movl %eax,LPatch9-4 + movl ppalremap(%esp),%eax + movl %eax,PPatch1-4 + movl %eax,PPatch2-4 + movl %eax,PPatch3-4 + movl %eax,PPatch4-4 + movl %eax,PPatch5-4 + movl %eax,PPatch6-4 + movl %eax,PPatch7-4 + movl %eax,PPatch8-4 + movl %eax,PPatch9-4 ret @@ -1529,10 +1561,13 @@ LFVLoop: shrl $16,%edx movb (%edi,%edx),%dl +// pix = apalremap[pix]; + andl $0x00FF,%edx + movb C(apalremap)(%edx), %dl + // pix = ((byte *)acolormap)[pix + (fv->v[4] & 0xFF00)]; movl fv_v+16(%ebx),%edi andl $0xFF00,%edi - andl $0x00FF,%edx addl %edx,%edi movl C(acolormap),%edx movb (%edx,%edi,1),%dl diff --git a/engine/sw/d_polyse.c b/engine/sw/d_polyse.c index bd8e2b7d2..dc0673d63 100644 --- a/engine/sw/d_polyse.c +++ b/engine/sw/d_polyse.c @@ -180,7 +180,7 @@ void D_PolysetDrawFinalVertsTrans (finalvert_t *fv, int numverts) *zbuf = z; pix = skintable[fv->v[3]>>16][fv->v[2]>>16]; - pix = ((qbyte *)acolormap)[pix + (fv->v[4] & 0xFF00) ]; + pix = ((qbyte *)acolormap)[apalremap[pix] + (fv->v[4] & 0xFF00) ]; d_viewbuffer[d_scantable[fv->v[1]] + fv->v[0]] = Trans(d_viewbuffer[d_scantable[fv->v[1]] + fv->v[0]], (unsigned char)pix); } } @@ -316,7 +316,7 @@ split: int pix; *zbuf = z; - pix = d_pcolormap[skintable[new[3]>>16][new[2]>>16]]; + pix = d_pcolormap[apalremap[skintable[new[3]>>16][new[2]>>16]]]; d_viewbuffer[d_scantable[new[1]] + new[0]] = Trans(d_viewbuffer[d_scantable[new[1]] + new[0]], (unsigned char)pix); } @@ -477,7 +477,7 @@ split: int pix; *zbuf = z; - pix = d_pcolormap[skintable[new[3]>>16][new[2]>>16]]; + pix = d_pcolormap[apalremap[skintable[new[3]>>16][new[2]>>16]]]; ((unsigned short *)d_viewbuffer)[d_scantable[new[1]] + new[0]] = pix;//d_8to32table[pix]; } @@ -529,7 +529,7 @@ void D_PolysetDrawSpans8Trans (spanpackage_t *pspanpackage) { if ((lzi >> 16) >= *lpz) { - *lpdest = Trans(*lpdest, ((qbyte *)acolormap)[*lptex + (llight & 0xFF00)]); + *lpdest = Trans(*lpdest, ((qbyte *)acolormap)[apalremap[*lptex] + (llight & 0xFF00)]); // gel mapping *lpdest = gelmap[*lpdest]; *lpz = lzi >> 16; } @@ -745,7 +745,7 @@ void D_PolysetDrawSpans16 (spanpackage_t *pspanpackage) { // ((qbyte *)acolormap)[*lptex + (llight & 0xFF00)]; lptex = (qbyte *)((unsigned char *)r_affinetridesc.pskin+tex); - lpdest[0] = ((unsigned short *)acolormap)[*lptex + (llight & 0xFF00)]; + lpdest[0] = ((unsigned short *)acolormap)[apalremap[*lptex] + (llight & 0xFF00)]; *lpz = lzi >> 16; } lpdest++; @@ -1123,7 +1123,7 @@ void D_PolysetDrawFinalVertsC (finalvert_t *fv, int numverts) *zbuf = z; pix = skintable[fv->v[3]>>16][fv->v[2]>>16]; - pix = ((qbyte *)acolormap)[pix + (fv->v[4] & 0xFF00) ]; + pix = ((qbyte *)acolormap)[apalremap[pix] + (fv->v[4] & 0xFF00) ]; d_viewbuffer[d_scantable[fv->v[1]] + fv->v[0]] = pix; } } @@ -1207,7 +1207,7 @@ void D_DrawSubdivC (void) *zbuf = z; pix = skintable[index0->v[3]>>16][index0->v[2]>>16]; - pix = ((qbyte *)acolormap)[pix + (index0->v[4] & 0xFF00) ]; + pix = ((qbyte *)acolormap)[apalremap[pix] + (index0->v[4] & 0xFF00) ]; d_viewbuffer[d_scantable[index0->v[1]] + index0->v[0]] = pix;//Trans(d_viewbuffer[d_scantable[index0->v[1]] + index0->v[0]], pix); } } @@ -1222,7 +1222,7 @@ void D_DrawSubdivC (void) *zbuf = z; pix = skintable[index1->v[3]>>16][index1->v[2]>>16]; - pix = ((qbyte *)acolormap)[pix + (index0->v[4] & 0xFF00) ]; + pix = ((qbyte *)acolormap)[apalremap[pix] + (index0->v[4] & 0xFF00) ]; d_viewbuffer[d_scantable[index1->v[1]] + index1->v[0]] = pix;//Trans(d_viewbuffer[d_scantable[index0->v[1]] + index0->v[0]], pix); } } @@ -1237,7 +1237,7 @@ void D_DrawSubdivC (void) *zbuf = z; pix = skintable[index2->v[3]>>16][index2->v[2]>>16]; - pix = ((qbyte *)acolormap)[pix + (index0->v[4] & 0xFF00) ]; + pix = ((qbyte *)acolormap)[apalremap[pix] + (index0->v[4] & 0xFF00) ]; d_viewbuffer[d_scantable[index2->v[1]] + index2->v[0]] = pix;//Trans(d_viewbuffer[d_scantable[index0->v[1]] + index0->v[0]], pix); } } @@ -1442,7 +1442,7 @@ split: int pix; *zbuf = z; - pix = d_pcolormap[skintable[new[3]>>16][new[2]>>16]]; + pix = d_pcolormap[apalremap[skintable[new[3]>>16][new[2]>>16]]]; d_viewbuffer[d_scantable[new[1]] + new[0]] = pix; } @@ -1756,7 +1756,7 @@ void D_PolysetDrawSpans8C (spanpackage_t *pspanpackage) { if ((lzi >> 16) >= *lpz) { - *lpdest = ((qbyte *)acolormap)[*lptex + (llight & 0xFF00)]; + *lpdest = ((qbyte *)acolormap)[apalremap[*lptex] + (llight & 0xFF00)]; // gel mapping *lpdest = gelmap[*lpdest]; *lpz = lzi >> 16; } @@ -2557,7 +2557,7 @@ split: int pix; d_pzbuffer[ofs] = new[5]; - pix = skintable[new[3]>>16][new[2]>>16]; + pix = apalremap[skintable[new[3]>>16][new[2]>>16]]; // pix = ((qbyte *)acolormap)[pix + (new[4] & 0xFF00)]; d_viewbuffer[ofs] = pix; } diff --git a/engine/sw/d_scan.c b/engine/sw/d_scan.c index 03d782cee..99ac8beee 100644 --- a/engine/sw/d_scan.c +++ b/engine/sw/d_scan.c @@ -1375,7 +1375,7 @@ void D_DrawSpans8 (espan_t *pspan) do { - *((unsigned int *)pdest)++ = *((pbase + (s >> 16) + (t >> 16) * cachewidth))* 0x01010101; + *((unsigned int *)pdest)++ = *((pbase + (s >> 16) + (t >> 16) * cachewidth)) * 0x01010101; s += sstep<<2; t += tstep<<2; } while((spancount-=4) > 3); diff --git a/engine/sw/d_trans.c b/engine/sw/d_trans.c index 7fdd076bc..7791f20d7 100644 --- a/engine/sw/d_trans.c +++ b/engine/sw/d_trans.c @@ -7,32 +7,55 @@ void MakeVideoPalette(void); void MakeSwizzledPalette(void); -void MakeFullbrightRemap(void); +void MakePaletteRemaps(void); int *srctable; int *dsttable; qbyte *pal555to8; int swzpal[TRANS_LEVELS][256]; -qbyte nofbremap[256]; + +// menutint +palremap_t *RebuildMenuTint(void); +palremap_t *mtpalremap; + +extern cvar_t r_menutint; +int mtmodified; #define palette host_basepal #define _abs(x) ((x)*(x)) +void D_ShutdownTrans(void) +{ + if (pal555to8) + { + BZ_Free(pal555to8); + pal555to8 = NULL; + } + + if (palremaps) + { + BZ_Free(palremaps); + palremapsize = 0; + palremaps = NULL; + } + + mtpalremap = NULL; + mtmodified = 0; +} + void D_InitTrans(void) { // create pal555to8 and swizzled palette MakeVideoPalette(); MakeSwizzledPalette(); - MakeFullbrightRemap(); + MakePaletteRemaps(); srctable = swzpal[0]; dsttable = swzpal[TRANS_MAX]; + mtpalremap = RebuildMenuTint(); } -#if 0 -#define Trans(p, p2) (t_curlookupp[p][p2]) -#else // TODO: INLINE THESE FUNCTIONS qbyte FASTCALL Trans(qbyte p, qbyte p2) { @@ -42,7 +65,6 @@ qbyte FASTCALL Trans(qbyte p, qbyte p2) return pal555to8[x & (x >> 15)]; } -#endif qbyte FASTCALL AddBlend(qbyte p, qbyte p2) { @@ -142,7 +164,7 @@ qbyte GetPalette(int red, int green, int blue) qbyte GetPaletteNoFB(int red, int green, int blue) { if (pal555to8) //fast precalculated (but ugly) method - return nofbremap[FindPalette(red,green,blue)]; + return fbremapidx(FindPalette(red,green,blue)); else //slow, horrible (but accurate) method. return FindIndexFromRGBNoFB(red, green, blue); } @@ -173,7 +195,7 @@ void MakeVideoPalette(void) FindIndexFromRGB(r<<3|r>>2, g<<3|g>>2, b<<3|b>>2); // write palette conversion table - if (r_palconvwrite.value) + if (d_palconvwrite.value) COM_WriteFile("pal555.pal", pal555to8, PAL555_SIZE); } @@ -200,18 +222,45 @@ void MakeSwizzledPalette(void) } } -void MakeFullbrightRemap(void) +// colormap functions +void MakePaletteRemaps(void) { int i; + palremapsize = d_palremapsize.value; + + if (palremapsize < 4) + { + Con_Printf("Invalid size for d_palremapsize, defaulting to 4.\n"); + palremapsize = 4; + } + + palremaps = BZ_Malloc(sizeof(palremap_t)*palremapsize); + + // build identity remap + palremaps[0].r = palremaps[0].g = palremaps[0].b = 255; + palremaps[0].key = 0x1 ^ 0x4 ^ 0; + palremaps[0].references = 999; + for (i = 0; i < 256; i++) + palremaps[0].pal[i] = i; + + // build fullbright remap + palremaps[1].r = palremaps[1].g = palremaps[1].b = 255; + palremaps[1].key = 0x1 ^ 0; + palremaps[1].references = 999; for (i = 0; i < 256 - vid.fullbright; i++) - nofbremap[i] = i; + palremaps[1].pal[i] = i; for (i = 256 - vid.fullbright; i < 256; i++) - nofbremap[i] = FindIndexFromRGBNoFB(host_basepal[i*3], host_basepal[i*3+1], host_basepal[i*3+2]); + palremaps[1].pal[i] = FindIndexFromRGBNoFB(host_basepal[i*3], host_basepal[i*3+1], host_basepal[i*3+2]); + + for (i = 2; i < palremapsize; i++) + { + palremaps[i].key = 0; + palremaps[i].references = 0; + } } -// colormap functions -void BuildModulatedColormap(qbyte *indexes, int red, int green, int blue, qboolean desaturate, qboolean fullbrights) +void BuildModulatedPalette(qbyte *indexes, int red, int green, int blue, qboolean desaturate, qboolean fullbrights, int topcolor, int bottomcolor) { qbyte *rgb = host_basepal; unsigned int r, g, b, x, invmask = 0; @@ -219,8 +268,7 @@ void BuildModulatedColormap(qbyte *indexes, int red, int green, int blue, qboole if (red < 0 || green < 0 || blue < 0) invmask = 0xff; - // generate colormap - + // generate palette remap if (desaturate) { int s; @@ -246,6 +294,14 @@ void BuildModulatedColormap(qbyte *indexes, int red, int green, int blue, qboole rgb += 3; } } + else if (red == 255 && green == 255 && blue == 255) + { + // identity merge + if (fullbrights) + memcpy(indexes, identityremap.pal, sizeof(identityremap)); + else + memcpy(indexes, fullbrightremap.pal, sizeof(fullbrightremap)); + } else { for (x = 0; x < 256; x++) @@ -270,6 +326,125 @@ void BuildModulatedColormap(qbyte *indexes, int red, int green, int blue, qboole } } + // handle top/bottom remap + if (topcolor == TOP_DEFAULT && bottomcolor == BOTTOM_DEFAULT) + return; + + { + qbyte topcolors[16]; + qbyte bottomcolors[16]; + + topcolor = topcolor * 16; + bottomcolor = bottomcolor * 16; + + for (x = 0; x < 16; x++) + { + if (topcolor < 128) + topcolors[x] = indexes[topcolor + x]; + else + topcolors[x] = indexes[topcolor + 15 - x]; + + if (bottomcolor < 128) + bottomcolors[x] = indexes[bottomcolor + x]; + else + bottomcolors[x] = indexes[bottomcolor + 15 - x]; + } + + for (x = 0; x < 16; x++) + { + indexes[TOP_RANGE + x] = topcolors[x]; + indexes[BOTTOM_RANGE + x] = bottomcolors[x]; + } + } +} + +palremap_t *D_GetPaletteRemap(int red, int green, int blue, qboolean desaturate, qboolean fullbrights, int topcolor, int bottomcolor) +{ + int i, key, deref = -1; + + topcolor = topcolor & 0xf; + bottomcolor = bottomcolor & 0xf; + + key = 0x1 ^ ((!!desaturate) << 1) ^ ((!!fullbrights) << 2) ^ (topcolor << 3) ^ (bottomcolor << 7); + + for (i = 0; i < palremapsize; i++) + { + if (palremaps[i].r == red && + palremaps[i].g == green && + palremaps[i].b == blue && + palremaps[i].key == key) + { + palremaps[i].references++; + return palremaps + i; + } + else if (palremaps[i].references <= 0) + deref = i; + } + + if (deref < 2) // no remaps found and all maps are referenced + return palremaps; // identity remap + + // return non-referenced map + BuildModulatedPalette(palremaps[deref].pal, red, green, blue, desaturate, fullbrights, topcolor, bottomcolor); + palremaps[deref].references++; + palremaps[deref].r = red; + palremaps[deref].g = green; + palremaps[deref].b = blue; + palremaps[deref].key = key; + return palremaps + deref; +} + +palremap_t *RebuildMenuTint(void) +{ + char *t; + int r, g, b; + + r = 255*r_menutint.value; + g = 0; + b = 0; + t = strstr(r_menutint.string, " "); + if (t) + { + g = 255*atof(t+1); + t = strstr(t+1, " "); + if (t) + b = 255*atof(t+1); + else + return NULL; + } + else + return NULL; + + return D_GetPaletteRemap(r, g, b, true, true, TOP_DEFAULT, BOTTOM_DEFAULT); +} + +void D_DereferenceRemap(palremap_t *palremap) +{ + if (palremap && palremap >= palremaps+2) + palremap->references--; +} + +qbyte *D_GetMenuTintPal(void) +{ + if (mtmodified != r_menutint.modified) + { + if (mtpalremap) + D_DereferenceRemap(mtpalremap); + + mtpalremap = RebuildMenuTint(); + mtmodified = r_menutint.modified; + } + + if (mtpalremap && mtpalremap != palremaps) + return mtpalremap->pal; + else + return NULL; +} + + +palremap_t *D_IdentityRemap(void) // TODO: explicitly inline this +{ + return palremaps; } void MediaSW_ShowFrame8bit(qbyte *framedata, int inwidth, int inheight, qbyte *palette) diff --git a/engine/sw/r_alias.c b/engine/sw/r_alias.c index 6574aa851..46475cc5e 100644 --- a/engine/sw/r_alias.c +++ b/engine/sw/r_alias.c @@ -40,7 +40,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. mtriangle_t *ptriangles; affinetridesc_t r_affinetridesc; -void * acolormap; // FIXME: should go away +void *acolormap; // FIXME: should go away +qbyte *apalremap; dtrivertx_t *r_apoldverts; dtrivertx_t *r_apnewverts; @@ -909,8 +910,8 @@ void R_AliasDrawModel (alight_t *plighting) R_AliasSetupLighting (plighting); R_AliasSetupFrame (); - if (!currententity->colormap) - currententity->colormap = vid.colormap; + if (!currententity->palremap) + currententity->palremap = D_IdentityRemap(); // Sys_Error ("R_AliasDrawModel: !currententity->colormap"); r_affinetridesc.drawtype = (currententity->trivial_accept == 3) && @@ -918,6 +919,11 @@ void R_AliasDrawModel (alight_t *plighting) r_affinetridesc.pstverts = (mstvert_t *)((qbyte *)paliashdr + paliashdr->stverts); + apalremap = currententity->palremap->pal; + acolormap = vid.colormap; + if (r_pixbytes == 2) + acolormap = vid.colormap16; + if (r_affinetridesc.drawtype) { D_PolysetUpdateTables (); // FIXME: precalc... @@ -925,14 +931,10 @@ void R_AliasDrawModel (alight_t *plighting) else { #if id386 - D_Aff8Patch (currententity->colormap); + D_Aff8Patch (acolormap, apalremap); #endif } - acolormap = currententity->colormap; - if (r_pixbytes == 2) - acolormap = vid.colormap16; - if (currententity == &cl.viewent[r_refdef.currentplayernum] || currententity->flags & Q2RF_DEPTHHACK) ziscale = (float)0x8000 * (float)0x10000 * 3.0; else diff --git a/engine/sw/r_main.c b/engine/sw/r_main.c index 700e0d16e..755a3371f 100644 --- a/engine/sw/r_main.c +++ b/engine/sw/r_main.c @@ -209,6 +209,7 @@ void SWR_DeInit (void) Cmd_RemoveCommand ("pointfile"); SWDraw_Shutdown(); + D_Shutdown(); } /* diff --git a/engine/sw/sw_draw.c b/engine/sw/sw_draw.c index e6d7125b9..771697b27 100644 --- a/engine/sw/sw_draw.c +++ b/engine/sw/sw_draw.c @@ -2379,53 +2379,14 @@ Draw_FadeScreen ================ */ -char fscolormap[256]; -int fsnodraw = 1; -int fsmodified; - void SWDraw_FadeScreen (void) { int x,y; - extern cvar_t r_menutint; VID_UnlockBuffer (); S_ExtraUpdate (); VID_LockBuffer (); - if (fsmodified != r_menutint.modified) - { - char *t; - int r, g, b; - - qbyte *rgb = (qbyte *)host_basepal; - - // parse r_menutint - fsnodraw = 0; - r = 255*r_menutint.value; - g = 0; - b = 0; - t = strstr(r_menutint.string, " "); - if (t) - { - g = 255*atof(t+1); - t = strstr(t+1, " "); - if (t) - b = 255*atof(t+1); - else - fsnodraw = 1; - } - else - fsnodraw = 1; - - // rebuild colormap here - BuildModulatedColormap(fscolormap, r, g, b, true, true); - - fsmodified = r_menutint.modified; - } - - if (fsnodraw) - return; - if (r_pixbytes == 4) { qbyte *pbuf; @@ -2458,7 +2419,12 @@ void SWDraw_FadeScreen (void) } else { - qbyte *pbuf; + qbyte *pbuf; + qbyte *mtpal = D_GetMenuTintPal(); + + if (!mtpal) + return; + for (y=0 ; y