(svn r2424) - Fix: backport the smallmap_gui.c changes from the map/ branch into trunk. This also implicitely fixes the bug where the game would crash in certain resolutions with certain minimap masks when dragged partly outside the game-area.
authorDarkvater
Mon, 06 Jun 2005 15:58:58 +0000
changeset 1918 68d78ef6833d
parent 1917 74cab7e464d1
child 1919 0ad642b26ff2
(svn r2424) - Fix: backport the smallmap_gui.c changes from the map/ branch into trunk. This also implicitely fixes the bug where the game would crash in certain resolutions with certain minimap masks when dragged partly outside the game-area.
known-bugs.txt
smallmap_gui.c
table/sprites.h
--- a/known-bugs.txt	Mon Jun 06 14:26:15 2005 +0000
+++ b/known-bugs.txt	Mon Jun 06 15:58:58 2005 +0000
@@ -18,7 +18,6 @@
 ------------------------------------------------------------------------
 URL: http://sourceforge.net/tracker/?atid=636365&group_id=103924&func=browse
 
--		Minimap crash with certain views and certain resolutions
 -		"Broken" autoreplace for dual-headed trains
 -1203319	Pre-signal exits not working when one way signal
 -1197116	Some stations are cargo-less
--- a/smallmap_gui.c	Mon Jun 06 14:26:15 2005 +0000
+++ b/smallmap_gui.c	Mon Jun 06 15:58:58 2005 +0000
@@ -2,6 +2,7 @@
 #include "openttd.h"
 #include "spritecache.h"
 #include "table/strings.h"
+#include "table/sprites.h"
 #include "map.h"
 #include "tile.h"
 #include "gui.h"
@@ -14,32 +15,33 @@
 #include "sound.h"
 
 static const Widget _smallmap_widgets[] = {
-{    WWT_TEXTBTN,   RESIZE_NONE,    13,     0,    10,     0,    13, STR_00C5,		STR_018B_CLOSE_WINDOW},
-{    WWT_CAPTION,  RESIZE_RIGHT,    13,    11,   433,     0,    13, STR_00B0_MAP,STR_018C_WINDOW_TITLE_DRAG_THIS},
-{  WWT_STICKYBOX,     RESIZE_LR,    13,   434,   445,     0,    13, 0x0,         STR_STICKY_BUTTON},
-{     WWT_IMGBTN,     RESIZE_RB,    13,     0,   445,    14,   257, 0x0,					STR_NULL},
-{          WWT_6,     RESIZE_RB,    13,     2,   443,    16,   255, 0x0,					STR_NULL},
-{     WWT_IMGBTN,   RESIZE_LRTB,    13,   380,   401,   258,   279, 0x2E2,				STR_0191_SHOW_LAND_CONTOURS_ON_MAP},
-{     WWT_IMGBTN,   RESIZE_LRTB,    13,   402,   423,   258,   279, 0x2E3,				STR_0192_SHOW_VEHICLES_ON_MAP},
-{     WWT_IMGBTN,   RESIZE_LRTB,    13,   424,   445,   258,   279, 0x2E5,				STR_0193_SHOW_INDUSTRIES_ON_MAP},
-{     WWT_IMGBTN,   RESIZE_LRTB,    13,   380,   401,   280,   301, 0x2E4,				STR_0194_SHOW_TRANSPORT_ROUTES_ON},
-{     WWT_IMGBTN,   RESIZE_LRTB,    13,   402,   423,   280,   301, 0x2E6,				STR_0195_SHOW_VEGETATION_ON_MAP},
-{     WWT_IMGBTN,   RESIZE_LRTB,    13,   424,   445,   280,   301, 0x2E7,				STR_0196_SHOW_LAND_OWNERS_ON_MAP},
-{     WWT_IMGBTN,   RESIZE_LRTB,    13,   358,   379,   258,   279, 0x0,					STR_NULL},
-{     WWT_IMGBTN,   RESIZE_LRTB,    13,   358,   379,   280,   301, 0xFED,				STR_0197_TOGGLE_TOWN_NAMES_ON_OFF},
-{     WWT_IMGBTN,    RESIZE_RTB,    13,     0,   357,   258,   301, 0x0,					STR_NULL},
-{      WWT_PANEL,    RESIZE_RTB,    13,     0,   433,   302,   313, 0x0,					STR_NULL},
-{  WWT_RESIZEBOX,   RESIZE_LRTB,    13,   434,   445,   302,   313, 0x0,					STR_RESIZE_BUTTON},
-{   WIDGETS_END},
+{   WWT_TEXTBTN,   RESIZE_NONE,    13,     0,    10,     0,    13, STR_00C5,                STR_018B_CLOSE_WINDOW},
+{   WWT_CAPTION,  RESIZE_RIGHT,    13,    11,   433,     0,    13, STR_00B0_MAP,            STR_018C_WINDOW_TITLE_DRAG_THIS},
+{ WWT_STICKYBOX,     RESIZE_LR,    13,   434,   445,     0,    13, 0x0,                     STR_STICKY_BUTTON},
+{    WWT_IMGBTN,     RESIZE_RB,    13,     0,   445,    14,   257, 0x0,                     STR_NULL},
+{         WWT_6,     RESIZE_RB,    13,     2,   443,    16,   255, 0x0,                     STR_NULL},
+{    WWT_IMGBTN,   RESIZE_LRTB,    13,   380,   401,   258,   279, SPR_IMG_SHOW_COUNTOURS,  STR_0191_SHOW_LAND_CONTOURS_ON_MAP},
+{    WWT_IMGBTN,   RESIZE_LRTB,    13,   402,   423,   258,   279, SPR_IMG_SHOW_VEHICLES,   STR_0192_SHOW_VEHICLES_ON_MAP},
+{    WWT_IMGBTN,   RESIZE_LRTB,    13,   424,   445,   258,   279, SPR_IMG_INDUSTRY,        STR_0193_SHOW_INDUSTRIES_ON_MAP},
+{    WWT_IMGBTN,   RESIZE_LRTB,    13,   380,   401,   280,   301, SPR_IMG_SHOW_ROUTES,     STR_0194_SHOW_TRANSPORT_ROUTES_ON},
+{    WWT_IMGBTN,   RESIZE_LRTB,    13,   402,   423,   280,   301, SPR_IMG_PLANTTREES,      STR_0195_SHOW_VEGETATION_ON_MAP},
+{    WWT_IMGBTN,   RESIZE_LRTB,    13,   424,   445,   280,   301, SPR_IMG_COMPANY_GENERAL, STR_0196_SHOW_LAND_OWNERS_ON_MAP},
+{    WWT_IMGBTN,   RESIZE_LRTB,    13,   358,   379,   258,   279, 0x0,                     STR_NULL},
+{    WWT_IMGBTN,   RESIZE_LRTB,    13,   358,   379,   280,   301, SPR_IMG_TOWN,            STR_0197_TOGGLE_TOWN_NAMES_ON_OFF},
+{    WWT_IMGBTN,    RESIZE_RTB,    13,     0,   357,   258,   301, 0x0,                     STR_NULL},
+{     WWT_PANEL,    RESIZE_RTB,    13,     0,   433,   302,   313, 0x0,                     STR_NULL},
+{ WWT_RESIZEBOX,   RESIZE_LRTB,    13,   434,   445,   302,   313, 0x0,                     STR_RESIZE_BUTTON},
+{  WIDGETS_END},
 };
 
 static int _smallmap_type;
 static bool _smallmap_show_towns = true;
 
-#define MK(a,b) a,b
-#define MKEND() 0xffff
-#define MS(a,b) (a|0x100),b
+#define MK(a,b) a, b
+#define MKEND() 0xFFFF
+#define MS(a,b) (a | 0x100), b
 
+/* Legend text giving the colours to look for on the minimap */
 static const uint16 _legend_land_contours[] = {
 	MK(0x5A,STR_00F0_100M),
 	MK(0x5C,STR_00F1_200M),
@@ -231,6 +233,7 @@
 #	define MKCOLOR(x) (x)
 #endif
 
+/* Height encodings; 16 levels XXX - needs updating for more/finer heights! */
 static const uint32 _map_height_bits[16] = {
 	MKCOLOR(0x5A5A5A5A),
 	MKCOLOR(0x5A5B5A5B),
@@ -260,6 +263,7 @@
 	return (colour & mask->mand) | mask->mor;
 }
 
+
 static const AndOr _smallmap_contours_andor[] = {
 	{MKCOLOR(0x00000000),MKCOLOR(0xFFFFFFFF)},
 	{MKCOLOR(0x000A0A00),MKCOLOR(0xFF0000FF)},
@@ -305,6 +309,36 @@
 	{MKCOLOR(0x00D7D700),MKCOLOR(0xFF0000FF)},
 };
 
+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(byte *dst, uint xc, uint yc, int pitch, int reps, uint32 mask, GetSmallMapPixels *proc)
+{
+	byte *dst_ptr_end = _screen.dst_ptr + _screen.width * _screen.height - _screen.width;
+
+	do {
+		// check if the tile (xc,yc) is within the map range
+		if (xc < MapSizeX() - 1 && yc < MapSizeY() - 1) {
+			// check if the dst pointer points to a pixel inside the screen buffer
+			if (dst > _screen.dst_ptr && dst < dst_ptr_end)
+				WRITE_PIXELS_OR(dst, proc(TILE_XY(xc, yc)) & mask );
+		}
+	// switch to next tile in the column
+	} while (xc++, yc++, dst += pitch, --reps != 0);
+}
+
 
 static inline TileType GetEffectiveTileType(TileIndex tile)
 {
@@ -324,7 +358,11 @@
 	return t;
 }
 
-
+/**
+ * Return the color a tile would be displayed with in the small map in mode "Contour".
+ * @param tile The tile of which we would like to get the color.
+ * @return The color of tile in the small map in mode "Contour"
+ */
 static inline uint32 GetSmallMapContoursPixels(TileIndex tile)
 {
 	TileType t = GetEffectiveTileType(tile);
@@ -333,16 +371,12 @@
 		ApplyMask(_map_height_bits[TileHeight(tile)], &_smallmap_contours_andor[t]);
 }
 
-static void DrawSmallMapContours(byte *dst, uint xc, uint yc, int pitch, int reps, uint32 mask)
-{
-	do {
-		if (xc < MapMaxX() && yc < MapMaxY())
-			if (dst > _screen.dst_ptr && dst < (_screen.dst_ptr + _screen.width * _screen.height - _screen.width))
-				WRITE_PIXELS_OR(dst, GetSmallMapContoursPixels(TILE_XY(xc,yc)) & mask);
-	} while (xc++,yc++,dst+=pitch,--reps != 0);
-}
-
-
+/**
+ * Return the color a tile would be displayed with in the small map in mode "Vehicles".
+ *
+ * @param t The tile of which we would like to get the color.
+ * @return The color of tile in the small map in mode "Vehicles"
+ */
 static inline uint32 GetSmallMapVehiclesPixels(TileIndex tile)
 {
 	TileType t = GetEffectiveTileType(tile);
@@ -350,15 +384,7 @@
 	return ApplyMask(MKCOLOR(0x54545454), &_smallmap_vehicles_andor[t]);
 }
 
-
-static void DrawSmallMapVehicles(byte *dst, uint xc, uint yc, int pitch, int reps, uint32 mask)
-{
-	do {
-		if (xc < MapMaxX() && yc < MapMaxY())
-			WRITE_PIXELS_OR( dst, GetSmallMapVehiclesPixels(TILE_XY(xc,yc)) & mask );
-	} while (xc++,yc++,dst+=pitch,--reps != 0);
-}
-
+/* Industry colours... a total of 175 gfx - XXX - increase if more industries */
 static const byte _industry_smallmap_colors[175] = {
 	215,215,215,215,215,215,215,184,
 	184,184,184,194,194,194,194,194,
@@ -384,6 +410,12 @@
 	 15, 15, 15, 15, 15, 15, 15,
 };
 
+/**
+ * Return the color a tile would be displayed with in the small map in mode "Industries".
+ *
+ * @param tile The tile of which we would like to get the color.
+ * @return The color of tile in the small map in mode "Industries"
+ */
 static inline uint32 GetSmallMapIndustriesPixels(TileIndex tile)
 {
 	TileType t = GetEffectiveTileType(tile);
@@ -391,19 +423,17 @@
 	if (t == MP_INDUSTRY) {
 		byte color = _industry_smallmap_colors[_map5[tile]];
 		return color + (color << 8) + (color << 16) + (color << 24);
-	} else {
-		return ApplyMask(MKCOLOR(0x54545454), &_smallmap_vehicles_andor[t]);
 	}
+
+	return ApplyMask(MKCOLOR(0x54545454), &_smallmap_vehicles_andor[t]);
 }
 
-static void DrawSmallMapIndustries(byte *dst, uint xc, uint yc, int pitch, int reps, uint32 mask)
-{
-	do {
-		if (xc < MapMaxX() && yc < MapMaxY())
-			WRITE_PIXELS_OR(dst, GetSmallMapIndustriesPixels(TILE_XY(xc,yc)) & mask);
-	} while (xc++,yc++,dst+=pitch,--reps != 0);
-}
-
+/**
+ * Return the color a tile would be displayed with in the small map in mode "Routes".
+ *
+ * @param t The tile of which we would like to get the color.
+ * @return The color of tile  in the small map in mode "Routes"
+ */
 static inline uint32 GetSmallMapRoutesPixels(TileIndex tile)
 {
 	TileType t = GetEffectiveTileType(tile);
@@ -425,27 +455,20 @@
 	return bits;
 }
 
-static void DrawSmallMapRoutes(byte *dst, uint xc, uint yc, int pitch, int reps, uint32 mask)
-{
-	do {
-		if (xc < MapMaxX() && yc < MapMaxY())
-			WRITE_PIXELS_OR(dst, GetSmallMapRoutesPixels(TILE_XY(xc,yc)) & mask);
-	} while (xc++,yc++,dst+=pitch,--reps != 0);
-}
 
 static const uint32 _vegetation_clear_bits[4 + 7] = {
-	MKCOLOR(0x37373737),
-	MKCOLOR(0x37373737),
-	MKCOLOR(0x37373737),
-	MKCOLOR(0x54545454),
+	MKCOLOR(0x37373737), ///< bare land
+	MKCOLOR(0x37373737), ///< 1/3 grass
+	MKCOLOR(0x37373737), ///< 2/3 grass
+	MKCOLOR(0x54545454), ///< full grass
 
-	MKCOLOR(0x52525252),
-	MKCOLOR(0x0A0A0A0A),
-	MKCOLOR(0x25252525),
-	MKCOLOR(0x98989898),
-	MKCOLOR(0xC2C2C2C2),
-	MKCOLOR(0x54545454),
-	MKCOLOR(0x54545454),
+	MKCOLOR(0x52525252), ///< rough land
+	MKCOLOR(0x0A0A0A0A), ///< rocks
+	MKCOLOR(0x25252525), ///< fields
+	MKCOLOR(0x98989898), ///< snow
+	MKCOLOR(0xC2C2C2C2), ///< desert
+	MKCOLOR(0x54545454), ///< unused
+	MKCOLOR(0x54545454), ///< unused
 };
 
 static inline uint32 GetSmallMapVegetationPixels(TileIndex tile)
@@ -481,17 +504,14 @@
 }
 
 
-static void DrawSmallMapVegetation(byte *dst, uint xc, uint yc, int pitch, int reps, uint32 mask)
-{
-	do {
-		if (xc < MapMaxX() && yc < MapMaxY())
-			WRITE_PIXELS_OR(dst, GetSmallMapVegetationPixels(TILE_XY(xc,yc)) & mask);
-	} while (xc++,yc++,dst+=pitch,--reps != 0);
-}
-
-
 static uint32 _owner_colors[256];
 
+/**
+ * Return the color a tile would be displayed with in the small map in mode "Owner".
+ *
+ * @param t The tile of which we would like to get the color.
+ * @return The color of tile in the small map in mode "Owner"
+ */
 static inline uint32 GetSmallMapOwnerPixels(TileIndex tile)
 {
 	TileType t = GetTileType(tile);
@@ -508,15 +528,6 @@
 }
 
 
-static void DrawSmallMapOwners(byte *dst, uint xc, uint yc, int pitch, int reps, uint32 mask)
-{
-	do {
-		if (xc < MapMaxX() && yc < MapMaxY())
-			WRITE_PIXELS_OR(dst, GetSmallMapOwnerPixels(TILE_XY(xc,yc)) & mask);
-	} while (xc++,yc++,dst+=pitch,--reps != 0);
-}
-
-
 static const uint32 _smallmap_mask_left[3] = {
 	MKCOLOR(0xFF000000),
 	MKCOLOR(0xFFFF0000),
@@ -531,15 +542,13 @@
 
 /* each tile has 4 x pixels and 1 y pixel */
 
-typedef void SmallmapDrawProc(byte *dst, uint xc, uint yc, int pitch, int reps, uint32 mask);
-
-static SmallmapDrawProc *_smallmap_draw_procs[] = {
-	DrawSmallMapContours,
-	DrawSmallMapVehicles,
-	DrawSmallMapIndustries,
-	DrawSmallMapRoutes,
-	DrawSmallMapVegetation,
-	DrawSmallMapOwners,
+static GetSmallMapPixels *_smallmap_draw_procs[] = {
+	GetSmallMapContoursPixels,
+	GetSmallMapVehiclesPixels,
+	GetSmallMapIndustriesPixels,
+	GetSmallMapRoutesPixels,
+	GetSmallMapVegetationPixels,
+	GetSmallMapOwnerPixels,
 };
 
 static const byte _vehicle_type_colors[6] = {
@@ -562,6 +571,20 @@
 	GfxFillRect(x2 - 3, y, x2, y2, 69);
 }
 
+/**
+ * Draws the small map.
+ *
+ * Basically, the small map is draw column of pixels by column of pixels. The pixels
+ * are drawn directly into the screen buffer. The final map is drawn in multiple passes.
+ * The passes are:
+ * <ol><li>The colors of tiles in the different modes.</li>
+ * <li>Town names (optional)</li>
+ *
+ * @param dpi pointer to pixel to write onto
+ * @param w pointer to Window struct
+ * @param type type of map requested (vegetation, owners, routes, etc)
+ * @param show_towns true if the town names should be displayed, false if not.
+ */
 static void DrawSmallMap(DrawPixelInfo *dpi, Window *w, int type, bool show_towns)
 {
 	DrawPixelInfo *old_dpi;
@@ -569,7 +592,6 @@
 	byte *ptr;
 	int tile_x;
 	int tile_y;
-	SmallmapDrawProc *proc;
 	ViewPort *vp;
 
 	old_dpi = _cur_dpi;
@@ -594,7 +616,7 @@
 		FOR_ALL_PLAYERS(p) {
 			if (p->is_active)
 				_owner_colors[p->index] =
-					dup_byte32(GetNonSprite(0x307 + p->player_color)[0xCB]);
+					dup_byte32(GetNonSprite(775 + p->player_color)[0xCB]); // XXX - magic pixel
 		}
 	}
 
@@ -620,8 +642,6 @@
 		}
 	}
 
-	proc = _smallmap_draw_procs[type];
-
 	ptr = dpi->dst_ptr - dx - 4;
 	x = - dx - 4;
 	y = 0;
@@ -653,7 +673,7 @@
 		reps = (dpi->height - y + 1) / 2;
 		if (reps > 0) {
 //			assert(ptr >= dpi->dst_ptr);
-			proc(ptr, tile_x, tile_y, dpi->pitch*2, reps, mask);
+			DrawSmallMapStuff(ptr, tile_x, tile_y, dpi->pitch*2, reps, mask, _smallmap_draw_procs[type]);
 		}
 
 skip_column:
@@ -723,7 +743,7 @@
 	}
 
 	if (show_towns) {
-		Town *t;
+		const Town *t;
 
 		FOR_ALL_TOWNS(t) {
 			if (t->xy != 0) {
@@ -778,7 +798,7 @@
 
 static void SmallMapWindowProc(Window *w, WindowEvent *e)
 {
-	switch(e->event) {
+	switch (e->event) {
 	case WE_PAINT: {
 		const uint16 *tbl;
 		int x,y,y_org;
@@ -816,8 +836,8 @@
 	} break;
 
 	case WE_CLICK:
-		switch(e->click.widget) {
-		case 4: {/* main wnd */
+		switch (e->click.widget) {
+		case 4: {/* Main wnd */
 			Window *w2;
 			Point pt;
 
@@ -830,12 +850,12 @@
 			WP(w2,vp_d).scrollpos_y = pt.y + ((_cursor.pos.y - w->top - 16) << 4) - (w2->viewport->virtual_height >> 1);
 		} break;
 
-		case 5: /* show land contours */
-		case 6: /* show vehicles */
-		case 7: /* show industries */
-		case 8: /* show transport routes */
-		case 9: /* show vegetation */
-		case 10: /* show land owners */
+		case 5: /* Show land contours */
+		case 6: /* Show vehicles */
+		case 7: /* Show industries */
+		case 8: /* Show transport routes */
+		case 9: /* Show vegetation */
+		case 10: /* Show land owners */
 			w->click_state &= ~(1<<5|1<<6|1<<7|1<<8|1<<9|1<<10);
 			w->click_state |= 1 << e->click.widget;
 			_smallmap_type = e->click.widget - 5;
--- a/table/sprites.h	Mon Jun 06 14:26:15 2005 +0000
+++ b/table/sprites.h	Mon Jun 06 15:58:58 2005 +0000
@@ -695,7 +695,11 @@
 	SPR_IMG_COMPANY_GENERAL = 743,
 	SPR_IMG_GRAPHS          = 745,
 	SPR_IMG_COMPANY_LEAGUE  = 684,
+	SPR_IMG_SHOW_COUNTOURS  = 738,
+	SPR_IMG_SHOW_VEHICLES   = 739,
+	SPR_IMG_SHOW_ROUTES     = 740,
 	SPR_IMG_INDUSTRY        = 741,
+	SPR_IMG_PLANTTREES      = 742,
 	SPR_IMG_TRAINLIST       = 731,
 	SPR_IMG_TRUCKLIST       = 732,
 	SPR_IMG_SHIPLIST        = 733,
@@ -710,7 +714,6 @@
 	SPR_IMG_MUSIC           = 713,
 	SPR_IMG_MESSAGES        = 680,
 	SPR_IMG_QUERY           = 723,
-	SPR_IMG_PLANTTREES      = 742,
 	SPR_IMG_SIGN            = 4082,
 	SPR_IMG_BUY_LAND        = 4791,