Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

additive translucency for fullbright sprites #1974

Open
wants to merge 2 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion src/doomstat.c
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@ demo_version_t demo_version; // killough 7/19/98: Boom version of demo
// v1.1-like pitched sounds
boolean pitched_sounds; // killough 10/98

boolean translucency; // killough 10/98
translucency_t translucency; // killough 10/98

int allow_pushers = 1; // MT_PUSH Things // phares 3/10/98
int default_allow_pushers; // killough 3/1/98: make local to each game
Expand Down
9 changes: 8 additions & 1 deletion src/doomstat.h
Original file line number Diff line number Diff line change
Expand Up @@ -122,7 +122,14 @@ extern boolean monkeys, default_monkeys;
// v1.1-like pitched sounds
extern boolean pitched_sounds;

extern boolean translucency;
typedef enum
{
TRANSLUCENCY_OFF,
TRANSLUCENCY_BOOM,
TRANSLUCENCY_ADD
} translucency_t;

extern translucency_t translucency;

extern int demo_insurance; // killough 4/5/98

Expand Down
15 changes: 0 additions & 15 deletions src/m_cheat.c
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ static void cheat_skill(char *buf);
static void cheat_skill0();
static void cheat_friction();
static void cheat_pushers();
static void cheat_tran();
static void cheat_massacre();
static void cheat_ddt();
static void cheat_hom();
Expand Down Expand Up @@ -280,19 +279,12 @@ struct cheat_s cheat[] = {
{"ammo", NULL, not_net | not_demo,
{cheat_ammox}, -1 }, // killough 2/16/98: end generalized weapons

{"tran", NULL, always,
{cheat_tran} }, // invoke translucency // phares

{"smart", NULL, not_net | not_demo,
{cheat_smart} }, // killough 2/21/98: smart monster toggle

{"pitch", NULL, always,
{cheat_pitch} }, // killough 2/21/98: pitched sound toggle

// killough 2/21/98: reduce RSI injury by adding simpler alias sequences:
{"mbfran", NULL, always,
{cheat_tran} }, // killough 2/21/98: same as mbftran

{"fast", NULL, not_net | not_demo,
{cheat_fast} }, // killough 3/6/98: -fast toggle

Expand Down Expand Up @@ -762,13 +754,6 @@ static void cheat_pushers()
(allow_pushers = !allow_pushers) ? "Pushers enabled" : "Pushers disabled");
}

// translucency cheat
static void cheat_tran()
{
displaymsg( // Ty 03/27/98 - *not* externalized
(translucency = !translucency) ? "Translucency enabled" : "Translucency disabled");
}

static void cheat_massacre() // jff 2/01/98 kill all monsters
{
// jff 02/01/98 'em' cheat - kill all monsters
Expand Down
11 changes: 9 additions & 2 deletions src/mn_setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -357,6 +357,7 @@ enum
str_bobbing_pct,
str_screen_melt,
str_invul_mode,
str_translucency,
};

static const char **GetStrings(int id);
Expand Down Expand Up @@ -3242,6 +3243,10 @@ static void SmoothLight(void)
setsizeneeded = true; // run R_ExecuteSetViewSize
}

static const char *translucency_strings[] = {
"Off", "Boom", "Add"
};

static const char *exit_sequence_strings[] = {
"Off", "Sound Only", "PWAD ENDOOM", "On"
};
Expand All @@ -3251,8 +3256,9 @@ static setup_menu_t gen_settings5[] = {
{"Smooth Pixel Scaling", S_ONOFF, OFF_CNTR_X, M_SPC, {"smooth_scaling"},
.action = ResetVideo},

{"Sprite Translucency", S_ONOFF | S_STRICT, OFF_CNTR_X, M_SPC,
{"translucency"}},
{"Sprite Translucency", S_CHOICE | S_STRICT, OFF_CNTR_X, M_SPC,
{"translucency"}, .strings_id = str_translucency,
.action = MN_Trans},

{"Translucency Filter", S_NUM | S_ACTION | S_PCT, OFF_CNTR_X, M_SPC,
{"tran_filter_pct"}, .action = MN_Trans},
Expand Down Expand Up @@ -4822,6 +4828,7 @@ static const char **selectstrings[] = {
bobbing_pct_strings,
screen_melt_strings,
invul_mode_strings,
translucency_strings,
};

static const char **GetStrings(int id)
Expand Down
236 changes: 132 additions & 104 deletions src/r_data.c
Original file line number Diff line number Diff line change
Expand Up @@ -31,6 +31,7 @@
#include "doomstat.h"
#include "i_printf.h"
#include "i_system.h"
#include "i_video.h"
#include "info.h"
#include "m_argv.h" // M_CheckParm()
#include "m_fixed.h"
Expand Down Expand Up @@ -676,7 +677,7 @@
directory = maptex+1;
}

offset = LONG(*directory);

Check warning on line 680 in src/r_data.c

View workflow job for this annotation

GitHub Actions / Clang-Tidy

src/r_data.c:680:16 [clang-analyzer-core.NullDereference]

Dereference of null pointer (loaded from variable 'directory')

if (offset > maxoff)
I_Error("R_InitTextures: bad texture directory");
Expand Down Expand Up @@ -919,133 +920,160 @@

int tran_filter_pct = 66; // filter percent

#define TSC 12 /* number of fixed point digits in filter percent */

void R_InitTranMap(int progress)
{
int lump = W_CheckNumForName("TRANMAP");
//!
// @category mod
//
// Forces a (re-)building of the translucency and color translation tables.
//
int force_rebuild = M_CheckParm("-tranmap");
//!
// @category mod
//
// Forces a (re-)building of the translucency and color translation tables.
//

// If a tranlucency filter map lump is present, use it
int force_rebuild = M_CheckParm("-tranmap");

if (lump != -1 && !force_rebuild) // Set a pointer to the translucency filter maps.
main_tranmap = W_CacheLumpNum(lump, PU_STATIC); // killough 4/11/98
else
{ // Compose a default transparent filter map based on PLAYPAL.
unsigned char *playpal = W_CacheLumpName("PLAYPAL", PU_STATIC);
char *fname = M_StringJoin(D_DoomPrefDir(), DIR_SEPARATOR_S, "tranmap.dat");
struct {
unsigned char pct;
unsigned char playpal[256*3]; // [FG] a palette has 256 colors saved as byte triples
} cache;
FILE *cachefp = M_fopen(fname,"r+b");

if (main_tranmap == NULL) // [FG] prevent memory leak
{
main_tranmap = Z_Malloc(256*256, PU_STATIC, 0); // killough 4/11/98
}
// If a tranlucency filter map lump is present, use it
int lump = W_CheckNumForName("TRANMAP");

// Use cached translucency filter if it's available
if (lump != -1 && W_LumpLength(lump) == 256 * 256 && !force_rebuild)
{
// Set a pointer to the translucency filter maps.
main_tranmap = W_CacheLumpNum(lump, PU_STATIC); // killough 4/11/98
add_tranmap = main_tranmap;
}
else
{
// Compose a default transparent filter map based on PLAYPAL.
unsigned char *playpal = W_CacheLumpName("PLAYPAL", PU_STATIC);
char *fname =
M_StringJoin(D_DoomPrefDir(), DIR_SEPARATOR_S, "tranmap.dat");

if (!cachefp ? cachefp = M_fopen(fname,"w+b") , 1 : // [FG] open for writing and reading
fread(&cache, 1, sizeof cache, cachefp) != sizeof cache ||
cache.pct != tran_filter_pct ||
memcmp(cache.playpal, playpal, sizeof cache.playpal) ||
fread(main_tranmap, 256, 256, cachefp) != 256 || // killough 4/11/98
force_rebuild)
struct
{
long pal[3][256], tot[256], pal_w1[3][256];
long w1 = ((unsigned long) tran_filter_pct<<TSC)/100;
long w2 = (1l<<TSC)-w1;
unsigned char pct;
unsigned char playpal[256 * 3]; // [FG] a palette has 256 colors
// saved as byte triples
} cache;

// First, convert playpal into long int type, and transpose array,
// for fast inner-loop calculations. Precompute tot array.
FILE *cachefp = M_fopen(fname, "r+b");

{
register int i = 255;
register const unsigned char *p = playpal+255*3;
do
{
register long t,d;
pal_w1[0][i] = (pal[0][i] = t = p[0]) * w1;
d = t*t;
pal_w1[1][i] = (pal[1][i] = t = p[1]) * w1;
d += t*t;
pal_w1[2][i] = (pal[2][i] = t = p[2]) * w1;
d += t*t;
p -= 3;
tot[i] = d << (TSC-1);
}
while (--i>=0);
}
if (main_tranmap == NULL) // [FG] prevent memory leak
{
main_tranmap =
Z_Malloc(256 * 256 * 2, PU_STATIC, 0); // killough 4/11/98
add_tranmap = main_tranmap + 256 * 256;
}

// Next, compute all entries using minimum arithmetic.
// Use cached translucency filter if it's available

{
int i,j;
byte *tp = main_tranmap;
for (i=0;i<256;i++)
{
long r1 = pal[0][i] * w2;
long g1 = pal[1][i] * w2;
long b1 = pal[2][i] * w2;
if (!cachefp ? cachefp = M_fopen(fname, "w+b"),
true : // [FG] open for writing and reading
fread(&cache, 1, sizeof cache, cachefp) != sizeof cache
|| cache.pct != tran_filter_pct
|| memcmp(cache.playpal, playpal, sizeof cache.playpal)
|| fread(main_tranmap, 256, 256 * 2, cachefp) != 256 * 2
|| // killough 4/11/98
force_rebuild)
{
byte *tp = main_tranmap, *ap = add_tranmap;

for (int i = 0; i < 256; i++)
{
if (!(i & 31) && progress)
I_PutChar(VB_INFO, '.');
{
I_PutChar(VB_INFO, '.');
}

if (!(~i & 15))
{
if (i & 32) // killough 10/98: display flashing disk
{
I_EndRead();
}
else
{
I_BeginRead(DISK_ICON_THRESHOLD);
}
}

for (int j = 0; j < 256; j++)
{
byte *bg = playpal + 3 * i;
byte *fg = playpal + 3 * j;
byte blend[3];
enum {r, g, b};

blend[r] = MIN(fg[r] + bg[r], 255);
blend[g] = MIN(fg[g] + bg[g], 255);
blend[b] = MIN(fg[b] + bg[b], 255);

*ap++ = I_GetNearestColor(playpal, blend[r], blend[g],
blend[b]);

// [crispy] shortcut: identical foreground and background
if (i == j)
{
*tp++ = i;
continue;
}

// [crispy] blended color - emphasize blues
// Colour matching in RGB space doesn't work very well with
// the blues in Doom's palette. Rather than do any colour
// conversions, just emphasize the blues when building the
// translucency table.
int btmp = fg[b] * 1.666 < (fg[r] + fg[g]) ? 0 : 50;
blend[r] = (tran_filter_pct * fg[r]
+ (100 - tran_filter_pct) * bg[r])
/ (100 + btmp);
blend[g] = (tran_filter_pct * fg[g]
+ (100 - tran_filter_pct) * bg[g])
/ (100 + btmp);
blend[b] = (tran_filter_pct * fg[b]
+ (100 - tran_filter_pct) * bg[b])
/ 100;

*tp++ = I_GetNearestColor(playpal, blend[r], blend[g],
blend[b]);
}
}

if (!(~i & 15))
{
if (i & 32) // killough 10/98: display flashing disk
I_EndRead();
else
I_BeginRead(DISK_ICON_THRESHOLD);
}

for (j=0;j<256;j++,tp++)
{
register int color = 255;
register long err;
long r = pal_w1[0][j] + r1;
long g = pal_w1[1][j] + g1;
long b = pal_w1[2][j] + b1;
long best = LONG_MAX;
do
if ((err = tot[color] - pal[0][color]*r
- pal[1][color]*g - pal[2][color]*b) < best)
best = err, *tp = color;
while (--color >= 0);
}
}
// [FG] finish progress line
if (progress)
I_PutChar(VB_INFO, '\n');
}
if (cachefp && !force_rebuild) // write out the cached translucency map
{
cache.pct = tran_filter_pct;
memcpy(cache.playpal, playpal, sizeof cache.playpal); // [FG] a palette has 256 colors saved as byte triples
fseek(cachefp, 0, SEEK_SET);
fwrite(&cache, 1, sizeof cache, cachefp);
fwrite(main_tranmap, 256, 256, cachefp);
I_PutChar(VB_INFO, '\n');
}

if (cachefp
&& !force_rebuild) // write out the cached translucency map
{
cache.pct = tran_filter_pct;
memcpy(cache.playpal, playpal,
sizeof cache.playpal); // [FG] a palette has 256 colors
// saved as byte triples
fseek(cachefp, 0, SEEK_SET);
fwrite(&cache, 1, sizeof cache, cachefp);
fwrite(main_tranmap, 256, 256 * 2, cachefp);
}
}
else
{
if (progress)
{
I_Printf(VB_INFO, "........");
}
}
else
if (progress)
I_Printf(VB_INFO, "........");

if (cachefp) // killough 11/98: fix filehandle leak
fclose(cachefp);
if (cachefp) // killough 11/98: fix filehandle leak
{
fclose(cachefp);
}

Z_ChangeTag(playpal, PU_CACHE);
free(fname);
Z_ChangeTag(playpal, PU_CACHE);
free(fname);
}
}

fullbright_tranmap =
(translucency == TRANSLUCENCY_ADD) ? add_tranmap : main_tranmap;
}
//
// R_InitData
// Locates all the lumps
Expand Down
1 change: 1 addition & 0 deletions src/r_data.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ boolean R_IsPatchLump (const int lump);
extern int numflats;

extern byte *main_tranmap, *tranmap;
extern byte *fullbright_tranmap, *add_tranmap;

extern int tran_filter_pct;

Expand Down
2 changes: 2 additions & 0 deletions src/r_draw.c
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,8 @@ static int linesize; // killough 11/98
byte *tranmap; // translucency filter maps 256x256 // phares
byte *main_tranmap; // killough 4/11/98

byte *fullbright_tranmap, *add_tranmap;

// Backing buffer containing the bezel drawn around the screen and surrounding
// background.

Expand Down
Loading