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