diff --git a/src/base_station_base.h b/src/base_station_base.h index 40543f1b8f..2ad09ca21c 100644 --- a/src/base_station_base.h +++ b/src/base_station_base.h @@ -62,8 +62,7 @@ struct BaseStation : StationPool::PoolItem<&_station_pool> { Owner owner; ///< The owner of this station StationFacility facilities; ///< The facilities that this station has - uint8 num_specs; ///< Number of specs in the speclist - StationSpecList *speclist; ///< List of station specs of this station + std::vector speclist; ///< List of rail station specs of this station. Date build_date; ///< Date of construction diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index 698d360a0c..bf938eab0f 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -683,7 +683,7 @@ int AllocateSpecToStation(const StationSpec *statspec, BaseStation *st, bool exe if (statspec == nullptr || st == nullptr) return 0; - for (i = 1; i < st->num_specs && i < NUM_STATIONSSPECS_PER_STATION; i++) { + for (i = 1; i < st->speclist.size() && i < NUM_STATIONSSPECS_PER_STATION; i++) { if (st->speclist[i].spec == nullptr && st->speclist[i].grfid == 0) break; } @@ -693,7 +693,7 @@ int AllocateSpecToStation(const StationSpec *statspec, BaseStation *st, bool exe * result in slightly "wrong" (as per specs) looking stations, * but it's fairly unlikely that one reaches the limit anyways. */ - for (i = 1; i < st->num_specs && i < NUM_STATIONSSPECS_PER_STATION; i++) { + for (i = 1; i < st->speclist.size() && i < NUM_STATIONSSPECS_PER_STATION; i++) { if (st->speclist[i].spec == statspec) return i; } @@ -701,18 +701,7 @@ int AllocateSpecToStation(const StationSpec *statspec, BaseStation *st, bool exe } if (exec) { - if (i >= st->num_specs) { - st->num_specs = i + 1; - st->speclist = ReallocT(st->speclist, st->num_specs); - - if (st->num_specs == 2) { - /* Initial allocation */ - st->speclist[0].spec = nullptr; - st->speclist[0].grfid = 0; - st->speclist[0].localidx = 0; - } - } - + if (i >= st->speclist.size()) st->speclist.resize(i + 1); st->speclist[i].spec = statspec; st->speclist[i].grfid = statspec->grf_prop.grffile->grfid; st->speclist[i].localidx = statspec->grf_prop.local_id; @@ -749,15 +738,16 @@ void DeallocateSpecFromStation(BaseStation *st, byte specindex) st->speclist[specindex].localidx = 0; /* If this was the highest spec index, reallocate */ - if (specindex == st->num_specs - 1) { - for (; st->speclist[st->num_specs - 1].grfid == 0 && st->num_specs > 1; st->num_specs--) {} + if (specindex == st->speclist.size() - 1) { + size_t num_specs; + for (num_specs = st->speclist.size() - 1; num_specs > 0; num_specs--) { + if (st->speclist[num_specs].grfid != 0) break; + } - if (st->num_specs > 1) { - st->speclist = ReallocT(st->speclist, st->num_specs); + if (num_specs > 0) { + st->speclist.resize(num_specs + 1); } else { - free(st->speclist); - st->num_specs = 0; - st->speclist = nullptr; + st->speclist.clear(); st->cached_anim_triggers = 0; st->cached_cargo_triggers = 0; return; @@ -854,7 +844,7 @@ const StationSpec *GetStationSpec(TileIndex t) const BaseStation *st = BaseStation::GetByTile(t); uint specindex = GetCustomStationSpecIndex(t); - return specindex < st->num_specs ? st->speclist[specindex].spec : nullptr; + return specindex < st->speclist.size() ? st->speclist[specindex].spec : nullptr; } @@ -1050,7 +1040,7 @@ void StationUpdateCachedTriggers(BaseStation *st) /* Combine animation trigger bitmask for all station specs * of this station. */ - for (uint i = 0; i < st->num_specs; i++) { + for (uint i = 0; i < st->speclist.size(); i++) { const StationSpec *ss = st->speclist[i].spec; if (ss != nullptr) { st->cached_anim_triggers |= ss->animation.triggers; diff --git a/src/saveload/station_sl.cpp b/src/saveload/station_sl.cpp index 20d70066e9..b5f4cbcd13 100644 --- a/src/saveload/station_sl.cpp +++ b/src/saveload/station_sl.cpp @@ -109,7 +109,7 @@ void AfterLoadStations() { /* Update the speclists of all stations to point to the currently loaded custom stations. */ for (BaseStation *st : BaseStation::Iterate()) { - for (uint i = 0; i < st->num_specs; i++) { + for (uint i = 0; i < st->speclist.size(); i++) { if (st->speclist[i].grfid == 0) continue; st->speclist[i].spec = StationClass::GetByGrf(st->speclist[i].grfid, st->speclist[i].localidx, nullptr); @@ -201,30 +201,29 @@ public: }; inline const static SaveLoadCompatTable compat_description = _station_spec_list_sl_compat; + static uint8 last_num_specs; ///< Number of specs of the last loaded station. + void Save(BaseStation *bst) const override { - SlSetStructListLength(bst->num_specs); - for (uint i = 0; i < bst->num_specs; i++) { + SlSetStructListLength(bst->speclist.size()); + for (uint i = 0; i < bst->speclist.size(); i++) { SlObject(&bst->speclist[i], this->GetDescription()); } } void Load(BaseStation *bst) const override { - if (!IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH)) { - bst->num_specs = (uint8)SlGetStructListLength(UINT8_MAX); - } + uint8 num_specs = IsSavegameVersionBefore(SLV_SAVELOAD_LIST_LENGTH) ? last_num_specs : (uint8)SlGetStructListLength(UINT8_MAX); - if (bst->num_specs != 0) { - /* Allocate speclist memory when loading a game */ - bst->speclist = CallocT(bst->num_specs); - for (uint i = 0; i < bst->num_specs; i++) { - SlObject(&bst->speclist[i], this->GetLoadDescription()); - } + bst->speclist.resize(num_specs); + for (uint i = 0; i < num_specs; i++) { + SlObject(&bst->speclist[i], this->GetLoadDescription()); } } }; +uint8 SlStationSpecList::last_num_specs; + class SlStationCargo : public DefaultSaveLoadHandler { public: inline static const SaveLoad description[] = { @@ -476,7 +475,7 @@ static const SaveLoad _old_station_desc[] = { /* Used by newstations for graphic variations */ SLE_CONDVAR(Station, random_bits, SLE_UINT16, SLV_27, SL_MAX_VERSION), SLE_CONDVAR(Station, waiting_triggers, SLE_UINT8, SLV_27, SL_MAX_VERSION), - SLE_CONDVAR(Station, num_specs, SLE_UINT8, SLV_27, SL_MAX_VERSION), + SLEG_CONDVAR("num_specs", SlStationSpecList::last_num_specs, SLE_UINT8, SLV_27, SL_MAX_VERSION), SLE_CONDREFLIST(Station, loading_vehicles, REF_VEHICLE, SLV_57, SL_MAX_VERSION), @@ -536,7 +535,7 @@ public: /* Used by newstations for graphic variations */ SLE_VAR(BaseStation, random_bits, SLE_UINT16), SLE_VAR(BaseStation, waiting_triggers, SLE_UINT8), - SLE_CONDVAR(BaseStation, num_specs, SLE_UINT8, SL_MIN_VERSION, SLV_SAVELOAD_LIST_LENGTH), + SLEG_CONDVAR("num_specs", SlStationSpecList::last_num_specs, SLE_UINT8, SL_MIN_VERSION, SLV_SAVELOAD_LIST_LENGTH), }; inline const static SaveLoadCompatTable compat_description = _station_base_sl_compat; diff --git a/src/station.cpp b/src/station.cpp index fc258fcc92..b73f566561 100644 --- a/src/station.cpp +++ b/src/station.cpp @@ -51,8 +51,6 @@ void RebuildStationKdtree() BaseStation::~BaseStation() { - free(this->speclist); - if (CleaningPool()) return; CloseWindowById(WC_TRAINS_LIST, VehicleListIdentifier(VL_STATION_LIST, VEH_TRAIN, this->owner, this->index).Pack()); @@ -227,7 +225,7 @@ void Station::MarkTilesDirty(bool cargo_change) const /* Don't waste time updating if there are no custom station graphics * that might change. Even if there are custom graphics, they might * not change. Unfortunately we have no way of telling. */ - if (this->num_specs == 0) return; + if (this->speclist.size() == 0) return; } for (h = 0; h < train_station.h; h++) {