Skip to content

Commit

Permalink
add "refraction" and "shadow" fuzz modes (#2043)
Browse files Browse the repository at this point in the history
* use Ceski's naming

* add simple "Shadow" mode

* add little noise using formula from Nugget Doom

* don't allow in netgame
  • Loading branch information
rfomin authored Dec 8, 2024
1 parent 458c61a commit 84a56a2
Show file tree
Hide file tree
Showing 4 changed files with 196 additions and 15 deletions.
9 changes: 9 additions & 0 deletions src/mn_setup.c
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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"},
Expand All @@ -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"}},
Expand Down Expand Up @@ -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
Expand Down
188 changes: 176 additions & 12 deletions src/r_draw.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

Expand Down Expand Up @@ -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;

void R_SetFuzzColumnMode(void)
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)
{
if (fuzzcolumn_mode && current_video_height > SCREENHEIGHT)
boolean cutoff = false;

// Adjust borders. Low...
if (!dc_yl)
{
fuzzblocksize = FixedToInt(video.yscale);
R_DrawFuzzColumn = R_DrawFuzzColumn_block;
dc_yl = 1;
}
else

// .. 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)
{
R_DrawFuzzColumn = R_DrawFuzzColumn_orig;
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)
{
fuzzmode_t mode =
strictmode || (netgame && !solonet) ? FUZZ_BLOCKY : fuzzmode;

switch (mode)
{
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;
}
}

Expand Down
9 changes: 8 additions & 1 deletion src/r_draw.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);
Expand Down
5 changes: 3 additions & 2 deletions src/r_main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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");
Expand Down

0 comments on commit 84a56a2

Please sign in to comment.