Skip to content

Commit

Permalink
Ui: refactor map location drawing
Browse files Browse the repository at this point in the history
  • Loading branch information
black-sliver committed Jul 29, 2024
1 parent d636abf commit ef85151
Show file tree
Hide file tree
Showing 4 changed files with 137 additions and 127 deletions.
137 changes: 11 additions & 126 deletions src/ui/mapwidget.cpp
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
#include "mapwidget.h"
#include "../core/util.h" // countOf
#include "../uilib/drawhelper.h"


namespace Ui {

Expand Down Expand Up @@ -191,142 +193,25 @@ void MapWidget::render(Renderer renderer, int offX, int offY)
int outerx = innerx-borderScreenSize;
int outery = innery-borderScreenSize;

SDL_Rect inner = {
.x = innerx, .y = innery, .w = locScreenInnerW, .h = locScreenInnerH
};
SDL_Rect outer = {
.x = outerx, .y = outery, .w = locScreenOuterW, .h = locScreenOuterH
};
SDL_Rect outerTop = {
.x = outer.x, .y = outer.y, .w = outer.w, .h = borderScreenSize
};
SDL_Rect outerBot = {
.x = outer.x, .y = outer.y + outer.h - borderScreenSize, .w = outer.w, .h = borderScreenSize
};
SDL_Rect outerLeft = {
.x = outer.x, .y = outer.y, .w = borderScreenSize, .h = outer.h
};
SDL_Rect outerRight = {
.x = outer.x + outer.w - borderScreenSize, .y = outer.y, .w = borderScreenSize, .h = outer.h
};

int state = (int)pos.state;
if (state == -1) continue; // hidden
if (state == 0 && _hideClearedLocations) continue;
if (state == 2 && _hideUnreachableLocations) continue;

bool hasAlpha;

if (!SplitRects || state<0 || state>=countOf(triangleValues)) {
const Widget::Color& c = (state<0 || state>=countOf(StateColors)) ?
StateColors[countOf(StateColors)-1] : StateColors[state];
hasAlpha = c.a < 0xff;
if (hasAlpha) {
// we have to draw 4 individual lines for border
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderFillRect(renderer, &outerTop);
SDL_RenderFillRect(renderer, &outerBot);
SDL_RenderFillRect(renderer, &outerLeft);
SDL_RenderFillRect(renderer, &outerRight);
} else {
// border as bigger background rect (optimized for sw rendering)
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderFillRect(renderer, &outer);
}
SDL_SetRenderDrawColor(renderer, c.r, c.g, c.b, c.a);
SDL_RenderFillRect(renderer, &inner);

continue;
}

const int* values = triangleValues[state];
const Widget::Color& topC = StateColors[values[0]];
const Widget::Color& leftC = StateColors[values[1]];
const Widget::Color& botC = StateColors[values[2]];
const Widget::Color& rightC = StateColors[values[3]];

hasAlpha = (topC.a < 0xff) ||
(leftC.a < 0xff) ||
(botC.a < 0xff) ||
(rightC.a < 0xff);

float fx = innerx;
float fy = innery;
float fw = locScreenInnerW;
float fh = locScreenInnerH;

if (hasAlpha) {
// we have to draw 4 individual lines for border
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderFillRect(renderer, &outerTop);
SDL_RenderFillRect(renderer, &outerBot);
SDL_RenderFillRect(renderer, &outerLeft);
SDL_RenderFillRect(renderer, &outerRight);
} else {
// border as bigger background rect
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderFillRect(renderer, &outer);
}

if (!hasAlpha || (values[0] == values[1] && values[1] == values[2] && values[2] == values[3])) {
SDL_SetRenderDrawColor(renderer, botC.r, botC.g, botC.b, botC.a);
SDL_RenderFillRect(renderer, &inner);
} else if (values[2] == values[3]) {
SDL_Color botRightColor = {botC.r, botC.g, botC.b, botC.a};
SDL_Vertex botRightVerts[] = {
{{fx + fw, fy}, botRightColor, {0, 0}},
{{fx, fy + fh}, botRightColor, {0, 0}},
{{fx + fw, fy + fh}, botRightColor, {0, 0}},
};
SDL_RenderGeometry(renderer, nullptr, botRightVerts, 3, nullptr, 0);
drawRect(renderer, {innerx, innery}, {locScreenInnerW, locScreenInnerH}, borderScreenSize,
c, c, c, c);
} else {
SDL_Color botColor = {botC.r, botC.g, botC.b, botC.a};
SDL_Vertex botVerts[] = {
{{fx, fy + fh}, botColor, {0, 0}},
{{fx + fw, fy + fw}, botColor, {0, 0}},
{{fx + fw/2, fy + fh/2}, botColor, {0, 0}},
};
SDL_RenderGeometry(renderer, nullptr, botVerts, 3, nullptr, 0);
}

if (values[2] != values[3]) {
SDL_Color rightColor = {rightC.r, rightC.g, rightC.b, rightC.a};
SDL_Vertex rightVerts[] = {
{{fx + fw, fy}, rightColor, {0, 0}},
{{fx + fw/2, fy + fh/2}, rightColor, {0, 0}},
{{fx + fw, fy + fh}, rightColor, {0, 0}},
};
SDL_RenderGeometry(renderer, nullptr, rightVerts, 3, nullptr, 0);
}

if (values[0] == values[1] && values[0] != values[2]) {
SDL_Color topLeftColor = {topC.r, topC.g, topC.b, topC.a};
SDL_Vertex topLeftVerts[] = {
{{fx, fy}, topLeftColor, {0, 0}},
{{fx, fy + fh}, topLeftColor, {0, 0}},
{{fx + fw, fy}, topLeftColor, {0, 0}},
};
SDL_RenderGeometry(renderer, nullptr, topLeftVerts, 3, nullptr, 0);
}

if (values[0] != values[1] && values[0] != values[2]) {
SDL_Color topColor = {topC.r, topC.g, topC.b, topC.a};
SDL_Vertex topVerts[] = {
{{fx, fy}, topColor, {0, 0}},
{{fx + fw/2, fy + fh/2}, topColor, {0, 0}},
{{fx + fw, fy}, topColor, {0, 0}},
};
SDL_RenderGeometry(renderer, nullptr, topVerts, 3, nullptr, 0);
}

if (values[1] != values[0] && values[1] != values[2]) {
SDL_Color leftColor = {leftC.r, leftC.g, leftC.b, leftC.a};
SDL_Vertex leftVerts[] = {
{{fx, fy}, leftColor, {0, 0}},
{{fx, fy + fh}, leftColor, {0, 0}},
{{fx + fw/2, fy + fh/2}, leftColor, {0, 0}},
};
SDL_RenderGeometry(renderer, nullptr, leftVerts, 3, nullptr, 0);
const int* values = triangleValues[state];
const Widget::Color& topC = StateColors[values[0]];
const Widget::Color& leftC = StateColors[values[1]];
const Widget::Color& botC = StateColors[values[2]];
const Widget::Color& rightC = StateColors[values[3]];
drawRect(renderer, {innerx, innery}, {locScreenInnerW, locScreenInnerH}, borderScreenSize,
topC, leftC, botC, rightC);
}
}
}
Expand Down
109 changes: 109 additions & 0 deletions src/uilib/drawhelper.cpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
#include "drawhelper.h"

namespace Ui {

void drawRect(Renderer renderer, Position pos, Size size, int borderWidth,
Widget::Color topC, Widget::Color leftC, Widget::Color botC, Widget::Color rightC)
{
SDL_Rect inner = {
.x = pos.left, .y = pos.top, .w = size.width, .h = size.height
};
SDL_Rect outer = {
.x = pos.left-borderWidth, .y = pos.top-borderWidth, .w = size.width + 2*borderWidth, .h = size.height + 2*borderWidth
};
SDL_Rect outerTop = {
.x = outer.x, .y = outer.y, .w = outer.w, .h = borderWidth
};
SDL_Rect outerBot = {
.x = outer.x, .y = outer.y + outer.h - borderWidth, .w = outer.w, .h = borderWidth
};
SDL_Rect outerLeft = {
.x = outer.x, .y = outer.y, .w = borderWidth, .h = outer.h
};
SDL_Rect outerRight = {
.x = outer.x + outer.w - borderWidth, .y = outer.y, .w = borderWidth, .h = outer.h
};

bool hasAlpha = topC.a != 0xff || leftC.a != 0xff || botC.a != 0xff || rightC.a != 0xff;

float fx = pos.left;
float fy = pos.top;
float fw = size.width;
float fh = size.height;

if (hasAlpha) {
// we have to draw 4 individual lines for border
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderFillRect(renderer, &outerTop);
SDL_RenderFillRect(renderer, &outerBot);
SDL_RenderFillRect(renderer, &outerLeft);
SDL_RenderFillRect(renderer, &outerRight);
} else {
// border as bigger background rect
SDL_SetRenderDrawColor(renderer, 0, 0, 0, 255);
SDL_RenderFillRect(renderer, &outer);
}

if (!hasAlpha || (topC == leftC && leftC == botC && botC == rightC)) {
SDL_SetRenderDrawColor(renderer, botC.r, botC.g, botC.b, botC.a);
SDL_RenderFillRect(renderer, &inner);
} else if (botC == rightC) {
SDL_Color botRightColor = {botC.r, botC.g, botC.b, botC.a};
SDL_Vertex botRightVerts[] = {
{{fx + fw, fy}, botRightColor, {0, 0}},
{{fx, fy + fh}, botRightColor, {0, 0}},
{{fx + fw, fy + fh}, botRightColor, {0, 0}},
};
SDL_RenderGeometry(renderer, nullptr, botRightVerts, 3, nullptr, 0);
} else {
SDL_Color botColor = {botC.r, botC.g, botC.b, botC.a};
SDL_Vertex botVerts[] = {
{{fx, fy + fh}, botColor, {0, 0}},
{{fx + fw, fy + fw}, botColor, {0, 0}},
{{fx + fw/2, fy + fh/2}, botColor, {0, 0}},
};
SDL_RenderGeometry(renderer, nullptr, botVerts, 3, nullptr, 0);
}

if (botC != rightC) {
SDL_Color rightColor = {rightC.r, rightC.g, rightC.b, rightC.a};
SDL_Vertex rightVerts[] = {
{{fx + fw, fy}, rightColor, {0, 0}},
{{fx + fw/2, fy + fh/2}, rightColor, {0, 0}},
{{fx + fw, fy + fh}, rightColor, {0, 0}},
};
SDL_RenderGeometry(renderer, nullptr, rightVerts, 3, nullptr, 0);
}

if (topC == leftC && topC != botC) {
SDL_Color topLeftColor = {topC.r, topC.g, topC.b, topC.a};
SDL_Vertex topLeftVerts[] = {
{{fx, fy}, topLeftColor, {0, 0}},
{{fx, fy + fh}, topLeftColor, {0, 0}},
{{fx + fw, fy}, topLeftColor, {0, 0}},
};
SDL_RenderGeometry(renderer, nullptr, topLeftVerts, 3, nullptr, 0);
}

if (topC != leftC && topC != botC) {
SDL_Color topColor = {topC.r, topC.g, topC.b, topC.a};
SDL_Vertex topVerts[] = {
{{fx, fy}, topColor, {0, 0}},
{{fx + fw/2, fy + fh/2}, topColor, {0, 0}},
{{fx + fw, fy}, topColor, {0, 0}},
};
SDL_RenderGeometry(renderer, nullptr, topVerts, 3, nullptr, 0);
}

if (leftC != topC && leftC != botC) {
SDL_Color leftColor = {leftC.r, leftC.g, leftC.b, leftC.a};
SDL_Vertex leftVerts[] = {
{{fx, fy}, leftColor, {0, 0}},
{{fx, fy + fh}, leftColor, {0, 0}},
{{fx + fw/2, fy + fh/2}, leftColor, {0, 0}},
};
SDL_RenderGeometry(renderer, nullptr, leftVerts, 3, nullptr, 0);
}
}

} // namespace Ui
14 changes: 14 additions & 0 deletions src/uilib/drawhelper.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
#pragma once

#include "widget.h"

namespace Ui {

void drawRect(Renderer renderer, Position pos, Size size, int borderWidth,
Widget::Color topC, Widget::Color leftC, Widget::Color botC, Widget::Color rightC);

void drawDiamond(Renderer renderer, Position pos, Size size, int borderWidth,
Widget::Color topC, Widget::Color leftC, Widget::Color botC, Widget::Color rightC);


} // namespace Ui
4 changes: 3 additions & 1 deletion src/uilib/widget.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,9 @@ class Widget {
r = 0; g = 0; b = 0; a = 0;
}
}
bool operator==(Color& other) const { return other.r==r && other.g==g && other.b==b && other.a==a; }
bool operator==(const Color& other) const { return other.r==r && other.g==g && other.b==b && other.a==a; }
bool operator!=(const Color& other) const { return ! (*this == other); }

private:
uint8_t hex(char c) {
if (c>='0' && c<='9') return (uint8_t)(c-'0');
Expand Down

0 comments on commit ef85151

Please sign in to comment.