Change TileElement to use OpenLoco's structure

This commit is contained in:
Michael Steenbeek 2018-09-13 15:19:08 +02:00
parent 574fd83882
commit a02d360df6
4 changed files with 160 additions and 50 deletions

View File

@ -1116,7 +1116,7 @@ static void window_tile_inspector_mousedown(rct_window* w, rct_widgetindex widge
// Set current value as checked
rct_tile_element* const tileElement = window_tile_inspector_get_selected_element(w);
dropdown_set_checked(tileElement->GetSceneryQuadrant(), true);
dropdown_set_checked(tileElement->AsWall()->GetSlope(), true);
break;
} // switch widget index
break;
@ -1570,10 +1570,10 @@ static void window_tile_inspector_invalidate(rct_window* w)
w->widgets[WIDX_SCENERY_CHECK_QUARTER_W].top = GBBT(propertiesAnchor, 1) - 5 + 7 * 1;
w->widgets[WIDX_SCENERY_CHECK_QUARTER_W].bottom = w->widgets[WIDX_SCENERY_CHECK_QUARTER_W].top + 13;
// This gets the relative rotation, by subtracting the camera's rotation, and wrapping it between 0-3 inclusive
bool N = tileElement->GetSceneryQuadrant() == ((0 - get_current_rotation()) & 3);
bool E = tileElement->GetSceneryQuadrant() == ((1 - get_current_rotation()) & 3);
bool S = tileElement->GetSceneryQuadrant() == ((2 - get_current_rotation()) & 3);
bool W = tileElement->GetSceneryQuadrant() == ((3 - get_current_rotation()) & 3);
bool N = tileElement->AsSmallScenery()->GetSceneryQuadrant() == ((0 - get_current_rotation()) & 3);
bool E = tileElement->AsSmallScenery()->GetSceneryQuadrant() == ((1 - get_current_rotation()) & 3);
bool S = tileElement->AsSmallScenery()->GetSceneryQuadrant() == ((2 - get_current_rotation()) & 3);
bool W = tileElement->AsSmallScenery()->GetSceneryQuadrant() == ((3 - get_current_rotation()) & 3);
widget_set_checkbox_value(w, WIDX_SCENERY_CHECK_QUARTER_N, N);
widget_set_checkbox_value(w, WIDX_SCENERY_CHECK_QUARTER_E, E);
widget_set_checkbox_value(w, WIDX_SCENERY_CHECK_QUARTER_S, S);
@ -1620,7 +1620,7 @@ static void window_tile_inspector_invalidate(rct_window* w)
w->widgets[WIDX_WALL_SPINNER_HEIGHT_DECREASE].bottom = GBBB(propertiesAnchor, 0) - 4;
w->widgets[WIDX_WALL_DROPDOWN_SLOPE].top = GBBT(propertiesAnchor, 1) + 3;
w->widgets[WIDX_WALL_DROPDOWN_SLOPE].bottom = GBBB(propertiesAnchor, 1) - 3;
w->widgets[WIDX_WALL_DROPDOWN_SLOPE].text = WallSlopeStringIds[tileElement->GetSceneryQuadrant()];
w->widgets[WIDX_WALL_DROPDOWN_SLOPE].text = WallSlopeStringIds[tileElement->AsWall()->GetSlope()];
w->widgets[WIDX_WALL_DROPDOWN_SLOPE_BUTTON].top = GBBT(propertiesAnchor, 1) + 4;
w->widgets[WIDX_WALL_DROPDOWN_SLOPE_BUTTON].bottom = GBBB(propertiesAnchor, 1) - 4;
const uint8_t wallType = tileElement->properties.wall.type;
@ -1880,7 +1880,7 @@ static void window_tile_inspector_paint(rct_window* w, rct_drawpixelinfo* dpi)
const rct_scenery_entry* sceneryEntry = get_small_scenery_entry(tileElement->properties.scenery.type);
if (!(scenery_small_entry_has_flag(sceneryEntry, SMALL_SCENERY_FLAG_FULL_TILE)))
{
int16_t quadrant = tileElement->GetSceneryQuadrant();
int16_t quadrant = tileElement->AsSmallScenery()->GetSceneryQuadrant();
static rct_string_id quadrant_string_idx[] = { STR_TILE_INSPECTOR_SCENERY_QUADRANT_SW,
STR_TILE_INSPECTOR_SCENERY_QUADRANT_NW,
STR_TILE_INSPECTOR_SCENERY_QUADRANT_NE,

View File

@ -114,7 +114,7 @@ void scenery_paint(paint_session* session, uint8_t direction, int32_t height, co
else
{
// 6DFFC2:
uint8_t ecx = (tileElement->GetSceneryQuadrant() + rotation) & 3;
uint8_t ecx = (tileElement->AsSmallScenery()->GetSceneryQuadrant() + rotation) & 3;
x_offset = ScenerySubTileOffsets[ecx].x;
y_offset = ScenerySubTileOffsets[ecx].y;
boxoffset.x = x_offset;
@ -386,7 +386,7 @@ void scenery_paint(paint_session* session, uint8_t direction, int32_t height, co
if (scenery_small_entry_has_flag(entry, SMALL_SCENERY_FLAG_VOFFSET_CENTRE))
{
// 6E075C:
direction = (tileElement->GetSceneryQuadrant() + rotation) % 4;
direction = (tileElement->AsSmallScenery()->GetSceneryQuadrant() + rotation) % 4;
paint_util_set_segment_support_height(
session, paint_util_rotate_segments(SEGMENT_B4 | SEGMENT_C8 | SEGMENT_CC, direction), height, 0x20);
return;
@ -404,7 +404,7 @@ void scenery_paint(paint_session* session, uint8_t direction, int32_t height, co
}
if (scenery_small_entry_has_flag(entry, SMALL_SCENERY_FLAG_VOFFSET_CENTRE))
{
direction = (tileElement->GetSceneryQuadrant() + rotation) % 4;
direction = (tileElement->AsSmallScenery()->GetSceneryQuadrant() + rotation) % 4;
paint_util_set_segment_support_height(
session, paint_util_rotate_segments(SEGMENT_B4 | SEGMENT_C8 | SEGMENT_CC, direction), 0xFFFF, 0);
return;

View File

@ -17,44 +17,49 @@
#include "LargeScenery.h"
#include "Scenery.h"
uint8_t rct_tile_element::GetType() const
uint8_t TileElementBase::GetType() const
{
return this->type & TILE_ELEMENT_TYPE_MASK;
}
void rct_tile_element::SetType(uint8_t newType)
void TileElementBase::SetType(uint8_t newType)
{
this->type &= ~TILE_ELEMENT_TYPE_MASK;
this->type |= (newType & TILE_ELEMENT_TYPE_MASK);
}
uint8_t rct_tile_element::GetDirection() const
uint8_t TileElementBase::GetDirection() const
{
return this->type & TILE_ELEMENT_DIRECTION_MASK;
}
void rct_tile_element::SetDirection(uint8_t direction)
void TileElementBase::SetDirection(uint8_t direction)
{
this->type &= ~TILE_ELEMENT_DIRECTION_MASK;
this->type |= (direction & TILE_ELEMENT_DIRECTION_MASK);
}
uint8_t rct_tile_element::GetDirectionWithOffset(uint8_t offset) const
uint8_t TileElementBase::GetDirectionWithOffset(uint8_t offset) const
{
return ((this->type & TILE_ELEMENT_DIRECTION_MASK) + offset) & TILE_ELEMENT_DIRECTION_MASK;
}
bool rct_tile_element::IsLastForTile() const
bool TileElementBase::IsLastForTile() const
{
return (this->flags & TILE_ELEMENT_FLAG_LAST_TILE) != 0;
}
bool rct_tile_element::IsGhost() const
bool TileElementBase::IsGhost() const
{
return (this->flags & TILE_ELEMENT_FLAG_GHOST) != 0;
}
uint8_t rct_tile_element::GetSceneryQuadrant() const
uint8_t SmallSceneryElement::GetSceneryQuadrant() const
{
return (this->type & TILE_ELEMENT_QUADRANT_MASK) >> 6;
}
uint8_t WallElement::GetSlope() const
{
return (this->type & TILE_ELEMENT_QUADRANT_MASK) >> 6;
}

View File

@ -121,38 +121,6 @@ union rct_tile_element_properties
};
assert_struct_size(rct_tile_element_properties, 4);
/**
* Map element structure
* size: 0x08
*/
struct rct_tile_element
{
uint8_t type; // 0
uint8_t flags; // 1
uint8_t base_height; // 2
uint8_t clearance_height; // 3
rct_tile_element_properties properties;
uint8_t GetType() const;
void SetType(uint8_t newType);
uint8_t GetDirection() const;
void SetDirection(uint8_t direction);
uint8_t GetDirectionWithOffset(uint8_t offset) const;
bool IsLastForTile() const;
bool IsGhost() const;
uint8_t GetSceneryQuadrant() const;
};
assert_struct_size(rct_tile_element, 8);
#pragma pack(pop)
enum
{
TILE_ELEMENT_QUADRANT_SW,
TILE_ELEMENT_QUADRANT_NW,
TILE_ELEMENT_QUADRANT_NE,
TILE_ELEMENT_QUADRANT_SE
};
enum
{
TILE_ELEMENT_TYPE_SURFACE = (0 << 2),
@ -168,6 +136,143 @@ enum
TILE_ELEMENT_TYPE_CORRUPT = (8 << 2),
};
enum class TileElementType : uint8_t
{
Surface = (0 << 2),
Path = (1 << 2),
Track = (2 << 2),
SmallScenery = (3 << 2),
Entrance = (4 << 2),
Wall = (5 << 2),
LargeScenery = (6 << 2),
Banner = (7 << 2),
Corrupt = (8 << 2),
};
struct SurfaceElement;
struct PathElement;
struct TrackElement;
struct SmallSceneryElement;
struct LargeSceneryElement;
struct WallElement;
struct EntranceElement;
struct BannerElement;
struct CorruptElement;
struct TileElementBase
{
uint8_t type; // 0
uint8_t flags; // 1
uint8_t base_height; // 2
uint8_t clearance_height; // 3
uint8_t GetType() const;
void SetType(uint8_t newType);
uint8_t GetDirection() const;
void SetDirection(uint8_t direction);
uint8_t GetDirectionWithOffset(uint8_t offset) const;
bool IsLastForTile() const;
bool IsGhost() const;
};
/**
* Map element structure
* size: 0x08
*/
struct rct_tile_element : public TileElementBase
{
// TODO: Remove this field.
rct_tile_element_properties properties;
template<typename TType, TileElementType TClass>
TType* as() const
{
return (TileElementType)GetType() == TClass ? (TType*)this : nullptr;
}
public:
SurfaceElement* AsSurface() const { return as<SurfaceElement, TileElementType::Surface>(); }
PathElement* AsPath() const { return as<PathElement, TileElementType::Path>(); }
TrackElement* AsTrack() const { return as<TrackElement, TileElementType::Track>(); }
SmallSceneryElement* AsSmallScenery() const { return as<SmallSceneryElement, TileElementType::SmallScenery>(); }
LargeSceneryElement* AsLargeScenery() const { return as<LargeSceneryElement, TileElementType::LargeScenery>(); }
WallElement* AsWall() const { return as<WallElement, TileElementType::Wall>(); }
EntranceElement* AsEntrance() const { return as<EntranceElement, TileElementType::Entrance>(); }
BannerElement* AsBanner() const { return as<BannerElement, TileElementType::Banner>(); }
CorruptElement* AsCorrupt() const { return as<CorruptElement, TileElementType::Corrupt>(); }
};
assert_struct_size(rct_tile_element, 8);
struct SurfaceElement : TileElementBase
{
rct_tile_element_surface_properties temp;
};
assert_struct_size(SurfaceElement, 8);
struct PathElement : TileElementBase
{
rct_tile_element_path_properties temp;
};
assert_struct_size(PathElement, 8);
struct TrackElement : TileElementBase
{
rct_tile_element_track_properties temp;
};
assert_struct_size(TrackElement, 8);
struct SmallSceneryElement : TileElementBase
{
rct_tile_element_scenery_properties temp;
public:
uint8_t GetSceneryQuadrant() const;
};
assert_struct_size(SmallSceneryElement, 8);
struct LargeSceneryElement : TileElementBase
{
rct_tile_element_scenerymultiple_properties temp;
};
assert_struct_size(LargeSceneryElement, 8);
struct WallElement : TileElementBase
{
rct_tile_element_wall_properties temp;
public:
uint8_t GetSlope() const;
};
assert_struct_size(WallElement, 8);
struct EntranceElement : TileElementBase
{
rct_tile_element_entrance_properties temp;
};
assert_struct_size(EntranceElement, 8);
struct BannerElement : TileElementBase
{
rct_tile_element_banner_properties temp;
};
assert_struct_size(BannerElement, 8);
struct CorruptElement : TileElementBase
{
uint8_t pad[4];
};
assert_struct_size(CorruptElement, 8);
#pragma pack(pop)
enum
{
TILE_ELEMENT_QUADRANT_SW,
TILE_ELEMENT_QUADRANT_NW,
TILE_ELEMENT_QUADRANT_NE,
TILE_ELEMENT_QUADRANT_SE
};
enum
{
TILE_ELEMENT_TYPE_FLAG_HIGHLIGHT = (1 << 6)