0x004B0CFC
| 83 | |
| 84 | // 0x004B0CFC |
| 85 | static void paintBogie(PaintSession& session, VehicleBogie* bogie) |
| 86 | { |
| 87 | auto* vehObject = ObjectManager::get<VehicleObject>(bogie->objectId); |
| 88 | if (bogie->objectSpriteType == SpriteIndex::null) |
| 89 | { |
| 90 | return; |
| 91 | } |
| 92 | |
| 93 | auto& sprite = vehObject->bogieSprites[bogie->objectSpriteType]; |
| 94 | uint8_t yaw = (bogie->spriteYaw + (session.getRotation() << 4)) & 0x3F; |
| 95 | auto pitch = bogie->spritePitch; |
| 96 | |
| 97 | if (bogie->has38Flags(Flags38::isReversed)) |
| 98 | { |
| 99 | // Flip the highest bit to reverse the yaw |
| 100 | yaw ^= (1 << 5); |
| 101 | pitch = kReversePitch[static_cast<uint8_t>(bogie->spritePitch)]; |
| 102 | } |
| 103 | auto yawIndex = (yaw >> 1) & 0x1F; |
| 104 | |
| 105 | switch (pitch) |
| 106 | { |
| 107 | case Pitch::flat: |
| 108 | case Pitch::up12deg: |
| 109 | case Pitch::up10deg: |
| 110 | case Pitch::up25deg: |
| 111 | case Pitch::up20deg: |
| 112 | break; |
| 113 | default: |
| 114 | if (sprite.hasFlags(BogieSpriteFlags::rotationalSymmetry)) |
| 115 | { |
| 116 | // Rotational symmetry will have 1 fewer bits of yaw |
| 117 | yawIndex ^= (1 << 4); |
| 118 | } |
| 119 | else |
| 120 | { |
| 121 | yawIndex ^= (1 << 5); |
| 122 | } |
| 123 | break; |
| 124 | } |
| 125 | switch (pitch) |
| 126 | { |
| 127 | case Pitch::flat: |
| 128 | { |
| 129 | if (sprite.hasFlags(BogieSpriteFlags::rotationalSymmetry)) |
| 130 | { |
| 131 | yawIndex &= 0xF; |
| 132 | } |
| 133 | const auto imageIndex = sprite.numFramesPerRotation * yawIndex + bogie->animationIndex + sprite.flatImageIds; |
| 134 | ImageId imageId{}; |
| 135 | if (bogie->has38Flags(Flags38::isGhost)) |
| 136 | { |
| 137 | session.setItemType(Ui::ViewportInteraction::InteractionItem::noInteraction); |
| 138 | imageId = Gfx::applyGhostToImage(imageIndex); |
| 139 | } |
| 140 | else if (bogie->hasVehicleFlags(VehicleFlags::unk_5)) |
| 141 | { |
| 142 | imageId = ImageId(imageIndex, ExtColour::unk74); |
no test coverage detected