1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2025-12-23 15:52:55 +01:00

Pass the surface and edge style object instead of repetitive lookups

This commit is contained in:
ζeh Matt
2023-08-27 00:05:38 +03:00
parent 45afc1f67b
commit 1f496173b1

View File

@@ -217,7 +217,7 @@ struct TileDescriptor
{
TileCoordsXY tile_coords;
const TileElement* tile_element;
ObjectEntryIndex terrain;
const TerrainSurfaceObject* surfaceObject;
uint8_t slope;
CornerHeight corner_heights;
};
@@ -300,95 +300,64 @@ static constexpr TileSurfaceBoundaryData _tileSurfaceBoundaries[4] = {
},
};
static const TerrainSurfaceObject* GetSurfaceObject(size_t index)
{
PROFILED_FUNCTION();
TerrainSurfaceObject* result{};
auto& objMgr = OpenRCT2::GetContext()->GetObjectManager();
auto obj = objMgr.GetLoadedObject(ObjectType::TerrainSurface, index);
if (obj != nullptr)
{
return static_cast<TerrainSurfaceObject*>(obj);
}
return result;
}
static ImageId GetSurfaceImage(
const PaintSession& session, ObjectEntryIndex index, int32_t offset, uint8_t rotation, int32_t grassLength, bool grid,
bool underground)
const PaintSession& session, const TerrainSurfaceObject* surfaceObject, int32_t offset, uint8_t rotation,
int32_t grassLength, bool grid, bool underground)
{
PROFILED_FUNCTION();
ImageId image;
auto obj = GetSurfaceObject(index);
if (obj != nullptr)
if (surfaceObject != nullptr)
{
image = ImageId(obj->GetImageId(
image = ImageId(surfaceObject->GetImageId(
{ session.MapPosition.x >> 5, session.MapPosition.y >> 5 }, grassLength, rotation, offset, grid, underground));
if (obj->Colour != 255)
if (surfaceObject->Colour != 255)
{
image = image.WithPrimary(obj->Colour);
image = image.WithPrimary(surfaceObject->Colour);
}
}
return image;
}
static ImageId GetSurfacePattern(uint8_t index, int32_t offset)
static ImageId GetSurfacePattern(const TerrainSurfaceObject* surfaceObject, int32_t offset)
{
PROFILED_FUNCTION();
ImageId image;
auto obj = GetSurfaceObject(index);
if (obj != nullptr)
if (surfaceObject != nullptr)
{
image = ImageId(obj->PatternBaseImageId + offset);
if (obj->Colour != 255)
image = ImageId(surfaceObject->PatternBaseImageId + offset);
if (surfaceObject->Colour != 255)
{
image = image.WithPrimary(obj->Colour);
image = image.WithPrimary(surfaceObject->Colour);
}
}
return image;
}
static bool SurfaceShouldSmoothSelf(uint8_t index)
static bool SurfaceShouldSmoothSelf(const TerrainSurfaceObject* surfaceObject)
{
PROFILED_FUNCTION();
if (surfaceObject == nullptr)
return false;
auto obj = GetSurfaceObject(index);
if (obj != nullptr)
{
return obj->Flags & TERRAIN_SURFACE_FLAGS::SMOOTH_WITH_SELF;
}
return false;
return surfaceObject->Flags & TERRAIN_SURFACE_FLAGS::SMOOTH_WITH_SELF;
}
static bool SurfaceShouldSmooth(uint8_t index)
static bool SurfaceShouldSmooth(const TerrainSurfaceObject* surfaceObject)
{
PROFILED_FUNCTION();
if (surfaceObject == nullptr)
return false;
auto obj = GetSurfaceObject(index);
if (obj != nullptr)
{
return obj->Flags & TERRAIN_SURFACE_FLAGS::SMOOTH_WITH_OTHER;
}
return false;
return surfaceObject->Flags & TERRAIN_SURFACE_FLAGS::SMOOTH_WITH_OTHER;
}
static ImageId GetEdgeImageWithOffset(uint8_t index, uint32_t offset)
static ImageId GetEdgeImageWithOffset(const TerrainEdgeObject* edgeObject, uint32_t offset)
{
ImageId result;
auto& objMgr = OpenRCT2::GetContext()->GetObjectManager();
auto obj = objMgr.GetLoadedObject(ObjectType::TerrainEdge, index);
if (obj != nullptr)
if (edgeObject != nullptr)
{
auto tobj = static_cast<TerrainEdgeObject*>(obj);
result = ImageId(tobj->BaseImageId + offset);
result = ImageId(edgeObject->BaseImageId + offset);
}
return result;
}
static ImageId GetEdgeImage(uint8_t index, uint8_t type)
static ImageId GetEdgeImage(const TerrainEdgeObject* edgeObject, uint8_t type)
{
static constexpr uint32_t offsets[] = {
0,
@@ -400,25 +369,20 @@ static ImageId GetEdgeImage(uint8_t index, uint8_t type)
ImageId result;
if (type < std::size(offsets))
{
result = GetEdgeImageWithOffset(index, offsets[type]);
result = GetEdgeImageWithOffset(edgeObject, offsets[type]);
}
return result;
}
static ImageId GetTunnelImage(ObjectEntryIndex index, uint8_t type, edge_t edge)
static ImageId GetTunnelImage(const TerrainEdgeObject* edgeObject, uint8_t type, edge_t edge)
{
PROFILED_FUNCTION();
static constexpr uint32_t offsets[TUNNEL_TYPE_COUNT] = { 36, 40, 44, 48, 52, 56, 60, 64, 68, 72, 76, 80,
36, 48, 60, 72, 76, 80, 84, 88, 92, 96, 100 };
bool hasDoors = false;
auto& objMgr = OpenRCT2::GetContext()->GetObjectManager();
auto obj = objMgr.GetLoadedObject(ObjectType::TerrainEdge, index);
if (obj != nullptr)
if (edgeObject != nullptr)
{
auto tobj = static_cast<TerrainEdgeObject*>(obj);
hasDoors = tobj->HasDoors && !tobj->UsesFallbackImages();
hasDoors = edgeObject->HasDoors && !edgeObject->UsesFallbackImages();
}
if (!hasDoors && type >= REGULAR_TUNNEL_TYPE_COUNT && type < std::size(offsets))
@@ -427,7 +391,7 @@ static ImageId GetTunnelImage(ObjectEntryIndex index, uint8_t type, edge_t edge)
ImageId result;
if (type < std::size(offsets))
{
result = GetEdgeImageWithOffset(index, offsets[type]).WithIndexOffset(edge == EDGE_BOTTOMRIGHT ? 2 : 0);
result = GetEdgeImageWithOffset(edgeObject, offsets[type]).WithIndexOffset(edge == EDGE_BOTTOMRIGHT ? 2 : 0);
}
return result;
}
@@ -522,21 +486,21 @@ static void ViewportSurfaceSmoothenEdge(
break;
}
if (self.terrain == neighbour.terrain)
if (self.surfaceObject == neighbour.surfaceObject)
{
// same tint
if (cl == dh)
return;
if (!SurfaceShouldSmoothSelf(self.terrain))
if (!SurfaceShouldSmoothSelf(self.surfaceObject))
return;
}
else
{
if (!SurfaceShouldSmooth(self.terrain))
if (!SurfaceShouldSmooth(self.surfaceObject))
return;
if (!SurfaceShouldSmooth(neighbour.terrain))
if (!SurfaceShouldSmooth(neighbour.surfaceObject))
return;
}
@@ -546,7 +510,7 @@ static void ViewportSurfaceSmoothenEdge(
{
AttachedPaintStruct* out = session.LastAttachedPS;
// set content and enable masking
out->ColourImageId = GetSurfacePattern(neighbour.terrain, cl);
out->ColourImageId = GetSurfacePattern(neighbour.surfaceObject, cl);
out->IsMasked = true;
}
}
@@ -569,7 +533,7 @@ static bool TileIsInsideClipView(const TileDescriptor& tile)
}
static void ViewportSurfaceDrawTileSideBottom(
PaintSession& session, enum edge_t edge, uint16_t height, uint8_t edgeStyle, struct TileDescriptor self,
PaintSession& session, enum edge_t edge, uint16_t height, const TerrainEdgeObject* edgeObject, struct TileDescriptor self,
struct TileDescriptor neighbour, bool isWater)
{
PROFILED_FUNCTION();
@@ -648,10 +612,10 @@ static void ViewportSurfaceDrawTileSideBottom(
return;
}
auto baseImageId = GetEdgeImage(edgeStyle, 0);
auto baseImageId = GetEdgeImage(edgeObject, 0);
if (session.ViewFlags & VIEWPORT_FLAG_UNDERGROUND_INSIDE)
{
baseImageId = GetEdgeImage(edgeStyle, 1);
baseImageId = GetEdgeImage(edgeObject, 1);
}
if (edge == EDGE_BOTTOMRIGHT)
@@ -739,7 +703,7 @@ static void ViewportSurfaceDrawTileSideBottom(
boundBoxLength -= 16;
}
auto imageId = GetTunnelImage(edgeStyle, tunnelType, edge);
auto imageId = GetTunnelImage(edgeObject, tunnelType, edge);
PaintAddImageAsParent(
session, imageId, { offset, zOffset },
{ { 0, 0, boundBoxOffsetZ }, { tunnelBounds.x, tunnelBounds.y, boundBoxLength - 1 } });
@@ -753,7 +717,7 @@ static void ViewportSurfaceDrawTileSideBottom(
boundBoxLength -= 16;
}
imageId = GetTunnelImage(edgeStyle, tunnelType, edge).WithIndexOffset(1);
imageId = GetTunnelImage(edgeObject, tunnelType, edge).WithIndexOffset(1);
PaintAddImageAsParent(
session, imageId, { offset, curHeight * COORDS_Z_PER_TINY_Z },
{ { tunnelTopBoundBoxOffset.x, tunnelTopBoundBoxOffset.y, boundBoxOffsetZ },
@@ -768,24 +732,24 @@ static void ViewportSurfaceDrawTileSideBottom(
* rct2: 0x0065EB7D, 0x0065F0D8
*/
static void ViewportSurfaceDrawLandSideBottom(
PaintSession& session, enum edge_t edge, uint16_t height, uint8_t edgeStyle, struct TileDescriptor self,
PaintSession& session, enum edge_t edge, uint16_t height, const TerrainEdgeObject* edgeObject, struct TileDescriptor self,
struct TileDescriptor neighbour)
{
ViewportSurfaceDrawTileSideBottom(session, edge, height, edgeStyle, self, neighbour, false);
ViewportSurfaceDrawTileSideBottom(session, edge, height, edgeObject, self, neighbour, false);
}
/**
* rct2: 0x0065F8B9, 0x0065FE26
*/
static void ViewportSurfaceDrawWaterSideBottom(
PaintSession& session, enum edge_t edge, uint16_t height, uint8_t edgeStyle, struct TileDescriptor self,
PaintSession& session, enum edge_t edge, uint16_t height, const TerrainEdgeObject* edgeObject, struct TileDescriptor self,
struct TileDescriptor neighbour)
{
ViewportSurfaceDrawTileSideBottom(session, edge, height, edgeStyle, self, neighbour, true);
ViewportSurfaceDrawTileSideBottom(session, edge, height, edgeObject, self, neighbour, true);
}
static void ViewportSurfaceDrawTileSideTop(
PaintSession& session, enum edge_t edge, uint16_t height, uint8_t terrain, struct TileDescriptor self,
PaintSession& session, enum edge_t edge, uint16_t height, const TerrainEdgeObject* edgeObject, struct TileDescriptor self,
struct TileDescriptor neighbour, bool isWater)
{
PROFILED_FUNCTION();
@@ -855,10 +819,10 @@ static void ViewportSurfaceDrawTileSideTop(
ImageId baseImageId;
if (isWater)
{
baseImageId = GetEdgeImage(terrain, 2); // var_08
baseImageId = GetEdgeImage(edgeObject, 2); // var_08
if (session.ViewFlags & VIEWPORT_FLAG_UNDERGROUND_INSIDE)
{
baseImageId = GetEdgeImage(terrain, 1); // var_04
baseImageId = GetEdgeImage(edgeObject, 1); // var_04
}
baseImageId = baseImageId.WithIndexOffset(edge == EDGE_TOPLEFT ? 5 : 0);
}
@@ -867,12 +831,12 @@ static void ViewportSurfaceDrawTileSideTop(
if (!(session.ViewFlags & VIEWPORT_FLAG_UNDERGROUND_INSIDE))
{
const uint8_t incline = (cornerHeight2 - cornerHeight1) + 1;
const auto imageId = GetEdgeImage(terrain, 3).WithIndexOffset((edge == EDGE_TOPLEFT ? 3 : 0) + incline);
const auto imageId = GetEdgeImage(edgeObject, 3).WithIndexOffset((edge == EDGE_TOPLEFT ? 3 : 0) + incline);
const int16_t y = (height - cornerHeight1) * COORDS_Z_PER_TINY_Z;
PaintAttachToPreviousPS(session, imageId, 0, y);
return;
}
baseImageId = GetEdgeImage(terrain, 1).WithIndexOffset(edge == EDGE_TOPLEFT ? 5 : 0);
baseImageId = GetEdgeImage(edgeObject, 1).WithIndexOffset(edge == EDGE_TOPLEFT ? 5 : 0);
}
uint8_t cur_height = std::min(neighbourCornerHeight2, neighbourCornerHeight1);
@@ -927,20 +891,20 @@ static void ViewportSurfaceDrawTileSideTop(
* rct2: 0x0065F63B, 0x0065F77D
*/
static void ViewportSurfaceDrawLandSideTop(
PaintSession& session, enum edge_t edge, uint16_t height, uint8_t terrain, struct TileDescriptor self,
PaintSession& session, enum edge_t edge, uint16_t height, const TerrainEdgeObject* edgeObject, struct TileDescriptor self,
struct TileDescriptor neighbour)
{
ViewportSurfaceDrawTileSideTop(session, edge, height, terrain, self, neighbour, false);
ViewportSurfaceDrawTileSideTop(session, edge, height, edgeObject, self, neighbour, false);
}
/**
* rct2: 0x0066039B, 0x006604F1
*/
static void ViewportSurfaceDrawWaterSideTop(
PaintSession& session, enum edge_t edge, uint16_t height, uint8_t terrain, struct TileDescriptor self,
PaintSession& session, enum edge_t edge, uint16_t height, const TerrainEdgeObject* edgeObject, struct TileDescriptor self,
struct TileDescriptor neighbour)
{
ViewportSurfaceDrawTileSideTop(session, edge, height, terrain, self, neighbour, true);
ViewportSurfaceDrawTileSideTop(session, edge, height, edgeObject, self, neighbour, true);
}
static std::pair<int32_t, int32_t> SurfaceGetHeightAboveWater(
@@ -1029,16 +993,18 @@ void PaintSurface(PaintSession& session, uint8_t direction, uint16_t height, con
const auto zoomLevel = session.DPI.zoom_level;
const uint8_t rotation = session.CurrentRotation;
const auto terrain_type = tileElement.GetSurfaceObjectIndex();
const uint8_t surfaceShape = ViewportSurfacePaintSetupGetRelativeSlope(tileElement, rotation);
const CoordsXY& base = session.SpritePosition;
const CornerHeight& cornerHeights = corner_heights[surfaceShape];
const TileElement* elementPtr = &reinterpret_cast<const TileElement&>(tileElement);
const auto* surfaceObject = tileElement.GetSurfaceStyleObject();
const auto* edgeObject = tileElement.GetEdgeObject();
TileDescriptor selfDescriptor = {
TileCoordsXY(base),
elementPtr,
terrain_type,
surfaceObject,
surfaceShape,
{
static_cast<uint8_t>(height / 16 + cornerHeights.top),
@@ -1076,7 +1042,7 @@ void PaintSurface(PaintSession& session, uint8_t direction, uint16_t height, con
descriptor.tile_coords = TileCoordsXY{ position };
descriptor.tile_element = reinterpret_cast<TileElement*>(surfaceElement);
descriptor.terrain = surfaceElement->GetSurfaceObjectIndex();
descriptor.surfaceObject = surfaceElement->GetSurfaceStyleObject();
descriptor.slope = surfaceSlope;
descriptor.corner_heights.top = baseHeight + ch.top;
descriptor.corner_heights.right = baseHeight + ch.right;
@@ -1131,7 +1097,7 @@ void PaintSurface(PaintSession& session, uint8_t direction, uint16_t height, con
}
else
{
imageId = GetSurfaceImage(session, terrain_type, image_offset, rotation, grassLength, showGridlines, false);
imageId = GetSurfaceImage(session, surfaceObject, image_offset, rotation, grassLength, showGridlines, false);
}
if (session.ViewFlags & (VIEWPORT_FLAG_UNDERGROUND_INSIDE | VIEWPORT_FLAG_HIDE_BASE))
{
@@ -1300,22 +1266,17 @@ 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, terrain_type, image_offset, rotation, 1, false, true);
auto imageId = GetSurfaceImage(session, surfaceObject, image_offset, rotation, 1, false, true);
PaintAttachToPreviousPS(session, imageId, 0, 0);
}
if (!(session.ViewFlags & VIEWPORT_FLAG_HIDE_VERTICAL))
{
const auto edgeStyle = tileElement.GetEdgeObjectIndex();
if (static_cast<int32_t>(edgeStyle) >= object_entry_group_counts[EnumValue(ObjectType::TerrainEdge)])
{
LOG_VERBOSE("edgeStyle: %d", edgeStyle);
}
ViewportSurfaceDrawLandSideTop(session, EDGE_TOPLEFT, height, edgeStyle, tileDescriptors[0], tileDescriptors[3]);
ViewportSurfaceDrawLandSideTop(session, EDGE_TOPRIGHT, height, edgeStyle, tileDescriptors[0], tileDescriptors[4]);
ViewportSurfaceDrawLandSideBottom(session, EDGE_BOTTOMLEFT, height, edgeStyle, tileDescriptors[0], tileDescriptors[1]);
ViewportSurfaceDrawLandSideBottom(session, EDGE_BOTTOMRIGHT, height, edgeStyle, tileDescriptors[0], tileDescriptors[2]);
ViewportSurfaceDrawLandSideTop(session, EDGE_TOPLEFT, height, edgeObject, tileDescriptors[0], tileDescriptors[3]);
ViewportSurfaceDrawLandSideTop(session, EDGE_TOPRIGHT, height, edgeObject, tileDescriptors[0], tileDescriptors[4]);
ViewportSurfaceDrawLandSideBottom(session, EDGE_BOTTOMLEFT, height, edgeObject, tileDescriptors[0], tileDescriptors[1]);
ViewportSurfaceDrawLandSideBottom(
session, EDGE_BOTTOMRIGHT, height, edgeObject, tileDescriptors[0], tileDescriptors[2]);
}
const uint16_t waterHeight = tileElement.GetWaterHeight();
@@ -1345,18 +1306,14 @@ void PaintSurface(PaintSession& session, uint8_t direction, uint16_t height, con
if (!(session.ViewFlags & VIEWPORT_FLAG_HIDE_VERTICAL))
{
// This wasn't in the original, but the code depended on globals that were only set in a different conditional
const uint32_t edgeStyle = tileElement.GetEdgeObjectIndex();
// end new code
ViewportSurfaceDrawWaterSideBottom(
session, EDGE_BOTTOMLEFT, waterHeight, edgeStyle, tileDescriptors[0], tileDescriptors[1]);
session, EDGE_BOTTOMLEFT, waterHeight, edgeObject, tileDescriptors[0], tileDescriptors[1]);
ViewportSurfaceDrawWaterSideBottom(
session, EDGE_BOTTOMRIGHT, waterHeight, edgeStyle, tileDescriptors[0], tileDescriptors[2]);
session, EDGE_BOTTOMRIGHT, waterHeight, edgeObject, tileDescriptors[0], tileDescriptors[2]);
ViewportSurfaceDrawWaterSideTop(
session, EDGE_TOPLEFT, waterHeight, edgeStyle, tileDescriptors[0], tileDescriptors[3]);
session, EDGE_TOPLEFT, waterHeight, edgeObject, tileDescriptors[0], tileDescriptors[3]);
ViewportSurfaceDrawWaterSideTop(
session, EDGE_TOPRIGHT, waterHeight, edgeStyle, tileDescriptors[0], tileDescriptors[4]);
session, EDGE_TOPRIGHT, waterHeight, edgeObject, tileDescriptors[0], tileDescriptors[4]);
}
}