Changeset - r7643:9ec38df7caf3
[Not reviewed]
master
0 5 0
rubidium - 17 years ago 2007-09-26 19:27:29
rubidium@openttd.org
(svn r11174) -Codechange: add possibility to show the bounding boxes of sprites using CTRL-B so one can get a better understanding of the used bounding boxes to fix the glitches that still exist. Patch by frosch.
Note that this is not completely glitch free, bounding boxes sometimes aren't removed properly. This is due to the fact that the bounding boxes sometimes are larger than the sprite, which causes a smaller part than the bounding box to be redrawn. This is NOT a bug, but a known implementation limit as we do not want to slow down normal games so the debug graphics are always 100% correct.
5 files changed with 101 insertions and 13 deletions:
0 comments (0 inline, 0 general)
src/gfx.cpp
Show inline comments
 
@@ -139,6 +139,50 @@ void GfxDrawLine(int x, int y, int x2, i
 
	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.
src/gfx.h
Show inline comments
 
@@ -268,6 +268,7 @@ void DrawStringRightAlignedUnderline(int
 

	
 
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);
src/main_gui.cpp
Show inline comments
 
@@ -59,6 +59,8 @@ static int _scengen_town_size = 1; // de
 
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,
 
			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) {
src/variables.h
Show inline comments
 
@@ -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;
src/viewport.cpp
Show inline comments
 
@@ -515,7 +515,7 @@ void AddSortableSpriteToDraw(SpriteID im
 
	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 im
 
	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);
 
		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 (ps->left >= vd->dpi.left + vd->dpi.width ||
 
	    right    <= vd->dpi.left ||
 
	    ps->top  >= vd->dpi.top + vd->dpi.height ||
 
	    bottom   <= vd->dpi.top) {
 
	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
 
	}
 
	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(Pa
 
	}
 
}
 

	
 
/**
 
 * 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, 
 

	
 
	ViewportSortParentSprites(parent_list);
 
	ViewportDrawParentSprites(parent_list);
 
	if (_draw_bounding_boxes) ViewportDrawBoundingBoxes(parent_list);
 

	
 
	if (vd.first_string != NULL) ViewportDrawStrings(&vd.dpi, vd.first_string);
 

	
0 comments (0 inline, 0 general)