add "refraction" and "shadow" fuzz modes (#2043)

* use Ceski's naming

* add simple "Shadow" mode

* add little noise using formula from Nugget Doom

* don't allow in netgame
This commit is contained in:
Roman Fomin 2024-12-08 10:22:54 +07:00 committed by GitHub
parent 458c61ae2d
commit 84a56a26f0
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 197 additions and 16 deletions

View File

@ -330,6 +330,7 @@ enum
str_overlay,
str_automap_preset,
str_automap_keyed_door,
str_fuzzmode,
str_weapon_slots_activation,
str_weapon_slots_selection,
str_weapon_slots,
@ -3239,6 +3240,10 @@ static const char *exit_sequence_strings[] = {
"Off", "Sound Only", "PWAD ENDOOM", "Full"
};
static const char *fuzzmode_strings[] = {
"Vanilla", "Refraction", "Shadow"
};
static setup_menu_t gen_settings5[] = {
{"Smooth Pixel Scaling", S_ONOFF, OFF_CNTR_X, M_SPC, {"smooth_scaling"},
@ -3250,6 +3255,9 @@ static setup_menu_t gen_settings5[] = {
{"Translucency Filter", S_NUM | S_ACTION | S_PCT, OFF_CNTR_X, M_SPC,
{"tran_filter_pct"}, .action = MN_Trans},
{"Partial Invisibility", S_CHOICE | S_STRICT, OFF_CNTR_X, M_SPC, {"fuzzmode"},
.strings_id = str_fuzzmode, .action = R_SetFuzzColumnMode},
MI_GAP,
{"Voxels", S_ONOFF | S_STRICT, OFF_CNTR_X, M_SPC, {"voxels_rendering"}},
@ -4788,6 +4796,7 @@ static const char **selectstrings[] = {
overlay_strings,
automap_preset_strings,
automap_keyed_door_strings,
fuzzmode_strings,
weapon_slots_activation_strings,
weapon_slots_selection_strings,
NULL, // str_weapon_slots

View File

@ -339,7 +339,7 @@ static const int fuzzoffset[FUZZTABLE] =
FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,
FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,
FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF,FUZZOFF,-FUZZOFF,FUZZOFF
};
};
static int fuzzpos = 0;
@ -370,7 +370,7 @@ void R_SetFuzzPosDraw(void)
// i.e. spectres and invisible players.
//
static void R_DrawFuzzColumn_orig(void)
static void DrawFuzzColumnOriginal(void)
{
boolean cutoff = false;
@ -448,7 +448,7 @@ static void R_DrawFuzzColumn_orig(void)
static int fuzzblocksize;
static void R_DrawFuzzColumn_block(void)
static void DrawFuzzColumnBlocky(void)
{
boolean cutoff = false;
@ -526,21 +526,185 @@ static void R_DrawFuzzColumn_block(void)
}
}
// [FG] spectre drawing mode: 0 original, 1 blocky (hires)
#define FUZZDARK 6 * 256
#define FUZZPAL 256
boolean fuzzcolumn_mode;
void (*R_DrawFuzzColumn)(void) = R_DrawFuzzColumn_orig;
static const int fuzzdark[FUZZTABLE] =
{
4 * FUZZPAL,0,6 * FUZZPAL,0,6 * FUZZPAL,6 * FUZZPAL,0,
6 * FUZZPAL,6 * FUZZPAL,0,6 * FUZZPAL,6 * FUZZPAL,6 * FUZZPAL,0,
6 * FUZZPAL,8 * FUZZPAL,6 * FUZZPAL,0,0,0,0,
4 * FUZZPAL,0,0,6 * FUZZPAL,6 * FUZZPAL,6 * FUZZPAL,6 * FUZZPAL,0,
4 * FUZZPAL,0,6 * FUZZPAL,6 * FUZZPAL,0,0,6 * FUZZPAL,
6 * FUZZPAL,0,0,0,0,6 * FUZZPAL,6 * FUZZPAL,
6 * FUZZPAL,6 * FUZZPAL,0,6 * FUZZPAL,6 * FUZZPAL,0,6 * FUZZPAL,
};
static void DrawFuzzColumnRefraction(void)
{
boolean cutoff = false;
if (dc_x % fuzzblocksize)
{
return;
}
if (!dc_yl)
{
dc_yl = 1;
}
if (dc_yh == viewheight - 1)
{
dc_yh = viewheight - 2;
cutoff = true;
}
int count = dc_yh - dc_yl;
if (count < 0)
{
return;
}
#ifdef RANGECHECK
if ((unsigned)dc_x >= video.width || dc_yl < 0 || dc_yh >= video.height)
{
I_Error("R_DrawFuzzColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
}
#endif
++count;
byte *dest = ylookup[dc_yl] + columnofs[dc_x];
int lines = fuzzblocksize - (dc_yl % fuzzblocksize);
int dark = FUZZDARK;
int offset = 0;
do
{
count -= lines;
// if (count < 0)
// {
// lines += count;
// count = 0;
// }
const int mask = count >> (8 * sizeof(mask) - 1);
lines += count & mask;
count &= ~mask;
const byte fuzz = fullcolormap[dark + dest[linesize * offset]];
do
{
memset(dest, fuzz, fuzzblocksize);
dest += linesize;
} while (--lines);
++fuzzpos;
// Clamp table lookup index.
fuzzpos &= (fuzzpos - FUZZTABLE) >> (8 * sizeof(fuzzpos) - 1); // killough 1/99
dark = fuzzdark[fuzzpos];
offset = fuzzoffset[fuzzpos];
lines = fuzzblocksize;
} while (count);
if (cutoff)
{
const byte fuzz =
fullcolormap[dark + dest[linesize * (offset - FUZZOFF) / 2]];
memset(dest, fuzz, fuzzblocksize);
}
}
static void DrawFuzzColumnShadow(void)
{
boolean cutoff = false;
// Adjust borders. Low...
if (!dc_yl)
{
dc_yl = 1;
}
// .. and high.
if (dc_yh == viewheight - 1)
{
dc_yh = viewheight - 2;
cutoff = true;
}
int count = dc_yh - dc_yl;
// Zero length.
if (count < 0)
{
return;
}
#ifdef RANGECHECK
if ((unsigned)dc_x >= video.width || dc_yl < 0 || dc_yh >= video.height)
{
I_Error("R_DrawFuzzColumn: %i to %i at %i", dc_yl, dc_yh, dc_x);
}
#endif
byte *dest = ylookup[dc_yl] + columnofs[dc_x];
count++; // killough 1/99: minor tuning
do
{
*dest = fullcolormap[8 * 256 + *dest];
dest += linesize; // killough 11/98
++fuzzpos;
// Clamp table lookup index.
fuzzpos &= (fuzzpos - FUZZTABLE) >> (8 * sizeof(fuzzpos) - 1); // killough 1/99
} while (--count);
if (cutoff)
{
*dest = fullcolormap[8 * 256 + *dest];
}
}
fuzzmode_t fuzzmode;
void (*R_DrawFuzzColumn)(void) = DrawFuzzColumnOriginal;
void R_SetFuzzColumnMode(void)
{
if (fuzzcolumn_mode && current_video_height > SCREENHEIGHT)
fuzzmode_t mode =
strictmode || (netgame && !solonet) ? FUZZ_BLOCKY : fuzzmode;
switch (mode)
{
fuzzblocksize = FixedToInt(video.yscale);
R_DrawFuzzColumn = R_DrawFuzzColumn_block;
}
else
{
R_DrawFuzzColumn = R_DrawFuzzColumn_orig;
case FUZZ_BLOCKY:
if (current_video_height > SCREENHEIGHT)
{
fuzzblocksize = FixedToInt(video.yscale);
R_DrawFuzzColumn = DrawFuzzColumnBlocky;
}
else
{
R_DrawFuzzColumn = DrawFuzzColumnOriginal;
}
break;
case FUZZ_REFRACTION:
fuzzblocksize = FixedToInt(video.yscale);
R_DrawFuzzColumn = DrawFuzzColumnRefraction;
break;
case FUZZ_SHADOW:
R_DrawFuzzColumn = DrawFuzzColumnShadow;
break;
}
}

View File

@ -48,7 +48,14 @@ void R_SetFuzzPosTic(void);
void R_SetFuzzPosDraw(void);
// [FG] spectre drawing mode
extern boolean fuzzcolumn_mode;
typedef enum
{
FUZZ_BLOCKY,
FUZZ_REFRACTION,
FUZZ_SHADOW,
} fuzzmode_t;
extern fuzzmode_t fuzzmode;
void R_SetFuzzColumnMode(void);
void R_DrawSkyColumn(void);

View File

@ -1041,8 +1041,9 @@ void R_BindRenderVariables(void)
M_BindBool("flipcorpses", &flipcorpses, NULL, false, ss_enem, wad_no,
"Randomly mirrored death animations");
M_BindBool("fuzzcolumn_mode", &fuzzcolumn_mode, NULL, true, ss_none, wad_no,
"Fuzz rendering (0 = Resolution-dependent; 1 = Blocky)");
M_BindNum("fuzzmode", &fuzzmode, NULL,
FUZZ_BLOCKY, FUZZ_BLOCKY, FUZZ_SHADOW, ss_none, wad_no,
"Partial Invisibility (0 = Vanilla; 1 = Refraction; 2 = Shadow)");
BIND_BOOL(draw_nearby_sprites, true,
"Draw sprites overlapping into visible sectors");