summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/gfx.cpp44
-rw-r--r--src/gfx.h1
-rw-r--r--src/main_gui.cpp9
-rw-r--r--src/variables.h2
-rw-r--r--src/viewport.cpp60
5 files changed, 102 insertions, 14 deletions
diff --git a/src/gfx.cpp b/src/gfx.cpp
index 8a1b9741c..411267525 100644
--- a/src/gfx.cpp
+++ b/src/gfx.cpp
@@ -139,6 +139,50 @@ void GfxDrawLine(int x, int y, int x2, int y2, int color)
blitter->DrawLine(dpi->dst_ptr, x, y, x2, y2, dpi->width, dpi->height, color);
}
+/**
+ * Draws the projection of a parallelepiped.
+ * This can be used to draw boxes in world coordinates.
+ *
+ * @param x Screen X-coordinate of top front corner.
+ * @param y Screen Y-coordinate of top front corner.
+ * @param dx1 Screen X-length of first edge.
+ * @param dy1 Screen Y-length of first edge.
+ * @param dx2 Screen X-length of second edge.
+ * @param dy2 Screen Y-length of second edge.
+ * @param dx3 Screen X-length of third edge.
+ * @param dy3 Screen Y-length of third edge.
+ */
+void DrawBox(int x, int y, int dx1, int dy1, int dx2, int dy2, int dx3, int dy3)
+{
+ /* ....
+ * .. ....
+ * .. ....
+ * .. ^
+ * <--__(dx1,dy1) /(dx2,dy2)
+ * : --__ / :
+ * : --__ / :
+ * : *(x,y) :
+ * : | :
+ * : | ..
+ * .... |(dx3,dy3)
+ * .... | ..
+ * ....V.
+ */
+
+ static const byte color = 255;
+
+ GfxDrawLine(x, y, x + dx1, y + dy1, color);
+ GfxDrawLine(x, y, x + dx2, y + dy2, color);
+ GfxDrawLine(x, y, x + dx3, y + dy3, color);
+
+ GfxDrawLine(x + dx1, y + dy1, x + dx1 + dx2, y + dy1 + dy2, color);
+ GfxDrawLine(x + dx1, y + dy1, x + dx1 + dx3, y + dy1 + dy3, color);
+ GfxDrawLine(x + dx2, y + dy2, x + dx2 + dx1, y + dy2 + dy1, color);
+ GfxDrawLine(x + dx2, y + dy2, x + dx2 + dx3, y + dy2 + dy3, color);
+ GfxDrawLine(x + dx3, y + dy3, x + dx3 + dx1, y + dy3 + dy1, color);
+ GfxDrawLine(x + dx3, y + dy3, x + dx3 + dx2, y + dy3 + dy2, color);
+}
+
/** Truncate a given string to a maximum width if neccessary.
* If the string is truncated, add three dots ('...') to show this.
diff --git a/src/gfx.h b/src/gfx.h
index f54c1fcd9..38d4b3052 100644
--- a/src/gfx.h
+++ b/src/gfx.h
@@ -268,6 +268,7 @@ void DrawStringRightAlignedUnderline(int x, int y, StringID str, uint16 color);
void GfxFillRect(int left, int top, int right, int bottom, int color);
void GfxDrawLine(int left, int top, int right, int bottom, int color);
+void DrawBox(int x, int y, int dx1, int dy1, int dx2, int dy2, int dx3, int dy3);
BoundingRect GetStringBoundingBox(const char *str);
uint32 FormatStringLinebreaks(char *str, int maxw);
diff --git a/src/main_gui.cpp b/src/main_gui.cpp
index 447aef59b..95289a1bd 100644
--- a/src/main_gui.cpp
+++ b/src/main_gui.cpp
@@ -59,6 +59,8 @@ static int _scengen_town_size = 1; // depress medium-sized towns per default
extern void GenerateIndustries();
extern bool GenerateTowns();
+bool _draw_bounding_boxes = false;
+
void CcGiveMoney(bool success, TileIndex tile, uint32 p1, uint32 p2)
{
@@ -2208,6 +2210,13 @@ static void MainWindowWndProc(Window *w, WindowEvent *e)
break;
}
+ if (e->we.keypress.keycode == ('B' | WKC_CTRL)) {
+ e->we.keypress.cont = false;
+ _draw_bounding_boxes = !_draw_bounding_boxes;
+ MarkWholeScreenDirty();
+ break;
+ }
+
if (_game_mode == GM_MENU) break;
switch (e->we.keypress.keycode) {
diff --git a/src/variables.h b/src/variables.h
index 0b385bb73..9d2b2e4a5 100644
--- a/src/variables.h
+++ b/src/variables.h
@@ -339,6 +339,8 @@ extern const byte _tileh_to_sprite[32];
extern const TileTypeProcs * const _tile_type_procs[16];
+extern bool _draw_bounding_boxes;
+
/* misc */
VARDEF char _screenshot_name[128];
VARDEF byte _vehicle_design_names;
diff --git a/src/viewport.cpp b/src/viewport.cpp
index 40abfd242..a33df3db3 100644
--- a/src/viewport.cpp
+++ b/src/viewport.cpp
@@ -515,7 +515,7 @@ void AddSortableSpriteToDraw(SpriteID image, SpriteID pal, int x, int y, int w,
ViewportDrawer *vd = _cur_vd;
ParentSpriteToDraw *ps;
Point pt;
- int32 right, bottom;
+ int32 left, right, top, bottom;
assert((image & SPRITE_MASK) < MAX_SPRITES);
@@ -552,22 +552,32 @@ void AddSortableSpriteToDraw(SpriteID image, SpriteID pal, int x, int y, int w,
pt = RemapCoords(x, y, z);
ps->x = pt.x;
ps->y = pt.y;
+
+ /* Compute screen extents of sprite */
if (image == SPR_EMPTY_BOUNDING_BOX) {
- ps->left = RemapCoords(x + w , y + bb_offset_y, z + bb_offset_z).x;
- right = RemapCoords(x + bb_offset_x, y + h , z + bb_offset_z).x;
- ps->top = RemapCoords(x + bb_offset_x, y + bb_offset_y, z + dz ).y;
- bottom = RemapCoords(x + w , y + h , z + bb_offset_z).y;
+ left = ps->left = RemapCoords(x + w , y + bb_offset_y, z + bb_offset_z).x;
+ right = RemapCoords(x + bb_offset_x, y + h , z + bb_offset_z).x + 1;
+ top = ps->top = RemapCoords(x + bb_offset_x, y + bb_offset_y, z + dz ).y;
+ bottom = RemapCoords(x + w , y + h , z + bb_offset_z).y + 1;
} else {
const Sprite *spr = GetSprite(image & SPRITE_MASK);
- ps->left = (pt.x += spr->x_offs);
- right = (pt.x + spr->width );
- ps->top = (pt.y += spr->y_offs);
- bottom = (pt.y + spr->height);
- }
- if (ps->left >= vd->dpi.left + vd->dpi.width ||
- right <= vd->dpi.left ||
- ps->top >= vd->dpi.top + vd->dpi.height ||
- bottom <= vd->dpi.top) {
+ left = ps->left = (pt.x += spr->x_offs);
+ right = (pt.x + spr->width );
+ top = ps->top = (pt.y += spr->y_offs);
+ bottom = (pt.y + spr->height);
+ }
+ if (_draw_bounding_boxes && (image != SPR_EMPTY_BOUNDING_BOX)) {
+ /* Compute maximal extents of sprite and it's bounding box */
+ left = min(left , RemapCoords(x + w , y + bb_offset_y, z + bb_offset_z).x);
+ right = max(right , RemapCoords(x + bb_offset_x, y + h , z + bb_offset_z).x + 1);
+ top = min(top , RemapCoords(x + bb_offset_x, y + bb_offset_y, z + dz ).y);
+ bottom = max(bottom, RemapCoords(x + w , y + h , z + bb_offset_z).y + 1);
+ }
+ /* Do not add the sprite to the viewport, if it is outside */
+ if (left >= vd->dpi.left + vd->dpi.width ||
+ right <= vd->dpi.left ||
+ top >= vd->dpi.top + vd->dpi.height ||
+ bottom <= vd->dpi.top) {
return;
}
@@ -616,6 +626,7 @@ void AddChildSpriteScreen(SpriteID image, SpriteID pal, int x, int y)
}
cs = (ChildScreenSpriteToDraw*)vd->spritelist_mem;
+ /* If the ParentSprite was clipped by the viewport bounds, do not draw the ChildSprites either */
if (vd->last_child == NULL) return;
vd->spritelist_mem += sizeof(ChildScreenSpriteToDraw);
@@ -1232,6 +1243,26 @@ static void ViewportDrawParentSprites(ParentSpriteToDraw *psd[])
}
}
+/**
+ * Draws the bounding boxes of all ParentSprites
+ * @param psd Array of ParentSprites
+ */
+static void ViewportDrawBoundingBoxes(ParentSpriteToDraw *psd[])
+{
+ for (; *psd != NULL; psd++) {
+ const ParentSpriteToDraw* ps = *psd;
+ Point pt1 = RemapCoords(ps->xmax + 1, ps->ymax + 1, ps->zmax + 1); // top front corner
+ Point pt2 = RemapCoords(ps->xmin , ps->ymax + 1, ps->zmax + 1); // top left corner
+ Point pt3 = RemapCoords(ps->xmax + 1, ps->ymin , ps->zmax + 1); // top right corner
+ Point pt4 = RemapCoords(ps->xmax + 1, ps->ymax + 1, ps->zmin ); // bottom front corner
+
+ DrawBox( pt1.x, pt1.y,
+ pt2.x - pt1.x, pt2.y - pt1.y,
+ pt3.x - pt1.x, pt3.y - pt1.y,
+ pt4.x - pt1.x, pt4.y - pt1.y);
+ }
+}
+
static void ViewportDrawStrings(DrawPixelInfo *dpi, const StringSpriteToDraw *ss)
{
DrawPixelInfo dp;
@@ -1355,6 +1386,7 @@ void ViewportDoDraw(const ViewPort *vp, int left, int top, int right, int bottom
ViewportSortParentSprites(parent_list);
ViewportDrawParentSprites(parent_list);
+ if (_draw_bounding_boxes) ViewportDrawBoundingBoxes(parent_list);
if (vd.first_string != NULL) ViewportDrawStrings(&vd.dpi, vd.first_string);