Browse Source

Automap: Scoped enums and wrappers to minimise bitwise operations (#2534)

pull/2539/head
Andrew James 5 years ago committed by Anders Jenbo
parent
commit
8d9c46290d
  1. 187
      Source/automap.cpp

187
Source/automap.cpp

@ -35,41 +35,48 @@ enum MapColors : uint8_t {
MapColorsItem = (PAL8_BLUE + 1), MapColorsItem = (PAL8_BLUE + 1),
}; };
/** The general shape of the tile */ struct AutomapTile {
enum class AutomapTypes : uint8_t { /** The general shape of the tile */
None, enum class Types : uint8_t {
Diamond, None,
Vertical, Diamond,
Horizontal, Vertical,
Cross, Horizontal,
FenceVertical, Cross,
FenceHorizontal, FenceVertical,
Corner, FenceHorizontal,
CaveHorizontalCross, Corner,
CaveVerticalCross, CaveHorizontalCross,
CaveHorizontal, CaveVerticalCross,
CaveVertical, CaveHorizontal,
CaveCross, CaveVertical,
}; CaveCross,
};
/** Additional details about the given tile */ Types type;
enum AutomapFlags : uint8_t {
// clang-format off /** Additional details about the given tile */
AutomapFlagVerticalDoor = 1 << 0, enum class Flags : uint8_t {
AutomapFlagHorizontalDoor = 1 << 1, // clang-format off
AutomapFlagVerticalArch = 1 << 2, VerticalDoor = 1 << 0,
AutomapFlagHorizontalArch = 1 << 3, HorizontalDoor = 1 << 1,
AutomapFlagVerticalGrate = 1 << 4, VerticalArch = 1 << 2,
AutomapFlagHorizontalGrate = 1 << 5, HorizontalArch = 1 << 3,
AutomapFlagDirt = 1 << 6, VerticalGrate = 1 << 4,
AutomapFlagStairs = 1 << 7, HorizontalGrate = 1 << 5,
// clang-format on VerticalPassage = VerticalDoor | VerticalArch | VerticalGrate,
}; HorizontalPassage = HorizontalDoor | HorizontalArch | HorizontalGrate,
Dirt = 1 << 6,
Stairs = 1 << 7,
// clang-format on
};
struct AutomapTile { Flags flags;
AutomapTypes type;
/** Uses AutomapFlags for flags */ constexpr bool HasFlag(Flags test) const
uint8_t flags; {
return (static_cast<uint8_t>(flags) & static_cast<uint8_t>(test)) != 0;
}
}; };
/** /**
@ -139,17 +146,17 @@ void DrawStairs(const Surface &out, Point center)
*/ */
void DrawHorizontal(const Surface &out, Point center, AutomapTile tile) void DrawHorizontal(const Surface &out, Point center, AutomapTile tile)
{ {
if ((tile.flags & (AutomapFlagHorizontalDoor | AutomapFlagHorizontalGrate | AutomapFlagHorizontalArch)) == 0) { if (!tile.HasFlag(AutomapTile::Flags::HorizontalPassage)) {
DrawMapLineSE(out, { center.x, center.y - AmLine16 }, AmLine16, MapColorsDim); DrawMapLineSE(out, { center.x, center.y - AmLine16 }, AmLine16, MapColorsDim);
return; return;
} }
if ((tile.flags & AutomapFlagHorizontalDoor) != 0) { if (tile.HasFlag(AutomapTile::Flags::HorizontalDoor)) {
DrawMapHorizontalDoor(out, { center.x + AmLine16, center.y - AmLine8 }); DrawMapHorizontalDoor(out, { center.x + AmLine16, center.y - AmLine8 });
} }
if ((tile.flags & AutomapFlagHorizontalGrate) != 0) { if (tile.HasFlag(AutomapTile::Flags::HorizontalGrate)) {
DrawMapLineSE(out, { center.x + AmLine16, center.y - AmLine8 }, AmLine8, MapColorsDim); DrawMapLineSE(out, { center.x + AmLine16, center.y - AmLine8 }, AmLine8, MapColorsDim);
DrawDiamond(out, { center.x, center.y - AmLine8 }, MapColorsDim); DrawDiamond(out, { center.x, center.y - AmLine8 }, MapColorsDim);
} else if ((tile.flags & AutomapFlagHorizontalArch) != 0) { } else if (tile.HasFlag(AutomapTile::Flags::HorizontalArch)) {
DrawDiamond(out, { center.x, center.y - AmLine8 }, MapColorsDim); DrawDiamond(out, { center.x, center.y - AmLine8 }, MapColorsDim);
} }
} }
@ -159,17 +166,17 @@ void DrawHorizontal(const Surface &out, Point center, AutomapTile tile)
*/ */
void DrawVertical(const Surface &out, Point center, AutomapTile tile) void DrawVertical(const Surface &out, Point center, AutomapTile tile)
{ {
if ((tile.flags & (AutomapFlagVerticalDoor | AutomapFlagVerticalGrate | AutomapFlagVerticalArch)) == 0) { if (!tile.HasFlag(AutomapTile::Flags::VerticalPassage)) {
DrawMapLineNE(out, { center.x - AmLine32, center.y }, AmLine16, MapColorsDim); DrawMapLineNE(out, { center.x - AmLine32, center.y }, AmLine16, MapColorsDim);
return; return;
} }
if ((tile.flags & AutomapFlagVerticalDoor) != 0) { // two wall segments with a door in the middle if (tile.HasFlag(AutomapTile::Flags::VerticalDoor)) { // two wall segments with a door in the middle
DrawMapVerticalDoor(out, { center.x - AmLine16, center.y - AmLine8 }); DrawMapVerticalDoor(out, { center.x - AmLine16, center.y - AmLine8 });
} }
if ((tile.flags & AutomapFlagVerticalGrate) != 0) { // right-facing half-wall if (tile.HasFlag(AutomapTile::Flags::VerticalGrate)) { // right-facing half-wall
DrawMapLineNE(out, { center.x - AmLine32, center.y }, AmLine8, MapColorsDim); DrawMapLineNE(out, { center.x - AmLine32, center.y }, AmLine8, MapColorsDim);
DrawDiamond(out, { center.x, center.y - AmLine8 }, MapColorsDim); DrawDiamond(out, { center.x, center.y - AmLine8 }, MapColorsDim);
} else if ((tile.flags & AutomapFlagVerticalArch) != 0) { // window or passable column } else if (tile.HasFlag(AutomapTile::Flags::VerticalArch)) { // window or passable column
DrawDiamond(out, { center.x, center.y - AmLine8 }, MapColorsDim); DrawDiamond(out, { center.x, center.y - AmLine8 }, MapColorsDim);
} }
} }
@ -179,7 +186,7 @@ void DrawVertical(const Surface &out, Point center, AutomapTile tile)
*/ */
void DrawCaveHorizontal(const Surface &out, Point center, AutomapTile tile) void DrawCaveHorizontal(const Surface &out, Point center, AutomapTile tile)
{ {
if ((tile.flags & AutomapFlagVerticalDoor) != 0) { if (tile.HasFlag(AutomapTile::Flags::VerticalDoor)) {
DrawMapHorizontalDoor(out, { center.x - AmLine16, center.y + AmLine8 }); DrawMapHorizontalDoor(out, { center.x - AmLine16, center.y + AmLine8 });
} else { } else {
DrawMapLineSE(out, { center.x - AmLine32, center.y }, AmLine16, MapColorsDim); DrawMapLineSE(out, { center.x - AmLine32, center.y }, AmLine16, MapColorsDim);
@ -191,7 +198,7 @@ void DrawCaveHorizontal(const Surface &out, Point center, AutomapTile tile)
*/ */
void DrawCaveVertical(const Surface &out, Point center, AutomapTile tile) void DrawCaveVertical(const Surface &out, Point center, AutomapTile tile)
{ {
if ((tile.flags & AutomapFlagHorizontalDoor) != 0) { if (tile.HasFlag(AutomapTile::Flags::HorizontalDoor)) {
DrawMapVerticalDoor(out, { center.x + AmLine16, center.y + AmLine8 }); DrawMapVerticalDoor(out, { center.x + AmLine16, center.y + AmLine8 });
} else { } else {
DrawMapLineNE(out, { center.x, center.y + AmLine16 }, AmLine16, MapColorsDim); DrawMapLineNE(out, { center.x, center.y + AmLine16 }, AmLine16, MapColorsDim);
@ -203,53 +210,53 @@ void DrawCaveVertical(const Surface &out, Point center, AutomapTile tile)
*/ */
void DrawAutomapTile(const Surface &out, Point center, AutomapTile tile) void DrawAutomapTile(const Surface &out, Point center, AutomapTile tile)
{ {
if (tile.type == AutomapTypes::None) if (tile.type == AutomapTile::Types::None)
return; return;
if ((tile.flags & AutomapFlagDirt) != 0) { if (tile.HasFlag(AutomapTile::Flags::Dirt)) {
DrawDirt(out, center); DrawDirt(out, center);
} }
if ((tile.flags & AutomapFlagStairs) != 0) { if (tile.HasFlag(AutomapTile::Flags::Stairs)) {
DrawStairs(out, center); DrawStairs(out, center);
} }
switch (tile.type) { switch (tile.type) {
case AutomapTypes::Diamond: // stand-alone column or other unpassable object case AutomapTile::Types::Diamond: // stand-alone column or other unpassable object
DrawDiamond(out, { center.x, center.y - AmLine8 }, MapColorsDim); DrawDiamond(out, { center.x, center.y - AmLine8 }, MapColorsDim);
break; break;
case AutomapTypes::Vertical: case AutomapTile::Types::Vertical:
case AutomapTypes::FenceVertical: case AutomapTile::Types::FenceVertical:
DrawVertical(out, center, tile); DrawVertical(out, center, tile);
break; break;
case AutomapTypes::Horizontal: case AutomapTile::Types::Horizontal:
case AutomapTypes::FenceHorizontal: case AutomapTile::Types::FenceHorizontal:
DrawHorizontal(out, center, tile); DrawHorizontal(out, center, tile);
break; break;
case AutomapTypes::Cross: case AutomapTile::Types::Cross:
DrawVertical(out, center, tile); DrawVertical(out, center, tile);
DrawHorizontal(out, center, tile); DrawHorizontal(out, center, tile);
break; break;
case AutomapTypes::CaveHorizontalCross: case AutomapTile::Types::CaveHorizontalCross:
DrawVertical(out, center, tile); DrawVertical(out, center, tile);
DrawCaveHorizontal(out, center, tile); DrawCaveHorizontal(out, center, tile);
break; break;
case AutomapTypes::CaveVerticalCross: case AutomapTile::Types::CaveVerticalCross:
DrawHorizontal(out, center, tile); DrawHorizontal(out, center, tile);
DrawCaveVertical(out, center, tile); DrawCaveVertical(out, center, tile);
break; break;
case AutomapTypes::CaveHorizontal: case AutomapTile::Types::CaveHorizontal:
DrawCaveHorizontal(out, center, tile); DrawCaveHorizontal(out, center, tile);
break; break;
case AutomapTypes::CaveVertical: case AutomapTile::Types::CaveVertical:
DrawCaveVertical(out, center, tile); DrawCaveVertical(out, center, tile);
break; break;
case AutomapTypes::CaveCross: case AutomapTile::Types::CaveCross:
DrawCaveHorizontal(out, center, tile); DrawCaveHorizontal(out, center, tile);
DrawCaveVertical(out, center, tile); DrawCaveVertical(out, center, tile);
break; break;
case AutomapTypes::Corner: case AutomapTile::Types::Corner:
case AutomapTypes::None: case AutomapTile::Types::None:
break; break;
} }
} }
@ -390,13 +397,13 @@ void DrawAutomapPlr(const Surface &out, const Displacement &myPlayerOffset, int
/** /**
* @brief Check if a given tile has the provided AutomapTile flag * @brief Check if a given tile has the provided AutomapTile flag
*/ */
bool HasAutomapFlag(Point position, AutomapFlags type) bool HasAutomapFlag(Point position, AutomapTile::Flags type)
{ {
if (position.x < 0 || position.x >= DMAXX || position.y < 0 || position.y >= DMAXX) { if (position.x < 0 || position.x >= DMAXX || position.y < 0 || position.y >= DMAXX) {
return false; return false;
} }
return (AutomapTypeTiles[dungeon[position.x][position.y]].flags & type) != 0; return AutomapTypeTiles[dungeon[position.x][position.y]].HasFlag(type);
} }
/** /**
@ -409,10 +416,10 @@ AutomapTile GetAutomapType(Point position)
} }
AutomapTile tile = AutomapTypeTiles[dungeon[position.x][position.y]]; AutomapTile tile = AutomapTypeTiles[dungeon[position.x][position.y]];
if (tile.type == AutomapTypes::Corner) { if (tile.type == AutomapTile::Types::Corner) {
if (HasAutomapFlag({ position.x - 1, position.y }, AutomapFlagHorizontalArch)) { if (HasAutomapFlag({ position.x - 1, position.y }, AutomapTile::Flags::HorizontalArch)) {
if (HasAutomapFlag({ position.x, position.y - 1 }, AutomapFlagVerticalArch)) { if (HasAutomapFlag({ position.x, position.y - 1 }, AutomapTile::Flags::VerticalArch)) {
tile.type = AutomapTypes::Diamond; tile.type = AutomapTile::Types::Diamond;
} }
} }
} }
@ -426,17 +433,17 @@ AutomapTile GetAutomapType(Point position)
AutomapTile GetAutomapTypeView(Point map) AutomapTile GetAutomapTypeView(Point map)
{ {
if (map.x == -1 && map.y >= 0 && map.y < DMAXY && AutomapView[0][map.y]) { if (map.x == -1 && map.y >= 0 && map.y < DMAXY && AutomapView[0][map.y]) {
if (HasAutomapFlag({ 0, map.y }, AutomapFlagDirt)) { if (HasAutomapFlag({ 0, map.y }, AutomapTile::Flags::Dirt)) {
return {}; return {};
} }
return { AutomapTypes::None, AutomapFlagDirt }; return { AutomapTile::Types::None, AutomapTile::Flags::Dirt };
} }
if (map.y == -1 && map.x >= 0 && map.x < DMAXY && AutomapView[map.x][0]) { if (map.y == -1 && map.x >= 0 && map.x < DMAXY && AutomapView[map.x][0]) {
if (HasAutomapFlag({ map.x, 0 }, AutomapFlagDirt)) { if (HasAutomapFlag({ map.x, 0 }, AutomapTile::Flags::Dirt)) {
return {}; return {};
} }
return { AutomapTypes::None, AutomapFlagDirt }; return { AutomapTile::Types::None, AutomapTile::Flags::Dirt };
} }
if (map.x < 0 || map.x >= DMAXX) { if (map.x < 0 || map.x >= DMAXX) {
@ -715,63 +722,63 @@ void SetAutomapView(Point position)
AutomapView[map.x][map.y] = true; AutomapView[map.x][map.y] = true;
AutomapTile tile = GetAutomapType(map); AutomapTile tile = GetAutomapType(map);
bool solid = (tile.flags & AutomapFlagDirt) != 0; bool solid = tile.HasFlag(AutomapTile::Flags::Dirt);
switch (tile.type) { switch (tile.type) {
case AutomapTypes::Vertical: case AutomapTile::Types::Vertical:
if (solid) { if (solid) {
auto tileSW = GetAutomapType({ map.x, map.y + 1 }); auto tileSW = GetAutomapType({ map.x, map.y + 1 });
if (tileSW.type == AutomapTypes::Corner && (tileSW.flags & AutomapFlagDirt) != 0) if (tileSW.type == AutomapTile::Types::Corner && tileSW.HasFlag(AutomapTile::Flags::Dirt))
AutomapView[map.x][map.y + 1] = true; AutomapView[map.x][map.y + 1] = true;
} else if (HasAutomapFlag({ map.x - 1, map.y }, AutomapFlagDirt)) { } else if (HasAutomapFlag({ map.x - 1, map.y }, AutomapTile::Flags::Dirt)) {
AutomapView[map.x - 1][map.y] = true; AutomapView[map.x - 1][map.y] = true;
} }
break; break;
case AutomapTypes::Horizontal: case AutomapTile::Types::Horizontal:
if (solid) { if (solid) {
auto tileSE = GetAutomapType({ map.x + 1, map.y }); auto tileSE = GetAutomapType({ map.x + 1, map.y });
if (tileSE.type == AutomapTypes::Corner && (tileSE.flags & AutomapFlagDirt) != 0) if (tileSE.type == AutomapTile::Types::Corner && tileSE.HasFlag(AutomapTile::Flags::Dirt))
AutomapView[map.x + 1][map.y] = true; AutomapView[map.x + 1][map.y] = true;
} else if (HasAutomapFlag({ map.x, map.y - 1 }, AutomapFlagDirt)) { } else if (HasAutomapFlag({ map.x, map.y - 1 }, AutomapTile::Flags::Dirt)) {
AutomapView[map.x][map.y - 1] = true; AutomapView[map.x][map.y - 1] = true;
} }
break; break;
case AutomapTypes::Cross: case AutomapTile::Types::Cross:
if (solid) { if (solid) {
auto tileSW = GetAutomapType({ map.x, map.y + 1 }); auto tileSW = GetAutomapType({ map.x, map.y + 1 });
if (tileSW.type == AutomapTypes::Corner && (tileSW.flags & AutomapFlagDirt) != 0) if (tileSW.type == AutomapTile::Types::Corner && tileSW.HasFlag(AutomapTile::Flags::Dirt))
AutomapView[map.x][map.y + 1] = true; AutomapView[map.x][map.y + 1] = true;
auto tileSE = GetAutomapType({ map.x + 1, map.y }); auto tileSE = GetAutomapType({ map.x + 1, map.y });
if (tileSE.type == AutomapTypes::Corner && (tileSE.flags & AutomapFlagDirt) != 0) if (tileSE.type == AutomapTile::Types::Corner && tileSE.HasFlag(AutomapTile::Flags::Dirt))
AutomapView[map.x + 1][map.y] = true; AutomapView[map.x + 1][map.y] = true;
} else { } else {
if (HasAutomapFlag({ map.x - 1, map.y }, AutomapFlagDirt)) if (HasAutomapFlag({ map.x - 1, map.y }, AutomapTile::Flags::Dirt))
AutomapView[map.x - 1][map.y] = true; AutomapView[map.x - 1][map.y] = true;
if (HasAutomapFlag({ map.x, map.y - 1 }, AutomapFlagDirt)) if (HasAutomapFlag({ map.x, map.y - 1 }, AutomapTile::Flags::Dirt))
AutomapView[map.x][map.y - 1] = true; AutomapView[map.x][map.y - 1] = true;
if (HasAutomapFlag({ map.x - 1, map.y - 1 }, AutomapFlagDirt)) if (HasAutomapFlag({ map.x - 1, map.y - 1 }, AutomapTile::Flags::Dirt))
AutomapView[map.x - 1][map.y - 1] = true; AutomapView[map.x - 1][map.y - 1] = true;
} }
break; break;
case AutomapTypes::FenceVertical: case AutomapTile::Types::FenceVertical:
if (solid) { if (solid) {
if (HasAutomapFlag({ map.x, map.y - 1 }, AutomapFlagDirt)) if (HasAutomapFlag({ map.x, map.y - 1 }, AutomapTile::Flags::Dirt))
AutomapView[map.x][map.y - 1] = true; AutomapView[map.x][map.y - 1] = true;
auto tileSW = GetAutomapType({ map.x, map.y + 1 }); auto tileSW = GetAutomapType({ map.x, map.y + 1 });
if (tileSW.type == AutomapTypes::Corner && (tileSW.flags & AutomapFlagDirt) != 0) if (tileSW.type == AutomapTile::Types::Corner && tileSW.HasFlag(AutomapTile::Flags::Dirt))
AutomapView[map.x][map.y + 1] = true; AutomapView[map.x][map.y + 1] = true;
} else if (HasAutomapFlag({ map.x - 1, map.y }, AutomapFlagDirt)) { } else if (HasAutomapFlag({ map.x - 1, map.y }, AutomapTile::Flags::Dirt)) {
AutomapView[map.x - 1][map.y] = true; AutomapView[map.x - 1][map.y] = true;
} }
break; break;
case AutomapTypes::FenceHorizontal: case AutomapTile::Types::FenceHorizontal:
if (solid) { if (solid) {
if (HasAutomapFlag({ map.x - 1, map.y }, AutomapFlagDirt)) if (HasAutomapFlag({ map.x - 1, map.y }, AutomapTile::Flags::Dirt))
AutomapView[map.x - 1][map.y] = true; AutomapView[map.x - 1][map.y] = true;
auto tileSE = GetAutomapType({ map.x + 1, map.y }); auto tileSE = GetAutomapType({ map.x + 1, map.y });
if (tileSE.type == AutomapTypes::Corner && (tileSE.flags & AutomapFlagDirt) != 0) if (tileSE.type == AutomapTile::Types::Corner && tileSE.HasFlag(AutomapTile::Flags::Dirt))
AutomapView[map.x + 1][map.y] = true; AutomapView[map.x + 1][map.y] = true;
} else if (HasAutomapFlag({ map.x, map.y - 1 }, AutomapFlagDirt)) { } else if (HasAutomapFlag({ map.x, map.y - 1 }, AutomapTile::Flags::Dirt)) {
AutomapView[map.x][map.y - 1] = true; AutomapView[map.x][map.y - 1] = true;
} }
break; break;

Loading…
Cancel
Save