diff --git a/src/newgrf.cpp b/src/newgrf.cpp index 3579ffc3ea..6c0b71dc03 100644 --- a/src/newgrf.cpp +++ b/src/newgrf.cpp @@ -1999,7 +1999,7 @@ static ChangeInfoResult StationChangeInfo(uint first, uint last, int prop, ByteR if (buf.HasData(4) && buf.PeekDWord() == 0) { buf.Skip(4); - extern const DrawTileSprites _station_display_datas_rail[8]; + extern const DrawTileSpriteSpan _station_display_datas_rail[8]; dts->Clone(&_station_display_datas_rail[t % 8]); continue; } @@ -2008,8 +2008,7 @@ static ChangeInfoResult StationChangeInfo(uint first, uint last, int prop, ByteR /* On error, bail out immediately. Temporary GRF data was already freed */ if (_cur.skip_sprites < 0) return CIR_DISABLED; - static std::vector tmp_layout; - tmp_layout.clear(); + std::vector tmp_layout; for (;;) { /* no relative bounding box support */ DrawTileSeqStruct &dtss = tmp_layout.emplace_back(); @@ -2027,7 +2026,7 @@ static ChangeInfoResult StationChangeInfo(uint first, uint last, int prop, ByteR /* On error, bail out immediately. Temporary GRF data was already freed */ if (_cur.skip_sprites < 0) return CIR_DISABLED; } - dts->Clone(tmp_layout.data()); + dts->seq = std::move(tmp_layout); } /* Number of layouts must be even, alternating X and Y */ diff --git a/src/newgrf_commons.cpp b/src/newgrf_commons.cpp index 23d6b803d0..c335183d8e 100644 --- a/src/newgrf_commons.cpp +++ b/src/newgrf_commons.cpp @@ -561,24 +561,6 @@ bool Convert8bitBooleanCallback(const GRFFile *grffile, uint16_t cbid, uint16_t /* static */ std::vector NewGRFSpriteLayout::result_seq; -/** - * Clone the building sprites of a spritelayout. - * @param source The building sprites to copy. - */ -void NewGRFSpriteLayout::Clone(const DrawTileSeqStruct *source) -{ - assert(this->seq == nullptr); - assert(source != nullptr); - - size_t count = 1; // 1 for the terminator - const DrawTileSeqStruct *element; - foreach_draw_tile_seq(element, source) count++; - - DrawTileSeqStruct *sprites = MallocT(count); - MemCpyT(sprites, source, count); - this->seq = sprites; -} - /** * Clone a spritelayout. * @param source The spritelayout to copy. @@ -605,11 +587,10 @@ void NewGRFSpriteLayout::Clone(const NewGRFSpriteLayout *source) */ void NewGRFSpriteLayout::Allocate(uint num_sprites) { - assert(this->seq == nullptr); + assert(this->seq.empty()); - DrawTileSeqStruct *sprites = CallocT(num_sprites + 1); - sprites[num_sprites].MakeTerminator(); - this->seq = sprites; + this->seq.resize(num_sprites + 1, {}); + this->seq[num_sprites].MakeTerminator(); } /** @@ -617,7 +598,7 @@ void NewGRFSpriteLayout::Allocate(uint num_sprites) */ void NewGRFSpriteLayout::AllocateRegisters() { - assert(this->seq != nullptr); + assert(!this->seq.empty()); assert(this->registers == nullptr); size_t count = 1; // 1 for the ground sprite @@ -661,7 +642,7 @@ uint32_t NewGRFSpriteLayout::PrepareLayout(uint32_t orig_offset, uint32_t newgrf * and apply the default sprite offsets (unless disabled). */ const TileLayoutRegisters *regs = this->registers; bool ground = true; - foreach_draw_tile_seq(result, result_seq.data()) { + foreach_draw_tile_seq(result, result_seq) { TileLayoutFlags flags = TLF_NOTHING; if (regs != nullptr) flags = regs->flags; @@ -715,7 +696,7 @@ void NewGRFSpriteLayout::ProcessRegisters(uint8_t resolved_var10, uint32_t resol DrawTileSeqStruct *result; const TileLayoutRegisters *regs = this->registers; bool ground = true; - foreach_draw_tile_seq(result, result_seq.data()) { + foreach_draw_tile_seq(result, result_seq) { TileLayoutFlags flags = TLF_NOTHING; if (regs != nullptr) flags = regs->flags; diff --git a/src/newgrf_commons.h b/src/newgrf_commons.h index 72708dd470..ad06336ec8 100644 --- a/src/newgrf_commons.h +++ b/src/newgrf_commons.h @@ -110,6 +110,7 @@ static const uint TLR_MAX_VAR10 = 7; ///< Maximum value for var 10. * layouts on the heap. It allocates data and frees them on destruction. */ struct NewGRFSpriteLayout : ZeroedMemoryAllocator, DrawTileSprites { + std::vector seq; const TileLayoutRegisters *registers; /** @@ -120,7 +121,6 @@ struct NewGRFSpriteLayout : ZeroedMemoryAllocator, DrawTileSprites { void Allocate(uint num_sprites); void AllocateRegisters(); - void Clone(const DrawTileSeqStruct *source); void Clone(const NewGRFSpriteLayout *source); /** @@ -130,13 +130,15 @@ struct NewGRFSpriteLayout : ZeroedMemoryAllocator, DrawTileSprites { void Clone(const DrawTileSprites *source) { assert(source != nullptr && this != source); + + auto source_sequence = source->GetSequence(); + assert(this->seq.empty() && !source_sequence.empty()); this->ground = source->ground; - this->Clone(source->seq); + this->seq.insert(this->seq.end(), source_sequence.begin(), source_sequence.end()); } virtual ~NewGRFSpriteLayout() { - free(this->seq); free(this->registers); } @@ -159,13 +161,15 @@ struct NewGRFSpriteLayout : ZeroedMemoryAllocator, DrawTileSprites { * @pre #PrepareLayout() and #ProcessRegisters() need calling first. * @return result spritelayout */ - const DrawTileSeqStruct *GetLayout(PalSpriteID *ground) const + std::span GetLayout(PalSpriteID *ground) const { - DrawTileSeqStruct *front = result_seq.data(); - *ground = front->image; - return front + 1; + *ground = result_seq[0].image; + return {++result_seq.begin(), result_seq.end()}; } + std::span GetSequence() const override { return {this->seq.begin(), this->seq.end()}; } + + private: static std::vector result_seq; ///< Temporary storage when preprocessing spritelayouts. }; diff --git a/src/newgrf_spritegroup.cpp b/src/newgrf_spritegroup.cpp index 1b8596659e..a8a081c0c2 100644 --- a/src/newgrf_spritegroup.cpp +++ b/src/newgrf_spritegroup.cpp @@ -293,7 +293,7 @@ const DrawTileSprites *TileLayoutSpriteGroup::ProcessRegisters(uint8_t *stage) c return &this->dts; } - static DrawTileSprites result; + static DrawTileSpriteSpan result; uint8_t actual_stage = stage != nullptr ? *stage : 0; this->dts.PrepareLayout(0, 0, 0, actual_stage, false); this->dts.ProcessRegisters(0, 0, false); diff --git a/src/newgrf_station.cpp b/src/newgrf_station.cpp index 1849ab711f..b4575f7e33 100644 --- a/src/newgrf_station.cpp +++ b/src/newgrf_station.cpp @@ -794,7 +794,7 @@ bool DrawStationTile(int x, int y, RailType railtype, Axis axis, StationClassID uint32_t relocation = 0; uint32_t ground_relocation = 0; const NewGRFSpriteLayout *layout = nullptr; - DrawTileSprites tmp_rail_layout; + DrawTileSpriteSpan tmp_rail_layout; if (statspec->renderdata.empty()) { sprites = GetStationTileLayout(StationType::Rail, tile + axis); diff --git a/src/object_cmd.cpp b/src/object_cmd.cpp index 763359b72d..a151b407be 100644 --- a/src/object_cmd.cpp +++ b/src/object_cmd.cpp @@ -473,7 +473,7 @@ static void DrawTile_Object(TileInfo *ti) if (!IsInvisibilitySet(TO_STRUCTURES)) { const DrawTileSeqStruct *dtss; - foreach_draw_tile_seq(dtss, dts->seq) { + foreach_draw_tile_seq(dtss, dts->GetSequence()) { AddSortableSpriteToDraw( dtss->image.sprite, palette, ti->x + dtss->delta_x, ti->y + dtss->delta_y, diff --git a/src/object_gui.cpp b/src/object_gui.cpp index 137f2e0156..3e21135dae 100644 --- a/src/object_gui.cpp +++ b/src/object_gui.cpp @@ -87,7 +87,7 @@ public: { const auto *spec = this->GetSpec(cls_id, id); if (!spec->grf_prop.HasGrfFile()) { - extern const DrawTileSprites _objects[]; + extern const DrawTileSpriteSpan _objects[]; const DrawTileSprites *dts = &_objects[spec->grf_prop.local_id]; DrawOrigTileSeqInGUI(x, y, dts, PAL_NONE); } else { @@ -207,7 +207,7 @@ public: int y = (ir.Height() + ScaleSpriteTrad(PREVIEW_HEIGHT)) / 2 - ScaleSpriteTrad(PREVIEW_BOTTOM); if (!spec->grf_prop.HasGrfFile()) { - extern const DrawTileSprites _objects[]; + extern const DrawTileSpriteSpan _objects[]; const DrawTileSprites *dts = &_objects[spec->grf_prop.local_id]; DrawOrigTileSeqInGUI(x, y, dts, PAL_NONE); } else { diff --git a/src/sprite.cpp b/src/sprite.cpp index eee9d03ae9..f9a3f8792d 100644 --- a/src/sprite.cpp +++ b/src/sprite.cpp @@ -32,7 +32,7 @@ void DrawCommonTileSeq(const TileInfo *ti, const DrawTileSprites *dts, Transpare bool parent_sprite_encountered = false; const DrawTileSeqStruct *dtss; bool skip_childs = false; - foreach_draw_tile_seq(dtss, dts->seq) { + foreach_draw_tile_seq(dtss, dts->GetSequence()) { SpriteID image = dtss->image.sprite; PaletteID pal = dtss->image.pal; @@ -95,7 +95,7 @@ void DrawCommonTileSeqInGUI(int x, int y, const DrawTileSprites *dts, int32_t or Point child_offset = {0, 0}; bool skip_childs = false; - foreach_draw_tile_seq(dtss, dts->seq) { + foreach_draw_tile_seq(dtss, dts->GetSequence()) { SpriteID image = dtss->image.sprite; PaletteID pal = dtss->image.pal; diff --git a/src/sprite.h b/src/sprite.h index f193302993..b6f915cd69 100644 --- a/src/sprite.h +++ b/src/sprite.h @@ -52,12 +52,33 @@ struct DrawTileSeqStruct { /** * Ground palette sprite of a tile, together with its sprite layout. - * This struct is used for static sprite layouts in the code. + * For static sprite layouts see #DrawTileSpriteSpan. * For allocated ones from NewGRF see #NewGRFSpriteLayout. */ struct DrawTileSprites { - PalSpriteID ground; ///< Palette and sprite for the ground - const DrawTileSeqStruct *seq; ///< Array of child sprites. Terminated with a terminator entry + PalSpriteID ground; ///< Palette and sprite for the ground + + DrawTileSprites(PalSpriteID ground) : ground(ground) {} + DrawTileSprites() = default; + + virtual ~DrawTileSprites() = default; + virtual std::span GetSequence() const = 0; +}; + +/** + * Ground palette sprite of a tile, together with its sprite layout. + * This struct is used for static sprite layouts in the code. + * For allocated ones from NewGRF see #NewGRFSpriteLayout. + */ +struct DrawTileSpriteSpan : DrawTileSprites { + std::span seq; ///< Child sprites, + + template + DrawTileSpriteSpan(PalSpriteID ground, const DrawTileSeqStruct (&seq)[N]) : DrawTileSprites(ground), seq(std::begin(seq), std::end(seq)) {} + DrawTileSpriteSpan(PalSpriteID ground) : DrawTileSprites(ground) {}; + DrawTileSpriteSpan() = default; + + std::span GetSequence() const override { return this->seq; } }; /** @@ -76,7 +97,7 @@ struct DrawBuildingsTileStruct { }; /** Iterate through all DrawTileSeqStructs in DrawTileSprites. */ -#define foreach_draw_tile_seq(idx, list) for (idx = list; !idx->IsTerminator(); idx++) +#define foreach_draw_tile_seq(idx, list) for (idx = list.data(); !idx->IsTerminator(); idx++) void DrawCommonTileSeq(const struct TileInfo *ti, const DrawTileSprites *dts, TransparencyOption to, int32_t orig_offset, uint32_t newgrf_offset, PaletteID default_palette, bool child_offset_is_unsigned); void DrawCommonTileSeqInGUI(int x, int y, const DrawTileSprites *dts, int32_t orig_offset, uint32_t newgrf_offset, PaletteID default_palette, bool child_offset_is_unsigned); diff --git a/src/station_cmd.cpp b/src/station_cmd.cpp index ccbd99cc88..4881c7c9fa 100644 --- a/src/station_cmd.cpp +++ b/src/station_cmd.cpp @@ -3084,7 +3084,7 @@ bool SplitGroundSpriteForOverlay(const TileInfo *ti, SpriteID *ground, RailTrack static void DrawTile_Station(TileInfo *ti) { const NewGRFSpriteLayout *layout = nullptr; - DrawTileSprites tmp_rail_layout; + DrawTileSpriteSpan tmp_rail_layout; const DrawTileSprites *t = nullptr; int32_t total_offset; const RailTypeInfo *rti = nullptr; @@ -3167,7 +3167,7 @@ static void DrawTile_Station(TileInfo *ti) palette = PALETTE_TO_GREY; } - if (layout == nullptr && (t == nullptr || t->seq == nullptr)) t = GetStationTileLayout(GetStationType(ti->tile), gfx); + if (layout == nullptr && (t == nullptr || t->GetSequence().empty())) t = GetStationTileLayout(GetStationType(ti->tile), gfx); /* don't show foundation for docks */ if (ti->tileh != SLOPE_FLAT && !IsDock(ti->tile)) { diff --git a/src/table/object_land.h b/src/table/object_land.h index f097de619c..46ce9c23e4 100644 --- a/src/table/object_land.h +++ b/src/table/object_land.h @@ -34,7 +34,7 @@ static const DrawTileSeqStruct _object_owned_land_seq[] = { TILE_SEQ_END() }; -extern const DrawTileSprites _objects[] = { +extern const DrawTileSpriteSpan _objects[] = { { { SPR_FLAT_2_THIRD_GRASS_TILE, PAL_NONE }, _object_transmitter_seq }, { { SPR_FLAT_2_THIRD_GRASS_TILE, PAL_NONE }, _object_lighthouse_seq }, { { SPR_CONCRETE_GROUND, PAL_NONE }, _object_statue_seq }, @@ -92,7 +92,7 @@ static const DrawTileSeqStruct _object_hq_huge_west[] = { #define TILE_SPRITE_LINE(img, dtss) { {img | (1 << PALETTE_MODIFIER_COLOUR), PAL_NONE}, dtss }, -static const DrawTileSprites _object_hq[] = { +static const DrawTileSpriteSpan _object_hq[] = { TILE_SPRITE_LINE(SPR_TINYHQ_NORTH, _object_nothing) TILE_SPRITE_LINE(SPR_TINYHQ_WEST, _object_nothing) TILE_SPRITE_LINE(SPR_TINYHQ_EAST, _object_nothing) diff --git a/src/table/road_land.h b/src/table/road_land.h index 3b9b557767..c3161dceb1 100644 --- a/src/table/road_land.h +++ b/src/table/road_land.h @@ -32,7 +32,7 @@ static const DrawTileSeqStruct _road_depot_NW[] = { TILE_SEQ_END() }; -static const DrawTileSprites _road_depot[] = { +static const DrawTileSpriteSpan _road_depot[] = { { {0xA4A, PAL_NONE}, _road_depot_NE }, { {0xA4A, PAL_NONE}, _road_depot_SE }, { {0xA4A, PAL_NONE}, _road_depot_SW }, @@ -49,7 +49,7 @@ static const DrawTileSeqStruct _crossing_layout_ALL[] = { TILE_SEQ_END() }; -static const DrawTileSprites _crossing_layout = { +static const DrawTileSpriteSpan _crossing_layout = { {0, PAL_NONE}, _crossing_layout_ALL }; @@ -59,7 +59,7 @@ static const DrawTileSeqStruct _crossing_layout_SW_ALL[] = { TILE_SEQ_END() }; -static const DrawTileSprites _crossing_layout_SW = { +static const DrawTileSpriteSpan _crossing_layout_SW = { {0, PAL_NONE}, _crossing_layout_SW_ALL }; @@ -69,7 +69,7 @@ static const DrawTileSeqStruct _crossing_layout_NW_ALL[] = { TILE_SEQ_END() }; -static const DrawTileSprites _crossing_layout_NW = { +static const DrawTileSpriteSpan _crossing_layout_NW = { {0, PAL_NONE}, _crossing_layout_NW_ALL }; @@ -79,7 +79,7 @@ static const DrawTileSeqStruct _crossing_layout_NE_ALL[] = { TILE_SEQ_END() }; -static const DrawTileSprites _crossing_layout_NE = { +static const DrawTileSpriteSpan _crossing_layout_NE = { {0, PAL_NONE}, _crossing_layout_NE_ALL }; @@ -89,7 +89,7 @@ static const DrawTileSeqStruct _crossing_layout_SE_ALL[] = { TILE_SEQ_END() }; -static const DrawTileSprites _crossing_layout_SE = { +static const DrawTileSpriteSpan _crossing_layout_SE = { {0, PAL_NONE}, _crossing_layout_SE_ALL }; diff --git a/src/table/station_land.h b/src/table/station_land.h index 01f906aedc..3999c83225 100644 --- a/src/table/station_land.h +++ b/src/table/station_land.h @@ -796,14 +796,14 @@ static const DrawTileSeqStruct _station_display_datas_waypoint_Y[] = { #undef TILE_SEQ_GROUND /** - * Constructor macro of a DrawTileSprites structure + * Constructor macro of a DrawTileSpriteSpan structure * @param img Ground sprite without palette of the tile * @param dtss Sequence child sprites of the tile */ #define TILE_SPRITE_LINE(img, dtss) { {img, PAL_NONE}, dtss }, -#define TILE_SPRITE_NULL() { {0, 0}, nullptr }, +#define TILE_SPRITE_NULL() { {0, 0} }, -extern const DrawTileSprites _station_display_datas_rail[] = { +extern const DrawTileSpriteSpan _station_display_datas_rail[] = { TILE_SPRITE_LINE(SPR_RAIL_TRACK_X, _station_display_datas_0) TILE_SPRITE_LINE(SPR_RAIL_TRACK_Y, _station_display_datas_1) TILE_SPRITE_LINE(SPR_RAIL_TRACK_X, _station_display_datas_2) @@ -814,7 +814,7 @@ extern const DrawTileSprites _station_display_datas_rail[] = { TILE_SPRITE_LINE(SPR_RAIL_TRACK_Y, _station_display_datas_7) }; -static const DrawTileSprites _station_display_datas_airport[] = { +static const DrawTileSpriteSpan _station_display_datas_airport[] = { TILE_SPRITE_LINE(SPR_AIRPORT_APRON, _station_display_nothing) // APT_APRON TILE_SPRITE_LINE(SPR_AIRPORT_APRON, _station_display_fence_nw) // APT_APRON_FENCE_NW TILE_SPRITE_LINE(SPR_AIRPORT_APRON, _station_display_fence_sw) // APT_APRON_FENCE_SW @@ -891,7 +891,7 @@ static const DrawTileSprites _station_display_datas_airport[] = { TILE_SPRITE_NULL() // APT_GRASS_FENCE_NE_FLAG_2 }; -static const DrawTileSprites _station_display_datas_airport_radar_grass_fence_sw[] = { +static const DrawTileSpriteSpan _station_display_datas_airport_radar_grass_fence_sw[] = { TILE_SPRITE_LINE(SPR_FLAT_GRASS_TILE, _station_display_radar_1_fence_sw) // APT_RADAR_GRASS_FENCE_SW TILE_SPRITE_LINE(SPR_FLAT_GRASS_TILE, _station_display_radar_2_fence_sw) TILE_SPRITE_LINE(SPR_FLAT_GRASS_TILE, _station_display_radar_3_fence_sw) @@ -906,14 +906,14 @@ static const DrawTileSprites _station_display_datas_airport_radar_grass_fence_sw TILE_SPRITE_LINE(SPR_FLAT_GRASS_TILE, _station_display_radar_12_fence_sw) }; -static const DrawTileSprites _station_display_datas_airport_flag_grass_fence_ne[] = { +static const DrawTileSpriteSpan _station_display_datas_airport_flag_grass_fence_ne[] = { TILE_SPRITE_LINE(SPR_AIRFIELD_APRON_D, _station_display_flag_1_fence_ne) // APT_GRASS_FENCE_NE_FLAG TILE_SPRITE_LINE(SPR_AIRFIELD_APRON_D, _station_display_flag_2_fence_ne) TILE_SPRITE_LINE(SPR_AIRFIELD_APRON_D, _station_display_flag_3_fence_ne) TILE_SPRITE_LINE(SPR_AIRFIELD_APRON_D, _station_display_flag_4_fence_ne) }; -static const DrawTileSprites _station_display_datas_airport_radar_fence_sw[] = { +static const DrawTileSpriteSpan _station_display_datas_airport_radar_fence_sw[] = { TILE_SPRITE_LINE(SPR_AIRPORT_APRON, _station_display_radar_1_fence_sw) // APT_RADAR_FENCE_SW TILE_SPRITE_LINE(SPR_AIRPORT_APRON, _station_display_radar_2_fence_sw) TILE_SPRITE_LINE(SPR_AIRPORT_APRON, _station_display_radar_3_fence_sw) @@ -928,7 +928,7 @@ static const DrawTileSprites _station_display_datas_airport_radar_fence_sw[] = { TILE_SPRITE_LINE(SPR_AIRPORT_APRON, _station_display_radar_12_fence_sw) }; -static const DrawTileSprites _station_display_datas_airport_radar_fence_ne[] = { +static const DrawTileSpriteSpan _station_display_datas_airport_radar_fence_ne[] = { TILE_SPRITE_LINE(SPR_AIRPORT_APRON, _station_display_radar_1_fence_ne) // APT_RADAR_FENCE_NE TILE_SPRITE_LINE(SPR_AIRPORT_APRON, _station_display_radar_2_fence_ne) TILE_SPRITE_LINE(SPR_AIRPORT_APRON, _station_display_radar_3_fence_ne) @@ -943,7 +943,7 @@ static const DrawTileSprites _station_display_datas_airport_radar_fence_ne[] = { TILE_SPRITE_LINE(SPR_AIRPORT_APRON, _station_display_radar_12_fence_ne) }; -static const DrawTileSprites _station_display_datas_airport_flag_grass_fence_ne_2[] = { +static const DrawTileSpriteSpan _station_display_datas_airport_flag_grass_fence_ne_2[] = { TILE_SPRITE_LINE(SPR_FLAT_GRASS_TILE, _station_display_flag_1_fence_ne) // APT_GRASS_FENCE_NE_FLAG_2 TILE_SPRITE_LINE(SPR_FLAT_GRASS_TILE, _station_display_flag_2_fence_ne) TILE_SPRITE_LINE(SPR_FLAT_GRASS_TILE, _station_display_flag_3_fence_ne) @@ -951,7 +951,7 @@ static const DrawTileSprites _station_display_datas_airport_flag_grass_fence_ne_ }; -static const DrawTileSprites _station_display_datas_truck[] = { +static const DrawTileSpriteSpan _station_display_datas_truck[] = { TILE_SPRITE_LINE(SPR_TRUCK_STOP_NE_GROUND | (1U << PALETTE_MODIFIER_COLOUR), _station_display_datas_67) TILE_SPRITE_LINE(SPR_TRUCK_STOP_SE_GROUND | (1U << PALETTE_MODIFIER_COLOUR), _station_display_datas_68) TILE_SPRITE_LINE(SPR_TRUCK_STOP_SW_GROUND | (1U << PALETTE_MODIFIER_COLOUR), _station_display_datas_69) @@ -960,7 +960,7 @@ static const DrawTileSprites _station_display_datas_truck[] = { TILE_SPRITE_LINE(SPR_ROAD_PAVED_STRAIGHT_Y, _station_display_datas_0169) }; -static const DrawTileSprites _station_display_datas_bus[] = { +static const DrawTileSpriteSpan _station_display_datas_bus[] = { TILE_SPRITE_LINE(SPR_BUS_STOP_NE_GROUND | (1U << PALETTE_MODIFIER_COLOUR), _station_display_datas_71) TILE_SPRITE_LINE(SPR_BUS_STOP_SE_GROUND | (1U << PALETTE_MODIFIER_COLOUR), _station_display_datas_72) TILE_SPRITE_LINE(SPR_BUS_STOP_SW_GROUND | (1U << PALETTE_MODIFIER_COLOUR), _station_display_datas_73) @@ -969,20 +969,20 @@ static const DrawTileSprites _station_display_datas_bus[] = { TILE_SPRITE_LINE(SPR_ROAD_PAVED_STRAIGHT_Y, _station_display_datas_0171) }; -static const DrawTileSprites _station_display_datas_road_waypoint[] = { - TILE_SPRITE_LINE(0, nullptr) - TILE_SPRITE_LINE(0, nullptr) - TILE_SPRITE_LINE(0, nullptr) - TILE_SPRITE_LINE(0, nullptr) +static const DrawTileSpriteSpan _station_display_datas_road_waypoint[] = { + TILE_SPRITE_NULL() + TILE_SPRITE_NULL() + TILE_SPRITE_NULL() + TILE_SPRITE_NULL() TILE_SPRITE_LINE(SPR_ROAD_PAVED_STRAIGHT_X, _station_display_datas_road_waypoint_X) TILE_SPRITE_LINE(SPR_ROAD_PAVED_STRAIGHT_Y, _station_display_datas_road_waypoint_Y) }; -static const DrawTileSprites _station_display_datas_oilrig[] = { +static const DrawTileSpriteSpan _station_display_datas_oilrig[] = { TILE_SPRITE_LINE(SPR_FLAT_WATER_TILE, _station_display_nothing) }; -static const DrawTileSprites _station_display_datas_dock[] = { +static const DrawTileSpriteSpan _station_display_datas_dock[] = { TILE_SPRITE_LINE(SPR_SHORE_BASE + SLOPE_SW, _station_display_datas_76) TILE_SPRITE_LINE(SPR_SHORE_BASE + SLOPE_NW, _station_display_datas_77) TILE_SPRITE_LINE(SPR_SHORE_BASE + SLOPE_NE, _station_display_datas_78) @@ -991,11 +991,11 @@ static const DrawTileSprites _station_display_datas_dock[] = { TILE_SPRITE_LINE(SPR_FLAT_WATER_TILE, _station_display_datas_81) }; -static const DrawTileSprites _station_display_datas_buoy[] = { +static const DrawTileSpriteSpan _station_display_datas_buoy[] = { TILE_SPRITE_LINE(SPR_FLAT_WATER_TILE, _station_display_datas_82) }; -static const DrawTileSprites _station_display_datas_waypoint[] = { +static const DrawTileSpriteSpan _station_display_datas_waypoint[] = { TILE_SPRITE_LINE(SPR_RAIL_TRACK_X, _station_display_datas_waypoint_X) TILE_SPRITE_LINE(SPR_RAIL_TRACK_Y, _station_display_datas_waypoint_Y) TILE_SPRITE_LINE(SPR_RAIL_TRACK_X, _station_display_datas_waypoint_X) @@ -1013,7 +1013,7 @@ static const DrawTileSprites _station_display_datas_waypoint[] = { * As these are drawn/build like stations, they may use the same number of layouts. */ static_assert(lengthof(_station_display_datas_rail) == lengthof(_station_display_datas_waypoint)); -static const std::array, to_underlying(StationType::End)> _station_display_datas = {{ +static const std::array, to_underlying(StationType::End)> _station_display_datas = {{ _station_display_datas_rail, _station_display_datas_airport, _station_display_datas_truck, diff --git a/src/table/track_land.h b/src/table/track_land.h index 70ea770bfe..246babf5a3 100644 --- a/src/table/track_land.h +++ b/src/table/track_land.h @@ -33,14 +33,14 @@ static const DrawTileSeqStruct _depot_gfx_NW[] = { TILE_SEQ_END() }; -static const DrawTileSprites _depot_gfx_table[] = { +static const DrawTileSpriteSpan _depot_gfx_table[] = { { {SPR_FLAT_GRASS_TILE, PAL_NONE}, _depot_gfx_NE }, { {SPR_RAIL_TRACK_Y, PAL_NONE}, _depot_gfx_SE }, { {SPR_RAIL_TRACK_X, PAL_NONE}, _depot_gfx_SW }, { {SPR_FLAT_GRASS_TILE, PAL_NONE}, _depot_gfx_NW } }; -static const DrawTileSprites _depot_invisible_gfx_table[] = { +static const DrawTileSpriteSpan _depot_invisible_gfx_table[] = { { {SPR_RAIL_TRACK_X, PAL_NONE}, _depot_gfx_NE }, { {SPR_RAIL_TRACK_Y, PAL_NONE}, _depot_gfx_SE }, { {SPR_RAIL_TRACK_X, PAL_NONE}, _depot_gfx_SW }, diff --git a/src/table/water_land.h b/src/table/water_land.h index 4bb0395ee7..27e2aa7257 100644 --- a/src/table/water_land.h +++ b/src/table/water_land.h @@ -23,7 +23,7 @@ #define TILE_SEQ_END() { (int8_t)0x80, 0, 0, 0, 0, 0, {0, 0} } /** - * Constructor macro of a DrawTileSprites structure + * Constructor macro of a DrawTileSpriteSpan structure * @param img Ground sprite without palette of the tile * @param dtss Sequence child sprites of the tile */ @@ -51,7 +51,7 @@ static const DrawTileSeqStruct _shipdepot_display_seq_4[] = { TILE_SEQ_END() }; -static const DrawTileSprites _shipdepot_display_data[][DEPOT_PART_END] = { +static const DrawTileSpriteSpan _shipdepot_display_data[][DEPOT_PART_END] = { { // AXIS_X TILE_SPRITE_LINE(0xFDD, _shipdepot_display_seq_1) // DEPOT_PART_NORTH TILE_SPRITE_LINE(0xFDD, _shipdepot_display_seq_2) // DEPOT_PART_SOUTH @@ -134,7 +134,7 @@ static const DrawTileSeqStruct _lock_display_seq_3t[] = { TILE_SEQ_END() }; -static const DrawTileSprites _lock_display_data[][DIAGDIR_END] = { +static const DrawTileSpriteSpan _lock_display_data[][DIAGDIR_END] = { { // LOCK_PART_MIDDLE TILE_SPRITE_LINE(1, _lock_display_seq_0) // NE TILE_SPRITE_LINE(0, _lock_display_seq_1) // SE diff --git a/src/water_cmd.cpp b/src/water_cmd.cpp index 71c8b33d55..b2bf30a18a 100644 --- a/src/water_cmd.cpp +++ b/src/water_cmd.cpp @@ -797,17 +797,18 @@ static void DrawCanalWater(TileIndex tile) * Draw a build sprite sequence for water tiles. * If buildings are invisible, nothing will be drawn. * @param ti Tile info. - * @param dtss Sprite sequence to draw. + * @param seq Sprite sequence to draw. * @param base Base sprite. * @param offset Additional sprite offset. * @param palette Palette to use. */ -static void DrawWaterTileStruct(const TileInfo *ti, const DrawTileSeqStruct *dtss, SpriteID base, uint offset, PaletteID palette, CanalFeature feature) +static void DrawWaterTileStruct(const TileInfo *ti, std::span seq, SpriteID base, uint offset, PaletteID palette, CanalFeature feature) { /* Don't draw if buildings are invisible. */ if (IsInvisibilitySet(TO_BUILDINGS)) return; - for (; !dtss->IsTerminator(); dtss++) { + const DrawTileSeqStruct *dtss; + foreach_draw_tile_seq(dtss, seq) { uint tile_offs = offset + dtss->image.sprite; if (feature < CF_END) tile_offs = GetCanalSpriteOffset(feature, ti->tile, tile_offs); AddSortableSpriteToDraw(base + tile_offs, palette, @@ -854,7 +855,7 @@ static void DrawWaterLock(const TileInfo *ti) zoffs = ti->z > z_threshold ? 24 : 0; } - DrawWaterTileStruct(ti, dts.seq, base, zoffs, PAL_NONE, CF_LOCKS); + DrawWaterTileStruct(ti, dts.GetSequence(), base, zoffs, PAL_NONE, CF_LOCKS); } /** Draw a ship depot tile. */