Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Automap Enhancements #6517

Draft
wants to merge 5 commits into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
779 changes: 570 additions & 209 deletions Source/automap.cpp

Large diffs are not rendered by default.

14 changes: 12 additions & 2 deletions Source/automap.h
Original file line number Diff line number Diff line change
Expand Up @@ -30,16 +30,21 @@ enum MapExplorationType : uint8_t {

/** Specifies whether the automap is enabled. */
extern DVL_API_FOR_TEST bool AutomapActive;
/** Specifies whether the automap is in minimap mode. */
extern DVL_API_FOR_TEST bool AutomapMini;
/** Specifies whether the automap is transparent. */
extern DVL_API_FOR_TEST bool AutomapTransparent;
/** Tracks the explored areas of the map. */
extern uint8_t AutomapView[DMAXX][DMAXY];
/** Specifies the scale of the automap. */
extern DVL_API_FOR_TEST int AutoMapScale;
extern DVL_API_FOR_TEST Displacement AutomapOffset;
extern Rectangle AutomapMiniRect;

inline int AmLine(int x)
{
assert(x >= 4 && x <= 64);
assert((x & (x - 1)) == 0);
assert(x >= 2 && x <= 64);
//assert((x & (x - 1)) == 0);
return AutoMapScale * x / 100;
}

Expand All @@ -58,6 +63,11 @@ void InitAutomap();
*/
void StartAutomap();

/**
* @brief Displays the minimap.
*/
void StartMinimap();

/**
* @brief Scrolls the automap upwards.
*/
Expand Down
8 changes: 6 additions & 2 deletions Source/control.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -991,10 +991,14 @@ void control_check_btn_press()

void DoAutoMap()
{
if (!AutomapActive)
if (!AutomapActive) {
StartAutomap();
else
} else if (!AutomapMini) {
StartMinimap();
} else {
AutomapActive = false;
AutomapMini = false;
}
}

void CheckPanelInfo()
Expand Down
9 changes: 9 additions & 0 deletions Source/engine.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -163,6 +163,15 @@ void DrawHalfTransparentRectTo(const Surface &out, int sx, int sy, int width, in
DrawHalfTransparentBlendedRectTo(out, sx, sy, width, height);
}

void SetHalfTransparentPixel(const Surface &out, Point position, std::uint8_t col)
{
if (out.InBounds(position)) {
uint8_t *pix = out.at(position.x, position.y);
const std::array<uint8_t, 256> &lookupTable = paletteTransparencyLookup[col];
*pix = lookupTable[*pix];
}
}

void UnsafeDrawBorder2px(const Surface &out, Rectangle rect, uint8_t color)
{
const size_t width = rect.size.width;
Expand Down
1 change: 1 addition & 0 deletions Source/engine.h
Original file line number Diff line number Diff line change
Expand Up @@ -117,6 +117,7 @@ void UnsafeDrawVerticalLine(const Surface &out, Point from, int height, std::uin
* @param height Rectangle height
*/
void DrawHalfTransparentRectTo(const Surface &out, int sx, int sy, int width, int height);
void SetHalfTransparentPixel(const Surface &out, Point position, std::uint8_t col);

/**
* Draws a 2px inset border.
Expand Down
138 changes: 126 additions & 12 deletions Source/engine/render/automap_render.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@
* Line drawing routines for the automap.
*/
#include "engine/render/automap_render.hpp"
#include "automap.h"
#include "engine.h"

#include <cstdint>

Expand All @@ -24,36 +26,74 @@ template <DirectionX DirX, DirectionY DirY>
void DrawMapLine(const Surface &out, Point from, int height, std::uint8_t colorIndex)
{
while (height-- > 0) {
out.SetPixel({ from.x, from.y + 1 }, 0);
out.SetPixel(from, colorIndex);
SetMapPixel(out, { from.x, from.y + 1 }, 0);
SetMapPixel(out, from, colorIndex);
from.x += static_cast<int>(DirX);
out.SetPixel({ from.x, from.y + 1 }, 0);
out.SetPixel(from, colorIndex);
SetMapPixel(out, { from.x, from.y + 1 }, 0);
SetMapPixel(out, from, colorIndex);
from.x += static_cast<int>(DirX);
from.y += static_cast<int>(DirY);
}
out.SetPixel({ from.x, from.y + 1 }, 0);
out.SetPixel(from, colorIndex);
SetMapPixel(out, { from.x, from.y + 1 }, 0);
SetMapPixel(out, from, colorIndex);
}

template <DirectionX DirX, DirectionY DirY>
void DrawMapLineSteep(const Surface &out, Point from, int width, std::uint8_t colorIndex)
{
while (width-- > 0) {
out.SetPixel({ from.x, from.y + 1 }, 0);
out.SetPixel(from, colorIndex);
SetMapPixel(out, { from.x, from.y + 1 }, 0);
SetMapPixel(out, from, colorIndex);
from.y += static_cast<int>(DirY);
out.SetPixel({ from.x, from.y + 1 }, 0);
out.SetPixel(from, colorIndex);
SetMapPixel(out, { from.x, from.y + 1 }, 0);
SetMapPixel(out, from, colorIndex);
from.y += static_cast<int>(DirY);
from.x += static_cast<int>(DirX);
}
out.SetPixel({ from.x, from.y + 1 }, 0);
out.SetPixel(from, colorIndex);
SetMapPixel(out, { from.x, from.y + 1 }, 0);
SetMapPixel(out, from, colorIndex);
}

void DrawMapFreeLine(const Surface &out, Point from, Point to, uint8_t colorIndex)
{
int dx = std::abs(to.x - from.x);
int dy = std::abs(to.y - from.y);
int sx = from.x < to.x ? 1 : -1;
int sy = from.y < to.y ? 1 : -1;
int err = dx - dy;

while (true) {
SetMapPixel(out, from, colorIndex);

if (from.x == to.x && from.y == to.y) {
break;
}

int e2 = 2 * err;
if (e2 > -dy) {
err -= dy;
from.x += sx;
}
if (e2 < dx) {
err += dx;
from.y += sy;
}
}
}

} // namespace

void SetMapPixel(const Surface &out, Point point, uint8_t color)
{
if (AutomapMini && !AutomapMiniRect.contains(point))
return;
if (!AutomapTransparent) {
out.SetPixel(point, color);
} else {
SetHalfTransparentPixel(out, point, color);
}
}

void DrawMapLineNE(const Surface &out, Point from, int height, std::uint8_t colorIndex)
{
DrawMapLine<DirectionX::EAST, DirectionY::NORTH>(out, from, height, colorIndex);
Expand Down Expand Up @@ -94,4 +134,78 @@ void DrawMapLineSteepSW(const Surface &out, Point from, int width, std::uint8_t
DrawMapLineSteep<DirectionX::WEST, DirectionY::SOUTH>(out, from, width, colorIndex);
}

void DrawMapEllipse(const Surface &out, Point from, int radius, uint8_t colorIndex)
{
from.y -= AmLine(8);

const int a = radius;
const int b = radius / 2;

int x = 0;
int y = b;

// Initial point
SetMapPixel(out, { from.x, from.y + b }, colorIndex);
SetMapPixel(out, { from.x, from.y - b }, colorIndex);

// Initialize the parameters
int p1 = (b * b) - (a * a * b) + (a * a) / 4;

// Region 1
while ((b * b * x) < (a * a * y)) {
x++;
if (p1 < 0) {
p1 += (2 * b * b * x) + (b * b);
} else {
y--;
p1 += (2 * b * b * x) - (2 * a * a * y) + (b * b);
}

SetMapPixel(out, { from.x + x, from.y + y }, colorIndex);
SetMapPixel(out, { from.x - x, from.y + y }, colorIndex);
SetMapPixel(out, { from.x + x, from.y - y }, colorIndex);
SetMapPixel(out, { from.x - x, from.y - y }, colorIndex);
}

// Initialize the second parameter for Region 2
int p2 = (b * b * ((x + 1) * (x + 1))) + (a * a * ((y - 1) * (y - 1))) - (a * a * b * b);

// Region 2
while (y > 0) {
y--;
if (p2 > 0) {
p2 += (-2 * a * a * y) + (a * a);
} else {
x++;
p2 += (2 * b * b * x) - (2 * a * a * y) + (a * a);
}

SetMapPixel(out, { from.x + x, from.y + y }, colorIndex);
SetMapPixel(out, { from.x - x, from.y + y }, colorIndex);
SetMapPixel(out, { from.x + x, from.y - y }, colorIndex);
SetMapPixel(out, { from.x - x, from.y - y }, colorIndex);
}
}

void DrawMapStar(const Surface &out, Point from, int radius, uint8_t color)
{
from.y -= AmLine(8);

const int scaleFactor = 128;
Point anchors[5];

anchors[0] = { from.x - (121 * radius / scaleFactor), from.y + (19 * radius / scaleFactor) }; // Left Point
anchors[1] = { from.x + (121 * radius / scaleFactor), from.y + (19 * radius / scaleFactor) }; // Right Point
anchors[2] = { from.x, from.y + (64 * radius / scaleFactor) }; // Bottom Point
anchors[3] = { from.x - (75 * radius / scaleFactor), from.y - (51 * radius / scaleFactor) }; // Top Left Point
anchors[4] = { from.x + (75 * radius / scaleFactor), from.y - (51 * radius / scaleFactor) }; // Top Right Point

// Draw lines between the anchors to form a star
DrawMapFreeLine(out, anchors[3], anchors[1], color); // Connect Top Left -> Right
DrawMapFreeLine(out, anchors[1], anchors[0], color); // Connect Right -> Left
DrawMapFreeLine(out, anchors[0], anchors[4], color); // Connect Left -> Top Right
DrawMapFreeLine(out, anchors[4], anchors[2], color); // Connect Top Right -> Bottom
DrawMapFreeLine(out, anchors[2], anchors[3], color); // Connect Bottom -> Top Left
}

} // namespace devilution
3 changes: 3 additions & 0 deletions Source/engine/render/automap_render.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

namespace devilution {

void SetMapPixel(const Surface &out, Point point, uint8_t color);
/**
* @brief Draw a line in the target buffer from the given point towards north east at an `atan(1/2)` angle.
*
Expand Down Expand Up @@ -88,5 +89,7 @@ void DrawMapLineSteepNW(const Surface &out, Point from, int width, std::uint8_t
* The end point is at `{ from.x - (width + 1), from.y + 2 * width }`.
*/
void DrawMapLineSteepSW(const Surface &out, Point from, int width, std::uint8_t colorIndex);
void DrawMapEllipse(const Surface &out, Point from, int radius, uint8_t colorIndex);
void DrawMapStar(const Surface &out, Point from, int radius, uint8_t colorIndex);
kphoenix137 marked this conversation as resolved.
Show resolved Hide resolved

} // namespace devilution
Loading