From 638214ba10a259bdf280283c07fde37f1df874f2 Mon Sep 17 00:00:00 2001 From: Fabian Greffrath Date: Fri, 1 Nov 2024 21:11:19 +0100 Subject: [PATCH 1/2] additive translucency for fullbright sprites Fixes #1968 --- src/doomstat.c | 2 +- src/doomstat.h | 9 +- src/mn_setup.c | 11 ++- src/r_data.c | 236 +++++++++++++++++++++++++++---------------------- src/r_data.h | 1 + src/r_draw.c | 2 + src/r_main.c | 3 +- src/r_things.c | 3 +- 8 files changed, 157 insertions(+), 110 deletions(-) diff --git a/src/doomstat.c b/src/doomstat.c index 0ff988b0f..5725512a2 100644 --- a/src/doomstat.c +++ b/src/doomstat.c @@ -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 diff --git a/src/doomstat.h b/src/doomstat.h index 5a2e18a15..6deabf507 100644 --- a/src/doomstat.h +++ b/src/doomstat.h @@ -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 diff --git a/src/mn_setup.c b/src/mn_setup.c index eece5e77d..dc43644e0 100644 --- a/src/mn_setup.c +++ b/src/mn_setup.c @@ -357,6 +357,7 @@ enum str_bobbing_pct, str_screen_melt, str_invul_mode, + str_translucency, }; static const char **GetStrings(int id); @@ -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" }; @@ -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}, @@ -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) diff --git a/src/r_data.c b/src/r_data.c index f8dd72821..a3a6568b1 100644 --- a/src/r_data.c +++ b/src/r_data.c @@ -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" @@ -919,133 +920,160 @@ int R_ColormapNumForName(const char *name) 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<=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 diff --git a/src/r_data.h b/src/r_data.h index feb21e59d..f6f7701d1 100644 --- a/src/r_data.h +++ b/src/r_data.h @@ -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; diff --git a/src/r_draw.c b/src/r_draw.c index 3d0f726d3..0b375ef98 100644 --- a/src/r_draw.c +++ b/src/r_draw.c @@ -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. diff --git a/src/r_main.c b/src/r_main.c index 1107f23ff..8b03e4a28 100644 --- a/src/r_main.c +++ b/src/r_main.c @@ -1034,7 +1034,8 @@ void R_BindRenderVariables(void) BIND_BOOL(flashing_hom, true, "Enable flashing of the HOM indicator"); BIND_NUM(screenblocks, 10, 3, 11, "Size of game-world screen"); - M_BindBool("translucency", &translucency, NULL, true, ss_gen, wad_yes, + M_BindNum("translucency", &translucency, NULL, TRANSLUCENCY_BOOM, + TRANSLUCENCY_OFF, TRANSLUCENCY_ADD, ss_gen, wad_yes, "Translucency for some things"); M_BindNum("tran_filter_pct", &tran_filter_pct, NULL, 66, 0, 100, ss_gen, wad_yes, diff --git a/src/r_things.c b/src/r_things.c index 140668f54..2853c39fe 100644 --- a/src/r_things.c +++ b/src/r_things.c @@ -450,7 +450,8 @@ void R_DrawVisSprite(vissprite_t *vis, int x1, int x2) && vis->mobjflags & MF_TRANSLUCENT) // phares { colfunc = R_DrawTLColumn; - tranmap = main_tranmap; // killough 4/11/98 + tranmap = (dc_colormap[0] == fullcolormap) ? + fullbright_tranmap : main_tranmap; // killough 4/11/98 } else colfunc = R_DrawColumn; // killough 3/14/98, 4/11/98 From f7a74c7fb23f3ab565261a2cca3fafb1fa2a6c64 Mon Sep 17 00:00:00 2001 From: Fabian Greffrath Date: Fri, 1 Nov 2024 21:16:18 +0100 Subject: [PATCH 2/2] remove translucency cheat --- src/m_cheat.c | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/src/m_cheat.c b/src/m_cheat.c index 66f95a78f..eeabc5267 100644 --- a/src/m_cheat.c +++ b/src/m_cheat.c @@ -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(); @@ -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 @@ -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