Codechange: Extract function to draw custom rail station foundations. (#14492)
This commit is contained in:
@@ -3073,6 +3073,74 @@ bool SplitGroundSpriteForOverlay(const TileInfo *ti, SpriteID *ground, RailTrack
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Draw custom station foundations for a NewGRF station if provided.
|
||||||
|
* @param statspec Custom NewGRF station.
|
||||||
|
* @param st Station being drawn.
|
||||||
|
* @param ti Tile being drawn.
|
||||||
|
* @param gfx Graphics layout for tile.
|
||||||
|
* @return true iff a custom foundation was drawn.
|
||||||
|
*/
|
||||||
|
static bool DrawCustomStationFoundations(const StationSpec *statspec, BaseStation *st, TileInfo *ti, StationGfx gfx)
|
||||||
|
{
|
||||||
|
if (statspec == nullptr || !statspec->flags.Test(StationSpecFlag::CustomFoundations)) return false;
|
||||||
|
|
||||||
|
/* Station has custom foundations.
|
||||||
|
* Check whether the foundation continues beyond the tile's upper sides. */
|
||||||
|
uint edge_info = 0;
|
||||||
|
auto [slope, z] = GetFoundationPixelSlope(ti->tile);
|
||||||
|
if (!HasFoundationNW(ti->tile, slope, z)) SetBit(edge_info, 0);
|
||||||
|
if (!HasFoundationNE(ti->tile, slope, z)) SetBit(edge_info, 1);
|
||||||
|
|
||||||
|
SpriteID image = GetCustomStationFoundationRelocation(statspec, st, ti->tile, gfx, edge_info);
|
||||||
|
if (image == 0) return false;
|
||||||
|
|
||||||
|
if (statspec->flags.Test(StationSpecFlag::ExtendedFoundations)) {
|
||||||
|
/* Station provides extended foundations. */
|
||||||
|
static constexpr uint8_t foundation_parts[] = {
|
||||||
|
UINT8_MAX, UINT8_MAX, UINT8_MAX, 0, // Invalid, Invalid, Invalid, SLOPE_SW
|
||||||
|
UINT8_MAX, 1, 2, 3, // Invalid, SLOPE_EW, SLOPE_SE, SLOPE_WSE
|
||||||
|
UINT8_MAX, 4, 5, 6, // Invalid, SLOPE_NW, SLOPE_NS, SLOPE_NWS
|
||||||
|
7, 8, 9, // SLOPE_NE, SLOPE_ENW, SLOPE_SEN
|
||||||
|
};
|
||||||
|
assert(ti->tileh < std::size(foundation_parts));
|
||||||
|
if (foundation_parts[ti->tileh] == UINT8_MAX) return false;
|
||||||
|
|
||||||
|
AddSortableSpriteToDraw(image + foundation_parts[ti->tileh], PAL_NONE, *ti, {{}, {TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1}, {}});
|
||||||
|
} else {
|
||||||
|
/* Draw simple foundations, built up from 8 possible foundation sprites.
|
||||||
|
* Each set bit represents one of the eight composite sprites to be drawn.
|
||||||
|
* 'Invalid' entries will not drawn but are included for completeness. */
|
||||||
|
static constexpr uint8_t composite_foundation_parts[] = {
|
||||||
|
0b0000'0000, 0b1101'0001, 0b1110'0100, 0b1110'0000, // Invalid, Invalid, Invalid, SLOPE_SW
|
||||||
|
0b1100'1010, 0b1100'1001, 0b1100'0100, 0b1100'0000, // Invalid, SLOPE_EW, SLOPE_SE, SLOPE_WSE
|
||||||
|
0b1101'0010, 0b1001'0001, 0b1110'0100, 0b1010'0000, // Invalid, SLOPE_NW, SLOPE_NS, SLOPE_NWS
|
||||||
|
0b0100'1010, 0b0000'1001, 0b0100'0100, // SLOPE_NE, SLOPE_ENW, SLOPE_SEN
|
||||||
|
};
|
||||||
|
assert(ti->tileh < std::size(composite_foundation_parts));
|
||||||
|
|
||||||
|
uint8_t parts = composite_foundation_parts[ti->tileh];
|
||||||
|
|
||||||
|
/* If foundations continue beyond the tile's upper sides then mask out the last two pieces. */
|
||||||
|
if (HasBit(edge_info, 0)) ClrBit(parts, 6);
|
||||||
|
if (HasBit(edge_info, 1)) ClrBit(parts, 7);
|
||||||
|
|
||||||
|
/* We always have to draw at least one sprite, so if we have no parts to draw fall back to default foundation. */
|
||||||
|
if (parts == 0) return false;
|
||||||
|
|
||||||
|
StartSpriteCombine();
|
||||||
|
for (uint i : SetBitIterator(parts)) {
|
||||||
|
AddSortableSpriteToDraw(image + i, PAL_NONE, *ti, {{}, {TILE_SIZE, TILE_SIZE, TILE_HEIGHT - 1}, {}});
|
||||||
|
}
|
||||||
|
EndSpriteCombine();
|
||||||
|
}
|
||||||
|
|
||||||
|
OffsetGroundSprite(0, -static_cast<int>(TILE_HEIGHT));
|
||||||
|
ti->z += ApplyPixelFoundationToSlope(FOUNDATION_LEVELED, ti->tileh);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
static void DrawTile_Station(TileInfo *ti)
|
static void DrawTile_Station(TileInfo *ti)
|
||||||
{
|
{
|
||||||
const NewGRFSpriteLayout *layout = nullptr;
|
const NewGRFSpriteLayout *layout = nullptr;
|
||||||
@@ -3164,70 +3232,7 @@ static void DrawTile_Station(TileInfo *ti)
|
|||||||
|
|
||||||
/* don't show foundation for docks */
|
/* don't show foundation for docks */
|
||||||
if (ti->tileh != SLOPE_FLAT && !IsDock(ti->tile)) {
|
if (ti->tileh != SLOPE_FLAT && !IsDock(ti->tile)) {
|
||||||
if (statspec != nullptr && statspec->flags.Test(StationSpecFlag::CustomFoundations)) {
|
if (!DrawCustomStationFoundations(statspec, st, ti, tile_layout)) {
|
||||||
/* Station has custom foundations.
|
|
||||||
* Check whether the foundation continues beyond the tile's upper sides. */
|
|
||||||
uint edge_info = 0;
|
|
||||||
auto [slope, z] = GetFoundationPixelSlope(ti->tile);
|
|
||||||
if (!HasFoundationNW(ti->tile, slope, z)) SetBit(edge_info, 0);
|
|
||||||
if (!HasFoundationNE(ti->tile, slope, z)) SetBit(edge_info, 1);
|
|
||||||
SpriteID image = GetCustomStationFoundationRelocation(statspec, st, ti->tile, tile_layout, edge_info);
|
|
||||||
if (image == 0) goto draw_default_foundation;
|
|
||||||
|
|
||||||
if (statspec->flags.Test(StationSpecFlag::ExtendedFoundations)) {
|
|
||||||
/* Station provides extended foundations. */
|
|
||||||
|
|
||||||
static const uint8_t foundation_parts[] = {
|
|
||||||
0, 0, 0, 0, // Invalid, Invalid, Invalid, SLOPE_SW
|
|
||||||
0, 1, 2, 3, // Invalid, SLOPE_EW, SLOPE_SE, SLOPE_WSE
|
|
||||||
0, 4, 5, 6, // Invalid, SLOPE_NW, SLOPE_NS, SLOPE_NWS
|
|
||||||
7, 8, 9 // SLOPE_NE, SLOPE_ENW, SLOPE_SEN
|
|
||||||
};
|
|
||||||
|
|
||||||
AddSortableSpriteToDraw(image + foundation_parts[ti->tileh], PAL_NONE, *ti, {{}, {TILE_SIZE, TILE_SIZE, 7}, {}});
|
|
||||||
} else {
|
|
||||||
/* Draw simple foundations, built up from 8 possible foundation sprites. */
|
|
||||||
|
|
||||||
/* Each set bit represents one of the eight composite sprites to be drawn.
|
|
||||||
* 'Invalid' entries will not drawn but are included for completeness. */
|
|
||||||
static const uint8_t composite_foundation_parts[] = {
|
|
||||||
/* Invalid (00000000), Invalid (11010001), Invalid (11100100), SLOPE_SW (11100000) */
|
|
||||||
0x00, 0xD1, 0xE4, 0xE0,
|
|
||||||
/* Invalid (11001010), SLOPE_EW (11001001), SLOPE_SE (11000100), SLOPE_WSE (11000000) */
|
|
||||||
0xCA, 0xC9, 0xC4, 0xC0,
|
|
||||||
/* Invalid (11010010), SLOPE_NW (10010001), SLOPE_NS (11100100), SLOPE_NWS (10100000) */
|
|
||||||
0xD2, 0x91, 0xE4, 0xA0,
|
|
||||||
/* SLOPE_NE (01001010), SLOPE_ENW (00001001), SLOPE_SEN (01000100) */
|
|
||||||
0x4A, 0x09, 0x44
|
|
||||||
};
|
|
||||||
|
|
||||||
uint8_t parts = composite_foundation_parts[ti->tileh];
|
|
||||||
|
|
||||||
/* If foundations continue beyond the tile's upper sides then
|
|
||||||
* mask out the last two pieces. */
|
|
||||||
if (HasBit(edge_info, 0)) ClrBit(parts, 6);
|
|
||||||
if (HasBit(edge_info, 1)) ClrBit(parts, 7);
|
|
||||||
|
|
||||||
if (parts == 0) {
|
|
||||||
/* We always have to draw at least one sprite to make sure there is a boundingbox and a sprite with the
|
|
||||||
* correct offset for the childsprites.
|
|
||||||
* So, draw the (completely empty) sprite of the default foundations. */
|
|
||||||
goto draw_default_foundation;
|
|
||||||
}
|
|
||||||
|
|
||||||
StartSpriteCombine();
|
|
||||||
for (int i = 0; i < 8; i++) {
|
|
||||||
if (HasBit(parts, i)) {
|
|
||||||
AddSortableSpriteToDraw(image + i, PAL_NONE, *ti, {{}, {TILE_SIZE, TILE_SIZE, 7}, {}});
|
|
||||||
}
|
|
||||||
}
|
|
||||||
EndSpriteCombine();
|
|
||||||
}
|
|
||||||
|
|
||||||
OffsetGroundSprite(0, -8);
|
|
||||||
ti->z += ApplyPixelFoundationToSlope(FOUNDATION_LEVELED, ti->tileh);
|
|
||||||
} else {
|
|
||||||
draw_default_foundation:
|
|
||||||
DrawFoundation(ti, FOUNDATION_LEVELED);
|
DrawFoundation(ti, FOUNDATION_LEVELED);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user