Generalize fullscreen tint application to more than one tint.

Currently, the only kinds of tint that can be applied simultaneously are
one "palfrom" per player, plus one loogie tint per player.  Each palfrom
still overrides the preceding one.  However, this is not a big problem IMO
since palfroms decrease at the same rate (loogie tint decreases at half the
speed).  This change is especially good for the splitscreen mod, since now
the tints of the two players won't compete with each other.  See the comment
in the source for some properties of the blending formula.

git-svn-id: https://svn.eduke32.com/eduke32@2954 1a8010ca-5511-0410-912e-c29ae57300e0
This commit is contained in:
helixhorned 2012-08-22 22:48:21 +00:00
parent ef8adcc51f
commit 96acc3dc52

View file

@ -311,14 +311,11 @@ void P_SetGamePalette(DukePlayer_t *player, uint8_t palid, int32_t set)
if (palid >= BASEPALCOUNT) if (palid >= BASEPALCOUNT)
palid = BASEPAL; palid = BASEPAL;
if (player != g_player[screenpeek].ps)
{
player->palette = palid;
return;
}
player->palette = palid; player->palette = palid;
if (player != g_player[screenpeek].ps)
return;
setbrightness(ud.brightness>>2, palid, set); setbrightness(ud.brightness>>2, palid, set);
} }
@ -2572,12 +2569,58 @@ static void M32_drawdebug(void)
} }
#endif #endif
////////// TINT ACCUMULATOR //////////
typedef struct {
int32_t r,g,b;
// f: 0-63 scale
int32_t maxf, sumf;
} palaccum_t;
#define PALACCUM_INITIALIZER { 0, 0, 0, 0, 0 }
/* For a picture frame F and n tints C_1, C_2, ... C_n weighted a_1, a_2,
* ... a_n (on a 0-1 scale), the faded frame is calculated as
*
* F_new := (1-max_i(a_i))*F + d*sum_i(a_i), where
*
* d := max_i(a_i)/sum_i(a_i).
*
* This means that
* 1) tint application is independent of their order.
* 2) going from n+1 to n tints is continuous.
*
* But note that for more than one tint, the composite tint will in general
* change its hue as the ratio of the weights of the individual ones changes.
*/
static void palaccum_add(palaccum_t *pa, const palette_t *pal, int32_t f)
{
f = clamp(f, 0, 63);
if (f == 0)
return;
pa->maxf = max(pa->maxf, f);
pa->sumf += f;
// TODO: we need to do away with this 0-63 scale weirdness someday.
pa->r += f*clamp(pal->r, 0, 63);
pa->g += f*clamp(pal->g, 0, 63);
pa->b += f*clamp(pal->b, 0, 63);
}
static void G_FadePalaccum(const palaccum_t *pa)
{
setpalettefade(pa->r/pa->sumf, pa->g/pa->sumf, pa->b/pa->sumf, pa->maxf);
}
////////// DISPLAYREST //////////
void G_DisplayRest(int32_t smoothratio) void G_DisplayRest(int32_t smoothratio)
{ {
int32_t a, i, j; int32_t a, i, j;
int32_t applyTint=0; palaccum_t tint = PALACCUM_INITIALIZER;
palette_t tempFade = { 0, 0, 0, 0 };
palette_t tempTint = { 0, 0, 0, 0 };
DukePlayer_t *const pp = g_player[screenpeek].ps; DukePlayer_t *const pp = g_player[screenpeek].ps;
DukePlayer_t *const pp2 = g_fakeMultiMode && ud.multimode==2 ? g_player[1].ps : NULL; DukePlayer_t *const pp2 = g_fakeMultiMode && ud.multimode==2 ? g_player[1].ps : NULL;
@ -2606,31 +2649,15 @@ void G_DisplayRest(int32_t smoothratio)
} }
#endif // USE_OPENGL #endif // USE_OPENGL
// this does pain tinting etc from the CON palaccum_add(&tint, &pp->pals, pp->pals.f);
// JBF 20040101: pals.f > 0 now >= 0 if (pp2)
// PK: was reset to > 0 (correctly, IMO) by TX in r1625. palaccum_add(&tint, &pp2->pals, pp2->pals.f);
if (pp->pals.f > 0 && pp->loogcnt == 0)
{ {
Bmemcpy(&tempFade, &pp->pals, sizeof(palette_t)); static const palette_t loogiepal = { 0, 63, 0, 0 };
applyTint = 1;
} palaccum_add(&tint, &loogiepal, pp->loogcnt>>1);
else if (pp2 && pp2->pals.f > 0 && pp2->loogcnt == 0) if (pp2)
{ palaccum_add(&tint, &loogiepal, pp2->loogcnt>>1);
Bmemcpy(&tempFade, &pp2->pals, sizeof(palette_t));
applyTint = 1;
}
// loogies courtesy of being snotted on
else if (pp->pals.f==0 && pp->loogcnt > 0)
{
palette_t lp = { 0, 64, 0, pp->loogcnt>>1 };
Bmemcpy(&tempFade, &lp, sizeof(palette_t));
applyTint = 1;
}
else if (pp2 && pp2->pals.f==0 && pp2->loogcnt > 0)
{
palette_t lp = { 0, 64, 0, pp2->loogcnt>>1 };
Bmemcpy(&tempFade, &lp, sizeof(palette_t));
applyTint = 1;
} }
if (g_restorePalette) if (g_restorePalette)
@ -2651,9 +2678,6 @@ void G_DisplayRest(int32_t smoothratio)
} }
} }
if (tempFade.f > 0 /*tempTint.f*/)
Bmemcpy(&tempTint, &tempFade, sizeof(palette_t));
if (ud.show_help) if (ud.show_help)
{ {
switch (ud.show_help) switch (ud.show_help)
@ -2678,9 +2702,6 @@ void G_DisplayRest(int32_t smoothratio)
G_UpdateScreenArea(); G_UpdateScreenArea();
} }
if (tempTint.f > 0 || applyTint)
G_FadePalette(tempTint.r,tempTint.g,tempTint.b,tempTint.f|128);
return; return;
} }
@ -2999,9 +3020,9 @@ void G_DisplayRest(int32_t smoothratio)
{ {
static int32_t applied = 0; static int32_t applied = 0;
if (tempTint.f > 0 || applyTint) if (tint.maxf)
{ {
G_FadePalette(tempTint.r,tempTint.g,tempTint.b,tempTint.f|128); G_FadePalaccum(&tint);
applied = 1; applied = 1;
} }
else if (applied) else if (applied)