Changeset - r12158:877810178bb1
[Not reviewed]
master
0 1 0
rubidium - 15 years ago 2009-06-16 10:46:11
rubidium@openttd.org
(svn r16579) -Codechange: rework smallmap code a bit; remove goto, remove some unneeded variables, return value directly instead of writing it to a variable to later return that
1 file changed with 140 insertions and 149 deletions:
0 comments (0 inline, 0 general)
src/smallmap_gui.cpp
Show inline comments
 
@@ -230,12 +230,11 @@ static uint _industry_to_list_pos[NUM_IN
 
 */
 
void BuildIndustriesLegend()
 
{
 
	const IndustrySpec *indsp;
 
	uint j = 0;
 

	
 
	/* Add each name */
 
	for (IndustryType i = 0; i < NUM_INDUSTRYTYPES; i++) {
 
		indsp = GetIndustrySpec(i);
 
		const IndustrySpec *indsp = GetIndustrySpec(i);
 
		if (indsp->enabled) {
 
			_legend_from_industries[j].legend = indsp->name;
 
			_legend_from_industries[j].colour = indsp->map_colour;
 
@@ -348,53 +347,6 @@ static const AndOr _smallmap_vegetation_
 

	
 
typedef uint32 GetSmallMapPixels(TileIndex tile); // typedef callthrough function
 

	
 
/**
 
 * Draws one column of the small map in a certain mode onto the screen buffer. This
 
 * function looks exactly the same for all types
 
 *
 
 * @param dst Pointer to a part of the screen buffer to write to.
 
 * @param xc The X coordinate of the first tile in the column.
 
 * @param yc The Y coordinate of the first tile in the column
 
 * @param pitch Number of pixels to advance in the screen buffer each time a pixel is written.
 
 * @param reps Number of lines to draw
 
 * @param mask ?
 
 * @param proc Pointer to the colour function
 
 * @see GetSmallMapPixels(TileIndex)
 
 */
 
static void DrawSmallMapStuff(void *dst, uint xc, uint yc, int pitch, int reps, uint32 mask, GetSmallMapPixels *proc)
 
{
 
	Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter();
 
	void *dst_ptr_abs_end = blitter->MoveTo(_screen.dst_ptr, 0, _screen.height);
 
	void *dst_ptr_end = blitter->MoveTo(dst_ptr_abs_end, -4, 0);
 

	
 
	do {
 
		/* check if the tile (xc,yc) is within the map range */
 
		uint min_xy = _settings_game.construction.freeform_edges ? 1 : 0;
 
		if (IsInsideMM(xc, min_xy, MapMaxX()) && IsInsideMM(yc, min_xy, MapMaxY())) {
 
			/* check if the dst pointer points to a pixel inside the screen buffer */
 
			if (dst < _screen.dst_ptr) continue;
 
			if (dst >= dst_ptr_abs_end) continue;
 

	
 
			uint32 val = proc(TileXY(xc, yc)) & mask;
 
			uint8 *val8 = (uint8 *)&val;
 

	
 
			if (dst <= dst_ptr_end) {
 
				blitter->SetPixelIfEmpty(dst, 0, 0, val8[0]);
 
				blitter->SetPixelIfEmpty(dst, 1, 0, val8[1]);
 
				blitter->SetPixelIfEmpty(dst, 2, 0, val8[2]);
 
				blitter->SetPixelIfEmpty(dst, 3, 0, val8[3]);
 
			} else {
 
				/* It happens that there are only 1, 2 or 3 pixels left to fill, so in that special case, write till the end of the video-buffer */
 
				int i = 0;
 
				do {
 
					blitter->SetPixelIfEmpty(dst, 0, 0, val8[i]);
 
				} while (i++, dst = blitter->MoveTo(dst, 1, 0), dst < dst_ptr_abs_end);
 
			}
 
		}
 
	/* switch to next tile in the column */
 
	} while (xc++, yc++, dst = blitter->MoveTo(dst, pitch, 0), --reps != 0);
 
}
 

	
 

	
 
static inline TileType GetEffectiveTileType(TileIndex tile)
 
{
 
@@ -421,8 +373,7 @@ static inline uint32 GetSmallMapContours
 
{
 
	TileType t = GetEffectiveTileType(tile);
 

	
 
	return
 
		ApplyMask(_map_height_bits[TileHeight(tile)], &_smallmap_contours_andor[t]);
 
	return ApplyMask(_map_height_bits[TileHeight(tile)], &_smallmap_contours_andor[t]);
 
}
 

	
 
/**
 
@@ -470,22 +421,20 @@ static inline uint32 GetSmallMapIndustri
 
static inline uint32 GetSmallMapRoutesPixels(TileIndex tile)
 
{
 
	TileType t = GetEffectiveTileType(tile);
 
	uint32 bits;
 

	
 
	if (t == MP_STATION) {
 
		switch (GetStationType(tile)) {
 
			case STATION_RAIL:    bits = MKCOLOUR(0x56565656); break;
 
			case STATION_AIRPORT: bits = MKCOLOUR(0xB8B8B8B8); break;
 
			case STATION_TRUCK:   bits = MKCOLOUR(0xC2C2C2C2); break;
 
			case STATION_BUS:     bits = MKCOLOUR(0xBFBFBFBF); break;
 
			case STATION_DOCK:    bits = MKCOLOUR(0x98989898); break;
 
			default:              bits = MKCOLOUR(0xFFFFFFFF); break;
 
			case STATION_RAIL:    return MKCOLOUR(0x56565656);
 
			case STATION_AIRPORT: return MKCOLOUR(0xB8B8B8B8);
 
			case STATION_TRUCK:   return MKCOLOUR(0xC2C2C2C2);
 
			case STATION_BUS:     return MKCOLOUR(0xBFBFBFBF);
 
			case STATION_DOCK:    return MKCOLOUR(0x98989898);
 
			default:              return MKCOLOUR(0xFFFFFFFF);
 
		}
 
	} else {
 
		/* ground colour */
 
		bits = ApplyMask(MKCOLOUR(0x54545454), &_smallmap_contours_andor[t]);
 
	}
 
	return bits;
 

	
 
	/* ground colour */
 
	return ApplyMask(MKCOLOUR(0x54545454), &_smallmap_contours_andor[t]);
 
}
 

	
 

	
 
@@ -503,35 +452,23 @@ static const uint32 _vegetation_clear_bi
 
static inline uint32 GetSmallMapVegetationPixels(TileIndex tile)
 
{
 
	TileType t = GetEffectiveTileType(tile);
 
	uint32 bits;
 

	
 
	switch (t) {
 
		case MP_CLEAR:
 
			if (IsClearGround(tile, CLEAR_GRASS) && GetClearDensity(tile) < 3) {
 
				bits = MKCOLOUR(0x37373737);
 
			} else {
 
				bits = _vegetation_clear_bits[GetClearGround(tile)];
 
			}
 
			break;
 
			return (IsClearGround(tile, CLEAR_GRASS) && GetClearDensity(tile) < 3) ? MKCOLOUR(0x37373737) : _vegetation_clear_bits[GetClearGround(tile)];
 

	
 
		case MP_INDUSTRY:
 
			bits = GetIndustrySpec(GetIndustryByTile(tile)->type)->check_proc == CHECK_FOREST ? MKCOLOUR(0xD0D0D0D0) : MKCOLOUR(0xB5B5B5B5);
 
			break;
 
			return GetIndustrySpec(GetIndustryByTile(tile)->type)->check_proc == CHECK_FOREST ? MKCOLOUR(0xD0D0D0D0) : MKCOLOUR(0xB5B5B5B5);
 

	
 
		case MP_TREES:
 
			if (GetTreeGround(tile) == TREE_GROUND_SNOW_DESERT) {
 
				bits = (_settings_game.game_creation.landscape == LT_ARCTIC) ? MKCOLOUR(0x98575798) : MKCOLOUR(0xC25757C2);
 
			} else {
 
				bits = MKCOLOUR(0x54575754);
 
				return (_settings_game.game_creation.landscape == LT_ARCTIC) ? MKCOLOUR(0x98575798) : MKCOLOUR(0xC25757C2);
 
			}
 
			break;
 
			return MKCOLOUR(0x54575754);
 

	
 
		default:
 
			bits = ApplyMask(MKCOLOUR(0x54545454), &_smallmap_vehicles_andor[t]);
 
			break;
 
			return ApplyMask(MKCOLOUR(0x54545454), &_smallmap_vehicles_andor[t]);
 
	}
 

	
 
	return bits;
 
}
 

	
 

	
 
@@ -623,6 +560,75 @@ class SmallMapWindow : public Window
 
	static const int COLUMN_WIDTH = 119;
 
	static const int MIN_LEGEND_HEIGHT = 6 * 7;
 

	
 
	/**
 
	 * Remap a map's tile X coordinate (TileX(TileIndex)) to
 
	 * a location on this smallmap.
 
	 * @param tile_x the tile's X coordinate.
 
	 * @return the X coordinate to draw on.
 
	 */
 
	inline int RemapX(int tile_x)
 
	{
 
		return tile_x - this->scroll_x / TILE_SIZE;
 
	}
 

	
 
	/**
 
	 * Remap a map's tile Y coordinate (TileY(TileIndex)) to
 
	 * a location on this smallmap.
 
	 * @param tile_y the tile's Y coordinate.
 
	 * @return the Y coordinate to draw on.
 
	 */
 
	inline int RemapY(int tile_y)
 
	{
 
		return tile_y - this->scroll_y / TILE_SIZE;
 
	}
 

	
 
	/**
 
	 * Draws one column of the small map in a certain mode onto the screen buffer. This
 
	 * function looks exactly the same for all types
 
	 *
 
	 * @param dst Pointer to a part of the screen buffer to write to.
 
	 * @param xc The X coordinate of the first tile in the column.
 
	 * @param yc The Y coordinate of the first tile in the column
 
	 * @param pitch Number of pixels to advance in the screen buffer each time a pixel is written.
 
	 * @param reps Number of lines to draw
 
	 * @param mask ?
 
	 * @param proc Pointer to the colour function
 
	 * @see GetSmallMapPixels(TileIndex)
 
	 */
 
	inline void DrawSmallMapStuff(void *dst, uint xc, uint yc, int pitch, int reps, uint32 mask, GetSmallMapPixels *proc)
 
	{
 
		Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter();
 
		void *dst_ptr_abs_end = blitter->MoveTo(_screen.dst_ptr, 0, _screen.height);
 
		void *dst_ptr_end = blitter->MoveTo(dst_ptr_abs_end, -4, 0);
 

	
 
		do {
 
			/* check if the tile (xc,yc) is within the map range */
 
			uint min_xy = _settings_game.construction.freeform_edges ? 1 : 0;
 
			if (IsInsideMM(xc, min_xy, MapMaxX()) && IsInsideMM(yc, min_xy, MapMaxY())) {
 
				/* check if the dst pointer points to a pixel inside the screen buffer */
 
				if (dst < _screen.dst_ptr) continue;
 
				if (dst >= dst_ptr_abs_end) continue;
 

	
 
				uint32 val = proc(TileXY(xc, yc)) & mask;
 
				uint8 *val8 = (uint8 *)&val;
 

	
 
				if (dst <= dst_ptr_end) {
 
					blitter->SetPixelIfEmpty(dst, 0, 0, val8[0]);
 
					blitter->SetPixelIfEmpty(dst, 1, 0, val8[1]);
 
					blitter->SetPixelIfEmpty(dst, 2, 0, val8[2]);
 
					blitter->SetPixelIfEmpty(dst, 3, 0, val8[3]);
 
				} else {
 
					/* It happens that there are only 1, 2 or 3 pixels left to fill, so in that special case, write till the end of the video-buffer */
 
					int i = 0;
 
					do {
 
						blitter->SetPixelIfEmpty(dst, 0, 0, val8[i]);
 
					} while (i++, dst = blitter->MoveTo(dst, 1, 0), dst < dst_ptr_abs_end);
 
				}
 
			}
 
		/* switch to next tile in the column */
 
		} while (xc++, yc++, dst = blitter->MoveTo(dst, pitch, 0), --reps != 0);
 
	}
 

	
 
public:
 
	/**
 
	 * Draws the small map.
 
@@ -642,11 +648,6 @@ public:
 
	{
 
		Blitter *blitter = BlitterFactoryBase::GetCurrentBlitter();
 
		DrawPixelInfo *old_dpi;
 
		int dx, dy, x, y, x2, y2;
 
		void *ptr;
 
		int tile_x;
 
		int tile_y;
 
		ViewPort *vp;
 

	
 
		old_dpi = _cur_dpi;
 
		_cur_dpi = dpi;
 
@@ -659,8 +660,8 @@ public:
 
			const Company *c;
 

	
 
			/* fill with some special colours */
 
			_owner_colours[OWNER_TOWN] = MKCOLOUR(0xB4B4B4B4);
 
			_owner_colours[OWNER_NONE] = MKCOLOUR(0x54545454);
 
			_owner_colours[OWNER_TOWN]  = MKCOLOUR(0xB4B4B4B4);
 
			_owner_colours[OWNER_NONE]  = MKCOLOUR(0x54545454);
 
			_owner_colours[OWNER_WATER] = MKCOLOUR(0xCACACACA);
 
			_owner_colours[OWNER_END]   = MKCOLOUR(0x20202020); // industry
 

	
 
@@ -671,15 +672,15 @@ public:
 
			}
 
		}
 

	
 
		tile_x = this->scroll_x / TILE_SIZE;
 
		tile_y = this->scroll_y / TILE_SIZE;
 
		int tile_x = this->scroll_x / TILE_SIZE;
 
		int tile_y = this->scroll_y / TILE_SIZE;
 

	
 
		dx = dpi->left + this->subscroll;
 
		int dx = dpi->left + this->subscroll;
 
		tile_x -= dx / 4;
 
		tile_y += dx / 4;
 
		dx &= 3;
 

	
 
		dy = dpi->top;
 
		int dy = dpi->top;
 
		tile_x += dy / 2;
 
		tile_y += dy / 2;
 

	
 
@@ -693,37 +694,35 @@ public:
 
			}
 
		}
 

	
 
		ptr = blitter->MoveTo(dpi->dst_ptr, -dx - 4, 0);
 
		x = - dx - 4;
 
		y = 0;
 
		void *ptr = blitter->MoveTo(dpi->dst_ptr, -dx - 4, 0);
 
		int x = - dx - 4;
 
		int y = 0;
 

	
 
		for (;;) {
 
			uint32 mask = 0xFFFFFFFF;
 
			int reps;
 
			int t;
 

	
 
			/* distance from left edge */
 
			if (x < 0) {
 
				if (x < -3) goto skip_column;
 
				/* mask to use at the left edge */
 
				mask = _smallmap_mask_left[x + 3];
 
			if (x >= -3) {
 
				if (x < 0) {
 
					/* mask to use at the left edge */
 
					mask = _smallmap_mask_left[x + 3];
 
				}
 

	
 
				/* distance from right edge */
 
				int t = dpi->width - x;
 
				if (t < 4) {
 
					if (t <= 0) break; // exit loop
 
					/* mask to use at the right edge */
 
					mask &= _smallmap_mask_right[t - 1];
 
				}
 

	
 
				/* number of lines */
 
				int reps = (dpi->height - y + 1) / 2;
 
				if (reps > 0) {
 
					this->DrawSmallMapStuff(ptr, tile_x, tile_y, dpi->pitch * 2, reps, mask, _smallmap_draw_procs[this->map_type]);
 
				}
 
			}
 

	
 
			/* distance from right edge */
 
			t = dpi->width - x;
 
			if (t < 4) {
 
				if (t <= 0) break; // exit loop
 
				/* mask to use at the right edge */
 
				mask &= _smallmap_mask_right[t - 1];
 
			}
 

	
 
			/* number of lines */
 
			reps = (dpi->height - y + 1) / 2;
 
			if (reps > 0) {
 
				DrawSmallMapStuff(ptr, tile_x, tile_y, dpi->pitch * 2, reps, mask, _smallmap_draw_procs[this->map_type]);
 
			}
 

	
 
	skip_column:
 
			if (y == 0) {
 
				tile_y++;
 
				y++;
 
@@ -740,17 +739,15 @@ public:
 
		/* draw vehicles? */
 
		if (this->map_type == SMT_CONTOUR || this->map_type == SMT_VEHICLES) {
 
			Vehicle *v;
 
			bool skip;
 
			byte colour;
 

	
 
			FOR_ALL_VEHICLES(v) {
 
				if (v->type != VEH_EFFECT &&
 
						(v->vehstatus & (VS_HIDDEN | VS_UNCLICKABLE)) == 0) {
 
					/* Remap into flat coordinates. */
 
					Point pt = RemapCoords(
 
						v->x_pos / TILE_SIZE - this->scroll_x / TILE_SIZE, // divide each one separately because (a-b)/c != a/c-b/c in integer world
 
						v->y_pos / TILE_SIZE - this->scroll_y / TILE_SIZE, //    dtto
 
						0);
 
							this->RemapX(v->x_pos / TILE_SIZE),
 
							this->RemapY(v->y_pos / TILE_SIZE),
 
							0);
 
					x = pt.x;
 
					y = pt.y;
 

	
 
@@ -759,7 +756,7 @@ public:
 
					if (!IsInsideMM(y, 0, dpi->height)) continue;
 

	
 
					/* Default is to draw both pixels. */
 
					skip = false;
 
					bool skip = false;
 

	
 
					/* Offset X coordinate */
 
					x -= this->subscroll + 3 + dpi->left;
 
@@ -776,7 +773,7 @@ public:
 
					}
 

	
 
					/* Calculate pointer to pixel and the colour */
 
					colour = (this->map_type == SMT_VEHICLES) ? _vehicle_type_colours[v->type] : 0xF;
 
					byte colour = (this->map_type == SMT_VEHICLES) ? _vehicle_type_colours[v->type] : 0xF;
 

	
 
					/* And draw either one or two pixels depending on clipping */
 
					blitter->SetPixel(dpi->dst_ptr, x, y, colour);
 
@@ -791,9 +788,9 @@ public:
 
			FOR_ALL_TOWNS(t) {
 
				/* Remap the town coordinate */
 
				Point pt = RemapCoords(
 
					(int)(TileX(t->xy) * TILE_SIZE - this->scroll_x) / TILE_SIZE,
 
					(int)(TileY(t->xy) * TILE_SIZE - this->scroll_y) / TILE_SIZE,
 
					0);
 
						this->RemapX(TileX(t->xy)),
 
						this->RemapY(TileY(t->xy)),
 
						0);
 
				x = pt.x - this->subscroll + 3 - (t->sign.width_2 >> 1);
 
				y = pt.y;
 

	
 
@@ -809,42 +806,36 @@ public:
 
			}
 
		}
 

	
 
		/* Draw map indicators */
 
		{
 
			Point pt;
 
		/* Find main viewport. */
 
		ViewPort *vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
 

	
 
			/* Find main viewport. */
 
			vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
 

	
 
			pt = RemapCoords(this->scroll_x, this->scroll_y, 0);
 
		/* Draw map indicators */
 
		Point pt = RemapCoords(this->scroll_x, this->scroll_y, 0);
 

	
 
			x = vp->virtual_left - pt.x;
 
			y = vp->virtual_top - pt.y;
 
			x2 = (x + vp->virtual_width) / TILE_SIZE;
 
			y2 = (y + vp->virtual_height) / TILE_SIZE;
 
			x /= TILE_SIZE;
 
			y /= TILE_SIZE;
 
		x = vp->virtual_left - pt.x;
 
		y = vp->virtual_top - pt.y;
 
		int x2 = (x + vp->virtual_width) / TILE_SIZE;
 
		int y2 = (y + vp->virtual_height) / TILE_SIZE;
 
		x /= TILE_SIZE;
 
		y /= TILE_SIZE;
 

	
 
			x -= this->subscroll;
 
			x2 -= this->subscroll;
 
		x -= this->subscroll;
 
		x2 -= this->subscroll;
 

	
 
			DrawVertMapIndicator(x, y, x, y2);
 
			DrawVertMapIndicator(x2, y, x2, y2);
 
		DrawVertMapIndicator(x, y, x, y2);
 
		DrawVertMapIndicator(x2, y, x2, y2);
 

	
 
			DrawHorizMapIndicator(x, y, x2, y);
 
			DrawHorizMapIndicator(x, y2, x2, y2);
 
		}
 
		DrawHorizMapIndicator(x, y, x2, y);
 
		DrawHorizMapIndicator(x, y2, x2, y2);
 
		_cur_dpi = old_dpi;
 
	}
 

	
 
	void SmallMapCenterOnCurrentPos()
 
	{
 
		int x, y;
 
		ViewPort *vp;
 
		vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
 
		ViewPort *vp = FindWindowById(WC_MAIN_WINDOW, 0)->viewport;
 

	
 
		x  = ((vp->virtual_width  - (this->widget[SM_WIDGET_MAP].right  - this->widget[SM_WIDGET_MAP].left) * TILE_SIZE) / 2 + vp->virtual_left) / 4;
 
		y  = ((vp->virtual_height - (this->widget[SM_WIDGET_MAP].bottom - this->widget[SM_WIDGET_MAP].top ) * TILE_SIZE) / 2 + vp->virtual_top ) / 2 - TILE_SIZE * 2;
 
		int x = ((vp->virtual_width  - (this->widget[SM_WIDGET_MAP].right  - this->widget[SM_WIDGET_MAP].left) * TILE_SIZE) / 2 + vp->virtual_left) / 4;
 
		int y = ((vp->virtual_height - (this->widget[SM_WIDGET_MAP].bottom - this->widget[SM_WIDGET_MAP].top ) * TILE_SIZE) / 2 + vp->virtual_top ) / 2 - TILE_SIZE * 2;
 
		this->scroll_x = (y - x) & ~0xF;
 
		this->scroll_y = (x + y) & ~0xF;
 
		this->SetDirty();
0 comments (0 inline, 0 general)