TrackAndDirection (#1017)

* Create new helper struct for trackdirection

* Split up into clear road or track

* Try name offsets where possible

* Update with knowledge from track branch
This commit is contained in:
Duncan 2021-08-17 07:15:40 +01:00 committed by GitHub
parent 6e74345b08
commit 055def4215
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 80 additions and 32 deletions

View File

@ -43,7 +43,7 @@ namespace OpenLoco::Vehicles
static loco_global<int32_t, 0x011360FC> _11360FC;
static loco_global<VehicleHead*, 0x01136240> _backupVeh0;
static loco_global<int16_t, 0x01136248> _backup2E;
static loco_global<int16_t, 0x0113624C> _backup2C;
static loco_global<TrackAndDirection, 0x0113624C> _backup2C;
static loco_global<int16_t, 0x01136250> _backupX;
static loco_global<int16_t, 0x01136254> _backupY;
static loco_global<uint8_t, 0x01136258> _backupZ;
@ -139,7 +139,7 @@ namespace OpenLoco::Vehicles
newBogie->tile_y = 0;
newBogie->tile_base_z = 0;
newBogie->var_2E = 0;
newBogie->var_2C = 0;
newBogie->var_2C = TrackAndDirection(0, 0);
newBogie->var_36 = lastVeh->getVar36();
newBogie->object_id = vehicleTypeId;
@ -258,7 +258,7 @@ namespace OpenLoco::Vehicles
newBody->tile_y = 0;
newBody->tile_base_z = 0;
newBody->var_2E = 0;
newBody->var_2C = 0;
newBody->var_2C = TrackAndDirection(0, 0);
newBody->var_36 = lastVeh->getVar36();
newBody->var_38 = Flags38::unk_0; // different to create bogie
newBody->object_id = vehicleTypeId;
@ -468,7 +468,7 @@ namespace OpenLoco::Vehicles
newHead->tile_base_z = 0;
newHead->var_28 = 0;
newHead->var_2E = 0;
newHead->var_2C = 0;
newHead->var_2C = TrackAndDirection(0, 0);
newHead->var_36 = orderId * max_num_routing_steps;
newHead->var_14 = 0;
newHead->var_09 = 0;
@ -506,7 +506,7 @@ namespace OpenLoco::Vehicles
newVeh1->tile_base_z = 0;
newVeh1->var_28 = 0;
newVeh1->var_2E = 0;
newVeh1->var_2C = 0;
newVeh1->var_2C = TrackAndDirection(0, 0);
newVeh1->var_36 = lastVeh->getVar36();
newVeh1->var_14 = 0;
newVeh1->var_09 = 0;
@ -537,7 +537,7 @@ namespace OpenLoco::Vehicles
newVeh2->tile_base_z = 0;
newVeh2->var_28 = 0;
newVeh2->var_2E = 0;
newVeh2->var_2C = 0;
newVeh2->var_2C = TrackAndDirection(0, 0);
newVeh2->var_36 = lastVeh->getVar36();
newVeh2->var_14 = 0;
newVeh2->var_09 = 0;
@ -574,7 +574,7 @@ namespace OpenLoco::Vehicles
newTail->tile_base_z = 0;
newTail->var_28 = 0;
newTail->var_2E = 0;
newTail->var_2C = 0;
newTail->var_2C = TrackAndDirection(0, 0);
newTail->var_36 = lastVeh->getVar36();
newTail->var_14 = 0;
newTail->var_09 = 0;
@ -640,7 +640,7 @@ namespace OpenLoco::Vehicles
}
// 0x004B05E4
static void placeDownVehicle(VehicleHead* const head, const coord_t x, const coord_t y, const uint8_t baseZ, const uint16_t unk1, const uint16_t unk2)
static void placeDownVehicle(VehicleHead* const head, const coord_t x, const coord_t y, const uint8_t baseZ, const TrackAndDirection unk1, const uint16_t unk2)
{
registers regs{};
regs.esi = X86Pointer(head);
@ -648,7 +648,7 @@ namespace OpenLoco::Vehicles
regs.cx = y;
regs.bx = unk2;
regs.dl = baseZ;
regs.ebp = unk1;
regs.ebp = unk1.track._data;
call(0x004B05E4, regs);
}

View File

@ -99,6 +99,54 @@ namespace OpenLoco::Vehicles
constexpr uint8_t cAirportMovementNodeNull = 0xFF;
#pragma pack(push, 1)
struct TrackAndDirection
{
struct _TrackAndDirection
{
uint16_t _data;
constexpr _TrackAndDirection(uint8_t id, uint8_t direction)
: _data((id << 3) | direction)
{
}
constexpr uint8_t id() const { return (_data >> 3) & 0x3F; }
constexpr uint8_t cardinalDirection() const { return _data & 0x3; }
constexpr bool isReversed() const { return _data & (1 << 2); }
constexpr bool operator==(const _TrackAndDirection other) const { return _data == other._data; }
constexpr bool operator!=(const _TrackAndDirection other) const { return !(_data == other._data); }
};
struct _RoadAndDirection
{
uint16_t _data;
constexpr _RoadAndDirection(uint8_t id, uint8_t direction)
: _data((id << 3) | direction)
{
}
constexpr uint8_t id() const { return (_data >> 3) & 0xF; }
constexpr uint8_t cardinalDirection() const { return _data & 0x3; }
// Used by road and tram vehicles to indicate side
constexpr bool isReversed() const { return _data & (1 << 2); }
// Road vehicles are briefly back to front when reaching dead ends
// Trams can stay back to front
constexpr bool isBackToFront() const { return _data & (1 << 7); }
// Related to road vehicles turning around
constexpr bool isUnk8() const { return _data & (1 << 8); }
constexpr bool operator==(const _RoadAndDirection other) const { return _data == other._data; }
constexpr bool operator!=(const _RoadAndDirection other) const { return !(_data == other._data); }
};
union
{
_TrackAndDirection track;
_RoadAndDirection road;
};
constexpr TrackAndDirection(uint8_t id, uint8_t direction)
: track(id, direction)
{
}
};
static_assert(sizeof(TrackAndDirection) == 2);
struct VehicleBase : EntityBase
{
private:
@ -205,7 +253,7 @@ namespace OpenLoco::Vehicles
uint8_t pad_24[0x26 - 0x24];
EntityId_t head; // 0x26
uint32_t var_28;
uint16_t var_2C;
TrackAndDirection var_2C;
uint16_t var_2E;
int16_t tile_x; // 0x30
int16_t tile_y; // 0x32
@ -348,7 +396,7 @@ namespace OpenLoco::Vehicles
uint8_t pad_24[0x26 - 0x24];
EntityId_t head; // 0x26
uint32_t var_28;
uint16_t var_2C;
TrackAndDirection var_2C;
uint16_t var_2E;
int16_t tile_x; // 0x30
int16_t tile_y; // 0x32
@ -380,7 +428,7 @@ namespace OpenLoco::Vehicles
uint8_t pad_24[0x26 - 0x24];
EntityId_t head; // 0x26
uint32_t var_28;
uint16_t var_2C;
TrackAndDirection var_2C;
uint16_t var_2E;
int16_t tile_x; // 0x30
int16_t tile_y; // 0x32
@ -426,7 +474,7 @@ namespace OpenLoco::Vehicles
ColourScheme colour_scheme; // 0x24
EntityId_t head; // 0x26
uint8_t pad_28[0x2C - 0x28];
uint16_t var_2C;
TrackAndDirection var_2C;
uint16_t var_2E;
int16_t tile_x; // 0x30
int16_t tile_y; // 0x32
@ -481,7 +529,7 @@ namespace OpenLoco::Vehicles
ColourScheme colour_scheme; // 0x24
EntityId_t head; // 0x26
uint8_t pad_28[0x2C - 0x28];
uint16_t var_2C;
TrackAndDirection var_2C;
uint16_t var_2E;
int16_t tile_x; // 0x30
int16_t tile_y; // 0x32
@ -524,7 +572,7 @@ namespace OpenLoco::Vehicles
uint8_t pad_24[0x26 - 0x24];
EntityId_t head; // 0x26
uint32_t var_28;
uint16_t var_2C;
TrackAndDirection var_2C;
uint16_t var_2E;
int16_t tile_x; // 0x30
int16_t tile_y; // 0x32

View File

@ -165,8 +165,8 @@ namespace OpenLoco::Vehicles
}
else
{
ah = vehicle_arr_4F865C[frontBogie->var_2C >> 2];
if (((frontBogie->var_2C >> 3) == 12) || ((frontBogie->var_2C >> 3) == 13))
ah = vehicle_arr_4F865C[frontBogie->var_2C.track._data >> 2];
if ((frontBogie->var_2C.track.id() == 12) || (frontBogie->var_2C.track.id() == 13))
{
if (frontBogie->var_2E >= 48)
{
@ -982,9 +982,9 @@ namespace OpenLoco::Vehicles
continue;
if (track->baseZ() != frontBogie->tile_base_z)
continue;
if (track->trackId() != ((frontBogie->var_2C >> 3) & 0x3F))
if (track->trackId() != frontBogie->var_2C.track.id())
continue;
if (track->unkDirection() != (frontBogie->var_2C & 0x3))
if (track->unkDirection() != frontBogie->var_2C.track.cardinalDirection())
continue;
if (!track->hasStationElement())
continue;
@ -1225,12 +1225,12 @@ namespace OpenLoco::Vehicles
auto yaw = (sprite_yaw + 16) & 0x3F;
auto firstBogie = var_38 & Flags38::isReversed ? backBogie : frontBogie;
auto unkFactor = 5;
if (!trackIdToSparkDirection[firstBogie->var_2C / 8])
if (!trackIdToSparkDirection[(firstBogie->var_2C.road._data >> 3)])
{
unkFactor = -5;
}
if (firstBogie->var_2C & (1 << 2))
if (firstBogie->var_2C.road.isReversed())
{
unkFactor = -unkFactor;
}

View File

@ -932,7 +932,7 @@ namespace OpenLoco::Vehicles
if (track_type == 0xFF || ObjectManager::get<RoadObject>(track_type)->flags & Flags12::isRoad)
{
if (train.veh1->var_2C & (1 << 7))
if (train.veh1->var_2C.road.isBackToFront())
{
param1 = 128;
turnaroundAtSignalTimeout = 544;
@ -942,7 +942,7 @@ namespace OpenLoco::Vehicles
{
// Tram
turnaroundAtSignalTimeout = tramSignalTimeout;
if (train.veh1->var_2C & (1 << 7))
if (train.veh1->var_2C.road.isBackToFront())
{
param1 = 64;
turnaroundAtSignalTimeout = 128;
@ -2526,8 +2526,8 @@ namespace OpenLoco::Vehicles
case TransportMode::rail:
{
auto tile = Map::TileManager::get(Pos2{ bogie->tile_x, bogie->tile_y });
auto direction = bogie->var_2C & 3;
auto trackId = (bogie->var_2C >> 3) & 0x3F;
auto direction = bogie->var_2C.track.cardinalDirection();
auto trackId = bogie->var_2C.track.id();
auto loadingModifier = 12;
auto* elStation = tile.trackStation(trackId, direction, bogie->tile_base_z);
if (elStation != nullptr)
@ -2545,8 +2545,8 @@ namespace OpenLoco::Vehicles
case TransportMode::road:
{
auto tile = Map::TileManager::get(Pos2{ bogie->tile_x, bogie->tile_y });
auto direction = bogie->var_2C & 3;
auto roadId = (bogie->var_2C >> 3) & 0xF;
auto direction = bogie->var_2C.road.cardinalDirection();
auto roadId = bogie->var_2C.road.id();
auto loadingModifier = 2;
auto* elStation = tile.roadStation(roadId, direction, bogie->tile_base_z);
if (elStation != nullptr)
@ -3204,8 +3204,8 @@ namespace OpenLoco::Vehicles
static StationId_t tryFindStationAt(VehicleBogie* bogie)
{
auto direction = bogie->var_2C & 3;
auto trackId = (bogie->var_2C >> 3) & 0x3F;
auto direction = bogie->var_2C.track.cardinalDirection();
auto trackId = bogie->var_2C.track.id();
auto tile = TileManager::get(Map::Pos2{ bogie->tile_x, bogie->tile_y });
auto* elStation = tile.trackStation(trackId, direction, bogie->tile_base_z);
@ -3332,7 +3332,7 @@ namespace OpenLoco::Vehicles
if (elRoad->isGhost() || elRoad->isFlag5())
continue;
if (elRoad->roadId() != ((veh->var_2C >> 3) & 0xF))
if (elRoad->roadId() != veh->var_2C.road.id())
continue;
return true;
@ -3354,10 +3354,10 @@ namespace OpenLoco::Vehicles
if (elTrack->isGhost() || elTrack->isFlag5())
continue;
if (elTrack->unkDirection() != (veh->var_2C & 0x3))
if (elTrack->unkDirection() != veh->var_2C.track.cardinalDirection())
continue;
if (elTrack->trackId() != ((veh->var_2C >> 3) & 0x3F))
if (elTrack->trackId() != veh->var_2C.track.id())
continue;
return true;