Skip to content

Commit 638214b

Browse files
additive translucency for fullbright sprites
Fixes #1968
1 parent 3d8ec36 commit 638214b

File tree

8 files changed

+157
-110
lines changed

8 files changed

+157
-110
lines changed

src/doomstat.c

+1-1
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@ demo_version_t demo_version; // killough 7/19/98: Boom version of demo
6565
// v1.1-like pitched sounds
6666
boolean pitched_sounds; // killough 10/98
6767

68-
boolean translucency; // killough 10/98
68+
translucency_t translucency; // killough 10/98
6969

7070
int allow_pushers = 1; // MT_PUSH Things // phares 3/10/98
7171
int default_allow_pushers; // killough 3/1/98: make local to each game

src/doomstat.h

+8-1
Original file line numberDiff line numberDiff line change
@@ -122,7 +122,14 @@ extern boolean monkeys, default_monkeys;
122122
// v1.1-like pitched sounds
123123
extern boolean pitched_sounds;
124124

125-
extern boolean translucency;
125+
typedef enum
126+
{
127+
TRANSLUCENCY_OFF,
128+
TRANSLUCENCY_BOOM,
129+
TRANSLUCENCY_ADD
130+
} translucency_t;
131+
132+
extern translucency_t translucency;
126133

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

src/mn_setup.c

+9-2
Original file line numberDiff line numberDiff line change
@@ -357,6 +357,7 @@ enum
357357
str_bobbing_pct,
358358
str_screen_melt,
359359
str_invul_mode,
360+
str_translucency,
360361
};
361362

362363
static const char **GetStrings(int id);
@@ -3242,6 +3243,10 @@ static void SmoothLight(void)
32423243
setsizeneeded = true; // run R_ExecuteSetViewSize
32433244
}
32443245

3246+
static const char *translucency_strings[] = {
3247+
"Off", "Boom", "Add"
3248+
};
3249+
32453250
static const char *exit_sequence_strings[] = {
32463251
"Off", "Sound Only", "PWAD ENDOOM", "On"
32473252
};
@@ -3251,8 +3256,9 @@ static setup_menu_t gen_settings5[] = {
32513256
{"Smooth Pixel Scaling", S_ONOFF, OFF_CNTR_X, M_SPC, {"smooth_scaling"},
32523257
.action = ResetVideo},
32533258

3254-
{"Sprite Translucency", S_ONOFF | S_STRICT, OFF_CNTR_X, M_SPC,
3255-
{"translucency"}},
3259+
{"Sprite Translucency", S_CHOICE | S_STRICT, OFF_CNTR_X, M_SPC,
3260+
{"translucency"}, .strings_id = str_translucency,
3261+
.action = MN_Trans},
32563262

32573263
{"Translucency Filter", S_NUM | S_ACTION | S_PCT, OFF_CNTR_X, M_SPC,
32583264
{"tran_filter_pct"}, .action = MN_Trans},
@@ -4822,6 +4828,7 @@ static const char **selectstrings[] = {
48224828
bobbing_pct_strings,
48234829
screen_melt_strings,
48244830
invul_mode_strings,
4831+
translucency_strings,
48254832
};
48264833

48274834
static const char **GetStrings(int id)

src/r_data.c

+132-104
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
#include "doomstat.h"
3232
#include "i_printf.h"
3333
#include "i_system.h"
34+
#include "i_video.h"
3435
#include "info.h"
3536
#include "m_argv.h" // M_CheckParm()
3637
#include "m_fixed.h"
@@ -919,133 +920,160 @@ int R_ColormapNumForName(const char *name)
919920

920921
int tran_filter_pct = 66; // filter percent
921922

922-
#define TSC 12 /* number of fixed point digits in filter percent */
923-
924923
void R_InitTranMap(int progress)
925924
{
926-
int lump = W_CheckNumForName("TRANMAP");
927-
//!
928-
// @category mod
929-
//
930-
// Forces a (re-)building of the translucency and color translation tables.
931-
//
932-
int force_rebuild = M_CheckParm("-tranmap");
925+
//!
926+
// @category mod
927+
//
928+
// Forces a (re-)building of the translucency and color translation tables.
929+
//
933930

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

936-
if (lump != -1 && !force_rebuild) // Set a pointer to the translucency filter maps.
937-
main_tranmap = W_CacheLumpNum(lump, PU_STATIC); // killough 4/11/98
938-
else
939-
{ // Compose a default transparent filter map based on PLAYPAL.
940-
unsigned char *playpal = W_CacheLumpName("PLAYPAL", PU_STATIC);
941-
char *fname = M_StringJoin(D_DoomPrefDir(), DIR_SEPARATOR_S, "tranmap.dat");
942-
struct {
943-
unsigned char pct;
944-
unsigned char playpal[256*3]; // [FG] a palette has 256 colors saved as byte triples
945-
} cache;
946-
FILE *cachefp = M_fopen(fname,"r+b");
947-
948-
if (main_tranmap == NULL) // [FG] prevent memory leak
949-
{
950-
main_tranmap = Z_Malloc(256*256, PU_STATIC, 0); // killough 4/11/98
951-
}
933+
// If a tranlucency filter map lump is present, use it
934+
int lump = W_CheckNumForName("TRANMAP");
952935

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

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

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

969-
{
970-
register int i = 255;
971-
register const unsigned char *p = playpal+255*3;
972-
do
973-
{
974-
register long t,d;
975-
pal_w1[0][i] = (pal[0][i] = t = p[0]) * w1;
976-
d = t*t;
977-
pal_w1[1][i] = (pal[1][i] = t = p[1]) * w1;
978-
d += t*t;
979-
pal_w1[2][i] = (pal[2][i] = t = p[2]) * w1;
980-
d += t*t;
981-
p -= 3;
982-
tot[i] = d << (TSC-1);
983-
}
984-
while (--i>=0);
985-
}
958+
if (main_tranmap == NULL) // [FG] prevent memory leak
959+
{
960+
main_tranmap =
961+
Z_Malloc(256 * 256 * 2, PU_STATIC, 0); // killough 4/11/98
962+
add_tranmap = main_tranmap + 256 * 256;
963+
}
986964

987-
// Next, compute all entries using minimum arithmetic.
965+
// Use cached translucency filter if it's available
988966

989-
{
990-
int i,j;
991-
byte *tp = main_tranmap;
992-
for (i=0;i<256;i++)
993-
{
994-
long r1 = pal[0][i] * w2;
995-
long g1 = pal[1][i] * w2;
996-
long b1 = pal[2][i] * w2;
967+
if (!cachefp ? cachefp = M_fopen(fname, "w+b"),
968+
true : // [FG] open for writing and reading
969+
fread(&cache, 1, sizeof cache, cachefp) != sizeof cache
970+
|| cache.pct != tran_filter_pct
971+
|| memcmp(cache.playpal, playpal, sizeof cache.playpal)
972+
|| fread(main_tranmap, 256, 256 * 2, cachefp) != 256 * 2
973+
|| // killough 4/11/98
974+
force_rebuild)
975+
{
976+
byte *tp = main_tranmap, *ap = add_tranmap;
997977

978+
for (int i = 0; i < 256; i++)
979+
{
998980
if (!(i & 31) && progress)
999-
I_PutChar(VB_INFO, '.');
981+
{
982+
I_PutChar(VB_INFO, '.');
983+
}
984+
985+
if (!(~i & 15))
986+
{
987+
if (i & 32) // killough 10/98: display flashing disk
988+
{
989+
I_EndRead();
990+
}
991+
else
992+
{
993+
I_BeginRead(DISK_ICON_THRESHOLD);
994+
}
995+
}
996+
997+
for (int j = 0; j < 256; j++)
998+
{
999+
byte *bg = playpal + 3 * i;
1000+
byte *fg = playpal + 3 * j;
1001+
byte blend[3];
1002+
enum {r, g, b};
1003+
1004+
blend[r] = MIN(fg[r] + bg[r], 255);
1005+
blend[g] = MIN(fg[g] + bg[g], 255);
1006+
blend[b] = MIN(fg[b] + bg[b], 255);
1007+
1008+
*ap++ = I_GetNearestColor(playpal, blend[r], blend[g],
1009+
blend[b]);
1010+
1011+
// [crispy] shortcut: identical foreground and background
1012+
if (i == j)
1013+
{
1014+
*tp++ = i;
1015+
continue;
1016+
}
1017+
1018+
// [crispy] blended color - emphasize blues
1019+
// Colour matching in RGB space doesn't work very well with
1020+
// the blues in Doom's palette. Rather than do any colour
1021+
// conversions, just emphasize the blues when building the
1022+
// translucency table.
1023+
int btmp = fg[b] * 1.666 < (fg[r] + fg[g]) ? 0 : 50;
1024+
blend[r] = (tran_filter_pct * fg[r]
1025+
+ (100 - tran_filter_pct) * bg[r])
1026+
/ (100 + btmp);
1027+
blend[g] = (tran_filter_pct * fg[g]
1028+
+ (100 - tran_filter_pct) * bg[g])
1029+
/ (100 + btmp);
1030+
blend[b] = (tran_filter_pct * fg[b]
1031+
+ (100 - tran_filter_pct) * bg[b])
1032+
/ 100;
1033+
1034+
*tp++ = I_GetNearestColor(playpal, blend[r], blend[g],
1035+
blend[b]);
1036+
}
1037+
}
10001038

1001-
if (!(~i & 15))
1002-
{
1003-
if (i & 32) // killough 10/98: display flashing disk
1004-
I_EndRead();
1005-
else
1006-
I_BeginRead(DISK_ICON_THRESHOLD);
1007-
}
1008-
1009-
for (j=0;j<256;j++,tp++)
1010-
{
1011-
register int color = 255;
1012-
register long err;
1013-
long r = pal_w1[0][j] + r1;
1014-
long g = pal_w1[1][j] + g1;
1015-
long b = pal_w1[2][j] + b1;
1016-
long best = LONG_MAX;
1017-
do
1018-
if ((err = tot[color] - pal[0][color]*r
1019-
- pal[1][color]*g - pal[2][color]*b) < best)
1020-
best = err, *tp = color;
1021-
while (--color >= 0);
1022-
}
1023-
}
10241039
// [FG] finish progress line
10251040
if (progress)
1026-
I_PutChar(VB_INFO, '\n');
1027-
}
1028-
if (cachefp && !force_rebuild) // write out the cached translucency map
10291041
{
1030-
cache.pct = tran_filter_pct;
1031-
memcpy(cache.playpal, playpal, sizeof cache.playpal); // [FG] a palette has 256 colors saved as byte triples
1032-
fseek(cachefp, 0, SEEK_SET);
1033-
fwrite(&cache, 1, sizeof cache, cachefp);
1034-
fwrite(main_tranmap, 256, 256, cachefp);
1042+
I_PutChar(VB_INFO, '\n');
1043+
}
1044+
1045+
if (cachefp
1046+
&& !force_rebuild) // write out the cached translucency map
1047+
{
1048+
cache.pct = tran_filter_pct;
1049+
memcpy(cache.playpal, playpal,
1050+
sizeof cache.playpal); // [FG] a palette has 256 colors
1051+
// saved as byte triples
1052+
fseek(cachefp, 0, SEEK_SET);
1053+
fwrite(&cache, 1, sizeof cache, cachefp);
1054+
fwrite(main_tranmap, 256, 256 * 2, cachefp);
1055+
}
1056+
}
1057+
else
1058+
{
1059+
if (progress)
1060+
{
1061+
I_Printf(VB_INFO, "........");
10351062
}
10361063
}
1037-
else
1038-
if (progress)
1039-
I_Printf(VB_INFO, "........");
10401064

1041-
if (cachefp) // killough 11/98: fix filehandle leak
1042-
fclose(cachefp);
1065+
if (cachefp) // killough 11/98: fix filehandle leak
1066+
{
1067+
fclose(cachefp);
1068+
}
10431069

1044-
Z_ChangeTag(playpal, PU_CACHE);
1045-
free(fname);
1070+
Z_ChangeTag(playpal, PU_CACHE);
1071+
free(fname);
10461072
}
1047-
}
10481073

1074+
fullbright_tranmap =
1075+
(translucency == TRANSLUCENCY_ADD) ? add_tranmap : main_tranmap;
1076+
}
10491077
//
10501078
// R_InitData
10511079
// Locates all the lumps

src/r_data.h

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ boolean R_IsPatchLump (const int lump);
5454
extern int numflats;
5555

5656
extern byte *main_tranmap, *tranmap;
57+
extern byte *fullbright_tranmap, *add_tranmap;
5758

5859
extern int tran_filter_pct;
5960

src/r_draw.c

+2
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,8 @@ static int linesize; // killough 11/98
6060
byte *tranmap; // translucency filter maps 256x256 // phares
6161
byte *main_tranmap; // killough 4/11/98
6262

63+
byte *fullbright_tranmap, *add_tranmap;
64+
6365
// Backing buffer containing the bezel drawn around the screen and surrounding
6466
// background.
6567

src/r_main.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -1034,7 +1034,8 @@ void R_BindRenderVariables(void)
10341034
BIND_BOOL(flashing_hom, true, "Enable flashing of the HOM indicator");
10351035
BIND_NUM(screenblocks, 10, 3, 11, "Size of game-world screen");
10361036

1037-
M_BindBool("translucency", &translucency, NULL, true, ss_gen, wad_yes,
1037+
M_BindNum("translucency", &translucency, NULL, TRANSLUCENCY_BOOM,
1038+
TRANSLUCENCY_OFF, TRANSLUCENCY_ADD, ss_gen, wad_yes,
10381039
"Translucency for some things");
10391040
M_BindNum("tran_filter_pct", &tran_filter_pct, NULL,
10401041
66, 0, 100, ss_gen, wad_yes,

src/r_things.c

+2-1
Original file line numberDiff line numberDiff line change
@@ -450,7 +450,8 @@ void R_DrawVisSprite(vissprite_t *vis, int x1, int x2)
450450
&& vis->mobjflags & MF_TRANSLUCENT) // phares
451451
{
452452
colfunc = R_DrawTLColumn;
453-
tranmap = main_tranmap; // killough 4/11/98
453+
tranmap = (dc_colormap[0] == fullcolormap) ?
454+
fullbright_tranmap : main_tranmap; // killough 4/11/98
454455
}
455456
else
456457
colfunc = R_DrawColumn; // killough 3/14/98, 4/11/98

0 commit comments

Comments
 (0)