Cache animated tile speed, use btree map for animated tiles
This commit is contained in:
@@ -38,6 +38,7 @@ add_files(
|
|||||||
airport.h
|
airport.h
|
||||||
airport_gui.cpp
|
airport_gui.cpp
|
||||||
animated_tile.cpp
|
animated_tile.cpp
|
||||||
|
animated_tile.h
|
||||||
animated_tile_func.h
|
animated_tile_func.h
|
||||||
articulated_vehicles.cpp
|
articulated_vehicles.cpp
|
||||||
articulated_vehicles.h
|
articulated_vehicles.h
|
||||||
|
@@ -8,16 +8,19 @@
|
|||||||
/** @file animated_tile.cpp Everything related to animated tiles. */
|
/** @file animated_tile.cpp Everything related to animated tiles. */
|
||||||
|
|
||||||
#include "stdafx.h"
|
#include "stdafx.h"
|
||||||
|
#include "animated_tile.h"
|
||||||
#include "core/alloc_func.hpp"
|
#include "core/alloc_func.hpp"
|
||||||
#include "core/smallvec_type.hpp"
|
#include "core/smallvec_type.hpp"
|
||||||
#include "tile_cmd.h"
|
#include "tile_cmd.h"
|
||||||
#include "viewport_func.h"
|
#include "viewport_func.h"
|
||||||
#include "framerate_type.h"
|
#include "framerate_type.h"
|
||||||
|
#include "date_func.h"
|
||||||
|
#include "3rdparty/cpp-btree/btree_map.h"
|
||||||
|
|
||||||
#include "safeguards.h"
|
#include "safeguards.h"
|
||||||
|
|
||||||
/** The table/list with animated tiles. */
|
/** The table/list with animated tiles. */
|
||||||
std::vector<TileIndex> _animated_tiles;
|
btree::btree_map<TileIndex, AnimatedTileInfo> _animated_tiles;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Removes the given tile from the animated tile table.
|
* Removes the given tile from the animated tile table.
|
||||||
@@ -25,14 +28,43 @@ std::vector<TileIndex> _animated_tiles;
|
|||||||
*/
|
*/
|
||||||
void DeleteAnimatedTile(TileIndex tile)
|
void DeleteAnimatedTile(TileIndex tile)
|
||||||
{
|
{
|
||||||
auto to_remove = std::find(_animated_tiles.begin(), _animated_tiles.end(), tile);
|
auto to_remove = _animated_tiles.find(tile);
|
||||||
if (to_remove != _animated_tiles.end()) {
|
if (to_remove != _animated_tiles.end() && !to_remove->second.pending_deletion) {
|
||||||
/* The order of the remaining elements must stay the same, otherwise the animation loop may miss a tile. */
|
to_remove->second.pending_deletion = true;
|
||||||
_animated_tiles.erase(to_remove);
|
|
||||||
MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE);
|
MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void UpdateAnimatedTileSpeed(TileIndex tile, AnimatedTileInfo &info)
|
||||||
|
{
|
||||||
|
extern uint8 GetAnimatedTileSpeed_Town(TileIndex tile);
|
||||||
|
extern uint8 GetAnimatedTileSpeed_Station(TileIndex tile);
|
||||||
|
extern uint8 GetAnimatedTileSpeed_Industry(TileIndex tile);
|
||||||
|
extern uint8 GetNewObjectTileAnimationSpeed(TileIndex tile);
|
||||||
|
|
||||||
|
switch (GetTileType(tile)) {
|
||||||
|
case MP_HOUSE:
|
||||||
|
info.speed = GetAnimatedTileSpeed_Town(tile);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MP_STATION:
|
||||||
|
info.speed = GetAnimatedTileSpeed_Station(tile);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MP_INDUSTRY:
|
||||||
|
info.speed = GetAnimatedTileSpeed_Industry(tile);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MP_OBJECT:
|
||||||
|
info.speed = GetNewObjectTileAnimationSpeed(tile);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
info.speed = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Add the given tile to the animated tile table (if it does not exist
|
* Add the given tile to the animated tile table (if it does not exist
|
||||||
* on that table yet). Also increases the size of the table if necessary.
|
* on that table yet). Also increases the size of the table if necessary.
|
||||||
@@ -41,7 +73,18 @@ void DeleteAnimatedTile(TileIndex tile)
|
|||||||
void AddAnimatedTile(TileIndex tile)
|
void AddAnimatedTile(TileIndex tile)
|
||||||
{
|
{
|
||||||
MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE);
|
MarkTileDirtyByTile(tile, VMDF_NOT_MAP_MODE);
|
||||||
include(_animated_tiles, tile);
|
AnimatedTileInfo &info = _animated_tiles[tile];
|
||||||
|
UpdateAnimatedTileSpeed(tile, info);
|
||||||
|
info.pending_deletion = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
int GetAnimatedTileSpeed(TileIndex tile)
|
||||||
|
{
|
||||||
|
const auto iter = _animated_tiles.find(tile);
|
||||||
|
if (iter != _animated_tiles.end() && !iter->second.pending_deletion) {
|
||||||
|
return iter->second.speed;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -56,40 +99,53 @@ void AnimateAnimatedTiles()
|
|||||||
|
|
||||||
PerformanceAccumulator framerate(PFE_GL_LANDSCAPE);
|
PerformanceAccumulator framerate(PFE_GL_LANDSCAPE);
|
||||||
|
|
||||||
const TileIndex *ti = _animated_tiles.data();
|
const uint32 ticks = (uint) _scaled_tick_counter;
|
||||||
while (ti < _animated_tiles.data() + _animated_tiles.size()) {
|
const uint8 max_speed = (ticks == 0) ? 32 : FindFirstBit(ticks);
|
||||||
const TileIndex curr = *ti;
|
|
||||||
switch (GetTileType(curr)) {
|
|
||||||
case MP_HOUSE:
|
|
||||||
AnimateTile_Town(curr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MP_STATION:
|
auto iter = _animated_tiles.begin();
|
||||||
AnimateTile_Station(curr);
|
while (iter != _animated_tiles.end()) {
|
||||||
break;
|
if (iter->second.pending_deletion) {
|
||||||
|
iter = _animated_tiles.erase(iter);
|
||||||
case MP_INDUSTRY:
|
continue;
|
||||||
AnimateTile_Industry(curr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case MP_OBJECT:
|
|
||||||
AnimateTile_Object(curr);
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
NOT_REACHED();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* During the AnimateTile call, DeleteAnimatedTile could have been called,
|
if (iter->second.speed <= max_speed) {
|
||||||
* deleting an element we've already processed and pushing the rest one
|
const TileIndex curr = iter->first;
|
||||||
* slot to the left. We can detect this by checking whether the index
|
switch (GetTileType(curr)) {
|
||||||
* in the current slot has changed - if it has, an element has been deleted,
|
case MP_HOUSE:
|
||||||
* and we should process the current slot again instead of going forward.
|
AnimateTile_Town(curr);
|
||||||
* NOTE: this will still break if more than one animated tile is being
|
break;
|
||||||
* deleted during the same AnimateTile call, but no code seems to
|
|
||||||
* be doing this anyway.
|
case MP_STATION:
|
||||||
*/
|
AnimateTile_Station(curr);
|
||||||
if (*ti == curr) ++ti;
|
break;
|
||||||
|
|
||||||
|
case MP_INDUSTRY:
|
||||||
|
AnimateTile_Industry(curr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case MP_OBJECT:
|
||||||
|
AnimateTile_Object(curr);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
NOT_REACHED();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
++iter;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateAllAnimatedTileSpeeds()
|
||||||
|
{
|
||||||
|
auto iter = _animated_tiles.begin();
|
||||||
|
while (iter != _animated_tiles.end()) {
|
||||||
|
if (iter->second.pending_deletion) {
|
||||||
|
iter = _animated_tiles.erase(iter);
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
UpdateAnimatedTileSpeed(iter->first, iter->second);
|
||||||
|
++iter;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
23
src/animated_tile.h
Normal file
23
src/animated_tile.h
Normal file
@@ -0,0 +1,23 @@
|
|||||||
|
/*
|
||||||
|
* This file is part of OpenTTD.
|
||||||
|
* OpenTTD is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by the Free Software Foundation, version 2.
|
||||||
|
* OpenTTD is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
|
||||||
|
* See the GNU General Public License for more details. You should have received a copy of the GNU General Public License along with OpenTTD. If not, see <http://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/** @file animated_tile.h %Tile animation! */
|
||||||
|
|
||||||
|
#ifndef ANIMATED_TILE_H
|
||||||
|
#define ANIMATED_TILE_H
|
||||||
|
|
||||||
|
#include "tile_type.h"
|
||||||
|
#include "3rdparty/cpp-btree/btree_map.h"
|
||||||
|
|
||||||
|
struct AnimatedTileInfo {
|
||||||
|
uint8 speed = 0;
|
||||||
|
bool pending_deletion = false;
|
||||||
|
};
|
||||||
|
|
||||||
|
extern btree::btree_map<TileIndex, AnimatedTileInfo> _animated_tiles;
|
||||||
|
|
||||||
|
#endif /* ANIMATED_TILE_H */
|
@@ -15,6 +15,7 @@
|
|||||||
void AddAnimatedTile(TileIndex tile);
|
void AddAnimatedTile(TileIndex tile);
|
||||||
void DeleteAnimatedTile(TileIndex tile);
|
void DeleteAnimatedTile(TileIndex tile);
|
||||||
void AnimateAnimatedTiles();
|
void AnimateAnimatedTiles();
|
||||||
|
void UpdateAllAnimatedTileSpeeds();
|
||||||
void InitializeAnimatedTiles();
|
void InitializeAnimatedTiles();
|
||||||
|
|
||||||
#endif /* ANIMATED_TILE_FUNC_H */
|
#endif /* ANIMATED_TILE_FUNC_H */
|
||||||
|
@@ -724,6 +724,47 @@ void AnimateTile_Industry(TileIndex tile)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
uint8 GetAnimatedTileSpeed_Industry(TileIndex tile)
|
||||||
|
{
|
||||||
|
IndustryGfx gfx = GetIndustryGfx(tile);
|
||||||
|
|
||||||
|
if (GetIndustryTileSpec(gfx)->animation.status != ANIM_STATUS_NO_ANIMATION) {
|
||||||
|
return GetNewIndustryTileAnimationSpeed(tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
switch (gfx) {
|
||||||
|
case GFX_SUGAR_MINE_SIEVE:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case GFX_TOFFEE_QUARY:
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
case GFX_BUBBLE_CATCHER:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case GFX_POWERPLANT_SPARKS:
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
case GFX_TOY_FACTORY:
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
case GFX_PLASTIC_FOUNTAIN_ANIMATED_1: case GFX_PLASTIC_FOUNTAIN_ANIMATED_2:
|
||||||
|
case GFX_PLASTIC_FOUNTAIN_ANIMATED_3: case GFX_PLASTIC_FOUNTAIN_ANIMATED_4:
|
||||||
|
case GFX_PLASTIC_FOUNTAIN_ANIMATED_5: case GFX_PLASTIC_FOUNTAIN_ANIMATED_6:
|
||||||
|
case GFX_PLASTIC_FOUNTAIN_ANIMATED_7: case GFX_PLASTIC_FOUNTAIN_ANIMATED_8:
|
||||||
|
return 2;
|
||||||
|
|
||||||
|
case GFX_OILWELL_ANIMATED_1:
|
||||||
|
case GFX_OILWELL_ANIMATED_2:
|
||||||
|
case GFX_OILWELL_ANIMATED_3:
|
||||||
|
return 3;
|
||||||
|
|
||||||
|
default:
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void CreateChimneySmoke(TileIndex tile)
|
static void CreateChimneySmoke(TileIndex tile)
|
||||||
{
|
{
|
||||||
uint x = TileX(tile) * TILE_SIZE;
|
uint x = TileX(tile) * TILE_SIZE;
|
||||||
|
@@ -312,3 +312,10 @@ void AirportAnimationTrigger(Station *st, AirpAnimationTrigger trigger, CargoID
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8 GetAirportTileAnimationSpeed(TileIndex tile)
|
||||||
|
{
|
||||||
|
const AirportTileSpec *ats = AirportTileSpec::GetByTile(tile);
|
||||||
|
if (ats == nullptr) return 0;
|
||||||
|
|
||||||
|
return AirportTileAnimationBase::GetAnimationSpeed(ats);
|
||||||
|
}
|
||||||
|
@@ -86,6 +86,7 @@ StationGfx GetTranslatedAirportTileID(StationGfx gfx);
|
|||||||
void AnimateAirportTile(TileIndex tile);
|
void AnimateAirportTile(TileIndex tile);
|
||||||
void AirportTileAnimationTrigger(Station *st, TileIndex tile, AirpAnimationTrigger trigger, CargoID cargo_type = CT_INVALID);
|
void AirportTileAnimationTrigger(Station *st, TileIndex tile, AirpAnimationTrigger trigger, CargoID cargo_type = CT_INVALID);
|
||||||
void AirportAnimationTrigger(Station *st, AirpAnimationTrigger trigger, CargoID cargo_type = CT_INVALID);
|
void AirportAnimationTrigger(Station *st, AirpAnimationTrigger trigger, CargoID cargo_type = CT_INVALID);
|
||||||
|
uint8 GetAirportTileAnimationSpeed(TileIndex tile);
|
||||||
bool DrawNewAirportTile(TileInfo *ti, Station *st, StationGfx gfx, const AirportTileSpec *airts);
|
bool DrawNewAirportTile(TileInfo *ti, Station *st, StationGfx gfx, const AirportTileSpec *airts);
|
||||||
|
|
||||||
#endif /* NEWGRF_AIRPORTTILES_H */
|
#endif /* NEWGRF_AIRPORTTILES_H */
|
||||||
|
@@ -133,4 +133,10 @@ struct AnimationBase {
|
|||||||
* result are not empty, it is a sound effect. */
|
* result are not empty, it is a sound effect. */
|
||||||
if (GB(callback, 8, 7) != 0 && _settings_client.sound.ambient) PlayTileSound(spec->grf_prop.grffile, GB(callback, 8, 7), tile);
|
if (GB(callback, 8, 7) != 0 && _settings_client.sound.ambient) PlayTileSound(spec->grf_prop.grffile, GB(callback, 8, 7), tile);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static uint8 GetAnimationSpeed(const Tspec *spec)
|
||||||
|
{
|
||||||
|
if (HasBit(spec->callback_mask, Tbase::cbm_animation_speed)) return 0;
|
||||||
|
return spec->animation.speed;
|
||||||
|
}
|
||||||
};
|
};
|
||||||
|
@@ -662,6 +662,14 @@ void AnimateNewHouseConstruction(TileIndex tile)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8 GetNewHouseTileAnimationSpeed(TileIndex tile)
|
||||||
|
{
|
||||||
|
const HouseSpec *hs = HouseSpec::Get(GetHouseType(tile));
|
||||||
|
if (hs == nullptr) return 0;
|
||||||
|
|
||||||
|
return HouseAnimationBase::GetAnimationSpeed(hs);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Check if GRF allows a given house to be constructed (callback 17)
|
* Check if GRF allows a given house to be constructed (callback 17)
|
||||||
* @param house_id house type
|
* @param house_id house type
|
||||||
|
@@ -144,6 +144,7 @@ void DrawNewHouseTile(TileInfo *ti, HouseID house_id);
|
|||||||
void DrawNewHouseTileInGUI(int x, int y, HouseID house_id, bool ground);
|
void DrawNewHouseTileInGUI(int x, int y, HouseID house_id, bool ground);
|
||||||
void AnimateNewHouseTile(TileIndex tile);
|
void AnimateNewHouseTile(TileIndex tile);
|
||||||
void AnimateNewHouseConstruction(TileIndex tile);
|
void AnimateNewHouseConstruction(TileIndex tile);
|
||||||
|
uint8 GetNewHouseTileAnimationSpeed(TileIndex tile);
|
||||||
|
|
||||||
uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town = nullptr, TileIndex tile = INVALID_TILE,
|
uint16 GetHouseCallback(CallbackID callback, uint32 param1, uint32 param2, HouseID house_id, Town *town = nullptr, TileIndex tile = INVALID_TILE,
|
||||||
bool not_yet_constructed = false, uint8 initial_random_bits = 0, CargoTypes watched_cargo_triggers = 0);
|
bool not_yet_constructed = false, uint8 initial_random_bits = 0, CargoTypes watched_cargo_triggers = 0);
|
||||||
|
@@ -300,6 +300,14 @@ bool StartStopIndustryTileAnimation(const Industry *ind, IndustryAnimationTrigge
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8 GetNewIndustryTileAnimationSpeed(TileIndex tile)
|
||||||
|
{
|
||||||
|
const IndustryTileSpec *itspec = GetIndustryTileSpec(GetIndustryGfx(tile));
|
||||||
|
if (itspec == nullptr) return 0;
|
||||||
|
|
||||||
|
return IndustryAnimationBase::GetAnimationSpeed(itspec);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trigger random triggers for an industry tile and reseed its random bits.
|
* Trigger random triggers for an industry tile and reseed its random bits.
|
||||||
* @param tile Industry tile to trigger.
|
* @param tile Industry tile to trigger.
|
||||||
|
@@ -64,6 +64,7 @@ CommandCost PerformIndustryTileSlopeCheck(TileIndex ind_base_tile, TileIndex ind
|
|||||||
void AnimateNewIndustryTile(TileIndex tile);
|
void AnimateNewIndustryTile(TileIndex tile);
|
||||||
bool StartStopIndustryTileAnimation(TileIndex tile, IndustryAnimationTrigger iat, uint32 random = Random());
|
bool StartStopIndustryTileAnimation(TileIndex tile, IndustryAnimationTrigger iat, uint32 random = Random());
|
||||||
bool StartStopIndustryTileAnimation(const Industry *ind, IndustryAnimationTrigger iat);
|
bool StartStopIndustryTileAnimation(const Industry *ind, IndustryAnimationTrigger iat);
|
||||||
|
uint8 GetNewIndustryTileAnimationSpeed(TileIndex tile);
|
||||||
|
|
||||||
|
|
||||||
/** Available industry tile triggers. */
|
/** Available industry tile triggers. */
|
||||||
|
@@ -530,6 +530,14 @@ void AnimateNewObjectTile(TileIndex tile)
|
|||||||
ObjectAnimationBase::AnimateTile(spec, Object::GetByTile(tile), tile, (spec->flags & OBJECT_FLAG_ANIM_RANDOM_BITS) != 0);
|
ObjectAnimationBase::AnimateTile(spec, Object::GetByTile(tile), tile, (spec->flags & OBJECT_FLAG_ANIM_RANDOM_BITS) != 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8 GetNewObjectTileAnimationSpeed(TileIndex tile)
|
||||||
|
{
|
||||||
|
const ObjectSpec *spec = ObjectSpec::GetByTile(tile);
|
||||||
|
if (spec == nullptr || !(spec->flags & OBJECT_FLAG_ANIMATION)) return 0;
|
||||||
|
|
||||||
|
return ObjectAnimationBase::GetAnimationSpeed(spec);
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Trigger the update of animation on a single tile.
|
* Trigger the update of animation on a single tile.
|
||||||
* @param o The object that got triggered.
|
* @param o The object that got triggered.
|
||||||
|
@@ -163,6 +163,7 @@ uint16 GetObjectCallback(CallbackID callback, uint32 param1, uint32 param2, cons
|
|||||||
void DrawNewObjectTile(TileInfo *ti, const ObjectSpec *spec);
|
void DrawNewObjectTile(TileInfo *ti, const ObjectSpec *spec);
|
||||||
void DrawNewObjectTileInGUI(int x, int y, const ObjectSpec *spec, uint8 view);
|
void DrawNewObjectTileInGUI(int x, int y, const ObjectSpec *spec, uint8 view);
|
||||||
void AnimateNewObjectTile(TileIndex tile);
|
void AnimateNewObjectTile(TileIndex tile);
|
||||||
|
uint8 GetNewObjectTileAnimationSpeed(TileIndex tile);
|
||||||
void TriggerObjectTileAnimation(Object *o, TileIndex tile, ObjectAnimationTrigger trigger, const ObjectSpec *spec);
|
void TriggerObjectTileAnimation(Object *o, TileIndex tile, ObjectAnimationTrigger trigger, const ObjectSpec *spec);
|
||||||
void TriggerObjectAnimation(Object *o, ObjectAnimationTrigger trigger, const ObjectSpec *spec);
|
void TriggerObjectAnimation(Object *o, ObjectAnimationTrigger trigger, const ObjectSpec *spec);
|
||||||
|
|
||||||
|
@@ -924,6 +924,14 @@ void AnimateStationTile(TileIndex tile)
|
|||||||
StationAnimationBase::AnimateTile(ss, BaseStation::GetByTile(tile), tile, HasBit(ss->flags, SSF_CB141_RANDOM_BITS));
|
StationAnimationBase::AnimateTile(ss, BaseStation::GetByTile(tile), tile, HasBit(ss->flags, SSF_CB141_RANDOM_BITS));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8 GetStationTileAnimationSpeed(TileIndex tile)
|
||||||
|
{
|
||||||
|
const StationSpec *ss = GetStationSpec(tile);
|
||||||
|
if (ss == nullptr) return 0;
|
||||||
|
|
||||||
|
return StationAnimationBase::GetAnimationSpeed(ss);
|
||||||
|
}
|
||||||
|
|
||||||
void TriggerStationAnimation(BaseStation *st, TileIndex tile, StationAnimationTrigger trigger, CargoID cargo_type)
|
void TriggerStationAnimation(BaseStation *st, TileIndex tile, StationAnimationTrigger trigger, CargoID cargo_type)
|
||||||
{
|
{
|
||||||
/* List of coverage areas for each animation trigger */
|
/* List of coverage areas for each animation trigger */
|
||||||
|
@@ -204,6 +204,7 @@ void DeallocateSpecFromStation(BaseStation *st, byte specindex);
|
|||||||
bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID sclass, uint station);
|
bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID sclass, uint station);
|
||||||
|
|
||||||
void AnimateStationTile(TileIndex tile);
|
void AnimateStationTile(TileIndex tile);
|
||||||
|
uint8 GetStationTileAnimationSpeed(TileIndex tile);
|
||||||
void TriggerStationAnimation(BaseStation *st, TileIndex tile, StationAnimationTrigger trigger, CargoID cargo_type = CT_INVALID);
|
void TriggerStationAnimation(BaseStation *st, TileIndex tile, StationAnimationTrigger trigger, CargoID cargo_type = CT_INVALID);
|
||||||
void TriggerStationRandomisation(Station *st, TileIndex tile, StationRandomTrigger trigger, CargoID cargo_type = CT_INVALID);
|
void TriggerStationRandomisation(Station *st, TileIndex tile, StationRandomTrigger trigger, CargoID cargo_type = CT_INVALID);
|
||||||
void StationUpdateCachedTriggers(BaseStation *st);
|
void StationUpdateCachedTriggers(BaseStation *st);
|
||||||
|
@@ -63,6 +63,7 @@
|
|||||||
#include "../bridge_signal_map.h"
|
#include "../bridge_signal_map.h"
|
||||||
#include "../water.h"
|
#include "../water.h"
|
||||||
#include "../settings_func.h"
|
#include "../settings_func.h"
|
||||||
|
#include "../animated_tile.h"
|
||||||
|
|
||||||
|
|
||||||
#include "saveload_internal.h"
|
#include "saveload_internal.h"
|
||||||
@@ -2461,16 +2462,9 @@ bool AfterLoadGame()
|
|||||||
/* Animated tiles would sometimes not be actually animated or
|
/* Animated tiles would sometimes not be actually animated or
|
||||||
* in case of old savegames duplicate. */
|
* in case of old savegames duplicate. */
|
||||||
|
|
||||||
extern std::vector<TileIndex> _animated_tiles;
|
for (auto tile = _animated_tiles.begin(); tile != _animated_tiles.end(); /* Nothing */) {
|
||||||
|
|
||||||
for (auto tile = _animated_tiles.begin(); tile < _animated_tiles.end(); /* Nothing */) {
|
|
||||||
/* Remove if tile is not animated */
|
/* Remove if tile is not animated */
|
||||||
bool remove = _tile_type_procs[GetTileType(*tile)]->animate_tile_proc == nullptr;
|
bool remove = _tile_type_procs[GetTileType(tile->first)]->animate_tile_proc == nullptr;
|
||||||
|
|
||||||
/* and remove if duplicate */
|
|
||||||
for (auto j = _animated_tiles.begin(); !remove && j < tile; j++) {
|
|
||||||
remove = *tile == *j;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (remove) {
|
if (remove) {
|
||||||
tile = _animated_tiles.erase(tile);
|
tile = _animated_tiles.erase(tile);
|
||||||
@@ -3806,6 +3800,10 @@ bool AfterLoadGame()
|
|||||||
RecalculateRoadCachedOneWayStates();
|
RecalculateRoadCachedOneWayStates();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (SlXvIsFeatureMissing(XSLFI_ANIMATED_TILE_EXTRA)) {
|
||||||
|
UpdateAllAnimatedTileSpeeds();
|
||||||
|
}
|
||||||
|
|
||||||
InitializeRoadGUI();
|
InitializeRoadGUI();
|
||||||
|
|
||||||
/* This needs to be done after conversion. */
|
/* This needs to be done after conversion. */
|
||||||
@@ -3928,4 +3926,5 @@ void ReloadNewGRFData()
|
|||||||
CheckTrainsLengths();
|
CheckTrainsLengths();
|
||||||
AfterLoadTemplateVehiclesUpdateImage();
|
AfterLoadTemplateVehiclesUpdateImage();
|
||||||
AfterLoadTemplateVehiclesUpdateProperties();
|
AfterLoadTemplateVehiclesUpdateProperties();
|
||||||
|
UpdateAllAnimatedTileSpeeds();
|
||||||
}
|
}
|
||||||
|
@@ -8,6 +8,7 @@
|
|||||||
/** @file animated_tile_sl.cpp Code handling saving and loading of animated tiles */
|
/** @file animated_tile_sl.cpp Code handling saving and loading of animated tiles */
|
||||||
|
|
||||||
#include "../stdafx.h"
|
#include "../stdafx.h"
|
||||||
|
#include "../animated_tile.h"
|
||||||
#include "../tile_type.h"
|
#include "../tile_type.h"
|
||||||
#include "../core/alloc_func.hpp"
|
#include "../core/alloc_func.hpp"
|
||||||
#include "../core/smallvec_type.hpp"
|
#include "../core/smallvec_type.hpp"
|
||||||
@@ -16,15 +17,21 @@
|
|||||||
|
|
||||||
#include "../safeguards.h"
|
#include "../safeguards.h"
|
||||||
|
|
||||||
extern std::vector<TileIndex> _animated_tiles;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Save the ANIT chunk.
|
* Save the ANIT chunk.
|
||||||
*/
|
*/
|
||||||
static void Save_ANIT()
|
static void Save_ANIT()
|
||||||
{
|
{
|
||||||
SlSetLength(_animated_tiles.size() * sizeof(_animated_tiles.front()));
|
uint count = 0;
|
||||||
SlArray(_animated_tiles.data(), _animated_tiles.size(), SLE_UINT32);
|
for (const auto &it : _animated_tiles) {
|
||||||
|
if (!it.second.pending_deletion) count++;
|
||||||
|
}
|
||||||
|
SlSetLength(count * 5);
|
||||||
|
for (const auto &it : _animated_tiles) {
|
||||||
|
if (it.second.pending_deletion) continue;
|
||||||
|
SlWriteUint32(it.first);
|
||||||
|
SlWriteByte(it.second.speed);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -40,15 +47,26 @@ static void Load_ANIT()
|
|||||||
|
|
||||||
for (int i = 0; i < 256; i++) {
|
for (int i = 0; i < 256; i++) {
|
||||||
if (anim_list[i] == 0) break;
|
if (anim_list[i] == 0) break;
|
||||||
_animated_tiles.push_back(anim_list[i]);
|
_animated_tiles[anim_list[i]] = {};
|
||||||
}
|
}
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint count = (uint)SlGetFieldLength() / sizeof(_animated_tiles.front());
|
|
||||||
_animated_tiles.clear();
|
_animated_tiles.clear();
|
||||||
_animated_tiles.resize(_animated_tiles.size() + count);
|
if (SlXvIsFeaturePresent(XSLFI_ANIMATED_TILE_EXTRA)) {
|
||||||
SlArray(_animated_tiles.data(), count, SLE_UINT32);
|
uint count = (uint)SlGetFieldLength() / 5;
|
||||||
|
for (uint i = 0; i < count; i++) {
|
||||||
|
TileIndex tile = SlReadUint32();
|
||||||
|
AnimatedTileInfo info = {};
|
||||||
|
info.speed = SlReadByte();
|
||||||
|
_animated_tiles[tile] = info;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
uint count = (uint)SlGetFieldLength() / 4;
|
||||||
|
for (uint i = 0; i < count; i++) {
|
||||||
|
_animated_tiles[SlReadUint32()] = {};
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@@ -139,6 +139,7 @@ const SlxiSubChunkInfo _sl_xv_sub_chunk_infos[] = {
|
|||||||
{ XSLFI_ONE_WAY_DT_ROAD_STOP, XSCF_NULL, 1, 1, "one_way_dt_road_stop", nullptr, nullptr, nullptr },
|
{ XSLFI_ONE_WAY_DT_ROAD_STOP, XSCF_NULL, 1, 1, "one_way_dt_road_stop", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_ONE_WAY_ROAD_STATE, XSCF_NULL, 1, 1, "one_way_road_state", nullptr, nullptr, nullptr },
|
{ XSLFI_ONE_WAY_ROAD_STATE, XSCF_NULL, 1, 1, "one_way_road_state", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_VENC_CHUNK, XSCF_IGNORABLE_ALL, 1, 1, "venc_chunk", nullptr, nullptr, "VENC" },
|
{ XSLFI_VENC_CHUNK, XSCF_IGNORABLE_ALL, 1, 1, "venc_chunk", nullptr, nullptr, "VENC" },
|
||||||
|
{ XSLFI_ANIMATED_TILE_EXTRA, XSCF_NULL, 1, 1, "animated_tile_extra", nullptr, nullptr, nullptr },
|
||||||
{ XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker
|
{ XSLFI_NULL, XSCF_NULL, 0, 0, nullptr, nullptr, nullptr, nullptr },// This is the end marker
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@@ -93,6 +93,7 @@ enum SlXvFeatureIndex {
|
|||||||
XSLFI_ONE_WAY_DT_ROAD_STOP, ///< One-way drive-through road stops
|
XSLFI_ONE_WAY_DT_ROAD_STOP, ///< One-way drive-through road stops
|
||||||
XSLFI_ONE_WAY_ROAD_STATE, ///< One-way road state cache
|
XSLFI_ONE_WAY_ROAD_STATE, ///< One-way road state cache
|
||||||
XSLFI_VENC_CHUNK, ///< VENC chunk
|
XSLFI_VENC_CHUNK, ///< VENC chunk
|
||||||
|
XSLFI_ANIMATED_TILE_EXTRA, ///< Animated tile extra info
|
||||||
|
|
||||||
XSLFI_RIFF_HEADER_60_BIT, ///< Size field in RIFF chunk header is 60 bit
|
XSLFI_RIFF_HEADER_60_BIT, ///< Size field in RIFF chunk header is 60 bit
|
||||||
XSLFI_HEIGHT_8_BIT, ///< Map tile height is 8 bit instead of 4 bit, but savegame version may be before this became true in trunk
|
XSLFI_HEIGHT_8_BIT, ///< Map tile height is 8 bit instead of 4 bit, but savegame version may be before this became true in trunk
|
||||||
|
@@ -26,6 +26,7 @@
|
|||||||
#include "../engine_func.h"
|
#include "../engine_func.h"
|
||||||
#include "../company_base.h"
|
#include "../company_base.h"
|
||||||
#include "../disaster_vehicle.h"
|
#include "../disaster_vehicle.h"
|
||||||
|
#include "../animated_tile.h"
|
||||||
#include "../core/smallvec_type.hpp"
|
#include "../core/smallvec_type.hpp"
|
||||||
#include "saveload_internal.h"
|
#include "saveload_internal.h"
|
||||||
#include "oldloader.h"
|
#include "oldloader.h"
|
||||||
@@ -483,7 +484,6 @@ static inline uint RemapOrderIndex(uint x)
|
|||||||
return _savegame_type == SGT_TTO ? (x - 0x1AC4) / 2 : (x - 0x1C18) / 2;
|
return _savegame_type == SGT_TTO ? (x - 0x1AC4) / 2 : (x - 0x1C18) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
extern std::vector<TileIndex> _animated_tiles;
|
|
||||||
extern char *_old_name_array;
|
extern char *_old_name_array;
|
||||||
|
|
||||||
static uint32 _old_town_index;
|
static uint32 _old_town_index;
|
||||||
@@ -643,7 +643,7 @@ static bool LoadOldAnimTileList(LoadgameState *ls, int num)
|
|||||||
/* The first zero in the loaded array indicates the end of the list. */
|
/* The first zero in the loaded array indicates the end of the list. */
|
||||||
for (int i = 0; i < 256; i++) {
|
for (int i = 0; i < 256; i++) {
|
||||||
if (anim_list[i] == 0) break;
|
if (anim_list[i] == 0) break;
|
||||||
_animated_tiles.push_back(anim_list[i]);
|
_animated_tiles[anim_list[i]] = {};
|
||||||
}
|
}
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@@ -3553,6 +3553,18 @@ void AnimateTile_Station(TileIndex tile)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8 GetAnimatedTileSpeed_Station(TileIndex tile)
|
||||||
|
{
|
||||||
|
if (HasStationRail(tile)) {
|
||||||
|
return GetStationTileAnimationSpeed(tile);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (IsAirport(tile)) {
|
||||||
|
AnimateAirportTile(tile);
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static bool ClickTile_Station(TileIndex tile)
|
static bool ClickTile_Station(TileIndex tile)
|
||||||
{
|
{
|
||||||
|
@@ -432,6 +432,14 @@ static Foundation GetFoundation_Town(TileIndex tile, Slope tileh)
|
|||||||
return FlatteningFoundation(tileh);
|
return FlatteningFoundation(tileh);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
uint8 GetAnimatedTileSpeed_Town(TileIndex tile)
|
||||||
|
{
|
||||||
|
if (GetHouseType(tile) >= NEW_HOUSE_OFFSET) {
|
||||||
|
return GetNewHouseTileAnimationSpeed(tile);
|
||||||
|
}
|
||||||
|
return 2;
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Animate a tile for a town
|
* Animate a tile for a town
|
||||||
* Only certain houses can be animated
|
* Only certain houses can be animated
|
||||||
|
Reference in New Issue
Block a user