OpenRCT2/test/testpaint/Compat.cpp

502 lines
11 KiB
C++
Raw Normal View History

2016-08-24 13:19:25 +02:00
/*****************************************************************************
* Copyright (c) 2014-2018 OpenRCT2 developers
2016-08-24 13:19:25 +02:00
*
* For a complete list of all authors, please refer to contributors.md
* Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
2016-08-24 13:19:25 +02:00
*
* OpenRCT2 is licensed under the GNU General Public License version 3.
2016-08-24 13:19:25 +02:00
*****************************************************************************/
2018-05-15 12:54:58 +02:00
#include "Addresses.h"
2017-02-20 21:05:59 +01:00
#include <openrct2/config/Config.h>
2018-01-06 00:08:58 +01:00
#include <openrct2/interface/Colour.h>
2018-01-06 00:45:53 +01:00
#include <openrct2/interface/Viewport.h>
2018-05-15 12:54:58 +02:00
#include <openrct2/object/Object.h>
#include <openrct2/paint/tile_element/Paint.TileElement.h>
2017-12-31 13:21:34 +01:00
#include <openrct2/ride/Ride.h>
2017-10-17 13:51:47 +02:00
#include <openrct2/ride/Track.h>
2018-05-15 12:54:58 +02:00
#include <openrct2/world/Location.hpp>
2018-01-11 10:59:26 +01:00
#include <openrct2/world/Sprite.h>
2018-05-01 20:21:21 +02:00
#include <openrct2/world/Surface.h>
2016-09-12 17:37:57 +02:00
class StationObject;
2018-06-22 22:29:03 +02:00
#define gRideEntries RCT2_ADDRESS(0x009ACFA4, rct_ride_entry*)
2018-11-01 13:53:50 +01:00
#define gTileElementTilePointers RCT2_ADDRESS(0x013CE9A4, TileElement*)
2018-06-22 22:29:03 +02:00
rct_sprite* sprite_list = RCT2_ADDRESS(0x010E63BC, rct_sprite);
2017-12-04 19:57:41 +01:00
2017-12-03 23:07:24 +01:00
Ride gRideList[MAX_RIDES];
int16_t gMapSizeUnits;
int16_t gMapBaseZ;
2016-09-12 17:37:57 +02:00
bool gTrackDesignSaveMode = false;
uint8_t gTrackDesignSaveRideIndex = RIDE_ID_NULL;
uint8_t gClipHeight = 255;
2020-03-07 21:07:18 +01:00
CoordsXY gClipSelectionA = { 0, 0 };
CoordsXY gClipSelectionB = { MAXIMUM_TILE_START_XY, MAXIMUM_TILE_START_XY };
uint32_t gScenarioTicks;
uint8_t gCurrentRotation;
2016-08-24 13:19:25 +02:00
// clang-format off
constexpr const std::array<CoordsXY, 8> CoordsDirectionDelta = {
CoordsXY{ -COORDS_XY_STEP, 0 },
CoordsXY{ 0, +COORDS_XY_STEP },
CoordsXY{ +COORDS_XY_STEP, 0 },
CoordsXY{ 0, -COORDS_XY_STEP },
CoordsXY{ -COORDS_XY_STEP, +COORDS_XY_STEP },
CoordsXY{ +COORDS_XY_STEP, +COORDS_XY_STEP },
CoordsXY{ +COORDS_XY_STEP, -COORDS_XY_STEP },
CoordsXY{ -COORDS_XY_STEP, -COORDS_XY_STEP },
};
2018-05-03 13:17:00 +02:00
const TileCoordsXY TileDirectionDelta[] = {
{ -1, 0 },
{ 0, +1 },
{ +1, 0 },
{ 0, -1 },
{ -1, +1 },
{ +1, +1 },
{ +1, -1 },
{ -1, -1 },
};
// clang-format on
2016-08-24 13:19:25 +02:00
2018-06-22 22:29:03 +02:00
TileCoordsXYZD ride_get_entrance_location(const Ride* ride, const int32_t stationIndex);
TileCoordsXYZD ride_get_exit_location(const Ride* ride, const int32_t stationIndex);
2018-06-22 22:29:03 +02:00
uint8_t get_current_rotation()
{
return gCurrentRotation & 3;
2016-08-24 13:19:25 +02:00
}
const uint32_t construction_markers[] = {
COLOUR_DARK_GREEN << 19 | COLOUR_GREY << 24 | IMAGE_TYPE_REMAP, // White
2018-06-22 22:29:03 +02:00
2 << 19 | 0b110000 << 19 | IMAGE_TYPE_TRANSPARENT, // Translucent
2016-08-24 13:19:25 +02:00
};
int object_entry_group_counts[] = {
2018-06-22 22:29:03 +02:00
128, // rides
252, // small scenery
128, // large scenery
128, // walls
32, // banners
16, // paths
15, // path bits
19, // scenery sets
1, // park entrance
1, // water
1 // scenario text
2016-08-24 13:19:25 +02:00
};
2017-02-21 07:29:06 +01:00
GeneralConfiguration gConfigGeneral;
uint16_t gMapSelectFlags;
uint16_t gMapSelectType;
2019-12-19 09:40:21 +01:00
CoordsXY gMapSelectPositionA;
CoordsXY gMapSelectPositionB;
CoordsXYZ gMapSelectArrowPosition;
uint8_t gMapSelectArrowDirection;
2016-08-24 13:19:25 +02:00
2018-11-01 13:53:50 +01:00
void entrance_paint(paint_session* session, uint8_t direction, int height, const TileElement* tile_element)
2018-06-22 22:29:03 +02:00
{
}
2018-11-01 13:53:50 +01:00
void banner_paint(paint_session* session, uint8_t direction, int height, const TileElement* tile_element)
2018-06-22 22:29:03 +02:00
{
}
2018-11-01 13:53:50 +01:00
void surface_paint(paint_session* session, uint8_t direction, uint16_t height, const TileElement* tileElement)
2018-06-22 22:29:03 +02:00
{
}
2018-11-01 13:53:50 +01:00
void path_paint(paint_session* session, uint16_t height, const TileElement* tileElement)
2018-06-22 22:29:03 +02:00
{
}
2018-11-01 13:53:50 +01:00
void scenery_paint(paint_session* session, uint8_t direction, int height, const TileElement* tileElement)
2018-06-22 22:29:03 +02:00
{
}
2018-11-01 13:53:50 +01:00
void fence_paint(paint_session* session, uint8_t direction, int height, const TileElement* tileElement)
2018-06-22 22:29:03 +02:00
{
}
2018-11-01 13:53:50 +01:00
void large_scenery_paint(paint_session* session, uint8_t direction, uint16_t height, const TileElement* tileElement)
2018-06-22 22:29:03 +02:00
{
}
2016-08-24 13:19:25 +02:00
2019-08-04 18:12:34 +02:00
Ride* get_ride(ride_id_t index)
2018-06-22 22:29:03 +02:00
{
2019-08-04 18:12:34 +02:00
if (index >= RCT12_MAX_RIDES_IN_PARK)
2018-06-22 22:29:03 +02:00
{
log_error("invalid index %d for ride", index);
2018-01-29 17:06:01 +01:00
return nullptr;
}
return &gRideList[index];
2016-08-24 13:19:25 +02:00
}
2018-06-22 22:29:03 +02:00
rct_ride_entry* get_ride_entry(int index)
{
if (index < 0 || index >= object_entry_group_counts[OBJECT_TYPE_RIDE])
{
log_error("invalid index %d for ride type", index);
2018-01-29 17:06:01 +01:00
return nullptr;
}
return gRideEntries[index];
2016-08-24 13:19:25 +02:00
}
rct_ride_entry* Ride::GetRideEntry() const
2018-06-22 22:29:03 +02:00
{
rct_ride_entry* rideEntry = get_ride_entry(subtype);
if (rideEntry == nullptr)
2018-06-22 22:29:03 +02:00
{
log_error("Invalid ride subtype for ride");
}
return rideEntry;
2016-08-24 13:19:25 +02:00
}
2018-06-22 22:29:03 +02:00
rct_sprite* get_sprite(size_t sprite_idx)
{
assert(sprite_idx < MAX_SPRITES);
return &sprite_list[sprite_idx];
2016-08-24 13:19:25 +02:00
}
bool TileElementBase::IsLastForTile() const
{
2020-03-04 22:28:06 +01:00
return (this->Flags & TILE_ELEMENT_FLAG_LAST_TILE) != 0;
}
void TileElementBase::SetLastForTile(bool on)
{
if (on)
2020-03-04 22:28:06 +01:00
Flags |= TILE_ELEMENT_FLAG_LAST_TILE;
else
2020-03-04 22:28:06 +01:00
Flags &= ~TILE_ELEMENT_FLAG_LAST_TILE;
2016-08-24 13:19:25 +02:00
}
2018-09-13 19:40:07 +02:00
uint8_t TileElementBase::GetType() const
{
return this->type & TILE_ELEMENT_TYPE_MASK;
2016-08-24 13:19:25 +02:00
}
2019-02-26 09:50:04 +01:00
bool TileElementBase::IsGhost() const
{
2020-03-04 22:28:06 +01:00
return (this->Flags & TILE_ELEMENT_FLAG_GHOST) != 0;
2019-02-26 09:50:04 +01:00
}
2019-02-27 11:54:08 +01:00
bool TrackElement::BlockBrakeClosed() const
{
2020-03-04 22:28:06 +01:00
return (Flags2 & TRACK_ELEMENT_FLAGS2_BLOCK_BRAKE_CLOSED) != 0;
2019-02-27 11:54:08 +01:00
}
TileElement* map_get_first_element_at(const CoordsXY& elementPos)
2018-06-22 22:29:03 +02:00
{
if (elementPos.x < 0 || elementPos.y < 0 || elementPos.x > 255 || elementPos.y > 255)
2018-06-22 22:29:03 +02:00
{
log_error("Trying to access element outside of range");
2018-01-29 17:06:01 +01:00
return nullptr;
}
auto tileElementPos = TileCoordsXY{ elementPos };
return gTileElementTilePointers[tileElementPos.x + tileElementPos.y * 256];
2016-08-24 13:19:25 +02:00
}
bool ride_type_has_flag(int rideType, uint32_t flag)
2016-08-24 13:19:25 +02:00
{
return (RideProperties[rideType].flags & flag) != 0;
2016-08-24 13:19:25 +02:00
}
2016-09-12 22:56:52 +02:00
int16_t get_height_marker_offset()
2016-09-12 22:56:52 +02:00
{
return 0;
2016-09-12 22:56:52 +02:00
}
bool is_csg_loaded()
{
return false;
}
uint8_t TrackElement::GetSeatRotation() const
{
2019-08-31 13:14:19 +02:00
return ColourScheme >> 4;
}
void TrackElement::SetSeatRotation(uint8_t newSeatRotation)
{
2019-08-31 13:14:19 +02:00
ColourScheme &= ~TRACK_ELEMENT_COLOUR_SEAT_ROTATION_MASK;
ColourScheme |= (newSeatRotation << 4);
}
bool TrackElement::IsTakingPhoto() const
{
2019-08-31 13:14:19 +02:00
return OnridePhotoBits != 0;
}
void TrackElement::SetPhotoTimeout()
{
2019-08-31 13:14:19 +02:00
OnridePhotoBits = 3;
}
void TrackElement::SetPhotoTimeout(uint8_t value)
{
OnridePhotoBits = value;
}
uint8_t TrackElement::GetPhotoTimeout() const
{
return OnridePhotoBits;
}
void TrackElement::DecrementPhotoTimeout()
{
2019-08-31 13:14:19 +02:00
OnridePhotoBits = std::max(0, OnridePhotoBits - 1);
}
uint16_t TrackElement::GetMazeEntry() const
{
2019-08-31 13:14:19 +02:00
return MazeEntry;
}
void TrackElement::SetMazeEntry(uint16_t newMazeEntry)
{
2019-08-31 13:14:19 +02:00
MazeEntry = newMazeEntry;
}
void TrackElement::MazeEntryAdd(uint16_t addVal)
{
2019-08-31 13:14:19 +02:00
MazeEntry |= addVal;
}
void TrackElement::MazeEntrySubtract(uint16_t subVal)
{
2019-08-31 13:14:19 +02:00
MazeEntry &= ~subVal;
}
2017-10-04 17:14:53 +02:00
2019-08-31 13:14:19 +02:00
track_type_t TrackElement::GetTrackType() const
2017-11-14 13:27:30 +01:00
{
2019-08-31 13:14:19 +02:00
return TrackType;
2017-11-14 13:27:30 +01:00
}
2019-08-31 13:14:19 +02:00
void TrackElement::SetTrackType(track_type_t newType)
2017-11-14 13:27:30 +01:00
{
2019-08-31 13:14:19 +02:00
TrackType = newType;
}
uint8_t TrackElement::GetSequenceIndex() const
{
2019-08-31 13:14:19 +02:00
return Sequence;
}
void TrackElement::SetSequenceIndex(uint8_t newSequenceIndex)
{
2019-08-31 13:14:19 +02:00
Sequence = newSequenceIndex;
}
uint8_t TrackElement::GetStationIndex() const
{
2019-08-31 13:14:19 +02:00
return StationIndex;
}
void TrackElement::SetStationIndex(uint8_t newStationIndex)
{
2019-08-31 13:14:19 +02:00
StationIndex = newStationIndex;
}
uint8_t TrackElement::GetDoorAState() const
{
2019-08-31 13:14:19 +02:00
return (ColourScheme & TRACK_ELEMENT_COLOUR_DOOR_A_MASK) >> 2;
}
uint8_t TrackElement::GetDoorBState() const
{
2019-08-31 13:14:19 +02:00
return (ColourScheme & TRACK_ELEMENT_COLOUR_DOOR_B_MASK) >> 5;
}
2020-02-16 22:21:17 +01:00
ride_id_t TrackElement::GetRideIndex() const
{
2019-08-31 13:14:19 +02:00
return RideIndex;
}
2020-02-16 22:21:17 +01:00
void TrackElement::SetRideIndex(ride_id_t newRideIndex)
{
2019-08-31 13:14:19 +02:00
RideIndex = newRideIndex;
}
uint8_t TrackElement::GetColourScheme() const
{
2019-08-31 13:14:19 +02:00
return ColourScheme & TRACK_ELEMENT_COLOUR_SCHEME_MASK;
}
void TrackElement::SetColourScheme(uint8_t newColourScheme)
{
2019-08-31 13:14:19 +02:00
ColourScheme &= ~TRACK_ELEMENT_COLOUR_SCHEME_MASK;
ColourScheme |= (newColourScheme & TRACK_ELEMENT_COLOUR_SCHEME_MASK);
}
bool TrackElement::HasCableLift() const
{
2019-08-31 13:14:19 +02:00
return Flags2 & TRACK_ELEMENT_FLAGS2_CABLE_LIFT;
}
void TrackElement::SetHasCableLift(bool on)
{
2019-08-31 13:14:19 +02:00
Flags2 &= ~TRACK_ELEMENT_FLAGS2_CABLE_LIFT;
if (on)
2019-08-31 13:14:19 +02:00
Flags2 |= TRACK_ELEMENT_FLAGS2_CABLE_LIFT;
}
bool TrackElement::IsInverted() const
{
2019-08-31 13:14:19 +02:00
return Flags2 & TRACK_ELEMENT_FLAGS2_INVERTED;
}
void TrackElement::SetInverted(bool inverted)
{
if (inverted)
{
2019-08-31 13:14:19 +02:00
Flags2 |= TRACK_ELEMENT_FLAGS2_INVERTED;
}
else
{
2019-08-31 13:14:19 +02:00
Flags2 &= ~TRACK_ELEMENT_FLAGS2_INVERTED;
}
}
uint8_t TrackElement::GetBrakeBoosterSpeed() const
{
2019-08-31 13:14:19 +02:00
return BrakeBoosterSpeed << 1;
}
void TrackElement::SetBrakeBoosterSpeed(uint8_t speed)
{
2019-08-31 13:14:19 +02:00
BrakeBoosterSpeed = (speed >> 1);
}
2019-08-31 13:14:19 +02:00
bool TrackElement::HasGreenLight() const
{
2019-08-31 13:14:19 +02:00
return (Flags2 & TRACK_ELEMENT_FLAGS2_HAS_GREEN_LIGHT) != 0;
}
2019-08-31 13:14:19 +02:00
void TrackElement::SetHasGreenLight(bool on)
{
2019-08-31 13:14:19 +02:00
Flags2 &= ~TRACK_ELEMENT_FLAGS2_HAS_GREEN_LIGHT;
if (on)
{
2019-08-31 13:14:19 +02:00
Flags2 |= TRACK_ELEMENT_FLAGS2_HAS_GREEN_LIGHT;
}
}
bool TrackElement::HasChain() const
{
2019-08-31 13:14:19 +02:00
return (Flags2 & TRACK_ELEMENT_FLAGS2_CHAIN_LIFT) != 0;
}
void TrackElement::SetHasChain(bool on)
{
if (on)
{
2019-08-31 13:14:19 +02:00
Flags2 |= TRACK_ELEMENT_FLAGS2_CHAIN_LIFT;
}
else
{
2019-08-31 13:14:19 +02:00
Flags2 &= ~TRACK_ELEMENT_FLAGS2_CHAIN_LIFT;
}
}
2018-06-22 22:29:03 +02:00
TileCoordsXYZD ride_get_entrance_location(const Ride* ride, const int32_t stationIndex)
{
return ride->stations[stationIndex].Entrance;
}
2018-06-22 22:29:03 +02:00
TileCoordsXYZD ride_get_exit_location(const Ride* ride, const int32_t stationIndex)
{
return ride->stations[stationIndex].Exit;
2018-05-15 12:54:58 +02:00
}
2018-09-15 23:32:19 +02:00
2018-09-23 12:01:58 +02:00
void TileElementBase::SetType(uint8_t newType)
{
this->type &= ~TILE_ELEMENT_TYPE_MASK;
this->type |= (newType & TILE_ELEMENT_TYPE_MASK);
}
2018-09-15 23:32:19 +02:00
uint8_t TileElementBase::GetDirection() const
{
return this->type & TILE_ELEMENT_DIRECTION_MASK;
}
uint8_t TileElementBase::GetDirectionWithOffset(uint8_t offset) const
{
return ((this->type & TILE_ELEMENT_DIRECTION_MASK) + offset) & TILE_ELEMENT_DIRECTION_MASK;
}
uint8_t SurfaceElement::GetSlope() const
{
2019-08-31 10:01:28 +02:00
return Slope;
2018-09-15 23:32:19 +02:00
}
int32_t SurfaceElement::GetWaterHeight() const
2018-09-15 23:32:19 +02:00
{
return WaterHeight * 16;
2018-09-15 23:32:19 +02:00
}
bool TrackElement::IsHighlighted() const
{
2019-08-31 13:14:19 +02:00
return (Flags2 & TRACK_ELEMENT_FLAGS2_HIGHLIGHT);
}
uint8_t PathElement::GetEdges() const
{
2020-03-04 22:28:06 +01:00
return Edges & 0xF;
}
StationObject* ride_get_station_object(const Ride* ride)
{
return nullptr;
}
2019-05-08 21:56:38 +02:00
2020-01-19 18:37:24 +01:00
bool Vehicle::IsGhost() const
2019-05-08 21:56:38 +02:00
{
auto r = get_ride(ride);
return r != nullptr && r->status == RIDE_STATUS_SIMULATING;
}
uint8_t TileElementBase::GetOccupiedQuadrants() const
{
2020-03-04 22:28:06 +01:00
return Flags & TILE_ELEMENT_OCCUPIED_QUADRANTS_MASK;
}
void TileElementBase::SetOccupiedQuadrants(uint8_t quadrants)
{
2020-03-04 22:28:06 +01:00
Flags &= ~TILE_ELEMENT_OCCUPIED_QUADRANTS_MASK;
Flags |= (quadrants & TILE_ELEMENT_OCCUPIED_QUADRANTS_MASK);
}
int32_t TileElementBase::GetBaseZ() const
{
return base_height * 8;
}
void TileElementBase::SetBaseZ(int32_t newZ)
{
base_height = (newZ / 8);
}
int32_t TileElementBase::GetClearanceZ() const
{
return clearance_height * 8;
}
void TileElementBase::SetClearanceZ(int32_t newZ)
{
clearance_height = (newZ / 8);
}
int32_t RideStation::GetBaseZ() const
{
return Height * 8;
}
void RideStation::SetBaseZ(int32_t newZ)
{
Height = newZ / 8;
}
CoordsXYZ RideStation::GetStart() const
{
TileCoordsXYZ stationTileCoords{ Start.x, Start.y, Height };
return stationTileCoords.ToCoordsXYZ();
}