Skip to content

Commit

Permalink
Change: Extend rail types to 64 (6 bit storage) -- added uint16 to ma…
Browse files Browse the repository at this point in the history
…p array.
  • Loading branch information
PeterN committed May 14, 2018
1 parent fb54dd0 commit 905a947
Show file tree
Hide file tree
Showing 14 changed files with 123 additions and 60 deletions.
2 changes: 1 addition & 1 deletion src/bridge_gui.cpp
Expand Up @@ -55,7 +55,7 @@ typedef GUIList<BuildBridgeData> GUIBridgeList; ///< List of bridges, used in #B
* @param p1 packed start tile coords (~ dx)
* @param p2 various bitstuffed elements
* - p2 = (bit 0- 7) - bridge type (hi bh)
* - p2 = (bit 8-11) - rail type or road types.
* - p2 = (bit 8-13) - rail type or road types.
* - p2 = (bit 15-16) - transport type.
*/
void CcBuildBridge(const CommandCost &result, TileIndex end_tile, uint32 p1, uint32 p2)
Expand Down
3 changes: 2 additions & 1 deletion src/bridge_map.h
Expand Up @@ -131,11 +131,12 @@ static inline void MakeBridgeRamp(TileIndex t, Owner o, BridgeType bridgetype, D
SetTileType(t, MP_TUNNELBRIDGE);
SetTileOwner(t, o);
_m[t].m2 = 0;
_m[t].m3 = rt;
_m[t].m3 = 0;
_m[t].m4 = 0;
_m[t].m5 = 1 << 7 | tt << 2 | d;
SB(_me[t].m6, 2, 4, bridgetype);
_me[t].m7 = 0;
_me[t].m8 = rt;
}

/**
Expand Down
5 changes: 3 additions & 2 deletions src/map_type.h
Expand Up @@ -33,8 +33,9 @@ assert_compile(sizeof(Tile) == 8);
* Look at docs/landscape.html for the exact meaning of the members.
*/
struct TileExtended {
byte m6; ///< General purpose
byte m7; ///< Primarily used for newgrf support
byte m6; ///< General purpose
byte m7; ///< Primarily used for newgrf support
uint16 m8; ///< Extended types.
};

/**
Expand Down
52 changes: 26 additions & 26 deletions src/rail_cmd.cpp
Expand Up @@ -166,19 +166,19 @@ RailType AllocateRailType(RailTypeLabel label)
rti->alternate_labels.Clear();

/* Make us compatible with ourself. */
rti->powered_railtypes = (RailTypes)(1 << rt);
rti->compatible_railtypes = (RailTypes)(1 << rt);
rti->powered_railtypes = (RailTypes)(1LL << rt);
rti->compatible_railtypes = (RailTypes)(1LL << rt);

/* We also introduce ourself. */
rti->introduces_railtypes = (RailTypes)(1 << rt);
rti->introduces_railtypes = (RailTypes)(1LL << rt);

/* Default sort order; order of allocation, but with some
* offsets so it's easier for NewGRF to pick a spot without
* changing the order of other (original) rail types.
* The << is so you can place other railtypes in between the
* other railtypes, the 7 is to be able to place something
* before the first (default) rail type. */
rti->sorting_order = rt << 4 | 7;
rti->sorting_order = rt << 2 | 7;
return rt;
}
}
Expand Down Expand Up @@ -441,7 +441,7 @@ static inline bool ValParamTrackOrientation(Track track)
*/
CommandCost CmdBuildSingleRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
RailType railtype = Extract<RailType, 0, 4>(p1);
RailType railtype = Extract<RailType, 0, 6>(p1);
Track track = Extract<Track, 0, 3>(p2);
CommandCost cost(EXPENSES_CONSTRUCTION);

Expand Down Expand Up @@ -854,19 +854,19 @@ static CommandCost ValidateAutoDrag(Trackdir *trackdir, TileIndex start, TileInd
* @param flags operation to perform
* @param p1 end tile of drag
* @param p2 various bitstuffed elements
* - p2 = (bit 0-3) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev), only used for building
* - p2 = (bit 4-6) - track-orientation, valid values: 0-5 (Track enum)
* - p2 = (bit 7) - 0 = build, 1 = remove tracks
* - p2 = (bit 8) - 0 = build up to an obstacle, 1 = fail if an obstacle is found (used for AIs).
* - p2 = (bit 0-5) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev), only used for building
* - p2 = (bit 8-10) - track-orientation, valid values: 0-5 (Track enum)
* - p2 = (bit 11) - 0 = build, 1 = remove tracks
* - p2 = (bit 12) - 0 = build up to an obstacle, 1 = fail if an obstacle is found (used for AIs).
* @param text unused
* @return the cost of this operation or an error
*/
static CommandCost CmdRailTrackHelper(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
CommandCost total_cost(EXPENSES_CONSTRUCTION);
Track track = Extract<Track, 4, 3>(p2);
bool remove = HasBit(p2, 7);
RailType railtype = Extract<RailType, 0, 4>(p2);
Track track = Extract<Track, 8, 3>(p2);
bool remove = HasBit(p2, 11);
RailType railtype = Extract<RailType, 0, 6>(p2);

if ((!remove && !ValParamRailtype(railtype)) || !ValParamTrackOrientation(track)) return CMD_ERROR;
if (p1 >= MapSize()) return CMD_ERROR;
Expand All @@ -884,7 +884,7 @@ static CommandCost CmdRailTrackHelper(TileIndex tile, DoCommandFlag flags, uint3
if (ret.Failed()) {
last_error = ret;
if (last_error.GetErrorMessage() != STR_ERROR_ALREADY_BUILT && !remove) {
if (HasBit(p2, 8)) return last_error;
if (HasBit(p2, 12)) return last_error;
break;
}

Expand Down Expand Up @@ -914,16 +914,16 @@ static CommandCost CmdRailTrackHelper(TileIndex tile, DoCommandFlag flags, uint3
* @param flags operation to perform
* @param p1 end tile of drag
* @param p2 various bitstuffed elements
* - p2 = (bit 0-3) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev)
* - p2 = (bit 4-6) - track-orientation, valid values: 0-5 (Track enum)
* - p2 = (bit 7) - 0 = build, 1 = remove tracks
* - p2 = (bit 0-5) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev)
* - p2 = (bit 8-10) - track-orientation, valid values: 0-5 (Track enum)
* - p2 = (bit 11) - 0 = build, 1 = remove tracks
* @param text unused
* @return the cost of this operation or an error
* @see CmdRailTrackHelper
*/
CommandCost CmdBuildRailroadTrack(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
return CmdRailTrackHelper(tile, flags, p1, ClrBit(p2, 7), text);
return CmdRailTrackHelper(tile, flags, p1, ClrBit(p2, 11), text);
}

/**
Expand All @@ -933,16 +933,16 @@ CommandCost CmdBuildRailroadTrack(TileIndex tile, DoCommandFlag flags, uint32 p1
* @param flags operation to perform
* @param p1 end tile of drag
* @param p2 various bitstuffed elements
* - p2 = (bit 0-3) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev), only used for building
* - p2 = (bit 4-6) - track-orientation, valid values: 0-5 (Track enum)
* - p2 = (bit 7) - 0 = build, 1 = remove tracks
* - p2 = (bit 0-5) - railroad type normal/maglev (0 = normal, 1 = mono, 2 = maglev), only used for building
* - p2 = (bit 8-10) - track-orientation, valid values: 0-5 (Track enum)
* - p2 = (bit 11) - 0 = build, 1 = remove tracks
* @param text unused
* @return the cost of this operation or an error
* @see CmdRailTrackHelper
*/
CommandCost CmdRemoveRailroadTrack(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
return CmdRailTrackHelper(tile, flags, p1, SetBit(p2, 7), text);
return CmdRailTrackHelper(tile, flags, p1, SetBit(p2, 11), text);
}

/**
Expand All @@ -960,7 +960,7 @@ CommandCost CmdRemoveRailroadTrack(TileIndex tile, DoCommandFlag flags, uint32 p
CommandCost CmdBuildTrainDepot(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
/* check railtype and valid direction for depot (0 through 3), 4 in total */
RailType railtype = Extract<RailType, 0, 4>(p1);
RailType railtype = Extract<RailType, 0, 6>(p1);
if (!ValParamRailtype(railtype)) return CMD_ERROR;

Slope tileh = GetTileSlope(tile);
Expand Down Expand Up @@ -1540,17 +1540,17 @@ static Vehicle *UpdateTrainPowerProc(Vehicle *v, void *data)
* @param flags operation to perform
* @param p1 start tile of drag
* @param p2 various bitstuffed elements:
* - p2 = (bit 0- 3) new railtype to convert to.
* - p2 = (bit 4) build diagonally or not.
* - p2 = (bit 0- 5) new railtype to convert to.
* - p2 = (bit 8) build diagonally or not.
* @param text unused
* @return the cost of this operation or an error
*/
CommandCost CmdConvertRail(TileIndex tile, DoCommandFlag flags, uint32 p1, uint32 p2, const char *text)
{
RailType totype = Extract<RailType, 0, 4>(p2);
RailType totype = Extract<RailType, 0, 6>(p2);
TileIndex area_start = p1;
TileIndex area_end = tile;
bool diagonal = HasBit(p2, 4);
bool diagonal = HasBit(p2, 8);

if (!ValParamRailtype(totype)) return CMD_ERROR;
if (area_start >= MapSize()) return CMD_ERROR;
Expand Down
10 changes: 5 additions & 5 deletions src/rail_gui.cpp
Expand Up @@ -192,7 +192,7 @@ static void PlaceRail_Station(TileIndex tile)
VpStartPlaceSizing(tile, VPM_X_AND_Y_LIMITED, DDSP_BUILD_STATION);
VpSetPlaceSizingLimit(_settings_game.station.station_spread);
} else {
uint32 p1 = _cur_railtype | _railstation.orientation << 4 | _settings_client.gui.station_numtracks << 8 | _settings_client.gui.station_platlength << 16 | _ctrl_pressed << 24;
uint32 p1 = _cur_railtype | _settings_client.gui.station_numtracks << 8 | _settings_client.gui.station_platlength << 16 | _ctrl_pressed << 24 | _railstation.orientation << 25;
uint32 p2 = _railstation.station_class | _railstation.station_type << 8 | INVALID_STATION << 16;

int w = _settings_client.gui.station_numtracks;
Expand Down Expand Up @@ -352,7 +352,7 @@ static void BuildRailClick_Remove(Window *w)

static void DoRailroadTrack(int mode)
{
DoCommandP(TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), _cur_railtype | (mode << 4),
DoCommandP(TileVirtXY(_thd.selstart.x, _thd.selstart.y), TileVirtXY(_thd.selend.x, _thd.selend.y), _cur_railtype | (mode << 8),
_remove_button_clicked ?
CMD_REMOVE_RAILROAD_TRACK | CMD_MSG(STR_ERROR_CAN_T_REMOVE_RAILROAD_TRACK) :
CMD_BUILD_RAILROAD_TRACK | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_TRACK),
Expand Down Expand Up @@ -711,7 +711,7 @@ struct BuildRailToolbarWindow : Window {
break;

case DDSP_CONVERT_RAIL:
DoCommandP(end_tile, start_tile, _cur_railtype | (_ctrl_pressed ? 0x10 : 0), CMD_CONVERT_RAIL | CMD_MSG(STR_ERROR_CAN_T_CONVERT_RAIL), CcPlaySound_SPLAT_RAIL);
DoCommandP(end_tile, start_tile, _cur_railtype | (_ctrl_pressed ? 0x100 : 0), CMD_CONVERT_RAIL | CMD_MSG(STR_ERROR_CAN_T_CONVERT_RAIL), CcPlaySound_SPLAT_RAIL);
break;

case DDSP_REMOVE_STATION:
Expand All @@ -729,7 +729,7 @@ struct BuildRailToolbarWindow : Window {
DoCommandP(end_tile, start_tile, _ctrl_pressed ? 0 : 1, CMD_REMOVE_FROM_RAIL_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_REMOVE_TRAIN_WAYPOINT), CcPlaySound_SPLAT_RAIL);
} else {
TileArea ta(start_tile, end_tile);
uint32 p1 = _cur_railtype | (select_method == VPM_X_LIMITED ? AXIS_X : AXIS_Y) << 4 | ta.w << 8 | ta.h << 16 | _ctrl_pressed << 24;
uint32 p1 = _cur_railtype | (select_method == VPM_X_LIMITED ? AXIS_X : AXIS_Y) << 25 | ta.w << 8 | ta.h << 16 | _ctrl_pressed << 24;
uint32 p2 = STAT_CLASS_WAYP | _cur_waypoint_type << 8 | INVALID_STATION << 16;

CommandContainer cmdcont = { ta.tile, p1, p2, CMD_BUILD_RAIL_WAYPOINT | CMD_MSG(STR_ERROR_CAN_T_BUILD_TRAIN_WAYPOINT), CcPlaySound_SPLAT_RAIL, "" };
Expand Down Expand Up @@ -886,7 +886,7 @@ static void HandleStationPlacement(TileIndex start, TileIndex end)

if (_railstation.orientation == AXIS_X) Swap(numtracks, platlength);

uint32 p1 = _cur_railtype | _railstation.orientation << 4 | numtracks << 8 | platlength << 16 | _ctrl_pressed << 24;
uint32 p1 = _cur_railtype | _railstation.orientation << 25 | numtracks << 8 | platlength << 16 | _ctrl_pressed << 24;
uint32 p2 = _railstation.station_class | _railstation.station_type << 8 | INVALID_STATION << 16;

CommandContainer cmdcont = { ta.tile, p1, p2, CMD_BUILD_RAIL_STATION | CMD_MSG(STR_ERROR_CAN_T_BUILD_RAILROAD_STATION), CcStation, "" };
Expand Down
10 changes: 6 additions & 4 deletions src/rail_map.h
Expand Up @@ -115,7 +115,7 @@ static inline bool IsRailDepotTile(TileIndex t)
*/
static inline RailType GetRailType(TileIndex t)
{
return (RailType)GB(_m[t].m3, 0, 4);
return (RailType)GB(_me[t].m8, 0, 6);
}

/**
Expand All @@ -125,7 +125,7 @@ static inline RailType GetRailType(TileIndex t)
*/
static inline void SetRailType(TileIndex t, RailType r)
{
SB(_m[t].m3, 0, 4, r);
SB(_me[t].m8, 0, 6, r);
}


Expand Down Expand Up @@ -522,11 +522,12 @@ static inline void MakeRailNormal(TileIndex t, Owner o, TrackBits b, RailType r)
SetTileType(t, MP_RAILWAY);
SetTileOwner(t, o);
_m[t].m2 = 0;
_m[t].m3 = r;
_m[t].m3 = 0;
_m[t].m4 = 0;
_m[t].m5 = RAIL_TILE_NORMAL << 6 | b;
SB(_me[t].m6, 2, 4, 0);
_me[t].m7 = 0;
_me[t].m8 = r;
}


Expand All @@ -535,11 +536,12 @@ static inline void MakeRailDepot(TileIndex t, Owner o, DepotID did, DiagDirectio
SetTileType(t, MP_RAILWAY);
SetTileOwner(t, o);
_m[t].m2 = did;
_m[t].m3 = r;
_m[t].m3 = 0;
_m[t].m4 = 0;
_m[t].m5 = RAIL_TILE_DEPOT << 6 | d;
SB(_me[t].m6, 2, 4, 0);
_me[t].m7 = 0;
_me[t].m8 = r;
}

#endif /* RAIL_MAP_H */
18 changes: 9 additions & 9 deletions src/rail_type.h
Expand Up @@ -32,7 +32,7 @@ enum RailType {
RAILTYPE_ELECTRIC = 1, ///< Electric rails
RAILTYPE_MONO = 2, ///< Monorail
RAILTYPE_MAGLEV = 3, ///< Maglev
RAILTYPE_END = 16, ///< Used for iterations
RAILTYPE_END = 64, ///< Used for iterations
INVALID_RAILTYPE = 0xFF, ///< Flag for invalid railtype

DEF_RAILTYPE_FIRST = RAILTYPE_END, ///< Default railtype: first available
Expand All @@ -43,19 +43,19 @@ enum RailType {
/** Allow incrementing of Track variables */
DECLARE_POSTFIX_INCREMENT(RailType)
/** Define basic enum properties */
template <> struct EnumPropsT<RailType> : MakeEnumPropsT<RailType, byte, RAILTYPE_BEGIN, RAILTYPE_END, INVALID_RAILTYPE, 4> {};
template <> struct EnumPropsT<RailType> : MakeEnumPropsT<RailType, byte, RAILTYPE_BEGIN, RAILTYPE_END, INVALID_RAILTYPE, 6> {};
typedef TinyEnumT<RailType> RailTypeByte;

/**
* The different roadtypes we support, but then a bitmask of them
*/
enum RailTypes {
RAILTYPES_NONE = 0, ///< No rail types
RAILTYPES_RAIL = 1 << RAILTYPE_RAIL, ///< Non-electrified rails
RAILTYPES_ELECTRIC = 1 << RAILTYPE_ELECTRIC, ///< Electrified rails
RAILTYPES_MONO = 1 << RAILTYPE_MONO, ///< Monorail!
RAILTYPES_MAGLEV = 1 << RAILTYPE_MAGLEV, ///< Ever fast maglev
INVALID_RAILTYPES = UINT_MAX, ///< Invalid railtypes
enum RailTypes : uint64 {
RAILTYPES_NONE = 0, ///< No rail types
RAILTYPES_RAIL = 1LL << RAILTYPE_RAIL, ///< Non-electrified rails
RAILTYPES_ELECTRIC = 1LL << RAILTYPE_ELECTRIC, ///< Electrified rails
RAILTYPES_MONO = 1LL << RAILTYPE_MONO, ///< Monorail!
RAILTYPES_MAGLEV = 1LL << RAILTYPE_MAGLEV, ///< Ever fast maglev
INVALID_RAILTYPES = UINT64_MAX, ///< Invalid railtypes?
};
DECLARE_ENUM_AS_BIT_SET(RailTypes)

Expand Down
32 changes: 32 additions & 0 deletions src/saveload/afterload.cpp
Expand Up @@ -1214,6 +1214,38 @@ bool AfterLoadGame()
}
}

/* Railtype moved from m3 to m8 in version 199. */
if (IsSavegameVersionBefore(199)) {
for (TileIndex t = 0; t < map_size; t++) {
switch (GetTileType(t)) {
case MP_RAILWAY:
SetRailType(t, (RailType)GB(_m[t].m3, 0, 4));
break;

case MP_ROAD:
if (IsLevelCrossing(t)) {
SetRailType(t, (RailType)GB(_m[t].m3, 0, 4));
}
break;

case MP_STATION:
if (HasStationRail(t)) {
SetRailType(t, (RailType)GB(_m[t].m3, 0, 4));
}
break;

case MP_TUNNELBRIDGE:
if (GetTunnelBridgeTransportType(t) == TRANSPORT_RAIL) {
SetRailType(t, (RailType)GB(_m[t].m3, 0, 4));
}
break;

default:
break;
}
}
}

/* Elrails got added in rev 24 */
if (IsSavegameVersionBefore(24)) {
RailType min_rail = RAILTYPE_ELECTRIC;
Expand Down
2 changes: 1 addition & 1 deletion src/saveload/company_sl.cpp
Expand Up @@ -259,7 +259,7 @@ static const SaveLoad _company_desc[] = {

SLE_VAR(CompanyProperties, colour, SLE_UINT8),
SLE_VAR(CompanyProperties, money_fraction, SLE_UINT8),
SLE_CONDVAR(CompanyProperties, avail_railtypes, SLE_VAR_I32 | SLE_FILE_I8, 0, 57),
SLE_CONDVAR(CompanyProperties, avail_railtypes, SLE_VAR_U64 | SLE_FILE_I8, 0, 57),
SLE_VAR(CompanyProperties, block_preview, SLE_UINT8),

SLE_CONDNULL(2, 0, 93), ///< cargo_types
Expand Down
26 changes: 25 additions & 1 deletion src/saveload/map_sl.cpp
Expand Up @@ -272,6 +272,29 @@ static void Save_MAP7()
}
}

static void Load_MAP8()
{
SmallStackSafeStackAlloc<uint16, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();

for (TileIndex i = 0; i != size;) {
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT16);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m8 = buf[j];
}
}

static void Save_MAP8()
{
SmallStackSafeStackAlloc<uint16, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();

SlSetLength(size * sizeof(uint16));
for (TileIndex i = 0; i != size;) {
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m8;
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT16);
}
}

extern const ChunkHandler _map_chunk_handlers[] = {
{ 'MAPS', Save_MAPS, Load_MAPS, NULL, Check_MAPS, CH_RIFF },
{ 'MAPT', Save_MAPT, Load_MAPT, NULL, NULL, CH_RIFF },
Expand All @@ -282,5 +305,6 @@ extern const ChunkHandler _map_chunk_handlers[] = {
{ 'M3HI', Save_MAP4, Load_MAP4, NULL, NULL, CH_RIFF },
{ 'MAP5', Save_MAP5, Load_MAP5, NULL, NULL, CH_RIFF },
{ 'MAPE', Save_MAP6, Load_MAP6, NULL, NULL, CH_RIFF },
{ 'MAP7', Save_MAP7, Load_MAP7, NULL, NULL, CH_RIFF | CH_LAST },
{ 'MAP7', Save_MAP7, Load_MAP7, NULL, NULL, CH_RIFF },
{ 'MAP8', Save_MAP8, Load_MAP8, NULL, NULL, CH_RIFF | CH_LAST },
};

0 comments on commit 905a947

Please sign in to comment.