Skip to content

Commit

Permalink
Heretic & Hexen: add option to toggle automap lines antialiasing
Browse files Browse the repository at this point in the history
Thick automap lines don't look great with antialiasing applied. This change makes antialiasing optional, allowing users to toggle it as needed.

Co-Authored-By: Julia Nechaevskaya <julia.nechaevskaya@live.com>
  • Loading branch information
pvictress and JNechaevsky committed Jan 7, 2025
1 parent 75051b3 commit d1d3120
Show file tree
Hide file tree
Showing 5 changed files with 229 additions and 170 deletions.
167 changes: 90 additions & 77 deletions src/heretic/am_map.c
Original file line number Diff line number Diff line change
Expand Up @@ -1360,96 +1360,109 @@ static inline void PUTDOT_THICK(int x, int y, pixel_t color)
// -----------------------------------------------------------------------------
// AM_drawFline
// Classic Bresenham w/ whatever optimizations needed for speed.
// [PN] Refactored to handle both antialiased and non-antialiased line drawing.
// -----------------------------------------------------------------------------

static void AM_drawFline(fline_t * fl, int color)
{
register int x, y, dx, dy, sx, sy, ax, ay, d;

switch (color)
{
case WALLCOLORS: DrawWuLine(fl, &(*antialias)[0][0]); break;
case FDWALLCOLORS: DrawWuLine(fl, &(*antialias)[1][0]); break;
case CDWALLCOLORS: DrawWuLine(fl, &(*antialias)[2][0]); break;
// [JN] Apply antialiasing for some extra lines as well:
case MLDONTDRAW1: DrawWuLine(fl, &(*antialias)[3][0]); break;
case MLDONTDRAW2: DrawWuLine(fl, &(*antialias)[4][0]); break;
case YELLOWKEY: DrawWuLine(fl, &(*antialias)[5][0]); break;
case GREENKEY: DrawWuLine(fl, &(*antialias)[6][0]); break;
case BLUEKEY: DrawWuLine(fl, &(*antialias)[7][0]); break;
case SECRETCOLORS: DrawWuLine(fl, &(*antialias)[8][0]); break;
case FSECRETCOLORS: DrawWuLine(fl, &(*antialias)[9][0]); break;
case EXITS: DrawWuLine(fl, &(*antialias)[10][0]); break;
// IDDT extended colors:
case IDDT_GREEN: DrawWuLine(fl, &(*antialias)[11][0]); break;
case IDDT_YELLOW: DrawWuLine(fl, &(*antialias)[12][0]); break;
case 150: DrawWuLine(fl, &(*antialias)[13][0]); break;
case 151: DrawWuLine(fl, &(*antialias)[14][0]); break;
case 152: DrawWuLine(fl, &(*antialias)[15][0]); break;
case 153: DrawWuLine(fl, &(*antialias)[16][0]); break;
case 154: DrawWuLine(fl, &(*antialias)[17][0]); break;
case 155: DrawWuLine(fl, &(*antialias)[18][0]); break;
case 156: DrawWuLine(fl, &(*antialias)[19][0]); break; // Used for TELEPORTERS as well
case 157: DrawWuLine(fl, &(*antialias)[20][0]); break;
case 158: DrawWuLine(fl, &(*antialias)[21][0]); break;
case 159: DrawWuLine(fl, &(*antialias)[22][0]); break;

default:
int actual_color;

if (automap_smooth)
{
// Use antialiasing if enabled
switch (color)
{
case WALLCOLORS: DrawWuLine(fl, &(*antialias)[0][0]); return;
case FDWALLCOLORS: DrawWuLine(fl, &(*antialias)[1][0]); return;
case CDWALLCOLORS: DrawWuLine(fl, &(*antialias)[2][0]); return;
// [JN] Apply antialiasing for some extra lines as well:
case MLDONTDRAW1: DrawWuLine(fl, &(*antialias)[3][0]); return;
case MLDONTDRAW2: DrawWuLine(fl, &(*antialias)[4][0]); return;
case YELLOWKEY: DrawWuLine(fl, &(*antialias)[5][0]); return;
case GREENKEY: DrawWuLine(fl, &(*antialias)[6][0]); return;
case BLUEKEY: DrawWuLine(fl, &(*antialias)[7][0]); return;
case SECRETCOLORS: DrawWuLine(fl, &(*antialias)[8][0]); return;
case FSECRETCOLORS: DrawWuLine(fl, &(*antialias)[9][0]); return;
case EXITS: DrawWuLine(fl, &(*antialias)[10][0]); return;
// IDDT extended colors:
case IDDT_GREEN: DrawWuLine(fl, &(*antialias)[11][0]); return;
case IDDT_YELLOW: DrawWuLine(fl, &(*antialias)[12][0]); return;
case 150: DrawWuLine(fl, &(*antialias)[13][0]); return;
case 151: DrawWuLine(fl, &(*antialias)[14][0]); return;
case 152: DrawWuLine(fl, &(*antialias)[15][0]); return;
case 153: DrawWuLine(fl, &(*antialias)[16][0]); return;
case 154: DrawWuLine(fl, &(*antialias)[17][0]); return;
case 155: DrawWuLine(fl, &(*antialias)[18][0]); return;
case 156: DrawWuLine(fl, &(*antialias)[19][0]); return; // Used for TELEPORTERS as well
case 157: DrawWuLine(fl, &(*antialias)[20][0]); return;
case 158: DrawWuLine(fl, &(*antialias)[21][0]); return;
case 159: DrawWuLine(fl, &(*antialias)[22][0]); return;
default: break;
}
}
else
{
// No antialiasing: map colors
switch (color)
{
// For debugging only
if (fl->a.x < 0 || fl->a.x >= f_w
|| fl->a.y < 0 || fl->a.y >= f_h
|| fl->b.x < 0 || fl->b.x >= f_w
|| fl->b.y < 0 || fl->b.y >= f_h)
{
return;
}
case WALLCOLORS: actual_color = automap_overlay ? 100 : 96; break;
case FDWALLCOLORS: actual_color = automap_overlay ? 106 : 110; break;
case CDWALLCOLORS: actual_color = 75; break;
default: actual_color = color; break;
}
}

// Debugging: check bounds
if (fl->a.x < 0 || fl->a.x >= f_w || fl->a.y < 0 || fl->a.y >= f_h
|| fl->b.x < 0 || fl->b.x >= f_w || fl->b.y < 0 || fl->b.y >= f_h)
{
return;
}

dx = fl->b.x - fl->a.x;
ax = 2 * (dx < 0 ? -dx : dx);
sx = dx < 0 ? -1 : 1;
// Bresenham's line algorithm
const int dx = fl->b.x - fl->a.x;
const int ax = 2 * (dx < 0 ? -dx : dx);
const int sx = dx < 0 ? -1 : 1;

dy = fl->b.y - fl->a.y;
ay = 2 * (dy < 0 ? -dy : dy);
sy = dy < 0 ? -1 : 1;
const int dy = fl->b.y - fl->a.y;
const int ay = 2 * (dy < 0 ? -dy : dy);
const int sy = dy < 0 ? -1 : 1;

x = fl->a.x;
y = fl->a.y;
int x = fl->a.x;
int y = fl->a.y;

if (ax > ay)
if (ax > ay)
{
int d = ay - ax / 2;
while (1)
{
PUTDOT_THICK(x, y, automap_smooth ? color : actual_color);
if (x == fl->b.x)
return;
if (d >= 0)
{
d = ay - ax / 2;
while (1)
{
PUTDOT_THICK(x, y, color);
if (x == fl->b.x)
return;
if (d >= 0)
{
y += sy;
d -= ax;
}
x += sx;
d += ay;
}
y += sy;
d -= ax;
}
else
x += sx;
d += ay;
}
}
else
{
int d = ax - ay / 2;
while (1)
{
PUTDOT_THICK(x, y, automap_smooth ? color : actual_color);
if (y == fl->b.y)
return;
if (d >= 0)
{
d = ax - ay / 2;
while (1)
{
PUTDOT_THICK(x, y, color);
if (y == fl->b.y)
return;
if (d >= 0)
{
x += sx;
d -= ay;
}
y += sy;
d += ax;
}
x += sx;
d -= ay;
}
y += sy;
d += ax;
}
}
}
Expand Down
39 changes: 26 additions & 13 deletions src/heretic/mn_menu.c
Original file line number Diff line number Diff line change
Expand Up @@ -584,6 +584,7 @@ static void M_ID_Widget_LevelName (int choice);
static void M_ID_Widget_Health (int choice);

static void M_Draw_ID_Automap (void);
static void M_ID_Automap_Smooth (int choice);
static void M_ID_Automap_Thick (int choice);
static void M_ID_Automap_Square (int choice);
static void M_ID_Automap_Secrets (int choice);
Expand Down Expand Up @@ -3113,6 +3114,7 @@ static void M_ID_Widget_Health (int choice)
// -----------------------------------------------------------------------------

static MenuItem_t ID_Menu_Automap[] = {
{ ITT_LRFUNC, "LINE SMOOTHING", M_ID_Automap_Smooth, 0, MENU_NONE },
{ ITT_LRFUNC, "LINE THICKNESS", M_ID_Automap_Thick, 0, MENU_NONE },
{ ITT_LRFUNC, "SQUARE ASPECT RATIO", M_ID_Automap_Square, 0, MENU_NONE },
{ ITT_LRFUNC, "MARK SECRET SECTORS", M_ID_Automap_Secrets, 0, MENU_NONE },
Expand All @@ -3124,7 +3126,7 @@ static MenuItem_t ID_Menu_Automap[] = {
static Menu_t ID_Def_Automap = {
ID_MENU_LEFTOFFSET, ID_MENU_TOPOFFSET,
M_Draw_ID_Automap,
6, ID_Menu_Automap,
7, ID_Menu_Automap,
0,
SmallFont, false, false,
MENU_ID_MAIN
Expand All @@ -3139,40 +3141,50 @@ static void M_Draw_ID_Automap (void)

MN_DrTextACentered("AUTOMAP", 10, cr[CR_YELLOW]);

// Line smoothing
sprintf(str, automap_smooth ? "ON" : "OFF");
MN_DrTextA(str, M_ItemRightAlign(str), 20,
M_Item_Glow(0, automap_smooth ? GLOW_GREEN : GLOW_DARKRED));

// Line thickness
sprintf(str, "%s", thickness[automap_thick]);
MN_DrTextA(str, M_ItemRightAlign(str), 20,
M_Item_Glow(0, automap_thick ? GLOW_GREEN : GLOW_DARKRED));
MN_DrTextA(str, M_ItemRightAlign(str), 30,
M_Item_Glow(1, automap_thick ? GLOW_GREEN : GLOW_DARKRED));

// Square aspect ratio
sprintf(str, automap_square ? "ON" : "OFF");
MN_DrTextA(str, M_ItemRightAlign(str), 30,
M_Item_Glow(1, automap_square ? GLOW_GREEN : GLOW_DARKRED));
MN_DrTextA(str, M_ItemRightAlign(str), 40,
M_Item_Glow(2, automap_square ? GLOW_GREEN : GLOW_DARKRED));

// Mark secret sectors
sprintf(str, automap_secrets == 1 ? "REVEALED" :
automap_secrets == 2 ? "ALWAYS" : "OFF");
MN_DrTextA(str, M_ItemRightAlign(str), 40,
M_Item_Glow(2, automap_secrets ? GLOW_GREEN : GLOW_DARKRED));
MN_DrTextA(str, M_ItemRightAlign(str), 50,
M_Item_Glow(3, automap_secrets ? GLOW_GREEN : GLOW_DARKRED));

// Rotate mode
sprintf(str, automap_rotate ? "ON" : "OFF");
MN_DrTextA(str, M_ItemRightAlign(str), 50,
M_Item_Glow(3, automap_rotate ? GLOW_GREEN : GLOW_DARKRED));
MN_DrTextA(str, M_ItemRightAlign(str), 60,
M_Item_Glow(4, automap_rotate ? GLOW_GREEN : GLOW_DARKRED));

// Overlay mode
sprintf(str, automap_overlay ? "ON" : "OFF");
MN_DrTextA(str, M_ItemRightAlign(str), 60,
M_Item_Glow(4, automap_overlay ? GLOW_GREEN : GLOW_DARKRED));
MN_DrTextA(str, M_ItemRightAlign(str), 70,
M_Item_Glow(5, automap_overlay ? GLOW_GREEN : GLOW_DARKRED));

// Overlay shading level
sprintf(str,"%d", automap_shading);
MN_DrTextA(str, M_ItemRightAlign(str), 70,
M_Item_Glow(5, !automap_overlay ? GLOW_DARKRED :
MN_DrTextA(str, M_ItemRightAlign(str), 80,
M_Item_Glow(6, !automap_overlay ? GLOW_DARKRED :
automap_shading == 0 ? GLOW_RED :
automap_shading == 12 ? GLOW_YELLOW : GLOW_GREEN));
}

static void M_ID_Automap_Smooth (int choice)
{
automap_smooth ^= 1;
}

static void M_ID_Automap_Thick (int choice)
{
automap_thick = M_INT_Slider(automap_thick, 0, 6, choice, false);
Expand Down Expand Up @@ -4552,6 +4564,7 @@ static void M_ID_ApplyResetHook (void)
widget_render = 0;
widget_health = 0;
// Automap
automap_smooth = 1;
automap_thick = 0;
automap_square = 0;
automap_secrets = 0;
Expand Down
Loading

0 comments on commit d1d3120

Please sign in to comment.