(svn r14828) -Codechange: move most of save/load-specific code to separate files

pull/155/head
smatz 16 years ago
parent e62e12e7f5
commit 91233ea596

@ -647,10 +647,6 @@
RelativePath=".\..\src\npf.cpp"
>
</File>
<File
RelativePath=".\..\src\oldloader.cpp"
>
</File>
<File
RelativePath=".\..\src\oldpool.cpp"
>
@ -691,10 +687,6 @@
RelativePath=".\..\src\road.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload.cpp"
>
</File>
<File
RelativePath=".\..\src\screenshot.cpp"
>
@ -1043,6 +1035,10 @@
RelativePath=".\..\src\gamelog.h"
>
</File>
<File
RelativePath=".\..\src\gamelog_internal.h"
>
</File>
<File
RelativePath=".\..\src\genworld.h"
>
@ -1359,10 +1355,6 @@
RelativePath=".\..\src\roadveh.h"
>
</File>
<File
RelativePath=".\..\src\saveload.h"
>
</File>
<File
RelativePath=".\..\src\screenshot.h"
>
@ -2008,6 +2000,122 @@
>
</File>
</Filter>
<Filter
Name="Save/Load handlers"
>
<File
RelativePath=".\..\src\saveload\afterload.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\ai_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\animated_tile_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\autoreplace_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\cargopacket_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\cheat_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\company_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\depot_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\economy_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\engine_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\gamelog_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\group_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\industry_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\map_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\misc_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\newgrf_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\oldloader.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\order_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\saveload.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\saveload.h"
>
</File>
<File
RelativePath=".\..\src\saveload\saveload_internal.h"
>
</File>
<File
RelativePath=".\..\src\saveload\signs_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\station_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\strings_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\subsidy_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\town_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\vehicle_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\waypoint_sl.cpp"
>
</File>
</Filter>
<Filter
Name="Tables"
>

@ -644,10 +644,6 @@
RelativePath=".\..\src\npf.cpp"
>
</File>
<File
RelativePath=".\..\src\oldloader.cpp"
>
</File>
<File
RelativePath=".\..\src\oldpool.cpp"
>
@ -688,10 +684,6 @@
RelativePath=".\..\src\road.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload.cpp"
>
</File>
<File
RelativePath=".\..\src\screenshot.cpp"
>
@ -1040,6 +1032,10 @@
RelativePath=".\..\src\gamelog.h"
>
</File>
<File
RelativePath=".\..\src\gamelog_internal.h"
>
</File>
<File
RelativePath=".\..\src\genworld.h"
>
@ -1356,10 +1352,6 @@
RelativePath=".\..\src\roadveh.h"
>
</File>
<File
RelativePath=".\..\src\saveload.h"
>
</File>
<File
RelativePath=".\..\src\screenshot.h"
>
@ -2005,6 +1997,122 @@
>
</File>
</Filter>
<Filter
Name="Save/Load handlers"
>
<File
RelativePath=".\..\src\saveload\afterload.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\ai_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\animated_tile_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\autoreplace_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\cargopacket_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\cheat_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\company_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\depot_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\economy_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\engine_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\gamelog_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\group_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\industry_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\map_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\misc_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\newgrf_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\oldloader.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\order_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\saveload.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\saveload.h"
>
</File>
<File
RelativePath=".\..\src\saveload\saveload_internal.h"
>
</File>
<File
RelativePath=".\..\src\saveload\signs_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\station_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\strings_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\subsidy_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\town_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\vehicle_sl.cpp"
>
</File>
<File
RelativePath=".\..\src\saveload\waypoint_sl.cpp"
>
</File>
</Filter>
<Filter
Name="Tables"
>

@ -50,7 +50,6 @@ network/network_gamelist.cpp
network/network_server.cpp
network/network_udp.cpp
npf.cpp
oldloader.cpp
oldpool.cpp
openttd.cpp
os_timer.cpp
@ -66,7 +65,6 @@ queue.cpp
rail.cpp
rev.cpp
road.cpp
saveload.cpp
screenshot.cpp
#if SDL
sdl.cpp
@ -193,6 +191,7 @@ fios.h
fontcache.h
functions.h
gamelog.h
gamelog_internal.h
genworld.h
gfx_func.h
gfx_type.h
@ -272,7 +271,6 @@ road_gui.h
road_internal.h
road_type.h
roadveh.h
saveload.h
screenshot.h
sdl.h
sound/sdl_s.h
@ -452,6 +450,36 @@ tunnelbridge_cmd.cpp
unmovable_cmd.cpp
water_cmd.cpp
# Save/Load handlers
saveload/afterload.cpp
saveload/ai_sl.cpp
saveload/animated_tile_sl.cpp
saveload/autoreplace_sl.cpp
saveload/cargopacket_sl.cpp
saveload/cheat_sl.cpp
saveload/company_sl.cpp
saveload/depot_sl.cpp
saveload/economy_sl.cpp
saveload/engine_sl.cpp
saveload/gamelog_sl.cpp
saveload/group_sl.cpp
saveload/industry_sl.cpp
saveload/map_sl.cpp
saveload/misc_sl.cpp
saveload/newgrf_sl.cpp
saveload/oldloader.cpp
saveload/order_sl.cpp
saveload/saveload.cpp
saveload/saveload.h
saveload/saveload_internal.h
saveload/signs_sl.cpp
saveload/station_sl.cpp
saveload/strings_sl.cpp
saveload/subsidy_sl.cpp
saveload/town_sl.cpp
saveload/vehicle_sl.cpp
saveload/waypoint_sl.cpp
# Tables
table/ai_rail.h
table/animcursors.h

@ -25,7 +25,6 @@
#include "../../window_func.h"
#include "../../vehicle_func.h"
#include "../../functions.h"
#include "../../saveload.h"
#include "../../company_func.h"
#include "../../company_base.h"
#include "../../settings_type.h"
@ -4027,74 +4026,3 @@ void AiDoGameLoop(Company *c)
_ai_actions[_companies_ai[c->index].state](c);
}
static const SaveLoad _company_ai_desc[] = {
SLE_VAR(CompanyAI, state, SLE_UINT8),
SLE_VAR(CompanyAI, tick, SLE_UINT8),
SLE_CONDVAR(CompanyAI, state_counter, SLE_FILE_U16 | SLE_VAR_U32, 0, 12),
SLE_CONDVAR(CompanyAI, state_counter, SLE_UINT32, 13, SL_MAX_VERSION),
SLE_VAR(CompanyAI, timeout_counter, SLE_UINT16),
SLE_VAR(CompanyAI, state_mode, SLE_UINT8),
SLE_VAR(CompanyAI, banned_tile_count, SLE_UINT8),
SLE_VAR(CompanyAI, railtype_to_use, SLE_UINT8),
SLE_VAR(CompanyAI, cargo_type, SLE_UINT8),
SLE_VAR(CompanyAI, num_wagons, SLE_UINT8),
SLE_VAR(CompanyAI, build_kind, SLE_UINT8),
SLE_VAR(CompanyAI, num_build_rec, SLE_UINT8),
SLE_VAR(CompanyAI, num_loco_to_build, SLE_UINT8),
SLE_VAR(CompanyAI, num_want_fullload, SLE_UINT8),
SLE_VAR(CompanyAI, route_type_mask, SLE_UINT8),
SLE_CONDVAR(CompanyAI, start_tile_a, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(CompanyAI, start_tile_a, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(CompanyAI, cur_tile_a, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(CompanyAI, cur_tile_a, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_VAR(CompanyAI, start_dir_a, SLE_UINT8),
SLE_VAR(CompanyAI, cur_dir_a, SLE_UINT8),
SLE_CONDVAR(CompanyAI, start_tile_b, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(CompanyAI, start_tile_b, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(CompanyAI, cur_tile_b, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(CompanyAI, cur_tile_b, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_VAR(CompanyAI, start_dir_b, SLE_UINT8),
SLE_VAR(CompanyAI, cur_dir_b, SLE_UINT8),
SLE_REF(CompanyAI, cur_veh, REF_VEHICLE),
SLE_ARR(CompanyAI, wagon_list, SLE_UINT16, 9),
SLE_ARR(CompanyAI, order_list_blocks, SLE_UINT8, 20),
SLE_ARR(CompanyAI, banned_tiles, SLE_UINT16, 16),
SLE_CONDNULL(64, 2, SL_MAX_VERSION),
SLE_END()
};
static const SaveLoad _company_ai_build_rec_desc[] = {
SLE_CONDVAR(AiBuildRec, spec_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(AiBuildRec, spec_tile, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(AiBuildRec, use_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(AiBuildRec, use_tile, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_VAR(AiBuildRec, rand_rng, SLE_UINT8),
SLE_VAR(AiBuildRec, cur_building_rule, SLE_UINT8),
SLE_VAR(AiBuildRec, unk6, SLE_UINT8),
SLE_VAR(AiBuildRec, unk7, SLE_UINT8),
SLE_VAR(AiBuildRec, buildcmd_a, SLE_UINT8),
SLE_VAR(AiBuildRec, buildcmd_b, SLE_UINT8),
SLE_VAR(AiBuildRec, direction, SLE_UINT8),
SLE_VAR(AiBuildRec, cargo, SLE_UINT8),
SLE_END()
};
void SaveLoad_AI(CompanyID company)
{
CompanyAI *cai = &_companies_ai[company];
SlObject(cai, _company_ai_desc);
for (int i = 0; i != cai->num_build_rec; i++) {
SlObject(&cai->src + i, _company_ai_build_rec_desc);
}
}

@ -10,7 +10,6 @@
#include "../../rail_type.h"
void AiDoGameLoop(Company *c);
void SaveLoad_AI(CompanyID company);
struct AiBuildRec {
TileIndex spec_tile;

@ -10,6 +10,7 @@
#include "../../vehicle_type.h"
#include "../../date_type.h"
#include "../../engine_type.h"
#include "../../direction_type.h"
/*
* These defines can be altered to change the behavoir of the AI

@ -99,6 +99,11 @@ void UpdateAirplanesOnNewStation(const Station *st);
*/
void UpdateAircraftCache(Vehicle *v);
void AircraftLeaveHangar(Vehicle *v);
void AircraftNextAirportPos_and_Order(Vehicle *v);
void SetAircraftPosition(Vehicle *v, int x, int y, int z);
byte GetAircraftFlyingAltitude(const Vehicle *v);
/**
* This class 'wraps' Vehicle; you do not actually instantiate this class.
* You create a Vehicle using AllocateVehicle, so it is added to the pool

@ -82,9 +82,6 @@ static bool AirportFindFreeTerminal(Vehicle *v, const AirportFTAClass *apc);
static bool AirportFindFreeHelipad(Vehicle *v, const AirportFTAClass *apc);
static void CrashAirplane(Vehicle *v);
void AircraftNextAirportPos_and_Order(Vehicle *v);
static byte GetAircraftFlyingAltitude(const Vehicle *v);
static const SpriteID _aircraft_sprite[] = {
0x0EB5, 0x0EBD, 0x0EC5, 0x0ECD,
0x0ED5, 0x0EDD, 0x0E9D, 0x0EA5,
@ -727,7 +724,7 @@ static void HelicopterTickHandler(Vehicle *v)
EndVehicleMove(u);
}
static void SetAircraftPosition(Vehicle *v, int x, int y, int z)
void SetAircraftPosition(Vehicle *v, int x, int y, int z)
{
v->x_pos = x;
v->y_pos = y;
@ -883,7 +880,7 @@ static int UpdateAircraftSpeed(Vehicle *v, uint speed_limit = SPEED_LIMIT_NONE,
* @param v The vehicle. Should be an aircraft
* @returns Altitude in pixel units
*/
static byte GetAircraftFlyingAltitude(const Vehicle *v)
byte GetAircraftFlyingAltitude(const Vehicle *v)
{
/* Make sure Aircraft fly no lower so that they don't conduct
* CFITs (controlled flight into terrain)
@ -1433,7 +1430,7 @@ void AircraftNextAirportPos_and_Order(Vehicle *v)
v->u.air.pos = v->u.air.previous_pos = AircraftGetEntryPoint(v, apc);
}
static void AircraftLeaveHangar(Vehicle *v)
void AircraftLeaveHangar(Vehicle *v)
{
v->cur_speed = 0;
v->subspeed = 0;
@ -2096,42 +2093,6 @@ Station *GetTargetAirportIfValid(const Vehicle *v)
return st->airport_tile == INVALID_TILE ? NULL : st;
}
/** need to be called to load aircraft from old version */
void UpdateOldAircraft()
{
/* set airport_flags to 0 for all airports just to be sure */
Station *st;
FOR_ALL_STATIONS(st) {
st->airport_flags = 0; // reset airport
}
Vehicle *v_oldstyle;
FOR_ALL_VEHICLES(v_oldstyle) {
/* airplane has another vehicle with subtype 4 (shadow), helicopter also has 3 (rotor)
* skip those */
if (v_oldstyle->type == VEH_AIRCRAFT && IsNormalAircraft(v_oldstyle)) {
/* airplane in terminal stopped doesn't hurt anyone, so goto next */
if (v_oldstyle->vehstatus & VS_STOPPED && v_oldstyle->u.air.state == 0) {
v_oldstyle->u.air.state = HANGAR;
continue;
}
AircraftLeaveHangar(v_oldstyle); // make airplane visible if it was in a depot for example
v_oldstyle->vehstatus &= ~VS_STOPPED; // make airplane moving
v_oldstyle->u.air.state = FLYING;
AircraftNextAirportPos_and_Order(v_oldstyle); // move it to the entry point of the airport
GetNewVehiclePosResult gp = GetNewVehiclePos(v_oldstyle);
v_oldstyle->tile = 0; // aircraft in air is tile=0
/* correct speed of helicopter-rotors */
if (v_oldstyle->subtype == AIR_HELICOPTER) v_oldstyle->Next()->Next()->cur_speed = 32;
/* set new position x,y,z */
SetAircraftPosition(v_oldstyle, gp.x, gp.y, GetAircraftFlyingAltitude(v_oldstyle));
}
}
}
/**
* Updates the status of the Aircraft heading or in the station
* @param st Station been updated

@ -4,7 +4,6 @@
#include "stdafx.h"
#include "openttd.h"
#include "saveload.h"
#include "landscape.h"
#include "core/alloc_func.hpp"
#include "functions.h"
@ -14,7 +13,7 @@ TileIndex *_animated_tile_list = NULL;
/** The number of animated tiles in the current state. */
uint _animated_tile_count = 0;
/** The number of slots for animated tiles allocated currently. */
static uint _animated_tile_allocated = 0;
uint _animated_tile_allocated = 0;
/**
* Removes the given tile from the animated tile table.
@ -90,46 +89,3 @@ void InitializeAnimatedTiles()
_animated_tile_count = 0;
_animated_tile_allocated = 256;
}
/**
* Save the ANIT chunk.
*/
static void Save_ANIT()
{
SlSetLength(_animated_tile_count * sizeof(*_animated_tile_list));
SlArray(_animated_tile_list, _animated_tile_count, SLE_UINT32);
}
/**
* Load the ANIT chunk; the chunk containing the animated tiles.
*/
static void Load_ANIT()
{
/* Before version 80 we did NOT have a variable length animated tile table */
if (CheckSavegameVersion(80)) {
/* In pre version 6, we has 16bit per tile, now we have 32bit per tile, convert it ;) */
SlArray(_animated_tile_list, 256, CheckSavegameVersion(6) ? (SLE_FILE_U16 | SLE_VAR_U32) : SLE_UINT32);
for (_animated_tile_count = 0; _animated_tile_count < 256; _animated_tile_count++) {
if (_animated_tile_list[_animated_tile_count] == 0) break;
}
return;
}
_animated_tile_count = (uint)SlGetFieldLength() / sizeof(*_animated_tile_list);
/* Determine a nice rounded size for the amount of allocated tiles */
_animated_tile_allocated = 256;
while (_animated_tile_allocated < _animated_tile_count) _animated_tile_allocated *= 2;
_animated_tile_list = ReallocT<TileIndex>(_animated_tile_list, _animated_tile_allocated);
SlArray(_animated_tile_list, _animated_tile_count, SLE_UINT32);
}
/**
* "Definition" imported by the saveload code to be able to load and save
* the animated tile table.
*/
extern const ChunkHandler _animated_tile_chunk_handlers[] = {
{ 'ANIT', Save_ANIT, Load_ANIT, CH_RIFF | CH_LAST},
};

@ -6,7 +6,6 @@
#include "openttd.h"
#include "debug.h"
#include "command_func.h"
#include "saveload.h"
#include "group.h"
#include "autoreplace_base.h"
#include "oldpool_func.h"
@ -102,46 +101,6 @@ CommandCost RemoveEngineReplacement(EngineRenewList *erl, EngineID engine, Group
return CMD_ERROR;
}
static const SaveLoad _engine_renew_desc[] = {
SLE_VAR(EngineRenew, from, SLE_UINT16),
SLE_VAR(EngineRenew, to, SLE_UINT16),
SLE_REF(EngineRenew, next, REF_ENGINE_RENEWS),
SLE_CONDVAR(EngineRenew, group_id, SLE_UINT16, 60, SL_MAX_VERSION),
SLE_END()
};
static void Save_ERNW()
{
EngineRenew *er;
FOR_ALL_ENGINE_RENEWS(er) {
SlSetArrayIndex(er->index);
SlObject(er, _engine_renew_desc);
}
}
static void Load_ERNW()
{
int index;
while ((index = SlIterateArray()) != -1) {
EngineRenew *er = new (index) EngineRenew();
SlObject(er, _engine_renew_desc);
/* Advanced vehicle lists, ungrouped vehicles got added */
if (CheckSavegameVersion(60)) {
er->group_id = ALL_GROUP;
} else if (CheckSavegameVersion(71)) {
if (er->group_id == DEFAULT_GROUP) er->group_id = ALL_GROUP;
}
}
}
extern const ChunkHandler _autoreplace_chunk_handlers[] = {
{ 'ERNW', Save_ERNW, Load_ERNW, CH_ARRAY | CH_LAST},
};
void InitializeEngineRenews()
{
/* Clean the engine renew pool and create 1 block in it */

@ -3,10 +3,8 @@
/** @file cargopacket.cpp Implementation of the cargo packets */
#include "stdafx.h"
#include "openttd.h"
#include "station_base.h"
#include "cargopacket.h"
#include "saveload.h"
#include "oldpool_func.h"
/* Initialize the cargopacket-pool */
@ -43,42 +41,6 @@ bool CargoPacket::SameSource(const CargoPacket *cp) const
return this->source_xy == cp->source_xy && this->days_in_transit == cp->days_in_transit && this->paid_for == cp->paid_for;
}
static const SaveLoad _cargopacket_desc[] = {
SLE_VAR(CargoPacket, source, SLE_UINT16),
SLE_VAR(CargoPacket, source_xy, SLE_UINT32),
SLE_VAR(CargoPacket, loaded_at_xy, SLE_UINT32),
SLE_VAR(CargoPacket, count, SLE_UINT16),
SLE_VAR(CargoPacket, days_in_transit, SLE_UINT8),
SLE_VAR(CargoPacket, feeder_share, SLE_INT64),
SLE_VAR(CargoPacket, paid_for, SLE_BOOL),
SLE_END()
};
static void Save_CAPA()
{
CargoPacket *cp;
FOR_ALL_CARGOPACKETS(cp) {
SlSetArrayIndex(cp->index);
SlObject(cp, _cargopacket_desc);
}
}
static void Load_CAPA()
{
int index;
while ((index = SlIterateArray()) != -1) {
CargoPacket *cp = new (index) CargoPacket();
SlObject(cp, _cargopacket_desc);
}
}
extern const ChunkHandler _cargopacket_chunk_handlers[] = {
{ 'CAPA', Save_CAPA, Load_CAPA, CH_ARRAY | CH_LAST},
};
/*
*
* Cargo list implementation

@ -3,7 +3,6 @@
/** @file cheat.cpp Handling (loading/saving/initializing) of cheats. */
#include "stdafx.h"
#include "saveload.h"
#include "cheat_type.h"
Cheats _cheats;
@ -13,31 +12,6 @@ void InitializeCheats()
memset(&_cheats, 0, sizeof(Cheats));
}
static void Save_CHTS()
{
/* Cannot use lengthof because _cheats is of type Cheats, not Cheat */
byte count = sizeof(_cheats) / sizeof(Cheat);
Cheat *cht = (Cheat*) &_cheats;
Cheat *cht_last = &cht[count];
SlSetLength(count * 2);
for (; cht != cht_last; cht++) {
SlWriteByte(cht->been_used);
SlWriteByte(cht->value);
}
}
static void Load_CHTS()
{
Cheat *cht = (Cheat*)&_cheats;
size_t count = SlGetFieldLength() / 2;
for (uint i = 0; i < count; i++) {
cht[i].been_used = (SlReadByte() != 0);
cht[i].value = (SlReadByte() != 0);
}
}
bool CheatHasBeenUsed()
{
/* Cannot use lengthof because _cheats is of type Cheats, not Cheat */
@ -50,8 +24,3 @@ bool CheatHasBeenUsed()
return false;
}
extern const ChunkHandler _cheat_chunk_handlers[] = {
{ 'CHTS', Save_CHTS, Load_CHTS, CH_RIFF | CH_LAST}
};

@ -10,7 +10,7 @@
#include "company_func.h"
#include "gfx_func.h"
#include "date_func.h"
#include "saveload.h"
#include "saveload/saveload.h"
#include "window_gui.h"
#include "newgrf.h"
#include "settings_type.h"

@ -10,7 +10,6 @@
#include "company_gui.h"
#include "town.h"
#include "news_func.h"
#include "saveload.h"
#include "command_func.h"
#include "network/network.h"
#include "network/network_func.h"
@ -110,74 +109,6 @@ void DrawCompanyIcon(CompanyID c, int x, int y)
DrawSprite(SPR_PLAYER_ICON, COMPANY_SPRITE_COLOR(c), x, y);
}
/**
* Converts an old company manager's face format to the new company manager's face format
*
* Meaning of the bits in the old face (some bits are used in several times):
* - 4 and 5: chin
* - 6 to 9: eyebrows
* - 10 to 13: nose
* - 13 to 15: lips (also moustache for males)
* - 16 to 19: hair
* - 20 to 22: eye color
* - 20 to 27: tie, ear rings etc.
* - 28 to 30: glasses
* - 19, 26 and 27: race (bit 27 set and bit 19 equal to bit 26 = black, otherwise white)
* - 31: gender (0 = male, 1 = female)
*
* @param face the face in the old format
* @return the face in the new format
*/
CompanyManagerFace ConvertFromOldCompanyManagerFace(uint32 face)
{
CompanyManagerFace cmf = 0;
GenderEthnicity ge = GE_WM;
if (HasBit(face, 31)) SetBit(ge, GENDER_FEMALE);
if (HasBit(face, 27) && (HasBit(face, 26) == HasBit(face, 19))) SetBit(ge, ETHNICITY_BLACK);
SetCompanyManagerFaceBits(cmf, CMFV_GEN_ETHN, ge, ge);
SetCompanyManagerFaceBits(cmf, CMFV_HAS_GLASSES, ge, GB(face, 28, 3) <= 1);
SetCompanyManagerFaceBits(cmf, CMFV_EYE_COLOUR, ge, HasBit(ge, ETHNICITY_BLACK) ? 0 : ClampU(GB(face, 20, 3), 5, 7) - 5);
SetCompanyManagerFaceBits(cmf, CMFV_CHIN, ge, ScaleCompanyManagerFaceValue(CMFV_CHIN, ge, GB(face, 4, 2)));
SetCompanyManagerFaceBits(cmf, CMFV_EYEBROWS, ge, ScaleCompanyManagerFaceValue(CMFV_EYEBROWS, ge, GB(face, 6, 4)));
SetCompanyManagerFaceBits(cmf, CMFV_HAIR, ge, ScaleCompanyManagerFaceValue(CMFV_HAIR, ge, GB(face, 16, 4)));
SetCompanyManagerFaceBits(cmf, CMFV_JACKET, ge, ScaleCompanyManagerFaceValue(CMFV_JACKET, ge, GB(face, 20, 2)));
SetCompanyManagerFaceBits(cmf, CMFV_COLLAR, ge, ScaleCompanyManagerFaceValue(CMFV_COLLAR, ge, GB(face, 22, 2)));
SetCompanyManagerFaceBits(cmf, CMFV_GLASSES, ge, GB(face, 28, 1));
uint lips = GB(face, 10, 4);
if (!HasBit(ge, GENDER_FEMALE) && lips < 4) {
SetCompanyManagerFaceBits(cmf, CMFV_HAS_MOUSTACHE, ge, true);
SetCompanyManagerFaceBits(cmf, CMFV_MOUSTACHE, ge, max(lips, 1U) - 1);
} else {
if (!HasBit(ge, GENDER_FEMALE)) {
lips = lips * 15 / 16;
lips -= 3;
if (HasBit(ge, ETHNICITY_BLACK) && lips > 8) lips = 0;
} else {
lips = ScaleCompanyManagerFaceValue(CMFV_LIPS, ge, lips);
}
SetCompanyManagerFaceBits(cmf, CMFV_LIPS, ge, lips);
uint nose = GB(face, 13, 3);
if (ge == GE_WF) {
nose = (nose * 3 >> 3) * 3 >> 2; // There is 'hole' in the nose sprites for females
} else {
nose = ScaleCompanyManagerFaceValue(CMFV_NOSE, ge, nose);
}
SetCompanyManagerFaceBits(cmf, CMFV_NOSE, ge, nose);
}
uint tie_earring = GB(face, 24, 4);
if (!HasBit(ge, GENDER_FEMALE) || tie_earring < 3) { // Not all females have an earring
if (HasBit(ge, GENDER_FEMALE)) SetCompanyManagerFaceBits(cmf, CMFV_HAS_TIE_EARRING, ge, true);
SetCompanyManagerFaceBits(cmf, CMFV_TIE_EARRING, ge, HasBit(ge, GENDER_FEMALE) ? tie_earring : ScaleCompanyManagerFaceValue(CMFV_TIE_EARRING, ge, tie_earring / 2));
}
return cmf;
}
/**
* Checks whether a company manager's face is a valid encoding.
* Unused bits are not enforced to be 0.
@ -936,159 +867,3 @@ CommandCost CmdCompanyCtrl(TileIndex tile, uint32 flags, uint32 p1, uint32 p2, c
return CommandCost();
}
/* Save/load of companies */
static const SaveLoad _company_desc[] = {
SLE_VAR(Company, name_2, SLE_UINT32),
SLE_VAR(Company, name_1, SLE_STRINGID),
SLE_CONDSTR(Company, name, SLE_STR, 0, 84, SL_MAX_VERSION),
SLE_VAR(Company, president_name_1, SLE_UINT16),
SLE_VAR(Company, president_name_2, SLE_UINT32),
SLE_CONDSTR(Company, president_name, SLE_STR, 0, 84, SL_MAX_VERSION),
SLE_VAR(Company, face, SLE_UINT32),
/* money was changed to a 64 bit field in savegame version 1. */
SLE_CONDVAR(Company, money, SLE_VAR_I64 | SLE_FILE_I32, 0, 0),
SLE_CONDVAR(Company, money, SLE_INT64, 1, SL_MAX_VERSION),
SLE_CONDVAR(Company, current_loan, SLE_VAR_I64 | SLE_FILE_I32, 0, 64),
SLE_CONDVAR(Company, current_loan, SLE_INT64, 65, SL_MAX_VERSION),
SLE_VAR(Company, colour, SLE_UINT8),
SLE_VAR(Company, money_fraction, SLE_UINT8),
SLE_CONDVAR(Company, avail_railtypes, SLE_UINT8, 0, 57),
SLE_VAR(Company, block_preview, SLE_UINT8),
SLE_CONDVAR(Company, cargo_types, SLE_FILE_U16 | SLE_VAR_U32, 0, 93),
SLE_CONDVAR(Company, cargo_types, SLE_UINT32, 94, SL_MAX_VERSION),
SLE_CONDVAR(Company, location_of_HQ, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Company, location_of_HQ, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Company, last_build_coordinate, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Company, last_build_coordinate, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Company, inaugurated_year, SLE_FILE_U8 | SLE_VAR_I32, 0, 30),
SLE_CONDVAR(Company, inaugurated_year, SLE_INT32, 31, SL_MAX_VERSION),
SLE_ARR(Company, share_owners, SLE_UINT8, 4),
SLE_VAR(Company, num_valid_stat_ent, SLE_UINT8),
SLE_VAR(Company, quarters_of_bankrupcy, SLE_UINT8),
SLE_CONDVAR(Company, bankrupt_asked, SLE_FILE_U8 | SLE_VAR_U16, 0, 103),
SLE_CONDVAR(Company, bankrupt_asked, SLE_UINT16, 104, SL_MAX_VERSION),
SLE_VAR(Company, bankrupt_timeout, SLE_INT16),
SLE_CONDVAR(Company, bankrupt_value, SLE_VAR_I64 | SLE_FILE_I32, 0, 64),
SLE_CONDVAR(Company, bankrupt_value, SLE_INT64, 65, SL_MAX_VERSION),
/* yearly expenses was changed to 64-bit in savegame version 2. */
SLE_CONDARR(Company, yearly_expenses, SLE_FILE_I32 | SLE_VAR_I64, 3 * 13, 0, 1),
SLE_CONDARR(Company, yearly_expenses, SLE_INT64, 3 * 13, 2, SL_MAX_VERSION),
SLE_CONDVAR(Company, is_ai, SLE_BOOL, 2, SL_MAX_VERSION),
SLE_CONDNULL(1, 4, 99),
/* Engine renewal settings */
SLE_CONDNULL(512, 16, 18),
SLE_CONDREF(Company, engine_renew_list, REF_ENGINE_RENEWS, 19, SL_MAX_VERSION),
SLE_CONDVAR(Company, engine_renew, SLE_BOOL, 16, SL_MAX_VERSION),
SLE_CONDVAR(Company, engine_renew_months, SLE_INT16, 16, SL_MAX_VERSION),
SLE_CONDVAR(Company, engine_renew_money, SLE_UINT32, 16, SL_MAX_VERSION),
SLE_CONDVAR(Company, renew_keep_length, SLE_BOOL, 2, SL_MAX_VERSION), // added with 16.1, but was blank since 2
/* reserve extra space in savegame here. (currently 63 bytes) */
SLE_CONDNULL(63, 2, SL_MAX_VERSION),
SLE_END()
};
static const SaveLoad _company_economy_desc[] = {
/* these were changed to 64-bit in savegame format 2 */
SLE_CONDVAR(CompanyEconomyEntry, income, SLE_FILE_I32 | SLE_VAR_I64, 0, 1),
SLE_CONDVAR(CompanyEconomyEntry, income, SLE_INT64, 2, SL_MAX_VERSION),
SLE_CONDVAR(CompanyEconomyEntry, expenses, SLE_FILE_I32 | SLE_VAR_I64, 0, 1),
SLE_CONDVAR(CompanyEconomyEntry, expenses, SLE_INT64, 2, SL_MAX_VERSION),
SLE_CONDVAR(CompanyEconomyEntry, company_value, SLE_FILE_I32 | SLE_VAR_I64, 0, 1),
SLE_CONDVAR(CompanyEconomyEntry, company_value, SLE_INT64, 2, SL_MAX_VERSION),
SLE_VAR(CompanyEconomyEntry, delivered_cargo, SLE_INT32),
SLE_VAR(CompanyEconomyEntry, performance_history, SLE_INT32),
SLE_END()
};
static const SaveLoad _company_livery_desc[] = {
SLE_CONDVAR(Livery, in_use, SLE_BOOL, 34, SL_MAX_VERSION),
SLE_CONDVAR(Livery, colour1, SLE_UINT8, 34, SL_MAX_VERSION),
SLE_CONDVAR(Livery, colour2, SLE_UINT8, 34, SL_MAX_VERSION),
SLE_END()
};
static void SaveLoad_PLYR(Company *c)
{
int i;
SlObject(c, _company_desc);
/* Write AI? */
if (!IsHumanCompany(c->index)) {
SaveLoad_AI(c->index);
}
/* Write economy */
SlObject(&c->cur_economy, _company_economy_desc);
/* Write old economy entries. */
for (i = 0; i < c->num_valid_stat_ent; i++) {
SlObject(&c->old_economy[i], _company_economy_desc);
}
/* Write each livery entry. */
int num_liveries = CheckSavegameVersion(63) ? LS_END - 4 : (CheckSavegameVersion(85) ? LS_END - 2: LS_END);
for (i = 0; i < num_liveries; i++) {
SlObject(&c->livery[i], _company_livery_desc);
}
if (num_liveries < LS_END) {
/* We want to insert some liveries somewhere in between. This means some have to be moved. */
memmove(&c->livery[LS_FREIGHT_WAGON], &c->livery[LS_PASSENGER_WAGON_MONORAIL], (LS_END - LS_FREIGHT_WAGON) * sizeof(c->livery[0]));
c->livery[LS_PASSENGER_WAGON_MONORAIL] = c->livery[LS_MONORAIL];
c->livery[LS_PASSENGER_WAGON_MAGLEV] = c->livery[LS_MAGLEV];
}
if (num_liveries == LS_END - 4) {
/* Copy bus/truck liveries over to trams */
c->livery[LS_PASSENGER_TRAM] = c->livery[LS_BUS];
c->livery[LS_FREIGHT_TRAM] = c->livery[LS_TRUCK];
}
}
static void Save_PLYR()
{
Company *c;
FOR_ALL_COMPANIES(c) {
SlSetArrayIndex(c->index);
SlAutolength((AutolengthProc*)SaveLoad_PLYR, c);
}
}
static void Load_PLYR()
{
int index;
while ((index = SlIterateArray()) != -1) {
Company *c = new (index) Company();
SaveLoad_PLYR(c);
_company_colours[index] = c->colour;
/* This is needed so an AI is attached to a loaded AI */
if (c->is_ai && (!_networking || _network_server) && _ai.enabled) {
/* Clear the memory of the new AI, otherwise we might be doing wrong things. */
memset(&_companies_ainew[index], 0, sizeof(CompanyAiNew));
AI_StartNewAI(c->index);
}
}
}
extern const ChunkHandler _company_chunk_handlers[] = {
{ 'PLYR', Save_PLYR, Load_PLYR, CH_ARRAY | CH_LAST},
};

@ -7,6 +7,8 @@
#include "core/random_func.hpp"
#include "core/bitmath_func.hpp"
#include "table/sprites.h"
#include "company_type.h"
/** The gender/race combinations that we have faces for */
enum GenderEthnicity {
@ -228,7 +230,6 @@ static inline SpriteID GetCompanyManagerFaceSprite(CompanyManagerFace cmf, Compa
}
void DrawCompanyManagerFace(CompanyManagerFace face, int color, int x, int y);
CompanyManagerFace ConvertFromOldCompanyManagerFace(uint32 face);
bool IsValidCompanyManagerFace(CompanyManagerFace cmf);
#endif /* COMPANY_MANAGER_FACE_H */

@ -8,7 +8,7 @@
#include "debug.h"
#include "engine_func.h"
#include "landscape.h"
#include "saveload.h"
#include "saveload/saveload.h"
#include "variables.h"
#include "network/network.h"
#include "network/network_func.h"

@ -15,7 +15,7 @@
#include "vehicle_base.h"
#include "debug.h"
#include "rail_gui.h"
#include "saveload.h"
#include "saveload/saveload.h"
Year _cur_year; ///< Current year, starting at 0
Month _cur_month; ///< Current month (0..11)

@ -3,10 +3,8 @@
/** @file depot.cpp Handling of depots. */
#include "stdafx.h"
#include "openttd.h"
#include "depot_base.h"
#include "landscape.h"
#include "saveload.h"
#include "order_func.h"
#include "window_func.h"
#include "oldpool_func.h"
@ -51,35 +49,3 @@ void InitializeDepots()
_Depot_pool.CleanPool();
_Depot_pool.AddBlockToPool();
}
static const SaveLoad _depot_desc[] = {
SLE_CONDVAR(Depot, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Depot, xy, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_VAR(Depot, town_index, SLE_UINT16),
SLE_END()
};
static void Save_DEPT()
{
Depot *depot;
FOR_ALL_DEPOTS(depot) {
SlSetArrayIndex(depot->index);
SlObject(depot, _depot_desc);
}
}
static void Load_DEPT()
{
int index;
while ((index = SlIterateArray()) != -1) {
Depot *depot = new (index) Depot();
SlObject(depot, _depot_desc);
}
}
extern const ChunkHandler _depot_chunk_handlers[] = {
{ 'DEPT', Save_DEPT, Load_DEPT, CH_ARRAY | CH_LAST},
};

@ -9,7 +9,6 @@
#include "company_base.h"
#include "company_func.h"
#include "command_func.h"
#include "saveload.h"
#include "industry.h"
#include "industry_map.h"
#include "town.h"
@ -767,7 +766,7 @@ void SetPriceBaseMultiplier(uint price, byte factor)
* Initialize the variables that will maintain the daily industry change system.
* @param init_counter specifies if the counter is required to be initialized
*/
static void StartupIndustryDailyChanges(bool init_counter)
void StartupIndustryDailyChanges(bool init_counter)
{
uint map_size = MapLogX() + MapLogY();
/* After getting map size, it needs to be scaled appropriately and divided by 31,
@ -1121,37 +1120,6 @@ no_add:;
InvalidateWindow(WC_SUBSIDIES_LIST, 0);
}
static const SaveLoad _subsidies_desc[] = {
SLE_VAR(Subsidy, cargo_type, SLE_UINT8),
SLE_VAR(Subsidy, age, SLE_UINT8),
SLE_CONDVAR(Subsidy, from, SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
SLE_CONDVAR(Subsidy, from, SLE_UINT16, 5, SL_MAX_VERSION),
SLE_CONDVAR(Subsidy, to, SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
SLE_CONDVAR(Subsidy, to, SLE_UINT16, 5, SL_MAX_VERSION),
SLE_END()
};
static void Save_SUBS()
{
int i;
Subsidy *s;
for (i = 0; i != lengthof(_subsidies); i++) {
s = &_subsidies[i];
if (s->cargo_type != CT_INVALID) {
SlSetArrayIndex(i);
SlObject(s, _subsidies_desc);
}
}
}
static void Load_SUBS()
{
int index;
while ((index = SlIterateArray()) != -1)
SlObject(&_subsidies[index], _subsidies_desc);
}
Money GetTransportedGoodsIncome(uint num_pieces, uint dist, byte transit_days, CargoID cargo_type)
{
const CargoSpec *cs = GetCargo(cargo_type);
@ -1994,54 +1962,3 @@ CommandCost CmdBuyCompany(TileIndex tile, uint32 flags, uint32 p1, uint32 p2, co
}
return CommandCost(EXPENSES_OTHER, c->bankrupt_value);
}
/** Prices */
static void SaveLoad_PRIC()
{
int vt = CheckSavegameVersion(65) ? (SLE_FILE_I32 | SLE_VAR_I64) : SLE_INT64;
SlArray(&_price, NUM_PRICES, vt);
SlArray(&_price_frac, NUM_PRICES, SLE_UINT16);
}
/** Cargo payment rates */
static void SaveLoad_CAPR()
{
uint num_cargo = CheckSavegameVersion(55) ? 12 : NUM_CARGO;
int vt = CheckSavegameVersion(65) ? (SLE_FILE_I32 | SLE_VAR_I64) : SLE_INT64;
SlArray(&_cargo_payment_rates, num_cargo, vt);
SlArray(&_cargo_payment_rates_frac, num_cargo, SLE_UINT16);
}
static const SaveLoad _economy_desc[] = {
SLE_CONDVAR(Economy, max_loan, SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
SLE_CONDVAR(Economy, max_loan, SLE_INT64, 65, SL_MAX_VERSION),
SLE_CONDVAR(Economy, max_loan_unround, SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
SLE_CONDVAR(Economy, max_loan_unround, SLE_INT64, 65, SL_MAX_VERSION),
SLE_CONDVAR(Economy, max_loan_unround_fract, SLE_UINT16, 70, SL_MAX_VERSION),
SLE_VAR(Economy, fluct, SLE_INT16),
SLE_VAR(Economy, interest_rate, SLE_UINT8),
SLE_VAR(Economy, infl_amount, SLE_UINT8),
SLE_VAR(Economy, infl_amount_pr, SLE_UINT8),
SLE_CONDVAR(Economy, industry_daily_change_counter, SLE_UINT32, 102, SL_MAX_VERSION),
SLE_END()
};
/** Economy variables */
static void Save_ECMY()
{
SlObject(&_economy, _economy_desc);
}
/** Economy variables */
static void Load_ECMY()
{
SlObject(&_economy, _economy_desc);
StartupIndustryDailyChanges(CheckSavegameVersion(102)); // old savegames will need to be initialized
}
extern const ChunkHandler _economy_chunk_handlers[] = {
{ 'PRIC', SaveLoad_PRIC, SaveLoad_PRIC, CH_RIFF | CH_AUTO_LENGTH},
{ 'CAPR', SaveLoad_CAPR, SaveLoad_CAPR, CH_RIFF | CH_AUTO_LENGTH},
{ 'SUBS', Save_SUBS, Load_SUBS, CH_ARRAY},
{ 'ECMY', Save_ECMY, Load_ECMY, CH_RIFF | CH_LAST},
};

@ -34,6 +34,7 @@ Pair SetupSubsidyDecodeParam(const Subsidy *s, bool mode);
void DeleteSubsidyWithTown(TownID index);
void DeleteSubsidyWithIndustry(IndustryID index);
void DeleteSubsidyWithStation(StationID index);
void StartupIndustryDailyChanges(bool init_counter);
Money GetTransportedGoodsIncome(uint num_pieces, uint dist, byte transit_days, CargoID cargo_type);
uint MoveGoodsToStation(TileIndex tile, int w, int h, CargoID type, uint amount);

@ -15,7 +15,6 @@
#include "gfx_func.h"
#include "news_func.h"
#include "command_func.h"
#include "saveload.h"
#include "company_func.h"
#include "debug.h"
#include "vehicle_gui.h"

@ -9,7 +9,6 @@
#include "company_func.h"
#include "command_func.h"
#include "news_func.h"
#include "saveload.h"
#include "variables.h"
#include "train.h"
#include "aircraft.h"
@ -27,7 +26,6 @@
#include "oldpool_func.h"
#include "core/alloc_func.hpp"
#include "vehicle_func.h"
#include <map>
#include "table/strings.h"
#include "table/engines.h"
@ -613,112 +611,3 @@ CargoID GetEngineCargoType(EngineID engine)
default: NOT_REACHED(); return CT_INVALID;
}
}
static const SaveLoad _engine_desc[] = {
SLE_CONDVAR(Engine, intro_date, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
SLE_CONDVAR(Engine, intro_date, SLE_INT32, 31, SL_MAX_VERSION),
SLE_CONDVAR(Engine, age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
SLE_CONDVAR(Engine, age, SLE_INT32, 31, SL_MAX_VERSION),
SLE_VAR(Engine, reliability, SLE_UINT16),
SLE_VAR(Engine, reliability_spd_dec, SLE_UINT16),
SLE_VAR(Engine, reliability_start, SLE_UINT16),
SLE_VAR(Engine, reliability_max, SLE_UINT16),
SLE_VAR(Engine, reliability_final, SLE_UINT16),
SLE_VAR(Engine, duration_phase_1, SLE_UINT16),
SLE_VAR(Engine, duration_phase_2, SLE_UINT16),
SLE_VAR(Engine, duration_phase_3, SLE_UINT16),
SLE_VAR(Engine, lifelength, SLE_UINT8),
SLE_VAR(Engine, flags, SLE_UINT8),
SLE_VAR(Engine, preview_company_rank,SLE_UINT8),
SLE_VAR(Engine, preview_wait, SLE_UINT8),
SLE_CONDNULL(1, 0, 44),
SLE_CONDVAR(Engine, company_avail, SLE_FILE_U8 | SLE_VAR_U16, 0, 103),
SLE_CONDVAR(Engine, company_avail, SLE_UINT16, 104, SL_MAX_VERSION),
SLE_CONDSTR(Engine, name, SLE_STR, 0, 84, SL_MAX_VERSION),
/* reserve extra space in savegame here. (currently 16 bytes) */
SLE_CONDNULL(16, 2, SL_MAX_VERSION),
SLE_END()
};
static std::map<EngineID, Engine> _temp_engine;
Engine *GetTempDataEngine(EngineID index)
{
return &_temp_engine[index];
}
static void Save_ENGN()
{
Engine *e;
FOR_ALL_ENGINES(e) {
SlSetArrayIndex(e->index);
SlObject(e, _engine_desc);
}
}
static void Load_ENGN()
{
/* As engine data is loaded before engines are initialized we need to load
* this information into a temporary array. This is then copied into the
* engine pool after processing NewGRFs by CopyTempEngineData(). */
int index;
while ((index = SlIterateArray()) != -1) {
Engine *e = GetTempDataEngine(index);
SlObject(e, _engine_desc);
}
}
/**
* Copy data from temporary engine array into the real engine pool.
*/
void CopyTempEngineData()
{
Engine *e;
FOR_ALL_ENGINES(e) {
if (e->index >= _temp_engine.size()) break;
const Engine *se = GetTempDataEngine(e->index);
e->intro_date = se->intro_date;
e->age = se->age;
e->reliability = se->reliability;
e->reliability_spd_dec = se->reliability_spd_dec;
e->reliability_start = se->reliability_start;
e->reliability_max = se->reliability_max;
e->reliability_final = se->reliability_final;
e->duration_phase_1 = se->duration_phase_1;
e->duration_phase_2 = se->duration_phase_2;
e->duration_phase_3 = se->duration_phase_3;
e->lifelength = se->lifelength;
e->flags = se->flags;
e->preview_company_rank= se->preview_company_rank;
e->preview_wait = se->preview_wait;
e->company_avail = se->company_avail;
if (se->name != NULL) e->name = strdup(se->name);
}
/* Get rid of temporary data */
_temp_engine.clear();
}
static void Load_ENGS()
{
/* Load old separate String ID list into a temporary array. This
* was always 256 entries. */
StringID names[256];
SlArray(names, lengthof(names), SLE_STRINGID);
/* Copy each string into the temporary engine array. */
for (EngineID engine = 0; engine < lengthof(names); engine++) {
Engine *e = GetTempDataEngine(engine);
e->name = CopyFromOldName(names[engine]);
}
}
extern const ChunkHandler _engine_chunk_handlers[] = {
{ 'ENGN', Save_ENGN, Load_ENGN, CH_ARRAY },
{ 'ENGS', NULL, Load_ENGS, CH_RIFF | CH_LAST },
};

@ -4,7 +4,7 @@
#include "stdafx.h"
#include "openttd.h"
#include "saveload.h"
#include "saveload/saveload.h"
#include "core/alloc_func.hpp"
#include "core/bitmath_func.hpp"
#include "core/math_func.hpp"
@ -13,13 +13,15 @@
#include "string_func.h"
#include "settings_type.h"
#include "newgrf_config.h"
#include <string.h>
#include <stdarg.h>
#include "gamelog.h"
#include "gamelog_internal.h"
#include "console_func.h"
#include "debug.h"
#include "rev.h"
#include <string.h>
#include <stdarg.h>
extern const uint16 SAVEGAME_VERSION; ///< current savegame version
extern SavegameType _savegame_type; ///< type of savegame we are loading
@ -28,79 +30,11 @@ extern uint32 _ttdp_version; ///< version of TTDP savegame (if applicable)
extern uint16 _sl_version; ///< the major savegame version identifier
extern byte _sl_minor_version; ///< the minor savegame version, DO NOT USE!
/** Type of logged change */
enum GamelogChangeType {
GLCT_MODE, ///< Scenario editor x Game, different landscape
GLCT_REVISION, ///< Changed game revision string
GLCT_OLDVER, ///< Loaded from savegame without logged data
GLCT_PATCH, ///< Non-networksafe patch value changed
GLCT_GRFADD, ///< Removed GRF
GLCT_GRFREM, ///< Added GRF
GLCT_GRFCOMPAT, ///< Loading compatible GRF
GLCT_GRFPARAM, ///< GRF parameter changed
GLCT_GRFMOVE, ///< GRF order changed
GLCT_GRFBUG, ///< GRF bug triggered
GLCT_END, ///< So we know how many GLCTs are there
GLCT_NONE = 0xFF, ///< In savegames, end of list
};
/** Contains information about one logged change */
struct LoggedChange {
GamelogChangeType ct; ///< Type of change logged in this struct
union {
struct {
byte mode; ///< new game mode - Editor x Game
byte landscape; ///< landscape (temperate, arctic, ...)
} mode;
struct {
char text[NETWORK_REVISION_LENGTH]; ///< revision string, _openttd_revision
uint32 newgrf; ///< _openttd_newgrf_version
uint16 slver; ///< _sl_version
byte modified; ///< _openttd_revision_modified
} revision;
struct {
uint32 type; ///< type of savegame, @see SavegameType
uint32 version; ///< major and minor version OR ttdp version
} oldver;
GRFIdentifier grfadd; ///< ID and md5sum of added GRF
struct {
uint32 grfid; ///< ID of removed GRF
} grfrem;
GRFIdentifier grfcompat; ///< ID and new md5sum of changed GRF
struct {
uint32 grfid; ///< ID of GRF with changed parameters
} grfparam;
struct {
uint32 grfid; ///< ID of moved GRF
int32 offset; ///< offset, positive = move down
} grfmove;
struct {
char *name; ///< name of the patch
int32 oldval; ///< old value
int32 newval; ///< new value
} patch;
struct {
uint64 data; ///< additional data
uint32 grfid; ///< ID of problematic GRF
byte bug; ///< type of bug, @see enum GRFBugs
} grfbug;
};
};
/** Contains information about one logged action that caused at least one logged change */
struct LoggedAction {
LoggedChange *change; ///< First logged change in this action
uint32 changes; ///< Number of changes in this action
GamelogActionType at; ///< Type of action
uint16 tick; ///< Tick when it happened
};
static GamelogActionType _gamelog_action_type = GLAT_NONE; ///< action to record if anything changes
static LoggedAction *_gamelog_action = NULL; ///< first logged action
static uint _gamelog_actions = 0; ///< number of actions
LoggedAction *_gamelog_action = NULL; ///< first logged action
uint _gamelog_actions = 0; ///< number of actions
static LoggedAction *_current_action = NULL; ///< current action we are logging, NULL when there is no action active
@ -728,155 +662,3 @@ void GamelogGRFUpdate(const GRFConfig *oldc, const GRFConfig *newc)
free(ol);
free(nl);
}
static const SaveLoad _glog_action_desc[] = {
SLE_VAR(LoggedAction, tick, SLE_UINT16),
SLE_END()
};
static const SaveLoad _glog_mode_desc[] = {
SLE_VAR(LoggedChange, mode.mode, SLE_UINT8),
SLE_VAR(LoggedChange, mode.landscape, SLE_UINT8),
SLE_END()
};
static const SaveLoad _glog_revision_desc[] = {
SLE_ARR(LoggedChange, revision.text, SLE_UINT8, NETWORK_REVISION_LENGTH),
SLE_VAR(LoggedChange, revision.newgrf, SLE_UINT32),
SLE_VAR(LoggedChange, revision.slver, SLE_UINT16),
SLE_VAR(LoggedChange, revision.modified, SLE_UINT8),
SLE_END()
};
static const SaveLoad _glog_oldver_desc[] = {
SLE_VAR(LoggedChange, oldver.type, SLE_UINT32),
SLE_VAR(LoggedChange, oldver.version, SLE_UINT32),
SLE_END()
};
static const SaveLoad _glog_patch_desc[] = {
SLE_STR(LoggedChange, patch.name, SLE_STR, 128),
SLE_VAR(LoggedChange, patch.oldval, SLE_INT32),
SLE_VAR(LoggedChange, patch.newval, SLE_INT32),
SLE_END()
};
static const SaveLoad _glog_grfadd_desc[] = {
SLE_VAR(LoggedChange, grfadd.grfid, SLE_UINT32 ),
SLE_ARR(LoggedChange, grfadd.md5sum, SLE_UINT8, 16),
SLE_END()
};
static const SaveLoad _glog_grfrem_desc[] = {
SLE_VAR(LoggedChange, grfrem.grfid, SLE_UINT32),
SLE_END()
};
static const SaveLoad _glog_grfcompat_desc[] = {
SLE_VAR(LoggedChange, grfcompat.grfid, SLE_UINT32 ),
SLE_ARR(LoggedChange, grfcompat.md5sum, SLE_UINT8, 16),
SLE_END()
};
static const SaveLoad _glog_grfparam_desc[] = {
SLE_VAR(LoggedChange, grfparam.grfid, SLE_UINT32),
SLE_END()
};
static const SaveLoad _glog_grfmove_desc[] = {
SLE_VAR(LoggedChange, grfmove.grfid, SLE_UINT32),
SLE_VAR(LoggedChange, grfmove.offset, SLE_INT32),
SLE_END()
};
static const SaveLoad _glog_grfbug_desc[] = {
SLE_VAR(LoggedChange, grfbug.data, SLE_UINT64),
SLE_VAR(LoggedChange, grfbug.grfid, SLE_UINT32),
SLE_VAR(LoggedChange, grfbug.bug, SLE_UINT8),
SLE_END()
};
static const SaveLoad *_glog_desc[] = {
_glog_mode_desc,
_glog_revision_desc,
_glog_oldver_desc,
_glog_patch_desc,
_glog_grfadd_desc,
_glog_grfrem_desc,
_glog_grfcompat_desc,
_glog_grfparam_desc,
_glog_grfmove_desc,
_glog_grfbug_desc,
};
assert_compile(lengthof(_glog_desc) == GLCT_END);
static void Load_GLOG()
{
assert(_gamelog_action == NULL);
assert(_gamelog_actions == 0);
GamelogActionType at;
while ((at = (GamelogActionType)SlReadByte()) != GLAT_NONE) {
_gamelog_action = ReallocT(_gamelog_action, _gamelog_actions + 1);
LoggedAction *la = &_gamelog_action[_gamelog_actions++];
la->at = at;
SlObject(la, _glog_action_desc); // has to be saved after 'DATE'!
la->change = NULL;
la->changes = 0;
GamelogChangeType ct;
while ((ct = (GamelogChangeType)SlReadByte()) != GLCT_NONE) {
la->change = ReallocT(la->change, la->changes + 1);
LoggedChange *lc = &la->change[la->changes++];
/* for SLE_STR, pointer has to be valid! so make it NULL */
memset(lc, 0, sizeof(*lc));
lc->ct = ct;
assert((uint)ct < GLCT_END);
SlObject(lc, _glog_desc[ct]);
}
}
}
static void Save_GLOG()
{
const LoggedAction *laend = &_gamelog_action[_gamelog_actions];
size_t length = 0;
for (const LoggedAction *la = _gamelog_action; la != laend; la++) {
const LoggedChange *lcend = &la->change[la->changes];
for (LoggedChange *lc = la->change; lc != lcend; lc++) {
assert((uint)lc->ct < lengthof(_glog_desc));
length += SlCalcObjLength(lc, _glog_desc[lc->ct]) + 1;
}
length += 4;
}
length++;
SlSetLength(length);
for (LoggedAction *la = _gamelog_action; la != laend; la++) {
SlWriteByte(la->at);
SlObject(la, _glog_action_desc);
const LoggedChange *lcend = &la->change[la->changes];
for (LoggedChange *lc = la->change; lc != lcend; lc++) {
SlWriteByte(lc->ct);
assert((uint)lc->ct < GLCT_END);
SlObject(lc, _glog_desc[lc->ct]);
}
SlWriteByte(GLCT_NONE);
}
SlWriteByte(GLAT_NONE);
}
extern const ChunkHandler _gamelog_chunk_handlers[] = {
{ 'GLOG', Save_GLOG, Load_GLOG, CH_RIFF | CH_LAST }
};

@ -0,0 +1,82 @@
/* $Id$ */
/** @file gamelog_internal.h Declaration shared among gamelog.cpp and saveload/gamelog_sl.cpp */
#ifndef GAMELOG_INTERNAL_H
#define GAMELOG_INTERNAL_H
#include "network/core/config.h"
/** Type of logged change */
enum GamelogChangeType {
GLCT_MODE, ///< Scenario editor x Game, different landscape
GLCT_REVISION, ///< Changed game revision string
GLCT_OLDVER, ///< Loaded from savegame without logged data
GLCT_PATCH, ///< Non-networksafe patch value changed
GLCT_GRFADD, ///< Removed GRF
GLCT_GRFREM, ///< Added GRF
GLCT_GRFCOMPAT, ///< Loading compatible GRF
GLCT_GRFPARAM, ///< GRF parameter changed
GLCT_GRFMOVE, ///< GRF order changed
GLCT_GRFBUG, ///< GRF bug triggered
GLCT_END, ///< So we know how many GLCTs are there
GLCT_NONE = 0xFF, ///< In savegames, end of list
};
/** Contains information about one logged change */
struct LoggedChange {
GamelogChangeType ct; ///< Type of change logged in this struct
union {
struct {
byte mode; ///< new game mode - Editor x Game
byte landscape; ///< landscape (temperate, arctic, ...)
} mode;
struct {
char text[NETWORK_REVISION_LENGTH]; ///< revision string, _openttd_revision
uint32 newgrf; ///< _openttd_newgrf_version
uint16 slver; ///< _sl_version
byte modified; ///< _openttd_revision_modified
} revision;
struct {
uint32 type; ///< type of savegame, @see SavegameType
uint32 version; ///< major and minor version OR ttdp version
} oldver;
GRFIdentifier grfadd; ///< ID and md5sum of added GRF
struct {
uint32 grfid; ///< ID of removed GRF
} grfrem;
GRFIdentifier grfcompat; ///< ID and new md5sum of changed GRF
struct {
uint32 grfid; ///< ID of GRF with changed parameters
} grfparam;
struct {
uint32 grfid; ///< ID of moved GRF
int32 offset; ///< offset, positive = move down
} grfmove;
struct {
char *name; ///< name of the patch
int32 oldval; ///< old value
int32 newval; ///< new value
} patch;
struct {
uint64 data; ///< additional data
uint32 grfid; ///< ID of problematic GRF
byte bug; ///< type of bug, @see enum GRFBugs
} grfbug;
};
};
/** Contains information about one logged action that caused at least one logged change */
struct LoggedAction {
LoggedChange *change; ///< First logged change in this action
uint32 changes; ///< Number of changes in this action
GamelogActionType at; ///< Type of action
uint16 tick; ///< Tick when it happened
};
extern LoggedAction *_gamelog_action;
extern uint _gamelog_actions;
#endif /* GAMELOG_INTERNAL_H */

@ -26,7 +26,7 @@
#include "newgrf_storage.h"
#include "water.h"
#include "tilehighlight_func.h"
#include "saveload.h"
#include "saveload/saveload.h"
#include "table/sprites.h"

@ -6,7 +6,6 @@
#include "openttd.h"
#include "variables.h"
#include "command_func.h"
#include "saveload.h"
#include "debug.h"
#include "group.h"
#include "train.h"
@ -421,40 +420,3 @@ void RemoveAllGroupsForCompany(const CompanyID company)
if (company == g->owner) delete g;
}
}
static const SaveLoad _group_desc[] = {
SLE_CONDVAR(Group, name, SLE_NAME, 0, 83),
SLE_CONDSTR(Group, name, SLE_STR, 0, 84, SL_MAX_VERSION),
SLE_VAR(Group, num_vehicle, SLE_UINT16),
SLE_VAR(Group, owner, SLE_UINT8),
SLE_VAR(Group, vehicle_type, SLE_UINT8),
SLE_VAR(Group, replace_protection, SLE_BOOL),
SLE_END()
};
static void Save_GROUP(void)
{
Group *g;
FOR_ALL_GROUPS(g) {
SlSetArrayIndex(g->index);
SlObject(g, _group_desc);
}
}
static void Load_GROUP(void)
{
int index;
while ((index = SlIterateArray()) != -1) {
Group *g = new (index) Group();
SlObject(g, _group_desc);
}
}
extern const ChunkHandler _group_chunk_handlers[] = {
{ 'GRPS', Save_GROUP, Load_GROUP, CH_ARRAY | CH_LAST},
};

@ -10,7 +10,7 @@
#include "void_map.h"
#include "debug.h"
#include "gui.h"
#include "saveload.h"
#include "saveload/saveload.h"
#include "bmp.h"
#include "gfx_func.h"
#include "core/alloc_func.hpp"

@ -14,7 +14,6 @@
#include "industry.h"
#include "town.h"
#include "news_func.h"
#include "saveload.h"
#include "variables.h"
#include "cheat_func.h"
#include "genworld.h"
@ -2397,146 +2396,3 @@ extern const TileTypeProcs _tile_type_industry_procs = {
GetFoundation_Industry, /* get_foundation_proc */
TerraformTile_Industry, /* terraform_tile_proc */
};
static const SaveLoad _industry_desc[] = {
SLE_CONDVAR(Industry, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Industry, xy, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_VAR(Industry, width, SLE_UINT8),
SLE_VAR(Industry, height, SLE_UINT8),
SLE_REF(Industry, town, REF_TOWN),
SLE_CONDNULL( 2, 0, 60), ///< used to be industry's produced_cargo
SLE_CONDARR(Industry, produced_cargo, SLE_UINT8, 2, 78, SL_MAX_VERSION),
SLE_CONDARR(Industry, incoming_cargo_waiting, SLE_UINT16, 3, 70, SL_MAX_VERSION),
SLE_ARR(Industry, produced_cargo_waiting, SLE_UINT16, 2),
SLE_ARR(Industry, production_rate, SLE_UINT8, 2),
SLE_CONDNULL( 3, 0, 60), ///< used to be industry's accepts_cargo
SLE_CONDARR(Industry, accepts_cargo, SLE_UINT8, 3, 78, SL_MAX_VERSION),
SLE_VAR(Industry, prod_level, SLE_UINT8),
SLE_ARR(Industry, this_month_production, SLE_UINT16, 2),
SLE_ARR(Industry, this_month_transported, SLE_UINT16, 2),
SLE_ARR(Industry, last_month_pct_transported, SLE_UINT8, 2),
SLE_ARR(Industry, last_month_production, SLE_UINT16, 2),
SLE_ARR(Industry, last_month_transported, SLE_UINT16, 2),
SLE_VAR(Industry, counter, SLE_UINT16),
SLE_VAR(Industry, type, SLE_UINT8),
SLE_VAR(Industry, owner, SLE_UINT8),
SLE_VAR(Industry, random_color, SLE_UINT8),
SLE_CONDVAR(Industry, last_prod_year, SLE_FILE_U8 | SLE_VAR_I32, 0, 30),
SLE_CONDVAR(Industry, last_prod_year, SLE_INT32, 31, SL_MAX_VERSION),
SLE_VAR(Industry, was_cargo_delivered, SLE_UINT8),
SLE_CONDVAR(Industry, founder, SLE_UINT8, 70, SL_MAX_VERSION),
SLE_CONDVAR(Industry, construction_date, SLE_INT32, 70, SL_MAX_VERSION),
SLE_CONDVAR(Industry, construction_type, SLE_UINT8, 70, SL_MAX_VERSION),
SLE_CONDVAR(Industry, last_cargo_accepted_at, SLE_INT32, 70, SL_MAX_VERSION),
SLE_CONDVAR(Industry, selected_layout, SLE_UINT8, 73, SL_MAX_VERSION),
SLE_CONDARRX(cpp_offsetof(Industry, psa) + cpp_offsetof(Industry::PersistentStorage, storage), SLE_UINT32, 16, 76, SL_MAX_VERSION),
SLE_CONDVAR(Industry, random_triggers, SLE_UINT8, 82, SL_MAX_VERSION),
SLE_CONDVAR(Industry, random, SLE_UINT16, 82, SL_MAX_VERSION),
/* reserve extra space in savegame here. (currently 32 bytes) */
SLE_CONDNULL(32, 2, SL_MAX_VERSION),
SLE_END()
};
static void Save_INDY()
{
Industry *ind;
/* Write the industries */
FOR_ALL_INDUSTRIES(ind) {
SlSetArrayIndex(ind->index);
SlObject(ind, _industry_desc);
}
}
/* Save and load the mapping between the industry/tile id on the map, and the grf file
* it came from. */
static const SaveLoad _industries_id_mapping_desc[] = {
SLE_VAR(EntityIDMapping, grfid, SLE_UINT32),
SLE_VAR(EntityIDMapping, entity_id, SLE_UINT8),
SLE_VAR(EntityIDMapping, substitute_id, SLE_UINT8),
SLE_END()
};
static void Save_IIDS()
{
uint i;
uint j = _industry_mngr.GetMaxMapping();
for (i = 0; i < j; i++) {
SlSetArrayIndex(i);
SlObject(&_industry_mngr.mapping_ID[i], _industries_id_mapping_desc);
}
}
static void Save_TIDS()
{
uint i;
uint j = _industile_mngr.GetMaxMapping();
for (i = 0; i < j; i++) {
SlSetArrayIndex(i);
SlObject(&_industile_mngr.mapping_ID[i], _industries_id_mapping_desc);
}
}
static void Load_INDY()
{
int index;
ResetIndustryCounts();
while ((index = SlIterateArray()) != -1) {
Industry *i = new (index) Industry();
SlObject(i, _industry_desc);
IncIndustryTypeCount(i->type);
}
}
static void Load_IIDS()
{
int index;
uint max_id;
/* clear the current mapping stored.
* This will create the manager if ever it is not yet done */
_industry_mngr.ResetMapping();
/* get boundary for the temporary map loader NUM_INDUSTRYTYPES? */
max_id = _industry_mngr.GetMaxMapping();
while ((index = SlIterateArray()) != -1) {
if ((uint)index >= max_id) break;
SlObject(&_industry_mngr.mapping_ID[index], _industries_id_mapping_desc);
}
}
static void Load_TIDS()
{
int index;
uint max_id;
/* clear the current mapping stored.
* This will create the manager if ever it is not yet done */
_industile_mngr.ResetMapping();
/* get boundary for the temporary map loader NUM_INDUSTILES? */
max_id = _industile_mngr.GetMaxMapping();
while ((index = SlIterateArray()) != -1) {
if ((uint)index >= max_id) break;
SlObject(&_industile_mngr.mapping_ID[index], _industries_id_mapping_desc);
}
}
extern const ChunkHandler _industry_chunk_handlers[] = {
{ 'INDY', Save_INDY, Load_INDY, CH_ARRAY},
{ 'IIDS', Save_IIDS, Load_IIDS, CH_ARRAY},
{ 'TIDS', Save_TIDS, Load_TIDS, CH_ARRAY | CH_LAST},
};

@ -7,7 +7,6 @@
#include "currency.h"
#include "landscape.h"
#include "news_func.h"
#include "saveload.h"
#include "vehicle_gui.h"
#include "variables.h"
#include "cheat_func.h"
@ -134,290 +133,3 @@ void InitializeLandscapeVariables(bool only_constants)
_cargo_payment_rates_frac[i] = 0;
}
}
static const SaveLoadGlobVarList _date_desc[] = {
SLEG_CONDVAR(_date, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
SLEG_CONDVAR(_date, SLE_INT32, 31, SL_MAX_VERSION),
SLEG_VAR(_date_fract, SLE_UINT16),
SLEG_VAR(_tick_counter, SLE_UINT16),
SLEG_VAR(_vehicle_id_ctr_day, SLE_UINT16),
SLEG_VAR(_age_cargo_skip_counter, SLE_UINT8),
SLE_CONDNULL(1, 0, 45),
SLEG_CONDVAR(_cur_tileloop_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLEG_CONDVAR(_cur_tileloop_tile, SLE_UINT32, 6, SL_MAX_VERSION),
SLEG_VAR(_disaster_delay, SLE_UINT16),
SLEG_VAR(_station_tick_ctr, SLE_UINT16),
SLEG_VAR(_random.state[0], SLE_UINT32),
SLEG_VAR(_random.state[1], SLE_UINT32),
SLEG_CONDVAR(_cur_town_ctr, SLE_FILE_U8 | SLE_VAR_U32, 0, 9),
SLEG_CONDVAR(_cur_town_ctr, SLE_UINT32, 10, SL_MAX_VERSION),
SLEG_VAR(_cur_company_tick_index, SLE_FILE_U8 | SLE_VAR_U32),
SLEG_VAR(_next_competitor_start, SLE_FILE_U16 | SLE_VAR_U32),
SLEG_VAR(_trees_tick_ctr, SLE_UINT8),
SLEG_CONDVAR(_pause_game, SLE_UINT8, 4, SL_MAX_VERSION),
SLEG_CONDVAR(_cur_town_iter, SLE_UINT32, 11, SL_MAX_VERSION),
SLEG_END()
};
/* Save load date related variables as well as persistent tick counters
* XXX: currently some unrelated stuff is just put here */
static void SaveLoad_DATE()
{
SlGlobList(_date_desc);
}
static const SaveLoadGlobVarList _view_desc[] = {
SLEG_CONDVAR(_saved_scrollpos_x, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
SLEG_CONDVAR(_saved_scrollpos_x, SLE_INT32, 6, SL_MAX_VERSION),
SLEG_CONDVAR(_saved_scrollpos_y, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
SLEG_CONDVAR(_saved_scrollpos_y, SLE_INT32, 6, SL_MAX_VERSION),
SLEG_VAR(_saved_scrollpos_zoom, SLE_UINT8),
SLEG_END()
};
static void SaveLoad_VIEW()
{
SlGlobList(_view_desc);
}
static uint32 _map_dim_x;
static uint32 _map_dim_y;
static const SaveLoadGlobVarList _map_dimensions[] = {
SLEG_CONDVAR(_map_dim_x, SLE_UINT32, 6, SL_MAX_VERSION),
SLEG_CONDVAR(_map_dim_y, SLE_UINT32, 6, SL_MAX_VERSION),
SLEG_END()
};
static void Save_MAPS()
{
_map_dim_x = MapSizeX();
_map_dim_y = MapSizeY();
SlGlobList(_map_dimensions);
}
static void Load_MAPS()
{
SlGlobList(_map_dimensions);
AllocateMap(_map_dim_x, _map_dim_y);
}
enum {
MAP_SL_BUF_SIZE = 4096
};
static void Load_MAPT()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
for (TileIndex i = 0; i != size;) {
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].type_height = buf[j];
}
}
static void Save_MAPT()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
SlSetLength(size);
for (TileIndex i = 0; i != size;) {
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].type_height;
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
}
}
static void Load_MAP1()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
for (TileIndex i = 0; i != size;) {
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m1 = buf[j];
}
}
static void Save_MAP1()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
SlSetLength(size);
for (TileIndex i = 0; i != size;) {
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m1;
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
}
}
static void Load_MAP2()
{
SmallStackSafeStackAlloc<uint16, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
for (TileIndex i = 0; i != size;) {
SlArray(buf, MAP_SL_BUF_SIZE,
/* In those versions the m2 was 8 bits */
CheckSavegameVersion(5) ? SLE_FILE_U8 | SLE_VAR_U16 : SLE_UINT16
);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m2 = buf[j];
}
}
static void Save_MAP2()
{
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] = _m[i++].m2;
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT16);
}
}
static void Load_MAP3()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
for (TileIndex i = 0; i != size;) {
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m3 = buf[j];
}
}
static void Save_MAP3()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
SlSetLength(size);
for (TileIndex i = 0; i != size;) {
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m3;
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
}
}
static void Load_MAP4()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
for (TileIndex i = 0; i != size;) {
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m4 = buf[j];
}
}
static void Save_MAP4()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
SlSetLength(size);
for (TileIndex i = 0; i != size;) {
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m4;
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
}
}
static void Load_MAP5()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
for (TileIndex i = 0; i != size;) {
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m5 = buf[j];
}
}
static void Save_MAP5()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
SlSetLength(size);
for (TileIndex i = 0; i != size;) {
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m5;
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
}
}
static void Load_MAP6()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
if (CheckSavegameVersion(42)) {
for (TileIndex i = 0; i != size;) {
/* 1024, otherwise we overflow on 64x64 maps! */
SlArray(buf, 1024, SLE_UINT8);
for (uint j = 0; j != 1024; j++) {
_m[i++].m6 = GB(buf[j], 0, 2);
_m[i++].m6 = GB(buf[j], 2, 2);
_m[i++].m6 = GB(buf[j], 4, 2);
_m[i++].m6 = GB(buf[j], 6, 2);
}
}
} else {
for (TileIndex i = 0; i != size;) {
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m6 = buf[j];
}
}
}
static void Save_MAP6()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
SlSetLength(size);
for (TileIndex i = 0; i != size;) {
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m6;
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
}
}
static void Load_MAP7()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
for (TileIndex i = 0; i != size;) {
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m7 = buf[j];
}
}
static void Save_MAP7()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
SlSetLength(size);
for (TileIndex i = 0; i != size;) {
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m7;
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
}
}
extern const ChunkHandler _misc_chunk_handlers[] = {
{ 'MAPS', Save_MAPS, Load_MAPS, CH_RIFF },
{ 'MAPT', Save_MAPT, Load_MAPT, CH_RIFF },
{ 'MAPO', Save_MAP1, Load_MAP1, CH_RIFF },
{ 'MAP2', Save_MAP2, Load_MAP2, CH_RIFF },
{ 'M3LO', Save_MAP3, Load_MAP3, CH_RIFF },
{ 'M3HI', Save_MAP4, Load_MAP4, CH_RIFF },
{ 'MAP5', Save_MAP5, Load_MAP5, CH_RIFF },
{ 'MAPE', Save_MAP6, Load_MAP6, CH_RIFF },
{ 'MAP7', Save_MAP7, Load_MAP7, CH_RIFF },
{ 'DATE', SaveLoad_DATE, SaveLoad_DATE, CH_RIFF},
{ 'VIEW', SaveLoad_VIEW, SaveLoad_VIEW, CH_RIFF | CH_LAST},
};

@ -9,7 +9,7 @@
#include "landscape.h"
#include "newgrf.h"
#include "newgrf_text.h"
#include "saveload.h"
#include "saveload/saveload.h"
#include "tile_map.h"
#include "gui.h"
#include "window_gui.h"

@ -12,7 +12,7 @@
#include "network_client.h"
#include "network_gamelist.h"
#include "network_gui.h"
#include "../saveload.h"
#include "../saveload/saveload.h"
#include "../command_func.h"
#include "../console_func.h"
#include "../variables.h"

@ -17,7 +17,7 @@
#include "network_udp.h"
#include "../console_func.h"
#include "../command_func.h"
#include "../saveload.h"
#include "../saveload/saveload.h"
#include "../station_base.h"
#include "../variables.h"
#include "../genworld.h"

@ -121,7 +121,7 @@ extern GRFLoadedFeatures _loaded_newgrf_features;
void LoadNewGRFFile(GRFConfig *config, uint file_index, GrfLoadingStage stage);
void LoadNewGRF(uint load_index, uint file_index);
void ReloadNewGRFData(); // in openttd.cpp
void ReloadNewGRFData(); // in saveload/afterload.cpp
void CDECL grfmsg(int severity, const char *str, ...);

@ -6,7 +6,6 @@
#include "openttd.h"
#include "debug.h"
#include "variables.h"
#include "saveload.h"
#include "md5.h"
#include "newgrf.h"
#include "newgrf_config.h"
@ -495,48 +494,3 @@ bool GRFConfig::IsOpenTTDBaseGRF() const
{
return (this->grfid & 0x00FFFFFF) == OPENTTD_GRAPHICS_BASE_GRF_ID;
}
static const SaveLoad _grfconfig_desc[] = {
SLE_STR(GRFConfig, filename, SLE_STR, 0x40),
SLE_VAR(GRFConfig, grfid, SLE_UINT32),
SLE_ARR(GRFConfig, md5sum, SLE_UINT8, 16),
SLE_ARR(GRFConfig, param, SLE_UINT32, 0x80),
SLE_VAR(GRFConfig, num_params, SLE_UINT8),
SLE_CONDVAR(GRFConfig, windows_paletted, SLE_BOOL, 101, SL_MAX_VERSION),
SLE_END()
};
static void Save_NGRF()
{
int index = 0;
for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
if (HasBit(c->flags, GCF_STATIC)) continue;
SlSetArrayIndex(index++);
SlObject(c, _grfconfig_desc);
}
}
static void Load_NGRF()
{
ClearGRFConfigList(&_grfconfig);
while (SlIterateArray() != -1) {
GRFConfig *c = CallocT<GRFConfig>(1);
SlObject(c, _grfconfig_desc);
if (CheckSavegameVersion(101)) c->windows_paletted = (_use_palette == PAL_WINDOWS);
AppendToGRFConfigList(&_grfconfig, c);
}
/* Append static NewGRF configuration */
AppendStaticGRFConfigs(&_grfconfig);
}
extern const ChunkHandler _newgrf_chunk_handlers[] = {
{ 'NGRF', Save_NGRF, Load_NGRF, CH_ARRAY | CH_LAST }
};

@ -34,53 +34,6 @@ static HouseClassMapping _class_mapping[HOUSE_CLASS_MAX];
HouseOverrideManager _house_mngr(NEW_HOUSE_OFFSET, HOUSE_MAX, INVALID_HOUSE_ID);
/**
* Check and update town and house values.
*
* Checked are the HouseIDs. Updated are the
* town population the number of houses per
* town, the town radius and the max passengers
* of the town.
*/
void UpdateHousesAndTowns()
{
Town *town;
InitializeBuildingCounts();
/* Reset town population and num_houses */
FOR_ALL_TOWNS(town) {
town->population = 0;
town->num_houses = 0;
}
for (TileIndex t = 0; t < MapSize(); t++) {
HouseID house_id;
if (!IsTileType(t, MP_HOUSE)) continue;
house_id = GetHouseType(t);
if (!GetHouseSpecs(house_id)->enabled && house_id >= NEW_HOUSE_OFFSET) {
/* The specs for this type of house are not available any more, so
* replace it with the substitute original house type. */
house_id = _house_mngr.GetSubstituteID(house_id);
SetHouseType(t, house_id);
}
town = GetTownByTile(t);
IncreaseBuildingCount(town, house_id);
if (IsHouseCompleted(t)) town->population += GetHouseSpecs(house_id)->population;
/* Increase the number of houses for every house, but only once. */
if (GetHouseNorthPart(house_id) == 0) town->num_houses++;
}
/* Update the population and num_house dependant values */
FOR_ALL_TOWNS(town) {
UpdateTownRadius(town);
UpdateTownMaxPass(town);
}
}
HouseClassID AllocateHouseClassID(byte grf_class_id, uint32 grfid)
{
/* Start from 1 because 0 means that no class has been assigned. */

@ -7,6 +7,7 @@
#include "town_type.h"
#include "newgrf_callbacks.h"
#include "tile_cmd.h"
/**
* Makes class IDs unique to each GRF file.
@ -26,8 +27,6 @@ struct HouseClassMapping {
uint8 class_id; ////< The class id within the grf file
};
void UpdateHousesAndTowns();
HouseClassID AllocateHouseClassID(byte grf_class_id, uint32 grfid);
void InitializeBuildingCounts();

@ -13,6 +13,7 @@
#include "strings_type.h"
#include "sprite.h"
#include "direction_type.h"
#include "newgrf.h"
enum StationClassID {
STAT_CLASS_BEGIN = 0, ///< the lowest valid value

File diff suppressed because it is too large Load Diff

@ -431,7 +431,4 @@ static inline bool IsValidOrderListID(uint index)
#define FOR_ALL_ORDER_LISTS_FROM(ol, start) for (ol = GetOrderList(start); ol != NULL; ol = (ol->index + 1U < GetOrderListPoolSize()) ? GetOrderList(ol->index + 1U) : NULL) if (ol->IsValid())
#define FOR_ALL_ORDER_LISTS(ol) FOR_ALL_ORDER_LISTS_FROM(ol, 0)
/* (Un)pack routines */
Order UnpackOldOrder(uint16 packed);
#endif /* ORDER_H */

@ -13,7 +13,6 @@
#include "command_func.h"
#include "company_func.h"
#include "news_func.h"
#include "saveload.h"
#include "vehicle_gui.h"
#include "cargotype.h"
#include "aircraft.h"
@ -147,82 +146,6 @@ Order::Order(uint32 packed)
this->travel_time = 0;
}
void Order::ConvertFromOldSavegame()
{
uint8 old_flags = this->flags;
this->flags = 0;
/* First handle non-stop */
if (_settings_client.gui.sg_new_nonstop) {
/* OFB_NON_STOP */
this->SetNonStopType((old_flags & 8) ? ONSF_NO_STOP_AT_ANY_STATION : ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
} else {
this->SetNonStopType((old_flags & 8) ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE);
}
switch (this->GetType()) {
/* Only a few types need the other savegame conversions. */
case OT_GOTO_DEPOT: case OT_GOTO_STATION: case OT_LOADING: break;
default: return;
}
if (this->GetType() != OT_GOTO_DEPOT) {
/* Then the load flags */
if ((old_flags & 2) != 0) { // OFB_UNLOAD
this->SetLoadType(OLFB_NO_LOAD);
} else if ((old_flags & 4) == 0) { // !OFB_FULL_LOAD
this->SetLoadType(OLF_LOAD_IF_POSSIBLE);
} else {
this->SetLoadType(_settings_client.gui.sg_full_load_any ? OLF_FULL_LOAD_ANY : OLFB_FULL_LOAD);
}
/* Finally fix the unload flags */
if ((old_flags & 1) != 0) { // OFB_TRANSFER
this->SetUnloadType(OUFB_TRANSFER);
} else if ((old_flags & 2) != 0) { // OFB_UNLOAD
this->SetUnloadType(OUFB_UNLOAD);
} else {
this->SetUnloadType(OUF_UNLOAD_IF_POSSIBLE);
}
} else {
/* Then the depot action flags */
this->SetDepotActionType(((old_flags & 6) == 4) ? ODATFB_HALT : ODATF_SERVICE_ONLY);
/* Finally fix the depot type flags */
uint t = ((old_flags & 6) == 6) ? ODTFB_SERVICE : ODTF_MANUAL;
if ((old_flags & 2) != 0) t |= ODTFB_PART_OF_ORDERS;
this->SetDepotOrderType((OrderDepotTypeFlags)t);
}
}
/**
*
* Unpacks a order from savegames with version 4 and lower
*
*/
static Order UnpackVersion4Order(uint16 packed)
{
return Order(GB(packed, 8, 8) << 16 | GB(packed, 4, 4) << 8 | GB(packed, 0, 4));
}
/**
*
* Unpacks a order from savegames made with TTD(Patch)
*
*/
Order UnpackOldOrder(uint16 packed)
{
Order order = UnpackVersion4Order(packed);
/*
* Sanity check
* TTD stores invalid orders as OT_NOTHING with non-zero flags/station
*/
if (!order.IsValid() && packed != 0) order.MakeDummy();
return order;
}
/**
*
* Updates the widgets of a vehicle which contains the order-data
@ -1898,118 +1821,3 @@ void InitializeOrders()
_backup_orders_tile = 0;
}
const SaveLoad *GetOrderDescription() {
static const SaveLoad _order_desc[] = {
SLE_VAR(Order, type, SLE_UINT8),
SLE_VAR(Order, flags, SLE_UINT8),
SLE_VAR(Order, dest, SLE_UINT16),
SLE_REF(Order, next, REF_ORDER),
SLE_CONDVAR(Order, refit_cargo, SLE_UINT8, 36, SL_MAX_VERSION),
SLE_CONDVAR(Order, refit_subtype, SLE_UINT8, 36, SL_MAX_VERSION),
SLE_CONDVAR(Order, wait_time, SLE_UINT16, 67, SL_MAX_VERSION),
SLE_CONDVAR(Order, travel_time, SLE_UINT16, 67, SL_MAX_VERSION),
/* Leftover from the minor savegame version stuff
* We will never use those free bytes, but we have to keep this line to allow loading of old savegames */
SLE_CONDNULL(10, 5, 35),
SLE_END()
};
return _order_desc;
}
static void Save_ORDR()
{
Order *order;
FOR_ALL_ORDERS(order) {
SlSetArrayIndex(order->index);
SlObject(order, GetOrderDescription());
}
}
static void Load_ORDR()
{
if (CheckSavegameVersionOldStyle(5, 2)) {
/* Version older than 5.2 did not have a ->next pointer. Convert them
(in the old days, the orderlist was 5000 items big) */
size_t len = SlGetFieldLength();
uint i;
if (CheckSavegameVersion(5)) {
/* Pre-version 5 had an other layout for orders
(uint16 instead of uint32) */
len /= sizeof(uint16);
uint16 *orders = MallocT<uint16>(len + 1);
SlArray(orders, len, SLE_UINT16);
for (i = 0; i < len; ++i) {
Order *order = new (i) Order();
order->AssignOrder(UnpackVersion4Order(orders[i]));
}
free(orders);
} else if (CheckSavegameVersionOldStyle(5, 2)) {
len /= sizeof(uint16);
uint16 *orders = MallocT<uint16>(len + 1);
SlArray(orders, len, SLE_UINT32);
for (i = 0; i < len; ++i) {
new (i) Order(orders[i]);
}
free(orders);
}
/* Update all the next pointer */
for (i = 1; i < len; ++i) {
/* The orders were built like this:
* While the order is valid, set the previous will get it's next pointer set
* We start with index 1 because no order will have the first in it's next pointer */
if (GetOrder(i)->IsValid())
GetOrder(i - 1)->next = GetOrder(i);
}
} else {
int index;
while ((index = SlIterateArray()) != -1) {
Order *order = new (index) Order();
SlObject(order, GetOrderDescription());
}
}
}
const SaveLoad *GetOrderListDescription() {
static const SaveLoad _orderlist_desc[] = {
SLE_REF(OrderList, first, REF_ORDER),
SLE_END()
};
return _orderlist_desc;
}
static void Save_ORDL()
{
OrderList *list;
FOR_ALL_ORDER_LISTS(list) {
SlSetArrayIndex(list->index);
SlObject(list, GetOrderListDescription());
}
}
static void Load_ORDL()
{
int index;
while ((index = SlIterateArray()) != -1) {
OrderList *list = new (index) OrderList();
SlObject(list, GetOrderListDescription());
}
}
extern const ChunkHandler _order_chunk_handlers[] = {
{ 'ORDR', Save_ORDR, Load_ORDR, CH_ARRAY},
{ 'ORDL', Save_ORDL, Load_ORDL, CH_ARRAY | CH_LAST},
};

File diff suppressed because it is too large Load Diff

@ -0,0 +1,79 @@
/* $Id$ */
/** @file ai_sl.cpp Code handling saving and loading of old AI + new AI initialisation after game load */
#include "../stdafx.h"
#include "../ai/ai.h"
#include "../ai/default/default.h"
#include "saveload.h"
static const SaveLoad _company_ai_desc[] = {
SLE_VAR(CompanyAI, state, SLE_UINT8),
SLE_VAR(CompanyAI, tick, SLE_UINT8),
SLE_CONDVAR(CompanyAI, state_counter, SLE_FILE_U16 | SLE_VAR_U32, 0, 12),
SLE_CONDVAR(CompanyAI, state_counter, SLE_UINT32, 13, SL_MAX_VERSION),
SLE_VAR(CompanyAI, timeout_counter, SLE_UINT16),
SLE_VAR(CompanyAI, state_mode, SLE_UINT8),
SLE_VAR(CompanyAI, banned_tile_count, SLE_UINT8),
SLE_VAR(CompanyAI, railtype_to_use, SLE_UINT8),
SLE_VAR(CompanyAI, cargo_type, SLE_UINT8),
SLE_VAR(CompanyAI, num_wagons, SLE_UINT8),
SLE_VAR(CompanyAI, build_kind, SLE_UINT8),
SLE_VAR(CompanyAI, num_build_rec, SLE_UINT8),
SLE_VAR(CompanyAI, num_loco_to_build, SLE_UINT8),
SLE_VAR(CompanyAI, num_want_fullload, SLE_UINT8),
SLE_VAR(CompanyAI, route_type_mask, SLE_UINT8),
SLE_CONDVAR(CompanyAI, start_tile_a, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(CompanyAI, start_tile_a, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(CompanyAI, cur_tile_a, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(CompanyAI, cur_tile_a, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_VAR(CompanyAI, start_dir_a, SLE_UINT8),
SLE_VAR(CompanyAI, cur_dir_a, SLE_UINT8),
SLE_CONDVAR(CompanyAI, start_tile_b, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(CompanyAI, start_tile_b, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(CompanyAI, cur_tile_b, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(CompanyAI, cur_tile_b, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_VAR(CompanyAI, start_dir_b, SLE_UINT8),
SLE_VAR(CompanyAI, cur_dir_b, SLE_UINT8),
SLE_REF(CompanyAI, cur_veh, REF_VEHICLE),
SLE_ARR(CompanyAI, wagon_list, SLE_UINT16, 9),
SLE_ARR(CompanyAI, order_list_blocks, SLE_UINT8, 20),
SLE_ARR(CompanyAI, banned_tiles, SLE_UINT16, 16),
SLE_CONDNULL(64, 2, SL_MAX_VERSION),
SLE_END()
};
static const SaveLoad _company_ai_build_rec_desc[] = {
SLE_CONDVAR(AiBuildRec, spec_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(AiBuildRec, spec_tile, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(AiBuildRec, use_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(AiBuildRec, use_tile, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_VAR(AiBuildRec, rand_rng, SLE_UINT8),
SLE_VAR(AiBuildRec, cur_building_rule, SLE_UINT8),
SLE_VAR(AiBuildRec, unk6, SLE_UINT8),
SLE_VAR(AiBuildRec, unk7, SLE_UINT8),
SLE_VAR(AiBuildRec, buildcmd_a, SLE_UINT8),
SLE_VAR(AiBuildRec, buildcmd_b, SLE_UINT8),
SLE_VAR(AiBuildRec, direction, SLE_UINT8),
SLE_VAR(AiBuildRec, cargo, SLE_UINT8),
SLE_END()
};
void SaveLoad_AI(CompanyID company)
{
CompanyAI *cai = &_companies_ai[company];
SlObject(cai, _company_ai_desc);
for (int i = 0; i != cai->num_build_rec; i++) {
SlObject(&cai->src + i, _company_ai_build_rec_desc);
}
}

@ -0,0 +1,56 @@
/* $Id$ */
/** @file animated_tile_sl.cpp Code handling saving and loading of animated tiles */
#include "../stdafx.h"
#include "../tile_type.h"
#include "../core/alloc_func.hpp"
#include "saveload.h"
extern TileIndex *_animated_tile_list;
extern uint _animated_tile_count;
extern uint _animated_tile_allocated;
/**
* Save the ANIT chunk.
*/
static void Save_ANIT()
{
SlSetLength(_animated_tile_count * sizeof(*_animated_tile_list));
SlArray(_animated_tile_list, _animated_tile_count, SLE_UINT32);
}
/**
* Load the ANIT chunk; the chunk containing the animated tiles.
*/
static void Load_ANIT()
{
/* Before version 80 we did NOT have a variable length animated tile table */
if (CheckSavegameVersion(80)) {
/* In pre version 6, we has 16bit per tile, now we have 32bit per tile, convert it ;) */
SlArray(_animated_tile_list, 256, CheckSavegameVersion(6) ? (SLE_FILE_U16 | SLE_VAR_U32) : SLE_UINT32);
for (_animated_tile_count = 0; _animated_tile_count < 256; _animated_tile_count++) {
if (_animated_tile_list[_animated_tile_count] == 0) break;
}
return;
}
_animated_tile_count = (uint)SlGetFieldLength() / sizeof(*_animated_tile_list);
/* Determine a nice rounded size for the amount of allocated tiles */
_animated_tile_allocated = 256;
while (_animated_tile_allocated < _animated_tile_count) _animated_tile_allocated *= 2;
_animated_tile_list = ReallocT<TileIndex>(_animated_tile_list, _animated_tile_allocated);
SlArray(_animated_tile_list, _animated_tile_count, SLE_UINT32);
}
/**
* "Definition" imported by the saveload code to be able to load and save
* the animated tile table.
*/
extern const ChunkHandler _animated_tile_chunk_handlers[] = {
{ 'ANIT', Save_ANIT, Load_ANIT, CH_RIFF | CH_LAST},
};

@ -0,0 +1,51 @@
/* $Id$ */
/** @file autoreplace_sl.cpp Code handling saving and loading of autoreplace rules */
#include "../stdafx.h"
#include "../autoreplace_type.h"
#include "../engine_type.h"
#include "../group_type.h"
#include "../autoreplace_base.h"
#include "saveload.h"
static const SaveLoad _engine_renew_desc[] = {
SLE_VAR(EngineRenew, from, SLE_UINT16),
SLE_VAR(EngineRenew, to, SLE_UINT16),
SLE_REF(EngineRenew, next, REF_ENGINE_RENEWS),
SLE_CONDVAR(EngineRenew, group_id, SLE_UINT16, 60, SL_MAX_VERSION),
SLE_END()
};
static void Save_ERNW()
{
EngineRenew *er;
FOR_ALL_ENGINE_RENEWS(er) {
SlSetArrayIndex(er->index);
SlObject(er, _engine_renew_desc);
}
}
static void Load_ERNW()
{
int index;
while ((index = SlIterateArray()) != -1) {
EngineRenew *er = new (index) EngineRenew();
SlObject(er, _engine_renew_desc);
/* Advanced vehicle lists, ungrouped vehicles got added */
if (CheckSavegameVersion(60)) {
er->group_id = ALL_GROUP;
} else if (CheckSavegameVersion(71)) {
if (er->group_id == DEFAULT_GROUP) er->group_id = ALL_GROUP;
}
}
}
extern const ChunkHandler _autoreplace_chunk_handlers[] = {
{ 'ERNW', Save_ERNW, Load_ERNW, CH_ARRAY | CH_LAST},
};

@ -0,0 +1,45 @@
/* $Id$ */
/** @file cargopacket_sl.cpp Code handling saving and loading of cargo packets */
#include "../stdafx.h"
#include "../openttd.h"
#include "../cargopacket.h"
#include "saveload.h"
static const SaveLoad _cargopacket_desc[] = {
SLE_VAR(CargoPacket, source, SLE_UINT16),
SLE_VAR(CargoPacket, source_xy, SLE_UINT32),
SLE_VAR(CargoPacket, loaded_at_xy, SLE_UINT32),
SLE_VAR(CargoPacket, count, SLE_UINT16),
SLE_VAR(CargoPacket, days_in_transit, SLE_UINT8),
SLE_VAR(CargoPacket, feeder_share, SLE_INT64),
SLE_VAR(CargoPacket, paid_for, SLE_BOOL),
SLE_END()
};
static void Save_CAPA()
{
CargoPacket *cp;
FOR_ALL_CARGOPACKETS(cp) {
SlSetArrayIndex(cp->index);
SlObject(cp, _cargopacket_desc);
}
}
static void Load_CAPA()
{
int index;
while ((index = SlIterateArray()) != -1) {
CargoPacket *cp = new (index) CargoPacket();
SlObject(cp, _cargopacket_desc);
}
}
extern const ChunkHandler _cargopacket_chunk_handlers[] = {
{ 'CAPA', Save_CAPA, Load_CAPA, CH_ARRAY | CH_LAST},
};

@ -0,0 +1,37 @@
/* $Id$ */
/** @file cheat_sl.cpp Code handling saving and loading of cheats */
#include "../stdafx.h"
#include "../cheat_type.h"
#include "saveload.h"
static void Save_CHTS()
{
/* Cannot use lengthof because _cheats is of type Cheats, not Cheat */
byte count = sizeof(_cheats) / sizeof(Cheat);
Cheat *cht = (Cheat*) &_cheats;
Cheat *cht_last = &cht[count];
SlSetLength(count * 2);
for (; cht != cht_last; cht++) {
SlWriteByte(cht->been_used);
SlWriteByte(cht->value);
}
}
static void Load_CHTS()
{
Cheat *cht = (Cheat*)&_cheats;
size_t count = SlGetFieldLength() / 2;
for (uint i = 0; i < count; i++) {
cht[i].been_used = (SlReadByte() != 0);
cht[i].value = (SlReadByte() != 0);
}
}
extern const ChunkHandler _cheat_chunk_handlers[] = {
{ 'CHTS', Save_CHTS, Load_CHTS, CH_RIFF | CH_LAST}
};

@ -0,0 +1,240 @@
/* $Id$ */
/** @file company_sl.cpp Code handling saving and loading of company data */
#include "../stdafx.h"
#include "../company_base.h"
#include "../company_func.h"
#include "../network/network.h"
#include "../ai/ai.h"
#include "../ai/trolly/trolly.h"
#include "../company_manager_face.h"
#include "saveload.h"
/**
* Converts an old company manager's face format to the new company manager's face format
*
* Meaning of the bits in the old face (some bits are used in several times):
* - 4 and 5: chin
* - 6 to 9: eyebrows
* - 10 to 13: nose
* - 13 to 15: lips (also moustache for males)
* - 16 to 19: hair
* - 20 to 22: eye color
* - 20 to 27: tie, ear rings etc.
* - 28 to 30: glasses
* - 19, 26 and 27: race (bit 27 set and bit 19 equal to bit 26 = black, otherwise white)
* - 31: gender (0 = male, 1 = female)
*
* @param face the face in the old format
* @return the face in the new format
*/
CompanyManagerFace ConvertFromOldCompanyManagerFace(uint32 face)
{
CompanyManagerFace cmf = 0;
GenderEthnicity ge = GE_WM;
if (HasBit(face, 31)) SetBit(ge, GENDER_FEMALE);
if (HasBit(face, 27) && (HasBit(face, 26) == HasBit(face, 19))) SetBit(ge, ETHNICITY_BLACK);
SetCompanyManagerFaceBits(cmf, CMFV_GEN_ETHN, ge, ge);
SetCompanyManagerFaceBits(cmf, CMFV_HAS_GLASSES, ge, GB(face, 28, 3) <= 1);
SetCompanyManagerFaceBits(cmf, CMFV_EYE_COLOUR, ge, HasBit(ge, ETHNICITY_BLACK) ? 0 : ClampU(GB(face, 20, 3), 5, 7) - 5);
SetCompanyManagerFaceBits(cmf, CMFV_CHIN, ge, ScaleCompanyManagerFaceValue(CMFV_CHIN, ge, GB(face, 4, 2)));
SetCompanyManagerFaceBits(cmf, CMFV_EYEBROWS, ge, ScaleCompanyManagerFaceValue(CMFV_EYEBROWS, ge, GB(face, 6, 4)));
SetCompanyManagerFaceBits(cmf, CMFV_HAIR, ge, ScaleCompanyManagerFaceValue(CMFV_HAIR, ge, GB(face, 16, 4)));
SetCompanyManagerFaceBits(cmf, CMFV_JACKET, ge, ScaleCompanyManagerFaceValue(CMFV_JACKET, ge, GB(face, 20, 2)));
SetCompanyManagerFaceBits(cmf, CMFV_COLLAR, ge, ScaleCompanyManagerFaceValue(CMFV_COLLAR, ge, GB(face, 22, 2)));
SetCompanyManagerFaceBits(cmf, CMFV_GLASSES, ge, GB(face, 28, 1));
uint lips = GB(face, 10, 4);
if (!HasBit(ge, GENDER_FEMALE) && lips < 4) {
SetCompanyManagerFaceBits(cmf, CMFV_HAS_MOUSTACHE, ge, true);
SetCompanyManagerFaceBits(cmf, CMFV_MOUSTACHE, ge, max(lips, 1U) - 1);
} else {
if (!HasBit(ge, GENDER_FEMALE)) {
lips = lips * 15 / 16;
lips -= 3;
if (HasBit(ge, ETHNICITY_BLACK) && lips > 8) lips = 0;
} else {
lips = ScaleCompanyManagerFaceValue(CMFV_LIPS, ge, lips);
}
SetCompanyManagerFaceBits(cmf, CMFV_LIPS, ge, lips);
uint nose = GB(face, 13, 3);
if (ge == GE_WF) {
nose = (nose * 3 >> 3) * 3 >> 2; // There is 'hole' in the nose sprites for females
} else {
nose = ScaleCompanyManagerFaceValue(CMFV_NOSE, ge, nose);
}
SetCompanyManagerFaceBits(cmf, CMFV_NOSE, ge, nose);
}
uint tie_earring = GB(face, 24, 4);
if (!HasBit(ge, GENDER_FEMALE) || tie_earring < 3) { // Not all females have an earring
if (HasBit(ge, GENDER_FEMALE)) SetCompanyManagerFaceBits(cmf, CMFV_HAS_TIE_EARRING, ge, true);
SetCompanyManagerFaceBits(cmf, CMFV_TIE_EARRING, ge, HasBit(ge, GENDER_FEMALE) ? tie_earring : ScaleCompanyManagerFaceValue(CMFV_TIE_EARRING, ge, tie_earring / 2));
}
return cmf;
}
/* Save/load of companies */
static const SaveLoad _company_desc[] = {
SLE_VAR(Company, name_2, SLE_UINT32),
SLE_VAR(Company, name_1, SLE_STRINGID),
SLE_CONDSTR(Company, name, SLE_STR, 0, 84, SL_MAX_VERSION),
SLE_VAR(Company, president_name_1, SLE_UINT16),
SLE_VAR(Company, president_name_2, SLE_UINT32),
SLE_CONDSTR(Company, president_name, SLE_STR, 0, 84, SL_MAX_VERSION),
SLE_VAR(Company, face, SLE_UINT32),
/* money was changed to a 64 bit field in savegame version 1. */
SLE_CONDVAR(Company, money, SLE_VAR_I64 | SLE_FILE_I32, 0, 0),
SLE_CONDVAR(Company, money, SLE_INT64, 1, SL_MAX_VERSION),
SLE_CONDVAR(Company, current_loan, SLE_VAR_I64 | SLE_FILE_I32, 0, 64),
SLE_CONDVAR(Company, current_loan, SLE_INT64, 65, SL_MAX_VERSION),
SLE_VAR(Company, colour, SLE_UINT8),
SLE_VAR(Company, money_fraction, SLE_UINT8),
SLE_CONDVAR(Company, avail_railtypes, SLE_UINT8, 0, 57),
SLE_VAR(Company, block_preview, SLE_UINT8),
SLE_CONDVAR(Company, cargo_types, SLE_FILE_U16 | SLE_VAR_U32, 0, 93),
SLE_CONDVAR(Company, cargo_types, SLE_UINT32, 94, SL_MAX_VERSION),
SLE_CONDVAR(Company, location_of_HQ, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Company, location_of_HQ, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Company, last_build_coordinate, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Company, last_build_coordinate, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Company, inaugurated_year, SLE_FILE_U8 | SLE_VAR_I32, 0, 30),
SLE_CONDVAR(Company, inaugurated_year, SLE_INT32, 31, SL_MAX_VERSION),
SLE_ARR(Company, share_owners, SLE_UINT8, 4),
SLE_VAR(Company, num_valid_stat_ent, SLE_UINT8),
SLE_VAR(Company, quarters_of_bankrupcy, SLE_UINT8),
SLE_CONDVAR(Company, bankrupt_asked, SLE_FILE_U8 | SLE_VAR_U16, 0, 103),
SLE_CONDVAR(Company, bankrupt_asked, SLE_UINT16, 104, SL_MAX_VERSION),
SLE_VAR(Company, bankrupt_timeout, SLE_INT16),
SLE_CONDVAR(Company, bankrupt_value, SLE_VAR_I64 | SLE_FILE_I32, 0, 64),
SLE_CONDVAR(Company, bankrupt_value, SLE_INT64, 65, SL_MAX_VERSION),
/* yearly expenses was changed to 64-bit in savegame version 2. */
SLE_CONDARR(Company, yearly_expenses, SLE_FILE_I32 | SLE_VAR_I64, 3 * 13, 0, 1),
SLE_CONDARR(Company, yearly_expenses, SLE_INT64, 3 * 13, 2, SL_MAX_VERSION),
SLE_CONDVAR(Company, is_ai, SLE_BOOL, 2, SL_MAX_VERSION),
SLE_CONDNULL(1, 4, 99),
/* Engine renewal settings */
SLE_CONDNULL(512, 16, 18),
SLE_CONDREF(Company, engine_renew_list, REF_ENGINE_RENEWS, 19, SL_MAX_VERSION),
SLE_CONDVAR(Company, engine_renew, SLE_BOOL, 16, SL_MAX_VERSION),
SLE_CONDVAR(Company, engine_renew_months, SLE_INT16, 16, SL_MAX_VERSION),
SLE_CONDVAR(Company, engine_renew_money, SLE_UINT32, 16, SL_MAX_VERSION),
SLE_CONDVAR(Company, renew_keep_length, SLE_BOOL, 2, SL_MAX_VERSION), // added with 16.1, but was blank since 2
/* reserve extra space in savegame here. (currently 63 bytes) */
SLE_CONDNULL(63, 2, SL_MAX_VERSION),
SLE_END()
};
static const SaveLoad _company_economy_desc[] = {
/* these were changed to 64-bit in savegame format 2 */
SLE_CONDVAR(CompanyEconomyEntry, income, SLE_FILE_I32 | SLE_VAR_I64, 0, 1),
SLE_CONDVAR(CompanyEconomyEntry, income, SLE_INT64, 2, SL_MAX_VERSION),
SLE_CONDVAR(CompanyEconomyEntry, expenses, SLE_FILE_I32 | SLE_VAR_I64, 0, 1),
SLE_CONDVAR(CompanyEconomyEntry, expenses, SLE_INT64, 2, SL_MAX_VERSION),
SLE_CONDVAR(CompanyEconomyEntry, company_value, SLE_FILE_I32 | SLE_VAR_I64, 0, 1),
SLE_CONDVAR(CompanyEconomyEntry, company_value, SLE_INT64, 2, SL_MAX_VERSION),
SLE_VAR(CompanyEconomyEntry, delivered_cargo, SLE_INT32),
SLE_VAR(CompanyEconomyEntry, performance_history, SLE_INT32),
SLE_END()
};
static const SaveLoad _company_livery_desc[] = {
SLE_CONDVAR(Livery, in_use, SLE_BOOL, 34, SL_MAX_VERSION),
SLE_CONDVAR(Livery, colour1, SLE_UINT8, 34, SL_MAX_VERSION),
SLE_CONDVAR(Livery, colour2, SLE_UINT8, 34, SL_MAX_VERSION),
SLE_END()
};
static void SaveLoad_PLYR(Company *c)
{
int i;
SlObject(c, _company_desc);
/* Write AI? */
if (!IsHumanCompany(c->index)) {
extern void SaveLoad_AI(CompanyID company);
SaveLoad_AI(c->index);
}
/* Write economy */
SlObject(&c->cur_economy, _company_economy_desc);
/* Write old economy entries. */
for (i = 0; i < c->num_valid_stat_ent; i++) {
SlObject(&c->old_economy[i], _company_economy_desc);
}
/* Write each livery entry. */
int num_liveries = CheckSavegameVersion(63) ? LS_END - 4 : (CheckSavegameVersion(85) ? LS_END - 2: LS_END);
for (i = 0; i < num_liveries; i++) {
SlObject(&c->livery[i], _company_livery_desc);
}
if (num_liveries < LS_END) {
/* We want to insert some liveries somewhere in between. This means some have to be moved. */
memmove(&c->livery[LS_FREIGHT_WAGON], &c->livery[LS_PASSENGER_WAGON_MONORAIL], (LS_END - LS_FREIGHT_WAGON) * sizeof(c->livery[0]));
c->livery[LS_PASSENGER_WAGON_MONORAIL] = c->livery[LS_MONORAIL];
c->livery[LS_PASSENGER_WAGON_MAGLEV] = c->livery[LS_MAGLEV];
}
if (num_liveries == LS_END - 4) {
/* Copy bus/truck liveries over to trams */
c->livery[LS_PASSENGER_TRAM] = c->livery[LS_BUS];
c->livery[LS_FREIGHT_TRAM] = c->livery[LS_TRUCK];
}
}
static void Save_PLYR()
{
Company *c;
FOR_ALL_COMPANIES(c) {
SlSetArrayIndex(c->index);
SlAutolength((AutolengthProc*)SaveLoad_PLYR, c);
}
}
static void Load_PLYR()
{
int index;
while ((index = SlIterateArray()) != -1) {
Company *c = new (index) Company();
SaveLoad_PLYR(c);
_company_colours[index] = c->colour;
/* This is needed so an AI is attached to a loaded AI */
if (c->is_ai && (!_networking || _network_server) && _ai.enabled) {
/* Clear the memory of the new AI, otherwise we might be doing wrong things. */
memset(&_companies_ainew[index], 0, sizeof(CompanyAiNew));
AI_StartNewAI(c->index);
}
}
}
extern const ChunkHandler _company_chunk_handlers[] = {
{ 'PLYR', Save_PLYR, Load_PLYR, CH_ARRAY | CH_LAST},
};

@ -0,0 +1,39 @@
/* $Id$ */
/** @file depot_sl.cpp Code handling saving and loading of depots */
#include "../stdafx.h"
#include "../depot_base.h"
#include "saveload.h"
static const SaveLoad _depot_desc[] = {
SLE_CONDVAR(Depot, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Depot, xy, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_VAR(Depot, town_index, SLE_UINT16),
SLE_END()
};
static void Save_DEPT()
{
Depot *depot;
FOR_ALL_DEPOTS(depot) {
SlSetArrayIndex(depot->index);
SlObject(depot, _depot_desc);
}
}
static void Load_DEPT()
{
int index;
while ((index = SlIterateArray()) != -1) {
Depot *depot = new (index) Depot();
SlObject(depot, _depot_desc);
}
}
extern const ChunkHandler _depot_chunk_handlers[] = {
{ 'DEPT', Save_DEPT, Load_DEPT, CH_ARRAY | CH_LAST},
};

@ -0,0 +1,58 @@
/* $Id$ */
/** @file economy_sl.cpp Code handling saving and loading of economy data */
#include "../stdafx.h"
#include "../economy_func.h"
#include "saveload.h"
/** Prices */
static void SaveLoad_PRIC()
{
int vt = CheckSavegameVersion(65) ? (SLE_FILE_I32 | SLE_VAR_I64) : SLE_INT64;
SlArray(&_price, NUM_PRICES, vt);
SlArray(&_price_frac, NUM_PRICES, SLE_UINT16);
}
/** Cargo payment rates */
static void SaveLoad_CAPR()
{
uint num_cargo = CheckSavegameVersion(55) ? 12 : NUM_CARGO;
int vt = CheckSavegameVersion(65) ? (SLE_FILE_I32 | SLE_VAR_I64) : SLE_INT64;
SlArray(&_cargo_payment_rates, num_cargo, vt);
SlArray(&_cargo_payment_rates_frac, num_cargo, SLE_UINT16);
}
static const SaveLoad _economy_desc[] = {
SLE_CONDVAR(Economy, max_loan, SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
SLE_CONDVAR(Economy, max_loan, SLE_INT64, 65, SL_MAX_VERSION),
SLE_CONDVAR(Economy, max_loan_unround, SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
SLE_CONDVAR(Economy, max_loan_unround, SLE_INT64, 65, SL_MAX_VERSION),
SLE_CONDVAR(Economy, max_loan_unround_fract, SLE_UINT16, 70, SL_MAX_VERSION),
SLE_VAR(Economy, fluct, SLE_INT16),
SLE_VAR(Economy, interest_rate, SLE_UINT8),
SLE_VAR(Economy, infl_amount, SLE_UINT8),
SLE_VAR(Economy, infl_amount_pr, SLE_UINT8),
SLE_CONDVAR(Economy, industry_daily_change_counter, SLE_UINT32, 102, SL_MAX_VERSION),
SLE_END()
};
/** Economy variables */
static void Save_ECMY()
{
SlObject(&_economy, _economy_desc);
}
/** Economy variables */
static void Load_ECMY()
{
SlObject(&_economy, _economy_desc);
StartupIndustryDailyChanges(CheckSavegameVersion(102)); // old savegames will need to be initialized
}
extern const ChunkHandler _economy_chunk_handlers[] = {
{ 'PRIC', SaveLoad_PRIC, SaveLoad_PRIC, CH_RIFF | CH_AUTO_LENGTH},
{ 'CAPR', SaveLoad_CAPR, SaveLoad_CAPR, CH_RIFF | CH_AUTO_LENGTH},
{ 'ECMY', Save_ECMY, Load_ECMY, CH_RIFF | CH_LAST},
};

@ -0,0 +1,118 @@
/* $Id$ */
/** @file engine_sl.cpp Code handling saving and loading of engines */
#include "../stdafx.h"
#include "saveload.h"
#include "saveload_internal.h"
#include "../engine_base.h"
#include <map>
static const SaveLoad _engine_desc[] = {
SLE_CONDVAR(Engine, intro_date, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
SLE_CONDVAR(Engine, intro_date, SLE_INT32, 31, SL_MAX_VERSION),
SLE_CONDVAR(Engine, age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
SLE_CONDVAR(Engine, age, SLE_INT32, 31, SL_MAX_VERSION),
SLE_VAR(Engine, reliability, SLE_UINT16),
SLE_VAR(Engine, reliability_spd_dec, SLE_UINT16),
SLE_VAR(Engine, reliability_start, SLE_UINT16),
SLE_VAR(Engine, reliability_max, SLE_UINT16),
SLE_VAR(Engine, reliability_final, SLE_UINT16),
SLE_VAR(Engine, duration_phase_1, SLE_UINT16),
SLE_VAR(Engine, duration_phase_2, SLE_UINT16),
SLE_VAR(Engine, duration_phase_3, SLE_UINT16),
SLE_VAR(Engine, lifelength, SLE_UINT8),
SLE_VAR(Engine, flags, SLE_UINT8),
SLE_VAR(Engine, preview_company_rank,SLE_UINT8),
SLE_VAR(Engine, preview_wait, SLE_UINT8),
SLE_CONDNULL(1, 0, 44),
SLE_CONDVAR(Engine, company_avail, SLE_FILE_U8 | SLE_VAR_U16, 0, 103),
SLE_CONDVAR(Engine, company_avail, SLE_UINT16, 104, SL_MAX_VERSION),
SLE_CONDSTR(Engine, name, SLE_STR, 0, 84, SL_MAX_VERSION),
/* reserve extra space in savegame here. (currently 16 bytes) */
SLE_CONDNULL(16, 2, SL_MAX_VERSION),
SLE_END()
};
static std::map<EngineID, Engine> _temp_engine;
Engine *GetTempDataEngine(EngineID index)
{
return &_temp_engine[index];
}
static void Save_ENGN()
{
Engine *e;
FOR_ALL_ENGINES(e) {
SlSetArrayIndex(e->index);
SlObject(e, _engine_desc);
}
}
static void Load_ENGN()
{
/* As engine data is loaded before engines are initialized we need to load
* this information into a temporary array. This is then copied into the
* engine pool after processing NewGRFs by CopyTempEngineData(). */
int index;
while ((index = SlIterateArray()) != -1) {
Engine *e = GetTempDataEngine(index);
SlObject(e, _engine_desc);
}
}
/**
* Copy data from temporary engine array into the real engine pool.
*/
void CopyTempEngineData()
{
Engine *e;
FOR_ALL_ENGINES(e) {
if (e->index >= _temp_engine.size()) break;
const Engine *se = GetTempDataEngine(e->index);
e->intro_date = se->intro_date;
e->age = se->age;
e->reliability = se->reliability;
e->reliability_spd_dec = se->reliability_spd_dec;
e->reliability_start = se->reliability_start;
e->reliability_max = se->reliability_max;
e->reliability_final = se->reliability_final;
e->duration_phase_1 = se->duration_phase_1;
e->duration_phase_2 = se->duration_phase_2;
e->duration_phase_3 = se->duration_phase_3;
e->lifelength = se->lifelength;
e->flags = se->flags;
e->preview_company_rank= se->preview_company_rank;
e->preview_wait = se->preview_wait;
e->company_avail = se->company_avail;
if (se->name != NULL) e->name = strdup(se->name);
}
/* Get rid of temporary data */
_temp_engine.clear();
}
static void Load_ENGS()
{
/* Load old separate String ID list into a temporary array. This
* was always 256 entries. */
StringID names[256];
SlArray(names, lengthof(names), SLE_STRINGID);
/* Copy each string into the temporary engine array. */
for (EngineID engine = 0; engine < lengthof(names); engine++) {
Engine *e = GetTempDataEngine(engine);
e->name = CopyFromOldName(names[engine]);
}
}
extern const ChunkHandler _engine_chunk_handlers[] = {
{ 'ENGN', Save_ENGN, Load_ENGN, CH_ARRAY },
{ 'ENGS', NULL, Load_ENGS, CH_RIFF | CH_LAST },
};

@ -0,0 +1,161 @@
/* $Id$ */
/** @file gamelog_sl.cpp Code handling saving and loading of gamelog data */
#include "../stdafx.h"
#include "../gamelog.h"
#include "../gamelog_internal.h"
#include "../core/alloc_func.hpp"
#include "saveload.h"
static const SaveLoad _glog_action_desc[] = {
SLE_VAR(LoggedAction, tick, SLE_UINT16),
SLE_END()
};
static const SaveLoad _glog_mode_desc[] = {
SLE_VAR(LoggedChange, mode.mode, SLE_UINT8),
SLE_VAR(LoggedChange, mode.landscape, SLE_UINT8),
SLE_END()
};
static const SaveLoad _glog_revision_desc[] = {
SLE_ARR(LoggedChange, revision.text, SLE_UINT8, NETWORK_REVISION_LENGTH),
SLE_VAR(LoggedChange, revision.newgrf, SLE_UINT32),
SLE_VAR(LoggedChange, revision.slver, SLE_UINT16),
SLE_VAR(LoggedChange, revision.modified, SLE_UINT8),
SLE_END()
};
static const SaveLoad _glog_oldver_desc[] = {
SLE_VAR(LoggedChange, oldver.type, SLE_UINT32),
SLE_VAR(LoggedChange, oldver.version, SLE_UINT32),
SLE_END()
};
static const SaveLoad _glog_patch_desc[] = {
SLE_STR(LoggedChange, patch.name, SLE_STR, 128),
SLE_VAR(LoggedChange, patch.oldval, SLE_INT32),
SLE_VAR(LoggedChange, patch.newval, SLE_INT32),
SLE_END()
};
static const SaveLoad _glog_grfadd_desc[] = {
SLE_VAR(LoggedChange, grfadd.grfid, SLE_UINT32 ),
SLE_ARR(LoggedChange, grfadd.md5sum, SLE_UINT8, 16),
SLE_END()
};
static const SaveLoad _glog_grfrem_desc[] = {
SLE_VAR(LoggedChange, grfrem.grfid, SLE_UINT32),
SLE_END()
};
static const SaveLoad _glog_grfcompat_desc[] = {
SLE_VAR(LoggedChange, grfcompat.grfid, SLE_UINT32 ),
SLE_ARR(LoggedChange, grfcompat.md5sum, SLE_UINT8, 16),
SLE_END()
};
static const SaveLoad _glog_grfparam_desc[] = {
SLE_VAR(LoggedChange, grfparam.grfid, SLE_UINT32),
SLE_END()
};
static const SaveLoad _glog_grfmove_desc[] = {
SLE_VAR(LoggedChange, grfmove.grfid, SLE_UINT32),
SLE_VAR(LoggedChange, grfmove.offset, SLE_INT32),
SLE_END()
};
static const SaveLoad _glog_grfbug_desc[] = {
SLE_VAR(LoggedChange, grfbug.data, SLE_UINT64),
SLE_VAR(LoggedChange, grfbug.grfid, SLE_UINT32),
SLE_VAR(LoggedChange, grfbug.bug, SLE_UINT8),
SLE_END()
};
static const SaveLoad *_glog_desc[] = {
_glog_mode_desc,
_glog_revision_desc,
_glog_oldver_desc,
_glog_patch_desc,
_glog_grfadd_desc,
_glog_grfrem_desc,
_glog_grfcompat_desc,
_glog_grfparam_desc,
_glog_grfmove_desc,
_glog_grfbug_desc,
};
assert_compile(lengthof(_glog_desc) == GLCT_END);
static void Load_GLOG()
{
assert(_gamelog_action == NULL);
assert(_gamelog_actions == 0);
GamelogActionType at;
while ((at = (GamelogActionType)SlReadByte()) != GLAT_NONE) {
_gamelog_action = ReallocT(_gamelog_action, _gamelog_actions + 1);
LoggedAction *la = &_gamelog_action[_gamelog_actions++];
la->at = at;
SlObject(la, _glog_action_desc); // has to be saved after 'DATE'!
la->change = NULL;
la->changes = 0;
GamelogChangeType ct;
while ((ct = (GamelogChangeType)SlReadByte()) != GLCT_NONE) {
la->change = ReallocT(la->change, la->changes + 1);
LoggedChange *lc = &la->change[la->changes++];
/* for SLE_STR, pointer has to be valid! so make it NULL */
memset(lc, 0, sizeof(*lc));
lc->ct = ct;
assert((uint)ct < GLCT_END);
SlObject(lc, _glog_desc[ct]);
}
}
}
static void Save_GLOG()
{
const LoggedAction *laend = &_gamelog_action[_gamelog_actions];
size_t length = 0;
for (const LoggedAction *la = _gamelog_action; la != laend; la++) {
const LoggedChange *lcend = &la->change[la->changes];
for (LoggedChange *lc = la->change; lc != lcend; lc++) {
assert((uint)lc->ct < lengthof(_glog_desc));
length += SlCalcObjLength(lc, _glog_desc[lc->ct]) + 1;
}
length += 4;
}
length++;
SlSetLength(length);
for (LoggedAction *la = _gamelog_action; la != laend; la++) {
SlWriteByte(la->at);
SlObject(la, _glog_action_desc);
const LoggedChange *lcend = &la->change[la->changes];
for (LoggedChange *lc = la->change; lc != lcend; lc++) {
SlWriteByte(lc->ct);
assert((uint)lc->ct < GLCT_END);
SlObject(lc, _glog_desc[lc->ct]);
}
SlWriteByte(GLCT_NONE);
}
SlWriteByte(GLAT_NONE);
}
extern const ChunkHandler _gamelog_chunk_handlers[] = {
{ 'GLOG', Save_GLOG, Load_GLOG, CH_RIFF | CH_LAST }
};

@ -0,0 +1,43 @@
/* $Id$ */
/** @file group_sl.cpp Code handling saving and loading of economy data */
#include "../stdafx.h"
#include "../group.h"
#include "saveload.h"
static const SaveLoad _group_desc[] = {
SLE_CONDVAR(Group, name, SLE_NAME, 0, 83),
SLE_CONDSTR(Group, name, SLE_STR, 0, 84, SL_MAX_VERSION),
SLE_VAR(Group, num_vehicle, SLE_UINT16),
SLE_VAR(Group, owner, SLE_UINT8),
SLE_VAR(Group, vehicle_type, SLE_UINT8),
SLE_VAR(Group, replace_protection, SLE_BOOL),
SLE_END()
};
static void Save_GRPS(void)
{
Group *g;
FOR_ALL_GROUPS(g) {
SlSetArrayIndex(g->index);
SlObject(g, _group_desc);
}
}
static void Load_GRPS(void)
{
int index;
while ((index = SlIterateArray()) != -1) {
Group *g = new (index) Group();
SlObject(g, _group_desc);
}
}
extern const ChunkHandler _group_chunk_handlers[] = {
{ 'GRPS', Save_GRPS, Load_GRPS, CH_ARRAY | CH_LAST},
};

@ -0,0 +1,155 @@
/* $Id$ */
/** @file industry_sl.cpp Code handling saving and loading of industries */
#include "../stdafx.h"
#include "../tile_type.h"
#include "../strings_type.h"
#include "../company_type.h"
#include "../industry.h"
#include "../newgrf_commons.h"
#include "saveload.h"
static const SaveLoad _industry_desc[] = {
SLE_CONDVAR(Industry, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Industry, xy, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_VAR(Industry, width, SLE_UINT8),
SLE_VAR(Industry, height, SLE_UINT8),
SLE_REF(Industry, town, REF_TOWN),
SLE_CONDNULL( 2, 0, 60), ///< used to be industry's produced_cargo
SLE_CONDARR(Industry, produced_cargo, SLE_UINT8, 2, 78, SL_MAX_VERSION),
SLE_CONDARR(Industry, incoming_cargo_waiting, SLE_UINT16, 3, 70, SL_MAX_VERSION),
SLE_ARR(Industry, produced_cargo_waiting, SLE_UINT16, 2),
SLE_ARR(Industry, production_rate, SLE_UINT8, 2),
SLE_CONDNULL( 3, 0, 60), ///< used to be industry's accepts_cargo
SLE_CONDARR(Industry, accepts_cargo, SLE_UINT8, 3, 78, SL_MAX_VERSION),
SLE_VAR(Industry, prod_level, SLE_UINT8),
SLE_ARR(Industry, this_month_production, SLE_UINT16, 2),
SLE_ARR(Industry, this_month_transported, SLE_UINT16, 2),
SLE_ARR(Industry, last_month_pct_transported, SLE_UINT8, 2),
SLE_ARR(Industry, last_month_production, SLE_UINT16, 2),
SLE_ARR(Industry, last_month_transported, SLE_UINT16, 2),
SLE_VAR(Industry, counter, SLE_UINT16),
SLE_VAR(Industry, type, SLE_UINT8),
SLE_VAR(Industry, owner, SLE_UINT8),
SLE_VAR(Industry, random_color, SLE_UINT8),
SLE_CONDVAR(Industry, last_prod_year, SLE_FILE_U8 | SLE_VAR_I32, 0, 30),
SLE_CONDVAR(Industry, last_prod_year, SLE_INT32, 31, SL_MAX_VERSION),
SLE_VAR(Industry, was_cargo_delivered, SLE_UINT8),
SLE_CONDVAR(Industry, founder, SLE_UINT8, 70, SL_MAX_VERSION),
SLE_CONDVAR(Industry, construction_date, SLE_INT32, 70, SL_MAX_VERSION),
SLE_CONDVAR(Industry, construction_type, SLE_UINT8, 70, SL_MAX_VERSION),
SLE_CONDVAR(Industry, last_cargo_accepted_at, SLE_INT32, 70, SL_MAX_VERSION),
SLE_CONDVAR(Industry, selected_layout, SLE_UINT8, 73, SL_MAX_VERSION),
SLE_CONDARRX(cpp_offsetof(Industry, psa) + cpp_offsetof(Industry::PersistentStorage, storage), SLE_UINT32, 16, 76, SL_MAX_VERSION),
SLE_CONDVAR(Industry, random_triggers, SLE_UINT8, 82, SL_MAX_VERSION),
SLE_CONDVAR(Industry, random, SLE_UINT16, 82, SL_MAX_VERSION),
/* reserve extra space in savegame here. (currently 32 bytes) */
SLE_CONDNULL(32, 2, SL_MAX_VERSION),
SLE_END()
};
static void Save_INDY()
{
Industry *ind;
/* Write the industries */
FOR_ALL_INDUSTRIES(ind) {
SlSetArrayIndex(ind->index);
SlObject(ind, _industry_desc);
}
}
/* Save and load the mapping between the industry/tile id on the map, and the grf file
* it came from. */
static const SaveLoad _industries_id_mapping_desc[] = {
SLE_VAR(EntityIDMapping, grfid, SLE_UINT32),
SLE_VAR(EntityIDMapping, entity_id, SLE_UINT8),
SLE_VAR(EntityIDMapping, substitute_id, SLE_UINT8),
SLE_END()
};
static void Save_IIDS()
{
uint i;
uint j = _industry_mngr.GetMaxMapping();
for (i = 0; i < j; i++) {
SlSetArrayIndex(i);
SlObject(&_industry_mngr.mapping_ID[i], _industries_id_mapping_desc);
}
}
static void Save_TIDS()
{
uint i;
uint j = _industile_mngr.GetMaxMapping();
for (i = 0; i < j; i++) {
SlSetArrayIndex(i);
SlObject(&_industile_mngr.mapping_ID[i], _industries_id_mapping_desc);
}
}
static void Load_INDY()
{
int index;
ResetIndustryCounts();
while ((index = SlIterateArray()) != -1) {
Industry *i = new (index) Industry();
SlObject(i, _industry_desc);
IncIndustryTypeCount(i->type);
}
}
static void Load_IIDS()
{
int index;
uint max_id;
/* clear the current mapping stored.
* This will create the manager if ever it is not yet done */
_industry_mngr.ResetMapping();
/* get boundary for the temporary map loader NUM_INDUSTRYTYPES? */
max_id = _industry_mngr.GetMaxMapping();
while ((index = SlIterateArray()) != -1) {
if ((uint)index >= max_id) break;
SlObject(&_industry_mngr.mapping_ID[index], _industries_id_mapping_desc);
}
}
static void Load_TIDS()
{
int index;
uint max_id;
/* clear the current mapping stored.
* This will create the manager if ever it is not yet done */
_industile_mngr.ResetMapping();
/* get boundary for the temporary map loader NUM_INDUSTILES? */
max_id = _industile_mngr.GetMaxMapping();
while ((index = SlIterateArray()) != -1) {
if ((uint)index >= max_id) break;
SlObject(&_industile_mngr.mapping_ID[index], _industries_id_mapping_desc);
}
}
extern const ChunkHandler _industry_chunk_handlers[] = {
{ 'INDY', Save_INDY, Load_INDY, CH_ARRAY},
{ 'IIDS', Save_IIDS, Load_IIDS, CH_ARRAY},
{ 'TIDS', Save_TIDS, Load_TIDS, CH_ARRAY | CH_LAST},
};

@ -0,0 +1,249 @@
/* $Id$ */
/** @file map_sl.cpp Code handling saving and loading of map */
#include "../stdafx.h"
#include "../tile_type.h"
#include "../map_func.h"
#include "../core/alloc_type.hpp"
#include "../core/bitmath_func.hpp"
#include "saveload.h"
static uint32 _map_dim_x;
static uint32 _map_dim_y;
static const SaveLoadGlobVarList _map_dimensions[] = {
SLEG_CONDVAR(_map_dim_x, SLE_UINT32, 6, SL_MAX_VERSION),
SLEG_CONDVAR(_map_dim_y, SLE_UINT32, 6, SL_MAX_VERSION),
SLEG_END()
};
static void Save_MAPS()
{
_map_dim_x = MapSizeX();
_map_dim_y = MapSizeY();
SlGlobList(_map_dimensions);
}
static void Load_MAPS()
{
SlGlobList(_map_dimensions);
AllocateMap(_map_dim_x, _map_dim_y);
}
enum {
MAP_SL_BUF_SIZE = 4096
};
static void Load_MAPT()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
for (TileIndex i = 0; i != size;) {
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].type_height = buf[j];
}
}
static void Save_MAPT()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
SlSetLength(size);
for (TileIndex i = 0; i != size;) {
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].type_height;
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
}
}
static void Load_MAP1()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
for (TileIndex i = 0; i != size;) {
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m1 = buf[j];
}
}
static void Save_MAP1()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
SlSetLength(size);
for (TileIndex i = 0; i != size;) {
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m1;
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
}
}
static void Load_MAP2()
{
SmallStackSafeStackAlloc<uint16, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
for (TileIndex i = 0; i != size;) {
SlArray(buf, MAP_SL_BUF_SIZE,
/* In those versions the m2 was 8 bits */
CheckSavegameVersion(5) ? SLE_FILE_U8 | SLE_VAR_U16 : SLE_UINT16
);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m2 = buf[j];
}
}
static void Save_MAP2()
{
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] = _m[i++].m2;
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT16);
}
}
static void Load_MAP3()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
for (TileIndex i = 0; i != size;) {
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m3 = buf[j];
}
}
static void Save_MAP3()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
SlSetLength(size);
for (TileIndex i = 0; i != size;) {
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m3;
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
}
}
static void Load_MAP4()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
for (TileIndex i = 0; i != size;) {
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m4 = buf[j];
}
}
static void Save_MAP4()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
SlSetLength(size);
for (TileIndex i = 0; i != size;) {
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m4;
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
}
}
static void Load_MAP5()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
for (TileIndex i = 0; i != size;) {
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m5 = buf[j];
}
}
static void Save_MAP5()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
SlSetLength(size);
for (TileIndex i = 0; i != size;) {
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m5;
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
}
}
static void Load_MAP6()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
if (CheckSavegameVersion(42)) {
for (TileIndex i = 0; i != size;) {
/* 1024, otherwise we overflow on 64x64 maps! */
SlArray(buf, 1024, SLE_UINT8);
for (uint j = 0; j != 1024; j++) {
_m[i++].m6 = GB(buf[j], 0, 2);
_m[i++].m6 = GB(buf[j], 2, 2);
_m[i++].m6 = GB(buf[j], 4, 2);
_m[i++].m6 = GB(buf[j], 6, 2);
}
}
} else {
for (TileIndex i = 0; i != size;) {
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _m[i++].m6 = buf[j];
}
}
}
static void Save_MAP6()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
SlSetLength(size);
for (TileIndex i = 0; i != size;) {
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _m[i++].m6;
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
}
}
static void Load_MAP7()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
for (TileIndex i = 0; i != size;) {
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) _me[i++].m7 = buf[j];
}
}
static void Save_MAP7()
{
SmallStackSafeStackAlloc<byte, MAP_SL_BUF_SIZE> buf;
TileIndex size = MapSize();
SlSetLength(size);
for (TileIndex i = 0; i != size;) {
for (uint j = 0; j != MAP_SL_BUF_SIZE; j++) buf[j] = _me[i++].m7;
SlArray(buf, MAP_SL_BUF_SIZE, SLE_UINT8);
}
}
extern const ChunkHandler _map_chunk_handlers[] = {
{ 'MAPS', Save_MAPS, Load_MAPS, CH_RIFF },
{ 'MAPT', Save_MAPT, Load_MAPT, CH_RIFF },
{ 'MAPO', Save_MAP1, Load_MAP1, CH_RIFF },
{ 'MAP2', Save_MAP2, Load_MAP2, CH_RIFF },
{ 'M3LO', Save_MAP3, Load_MAP3, CH_RIFF },
{ 'M3HI', Save_MAP4, Load_MAP4, CH_RIFF },
{ 'MAP5', Save_MAP5, Load_MAP5, CH_RIFF },
{ 'MAPE', Save_MAP6, Load_MAP6, CH_RIFF },
{ 'MAP7', Save_MAP7, Load_MAP7, CH_RIFF },
};

@ -0,0 +1,105 @@
/* $Id$ */
/** @file misc_sl.cpp Saving and loading of things that didn't fit anywhere else */
#include "../stdafx.h"
#include "../date_func.h"
#include "../variables.h"
#include "../core/random_func.hpp"
#include "../openttd.h"
#include "../tile_type.h"
#include "../zoom_func.h"
#include "../vehicle_func.h"
#include "../window_gui.h"
#include "../window_func.h"
#include "../viewport_func.h"
#include "../gfx_func.h"
#include "saveload.h"
extern TileIndex _cur_tileloop_tile;
/* Keep track of current game position */
int _saved_scrollpos_x;
int _saved_scrollpos_y;
void SaveViewportBeforeSaveGame()
{
const Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
if (w != NULL) {
_saved_scrollpos_x = w->viewport->scrollpos_x;
_saved_scrollpos_y = w->viewport->scrollpos_y;
_saved_scrollpos_zoom = w->viewport->zoom;
}
}
void ResetViewportAfterLoadGame()
{
Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
w->viewport->scrollpos_x = _saved_scrollpos_x;
w->viewport->scrollpos_y = _saved_scrollpos_y;
w->viewport->dest_scrollpos_x = _saved_scrollpos_x;
w->viewport->dest_scrollpos_y = _saved_scrollpos_y;
ViewPort *vp = w->viewport;
vp->zoom = min(_saved_scrollpos_zoom, ZOOM_LVL_MAX);
vp->virtual_width = ScaleByZoom(vp->width, vp->zoom);
vp->virtual_height = ScaleByZoom(vp->height, vp->zoom);
DoZoomInOutWindow(ZOOM_NONE, w); // update button status
MarkWholeScreenDirty();
}
static const SaveLoadGlobVarList _date_desc[] = {
SLEG_CONDVAR(_date, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
SLEG_CONDVAR(_date, SLE_INT32, 31, SL_MAX_VERSION),
SLEG_VAR(_date_fract, SLE_UINT16),
SLEG_VAR(_tick_counter, SLE_UINT16),
SLEG_VAR(_vehicle_id_ctr_day, SLE_UINT16),
SLEG_VAR(_age_cargo_skip_counter, SLE_UINT8),
SLE_CONDNULL(1, 0, 45),
SLEG_CONDVAR(_cur_tileloop_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLEG_CONDVAR(_cur_tileloop_tile, SLE_UINT32, 6, SL_MAX_VERSION),
SLEG_VAR(_disaster_delay, SLE_UINT16),
SLEG_VAR(_station_tick_ctr, SLE_UINT16),
SLEG_VAR(_random.state[0], SLE_UINT32),
SLEG_VAR(_random.state[1], SLE_UINT32),
SLEG_CONDVAR(_cur_town_ctr, SLE_FILE_U8 | SLE_VAR_U32, 0, 9),
SLEG_CONDVAR(_cur_town_ctr, SLE_UINT32, 10, SL_MAX_VERSION),
SLEG_VAR(_cur_company_tick_index, SLE_FILE_U8 | SLE_VAR_U32),
SLEG_VAR(_next_competitor_start, SLE_FILE_U16 | SLE_VAR_U32),
SLEG_VAR(_trees_tick_ctr, SLE_UINT8),
SLEG_CONDVAR(_pause_game, SLE_UINT8, 4, SL_MAX_VERSION),
SLEG_CONDVAR(_cur_town_iter, SLE_UINT32, 11, SL_MAX_VERSION),
SLEG_END()
};
/* Save load date related variables as well as persistent tick counters
* XXX: currently some unrelated stuff is just put here */
static void SaveLoad_DATE()
{
SlGlobList(_date_desc);
}
static const SaveLoadGlobVarList _view_desc[] = {
SLEG_CONDVAR(_saved_scrollpos_x, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
SLEG_CONDVAR(_saved_scrollpos_x, SLE_INT32, 6, SL_MAX_VERSION),
SLEG_CONDVAR(_saved_scrollpos_y, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
SLEG_CONDVAR(_saved_scrollpos_y, SLE_INT32, 6, SL_MAX_VERSION),
SLEG_VAR(_saved_scrollpos_zoom, SLE_UINT8),
SLEG_END()
};
static void SaveLoad_VIEW()
{
SlGlobList(_view_desc);
}
extern const ChunkHandler _misc_chunk_handlers[] = {
{ 'DATE', SaveLoad_DATE, SaveLoad_DATE, CH_RIFF},
{ 'VIEW', SaveLoad_VIEW, SaveLoad_VIEW, CH_RIFF | CH_LAST},
};

@ -0,0 +1,52 @@
/* $Id$ */
/** @file newgrf_sl.cpp Code handling saving and loading of newgrf config */
#include "../stdafx.h"
#include "../newgrf_config.h"
#include "../core/bitmath_func.hpp"
#include "../core/alloc_func.hpp"
#include "../gfx_func.h"
#include "saveload.h"
static const SaveLoad _grfconfig_desc[] = {
SLE_STR(GRFConfig, filename, SLE_STR, 0x40),
SLE_VAR(GRFConfig, grfid, SLE_UINT32),
SLE_ARR(GRFConfig, md5sum, SLE_UINT8, 16),
SLE_ARR(GRFConfig, param, SLE_UINT32, 0x80),
SLE_VAR(GRFConfig, num_params, SLE_UINT8),
SLE_CONDVAR(GRFConfig, windows_paletted, SLE_BOOL, 101, SL_MAX_VERSION),
SLE_END()
};
static void Save_NGRF()
{
int index = 0;
for (GRFConfig *c = _grfconfig; c != NULL; c = c->next) {
if (HasBit(c->flags, GCF_STATIC)) continue;
SlSetArrayIndex(index++);
SlObject(c, _grfconfig_desc);
}
}
static void Load_NGRF()
{
ClearGRFConfigList(&_grfconfig);
while (SlIterateArray() != -1) {
GRFConfig *c = CallocT<GRFConfig>(1);
SlObject(c, _grfconfig_desc);
if (CheckSavegameVersion(101)) c->windows_paletted = (_use_palette == PAL_WINDOWS);
AppendToGRFConfigList(&_grfconfig, c);
}
/* Append static NewGRF configuration */
AppendStaticGRFConfigs(&_grfconfig);
}
extern const ChunkHandler _newgrf_chunk_handlers[] = {
{ 'NGRF', Save_NGRF, Load_NGRF, CH_ARRAY | CH_LAST }
};

@ -2,34 +2,36 @@
/** @file oldloader.cpp Loading of old TTD(patch) savegames. */
#include "stdafx.h"
#include "openttd.h"
#include "station_map.h"
#include "town.h"
#include "industry.h"
#include "company_func.h"
#include "company_base.h"
#include "aircraft.h"
#include "roadveh.h"
#include "ship.h"
#include "train.h"
#include "signs_base.h"
#include "debug.h"
#include "depot_base.h"
#include "newgrf_config.h"
#include "ai/ai.h"
#include "ai/default/default.h"
#include "zoom_func.h"
#include "functions.h"
#include "date_func.h"
#include "vehicle_func.h"
#include "variables.h"
#include "saveload.h"
#include "strings_func.h"
#include "effectvehicle_base.h"
#include "../stdafx.h"
#include "../openttd.h"
#include "../station_map.h"
#include "../town.h"
#include "../industry.h"
#include "../company_func.h"
#include "../company_base.h"
#include "../aircraft.h"
#include "../roadveh.h"
#include "../ship.h"
#include "../train.h"
#include "../signs_base.h"
#include "../debug.h"
#include "../depot_base.h"
#include "../newgrf_config.h"
#include "../ai/ai.h"
#include "../ai/default/default.h"
#include "../zoom_func.h"
#include "../functions.h"
#include "../date_func.h"
#include "../vehicle_func.h"
#include "../variables.h"
#include "../strings_func.h"
#include "../effectvehicle_base.h"
#include "table/strings.h"
#include "saveload.h"
#include "saveload_internal.h"
enum {
HEADER_SIZE = 49,
BUFFER_SIZE = 4096,

@ -0,0 +1,203 @@
/* $Id$ */
/** @file order_sl.cpp Code handling saving and loading of orders */
#include "../stdafx.h"
#include "../order_base.h"
#include "../core/alloc_func.hpp"
#include "../settings_type.h"
#include "saveload.h"
void Order::ConvertFromOldSavegame()
{
uint8 old_flags = this->flags;
this->flags = 0;
/* First handle non-stop */
if (_settings_client.gui.sg_new_nonstop) {
/* OFB_NON_STOP */
this->SetNonStopType((old_flags & 8) ? ONSF_NO_STOP_AT_ANY_STATION : ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS);
} else {
this->SetNonStopType((old_flags & 8) ? ONSF_NO_STOP_AT_INTERMEDIATE_STATIONS : ONSF_STOP_EVERYWHERE);
}
switch (this->GetType()) {
/* Only a few types need the other savegame conversions. */
case OT_GOTO_DEPOT: case OT_GOTO_STATION: case OT_LOADING: break;
default: return;
}
if (this->GetType() != OT_GOTO_DEPOT) {
/* Then the load flags */
if ((old_flags & 2) != 0) { // OFB_UNLOAD
this->SetLoadType(OLFB_NO_LOAD);
} else if ((old_flags & 4) == 0) { // !OFB_FULL_LOAD
this->SetLoadType(OLF_LOAD_IF_POSSIBLE);
} else {
this->SetLoadType(_settings_client.gui.sg_full_load_any ? OLF_FULL_LOAD_ANY : OLFB_FULL_LOAD);
}
/* Finally fix the unload flags */
if ((old_flags & 1) != 0) { // OFB_TRANSFER
this->SetUnloadType(OUFB_TRANSFER);
} else if ((old_flags & 2) != 0) { // OFB_UNLOAD
this->SetUnloadType(OUFB_UNLOAD);
} else {
this->SetUnloadType(OUF_UNLOAD_IF_POSSIBLE);
}
} else {
/* Then the depot action flags */
this->SetDepotActionType(((old_flags & 6) == 4) ? ODATFB_HALT : ODATF_SERVICE_ONLY);
/* Finally fix the depot type flags */
uint t = ((old_flags & 6) == 6) ? ODTFB_SERVICE : ODTF_MANUAL;
if ((old_flags & 2) != 0) t |= ODTFB_PART_OF_ORDERS;
this->SetDepotOrderType((OrderDepotTypeFlags)t);
}
}
/** Unpacks a order from savegames with version 4 and lower
* @param packed packed order
* @return unpacked order
*/
static Order UnpackVersion4Order(uint16 packed)
{
return Order(GB(packed, 8, 8) << 16 | GB(packed, 4, 4) << 8 | GB(packed, 0, 4));
}
/** Unpacks a order from savegames made with TTD(Patch)
* @param packed packed order
* @return unpacked order
*/
Order UnpackOldOrder(uint16 packed)
{
Order order = UnpackVersion4Order(packed);
/*
* Sanity check
* TTD stores invalid orders as OT_NOTHING with non-zero flags/station
*/
if (!order.IsValid() && packed != 0) order.MakeDummy();
return order;
}
const SaveLoad *GetOrderDescription()
{
static const SaveLoad _order_desc[] = {
SLE_VAR(Order, type, SLE_UINT8),
SLE_VAR(Order, flags, SLE_UINT8),
SLE_VAR(Order, dest, SLE_UINT16),
SLE_REF(Order, next, REF_ORDER),
SLE_CONDVAR(Order, refit_cargo, SLE_UINT8, 36, SL_MAX_VERSION),
SLE_CONDVAR(Order, refit_subtype, SLE_UINT8, 36, SL_MAX_VERSION),
SLE_CONDVAR(Order, wait_time, SLE_UINT16, 67, SL_MAX_VERSION),
SLE_CONDVAR(Order, travel_time, SLE_UINT16, 67, SL_MAX_VERSION),
/* Leftover from the minor savegame version stuff
* We will never use those free bytes, but we have to keep this line to allow loading of old savegames */
SLE_CONDNULL(10, 5, 35),
SLE_END()
};
return _order_desc;
}
static void Save_ORDR()
{
Order *order;
FOR_ALL_ORDERS(order) {
SlSetArrayIndex(order->index);
SlObject(order, GetOrderDescription());
}
}
static void Load_ORDR()
{
if (CheckSavegameVersionOldStyle(5, 2)) {
/* Version older than 5.2 did not have a ->next pointer. Convert them
(in the old days, the orderlist was 5000 items big) */
size_t len = SlGetFieldLength();
uint i;
if (CheckSavegameVersion(5)) {
/* Pre-version 5 had an other layout for orders
(uint16 instead of uint32) */
len /= sizeof(uint16);
uint16 *orders = MallocT<uint16>(len + 1);
SlArray(orders, len, SLE_UINT16);
for (i = 0; i < len; ++i) {
Order *order = new (i) Order();
order->AssignOrder(UnpackVersion4Order(orders[i]));
}
free(orders);
} else if (CheckSavegameVersionOldStyle(5, 2)) {
len /= sizeof(uint16);
uint16 *orders = MallocT<uint16>(len + 1);
SlArray(orders, len, SLE_UINT32);
for (i = 0; i < len; ++i) {
new (i) Order(orders[i]);
}
free(orders);
}
/* Update all the next pointer */
for (i = 1; i < len; ++i) {
/* The orders were built like this:
* While the order is valid, set the previous will get it's next pointer set
* We start with index 1 because no order will have the first in it's next pointer */
if (GetOrder(i)->IsValid())
GetOrder(i - 1)->next = GetOrder(i);
}
} else {
int index;
while ((index = SlIterateArray()) != -1) {
Order *order = new (index) Order();
SlObject(order, GetOrderDescription());
}
}
}
const SaveLoad *GetOrderListDescription()
{
static const SaveLoad _orderlist_desc[] = {
SLE_REF(OrderList, first, REF_ORDER),
SLE_END()
};
return _orderlist_desc;
}
static void Save_ORDL()
{
OrderList *list;
FOR_ALL_ORDER_LISTS(list) {
SlSetArrayIndex(list->index);
SlObject(list, GetOrderListDescription());
}
}
static void Load_ORDL()
{
int index;
while ((index = SlIterateArray()) != -1) {
OrderList *list = new (index) OrderList();
SlObject(list, GetOrderListDescription());
}
}
extern const ChunkHandler _order_chunk_handlers[] = {
{ 'ORDR', Save_ORDR, Load_ORDR, CH_ARRAY},
{ 'ORDL', Save_ORDL, Load_ORDL, CH_ARRAY | CH_LAST},
};

@ -13,32 +13,35 @@
* <li>repeat this until everything is done, and flush any remaining output to file
* </ol>
*/
#include "stdafx.h"
#include "openttd.h"
#include "debug.h"
#include "station_base.h"
#include "thread.h"
#include "town.h"
#include "saveload.h"
#include "network/network.h"
#include "variables.h"
#include "window_func.h"
#include "strings_func.h"
#include "gfx_func.h"
#include "core/alloc_func.hpp"
#include "functions.h"
#include "core/endian_func.hpp"
#include "vehicle_base.h"
#include "company_func.h"
#include "date_func.h"
#include "autoreplace_base.h"
#include "statusbar_gui.h"
#include "fileio_func.h"
#include <list>
#include "gamelog.h"
#include "../stdafx.h"
#include "../openttd.h"
#include "../debug.h"
#include "../station_base.h"
#include "../thread.h"
#include "../town.h"
#include "../network/network.h"
#include "../variables.h"
#include "../window_func.h"
#include "../strings_func.h"
#include "../gfx_func.h"
#include "../core/alloc_func.hpp"
#include "../functions.h"
#include "../core/endian_func.hpp"
#include "../vehicle_base.h"
#include "../company_func.h"
#include "../date_func.h"
#include "../autoreplace_base.h"
#include "../statusbar_gui.h"
#include "../fileio_func.h"
#include "../gamelog.h"
#include "table/strings.h"
#include "saveload.h"
#include "saveload_internal.h"
#include <list>
extern const uint16 SAVEGAME_VERSION = 105;
SavegameType _savegame_type; ///< type of savegame we are loading
@ -1069,7 +1072,7 @@ static void SlLoadChunks()
*******************************************/
#define LZO_SIZE 8192
#include "minilzo.h"
#include "../minilzo.h"
static size_t ReadLZO()
{
@ -1157,8 +1160,8 @@ static void UninitNoComp()
********** START OF MEMORY CODE (in ram)****
********************************************/
#include "table/sprites.h"
#include "gui.h"
#include "../table/sprites.h"
#include "../gui.h"
struct ThreadedSave {
uint count;
@ -1298,6 +1301,7 @@ static void UninitWriteZlib()
/* these define the chunks */
extern const ChunkHandler _gamelog_chunk_handlers[];
extern const ChunkHandler _map_chunk_handlers[];
extern const ChunkHandler _misc_chunk_handlers[];
extern const ChunkHandler _name_chunk_handlers[];
extern const ChunkHandler _cheat_chunk_handlers[] ;
@ -1313,6 +1317,7 @@ extern const ChunkHandler _sign_chunk_handlers[];
extern const ChunkHandler _station_chunk_handlers[];
extern const ChunkHandler _industry_chunk_handlers[];
extern const ChunkHandler _economy_chunk_handlers[];
extern const ChunkHandler _subsidy_chunk_handlers[];
extern const ChunkHandler _animated_tile_chunk_handlers[];
extern const ChunkHandler _newgrf_chunk_handlers[];
extern const ChunkHandler _group_chunk_handlers[];
@ -1321,6 +1326,7 @@ extern const ChunkHandler _autoreplace_chunk_handlers[];
static const ChunkHandler * const _chunk_handlers[] = {
_gamelog_chunk_handlers,
_map_chunk_handlers,
_misc_chunk_handlers,
_name_chunk_handlers,
_cheat_chunk_handlers,
@ -1331,6 +1337,7 @@ static const ChunkHandler * const _chunk_handlers[] = {
_order_chunk_handlers,
_industry_chunk_handlers,
_economy_chunk_handlers,
_subsidy_chunk_handlers,
_engine_chunk_handlers,
_town_chunk_handlers,
_sign_chunk_handlers,
@ -1501,7 +1508,6 @@ static const SaveLoadFormat *GetSavegameFormat(const char *s)
/* actual loader/saver function */
void InitializeGame(uint size_x, uint size_y, bool reset_date);
extern bool AfterLoadGame();
extern void SaveViewportBeforeSaveGame();
extern bool LoadOldSaveGame(const char *file);
/** Small helper function to close the to be loaded savegame an signal error */

@ -5,7 +5,7 @@
#ifndef SAVELOAD_H
#define SAVELOAD_H
#include "fileio_type.h"
#include "../fileio_type.h"
#ifdef SIZE_MAX
#undef SIZE_MAX

@ -0,0 +1,40 @@
/* $Id$ */
/** @file saveload_internal.h Declaration of functions used in more save/load files */
#ifndef SAVELOAD_INTERNAL_H
#define SAVELOAD_INTERNAL_H
#include "../strings_type.h"
#include "../company_manager_face.h"
#include "../order_base.h"
void InitializeOldNames();
StringID RemapOldStringID(StringID s);
char *CopyFromOldName(StringID id);
void ResetOldNames();
void FixOldWaypoints();
void AfterLoadWaypoints();
void AfterLoadVehicles(bool part_of_load);
void AfterLoadStations();
void AfterLoadTown();
void UpdateHousesAndTowns();
void UpdateOldAircraft();
void SaveViewportBeforeSaveGame();
void ResetViewportAfterLoadGame();
void ConvertOldMultiheadToNew();
void ConnectMultiheadedTrains();
extern int32 _saved_scrollpos_x;
extern int32 _saved_scrollpos_y;
CompanyManagerFace ConvertFromOldCompanyManagerFace(uint32 face);
Order UnpackOldOrder(uint16 packed);
#endif /* SAVELOAD_INTERNAL_H */

@ -0,0 +1,49 @@
/* $Id$ */
/** @file signs_sl.cpp Code handling saving and loading of economy data */
#include "../stdafx.h"
#include "../strings_func.h"
#include "../company_func.h"
#include "../signs_base.h"
#include "../signs_func.h"
#include "saveload_internal.h"
#include "saveload.h"
static const SaveLoad _sign_desc[] = {
SLE_CONDVAR(Sign, name, SLE_NAME, 0, 83),
SLE_CONDSTR(Sign, name, SLE_STR, 0, 84, SL_MAX_VERSION),
SLE_CONDVAR(Sign, x, SLE_FILE_I16 | SLE_VAR_I32, 0, 4),
SLE_CONDVAR(Sign, y, SLE_FILE_I16 | SLE_VAR_I32, 0, 4),
SLE_CONDVAR(Sign, x, SLE_INT32, 5, SL_MAX_VERSION),
SLE_CONDVAR(Sign, y, SLE_INT32, 5, SL_MAX_VERSION),
SLE_CONDVAR(Sign, owner, SLE_UINT8, 6, SL_MAX_VERSION),
SLE_VAR(Sign, z, SLE_UINT8),
SLE_END()
};
/** Save all signs */
static void Save_SIGN()
{
Sign *si;
FOR_ALL_SIGNS(si) {
SlSetArrayIndex(si->index);
SlObject(si, _sign_desc);
}
}
/** Load all signs */
static void Load_SIGN()
{
int index;
while ((index = SlIterateArray()) != -1) {
Sign *si = new (index) Sign();
SlObject(si, _sign_desc);
}
}
extern const ChunkHandler _sign_chunk_handlers[] = {
{ 'SIGN', Save_SIGN, Load_SIGN, CH_ARRAY | CH_LAST},
};

@ -0,0 +1,227 @@
/* $Id$ */
/** @file station_sl.cpp Code handling saving and loading of economy data */
#include "../stdafx.h"
#include "../station_base.h"
#include "../core/bitmath_func.hpp"
#include "../core/alloc_func.hpp"
#include "../variables.h"
#include "../newgrf_station.h"
#include "saveload.h"
void AfterLoadStations()
{
/* Update the speclists of all stations to point to the currently loaded custom stations. */
Station *st;
FOR_ALL_STATIONS(st) {
for (uint i = 0; i < st->num_specs; i++) {
if (st->speclist[i].grfid == 0) continue;
st->speclist[i].spec = GetCustomStationSpecByGrf(st->speclist[i].grfid, st->speclist[i].localidx);
}
for (CargoID c = 0; c < NUM_CARGO; c++) st->goods[c].cargo.InvalidateCache();
StationUpdateAnimTriggers(st);
}
}
static const SaveLoad _roadstop_desc[] = {
SLE_VAR(RoadStop, xy, SLE_UINT32),
SLE_CONDNULL(1, 0, 44),
SLE_VAR(RoadStop, status, SLE_UINT8),
/* Index was saved in some versions, but this is not needed */
SLE_CONDNULL(4, 0, 8),
SLE_CONDNULL(2, 0, 44),
SLE_CONDNULL(1, 0, 25),
SLE_REF(RoadStop, next, REF_ROADSTOPS),
SLE_CONDNULL(2, 0, 44),
SLE_CONDNULL(4, 0, 24),
SLE_CONDNULL(1, 25, 25),
SLE_END()
};
static const SaveLoad _station_desc[] = {
SLE_CONDVAR(Station, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Station, xy, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDNULL(4, 0, 5), ///< bus/lorry tile
SLE_CONDVAR(Station, train_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Station, train_tile, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Station, airport_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Station, airport_tile, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Station, dock_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Station, dock_tile, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_REF(Station, town, REF_TOWN),
SLE_VAR(Station, trainst_w, SLE_UINT8),
SLE_CONDVAR(Station, trainst_h, SLE_UINT8, 2, SL_MAX_VERSION),
SLE_CONDNULL(1, 0, 3), ///< alpha_order
SLE_VAR(Station, string_id, SLE_STRINGID),
SLE_CONDSTR(Station, name, SLE_STR, 0, 84, SL_MAX_VERSION),
SLE_CONDVAR(Station, indtype, SLE_UINT8, 103, SL_MAX_VERSION),
SLE_VAR(Station, had_vehicle_of_type, SLE_UINT16),
SLE_VAR(Station, time_since_load, SLE_UINT8),
SLE_VAR(Station, time_since_unload, SLE_UINT8),
SLE_VAR(Station, delete_ctr, SLE_UINT8),
SLE_VAR(Station, owner, SLE_UINT8),
SLE_VAR(Station, facilities, SLE_UINT8),
SLE_VAR(Station, airport_type, SLE_UINT8),
SLE_CONDNULL(2, 0, 5), ///< Truck/bus stop status
SLE_CONDNULL(1, 0, 4), ///< Blocked months
SLE_CONDVAR(Station, airport_flags, SLE_VAR_U64 | SLE_FILE_U16, 0, 2),
SLE_CONDVAR(Station, airport_flags, SLE_VAR_U64 | SLE_FILE_U32, 3, 45),
SLE_CONDVAR(Station, airport_flags, SLE_UINT64, 46, SL_MAX_VERSION),
SLE_CONDNULL(2, 0, 25), ///< last-vehicle
SLE_CONDVAR(Station, last_vehicle_type, SLE_UINT8, 26, SL_MAX_VERSION),
SLE_CONDNULL(2, 3, 25), ///< custom station class and id
SLE_CONDVAR(Station, build_date, SLE_FILE_U16 | SLE_VAR_I32, 3, 30),
SLE_CONDVAR(Station, build_date, SLE_INT32, 31, SL_MAX_VERSION),
SLE_CONDREF(Station, bus_stops, REF_ROADSTOPS, 6, SL_MAX_VERSION),
SLE_CONDREF(Station, truck_stops, REF_ROADSTOPS, 6, SL_MAX_VERSION),
/* Used by newstations for graphic variations */
SLE_CONDVAR(Station, random_bits, SLE_UINT16, 27, SL_MAX_VERSION),
SLE_CONDVAR(Station, waiting_triggers, SLE_UINT8, 27, SL_MAX_VERSION),
SLE_CONDVAR(Station, num_specs, SLE_UINT8, 27, SL_MAX_VERSION),
SLE_CONDLST(Station, loading_vehicles, REF_VEHICLE, 57, SL_MAX_VERSION),
/* reserve extra space in savegame here. (currently 32 bytes) */
SLE_CONDNULL(32, 2, SL_MAX_VERSION),
SLE_END()
};
static uint16 _waiting_acceptance;
static uint16 _cargo_source;
static uint32 _cargo_source_xy;
static uint16 _cargo_days;
static Money _cargo_feeder_share;
static const SaveLoad _station_speclist_desc[] = {
SLE_CONDVAR(StationSpecList, grfid, SLE_UINT32, 27, SL_MAX_VERSION),
SLE_CONDVAR(StationSpecList, localidx, SLE_UINT8, 27, SL_MAX_VERSION),
SLE_END()
};
void SaveLoad_STNS(Station *st)
{
static const SaveLoad _goods_desc[] = {
SLEG_CONDVAR( _waiting_acceptance, SLE_UINT16, 0, 67),
SLE_CONDVAR(GoodsEntry, acceptance_pickup, SLE_UINT8, 68, SL_MAX_VERSION),
SLE_CONDNULL(2, 51, 67),
SLE_VAR(GoodsEntry, days_since_pickup, SLE_UINT8),
SLE_VAR(GoodsEntry, rating, SLE_UINT8),
SLEG_CONDVAR( _cargo_source, SLE_FILE_U8 | SLE_VAR_U16, 0, 6),
SLEG_CONDVAR( _cargo_source, SLE_UINT16, 7, 67),
SLEG_CONDVAR( _cargo_source_xy, SLE_UINT32, 44, 67),
SLEG_CONDVAR( _cargo_days, SLE_UINT8, 0, 67),
SLE_VAR(GoodsEntry, last_speed, SLE_UINT8),
SLE_VAR(GoodsEntry, last_age, SLE_UINT8),
SLEG_CONDVAR( _cargo_feeder_share, SLE_FILE_U32 | SLE_VAR_I64, 14, 64),
SLEG_CONDVAR( _cargo_feeder_share, SLE_INT64, 65, 67),
SLE_CONDLST(GoodsEntry, cargo.packets, REF_CARGO_PACKET, 68, SL_MAX_VERSION),
SLE_END()
};
SlObject(st, _station_desc);
_waiting_acceptance = 0;
uint num_cargo = CheckSavegameVersion(55) ? 12 : NUM_CARGO;
for (CargoID i = 0; i < num_cargo; i++) {
GoodsEntry *ge = &st->goods[i];
SlObject(ge, _goods_desc);
if (CheckSavegameVersion(68)) {
SB(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
if (GB(_waiting_acceptance, 0, 12) != 0) {
/* Don't construct the packet with station here, because that'll fail with old savegames */
CargoPacket *cp = new CargoPacket();
/* In old versions, enroute_from used 0xFF as INVALID_STATION */
cp->source = (CheckSavegameVersion(7) && _cargo_source == 0xFF) ? INVALID_STATION : _cargo_source;
cp->count = GB(_waiting_acceptance, 0, 12);
cp->days_in_transit = _cargo_days;
cp->feeder_share = _cargo_feeder_share;
cp->source_xy = _cargo_source_xy;
cp->days_in_transit = _cargo_days;
cp->feeder_share = _cargo_feeder_share;
SB(ge->acceptance_pickup, GoodsEntry::PICKUP, 1, 1);
ge->cargo.Append(cp);
}
}
}
if (st->num_specs != 0) {
/* Allocate speclist memory when loading a game */
if (st->speclist == NULL) st->speclist = CallocT<StationSpecList>(st->num_specs);
for (uint i = 0; i < st->num_specs; i++) {
SlObject(&st->speclist[i], _station_speclist_desc);
}
}
}
static void Save_STNS()
{
Station *st;
/* Write the stations */
FOR_ALL_STATIONS(st) {
SlSetArrayIndex(st->index);
SlAutolength((AutolengthProc*)SaveLoad_STNS, st);
}
}
static void Load_STNS()
{
int index;
while ((index = SlIterateArray()) != -1) {
Station *st = new (index) Station();
SaveLoad_STNS(st);
}
/* This is to ensure all pointers are within the limits of _stations_size */
if (_station_tick_ctr > GetMaxStationIndex()) _station_tick_ctr = 0;
}
static void Save_ROADSTOP()
{
RoadStop *rs;
FOR_ALL_ROADSTOPS(rs) {
SlSetArrayIndex(rs->index);
SlObject(rs, _roadstop_desc);
}
}
static void Load_ROADSTOP()
{
int index;
while ((index = SlIterateArray()) != -1) {
RoadStop *rs = new (index) RoadStop(INVALID_TILE);
SlObject(rs, _roadstop_desc);
}
}
extern const ChunkHandler _station_chunk_handlers[] = {
{ 'STNS', Save_STNS, Load_STNS, CH_ARRAY },
{ 'ROAD', Save_ROADSTOP, Load_ROADSTOP, CH_ARRAY | CH_LAST},
};

@ -0,0 +1,126 @@
/* $Id$ */
/** @file strings_sl.cpp Code handling saving and loading of strings */
#include "../stdafx.h"
#include "../strings_type.h"
#include "../core/math_func.hpp"
#include "../core/bitmath_func.hpp"
#include "../core/alloc_func.hpp"
#include "../string_func.h"
#include "table/strings.h"
#include "saveload.h"
/**
* Remap a string ID from the old format to the new format
* @param s StringID that requires remapping
* @return translated ID
*/
StringID RemapOldStringID(StringID s)
{
switch (s) {
case 0x0006: return STR_SV_EMPTY;
case 0x7000: return STR_SV_UNNAMED;
case 0x70E4: return SPECSTR_PLAYERNAME_ENGLISH;
case 0x70E9: return SPECSTR_PLAYERNAME_ENGLISH;
case 0x8864: return STR_SV_TRAIN_NAME;
case 0x902B: return STR_SV_ROADVEH_NAME;
case 0x9830: return STR_SV_SHIP_NAME;
case 0xA02F: return STR_SV_AIRCRAFT_NAME;
default:
if (IsInsideMM(s, 0x300F, 0x3030)) {
return s - 0x300F + STR_SV_STNAME;
} else {
return s;
}
}
}
/** Location to load the old names to. */
char *_old_name_array = NULL;
/**
* Copy and convert old custom names to UTF-8.
* They were all stored in a 512 by 32 long string array and are
* now stored with stations, waypoints and other places with names.
* @param id the StringID of the custom name to clone.
* @return the clones custom name.
*/
char *CopyFromOldName(StringID id)
{
/* Is this name an (old) custom name? */
if (GB(id, 11, 5) != 15) return NULL;
if (CheckSavegameVersion(37)) {
/* Old names were 32 characters long, so 128 characters should be
* plenty to allow for expansion when converted to UTF-8. */
char tmp[128];
const char *strfrom = &_old_name_array[32 * GB(id, 0, 9)];
char *strto = tmp;
for (; *strfrom != '\0'; strfrom++) {
WChar c = (byte)*strfrom;
/* Map from non-ISO8859-15 characters to UTF-8. */
switch (c) {
case 0xA4: c = 0x20AC; break; // Euro
case 0xA6: c = 0x0160; break; // S with caron
case 0xA8: c = 0x0161; break; // s with caron
case 0xB4: c = 0x017D; break; // Z with caron
case 0xB8: c = 0x017E; break; // z with caron
case 0xBC: c = 0x0152; break; // OE ligature
case 0xBD: c = 0x0153; break; // oe ligature
case 0xBE: c = 0x0178; break; // Y with diaresis
default: break;
}
/* Check character will fit into our buffer. */
if (strto + Utf8CharLen(c) > lastof(tmp)) break;
strto += Utf8Encode(strto, c);
}
/* Terminate the new string and copy it back to the name array */
*strto = '\0';
return strdup(tmp);
} else {
/* Name will already be in UTF-8. */
return strdup(&_old_name_array[32 * GB(id, 0, 9)]);
}
}
/**
* Free the memory of the old names array.
* Should be called once the old names have all been converted.
*/
void ResetOldNames()
{
free(_old_name_array);
_old_name_array = NULL;
}
/**
* Initialize the old names table memory.
*/
void InitializeOldNames()
{
free(_old_name_array);
_old_name_array = CallocT<char>(512 * 32);
}
static void Load_NAME()
{
int index;
while ((index = SlIterateArray()) != -1) {
SlArray(&_old_name_array[32 * index], SlGetFieldLength(), SLE_UINT8);
}
}
extern const ChunkHandler _name_chunk_handlers[] = {
{ 'NAME', NULL, Load_NAME, CH_ARRAY | CH_LAST},
};

@ -0,0 +1,43 @@
/* $Id$ */
/** @file subsidy_sl.cpp Code handling saving and loading of subsidies */
#include "../stdafx.h"
#include "../economy_func.h"
#include "saveload.h"
static const SaveLoad _subsidies_desc[] = {
SLE_VAR(Subsidy, cargo_type, SLE_UINT8),
SLE_VAR(Subsidy, age, SLE_UINT8),
SLE_CONDVAR(Subsidy, from, SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
SLE_CONDVAR(Subsidy, from, SLE_UINT16, 5, SL_MAX_VERSION),
SLE_CONDVAR(Subsidy, to, SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
SLE_CONDVAR(Subsidy, to, SLE_UINT16, 5, SL_MAX_VERSION),
SLE_END()
};
void Save_SUBS()
{
int i;
Subsidy *s;
for (i = 0; i != lengthof(_subsidies); i++) {
s = &_subsidies[i];
if (s->cargo_type != CT_INVALID) {
SlSetArrayIndex(i);
SlObject(s, _subsidies_desc);
}
}
}
void Load_SUBS()
{
int index;
while ((index = SlIterateArray()) != -1)
SlObject(&_subsidies[index], _subsidies_desc);
}
extern const ChunkHandler _subsidy_chunk_handlers[] = {
{ 'SUBS', Save_SUBS, Load_SUBS, CH_ARRAY},
};

@ -0,0 +1,210 @@
/* $Id$ */
/** @file town_sl.cpp Code handling saving and loading of towns and houses */
#include "../stdafx.h"
#include "../town.h"
#include "../newgrf_house.h"
#include "../newgrf_commons.h"
#include "../variables.h"
#include "../tile_map.h"
#include "../town_map.h"
#include "saveload.h"
extern uint _total_towns;
/**
* Check and update town and house values.
*
* Checked are the HouseIDs. Updated are the
* town population the number of houses per
* town, the town radius and the max passengers
* of the town.
*/
void UpdateHousesAndTowns()
{
Town *town;
InitializeBuildingCounts();
/* Reset town population and num_houses */
FOR_ALL_TOWNS(town) {
town->population = 0;
town->num_houses = 0;
}
for (TileIndex t = 0; t < MapSize(); t++) {
HouseID house_id;
if (!IsTileType(t, MP_HOUSE)) continue;
house_id = GetHouseType(t);
if (!GetHouseSpecs(house_id)->enabled && house_id >= NEW_HOUSE_OFFSET) {
/* The specs for this type of house are not available any more, so
* replace it with the substitute original house type. */
house_id = _house_mngr.GetSubstituteID(house_id);
SetHouseType(t, house_id);
}
town = GetTownByTile(t);
IncreaseBuildingCount(town, house_id);
if (IsHouseCompleted(t)) town->population += GetHouseSpecs(house_id)->population;
/* Increase the number of houses for every house, but only once. */
if (GetHouseNorthPart(house_id) == 0) town->num_houses++;
}
/* Update the population and num_house dependant values */
FOR_ALL_TOWNS(town) {
UpdateTownRadius(town);
UpdateTownMaxPass(town);
}
}
/** Save and load of towns. */
static const SaveLoad _town_desc[] = {
SLE_CONDVAR(Town, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Town, xy, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDNULL(2, 0, 2), ///< population, no longer in use
SLE_CONDNULL(4, 3, 84), ///< population, no longer in use
SLE_CONDNULL(2, 0, 91), ///< num_houses, no longer in use
SLE_CONDVAR(Town, townnamegrfid, SLE_UINT32, 66, SL_MAX_VERSION),
SLE_VAR(Town, townnametype, SLE_UINT16),
SLE_VAR(Town, townnameparts, SLE_UINT32),
SLE_CONDSTR(Town, name, SLE_STR, 0, 84, SL_MAX_VERSION),
SLE_VAR(Town, flags12, SLE_UINT8),
SLE_CONDVAR(Town, statues, SLE_FILE_U8 | SLE_VAR_U16, 0, 103),
SLE_CONDVAR(Town, statues, SLE_UINT16, 104, SL_MAX_VERSION),
SLE_CONDNULL(1, 0, 1), ///< sort_index, no longer in use
SLE_CONDVAR(Town, have_ratings, SLE_FILE_U8 | SLE_VAR_U16, 0, 103),
SLE_CONDVAR(Town, have_ratings, SLE_UINT16, 104, SL_MAX_VERSION),
SLE_CONDARR(Town, ratings, SLE_INT16, 8, 0, 103),
SLE_CONDARR(Town, ratings, SLE_INT16, MAX_COMPANIES, 104, SL_MAX_VERSION),
/* failed bribe attempts are stored since savegame format 4 */
SLE_CONDARR(Town, unwanted, SLE_INT8, 8, 4, 103),
SLE_CONDARR(Town, unwanted, SLE_INT8, MAX_COMPANIES, 104, SL_MAX_VERSION),
SLE_CONDVAR(Town, max_pass, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
SLE_CONDVAR(Town, max_mail, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
SLE_CONDVAR(Town, new_max_pass, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
SLE_CONDVAR(Town, new_max_mail, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
SLE_CONDVAR(Town, act_pass, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
SLE_CONDVAR(Town, act_mail, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
SLE_CONDVAR(Town, new_act_pass, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
SLE_CONDVAR(Town, new_act_mail, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
SLE_CONDVAR(Town, max_pass, SLE_UINT32, 9, SL_MAX_VERSION),
SLE_CONDVAR(Town, max_mail, SLE_UINT32, 9, SL_MAX_VERSION),
SLE_CONDVAR(Town, new_max_pass, SLE_UINT32, 9, SL_MAX_VERSION),
SLE_CONDVAR(Town, new_max_mail, SLE_UINT32, 9, SL_MAX_VERSION),
SLE_CONDVAR(Town, act_pass, SLE_UINT32, 9, SL_MAX_VERSION),
SLE_CONDVAR(Town, act_mail, SLE_UINT32, 9, SL_MAX_VERSION),
SLE_CONDVAR(Town, new_act_pass, SLE_UINT32, 9, SL_MAX_VERSION),
SLE_CONDVAR(Town, new_act_mail, SLE_UINT32, 9, SL_MAX_VERSION),
SLE_VAR(Town, pct_pass_transported, SLE_UINT8),
SLE_VAR(Town, pct_mail_transported, SLE_UINT8),
SLE_VAR(Town, act_food, SLE_UINT16),
SLE_VAR(Town, act_water, SLE_UINT16),
SLE_VAR(Town, new_act_food, SLE_UINT16),
SLE_VAR(Town, new_act_water, SLE_UINT16),
SLE_CONDVAR(Town, time_until_rebuild, SLE_UINT8, 0, 53),
SLE_CONDVAR(Town, grow_counter, SLE_UINT8, 0, 53),
SLE_CONDVAR(Town, growth_rate, SLE_UINT8, 0, 53),
SLE_CONDVAR(Town, time_until_rebuild, SLE_UINT16, 54, SL_MAX_VERSION),
SLE_CONDVAR(Town, grow_counter, SLE_UINT16, 54, SL_MAX_VERSION),
SLE_CONDVAR(Town, growth_rate, SLE_INT16, 54, SL_MAX_VERSION),
SLE_VAR(Town, fund_buildings_months, SLE_UINT8),
SLE_VAR(Town, road_build_months, SLE_UINT8),
SLE_CONDVAR(Town, exclusivity, SLE_UINT8, 2, SL_MAX_VERSION),
SLE_CONDVAR(Town, exclusive_counter, SLE_UINT8, 2, SL_MAX_VERSION),
SLE_CONDVAR(Town, larger_town, SLE_BOOL, 56, SL_MAX_VERSION),
/* reserve extra space in savegame here. (currently 30 bytes) */
SLE_CONDNULL(30, 2, SL_MAX_VERSION),
SLE_END()
};
/* Save and load the mapping between the house id on the map, and the grf file
* it came from. */
static const SaveLoad _house_id_mapping_desc[] = {
SLE_VAR(EntityIDMapping, grfid, SLE_UINT32),
SLE_VAR(EntityIDMapping, entity_id, SLE_UINT8),
SLE_VAR(EntityIDMapping, substitute_id, SLE_UINT8),
SLE_END()
};
static void Save_HOUSEIDS()
{
uint j = _house_mngr.GetMaxMapping();
for (uint i = 0; i < j; i++) {
SlSetArrayIndex(i);
SlObject(&_house_mngr.mapping_ID[i], _house_id_mapping_desc);
}
}
static void Load_HOUSEIDS()
{
int index;
_house_mngr.ResetMapping();
uint max_id = _house_mngr.GetMaxMapping();
while ((index = SlIterateArray()) != -1) {
if ((uint)index >= max_id) break;
SlObject(&_house_mngr.mapping_ID[index], _house_id_mapping_desc);
}
}
static void Save_TOWN()
{
Town *t;
FOR_ALL_TOWNS(t) {
SlSetArrayIndex(t->index);
SlObject(t, _town_desc);
}
}
static void Load_TOWN()
{
int index;
_total_towns = 0;
while ((index = SlIterateArray()) != -1) {
Town *t = new (index) Town();
SlObject(t, _town_desc);
_total_towns++;
}
/* This is to ensure all pointers are within the limits of
* the size of the TownPool */
if (_cur_town_ctr > GetMaxTownIndex())
_cur_town_ctr = 0;
}
void AfterLoadTown()
{
Town *t;
FOR_ALL_TOWNS(t) t->InitializeLayout();
}
extern const ChunkHandler _town_chunk_handlers[] = {
{ 'HIDS', Save_HOUSEIDS, Load_HOUSEIDS, CH_ARRAY },
{ 'CITY', Save_TOWN, Load_TOWN, CH_ARRAY | CH_LAST},
};

@ -0,0 +1,670 @@
/* $Id$ */
/** @file vehicle_sl.cpp Code handling saving and loading of vehicles */
#include "../stdafx.h"
#include "../vehicle_base.h"
#include "../vehicle_func.h"
#include "../train.h"
#include "../roadveh.h"
#include "../ship.h"
#include "../aircraft.h"
#include "../effectvehicle_base.h"
#include "saveload.h"
#include <map>
/*
* Link front and rear multiheaded engines to each other
* This is done when loading a savegame
*/
void ConnectMultiheadedTrains()
{
Vehicle *v;
FOR_ALL_VEHICLES(v) {
if (v->type == VEH_TRAIN) {
v->u.rail.other_multiheaded_part = NULL;
}
}
FOR_ALL_VEHICLES(v) {
if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) {
/* Two ways to associate multiheaded parts to each other:
* sequential-matching: Trains shall be arranged to look like <..>..<..>..<..>..
* bracket-matching: Free vehicle chains shall be arranged to look like ..<..<..>..<..>..>..
*
* Note: Old savegames might contain chains which do not comply with these rules, e.g.
* - the front and read parts have invalid orders
* - different engine types might be combined
* - there might be different amounts of front and rear parts.
*
* Note: The multiheaded parts need to be matched exactly like they are matched on the server, else desyncs will occur.
* This is why two matching strategies are needed.
*/
bool sequential_matching = IsFrontEngine(v);
for (Vehicle *u = v; u != NULL; u = GetNextVehicle(u)) {
if (u->u.rail.other_multiheaded_part != NULL) continue; // we already linked this one
if (IsMultiheaded(u)) {
if (!IsTrainEngine(u)) {
/* we got a rear car without a front car. We will convert it to a front one */
SetTrainEngine(u);
u->spritenum--;
}
/* Find a matching back part */
EngineID eid = u->engine_type;
Vehicle *w;
if (sequential_matching) {
for (w = GetNextVehicle(u); w != NULL; w = GetNextVehicle(w)) {
if (w->engine_type != eid || w->u.rail.other_multiheaded_part != NULL || !IsMultiheaded(w)) continue;
/* we found a car to partner with this engine. Now we will make sure it face the right way */
if (IsTrainEngine(w)) {
ClearTrainEngine(w);
w->spritenum++;
}
break;
}
} else {
uint stack_pos = 0;
for (w = GetNextVehicle(u); w != NULL; w = GetNextVehicle(w)) {
if (w->engine_type != eid || w->u.rail.other_multiheaded_part != NULL || !IsMultiheaded(w)) continue;
if (IsTrainEngine(w)) {
stack_pos++;
} else {
if (stack_pos == 0) break;
stack_pos--;
}
}
}
if (w != NULL) {
w->u.rail.other_multiheaded_part = u;
u->u.rail.other_multiheaded_part = w;
} else {
/* we got a front car and no rear cars. We will fake this one for forget that it should have been multiheaded */
ClearMultiheaded(u);
}
}
}
}
}
}
/**
* Converts all trains to the new subtype format introduced in savegame 16.2
* It also links multiheaded engines or make them forget they are multiheaded if no suitable partner is found
*/
void ConvertOldMultiheadToNew()
{
Vehicle *v;
FOR_ALL_VEHICLES(v) {
if (v->type == VEH_TRAIN) {
SetBit(v->subtype, 7); // indicates that it's the old format and needs to be converted in the next loop
}
}
FOR_ALL_VEHICLES(v) {
if (v->type == VEH_TRAIN) {
if (HasBit(v->subtype, 7) && ((v->subtype & ~0x80) == 0 || (v->subtype & ~0x80) == 4)) {
for (Vehicle *u = v; u != NULL; u = u->Next()) {
const RailVehicleInfo *rvi = RailVehInfo(u->engine_type);
ClrBit(u->subtype, 7);
switch (u->subtype) {
case 0: /* TS_Front_Engine */
if (rvi->railveh_type == RAILVEH_MULTIHEAD) SetMultiheaded(u);
SetFrontEngine(u);
SetTrainEngine(u);
break;
case 1: /* TS_Artic_Part */
u->subtype = 0;
SetArticulatedPart(u);
break;
case 2: /* TS_Not_First */
u->subtype = 0;
if (rvi->railveh_type == RAILVEH_WAGON) {
// normal wagon
SetTrainWagon(u);
break;
}
if (rvi->railveh_type == RAILVEH_MULTIHEAD && rvi->image_index == u->spritenum - 1) {
// rear end of a multiheaded engine
SetMultiheaded(u);
break;
}
if (rvi->railveh_type == RAILVEH_MULTIHEAD) SetMultiheaded(u);
SetTrainEngine(u);
break;
case 4: /* TS_Free_Car */
u->subtype = 0;
SetTrainWagon(u);
SetFreeWagon(u);
break;
default: NOT_REACHED(); break;
}
}
}
}
}
}
/** need to be called to load aircraft from old version */
void UpdateOldAircraft()
{
/* set airport_flags to 0 for all airports just to be sure */
Station *st;
FOR_ALL_STATIONS(st) {
st->airport_flags = 0; // reset airport
}
Vehicle *v_oldstyle;
FOR_ALL_VEHICLES(v_oldstyle) {
/* airplane has another vehicle with subtype 4 (shadow), helicopter also has 3 (rotor)
* skip those */
if (v_oldstyle->type == VEH_AIRCRAFT && IsNormalAircraft(v_oldstyle)) {
/* airplane in terminal stopped doesn't hurt anyone, so goto next */
if (v_oldstyle->vehstatus & VS_STOPPED && v_oldstyle->u.air.state == 0) {
v_oldstyle->u.air.state = HANGAR;
continue;
}
AircraftLeaveHangar(v_oldstyle); // make airplane visible if it was in a depot for example
v_oldstyle->vehstatus &= ~VS_STOPPED; // make airplane moving
v_oldstyle->u.air.state = FLYING;
AircraftNextAirportPos_and_Order(v_oldstyle); // move it to the entry point of the airport
GetNewVehiclePosResult gp = GetNewVehiclePos(v_oldstyle);
v_oldstyle->tile = 0; // aircraft in air is tile=0
/* correct speed of helicopter-rotors */
if (v_oldstyle->subtype == AIR_HELICOPTER) v_oldstyle->Next()->Next()->cur_speed = 32;
/* set new position x,y,z */
SetAircraftPosition(v_oldstyle, gp.x, gp.y, GetAircraftFlyingAltitude(v_oldstyle));
}
}
}
/** Called after load to update coordinates */
void AfterLoadVehicles(bool part_of_load)
{
Vehicle *v;
FOR_ALL_VEHICLES(v) {
/* Reinstate the previous pointer */
if (v->Next() != NULL) v->Next()->previous = v;
if (v->NextShared() != NULL) v->NextShared()->previous_shared = v;
v->UpdateDeltaXY(v->direction);
if (part_of_load) v->fill_percent_te_id = INVALID_TE_ID;
v->first = NULL;
if (v->type == VEH_TRAIN) v->u.rail.first_engine = INVALID_ENGINE;
if (v->type == VEH_ROAD) v->u.road.first_engine = INVALID_ENGINE;
v->cargo.InvalidateCache();
}
/* AfterLoadVehicles may also be called in case of NewGRF reload, in this
* case we may not convert orders again. */
if (part_of_load) {
/* Create shared vehicle chain for very old games (pre 5,2) and create
* OrderList from shared vehicle chains. For this to work correctly, the
* following conditions must be fulfilled:
* a) both next_shared and previous_shared are not set for pre 5,2 games
* b) both next_shared and previous_shared are set for later games
*/
std::map<Order*, OrderList*> mapping;
FOR_ALL_VEHICLES(v) {
if (v->orders.old != NULL) {
if (CheckSavegameVersion(105)) { // Pre-105 didn't save an OrderList
if (mapping[v->orders.old] == NULL) {
/* This adds the whole shared vehicle chain for case b */
v->orders.list = mapping[v->orders.old] = new OrderList(v->orders.old, v);
} else {
v->orders.list = mapping[v->orders.old];
/* For old games (case a) we must create the shared vehicle chain */
if (CheckSavegameVersionOldStyle(5, 2)) {
v->AddToShared(v->orders.list->GetFirstSharedVehicle());
}
}
} else { // OrderList was saved as such, only recalculate not saved values
if (v->PreviousShared() == NULL) {
new (v->orders.list) OrderList(v->orders.list->GetFirstOrder(), v);
}
}
}
}
}
FOR_ALL_VEHICLES(v) {
/* Fill the first pointers */
if (v->Previous() == NULL) {
for (Vehicle *u = v; u != NULL; u = u->Next()) {
u->first = v;
}
}
}
FOR_ALL_VEHICLES(v) {
assert(v->first != NULL);
if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) {
if (IsFrontEngine(v)) v->u.rail.last_speed = v->cur_speed; // update displayed train speed
TrainConsistChanged(v, false);
} else if (v->type == VEH_ROAD && IsRoadVehFront(v)) {
RoadVehUpdateCache(v);
}
}
/* Stop non-front engines */
FOR_ALL_VEHICLES(v) {
if (v->type == VEH_TRAIN && IsTrainEngine(v) && !IsFrontEngine(v)) v->vehstatus |= VS_STOPPED;
}
FOR_ALL_VEHICLES(v) {
switch (v->type) {
case VEH_ROAD:
v->u.road.roadtype = HasBit(EngInfo(v->engine_type)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD;
v->u.road.compatible_roadtypes = RoadTypeToRoadTypes(v->u.road.roadtype);
/* FALL THROUGH */
case VEH_TRAIN:
case VEH_SHIP:
v->cur_image = v->GetImage(v->direction);
break;
case VEH_AIRCRAFT:
if (IsNormalAircraft(v)) {
v->cur_image = v->GetImage(v->direction);
/* The plane's shadow will have the same image as the plane */
Vehicle *shadow = v->Next();
shadow->cur_image = v->cur_image;
/* In the case of a helicopter we will update the rotor sprites */
if (v->subtype == AIR_HELICOPTER) {
Vehicle *rotor = shadow->Next();
rotor->cur_image = GetRotorImage(v);
}
UpdateAircraftCache(v);
}
break;
default: break;
}
v->left_coord = INVALID_COORD;
VehiclePositionChanged(v);
}
}
static uint8 _cargo_days;
static uint16 _cargo_source;
static uint32 _cargo_source_xy;
static uint16 _cargo_count;
static uint16 _cargo_paid_for;
static Money _cargo_feeder_share;
static uint32 _cargo_loaded_at_xy;
/**
* Make it possible to make the saveload tables "friends" of other classes.
* @param vt the vehicle type. Can be VEH_END for the common vehicle description data
* @return the saveload description
*/
const SaveLoad *GetVehicleDescription(VehicleType vt)
{
/** Save and load of vehicles */
static const SaveLoad _common_veh_desc[] = {
SLE_VAR(Vehicle, subtype, SLE_UINT8),
SLE_REF(Vehicle, next, REF_VEHICLE_OLD),
SLE_CONDVAR(Vehicle, name, SLE_NAME, 0, 83),
SLE_CONDSTR(Vehicle, name, SLE_STR, 0, 84, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, unitnumber, SLE_FILE_U8 | SLE_VAR_U16, 0, 7),
SLE_CONDVAR(Vehicle, unitnumber, SLE_UINT16, 8, SL_MAX_VERSION),
SLE_VAR(Vehicle, owner, SLE_UINT8),
SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Vehicle, tile, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, dest_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Vehicle, dest_tile, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, x_pos, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Vehicle, x_pos, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, y_pos, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Vehicle, y_pos, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_VAR(Vehicle, z_pos, SLE_UINT8),
SLE_VAR(Vehicle, direction, SLE_UINT8),
SLE_CONDNULL(2, 0, 57),
SLE_VAR(Vehicle, spritenum, SLE_UINT8),
SLE_CONDNULL(5, 0, 57),
SLE_VAR(Vehicle, engine_type, SLE_UINT16),
SLE_VAR(Vehicle, max_speed, SLE_UINT16),
SLE_VAR(Vehicle, cur_speed, SLE_UINT16),
SLE_VAR(Vehicle, subspeed, SLE_UINT8),
SLE_VAR(Vehicle, acceleration, SLE_UINT8),
SLE_VAR(Vehicle, progress, SLE_UINT8),
SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
SLE_CONDVAR(Vehicle, last_station_visited, SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
SLE_CONDVAR(Vehicle, last_station_visited, SLE_UINT16, 5, SL_MAX_VERSION),
SLE_VAR(Vehicle, cargo_type, SLE_UINT8),
SLE_CONDVAR(Vehicle, cargo_subtype, SLE_UINT8, 35, SL_MAX_VERSION),
SLEG_CONDVAR( _cargo_days, SLE_UINT8, 0, 67),
SLEG_CONDVAR( _cargo_source, SLE_FILE_U8 | SLE_VAR_U16, 0, 6),
SLEG_CONDVAR( _cargo_source, SLE_UINT16, 7, 67),
SLEG_CONDVAR( _cargo_source_xy, SLE_UINT32, 44, 67),
SLE_VAR(Vehicle, cargo_cap, SLE_UINT16),
SLEG_CONDVAR( _cargo_count, SLE_UINT16, 0, 67),
SLE_CONDLST(Vehicle, cargo, REF_CARGO_PACKET, 68, SL_MAX_VERSION),
SLE_VAR(Vehicle, day_counter, SLE_UINT8),
SLE_VAR(Vehicle, tick_counter, SLE_UINT8),
SLE_CONDVAR(Vehicle, running_ticks, SLE_UINT8, 88, SL_MAX_VERSION),
SLE_VAR(Vehicle, cur_order_index, SLE_UINT8),
/* num_orders is now part of OrderList and is not saved but counted */
SLE_CONDNULL(1, 0, 104),
/* This next line is for version 4 and prior compatibility.. it temporarily reads
type and flags (which were both 4 bits) into type. Later on this is
converted correctly */
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, type), SLE_UINT8, 0, 4),
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
/* Orders for version 5 and on */
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, type), SLE_UINT8, 5, SL_MAX_VERSION),
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, flags), SLE_UINT8, 5, SL_MAX_VERSION),
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_UINT16, 5, SL_MAX_VERSION),
/* Refit in current order */
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, refit_cargo), SLE_UINT8, 36, SL_MAX_VERSION),
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, refit_subtype), SLE_UINT8, 36, SL_MAX_VERSION),
/* Timetable in current order */
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, wait_time), SLE_UINT16, 67, SL_MAX_VERSION),
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, travel_time), SLE_UINT16, 67, SL_MAX_VERSION),
SLE_CONDREF(Vehicle, orders, REF_ORDER, 0, 104),
SLE_CONDREF(Vehicle, orders, REF_ORDERLIST, 105, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
SLE_CONDVAR(Vehicle, age, SLE_INT32, 31, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, max_age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
SLE_CONDVAR(Vehicle, max_age, SLE_INT32, 31, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, date_of_last_service, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
SLE_CONDVAR(Vehicle, date_of_last_service, SLE_INT32, 31, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, service_interval, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
SLE_CONDVAR(Vehicle, service_interval, SLE_INT32, 31, SL_MAX_VERSION),
SLE_VAR(Vehicle, reliability, SLE_UINT16),
SLE_VAR(Vehicle, reliability_spd_dec, SLE_UINT16),
SLE_VAR(Vehicle, breakdown_ctr, SLE_UINT8),
SLE_VAR(Vehicle, breakdown_delay, SLE_UINT8),
SLE_VAR(Vehicle, breakdowns_since_last_service, SLE_UINT8),
SLE_VAR(Vehicle, breakdown_chance, SLE_UINT8),
SLE_CONDVAR(Vehicle, build_year, SLE_FILE_U8 | SLE_VAR_I32, 0, 30),
SLE_CONDVAR(Vehicle, build_year, SLE_INT32, 31, SL_MAX_VERSION),
SLE_VAR(Vehicle, load_unload_time_rem, SLE_UINT16),
SLEG_CONDVAR( _cargo_paid_for, SLE_UINT16, 45, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, vehicle_flags, SLE_UINT8, 40, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, profit_this_year, SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
SLE_CONDVAR(Vehicle, profit_this_year, SLE_INT64, 65, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, profit_last_year, SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
SLE_CONDVAR(Vehicle, profit_last_year, SLE_INT64, 65, SL_MAX_VERSION),
SLEG_CONDVAR( _cargo_feeder_share, SLE_FILE_I32 | SLE_VAR_I64, 51, 64),
SLEG_CONDVAR( _cargo_feeder_share, SLE_INT64, 65, 67),
SLEG_CONDVAR( _cargo_loaded_at_xy, SLE_UINT32, 51, 67),
SLE_CONDVAR(Vehicle, value, SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
SLE_CONDVAR(Vehicle, value, SLE_INT64, 65, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, random_bits, SLE_UINT8, 2, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, waiting_triggers, SLE_UINT8, 2, SL_MAX_VERSION),
SLE_CONDREF(Vehicle, next_shared, REF_VEHICLE, 2, SL_MAX_VERSION),
SLE_CONDNULL(2, 2, 68),
SLE_CONDNULL(4, 69, 100),
SLE_CONDVAR(Vehicle, group_id, SLE_UINT16, 60, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, current_order_time, SLE_UINT32, 67, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, lateness_counter, SLE_INT32, 67, SL_MAX_VERSION),
/* reserve extra space in savegame here. (currently 10 bytes) */
SLE_CONDNULL(10, 2, SL_MAX_VERSION),
SLE_END()
};
static const SaveLoad _train_desc[] = {
SLE_WRITEBYTE(Vehicle, type, VEH_TRAIN),
SLE_VEH_INCLUDEX(),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, crash_anim_pos), SLE_UINT16),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, force_proceed), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, railtype), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, track), SLE_UINT8),
SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, flags), SLE_FILE_U8 | SLE_VAR_U16, 2, 99),
SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, flags), SLE_UINT16, 100, SL_MAX_VERSION),
SLE_CONDNULL(2, 2, 59),
SLE_CONDNULL(2, 2, 19),
/* reserve extra space in savegame here. (currently 11 bytes) */
SLE_CONDNULL(11, 2, SL_MAX_VERSION),
SLE_END()
};
static const SaveLoad _roadveh_desc[] = {
SLE_WRITEBYTE(Vehicle, type, VEH_ROAD),
SLE_VEH_INCLUDEX(),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, state), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, frame), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, blocked_ctr), SLE_UINT16),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, overtaking), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, overtaking_ctr), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, crashed_ctr), SLE_UINT16),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, reverse_ctr), SLE_UINT8),
SLE_CONDREFX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, slot), REF_ROADSTOPS, 6, SL_MAX_VERSION),
SLE_CONDNULL(1, 6, SL_MAX_VERSION),
SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, slot_age), SLE_UINT8, 6, SL_MAX_VERSION),
/* reserve extra space in savegame here. (currently 16 bytes) */
SLE_CONDNULL(16, 2, SL_MAX_VERSION),
SLE_END()
};
static const SaveLoad _ship_desc[] = {
SLE_WRITEBYTE(Vehicle, type, VEH_SHIP),
SLE_VEH_INCLUDEX(),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleShip, state), SLE_UINT8),
/* reserve extra space in savegame here. (currently 16 bytes) */
SLE_CONDNULL(16, 2, SL_MAX_VERSION),
SLE_END()
};
static const SaveLoad _aircraft_desc[] = {
SLE_WRITEBYTE(Vehicle, type, VEH_AIRCRAFT),
SLE_VEH_INCLUDEX(),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, crashed_counter), SLE_UINT16),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, pos), SLE_UINT8),
SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, targetairport), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, targetairport), SLE_UINT16, 5, SL_MAX_VERSION),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, state), SLE_UINT8),
SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, previous_pos), SLE_UINT8, 2, SL_MAX_VERSION),
/* reserve extra space in savegame here. (currently 15 bytes) */
SLE_CONDNULL(15, 2, SL_MAX_VERSION),
SLE_END()
};
static const SaveLoad _special_desc[] = {
SLE_WRITEBYTE(Vehicle, type, VEH_EFFECT),
SLE_VAR(Vehicle, subtype, SLE_UINT8),
SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Vehicle, tile, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, x_pos, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
SLE_CONDVAR(Vehicle, x_pos, SLE_INT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, y_pos, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
SLE_CONDVAR(Vehicle, y_pos, SLE_INT32, 6, SL_MAX_VERSION),
SLE_VAR(Vehicle, z_pos, SLE_UINT8),
SLE_VAR(Vehicle, cur_image, SLE_UINT16),
SLE_CONDNULL(5, 0, 57),
SLE_VAR(Vehicle, progress, SLE_UINT8),
SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleEffect, animation_state), SLE_UINT16),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleEffect, animation_substate), SLE_UINT8),
SLE_CONDVAR(Vehicle, spritenum, SLE_UINT8, 2, SL_MAX_VERSION),
/* reserve extra space in savegame here. (currently 15 bytes) */
SLE_CONDNULL(15, 2, SL_MAX_VERSION),
SLE_END()
};
static const SaveLoad _disaster_desc[] = {
SLE_WRITEBYTE(Vehicle, type, VEH_DISASTER),
SLE_REF(Vehicle, next, REF_VEHICLE_OLD),
SLE_VAR(Vehicle, subtype, SLE_UINT8),
SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Vehicle, tile, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, dest_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Vehicle, dest_tile, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, x_pos, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
SLE_CONDVAR(Vehicle, x_pos, SLE_INT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, y_pos, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
SLE_CONDVAR(Vehicle, y_pos, SLE_INT32, 6, SL_MAX_VERSION),
SLE_VAR(Vehicle, z_pos, SLE_UINT8),
SLE_VAR(Vehicle, direction, SLE_UINT8),
SLE_CONDNULL(5, 0, 57),
SLE_VAR(Vehicle, owner, SLE_UINT8),
SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_UINT16, 5, SL_MAX_VERSION),
SLE_VAR(Vehicle, cur_image, SLE_UINT16),
SLE_CONDVAR(Vehicle, age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
SLE_CONDVAR(Vehicle, age, SLE_INT32, 31, SL_MAX_VERSION),
SLE_VAR(Vehicle, tick_counter, SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleDisaster, image_override), SLE_UINT16),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleDisaster, big_ufo_destroyer_target), SLE_UINT16),
/* reserve extra space in savegame here. (currently 16 bytes) */
SLE_CONDNULL(16, 2, SL_MAX_VERSION),
SLE_END()
};
static const SaveLoad *_veh_descs[] = {
_train_desc,
_roadveh_desc,
_ship_desc,
_aircraft_desc,
_special_desc,
_disaster_desc,
_common_veh_desc,
};
return _veh_descs[vt];
}
/** Will be called when the vehicles need to be saved. */
static void Save_VEHS()
{
Vehicle *v;
/* Write the vehicles */
FOR_ALL_VEHICLES(v) {
SlSetArrayIndex(v->index);
SlObject(v, GetVehicleDescription(v->type));
}
}
/** Will be called when vehicles need to be loaded. */
void Load_VEHS()
{
int index;
_cargo_count = 0;
while ((index = SlIterateArray()) != -1) {
Vehicle *v;
VehicleType vtype = (VehicleType)SlReadByte();
switch (vtype) {
case VEH_TRAIN: v = new (index) Train(); break;
case VEH_ROAD: v = new (index) RoadVehicle(); break;
case VEH_SHIP: v = new (index) Ship(); break;
case VEH_AIRCRAFT: v = new (index) Aircraft(); break;
case VEH_EFFECT: v = new (index) EffectVehicle(); break;
case VEH_DISASTER: v = new (index) DisasterVehicle(); break;
case VEH_INVALID: v = new (index) InvalidVehicle(); break;
default: NOT_REACHED();
}
SlObject(v, GetVehicleDescription(vtype));
if (_cargo_count != 0 && IsCompanyBuildableVehicleType(v)) {
/* Don't construct the packet with station here, because that'll fail with old savegames */
CargoPacket *cp = new CargoPacket();
cp->source = _cargo_source;
cp->source_xy = _cargo_source_xy;
cp->count = _cargo_count;
cp->days_in_transit = _cargo_days;
cp->feeder_share = _cargo_feeder_share;
cp->loaded_at_xy = _cargo_loaded_at_xy;
v->cargo.Append(cp);
}
/* Old savegames used 'last_station_visited = 0xFF' */
if (CheckSavegameVersion(5) && v->last_station_visited == 0xFF)
v->last_station_visited = INVALID_STATION;
if (CheckSavegameVersion(5)) {
/* Convert the current_order.type (which is a mix of type and flags, because
* in those versions, they both were 4 bits big) to type and flags */
v->current_order.flags = GB(v->current_order.type, 4, 4);
v->current_order.type &= 0x0F;
}
/* Advanced vehicle lists got added */
if (CheckSavegameVersion(60)) v->group_id = DEFAULT_GROUP;
}
}
extern const ChunkHandler _veh_chunk_handlers[] = {
{ 'VEHS', Save_VEHS, Load_VEHS, CH_SPARSE_ARRAY | CH_LAST},
};

@ -0,0 +1,96 @@
/* $Id$ */
/** @file waypoint_sl.cpp Code handling saving and loading of waypoints */
#include "../stdafx.h"
#include "../waypoint.h"
#include "../newgrf_station.h"
#include "../town.h"
#include "table/strings.h"
#include "saveload.h"
/**
* Update waypoint graphics id against saved GRFID/localidx.
* This is to ensure the chosen graphics are correct if GRF files are changed.
*/
void AfterLoadWaypoints()
{
Waypoint *wp;
FOR_ALL_WAYPOINTS(wp) {
uint i;
if (wp->grfid == 0) continue;
for (i = 0; i < GetNumCustomStations(STAT_CLASS_WAYP); i++) {
const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, i);
if (statspec != NULL && statspec->grffile->grfid == wp->grfid && statspec->localidx == wp->localidx) {
wp->stat_id = i;
break;
}
}
}
}
/**
* Fix savegames which stored waypoints in their old format
*/
void FixOldWaypoints()
{
Waypoint *wp;
/* Convert the old 'town_or_string', to 'string' / 'town' / 'town_cn' */
FOR_ALL_WAYPOINTS(wp) {
wp->town_index = ClosestTownFromTile(wp->xy, UINT_MAX)->index;
wp->town_cn = 0;
if (wp->string & 0xC000) {
wp->town_cn = wp->string & 0x3F;
wp->string = STR_NULL;
}
}
}
static const SaveLoad _waypoint_desc[] = {
SLE_CONDVAR(Waypoint, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Waypoint, xy, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Waypoint, town_index, SLE_UINT16, 12, SL_MAX_VERSION),
SLE_CONDVAR(Waypoint, town_cn, SLE_FILE_U8 | SLE_VAR_U16, 12, 88),
SLE_CONDVAR(Waypoint, town_cn, SLE_UINT16, 89, SL_MAX_VERSION),
SLE_CONDVAR(Waypoint, string, SLE_STRINGID, 0, 83),
SLE_CONDSTR(Waypoint, name, SLE_STR, 0, 84, SL_MAX_VERSION),
SLE_VAR(Waypoint, deleted, SLE_UINT8),
SLE_CONDVAR(Waypoint, build_date, SLE_FILE_U16 | SLE_VAR_I32, 3, 30),
SLE_CONDVAR(Waypoint, build_date, SLE_INT32, 31, SL_MAX_VERSION),
SLE_CONDVAR(Waypoint, localidx, SLE_UINT8, 3, SL_MAX_VERSION),
SLE_CONDVAR(Waypoint, grfid, SLE_UINT32, 17, SL_MAX_VERSION),
SLE_CONDVAR(Waypoint, owner, SLE_UINT8, 101, SL_MAX_VERSION),
SLE_END()
};
static void Save_WAYP()
{
Waypoint *wp;
FOR_ALL_WAYPOINTS(wp) {
SlSetArrayIndex(wp->index);
SlObject(wp, _waypoint_desc);
}
}
static void Load_WAYP()
{
int index;
while ((index = SlIterateArray()) != -1) {
Waypoint *wp = new (index) Waypoint();
SlObject(wp, _waypoint_desc);
}
}
extern const ChunkHandler _waypoint_chunk_handlers[] = {
{ 'CHKP', Save_WAYP, Load_WAYP, CH_ARRAY | CH_LAST},
};

@ -17,7 +17,7 @@
#include "core/alloc_func.hpp"
#include "core/endian_func.hpp"
#include "map_func.h"
#include "saveload.h"
#include "saveload/saveload.h"
#include "company_func.h"
#include "table/strings.h"

@ -29,7 +29,6 @@
#include "settings_internal.h"
#include "command_func.h"
#include "console_func.h"
#include "saveload.h"
#include "npf.h"
#include "yapf/yapf.h"
#include "newgrf.h"

@ -5,7 +5,7 @@
#ifndef SETTINGS_INTERNAL_H
#define SETTINGS_INTERNAL_H
#include "saveload.h"
#include "saveload/saveload.h"
#include "settings_type.h"
/** Convention/Type of settings. This is then further specified if necessary

@ -8,7 +8,6 @@
#include "company_func.h"
#include "signs_base.h"
#include "signs_func.h"
#include "saveload.h"
#include "command_func.h"
#include "variables.h"
#include "strings_func.h"
@ -56,17 +55,12 @@ static void UpdateSignVirtCoords(Sign *si)
UpdateViewportSignPos(&si->sign, pt.x, pt.y - 6, STR_2806);
}
/**
*
* Update the coordinates of all signs
*
*/
/** Update the coordinates of all signs */
void UpdateAllSignVirtCoords()
{
Sign *si;
FOR_ALL_SIGNS(si) UpdateSignVirtCoords(si);
}
/**
@ -203,48 +197,3 @@ void InitializeSigns()
_Sign_pool.CleanPool();
_Sign_pool.AddBlockToPool();
}
static const SaveLoad _sign_desc[] = {
SLE_CONDVAR(Sign, name, SLE_NAME, 0, 83),
SLE_CONDSTR(Sign, name, SLE_STR, 0, 84, SL_MAX_VERSION),
SLE_CONDVAR(Sign, x, SLE_FILE_I16 | SLE_VAR_I32, 0, 4),
SLE_CONDVAR(Sign, y, SLE_FILE_I16 | SLE_VAR_I32, 0, 4),
SLE_CONDVAR(Sign, x, SLE_INT32, 5, SL_MAX_VERSION),
SLE_CONDVAR(Sign, y, SLE_INT32, 5, SL_MAX_VERSION),
SLE_CONDVAR(Sign, owner, SLE_UINT8, 6, SL_MAX_VERSION),
SLE_VAR(Sign, z, SLE_UINT8),
SLE_END()
};
/**
*
* Save all signs
*
*/
static void Save_SIGN()
{
Sign *si;
FOR_ALL_SIGNS(si) {
SlSetArrayIndex(si->index);
SlObject(si, _sign_desc);
}
}
/**
*
* Load all signs
*
*/
static void Load_SIGN()
{
int index;
while ((index = SlIterateArray()) != -1) {
Sign *si = new (index) Sign();
SlObject(si, _sign_desc);
}
}
extern const ChunkHandler _sign_chunk_handlers[] = {
{ 'SIGN', Save_SIGN, Load_SIGN, CH_ARRAY | CH_LAST},
};

@ -7,6 +7,7 @@
#include "signs_type.h"
#include "viewport_type.h"
#include "tile_type.h"
#include "oldpool.h"
DECLARE_OLD_POOL(Sign, Sign, 2, 16000)

@ -9,7 +9,6 @@
#include "station_map.h"
#include "station_base.h"
#include "town.h"
#include "saveload.h"
#include "company_func.h"
#include "airport.h"
#include "sprite.h"

@ -15,7 +15,6 @@
#include "command_func.h"
#include "town.h"
#include "news_func.h"
#include "saveload.h"
#include "airport.h"
#include "sprite.h"
#include "train.h"
@ -3185,24 +3184,6 @@ void InitializeStations()
_station_tick_ctr = 0;
}
void AfterLoadStations()
{
/* Update the speclists of all stations to point to the currently loaded custom stations. */
Station *st;
FOR_ALL_STATIONS(st) {
for (uint i = 0; i < st->num_specs; i++) {
if (st->speclist[i].grfid == 0) continue;
st->speclist[i].spec = GetCustomStationSpecByGrf(st->speclist[i].grfid, st->speclist[i].localidx);
}
for (CargoID c = 0; c < NUM_CARGO; c++) st->goods[c].cargo.InvalidateCache();
StationUpdateAnimTriggers(st);
}
}
static CommandCost TerraformTile_Station(TileIndex tile, uint32 flags, uint z_new, Slope tileh_new)
{
if (_settings_game.construction.build_on_slopes && AutoslopeEnabled()) {
@ -3255,200 +3236,3 @@ extern const TileTypeProcs _tile_type_station_procs = {
GetFoundation_Station, /* get_foundation_proc */
TerraformTile_Station, /* terraform_tile_proc */
};
static const SaveLoad _roadstop_desc[] = {
SLE_VAR(RoadStop, xy, SLE_UINT32),
SLE_CONDNULL(1, 0, 44),
SLE_VAR(RoadStop, status, SLE_UINT8),
/* Index was saved in some versions, but this is not needed */
SLE_CONDNULL(4, 0, 8),
SLE_CONDNULL(2, 0, 44),
SLE_CONDNULL(1, 0, 25),
SLE_REF(RoadStop, next, REF_ROADSTOPS),
SLE_CONDNULL(2, 0, 44),
SLE_CONDNULL(4, 0, 24),
SLE_CONDNULL(1, 25, 25),
SLE_END()
};
static const SaveLoad _station_desc[] = {
SLE_CONDVAR(Station, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Station, xy, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDNULL(4, 0, 5), ///< bus/lorry tile
SLE_CONDVAR(Station, train_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Station, train_tile, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Station, airport_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Station, airport_tile, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Station, dock_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Station, dock_tile, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_REF(Station, town, REF_TOWN),
SLE_VAR(Station, trainst_w, SLE_UINT8),
SLE_CONDVAR(Station, trainst_h, SLE_UINT8, 2, SL_MAX_VERSION),
SLE_CONDNULL(1, 0, 3), ///< alpha_order
SLE_VAR(Station, string_id, SLE_STRINGID),
SLE_CONDSTR(Station, name, SLE_STR, 0, 84, SL_MAX_VERSION),
SLE_CONDVAR(Station, indtype, SLE_UINT8, 103, SL_MAX_VERSION),
SLE_VAR(Station, had_vehicle_of_type, SLE_UINT16),
SLE_VAR(Station, time_since_load, SLE_UINT8),
SLE_VAR(Station, time_since_unload, SLE_UINT8),
SLE_VAR(Station, delete_ctr, SLE_UINT8),
SLE_VAR(Station, owner, SLE_UINT8),
SLE_VAR(Station, facilities, SLE_UINT8),
SLE_VAR(Station, airport_type, SLE_UINT8),
SLE_CONDNULL(2, 0, 5), ///< Truck/bus stop status
SLE_CONDNULL(1, 0, 4), ///< Blocked months
SLE_CONDVAR(Station, airport_flags, SLE_VAR_U64 | SLE_FILE_U16, 0, 2),
SLE_CONDVAR(Station, airport_flags, SLE_VAR_U64 | SLE_FILE_U32, 3, 45),
SLE_CONDVAR(Station, airport_flags, SLE_UINT64, 46, SL_MAX_VERSION),
SLE_CONDNULL(2, 0, 25), ///< last-vehicle
SLE_CONDVAR(Station, last_vehicle_type, SLE_UINT8, 26, SL_MAX_VERSION),
SLE_CONDNULL(2, 3, 25), ///< custom station class and id
SLE_CONDVAR(Station, build_date, SLE_FILE_U16 | SLE_VAR_I32, 3, 30),
SLE_CONDVAR(Station, build_date, SLE_INT32, 31, SL_MAX_VERSION),
SLE_CONDREF(Station, bus_stops, REF_ROADSTOPS, 6, SL_MAX_VERSION),
SLE_CONDREF(Station, truck_stops, REF_ROADSTOPS, 6, SL_MAX_VERSION),
/* Used by newstations for graphic variations */
SLE_CONDVAR(Station, random_bits, SLE_UINT16, 27, SL_MAX_VERSION),
SLE_CONDVAR(Station, waiting_triggers, SLE_UINT8, 27, SL_MAX_VERSION),
SLE_CONDVAR(Station, num_specs, SLE_UINT8, 27, SL_MAX_VERSION),
SLE_CONDLST(Station, loading_vehicles, REF_VEHICLE, 57, SL_MAX_VERSION),
/* reserve extra space in savegame here. (currently 32 bytes) */
SLE_CONDNULL(32, 2, SL_MAX_VERSION),
SLE_END()
};
static uint16 _waiting_acceptance;
static uint16 _cargo_source;
static uint32 _cargo_source_xy;
static uint16 _cargo_days;
static Money _cargo_feeder_share;
static const SaveLoad _station_speclist_desc[] = {
SLE_CONDVAR(StationSpecList, grfid, SLE_UINT32, 27, SL_MAX_VERSION),
SLE_CONDVAR(StationSpecList, localidx, SLE_UINT8, 27, SL_MAX_VERSION),
SLE_END()
};
void SaveLoad_STNS(Station *st)
{
static const SaveLoad _goods_desc[] = {
SLEG_CONDVAR( _waiting_acceptance, SLE_UINT16, 0, 67),
SLE_CONDVAR(GoodsEntry, acceptance_pickup, SLE_UINT8, 68, SL_MAX_VERSION),
SLE_CONDNULL(2, 51, 67),
SLE_VAR(GoodsEntry, days_since_pickup, SLE_UINT8),
SLE_VAR(GoodsEntry, rating, SLE_UINT8),
SLEG_CONDVAR( _cargo_source, SLE_FILE_U8 | SLE_VAR_U16, 0, 6),
SLEG_CONDVAR( _cargo_source, SLE_UINT16, 7, 67),
SLEG_CONDVAR( _cargo_source_xy, SLE_UINT32, 44, 67),
SLEG_CONDVAR( _cargo_days, SLE_UINT8, 0, 67),
SLE_VAR(GoodsEntry, last_speed, SLE_UINT8),
SLE_VAR(GoodsEntry, last_age, SLE_UINT8),
SLEG_CONDVAR( _cargo_feeder_share, SLE_FILE_U32 | SLE_VAR_I64, 14, 64),
SLEG_CONDVAR( _cargo_feeder_share, SLE_INT64, 65, 67),
SLE_CONDLST(GoodsEntry, cargo.packets, REF_CARGO_PACKET, 68, SL_MAX_VERSION),
SLE_END()
};
SlObject(st, _station_desc);
_waiting_acceptance = 0;
uint num_cargo = CheckSavegameVersion(55) ? 12 : NUM_CARGO;
for (CargoID i = 0; i < num_cargo; i++) {
GoodsEntry *ge = &st->goods[i];
SlObject(ge, _goods_desc);
if (CheckSavegameVersion(68)) {
SB(ge->acceptance_pickup, GoodsEntry::ACCEPTANCE, 1, HasBit(_waiting_acceptance, 15));
if (GB(_waiting_acceptance, 0, 12) != 0) {
/* Don't construct the packet with station here, because that'll fail with old savegames */
CargoPacket *cp = new CargoPacket();
/* In old versions, enroute_from used 0xFF as INVALID_STATION */
cp->source = (CheckSavegameVersion(7) && _cargo_source == 0xFF) ? INVALID_STATION : _cargo_source;
cp->count = GB(_waiting_acceptance, 0, 12);
cp->days_in_transit = _cargo_days;
cp->feeder_share = _cargo_feeder_share;
cp->source_xy = _cargo_source_xy;
cp->days_in_transit = _cargo_days;
cp->feeder_share = _cargo_feeder_share;
SB(ge->acceptance_pickup, GoodsEntry::PICKUP, 1, 1);
ge->cargo.Append(cp);
}
}
}
if (st->num_specs != 0) {
/* Allocate speclist memory when loading a game */
if (st->speclist == NULL) st->speclist = CallocT<StationSpecList>(st->num_specs);
for (uint i = 0; i < st->num_specs; i++) {
SlObject(&st->speclist[i], _station_speclist_desc);
}
}
}
static void Save_STNS()
{
Station *st;
/* Write the stations */
FOR_ALL_STATIONS(st) {
SlSetArrayIndex(st->index);
SlAutolength((AutolengthProc*)SaveLoad_STNS, st);
}
}
static void Load_STNS()
{
int index;
while ((index = SlIterateArray()) != -1) {
Station *st = new (index) Station();
SaveLoad_STNS(st);
}
/* This is to ensure all pointers are within the limits of _stations_size */
if (_station_tick_ctr > GetMaxStationIndex()) _station_tick_ctr = 0;
}
static void Save_ROADSTOP()
{
RoadStop *rs;
FOR_ALL_ROADSTOPS(rs) {
SlSetArrayIndex(rs->index);
SlObject(rs, _roadstop_desc);
}
}
static void Load_ROADSTOP()
{
int index;
while ((index = SlIterateArray()) != -1) {
RoadStop *rs = new (index) RoadStop(INVALID_TILE);
SlObject(rs, _roadstop_desc);
}
}
extern const ChunkHandler _station_chunk_handlers[] = {
{ 'STNS', Save_STNS, Load_STNS, CH_ARRAY },
{ 'ROAD', Save_ROADSTOP, Load_ROADSTOP, CH_ARRAY | CH_LAST},
};

@ -25,7 +25,6 @@ StationSet FindStationsAroundTiles(TileIndex tile, int w_prod, int h_prod);
void ShowStationViewWindow(StationID station);
void UpdateAllStationVirtCoord();
void AfterLoadStations();
void GetProductionAroundTiles(AcceptedCargo produced, TileIndex tile, int w, int h, int rad);
void GetAcceptanceAroundTiles(AcceptedCargo accepts, TileIndex tile, int w, int h, int rad);

@ -39,7 +39,6 @@
#include "video/video_driver.hpp"
#include "engine_func.h"
#include "engine_base.h"
#include "saveload.h"
#include "strgen/strgen.h"
#include "table/strings.h"
@ -1593,114 +1592,3 @@ void CheckForMissingGlyphsInLoadedLanguagePack()
/* --- Handling of saving/loading string IDs from old savegames --- */
/**
* Remap a string ID from the old format to the new format
* @param s StringID that requires remapping
* @return translated ID
*/
StringID RemapOldStringID(StringID s)
{
switch (s) {
case 0x0006: return STR_SV_EMPTY;
case 0x7000: return STR_SV_UNNAMED;
case 0x70E4: return SPECSTR_PLAYERNAME_ENGLISH;
case 0x70E9: return SPECSTR_PLAYERNAME_ENGLISH;
case 0x8864: return STR_SV_TRAIN_NAME;
case 0x902B: return STR_SV_ROADVEH_NAME;
case 0x9830: return STR_SV_SHIP_NAME;
case 0xA02F: return STR_SV_AIRCRAFT_NAME;
default:
if (IsInsideMM(s, 0x300F, 0x3030)) {
return s - 0x300F + STR_SV_STNAME;
} else {
return s;
}
}
}
/** Location to load the old names to. */
char *_old_name_array = NULL;
/**
* Copy and convert old custom names to UTF-8.
* They were all stored in a 512 by 32 long string array and are
* now stored with stations, waypoints and other places with names.
* @param id the StringID of the custom name to clone.
* @return the clones custom name.
*/
char *CopyFromOldName(StringID id)
{
/* Is this name an (old) custom name? */
if (GB(id, 11, 5) != 15) return NULL;
if (CheckSavegameVersion(37)) {
/* Old names were 32 characters long, so 128 characters should be
* plenty to allow for expansion when converted to UTF-8. */
char tmp[128];
const char *strfrom = &_old_name_array[32 * GB(id, 0, 9)];
char *strto = tmp;
for (; *strfrom != '\0'; strfrom++) {
WChar c = (byte)*strfrom;
/* Map from non-ISO8859-15 characters to UTF-8. */
switch (c) {
case 0xA4: c = 0x20AC; break; // Euro
case 0xA6: c = 0x0160; break; // S with caron
case 0xA8: c = 0x0161; break; // s with caron
case 0xB4: c = 0x017D; break; // Z with caron
case 0xB8: c = 0x017E; break; // z with caron
case 0xBC: c = 0x0152; break; // OE ligature
case 0xBD: c = 0x0153; break; // oe ligature
case 0xBE: c = 0x0178; break; // Y with diaresis
default: break;
}
/* Check character will fit into our buffer. */
if (strto + Utf8CharLen(c) > lastof(tmp)) break;
strto += Utf8Encode(strto, c);
}
/* Terminate the new string and copy it back to the name array */
*strto = '\0';
return strdup(tmp);
} else {
/* Name will already be in UTF-8. */
return strdup(&_old_name_array[32 * GB(id, 0, 9)]);
}
}
/**
* Free the memory of the old names array.
* Should be called once the old names have all been converted.
*/
void ResetOldNames()
{
free(_old_name_array);
_old_name_array = NULL;
}
/**
* Initialize the old names table memory.
*/
void InitializeOldNames()
{
free(_old_name_array);
_old_name_array = CallocT<char>(512 * 32);
}
static void Load_NAME()
{
int index;
while ((index = SlIterateArray()) != -1) {
SlArray(&_old_name_array[32 * index], SlGetFieldLength(), SLE_UINT8);
}
}
extern const ChunkHandler _name_chunk_handlers[] = {
{ 'NAME', NULL, Load_NAME, CH_ARRAY | CH_LAST},
};

@ -68,7 +68,4 @@ struct StringIDCompare
void CheckForMissingGlyphsInLoadedLanguagePack();
StringID RemapOldStringID(StringID s);
char *CopyFromOldName(StringID id);
#endif /* STRINGS_TYPE_H */

@ -362,7 +362,6 @@ extern int _cleared_town_rating;
void ResetHouses();
void ClearTownHouse(Town *t, TileIndex tile);
void AfterLoadTown();
void UpdateTownMaxPass(Town *t);
void UpdateTownRadius(Town *t);
bool CheckIfAuthorityAllows(TileIndex tile);

@ -19,7 +19,6 @@
#include "station_base.h"
#include "company_base.h"
#include "news_func.h"
#include "saveload.h"
#include "gui.h"
#include "unmovable_map.h"
#include "water_map.h"
@ -2676,155 +2675,6 @@ extern const TileTypeProcs _tile_type_town_procs = {
TerraformTile_Town, // terraform_tile_proc
};
/** Save and load of towns. */
static const SaveLoad _town_desc[] = {
SLE_CONDVAR(Town, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Town, xy, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDNULL(2, 0, 2), ///< population, no longer in use
SLE_CONDNULL(4, 3, 84), ///< population, no longer in use
SLE_CONDNULL(2, 0, 91), ///< num_houses, no longer in use
SLE_CONDVAR(Town, townnamegrfid, SLE_UINT32, 66, SL_MAX_VERSION),
SLE_VAR(Town, townnametype, SLE_UINT16),
SLE_VAR(Town, townnameparts, SLE_UINT32),
SLE_CONDSTR(Town, name, SLE_STR, 0, 84, SL_MAX_VERSION),
SLE_VAR(Town, flags12, SLE_UINT8),
SLE_CONDVAR(Town, statues, SLE_FILE_U8 | SLE_VAR_U16, 0, 103),
SLE_CONDVAR(Town, statues, SLE_UINT16, 104, SL_MAX_VERSION),
SLE_CONDNULL(1, 0, 1), ///< sort_index, no longer in use
SLE_CONDVAR(Town, have_ratings, SLE_FILE_U8 | SLE_VAR_U16, 0, 103),
SLE_CONDVAR(Town, have_ratings, SLE_UINT16, 104, SL_MAX_VERSION),
SLE_CONDARR(Town, ratings, SLE_INT16, 8, 0, 103),
SLE_CONDARR(Town, ratings, SLE_INT16, MAX_COMPANIES, 104, SL_MAX_VERSION),
/* failed bribe attempts are stored since savegame format 4 */
SLE_CONDARR(Town, unwanted, SLE_INT8, 8, 4, 103),
SLE_CONDARR(Town, unwanted, SLE_INT8, MAX_COMPANIES, 104, SL_MAX_VERSION),
SLE_CONDVAR(Town, max_pass, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
SLE_CONDVAR(Town, max_mail, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
SLE_CONDVAR(Town, new_max_pass, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
SLE_CONDVAR(Town, new_max_mail, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
SLE_CONDVAR(Town, act_pass, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
SLE_CONDVAR(Town, act_mail, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
SLE_CONDVAR(Town, new_act_pass, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
SLE_CONDVAR(Town, new_act_mail, SLE_FILE_U16 | SLE_VAR_U32, 0, 8),
SLE_CONDVAR(Town, max_pass, SLE_UINT32, 9, SL_MAX_VERSION),
SLE_CONDVAR(Town, max_mail, SLE_UINT32, 9, SL_MAX_VERSION),
SLE_CONDVAR(Town, new_max_pass, SLE_UINT32, 9, SL_MAX_VERSION),
SLE_CONDVAR(Town, new_max_mail, SLE_UINT32, 9, SL_MAX_VERSION),
SLE_CONDVAR(Town, act_pass, SLE_UINT32, 9, SL_MAX_VERSION),
SLE_CONDVAR(Town, act_mail, SLE_UINT32, 9, SL_MAX_VERSION),
SLE_CONDVAR(Town, new_act_pass, SLE_UINT32, 9, SL_MAX_VERSION),
SLE_CONDVAR(Town, new_act_mail, SLE_UINT32, 9, SL_MAX_VERSION),
SLE_VAR(Town, pct_pass_transported, SLE_UINT8),
SLE_VAR(Town, pct_mail_transported, SLE_UINT8),
SLE_VAR(Town, act_food, SLE_UINT16),
SLE_VAR(Town, act_water, SLE_UINT16),
SLE_VAR(Town, new_act_food, SLE_UINT16),
SLE_VAR(Town, new_act_water, SLE_UINT16),
SLE_CONDVAR(Town, time_until_rebuild, SLE_UINT8, 0, 53),
SLE_CONDVAR(Town, grow_counter, SLE_UINT8, 0, 53),
SLE_CONDVAR(Town, growth_rate, SLE_UINT8, 0, 53),
SLE_CONDVAR(Town, time_until_rebuild, SLE_UINT16, 54, SL_MAX_VERSION),
SLE_CONDVAR(Town, grow_counter, SLE_UINT16, 54, SL_MAX_VERSION),
SLE_CONDVAR(Town, growth_rate, SLE_INT16, 54, SL_MAX_VERSION),
SLE_VAR(Town, fund_buildings_months, SLE_UINT8),
SLE_VAR(Town, road_build_months, SLE_UINT8),
SLE_CONDVAR(Town, exclusivity, SLE_UINT8, 2, SL_MAX_VERSION),
SLE_CONDVAR(Town, exclusive_counter, SLE_UINT8, 2, SL_MAX_VERSION),
SLE_CONDVAR(Town, larger_town, SLE_BOOL, 56, SL_MAX_VERSION),
/* reserve extra space in savegame here. (currently 30 bytes) */
SLE_CONDNULL(30, 2, SL_MAX_VERSION),
SLE_END()
};
/* Save and load the mapping between the house id on the map, and the grf file
* it came from. */
static const SaveLoad _house_id_mapping_desc[] = {
SLE_VAR(EntityIDMapping, grfid, SLE_UINT32),
SLE_VAR(EntityIDMapping, entity_id, SLE_UINT8),
SLE_VAR(EntityIDMapping, substitute_id, SLE_UINT8),
SLE_END()
};
static void Save_HOUSEIDS()
{
uint j = _house_mngr.GetMaxMapping();
for (uint i = 0; i < j; i++) {
SlSetArrayIndex(i);
SlObject(&_house_mngr.mapping_ID[i], _house_id_mapping_desc);
}
}
static void Load_HOUSEIDS()
{
int index;
_house_mngr.ResetMapping();
uint max_id = _house_mngr.GetMaxMapping();
while ((index = SlIterateArray()) != -1) {
if ((uint)index >= max_id) break;
SlObject(&_house_mngr.mapping_ID[index], _house_id_mapping_desc);
}
}
static void Save_TOWN()
{
Town *t;
FOR_ALL_TOWNS(t) {
SlSetArrayIndex(t->index);
SlObject(t, _town_desc);
}
}
static void Load_TOWN()
{
int index;
_total_towns = 0;
while ((index = SlIterateArray()) != -1) {
Town *t = new (index) Town();
SlObject(t, _town_desc);
_total_towns++;
}
/* This is to ensure all pointers are within the limits of
* the size of the TownPool */
if (_cur_town_ctr > GetMaxTownIndex())
_cur_town_ctr = 0;
}
void AfterLoadTown()
{
Town *t;
FOR_ALL_TOWNS(t) t->InitializeLayout();
}
extern const ChunkHandler _town_chunk_handlers[] = {
{ 'HIDS', Save_HOUSEIDS, Load_HOUSEIDS, CH_ARRAY },
{ 'CITY', Save_TOWN, Load_TOWN, CH_ARRAY | CH_LAST},
};
void ResetHouses()
{
memset(&_house_specs, 0, sizeof(_house_specs));

@ -287,9 +287,6 @@ static inline Vehicle *GetPrevUnit(const Vehicle *v)
return w;
}
void ConvertOldMultiheadToNew();
void ConnectMultiheadedTrains();
void CcBuildLoco(bool success, TileIndex tile, uint32 p1, uint32 p2);
void CcBuildWagon(bool success, TileIndex tile, uint32 p1, uint32 p2);

@ -4500,146 +4500,3 @@ void InitializeTrains()
{
_age_cargo_skip_counter = 1;
}
/*
* Link front and rear multiheaded engines to each other
* This is done when loading a savegame
*/
void ConnectMultiheadedTrains()
{
Vehicle *v;
FOR_ALL_VEHICLES(v) {
if (v->type == VEH_TRAIN) {
v->u.rail.other_multiheaded_part = NULL;
}
}
FOR_ALL_VEHICLES(v) {
if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) {
/* Two ways to associate multiheaded parts to each other:
* sequential-matching: Trains shall be arranged to look like <..>..<..>..<..>..
* bracket-matching: Free vehicle chains shall be arranged to look like ..<..<..>..<..>..>..
*
* Note: Old savegames might contain chains which do not comply with these rules, e.g.
* - the front and read parts have invalid orders
* - different engine types might be combined
* - there might be different amounts of front and rear parts.
*
* Note: The multiheaded parts need to be matched exactly like they are matched on the server, else desyncs will occur.
* This is why two matching strategies are needed.
*/
bool sequential_matching = IsFrontEngine(v);
for (Vehicle *u = v; u != NULL; u = GetNextVehicle(u)) {
if (u->u.rail.other_multiheaded_part != NULL) continue; // we already linked this one
if (IsMultiheaded(u)) {
if (!IsTrainEngine(u)) {
/* we got a rear car without a front car. We will convert it to a front one */
SetTrainEngine(u);
u->spritenum--;
}
/* Find a matching back part */
EngineID eid = u->engine_type;
Vehicle *w;
if (sequential_matching) {
for (w = GetNextVehicle(u); w != NULL; w = GetNextVehicle(w)) {
if (w->engine_type != eid || w->u.rail.other_multiheaded_part != NULL || !IsMultiheaded(w)) continue;
/* we found a car to partner with this engine. Now we will make sure it face the right way */
if (IsTrainEngine(w)) {
ClearTrainEngine(w);
w->spritenum++;
}
break;
}
} else {
uint stack_pos = 0;
for (w = GetNextVehicle(u); w != NULL; w = GetNextVehicle(w)) {
if (w->engine_type != eid || w->u.rail.other_multiheaded_part != NULL || !IsMultiheaded(w)) continue;
if (IsTrainEngine(w)) {
stack_pos++;
} else {
if (stack_pos == 0) break;
stack_pos--;
}
}
}
if (w != NULL) {
w->u.rail.other_multiheaded_part = u;
u->u.rail.other_multiheaded_part = w;
} else {
/* we got a front car and no rear cars. We will fake this one for forget that it should have been multiheaded */
ClearMultiheaded(u);
}
}
}
}
}
}
/**
* Converts all trains to the new subtype format introduced in savegame 16.2
* It also links multiheaded engines or make them forget they are multiheaded if no suitable partner is found
*/
void ConvertOldMultiheadToNew()
{
Vehicle *v;
FOR_ALL_VEHICLES(v) {
if (v->type == VEH_TRAIN) {
SetBit(v->subtype, 7); // indicates that it's the old format and needs to be converted in the next loop
}
}
FOR_ALL_VEHICLES(v) {
if (v->type == VEH_TRAIN) {
if (HasBit(v->subtype, 7) && ((v->subtype & ~0x80) == 0 || (v->subtype & ~0x80) == 4)) {
for (Vehicle *u = v; u != NULL; u = u->Next()) {
const RailVehicleInfo *rvi = RailVehInfo(u->engine_type);
ClrBit(u->subtype, 7);
switch (u->subtype) {
case 0: /* TS_Front_Engine */
if (rvi->railveh_type == RAILVEH_MULTIHEAD) SetMultiheaded(u);
SetFrontEngine(u);
SetTrainEngine(u);
break;
case 1: /* TS_Artic_Part */
u->subtype = 0;
SetArticulatedPart(u);
break;
case 2: /* TS_Not_First */
u->subtype = 0;
if (rvi->railveh_type == RAILVEH_WAGON) {
// normal wagon
SetTrainWagon(u);
break;
}
if (rvi->railveh_type == RAILVEH_MULTIHEAD && rvi->image_index == u->spritenum - 1) {
// rear end of a multiheaded engine
SetMultiheaded(u);
break;
}
if (rvi->railveh_type == RAILVEH_MULTIHEAD) SetMultiheaded(u);
SetTrainEngine(u);
break;
case 4: /* TS_Free_Car */
u->subtype = 0;
SetTrainWagon(u);
SetFreeWagon(u);
break;
default: NOT_REACHED(); break;
}
}
}
}
}
}

@ -33,10 +33,6 @@ VARDEF uint _next_competitor_start;
/* Determines how often to run the tree loop */
VARDEF byte _trees_tick_ctr;
/* Keep track of current game position */
VARDEF int _saved_scrollpos_x;
VARDEF int _saved_scrollpos_y;
/* NOSAVE: Used in palette animations only, not really important. */
VARDEF int _palette_animation_counter;

@ -15,7 +15,7 @@
#include "gfx_func.h"
#include "news_func.h"
#include "command_func.h"
#include "saveload.h"
#include "saveload/saveload.h"
#include "company_func.h"
#include "debug.h"
#include "vehicle_gui.h"
@ -59,9 +59,6 @@
#include "table/sprites.h"
#include "table/strings.h"
#include <map>
#define INVALID_COORD (0x7fffffff)
#define GEN_HASH(x, y) ((GB((y), 6, 6) << 6) + GB((x), 7, 6))
VehicleID _vehicle_id_ctr_day;
@ -222,120 +219,6 @@ void VehiclePositionChanged(Vehicle *v)
v->bottom_coord = pt.y + spr->height + 2;
}
/** Called after load to update coordinates */
void AfterLoadVehicles(bool part_of_load)
{
Vehicle *v;
FOR_ALL_VEHICLES(v) {
/* Reinstate the previous pointer */
if (v->Next() != NULL) v->Next()->previous = v;
if (v->NextShared() != NULL) v->NextShared()->previous_shared = v;
v->UpdateDeltaXY(v->direction);
if (part_of_load) v->fill_percent_te_id = INVALID_TE_ID;
v->first = NULL;
if (v->type == VEH_TRAIN) v->u.rail.first_engine = INVALID_ENGINE;
if (v->type == VEH_ROAD) v->u.road.first_engine = INVALID_ENGINE;
v->cargo.InvalidateCache();
}
/* AfterLoadVehicles may also be called in case of NewGRF reload, in this
* case we may not convert orders again. */
if (part_of_load) {
/* Create shared vehicle chain for very old games (pre 5,2) and create
* OrderList from shared vehicle chains. For this to work correctly, the
* following conditions must be fulfilled:
* a) both next_shared and previous_shared are not set for pre 5,2 games
* b) both next_shared and previous_shared are set for later games
*/
std::map<Order*, OrderList*> mapping;
FOR_ALL_VEHICLES(v) {
if (v->orders.old != NULL) {
if (CheckSavegameVersion(105)) { // Pre-105 didn't save an OrderList
if (mapping[v->orders.old] == NULL) {
/* This adds the whole shared vehicle chain for case b */
v->orders.list = mapping[v->orders.old] = new OrderList(v->orders.old, v);
} else {
v->orders.list = mapping[v->orders.old];
/* For old games (case a) we must create the shared vehicle chain */
if (CheckSavegameVersionOldStyle(5, 2)) {
v->AddToShared(v->orders.list->GetFirstSharedVehicle());
}
}
} else { // OrderList was saved as such, only recalculate not saved values
if (v->PreviousShared() == NULL) {
new (v->orders.list) OrderList(v->orders.list->GetFirstOrder(), v);
}
}
}
}
}
FOR_ALL_VEHICLES(v) {
/* Fill the first pointers */
if (v->Previous() == NULL) {
for (Vehicle *u = v; u != NULL; u = u->Next()) {
u->first = v;
}
}
}
FOR_ALL_VEHICLES(v) {
assert(v->first != NULL);
if (v->type == VEH_TRAIN && (IsFrontEngine(v) || IsFreeWagon(v))) {
if (IsFrontEngine(v)) v->u.rail.last_speed = v->cur_speed; // update displayed train speed
TrainConsistChanged(v, false);
} else if (v->type == VEH_ROAD && IsRoadVehFront(v)) {
RoadVehUpdateCache(v);
}
}
/* Stop non-front engines */
FOR_ALL_VEHICLES(v) {
if (v->type == VEH_TRAIN && IsTrainEngine(v) && !IsFrontEngine(v)) v->vehstatus |= VS_STOPPED;
}
FOR_ALL_VEHICLES(v) {
switch (v->type) {
case VEH_ROAD:
v->u.road.roadtype = HasBit(EngInfo(v->engine_type)->misc_flags, EF_ROAD_TRAM) ? ROADTYPE_TRAM : ROADTYPE_ROAD;
v->u.road.compatible_roadtypes = RoadTypeToRoadTypes(v->u.road.roadtype);
/* FALL THROUGH */
case VEH_TRAIN:
case VEH_SHIP:
v->cur_image = v->GetImage(v->direction);
break;
case VEH_AIRCRAFT:
if (IsNormalAircraft(v)) {
v->cur_image = v->GetImage(v->direction);
/* The plane's shadow will have the same image as the plane */
Vehicle *shadow = v->Next();
shadow->cur_image = v->cur_image;
/* In the case of a helicopter we will update the rotor sprites */
if (v->subtype == AIR_HELICOPTER) {
Vehicle *rotor = shadow->Next();
rotor->cur_image = GetRotorImage(v);
}
UpdateAircraftCache(v);
}
break;
default: break;
}
v->left_coord = INVALID_COORD;
VehiclePositionChanged(v);
}
}
Vehicle::Vehicle()
{
this->type = VEH_INVALID;
@ -622,11 +505,19 @@ void ResetVehicleColorMap()
FOR_ALL_VEHICLES(v) { v->colormap = PAL_NONE; }
}
/**
* List of vehicles that should check for autoreplace this tick.
* Mapping of vehicle -> leave depot immediatelly after autoreplace.
*/
typedef SmallMap<Vehicle *, bool, 4> AutoreplaceMap;
static AutoreplaceMap _vehicles_to_autoreplace;
void InitializeVehicles()
{
_Vehicle_pool.CleanPool();
_Vehicle_pool.AddBlockToPool();
_vehicles_to_autoreplace.Reset();
ResetVehiclePosHash();
}
@ -739,13 +630,6 @@ Vehicle::~Vehicle()
new (this) InvalidVehicle();
}
/**
* List of vehicles that should check for autoreplace this tick.
* Mapping of vehicle -> leave depot immediatelly after autoreplace.
*/
typedef SmallMap<Vehicle *, bool, 4> AutoreplaceMap;
static AutoreplaceMap _vehicles_to_autoreplace;
/** Adds a vehicle to the list of vehicles, that visited a depot this tick
* @param *v vehicle to add
*/
@ -2128,367 +2012,6 @@ SpriteID GetVehiclePalette(const Vehicle *v)
return GetEngineColourMap(v->engine_type, v->owner, INVALID_ENGINE, v);
}
static uint8 _cargo_days;
static uint16 _cargo_source;
static uint32 _cargo_source_xy;
static uint16 _cargo_count;
static uint16 _cargo_paid_for;
static Money _cargo_feeder_share;
static uint32 _cargo_loaded_at_xy;
/**
* Make it possible to make the saveload tables "friends" of other classes.
* @param vt the vehicle type. Can be VEH_END for the common vehicle description data
* @return the saveload description
*/
const SaveLoad *GetVehicleDescription(VehicleType vt)
{
/** Save and load of vehicles */
static const SaveLoad _common_veh_desc[] = {
SLE_VAR(Vehicle, subtype, SLE_UINT8),
SLE_REF(Vehicle, next, REF_VEHICLE_OLD),
SLE_CONDVAR(Vehicle, name, SLE_NAME, 0, 83),
SLE_CONDSTR(Vehicle, name, SLE_STR, 0, 84, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, unitnumber, SLE_FILE_U8 | SLE_VAR_U16, 0, 7),
SLE_CONDVAR(Vehicle, unitnumber, SLE_UINT16, 8, SL_MAX_VERSION),
SLE_VAR(Vehicle, owner, SLE_UINT8),
SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Vehicle, tile, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, dest_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Vehicle, dest_tile, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, x_pos, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Vehicle, x_pos, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, y_pos, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Vehicle, y_pos, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_VAR(Vehicle, z_pos, SLE_UINT8),
SLE_VAR(Vehicle, direction, SLE_UINT8),
SLE_CONDNULL(2, 0, 57),
SLE_VAR(Vehicle, spritenum, SLE_UINT8),
SLE_CONDNULL(5, 0, 57),
SLE_VAR(Vehicle, engine_type, SLE_UINT16),
SLE_VAR(Vehicle, max_speed, SLE_UINT16),
SLE_VAR(Vehicle, cur_speed, SLE_UINT16),
SLE_VAR(Vehicle, subspeed, SLE_UINT8),
SLE_VAR(Vehicle, acceleration, SLE_UINT8),
SLE_VAR(Vehicle, progress, SLE_UINT8),
SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
SLE_CONDVAR(Vehicle, last_station_visited, SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
SLE_CONDVAR(Vehicle, last_station_visited, SLE_UINT16, 5, SL_MAX_VERSION),
SLE_VAR(Vehicle, cargo_type, SLE_UINT8),
SLE_CONDVAR(Vehicle, cargo_subtype, SLE_UINT8, 35, SL_MAX_VERSION),
SLEG_CONDVAR( _cargo_days, SLE_UINT8, 0, 67),
SLEG_CONDVAR( _cargo_source, SLE_FILE_U8 | SLE_VAR_U16, 0, 6),
SLEG_CONDVAR( _cargo_source, SLE_UINT16, 7, 67),
SLEG_CONDVAR( _cargo_source_xy, SLE_UINT32, 44, 67),
SLE_VAR(Vehicle, cargo_cap, SLE_UINT16),
SLEG_CONDVAR( _cargo_count, SLE_UINT16, 0, 67),
SLE_CONDLST(Vehicle, cargo, REF_CARGO_PACKET, 68, SL_MAX_VERSION),
SLE_VAR(Vehicle, day_counter, SLE_UINT8),
SLE_VAR(Vehicle, tick_counter, SLE_UINT8),
SLE_CONDVAR(Vehicle, running_ticks, SLE_UINT8, 88, SL_MAX_VERSION),
SLE_VAR(Vehicle, cur_order_index, SLE_UINT8),
/* num_orders is now part of OrderList and is not saved but counted */
SLE_CONDNULL(1, 0, 104),
/* This next line is for version 4 and prior compatibility.. it temporarily reads
type and flags (which were both 4 bits) into type. Later on this is
converted correctly */
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, type), SLE_UINT8, 0, 4),
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
/* Orders for version 5 and on */
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, type), SLE_UINT8, 5, SL_MAX_VERSION),
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, flags), SLE_UINT8, 5, SL_MAX_VERSION),
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_UINT16, 5, SL_MAX_VERSION),
/* Refit in current order */
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, refit_cargo), SLE_UINT8, 36, SL_MAX_VERSION),
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, refit_subtype), SLE_UINT8, 36, SL_MAX_VERSION),
/* Timetable in current order */
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, wait_time), SLE_UINT16, 67, SL_MAX_VERSION),
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, travel_time), SLE_UINT16, 67, SL_MAX_VERSION),
SLE_CONDREF(Vehicle, orders, REF_ORDER, 0, 104),
SLE_CONDREF(Vehicle, orders, REF_ORDERLIST, 105, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
SLE_CONDVAR(Vehicle, age, SLE_INT32, 31, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, max_age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
SLE_CONDVAR(Vehicle, max_age, SLE_INT32, 31, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, date_of_last_service, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
SLE_CONDVAR(Vehicle, date_of_last_service, SLE_INT32, 31, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, service_interval, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
SLE_CONDVAR(Vehicle, service_interval, SLE_INT32, 31, SL_MAX_VERSION),
SLE_VAR(Vehicle, reliability, SLE_UINT16),
SLE_VAR(Vehicle, reliability_spd_dec, SLE_UINT16),
SLE_VAR(Vehicle, breakdown_ctr, SLE_UINT8),
SLE_VAR(Vehicle, breakdown_delay, SLE_UINT8),
SLE_VAR(Vehicle, breakdowns_since_last_service, SLE_UINT8),
SLE_VAR(Vehicle, breakdown_chance, SLE_UINT8),
SLE_CONDVAR(Vehicle, build_year, SLE_FILE_U8 | SLE_VAR_I32, 0, 30),
SLE_CONDVAR(Vehicle, build_year, SLE_INT32, 31, SL_MAX_VERSION),
SLE_VAR(Vehicle, load_unload_time_rem, SLE_UINT16),
SLEG_CONDVAR( _cargo_paid_for, SLE_UINT16, 45, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, vehicle_flags, SLE_UINT8, 40, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, profit_this_year, SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
SLE_CONDVAR(Vehicle, profit_this_year, SLE_INT64, 65, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, profit_last_year, SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
SLE_CONDVAR(Vehicle, profit_last_year, SLE_INT64, 65, SL_MAX_VERSION),
SLEG_CONDVAR( _cargo_feeder_share, SLE_FILE_I32 | SLE_VAR_I64,51, 64),
SLEG_CONDVAR( _cargo_feeder_share, SLE_INT64, 65, 67),
SLEG_CONDVAR( _cargo_loaded_at_xy, SLE_UINT32, 51, 67),
SLE_CONDVAR(Vehicle, value, SLE_FILE_I32 | SLE_VAR_I64, 0, 64),
SLE_CONDVAR(Vehicle, value, SLE_INT64, 65, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, random_bits, SLE_UINT8, 2, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, waiting_triggers, SLE_UINT8, 2, SL_MAX_VERSION),
SLE_CONDREF(Vehicle, next_shared, REF_VEHICLE, 2, SL_MAX_VERSION),
SLE_CONDNULL(2, 2, 68),
SLE_CONDNULL(4, 69, 100),
SLE_CONDVAR(Vehicle, group_id, SLE_UINT16, 60, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, current_order_time, SLE_UINT32, 67, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, lateness_counter, SLE_INT32, 67, SL_MAX_VERSION),
/* reserve extra space in savegame here. (currently 10 bytes) */
SLE_CONDNULL(10, 2, SL_MAX_VERSION),
SLE_END()
};
static const SaveLoad _train_desc[] = {
SLE_WRITEBYTE(Vehicle, type, VEH_TRAIN),
SLE_VEH_INCLUDEX(),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, crash_anim_pos), SLE_UINT16),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, force_proceed), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, railtype), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, track), SLE_UINT8),
SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, flags), SLE_FILE_U8 | SLE_VAR_U16, 2, 99),
SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRail, flags), SLE_UINT16,100, SL_MAX_VERSION),
SLE_CONDNULL(2, 2, 59),
SLE_CONDNULL(2, 2, 19),
/* reserve extra space in savegame here. (currently 11 bytes) */
SLE_CONDNULL(11, 2, SL_MAX_VERSION),
SLE_END()
};
static const SaveLoad _roadveh_desc[] = {
SLE_WRITEBYTE(Vehicle, type, VEH_ROAD),
SLE_VEH_INCLUDEX(),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, state), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, frame), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, blocked_ctr), SLE_UINT16),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, overtaking), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, overtaking_ctr), SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, crashed_ctr), SLE_UINT16),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, reverse_ctr), SLE_UINT8),
SLE_CONDREFX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, slot), REF_ROADSTOPS, 6, SL_MAX_VERSION),
SLE_CONDNULL(1, 6, SL_MAX_VERSION),
SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleRoad, slot_age), SLE_UINT8, 6, SL_MAX_VERSION),
/* reserve extra space in savegame here. (currently 16 bytes) */
SLE_CONDNULL(16, 2, SL_MAX_VERSION),
SLE_END()
};
static const SaveLoad _ship_desc[] = {
SLE_WRITEBYTE(Vehicle, type, VEH_SHIP),
SLE_VEH_INCLUDEX(),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleShip, state), SLE_UINT8),
/* reserve extra space in savegame here. (currently 16 bytes) */
SLE_CONDNULL(16, 2, SL_MAX_VERSION),
SLE_END()
};
static const SaveLoad _aircraft_desc[] = {
SLE_WRITEBYTE(Vehicle, type, VEH_AIRCRAFT),
SLE_VEH_INCLUDEX(),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, crashed_counter), SLE_UINT16),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, pos), SLE_UINT8),
SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, targetairport), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, targetairport), SLE_UINT16, 5, SL_MAX_VERSION),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, state), SLE_UINT8),
SLE_CONDVARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleAir, previous_pos), SLE_UINT8, 2, SL_MAX_VERSION),
/* reserve extra space in savegame here. (currently 15 bytes) */
SLE_CONDNULL(15, 2, SL_MAX_VERSION),
SLE_END()
};
static const SaveLoad _special_desc[] = {
SLE_WRITEBYTE(Vehicle, type, VEH_EFFECT),
SLE_VAR(Vehicle, subtype, SLE_UINT8),
SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Vehicle, tile, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, x_pos, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
SLE_CONDVAR(Vehicle, x_pos, SLE_INT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, y_pos, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
SLE_CONDVAR(Vehicle, y_pos, SLE_INT32, 6, SL_MAX_VERSION),
SLE_VAR(Vehicle, z_pos, SLE_UINT8),
SLE_VAR(Vehicle, cur_image, SLE_UINT16),
SLE_CONDNULL(5, 0, 57),
SLE_VAR(Vehicle, progress, SLE_UINT8),
SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleEffect, animation_state), SLE_UINT16),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleEffect, animation_substate), SLE_UINT8),
SLE_CONDVAR(Vehicle, spritenum, SLE_UINT8, 2, SL_MAX_VERSION),
/* reserve extra space in savegame here. (currently 15 bytes) */
SLE_CONDNULL(15, 2, SL_MAX_VERSION),
SLE_END()
};
static const SaveLoad _disaster_desc[] = {
SLE_WRITEBYTE(Vehicle, type, VEH_DISASTER),
SLE_REF(Vehicle, next, REF_VEHICLE_OLD),
SLE_VAR(Vehicle, subtype, SLE_UINT8),
SLE_CONDVAR(Vehicle, tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Vehicle, tile, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, dest_tile, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Vehicle, dest_tile, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, x_pos, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
SLE_CONDVAR(Vehicle, x_pos, SLE_INT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Vehicle, y_pos, SLE_FILE_I16 | SLE_VAR_I32, 0, 5),
SLE_CONDVAR(Vehicle, y_pos, SLE_INT32, 6, SL_MAX_VERSION),
SLE_VAR(Vehicle, z_pos, SLE_UINT8),
SLE_VAR(Vehicle, direction, SLE_UINT8),
SLE_CONDNULL(5, 0, 57),
SLE_VAR(Vehicle, owner, SLE_UINT8),
SLE_VAR(Vehicle, vehstatus, SLE_UINT8),
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_FILE_U8 | SLE_VAR_U16, 0, 4),
SLE_CONDVARX(cpp_offsetof(Vehicle, current_order) + cpp_offsetof(Order, dest), SLE_UINT16, 5, SL_MAX_VERSION),
SLE_VAR(Vehicle, cur_image, SLE_UINT16),
SLE_CONDVAR(Vehicle, age, SLE_FILE_U16 | SLE_VAR_I32, 0, 30),
SLE_CONDVAR(Vehicle, age, SLE_INT32, 31, SL_MAX_VERSION),
SLE_VAR(Vehicle, tick_counter, SLE_UINT8),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleDisaster, image_override), SLE_UINT16),
SLE_VARX(cpp_offsetof(Vehicle, u) + cpp_offsetof(VehicleDisaster, big_ufo_destroyer_target), SLE_UINT16),
/* reserve extra space in savegame here. (currently 16 bytes) */
SLE_CONDNULL(16, 2, SL_MAX_VERSION),
SLE_END()
};
static const SaveLoad *_veh_descs[] = {
_train_desc,
_roadveh_desc,
_ship_desc,
_aircraft_desc,
_special_desc,
_disaster_desc,
_common_veh_desc,
};
return _veh_descs[vt];
}
/** Will be called when the vehicles need to be saved. */
static void Save_VEHS()
{
Vehicle *v;
/* Write the vehicles */
FOR_ALL_VEHICLES(v) {
SlSetArrayIndex(v->index);
SlObject(v, GetVehicleDescription(v->type));
}
}
/** Will be called when vehicles need to be loaded. */
void Load_VEHS()
{
_vehicles_to_autoreplace.Reset();
int index;
_cargo_count = 0;
while ((index = SlIterateArray()) != -1) {
Vehicle *v;
VehicleType vtype = (VehicleType)SlReadByte();
switch (vtype) {
case VEH_TRAIN: v = new (index) Train(); break;
case VEH_ROAD: v = new (index) RoadVehicle(); break;
case VEH_SHIP: v = new (index) Ship(); break;
case VEH_AIRCRAFT: v = new (index) Aircraft(); break;
case VEH_EFFECT: v = new (index) EffectVehicle(); break;
case VEH_DISASTER: v = new (index) DisasterVehicle(); break;
case VEH_INVALID: v = new (index) InvalidVehicle(); break;
default: NOT_REACHED();
}
SlObject(v, GetVehicleDescription(vtype));
if (_cargo_count != 0 && IsCompanyBuildableVehicleType(v)) {
/* Don't construct the packet with station here, because that'll fail with old savegames */
CargoPacket *cp = new CargoPacket();
cp->source = _cargo_source;
cp->source_xy = _cargo_source_xy;
cp->count = _cargo_count;
cp->days_in_transit = _cargo_days;
cp->feeder_share = _cargo_feeder_share;
cp->loaded_at_xy = _cargo_loaded_at_xy;
v->cargo.Append(cp);
}
/* Old savegames used 'last_station_visited = 0xFF' */
if (CheckSavegameVersion(5) && v->last_station_visited == 0xFF)
v->last_station_visited = INVALID_STATION;
if (CheckSavegameVersion(5)) {
/* Convert the current_order.type (which is a mix of type and flags, because
* in those versions, they both were 4 bits big) to type and flags */
v->current_order.flags = GB(v->current_order.type, 4, 4);
v->current_order.type &= 0x0F;
}
/* Advanced vehicle lists got added */
if (CheckSavegameVersion(60)) v->group_id = DEFAULT_GROUP;
}
}
extern const ChunkHandler _veh_chunk_handlers[] = {
{ 'VEHS', Save_VEHS, Load_VEHS, CH_SPARSE_ARRAY | CH_LAST},
};
void Vehicle::BeginLoading()
{

@ -194,7 +194,6 @@ DECLARE_OLD_POOL(Vehicle, Vehicle, 9, 125)
/* Some declarations of functions, so we can make them friendly */
struct SaveLoad;
extern const SaveLoad *GetVehicleDescription(VehicleType vt);
extern void AfterLoadVehicles(bool part_of_load);
struct LoadgameState;
extern bool LoadOldVehicle(LoadgameState *ls, int num);
@ -712,4 +711,6 @@ Trackdir GetVehicleTrackdir(const Vehicle* v);
void CheckVehicle32Day(Vehicle *v);
static const int32 INVALID_COORD = 0x7fffffff;
#endif /* VEHICLE_BASE_H */

@ -2785,33 +2785,3 @@ void ResetObjectToPlace()
{
SetObjectToPlace(SPR_CURSOR_MOUSE, PAL_NONE, VHM_NONE, WC_MAIN_WINDOW, 0);
}
void SaveViewportBeforeSaveGame()
{
const Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
if (w != NULL) {
_saved_scrollpos_x = w->viewport->scrollpos_x;
_saved_scrollpos_y = w->viewport->scrollpos_y;
_saved_scrollpos_zoom = w->viewport->zoom;
}
}
void ResetViewportAfterLoadGame()
{
Window *w = FindWindowById(WC_MAIN_WINDOW, 0);
w->viewport->scrollpos_x = _saved_scrollpos_x;
w->viewport->scrollpos_y = _saved_scrollpos_y;
w->viewport->dest_scrollpos_x = _saved_scrollpos_x;
w->viewport->dest_scrollpos_y = _saved_scrollpos_y;
ViewPort *vp = w->viewport;
vp->zoom = min(_saved_scrollpos_zoom, ZOOM_LVL_MAX);
vp->virtual_width = ScaleByZoom(vp->width, vp->zoom);
vp->virtual_height = ScaleByZoom(vp->height, vp->zoom);
DoZoomInOutWindow(ZOOM_NONE, w); // update button status
MarkWholeScreenDirty();
}

@ -15,6 +15,5 @@ void DrawWaterClassGround(const struct TileInfo *ti);
void DrawShoreTile(Slope tileh);
void MakeWaterKeepingClass(TileIndex tile, Owner o);
void SetWaterClassDependingOnSurroundings(TileIndex t, bool include_invalid_water_class);
#endif /* WATER_H */

@ -101,88 +101,6 @@ static void MarkCanalsAndRiversAroundDirty(TileIndex tile)
}
}
/**
* Makes a tile canal or water depending on the surroundings.
*
* Must only be used for converting old savegames. Use WaterClass now.
*
* This as for example docks and shipdepots do not store
* whether the tile used to be canal or 'normal' water.
* @param t the tile to change.
* @param o the owner of the new tile.
* @param include_invalid_water_class Also consider WATER_CLASS_INVALID, i.e. industry tiles on land
*/
void SetWaterClassDependingOnSurroundings(TileIndex t, bool include_invalid_water_class)
{
/* If the slope is not flat, we always assume 'land' (if allowed). Also for one-corner-raised-shores.
* Note: Wrt. autosloping under industry tiles this is the most fool-proof behaviour. */
if (GetTileSlope(t, NULL) != SLOPE_FLAT) {
if (include_invalid_water_class) {
SetWaterClass(t, WATER_CLASS_INVALID);
return;
} else {
NOT_REACHED();
}
}
/* Mark tile dirty in all cases */
MarkTileDirtyByTile(t);
if (TileX(t) == 0 || TileY(t) == 0 || TileX(t) == MapMaxX() - 1 || TileY(t) == MapMaxY() - 1) {
/* tiles at map borders are always WATER_CLASS_SEA */
SetWaterClass(t, WATER_CLASS_SEA);
return;
}
bool has_water = false;
bool has_canal = false;
bool has_river = false;
for (DiagDirection dir = DIAGDIR_BEGIN; dir < DIAGDIR_END; dir++) {
TileIndex neighbour = TileAddByDiagDir(t, dir);
switch (GetTileType(neighbour)) {
case MP_WATER:
/* clear water and shipdepots have already a WaterClass associated */
if (IsCoast(neighbour)) {
has_water = true;
} else if (!IsLock(neighbour)) {
switch (GetWaterClass(neighbour)) {
case WATER_CLASS_SEA: has_water = true; break;
case WATER_CLASS_CANAL: has_canal = true; break;
case WATER_CLASS_RIVER: has_river = true; break;
default: NOT_REACHED();
}
}
break;
case MP_RAILWAY:
/* Shore or flooded halftile */
has_water |= (GetRailGroundType(neighbour) == RAIL_GROUND_WATER);
break;
case MP_TREES:
/* trees on shore */
has_water |= (GetTreeGround(neighbour) == TREE_GROUND_SHORE);
break;
default: break;
}
}
if (!has_water && !has_canal && !has_river && include_invalid_water_class) {
SetWaterClass(t, WATER_CLASS_INVALID);
return;
}
if (has_river && !has_canal) {
SetWaterClass(t, WATER_CLASS_RIVER);
} else if (has_canal || !has_water) {
SetWaterClass(t, WATER_CLASS_CANAL);
} else {
SetWaterClass(t, WATER_CLASS_SEA);
}
}
/** Build a ship depot.
* @param tile tile where ship depot is built

@ -11,7 +11,6 @@
#include "rail_map.h"
#include "rail.h"
#include "bridge_map.h"
#include "saveload.h"
#include "station_base.h"
#include "town.h"
#include "waypoint.h"
@ -157,29 +156,6 @@ static Waypoint *FindDeletedWaypointCloseTo(TileIndex tile)
return best;
}
/**
* Update waypoint graphics id against saved GRFID/localidx.
* This is to ensure the chosen graphics are correct if GRF files are changed.
*/
void AfterLoadWaypoints()
{
Waypoint *wp;
FOR_ALL_WAYPOINTS(wp) {
uint i;
if (wp->grfid == 0) continue;
for (i = 0; i < GetNumCustomStations(STAT_CLASS_WAYP); i++) {
const StationSpec *statspec = GetCustomStationSpec(STAT_CLASS_WAYP, i);
if (statspec != NULL && statspec->grffile->grfid == wp->grfid && statspec->localidx == wp->localidx) {
wp->stat_id = i;
break;
}
}
}
}
/** Convert existing rail to waypoint. Eg build a waypoint station over
* piece of rail
* @param tile tile where waypoint will be built
@ -463,69 +439,8 @@ Waypoint::~Waypoint()
this->xy = INVALID_TILE;
}
/**
* Fix savegames which stored waypoints in their old format
*/
void FixOldWaypoints()
{
Waypoint *wp;
/* Convert the old 'town_or_string', to 'string' / 'town' / 'town_cn' */
FOR_ALL_WAYPOINTS(wp) {
wp->town_index = ClosestTownFromTile(wp->xy, UINT_MAX)->index;
wp->town_cn = 0;
if (wp->string & 0xC000) {
wp->town_cn = wp->string & 0x3F;
wp->string = STR_NULL;
}
}
}
void InitializeWaypoints()
{
_Waypoint_pool.CleanPool();
_Waypoint_pool.AddBlockToPool();
}
static const SaveLoad _waypoint_desc[] = {
SLE_CONDVAR(Waypoint, xy, SLE_FILE_U16 | SLE_VAR_U32, 0, 5),
SLE_CONDVAR(Waypoint, xy, SLE_UINT32, 6, SL_MAX_VERSION),
SLE_CONDVAR(Waypoint, town_index, SLE_UINT16, 12, SL_MAX_VERSION),
SLE_CONDVAR(Waypoint, town_cn, SLE_FILE_U8 | SLE_VAR_U16, 12, 88),
SLE_CONDVAR(Waypoint, town_cn, SLE_UINT16, 89, SL_MAX_VERSION),
SLE_CONDVAR(Waypoint, string, SLE_STRINGID, 0, 83),
SLE_CONDSTR(Waypoint, name, SLE_STR, 0, 84, SL_MAX_VERSION),
SLE_VAR(Waypoint, deleted, SLE_UINT8),
SLE_CONDVAR(Waypoint, build_date, SLE_FILE_U16 | SLE_VAR_I32, 3, 30),
SLE_CONDVAR(Waypoint, build_date, SLE_INT32, 31, SL_MAX_VERSION),
SLE_CONDVAR(Waypoint, localidx, SLE_UINT8, 3, SL_MAX_VERSION),
SLE_CONDVAR(Waypoint, grfid, SLE_UINT32, 17, SL_MAX_VERSION),
SLE_CONDVAR(Waypoint, owner, SLE_UINT8, 101, SL_MAX_VERSION),
SLE_END()
};
static void Save_WAYP()
{
Waypoint *wp;
FOR_ALL_WAYPOINTS(wp) {
SlSetArrayIndex(wp->index);
SlObject(wp, _waypoint_desc);
}
}
static void Load_WAYP()
{
int index;
while ((index = SlIterateArray()) != -1) {
Waypoint *wp = new (index) Waypoint();
SlObject(wp, _waypoint_desc);
}
}
extern const ChunkHandler _waypoint_chunk_handlers[] = {
{ 'CHKP', Save_WAYP, Load_WAYP, CH_ARRAY | CH_LAST},
};

@ -12,6 +12,7 @@
#include "station_type.h"
#include "town_type.h"
#include "viewport_type.h"
#include "date_type.h"
DECLARE_OLD_POOL(Waypoint, Waypoint, 3, 8000)
@ -63,8 +64,6 @@ CommandCost RemoveTrainWaypoint(TileIndex tile, uint32 flags, bool justremove);
Station *ComposeWaypointStation(TileIndex tile);
void ShowWaypointWindow(const Waypoint *wp);
void DrawWaypointSprite(int x, int y, int stat_id, RailType railtype);
void FixOldWaypoints();
void UpdateAllWaypointSigns();
void AfterLoadWaypoints();
#endif /* WAYPOINT_H */

@ -5,7 +5,7 @@
#include "stdafx.h"
#include "openttd.h"
#include "debug.h"
#include "saveload.h"
#include "saveload/saveload.h"
#include "gfx_func.h"
#include "textbuf_gui.h"
#include "fileio_func.h"

Loading…
Cancel
Save