diff --git a/src/openrct2/paint/tile_element/Paint.Surface.cpp b/src/openrct2/paint/tile_element/Paint.Surface.cpp index a09298289a..45259ceb8b 100644 --- a/src/openrct2/paint/tile_element/Paint.Surface.cpp +++ b/src/openrct2/paint/tile_element/Paint.Surface.cpp @@ -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(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(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(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 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(tileElement); + const auto* surfaceObject = tileElement.GetSurfaceStyleObject(); + const auto* edgeObject = tileElement.GetEdgeObject(); + TileDescriptor selfDescriptor = { TileCoordsXY(base), elementPtr, - terrain_type, + surfaceObject, surfaceShape, { static_cast(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(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(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]); } }