Skip to content

Commit 76531bd

Browse files
drawMinimap
1 parent c650bdd commit 76531bd

4 files changed

Lines changed: 71 additions & 51 deletions

File tree

CIO/CMinimapWindow.cpp

Lines changed: 48 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
#include "../CMap.h"
88
#include "../Texture.h"
99
#include "../globals.h"
10+
#include "CFont.h"
1011

1112
void CMinimapWindow::Draw(Position /*parentOrigin*/)
1213
{
@@ -24,24 +25,58 @@ void CMinimapWindow::Draw(Position /*parentOrigin*/)
2425
if(contentW <= 0 || contentH <= 0)
2526
return;
2627

27-
// Draw minimap terrain overlay onto a temporary SDL surface, then upload to texture
28-
if(auto* map = global::s2->getMapObj())
28+
auto* map = global::s2->getMapObj();
29+
if(!map)
30+
return;
31+
32+
// Fill pixel buffer with minimap terrain
33+
int num_x = 1, num_y = 1;
34+
map->drawMinimap(pixels_, contentW, contentH, num_x, num_y);
35+
36+
// Upload to texture and draw
37+
if(!minimapTex_.isValid() || minimapTex_.getWidth() != contentW || minimapTex_.getHeight() != contentH)
38+
minimapTex_.createEmpty(Extent(contentW, contentH));
39+
minimapTex_.upload(pixels_.data());
40+
minimapTex_.Draw(Rect(contentX, contentY, contentW, contentH));
41+
42+
// Draw player flags and numbers on top
43+
for(int i = 0; i < MAXPLAYERS; i++)
2944
{
30-
// Create or resize the minimap surface
31-
if(!minimapSurface_ || minimapSurface_->w != contentW || minimapSurface_->h != contentH)
32-
minimapSurface_ = makeRGBSurface(static_cast<unsigned>(contentW), static_cast<unsigned>(contentH), true);
45+
const auto hqX = map->getPlayerHQx()[i];
46+
const auto hqY = map->getPlayerHQy()[i];
47+
if(hqX == 0xFFFF || hqY == 0xFFFF)
48+
continue;
3349

34-
if(minimapSurface_)
50+
const int flagIdx = FLAG_BLUE_DARK + i % 7;
51+
const auto& flagBmp = global::bmpArray[flagIdx];
52+
auto& flagTex = getBmpTexture(flagIdx);
53+
if(flagTex.isValid())
3554
{
36-
// Clear with transparency
37-
SDL_FillRect(minimapSurface_.get(), nullptr, SDL_MapRGBA(minimapSurface_->format, 0, 0, 0, 0));
55+
const int fx = contentX + hqX / num_x - static_cast<int>(flagBmp.nx);
56+
const int fy = contentY + hqY / num_y - static_cast<int>(flagBmp.ny);
57+
flagTex.Draw(Position(fx, fy));
58+
}
3859

39-
// Draw minimap onto the temporary surface
40-
map->drawMinimap(minimapSurface_.get());
60+
// Player number
61+
CFont::Draw(std::to_string(i + 1), Position(contentX + hqX / num_x, contentY + hqY / num_y), FontSize::Small,
62+
FontColor::MintGreen);
63+
}
4164

42-
// Upload to texture and draw
43-
minimapTex_.load(minimapSurface_.get());
44-
minimapTex_.Draw(Rect(contentX, contentY, contentW, contentH));
65+
// Draw the position arrow
66+
{
67+
const int arrowIdx = MAPPIC_ARROWCROSS_ORANGE;
68+
const auto& arrowBmp = global::bmpArray[arrowIdx];
69+
auto& arrowTex = getBmpTexture(arrowIdx);
70+
if(arrowTex.isValid())
71+
{
72+
const auto& dispRect = map->getDisplayRect();
73+
const int ax = contentX
74+
+ (dispRect.left + static_cast<int>(dispRect.getSize().x) / 2) / triangleWidth / num_x
75+
- static_cast<int>(arrowBmp.nx);
76+
const int ay = contentY
77+
+ (dispRect.top + static_cast<int>(dispRect.getSize().y) / 2) / triangleHeight / num_y
78+
- static_cast<int>(arrowBmp.ny);
79+
arrowTex.Draw(Position(ax, ay));
4580
}
4681
}
4782
}

CIO/CMinimapWindow.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@
66

77
#include "../Texture.h"
88
#include "CWindow.h"
9+
#include <vector>
910

1011
class CMinimapWindow final : public CWindow
1112
{
12-
/// Temporary SDL surface for minimap terrain overlay (kept until terrain is also OpenGL)
13-
SdlSurface minimapSurface_;
13+
std::vector<uint32_t> pixels_; ///< Pixel buffer for minimap terrain
1414
Texture minimapTex_;
1515

1616
void Draw(Position parentOrigin) override;

CMap.cpp

Lines changed: 16 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -1328,18 +1328,18 @@ static void getTriangleColor(const bobMAP& map, Uint8 rawTextureId, Sint16& r, S
13281328
b = 128;
13291329
}
13301330

1331-
void CMap::drawMinimap(SDL_Surface* Window)
1331+
void CMap::drawMinimap(std::vector<uint32_t>& pixels, int w, int h, int& num_x, int& num_y)
13321332
{
1333-
// this variables are needed to reduce the size of minimap-windows of big maps
1334-
int num_x = (map->width > 256 ? map->width / 256 : 1);
1335-
int num_y = (map->height > 256 ? map->height / 256 : 1);
1333+
// Scale factors to keep minimap within a reasonable size
1334+
num_x = (map->width > 256 ? map->width / 256 : 1);
1335+
num_y = (map->height > 256 ? map->height / 256 : 1);
13361336

1337-
// make sure the minimap has the same proportions as the "real" map, so scale the same rate
1337+
// Keep aspect ratio uniform
13381338
num_x = (num_x > num_y ? num_x : num_y);
1339-
num_y = (num_x > num_y ? num_x : num_y);
1339+
num_y = num_x;
13401340

1341-
// if (Window->w < map->width || Window->h < map->height)
1342-
// return;
1341+
// Ensure pixel buffer is the right size
1342+
pixels.assign(static_cast<size_t>(w) * h, 0);
13431343

13441344
for(int y = 0; y < map->height; y++)
13451345
{
@@ -1354,9 +1354,12 @@ void CMap::drawMinimap(SDL_Surface* Window)
13541354
Sint16 r, g, b;
13551355
getTriangleColor(*map, map->getVertex(x, y).rsuTexture, r, g, b);
13561356

1357-
Uint32* row = (Uint32*)Window->pixels + (y / num_y + 20) * Window->pitch / 4; //-V206
1358-
//+6 because of the left window frame
1359-
Uint32* pixel = row + x / num_x + 6;
1357+
const int py = y / num_y;
1358+
const int px = x / num_x;
1359+
if(py >= h || px >= w)
1360+
continue;
1361+
1362+
auto& pixel = pixels[static_cast<size_t>(py) * w + px];
13601363

13611364
Sint32 vertexLighting = map->getVertex(x, y).i;
13621365
r = ((r * vertexLighting) >> 16);
@@ -1365,32 +1368,10 @@ void CMap::drawMinimap(SDL_Surface* Window)
13651368
const auto r8 = (Uint8)(r > 255 ? 255 : (r < 0 ? 0 : r));
13661369
const auto g8 = (Uint8)(g > 255 ? 255 : (g < 0 ? 0 : g));
13671370
const auto b8 = (Uint8)(b > 255 ? 255 : (b < 0 ? 0 : b));
1368-
*pixel = ((r8 << Window->format->Rshift) + (g8 << Window->format->Gshift) + (b8 << Window->format->Bshift));
1369-
}
1370-
}
1371-
1372-
// draw the player flags
1373-
for(int i = 0; i < MAXPLAYERS; i++)
1374-
{
1375-
if(PlayerHQx[i] != 0xFFFF && PlayerHQy[i] != 0xFFFF)
1376-
{
1377-
// draw flag
1378-
//%7 cause in the original game there are only 7 players and 7 different flags
1379-
CSurface::Draw(Window, global::bmpArray[FLAG_BLUE_DARK + i % 7].surface,
1380-
6 + PlayerHQx[i] / num_x - global::bmpArray[FLAG_BLUE_DARK + i % 7].nx,
1381-
20 + PlayerHQy[i] / num_y - global::bmpArray[FLAG_BLUE_DARK + i % 7].ny);
1382-
// write player number
1383-
CFont::writeText(Window, std::to_string(i + 1), 6 + PlayerHQx[i] / num_x, 20 + PlayerHQy[i] / num_y,
1384-
FontSize::Small, FontColor::MintGreen);
1371+
// BGRA format: A<<24 | R<<16 | G<<8 | B
1372+
pixel = (0xFFu << 24) | (r8 << 16) | (g8 << 8) | b8;
13851373
}
13861374
}
1387-
1388-
// draw the arrow --> 6px is width of left window frame and 20px is the height of the upper window frame
1389-
CSurface::Draw(Window, global::bmpArray[MAPPIC_ARROWCROSS_ORANGE].surface,
1390-
6 + (displayRect.left + displayRect.getSize().x / 2) / triangleWidth / num_x
1391-
- global::bmpArray[MAPPIC_ARROWCROSS_ORANGE].nx,
1392-
20 + (displayRect.top + displayRect.getSize().y / 2) / triangleHeight / num_y
1393-
- global::bmpArray[MAPPIC_ARROWCROSS_ORANGE].ny);
13941375
}
13951376

13961377
void CMap::modifyVertex()

CMap.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -161,7 +161,11 @@ class CMap
161161
std::string getAuthor() const { return map->getAuthor(); }
162162
void setAuthor(const std::string& author) { map->setAuthor(author); }
163163

164-
void drawMinimap(SDL_Surface* Window);
164+
/// Fill a pixel buffer with the minimap terrain view.
165+
/// @param pixels BGRA pixel buffer (w * h entries, 0xAARRGGBB layout).
166+
/// @param w,h Dimensions of the pixel buffer.
167+
/// @param num_x,num_y Output: scaling factors (map coords → pixel coords).
168+
void drawMinimap(std::vector<uint32_t>& pixels, int w, int h, int& num_x, int& num_y);
165169
void render();
166170
// get and set some variables necessary for cursor behavior
167171
void setHexagonMode(bool HexagonMode)

0 commit comments

Comments
 (0)