changeset 17855:a35585431755 draft

(svn r22646) -Codechange: Simplify MP_WATER map accessors, esp. for locks and depots. (based on patched by adf88 and michi_cc)
author frosch <frosch@openttd.org>
date Sun, 10 Jul 2011 13:04:04 +0000
parents dad45d2edebf
children 182eebeb857e
files src/dock_gui.cpp src/newgrf_canal.cpp src/table/water_land.h src/water.h src/water_cmd.cpp src/water_map.h
diffstat 6 files changed, 127 insertions(+), 81 deletions(-) [+]
line wrap: on
line diff
--- a/src/dock_gui.cpp
+++ b/src/dock_gui.cpp
@@ -522,10 +522,10 @@
 	{
 		this->DrawWidgets();
 
-		DrawShipDepotSprite(this->GetWidget<NWidgetBase>(BDDW_X)->pos_x + 64, this->GetWidget<NWidgetBase>(BDDW_X)->pos_y + 18, 0);
-		DrawShipDepotSprite(this->GetWidget<NWidgetBase>(BDDW_X)->pos_x + 32, this->GetWidget<NWidgetBase>(BDDW_X)->pos_y + 34, 1);
-		DrawShipDepotSprite(this->GetWidget<NWidgetBase>(BDDW_Y)->pos_x + 32, this->GetWidget<NWidgetBase>(BDDW_Y)->pos_y + 18, 2);
-		DrawShipDepotSprite(this->GetWidget<NWidgetBase>(BDDW_Y)->pos_x + 64, this->GetWidget<NWidgetBase>(BDDW_Y)->pos_y + 34, 3);
+		DrawShipDepotSprite(this->GetWidget<NWidgetBase>(BDDW_X)->pos_x + 64, this->GetWidget<NWidgetBase>(BDDW_X)->pos_y + 18, AXIS_X, DEPOT_PART_NORTH);
+		DrawShipDepotSprite(this->GetWidget<NWidgetBase>(BDDW_X)->pos_x + 32, this->GetWidget<NWidgetBase>(BDDW_X)->pos_y + 34, AXIS_X, DEPOT_PART_SOUTH);
+		DrawShipDepotSprite(this->GetWidget<NWidgetBase>(BDDW_Y)->pos_x + 32, this->GetWidget<NWidgetBase>(BDDW_Y)->pos_y + 18, AXIS_Y, DEPOT_PART_NORTH);
+		DrawShipDepotSprite(this->GetWidget<NWidgetBase>(BDDW_Y)->pos_x + 64, this->GetWidget<NWidgetBase>(BDDW_Y)->pos_y + 34, AXIS_Y, DEPOT_PART_SOUTH);
 	}
 
 	virtual void OnClick(Point pt, int widget, int click_count)
--- a/src/newgrf_canal.cpp
+++ b/src/newgrf_canal.cpp
@@ -50,7 +50,7 @@
 		case 0x80: {
 			uint z = GetTileZ(tile) / TILE_HEIGHT;
 			/* Return consistent height within locks */
-			if (IsTileType(tile, MP_WATER) && IsLock(tile) && GetSection(tile) >= 8) z--;
+			if (IsTileType(tile, MP_WATER) && IsLock(tile) && GetLockPart(tile) == LOCK_PART_UPPER) z--;
 			return z;
 		}
 
--- a/src/table/water_land.h
+++ b/src/table/water_land.h
@@ -53,11 +53,15 @@
 	TILE_SEQ_END()
 };
 
-static const DrawTileSprites _shipdepot_display_data[] = {
-	TILE_SPRITE_LINE(0xFDD, _shipdepot_display_seq_1)
-	TILE_SPRITE_LINE(0xFDD, _shipdepot_display_seq_2)
-	TILE_SPRITE_LINE(0xFDD, _shipdepot_display_seq_3)
-	TILE_SPRITE_LINE(0xFDD, _shipdepot_display_seq_4)
+static const DrawTileSprites _shipdepot_display_data[][DEPOT_PART_END] = {
+	{ // AXIS_X
+		TILE_SPRITE_LINE(0xFDD, _shipdepot_display_seq_1) // DEPOT_PART_NORTH
+		TILE_SPRITE_LINE(0xFDD, _shipdepot_display_seq_2) // DEPOT_PART_SOUTH
+	},
+	{ // AXIS_Y
+		TILE_SPRITE_LINE(0xFDD, _shipdepot_display_seq_3) // DEPOT_PART_NORTH
+		TILE_SPRITE_LINE(0xFDD, _shipdepot_display_seq_4) // DEPOT_PART_SOUTH
+	},
 };
 
 static const DrawTileSeqStruct _lock_display_seq_0[] = {
@@ -132,21 +136,27 @@
 	TILE_SEQ_END()
 };
 
-static const DrawTileSprites _lock_display_data[] = {
-	TILE_SPRITE_LINE(1, _lock_display_seq_0)
-	TILE_SPRITE_LINE(0, _lock_display_seq_1)
-	TILE_SPRITE_LINE(2, _lock_display_seq_2)
-	TILE_SPRITE_LINE(3, _lock_display_seq_3)
+static const DrawTileSprites _lock_display_data[][DIAGDIR_END] = {
+	{ // LOCK_PART_MIDDLE
+		TILE_SPRITE_LINE(1, _lock_display_seq_0) // NE
+		TILE_SPRITE_LINE(0, _lock_display_seq_1) // SE
+		TILE_SPRITE_LINE(2, _lock_display_seq_2) // SW
+		TILE_SPRITE_LINE(3, _lock_display_seq_3) // NW
+	},
 
-	TILE_SPRITE_LINE(0xFDD, _lock_display_seq_0b)
-	TILE_SPRITE_LINE(0xFDD, _lock_display_seq_1b)
-	TILE_SPRITE_LINE(0xFDD, _lock_display_seq_2b)
-	TILE_SPRITE_LINE(0xFDD, _lock_display_seq_3b)
+	{ // LOCK_PART_LOWER
+		TILE_SPRITE_LINE(0xFDD, _lock_display_seq_0b) // NE
+		TILE_SPRITE_LINE(0xFDD, _lock_display_seq_1b) // SE
+		TILE_SPRITE_LINE(0xFDD, _lock_display_seq_2b) // SW
+		TILE_SPRITE_LINE(0xFDD, _lock_display_seq_3b) // NW
+	},
 
-	TILE_SPRITE_LINE(0xFDD, _lock_display_seq_0t)
-	TILE_SPRITE_LINE(0xFDD, _lock_display_seq_1t)
-	TILE_SPRITE_LINE(0xFDD, _lock_display_seq_2t)
-	TILE_SPRITE_LINE(0xFDD, _lock_display_seq_3t)
+	{ // LOCK_PART_UPPER
+		TILE_SPRITE_LINE(0xFDD, _lock_display_seq_0t) // NE
+		TILE_SPRITE_LINE(0xFDD, _lock_display_seq_1t) // SE
+		TILE_SPRITE_LINE(0xFDD, _lock_display_seq_2t) // SW
+		TILE_SPRITE_LINE(0xFDD, _lock_display_seq_3t) // NW
+	},
 };
 
 #undef TILE_SEQ_LINE
--- a/src/water.h
+++ b/src/water.h
@@ -15,6 +15,7 @@
 #include "tile_type.h"
 #include "company_type.h"
 #include "slope_type.h"
+#include "water_map.h"
 
 /**
  * Describes the behaviour of a tile during flooding.
@@ -34,7 +35,7 @@
 
 void ConvertGroundTilesIntoWaterTiles();
 
-void DrawShipDepotSprite(int x, int y, int image);
+void DrawShipDepotSprite(int x, int y, Axis axis, DepotPart part);
 void DrawWaterClassGround(const struct TileInfo *ti);
 void DrawShoreTile(Slope tileh);
 
--- a/src/water_cmd.cpp
+++ b/src/water_cmd.cpp
@@ -134,8 +134,8 @@
 		Depot *depot = new Depot(tile);
 		depot->build_date = _date;
 
-		MakeShipDepot(tile,  _current_company, depot->index, DEPOT_NORTH, axis, wc1);
-		MakeShipDepot(tile2, _current_company, depot->index, DEPOT_SOUTH, axis, wc2);
+		MakeShipDepot(tile,  _current_company, depot->index, DEPOT_PART_NORTH, axis, wc1);
+		MakeShipDepot(tile2, _current_company, depot->index, DEPOT_PART_SOUTH, axis, wc2);
 		MarkTileDirtyByTile(tile);
 		MarkTileDirtyByTile(tile2);
 		MakeDefaultName(depot);
@@ -426,16 +426,17 @@
 		}
 
 		case WATER_TILE_LOCK: {
-			static const TileIndexDiffC _lock_tomiddle_offs[] = {
-				{ 0,  0}, {0,  0}, { 0, 0}, {0,  0}, // middle
-				{-1,  0}, {0,  1}, { 1, 0}, {0, -1}, // lower
-				{ 1,  0}, {0, -1}, {-1, 0}, {0,  1}, // upper
+			static const TileIndexDiffC _lock_tomiddle_offs[][DIAGDIR_END] = {
+				/*   NE       SE        SW      NW       */
+				{ { 0,  0}, {0,  0}, { 0, 0}, {0,  0} }, // LOCK_PART_MIDDLE
+				{ {-1,  0}, {0,  1}, { 1, 0}, {0, -1} }, // LOCK_PART_LOWER
+				{ { 1,  0}, {0, -1}, {-1, 0}, {0,  1} }, // LOCK_PART_UPPER
 			};
 
 			if (flags & DC_AUTO) return_cmd_error(STR_ERROR_BUILDING_MUST_BE_DEMOLISHED);
 			if (_current_company == OWNER_WATER) return CMD_ERROR;
 			/* move to the middle tile.. */
-			return RemoveLock(tile + ToTileIndexDiff(_lock_tomiddle_offs[GetSection(tile)]), flags);
+			return RemoveLock(tile + ToTileIndexDiff(_lock_tomiddle_offs[GetLockPart(tile)][GetLockDirection(tile)]), flags);
 		}
 
 		case WATER_TILE_DEPOT:
@@ -641,8 +642,8 @@
 /** Draw a lock tile. */
 static void DrawWaterLock(const TileInfo *ti)
 {
-	int section = GetSection(ti->tile);
-	const DrawTileSprites &dts = _lock_display_data[section];
+	int part = GetLockPart(ti->tile);
+	const DrawTileSprites &dts = _lock_display_data[part][GetLockDirection(ti->tile)];
 
 	/* Draw ground sprite. */
 	SpriteID image = dts.ground.sprite;
@@ -670,7 +671,7 @@
 	if (base == 0) {
 		/* If no custom graphics, use defaults. */
 		base = SPR_LOCK_BASE;
-		uint8 z_threshold = section >= 8 ? 8 : 0;
+		uint8 z_threshold = part == LOCK_PART_UPPER ? 8 : 0;
 		zoffs = ti->z > z_threshold ? 24 : 0;
 	}
 
@@ -681,7 +682,7 @@
 static void DrawWaterDepot(const TileInfo *ti)
 {
 	DrawWaterClassGround(ti);
-	DrawWaterTileStruct(ti, _shipdepot_display_data[GetSection(ti->tile)].seq, 0, 0, COMPANY_SPRITE_COLOUR(GetTileOwner(ti->tile)), CF_END);
+	DrawWaterTileStruct(ti, _shipdepot_display_data[GetShipDepotAxis(ti->tile)][GetShipDepotPart(ti->tile)].seq, 0, 0, COMPANY_SPRITE_COLOUR(GetTileOwner(ti->tile)), CF_END);
 }
 
 static void DrawRiverWater(const TileInfo *ti)
@@ -773,9 +774,9 @@
 	}
 }
 
-void DrawShipDepotSprite(int x, int y, int image)
+void DrawShipDepotSprite(int x, int y, Axis axis, DepotPart part)
 {
-	const DrawTileSprites &dts = _shipdepot_display_data[image];
+	const DrawTileSprites &dts = _shipdepot_display_data[axis][part];
 
 	DrawSprite(dts.ground.sprite, dts.ground.pal, x, y);
 	DrawOrigTileSeqInGUI(x, y, &dts, COMPANY_SPRITE_COLOUR(_local_company));
--- a/src/water_map.h
+++ b/src/water_map.h
@@ -15,6 +15,28 @@
 #include "depot_type.h"
 #include "tile_map.h"
 
+/**
+ * Bit field layout of m5 for water tiles.
+ */
+enum WaterTileTypeBitLayout {
+	WBL_TYPE_BEGIN        = 4,   ///< Start of the 'type' bitfield.
+	WBL_TYPE_COUNT        = 4,   ///< Length of the 'type' bitfield.
+
+	WBL_TYPE_NORMAL       = 0x0, ///< Clear water or coast ('type' bitfield).
+	WBL_TYPE_LOCK         = 0x1, ///< Lock ('type' bitfield).
+	WBL_TYPE_DEPOT        = 0x8, ///< Depot ('type' bitfield).
+
+	WBL_COAST_FLAG        = 0,   ///< Flag for coast.
+
+	WBL_LOCK_ORIENT_BEGIN = 0,   ///< Start of lock orientiation bitfield.
+	WBL_LOCK_ORIENT_COUNT = 2,   ///< Length of lock orientiation bitfield.
+	WBL_LOCK_PART_BEGIN   = 2,   ///< Start of lock part bitfield.
+	WBL_LOCK_PART_COUNT   = 2,   ///< Length of lock part bitfield.
+
+	WBL_DEPOT_PART        = 0,   ///< Depot part flag.
+	WBL_DEPOT_AXIS        = 1,   ///< Depot axis flag.
+};
+
 /** Available water tile types. */
 enum WaterTileType {
 	WATER_TILE_CLEAR, ///< Plain water.
@@ -35,17 +57,16 @@
 
 /** Sections of the water depot. */
 enum DepotPart {
-	DEPOT_NORTH = 0x80,
-	DEPOT_SOUTH = 0x81,
-	DEPOT_END   = 0x84,
+	DEPOT_PART_NORTH = 0, ///< Northern part of a depot.
+	DEPOT_PART_SOUTH = 1, ///< Southern part of a depot.
+	DEPOT_PART_END
 };
 
 /** Sections of the water lock. */
 enum LockPart {
-	LOCK_MIDDLE = 0x10,
-	LOCK_LOWER  = 0x14,
-	LOCK_UPPER  = 0x18,
-	LOCK_END    = 0x1C
+	LOCK_PART_MIDDLE = 0, ///< Middle part of a lock.
+	LOCK_PART_LOWER  = 1, ///< Lower part of a lock.
+	LOCK_PART_UPPER  = 2, ///< Upper part of a lock.
 };
 
 /**
@@ -57,12 +78,12 @@
 {
 	assert(IsTileType(t, MP_WATER));
 
-	if (_m[t].m5 == 0) return WATER_TILE_CLEAR;
-	if (_m[t].m5 == 1) return WATER_TILE_COAST;
-	if (IsInsideMM(_m[t].m5, LOCK_MIDDLE, LOCK_END)) return WATER_TILE_LOCK;
-
-	assert(IsInsideMM(_m[t].m5, DEPOT_NORTH, DEPOT_END));
-	return WATER_TILE_DEPOT;
+	switch (GB(_m[t].m5, WBL_TYPE_BEGIN, WBL_TYPE_COUNT)) {
+		case WBL_TYPE_NORMAL: return HasBit(_m[t].m5, WBL_COAST_FLAG) ? WATER_TILE_COAST : WATER_TILE_CLEAR;
+		case WBL_TYPE_LOCK:   return WATER_TILE_LOCK;
+		case WBL_TYPE_DEPOT:  return WATER_TILE_DEPOT;
+		default: NOT_REACHED();
+	}
 }
 
 /**
@@ -182,23 +203,13 @@
 }
 
 /**
- * Get the other tile of the ship depot.
- * @param t Tile to query, containing one section of a ship depot.
- * @return Tile containing the other section of the depot.
- */
-static inline TileIndex GetOtherShipDepotTile(TileIndex t)
-{
-	return t + (HasBit(_m[t].m5, 0) ? -1 : 1) * (HasBit(_m[t].m5, 1) ? TileDiffXY(0, 1) : TileDiffXY(1, 0));
-}
-
-/**
  * Is it a water tile with a ship depot on it?
  * @param t Water tile to query.
  * @return \c true if it is a ship depot tile.
  */
 static inline bool IsShipDepot(TileIndex t)
 {
-	return IsInsideMM(_m[t].m5, DEPOT_NORTH, DEPOT_END);
+	return GetWaterTileType(t) == WATER_TILE_DEPOT;
 }
 
 /**
@@ -218,7 +229,19 @@
  */
 static inline Axis GetShipDepotAxis(TileIndex t)
 {
-	return (Axis)GB(_m[t].m5, 1, 1);
+	return (Axis)GB(_m[t].m5, WBL_DEPOT_AXIS, 1);
+}
+
+/**
+ * Get the part of a ship depot.
+ * @param t Water tile to query.
+ * @return Part of the depot.
+ * @pre IsShipDepotTile(t)
+ */
+static inline DepotPart GetShipDepotPart(TileIndex t)
+{
+	assert(IsShipDepotTile(t));
+	return (DepotPart)GB(_m[t].m5, WBL_DEPOT_PART, 1);
 }
 
 /**
@@ -228,7 +251,17 @@
  */
 static inline DiagDirection GetShipDepotDirection(TileIndex t)
 {
-	return XYNSToDiagDir(GetShipDepotAxis(t), GB(_m[t].m5, 0, 1));
+	return XYNSToDiagDir(GetShipDepotAxis(t), GetShipDepotPart(t));
+}
+
+/**
+ * Get the other tile of the ship depot.
+ * @param t Tile to query, containing one section of a ship depot.
+ * @return Tile containing the other section of the depot.
+ */
+static inline TileIndex GetOtherShipDepotTile(TileIndex t)
+{
+	return t + (GetShipDepotPart(t) != DEPOT_PART_NORTH ? -1 : 1) * (GetShipDepotAxis(t) != AXIS_X ? TileDiffXY(0, 1) : TileDiffXY(1, 0));
 }
 
 /**
@@ -251,7 +284,7 @@
  */
 static inline bool IsLock(TileIndex t)
 {
-	return IsInsideMM(_m[t].m5, LOCK_MIDDLE, LOCK_END);
+	return GetWaterTileType(t) == WATER_TILE_LOCK;
 }
 
 /**
@@ -261,18 +294,18 @@
  */
 static inline DiagDirection GetLockDirection(TileIndex t)
 {
-	return (DiagDirection)GB(_m[t].m5, 0, 2);
+	return (DiagDirection)GB(_m[t].m5, WBL_LOCK_ORIENT_BEGIN, WBL_LOCK_ORIENT_COUNT);
 }
 
 /**
- * Get a section of a depot or a lock.
+ * Get the part of a lock.
  * @param t Water tile to query.
- * @return The section.
+ * @return The part.
  */
-static inline byte GetSection(TileIndex t)
+static inline byte GetLockPart(TileIndex t)
 {
-	assert(GetWaterTileType(t) == WATER_TILE_LOCK || GetWaterTileType(t) == WATER_TILE_DEPOT);
-	return GB(_m[t].m5, 0, 4);
+	assert(GetWaterTileType(t) == WATER_TILE_LOCK);
+	return GB(_m[t].m5, WBL_LOCK_PART_BEGIN, WBL_LOCK_PART_COUNT);
 }
 
 /**
@@ -309,7 +342,7 @@
 	_m[t].m2 = 0;
 	_m[t].m3 = 0;
 	_m[t].m4 = 0;
-	_m[t].m5 = 1;
+	_m[t].m5 = WBL_TYPE_NORMAL << WBL_TYPE_BEGIN | 1 << WBL_COAST_FLAG;
 	SB(_m[t].m6, 2, 4, 0);
 	_me[t].m7 = 0;
 }
@@ -329,7 +362,7 @@
 	_m[t].m2 = 0;
 	_m[t].m3 = 0;
 	_m[t].m4 = random_bits;
-	_m[t].m5 = 0;
+	_m[t].m5 = WBL_TYPE_NORMAL << WBL_TYPE_BEGIN;
 	SB(_m[t].m6, 2, 4, 0);
 	_me[t].m7 = 0;
 }
@@ -370,11 +403,11 @@
  * @param t    Tile to place the ship depot section.
  * @param o    Owner of the depot.
  * @param did  Depot ID.
- * @param base Depot base (either #DEPOT_NORTH or #DEPOT_SOUTH).
+ * @param part Depot part (either #DEPOT_PART_NORTH or #DEPOT_PART_SOUTH).
  * @param a    Axis of the depot.
  * @param original_water_class Original water class.
  */
-static inline void MakeShipDepot(TileIndex t, Owner o, DepotID did, DepotPart base, Axis a, WaterClass original_water_class)
+static inline void MakeShipDepot(TileIndex t, Owner o, DepotID did, DepotPart part, Axis a, WaterClass original_water_class)
 {
 	SetTileType(t, MP_WATER);
 	SetTileOwner(t, o);
@@ -382,7 +415,7 @@
 	_m[t].m2 = did;
 	_m[t].m3 = 0;
 	_m[t].m4 = 0;
-	_m[t].m5 = base + a * 2;
+	_m[t].m5 = WBL_TYPE_DEPOT << WBL_TYPE_BEGIN | part << WBL_DEPOT_PART | a << WBL_DEPOT_AXIS;
 	SB(_m[t].m6, 2, 4, 0);
 	_me[t].m7 = 0;
 }
@@ -391,11 +424,12 @@
  * Make a lock section.
  * @param t Tile to place the water lock section.
  * @param o Owner of the lock.
- * @param section Section to place.
+ * @param part Part to place.
+ * @param dir Lock orientation
  * @param original_water_class Original water class.
  * @see MakeLock
  */
-static inline void MakeLockTile(TileIndex t, Owner o, byte section, WaterClass original_water_class)
+static inline void MakeLockTile(TileIndex t, Owner o, LockPart part, DiagDirection dir, WaterClass original_water_class)
 {
 	SetTileType(t, MP_WATER);
 	SetTileOwner(t, o);
@@ -403,7 +437,7 @@
 	_m[t].m2 = 0;
 	_m[t].m3 = 0;
 	_m[t].m4 = 0;
-	_m[t].m5 = section;
+	_m[t].m5 = WBL_TYPE_LOCK << WBL_TYPE_BEGIN | part << WBL_LOCK_PART_BEGIN | dir << WBL_LOCK_ORIENT_BEGIN;
 	SB(_m[t].m6, 2, 4, 0);
 	_me[t].m7 = 0;
 }
@@ -420,11 +454,11 @@
 {
 	TileIndexDiff delta = TileOffsByDiagDir(d);
 
-	MakeLockTile(t, o, LOCK_MIDDLE + d, WATER_CLASS_CANAL);
+	MakeLockTile(t, o, LOCK_PART_MIDDLE, d, WATER_CLASS_CANAL);
 	/* Keep the current owner for the upper and lower part if it is a
 	 * water tile so we can restore the owner after deleting the lock. */
-	MakeLockTile(t - delta, IsWaterTile(t - delta) ? GetTileOwner(t - delta) : o, LOCK_LOWER + d, wc_lower);
-	MakeLockTile(t + delta, IsWaterTile(t + delta) ? GetTileOwner(t + delta) : o, LOCK_UPPER + d, wc_upper);
+	MakeLockTile(t - delta, IsWaterTile(t - delta) ? GetTileOwner(t - delta) : o, LOCK_PART_LOWER, d, wc_lower);
+	MakeLockTile(t + delta, IsWaterTile(t + delta) ? GetTileOwner(t + delta) : o, LOCK_PART_UPPER, d, wc_upper);
 }
 
 #endif /* WATER_MAP_H */