(svn r3019) -Codechange: Replace explicit shifting/anding/oring with GB and SB
authortron
Wed, 05 Oct 2005 07:20:26 +0000
changeset 2493 d834d0c1502a
parent 2492 3f32f9f9fd78
child 2494 c241575eb54e
(svn r3019) -Codechange: Replace explicit shifting/anding/oring with GB and SB
depot.h
industry_cmd.c
macros.h
npf.c
pathfind.c
pathfind.h
pbs.c
rail_cmd.c
road_cmd.c
roadveh_cmd.c
station_cmd.c
tile.h
town_cmd.c
train_cmd.c
train_gui.c
tunnelbridge_cmd.c
water_cmd.c
--- a/depot.h	Wed Oct 05 04:00:39 2005 +0000
+++ b/depot.h	Wed Oct 05 07:20:26 2005 +0000
@@ -104,10 +104,10 @@
 		case TRANSPORT_RAIL:
 		case TRANSPORT_ROAD:
 			/* Rail and road store a diagonal direction in bits 0 and 1 */
-			return (DiagDirection)(_m[tile].m5 & 3);
+			return (DiagDirection)GB(_m[tile].m5, 0, 2);
 		case TRANSPORT_WATER:
 			/* Water is stubborn, it stores the directions in a different order. */
-			switch (_m[tile].m5 & 3) {
+			switch (GB(_m[tile].m5, 0, 2)) {
 				case 0: return DIAGDIR_NE;
 				case 1: return DIAGDIR_SW;
 				case 2: return DIAGDIR_NW;
--- a/industry_cmd.c	Wed Oct 05 04:00:39 2005 +0000
+++ b/industry_cmd.c	Wed Oct 05 07:20:26 2005 +0000
@@ -351,7 +351,7 @@
 	ormod = (ind->color_map+0x307) << PALETTE_SPRITE_START;
 
 	/* Retrieve pointer to the draw industry tile struct */
-	dits = &_industry_draw_tile_data[(ti->map5 << 2) | (_m[ti->tile].m1 & 3)];
+	dits = &_industry_draw_tile_data[(ti->map5 << 2) | GB(_m[ti->tile].m1, 0, 2)];
 
 	image = dits->sprite_1;
 	if (image & PALETTE_MODIFIER_COLOR && (image & PALETTE_SPRITE_MASK) == 0)
--- a/macros.h	Wed Oct 05 04:00:39 2005 +0000
+++ b/macros.h	Wed Oct 05 07:20:26 2005 +0000
@@ -145,11 +145,11 @@
 #endif
 
 /// Fetch n bits starting at bit s from x
-#define GB(x, s, n) (((x) >> (s)) & ((1 << (n)) - 1))
+#define GB(x, s, n) (((x) >> (s)) & ((1U << (n)) - 1))
 /// Set n bits starting at bit s in x to d
-#define SB(x, s, n, d) ((x) = ((x) & ~(((1 << (n)) - 1) << (s))) | ((d) << (s)))
+#define SB(x, s, n, d) ((x) = ((x) & ~(((1U << (n)) - 1) << (s))) | ((d) << (s)))
 /// Add i to the n bits starting at bit s in x
-#define AB(x, s, n, i) ((x) = ((x) & ~(((1 << (n)) - 1) << (s))) | (((x) + ((i) << (s))) & (((1 << (n)) - 1) << (s))))
+#define AB(x, s, n, i) ((x) = ((x) & ~(((1U << (n)) - 1) << (s))) | (((x) + ((i) << (s))) & (((1U << (n)) - 1) << (s))))
 
 /**
  * ROtate x Left/Right by n (must be >= 0)
--- a/npf.c	Wed Oct 05 04:00:39 2005 +0000
+++ b/npf.c	Wed Oct 05 07:20:26 2005 +0000
@@ -60,8 +60,10 @@
 	uint32 ts;
 
 	/* Can always go into a tunnel */
-	if (IsTileType(tile, MP_TUNNELBRIDGE) && (_m[tile].m5 & 0xF0)==0 && (_m[tile].m5 & 3) == exitdir)
+	if (IsTileType(tile, MP_TUNNELBRIDGE) && GB(_m[tile].m5, 4, 4) == 0 &&
+			GB(_m[tile].m5, 0, 2) == exitdir) {
 		return false;
+	}
 
 	/* Cannot go through the back of a depot */
 	if (IsTileDepotType(tile, TRANSPORT_RAIL) && (exitdir != GetDepotDirection(tile, TRANSPORT_RAIL)))
@@ -88,8 +90,11 @@
 			return true;
 
 		/* Prevent us from falling off a slope into a tunnel exit */
-		if (IsTileType(dst_tile, MP_TUNNELBRIDGE) && (_m[dst_tile].m5 & 0xF0)==0 && (DiagDirection)(_m[dst_tile].m5 & 3) == ReverseDiagdir(exitdir))
-				return true;
+		if (IsTileType(dst_tile, MP_TUNNELBRIDGE) &&
+				GB(_m[dst_tile].m5, 4, 4) == 0 &&
+				(DiagDirection)GB(_m[dst_tile].m5, 0, 2) == ReverseDiagdir(exitdir)) {
+			return true;
+		}
 
 		/* Check for oneway signal against us */
 		if (IsTileType(dst_tile, MP_RAILWAY) && GetRailTileType(dst_tile) == RAIL_TYPE_SIGNALS) {
@@ -312,7 +317,7 @@
 {
 	DiagDirection exitdir = TrackdirToExitdir((Trackdir)current->direction);
 	TileIndex tile = current->tile;
-	if ( (DiagDirection)(_m[tile].m5 & 3) == ReverseDiagdir(exitdir)) {
+	if ((DiagDirection)GB(_m[tile].m5, 0, 2) == ReverseDiagdir(exitdir)) {
 		/* We just popped out if this tunnel, since were
 		 * facing the tunnel exit */
 		FindLengthOfTunnelResult flotr;
@@ -364,13 +369,13 @@
 				/* DEBUG: mark visited tiles by mowing the grass under them
 				 * ;-) */
 				if (!IsTileDepotType(tile, TRANSPORT_RAIL)) {
-					_m[tile].m2 &= ~15; /* Clear bits 0-3 */
+					SB(_m[tile].m2, 0, 4, 0);
 					MarkTileDirtyByTile(tile);
 				}
 				break;
 			case MP_STREET:
 				if (!IsTileDepotType(tile, TRANSPORT_ROAD)) {
-					_m[tile].m4 &= ~0x70; /* Clear bits 4-6 */
+					SB(_m[tile].m2, 4, 3, 0);
 					MarkTileDirtyByTile(tile);
 				}
 				break;
@@ -408,7 +413,7 @@
 	/* Determine base length */
 	switch (GetTileType(tile)) {
 		case MP_TUNNELBRIDGE:
-			if ((_m[tile].m5 & 0xF0)==0) {
+			if (GB(_m[tile].m5, 4, 4) == 0) {
 				cost = NPFTunnelCost(current);
 				break;
 			}
@@ -452,7 +457,7 @@
 	/* Determine base length */
 	switch (GetTileType(tile)) {
 		case MP_TUNNELBRIDGE:
-			if ((_m[tile].m5 & 0xF0)==0) {
+			if (GB(_m[tile].m5, 4, 4) == 0) {
 				cost = NPFTunnelCost(current);
 				break;
 			}
@@ -659,10 +664,10 @@
  * intensive owner check, instead we will just assume that if the vehicle
  * managed to get on the bridge, it is probably allowed to :-)
  */
-			if ((_m[tile].m5 & 0xC6) == 0xC0 && (unsigned)(_m[tile].m5 & 0x1) == (enterdir & 0x1)) {
+			if ((_m[tile].m5 & 0xC6) == 0xC0 && GB(_m[tile].m5, 0, 1) == (enterdir & 0x1)) {
 				/* on the middle part of a railway bridge: find bridge ending */
 				while (IsTileType(tile, MP_TUNNELBRIDGE) && !((_m[tile].m5 & 0xC6) == 0x80)) {
-					tile += TileOffsByDir(_m[tile].m5 & 0x1);
+					tile += TileOffsByDir(GB(_m[tile].m5, 0, 1));
 				}
 			}
 			/* if we were on a railway middle part, we are now at a railway bridge ending */
@@ -670,7 +675,7 @@
 			if (
 				(_m[tile].m5 & 0xFC) == 0 /* railway tunnel */
 				|| (_m[tile].m5 & 0xC6) == 0x80 /* railway bridge ending */
-				|| ((_m[tile].m5 & 0xF8) == 0xE0 && ((unsigned)_m[tile].m5 & 0x1) != (enterdir & 0x1)) /* railway under bridge */
+				|| ((_m[tile].m5 & 0xF8) == 0xE0 && GB(_m[tile].m5, 0, 1) != (enterdir & 0x1)) /* railway under bridge */
 				)
 				return IsTileOwner(tile, owner);
 			break;
@@ -704,7 +709,8 @@
 	aystar->EndNodeCheck(aystar, current);
 
 	/* Find dest tile */
-	if (IsTileType(src_tile, MP_TUNNELBRIDGE) && (_m[src_tile].m5 & 0xF0)==0 && (DiagDirection)(_m[src_tile].m5 & 3) == src_exitdir) {
+	if (IsTileType(src_tile, MP_TUNNELBRIDGE) && GB(_m[src_tile].m5, 4, 4) == 0 &&
+			(DiagDirection)GB(_m[src_tile].m5, 0, 2) == src_exitdir) {
 		/* This is a tunnel. We know this tunnel is our type,
 		 * otherwise we wouldn't have got here. It is also facing us,
 		 * so we should skip it's body */
@@ -749,8 +755,10 @@
 	/* I can't enter a tunnel entry/exit tile from a tile above the tunnel. Note
 	 * that I can enter the tunnel from a tile below the tunnel entrance. This
 	 * solves the problem of vehicles wanting to drive off a tunnel entrance */
-	if (IsTileType(dst_tile, MP_TUNNELBRIDGE) && (_m[dst_tile].m5 & 0xF0) == 0 && GetTileZ(dst_tile) < GetTileZ(src_tile))
+	if (IsTileType(dst_tile, MP_TUNNELBRIDGE) && GB(_m[dst_tile].m5, 4, 4) == 0 &&
+			GetTileZ(dst_tile) < GetTileZ(src_tile)) {
 		return;
+	}
 
 	/* check correct rail type (mono, maglev, etc) */
 	if (type == TRANSPORT_RAIL) {
--- a/pathfind.c	Wed Oct 05 04:00:39 2005 +0000
+++ b/pathfind.c	Wed Oct 05 07:20:26 2005 +0000
@@ -209,7 +209,7 @@
 /* Returns the end tile and the length of a tunnel. The length does not
  * include the starting tile (entry), it does include the end tile (exit).
  */
-FindLengthOfTunnelResult FindLengthOfTunnel(TileIndex tile, int direction)
+FindLengthOfTunnelResult FindLengthOfTunnel(TileIndex tile, uint direction)
 {
 	FindLengthOfTunnelResult flotr;
 	int x,y;
@@ -231,11 +231,12 @@
 		tile = TileVirtXY(x, y);
 
 		if (IsTileType(tile, MP_TUNNELBRIDGE) &&
-				(_m[tile].m5 & 0xF0) == 0 &&					// tunnel entrance/exit
-				//((_m[tile].m5>>2)&3) == type &&		// rail/road-tunnel <-- This is not necesary to check, right?
-				((_m[tile].m5 & 3)^2) == direction &&	// entrance towards: 0 = NE, 1 = SE, 2 = SW, 3 = NW
-				GetSlopeZ(x+8, y+8) == z)
-					break;
+				GB(_m[tile].m5, 4, 4) == 0 &&               // tunnel entrance/exit
+				// GB(_m[tile].m5, 2, 2) == type &&            // rail/road-tunnel <-- This is not necesary to check, right?
+				(GB(_m[tile].m5, 0, 2) ^ 2) == direction && // entrance towards: 0 = NE, 1 = SE, 2 = SW, 3 = NW
+				GetSlopeZ(x + 8, y + 8) == z) {
+			break;
+		}
 	}
 
 	flotr.tile = tile;
@@ -274,16 +275,18 @@
 48,56,56,58,56,60,60,62,
 };
 
-static void TPFMode1(TrackPathFinder *tpf, TileIndex tile, int direction)
+static void TPFMode1(TrackPathFinder *tpf, TileIndex tile, uint direction)
 {
 	uint bits;
 	int i;
 	RememberData rd;
 	TileIndex tile_org = tile;
 
-	if (IsTileType(tile, MP_TUNNELBRIDGE) && (_m[tile].m5 & 0xF0) == 0) {
-		if ((_m[tile].m5 & 3) != direction || ((_m[tile].m5>>2)&3) != tpf->tracktype)
+	if (IsTileType(tile, MP_TUNNELBRIDGE) && GB(_m[tile].m5, 4, 4) == 0) {
+		if (GB(_m[tile].m5, 0, 2) != direction ||
+				GB(_m[tile].m5, 2, 2) != tpf->tracktype) {
 			return;
+		}
 		tile = SkipToEndOfTunnel(tpf, tile, direction);
 	}
 	tile += TileOffsByDir(direction);
@@ -704,11 +707,11 @@
 		// If the tile is the entry tile of a tunnel, and we're not going out of the tunnel,
 		//   need to find the exit of the tunnel.
 		if (IsTileType(tile, MP_TUNNELBRIDGE)) {
-			if ((_m[tile].m5 & 0xF0) == 0 &&
-				(uint)(_m[tile].m5 & 3) != (direction ^ 2)) {
+			if (GB(_m[tile].m5, 4, 4) == 0 &&
+					GB(_m[tile].m5, 0, 2) != (direction ^ 2)) {
 				/* This is a tunnel tile */
 				/* We are not just driving out of the tunnel */
-				if ( (uint)(_m[tile].m5 & 3) != direction || GB(_m[tile].m5, 2, 2) != tpf->tracktype)
+				if (GB(_m[tile].m5, 0, 2) != direction || GB(_m[tile].m5, 2, 2) != tpf->tracktype)
 					/* We are not driving into the tunnel, or it
 					 * is an invalid tunnel */
 					continue;
@@ -761,7 +764,7 @@
 
 			// The tile has no reachable tracks, or
 			// does the tile contain more than one track?
-			if (bits == 0 || KILL_FIRST_BIT(_m[tile].m5 & 0x3F) != 0)
+			if (bits == 0 || KILL_FIRST_BIT(GB(_m[tile].m5, 0, 6)) != 0)
 				break;
 
 			// If we reach here, the tile has exactly one track, and this
--- a/pathfind.h	Wed Oct 05 04:00:39 2005 +0000
+++ b/pathfind.h	Wed Oct 05 07:20:26 2005 +0000
@@ -64,7 +64,7 @@
 	TileIndex tile;
 	int length;
 } FindLengthOfTunnelResult;
-FindLengthOfTunnelResult FindLengthOfTunnel(TileIndex tile, int direction);
+FindLengthOfTunnelResult FindLengthOfTunnel(TileIndex tile, uint direction);
 
 void NewTrainPathfind(TileIndex tile, TileIndex dest, byte direction, NTPEnumProc *enum_proc, void *data);
 
--- a/pbs.c	Wed Oct 05 04:00:39 2005 +0000
+++ b/pbs.c	Wed Oct 05 07:20:26 2005 +0000
@@ -57,15 +57,14 @@
 				SETBIT(_m[tile].m3, 6);
 			} else {
 				// normal rail track
-				byte encrt = (_m[tile].m4 & 0xF0) >> 4; // get current encoded info (see comments at top of file)
+				byte encrt = GB(_m[tile].m4, 4, 4); // get current encoded info (see comments at top of file)
 
 				if (encrt == 0) // nothing reserved before
 					encrt = track + 1;
 				else if (encrt == (track^1) + 1) // opposite track reserved before
 					encrt |= 8;
 
-				_m[tile].m4 &= ~0xF0;
-				_m[tile].m4 |= encrt << 4;
+				SB(_m[tile].m4, 4, 4, encrt);
 			}
 			break;
 		case MP_TUNNELBRIDGE:
@@ -99,12 +98,12 @@
 				return HASBIT(_m[tile].m5, 0) ? 2 : 1;
 			} else {
 				// normal track
-				byte res = encrt_to_reserved[(_m[tile].m4 & 0xF0) >> 4];
+				byte res = encrt_to_reserved[GB(_m[tile].m4, 4, 4)];
 				assert(res != 0xFF);
 				return res;
 			}
 		case MP_TUNNELBRIDGE:
-			return (_m[tile].m4 & 3);
+			return GB(_m[tile].m4, 0, 2);
 		case MP_STATION:
 			// check if its reserved
 			if (!HASBIT(_m[tile].m3, 6)) return 0;
@@ -131,12 +130,12 @@
 				return HASBIT(_m[tile].m3, 6) ? TRACKDIR_BIT_MASK : 0;
 			} else {
 				// normal track
-				uint16 res = encrt_to_unavail[(_m[tile].m4 & 0xF0) >> 4];
+				uint16 res = encrt_to_unavail[GB(_m[tile].m4, 4, 4)];
 				assert(res != 0xFFFF);
 				return res;
 			}
 		case MP_TUNNELBRIDGE:
-			return (_m[tile].m4 & 3) | ((_m[tile].m4 & 3) << 8);
+			return GB(_m[tile].m4, 0, 2) | (GB(_m[tile].m4, 0, 2) << 8);
 		case MP_STATION:
 			return HASBIT(_m[tile].m3, 6) ? TRACKDIR_BIT_MASK : 0;
 		case MP_STREET:
@@ -159,7 +158,7 @@
 				CLRBIT(_m[tile].m3, 6);
 			} else {
 				// normal rail track
-				byte encrt = (_m[tile].m4 & 0xF0) >> 4;
+				byte encrt = GB(_m[tile].m4, 4, 4);
 
 				if (encrt == track + 1)
 					encrt = 0;
@@ -168,8 +167,7 @@
 				else if (encrt == (track^1) + 1 + 8)
 					encrt &= 7;
 
-				_m[tile].m4 &= ~0xF0;
-				_m[tile].m4 |= encrt << 4;
+				SB(_m[tile].m4, 4, 4, encrt);
 			}
 			break;
 		case MP_TUNNELBRIDGE:
@@ -203,7 +201,9 @@
 		if (tile == end_tile && TrackdirToTrack(trackdir) == TrackdirToTrack(end_trackdir))
 			return;
 
-		if (IsTileType(tile, MP_TUNNELBRIDGE) && (_m[tile].m5 & 0xF0)==0 && (unsigned)(_m[tile].m5 & 3) == TrackdirToExitdir(trackdir)) {
+		if (IsTileType(tile, MP_TUNNELBRIDGE) &&
+				GB(_m[tile].m5, 4, 4) == 0 &&
+				GB(_m[tile].m5, 0, 2) == TrackdirToExitdir(trackdir)) {
 			// this is a tunnel
 			flotr = FindLengthOfTunnel(tile, TrackdirToExitdir(trackdir));
 
--- a/rail_cmd.c	Wed Oct 05 04:00:39 2005 +0000
+++ b/rail_cmd.c	Wed Oct 05 07:20:26 2005 +0000
@@ -300,8 +300,7 @@
 
 					if (flags & DC_EXEC) {
 						SetTileOwner(tile, _current_player);
-						_m[tile].m3 &= ~0x0F;
-						_m[tile].m3 |= p1;
+						SB(_m[tile].m3, 0, 4, p1);
 						_m[tile].m5 = (m5 & 0xC7) | 0x20; // railroad under bridge
 					}
 					break;
@@ -322,7 +321,7 @@
 			}
 			if (m5 & RAIL_TYPE_SPECIAL ||
 					!IsTileOwner(tile, _current_player) ||
-					(_m[tile].m3 & 0xFU) != p1) {
+					GB(_m[tile].m3, 0, 4) != p1) {
 				// Get detailed error message
 				return DoCommandByTile(tile, 0, 0, flags, CMD_LANDSCAPE_CLEAR);
 			}
@@ -453,11 +452,7 @@
 			_m[tile].m5 = _m[tile].m5 & 0xC7;
 			break;
 		case MP_STREET:
-			if (!(_m[tile].m5 & 0xF0))
-				return CMD_ERROR;
-
-			if (_m[tile].m5 & 0xE0)
-				return CMD_ERROR;
+			if (!IsLevelCrossing(tile)) return CMD_ERROR;
 
 			/* This is a crossing, let's check if the direction is correct */
 			if (_m[tile].m5 & 8) {
@@ -793,8 +788,7 @@
 				if (pre_signal) {
 					// cycle between normal -> pre -> exit -> combo -> pbs ->...
 					byte type = ((GetSignalType(tile, track) + 1) % 5);
-					_m[tile].m4 &= ~0x07;
-					_m[tile].m4 |= type ;
+					SB(_m[tile].m4, 0, 3, type);
 				} else {
 					// cycle between two-way -> one-way -> one-way -> ...
 					/* TODO: Rewrite switch into something more general */
@@ -961,9 +955,9 @@
 		_m[tile].m3 &= ~SignalOnTrack(track);
 
 		/* removed last signal from tile? */
-		if ((_m[tile].m3 & 0xF0) == 0) {
-			_m[tile].m5 &= ~RAIL_TYPE_SIGNALS;
-			_m[tile].m2 &= ~0xF0;
+		if (GB(_m[tile].m3, 4, 4) == 0) {
+			SB(_m[tile].m2, 4, 4, 0);
+			SB(_m[tile].m5, 6, 2, RAIL_TYPE_NORMAL >> 6); // XXX >> because the constant is meant for direct application, not use with SB
 			CLRBIT(_m[tile].m4, 3); // remove any possible semaphores
 		}
 
@@ -997,7 +991,7 @@
 
 	// change type.
 	if (exec) {
-		_m[tile].m3 = (_m[tile].m3 & 0xF0) + totype;
+		SB(_m[tile].m3, 4, 4, totype);
 		MarkTileDirtyByTile(tile);
 	}
 
@@ -1757,10 +1751,10 @@
 	 * is some kind of invisible black hole, and there is some special magic going
 	 * on in there. This 'workaround' can be removed once the maprewrite is done.
 	 */
-	if (GetTileType(tile)==MP_TUNNELBRIDGE && ((_m[tile].m5 & 0xF0)==0)) {
+	if (GetTileType(tile) == MP_TUNNELBRIDGE && GB(_m[tile].m5, 4, 4) == 0) {
 		// It is a tunnel we're checking, we need to do some special stuff
 		// because VehicleFromPos will not find the vihicle otherwise
-		byte direction = _m[tile].m5 & 3;
+		byte direction = GB(_m[tile].m5, 0, 2);
 		FindLengthOfTunnelResult flotr;
 		flotr = FindLengthOfTunnel(tile, direction);
 		dest.track = 1 << (direction & 1); // get the trackbit the vehicle would have if it has not entered the tunnel yet (ie is still visible)
@@ -1845,8 +1839,7 @@
 	if (_patches.auto_pbs_placement && !(ssd->stop) && (ssd->has_pbssignal == 0xE) && !ssd->has_presignal && (ssd->presignal_exits == 0)) // 0xE means at least 2 pbs signals, and at least 1 entry and 1 exit, see comments ssd->has_pbssignal
 	for(i=0; i!=ssd->pbs_cur; i++) {
 		TileIndex tile = ssd->pbs_tile[i];
-		_m[tile].m4 &= ~0x07;
-		_m[tile].m4 |= 0x04;
+		SB(_m[tile].m4, 0, 3, SIGTYPE_PBS);
 		MarkTileDirtyByTile(tile);
 	};
 
@@ -2006,7 +1999,7 @@
 	uint16 m2;
 	byte owner;
 
-	m2 = _m[tile].m2 & 0xF;
+	m2 = GB(_m[tile].m2, 0, 4);
 
 	/* special code for alps landscape */
 	if (_opt.landscape == LT_HILLY) {
@@ -2158,7 +2151,7 @@
 				STR_NULL, STR_NULL
 			};
 
-			td->str = signal_type[_m[tile].m4 & 0x7];
+			td->str = signal_type[GB(_m[tile].m4, 0, 3)];
 			break;
 		}
 
--- a/road_cmd.c	Wed Oct 05 04:00:39 2005 +0000
+++ b/road_cmd.c	Wed Oct 05 07:20:26 2005 +0000
@@ -231,11 +231,11 @@
 				ChangeTownRating(t, -road_remove_cost[(byte)edge_road], RATING_ROAD_MINIMUM);
 
 				_m[tile].m5 ^= c;
-				if ((_m[tile].m5&0xF) == 0)
+				if (GB(_m[tile].m5, 0, 4) == 0) {
 					DoClearSquare(tile);
-				else
+				} else {
 					MarkTileDirtyByTile(tile);
-
+				}
 			}
 			return cost;
 		} else if ((ti.map5 & 0xE0) == 0) { // railroad crossing
@@ -499,11 +499,11 @@
 	if (!CheckTileOwnership(tile) || !EnsureNoVehicle(tile)) return CMD_ERROR;
 
 	// tile is already of requested type?
-	if ((_m[tile].m4 & 0xFU) == totype) return CMD_ERROR;
+	if (GB(_m[tile].m4, 0, 4) == totype) return CMD_ERROR;
 
 	if (exec) {
 		// change type.
-		_m[tile].m4 = (_m[tile].m4 & 0xF0) + totype;
+		SB(_m[tile].m4, 0, 4, totype);
 		MarkTileDirtyByTile(tile);
 	}
 
@@ -866,7 +866,7 @@
 			if (m2 > 1) image += 4;
 		}
 
-		DrawGroundSprite(image + (_m[ti->tile].m4 & 0xF) * 12);
+		DrawGroundSprite(image + GB(_m[ti->tile].m4, 0, 4) * 12);
 
 		if (_debug_pbs_level >= 1) {
 			byte pbs = PBSTileReserved(ti->tile);
@@ -1072,7 +1072,7 @@
 			} else {
 				b = 0;
 			}
-			_m[tile].m4 = (_m[tile].m4 & ~0x70) | (b << 4);
+			SB(_m[tile].m4, 4, 3, b);
 			MarkTileDirtyByTile(tile);
 		}
 	} else {
@@ -1097,9 +1097,7 @@
 
 static void ClickTile_Road(TileIndex tile)
 {
-	if ((_m[tile].m5 & 0xF0) == 0x20) {
-		ShowRoadDepotWindow(tile);
-	}
+	if (GB(_m[tile].m5, 4, 4) == 2) ShowRoadDepotWindow(tile);
 }
 
 static const byte _road_trackbits[16] = {
@@ -1163,15 +1161,15 @@
 static uint32 VehicleEnter_Road(Vehicle *v, TileIndex tile, int x, int y)
 {
 	if (IsLevelCrossing(tile)) {
-		if (v->type == VEH_Train && (_m[tile].m5 & 4) == 0) {
+		if (v->type == VEH_Train && GB(_m[tile].m5, 2, 1) == 0) {
 			/* train crossing a road */
 			SndPlayVehicleFx(SND_0E_LEVEL_CROSSING, v);
-			_m[tile].m5 |= 4;
+			SB(_m[tile].m5, 2, 1, 1);
 			MarkTileDirtyByTile(tile);
 		}
-	} else if ((_m[tile].m5&0xF0) ==  0x20){
+	} else if (GB(_m[tile].m5, 4, 4) == 2) {
 		if (v->type == VEH_Road && v->u.road.frame == 11) {
-			if (_roadveh_enter_depot_unk0[_m[tile].m5&3] == v->u.road.state) {
+			if (_roadveh_enter_depot_unk0[GB(_m[tile].m5, 0, 2)] == v->u.road.state) {
 				RoadVehEnterDepot(v);
 				return 4;
 			}
@@ -1184,15 +1182,13 @@
 {
 	if (IsLevelCrossing(tile) && v->type == VEH_Train && v->next == NULL) {
 		// Turn off level crossing lights
-		_m[tile].m5 &= ~4;
+		SB(_m[tile].m5, 2, 1, 0);
 		MarkTileDirtyByTile(tile);
 	}
 }
 
 static void ChangeTileOwner_Road(TileIndex tile, PlayerID old_player, PlayerID new_player)
 {
-	byte b;
-
 	// road/rail crossing where the road is owned by the current player?
 	if (old_player == _m[tile].m3 && IsLevelCrossing(tile)) {
 		_m[tile].m3 = (new_player == OWNER_SPECTATOR) ? OWNER_NONE : new_player;
@@ -1203,8 +1199,7 @@
 	if (new_player != 255) {
 		SetTileOwner(tile, new_player);
 	}	else {
-		b = _m[tile].m5&0xF0;
-		if (b == 0) {
+		if (GB(_m[tile].m5, 4, 4) == 0) {
 			SetTileOwner(tile, OWNER_NONE);
 		} else if (IsLevelCrossing(tile)) {
 			_m[tile].m5 = (_m[tile].m5&8) ? 0x5 : 0xA;
--- a/roadveh_cmd.c	Wed Oct 05 04:00:39 2005 +0000
+++ b/roadveh_cmd.c	Wed Oct 05 07:20:26 2005 +0000
@@ -284,7 +284,7 @@
 	tile += TileOffsByDir(_road_pf_directions[track]);
 
 	if (IsTileType(tile, MP_STREET) &&
-			(_m[tile].m5 & 0xF0) == 0x20 &&
+			GB(_m[tile].m5, 4, 4) == 2 &&
 			IsTileOwner(tile, rfdd->owner)) {
 
 		if (length < rfdd->best_length) {
@@ -1034,7 +1034,7 @@
 	}
 
 	if (IsTileType(tile, MP_STREET)) {
-		if ((_m[tile].m5&0xF0) == 0x20 && IsTileOwner(tile, v->owner))
+		if (GB(_m[tile].m5, 4, 4) == 2 && IsTileOwner(tile, v->owner))
 			/* Road crossing */
 			bitmask |= _road_veh_fp_ax_or[_m[tile].m5&3];
 	} else if (IsTileType(tile, MP_STATION)) {
@@ -1237,7 +1237,7 @@
 
 		v->cur_speed = 0;
 
-		dir = _m[v->tile].m5&3;
+		dir = GB(_m[v->tile].m5, 0, 2);
 		v->direction = dir*2+1;
 
 		rd2 = _roadveh_data_2[dir];
@@ -1286,7 +1286,7 @@
 		}
 
 		if (IsTileType(gp.new_tile, MP_TUNNELBRIDGE) &&
-				(_m[gp.new_tile].m5&0xF0) == 0 &&
+				GB(_m[gp.new_tile].m5, 4, 4) == 0 &&
 				(VehicleEnterTile(v, gp.new_tile, gp.x, gp.y)&4)) {
 
 			//new_dir = RoadGetNewDirection(v, gp.x, gp.y)
--- a/station_cmd.c	Wed Oct 05 04:00:39 2005 +0000
+++ b/station_cmd.c	Wed Oct 05 07:20:26 2005 +0000
@@ -1430,11 +1430,11 @@
 	if (_m[tile].m5 >= 8) return CMD_ERROR;
 
 	// tile is already of requested type?
-	if ((_m[tile].m3 & 0xFU) == totype) return CMD_ERROR;
+	if (GB(_m[tile].m3, 0, 4) == totype) return CMD_ERROR;
 
 	if (exec) {
 		// change type.
-		_m[tile].m3 = (_m[tile].m3 & 0xF0) + totype;
+		SB(_m[tile].m3, 0, 4, totype);
 		MarkTileDirtyByTile(tile);
 	}
 
@@ -2131,7 +2131,7 @@
 	uint32 image;
 	const DrawTileSeqStruct *dtss;
 	const DrawTileSprites *t = NULL;
-	byte railtype = _m[ti->tile].m3 & 0xF;
+	byte railtype = GB(_m[ti->tile].m3, 0, 4);
 	const RailtypeInfo *rti = GetRailTypeInfo(railtype);
 	SpriteID offset;
 	uint32 relocation = 0;
--- a/tile.h	Wed Oct 05 04:00:39 2005 +0000
+++ b/tile.h	Wed Oct 05 07:20:26 2005 +0000
@@ -99,7 +99,7 @@
 
 static inline bool IsTunnelTile(TileIndex tile)
 {
-	return IsTileType(tile, MP_TUNNELBRIDGE) && (_m[tile].m5 & 0xF0) == 0;
+	return IsTileType(tile, MP_TUNNELBRIDGE) && GB(_m[tile].m5, 4, 4) == 0;
 }
 
 static inline Owner GetTileOwner(TileIndex tile)
--- a/town_cmd.c	Wed Oct 05 04:00:39 2005 +0000
+++ b/town_cmd.c	Wed Oct 05 07:20:26 2005 +0000
@@ -78,7 +78,7 @@
 
 static void TownDrawHouseLift(const TileInfo *ti)
 {
-	AddChildSpriteScreen(0x5A3, 0xE, 0x3C - (_m[ti->tile].m1 & 0x7F));
+	AddChildSpriteScreen(0x5A3, 0xE, 0x3C - GB(_m[ti->tile].m1, 0, 7));
 }
 
 typedef void TownDrawTileProc(const TileInfo *ti);
@@ -183,10 +183,10 @@
 		SB(_m[tile].m5, 0, 6, i);
 	}
 
-	a = _m[tile].m1 & 0x7F;
-	b = (_m[tile].m5&0x3F) * 6;
+	a = GB(_m[tile].m1, 0, 7);
+	b = GB(_m[tile].m5, 0, 6) * 6;
 	a += (a < b) ? 1 : -1;
-	_m[tile].m1 = (_m[tile].m1 & 0x80) | a;
+	SB(_m[tile].m1, 0, 7, a);
 
 	if (a == b) {
 		_m[tile].m1 &= 0x7F;
@@ -623,7 +623,7 @@
 
 		// Reached a tunnel? Then continue at the other side of it.
 		if (IsTileType(tile, MP_TUNNELBRIDGE) && (_m[tile].m5& ~3) == 4) {
-			FindLengthOfTunnelResult flotr = FindLengthOfTunnel(tile, _m[tile].m5&3);
+			FindLengthOfTunnelResult flotr = FindLengthOfTunnel(tile, GB(_m[tile].m5, 0, 2));
 			*tile_ptr = flotr.tile;
 			return;
 		}
--- a/train_cmd.c	Wed Oct 05 04:00:39 2005 +0000
+++ b/train_cmd.c	Wed Oct 05 07:20:26 2005 +0000
@@ -1258,8 +1258,8 @@
 		/* Check if there is a train on the tile itself */
 		if (VehicleFromPos(tile, &tile, TestTrainOnCrossing) == NULL) {
 			/* If light is on, switch light off */
-			if (_m[tile].m5 & 4) {
-				_m[tile].m5 &= ~4;
+			if (GB(_m[tile].m5, 2, 1) != 0) {
+				SB(_m[tile].m5, 2, 1, 0);
 				MarkTileDirtyByTile(tile);
 			}
 		}
@@ -1322,7 +1322,7 @@
 		return v->tile;
 
 	for (tile = v->tile;; tile += delta) {
-		if (IsTunnelTile(tile) && (_m[tile].m5 & 0x3) != (direction) && GetTileZ(tile) == v->z_pos)
+		if (IsTunnelTile(tile) && GB(_m[tile].m5, 0, 2) != direction && GetTileZ(tile) == v->z_pos)
  			break;
  	}
  	return tile;
@@ -2466,7 +2466,7 @@
 			// tracks over roads, do owner check of tracks
 			return
 				IsTileOwner(tile, v->owner) &&
-				(v->subtype != TS_Front_Engine || (_m[tile].m4 & 0xF) == v->u.rail.railtype);
+				(v->subtype != TS_Front_Engine || GB(_m[tile].m4, 0, 4) == v->u.rail.railtype);
 
 		default:
 			return true;
@@ -3173,8 +3173,8 @@
 		if ((ts &= (ts >> 16)) == 0) {
 			// make a rail/road crossing red
 			if (IsTileType(tile, MP_STREET) && IsLevelCrossing(tile)) {
-				if (!(_m[tile].m5 & 4)) {
-					_m[tile].m5 |= 4;
+				if (GB(_m[tile].m5, 2, 1) == 0) {
+					SB(_m[tile].m5, 2, 1, 1);
 					SndPlayVehicleFx(SND_0E_LEVEL_CROSSING, v);
 					MarkTileDirtyByTile(tile);
 				}
@@ -3319,7 +3319,7 @@
 
 void TrainEnterDepot(Vehicle *v, TileIndex tile)
 {
-	SetSignalsOnBothDir(tile, _depot_track_ind[_m[tile].m5&3]);
+	SetSignalsOnBothDir(tile, _depot_track_ind[GB(_m[tile].m5, 0, 2)]);
 
 	if (v->subtype != TS_Front_Engine)
 		v = GetFirstVehicleInChain(v);
--- a/train_gui.c	Wed Oct 05 04:00:39 2005 +0000
+++ b/train_gui.c	Wed Oct 05 07:20:26 2005 +0000
@@ -341,7 +341,7 @@
 
 	if (tile != 0) {
 		w->caption_color = GetTileOwner(tile);
-		WP(w,buildtrain_d).railtype = _m[tile].m3 & 0xF;
+		WP(w,buildtrain_d).railtype = GB(_m[tile].m3, 0, 4);
 	} else {
 		w->caption_color = _local_player;
 		WP(w,buildtrain_d).railtype = GetBestRailtype(GetPlayer(_local_player));
--- a/tunnelbridge_cmd.c	Wed Oct 05 04:00:39 2005 +0000
+++ b/tunnelbridge_cmd.c	Wed Oct 05 07:20:26 2005 +0000
@@ -627,7 +627,7 @@
 		len++;
 	} while (
 		!IsTileType(tile, MP_TUNNELBRIDGE) ||
-		(_m[tile].m5 & 0xF0) != 0 ||
+		GB(_m[tile].m5, 4, 4) != 0 ||
 		(_m[tile].m5 ^ 2) != m5 ||
 		GetTileZ(tile) != z
 	);
@@ -676,8 +676,8 @@
 	if (flags & DC_EXEC) {
 		// We first need to request the direction before calling DoClearSquare
 		//  else the direction is always 0.. dah!! ;)
-		byte tile_dir = _m[tile].m5&3;
-		byte endtile_dir = _m[endtile].m5&3;
+		byte tile_dir = GB(_m[tile].m5, 0, 2);
+		byte endtile_dir = GB(_m[endtile].m5, 0, 2);
 		DoClearSquare(tile);
 		DoClearSquare(endtile);
 		UpdateSignalsOnSegment(tile, _updsignals_tunnel_dir[tile_dir]);
@@ -690,7 +690,7 @@
 
 static TileIndex FindEdgesOfBridge(TileIndex tile, TileIndex *endtile)
 {
-	int direction = _m[tile].m5 & 1;
+	int direction = GB(_m[tile].m5, 0, 1);
 	TileIndex start;
 
 	// find start of bridge
@@ -723,7 +723,7 @@
 
 	SET_EXPENSES_TYPE(EXPENSES_CONSTRUCTION);
 
-	direction = _m[tile].m5&1;
+	direction = GB(_m[tile].m5, 0, 1);
 
 	/* delete stuff under the middle part if there's a transport route there..? */
 	if ((_m[tile].m5 & 0xE0) == 0xE0) {
@@ -871,14 +871,14 @@
 		// railway tunnel
 		if (!CheckTileOwnership(tile)) return CMD_ERROR;
 
-		if ((_m[tile].m3 & 0xFU) == totype) return CMD_ERROR;
+		if (GB(_m[tile].m3, 0, 4) == totype) return CMD_ERROR;
 
 		endtile = CheckTunnelBusy(tile, &length);
 		if (endtile == INVALID_TILE) return CMD_ERROR;
 
 		if (exec) {
-			_m[tile].m3 = (_m[tile].m3 & 0xF0) + totype;
-			_m[endtile].m3 = (_m[endtile].m3 & 0xF0) + totype;
+			SB(_m[tile].m3, 0, 4, totype);
+			SB(_m[endtile].m3, 0, 4, totype);
 			MarkTileDirtyByTile(tile);
 			MarkTileDirtyByTile(endtile);
 		}
@@ -890,10 +890,10 @@
 			return CMD_ERROR;
 
 		// tile is already of requested type?
-		if ((_m[tile].m3 & 0xFU) == totype) return CMD_ERROR;
+		if (GB(_m[tile].m3, 0, 4) == totype) return CMD_ERROR;
 		// change type.
 		if (exec) {
-			_m[tile].m3 = (_m[tile].m3 & 0xF0) + totype;
+			SB(_m[tile].m3, 0, 4, totype);
 			MarkTileDirtyByTile(tile);
 		}
 		return _price.build_rail >> 1;
@@ -919,19 +919,19 @@
 			return CMD_ERROR;
 		}
 
-		if ((_m[tile].m3 & 0xFU) == totype) return CMD_ERROR;
+		if (GB(_m[tile].m3, 0, 4) == totype) return CMD_ERROR;
 		cost = 0;
 		do {
 			if (exec) {
 				if (tile == starttile || tile == endtile) {
-					_m[tile].m3 = (_m[tile].m3 & 0xF0) + totype;
+					SB(_m[tile].m3, 0, 4, totype);
 				} else {
-					_m[tile].m3 = (_m[tile].m3 & 0x0F) + (totype << 4);
+					SB(_m[tile].m3, 4, 4, totype);
 				}
 				MarkTileDirtyByTile(tile);
 			}
 			cost += (_price.build_rail>>1);
-			tile += _m[tile].m5 & 1 ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
+			tile += GB(_m[tile].m5, 0, 1) ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
 		} while (tile <= endtile);
 
 		return cost;
@@ -947,7 +947,7 @@
 	TileIndex tile = ti->tile;
 
 	// find the end tile of the bridge.
-	delta = (_m[tile].m5 & 1) ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
+	delta = GB(_m[tile].m5, 0, 1) ? TileDiffXY(0, 1) : TileDiffXY(1, 0);
 	do {
 		assert((_m[tile].m5 & 0xC0) == 0xC0);	// bridge and middle part
 		tile += delta;
@@ -1124,7 +1124,7 @@
 				}
 
 				if (!(image&1)) {
-					const RailtypeInfo *rti = GetRailTypeInfo(_m[ti->tile].m3 & 0xF);
+					const RailtypeInfo *rti = GetRailTypeInfo(GB(_m[ti->tile].m3, 0, 4));
 					// railway
 					image = 0x3F3 + (ti->map5 & 1);
 					if (ti->tileh != 0) image = _track_sloped_sprites[ti->tileh - 1] + 0x3F3;
@@ -1316,7 +1316,7 @@
 
 		/* scan to the end of the bridge, that's where the owner is stored */
 		if (_m[tile].m5 & 0x40) {
-			TileIndexDiff delta = _m[tile].m5 & 1 ? TileDiffXY(0, -1) : TileDiffXY(-1, 0);
+			TileIndexDiff delta = GB(_m[tile].m5, 0, 1) ? TileDiffXY(0, -1) : TileDiffXY(-1, 0);
 
 			do tile += delta; while (_m[tile].m5 & 0x40);
 		}
@@ -1450,7 +1450,7 @@
 	int dir, vdir;
 	byte fc;
 
-	if ((_m[tile].m5 & 0xF0) == 0) {
+	if (GB(_m[tile].m5, 4, 4) == 0) {
 		z = GetSlopeZ(x, y) - v->z_pos;
 		if (myabs(z) > 2)
 			return 8;
@@ -1458,7 +1458,7 @@
 		if (v->type == VEH_Train) {
 			fc = (x&0xF)+(y<<4);
 
-			dir = _m[tile].m5 & 3;
+			dir = GB(_m[tile].m5, 0, 2);
 			vdir = v->direction >> 1;
 
 			if (v->u.rail.track != 0x40 && dir == vdir) {
@@ -1487,7 +1487,7 @@
 			}
 		} else if (v->type == VEH_Road) {
 			fc = (x&0xF)+(y<<4);
-			dir = _m[tile].m5 & 3;
+			dir = GB(_m[tile].m5, 0, 2);
 			vdir = v->direction >> 1;
 
 			// Enter tunnel?
@@ -1542,7 +1542,7 @@
 	byte z = v->z_pos;
 
 	for (tile = v->tile;; tile += delta) {
-		if (IsTileType(tile, MP_TUNNELBRIDGE) && (_m[tile].m5 & 0xF0) == 0 &&
+		if (IsTileType(tile, MP_TUNNELBRIDGE) && GB(_m[tile].m5, 4, 4) == 0 &&
 				GetTileZ(tile) == z)
 			break;
 	}
--- a/water_cmd.c	Wed Oct 05 04:00:39 2005 +0000
+++ b/water_cmd.c	Wed Oct 05 07:20:26 2005 +0000
@@ -144,7 +144,7 @@
 
 static int32 RemoveShiplift(TileIndex tile, uint32 flags)
 {
-	TileIndexDiff delta = TileOffsByDir(_m[tile].m5 & 3);
+	TileIndexDiff delta = TileOffsByDir(GB(_m[tile].m5, 0, 2));
 
 	// make sure no vehicle is on the tile.
 	if (!EnsureNoVehicle(tile) || !EnsureNoVehicle(tile + delta) || !EnsureNoVehicle(tile - delta))
@@ -500,7 +500,7 @@
 		switch (GetTileType(target)) {
 			case MP_RAILWAY: {
 				uint slope = GetTileSlope(target, NULL);
-				byte tracks = _m[target].m5 & 0x3F;
+				byte tracks = GB(_m[target].m5, 0, 6);
 				if (!(
 						(slope == 1 && tracks == 0x20) ||
 						(slope == 2 && tracks == 0x04) ||