1
0
mirror of https://github.com/OpenRCT2/OpenRCT2 synced 2026-01-17 12:03:07 +01:00

Move all RCT1 to RCT1 namespace (#15283)

This commit is contained in:
Duncan
2021-08-25 20:44:24 +01:00
committed by GitHub
parent 4d261b389c
commit b97c46421e
6 changed files with 4187 additions and 4173 deletions

View File

@@ -1001,7 +1001,7 @@ bool RCT1DataPresentAtLocation(const utf8* path)
bool CsgIsUsable(const rct_gx& csg)
{
return csg.header.total_size == RCT1_LL_CSG1_DAT_FILE_SIZE && csg.header.num_entries == RCT1_NUM_LL_CSG_ENTRIES;
return csg.header.total_size == RCT1::RCT1_LL_CSG1_DAT_FILE_SIZE && csg.header.num_entries == RCT1::RCT1_NUM_LL_CSG_ENTRIES;
}
bool CsgAtLocationIsUsable(const utf8* path)

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

View File

@@ -22,274 +22,278 @@
#include "../ride/TrackDesign.h"
#include "../ride/TrackDesignRepository.h"
/**
* Class to import RollerCoaster Tycoon 1 track designs (*.TD4).
*/
class TD4Importer final : public ITrackImporter
namespace RCT1
{
private:
OpenRCT2::MemoryStream _stream;
std::string _name;
public:
TD4Importer()
/**
* Class to import RollerCoaster Tycoon 1 track designs (*.TD4).
*/
class TD4Importer final : public ITrackImporter
{
}
private:
OpenRCT2::MemoryStream _stream;
std::string _name;
bool Load(const utf8* path) override
{
const utf8* extension = Path::GetExtension(path);
if (String::Equals(extension, ".td4", true))
public:
TD4Importer()
{
_name = GetNameFromTrackPath(path);
auto fs = OpenRCT2::FileStream(path, OpenRCT2::FILE_MODE_OPEN);
return LoadFromStream(&fs);
}
else
{
throw std::runtime_error("Invalid RCT1 track extension.");
}
}
bool LoadFromStream(OpenRCT2::IStream* stream) override
{
auto checksumType = SawyerEncoding::ValidateTrackChecksum(stream);
if (!gConfigGeneral.allow_loading_with_incorrect_checksum && checksumType == RCT12TrackDesignVersion::unknown)
{
throw IOException("Invalid checksum.");
}
auto chunkReader = SawyerChunkReader(stream);
auto data = chunkReader.ReadChunkTrack();
_stream.WriteArray<const uint8_t>(reinterpret_cast<const uint8_t*>(data->GetData()), data->GetLength());
_stream.SetPosition(0);
return true;
}
std::unique_ptr<TrackDesign> Import() override
{
std::unique_ptr<TrackDesign> td = std::make_unique<TrackDesign>();
_stream.SetPosition(7);
RCT12TrackDesignVersion version = static_cast<RCT12TrackDesignVersion>(_stream.ReadValue<uint8_t>() >> 2);
if (version != RCT12TrackDesignVersion::TD4 && version != RCT12TrackDesignVersion::TD4_AA)
bool Load(const utf8* path) override
{
throw IOException("Version number incorrect.");
}
_stream.SetPosition(0);
if (version == RCT12TrackDesignVersion::TD4_AA)
{
return ImportAA();
}
else
{
return ImportTD4();
}
}
private:
std::unique_ptr<TrackDesign> ImportAA()
{
std::unique_ptr<TrackDesign> td = std::make_unique<TrackDesign>();
rct_track_td4_aa td4aa{};
_stream.Read(&td4aa, sizeof(rct_track_td4_aa));
for (int32_t i = 0; i < RCT12_NUM_COLOUR_SCHEMES; i++)
{
td->track_spine_colour[i] = RCT1::GetColour(td4aa.track_spine_colour[i]);
td->track_rail_colour[i] = RCT1::GetColour(td4aa.track_rail_colour[i]);
td->track_support_colour[i] = RCT1::GetColour(td4aa.track_support_colour[i]);
}
td->flags2 = td4aa.flags2;
return ImportTD4Base(std::move(td), td4aa);
}
std::unique_ptr<TrackDesign> ImportTD4()
{
std::unique_ptr<TrackDesign> td = std::make_unique<TrackDesign>();
rct_track_td4 td4{};
_stream.Read(&td4, sizeof(rct_track_td4));
for (int32_t i = 0; i < NUM_COLOUR_SCHEMES; i++)
{
td->track_spine_colour[i] = RCT1::GetColour(td4.track_spine_colour_v0);
td->track_rail_colour[i] = RCT1::GetColour(td4.track_rail_colour_v0);
td->track_support_colour[i] = RCT1::GetColour(td4.track_support_colour_v0);
// Mazes were only hedges
switch (td4.type)
const utf8* extension = Path::GetExtension(path);
if (String::Equals(extension, ".td4", true))
{
case RCT1_RIDE_TYPE_HEDGE_MAZE:
td->track_support_colour[i] = MAZE_WALL_TYPE_HEDGE;
break;
case RCT1_RIDE_TYPE_RIVER_RAPIDS:
td->track_spine_colour[i] = COLOUR_WHITE;
td->track_rail_colour[i] = COLOUR_WHITE;
break;
}
}
td->flags2 = 0;
return ImportTD4Base(std::move(td), td4);
}
std::unique_ptr<TrackDesign> ImportTD4Base(std::unique_ptr<TrackDesign> td, rct_track_td4& td4Base)
{
td->type = RCT1::GetRideType(td4Base.type, td4Base.vehicle_type);
// All TD4s that use powered launch use the type that doesn't pass the station.
td->ride_mode = static_cast<RideMode>(td4Base.mode);
if (td4Base.mode == RCT1_RIDE_MODE_POWERED_LAUNCH)
{
td->ride_mode = RideMode::PoweredLaunch;
}
// Convert RCT1 vehicle type to RCT2 vehicle type. Initialise with a string consisting of 8 spaces.
rct_object_entry vehicleObject = { 0x80, " " };
if (td4Base.type == RIDE_TYPE_MAZE)
{
const char* vehObjName = RCT1::GetRideTypeObject(td4Base.type);
assert(vehObjName != nullptr);
std::memcpy(vehicleObject.name, vehObjName, std::min(String::SizeOf(vehObjName), static_cast<size_t>(8)));
}
else
{
const char* vehObjName = RCT1::GetVehicleObject(td4Base.vehicle_type);
assert(vehObjName != nullptr);
std::memcpy(vehicleObject.name, vehObjName, std::min(String::SizeOf(vehObjName), static_cast<size_t>(8)));
}
std::memcpy(&td->vehicle_object, &vehicleObject, sizeof(rct_object_entry));
td->vehicle_type = td4Base.vehicle_type;
td->flags = td4Base.flags;
td->colour_scheme = td4Base.version_and_colour_scheme & 0x3;
// Vehicle colours
for (int32_t i = 0; i < RCT1_MAX_TRAINS_PER_RIDE; i++)
{
// RCT1 had no third colour
RCT1::RCT1VehicleColourSchemeCopyDescriptor colourSchemeCopyDescriptor = RCT1::GetColourSchemeCopyDescriptor(
td4Base.vehicle_type);
if (colourSchemeCopyDescriptor.colour1 == COPY_COLOUR_1)
{
td->vehicle_colours[i].body_colour = RCT1::GetColour(td4Base.vehicle_colours[i].body_colour);
}
else if (colourSchemeCopyDescriptor.colour1 == COPY_COLOUR_2)
{
td->vehicle_colours[i].body_colour = RCT1::GetColour(td4Base.vehicle_colours[i].trim_colour);
_name = GetNameFromTrackPath(path);
auto fs = OpenRCT2::FileStream(path, OpenRCT2::FILE_MODE_OPEN);
return LoadFromStream(&fs);
}
else
{
td->vehicle_colours[i].body_colour = colourSchemeCopyDescriptor.colour1;
throw std::runtime_error("Invalid RCT1 track extension.");
}
}
bool LoadFromStream(OpenRCT2::IStream* stream) override
{
auto checksumType = SawyerEncoding::ValidateTrackChecksum(stream);
if (!gConfigGeneral.allow_loading_with_incorrect_checksum && checksumType == RCT12TrackDesignVersion::unknown)
{
throw IOException("Invalid checksum.");
}
if (colourSchemeCopyDescriptor.colour2 == COPY_COLOUR_1)
auto chunkReader = SawyerChunkReader(stream);
auto data = chunkReader.ReadChunkTrack();
_stream.WriteArray<const uint8_t>(reinterpret_cast<const uint8_t*>(data->GetData()), data->GetLength());
_stream.SetPosition(0);
return true;
}
std::unique_ptr<TrackDesign> Import() override
{
std::unique_ptr<TrackDesign> td = std::make_unique<TrackDesign>();
_stream.SetPosition(7);
RCT12TrackDesignVersion version = static_cast<RCT12TrackDesignVersion>(_stream.ReadValue<uint8_t>() >> 2);
if (version != RCT12TrackDesignVersion::TD4 && version != RCT12TrackDesignVersion::TD4_AA)
{
td->vehicle_colours[i].trim_colour = RCT1::GetColour(td4Base.vehicle_colours[i].body_colour);
throw IOException("Version number incorrect.");
}
else if (colourSchemeCopyDescriptor.colour2 == COPY_COLOUR_2)
_stream.SetPosition(0);
if (version == RCT12TrackDesignVersion::TD4_AA)
{
td->vehicle_colours[i].trim_colour = RCT1::GetColour(td4Base.vehicle_colours[i].trim_colour);
return ImportAA();
}
else
{
td->vehicle_colours[i].trim_colour = colourSchemeCopyDescriptor.colour2;
}
if (colourSchemeCopyDescriptor.colour3 == COPY_COLOUR_1)
{
td->vehicle_additional_colour[i] = RCT1::GetColour(td4Base.vehicle_colours[i].body_colour);
}
else if (colourSchemeCopyDescriptor.colour3 == COPY_COLOUR_2)
{
td->vehicle_additional_colour[i] = RCT1::GetColour(td4Base.vehicle_colours[i].trim_colour);
}
else
{
td->vehicle_additional_colour[i] = colourSchemeCopyDescriptor.colour3;
return ImportTD4();
}
}
// Set remaining vehicles to same colour as first vehicle
for (size_t i = RCT1_MAX_TRAINS_PER_RIDE; i < std::size(td->vehicle_colours); i++)
{
td->vehicle_colours[i] = td->vehicle_colours[0];
td->vehicle_additional_colour[i] = td->vehicle_additional_colour[0];
}
td->depart_flags = td4Base.depart_flags;
td->number_of_trains = td4Base.number_of_trains;
td->number_of_cars_per_train = td4Base.number_of_cars_per_train;
td->min_waiting_time = td4Base.min_waiting_time;
td->max_waiting_time = td4Base.max_waiting_time;
td->operation_setting = std::min(td4Base.operation_setting, GetRideTypeDescriptor(td->type).OperatingSettings.MaxValue);
td->max_speed = td4Base.max_speed;
td->average_speed = td4Base.average_speed;
td->ride_length = td4Base.ride_length;
td->max_positive_vertical_g = td4Base.max_positive_vertical_g;
td->max_negative_vertical_g = td4Base.max_negative_vertical_g;
td->max_lateral_g = td4Base.max_lateral_g;
if (td->type == RIDE_TYPE_MINI_GOLF)
private:
std::unique_ptr<TrackDesign> ImportAA()
{
td->holes = td4Base.num_holes;
}
else
{
td->inversions = td4Base.num_inversions;
}
std::unique_ptr<TrackDesign> td = std::make_unique<TrackDesign>();
rct_track_td4_aa td4aa{};
_stream.Read(&td4aa, sizeof(rct_track_td4_aa));
td->drops = td4Base.num_drops;
td->highest_drop_height = td4Base.highest_drop_height / 2;
td->excitement = td4Base.excitement;
td->intensity = td4Base.intensity;
td->nausea = td4Base.nausea;
td->upkeep_cost = td4Base.upkeep_cost;
td->space_required_x = 255;
td->space_required_y = 255;
td->lift_hill_speed = 5;
td->num_circuits = 0;
td->operation_setting = std::min(td->operation_setting, GetRideTypeDescriptor(td->type).OperatingSettings.MaxValue);
if (td->type == RIDE_TYPE_MAZE)
{
rct_td46_maze_element t4MazeElement{};
t4MazeElement.all = !0;
while (t4MazeElement.all != 0)
for (int32_t i = 0; i < RCT12_NUM_COLOUR_SCHEMES; i++)
{
_stream.Read(&t4MazeElement, sizeof(rct_td46_maze_element));
if (t4MazeElement.all != 0)
td->track_spine_colour[i] = RCT1::GetColour(td4aa.track_spine_colour[i]);
td->track_rail_colour[i] = RCT1::GetColour(td4aa.track_rail_colour[i]);
td->track_support_colour[i] = RCT1::GetColour(td4aa.track_support_colour[i]);
}
td->flags2 = td4aa.flags2;
return ImportTD4Base(std::move(td), td4aa);
}
std::unique_ptr<TrackDesign> ImportTD4()
{
std::unique_ptr<TrackDesign> td = std::make_unique<TrackDesign>();
rct_track_td4 td4{};
_stream.Read(&td4, sizeof(rct_track_td4));
for (int32_t i = 0; i < NUM_COLOUR_SCHEMES; i++)
{
td->track_spine_colour[i] = RCT1::GetColour(td4.track_spine_colour_v0);
td->track_rail_colour[i] = RCT1::GetColour(td4.track_rail_colour_v0);
td->track_support_colour[i] = RCT1::GetColour(td4.track_support_colour_v0);
// Mazes were only hedges
switch (td4.type)
{
TrackDesignMazeElement mazeElement{};
mazeElement.x = t4MazeElement.x;
mazeElement.y = t4MazeElement.y;
mazeElement.direction = t4MazeElement.direction;
mazeElement.type = t4MazeElement.type;
td->maze_elements.push_back(mazeElement);
case RCT1_RIDE_TYPE_HEDGE_MAZE:
td->track_support_colour[i] = MAZE_WALL_TYPE_HEDGE;
break;
case RCT1_RIDE_TYPE_RIVER_RAPIDS:
td->track_spine_colour[i] = COLOUR_WHITE;
td->track_rail_colour[i] = COLOUR_WHITE;
break;
}
}
}
else
{
rct_td46_track_element t4TrackElement{};
for (uint8_t endFlag = _stream.ReadValue<uint8_t>(); endFlag != 0xFF; endFlag = _stream.ReadValue<uint8_t>())
{
_stream.SetPosition(_stream.GetPosition() - 1);
_stream.Read(&t4TrackElement, sizeof(rct_td46_track_element));
TrackDesignTrackElement trackElement{};
trackElement.type = RCT1TrackTypeToOpenRCT2(t4TrackElement.type, td->type);
trackElement.flags = t4TrackElement.flags;
td->track_elements.push_back(trackElement);
}
td->flags2 = 0;
return ImportTD4Base(std::move(td), td4);
}
td->name = _name;
return td;
}
};
std::unique_ptr<TrackDesign> ImportTD4Base(std::unique_ptr<TrackDesign> td, rct_track_td4& td4Base)
{
td->type = RCT1::GetRideType(td4Base.type, td4Base.vehicle_type);
// All TD4s that use powered launch use the type that doesn't pass the station.
td->ride_mode = static_cast<RideMode>(td4Base.mode);
if (td4Base.mode == RCT1_RIDE_MODE_POWERED_LAUNCH)
{
td->ride_mode = RideMode::PoweredLaunch;
}
// Convert RCT1 vehicle type to RCT2 vehicle type. Initialise with a string consisting of 8 spaces.
rct_object_entry vehicleObject = { 0x80, " " };
if (td4Base.type == RIDE_TYPE_MAZE)
{
const char* vehObjName = RCT1::GetRideTypeObject(td4Base.type);
assert(vehObjName != nullptr);
std::memcpy(vehicleObject.name, vehObjName, std::min(String::SizeOf(vehObjName), static_cast<size_t>(8)));
}
else
{
const char* vehObjName = RCT1::GetVehicleObject(td4Base.vehicle_type);
assert(vehObjName != nullptr);
std::memcpy(vehicleObject.name, vehObjName, std::min(String::SizeOf(vehObjName), static_cast<size_t>(8)));
}
std::memcpy(&td->vehicle_object, &vehicleObject, sizeof(rct_object_entry));
td->vehicle_type = td4Base.vehicle_type;
td->flags = td4Base.flags;
td->colour_scheme = td4Base.version_and_colour_scheme & 0x3;
// Vehicle colours
for (int32_t i = 0; i < RCT1_MAX_TRAINS_PER_RIDE; i++)
{
// RCT1 had no third colour
RCT1::RCT1VehicleColourSchemeCopyDescriptor colourSchemeCopyDescriptor = RCT1::GetColourSchemeCopyDescriptor(
td4Base.vehicle_type);
if (colourSchemeCopyDescriptor.colour1 == COPY_COLOUR_1)
{
td->vehicle_colours[i].body_colour = RCT1::GetColour(td4Base.vehicle_colours[i].body_colour);
}
else if (colourSchemeCopyDescriptor.colour1 == COPY_COLOUR_2)
{
td->vehicle_colours[i].body_colour = RCT1::GetColour(td4Base.vehicle_colours[i].trim_colour);
}
else
{
td->vehicle_colours[i].body_colour = colourSchemeCopyDescriptor.colour1;
}
if (colourSchemeCopyDescriptor.colour2 == COPY_COLOUR_1)
{
td->vehicle_colours[i].trim_colour = RCT1::GetColour(td4Base.vehicle_colours[i].body_colour);
}
else if (colourSchemeCopyDescriptor.colour2 == COPY_COLOUR_2)
{
td->vehicle_colours[i].trim_colour = RCT1::GetColour(td4Base.vehicle_colours[i].trim_colour);
}
else
{
td->vehicle_colours[i].trim_colour = colourSchemeCopyDescriptor.colour2;
}
if (colourSchemeCopyDescriptor.colour3 == COPY_COLOUR_1)
{
td->vehicle_additional_colour[i] = RCT1::GetColour(td4Base.vehicle_colours[i].body_colour);
}
else if (colourSchemeCopyDescriptor.colour3 == COPY_COLOUR_2)
{
td->vehicle_additional_colour[i] = RCT1::GetColour(td4Base.vehicle_colours[i].trim_colour);
}
else
{
td->vehicle_additional_colour[i] = colourSchemeCopyDescriptor.colour3;
}
}
// Set remaining vehicles to same colour as first vehicle
for (size_t i = RCT1_MAX_TRAINS_PER_RIDE; i < std::size(td->vehicle_colours); i++)
{
td->vehicle_colours[i] = td->vehicle_colours[0];
td->vehicle_additional_colour[i] = td->vehicle_additional_colour[0];
}
td->depart_flags = td4Base.depart_flags;
td->number_of_trains = td4Base.number_of_trains;
td->number_of_cars_per_train = td4Base.number_of_cars_per_train;
td->min_waiting_time = td4Base.min_waiting_time;
td->max_waiting_time = td4Base.max_waiting_time;
td->operation_setting = std::min(
td4Base.operation_setting, GetRideTypeDescriptor(td->type).OperatingSettings.MaxValue);
td->max_speed = td4Base.max_speed;
td->average_speed = td4Base.average_speed;
td->ride_length = td4Base.ride_length;
td->max_positive_vertical_g = td4Base.max_positive_vertical_g;
td->max_negative_vertical_g = td4Base.max_negative_vertical_g;
td->max_lateral_g = td4Base.max_lateral_g;
if (td->type == RIDE_TYPE_MINI_GOLF)
{
td->holes = td4Base.num_holes;
}
else
{
td->inversions = td4Base.num_inversions;
}
td->drops = td4Base.num_drops;
td->highest_drop_height = td4Base.highest_drop_height / 2;
td->excitement = td4Base.excitement;
td->intensity = td4Base.intensity;
td->nausea = td4Base.nausea;
td->upkeep_cost = td4Base.upkeep_cost;
td->space_required_x = 255;
td->space_required_y = 255;
td->lift_hill_speed = 5;
td->num_circuits = 0;
td->operation_setting = std::min(td->operation_setting, GetRideTypeDescriptor(td->type).OperatingSettings.MaxValue);
if (td->type == RIDE_TYPE_MAZE)
{
rct_td46_maze_element t4MazeElement{};
t4MazeElement.all = !0;
while (t4MazeElement.all != 0)
{
_stream.Read(&t4MazeElement, sizeof(rct_td46_maze_element));
if (t4MazeElement.all != 0)
{
TrackDesignMazeElement mazeElement{};
mazeElement.x = t4MazeElement.x;
mazeElement.y = t4MazeElement.y;
mazeElement.direction = t4MazeElement.direction;
mazeElement.type = t4MazeElement.type;
td->maze_elements.push_back(mazeElement);
}
}
}
else
{
rct_td46_track_element t4TrackElement{};
for (uint8_t endFlag = _stream.ReadValue<uint8_t>(); endFlag != 0xFF; endFlag = _stream.ReadValue<uint8_t>())
{
_stream.SetPosition(_stream.GetPosition() - 1);
_stream.Read(&t4TrackElement, sizeof(rct_td46_track_element));
TrackDesignTrackElement trackElement{};
trackElement.type = RCT1TrackTypeToOpenRCT2(t4TrackElement.type, td->type);
trackElement.flags = t4TrackElement.flags;
td->track_elements.push_back(trackElement);
}
}
td->name = _name;
return td;
}
};
} // namespace RCT1
std::unique_ptr<ITrackImporter> TrackImporter::CreateTD4()
{
return std::make_unique<TD4Importer>();
return std::make_unique<RCT1::TD4Importer>();
}

View File

@@ -1396,13 +1396,13 @@ namespace RCT1
};
return map[sceneryType];
}
// clang-format on
track_type_t RCT1TrackTypeToOpenRCT2(RCT12TrackType origTrackType, uint8_t rideType)
{
if (GetRideTypeDescriptor(rideType).HasFlag(RIDE_TYPE_FLAG_FLAT_RIDE))
return RCT12FlatTrackTypeToOpenRCT2(origTrackType);
return origTrackType;
}
} // namespace RCT1
track_type_t RCT1TrackTypeToOpenRCT2(RCT12TrackType origTrackType, uint8_t rideType)
{
if (GetRideTypeDescriptor(rideType).HasFlag(RIDE_TYPE_FLAG_FLAT_RIDE))
return RCT12FlatTrackTypeToOpenRCT2(origTrackType);
return origTrackType;
}
// clang-format on

View File

@@ -1089,7 +1089,7 @@ enum
SPR_G2_END = SPR_G2_SINGLE_RAIL_END,
SPR_CSG_BEGIN = SPR_G2_END,
SPR_CSG_END = SPR_CSG_BEGIN + RCT1_NUM_LL_CSG_ENTRIES,
SPR_CSG_END = SPR_CSG_BEGIN + RCT1::RCT1_NUM_LL_CSG_ENTRIES,
SPR_SCROLLING_TEXT_START = SPR_CSG_END,
SPR_SCROLLING_TEXT_END = SPR_SCROLLING_TEXT_START + OpenRCT2::MaxScrollingTextEntries,