diff options
-rw-r--r-- | src/gfx.cpp | 44 | ||||
-rw-r--r-- | src/gfx.h | 1 | ||||
-rw-r--r-- | src/main_gui.cpp | 9 | ||||
-rw-r--r-- | src/variables.h | 2 | ||||
-rw-r--r-- | src/viewport.cpp | 60 |
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. @@ -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); |