1 /*****************************************************************************
2 * Copyright (c) 2014-2020 OpenRCT2 developers
3 *
4 * For a complete list of all authors, please refer to contributors.md
5 * Interested in contributing? Visit https://github.com/OpenRCT2/OpenRCT2
6 *
7 * OpenRCT2 is licensed under the GNU General Public License version 3.
8 *****************************************************************************/
9
10 #include "../../common.h"
11 #include "../../interface/Viewport.h"
12 #include "../../paint/Paint.h"
13 #include "../../paint/Supports.h"
14 #include "../Track.h"
15 #include "../TrackPaint.h"
16
17 enum
18 {
19 SPR_LIFT_CAGE_BACK = 14994,
20 SPR_LIFT_CAGE_FRONT = 14995,
21 SPR_LIFT_CAGE_NE_BACK = 14996,
22 SPR_LIFT_CAGE_NE_FRONT = 14997,
23 SPR_LIFT_CAGE_SE_BACK = 14998,
24 SPR_LIFT_CAGE_SE_FRONT = 14999,
25 SPR_LIFT_CAGE_SW_BACK = 15000,
26 SPR_LIFT_CAGE_SW_FRONT = 15001,
27 SPR_LIFT_CAGE_NW_BACK = 15002,
28 SPR_LIFT_CAGE_NW_FRONT = 15003,
29 };
30
31 static constexpr const uint32_t lift_cage_sprites[][2] = {
32 { SPR_LIFT_CAGE_BACK, SPR_LIFT_CAGE_FRONT }, { SPR_LIFT_CAGE_NE_BACK, SPR_LIFT_CAGE_NE_FRONT },
33 { SPR_LIFT_CAGE_SE_BACK, SPR_LIFT_CAGE_SE_FRONT }, { SPR_LIFT_CAGE_SW_BACK, SPR_LIFT_CAGE_SW_FRONT },
34 { SPR_LIFT_CAGE_NW_BACK, SPR_LIFT_CAGE_NW_FRONT },
35 };
36
paint_lift_cage(paint_session * session,int8_t index,uint32_t colourFlags,int32_t height,uint8_t rotation)37 static void paint_lift_cage(paint_session* session, int8_t index, uint32_t colourFlags, int32_t height, uint8_t rotation)
38 {
39 uint32_t imageId;
40
41 imageId = lift_cage_sprites[1 + index][0] | colourFlags;
42 PaintAddImageAsParent(session, imageId, { 0, 0, height }, { 2, 2, 30 }, { 2, 2, height });
43
44 imageId = lift_cage_sprites[1 + index][1] | colourFlags;
45 PaintAddImageAsParent(session, imageId, { 0, 0, height }, { 2, 2, 30 }, { 28, 28, height });
46 }
47
48 /** rct2: 0x0076C6CC */
paint_lift_base(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)49 static void paint_lift_base(
50 paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
51 const TrackElement& trackElement)
52 {
53 trackSequence = track_map_3x3[direction][trackSequence];
54
55 if (trackSequence == 0)
56 {
57 paint_lift_cage(session, direction, session->TrackColours[SCHEME_TRACK], height, session->CurrentRotation);
58
59 paint_lift_cage(session, -1, session->TrackColours[SCHEME_TRACK], height + 32, session->CurrentRotation);
60
61 paint_lift_cage(session, -1, session->TrackColours[SCHEME_TRACK], height + 64, session->CurrentRotation);
62
63 paint_util_set_vertical_tunnel(session, height + 96);
64 paint_util_set_segment_support_height(session, SEGMENTS_ALL, 0xFFFF, 0);
65
66 #ifdef __TESTPAINT__
67 paint_util_set_general_support_height(session, height + 32, 0x20);
68 #else
69 paint_util_set_general_support_height(session, height + 96, 0x20);
70 #endif
71
72 return;
73 }
74
75 int32_t edges = edges_3x3[trackSequence];
76
77 uint32_t imageId = SPR_FLOOR_METAL_B | session->TrackColours[SCHEME_SUPPORTS];
78 PaintAddImageAsParent(session, imageId, { 0, 0, height }, { 32, 32, 1 }, { 0, 0, height });
79
80 if (ride != nullptr)
81 {
82 track_paint_util_paint_fences(
83 session, edges, session->MapPosition, trackElement, ride, session->TrackColours[SCHEME_TRACK], height,
84 fenceSpritesMetalB, session->CurrentRotation);
85 }
86
87 int32_t blockedSegments = 0;
88 switch (trackSequence)
89 {
90 case 1:
91 blockedSegments = SEGMENT_B8 | SEGMENT_C8 | SEGMENT_B4 | SEGMENT_CC | SEGMENT_BC;
92 break;
93 case 2:
94 blockedSegments = SEGMENT_B4 | SEGMENT_CC | SEGMENT_BC;
95 break;
96 case 3:
97 blockedSegments = SEGMENT_B4 | SEGMENT_CC | SEGMENT_BC | SEGMENT_D4 | SEGMENT_C0;
98 break;
99 case 4:
100 blockedSegments = SEGMENT_B4 | SEGMENT_C8 | SEGMENT_B8;
101 break;
102 case 5:
103 blockedSegments = SEGMENT_BC | SEGMENT_D4 | SEGMENT_C0;
104 break;
105 case 6:
106 blockedSegments = SEGMENT_B4 | SEGMENT_C8 | SEGMENT_B8 | SEGMENT_D0 | SEGMENT_C0;
107 break;
108 case 7:
109 blockedSegments = SEGMENT_B8 | SEGMENT_D0 | SEGMENT_C0 | SEGMENT_D4 | SEGMENT_BC;
110 break;
111 case 8:
112 blockedSegments = SEGMENT_B8 | SEGMENT_D0 | SEGMENT_C0;
113 break;
114 }
115 paint_util_set_segment_support_height(session, blockedSegments, 0xFFFF, 0);
116 paint_util_set_segment_support_height(session, SEGMENTS_ALL & ~blockedSegments, height + 2, 0x20);
117 paint_util_set_general_support_height(session, height + 32, 0x20);
118 }
119
120 /** rct2: 0x0076C6DC */
paint_lift_tower_section(paint_session * session,const Ride * ride,uint8_t trackSequence,uint8_t direction,int32_t height,const TrackElement & trackElement)121 static void paint_lift_tower_section(
122 paint_session* session, const Ride* ride, uint8_t trackSequence, uint8_t direction, int32_t height,
123 const TrackElement& trackElement)
124 {
125 if (trackSequence == 1)
126 {
127 return;
128 }
129
130 paint_lift_cage(session, -1, session->TrackColours[SCHEME_TRACK], height, session->CurrentRotation);
131
132 paint_util_set_segment_support_height(session, SEGMENTS_ALL, 0xFFFF, 0);
133
134 paint_util_set_vertical_tunnel(session, height + 32);
135 paint_util_set_general_support_height(session, height + 32, 0x20);
136 }
137
138 /**
139 * rct2: 0x0076C5BC
140 */
get_track_paint_function_lift(int32_t trackType)141 TRACK_PAINT_FUNCTION get_track_paint_function_lift(int32_t trackType)
142 {
143 switch (trackType)
144 {
145 case TrackElemType::TowerBase:
146 return paint_lift_base;
147
148 case TrackElemType::TowerSection:
149 return paint_lift_tower_section;
150 }
151
152 return nullptr;
153 }
154