Speed up TerrainSurfaceObject::GetImageId()

This commit is contained in:
mrmbernardi 2024-04-26 09:52:19 +02:00 committed by GitHub
parent 5837a33a60
commit f4cebb11df
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
6 changed files with 70 additions and 65 deletions

View File

@ -69,7 +69,7 @@ void LandTool::ShowSurfaceStyleDropdown(WindowBase* w, Widget* widget, ObjectEnt
if (surfaceObj != nullptr && !surfaceObj->UsesFallbackImages())
{
auto imageId = ImageId(surfaceObj->IconImageId);
if (surfaceObj->Colour != 255)
if (surfaceObj->Colour != TerrainSurfaceObject::kNoValue)
imageId = imageId.WithPrimary(surfaceObj->Colour);
gDropdownItems[itemIndex].Format = Dropdown::FormatLandPicker;

View File

@ -325,7 +325,7 @@ static Widget window_land_widgets[] = {
if (surfaceObj != nullptr)
{
surfaceImage = ImageId(surfaceObj->IconImageId);
if (surfaceObj->Colour != 255)
if (surfaceObj->Colour != TerrainSurfaceObject::kNoValue)
surfaceImage = surfaceImage.WithPrimary(surfaceObj->Colour);
}

View File

@ -678,7 +678,7 @@ static uint64_t PressedWidgets[WINDOW_MAPGEN_PAGE_COUNT] = {
if (surfaceObj != nullptr)
{
surfaceImage = ImageId(surfaceObj->IconImageId);
if (surfaceObj->Colour != 255)
if (surfaceObj->Colour != TerrainSurfaceObject::kNoValue)
{
surfaceImage = surfaceImage.WithPrimary(surfaceObj->Colour);
}

View File

@ -12,11 +12,9 @@
#include "TerrainSurfaceObject.h"
#include "../Context.h"
#include "../core/IStream.hpp"
#include "../core/Guard.hpp"
#include "../core/Json.hpp"
#include "../core/String.hpp"
#include "../drawing/Drawing.h"
#include "../localisation/Localisation.h"
#include "../world/Location.hpp"
#include "ObjectManager.h"
@ -34,7 +32,7 @@ void TerrainSurfaceObject::Load()
{
EntryBaseImageId = IconImageId + 1;
}
NumEntries = (GetImageTable().GetCount() - EntryBaseImageId) / NUM_IMAGES_IN_ENTRY;
NumEntries = (GetImageTable().GetCount() - EntryBaseImageId) / kNumImagesInEntry;
}
void TerrainSurfaceObject::Unload()
@ -52,7 +50,7 @@ void TerrainSurfaceObject::Unload()
void TerrainSurfaceObject::DrawPreview(DrawPixelInfo& dpi, int32_t width, int32_t height) const
{
auto imageId = ImageId(GetImageId({}, 1, 0, 0, false, false));
if (Colour != 255)
if (Colour != kNoValue)
{
imageId = imageId.WithPrimary(Colour);
}
@ -84,7 +82,7 @@ void TerrainSurfaceObject::ReadJson(IReadObjectContext* context, json_t& root)
if (properties.is_object())
{
Colour = Colour::FromString(Json::GetString(properties["colour"]), 255);
Colour = Colour::FromString(Json::GetString(properties["colour"]), kNoValue);
Rotations = Json::GetNumber<int8_t>(properties["rotations"], 1);
Price = Json::GetNumber<money64>(properties["price"]);
Flags = Json::GetFlags<TERRAIN_SURFACE_FLAGS>(
@ -108,13 +106,17 @@ void TerrainSurfaceObject::ReadJson(IReadObjectContext* context, json_t& root)
if (el.is_object())
{
SpecialEntry entry;
entry.Index = Json::GetNumber<uint32_t>(el["index"]);
entry.Length = Json::GetNumber<int32_t>(el["length"], -1);
entry.Rotation = Json::GetNumber<int32_t>(el["rotation"], -1);
entry.Variation = Json::GetNumber<int32_t>(el["variation"], -1);
entry.Grid = Json::GetBoolean(el["grid"]);
entry.Underground = Json::GetBoolean(el["underground"]);
SpecialEntries.push_back(std::move(entry));
entry.Index = Json::GetNumber<uint8_t>(el["index"]);
entry.Length = Json::GetNumber<uint8_t>(el["length"], kNoValue);
entry.Rotation = Json::GetNumber<uint8_t>(el["rotation"], kNoValue);
entry.Variation = Json::GetNumber<uint8_t>(el["variation"], kNoValue);
if (Json::GetBoolean(el["underground"]))
SpecialEntriesUnderground.push_back(entry);
else if (Json::GetBoolean(el["grid"]))
SpecialEntriesGrid.push_back(entry);
else
SpecialEntries.push_back(entry);
}
}
}
@ -136,24 +138,43 @@ void TerrainSurfaceObject::ReadJson(IReadObjectContext* context, json_t& root)
PopulateTablesFromJson(context, root);
}
uint32_t TerrainSurfaceObject::GetImageId(
const CoordsXY& position, int32_t length, int32_t rotation, int32_t offset, bool grid, bool underground) const
ImageId TerrainSurfaceObject::GetImageId(
const CoordsXY& position, uint8_t length, uint8_t rotation, uint8_t offset, bool grid, bool underground) const
{
uint32_t result = (underground ? DefaultUndergroundEntry : (grid ? DefaultGridEntry : DefaultEntry));
uint32_t result = DefaultEntry;
std::span<const SpecialEntry> entries(SpecialEntries);
if (underground)
{
result = DefaultUndergroundEntry;
entries = std::span<const SpecialEntry>(SpecialEntriesUnderground);
}
else if (grid)
{
result = DefaultGridEntry;
entries = std::span<const SpecialEntry>(SpecialEntriesGrid);
}
TileCoordsXY tilePos(position);
uint8_t variation = ((tilePos.x << 1) & 0b10) | (tilePos.y & 0b01);
// Look for a matching special
auto variation = ((position.x << 1) & 0b10) | (position.y & 0b01);
for (const auto& special : SpecialEntries)
for (const SpecialEntry& special : entries)
{
if ((special.Length == -1 || special.Length == length) && (special.Rotation == -1 || special.Rotation == rotation)
&& (special.Variation == -1 || special.Variation == variation) && special.Grid == grid
&& special.Underground == underground)
if ((special.Length == kNoValue || special.Length == length)
&& (special.Rotation == kNoValue || special.Rotation == rotation)
&& (special.Variation == kNoValue || special.Variation == variation))
{
result = special.Index;
break;
}
}
return EntryBaseImageId + (result * NUM_IMAGES_IN_ENTRY) + offset;
ImageId image(EntryBaseImageId + (result * kNumImagesInEntry) + offset);
if (Colour != kNoValue)
{
image = image.WithPrimary(Colour);
}
return image;
}
TerrainSurfaceObject* TerrainSurfaceObject::GetById(ObjectEntryIndex entryIndex)

View File

@ -26,17 +26,16 @@ class TerrainSurfaceObject final : public Object
private:
struct SpecialEntry
{
uint32_t Index{};
int32_t Length{};
int32_t Rotation{};
int32_t Variation{};
bool Grid{};
bool Underground{};
uint8_t Index{};
uint8_t Length{};
uint8_t Rotation{};
uint8_t Variation{};
};
static constexpr auto NUM_IMAGES_IN_ENTRY = 19;
static constexpr auto kNumImagesInEntry = 19;
public:
static constexpr uint8_t kNoValue = 0xFF;
StringId NameStringId{};
uint32_t IconImageId{};
uint32_t PatternBaseImageId{};
@ -47,7 +46,8 @@ public:
uint32_t DefaultGridEntry{};
uint32_t DefaultUndergroundEntry{};
std::vector<SpecialEntry> SpecialEntries;
std::vector<uint32_t> SpecialEntryMap;
std::vector<SpecialEntry> SpecialEntriesUnderground;
std::vector<SpecialEntry> SpecialEntriesGrid;
colour_t Colour{};
uint8_t Rotations{};
@ -61,8 +61,8 @@ public:
void DrawPreview(DrawPixelInfo& dpi, int32_t width, int32_t height) const override;
uint32_t GetImageId(
const CoordsXY& position, int32_t length, int32_t rotation, int32_t offset, bool grid, bool underground) const;
ImageId GetImageId(
const CoordsXY& position, uint8_t length, uint8_t rotation, uint8_t offset, bool grid, bool underground) const;
static TerrainSurfaceObject* GetById(ObjectEntryIndex entryIndex);
};

View File

@ -302,30 +302,13 @@ static constexpr TileSurfaceBoundaryData _tileSurfaceBoundaries[4] = {
},
};
static ImageId GetSurfaceImage(
const PaintSession& session, const TerrainSurfaceObject* surfaceObject, int32_t offset, uint8_t rotation,
int32_t grassLength, bool grid, bool underground)
{
ImageId image;
if (surfaceObject != nullptr)
{
image = ImageId(surfaceObject->GetImageId(
{ session.MapPosition.x >> 5, session.MapPosition.y >> 5 }, grassLength, rotation, offset, grid, underground));
if (surfaceObject->Colour != 255)
{
image = image.WithPrimary(surfaceObject->Colour);
}
}
return image;
}
static ImageId GetSurfacePattern(const TerrainSurfaceObject* surfaceObject, int32_t offset)
{
ImageId image;
if (surfaceObject != nullptr)
{
image = ImageId(surfaceObject->PatternBaseImageId + offset);
if (surfaceObject->Colour != 255)
if (surfaceObject->Colour != TerrainSurfaceObject::kNoValue)
{
image = image.WithPrimary(surfaceObject->Colour);
}
@ -1108,15 +1091,6 @@ void PaintSurface(PaintSession& session, uint8_t direction, uint16_t height, con
{
const bool showGridlines = (session.ViewFlags & VIEWPORT_FLAG_GRIDLINES);
auto grassLength = -1;
if (zoomLevel <= ZoomLevel{ 0 })
{
if ((session.ViewFlags & (VIEWPORT_FLAG_HIDE_BASE | VIEWPORT_FLAG_UNDERGROUND_INSIDE)) == 0)
{
grassLength = tileElement.GetGrassLength() & 0x7;
}
}
assert(surfaceShape < std::size(Byte97B444));
const uint8_t image_offset = Byte97B444[surfaceShape];
@ -1125,9 +1099,17 @@ void PaintSurface(PaintSession& session, uint8_t direction, uint16_t height, con
{
imageId = ImageId(SPR_TERRAIN_TRACK_DESIGNER);
}
else
else if (surfaceObject != nullptr)
{
imageId = GetSurfaceImage(session, surfaceObject, image_offset, rotation, grassLength, showGridlines, false);
uint8_t grassLength = TerrainSurfaceObject::kNoValue;
if (zoomLevel <= ZoomLevel{ 0 })
{
if ((session.ViewFlags & (VIEWPORT_FLAG_HIDE_BASE | VIEWPORT_FLAG_UNDERGROUND_INSIDE)) == 0)
{
grassLength = tileElement.GetGrassLength() & 0x7;
}
}
imageId = surfaceObject->GetImageId(session.MapPosition, grassLength, rotation, image_offset, showGridlines, false);
}
if (session.ViewFlags & (VIEWPORT_FLAG_UNDERGROUND_INSIDE | VIEWPORT_FLAG_HIDE_BASE))
{
@ -1299,7 +1281,9 @@ void PaintSurface(PaintSession& session, uint8_t direction, uint16_t height, con
&& !(gScreenFlags & (SCREEN_FLAGS_TRACK_DESIGNER | SCREEN_FLAGS_TRACK_MANAGER)))
{
const uint8_t image_offset = Byte97B444[surfaceShape];
auto imageId = GetSurfaceImage(session, surfaceObject, image_offset, rotation, 1, false, true);
ImageId imageId;
if (surfaceObject != nullptr)
imageId = surfaceObject->GetImageId(session.MapPosition, 1, rotation, image_offset, false, true);
PaintAttachToPreviousPS(session, imageId, 0, 0);
}