changeset 6134:7f92815712e4 draft

(svn r8876) -Fix Replace tests with magic numbers by a simple extraction template for command parameters
author tron <tron@openttd.org>
date Sat, 24 Feb 2007 09:42:39 +0000
parents 49a563250135
children b7dd9b8d1c54
files src/cmd_helper.h src/depot.h src/rail_cmd.cpp src/road_cmd.cpp src/station_cmd.cpp src/water_cmd.cpp
diffstat 6 files changed, 58 insertions(+), 28 deletions(-) [+]
line wrap: on
line diff
new file mode 100644
--- /dev/null
+++ b/src/cmd_helper.h
@@ -0,0 +1,28 @@
+/* $Id$ */
+
+#ifndef CMD_HELPER_H
+#define CMD_HELPER_H
+
+#include "direction.h"
+#include "macros.h"
+#include "road.h"
+
+
+template<uint N> static inline void ExtractValid();
+template<> static inline void ExtractValid<1>() {}
+
+
+template<typename T> struct ExtractBits;
+template<> struct ExtractBits<Axis>          { static const uint Count =  1; };
+template<> struct ExtractBits<DiagDirection> { static const uint Count =  2; };
+template<> struct ExtractBits<RoadBits>      { static const uint Count =  4; };
+
+
+template<typename T, uint N, typename U> static inline T Extract(U v)
+{
+	// Check if there are enough bits in v
+	ExtractValid<N + ExtractBits<T>::Count <= sizeof(U) * 8>();
+	return (T)GB(v, N, ExtractBits<T>::Count);
+}
+
+#endif
--- a/src/depot.h
+++ b/src/depot.h
@@ -85,7 +85,7 @@
 
 /**
  * Find out if the slope of the tile is suitable to build a depot of given direction
- * @param direction The direction in which the depot's exit points. Starts with 0 as NE and goes Clockwise
+ * @param direction The direction in which the depot's exit points
  * @param tileh The slope of the tile in question
  * @return true if the construction is possible
 
@@ -98,7 +98,7 @@
  * 03 (exit towards NW) we need either bit 0 or 4 set in tileh: 0x4C >> 3 = 1001<p>
  * So ((0x4C >> direction) & tileh) determines whether the depot can be built on the current tileh
  */
-static inline bool CanBuildDepotByTileh(uint32 direction, Slope tileh)
+static inline bool CanBuildDepotByTileh(DiagDirection direction, Slope tileh)
 {
 	return ((0x4C >> direction) & tileh) != 0;
 }
--- a/src/rail_cmd.cpp
+++ b/src/rail_cmd.cpp
@@ -3,6 +3,7 @@
 #include "stdafx.h"
 #include "openttd.h"
 #include "bridge_map.h"
+#include "cmd_helper.h"
 #include "debug.h"
 #include "functions.h"
 #include "rail_map.h"
@@ -540,7 +541,7 @@
 /** Build a train depot
  * @param tile position of the train depot
  * @param p1 rail type
- * @param p2 entrance direction (DiagDirection)
+ * @param p2 bit 0..1 entrance direction (DiagDirection)
  *
  * @todo When checking for the tile slope,
  * distingush between "Flat land required" and "land sloped in wrong direction"
@@ -554,10 +555,12 @@
 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 
 	/* check railtype and valid direction for depot (0 through 3), 4 in total */
-	if (!ValParamRailtype(p1) || p2 > 3) return CMD_ERROR;
+	if (!ValParamRailtype(p1)) return CMD_ERROR;
 
 	tileh = GetTileSlope(tile, NULL);
 
+	DiagDirection dir = Extract<DiagDirection, 0>(p2);
+
 	/* Prohibit construction if
 	 * The tile is non-flat AND
 	 * 1) The AI is "old-school"
@@ -570,7 +573,7 @@
 				_is_old_ai_player ||
 				!_patches.build_on_slopes ||
 				IsSteepSlope(tileh) ||
-				!CanBuildDepotByTileh(p2, tileh)
+				!CanBuildDepotByTileh(dir, tileh)
 			)) {
 		return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 	}
@@ -585,7 +588,6 @@
 	if (d == NULL) return CMD_ERROR;
 
 	if (flags & DC_EXEC) {
-		DiagDirection dir = (DiagDirection)p2;
 		MakeRailDepot(tile, _current_player, dir, (RailType)p1);
 		MarkTileDirtyByTile(tile);
 
--- a/src/road_cmd.cpp
+++ b/src/road_cmd.cpp
@@ -3,6 +3,7 @@
 #include "stdafx.h"
 #include "openttd.h"
 #include "bridge_map.h"
+#include "cmd_helper.h"
 #include "rail_map.h"
 #include "road_map.h"
 #include "sprite.h"
@@ -85,7 +86,7 @@
 
 /** Delete a piece of road.
  * @param tile tile where to remove road from
- * @param p1 road piece flags
+ * @param p1 bit 0..3 road pieces to remove (RoadBits)
  * @param p2 unused
  */
 int32 CmdRemoveRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
@@ -98,14 +99,9 @@
 	/* true if the roadpiece was always removeable,
 	 * false if it was a center piece. Affects town ratings drop */
 	bool edge_road;
-	RoadBits pieces;
 
 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 
-	/* Road pieces are max 4 bitset values (NE, NW, SE, SW) */
-	if (p1 >> 4) return CMD_ERROR;
-	pieces = (RoadBits)p1;
-
 	if (!IsTileType(tile, MP_STREET)) return CMD_ERROR;
 
 	owner = IsLevelCrossingTile(tile) ? GetCrossingRoadOwner(tile) : GetTileOwner(tile);
@@ -116,6 +112,8 @@
 		t = NULL;
 	}
 
+	RoadBits pieces = Extract<RoadBits, 0>(p1);
+
 	if (!CheckAllowRemoveRoad(tile, pieces, &edge_road)) return CMD_ERROR;
 
 	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
@@ -249,7 +247,7 @@
 
 /** Build a piece of road.
  * @param tile tile where to build road
- * @param p1 road piece flags
+ * @param p1 bit 0..3 road pieces to build (RoadBits)
  * @param p2 the town that is building the road (0 if not applicable)
  */
 int32 CmdBuildRoad(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
@@ -257,15 +255,15 @@
 	int32 cost = 0;
 	int32 ret;
 	RoadBits existing = ROAD_NONE;
-	RoadBits pieces;
 	Slope tileh;
 
 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 
 	/* Road pieces are max 4 bitset values (NE, NW, SE, SW) and town can only be non-zero
 	 * if a non-player is building the road */
-	if ((p1 >> 4) || (IsValidPlayer(_current_player) && p2 != 0) || (_current_player == OWNER_TOWN && !IsValidTownID(p2))) return CMD_ERROR;
-	pieces = (RoadBits)p1;
+	if ((IsValidPlayer(_current_player) && p2 != 0) || (_current_player == OWNER_TOWN && !IsValidTownID(p2))) return CMD_ERROR;
+
+	RoadBits pieces = Extract<RoadBits, 0>(p1);
 
 	tileh = GetTileSlope(tile, NULL);
 
@@ -502,7 +500,7 @@
 
 /** Build a road depot.
  * @param tile tile where to build the depot
- * @param p1 entrance direction (DiagDirection)
+ * @param p1 bit 0..1 entrance direction (DiagDirection)
  * @param p2 unused
  *
  * @todo When checking for the tile slope,
@@ -516,13 +514,13 @@
 
 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 
-	if (p1 > 3) return CMD_ERROR; // check direction
+	DiagDirection dir = Extract<DiagDirection, 0>(p1);
 
 	tileh = GetTileSlope(tile, NULL);
 	if (tileh != SLOPE_FLAT && (
 				!_patches.build_on_slopes ||
 				IsSteepSlope(tileh) ||
-				!CanBuildDepotByTileh(p1, tileh)
+				!CanBuildDepotByTileh(dir, tileh)
 			)) {
 		return_cmd_error(STR_0007_FLAT_LAND_REQUIRED);
 	}
@@ -539,7 +537,7 @@
 		dep->xy = tile;
 		dep->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
 
-		MakeRoadDepot(tile, _current_player, (DiagDirection)p1);
+		MakeRoadDepot(tile, _current_player, dir);
 		MarkTileDirtyByTile(tile);
 	}
 	return cost + _price.build_road_depot;
--- a/src/station_cmd.cpp
+++ b/src/station_cmd.cpp
@@ -6,6 +6,7 @@
 #include "openttd.h"
 #include "aircraft.h"
 #include "bridge_map.h"
+#include "cmd_helper.h"
 #include "debug.h"
 #include "functions.h"
 #include "station_map.h"
@@ -787,7 +788,7 @@
 /** Build railroad station
  * @param tile_org starting position of station dragging/placement
  * @param p1 various bitstuffed elements
- * - p1 = (bit  0)    - orientation (p1 & 1)
+ * - p1 = (bit  0)    - orientation (Axis)
  * - p1 = (bit  8-15) - number of tracks
  * - p1 = (bit 16-23) - platform length
  * @param p2 various bitstuffed elements
@@ -807,7 +808,7 @@
 	if (!ValParamRailtype(p2 & 0xF)) return CMD_ERROR;
 
 	/* unpack parameters */
-	Axis axis = (Axis)GB(p1, 0, 1);
+	Axis axis = Extract<Axis, 0>(p1);
 	uint numtracks = GB(p1,  8, 8);
 	uint plat_len  = GB(p1, 16, 8);
 	if (axis == AXIS_X) {
--- a/src/water_cmd.cpp
+++ b/src/water_cmd.cpp
@@ -3,6 +3,7 @@
 #include "stdafx.h"
 #include "openttd.h"
 #include "bridge_map.h"
+#include "cmd_helper.h"
 #include "station_map.h"
 #include "table/sprites.h"
 #include "table/strings.h"
@@ -45,7 +46,7 @@
 
 /** Build a ship depot.
  * @param tile tile where ship depot is built
- * @param p1 depot direction (0 == X or 1 == Y)
+ * @param p1 bit 0 depot orientation (Axis)
  * @param p2 unused
  */
 int32 CmdBuildShipDepot(TileIndex tile, uint32 flags, uint32 p1, uint32 p2)
@@ -57,11 +58,11 @@
 
 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 
-	if (p1 > 1) return CMD_ERROR;
-
 	if (!EnsureNoVehicle(tile)) return CMD_ERROR;
 
-	tile2 = tile + (p1 ? TileDiffXY(0, 1) : TileDiffXY(1, 0));
+	Axis axis = Extract<Axis, 0>(p1);
+
+	tile2 = tile + (axis == AXIS_X ? TileDiffXY(1, 0) : TileDiffXY(0, 1));
 	if (!EnsureNoVehicle(tile2)) return CMD_ERROR;
 
 	if (!IsClearWaterTile(tile) || !IsClearWaterTile(tile2))
@@ -84,8 +85,8 @@
 		depot->xy = tile;
 		depot->town_index = ClosestTownFromTile(tile, (uint)-1)->index;
 
-		MakeShipDepot(tile, _current_player, DEPOT_NORTH, (Axis)p1);
-		MakeShipDepot(tile2, _current_player, DEPOT_SOUTH, (Axis)p1);
+		MakeShipDepot(tile,  _current_player, DEPOT_NORTH, axis);
+		MakeShipDepot(tile2, _current_player, DEPOT_SOUTH, axis);
 		MarkTileDirtyByTile(tile);
 		MarkTileDirtyByTile(tile2);
 	}