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 #pragma once
11 
12 #include "../common.h"
13 #include "../localisation/Formatter.h"
14 #include "../ride/RideTypes.h"
15 #include "../world/Location.hpp"
16 #include "../world/ScenerySelection.h"
17 #include "ZoomLevel.h"
18 
19 #include <functional>
20 #include <limits>
21 #include <list>
22 #include <memory>
23 #include <variant>
24 
25 struct rct_drawpixelinfo;
26 struct rct_window;
27 union rct_window_event;
28 struct track_design_file_ref;
29 struct TitleSequence;
30 struct TextInputSession;
31 struct scenario_index_entry;
32 
33 enum class VisibilityCache : uint8_t;
34 enum class CursorID : uint8_t;
35 enum class RideConstructionState : uint8_t;
36 
37 #define SCROLLABLE_ROW_HEIGHT 12
38 #define LIST_ROW_HEIGHT 12
39 #define TABLE_CELL_HEIGHT 12
40 #define BUTTON_FACE_HEIGHT 12
41 
42 #define TEXT_INPUT_SIZE 1024
43 #define TOP_TOOLBAR_HEIGHT 27
44 
45 extern char gTextBoxInput[TEXT_INPUT_SIZE];
46 extern int32_t gMaxTextBoxInputLength;
47 extern int32_t gTextBoxFrameNo;
48 extern bool gUsingWidgetTextBox;
49 extern struct TextInputSession* gTextInput;
50 
51 using wndproc = void(struct rct_window*, union rct_window_event*);
52 
53 using rct_windowclass = uint8_t;
54 using rct_windownumber = uint16_t;
55 using rct_widgetindex = int16_t;
56 
57 struct window_identifier
58 {
59     rct_windowclass classification;
60     rct_windownumber number;
61 };
62 
63 struct widget_identifier
64 {
65     window_identifier window;
66     rct_widgetindex widget_index;
67 };
68 
69 extern widget_identifier gCurrentTextBox;
70 
71 using WidgetFlags = uint32_t;
72 namespace WIDGET_FLAGS
73 {
74     const WidgetFlags TEXT_IS_STRING = 1 << 0;
75     const WidgetFlags IS_ENABLED = 1 << 1;
76     const WidgetFlags IS_PRESSED = 1 << 2;
77     const WidgetFlags IS_DISABLED = 1 << 3;
78     const WidgetFlags TOOLTIP_IS_STRING = 1 << 4;
79     const WidgetFlags IS_HIDDEN = 1 << 5;
80     const WidgetFlags IS_HOLDABLE = 1 << 6;
81 } // namespace WIDGET_FLAGS
82 
83 enum class WindowWidgetType : uint8_t;
84 
85 /**
86  * Widget structure
87  * size: 0x10
88  */
89 struct rct_widget
90 {
91     WindowWidgetType type; // 0x00
92     uint8_t colour;        // 0x01
93     int16_t left;          // 0x02
94     int16_t right;         // 0x04
95     int16_t top;           // 0x06
96     int16_t bottom;        // 0x08
97     union
98     { // 0x0A
99         uint32_t image;
100         rct_string_id text;
101         uint32_t content;
102         utf8* string;
103     };
104     rct_string_id tooltip; // 0x0E
105 
106     // New properties
107     WidgetFlags flags{};
108     utf8* sztooltip{};
109 
widthrct_widget110     int16_t width() const
111     {
112         return right - left;
113     }
114 
heightrct_widget115     int16_t height() const
116     {
117         return bottom - top;
118     }
119 
midXrct_widget120     int16_t midX() const
121     {
122         return (left + right) / 2;
123     }
124 
midYrct_widget125     int16_t midY() const
126     {
127         return (top + bottom) / 2;
128     }
129 
textToprct_widget130     int16_t textTop() const
131     {
132         if (height() >= 10)
133             return std::max<int32_t>(top, top + (height() / 2) - 5);
134 
135         return top - 1;
136     }
137 
IsVisiblerct_widget138     bool IsVisible() const
139     {
140         return !(flags & WIDGET_FLAGS::IS_HIDDEN);
141     }
142 };
143 
144 /**
145  * Viewport structure
146  */
147 struct rct_viewport
148 {
149     int32_t width;
150     int32_t height;
151     ScreenCoordsXY pos;
152     ScreenCoordsXY viewPos;
153     int32_t view_width;
154     int32_t view_height;
155     uint32_t flags;
156     ZoomLevel zoom;
157     uint8_t var_11;
158     VisibilityCache visibility;
159 
160     // Use this function on coordinates that are relative to the viewport zoom i.e. a peeps x, y position after transforming
161     // from its x, y, z
Containsrct_viewport162     [[nodiscard]] constexpr bool Contains(const ScreenCoordsXY& vpos) const
163     {
164         return (
165             vpos.y >= viewPos.y && vpos.y < viewPos.y + view_height && vpos.x >= viewPos.x && vpos.x < viewPos.x + view_width);
166     }
167 
168     // Use this function on coordinates that are relative to the screen that is been drawn i.e. the cursor position
ContainsScreenrct_viewport169     [[nodiscard]] constexpr bool ContainsScreen(const ScreenCoordsXY& sPos) const
170     {
171         return (sPos.x >= pos.x && sPos.x < pos.x + width && sPos.y >= pos.y && sPos.y < pos.y + height);
172     }
173 
174     [[nodiscard]] ScreenCoordsXY ScreenToViewportCoord(const ScreenCoordsXY& screenCoord) const;
175 
176     void Invalidate() const;
177 };
178 
179 /**
180  * Scroll structure
181  * size: 0x12
182  */
183 struct rct_scroll
184 {
185     uint16_t flags{};          // 0x00
186     uint16_t h_left{};         // 0x02
187     uint16_t h_right{};        // 0x04
188     uint16_t h_thumb_left{};   // 0x06
189     uint16_t h_thumb_right{};  // 0x08
190     uint16_t v_top{};          // 0x0A
191     uint16_t v_bottom{};       // 0x0C
192     uint16_t v_thumb_top{};    // 0x0E
193     uint16_t v_thumb_bottom{}; // 0x10
194 };
195 
196 constexpr auto WINDOW_SCROLL_UNDEFINED = std::numeric_limits<uint16_t>::max();
197 
198 struct Focus
199 {
200     using CoordinateFocus = CoordsXYZ;
201     using EntityFocus = uint16_t;
202 
203     uint8_t zoom = 0;
204     std::variant<CoordinateFocus, EntityFocus> data;
205 
206     template<typename T> constexpr explicit Focus(T newValue, uint8_t newZoom = 0)
207     {
208         data = newValue;
209         zoom = newZoom;
210     }
211 
212     CoordsXYZ GetPos() const;
213 
214     constexpr bool operator==(const Focus& other) const
215     {
216         if (zoom != other.zoom)
217         {
218             return false;
219         }
220         return data == other.data;
221     }
222     constexpr bool operator!=(const Focus& other) const
223     {
224         return !(*this == other);
225     }
226 };
227 
228 struct rct_window_event_list
229 {
230     void (*close)(struct rct_window*){};
231     void (*mouse_up)(struct rct_window*, rct_widgetindex){};
232     void (*resize)(struct rct_window*){};
233     void (*mouse_down)(struct rct_window*, rct_widgetindex, rct_widget*){};
234     void (*dropdown)(struct rct_window*, rct_widgetindex, int32_t){};
235     void (*unknown_05)(struct rct_window*){};
236     void (*update)(struct rct_window*){};
237     void (*periodic_update)(struct rct_window*){};
238     void (*unknown_08)(struct rct_window*){};
239     void (*tool_update)(struct rct_window*, rct_widgetindex, const ScreenCoordsXY&){};
240     void (*tool_down)(struct rct_window*, rct_widgetindex, const ScreenCoordsXY&){};
241     void (*tool_drag)(struct rct_window*, rct_widgetindex, const ScreenCoordsXY&){};
242     void (*tool_up)(struct rct_window*, rct_widgetindex, const ScreenCoordsXY&){};
243     void (*tool_abort)(struct rct_window*, rct_widgetindex){};
244     void (*unknown_0E)(struct rct_window*){};
245     void (*get_scroll_size)(struct rct_window*, int32_t, int32_t*, int32_t*){};
246     void (*scroll_mousedown)(struct rct_window*, int32_t, const ScreenCoordsXY&){};
247     void (*scroll_mousedrag)(struct rct_window*, int32_t, const ScreenCoordsXY&){};
248     void (*scroll_mouseover)(struct rct_window*, int32_t, const ScreenCoordsXY&){};
249     void (*text_input)(struct rct_window*, rct_widgetindex, char*){};
250     void (*viewport_rotate)(struct rct_window*){};
251     void (*unknown_15)(struct rct_window*, int32_t, int32_t){};
252     OpenRCT2String (*tooltip)(struct rct_window*, const rct_widgetindex, const rct_string_id){};
253     void (*cursor)(struct rct_window*, rct_widgetindex, const ScreenCoordsXY&, CursorID*){};
254     void (*moved)(struct rct_window*, const ScreenCoordsXY&){};
255     void (*invalidate)(struct rct_window*){};
256     void (*paint)(struct rct_window*, rct_drawpixelinfo*){};
257     void (*scroll_paint)(struct rct_window*, rct_drawpixelinfo*, int32_t){};
258 
259     typedef void (*fnEventInitializer)(rct_window_event_list&);
rct_window_event_listrct_window_event_list260     rct_window_event_list(fnEventInitializer fn)
261     {
262         fn(*this);
263     }
264 };
265 
266 struct campaign_variables
267 {
268     int16_t campaign_type;
269     int16_t no_weeks; // 0x482
270     union
271     {
272         ride_id_t RideId;            // 0x484
273         ObjectEntryIndex ShopItemId; // 0x484
274     };
275     uint32_t pad_486;
276 };
277 
278 struct new_ride_variables
279 {
280     RideSelection SelectedRide;    // 0x480
281     RideSelection HighlightedRide; // 0x482
282     uint16_t pad_484;
283     uint16_t pad_486;
284     uint16_t selected_ride_countdown; // 488
285 };
286 
287 struct news_variables
288 {
289     int16_t var_480;
290     int16_t var_482;
291     uint16_t var_484;
292     uint16_t var_486;
293     uint16_t var_488;
294 };
295 
296 struct map_variables
297 {
298     int16_t rotation;
299     int16_t var_482;
300     uint16_t var_484;
301     uint16_t var_486;
302     uint16_t var_488;
303 };
304 
305 struct ride_variables
306 {
307     int16_t view;
308     int32_t var_482;
309     int32_t var_486;
310 };
311 
312 struct track_list_variables
313 {
314     bool track_list_being_updated;
315     bool reload_track_designs;
316 };
317 
318 struct error_variables
319 {
320     uint16_t var_480;
321 };
322 
323 struct rct_window;
324 
325 #define RCT_WINDOW_RIGHT(w) ((w)->windowPos.x + (w)->width)
326 #define RCT_WINDOW_BOTTOM(w) ((w)->windowPos.y + (w)->height)
327 
328 enum WINDOW_FLAGS
329 {
330     /*
331     WF_TIMEOUT_SHL = 0,
332     WF_TIMEOUT_MASK = 7,
333     WF_DRAGGING = 1 << 3,
334     WF_SCROLLER_UP = 1 << 4,
335     WF_SCROLLER_DOWN = 1 << 5,
336     WF_SCROLLER_MIDDLE = 1 << 6,
337     WF_DISABLE_VP_SCROLL = 1 << 9,
338     */
339 
340     WF_STICK_TO_BACK = (1 << 0),
341     WF_STICK_TO_FRONT = (1 << 1),
342     WF_NO_SCROLLING = (1 << 2), // User is unable to scroll this viewport
343     WF_SCROLLING_TO_LOCATION = (1 << 3),
344     WF_TRANSPARENT = (1 << 4),
345     WF_NO_BACKGROUND = (1 << 5), // Instead of half transparency, completely remove the window background
346     WF_7 = (1 << 7),
347     WF_RESIZABLE = (1 << 8),
348     WF_NO_AUTO_CLOSE = (1 << 9), // Don't auto close this window if too many windows are open
349     WF_10 = (1 << 10),
350     WF_WHITE_BORDER_ONE = (1 << 12),
351     WF_WHITE_BORDER_MASK = (1 << 12) | (1 << 13),
352 
353     WF_NO_SNAPPING = (1 << 15),
354 
355     // Create only flags
356     WF_AUTO_POSITION = (1 << 16),
357     WF_CENTRE_SCREEN = (1 << 17),
358 };
359 
360 enum SCROLL_FLAGS
361 {
362     HSCROLLBAR_VISIBLE = (1 << 0),
363     HSCROLLBAR_THUMB_PRESSED = (1 << 1),
364     HSCROLLBAR_LEFT_PRESSED = (1 << 2),
365     HSCROLLBAR_RIGHT_PRESSED = (1 << 3),
366     VSCROLLBAR_VISIBLE = (1 << 4),
367     VSCROLLBAR_THUMB_PRESSED = (1 << 5),
368     VSCROLLBAR_UP_PRESSED = (1 << 6),
369     VSCROLLBAR_DOWN_PRESSED = (1 << 7),
370 };
371 
372 #define SCROLLBAR_SIZE 16
373 
374 enum
375 {
376     SCROLL_PART_NONE = -1,
377     SCROLL_PART_VIEW = 0,
378     SCROLL_PART_HSCROLLBAR_LEFT = 1,
379     SCROLL_PART_HSCROLLBAR_RIGHT = 2,
380     SCROLL_PART_HSCROLLBAR_LEFT_TROUGH = 3,
381     SCROLL_PART_HSCROLLBAR_RIGHT_TROUGH = 4,
382     SCROLL_PART_HSCROLLBAR_THUMB = 5,
383     SCROLL_PART_VSCROLLBAR_TOP = 6,
384     SCROLL_PART_VSCROLLBAR_BOTTOM = 7,
385     SCROLL_PART_VSCROLLBAR_TOP_TROUGH = 8,
386     SCROLL_PART_VSCROLLBAR_BOTTOM_TROUGH = 9,
387     SCROLL_PART_VSCROLLBAR_THUMB = 10,
388 };
389 
390 enum
391 {
392     WC_MAIN_WINDOW = 0,
393     WC_TOP_TOOLBAR = 1,
394     WC_BOTTOM_TOOLBAR = 2,
395     WC_TOOLTIP = 5,
396     WC_DROPDOWN = 6,
397     WC_ABOUT = 8,
398     // WC_PUBLISHER_CREDITS = 9,
399     // WC_MUSIC_CREDITS = 10,
400     WC_ERROR = 11,
401     WC_RIDE = 12,
402     WC_RIDE_CONSTRUCTION = 13,
403     WC_SAVE_PROMPT = 14,
404     WC_RIDE_LIST = 15,
405     WC_CONSTRUCT_RIDE = 16,
406     WC_DEMOLISH_RIDE_PROMPT = 17,
407     WC_SCENERY = 18,
408     WC_OPTIONS = 19,
409     WC_FOOTPATH = 20,
410     WC_LAND = 21,
411     WC_WATER = 22,
412     WC_PEEP = 23,
413     WC_GUEST_LIST = 24,
414     WC_STAFF_LIST = 25,
415     WC_FIRE_PROMPT = 26,
416     WC_PARK_INFORMATION = 27,
417     WC_FINANCES = 28,
418     WC_TITLE_MENU = 29,
419     WC_TITLE_EXIT = 30,
420     WC_RECENT_NEWS = 31,
421     WC_SCENARIO_SELECT = 32,
422     WC_TRACK_DESIGN_LIST = 33,
423     WC_TRACK_DESIGN_PLACE = 34,
424     WC_NEW_CAMPAIGN = 35,
425     WC_KEYBOARD_SHORTCUT_LIST = 36,
426     WC_CHANGE_KEYBOARD_SHORTCUT = 37,
427     WC_MAP = 38,
428     WC_TITLE_LOGO = 39,
429     WC_BANNER = 40,
430     WC_MAP_TOOLTIP = 41,
431     WC_EDITOR_OBJECT_SELECTION = 42,
432     WC_EDITOR_INVENTION_LIST = 43,
433     WC_EDITOR_INVENTION_LIST_DRAG = 44,
434     WC_EDITOR_SCENARIO_OPTIONS = 45,
435     WC_EDITOR_OBJECTIVE_OPTIONS = 46,
436     WC_MANAGE_TRACK_DESIGN = 47,
437     WC_TRACK_DELETE_PROMPT = 48,
438     WC_INSTALL_TRACK = 49,
439     WC_CLEAR_SCENERY = 50,
440     WC_SCENERY_SCATTER = 51,
441     WC_NOTIFICATION_OPTIONS = 109,
442     WC_CHEATS = 110,
443     WC_RESEARCH = 111,
444     WC_VIEWPORT = 112,
445     WC_TEXTINPUT = 113,
446     WC_MAPGEN = 114,
447     WC_LOADSAVE = 115,
448     WC_LOADSAVE_OVERWRITE_PROMPT = 116,
449     WC_TITLE_OPTIONS = 117,
450     WC_LAND_RIGHTS = 118,
451     WC_THEMES = 119,
452     WC_TILE_INSPECTOR = 120,
453     WC_CHANGELOG = 121,
454     WC_TITLE_EDITOR = 122,
455     WC_TITLE_COMMAND_EDITOR = 123,
456     WC_MULTIPLAYER = 124,
457     WC_PLAYER = 125,
458     WC_NETWORK_STATUS = 126,
459     WC_SERVER_LIST = 127,
460     WC_SERVER_START = 128,
461     WC_CUSTOM_CURRENCY_CONFIG = 129,
462     WC_DEBUG_PAINT = 130,
463     WC_VIEW_CLIPPING = 131,
464     WC_OBJECT_LOAD_ERROR = 132,
465 
466     // Only used for colour schemes
467     WC_STAFF = 220,
468     WC_EDITOR_TRACK_BOTTOM_TOOLBAR = 221,
469     WC_EDITOR_SCENARIO_BOTTOM_TOOLBAR = 222,
470     WC_CHAT = 223,
471     WC_CONSOLE = 224,
472     WC_CUSTOM = 225,
473 
474     WC_NULL = 255,
475 };
476 
477 enum
478 {
479     WV_PARK_AWARDS,
480     WV_PARK_RATING,
481     WV_PARK_OBJECTIVE,
482     WV_PARK_GUESTS,
483     WV_FINANCES_RESEARCH,
484     WV_RIDE_RESEARCH,
485     WV_MAZE_CONSTRUCTION,
486     WV_NETWORK_PASSWORD,
487     WV_EDITOR_BOTTOM_TOOLBAR,
488     WV_EDITOR_MAIN,
489     WV_CHANGELOG,
490     WV_NEW_VERSION_INFO,
491 };
492 
493 enum
494 {
495     WD_BANNER,
496     WD_NEW_CAMPAIGN,
497     WD_DEMOLISH_RIDE,
498     WD_REFURBISH_RIDE,
499     WD_SIGN,
500     WD_SIGN_SMALL,
501 
502     WD_PLAYER,
503 
504     WD_VEHICLE,
505     WD_TRACK,
506 };
507 
508 #define validate_global_widx(wc, widx)                                                                                         \
509     static_assert(widx == wc##__##widx, "Global WIDX of " #widx " doesn't match actual value.")
510 
511 #define WC_MAIN_WINDOW__0 0
512 #define WC_TOP_TOOLBAR__WIDX_PAUSE 0
513 #define WC_TOP_TOOLBAR__WIDX_LAND 8
514 #define WC_TOP_TOOLBAR__WIDX_WATER 9
515 #define WC_TOP_TOOLBAR__WIDX_SCENERY 10
516 #define WC_TOP_TOOLBAR__WIDX_PATH 11
517 #define WC_TOP_TOOLBAR__WIDX_CLEAR_SCENERY 17
518 #define WC_RIDE_CONSTRUCTION__WIDX_CONSTRUCT 23
519 #define WC_RIDE_CONSTRUCTION__WIDX_ENTRANCE 29
520 #define WC_RIDE_CONSTRUCTION__WIDX_EXIT 30
521 #define WC_RIDE_CONSTRUCTION__WIDX_ROTATE 32
522 #define WC_SCENERY__WIDX_SCENERY_TAB_1 12
523 #define WC_SCENERY__WIDX_SCENERY_ROTATE_OBJECTS_BUTTON 5
524 #define WC_SCENERY__WIDX_SCENERY_EYEDROPPER_BUTTON 10
525 #define WC_PEEP__WIDX_PATROL 10
526 #define WC_PEEP__WIDX_ACTION_LBL 13
527 #define WC_PEEP__WIDX_PICKUP 14
528 #define WC_TRACK_DESIGN_LIST__WIDX_ROTATE 8
529 #define WC_TRACK_DESIGN_PLACE__WIDX_ROTATE 3
530 #define WC_MAP__WIDX_ROTATE_90 20
531 #define WC_EDITOR_OBJECT_SELECTION__WIDX_TAB_1 21
532 #define WC_STAFF__WIDX_PICKUP 9
533 #define WC_TILE_INSPECTOR__WIDX_BUTTON_ROTATE 14
534 #define WC_TILE_INSPECTOR__WIDX_BUTTON_CORRUPT 10
535 #define WC_TILE_INSPECTOR__WIDX_BUTTON_COPY 17
536 #define WC_TILE_INSPECTOR__WIDX_BUTTON_PASTE 16
537 #define WC_TILE_INSPECTOR__WIDX_BUTTON_REMOVE 11
538 #define WC_TILE_INSPECTOR__WIDX_BUTTON_MOVE_UP 12
539 #define WC_TILE_INSPECTOR__WIDX_BUTTON_MOVE_DOWN 13
540 #define WC_TILE_INSPECTOR__WIDX_SPINNER_X_INCREASE 5
541 #define WC_TILE_INSPECTOR__WIDX_SPINNER_X_DECREASE 6
542 #define WC_TILE_INSPECTOR__WIDX_SPINNER_Y_INCREASE 8
543 #define WC_TILE_INSPECTOR__WIDX_SPINNER_Y_DECREASE 9
544 #define WC_TILE_INSPECTOR__TILE_INSPECTOR_PAGE_SURFACE TileInspectorPage::Surface
545 #define WC_TILE_INSPECTOR__WIDX_SURFACE_SPINNER_HEIGHT_INCREASE 27
546 #define WC_TILE_INSPECTOR__WIDX_SURFACE_SPINNER_HEIGHT_DECREASE 28
547 #define WC_TILE_INSPECTOR__TILE_INSPECTOR_PAGE_PATH TileInspectorPage::Path
548 #define WC_TILE_INSPECTOR__WIDX_PATH_SPINNER_HEIGHT_INCREASE 27
549 #define WC_TILE_INSPECTOR__WIDX_PATH_SPINNER_HEIGHT_DECREASE 28
550 #define WC_TILE_INSPECTOR__TILE_INSPECTOR_PAGE_TRACK TileInspectorPage::Track
551 #define WC_TILE_INSPECTOR__WIDX_TRACK_SPINNER_HEIGHT_INCREASE 28
552 #define WC_TILE_INSPECTOR__WIDX_TRACK_SPINNER_HEIGHT_DECREASE 29
553 #define WC_TILE_INSPECTOR__TILE_INSPECTOR_PAGE_SCENERY TileInspectorPage::Scenery
554 #define WC_TILE_INSPECTOR__WIDX_SCENERY_SPINNER_HEIGHT_INCREASE 27
555 #define WC_TILE_INSPECTOR__WIDX_SCENERY_SPINNER_HEIGHT_DECREASE 28
556 #define WC_TILE_INSPECTOR__TILE_INSPECTOR_PAGE_ENTRANCE TileInspectorPage::Entrance
557 #define WC_TILE_INSPECTOR__WIDX_ENTRANCE_SPINNER_HEIGHT_INCREASE 27
558 #define WC_TILE_INSPECTOR__WIDX_ENTRANCE_SPINNER_HEIGHT_DECREASE 28
559 #define WC_TILE_INSPECTOR__TILE_INSPECTOR_PAGE_WALL TileInspectorPage::Wall
560 #define WC_TILE_INSPECTOR__WIDX_WALL_SPINNER_HEIGHT_INCREASE 27
561 #define WC_TILE_INSPECTOR__WIDX_WALL_SPINNER_HEIGHT_DECREASE 28
562 #define WC_TILE_INSPECTOR__TILE_INSPECTOR_PAGE_LARGE_SCENERY TileInspectorPage::LargeScenery
563 #define WC_TILE_INSPECTOR__WIDX_LARGE_SCENERY_SPINNER_HEIGHT_INCREASE 27
564 #define WC_TILE_INSPECTOR__WIDX_LARGE_SCENERY_SPINNER_HEIGHT_DECREASE 28
565 #define WC_TILE_INSPECTOR__TILE_INSPECTOR_PAGE_BANNER TileInspectorPage::Banner
566 #define WC_TILE_INSPECTOR__WIDX_BANNER_SPINNER_HEIGHT_INCREASE 27
567 #define WC_TILE_INSPECTOR__WIDX_BANNER_SPINNER_HEIGHT_DECREASE 28
568 #define WC_TILE_INSPECTOR__TILE_INSPECTOR_PAGE_CORRUPT TileInspectorPage::Corrupt
569 #define WC_TILE_INSPECTOR__WIDX_CORRUPT_SPINNER_HEIGHT_INCREASE 27
570 #define WC_TILE_INSPECTOR__WIDX_CORRUPT_SPINNER_HEIGHT_DECREASE 28
571 
572 enum class PromptMode : uint8_t
573 {
574     SaveBeforeLoad = 0,
575     SaveBeforeQuit,
576     SaveBeforeQuit2,
577     Quit
578 };
579 
580 enum BTM_TOOLBAR_DIRTY_FLAGS
581 {
582     BTM_TB_DIRTY_FLAG_MONEY = (1 << 0),
583     BTM_TB_DIRTY_FLAG_DATE = (1 << 1),
584     BTM_TB_DIRTY_FLAG_PEEP_COUNT = (1 << 2),
585     BTM_TB_DIRTY_FLAG_CLIMATE = (1 << 3),
586     BTM_TB_DIRTY_FLAG_PARK_RATING = (1 << 4)
587 };
588 
589 // 000N_TTTL
590 enum
591 {
592     LOADSAVETYPE_LOAD = 0 << 0,
593     LOADSAVETYPE_SAVE = 1 << 0,
594 
595     LOADSAVETYPE_GAME = 0 << 1,
596     LOADSAVETYPE_LANDSCAPE = 1 << 1,
597     LOADSAVETYPE_SCENARIO = 2 << 1,
598     LOADSAVETYPE_TRACK = 3 << 1,
599     LOADSAVETYPE_HEIGHTMAP = 4 << 1,
600 };
601 
602 enum
603 {
604     MODAL_RESULT_FAIL = -1,
605     MODAL_RESULT_CANCEL,
606     MODAL_RESULT_OK
607 };
608 
609 enum class VisibilityCache : uint8_t
610 {
611     Unknown,
612     Visible,
613     Covered
614 };
615 
616 enum class GuestListFilterType : int32_t
617 {
618     GuestsOnRide,
619     GuestsInQueue,
620     GuestsThinkingAboutRide,
621     GuestsThinkingX,
622 };
623 
624 enum class Tool
625 {
626     Arrow = 0,
627     UpArrow = 2,
628     UpDownArrow = 3,
629     Picker = 7,
630     Crosshair = 12,
631     PathDown = 17,
632     DigDown = 18,
633     WaterDown = 19,
634     WalkDown = 22,
635     PaintDown = 23,
636     EntranceDown = 24,
637 };
638 
639 using modal_callback = void (*)(int32_t result);
640 using close_callback = void (*)();
641 
642 #define WINDOW_LIMIT_MIN 4
643 #define WINDOW_LIMIT_MAX 64
644 #define WINDOW_LIMIT_RESERVED 4 // Used to reserve room for the main viewport, toolbars, etc.
645 
646 extern rct_window* gWindowAudioExclusive;
647 
648 extern uint16_t gWindowUpdateTicks;
649 namespace MapFlashingFlags
650 {
651     constexpr uint16_t GuestListOpen = (1 << 0);
652     constexpr uint16_t FlashGuests = (1 << 1);
653     constexpr uint16_t StaffListOpen = (1 << 2);
654     constexpr uint16_t FlashStaff = (1 << 3);
655     constexpr uint16_t SwitchColour = (1 << 15); // Every couple ticks the colour switches
656 } // namespace MapFlashingFlags
657 extern uint16_t gWindowMapFlashingFlags;
658 
659 extern colour_t gCurrentWindowColours[4];
660 
661 extern bool gDisableErrorWindowSound;
662 
663 std::list<std::shared_ptr<rct_window>>::iterator window_get_iterator(const rct_window* w);
664 void window_visit_each(std::function<void(rct_window*)> func);
665 
666 void window_dispatch_update_all();
667 void window_update_all_viewports();
668 void window_update_all();
669 
670 void window_set_window_limit(int32_t value);
671 
672 rct_window* window_bring_to_front(rct_window* w);
673 rct_window* window_bring_to_front_by_class(rct_windowclass cls);
674 rct_window* window_bring_to_front_by_class_with_flags(rct_windowclass cls, uint16_t flags);
675 rct_window* window_bring_to_front_by_number(rct_windowclass cls, rct_windownumber number);
676 
677 rct_window* WindowCreate(
678     std::unique_ptr<rct_window>&& w, rct_windowclass cls, ScreenCoordsXY pos, int32_t width, int32_t height, uint32_t flags);
679 template<typename T, typename std::enable_if<std::is_base_of<rct_window, T>::value>::type* = nullptr>
680 T* WindowCreate(rct_windowclass cls, const ScreenCoordsXY& pos, int32_t width, int32_t height, uint32_t flags = 0)
681 {
682     return static_cast<T*>(WindowCreate(std::make_unique<T>(), cls, pos, width, height, flags));
683 }
684 template<typename T, typename std::enable_if<std::is_base_of<rct_window, T>::value>::type* = nullptr>
685 T* WindowCreate(rct_windowclass cls, int32_t width, int32_t height, uint32_t flags = 0)
686 {
687     return static_cast<T*>(WindowCreate(std::make_unique<T>(), cls, {}, width, height, flags | WF_AUTO_POSITION));
688 }
689 template<typename T, typename std::enable_if<std::is_base_of<rct_window, T>::value>::type* = nullptr>
690 T* WindowFocusOrCreate(rct_windowclass cls, const ScreenCoordsXY& pos, int32_t width, int32_t height, uint32_t flags = 0)
691 {
692     auto* w = window_bring_to_front_by_class(cls);
693     if (w == nullptr)
694     {
695         w = WindowCreate<T>(cls, pos, width, height, flags);
696     }
697     return static_cast<T*>(w);
698 }
699 template<typename T, typename std::enable_if<std::is_base_of<rct_window, T>::value>::type* = nullptr>
700 T* WindowFocusOrCreate(rct_windowclass cls, int32_t width, int32_t height, uint32_t flags = 0)
701 {
702     auto* w = window_bring_to_front_by_class(cls);
703     if (w == nullptr)
704     {
705         w = WindowCreate<T>(cls, width, height, flags);
706     }
707     return static_cast<T*>(w);
708 }
709 
710 rct_window* WindowCreate(
711     const ScreenCoordsXY& pos, int32_t width, int32_t height, rct_window_event_list* event_handlers, rct_windowclass cls,
712     uint32_t flags);
713 rct_window* WindowCreateAutoPos(
714     int32_t width, int32_t height, rct_window_event_list* event_handlers, rct_windowclass cls, uint32_t flags);
715 rct_window* WindowCreateCentred(
716     int32_t width, int32_t height, rct_window_event_list* event_handlers, rct_windowclass cls, uint32_t flags);
717 
718 void window_close(rct_window* window);
719 void window_close_by_class(rct_windowclass cls);
720 void window_close_by_number(rct_windowclass cls, rct_windownumber number);
721 void window_close_top();
722 void window_close_all();
723 void window_close_all_except_class(rct_windowclass cls);
724 void window_close_all_except_flags(uint16_t flags);
725 rct_window* window_find_by_class(rct_windowclass cls);
726 rct_window* window_find_by_number(rct_windowclass cls, rct_windownumber number);
727 rct_window* window_find_from_point(const ScreenCoordsXY& screenCoords);
728 rct_widgetindex window_find_widget_from_point(rct_window* w, const ScreenCoordsXY& screenCoords);
729 void window_invalidate_by_class(rct_windowclass cls);
730 void window_invalidate_by_number(rct_windowclass cls, rct_windownumber number);
731 void window_invalidate_all();
732 void widget_invalidate(rct_window* w, rct_widgetindex widgetIndex);
733 void widget_invalidate_by_class(rct_windowclass cls, rct_widgetindex widgetIndex);
734 void widget_invalidate_by_number(rct_windowclass cls, rct_windownumber number, rct_widgetindex widgetIndex);
735 void WindowInitScrollWidgets(rct_window* w);
736 void window_update_scroll_widgets(rct_window* w);
737 int32_t window_get_scroll_data_index(rct_window* w, rct_widgetindex widget_index);
738 
739 void window_push_others_right(rct_window* w);
740 void window_push_others_below(rct_window* w1);
741 
742 rct_window* window_get_main();
743 
744 void window_scroll_to_location(rct_window* w, const CoordsXYZ& coords);
745 void window_rotate_camera(rct_window* w, int32_t direction);
746 void window_viewport_get_map_coords_by_cursor(
747     rct_window* w, int32_t* map_x, int32_t* map_y, int32_t* offset_x, int32_t* offset_y);
748 void window_viewport_centre_tile_around_cursor(rct_window* w, int32_t map_x, int32_t map_y, int32_t offset_x, int32_t offset_y);
749 void window_check_all_valid_zoom();
750 void window_zoom_set(rct_window* w, ZoomLevel zoomLevel, bool atCursor);
751 void window_zoom_in(rct_window* w, bool atCursor);
752 void window_zoom_out(rct_window* w, bool atCursor);
753 void main_window_zoom(bool zoomIn, bool atCursor);
754 
755 void window_show_textinput(rct_window* w, rct_widgetindex widgetIndex, uint16_t title, uint16_t text, int32_t value);
756 
757 void window_draw_all(rct_drawpixelinfo* dpi, int32_t left, int32_t top, int32_t right, int32_t bottom);
758 void window_draw(rct_drawpixelinfo* dpi, rct_window* w, int32_t left, int32_t top, int32_t right, int32_t bottom);
759 void WindowDrawWidgets(rct_window* w, rct_drawpixelinfo* dpi);
760 void window_draw_viewport(rct_drawpixelinfo* dpi, rct_window* w);
761 
762 void window_set_position(rct_window* w, const ScreenCoordsXY& screenCoords);
763 void window_move_position(rct_window* w, const ScreenCoordsXY& screenCoords);
764 void window_resize(rct_window* w, int32_t dw, int32_t dh);
765 void window_set_resize(rct_window* w, int32_t minWidth, int32_t minHeight, int32_t maxWidth, int32_t maxHeight);
766 
767 bool tool_set(rct_window* w, rct_widgetindex widgetIndex, Tool tool);
768 void tool_cancel();
769 
770 void window_close_construction_windows();
771 
772 void window_update_viewport_ride_music();
773 
774 rct_viewport* window_get_viewport(rct_window* window);
775 
776 // Open window functions
777 void window_relocate_windows(int32_t width, int32_t height);
778 void window_resize_gui(int32_t width, int32_t height);
779 void window_resize_gui_scenario_editor(int32_t width, int32_t height);
780 void window_ride_construct(rct_window* w);
781 void ride_construction_toolupdate_entrance_exit(const ScreenCoordsXY& screenCoords);
782 void ride_construction_toolupdate_construct(const ScreenCoordsXY& screenCoords);
783 void ride_construction_tooldown_construct(const ScreenCoordsXY& screenCoords);
784 
785 void window_align_tabs(rct_window* w, rct_widgetindex start_tab_id, rct_widgetindex end_tab_id);
786 
787 void window_staff_list_init_vars();
788 
789 void window_event_close_call(rct_window* w);
790 void window_event_mouse_up_call(rct_window* w, rct_widgetindex widgetIndex);
791 void window_event_resize_call(rct_window* w);
792 void window_event_mouse_down_call(rct_window* w, rct_widgetindex widgetIndex);
793 void window_event_dropdown_call(rct_window* w, rct_widgetindex widgetIndex, int32_t dropdownIndex);
794 void window_event_unknown_05_call(rct_window* w);
795 void window_event_update_call(rct_window* w);
796 void window_event_periodic_update_call(rct_window* w);
797 void window_event_unknown_08_call(rct_window* w);
798 void window_event_tool_update_call(rct_window* w, rct_widgetindex widgetIndex, const ScreenCoordsXY& screenCoords);
799 void window_event_tool_down_call(rct_window* w, rct_widgetindex widgetIndex, const ScreenCoordsXY& screenCoords);
800 void window_event_tool_drag_call(rct_window* w, rct_widgetindex widgetIndex, const ScreenCoordsXY& screenCoords);
801 void window_event_tool_up_call(rct_window* w, rct_widgetindex widgetIndex, const ScreenCoordsXY& screenCoords);
802 void window_event_tool_abort_call(rct_window* w, rct_widgetindex widgetIndex);
803 void window_event_unknown_0E_call(rct_window* w);
804 void window_get_scroll_size(rct_window* w, int32_t scrollIndex, int32_t* width, int32_t* height);
805 void window_event_scroll_mousedown_call(rct_window* w, int32_t scrollIndex, const ScreenCoordsXY& screenCoords);
806 void window_event_scroll_mousedrag_call(rct_window* w, int32_t scrollIndex, const ScreenCoordsXY& screenCoords);
807 void window_event_scroll_mouseover_call(rct_window* w, int32_t scrollIndex, const ScreenCoordsXY& screenCoords);
808 void window_event_textinput_call(rct_window* w, rct_widgetindex widgetIndex, char* text);
809 void window_event_viewport_rotate_call(rct_window* w);
810 void window_event_unknown_15_call(rct_window* w, int32_t scrollIndex, int32_t scrollAreaType);
811 OpenRCT2String window_event_tooltip_call(rct_window* w, const rct_widgetindex widgetIndex, const rct_string_id fallback);
812 CursorID window_event_cursor_call(rct_window* w, rct_widgetindex widgetIndex, const ScreenCoordsXY& screenCoords);
813 void window_event_moved_call(rct_window* w, const ScreenCoordsXY& screenCoords);
814 void window_event_invalidate_call(rct_window* w);
815 void window_event_paint_call(rct_window* w, rct_drawpixelinfo* dpi);
816 void window_event_scroll_paint_call(rct_window* w, rct_drawpixelinfo* dpi, int32_t scrollIndex);
817 
818 void InvalidateAllWindowsAfterInput();
819 void textinput_cancel();
820 
821 void window_move_and_snap(rct_window* w, ScreenCoordsXY newWindowCoords, int32_t snapProximity);
822 int32_t window_can_resize(rct_window* w);
823 
824 void window_start_textbox(
825     rct_window* call_w, rct_widgetindex call_widget, rct_string_id existing_text, char* existing_args, int32_t maxLength);
826 void window_cancel_textbox();
827 void window_update_textbox_caret();
828 void window_update_textbox();
829 
830 bool window_is_visible(rct_window* w);
831 
832 bool scenery_tool_is_active();
833 
834 rct_viewport* window_get_previous_viewport(rct_viewport* current);
835 void window_reset_visibilities();
836 void window_init_all();
837 
838 // Cheat: in-game land ownership editor
839 void toggle_ingame_land_ownership_editor();
840 
841 void window_ride_construction_keyboard_shortcut_turn_left();
842 void window_ride_construction_keyboard_shortcut_turn_right();
843 void window_ride_construction_keyboard_shortcut_use_track_default();
844 void window_ride_construction_keyboard_shortcut_slope_down();
845 void window_ride_construction_keyboard_shortcut_slope_up();
846 void window_ride_construction_keyboard_shortcut_chain_lift_toggle();
847 void window_ride_construction_keyboard_shortcut_bank_left();
848 void window_ride_construction_keyboard_shortcut_bank_right();
849 void window_ride_construction_keyboard_shortcut_previous_track();
850 void window_ride_construction_keyboard_shortcut_next_track();
851 void window_ride_construction_keyboard_shortcut_build_current();
852 void window_ride_construction_keyboard_shortcut_demolish_current();
853 
854 void window_footpath_keyboard_shortcut_turn_left();
855 void window_footpath_keyboard_shortcut_turn_right();
856 void window_footpath_keyboard_shortcut_slope_down();
857 void window_footpath_keyboard_shortcut_slope_up();
858 void window_footpath_keyboard_shortcut_build_current();
859 void window_footpath_keyboard_shortcut_demolish_current();
860 
861 void window_follow_sprite(rct_window* w, size_t spriteIndex);
862 void window_unfollow_sprite(rct_window* w);
863 
864 bool window_ride_construction_update_state(
865     int32_t* trackType, int32_t* trackDirection, ride_id_t* rideIndex, int32_t* _liftHillAndAlternativeState,
866     CoordsXYZ* trackPos, int32_t* properties);
867 money32 place_provisional_track_piece(
868     ride_id_t rideIndex, int32_t trackType, int32_t trackDirection, int32_t liftHillAndAlternativeState,
869     const CoordsXYZ& trackPos);
870 
871 extern uint64_t _enabledRidePieces;
872 extern RideConstructionState _rideConstructionState2;
873 extern bool _stationConstructed;
874 extern bool _deferClose;
875 
876 rct_window* window_get_listening();
877 rct_windowclass window_get_classification(rct_window* window);
878