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 "Drawing.h"
11
12 #include "../Context.h"
13 #include "../OpenRCT2.h"
14 #include "../common.h"
15 #include "../core/Guard.hpp"
16 #include "../object/Object.h"
17 #include "../platform/platform.h"
18 #include "../sprites.h"
19 #include "../util/Util.h"
20 #include "../world/Location.hpp"
21 #include "../world/Water.h"
22
23 #include <cstring>
24
GetDefault()25 const PaletteMap& PaletteMap::GetDefault()
26 {
27 static bool initialised = false;
28 static uint8_t data[256];
29 static PaletteMap defaultMap(data);
30 if (!initialised)
31 {
32 for (size_t i = 0; i < sizeof(data); i++)
33 {
34 data[i] = static_cast<uint8_t>(i);
35 }
36 }
37 return defaultMap;
38 }
39
operator [](size_t index)40 uint8_t& PaletteMap::operator[](size_t index)
41 {
42 assert(index < _dataLength);
43
44 // Provide safety in release builds
45 if (index >= _dataLength)
46 {
47 static uint8_t dummy;
48 return dummy;
49 }
50
51 return _data[index];
52 }
53
operator [](size_t index) const54 uint8_t PaletteMap::operator[](size_t index) const
55 {
56 assert(index < _dataLength);
57
58 // Provide safety in release builds
59 if (index >= _dataLength)
60 {
61 return 0;
62 }
63
64 return _data[index];
65 }
66
Blend(uint8_t src,uint8_t dst) const67 uint8_t PaletteMap::Blend(uint8_t src, uint8_t dst) const
68 {
69 // src = 0 would be transparent so there is no blend palette for that, hence (src - 1)
70 assert(src != 0 && (src - 1) < _numMaps);
71 assert(dst < _mapLength);
72 auto idx = ((src - 1) * 256) + dst;
73 return (*this)[idx];
74 }
75
Copy(size_t dstIndex,const PaletteMap & src,size_t srcIndex,size_t length)76 void PaletteMap::Copy(size_t dstIndex, const PaletteMap& src, size_t srcIndex, size_t length)
77 {
78 auto maxLength = std::min(_mapLength - srcIndex, _mapLength - dstIndex);
79 assert(length <= maxLength);
80 auto copyLength = std::min(length, maxLength);
81 std::memcpy(&_data[dstIndex], &src._data[srcIndex], copyLength);
82 }
83
84 uint8_t gGamePalette[256 * 4];
85 uint32_t gPaletteEffectFrame;
86
87 uint32_t gPickupPeepImage;
88 int32_t gPickupPeepX;
89 int32_t gPickupPeepY;
90
91 /**
92 * 12 elements from 0xF3 are the peep top colour, 12 elements from 0xCA are peep trouser colour
93 *
94 * rct2: 0x0009ABE0C
95 */
96 // clang-format off
97 thread_local uint8_t gPeepPalette[256] = {
98 0x00, 0xF3, 0xF4, 0xF5, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
99 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
100 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
101 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
102 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
103 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
104 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
105 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
106 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
107 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
108 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
109 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
110 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
111 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
112 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
113 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
114 };
115
116 /** rct2: 0x009ABF0C */
117 thread_local uint8_t gOtherPalette[256] = {
118 0x00, 0xF3, 0xF4, 0xF5, 0x04, 0x05, 0x06, 0x07, 0x08, 0x09, 0x0A, 0x0B, 0x0C, 0x0D, 0x0E, 0x0F,
119 0x10, 0x11, 0x12, 0x13, 0x14, 0x15, 0x16, 0x17, 0x18, 0x19, 0x1A, 0x1B, 0x1C, 0x1D, 0x1E, 0x1F,
120 0x20, 0x21, 0x22, 0x23, 0x24, 0x25, 0x26, 0x27, 0x28, 0x29, 0x2A, 0x2B, 0x2C, 0x2D, 0x2E, 0x2F,
121 0x30, 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x3A, 0x3B, 0x3C, 0x3D, 0x3E, 0x3F,
122 0x40, 0x41, 0x42, 0x43, 0x44, 0x45, 0x46, 0x47, 0x48, 0x49, 0x4A, 0x4B, 0x4C, 0x4D, 0x4E, 0x4F,
123 0x50, 0x51, 0x52, 0x53, 0x54, 0x55, 0x56, 0x57, 0x58, 0x59, 0x5A, 0x5B, 0x5C, 0x5D, 0x5E, 0x5F,
124 0x60, 0x61, 0x62, 0x63, 0x64, 0x65, 0x66, 0x67, 0x68, 0x69, 0x6A, 0x6B, 0x6C, 0x6D, 0x6E, 0x6F,
125 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77, 0x78, 0x79, 0x7A, 0x7B, 0x7C, 0x7D, 0x7E, 0x7F,
126 0x80, 0x81, 0x82, 0x83, 0x84, 0x85, 0x86, 0x87, 0x88, 0x89, 0x8A, 0x8B, 0x8C, 0x8D, 0x8E, 0x8F,
127 0x90, 0x91, 0x92, 0x93, 0x94, 0x95, 0x96, 0x97, 0x98, 0x99, 0x9A, 0x9B, 0x9C, 0x9D, 0x9E, 0x9F,
128 0xA0, 0xA1, 0xA2, 0xA3, 0xA4, 0xA5, 0xA6, 0xA7, 0xA8, 0xA9, 0xAA, 0xAB, 0xAC, 0xAD, 0xAE, 0xAF,
129 0xB0, 0xB1, 0xB2, 0xB3, 0xB4, 0xB5, 0xB6, 0xB7, 0xB8, 0xB9, 0xBA, 0xBB, 0xBC, 0xBD, 0xBE, 0xBF,
130 0xC0, 0xC1, 0xC2, 0xC3, 0xC4, 0xC5, 0xC6, 0xC7, 0xC8, 0xC9, 0xCA, 0xCB, 0xCC, 0xCD, 0xCE, 0xCF,
131 0xD0, 0xD1, 0xD2, 0xD3, 0xD4, 0xD5, 0xD6, 0xD7, 0xD8, 0xD9, 0xDA, 0xDB, 0xDC, 0xDD, 0xDE, 0xDF,
132 0xE0, 0xE1, 0xE2, 0xE3, 0xE4, 0xE5, 0xE6, 0xE7, 0xE8, 0xE9, 0xEA, 0xEB, 0xEC, 0xED, 0xEE, 0xEF,
133 0xF0, 0xF1, 0xF2, 0xF3, 0xF4, 0xF5, 0xF6, 0xF7, 0xF8, 0xF9, 0xFA, 0xFB, 0xFC, 0xFD, 0xFE, 0xFF,
134 };
135
136 // Originally 0x9ABE04
137 uint8_t text_palette[0x8] = {
138 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
139 };
140
141 enum
142 {
143 SPR_PALETTE_3100 = 3100,
144 SPR_PALETTE_3101 = 3101,
145 SPR_PALETTE_3102 = 3102,
146 SPR_PALETTE_3103 = 3103,
147 SPR_PALETTE_3104 = 3104,
148 SPR_PALETTE_3105 = 3105,
149 SPR_PALETTE_3106 = 3106,
150 SPR_PALETTE_3107 = 3107,
151 SPR_PALETTE_3108 = 3108,
152 SPR_PALETTE_3109 = 3109,
153 SPR_PALETTE_3110 = 3110,
154
155 SPR_PALETTE_BLACK = 4915,
156 SPR_PALETTE_GREY = 4916,
157 SPR_PALETTE_WHITE = 4917,
158 SPR_PALETTE_DARK_PURPLE = 4918,
159 SPR_PALETTE_LIGHT_PURPLE = 4919,
160 SPR_PALETTE_BRIGHT_PURPLE = 4920,
161 SPR_PALETTE_DARK_BLUE = 4921,
162 SPR_PALETTE_LIGHT_BLUE = 4922,
163 SPR_PALETTE_ICY_BLUE = 4923,
164 SPR_PALETTE_TEAL = 4924,
165 SPR_PALETTE_AQUAMARINE = 4925,
166 SPR_PALETTE_SATURATED_GREEN = 4926,
167 SPR_PALETTE_DARK_GREEN = 4927,
168 SPR_PALETTE_MOSS_GREEN = 4928,
169 SPR_PALETTE_BRIGHT_GREEN = 4929,
170 SPR_PALETTE_OLIVE_GREEN = 4930,
171 SPR_PALETTE_DARK_OLIVE_GREEN = 4931,
172 SPR_PALETTE_BRIGHT_YELLOW = 4932,
173 SPR_PALETTE_YELLOW = 4933,
174 SPR_PALETTE_DARK_YELLOW = 4934,
175 SPR_PALETTE_LIGHT_ORANGE = 4935,
176 SPR_PALETTE_DARK_ORANGE = 4936,
177 SPR_PALETTE_LIGHT_BROWN = 4937,
178 SPR_PALETTE_SATURATED_BROWN = 4938,
179 SPR_PALETTE_DARK_BROWN = 4939,
180 SPR_PALETTE_SALMON_PINK = 4940,
181 SPR_PALETTE_BORDEAUX_RED = 4941,
182 SPR_PALETTE_SATURATED_RED = 4942,
183 SPR_PALETTE_BRIGHT_RED = 4943,
184 SPR_PALETTE_DARK_PINK = 4944,
185 SPR_PALETTE_BRIGHT_PINK = 4945,
186 SPR_PALETTE_LIGHT_PINK = 4946,
187 SPR_PALETTE_WATER = 4947,
188 SPR_PALETTE_4948 = 4948,
189 SPR_PALETTE_4949 = 4949,
190 SPR_PALETTE_4950 = 4950,
191 SPR_PALETTE_DARKEN_3 = 4951,
192 SPR_PALETTE_4952 = 4952,
193 SPR_PALETTE_DARKEN_1 = 4953,
194 SPR_PALETTE_DARKEN_2 = 4954,
195 SPR_PALETTE_4955 = 4955,
196 SPR_PALETTE_TRANSLUCENT_GREY = 4956,
197 SPR_PALETTE_TRANSLUCENT_GREY_HIGHLIGHT = 4957,
198 SPR_PALETTE_TRANSLUCENT_GREY_SHADOW = 4958,
199 SPR_PALETTE_TRANSLUCENT_LIGHT_BLUE = 4959,
200 SPR_PALETTE_TRANSLUCENT_LIGHT_BLUE_HIGHLIGHT = 4960,
201 SPR_PALETTE_TRANSLUCENT_LIGHT_BLUE_SHADOW = 4961,
202 SPR_PALETTE_TRANSLUCENT_BORDEAUX_RED = 4962,
203 SPR_PALETTE_TRANSLUCENT_BORDEAUX_RED_HIGHLIGHT = 4963,
204 SPR_PALETTE_TRANSLUCENT_BORDEAUX_RED_SHADOW = 4964,
205 SPR_PALETTE_TRANSLUCENT_DARK_GREEN = 4965,
206 SPR_PALETTE_TRANSLUCENT_DARK_GREEN_HIGHLIGHT = 4966,
207 SPR_PALETTE_TRANSLUCENT_DARK_GREEN_SHADOW = 4967,
208 SPR_PALETTE_TRANSLUCENT_LIGHT_PURPLE = 4968,
209 SPR_PALETTE_TRANSLUCENT_LIGHT_PURPLE_HIGHLIGHT = 4969,
210 SPR_PALETTE_TRANSLUCENT_LIGHT_PURPLE_SHADOW = 4970,
211 SPR_PALETTE_TRANSLUCENT_DARK_OLIVE_GREEN = 4971,
212 SPR_PALETTE_TRANSLUCENT_DARK_OLIVE_GREEN_HIGHLIGHT = 4972,
213 SPR_PALETTE_TRANSLUCENT_DARK_OLIVE_GREEN_SHADOW = 4973,
214 SPR_PALETTE_TRANSLUCENT_LIGHT_BROWN = 4974,
215 SPR_PALETTE_TRANSLUCENT_LIGHT_BROWN_HIGHLIGHT = 4975,
216 SPR_PALETTE_TRANSLUCENT_LIGHT_BROWN_SHADOW = 4976,
217 SPR_PALETTE_TRANSLUCENT_YELLOW = 4977,
218 SPR_PALETTE_TRANSLUCENT_YELLOW_HIGHLIGHT = 4978,
219 SPR_PALETTE_TRANSLUCENT_YELLOW_SHADOW = 4979,
220 SPR_PALETTE_TRANSLUCENT_MOSS_GREEN = 4980,
221 SPR_PALETTE_TRANSLUCENT_MOSS_GREEN_HIGHLIGHT = 4981,
222 SPR_PALETTE_TRANSLUCENT_MOSS_GREEN_SHADOW = 4982,
223 SPR_PALETTE_TRANSLUCENT_OLIVE_GREEN = 4983,
224 SPR_PALETTE_TRANSLUCENT_OLIVE_GREEN_HIGHLIGHT = 4984,
225 SPR_PALETTE_TRANSLUCENT_OLIVE_GREEN_SHADOW = 4985,
226 SPR_PALETTE_TRANSLUCENT_BRIGHT_GREEN = 4986,
227 SPR_PALETTE_TRANSLUCENT_BRIGHT_GREEN_HIGHLIGHT = 4987,
228 SPR_PALETTE_TRANSLUCENT_BRIGHT_GREEN_SHADOW = 4988,
229 SPR_PALETTE_TRANSLUCENT_SALMON_PINK = 4989,
230 SPR_PALETTE_TRANSLUCENT_SALMON_PINK_HIGHLIGHT = 4990,
231 SPR_PALETTE_TRANSLUCENT_SALMON_PINK_SHADOW = 4991,
232 SPR_PALETTE_TRANSLUCENT_BRIGHT_PURPLE = 4992,
233 SPR_PALETTE_TRANSLUCENT_BRIGHT_PURPLE_HIGHLIGHT = 4993,
234 SPR_PALETTE_TRANSLUCENT_BRIGHT_PURPLE_SHADOW = 4994,
235 SPR_PALETTE_TRANSLUCENT_BRIGHT_RED = 4995,
236 SPR_PALETTE_TRANSLUCENT_BRIGHT_RED_HIGHLIGHT = 4996,
237 SPR_PALETTE_TRANSLUCENT_BRIGHT_RED_SHADOW = 4997,
238 SPR_PALETTE_TRANSLUCENT_LIGHT_ORANGE = 4998,
239 SPR_PALETTE_TRANSLUCENT_LIGHT_ORANGE_HIGHLIGHT = 4999,
240 SPR_PALETTE_TRANSLUCENT_LIGHT_ORANGE_SHADOW = 5000,
241 SPR_PALETTE_TRANSLUCENT_TEAL = 5001,
242 SPR_PALETTE_TRANSLUCENT_TEAL_HIGHLIGHT = 5002,
243 SPR_PALETTE_TRANSLUCENT_TEAL_SHADOW = 5003,
244 SPR_PALETTE_TRANSLUCENT_BRIGHT_PINK = 5004,
245 SPR_PALETTE_TRANSLUCENT_BRIGHT_PINK_HIGHLIGHT = 5005,
246 SPR_PALETTE_TRANSLUCENT_BRIGHT_PINK_SHADOW = 5006,
247 SPR_PALETTE_TRANSLUCENT_DARK_BROWN = 5007,
248 SPR_PALETTE_TRANSLUCENT_DARK_BROWN_HIGHLIGHT = 5008,
249 SPR_PALETTE_TRANSLUCENT_DARK_BROWN_SHADOW = 5009,
250 SPR_PALETTE_TRANSLUCENT_LIGHT_PINK = 5010,
251 SPR_PALETTE_TRANSLUCENT_LIGHT_PINK_HIGHLIGHT = 5011,
252 SPR_PALETTE_TRANSLUCENT_LIGHT_PINK_SHADOW = 5012,
253 SPR_PALETTE_TRANSLUCENT_WHITE = 5013,
254 SPR_PALETTE_TRANSLUCENT_WHITE_HIGHLIGHT = 5014,
255 SPR_PALETTE_TRANSLUCENT_WHITE_SHADOW = 5015,
256 SPR_PALETTE_GLASS_BLACK = 5016,
257 SPR_PALETTE_GLASS_GREY = 5017,
258 SPR_PALETTE_GLASS_WHITE = 5018,
259 SPR_PALETTE_GLASS_DARK_PURPLE = 5019,
260 SPR_PALETTE_GLASS_LIGHT_PURPLE = 5020,
261 SPR_PALETTE_GLASS_BRIGHT_PURPLE = 5021,
262 SPR_PALETTE_GLASS_DARK_BLUE = 5022,
263 SPR_PALETTE_GLASS_LIGHT_BLUE = 5023,
264 SPR_PALETTE_GLASS_ICY_BLUE = 5024,
265 SPR_PALETTE_GLASS_TEAL = 5025,
266 SPR_PALETTE_GLASS_AQUAMARINE = 5026,
267 SPR_PALETTE_GLASS_SATURATED_GREEN = 5027,
268 SPR_PALETTE_GLASS_DARK_GREEN = 5028,
269 SPR_PALETTE_GLASS_MOSS_GREEN = 5029,
270 SPR_PALETTE_GLASS_BRIGHT_GREEN = 5030,
271 SPR_PALETTE_GLASS_OLIVE_GREEN = 5031,
272 SPR_PALETTE_GLASS_DARK_OLIVE_GREEN = 5032,
273 SPR_PALETTE_GLASS_BRIGHT_YELLOW = 5033,
274 SPR_PALETTE_GLASS_YELLOW = 5034,
275 SPR_PALETTE_GLASS_DARK_YELLOW = 5035,
276 SPR_PALETTE_GLASS_LIGHT_ORANGE = 5036,
277 SPR_PALETTE_GLASS_DARK_ORANGE = 5037,
278 SPR_PALETTE_GLASS_LIGHT_BROWN = 5038,
279 SPR_PALETTE_GLASS_SATURATED_BROWN = 5039,
280 SPR_PALETTE_GLASS_DARK_BROWN = 5040,
281 SPR_PALETTE_GLASS_SALMON_PINK = 5041,
282 SPR_PALETTE_GLASS_BORDEAUX_RED = 5042,
283 SPR_PALETTE_GLASS_SATURATED_RED = 5043,
284 SPR_PALETTE_GLASS_BRIGHT_RED = 5044,
285 SPR_PALETTE_GLASS_DARK_PINK = 5045,
286 SPR_PALETTE_GLASS_BRIGHT_PINK = 5046,
287 SPR_PALETTE_GLASS_LIGHT_PINK = 5047,
288 };
289
290 const FilterPaletteID GlassPaletteIds[COLOUR_COUNT] = {
291 FilterPaletteID::PaletteGlassBlack,
292 FilterPaletteID::PaletteGlassGrey,
293 FilterPaletteID::PaletteGlassWhite,
294 FilterPaletteID::PaletteGlassDarkPurple,
295 FilterPaletteID::PaletteGlassLightPurple,
296 FilterPaletteID::PaletteGlassBrightPurple,
297 FilterPaletteID::PaletteGlassDarkBlue,
298 FilterPaletteID::PaletteGlassLightBlue,
299 FilterPaletteID::PaletteGlassIcyBlue,
300 FilterPaletteID::PaletteGlassTeal,
301 FilterPaletteID::PaletteGlassAquamarine,
302 FilterPaletteID::PaletteGlassSaturatedGreen,
303 FilterPaletteID::PaletteGlassDarkGreen,
304 FilterPaletteID::PaletteGlassMossGreen,
305 FilterPaletteID::PaletteGlassBrightGreen,
306 FilterPaletteID::PaletteGlassOliveGreen,
307 FilterPaletteID::PaletteGlassDarkOliveGreen,
308 FilterPaletteID::PaletteGlassBrightYellow,
309 FilterPaletteID::PaletteGlassYellow,
310 FilterPaletteID::PaletteGlassDarkYellow,
311 FilterPaletteID::PaletteGlassLightOrange,
312 FilterPaletteID::PaletteGlassDarkOrange,
313 FilterPaletteID::PaletteGlassLightBrown,
314 FilterPaletteID::PaletteGlassSaturatedBrown,
315 FilterPaletteID::PaletteGlassDarkBrown,
316 FilterPaletteID::PaletteGlassSalmonPink,
317 FilterPaletteID::PaletteGlassBordeauxRed,
318 FilterPaletteID::PaletteGlassSaturatedRed,
319 FilterPaletteID::PaletteGlassBrightRed,
320 FilterPaletteID::PaletteGlassDarkPink,
321 FilterPaletteID::PaletteGlassBrightPink,
322 FilterPaletteID::PaletteGlassLightPink,
323 };
324
325 // Previously 0x97FCBC use it to get the correct palette from g1_elements
326 static const uint16_t palette_to_g1_offset[PALETTE_TO_G1_OFFSET_COUNT] = {
327 SPR_PALETTE_BLACK,
328 SPR_PALETTE_GREY,
329 SPR_PALETTE_WHITE,
330 SPR_PALETTE_DARK_PURPLE,
331 SPR_PALETTE_LIGHT_PURPLE,
332 SPR_PALETTE_BRIGHT_PURPLE,
333 SPR_PALETTE_DARK_BLUE,
334 SPR_PALETTE_LIGHT_BLUE,
335 SPR_PALETTE_ICY_BLUE,
336 SPR_PALETTE_TEAL,
337 SPR_PALETTE_AQUAMARINE,
338 SPR_PALETTE_SATURATED_GREEN,
339 SPR_PALETTE_DARK_GREEN,
340 SPR_PALETTE_MOSS_GREEN,
341 SPR_PALETTE_BRIGHT_GREEN,
342 SPR_PALETTE_OLIVE_GREEN,
343 SPR_PALETTE_DARK_OLIVE_GREEN,
344 SPR_PALETTE_BRIGHT_YELLOW,
345 SPR_PALETTE_YELLOW,
346 SPR_PALETTE_DARK_YELLOW,
347 SPR_PALETTE_LIGHT_ORANGE,
348 SPR_PALETTE_DARK_ORANGE,
349 SPR_PALETTE_LIGHT_BROWN,
350 SPR_PALETTE_SATURATED_BROWN,
351 SPR_PALETTE_DARK_BROWN,
352 SPR_PALETTE_SALMON_PINK,
353 SPR_PALETTE_BORDEAUX_RED,
354 SPR_PALETTE_SATURATED_RED,
355 SPR_PALETTE_BRIGHT_RED,
356 SPR_PALETTE_DARK_PINK,
357 SPR_PALETTE_BRIGHT_PINK,
358 SPR_PALETTE_LIGHT_PINK,
359
360
361 SPR_PALETTE_WATER, // PaletteWater (water)
362 SPR_PALETTE_3100,
363 SPR_PALETTE_3101, // Palette34
364 SPR_PALETTE_3102,
365 SPR_PALETTE_3103,
366 SPR_PALETTE_3104,
367 SPR_PALETTE_3106,
368 SPR_PALETTE_3107,
369 SPR_PALETTE_3108, // 40
370 SPR_PALETTE_3109,
371 SPR_PALETTE_3110,
372 SPR_PALETTE_3105,
373 SPR_PALETTE_4948,
374 SPR_PALETTE_4949, // Palette45
375 SPR_PALETTE_4950,
376 SPR_PALETTE_DARKEN_3, // PaletteDarken3
377 SPR_PALETTE_4952, // Decreases contrast
378 SPR_PALETTE_DARKEN_1, // PaletteDarken1
379 SPR_PALETTE_DARKEN_2, // PaletteDarken2 (construction marker)
380 SPR_PALETTE_4955, // Palette51
381
382 SPR_PALETTE_TRANSLUCENT_GREY,
383 SPR_PALETTE_TRANSLUCENT_GREY_HIGHLIGHT,
384 SPR_PALETTE_TRANSLUCENT_GREY_SHADOW,
385 SPR_PALETTE_TRANSLUCENT_LIGHT_BLUE,
386 SPR_PALETTE_TRANSLUCENT_LIGHT_BLUE_HIGHLIGHT,
387 SPR_PALETTE_TRANSLUCENT_LIGHT_BLUE_SHADOW,
388 SPR_PALETTE_TRANSLUCENT_BORDEAUX_RED,
389 SPR_PALETTE_TRANSLUCENT_BORDEAUX_RED_HIGHLIGHT,
390 SPR_PALETTE_TRANSLUCENT_BORDEAUX_RED_SHADOW,
391 SPR_PALETTE_TRANSLUCENT_DARK_GREEN,
392 SPR_PALETTE_TRANSLUCENT_DARK_GREEN_HIGHLIGHT,
393 SPR_PALETTE_TRANSLUCENT_DARK_GREEN_SHADOW,
394 SPR_PALETTE_TRANSLUCENT_LIGHT_PURPLE,
395 SPR_PALETTE_TRANSLUCENT_LIGHT_PURPLE_HIGHLIGHT,
396 SPR_PALETTE_TRANSLUCENT_LIGHT_PURPLE_SHADOW,
397 SPR_PALETTE_TRANSLUCENT_DARK_OLIVE_GREEN,
398 SPR_PALETTE_TRANSLUCENT_DARK_OLIVE_GREEN_HIGHLIGHT,
399 SPR_PALETTE_TRANSLUCENT_DARK_OLIVE_GREEN_SHADOW,
400 SPR_PALETTE_TRANSLUCENT_LIGHT_BROWN,
401 SPR_PALETTE_TRANSLUCENT_LIGHT_BROWN_HIGHLIGHT,
402 SPR_PALETTE_TRANSLUCENT_LIGHT_BROWN_SHADOW,
403 SPR_PALETTE_TRANSLUCENT_YELLOW,
404 SPR_PALETTE_TRANSLUCENT_YELLOW_HIGHLIGHT,
405 SPR_PALETTE_TRANSLUCENT_YELLOW_SHADOW,
406 SPR_PALETTE_TRANSLUCENT_MOSS_GREEN,
407 SPR_PALETTE_TRANSLUCENT_MOSS_GREEN_HIGHLIGHT,
408 SPR_PALETTE_TRANSLUCENT_MOSS_GREEN_SHADOW,
409 SPR_PALETTE_TRANSLUCENT_OLIVE_GREEN,
410 SPR_PALETTE_TRANSLUCENT_OLIVE_GREEN_HIGHLIGHT,
411 SPR_PALETTE_TRANSLUCENT_OLIVE_GREEN_SHADOW,
412 SPR_PALETTE_TRANSLUCENT_BRIGHT_GREEN,
413 SPR_PALETTE_TRANSLUCENT_BRIGHT_GREEN_HIGHLIGHT,
414 SPR_PALETTE_TRANSLUCENT_BRIGHT_GREEN_SHADOW,
415 SPR_PALETTE_TRANSLUCENT_SALMON_PINK,
416 SPR_PALETTE_TRANSLUCENT_SALMON_PINK_HIGHLIGHT,
417 SPR_PALETTE_TRANSLUCENT_SALMON_PINK_SHADOW,
418 SPR_PALETTE_TRANSLUCENT_BRIGHT_PURPLE,
419 SPR_PALETTE_TRANSLUCENT_BRIGHT_PURPLE_HIGHLIGHT,
420 SPR_PALETTE_TRANSLUCENT_BRIGHT_PURPLE_SHADOW,
421 SPR_PALETTE_TRANSLUCENT_BRIGHT_RED,
422 SPR_PALETTE_TRANSLUCENT_BRIGHT_RED_HIGHLIGHT,
423 SPR_PALETTE_TRANSLUCENT_BRIGHT_RED_SHADOW,
424 SPR_PALETTE_TRANSLUCENT_LIGHT_ORANGE,
425 SPR_PALETTE_TRANSLUCENT_LIGHT_ORANGE_HIGHLIGHT,
426 SPR_PALETTE_TRANSLUCENT_LIGHT_ORANGE_SHADOW,
427 SPR_PALETTE_TRANSLUCENT_TEAL,
428 SPR_PALETTE_TRANSLUCENT_TEAL_HIGHLIGHT,
429 SPR_PALETTE_TRANSLUCENT_TEAL_SHADOW,
430 SPR_PALETTE_TRANSLUCENT_BRIGHT_PINK,
431 SPR_PALETTE_TRANSLUCENT_BRIGHT_PINK_HIGHLIGHT,
432 SPR_PALETTE_TRANSLUCENT_BRIGHT_PINK_SHADOW,
433 SPR_PALETTE_TRANSLUCENT_DARK_BROWN,
434 SPR_PALETTE_TRANSLUCENT_DARK_BROWN_HIGHLIGHT,
435 SPR_PALETTE_TRANSLUCENT_DARK_BROWN_SHADOW,
436 SPR_PALETTE_TRANSLUCENT_LIGHT_PINK,
437 SPR_PALETTE_TRANSLUCENT_LIGHT_PINK_HIGHLIGHT,
438 SPR_PALETTE_TRANSLUCENT_LIGHT_PINK_SHADOW,
439 SPR_PALETTE_TRANSLUCENT_WHITE,
440 SPR_PALETTE_TRANSLUCENT_WHITE_HIGHLIGHT,
441 SPR_PALETTE_TRANSLUCENT_WHITE_SHADOW,
442
443 SPR_PALETTE_GLASS_BLACK,
444 SPR_PALETTE_GLASS_GREY,
445 SPR_PALETTE_GLASS_WHITE,
446 SPR_PALETTE_GLASS_DARK_PURPLE,
447 SPR_PALETTE_GLASS_LIGHT_PURPLE,
448 SPR_PALETTE_GLASS_BRIGHT_PURPLE,
449 SPR_PALETTE_GLASS_DARK_BLUE,
450 SPR_PALETTE_GLASS_LIGHT_BLUE,
451 SPR_PALETTE_GLASS_ICY_BLUE,
452 SPR_PALETTE_GLASS_TEAL,
453 SPR_PALETTE_GLASS_AQUAMARINE,
454 SPR_PALETTE_GLASS_SATURATED_GREEN,
455 SPR_PALETTE_GLASS_DARK_GREEN,
456 SPR_PALETTE_GLASS_MOSS_GREEN,
457 SPR_PALETTE_GLASS_BRIGHT_GREEN,
458 SPR_PALETTE_GLASS_OLIVE_GREEN,
459 SPR_PALETTE_GLASS_DARK_OLIVE_GREEN,
460 SPR_PALETTE_GLASS_BRIGHT_YELLOW,
461 SPR_PALETTE_GLASS_YELLOW,
462 SPR_PALETTE_GLASS_DARK_YELLOW,
463 SPR_PALETTE_GLASS_LIGHT_ORANGE,
464 SPR_PALETTE_GLASS_DARK_ORANGE,
465 SPR_PALETTE_GLASS_LIGHT_BROWN,
466 SPR_PALETTE_GLASS_SATURATED_BROWN,
467 SPR_PALETTE_GLASS_DARK_BROWN,
468 SPR_PALETTE_GLASS_SALMON_PINK,
469 SPR_PALETTE_GLASS_BORDEAUX_RED,
470 SPR_PALETTE_GLASS_SATURATED_RED,
471 SPR_PALETTE_GLASS_BRIGHT_RED,
472 SPR_PALETTE_GLASS_DARK_PINK,
473 SPR_PALETTE_GLASS_BRIGHT_PINK,
474 SPR_PALETTE_GLASS_LIGHT_PINK,
475 };
476
477 #define WINDOW_PALETTE_GREY {FilterPaletteID::PaletteTranslucentGrey, FilterPaletteID::PaletteTranslucentGreyHighlight, FilterPaletteID::PaletteTranslucentGreyShadow}
478 #define WINDOW_PALETTE_LIGHT_PURPLE {FilterPaletteID::PaletteTranslucentLightPurple, FilterPaletteID::PaletteTranslucentLightPurpleHighlight, FilterPaletteID::PaletteTranslucentLightPurpleShadow}
479 #define WINDOW_PALETTE_LIGHT_BLUE {FilterPaletteID::PaletteTranslucentLightBlue, FilterPaletteID::PaletteTranslucentLightBlueHighlight, FilterPaletteID::PaletteTranslucentLightBlueShadow}
480 #define WINDOW_PALETTE_TEAL {FilterPaletteID::PaletteTranslucentTeal, FilterPaletteID::PaletteTranslucentTealHighlight, FilterPaletteID::PaletteTranslucentTealShadow}
481 #define WINDOW_PALETTE_BRIGHT_GREEN {FilterPaletteID::PaletteTranslucentBrightGreen, FilterPaletteID::PaletteTranslucentBrightGreenHighlight, FilterPaletteID::PaletteTranslucentBrightGreenShadow}
482 #define WINDOW_PALETTE_YELLOW {FilterPaletteID::PaletteTranslucentYellow, FilterPaletteID::PaletteTranslucentYellowHighlight, FilterPaletteID::PaletteTranslucentYellowShadow}
483 #define WINDOW_PALETTE_LIGHT_ORANGE {FilterPaletteID::PaletteTranslucentLightOrange, FilterPaletteID::PaletteTranslucentLightOrangeHighlight, FilterPaletteID::PaletteTranslucentLightOrangeShadow}
484 #define WINDOW_PALETTE_LIGHT_BROWN {FilterPaletteID::PaletteTranslucentLightBrown, FilterPaletteID::PaletteTranslucentLightBrownHighlight, FilterPaletteID::PaletteTranslucentLightBrownShadow}
485 #define WINDOW_PALETTE_BRIGHT_RED {FilterPaletteID::PaletteTranslucentBrightRed, FilterPaletteID::PaletteTranslucentBrightRedHighlight, FilterPaletteID::PaletteTranslucentBrightRedShadow}
486 #define WINDOW_PALETTE_BRIGHT_PINK {FilterPaletteID::PaletteTranslucentBrightPink, FilterPaletteID::PaletteTranslucentBrightPinkHighlight, FilterPaletteID::PaletteTranslucentBrightPinkShadow}
487
488 const translucent_window_palette TranslucentWindowPalettes[COLOUR_COUNT] = {
489 WINDOW_PALETTE_GREY, // COLOUR_BLACK
490 WINDOW_PALETTE_GREY, // COLOUR_GREY
491 {FilterPaletteID::PaletteTranslucentWhite, FilterPaletteID::PaletteTranslucentWhiteHighlight, FilterPaletteID::PaletteTranslucentWhiteShadow},
492 WINDOW_PALETTE_LIGHT_PURPLE, // COLOUR_DARK_PURPLE
493 WINDOW_PALETTE_LIGHT_PURPLE, // COLOUR_LIGHT_PURPLE
494 {FilterPaletteID::PaletteTranslucentBrightPurple, FilterPaletteID::PaletteTranslucentBrightPurpleHighlight, FilterPaletteID::PaletteTranslucentBrightPurpleShadow},
495 WINDOW_PALETTE_LIGHT_BLUE, // COLOUR_DARK_BLUE
496 WINDOW_PALETTE_LIGHT_BLUE, // COLOUR_LIGHT_BLUE
497 WINDOW_PALETTE_LIGHT_BLUE, // COLOUR_ICY_BLUE
498 WINDOW_PALETTE_TEAL, // COLOUR_TEAL
499 WINDOW_PALETTE_TEAL, // COLOUR_AQUAMARINE
500 WINDOW_PALETTE_BRIGHT_GREEN, // COLOUR_SATURATED_GREEN
501 {FilterPaletteID::PaletteTranslucentDarkGreen, FilterPaletteID::PaletteTranslucentDarkGreenHighlight, FilterPaletteID::PaletteTranslucentDarkGreenShadow},
502 {FilterPaletteID::PaletteTranslucentMossGreen, FilterPaletteID::PaletteTranslucentMossGreenHighlight, FilterPaletteID::PaletteTranslucentMossGreenShadow},
503 WINDOW_PALETTE_BRIGHT_GREEN, // COLOUR_BRIGHT_GREEN
504 {FilterPaletteID::PaletteTranslucentOliveGreen, FilterPaletteID::PaletteTranslucentOliveGreenHighlight, FilterPaletteID::PaletteTranslucentOliveGreenShadow},
505 {FilterPaletteID::PaletteTranslucentDarkOliveGreen, FilterPaletteID::PaletteTranslucentDarkOliveGreenHighlight, FilterPaletteID::PaletteTranslucentDarkOliveGreenShadow},
506 WINDOW_PALETTE_YELLOW, // COLOUR_BRIGHT_YELLOW
507 WINDOW_PALETTE_YELLOW, // COLOUR_YELLOW
508 WINDOW_PALETTE_YELLOW, // COLOUR_DARK_YELLOW
509 WINDOW_PALETTE_LIGHT_ORANGE, // COLOUR_LIGHT_ORANGE
510 WINDOW_PALETTE_LIGHT_ORANGE, // COLOUR_DARK_ORANGE
511 WINDOW_PALETTE_LIGHT_BROWN, // COLOUR_LIGHT_BROWN
512 WINDOW_PALETTE_LIGHT_BROWN, // COLOUR_SATURATED_BROWN
513 {FilterPaletteID::PaletteTranslucentDarkBrown, FilterPaletteID::PaletteTranslucentDarkBrownHighlight, FilterPaletteID::PaletteTranslucentDarkBrownShadow},
514 {FilterPaletteID::PaletteTranslucentSalmonPink, FilterPaletteID::PaletteTranslucentSalmonPinkHighlight, FilterPaletteID::PaletteTranslucentSalmonPinkShadow},
515 {FilterPaletteID::PaletteTranslucentBordeauxRed, FilterPaletteID::PaletteTranslucentBordeauxRedHighlight, FilterPaletteID::PaletteTranslucentBordeauxRedShadow},
516 WINDOW_PALETTE_BRIGHT_RED, // COLOUR_SATURATED_RED
517 WINDOW_PALETTE_BRIGHT_RED, // COLOUR_BRIGHT_RED
518 WINDOW_PALETTE_BRIGHT_PINK, // COLOUR_DARK_PINK
519 WINDOW_PALETTE_BRIGHT_PINK, // COLOUR_BRIGHT_PINK
520 {FilterPaletteID::PaletteTranslucentLightPink, FilterPaletteID::PaletteTranslucentLightPinkHighlight, FilterPaletteID::PaletteTranslucentLightPinkShadow},
521 };
522 // clang-format on
523
GetCatalogue() const524 ImageCatalogue ImageId::GetCatalogue() const
525 {
526 auto index = GetIndex();
527 if (index == SPR_TEMP)
528 {
529 return ImageCatalogue::TEMPORARY;
530 }
531 if (index < SPR_RCTC_G1_END)
532 {
533 return ImageCatalogue::G1;
534 }
535 if (index < SPR_G2_END)
536 {
537 return ImageCatalogue::G2;
538 }
539 if (index < SPR_CSG_END)
540 {
541 return ImageCatalogue::CSG;
542 }
543 if (index < SPR_IMAGE_LIST_END)
544 {
545 return ImageCatalogue::OBJECT;
546 }
547 return ImageCatalogue::UNKNOWN;
548 }
549
550 void (*mask_fn)(
551 int32_t width, int32_t height, const uint8_t* RESTRICT maskSrc, const uint8_t* RESTRICT colourSrc, uint8_t* RESTRICT dst,
552 int32_t maskWrap, int32_t colourWrap, int32_t dstWrap)
553 = nullptr;
554
mask_init()555 void mask_init()
556 {
557 if (avx2_available())
558 {
559 log_verbose("registering AVX2 mask function");
560 mask_fn = mask_avx2;
561 }
562 else if (sse41_available())
563 {
564 log_verbose("registering SSE4.1 mask function");
565 mask_fn = mask_sse4_1;
566 }
567 else
568 {
569 log_verbose("registering scalar mask function");
570 mask_fn = mask_scalar;
571 }
572 }
573
gfx_filter_pixel(rct_drawpixelinfo * dpi,const ScreenCoordsXY & coords,FilterPaletteID palette)574 void gfx_filter_pixel(rct_drawpixelinfo* dpi, const ScreenCoordsXY& coords, FilterPaletteID palette)
575 {
576 gfx_filter_rect(dpi, { coords, coords }, palette);
577 }
578
579 /**
580 *
581 * rct2: 0x00683854
582 * a1 (ebx)
583 * product (cl)
584 */
gfx_transpose_palette(int32_t pal,uint8_t product)585 void gfx_transpose_palette(int32_t pal, uint8_t product)
586 {
587 const rct_g1_element* g1 = gfx_get_g1_element(pal);
588 if (g1 != nullptr)
589 {
590 int32_t width = g1->width;
591 int32_t x = g1->x_offset;
592 uint8_t* dest_pointer = &gGamePalette[x * 4];
593 uint8_t* source_pointer = g1->offset;
594
595 for (; width > 0; width--)
596 {
597 dest_pointer[0] = (source_pointer[0] * product) >> 8;
598 dest_pointer[1] = (source_pointer[1] * product) >> 8;
599 dest_pointer[2] = (source_pointer[2] * product) >> 8;
600 source_pointer += 3;
601 dest_pointer += 4;
602 }
603 platform_update_palette(gGamePalette, 10, 236);
604 }
605 }
606
607 /**
608 *
609 * rct2: 0x006837E3
610 */
load_palette()611 void load_palette()
612 {
613 if (gOpenRCT2NoGraphics)
614 {
615 return;
616 }
617
618 auto water_type = static_cast<rct_water_type*>(object_entry_get_chunk(ObjectType::Water, 0));
619
620 uint32_t palette = 0x5FC;
621
622 if (water_type != nullptr)
623 {
624 openrct2_assert(water_type->image_id != 0xFFFFFFFF, "Failed to load water palette");
625 palette = water_type->image_id;
626 }
627
628 const rct_g1_element* g1 = gfx_get_g1_element(palette);
629 if (g1 != nullptr)
630 {
631 int32_t width = g1->width;
632 int32_t x = g1->x_offset;
633 uint8_t* src = g1->offset;
634 uint8_t* dst = &gGamePalette[x * 4];
635 for (; width > 0; width--)
636 {
637 dst[0] = src[0];
638 dst[1] = src[1];
639 dst[2] = src[2];
640 src += 3;
641 dst += 4;
642 }
643 }
644 platform_update_palette(gGamePalette, 10, 236);
645 gfx_invalidate_screen();
646 }
647
648 /**
649 *
650 * rct2: 0x006ED7E5
651 */
gfx_invalidate_screen()652 void gfx_invalidate_screen()
653 {
654 gfx_set_dirty_blocks({ { 0, 0 }, { context_get_width(), context_get_height() } });
655 }
656
657 /*
658 *
659 * rct2: 0x006EE53B
660 * left (ax)
661 * width (bx)
662 * top (cx)
663 * height (dx)
664 * drawpixelinfo (edi)
665 */
clip_drawpixelinfo(rct_drawpixelinfo * dst,rct_drawpixelinfo * src,const ScreenCoordsXY & coords,int32_t width,int32_t height)666 bool clip_drawpixelinfo(
667 rct_drawpixelinfo* dst, rct_drawpixelinfo* src, const ScreenCoordsXY& coords, int32_t width, int32_t height)
668 {
669 int32_t right = coords.x + width;
670 int32_t bottom = coords.y + height;
671
672 *dst = *src;
673 dst->zoom_level = 0;
674
675 if (coords.x > dst->x)
676 {
677 uint16_t clippedFromLeft = coords.x - dst->x;
678 dst->width -= clippedFromLeft;
679 dst->x = coords.x;
680 dst->pitch += clippedFromLeft;
681 dst->bits += clippedFromLeft;
682 }
683
684 int32_t stickOutWidth = dst->x + dst->width - right;
685 if (stickOutWidth > 0)
686 {
687 dst->width -= stickOutWidth;
688 dst->pitch += stickOutWidth;
689 }
690
691 if (coords.y > dst->y)
692 {
693 uint16_t clippedFromTop = coords.y - dst->y;
694 dst->height -= clippedFromTop;
695 dst->y = coords.y;
696 uint32_t bitsPlus = (dst->pitch + dst->width) * clippedFromTop;
697 dst->bits += bitsPlus;
698 }
699
700 int32_t bp = dst->y + dst->height - bottom;
701 if (bp > 0)
702 {
703 dst->height -= bp;
704 }
705
706 if (dst->width > 0 && dst->height > 0)
707 {
708 dst->x -= coords.x;
709 dst->y -= coords.y;
710 return true;
711 }
712
713 return false;
714 }
715
gfx_invalidate_pickedup_peep()716 void gfx_invalidate_pickedup_peep()
717 {
718 uint32_t sprite = gPickupPeepImage;
719 if (sprite != UINT32_MAX)
720 {
721 const rct_g1_element* g1 = gfx_get_g1_element(sprite & 0x7FFFF);
722 if (g1 != nullptr)
723 {
724 int32_t left = gPickupPeepX + g1->x_offset;
725 int32_t top = gPickupPeepY + g1->y_offset;
726 int32_t right = left + g1->width;
727 int32_t bottom = top + g1->height;
728 gfx_set_dirty_blocks({ { left, top }, { right, bottom } });
729 }
730 }
731 }
732
gfx_draw_pickedup_peep(rct_drawpixelinfo * dpi)733 void gfx_draw_pickedup_peep(rct_drawpixelinfo* dpi)
734 {
735 if (gPickupPeepImage != UINT32_MAX)
736 {
737 gfx_draw_sprite(dpi, gPickupPeepImage, { gPickupPeepX, gPickupPeepY }, 0);
738 }
739 }
740
GetPaletteG1Index(colour_t paletteId)741 std::optional<uint32_t> GetPaletteG1Index(colour_t paletteId)
742 {
743 if (paletteId < std::size(palette_to_g1_offset))
744 {
745 return palette_to_g1_offset[paletteId];
746 }
747 return std::nullopt;
748 }
749
GetPaletteMapForColour(colour_t paletteId)750 std::optional<PaletteMap> GetPaletteMapForColour(colour_t paletteId)
751 {
752 auto g1Index = GetPaletteG1Index(paletteId);
753 if (g1Index.has_value())
754 {
755 auto g1 = gfx_get_g1_element(g1Index.value());
756 if (g1 != nullptr)
757 {
758 return PaletteMap(g1->offset, g1->height, g1->width);
759 }
760 }
761 return std::nullopt;
762 }
763
GetBytesPerRow() const764 size_t rct_drawpixelinfo::GetBytesPerRow() const
765 {
766 return static_cast<size_t>(width) + pitch;
767 }
768
GetBitsOffset(const ScreenCoordsXY & pos) const769 uint8_t* rct_drawpixelinfo::GetBitsOffset(const ScreenCoordsXY& pos) const
770 {
771 return bits + pos.x + (pos.y * GetBytesPerRow());
772 }
773
Crop(const ScreenCoordsXY & pos,const ScreenSize & size) const774 rct_drawpixelinfo rct_drawpixelinfo::Crop(const ScreenCoordsXY& pos, const ScreenSize& size) const
775 {
776 rct_drawpixelinfo result = *this;
777 result.bits = GetBitsOffset(pos);
778 result.x = static_cast<int16_t>(pos.x);
779 result.y = static_cast<int16_t>(pos.y);
780 result.width = static_cast<int16_t>(size.width);
781 result.height = static_cast<int16_t>(size.height);
782 result.pitch = static_cast<int16_t>(width + pitch - size.width);
783 return result;
784 }
785