Changeset - r6000:e72d89b471ab
[Not reviewed]
master
0 6 0
rubidium - 18 years ago 2007-02-13 22:27:27
rubidium@openttd.org
(svn r8715) -Codechange/cleanup: replace magic numbers related to state of road vehicles with enums. Original patch by mart3p.
6 files changed with 82 insertions and 38 deletions:
0 comments (0 inline, 0 general)
src/openttd.cpp
Show inline comments
 
@@ -1455,13 +1455,13 @@ bool AfterLoadGame(void)
 
			} else {
 
				continue;
 
			}
 
			if (v->type == VEH_Train) {
 
				v->u.rail.track = TRACK_BIT_WORMHOLE;
 
			} else {
 
				v->u.road.state = 0xFF;
 
				v->u.road.state = RVSB_WORMHOLE;
 
			}
 
		}
 
	}
 

	
 
	/* Elrails got added in rev 24 */
 
	if (CheckSavegameVersion(24)) {
src/roadveh_cmd.cpp
Show inline comments
 
@@ -71,12 +71,29 @@ static const TrackdirBits _road_exit_dir
 
	TRACKDIR_BIT_LOWER_W | TRACKDIR_BIT_X_SW    | TRACKDIR_BIT_LEFT_S,
 
	TRACKDIR_BIT_LEFT_N  | TRACKDIR_BIT_UPPER_W | TRACKDIR_BIT_Y_NW,
 
	TRACKDIR_BIT_RIGHT_N | TRACKDIR_BIT_UPPER_E | TRACKDIR_BIT_X_NE,
 
	TRACKDIR_BIT_RIGHT_S | TRACKDIR_BIT_LOWER_E | TRACKDIR_BIT_Y_SE
 
};
 

	
 
/** Converts the exit direction of a depot to trackdir the vehicle is going to drive to */
 
static const Trackdir _roadveh_depot_exit_trackdir[DIAGDIR_END] = {
 
	TRACKDIR_X_NE, TRACKDIR_Y_SE, TRACKDIR_X_SW, TRACKDIR_Y_NW
 
};
 

	
 
/** Checks whether the trackdir means that we are reversing */
 
static bool IsReversingRoadTrackdir(Trackdir dir)
 
{
 
	return (dir & 0x07) >= 6;
 
}
 

	
 
/** Checks whether the given trackdir is a straight road */
 
static bool IsStraightRoadTrackdir(Trackdir dir)
 
{
 
	return (dir & 0x06) == 0;
 
}
 

	
 
int GetRoadVehImage(const Vehicle* v, Direction direction)
 
{
 
	int img = v->spritenum;
 
	int image;
 

	
 
	if (is_custom_sprite(img)) {
 
@@ -158,13 +175,13 @@ int32 CmdBuildRoadVeh(TileIndex tile, ui
 
		y = TileY(tile) * TILE_SIZE + TILE_SIZE / 2;
 
		v->x_pos = x;
 
		v->y_pos = y;
 
		v->z_pos = GetSlopeZ(x,y);
 
		v->z_height = 6;
 

	
 
		v->u.road.state = 254;
 
		v->u.road.state = RVSB_IN_DEPOT;
 
		v->vehstatus = VS_HIDDEN|VS_STOPPED|VS_DEFPAL;
 

	
 
		v->spritenum = rvi->image_index;
 
		v->cargo_type = rvi->cargo_type;
 
		v->cargo_subtype = 0;
 
		v->cargo_cap = rvi->capacity;
 
@@ -449,13 +466,13 @@ int32 CmdTurnRoadVeh(TileIndex tile, uin
 
	if (v->type != VEH_Road || !CheckOwnership(v->owner)) return CMD_ERROR;
 

	
 
	if (v->vehstatus & VS_STOPPED ||
 
			v->u.road.crashed_ctr != 0 ||
 
			v->breakdown_ctr != 0 ||
 
			v->u.road.overtaking != 0 ||
 
			v->u.road.state == 255 ||
 
			v->u.road.state == RVSB_WORMHOLE ||
 
			IsRoadVehInDepot(v) ||
 
			v->cur_speed < 5) {
 
		return CMD_ERROR;
 
	}
 

	
 
	if (IsTunnelTile(v->tile) && DirToDiagDir(v->direction) == GetTunnelDirection(v->tile)) return CMD_ERROR;
 
@@ -499,13 +516,13 @@ static void ClearCrashedStation(Vehicle 
 
	RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile));
 

	
 
	/* Mark the station entrance as not busy */
 
	rs->SetEntranceBusy(false);
 

	
 
	/* Free the parking bay */
 
	rs->FreeBay(HASBIT(v->u.road.state, 1) ? 1 : 0);
 
	rs->FreeBay(HASBIT(v->u.road.state, RVS_USING_SECOND_BAY) ? 1 : 0);
 
}
 

	
 
static void RoadVehDelete(Vehicle *v)
 
{
 
	DeleteWindowById(WC_VEHICLE_VIEW, v->index);
 

	
 
@@ -604,13 +621,13 @@ static void RoadVehCrash(Vehicle *v)
 
}
 

	
 
static void RoadVehCheckTrainCrash(Vehicle *v)
 
{
 
	TileIndex tile;
 

	
 
	if (v->u.road.state == 255) return;
 
	if (v->u.road.state == RVSB_WORMHOLE) return;
 

	
 
	tile = v->tile;
 

	
 
	if (!IsLevelCrossingTile(tile)) return;
 

	
 
	if (VehicleFromPos(tile, v, EnumCheckRoadVehCrashTrain) != NULL)
 
@@ -872,13 +889,13 @@ static bool RoadVehAccelerate(Vehicle *v
 
{
 
	uint spd = v->cur_speed + 1 + (v->u.road.overtaking != 0 ? 1 : 0);
 
	byte t;
 

	
 
	// Clamp
 
	spd = min(spd, v->max_speed);
 
	if (v->u.road.state == 255) spd = min(spd, SetSpeedLimitOnBridge(v));
 
	if (v->u.road.state == RVSB_WORMHOLE) spd = min(spd, SetSpeedLimitOnBridge(v));
 

	
 
	//updates statusbar only if speed have changed to save CPU time
 
	if (spd != v->cur_speed) {
 
		v->cur_speed = spd;
 
		if (_patches.vehicle_speed) {
 
			InvalidateWindowWidget(WC_VEHICLE_VIEW, v->index, STATUS_BAR);
 
@@ -963,13 +980,14 @@ static void RoadVehCheckOvertake(Vehicle
 
			u->cur_speed != 0) {
 
		return;
 
	}
 

	
 
	if (v->direction != u->direction || !(v->direction & 1)) return;
 

	
 
	if (v->u.road.state >= 32 || (v->u.road.state & 7) > 1) return;
 
	/* Check if vehicle is in a road stop, depot, tunnel or bridge or not on a straight road */
 
	if (v->u.road.state >= RVS_IN_ROAD_STOP || !IsStraightRoadTrackdir((Trackdir)(v->u.road.state & RVSB_TRACKDIR_MASK))) return;
 

	
 
	tt = GetTileTrackStatus(v->tile, TRANSPORT_ROAD) & 0x3F;
 
	if ((tt & 3) == 0) return;
 
	if ((tt & 0x3C) != 0) return;
 

	
 
	if (tt == 3) tt = (v->direction & 2) ? 2 : 1;
 
@@ -1239,17 +1257,12 @@ static const byte _road_veh_data_1[] = {
 
	20, 20, 16, 16, 0, 0, 0, 0,
 
	19, 19, 15, 15, 0, 0, 0, 0,
 
	16, 16, 12, 12, 0, 0, 0, 0,
 
	15, 15, 11, 11
 
};
 

	
 
/** Converts the exit direction of a depot to trackdir the vehicle is going to drive to */
 
static const Trackdir _roadveh_depot_exit_trackdir[DIAGDIR_END] = {
 
	TRACKDIR_X_NE, TRACKDIR_Y_SE, TRACKDIR_X_SW, TRACKDIR_Y_NW
 
};
 

	
 
static void RoadVehController(Vehicle *v)
 
{
 
	Direction new_dir;
 
	Direction old_dir;
 
	RoadDriveEntry rd;
 
	int x,y;
 
@@ -1324,25 +1337,22 @@ static void RoadVehController(Vehicle *v
 
	if (!RoadVehAccelerate(v)) return;
 

	
 
	if (v->u.road.overtaking != 0)  {
 
		if (++v->u.road.overtaking_ctr >= 35)
 
			/* If overtaking just aborts at a random moment, we can have a out-of-bound problem,
 
			 *  if the vehicle started a corner. To protect that, only allow an abort of
 
			 *  overtake if we are on straight road, which are the 8 states below */
 
			if (v->u.road.state == 0  || v->u.road.state == 1  ||
 
					v->u.road.state == 8  || v->u.road.state == 9  ||
 
					v->u.road.state == 16 || v->u.road.state == 17 ||
 
					v->u.road.state == 24 || v->u.road.state == 25) {
 
			 *  overtake if we are on straight roads */
 
			if (v->u.road.state < RVSB_IN_ROAD_STOP && IsStraightRoadTrackdir((Trackdir)v->u.road.state)) {
 
				v->u.road.overtaking = 0;
 
			}
 
	}
 

	
 
	/* Save old vehicle position to use at end of move to set viewport area dirty */
 
	BeginVehicleMove(v);
 

	
 
	if (v->u.road.state == 255) {
 
	if (v->u.road.state == RVSB_WORMHOLE) {
 
		/* Vehicle is on a bridge or in a tunnel */
 
		GetNewVehiclePosResult gp;
 

	
 
		GetNewVehiclePos(v, &gp);
 

	
 
		const Vehicle *u = RoadVehFindCloseTo(v, gp.x, gp.y, v->direction);
 
@@ -1364,13 +1374,13 @@ static void RoadVehController(Vehicle *v
 
		VehiclePositionChanged(v);
 
		if (!(v->vehstatus & VS_HIDDEN)) EndVehicleMove(v);
 
		return;
 
	}
 

	
 
	/* Get move position data for next frame */
 
	rd = _road_drive_data[(v->u.road.state + (_opt.road_side << 4)) ^ v->u.road.overtaking][v->u.road.frame + 1];
 
	rd = _road_drive_data[(v->u.road.state + (_opt.road_side << RVS_DRIVE_SIDE)) ^ v->u.road.overtaking][v->u.road.frame + 1];
 

	
 
	if (rd.x & 0x80) {
 
		/* Vehicle is moving to the next tile */
 
		TileIndex tile = v->tile + TileOffsByDiagDir(rd.x & 3);
 
		Trackdir dir = RoadFindPathToDest(v, tile, (DiagDirection)(rd.x & 3));
 
		uint32 r;
 
@@ -1381,13 +1391,13 @@ static void RoadVehController(Vehicle *v
 
			/* No path was found to destination */
 
			v->cur_speed = 0;
 
			return;
 
		}
 

	
 
again:
 
		if ((dir & 7) >= 6) {
 
		if (IsReversingRoadTrackdir(dir)) {
 
			/* Turning around */
 
			tile = v->tile;
 
		}
 

	
 
		/* Get position data for first frame on the new tile */
 
		rdp = _road_drive_data[(dir + (_opt.road_side << 4)) ^ v->u.road.overtaking];
 
@@ -1403,29 +1413,29 @@ again:
 
			/* Vehicle cannot enter the tile */
 
			if (!IsTileType(tile, MP_TUNNELBRIDGE)) {
 
				v->cur_speed = 0;
 
				return;
 
			}
 
			/* Try an about turn to re-enter the previous tile */
 
			dir = _road_reverse_table[rd.x&3];
 
			dir = _road_reverse_table[rd.x & 3];
 
			goto again;
 
		}
 

	
 
		if (IS_BYTE_INSIDE(v->u.road.state, 0x20, 0x30) && IsTileType(v->tile, MP_STATION)) {
 
			if ((dir & 7) >= 6) {
 
		if (IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END) && IsTileType(v->tile, MP_STATION)) {
 
			if (IsReversingRoadTrackdir(dir)) {
 
				/* New direction is trying to turn vehicle around.
 
				 * We can't turn at the exit of a road stop so wait.*/
 
				v->cur_speed = 0;
 
				return;
 
			}
 
			if (IsRoadStop(v->tile)) {
 
				/* The tile that the vehicle is leaving is a road stop */
 
				RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile));
 

	
 
				/* Vehicle is leaving a road stop tile, mark bay as free and clear the usage bit */
 
				rs->FreeBay(HASBIT(v->u.road.state, 1) ? 1 : 0);
 
				rs->FreeBay(HASBIT(v->u.road.state, RVS_USING_SECOND_BAY) ? 1 : 0);
 
				rs->SetEntranceBusy(false);
 
			}
 
		}
 

	
 
		if (!HASBIT(r, VETS_ENTERED_WORMHOLE)) {
 
			/* Set vehicle to first frame on new tile */
 
@@ -1472,13 +1482,13 @@ again:
 
			/* Vehicle cannot enter the tile */
 
			v->cur_speed = 0;
 
			return;
 
		}
 

	
 
		/* Set vehicle to second frame on the tile */
 
		v->u.road.state = tmp & ~16;
 
		CLRBIT(v->u.road.state, RVS_DRIVE_SIDE);
 
		v->u.road.frame = 1;
 

	
 
		if (newdir != v->direction) {
 
			v->direction = newdir;
 
			v->cur_speed -= v->cur_speed >> 2;
 
		}
 
@@ -1492,13 +1502,13 @@ again:
 
	/* Calculate new position for the vehicle */
 
	x = (v->x_pos & ~15) + (rd.x & 15);
 
	y = (v->y_pos & ~15) + (rd.y & 15);
 

	
 
	new_dir = RoadVehGetSlidingDirection(v, x, y);
 

	
 
	if (!IS_BYTE_INSIDE(v->u.road.state, 0x20, 0x30)) {
 
	if (!IS_BYTE_INSIDE(v->u.road.state, RVSB_IN_ROAD_STOP, RVSB_IN_ROAD_STOP_END)) {
 
		/* Vehicle is not in a road stop.
 
		 * Check for another vehicle to overtake */
 
		Vehicle* u = RoadVehFindCloseTo(v, x, y, new_dir);
 

	
 
		if (u != NULL) {
 
			/* There is a vehicle in front overtake it if possible */
 
@@ -1521,14 +1531,14 @@ again:
 
			 * for vehicles changing direction in a road stop. This causes frames to
 
			 * be repeated. Is this intended? */
 
			return;
 
		}
 
	}
 

	
 
	if (v->u.road.state >= 0x20 &&
 
			_road_veh_data_1[v->u.road.state - 0x20 + (_opt.road_side<<4)] == v->u.road.frame) {
 
	if (v->u.road.state >= RVSB_IN_ROAD_STOP &&
 
			_road_veh_data_1[v->u.road.state - RVSB_IN_ROAD_STOP + (_opt.road_side << RVS_DRIVE_SIDE)] == v->u.road.frame) {
 
		RoadStop *rs = GetRoadStopByTile(v->tile, GetRoadStopType(v->tile));
 
		Station* st = GetStationByTile(v->tile);
 

	
 
		/* Vehicle is at the stop position (at a bay) in a road stop.
 
		 * Note, if vehicle is loading/unloading it has already been handled,
 
		 * so if we get here the vehicle has just arrived or is just ready to leave. */
src/station_cmd.cpp
Show inline comments
 
@@ -2219,25 +2219,25 @@ static uint32 VehicleEnter_Station(Vehic
 
						}
 
					}
 
				}
 
			}
 
		}
 
	} else if (v->type == VEH_Road) {
 
		if (v->u.road.state < 16 && !HASBIT(v->u.road.state, 2) && v->u.road.frame == 0) {
 
		if (v->u.road.state < RVSB_IN_ROAD_STOP && v->u.road.frame == 0) {
 
			if (IsRoadStop(tile)) {
 
				/* Attempt to allocate a parking bay in a road stop */
 
				RoadStop *rs = GetRoadStopByTile(tile, GetRoadStopType(tile));
 

	
 
				/* Check if station is busy or if there are no free bays. */
 
				if (rs->IsEntranceBusy() || !rs->HasFreeBay()) return VETSB_CANNOT_ENTER;
 

	
 
				v->u.road.state += 32;
 
				SETBIT(v->u.road.state, RVS_IN_ROAD_STOP);
 

	
 
				/* Allocate a bay and update the road state */
 
				uint bay_nr = rs->AllocateBay();
 
				SB(v->u.road.state, 1, 1, bay_nr);
 
				SB(v->u.road.state, RVS_USING_SECOND_BAY, 1, bay_nr);
 

	
 
				/* Mark the station entrace as busy */
 
				rs->SetEntranceBusy(true);
 
			}
 
		}
 
	}
src/tunnelbridge_cmd.cpp
Show inline comments
 
@@ -1247,13 +1247,16 @@ static void ChangeTileOwner_TunnelBridge
 

	
 
static const byte _tunnel_fractcoord_1[4]    = {0x8E, 0x18, 0x81, 0xE8};
 
static const byte _tunnel_fractcoord_2[4]    = {0x81, 0x98, 0x87, 0x38};
 
static const byte _tunnel_fractcoord_3[4]    = {0x82, 0x88, 0x86, 0x48};
 
static const byte _exit_tunnel_track[4]      = {1, 2, 1, 2};
 

	
 
static const byte _road_exit_tunnel_state[4] = {8, 9, 0, 1};
 
/** Get the trackdir of the exit of a tunnel */
 
static const Trackdir _road_exit_tunnel_state[DIAGDIR_END] = {
 
	TRACKDIR_X_SW, TRACKDIR_Y_NW, TRACKDIR_X_NE, TRACKDIR_Y_SE
 
};
 
static const byte _road_exit_tunnel_frame[4] = {2, 7, 9, 4};
 

	
 
static const byte _tunnel_fractcoord_4[4]    = {0x52, 0x85, 0x98, 0x29};
 
static const byte _tunnel_fractcoord_5[4]    = {0x92, 0x89, 0x58, 0x25};
 
static const byte _tunnel_fractcoord_6[4]    = {0x92, 0x89, 0x56, 0x45};
 
static const byte _tunnel_fractcoord_7[4]    = {0x52, 0x85, 0x96, 0x49};
 
@@ -1301,17 +1304,17 @@ static uint32 VehicleEnter_TunnelBridge(
 
		} else if (v->type == VEH_Road) {
 
			fc = (x & 0xF) + (y << 4);
 
			dir = GetTunnelDirection(tile);
 
			vdir = DirToDiagDir(v->direction);
 

	
 
			// Enter tunnel?
 
			if (v->u.road.state != 0xFF && dir == vdir) {
 
			if (v->u.road.state != RVSB_WORMHOLE && dir == vdir) {
 
				if (fc == _tunnel_fractcoord_4[dir] ||
 
						fc == _tunnel_fractcoord_5[dir]) {
 
					v->tile = tile;
 
					v->u.road.state = 0xFF;
 
					v->u.road.state = RVSB_WORMHOLE;
 
					v->vehstatus |= VS_HIDDEN;
 
					return VETSB_ENTERED_WORMHOLE;
 
				} else {
 
					return VETSB_CONTINUE;
 
				}
 
			}
 
@@ -1351,24 +1354,24 @@ static uint32 VehicleEnter_TunnelBridge(
 
			}
 
			if (v->type == VEH_Train) {
 
				v->u.rail.track = TRACK_BIT_WORMHOLE;
 
				CLRBIT(v->u.rail.flags, VRF_GOINGUP);
 
				CLRBIT(v->u.rail.flags, VRF_GOINGDOWN);
 
			} else {
 
				v->u.road.state = 0xFF;
 
				v->u.road.state = RVSB_WORMHOLE;
 
			}
 
			return VETSB_ENTERED_WORMHOLE;
 
		} else if (DirToDiagDir(v->direction) == ReverseDiagDir(dir)) {
 
			v->tile = tile;
 
			if (v->type == VEH_Train) {
 
				if (v->u.rail.track == TRACK_BIT_WORMHOLE) {
 
					v->u.rail.track = (DiagDirToAxis(dir) == AXIS_X ? TRACK_BIT_X : TRACK_BIT_Y);
 
					return VETSB_ENTERED_WORMHOLE;
 
				}
 
			} else {
 
				if (v->u.road.state == 0xFF) {
 
				if (v->u.road.state == RVSB_WORMHOLE) {
 
					v->u.road.state = _road_exit_tunnel_state[dir];
 
					v->u.road.frame = 0;
 
					return VETSB_ENTERED_WORMHOLE;
 
				}
 
			}
 
			return VETSB_CONTINUE;
src/vehicle.cpp
Show inline comments
 
@@ -2521,13 +2521,13 @@ void VehicleEnterDepot(Vehicle *v)
 
			UpdateSignalsOnSegment(v->tile, GetRailDepotDirection(v->tile));
 
			v->load_unload_time_rem = 0;
 
			break;
 

	
 
		case VEH_Road:
 
			InvalidateWindowClasses(WC_ROADVEH_LIST);
 
			v->u.road.state = 254;
 
			v->u.road.state = RVSB_IN_DEPOT;
 
			break;
 

	
 
		case VEH_Ship:
 
			InvalidateWindowClasses(WC_SHIPS_LIST);
 
			v->u.ship.state = TRACK_BIT_DEPOT;
 
			RecalcShipStuff(v);
src/vehicle.h
Show inline comments
 
@@ -24,12 +24,43 @@ enum VehicleEnterTileStatus {
 
	VETSB_CONTINUE         = 0,                          ///< The vehicle can continue normally
 
	VETSB_ENTERED_STATION  = 1 << VETS_ENTERED_STATION,  ///< The vehicle entered a station
 
	VETSB_ENTERED_WORMHOLE = 1 << VETS_ENTERED_WORMHOLE, ///< The vehicle either entered a bridge, tunnel or depot tile (this includes the last tile of the bridge/tunnel)
 
	VETSB_CANNOT_ENTER     = 1 << VETS_CANNOT_ENTER,     ///< The vehicle cannot enter the tile
 
};
 

	
 
/** Road vehicle states */
 
enum RoadVehicleStates {
 
	/*
 
	 * Lower 4 bits are used for vehicle track direction. (Trackdirs)
 
	 * When in a road stop (bit 5 set) these bits give the
 
	 * track direction of the entry to the road stop.
 
	 * As the entry direction will always be a diagonal
 
	 * direction (X_NE, Y_SE, X_SW or Y_NW) only bits 0 and 3
 
	 * are needed to hold this direction. Bit 1 is then used to show
 
	 * that the vehicle is using the second road stop bay.
 
	 */
 

	
 
	/* Numeric values */
 
	RVSB_IN_DEPOT                = 0xFE,                      ///< The vehicle is in a depot
 
	RVSB_WORMHOLE                = 0xFF,                      ///< The vehicle is in a tunnel and/or bridge
 

	
 
	/* Bit numbers */
 
	RVS_USING_SECOND_BAY         =    1,                      ///< Only used while in a road stop
 
	RVS_DRIVE_SIDE               =    4,                      ///< Only used when retrieving move data and for turning vehicles
 
	RVS_IN_ROAD_STOP             =    5,                      ///< The vehicle is in a road stop
 

	
 
	/* Bit sets of the above specified bits */
 
	RVSB_USING_SECOND_BAY        = 1 << RVS_USING_SECOND_BAY, ///< Only used while in a road stop
 
	RVSB_DRIVE_SIDE              = 1 << RVS_DRIVE_SIDE,       ///< Only used when retrieving move data and for turning vehicles
 
	RVSB_IN_ROAD_STOP            = 1 << RVS_IN_ROAD_STOP,     ///< The vehicle is in a road stop
 
	RVSB_IN_ROAD_STOP_END        = RVSB_IN_ROAD_STOP + TRACKDIR_END,
 

	
 
	RVSB_TRACKDIR_MASK           = 0x0F,                      ///< The mask used to extract track dirs
 
	RVSB_ROAD_STOP_TRACKDIR_MASK = 0x09                       ///< Only bits 0 and 3 are used to encode the trackdir for road stops
 
};
 

	
 
enum {
 
	VEH_Train,
 
	VEH_Road,
 
	VEH_Ship,
 
	VEH_Aircraft,
 
	VEH_Special,
 
@@ -133,13 +164,13 @@ typedef struct VehicleAir {
 
	byte previous_pos;
 
	StationID targetairport;
 
	byte state;
 
} VehicleAir;
 

	
 
typedef struct VehicleRoad {
 
	byte state;
 
	byte state;             /// @see RoadVehicleStates
 
	byte frame;
 
	uint16 blocked_ctr;
 
	byte overtaking;
 
	byte overtaking_ctr;
 
	uint16 crashed_ctr;
 
	byte reverse_ctr;
0 comments (0 inline, 0 general)