From 8a181b5513ca3432f09fd5934d671e3d2ac1630f Mon Sep 17 00:00:00 2001 From: Gymnasiast Date: Thu, 9 May 2024 02:45:07 +0200 Subject: [PATCH] Split colours and colour flags --- src/openrct2-ui/interface/Dropdown.h | 12 +- src/openrct2-ui/interface/InGameConsole.cpp | 14 +- src/openrct2-ui/interface/Theme.cpp | 277 ++++++++---------- src/openrct2-ui/interface/Theme.h | 6 +- src/openrct2-ui/interface/Widget.cpp | 134 ++++----- src/openrct2-ui/interface/Window.cpp | 2 +- src/openrct2-ui/scripting/CustomListView.cpp | 10 +- src/openrct2-ui/scripting/CustomWindow.cpp | 15 +- .../scripting/ScGraphicsContext.hpp | 4 +- src/openrct2-ui/scripting/ScWindow.hpp | 16 +- src/openrct2-ui/windows/AssetPacks.cpp | 6 +- src/openrct2-ui/windows/Banner.cpp | 2 +- src/openrct2-ui/windows/Cheats.cpp | 2 +- src/openrct2-ui/windows/DebugPaint.cpp | 2 +- src/openrct2-ui/windows/Dropdown.cpp | 38 +-- .../windows/EditorBottomToolbar.cpp | 7 +- .../windows/EditorInventionsList.cpp | 10 +- .../windows/EditorObjectSelection.cpp | 14 +- .../windows/EditorObjectiveOptions.cpp | 6 +- src/openrct2-ui/windows/Finances.cpp | 4 +- src/openrct2-ui/windows/GameBottomToolbar.cpp | 30 +- src/openrct2-ui/windows/Guest.cpp | 2 +- src/openrct2-ui/windows/GuestList.cpp | 3 +- src/openrct2-ui/windows/InstallTrack.cpp | 2 +- src/openrct2-ui/windows/LoadSave.cpp | 3 +- src/openrct2-ui/windows/MapGen.cpp | 18 +- src/openrct2-ui/windows/Multiplayer.cpp | 5 +- src/openrct2-ui/windows/NewRide.cpp | 4 +- src/openrct2-ui/windows/ObjectLoadError.cpp | 8 +- src/openrct2-ui/windows/Options.cpp | 6 +- src/openrct2-ui/windows/Ride.cpp | 2 +- src/openrct2-ui/windows/RideList.cpp | 3 +- src/openrct2-ui/windows/ScenarioSelect.cpp | 11 +- src/openrct2-ui/windows/Scenery.cpp | 4 +- src/openrct2-ui/windows/ServerList.cpp | 6 +- src/openrct2-ui/windows/ShortcutKeys.cpp | 6 +- src/openrct2-ui/windows/Sign.cpp | 4 +- src/openrct2-ui/windows/StaffList.cpp | 2 +- src/openrct2-ui/windows/TextInput.cpp | 2 +- src/openrct2-ui/windows/Themes.cpp | 54 ++-- src/openrct2-ui/windows/TileInspector.cpp | 13 +- src/openrct2-ui/windows/TitleLogo.cpp | 6 +- src/openrct2-ui/windows/TitleMenu.cpp | 4 +- src/openrct2-ui/windows/TopToolbar.cpp | 33 ++- src/openrct2-ui/windows/TrackDesignPlace.cpp | 2 +- src/openrct2-ui/windows/TrackList.cpp | 4 +- src/openrct2/drawing/Drawing.String.cpp | 34 +-- src/openrct2/drawing/Drawing.h | 9 +- src/openrct2/drawing/Rect.cpp | 20 +- src/openrct2/drawing/Text.h | 79 ++++- src/openrct2/interface/Chat.cpp | 2 +- src/openrct2/interface/Chat.h | 3 +- src/openrct2/interface/Colour.cpp | 55 ++++ src/openrct2/interface/Colour.h | 56 ++-- src/openrct2/interface/Window.cpp | 9 +- src/openrct2/interface/Window.h | 3 +- src/openrct2/interface/Window_internal.h | 3 +- src/openrct2/paint/Paint.cpp | 2 +- 58 files changed, 596 insertions(+), 497 deletions(-) diff --git a/src/openrct2-ui/interface/Dropdown.h b/src/openrct2-ui/interface/Dropdown.h index 003417cc47..95a451c872 100644 --- a/src/openrct2-ui/interface/Dropdown.h +++ b/src/openrct2-ui/interface/Dropdown.h @@ -49,16 +49,18 @@ namespace OpenRCT2::Ui::Windows extern int32_t gDropdownDefaultIndex; void WindowDropdownShowText( - const ScreenCoordsXY& screenPos, int32_t extray, uint8_t colour, uint8_t flags, size_t num_items); + const ScreenCoordsXY& screenPos, int32_t extray, ColourWithFlags colour, uint8_t flags, size_t num_items); void WindowDropdownShowTextCustomWidth( - const ScreenCoordsXY& screenPos, int32_t extray, uint8_t colour, uint8_t custom_height, uint8_t flags, size_t num_items, - int32_t width); + const ScreenCoordsXY& screenPos, int32_t extray, ColourWithFlags colour, uint8_t custom_height, uint8_t flags, + size_t num_items, int32_t width); void WindowDropdownShowImage( - int32_t x, int32_t y, int32_t extray, uint8_t colour, uint8_t flags, int32_t numItems, int32_t itemWidth, + int32_t x, int32_t y, int32_t extray, ColourWithFlags colour, uint8_t flags, int32_t numItems, int32_t itemWidth, int32_t itemHeight, int32_t numColumns); void WindowDropdownClose(); int32_t DropdownIndexFromPoint(const ScreenCoordsXY& loc, WindowBase* w); - void WindowDropdownShowColour(WindowBase* w, Widget* widget, uint8_t dropdownColour, uint8_t selectedColour); + void WindowDropdownShowColour( + WindowBase* w, Widget* widget, ColourWithFlags dropdownColour, colour_t selectedColour, + bool alwaysHideSpecialColours = false); void WindowDropdownShowColourAvailable( WindowBase* w, Widget* widget, uint8_t dropdownColour, uint8_t selectedColour, uint32_t availableColours); uint32_t DropdownGetAppropriateImageDropdownItemsPerRow(uint32_t numItems); diff --git a/src/openrct2-ui/interface/InGameConsole.cpp b/src/openrct2-ui/interface/InGameConsole.cpp index a95437ab47..20601dad3d 100644 --- a/src/openrct2-ui/interface/InGameConsole.cpp +++ b/src/openrct2-ui/interface/InGameConsole.cpp @@ -280,7 +280,7 @@ void InGameConsole::Draw(DrawPixelInfo& dpi) const return; // Set font - uint8_t textColour = NOT_TRANSLUCENT(ThemeGetColour(WindowClass::Console, 1)); + ColourWithFlags textColour = { ThemeGetColour(WindowClass::Console, 1).colour, 0 }; const int32_t lineHeight = InGameConsoleGetLineHeight(); const int32_t maxLines = GetNumVisibleLines(); @@ -288,7 +288,7 @@ void InGameConsole::Draw(DrawPixelInfo& dpi) const // as opposed to a desaturated grey thread_local std::string _colourFormatStr; _colourFormatStr.clear(); - if (textColour == COLOUR_BLACK) + if (textColour.colour == COLOUR_BLACK) { _colourFormatStr = "{BLACK}"; } @@ -296,7 +296,7 @@ void InGameConsole::Draw(DrawPixelInfo& dpi) const // TTF looks far better without the outlines if (!LocalisationService_UseTrueTypeFont()) { - textColour |= COLOUR_FLAG_OUTLINE; + textColour.setFlag(ColourFlag::withOutline, true); } Invalidate(); @@ -310,7 +310,7 @@ void InGameConsole::Draw(DrawPixelInfo& dpi) const FilterPaletteID::Palette51); // Paint background colour. - uint8_t backgroundColour = ThemeGetColour(WindowClass::Console, 0); + auto backgroundColour = ThemeGetColour(WindowClass::Console, 0); GfxFillRectInset(dpi, { _consoleTopLeft, _consoleBottomRight }, backgroundColour, INSET_RECT_FLAG_FILL_NONE); GfxFillRectInset( dpi, { _consoleTopLeft + ScreenCoordsXY{ 1, 1 }, _consoleBottomRight - ScreenCoordsXY{ 1, 1 } }, backgroundColour, @@ -338,13 +338,13 @@ void InGameConsole::Draw(DrawPixelInfo& dpi) const if (_consoleCaretTicks < CONSOLE_CARET_FLASH_THRESHOLD) { auto caret = screenCoords + ScreenCoordsXY{ _caretScreenPosX, lineHeight }; - uint8_t caretColour = ColourMapA[BASE_COLOUR(textColour)].lightest; + uint8_t caretColour = ColourMapA[textColour.colour].lightest; GfxFillRect(dpi, { caret, caret + ScreenCoordsXY{ CONSOLE_CARET_WIDTH, 1 } }, caretColour); } // What about border colours? - uint8_t borderColour1 = ColourMapA[BASE_COLOUR(backgroundColour)].light; - uint8_t borderColour2 = ColourMapA[BASE_COLOUR(backgroundColour)].mid_dark; + uint8_t borderColour1 = ColourMapA[backgroundColour.colour].light; + uint8_t borderColour2 = ColourMapA[backgroundColour.colour].mid_dark; // Input area top border GfxFillRect( diff --git a/src/openrct2-ui/interface/Theme.cpp b/src/openrct2-ui/interface/Theme.cpp index 6e605b0db0..13c66211c4 100644 --- a/src/openrct2-ui/interface/Theme.cpp +++ b/src/openrct2-ui/interface/Theme.cpp @@ -34,6 +34,8 @@ using namespace OpenRCT2; +static constexpr uint8_t kCurrentThemeVersion = 1; + struct WindowThemeDesc; /** @@ -41,7 +43,7 @@ struct WindowThemeDesc; */ struct WindowTheme { - colour_t Colours[6]; + ColourWithFlags Colours[6]; }; /** @@ -56,7 +58,7 @@ struct UIThemeWindowEntry /** * @note json is deliberately left non-const: json_t behaviour changes when const */ - static UIThemeWindowEntry FromJson(const WindowThemeDesc* wtDesc, json_t& json); + static UIThemeWindowEntry FromJson(const WindowThemeDesc* wtDesc, json_t& json, uint8_t version); }; /** @@ -115,75 +117,84 @@ struct WindowThemeDesc #define TWINDOW(window_class, window_name, window_string_id, theme) { window_class, window_name, window_string_id, theme } +static constexpr ColourWithFlags opaque(colour_t colour) +{ + return ColourWithFlags{ colour }; +} +static constexpr ColourWithFlags translucent(colour_t colour) +{ + return ColourWithFlags{ colour, EnumToFlag(ColourFlag::translucent) }; +} + static constexpr WindowThemeDesc WindowThemeDescriptors[] = { // WindowClass WindowClassSZ WindowName NumColours, DefaultTheme - { WindowClass::TopToolbar, "WC_TOP_TOOLBAR", STR_THEMES_WINDOW_TOP_TOOLBAR, COLOURS_4(COLOUR_LIGHT_BLUE, COLOUR_DARK_GREEN, COLOUR_DARK_BROWN, COLOUR_GREY ) }, - { WindowClass::BottomToolbar, "WC_BOTTOM_TOOLBAR", STR_THEMES_WINDOW_BOTTOM_TOOLBAR, COLOURS_4(TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN), COLOUR_BLACK, COLOUR_BRIGHT_GREEN ) }, - { WindowClass::Ride, "WC_RIDE", STR_THEMES_WINDOW_RIDE, COLOURS_3(COLOUR_GREY, COLOUR_BORDEAUX_RED, COLOUR_SATURATED_GREEN ) }, - { WindowClass::RideConstruction, "WC_RIDE_CONSTRUCTION", STR_THEMES_WINDOW_RIDE_CONSTRUCTION, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) }, - { WindowClass::RideList, "WC_RIDE_LIST", STR_THEMES_WINDOW_RIDE_LIST, COLOURS_3(COLOUR_GREY, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) }, - { WindowClass::SavePrompt, "WC_SAVE_PROMPT", STR_THEMES_WINDOW_SAVE_PROMPT, COLOURS_1(TRANSLUCENT(COLOUR_BORDEAUX_RED) ) }, - { WindowClass::ConstructRide, "WC_CONSTRUCT_RIDE", STR_THEMES_WINDOW_CONSTRUCT_RIDE, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) }, - { WindowClass::DemolishRidePrompt, "WC_DEMOLISH_RIDE_PROMPT", STR_THEMES_WINDOW_DEMOLISH_RIDE_PROMPT, COLOURS_1(TRANSLUCENT(COLOUR_BORDEAUX_RED) ) }, - { WindowClass::Scenery, "WC_SCENERY", STR_THEMES_WINDOW_SCENERY, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_GREEN, COLOUR_DARK_GREEN ) }, - { WindowClass::SceneryScatter, "WC_SCENERY_SCATTER", STR_THEMES_WINDOW_SCENERY_SCATTER, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_GREEN, COLOUR_DARK_GREEN ) }, - { WindowClass::Options, "WC_OPTIONS", STR_THEMES_WINDOW_OPTIONS, COLOURS_3(COLOUR_GREY, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) }, - { WindowClass::AssetPacks, "WC_ASSET_PACKS", STR_ASSET_PACKS, COLOURS_3(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) }, - { WindowClass::Footpath, "WC_FOOTPATH", STR_THEMES_WINDOW_FOOTPATH, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) }, - { WindowClass::Land, "WC_LAND", STR_THEMES_WINDOW_LAND, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) }, - { WindowClass::Water, "WC_WATER", STR_THEMES_WINDOW_WATER, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) }, - { WindowClass::Peep, "WC_PEEP", STR_THEMES_WINDOW_PEEP, COLOURS_3(COLOUR_GREY, COLOUR_OLIVE_GREEN, COLOUR_OLIVE_GREEN ) }, - { WindowClass::GuestList, "WC_GUEST_LIST", STR_THEMES_WINDOW_GUEST_LIST, COLOURS_3(COLOUR_GREY, COLOUR_OLIVE_GREEN, COLOUR_OLIVE_GREEN ) }, - { WindowClass::StaffList, "WC_STAFF_LIST", STR_THEMES_WINDOW_STAFF_LIST, COLOURS_3(COLOUR_GREY, COLOUR_LIGHT_PURPLE, COLOUR_LIGHT_PURPLE ) }, - { WindowClass::FirePrompt, "WC_FIRE_PROMPT", STR_THEMES_WINDOW_FIRE_PROMPT, COLOURS_1(TRANSLUCENT(COLOUR_BORDEAUX_RED) ) }, - { WindowClass::ParkInformation, "WC_PARK_INFORMATION", STR_THEMES_WINDOW_PARK_INFORMATION, COLOURS_3(COLOUR_GREY, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) }, - { WindowClass::Finances, "WC_FINANCES", STR_THEMES_WINDOW_FINANCES, COLOURS_3(COLOUR_GREY, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) }, - { WindowClass::TitleMenu, "WC_TITLE_MENU", STR_THEMES_WINDOW_TITLE_MENU_BUTTONS, COLOURS_3(TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN) ) }, - { WindowClass::TitleExit, "WC_TITLE_EXIT", STR_THEMES_WINDOW_TITLE_MENU_EXIT, COLOURS_3(TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN) ) }, - { WindowClass::RecentNews, "WC_RECENT_NEWS", STR_THEMES_WINDOW_RECENT_NEWS, COLOURS_3(COLOUR_GREY, COLOUR_GREY, COLOUR_BLACK ) }, - { WindowClass::ScenarioSelect, "WC_SCENARIO_SELECT", STR_THEMES_WINDOW_TITLE_MENU_SCENARIO_SELECTION, COLOURS_3(COLOUR_GREY, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) }, - { WindowClass::TrackDesignList, "WC_TRACK_DESIGN_LIST", STR_THEMES_WINDOW_TRACK_DESIGN_LIST, COLOURS_3(COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) }, - { WindowClass::TrackDesignPlace, "WC_TRACK_DESIGN_PLACE", STR_THEMES_WINDOW_TRACK_DESIGN_PLACE, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) }, - { WindowClass::NewCampaign, "WC_NEW_CAMPAIGN", STR_THEMES_WINDOW_NEW_CAMPAIGN, COLOURS_3(COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) }, - { WindowClass::KeyboardShortcutList, "WC_KEYBOARD_SHORTCUT_LIST", STR_THEMES_WINDOW_KEYBOARD_SHORTCUT_LIST, COLOURS_3(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) }, - { WindowClass::ChangeKeyboardShortcut, "WC_CHANGE_KEYBOARD_SHORTCUT", STR_THEMES_WINDOW_CHANGE_KEYBOARD_SHORTCUT, COLOURS_3(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) }, - { WindowClass::ResetShortcutKeysPrompt, "WC_RESET_SHORTCUT_KEYS_PROMPT", STR_SHORTCUT_ACTION_RESET, COLOURS_1(TRANSLUCENT(COLOUR_BORDEAUX_RED) ) }, - { WindowClass::Map, "WC_MAP", STR_THEMES_WINDOW_MAP, COLOURS_2(COLOUR_DARK_GREEN, COLOUR_DARK_BROWN ) }, - { WindowClass::Banner, "WC_BANNER", STR_THEMES_WINDOW_BANNER, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) }, - { WindowClass::EditorObjectSelection, "WC_EDITOR_OBJECT_SELECTION", STR_THEMES_WINDOW_EDITOR_OBJECT_SELECTION, COLOURS_3(COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_GREY ) }, - { WindowClass::EditorInventionList, "WC_EDITOR_INVENTION_LIST", STR_THEMES_WINDOW_EDITOR_INVENTION_LIST, COLOURS_3(COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_GREY ) }, - { WindowClass::EditorScenarioOptions, "WC_EDITOR_SCENARIO_OPTIONS", STR_THEMES_WINDOW_EDITOR_SCENARIO_OPTIONS, COLOURS_3(COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_GREY ) }, - { WindowClass::EditorObjectiveOptions, "WC_EDITOR_OBJECTIVE_OPTIONS", STR_THEMES_WINDOW_EDTIOR_OBJECTIVE_OPTIONS, COLOURS_3(COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_GREY ) }, - { WindowClass::ManageTrackDesign, "WC_MANAGE_TRACK_DESIGN", STR_THEMES_WINDOW_MANAGE_TRACK_DESIGN, COLOURS_3(COLOUR_GREY, COLOUR_GREY, COLOUR_GREY ) }, - { WindowClass::TrackDeletePrompt, "WC_TRACK_DELETE_PROMPT", STR_THEMES_WINDOW_TRACK_DELETE_PROMPT, COLOURS_3(COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) }, - { WindowClass::InstallTrack, "WC_INSTALL_TRACK", STR_THEMES_WINDOW_INSTALL_TRACK, COLOURS_3(COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) }, - { WindowClass::ClearScenery, "WC_CLEAR_SCENERY", STR_THEMES_WINDOW_CLEAR_SCENERY, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) }, - { WindowClass::Cheats, "WC_CHEATS", STR_CHEAT_TITLE, COLOURS_2(COLOUR_GREY, COLOUR_DARK_YELLOW ) }, - { WindowClass::Research, "WC_RESEARCH", STR_THEMES_WINDOW_RESEARCH, COLOURS_3(COLOUR_GREY, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) }, - { WindowClass::Viewport, "WC_VIEWPORT", STR_THEMES_WINDOW_VIEWPORT, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) }, - { WindowClass::Mapgen, "WC_MAPGEN", STR_THEMES_WINDOW_MAPGEN, COLOURS_3(COLOUR_DARK_GREEN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) }, - { WindowClass::Loadsave, "WC_LOADSAVE", STR_THEMES_WINDOW_LOADSAVE, COLOURS_3(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) }, - { WindowClass::LoadsaveOverwritePrompt, "WC_LOADSAVE_OVERWRITE_PROMPT", STR_THEMES_WINDOW_LOADSAVE_OVERWRITE_PROMPT, COLOURS_1(TRANSLUCENT(COLOUR_BORDEAUX_RED) ) }, - { WindowClass::TitleOptions, "WC_TITLE_OPTIONS", STR_THEMES_WINDOW_TITLE_MENU_OPTIONS, COLOURS_3(TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN) ) }, - { WindowClass::LandRights, "WC_LAND_RIGHTS", STR_THEMES_WINDOW_LAND_RIGHTS, COLOURS_3(COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) }, - { WindowClass::Themes, "WC_THEMES", STR_THEMES_WINDOW_THEMES, COLOURS_3(COLOUR_GREY, COLOUR_DARK_GREEN, COLOUR_DARK_GREEN ) }, - { WindowClass::Staff, "WC_STAFF", STR_THEMES_WINDOW_STAFF, COLOURS_3(COLOUR_GREY, COLOUR_LIGHT_PURPLE, COLOUR_LIGHT_PURPLE ) }, - { WindowClass::EditorTrackBottomToolbar, "WC_EDITOR_TRACK_BOTTOM_TOOLBAR", STR_THEMES_WINDOW_BOTTOM_TOOLBAR_TRACK_EDITOR, COLOURS_3(TRANSLUCENT(COLOUR_LIGHT_BLUE), TRANSLUCENT(COLOUR_LIGHT_BLUE), TRANSLUCENT(COLOUR_LIGHT_BLUE) ) }, - { WindowClass::EditorScenarioBottomToolbar, "WC_EDITOR_SCENARIO_BOTTOM_TOOLBAR", STR_THEMES_WINDOW_BOTTOM_TOOLBAR_SCENARIO_EDITOR, COLOURS_3(TRANSLUCENT(COLOUR_LIGHT_BROWN), TRANSLUCENT(COLOUR_LIGHT_BROWN), TRANSLUCENT(COLOUR_MOSS_GREEN) ) }, - { WindowClass::TileInspector, "WC_TILE_INSPECTOR", STR_TILE_INSPECTOR_TITLE, COLOURS_2(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) }, - { WindowClass::ViewClipping, "WC_VIEW_CLIPPING", STR_VIEW_CLIPPING_TITLE, COLOURS_1(COLOUR_DARK_GREEN ) }, - { WindowClass::PatrolArea, "WC_PATROL_AREA", STR_SET_PATROL_AREA, COLOURS_3(COLOUR_LIGHT_PURPLE, COLOUR_LIGHT_PURPLE, COLOUR_LIGHT_PURPLE ) }, - { WindowClass::Transparency, "WC_TRANSPARENCY", STR_TRANSPARENCY_OPTIONS_TITLE, COLOURS_3(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) }, - { WindowClass::About, "WC_ABOUT", STR_ABOUT, COLOURS_2(COLOUR_GREY, COLOUR_LIGHT_BLUE ) }, - { WindowClass::Changelog, "WC_CHANGELOG", STR_CHANGELOG_TITLE, COLOURS_2(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) }, - { WindowClass::Multiplayer, "WC_MULTIPLAYER", STR_MULTIPLAYER, COLOURS_3(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) }, - { WindowClass::Player, "WC_PLAYER", STR_THEMES_WINDOW_PLAYER, COLOURS_3(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) }, - { WindowClass::NetworkStatus, "WC_NETWORK_STATUS", STR_THEMES_WINDOW_NETWORK_STATUS, COLOURS_1(COLOUR_BLACK ) }, - { WindowClass::ServerList, "WC_SERVER_LIST", STR_SERVER_LIST, COLOURS_2(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) }, - { WindowClass::Chat, "WC_CHAT", STR_CHAT, COLOURS_1(TRANSLUCENT(COLOUR_GREY) ) }, - { WindowClass::Console, "WC_CONSOLE", STR_CONSOLE, COLOURS_2(TRANSLUCENT(COLOUR_LIGHT_BLUE), COLOUR_WHITE ) }, - { WindowClass::ProgressWindow, "WC_PROGRESS_WINDOW", STR_THEME_LOADING_WINDOW, COLOURS_1(COLOUR_BLACK ) }, + { WindowClass::TopToolbar, "WC_TOP_TOOLBAR", STR_THEMES_WINDOW_TOP_TOOLBAR, COLOURS_4(opaque(COLOUR_LIGHT_BLUE), opaque(COLOUR_DARK_GREEN), opaque(COLOUR_DARK_BROWN), opaque(COLOUR_GREY) ) }, + { WindowClass::BottomToolbar, "WC_BOTTOM_TOOLBAR", STR_THEMES_WINDOW_BOTTOM_TOOLBAR, COLOURS_4(translucent(COLOUR_DARK_GREEN), translucent(COLOUR_DARK_GREEN), opaque(COLOUR_BLACK), opaque(COLOUR_BRIGHT_GREEN) ) }, + { WindowClass::Ride, "WC_RIDE", STR_THEMES_WINDOW_RIDE, COLOURS_3(opaque(COLOUR_GREY), opaque(COLOUR_BORDEAUX_RED), opaque(COLOUR_SATURATED_GREEN) ) }, + { WindowClass::RideConstruction, "WC_RIDE_CONSTRUCTION", STR_THEMES_WINDOW_RIDE_CONSTRUCTION, COLOURS_3(opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN) ) }, + { WindowClass::RideList, "WC_RIDE_LIST", STR_THEMES_WINDOW_RIDE_LIST, COLOURS_3(opaque(COLOUR_GREY), opaque(COLOUR_BORDEAUX_RED), opaque(COLOUR_BORDEAUX_RED) ) }, + { WindowClass::SavePrompt, "WC_SAVE_PROMPT", STR_THEMES_WINDOW_SAVE_PROMPT, COLOURS_1(translucent(COLOUR_BORDEAUX_RED) ) }, + { WindowClass::ConstructRide, "WC_CONSTRUCT_RIDE", STR_THEMES_WINDOW_CONSTRUCT_RIDE, COLOURS_3(opaque(COLOUR_DARK_BROWN), opaque(COLOUR_BORDEAUX_RED), opaque(COLOUR_BORDEAUX_RED) ) }, + { WindowClass::DemolishRidePrompt, "WC_DEMOLISH_RIDE_PROMPT", STR_THEMES_WINDOW_DEMOLISH_RIDE_PROMPT, COLOURS_1(translucent(COLOUR_BORDEAUX_RED) ) }, + { WindowClass::Scenery, "WC_SCENERY", STR_THEMES_WINDOW_SCENERY, COLOURS_3(opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_GREEN), opaque(COLOUR_DARK_GREEN) ) }, + { WindowClass::SceneryScatter, "WC_SCENERY_SCATTER", STR_THEMES_WINDOW_SCENERY_SCATTER, COLOURS_3(opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_GREEN), opaque(COLOUR_DARK_GREEN) ) }, + { WindowClass::Options, "WC_OPTIONS", STR_THEMES_WINDOW_OPTIONS, COLOURS_3(opaque(COLOUR_GREY), opaque(COLOUR_LIGHT_BLUE), opaque(COLOUR_LIGHT_BLUE) ) }, + { WindowClass::AssetPacks, "WC_ASSET_PACKS", STR_ASSET_PACKS, COLOURS_3(opaque(COLOUR_LIGHT_BLUE), opaque(COLOUR_LIGHT_BLUE), opaque(COLOUR_LIGHT_BLUE) ) }, + { WindowClass::Footpath, "WC_FOOTPATH", STR_THEMES_WINDOW_FOOTPATH, COLOURS_3(opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN) ) }, + { WindowClass::Land, "WC_LAND", STR_THEMES_WINDOW_LAND, COLOURS_3(opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN) ) }, + { WindowClass::Water, "WC_WATER", STR_THEMES_WINDOW_WATER, COLOURS_3(opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN) ) }, + { WindowClass::Peep, "WC_PEEP", STR_THEMES_WINDOW_PEEP, COLOURS_3(opaque(COLOUR_GREY), opaque(COLOUR_OLIVE_GREEN), opaque(COLOUR_OLIVE_GREEN) ) }, + { WindowClass::GuestList, "WC_GUEST_LIST", STR_THEMES_WINDOW_GUEST_LIST, COLOURS_3(opaque(COLOUR_GREY), opaque(COLOUR_OLIVE_GREEN), opaque(COLOUR_OLIVE_GREEN) ) }, + { WindowClass::StaffList, "WC_STAFF_LIST", STR_THEMES_WINDOW_STAFF_LIST, COLOURS_3(opaque(COLOUR_GREY), opaque(COLOUR_LIGHT_PURPLE), opaque(COLOUR_LIGHT_PURPLE) ) }, + { WindowClass::FirePrompt, "WC_FIRE_PROMPT", STR_THEMES_WINDOW_FIRE_PROMPT, COLOURS_1(translucent(COLOUR_BORDEAUX_RED) ) }, + { WindowClass::ParkInformation, "WC_PARK_INFORMATION", STR_THEMES_WINDOW_PARK_INFORMATION, COLOURS_3(opaque(COLOUR_GREY), opaque(COLOUR_DARK_YELLOW), opaque(COLOUR_DARK_YELLOW) ) }, + { WindowClass::Finances, "WC_FINANCES", STR_THEMES_WINDOW_FINANCES, COLOURS_3(opaque(COLOUR_GREY), opaque(COLOUR_DARK_YELLOW), opaque(COLOUR_DARK_YELLOW) ) }, + { WindowClass::TitleMenu, "WC_TITLE_MENU", STR_THEMES_WINDOW_TITLE_MENU_BUTTONS, COLOURS_3(translucent(COLOUR_DARK_GREEN), translucent(COLOUR_DARK_GREEN), translucent(COLOUR_DARK_GREEN) ) }, + { WindowClass::TitleExit, "WC_TITLE_EXIT", STR_THEMES_WINDOW_TITLE_MENU_EXIT, COLOURS_3(translucent(COLOUR_DARK_GREEN), translucent(COLOUR_DARK_GREEN), translucent(COLOUR_DARK_GREEN) ) }, + { WindowClass::RecentNews, "WC_RECENT_NEWS", STR_THEMES_WINDOW_RECENT_NEWS, COLOURS_3(opaque(COLOUR_GREY), opaque(COLOUR_GREY), opaque(COLOUR_BLACK) ) }, + { WindowClass::ScenarioSelect, "WC_SCENARIO_SELECT", STR_THEMES_WINDOW_TITLE_MENU_SCENARIO_SELECTION, COLOURS_3(opaque(COLOUR_GREY), opaque(COLOUR_BORDEAUX_RED), opaque(COLOUR_BORDEAUX_RED) ) }, + { WindowClass::TrackDesignList, "WC_TRACK_DESIGN_LIST", STR_THEMES_WINDOW_TRACK_DESIGN_LIST, COLOURS_3(opaque(COLOUR_BORDEAUX_RED), opaque(COLOUR_BORDEAUX_RED), opaque(COLOUR_BORDEAUX_RED) ) }, + { WindowClass::TrackDesignPlace, "WC_TRACK_DESIGN_PLACE", STR_THEMES_WINDOW_TRACK_DESIGN_PLACE, COLOURS_3(opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN) ) }, + { WindowClass::NewCampaign, "WC_NEW_CAMPAIGN", STR_THEMES_WINDOW_NEW_CAMPAIGN, COLOURS_3(opaque(COLOUR_DARK_YELLOW), opaque(COLOUR_DARK_YELLOW), opaque(COLOUR_DARK_YELLOW) ) }, + { WindowClass::KeyboardShortcutList, "WC_KEYBOARD_SHORTCUT_LIST", STR_THEMES_WINDOW_KEYBOARD_SHORTCUT_LIST, COLOURS_3(opaque(COLOUR_LIGHT_BLUE), opaque(COLOUR_LIGHT_BLUE), opaque(COLOUR_LIGHT_BLUE) ) }, + { WindowClass::ChangeKeyboardShortcut, "WC_CHANGE_KEYBOARD_SHORTCUT", STR_THEMES_WINDOW_CHANGE_KEYBOARD_SHORTCUT, COLOURS_3(opaque(COLOUR_LIGHT_BLUE), opaque(COLOUR_LIGHT_BLUE), opaque(COLOUR_LIGHT_BLUE) ) }, + { WindowClass::ResetShortcutKeysPrompt, "WC_RESET_SHORTCUT_KEYS_PROMPT", STR_SHORTCUT_ACTION_RESET, COLOURS_1(translucent(COLOUR_BORDEAUX_RED) ) }, + { WindowClass::Map, "WC_MAP", STR_THEMES_WINDOW_MAP, COLOURS_2(opaque(COLOUR_DARK_GREEN), opaque(COLOUR_DARK_BROWN) ) }, + { WindowClass::Banner, "WC_BANNER", STR_THEMES_WINDOW_BANNER, COLOURS_3(opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN) ) }, + { WindowClass::EditorObjectSelection, "WC_EDITOR_OBJECT_SELECTION", STR_THEMES_WINDOW_EDITOR_OBJECT_SELECTION, COLOURS_3(opaque(COLOUR_LIGHT_PURPLE), opaque(COLOUR_GREY), opaque(COLOUR_GREY) ) }, + { WindowClass::EditorInventionList, "WC_EDITOR_INVENTION_LIST", STR_THEMES_WINDOW_EDITOR_INVENTION_LIST, COLOURS_3(opaque(COLOUR_LIGHT_PURPLE), opaque(COLOUR_GREY), opaque(COLOUR_GREY) ) }, + { WindowClass::EditorScenarioOptions, "WC_EDITOR_SCENARIO_OPTIONS", STR_THEMES_WINDOW_EDITOR_SCENARIO_OPTIONS, COLOURS_3(opaque(COLOUR_LIGHT_PURPLE), opaque(COLOUR_GREY), opaque(COLOUR_GREY) ) }, + { WindowClass::EditorObjectiveOptions, "WC_EDITOR_OBJECTIVE_OPTIONS", STR_THEMES_WINDOW_EDTIOR_OBJECTIVE_OPTIONS, COLOURS_3(opaque(COLOUR_LIGHT_PURPLE), opaque(COLOUR_GREY), opaque(COLOUR_GREY) ) }, + { WindowClass::ManageTrackDesign, "WC_MANAGE_TRACK_DESIGN", STR_THEMES_WINDOW_MANAGE_TRACK_DESIGN, COLOURS_3(opaque(COLOUR_GREY), opaque(COLOUR_GREY), opaque(COLOUR_GREY) ) }, + { WindowClass::TrackDeletePrompt, "WC_TRACK_DELETE_PROMPT", STR_THEMES_WINDOW_TRACK_DELETE_PROMPT, COLOURS_3(opaque(COLOUR_BORDEAUX_RED), opaque(COLOUR_BORDEAUX_RED), opaque(COLOUR_BORDEAUX_RED) ) }, + { WindowClass::InstallTrack, "WC_INSTALL_TRACK", STR_THEMES_WINDOW_INSTALL_TRACK, COLOURS_3(opaque(COLOUR_BORDEAUX_RED), opaque(COLOUR_BORDEAUX_RED), opaque(COLOUR_BORDEAUX_RED) ) }, + { WindowClass::ClearScenery, "WC_CLEAR_SCENERY", STR_THEMES_WINDOW_CLEAR_SCENERY, COLOURS_3(opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN) ) }, + { WindowClass::Cheats, "WC_CHEATS", STR_CHEAT_TITLE, COLOURS_2(opaque(COLOUR_GREY), opaque(COLOUR_DARK_YELLOW) ) }, + { WindowClass::Research, "WC_RESEARCH", STR_THEMES_WINDOW_RESEARCH, COLOURS_3(opaque(COLOUR_GREY), opaque(COLOUR_DARK_YELLOW), opaque(COLOUR_DARK_YELLOW) ) }, + { WindowClass::Viewport, "WC_VIEWPORT", STR_THEMES_WINDOW_VIEWPORT, COLOURS_3(opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN) ) }, + { WindowClass::Mapgen, "WC_MAPGEN", STR_THEMES_WINDOW_MAPGEN, COLOURS_3(opaque(COLOUR_DARK_GREEN), opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN) ) }, + { WindowClass::Loadsave, "WC_LOADSAVE", STR_THEMES_WINDOW_LOADSAVE, COLOURS_3(opaque(COLOUR_LIGHT_BLUE), opaque(COLOUR_LIGHT_BLUE), opaque(COLOUR_LIGHT_BLUE) ) }, + { WindowClass::LoadsaveOverwritePrompt, "WC_LOADSAVE_OVERWRITE_PROMPT", STR_THEMES_WINDOW_LOADSAVE_OVERWRITE_PROMPT, COLOURS_1(translucent(COLOUR_BORDEAUX_RED) ) }, + { WindowClass::TitleOptions, "WC_TITLE_OPTIONS", STR_THEMES_WINDOW_TITLE_MENU_OPTIONS, COLOURS_3(translucent(COLOUR_DARK_GREEN), translucent(COLOUR_DARK_GREEN), translucent(COLOUR_DARK_GREEN) ) }, + { WindowClass::LandRights, "WC_LAND_RIGHTS", STR_THEMES_WINDOW_LAND_RIGHTS, COLOURS_3(opaque(COLOUR_DARK_YELLOW), opaque(COLOUR_DARK_YELLOW), opaque(COLOUR_DARK_YELLOW) ) }, + { WindowClass::Themes, "WC_THEMES", STR_THEMES_WINDOW_THEMES, COLOURS_3(opaque(COLOUR_GREY), opaque(COLOUR_DARK_GREEN), opaque(COLOUR_DARK_GREEN) ) }, + { WindowClass::Staff, "WC_STAFF", STR_THEMES_WINDOW_STAFF, COLOURS_3(opaque(COLOUR_GREY), opaque(COLOUR_LIGHT_PURPLE), opaque(COLOUR_LIGHT_PURPLE) ) }, + { WindowClass::EditorTrackBottomToolbar, "WC_EDITOR_TRACK_BOTTOM_TOOLBAR", STR_THEMES_WINDOW_BOTTOM_TOOLBAR_TRACK_EDITOR, COLOURS_3(translucent(COLOUR_LIGHT_BLUE), translucent(COLOUR_LIGHT_BLUE), translucent(COLOUR_LIGHT_BLUE) ) }, + { WindowClass::EditorScenarioBottomToolbar, "WC_EDITOR_SCENARIO_BOTTOM_TOOLBAR", STR_THEMES_WINDOW_BOTTOM_TOOLBAR_SCENARIO_EDITOR, COLOURS_3(translucent(COLOUR_LIGHT_BROWN), translucent(COLOUR_LIGHT_BROWN), translucent(COLOUR_MOSS_GREEN) ) }, + { WindowClass::TileInspector, "WC_TILE_INSPECTOR", STR_TILE_INSPECTOR_TITLE, COLOURS_2(opaque(COLOUR_LIGHT_BLUE), opaque(COLOUR_LIGHT_BLUE) ) }, + { WindowClass::ViewClipping, "WC_VIEW_CLIPPING", STR_VIEW_CLIPPING_TITLE, COLOURS_1(opaque(COLOUR_DARK_GREEN) ) }, + { WindowClass::PatrolArea, "WC_PATROL_AREA", STR_SET_PATROL_AREA, COLOURS_3(opaque(COLOUR_LIGHT_PURPLE), opaque(COLOUR_LIGHT_PURPLE), opaque(COLOUR_LIGHT_PURPLE) ) }, + { WindowClass::Transparency, "WC_TRANSPARENCY", STR_TRANSPARENCY_OPTIONS_TITLE, COLOURS_3(opaque(COLOUR_LIGHT_BLUE), opaque(COLOUR_LIGHT_BLUE), opaque(COLOUR_LIGHT_BLUE) ) }, + { WindowClass::About, "WC_ABOUT", STR_ABOUT, COLOURS_2(opaque(COLOUR_GREY), opaque(COLOUR_LIGHT_BLUE) ) }, + { WindowClass::Changelog, "WC_CHANGELOG", STR_CHANGELOG_TITLE, COLOURS_2(opaque(COLOUR_LIGHT_BLUE), opaque(COLOUR_LIGHT_BLUE) ) }, + { WindowClass::Multiplayer, "WC_MULTIPLAYER", STR_MULTIPLAYER, COLOURS_3(opaque(COLOUR_LIGHT_BLUE), opaque(COLOUR_LIGHT_BLUE), opaque(COLOUR_LIGHT_BLUE) ) }, + { WindowClass::Player, "WC_PLAYER", STR_THEMES_WINDOW_PLAYER, COLOURS_3(opaque(COLOUR_LIGHT_BLUE), opaque(COLOUR_LIGHT_BLUE), opaque(COLOUR_LIGHT_BLUE) ) }, + { WindowClass::NetworkStatus, "WC_NETWORK_STATUS", STR_THEMES_WINDOW_NETWORK_STATUS, COLOURS_1(opaque(COLOUR_BLACK) ) }, + { WindowClass::ServerList, "WC_SERVER_LIST", STR_SERVER_LIST, COLOURS_2(opaque(COLOUR_LIGHT_BLUE), opaque(COLOUR_LIGHT_BLUE) ) }, + { WindowClass::Chat, "WC_CHAT", STR_CHAT, COLOURS_1(translucent(COLOUR_GREY) ) }, + { WindowClass::Console, "WC_CONSOLE", STR_CONSOLE, COLOURS_2(translucent(COLOUR_LIGHT_BLUE), opaque(COLOUR_WHITE) ) }, + { WindowClass::ProgressWindow, "WC_PROGRESS_WINDOW", STR_THEME_LOADING_WINDOW, COLOURS_1(opaque(COLOUR_BLACK) ) }, }; #pragma endregion @@ -194,28 +205,28 @@ static constexpr WindowThemeDesc WindowThemeDescriptors[] = static constexpr UIThemeWindowEntry PredefinedThemeRCT1_Entries[] = { - { WindowClass::TopToolbar, COLOURS_RCT1(COLOUR_GREY, COLOUR_GREY, COLOUR_GREY, COLOUR_GREY, COLOUR_BLACK, COLOUR_BLACK) }, - { WindowClass::BottomToolbar, COLOURS_RCT1(TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), COLOUR_BLACK, COLOUR_YELLOW, COLOUR_BLACK, COLOUR_BLACK) }, - { WindowClass::Ride, COLOURS_RCT1(COLOUR_BORDEAUX_RED, COLOUR_GREY, COLOUR_SATURATED_GREEN, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) }, - { WindowClass::RideList, COLOURS_RCT1(COLOUR_BORDEAUX_RED, COLOUR_GREY, COLOUR_GREY, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) }, - { WindowClass::ConstructRide, COLOURS_RCT1(COLOUR_BORDEAUX_RED, COLOUR_GREY, COLOUR_GREY, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) }, - { WindowClass::Peep, COLOURS_RCT1(COLOUR_LIGHT_BROWN, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) }, - { WindowClass::GuestList, COLOURS_RCT1(COLOUR_LIGHT_BROWN, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) }, - { WindowClass::StaffList, COLOURS_RCT1(COLOUR_DARK_GREEN, COLOUR_LIGHT_PURPLE, COLOUR_LIGHT_PURPLE, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) }, - { WindowClass::Finances, COLOURS_RCT1(COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_GREY, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) }, - { WindowClass::TitleMenu, COLOURS_RCT1(TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) }, - { WindowClass::TitleExit, COLOURS_RCT1(TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) }, - { WindowClass::NewCampaign, COLOURS_RCT1(COLOUR_LIGHT_PURPLE, COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) }, - { WindowClass::TitleOptions, COLOURS_RCT1(TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) }, - { WindowClass::Staff, COLOURS_RCT1(COLOUR_DARK_GREEN, COLOUR_LIGHT_PURPLE, COLOUR_LIGHT_PURPLE, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) }, - { WindowClass::Options, COLOURS_RCT1(COLOUR_GREY, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) }, - { WindowClass::AssetPacks, COLOURS_RCT1(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) }, - { WindowClass::KeyboardShortcutList, COLOURS_RCT1(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) }, - { WindowClass::ChangeKeyboardShortcut, COLOURS_RCT1(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) }, - { WindowClass::TrackDesignList, COLOURS_RCT1(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) }, - { WindowClass::Map, COLOURS_RCT1(COLOUR_DARK_BROWN, COLOUR_GREY, COLOUR_GREY, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) }, - { WindowClass::About, COLOURS_RCT1(COLOUR_GREY, COLOUR_DARK_BROWN, COLOUR_WHITE, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) }, - { WindowClass::Changelog, COLOURS_RCT1(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_WHITE, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) }, + { WindowClass::TopToolbar, COLOURS_RCT1(opaque(COLOUR_GREY), opaque(COLOUR_GREY), opaque(COLOUR_GREY), opaque(COLOUR_GREY), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK)) }, + { WindowClass::BottomToolbar, COLOURS_RCT1(translucent(COLOUR_GREY), translucent(COLOUR_GREY), opaque(COLOUR_BLACK), opaque(COLOUR_YELLOW), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK)) }, + { WindowClass::Ride, COLOURS_RCT1(opaque(COLOUR_BORDEAUX_RED), opaque(COLOUR_GREY), opaque(COLOUR_SATURATED_GREEN), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK)) }, + { WindowClass::RideList, COLOURS_RCT1(opaque(COLOUR_BORDEAUX_RED), opaque(COLOUR_GREY), opaque(COLOUR_GREY), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK)) }, + { WindowClass::ConstructRide, COLOURS_RCT1(opaque(COLOUR_BORDEAUX_RED), opaque(COLOUR_GREY), opaque(COLOUR_GREY), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK)) }, + { WindowClass::Peep, COLOURS_RCT1(opaque(COLOUR_LIGHT_BROWN), opaque(COLOUR_BORDEAUX_RED), opaque(COLOUR_BORDEAUX_RED), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK)) }, + { WindowClass::GuestList, COLOURS_RCT1(opaque(COLOUR_LIGHT_BROWN), opaque(COLOUR_BORDEAUX_RED), opaque(COLOUR_BORDEAUX_RED), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK)) }, + { WindowClass::StaffList, COLOURS_RCT1(opaque(COLOUR_DARK_GREEN), opaque(COLOUR_LIGHT_PURPLE), opaque(COLOUR_LIGHT_PURPLE), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK)) }, + { WindowClass::Finances, COLOURS_RCT1(opaque(COLOUR_LIGHT_PURPLE), opaque(COLOUR_GREY), opaque(COLOUR_GREY), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK)) }, + { WindowClass::TitleMenu, COLOURS_RCT1(translucent(COLOUR_GREY), translucent(COLOUR_GREY), translucent(COLOUR_GREY), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK)) }, + { WindowClass::TitleExit, COLOURS_RCT1(translucent(COLOUR_GREY), translucent(COLOUR_GREY), translucent(COLOUR_GREY), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK)) }, + { WindowClass::NewCampaign, COLOURS_RCT1(opaque(COLOUR_LIGHT_PURPLE), opaque(COLOUR_LIGHT_PURPLE), opaque(COLOUR_GREY), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK)) }, + { WindowClass::TitleOptions, COLOURS_RCT1(translucent(COLOUR_GREY), translucent(COLOUR_GREY), translucent(COLOUR_GREY), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK)) }, + { WindowClass::Staff, COLOURS_RCT1(opaque(COLOUR_DARK_GREEN), opaque(COLOUR_LIGHT_PURPLE), opaque(COLOUR_LIGHT_PURPLE), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK)) }, + { WindowClass::Options, COLOURS_RCT1(opaque(COLOUR_GREY), opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK)) }, + { WindowClass::AssetPacks, COLOURS_RCT1(opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK)) }, + { WindowClass::KeyboardShortcutList, COLOURS_RCT1(opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK)) }, + { WindowClass::ChangeKeyboardShortcut, COLOURS_RCT1(opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK)) }, + { WindowClass::TrackDesignList, COLOURS_RCT1(opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK)) }, + { WindowClass::Map, COLOURS_RCT1(opaque(COLOUR_DARK_BROWN), opaque(COLOUR_GREY), opaque(COLOUR_GREY), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK)) }, + { WindowClass::About, COLOURS_RCT1(opaque(COLOUR_GREY), opaque(COLOUR_DARK_BROWN), opaque(COLOUR_WHITE), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK)) }, + { WindowClass::Changelog, COLOURS_RCT1(opaque(COLOUR_DARK_BROWN), opaque(COLOUR_DARK_BROWN), opaque(COLOUR_WHITE), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK), opaque(COLOUR_BLACK)) }, THEME_DEF_END, }; // clang-format on @@ -286,18 +297,20 @@ json_t UIThemeWindowEntry::ToJson() const json_t jsonColours = json_t::array(); for (uint8_t i = 0; i < wtDesc->NumColours; i++) { - colour_t colour = Theme.Colours[i]; - jsonColours.emplace_back(colour); + json_t jsonEntry = { { "colour", Colour::ToString(Theme.Colours[i].colour) }, + { "translucent", Theme.Colours[i].hasFlag(ColourFlag::translucent) } }; + + jsonColours.emplace_back(jsonEntry); } - json_t jsonEntry = { + json_t colourSettingsEntry = { { "colours", jsonColours }, }; - return jsonEntry; + return colourSettingsEntry; } -UIThemeWindowEntry UIThemeWindowEntry::FromJson(const WindowThemeDesc* wtDesc, json_t& jsonData) +UIThemeWindowEntry UIThemeWindowEntry::FromJson(const WindowThemeDesc* wtDesc, json_t& jsonData, uint8_t version) { Guard::Assert(jsonData.is_object(), "UIThemeWindowEntry::FromJson expects parameter jsonData to be object"); @@ -317,7 +330,20 @@ UIThemeWindowEntry UIThemeWindowEntry::FromJson(const WindowThemeDesc* wtDesc, j for (size_t i = 0; i < colourCount; i++) { - result.Theme.Colours[i] = Json::GetNumber(jsonColours[i]); + if (version == 0) + { + auto number = Json::GetNumber(jsonColours[i]); + result.Theme.Colours[i] = ColourWithFlags::fromLegacy(number); + } + else + { + auto colourObject = Json::AsObject(jsonColours[i]); + auto colour = Colour::FromString(Json::GetString(colourObject["colour"]), COLOUR_BLACK); + auto isTranslucent = Json::GetBoolean(colourObject["translucent"], false); + uint8_t flags = isTranslucent ? EnumToFlag(ColourFlag::translucent) : 0; + + result.Theme.Colours[i] = { colour, flags }; + } } return result; @@ -385,6 +411,7 @@ json_t UITheme::ToJson() const // Create theme object json_t jsonTheme = { { "name", Name }, + { "version", kCurrentThemeVersion }, { "entries", jsonEntries }, { "useLightsRide", (Flags & UITHEME_FLAG_USE_LIGHTS_RIDE) != 0 }, { "useLightsPark", (Flags & UITHEME_FLAG_USE_LIGHTS_PARK) != 0 }, @@ -422,6 +449,7 @@ UITheme* UITheme::FromJson(json_t& jsonObj) { ThrowThemeLoadException(); } + auto version = Json::GetNumber(jsonObj["version"], 0); json_t jsonEntries = jsonObj["entries"]; @@ -451,7 +479,7 @@ UITheme* UITheme::FromJson(json_t& jsonObj) continue; } - UIThemeWindowEntry entry = UIThemeWindowEntry::FromJson(wtDesc, jsonValue); + UIThemeWindowEntry entry = UIThemeWindowEntry::FromJson(wtDesc, jsonValue, version); result->SetEntry(&entry); } } @@ -730,7 +758,7 @@ size_t ThemeGetIndexForName(const utf8* name) return SIZE_MAX; } -uint8_t ThemeGetColour(WindowClass wc, uint8_t index) +ColourWithFlags ThemeGetColour(WindowClass wc, uint8_t index) { const UIThemeWindowEntry* entry = ThemeManager::CurrentTheme->GetEntry(wc); if (entry == nullptr) @@ -738,7 +766,7 @@ uint8_t ThemeGetColour(WindowClass wc, uint8_t index) const WindowThemeDesc* desc = GetWindowThemeDescriptor(wc); if (desc == nullptr) { - return 0; + return {}; } return desc->DefaultTheme.Colours[index]; } @@ -746,7 +774,7 @@ uint8_t ThemeGetColour(WindowClass wc, uint8_t index) return entry->Theme.Colours[index]; } -void ThemeSetColour(WindowClass wc, uint8_t index, colour_t colour) +void ThemeSetColour(WindowClass wc, uint8_t index, ColourWithFlags colour) { UIThemeWindowEntry entry{}; entry.Class = wc; @@ -772,55 +800,6 @@ void ThemeSetColour(WindowClass wc, uint8_t index, colour_t colour) ThemeSave(); } -// Quick and dirty mapping for new colours to original colours, until flags are extracted from colour upper bits -colour_t ThemeOverrideExtendedColour(colour_t inputColour) -{ - switch (inputColour) - { - case COLOUR_DARK_OLIVE_DARK: - case COLOUR_DARK_OLIVE_LIGHT: - return COLOUR_DARK_OLIVE_GREEN; - case COLOUR_SATURATED_BROWN_LIGHT: - return COLOUR_LIGHT_BROWN; - case COLOUR_BORDEAUX_RED_DARK: - case COLOUR_BORDEAUX_RED_LIGHT: - return COLOUR_BORDEAUX_RED; - case COLOUR_GRASS_GREEN_DARK: - case COLOUR_GRASS_GREEN_LIGHT: - return COLOUR_MOSS_GREEN; - case COLOUR_OLIVE_DARK: - case COLOUR_OLIVE_LIGHT: - return COLOUR_OLIVE_GREEN; - case COLOUR_SATURATED_GREEN_LIGHT: - return COLOUR_BRIGHT_GREEN; - case COLOUR_TAN_DARK: - case COLOUR_TAN_LIGHT: - return COLOUR_SALMON_PINK; - case COLOUR_DULL_PURPLE_LIGHT: - return COLOUR_LIGHT_PURPLE; - case COLOUR_DULL_GREEN_DARK: - case COLOUR_DULL_GREEN_LIGHT: - return COLOUR_DARK_GREEN; - case COLOUR_SATURATED_PURPLE_DARK: - case COLOUR_SATURATED_PURPLE_LIGHT: - return COLOUR_BRIGHT_PURPLE; - case COLOUR_ORANGE_LIGHT: - return COLOUR_LIGHT_ORANGE; - case COLOUR_AQUA_DARK: - return COLOUR_AQUAMARINE; - case COLOUR_MAGENTA_LIGHT: - return COLOUR_BRIGHT_PINK; - case COLOUR_DULL_BROWN_DARK: - case COLOUR_DULL_BROWN_LIGHT: - return COLOUR_DARK_BROWN; - case COLOUR_INVISIBLE: - case COLOUR_VOID: - return COLOUR_BLACK; - default: - return inputColour; - } -} - uint8_t ThemeGetFlags() { return ThemeManager::CurrentTheme->Flags; diff --git a/src/openrct2-ui/interface/Theme.h b/src/openrct2-ui/interface/Theme.h index 2d6399d699..8c5bf8d6f5 100644 --- a/src/openrct2-ui/interface/Theme.h +++ b/src/openrct2-ui/interface/Theme.h @@ -10,6 +10,7 @@ #pragma once #include +#include #include enum @@ -35,9 +36,8 @@ size_t ThemeManagerGetAvailableThemeIndex(); void ThemeManagerSetActiveAvailableTheme(size_t index); size_t ThemeGetIndexForName(const utf8* name); -colour_t ThemeGetColour(WindowClass wc, uint8_t index); -void ThemeSetColour(WindowClass wc, uint8_t index, colour_t colour); -colour_t ThemeOverrideExtendedColour(colour_t inputColour); +ColourWithFlags ThemeGetColour(WindowClass wc, uint8_t index); +void ThemeSetColour(WindowClass wc, uint8_t index, ColourWithFlags colour); uint8_t ThemeGetFlags(); void ThemeSetFlags(uint8_t flags); void ThemeSave(); diff --git a/src/openrct2-ui/interface/Widget.cpp b/src/openrct2-ui/interface/Widget.cpp index f66b2e629a..30307c3c0c 100644 --- a/src/openrct2-ui/interface/Widget.cpp +++ b/src/openrct2-ui/interface/Widget.cpp @@ -40,9 +40,9 @@ static void WidgetCheckboxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wi static void WidgetCloseboxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex); static void WidgetScrollDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex); static void WidgetHScrollbarDraw( - DrawPixelInfo& dpi, const ScrollBar& scroll, int32_t l, int32_t t, int32_t r, int32_t b, int32_t colour); + DrawPixelInfo& dpi, const ScrollBar& scroll, int32_t l, int32_t t, int32_t r, int32_t b, ColourWithFlags colour); static void WidgetVScrollbarDraw( - DrawPixelInfo& dpi, const ScrollBar& scroll, int32_t l, int32_t t, int32_t r, int32_t b, int32_t colour); + DrawPixelInfo& dpi, const ScrollBar& scroll, int32_t l, int32_t t, int32_t r, int32_t b, ColourWithFlags colour); static void WidgetDrawImage(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetIndex); /** @@ -135,8 +135,7 @@ static void WidgetFrameDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widge // uint8_t press = ((w.flags & WF_10) ? INSET_RECT_FLAG_FILL_MID_LIGHT : 0); - // Get the colour - uint8_t colour = w.colours[widget.colour]; + auto colour = w.colours[widget.colour]; // Draw the frame GfxFillRectInset(dpi, { leftTop, { r, b } }, colour, press); @@ -149,7 +148,7 @@ static void WidgetFrameDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widge // Draw the resize sprite at the bottom right corner leftTop = w.windowPos + ScreenCoordsXY{ widget.right - 18, widget.bottom - 18 }; - GfxDrawSprite(dpi, ImageId(SPR_RESIZE, colour & 0x7F), leftTop); + GfxDrawSprite(dpi, ImageId(SPR_RESIZE, colour.colour), leftTop); } /** @@ -166,8 +165,7 @@ static void WidgetResizeDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widg int32_t r = w.windowPos.x + widget.right; int32_t b = w.windowPos.y + widget.bottom; - // Get the colour - uint8_t colour = w.colours[widget.colour]; + auto colour = w.colours[widget.colour]; // Draw the panel GfxFillRectInset(dpi, { leftTop, { r, b } }, colour, 0); @@ -180,7 +178,7 @@ static void WidgetResizeDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widg // Draw the resize sprite at the bottom right corner leftTop = w.windowPos + ScreenCoordsXY{ widget.right - 18, widget.bottom - 18 }; - GfxDrawSprite(dpi, ImageId(SPR_RESIZE, colour & 0x7F), leftTop); + GfxDrawSprite(dpi, ImageId(SPR_RESIZE, colour.colour), leftTop); } /** @@ -199,8 +197,7 @@ static void WidgetButtonDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widg // Check if the button is pressed down uint8_t press = WidgetIsPressed(w, widgetIndex) || WidgetIsActiveTool(w, widgetIndex) ? INSET_RECT_FLAG_BORDER_INSET : 0; - // Get the colour - uint8_t colour = w.colours[widget.colour]; + auto colour = w.colours[widget.colour]; if (static_cast(widget.image.ToUInt32()) == -2) { @@ -256,7 +253,7 @@ static void WidgetTabDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetI auto leftTop = w.windowPos + ScreenCoordsXY{ widget.left, widget.top }; // Get the colour and disabled image - auto colour = w.colours[widget.colour] & 0x7F; + auto colour = w.colours[widget.colour].colour; const auto newIndex = widget.image.GetIndex() + 2; auto image = widget.image.WithIndex(newIndex).WithPrimary(colour); @@ -283,8 +280,7 @@ static void WidgetFlatButtonDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex ScreenRect rect{ w.windowPos + ScreenCoordsXY{ widget.left, widget.top }, w.windowPos + ScreenCoordsXY{ widget.right, widget.bottom } }; - // Get the colour - uint8_t colour = w.colours[widget.colour]; + auto colour = w.colours[widget.colour]; // Check if the button is pressed down if (WidgetIsPressed(w, widgetIndex) || WidgetIsActiveTool(w, widgetIndex)) @@ -317,8 +313,7 @@ static void WidgetTextButton(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widg ScreenRect rect{ w.windowPos + ScreenCoordsXY{ widget.left, widget.top }, w.windowPos + ScreenCoordsXY{ widget.right, widget.bottom } }; - // Get the colour - uint8_t colour = w.colours[widget.colour]; + auto colour = w.colours[widget.colour]; // Border uint8_t press = WidgetIsPressed(w, widgetIndex) || WidgetIsActiveTool(w, widgetIndex) ? INSET_RECT_FLAG_BORDER_INSET : 0; @@ -347,11 +342,10 @@ static void WidgetTextCentred(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wid if (widget.text == STR_NONE) return; - // Get the colour - colour_t colour = w.colours[widget.colour]; - colour &= ~(COLOUR_FLAG_TRANSLUCENT); + auto colour = w.colours[widget.colour]; + colour.setFlag(ColourFlag::translucent, false); if (WidgetIsDisabled(w, widgetIndex)) - colour |= COLOUR_FLAG_INSET; + colour.setFlag(ColourFlag::inset, true); // Resolve the absolute ltrb auto topLeft = w.windowPos + ScreenCoordsXY{ widget.left, 0 }; @@ -393,10 +387,9 @@ static void WidgetText(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widgetInde if (widget.text == STR_NONE || widget.content == kWidgetContentEmpty) return; - // Get the colour - uint8_t colour = w.colours[widget.colour]; + auto colour = w.colours[widget.colour]; if (WidgetIsDisabled(w, widgetIndex)) - colour |= COLOUR_FLAG_INSET; + colour.setFlag(ColourFlag::inset, true); // Resolve the absolute ltrb int32_t l = w.windowPos.x + widget.left; @@ -443,8 +436,7 @@ static void WidgetTextInset(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widge ScreenRect rect{ w.windowPos + ScreenCoordsXY{ widget.left, widget.top }, w.windowPos + ScreenCoordsXY{ widget.right, widget.bottom } }; - // Get the colour - uint8_t colour = w.colours[widget.colour]; + auto colour = w.colours[widget.colour]; GfxFillRectInset(dpi, rect, colour, INSET_RECT_F_60); WidgetText(dpi, w, widgetIndex); @@ -488,9 +480,9 @@ static void WidgetGroupboxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wi auto [stringId, formatArgs] = WidgetGetStringidAndArgs(widget); if (stringId != STR_NONE) { - uint8_t colour = w.colours[widget.colour] & 0x7F; + auto colour = w.colours[widget.colour].withFlag(ColourFlag::translucent, false); if (WidgetIsDisabled(w, widgetIndex)) - colour |= COLOUR_FLAG_INSET; + colour.setFlag(ColourFlag::inset, true); utf8 buffer[512] = { 0 }; OpenRCT2::FormatStringLegacy(buffer, sizeof(buffer), stringId, formatArgs); @@ -507,8 +499,7 @@ static void WidgetGroupboxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wi const auto r = w.windowPos.x + widget.right; const auto b = w.windowPos.y + widget.bottom; - // Get the colour - uint8_t colour = w.colours[widget.colour] & 0x7F; + uint8_t colour = w.colours[widget.colour].colour; // Border left of text GfxFillRect(dpi, { { l, t }, { l + 4, t } }, ColourMapA[colour].mid_dark); @@ -544,8 +535,7 @@ static void WidgetCaptionDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wid auto topLeft = w.windowPos + ScreenCoordsXY{ widget->left, widget->top }; auto bottomRight = w.windowPos + ScreenCoordsXY{ widget->right, widget->bottom }; - // Get the colour - uint8_t colour = w.colours[widget->colour]; + auto colour = w.colours[widget->colour]; uint8_t press = INSET_RECT_F_60; if (w.flags & WF_10) @@ -554,9 +544,10 @@ static void WidgetCaptionDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wid GfxFillRectInset(dpi, { topLeft, bottomRight }, colour, press); // Black caption bars look slightly green, this fixes that - if (colour == 0) + if (colour.colour == COLOUR_BLACK) GfxFillRect( - dpi, { { topLeft + ScreenCoordsXY{ 1, 1 } }, { bottomRight - ScreenCoordsXY{ 1, 1 } } }, ColourMapA[colour].dark); + dpi, { { topLeft + ScreenCoordsXY{ 1, 1 } }, { bottomRight - ScreenCoordsXY{ 1, 1 } } }, + ColourMapA[colour.colour].dark); else GfxFilterRect( dpi, { { topLeft + ScreenCoordsXY{ 1, 1 } }, { bottomRight - ScreenCoordsXY{ 1, 1 } } }, @@ -580,7 +571,7 @@ static void WidgetCaptionDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wid DrawTextEllipsised( dpi, topLeft, width, widget->text, Formatter::Common(), - { COLOUR_WHITE | static_cast(COLOUR_FLAG_OUTLINE), TextAlignment::CENTRE }); + { ColourWithFlags{ COLOUR_WHITE }.withFlag(ColourFlag::withOutline, true), TextAlignment::CENTRE }); } /** @@ -603,8 +594,7 @@ static void WidgetCloseboxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wi if (WidgetIsPressed(w, widgetIndex) || WidgetIsActiveTool(w, widgetIndex)) press |= INSET_RECT_FLAG_BORDER_INSET; - // Get the colour - uint8_t colour = w.colours[widget.colour]; + auto colour = w.colours[widget.colour]; // Draw the button GfxFillRectInset(dpi, { topLeft, bottomRight }, colour, press); @@ -615,7 +605,8 @@ static void WidgetCloseboxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wi topLeft = w.windowPos + ScreenCoordsXY{ widget.midX() - 1, std::max(widget.top, widget.midY() - 5) }; if (WidgetIsDisabled(w, widgetIndex)) - colour |= COLOUR_FLAG_INSET; + colour.setFlag(ColourFlag::inset, true); + ; DrawTextEllipsised(dpi, topLeft, widget.width() - 2, widget.text, Formatter::Common(), { colour, TextAlignment::CENTRE }); } @@ -634,22 +625,21 @@ static void WidgetCheckboxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wi ScreenCoordsXY bottomRight = w.windowPos + ScreenCoordsXY{ widget.right, widget.bottom }; ScreenCoordsXY midLeft = { topLeft.x, (topLeft.y + bottomRight.y) / 2 }; - // Get the colour - colour_t colour = w.colours[widget.colour]; + auto colour = w.colours[widget.colour]; // checkbox GfxFillRectInset(dpi, { midLeft - ScreenCoordsXY{ 0, 5 }, midLeft + ScreenCoordsXY{ 9, 4 } }, colour, INSET_RECT_F_60); if (WidgetIsDisabled(w, widgetIndex)) { - colour |= COLOUR_FLAG_INSET; + colour.setFlag(ColourFlag::inset, true); } // fill it when checkbox is pressed if (WidgetIsPressed(w, widgetIndex)) { DrawText( - dpi, { midLeft - ScreenCoordsXY{ 0, 5 } }, { static_cast(NOT_TRANSLUCENT(colour)) }, + dpi, { midLeft - ScreenCoordsXY{ 0, 5 } }, { colour.withFlag(ColourFlag::translucent, false) }, static_cast(CheckBoxMarkString)); } @@ -676,8 +666,7 @@ static void WidgetScrollDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widg ScreenCoordsXY topLeft = w.windowPos + ScreenCoordsXY{ widget.left, widget.top }; ScreenCoordsXY bottomRight = w.windowPos + ScreenCoordsXY{ widget.right, widget.bottom }; - // Get the colour - uint8_t colour = w.colours[widget.colour]; + auto colour = w.colours[widget.colour]; // Draw the border GfxFillRectInset(dpi, { topLeft, bottomRight }, colour, INSET_RECT_F_60); @@ -734,16 +723,18 @@ static void WidgetScrollDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widg } static void WidgetHScrollbarDraw( - DrawPixelInfo& dpi, const ScrollBar& scroll, int32_t l, int32_t t, int32_t r, int32_t b, int32_t colour) + DrawPixelInfo& dpi, const ScrollBar& scroll, int32_t l, int32_t t, int32_t r, int32_t b, ColourWithFlags colour) { - colour &= 0x7F; + colour.setFlag(ColourFlag::translucent, false); + // Trough - GfxFillRect(dpi, { { l + kScrollBarWidth, t }, { r - kScrollBarWidth, b } }, ColourMapA[colour].lighter); - GfxFillRect(dpi, { { l + kScrollBarWidth, t }, { r - kScrollBarWidth, b } }, 0x1000000 | ColourMapA[colour].mid_dark); - GfxFillRect(dpi, { { l + kScrollBarWidth, t + 2 }, { r - kScrollBarWidth, t + 2 } }, ColourMapA[colour].mid_dark); - GfxFillRect(dpi, { { l + kScrollBarWidth, t + 3 }, { r - kScrollBarWidth, t + 3 } }, ColourMapA[colour].lighter); - GfxFillRect(dpi, { { l + kScrollBarWidth, t + 7 }, { r - kScrollBarWidth, t + 7 } }, ColourMapA[colour].mid_dark); - GfxFillRect(dpi, { { l + kScrollBarWidth, t + 8 }, { r - kScrollBarWidth, t + 8 } }, ColourMapA[colour].lighter); + GfxFillRect(dpi, { { l + kScrollBarWidth, t }, { r - kScrollBarWidth, b } }, ColourMapA[colour.colour].lighter); + GfxFillRect( + dpi, { { l + kScrollBarWidth, t }, { r - kScrollBarWidth, b } }, 0x1000000 | ColourMapA[colour.colour].mid_dark); + GfxFillRect(dpi, { { l + kScrollBarWidth, t + 2 }, { r - kScrollBarWidth, t + 2 } }, ColourMapA[colour.colour].mid_dark); + GfxFillRect(dpi, { { l + kScrollBarWidth, t + 3 }, { r - kScrollBarWidth, t + 3 } }, ColourMapA[colour.colour].lighter); + GfxFillRect(dpi, { { l + kScrollBarWidth, t + 7 }, { r - kScrollBarWidth, t + 7 } }, ColourMapA[colour.colour].mid_dark); + GfxFillRect(dpi, { { l + kScrollBarWidth, t + 8 }, { r - kScrollBarWidth, t + 8 } }, ColourMapA[colour.colour].lighter); // Left button { @@ -772,16 +763,18 @@ static void WidgetHScrollbarDraw( } static void WidgetVScrollbarDraw( - DrawPixelInfo& dpi, const ScrollBar& scroll, int32_t l, int32_t t, int32_t r, int32_t b, int32_t colour) + DrawPixelInfo& dpi, const ScrollBar& scroll, int32_t l, int32_t t, int32_t r, int32_t b, ColourWithFlags colour) { - colour &= 0x7F; + colour.setFlag(ColourFlag::translucent, false); + // Trough - GfxFillRect(dpi, { { l, t + kScrollBarWidth }, { r, b - kScrollBarWidth } }, ColourMapA[colour].lighter); - GfxFillRect(dpi, { { l, t + kScrollBarWidth }, { r, b - kScrollBarWidth } }, 0x1000000 | ColourMapA[colour].mid_dark); - GfxFillRect(dpi, { { l + 2, t + kScrollBarWidth }, { l + 2, b - kScrollBarWidth } }, ColourMapA[colour].mid_dark); - GfxFillRect(dpi, { { l + 3, t + kScrollBarWidth }, { l + 3, b - kScrollBarWidth } }, ColourMapA[colour].lighter); - GfxFillRect(dpi, { { l + 7, t + kScrollBarWidth }, { l + 7, b - kScrollBarWidth } }, ColourMapA[colour].mid_dark); - GfxFillRect(dpi, { { l + 8, t + kScrollBarWidth }, { l + 8, b - kScrollBarWidth } }, ColourMapA[colour].lighter); + GfxFillRect(dpi, { { l, t + kScrollBarWidth }, { r, b - kScrollBarWidth } }, ColourMapA[colour.colour].lighter); + GfxFillRect( + dpi, { { l, t + kScrollBarWidth }, { r, b - kScrollBarWidth } }, 0x1000000 | ColourMapA[colour.colour].mid_dark); + GfxFillRect(dpi, { { l + 2, t + kScrollBarWidth }, { l + 2, b - kScrollBarWidth } }, ColourMapA[colour.colour].mid_dark); + GfxFillRect(dpi, { { l + 3, t + kScrollBarWidth }, { l + 3, b - kScrollBarWidth } }, ColourMapA[colour.colour].lighter); + GfxFillRect(dpi, { { l + 7, t + kScrollBarWidth }, { l + 7, b - kScrollBarWidth } }, ColourMapA[colour.colour].mid_dark); + GfxFillRect(dpi, { { l + 8, t + kScrollBarWidth }, { l + 8, b - kScrollBarWidth } }, ColourMapA[colour.colour].lighter); // Up button GfxFillRectInset( @@ -794,7 +787,7 @@ static void WidgetVScrollbarDraw( dpi, { { l, std::max(t + kScrollBarWidth, t + scroll.v_thumb_top - 1) }, { r, std::min(b - kScrollBarWidth, t + scroll.v_thumb_bottom - 1) } }, - colour, ((scroll.flags & VSCROLLBAR_THUMB_PRESSED) ? INSET_RECT_FLAG_BORDER_INSET : 0)); + { colour }, ((scroll.flags & VSCROLLBAR_THUMB_PRESSED) ? INSET_RECT_FLAG_BORDER_INSET : 0)); // Down button GfxFillRectInset( @@ -820,25 +813,21 @@ static void WidgetDrawImage(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex widge // Resolve the absolute ltrb auto screenCoords = w.windowPos + ScreenCoordsXY{ widget.left, widget.top }; - // Get the colour - uint8_t colour = NOT_TRANSLUCENT(w.colours[widget.colour]); - if (widget.type == WindowWidgetType::ColourBtn || widget.type == WindowWidgetType::TrnBtn || widget.type == WindowWidgetType::Tab) if (WidgetIsPressed(w, widgetIndex) || WidgetIsActiveTool(w, widgetIndex)) image = image.WithIndexOffset(1); + const auto colour = w.colours[widget.colour].colour; if (WidgetIsDisabled(w, widgetIndex)) { // Draw greyed out (light border bottom right shadow) - colour = w.colours[widget.colour]; - colour = ColourMapA[NOT_TRANSLUCENT(colour)].lighter; - GfxDrawSpriteSolid(dpi, image, screenCoords + ScreenCoordsXY{ 1, 1 }, colour); + auto mappedColour = ColourMapA[colour].lighter; + GfxDrawSpriteSolid(dpi, image, screenCoords + ScreenCoordsXY{ 1, 1 }, mappedColour); // Draw greyed out (dark) - colour = w.colours[widget.colour]; - colour = ColourMapA[NOT_TRANSLUCENT(colour)].mid_light; - GfxDrawSpriteSolid(dpi, image, screenCoords, colour); + mappedColour = ColourMapA[colour].mid_light; + GfxDrawSpriteSolid(dpi, image, screenCoords, mappedColour); } else { @@ -1138,15 +1127,12 @@ static void WidgetTextBoxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wid ScreenCoordsXY topLeft{ w.windowPos + ScreenCoordsXY{ widget.left, widget.top } }; ScreenCoordsXY bottomRight{ w.windowPos + ScreenCoordsXY{ widget.right, widget.bottom } }; - // Get the colour - uint8_t colour = w.colours[widget.colour]; - auto& tbIdent = OpenRCT2::Ui::Windows::GetCurrentTextBox(); bool active = w.classification == tbIdent.window.classification && w.number == tbIdent.window.number && widgetIndex == tbIdent.widget_index; // GfxFillRectInset(dpi, l, t, r, b, colour, 0x20 | (!active ? 0x40 : 0x00)); - GfxFillRectInset(dpi, { topLeft, bottomRight }, colour, INSET_RECT_F_60); + GfxFillRectInset(dpi, { topLeft, bottomRight }, w.colours[widget.colour], INSET_RECT_F_60); // Figure out where the text should be positioned vertically. topLeft.y = w.windowPos.y + widget.textTop(); @@ -1188,7 +1174,7 @@ static void WidgetTextBoxDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex wid if (OpenRCT2::Ui::Windows::TextBoxCaretIsFlashed()) { - colour = ColourMapA[w.colours[1]].mid_light; + auto colour = ColourMapA[w.colours[1].colour].mid_light; auto y = topLeft.y + (widget.height() - 1); GfxFillRect(dpi, { { curX, y }, { curX + width, y } }, colour + 5); } @@ -1221,7 +1207,7 @@ static void WidgetProgressBarDraw(DrawPixelInfo& dpi, WindowBase& w, WidgetIndex { GfxFillRectInset( dpi, { topLeft + ScreenCoordsXY{ 1, 1 }, topLeft + ScreenCoordsXY{ fillSize + 1, widget.height() - 1 } }, - widget.colour, 0); + { widget.colour }, 0); } } diff --git a/src/openrct2-ui/interface/Window.cpp b/src/openrct2-ui/interface/Window.cpp index 55f81121e3..452cf4381f 100644 --- a/src/openrct2-ui/interface/Window.cpp +++ b/src/openrct2-ui/interface/Window.cpp @@ -644,7 +644,7 @@ void WindowDrawWidgets(WindowBase& w, DrawPixelInfo& dpi) if (w.flags & WF_WHITE_BORDER_MASK) { GfxFillRectInset( - dpi, { w.windowPos, w.windowPos + ScreenCoordsXY{ w.width - 1, w.height - 1 } }, COLOUR_WHITE, + dpi, { w.windowPos, w.windowPos + ScreenCoordsXY{ w.width - 1, w.height - 1 } }, { COLOUR_WHITE }, INSET_RECT_FLAG_FILL_NONE); } } diff --git a/src/openrct2-ui/scripting/CustomListView.cpp b/src/openrct2-ui/scripting/CustomListView.cpp index c2546453b5..ff08ff2694 100644 --- a/src/openrct2-ui/scripting/CustomListView.cpp +++ b/src/openrct2-ui/scripting/CustomListView.cpp @@ -551,7 +551,7 @@ void CustomListView::MouseUp(const ScreenCoordsXY& pos) void CustomListView::Paint(WindowBase* w, DrawPixelInfo& dpi, const ScrollBar* scroll) const { - auto paletteIndex = ColourMapA[w->colours[1]].mid_light; + auto paletteIndex = ColourMapA[w->colours[1].colour].mid_light; GfxFillRect(dpi, { { dpi.x, dpi.y }, { dpi.x + dpi.width, dpi.y + dpi.height } }, paletteIndex); int32_t y = ShowColumnHeaders ? COLUMN_HEADER_HEIGHT : 0; @@ -596,7 +596,7 @@ void CustomListView::Paint(WindowBase* w, DrawPixelInfo& dpi, const ScrollBar* s { GfxFillRect( dpi, { { dpi.x, y }, { dpi.x + dpi.width, y + (kListRowHeight - 1) } }, - ColourMapA[w->colours[1]].lighter | 0x1000000); + ColourMapA[w->colours[1].colour].lighter | 0x1000000); } // Columns @@ -640,7 +640,7 @@ void CustomListView::Paint(WindowBase* w, DrawPixelInfo& dpi, const ScrollBar* s { y = scroll->v_top; - auto bgColour = ColourMapA[w->colours[1]].mid_light; + auto bgColour = ColourMapA[w->colours[1].colour].mid_light; GfxFillRect(dpi, { { dpi.x, y }, { dpi.x + dpi.width, y + 12 } }, bgColour); int32_t x = 0; @@ -704,8 +704,8 @@ void CustomListView::PaintSeperator( auto lineY1 = lineY0 + 1; auto baseColour = ParentWindow->colours[1]; - auto lightColour = ColourMapA[baseColour].lighter; - auto darkColour = ColourMapA[baseColour].mid_dark; + auto lightColour = ColourMapA[baseColour.colour].lighter; + auto darkColour = ColourMapA[baseColour.colour].mid_dark; if (hasText) { diff --git a/src/openrct2-ui/scripting/CustomWindow.cpp b/src/openrct2-ui/scripting/CustomWindow.cpp index f1a8e9ede0..2a79090b59 100644 --- a/src/openrct2-ui/scripting/CustomWindow.cpp +++ b/src/openrct2-ui/scripting/CustomWindow.cpp @@ -250,7 +250,7 @@ namespace OpenRCT2::Ui::Windows std::string Title; std::optional Id; std::vector Widgets; - std::vector Colours; + std::vector Colours; std::vector Tabs; std::optional TabIndex; @@ -302,14 +302,13 @@ namespace OpenRCT2::Ui::Windows { auto dukColours = desc["colours"].as_array(); std::transform(dukColours.begin(), dukColours.end(), std::back_inserter(result.Colours), [](const DukValue& w) { - colour_t c = COLOUR_BLACK; + ColourWithFlags c = { COLOUR_BLACK }; if (w.type() == DukValue::Type::NUMBER) { - c = std::clamp(BASE_COLOUR(w.as_int()), COLOUR_BLACK, COLOUR_COUNT - 1); - if (w.as_int() & COLOUR_FLAG_TRANSLUCENT) - { - c = TRANSLUCENT(c); - } + colour_t colour = w.as_int() & ~kLegacyColourFlagTranslucent; + auto isTranslucent = (w.as_int() & kLegacyColourFlagTranslucent); + c.colour = std::clamp(colour, COLOUR_BLACK, COLOUR_COUNT - 1); + c.flags = (isTranslucent ? EnumToFlag(ColourFlag::translucent) : 0); } return c; }); @@ -476,7 +475,7 @@ namespace OpenRCT2::Ui::Windows // This has to be called to ensure the window frame is correctly initialised - not doing this will // cause an assertion to be hit. ResizeFrameWithPage(); - widgets[WIDX_CLOSE].text = (colours[0] & COLOUR_FLAG_TRANSLUCENT) ? STR_CLOSE_X_WHITE : STR_CLOSE_X; + widgets[WIDX_CLOSE].text = colours[0].hasFlag(ColourFlag::translucent) ? STR_CLOSE_X_WHITE : STR_CLOSE_X; // Having the content panel visible for transparent windows makes the borders darker than they should be // For now just hide it if there are no tabs and the window is not resizable diff --git a/src/openrct2-ui/scripting/ScGraphicsContext.hpp b/src/openrct2-ui/scripting/ScGraphicsContext.hpp index 5db181bed3..086d14065e 100644 --- a/src/openrct2-ui/scripting/ScGraphicsContext.hpp +++ b/src/openrct2-ui/scripting/ScGraphicsContext.hpp @@ -163,13 +163,13 @@ namespace OpenRCT2::Scripting void box(int32_t x, int32_t y, int32_t width, int32_t height) { - GfxFillRectInset(_dpi, { x, y, x + width - 1, y + height - 1 }, _colour.value_or(0), 0); + GfxFillRectInset(_dpi, { x, y, x + width - 1, y + height - 1 }, { _colour.value_or(0) }, 0); } void well(int32_t x, int32_t y, int32_t width, int32_t height) { GfxFillRectInset( - _dpi, { x, y, x + width - 1, y + height - 1 }, _colour.value_or(0), + _dpi, { x, y, x + width - 1, y + height - 1 }, { _colour.value_or(0) }, INSET_RECT_FLAG_BORDER_INSET | INSET_RECT_FLAG_FILL_DONT_LIGHTEN); } diff --git a/src/openrct2-ui/scripting/ScWindow.hpp b/src/openrct2-ui/scripting/ScWindow.hpp index 1c57f3e26b..c24803b167 100644 --- a/src/openrct2-ui/scripting/ScWindow.hpp +++ b/src/openrct2-ui/scripting/ScWindow.hpp @@ -238,7 +238,10 @@ namespace OpenRCT2::Scripting result.reserve(std::size(w->colours)); for (auto c : w->colours) { - result.push_back(c); + auto colour = c.colour; + if (c.hasFlag(ColourFlag::translucent)) + colour |= kLegacyColourFlagTranslucent; + result.push_back(colour); } } return result; @@ -250,14 +253,13 @@ namespace OpenRCT2::Scripting { for (size_t i = 0; i < std::size(w->colours); i++) { - int32_t c = COLOUR_BLACK; + auto c = ColourWithFlags{ COLOUR_BLACK }; if (i < colours.size()) { - c = std::clamp(BASE_COLOUR(colours[i]), COLOUR_BLACK, COLOUR_COUNT - 1); - if (colours[i] & COLOUR_FLAG_TRANSLUCENT) - { - c = TRANSLUCENT(c); - } + colour_t colour = colours[i] & ~kLegacyColourFlagTranslucent; + auto isTranslucent = (colours[i] & kLegacyColourFlagTranslucent); + c.colour = std::clamp(colour, COLOUR_BLACK, COLOUR_COUNT - 1); + c.flags = (isTranslucent ? EnumToFlag(ColourFlag::translucent) : 0); } w->colours[i] = c; } diff --git a/src/openrct2-ui/windows/AssetPacks.cpp b/src/openrct2-ui/windows/AssetPacks.cpp index 6ff55c1f5a..fafe057c39 100644 --- a/src/openrct2-ui/windows/AssetPacks.cpp +++ b/src/openrct2-ui/windows/AssetPacks.cpp @@ -196,7 +196,7 @@ static Widget WindowAssetPacksWidgets[] = { auto dpiCoords = ScreenCoordsXY{ dpi.x, dpi.y }; GfxFillRect( dpi, { dpiCoords, dpiCoords + ScreenCoordsXY{ dpi.width - 1, dpi.height - 1 } }, - ColourMapA[colours[1]].mid_light); + ColourMapA[colours[1].colour].mid_light); auto assetPackManager = GetContext()->GetAssetPackManager(); if (assetPackManager == nullptr) @@ -243,12 +243,12 @@ static Widget WindowAssetPacksWidgets[] = { auto fillRectangle = ScreenRect{ { 0, y }, { listWidth, y + ItemHeight - 1 } }; if (isSelected) { - GfxFillRect(dpi, fillRectangle, ColourMapA[colours[1]].mid_dark); + GfxFillRect(dpi, fillRectangle, ColourMapA[colours[1].colour].mid_dark); stringId = STR_WINDOW_COLOUR_2_STRINGID; } else if (isHighlighted) { - GfxFillRect(dpi, fillRectangle, ColourMapA[colours[1]].mid_dark); + GfxFillRect(dpi, fillRectangle, ColourMapA[colours[1].colour].mid_dark); } DrawTextEllipsised(dpi, { 16, y + 1 }, listWidth, stringId, ft); diff --git a/src/openrct2-ui/windows/Banner.cpp b/src/openrct2-ui/windows/Banner.cpp index 9d32c0f8e7..1647ccd409 100644 --- a/src/openrct2-ui/windows/Banner.cpp +++ b/src/openrct2-ui/windows/Banner.cpp @@ -160,7 +160,7 @@ static Widget window_banner_widgets[] = { switch (widgetIndex) { case WIDX_MAIN_COLOUR: - WindowDropdownShowColour(this, widget, TRANSLUCENT(colours[1]), banner->colour); + WindowDropdownShowColour(this, widget, colours[1].withFlag(ColourFlag::translucent, true), banner->colour); break; case WIDX_TEXT_COLOUR_DROPDOWN_BUTTON: diff --git a/src/openrct2-ui/windows/Cheats.cpp b/src/openrct2-ui/windows/Cheats.cpp index 07fe8c8f3e..74978cdcc1 100644 --- a/src/openrct2-ui/windows/Cheats.cpp +++ b/src/openrct2-ui/windows/Cheats.cpp @@ -540,7 +540,7 @@ static StringId window_cheats_page_titles[] = { ft.Add(_moneySpinnerValue); if (IsWidgetDisabled(WIDX_MONEY_SPINNER)) { - colour |= COLOUR_FLAG_INSET; + colour.setFlag(ColourFlag::inset, true); } int32_t actual_month = _monthSpinnerValue - 1; DrawTextBasic(dpi, windowPos + ScreenCoordsXY{ _xLcol, 93 }, STR_BOTTOM_TOOLBAR_CASH, ft, { colour }); diff --git a/src/openrct2-ui/windows/DebugPaint.cpp b/src/openrct2-ui/windows/DebugPaint.cpp index b408cfc2e9..1a7fce280d 100644 --- a/src/openrct2-ui/windows/DebugPaint.cpp +++ b/src/openrct2-ui/windows/DebugPaint.cpp @@ -58,7 +58,7 @@ static Widget window_debug_paint_widgets[] = { InitScrollWidgets(); WindowPushOthersBelow(*this); - colours[0] = TRANSLUCENT(COLOUR_BLACK); + colours[0] = ColourWithFlags{ COLOUR_BLACK }.withFlag(ColourFlag::translucent, true); colours[1] = COLOUR_GREY; ResizeLanguage = LANGUAGE_UNDEFINED; diff --git a/src/openrct2-ui/windows/Dropdown.cpp b/src/openrct2-ui/windows/Dropdown.cpp index d29b417498..cb31113723 100644 --- a/src/openrct2-ui/windows/Dropdown.cpp +++ b/src/openrct2-ui/windows/Dropdown.cpp @@ -118,17 +118,18 @@ namespace OpenRCT2::Ui::Windows const ScreenCoordsXY rightBottom = leftTop + ScreenCoordsXY{ ItemWidth - 1, 0 }; const ScreenCoordsXY shadowOffset{ 0, 1 }; - if (colours[0] & COLOUR_FLAG_TRANSLUCENT) + if (colours[0].hasFlag(ColourFlag::translucent)) { - TranslucentWindowPalette palette = TranslucentWindowPalettes[BASE_COLOUR(colours[0])]; + TranslucentWindowPalette palette = TranslucentWindowPalettes[colours[0].colour]; GfxFilterRect(dpi, { leftTop, rightBottom }, palette.highlight); GfxFilterRect(dpi, { leftTop + shadowOffset, rightBottom + shadowOffset }, palette.shadow); } else { - GfxFillRect(dpi, { leftTop, rightBottom }, ColourMapA[colours[0]].mid_dark); + GfxFillRect(dpi, { leftTop, rightBottom }, ColourMapA[colours[0].colour].mid_dark); GfxFillRect( - dpi, { leftTop + shadowOffset, rightBottom + shadowOffset }, ColourMapA[colours[0]].lightest); + dpi, { leftTop + shadowOffset, rightBottom + shadowOffset }, + ColourMapA[colours[0].colour].lightest); } } else @@ -157,11 +158,11 @@ namespace OpenRCT2::Ui::Windows item++; // Calculate colour - colour_t colour = NOT_TRANSLUCENT(colours[0]); + ColourWithFlags colour = { colours[0].colour }; if (i == highlightedIndex) - colour = COLOUR_WHITE; + colour.colour = COLOUR_WHITE; if (i < Dropdown::ItemsMaxSize && Dropdown::IsDisabled(i)) - colour = NOT_TRANSLUCENT(colours[0]) | COLOUR_FLAG_INSET; + colour = { colours[0].colour, EnumToFlag(ColourFlag::inset) }; // Draw item string auto yOffset = GetAdditionalRowPadding(); @@ -182,7 +183,7 @@ namespace OpenRCT2::Ui::Windows } void SetTextItems( - const ScreenCoordsXY& screenPos, int32_t extraY, uint8_t colour, uint8_t customHeight, uint8_t txtFlags, + const ScreenCoordsXY& screenPos, int32_t extraY, ColourWithFlags colour, uint8_t customHeight, uint8_t txtFlags, size_t numItems, int32_t itemWidth) { // Set and calculate num items, rows and columns @@ -208,13 +209,13 @@ namespace OpenRCT2::Ui::Windows UpdateSizeAndPosition(screenPos, extraY); - if (colour & COLOUR_FLAG_TRANSLUCENT) + if (colour.hasFlag(ColourFlag::translucent)) flags |= WF_TRANSPARENT; colours[0] = colour; } void SetImageItems( - const ScreenCoordsXY& screenPos, int32_t extraY, uint8_t colour, int32_t numItems, int32_t itemWidth, + const ScreenCoordsXY& screenPos, int32_t extraY, ColourWithFlags colour, int32_t numItems, int32_t itemWidth, int32_t itemHeight, int32_t numColumns) { UseImages = _dropdownPrepareUseImages; @@ -243,7 +244,7 @@ namespace OpenRCT2::Ui::Windows UpdateSizeAndPosition(screenPos, extraY); - if (colour & COLOUR_FLAG_TRANSLUCENT) + if (colour.hasFlag(ColourFlag::translucent)) flags |= WF_TRANSPARENT; colours[0] = colour; } @@ -318,7 +319,7 @@ namespace OpenRCT2::Ui::Windows * @param colour (al) */ void WindowDropdownShowText( - const ScreenCoordsXY& screenPos, int32_t extray, uint8_t colour, uint8_t flags, size_t num_items) + const ScreenCoordsXY& screenPos, int32_t extray, ColourWithFlags colour, uint8_t flags, size_t num_items) { int32_t string_width, max_string_width; char buffer[256]; @@ -348,8 +349,8 @@ namespace OpenRCT2::Ui::Windows * @param custom_height (ah) requires flag set as well */ void WindowDropdownShowTextCustomWidth( - const ScreenCoordsXY& screenPos, int32_t extray, uint8_t colour, uint8_t custom_height, uint8_t flags, size_t num_items, - int32_t width) + const ScreenCoordsXY& screenPos, int32_t extray, ColourWithFlags colour, uint8_t custom_height, uint8_t flags, + size_t num_items, int32_t width) { InputSetFlag(static_cast(INPUT_FLAG_DROPDOWN_STAY_OPEN | INPUT_FLAG_DROPDOWN_MOUSE_UP), false); if (flags & Dropdown::Flag::StayOpen || Config::Get().interface.EnlargedUi) @@ -380,7 +381,7 @@ namespace OpenRCT2::Ui::Windows * @param numColumns (bl) */ void WindowDropdownShowImage( - int32_t x, int32_t y, int32_t extray, uint8_t colour, uint8_t flags, int32_t numItems, int32_t itemWidth, + int32_t x, int32_t y, int32_t extray, ColourWithFlags colour, uint8_t flags, int32_t numItems, int32_t itemWidth, int32_t itemHeight, int32_t numColumns) { InputSetFlag(static_cast(INPUT_FLAG_DROPDOWN_STAY_OPEN | INPUT_FLAG_DROPDOWN_MOUSE_UP), false); @@ -493,12 +494,13 @@ static constexpr colour_t kColoursDropdownOrder[] = { /** * rct2: 0x006ED43D */ - void WindowDropdownShowColour(WindowBase* w, Widget* widget, uint8_t dropdownColour, uint8_t selectedColour) + void WindowDropdownShowColour( + WindowBase* w, Widget* widget, ColourWithFlags dropdownColour, colour_t selectedColour, bool alwaysHideSpecialColours) { int32_t defaultIndex = -1; - auto numColours = (GetGameState().Cheats.AllowSpecialColourSchemes) ? static_cast(COLOUR_COUNT) - : COLOUR_NUM_NORMAL; + const bool specialColoursEnabled = !alwaysHideSpecialColours && GetGameState().Cheats.AllowSpecialColourSchemes; + auto numColours = specialColoursEnabled ? static_cast(COLOUR_COUNT) : COLOUR_NUM_NORMAL; // Set items for (uint64_t i = 0; i < numColours; i++) { diff --git a/src/openrct2-ui/windows/EditorBottomToolbar.cpp b/src/openrct2-ui/windows/EditorBottomToolbar.cpp index 2fe2cda019..f275ac0594 100644 --- a/src/openrct2-ui/windows/EditorBottomToolbar.cpp +++ b/src/openrct2-ui/windows/EditorBottomToolbar.cpp @@ -285,7 +285,7 @@ static Widget _editorBottomToolbarWidgets[] = { dpi, ImageId(SPR_PREVIOUS), windowPos + ScreenCoordsXY{ widgets[WIDX_PREVIOUS_IMAGE].left + 6, widgets[WIDX_PREVIOUS_IMAGE].top + 6 }); - colour_t textColour = NOT_TRANSLUCENT(colours[1]); + colour_t textColour = colours[1].colour; if (gHoverWidget.window_classification == WindowClass::BottomToolbar && gHoverWidget.widget_index == WIDX_PREVIOUS_STEP_BUTTON) { @@ -323,7 +323,7 @@ static Widget _editorBottomToolbarWidgets[] = { dpi, ImageId(SPR_NEXT), windowPos + ScreenCoordsXY{ widgets[WIDX_NEXT_IMAGE].right - 29, widgets[WIDX_NEXT_IMAGE].top + 6 }); - colour_t textColour = NOT_TRANSLUCENT(colours[1]); + colour_t textColour = colours[1].colour; if (gHoverWidget.window_classification == WindowClass::BottomToolbar && gHoverWidget.widget_index == WIDX_NEXT_STEP_BUTTON) @@ -346,9 +346,10 @@ static Widget _editorBottomToolbarWidgets[] = { { int16_t stateX = (widgets[WIDX_PREVIOUS_IMAGE].right + widgets[WIDX_NEXT_IMAGE].left) / 2 + windowPos.x; int16_t stateY = height - 0x0C + windowPos.y; + auto colour = colours[2].withFlag(ColourFlag::translucent, false).withFlag(ColourFlag::withOutline, true); DrawTextBasic( dpi, { stateX, stateY }, _editorStepNames[EnumValue(GetGameState().EditorStep)], {}, - { static_cast(NOT_TRANSLUCENT(colours[2]) | COLOUR_FLAG_OUTLINE), TextAlignment::CENTRE }); + { colour, TextAlignment::CENTRE }); } static constexpr FuncPtr _previousButtonMouseUp[] = { diff --git a/src/openrct2-ui/windows/EditorInventionsList.cpp b/src/openrct2-ui/windows/EditorInventionsList.cpp index beafebca55..374cef426d 100644 --- a/src/openrct2-ui/windows/EditorInventionsList.cpp +++ b/src/openrct2-ui/windows/EditorInventionsList.cpp @@ -275,7 +275,7 @@ static Widget _inventionListDragWidgets[] = { const auto& gameState = GetGameState(); // Draw background - uint8_t paletteIndex = ColourMapA[colours[1]].mid_light; + uint8_t paletteIndex = ColourMapA[colours[1].colour].mid_light; GfxClear(dpi, paletteIndex); int16_t boxWidth = widgets[WIDX_RESEARCH_ORDER_SCROLL].width(); @@ -313,7 +313,7 @@ static Widget _inventionListDragWidgets[] = { // TODO: this parameter by itself produces very light text. // It needs a {BLACK} token in the string to work properly. - colour_t colour = COLOUR_BLACK; + ColourWithFlags colour = { COLOUR_BLACK }; FontStyle fontStyle = FontStyle::Medium; auto darkness = TextDarkness::Regular; @@ -323,7 +323,7 @@ static Widget _inventionListDragWidgets[] = { darkness = TextDarkness::ExtraDark; else darkness = TextDarkness::Dark; - colour = colours[1] | COLOUR_FLAG_INSET; + colour = colours[1].withFlag(ColourFlag::inset, true); } DrawResearchItem(dpi, researchItem, boxWidth, { 1, itemY }, STR_BLACK_STRING, { colour, fontStyle, darkness }); @@ -379,7 +379,7 @@ static Widget _inventionListDragWidgets[] = { dpi, { windowPos + ScreenCoordsXY{ bkWidget.left + 1, bkWidget.top + 1 }, windowPos + ScreenCoordsXY{ bkWidget.right - 1, bkWidget.bottom - 1 } }, - ColourMapA[colours[1]].darkest); + ColourMapA[colours[1].colour].darkest); auto* researchItem = WindowEditorInventionsListDragGetItem(); if (researchItem == nullptr || researchItem->IsNull()) @@ -658,7 +658,7 @@ static Widget _inventionListDragWidgets[] = { DrawResearchItem( dpi, _draggedItem, width, screenCoords, STR_WINDOW_COLOUR_2_STRINGID, - { COLOUR_BLACK | static_cast(COLOUR_FLAG_OUTLINE) }); + { ColourWithFlags{ COLOUR_BLACK }.withFlag(ColourFlag::withOutline, true) }); } void Init(ResearchItem& researchItem, const ScreenCoordsXY& editorPos, int objectSelectionScrollWidth) diff --git a/src/openrct2-ui/windows/EditorObjectSelection.cpp b/src/openrct2-ui/windows/EditorObjectSelection.cpp index cd340d92b1..0971266c0c 100644 --- a/src/openrct2-ui/windows/EditorObjectSelection.cpp +++ b/src/openrct2-ui/windows/EditorObjectSelection.cpp @@ -722,7 +722,7 @@ static std::vector _window_editor_object_selection_widgets = { ScreenCoordsXY screenCoords; bool ridePage = (GetSelectedObjectType() == ObjectType::Ride); - uint8_t paletteIndex = ColourMapA[colours[1]].mid_light; + uint8_t paletteIndex = ColourMapA[colours[1].colour].mid_light; GfxClear(dpi, paletteIndex); screenCoords.y = 0; @@ -750,12 +750,12 @@ static std::vector _window_editor_object_selection_widgets = { { screenCoords.x = 2; auto darkness = highlighted ? TextDarkness::ExtraDark : TextDarkness::Dark; - colour_t colour2 = NOT_TRANSLUCENT(colours[1]); + auto colour2 = colours[1].withFlag(ColourFlag::translucent, false); if (*listItem.flags & (ObjectSelectionFlags::InUse | ObjectSelectionFlags::AlwaysRequired)) - colour2 |= COLOUR_FLAG_INSET; + colour2.setFlag(ColourFlag::inset, true); DrawText( - dpi, screenCoords, { static_cast(colour2), FontStyle::Medium, darkness }, + dpi, screenCoords, { colour2, FontStyle::Medium, darkness }, static_cast(CheckBoxMarkString)); } @@ -768,7 +768,7 @@ static std::vector _window_editor_object_selection_widgets = { auto darkness = TextDarkness::Regular; if (*listItem.flags & ObjectSelectionFlags::Flag6) { - colour = colours[1] & 0x7F; + colour = colours[1].colour; darkness = TextDarkness::Dark; } @@ -1032,7 +1032,7 @@ static std::vector _window_editor_object_selection_widgets = { spriteIndex += (i == 4 ? ThrillRidesTabAnimationSequence[frame] : frame); auto screenPos = windowPos + ScreenCoordsXY{ widget.left, widget.top }; - GfxDrawSprite(dpi, ImageId(spriteIndex, colours[1]), screenPos); + GfxDrawSprite(dpi, ImageId(spriteIndex, colours[1].colour), screenPos); } } @@ -1042,7 +1042,7 @@ static std::vector _window_editor_object_selection_widgets = { dpi, { windowPos + ScreenCoordsXY{ previewWidget.left + 1, previewWidget.top + 1 }, windowPos + ScreenCoordsXY{ previewWidget.right - 1, previewWidget.bottom - 1 } }, - ColourMapA[colours[1]].darkest); + ColourMapA[colours[1].colour].darkest); // Draw number of selected items if (!(gScreenFlags & SCREEN_FLAGS_TRACK_MANAGER)) diff --git a/src/openrct2-ui/windows/EditorObjectiveOptions.cpp b/src/openrct2-ui/windows/EditorObjectiveOptions.cpp index 26c6486156..a94967d25f 100644 --- a/src/openrct2-ui/windows/EditorObjectiveOptions.cpp +++ b/src/openrct2-ui/windows/EditorObjectiveOptions.cpp @@ -949,7 +949,7 @@ static uint64_t window_editor_objective_options_page_hold_down_widgets[] = { ft.Add(gameState.ScenarioObjective.Currency); break; } - DrawTextBasic(dpi, screenCoords, stringId, ft, COLOUR_BLACK); + DrawTextBasic(dpi, screenCoords, stringId, ft, { COLOUR_BLACK }); } if (widgets[WIDX_OBJECTIVE_ARG_2].type != WindowWidgetType::Empty) @@ -1142,7 +1142,7 @@ static uint64_t window_editor_objective_options_page_hold_down_widgets[] = { */ void OnScrollDrawRides(DrawPixelInfo& dpi, int32_t scrollIndex) { - int32_t colour = ColourMapA[colours[1]].mid_light; + int32_t colour = ColourMapA[colours[1].colour].mid_light; GfxFillRect(dpi, { { dpi.x, dpi.y }, { dpi.x + dpi.width - 1, dpi.y + dpi.height - 1 } }, colour); for (int32_t i = 0; i < static_cast(_rideableRides.size()); i++) @@ -1171,7 +1171,7 @@ static uint64_t window_editor_objective_options_page_hold_down_widgets[] = { { auto darkness = stringId == STR_WINDOW_COLOUR_2_STRINGID ? TextDarkness::ExtraDark : TextDarkness::Dark; DrawText( - dpi, { 2, y }, { static_cast(colours[1] & 0x7F), FontStyle::Medium, darkness }, + dpi, { 2, y }, { colours[1].withFlag(ColourFlag::translucent, false), FontStyle::Medium, darkness }, static_cast(CheckBoxMarkString)); } diff --git a/src/openrct2-ui/windows/Finances.cpp b/src/openrct2-ui/windows/Finances.cpp index 6e6716379c..2cccab1b92 100644 --- a/src/openrct2-ui/windows/Finances.cpp +++ b/src/openrct2-ui/windows/Finances.cpp @@ -380,7 +380,7 @@ static Widget _windowFinancesResearchWidgets[] = dpi, { screenCoords - ScreenCoordsXY{ 0, 1 }, screenCoords + ScreenCoordsXY{ row_width, (kTableCellHeight - 2) } }, - ColourMapA[colours[1]].lighter | 0x1000000); + ColourMapA[colours[1].colour].lighter | 0x1000000); screenCoords.y += kTableCellHeight; } @@ -553,7 +553,7 @@ static Widget _windowFinancesResearchWidgets[] = GfxFillRect( dpi, { screenCoords - ScreenCoordsXY{ 0, 1 }, screenCoords + ScreenCoordsXY{ 121, (kTableCellHeight - 2) } }, - ColourMapA[colours[1]].lighter | 0x1000000); + ColourMapA[colours[1].colour].lighter | 0x1000000); DrawTextBasic(dpi, screenCoords - ScreenCoordsXY{ 0, 1 }, _windowFinancesSummaryRowLabels[i]); screenCoords.y += kTableCellHeight; diff --git a/src/openrct2-ui/windows/GameBottomToolbar.cpp b/src/openrct2-ui/windows/GameBottomToolbar.cpp index 392a4b50d2..f4f48dbe88 100644 --- a/src/openrct2-ui/windows/GameBottomToolbar.cpp +++ b/src/openrct2-ui/windows/GameBottomToolbar.cpp @@ -76,6 +76,14 @@ static Widget window_game_bottom_toolbar_widgets[] = class GameBottomToolbar final : public Window { private: + colour_t GetHoverWidgetColour(WidgetIndex index) + { + return ( + gHoverWidget.window_classification == WindowClass::BottomToolbar && gHoverWidget.widget_index == index + ? static_cast(COLOUR_WHITE) + : colours[0].colour); + } + void DrawLeftPanel(DrawPixelInfo& dpi) { const auto topLeft = windowPos @@ -99,11 +107,7 @@ static Widget window_game_bottom_toolbar_widgets[] = auto screenCoords = ScreenCoordsXY{ windowPos.x + widget.midX(), windowPos.y + widget.midY() - (line_height == 10 ? 5 : 6) }; - colour_t colour - = (gHoverWidget.window_classification == WindowClass::BottomToolbar - && gHoverWidget.widget_index == WIDX_MONEY - ? COLOUR_WHITE - : NOT_TRANSLUCENT(colours[0])); + auto colour = GetHoverWidgetColour(WIDX_MONEY); StringId stringId = gameState.Cash < 0 ? STR_BOTTOM_TOOLBAR_CASH_NEGATIVE : STR_BOTTOM_TOOLBAR_CASH; auto ft = Formatter(); ft.Add(gameState.Cash); @@ -129,11 +133,7 @@ static Widget window_game_bottom_toolbar_widgets[] = StringId stringId = gameState.NumGuestsInPark == 1 ? _guestCountFormatsSingular[gameState.GuestChangeModifier] : _guestCountFormats[gameState.GuestChangeModifier]; - colour_t colour - = (gHoverWidget.window_classification == WindowClass::BottomToolbar - && gHoverWidget.widget_index == WIDX_GUESTS - ? COLOUR_WHITE - : NOT_TRANSLUCENT(colours[0])); + auto colour = GetHoverWidgetColour(WIDX_GUESTS); auto ft = Formatter(); ft.Add(gameState.NumGuestsInPark); DrawTextBasic(dpi, screenCoords, stringId, ft, { colour, TextAlignment::CENTRE }); @@ -144,7 +144,7 @@ static Widget window_game_bottom_toolbar_widgets[] = Widget widget = window_game_bottom_toolbar_widgets[WIDX_PARK_RATING]; auto screenCoords = windowPos + ScreenCoordsXY{ widget.left + 11, widget.midY() - 5 }; - DrawParkRating(dpi, colours[3], screenCoords, std::max(10, ((gameState.Park.Rating / 4) * 263) / 256)); + DrawParkRating(dpi, colours[3].colour, screenCoords, std::max(10, ((gameState.Park.Rating / 4) * 263) / 256)); } } @@ -158,7 +158,8 @@ static Widget window_game_bottom_toolbar_widgets[] = if (bar_width > 2) { GfxFillRectInset( - dpi, { coords + ScreenCoordsXY{ 2, 2 }, coords + ScreenCoordsXY{ bar_width - 1, 8 } }, colour, 0); + dpi, { coords + ScreenCoordsXY{ 2, 2 }, coords + ScreenCoordsXY{ bar_width - 1, 8 } }, + ColourWithFlags{ static_cast(colour) }, 0); } } @@ -190,10 +191,7 @@ static Widget window_game_bottom_toolbar_widgets[] = int32_t month = date.GetMonth(); int32_t day = date.GetDay(); - colour_t colour - = (gHoverWidget.window_classification == WindowClass::BottomToolbar && gHoverWidget.widget_index == WIDX_DATE - ? COLOUR_WHITE - : NOT_TRANSLUCENT(colours[0])); + auto colour = GetHoverWidgetColour(WIDX_DATE); StringId stringId = DateFormatStringFormatIds[Config::Get().general.DateFormat]; auto ft = Formatter(); ft.Add(DateDayNames[day]); diff --git a/src/openrct2-ui/windows/Guest.cpp b/src/openrct2-ui/windows/Guest.cpp index d1cc1937c0..62980189fd 100644 --- a/src/openrct2-ui/windows/Guest.cpp +++ b/src/openrct2-ui/windows/Guest.cpp @@ -1336,7 +1336,7 @@ static_assert(_guestWindowPageWidgets.size() == WINDOW_GUEST_PAGE_COUNT); void OnScrollDrawRides(int32_t scrollIndex, DrawPixelInfo& dpi) { - auto colour = ColourMapA[colours[1]].mid_light; + auto colour = ColourMapA[colours[1].colour].mid_light; GfxFillRect(dpi, { { dpi.x, dpi.y }, { dpi.x + dpi.width - 1, dpi.y + dpi.height - 1 } }, colour); for (int32_t listIndex = 0; listIndex < static_cast(_riddenRides.size()); listIndex++) diff --git a/src/openrct2-ui/windows/GuestList.cpp b/src/openrct2-ui/windows/GuestList.cpp index deb54d58c9..f0086cfd8c 100644 --- a/src/openrct2-ui/windows/GuestList.cpp +++ b/src/openrct2-ui/windows/GuestList.cpp @@ -594,7 +594,8 @@ static Widget window_guest_list_widgets[] = { void OnScrollDraw(int32_t scrollIndex, DrawPixelInfo& dpi) override { GfxFillRect( - dpi, { { dpi.x, dpi.y }, { dpi.x + dpi.width - 1, dpi.y + dpi.height - 1 } }, ColourMapA[colours[1]].mid_light); + dpi, { { dpi.x, dpi.y }, { dpi.x + dpi.width - 1, dpi.y + dpi.height - 1 } }, + ColourMapA[colours[1].colour].mid_light); switch (_selectedTab) { case TabId::Individual: diff --git a/src/openrct2-ui/windows/InstallTrack.cpp b/src/openrct2-ui/windows/InstallTrack.cpp index a93a544d50..121880b216 100644 --- a/src/openrct2-ui/windows/InstallTrack.cpp +++ b/src/openrct2-ui/windows/InstallTrack.cpp @@ -154,7 +154,7 @@ static Widget window_install_track_widgets[] = { // Track preview Widget* widget = &window_install_track_widgets[WIDX_TRACK_PREVIEW]; auto screenPos = windowPos + ScreenCoordsXY{ widget->left + 1, widget->top + 1 }; - int32_t colour = ColourMapA[colours[0]].darkest; + int32_t colour = ColourMapA[colours[0].colour].darkest; GfxFillRect(dpi, { screenPos, screenPos + ScreenCoordsXY{ 369, 216 } }, colour); G1Element g1temp = {}; diff --git a/src/openrct2-ui/windows/LoadSave.cpp b/src/openrct2-ui/windows/LoadSave.cpp index a00bf2648c..ef6272bc20 100644 --- a/src/openrct2-ui/windows/LoadSave.cpp +++ b/src/openrct2-ui/windows/LoadSave.cpp @@ -976,7 +976,8 @@ static Widget window_loadsave_widgets[] = void OnScrollDraw(int32_t scrollIndex, DrawPixelInfo& dpi) override { GfxFillRect( - dpi, { { dpi.x, dpi.y }, { dpi.x + dpi.width - 1, dpi.y + dpi.height - 1 } }, ColourMapA[colours[1]].mid_light); + dpi, { { dpi.x, dpi.y }, { dpi.x + dpi.width - 1, dpi.y + dpi.height - 1 } }, + ColourMapA[colours[1].colour].mid_light); const int32_t listWidth = widgets[WIDX_SCROLL].width(); const int32_t dateAnchor = widgets[WIDX_SORT_DATE].left + maxDateWidth + DATE_TIME_GAP; diff --git a/src/openrct2-ui/windows/MapGen.cpp b/src/openrct2-ui/windows/MapGen.cpp index 56a5ddd44c..f5ccdd3421 100644 --- a/src/openrct2-ui/windows/MapGen.cpp +++ b/src/openrct2-ui/windows/MapGen.cpp @@ -654,13 +654,13 @@ static uint64_t PressedWidgets[WINDOW_MAPGEN_PAGE_COUNT] = { if (IsWidgetDisabled(widgetIndex)) { // Draw greyed out (light border bottom right shadow) - auto colour = colours[widget.colour]; - colour = ColourMapA[NOT_TRANSLUCENT(colour)].lighter; + auto colour = colours[widget.colour].colour; + colour = ColourMapA[colour].lighter; GfxDrawSpriteSolid(dpi, image, pos + ScreenCoordsXY{ 1, 1 }, colour); // Draw greyed out (dark) - colour = colours[widget.colour]; - colour = ColourMapA[NOT_TRANSLUCENT(colour)].mid_light; + colour = colours[widget.colour].colour; + colour = ColourMapA[colour].mid_light; GfxDrawSpriteSolid(dpi, image, pos, colour); } else @@ -1013,7 +1013,7 @@ static uint64_t PressedWidgets[WINDOW_MAPGEN_PAGE_COUNT] = { DrawTabImages(dpi); DrawDropdownButtons(dpi, WIDX_SIMPLEX_FLOOR_TEXTURE, WIDX_SIMPLEX_WALL_TEXTURE); - const uint8_t textColour = colours[1]; + const auto textColour = colours[1]; DrawTextBasic( dpi, windowPos + ScreenCoordsXY{ 5, widgets[WIDX_SIMPLEX_LOW].top + 1 }, STR_MAPGEN_SIMPLEX_NOISE_LOW_, {}, @@ -1198,11 +1198,11 @@ static uint64_t PressedWidgets[WINDOW_MAPGEN_PAGE_COUNT] = { DrawWidgets(dpi); DrawTabImages(dpi); - const colour_t enabledColour = colours[1]; - const colour_t disabledColour = enabledColour | COLOUR_FLAG_INSET; + const auto enabledColour = colours[1]; + const auto disabledColour = enabledColour.withFlag(ColourFlag::inset, true); // Smooth strength label and value - const colour_t strengthColour = _heightmapSmoothMap ? enabledColour : disabledColour; + const auto strengthColour = _heightmapSmoothMap ? enabledColour : disabledColour; DrawTextBasic( dpi, windowPos + ScreenCoordsXY{ 5, widgets[WIDX_HEIGHTMAP_STRENGTH].top + 1 }, STR_MAPGEN_SMOOTH_STRENGTH, {}, { strengthColour }); @@ -1216,7 +1216,7 @@ static uint64_t PressedWidgets[WINDOW_MAPGEN_PAGE_COUNT] = { STR_COMMA16, ft, { strengthColour }); // Low label and value - const colour_t labelColour = _heightmapLoaded ? enabledColour : disabledColour; + const auto labelColour = _heightmapLoaded ? enabledColour : disabledColour; DrawTextBasic( dpi, windowPos + ScreenCoordsXY{ 5, widgets[WIDX_HEIGHTMAP_LOW].top + 1 }, STR_MAPGEN_SIMPLEX_NOISE_LOW_, {}, { labelColour }); diff --git a/src/openrct2-ui/windows/Multiplayer.cpp b/src/openrct2-ui/windows/Multiplayer.cpp index 875f13ce1a..22fc14d829 100644 --- a/src/openrct2-ui/windows/Multiplayer.cpp +++ b/src/openrct2-ui/windows/Multiplayer.cpp @@ -758,7 +758,7 @@ static constexpr StringId WindowMultiplayerPageTitles[] = { _buffer.clear(); // Draw player name - colour_t colour = COLOUR_BLACK; + auto colour = ColourWithFlags{ COLOUR_BLACK }; if (listPosition == selected_list_item) { GfxFilterRect( @@ -886,7 +886,8 @@ static constexpr StringId WindowMultiplayerPageTitles[] = { auto dpiCoords = ScreenCoordsXY{ dpi.x, dpi.y }; GfxFillRect( - dpi, { dpiCoords, dpiCoords + ScreenCoordsXY{ dpi.width - 1, dpi.height - 1 } }, ColourMapA[colours[1]].mid_light); + dpi, { dpiCoords, dpiCoords + ScreenCoordsXY{ dpi.width - 1, dpi.height - 1 } }, + ColourMapA[colours[1].colour].mid_light); for (int32_t i = 0; i < NetworkGetNumActions(); i++) { diff --git a/src/openrct2-ui/windows/NewRide.cpp b/src/openrct2-ui/windows/NewRide.cpp index 915e91ccd5..c7513e4da7 100644 --- a/src/openrct2-ui/windows/NewRide.cpp +++ b/src/openrct2-ui/windows/NewRide.cpp @@ -479,7 +479,7 @@ static Widget window_new_ride_widgets[] = { return; } - GfxClear(dpi, ColourMapA[colours[1]].mid_light); + GfxClear(dpi, ColourMapA[colours[1].colour].mid_light); ScreenCoordsXY coords{ 1, 1 }; RideSelection* listItem = _windowNewRideListItems; @@ -986,7 +986,7 @@ static Widget window_new_ride_widgets[] = { spriteIndex += tab == THRILL_TAB ? ThrillRidesTabAnimationSequence[frame] : frame; GfxDrawSprite( - dpi, ImageId(spriteIndex, colours[1]), + dpi, ImageId(spriteIndex, colours[1].colour), windowPos + ScreenCoordsXY{ widgets[widgetIndex].left, widgets[widgetIndex].top }); } } diff --git a/src/openrct2-ui/windows/ObjectLoadError.cpp b/src/openrct2-ui/windows/ObjectLoadError.cpp index 427b5c6705..8852b03ee8 100644 --- a/src/openrct2-ui/windows/ObjectLoadError.cpp +++ b/src/openrct2-ui/windows/ObjectLoadError.cpp @@ -508,7 +508,7 @@ static Widget window_object_load_error_widgets[] = { auto dpiCoords = ScreenCoordsXY{ dpi.x, dpi.y }; GfxFillRect( dpi, { dpiCoords, dpiCoords + ScreenCoordsXY{ dpi.width - 1, dpi.height - 1 } }, - ColourMapA[colours[1]].mid_light); + ColourMapA[colours[1].colour].mid_light); const int32_t listWidth = widgets[WIDX_SCROLL].width(); for (int32_t i = 0; i < no_list_items; i++) @@ -525,11 +525,11 @@ static Widget window_object_load_error_widgets[] = { { listWidth, screenCoords.y + kScrollableRowHeight - 1 } }; // If hovering over item, change the color and fill the backdrop. if (i == selected_list_item) - GfxFillRect(dpi, screenRect, ColourMapA[colours[1]].darker); + GfxFillRect(dpi, screenRect, ColourMapA[colours[1].colour].darker); else if (i == _highlightedIndex) - GfxFillRect(dpi, screenRect, ColourMapA[colours[1]].mid_dark); + GfxFillRect(dpi, screenRect, ColourMapA[colours[1].colour].mid_dark); else if ((i & 1) != 0) // odd / even check - GfxFillRect(dpi, screenRect, ColourMapA[colours[1]].light); + GfxFillRect(dpi, screenRect, ColourMapA[colours[1].colour].light); // Draw the actual object entry's name... screenCoords.x = NAME_COL_LEFT - 3; diff --git a/src/openrct2-ui/windows/Options.cpp b/src/openrct2-ui/windows/Options.cpp index 1a4e09d0d5..7a0fb76630 100644 --- a/src/openrct2-ui/windows/Options.cpp +++ b/src/openrct2-ui/windows/Options.cpp @@ -2116,14 +2116,14 @@ static Widget *window_options_page_widgets[] = { else { // Get the window background colour - uint8_t window_colour = NOT_TRANSLUCENT(colours[widget->colour]); + auto windowColour = colours[widget->colour].colour; // Draw greyed out (light border bottom right shadow) GfxDrawSpriteSolid( - dpi, ImageId(spriteIndex), screenCoords + ScreenCoordsXY{ 1, 1 }, ColourMapA[window_colour].lighter); + dpi, ImageId(spriteIndex), screenCoords + ScreenCoordsXY{ 1, 1 }, ColourMapA[windowColour].lighter); // Draw greyed out (dark) - GfxDrawSpriteSolid(dpi, ImageId(spriteIndex), screenCoords, ColourMapA[window_colour].mid_light); + GfxDrawSpriteSolid(dpi, ImageId(spriteIndex), screenCoords, ColourMapA[windowColour].mid_light); } } diff --git a/src/openrct2-ui/windows/Ride.cpp b/src/openrct2-ui/windows/Ride.cpp index 5b8a1ce0e5..386d599780 100644 --- a/src/openrct2-ui/windows/Ride.cpp +++ b/src/openrct2-ui/windows/Ride.cpp @@ -3629,7 +3629,7 @@ static_assert(std::size(RatingNames) == 6); ft.Add(ride->num_block_brakes + ride->num_stations); DrawTextBasic( dpi, windowPos + ScreenCoordsXY{ 21, ride->mode == RideMode::PoweredLaunchBlockSectioned ? 89 : 61 }, - STR_BLOCK_SECTIONS, ft, COLOUR_BLACK); + STR_BLOCK_SECTIONS, ft, { COLOUR_BLACK }); } } diff --git a/src/openrct2-ui/windows/RideList.cpp b/src/openrct2-ui/windows/RideList.cpp index 5d8a00ed1b..acd3b734a9 100644 --- a/src/openrct2-ui/windows/RideList.cpp +++ b/src/openrct2-ui/windows/RideList.cpp @@ -542,7 +542,8 @@ static Widget _rideListWidgets[] = { { auto dpiCoords = ScreenCoordsXY{ dpi.x, dpi.y }; GfxFillRect( - dpi, { dpiCoords, dpiCoords + ScreenCoordsXY{ dpi.width, dpi.height } }, ColourMapA[colours[1]].mid_light); + dpi, { dpiCoords, dpiCoords + ScreenCoordsXY{ dpi.width, dpi.height } }, + ColourMapA[colours[1].colour].mid_light); auto y = 0; for (size_t i = 0; i < _rideList.size(); i++) diff --git a/src/openrct2-ui/windows/ScenarioSelect.cpp b/src/openrct2-ui/windows/ScenarioSelect.cpp index abd34d630f..25cfc23ce2 100644 --- a/src/openrct2-ui/windows/ScenarioSelect.cpp +++ b/src/openrct2-ui/windows/ScenarioSelect.cpp @@ -393,7 +393,7 @@ static Widget _scenarioSelectWidgets[] = { void OnScrollDraw(int32_t scrollIndex, DrawPixelInfo& dpi) override { - uint8_t paletteIndex = ColourMapA[colours[1]].mid_light; + uint8_t paletteIndex = ColourMapA[colours[1].colour].mid_light; GfxClear(dpi, paletteIndex); StringId highlighted_format = STR_WINDOW_COLOUR_2_STRINGID; @@ -451,7 +451,8 @@ static Widget _scenarioSelectWidgets[] = { auto ft = Formatter(); ft.Add(STR_STRING); ft.Add(buffer); - colour_t colour = isDisabled ? colours[1] | COLOUR_FLAG_INSET : COLOUR_BLACK; + auto colour = isDisabled ? colours[1].withFlag(ColourFlag::inset, true) + : ColourWithFlags{ COLOUR_BLACK }; auto darkness = isDisabled ? TextDarkness::Dark : TextDarkness::Regular; const auto scrollCentre = widgets[WIDX_SCENARIOLIST].width() / 2; @@ -490,9 +491,9 @@ static Widget _scenarioSelectWidgets[] = { private: void DrawCategoryHeading(DrawPixelInfo& dpi, int32_t left, int32_t right, int32_t y, StringId stringId) const { - colour_t baseColour = colours[1]; - colour_t lightColour = ColourMapA[baseColour].lighter; - colour_t darkColour = ColourMapA[baseColour].mid_dark; + auto baseColour = colours[1]; + colour_t lightColour = ColourMapA[baseColour.colour].lighter; + colour_t darkColour = ColourMapA[baseColour.colour].mid_dark; // Draw string int32_t centreX = (left + right) / 2; diff --git a/src/openrct2-ui/windows/Scenery.cpp b/src/openrct2-ui/windows/Scenery.cpp index 038bf74f89..36eec93baf 100644 --- a/src/openrct2-ui/windows/Scenery.cpp +++ b/src/openrct2-ui/windows/Scenery.cpp @@ -1327,7 +1327,7 @@ static Widget WindowSceneryBaseWidgets[] = { auto scgEntry = tabInfo.GetSceneryGroupEntry(); if (scgEntry != nullptr) { - widget.image = ImageId(scgEntry->image, colours[1]); + widget.image = ImageId(scgEntry->image, colours[1].colour); } } @@ -1624,7 +1624,7 @@ static Widget WindowSceneryBaseWidgets[] = { void ContentScrollDraw(DrawPixelInfo& dpi) { - GfxClear(dpi, ColourMapA[colours[1]].mid_light); + GfxClear(dpi, ColourMapA[colours[1].colour].mid_light); auto numColumns = GetNumColumns(); auto tabIndex = _activeTabIndex; diff --git a/src/openrct2-ui/windows/ServerList.cpp b/src/openrct2-ui/windows/ServerList.cpp index b775b8a2d3..6fa38bc01a 100644 --- a/src/openrct2-ui/windows/ServerList.cpp +++ b/src/openrct2-ui/windows/ServerList.cpp @@ -238,7 +238,7 @@ static Widget _serverListWidgets[] = { } auto dropdownPos = ScreenCoordsXY{ windowPos.x + listWidget.left + screenCoords.x + 2 - scrolls[0].h_left, windowPos.y + listWidget.top + screenCoords.y + 2 - scrolls[0].v_top }; - WindowDropdownShowText(dropdownPos, 0, COLOUR_GREY, 0, 2); + WindowDropdownShowText(dropdownPos, 0, { COLOUR_GREY }, 0, 2); } } @@ -334,7 +334,7 @@ static Widget _serverListWidgets[] = { void OnScrollDraw(int32_t scrollIndex, DrawPixelInfo& dpi) override { - uint8_t paletteIndex = ColourMapA[colours[1]].mid_light; + uint8_t paletteIndex = ColourMapA[colours[1].colour].mid_light; GfxClear(dpi, paletteIndex); auto& listWidget = widgets[WIDX_LIST]; @@ -359,7 +359,7 @@ static Widget _serverListWidgets[] = { _version = serverDetails.Version; } - colour_t colour = colours[1]; + auto colour = colours[1]; if (serverDetails.Favourite) { colour = COLOUR_YELLOW; diff --git a/src/openrct2-ui/windows/ShortcutKeys.cpp b/src/openrct2-ui/windows/ShortcutKeys.cpp index 05f34fab59..ca356659ca 100644 --- a/src/openrct2-ui/windows/ShortcutKeys.cpp +++ b/src/openrct2-ui/windows/ShortcutKeys.cpp @@ -307,7 +307,7 @@ static Widget window_shortcut_change_widgets[] = { auto dpiCoords = ScreenCoordsXY{ dpi.x, dpi.y }; GfxFillRect( dpi, { dpiCoords, dpiCoords + ScreenCoordsXY{ dpi.width - 1, dpi.height - 1 } }, - ColourMapA[colours[1]].mid_light); + ColourMapA[colours[1].colour].mid_light); // TODO: the line below is a workaround for what is presumably a bug with dpi->width // see https://github.com/OpenRCT2/OpenRCT2/issues/11238 for details @@ -506,8 +506,8 @@ static Widget window_shortcut_change_widgets[] = { void DrawSeparator(DrawPixelInfo& dpi, int32_t y, int32_t scrollWidth) { const int32_t top = y + (kScrollableRowHeight / 2) - 1; - GfxFillRect(dpi, { { 0, top }, { scrollWidth, top } }, ColourMapA[colours[0]].mid_dark); - GfxFillRect(dpi, { { 0, top + 1 }, { scrollWidth, top + 1 } }, ColourMapA[colours[0]].lightest); + GfxFillRect(dpi, { { 0, top }, { scrollWidth, top } }, ColourMapA[colours[0].colour].mid_dark); + GfxFillRect(dpi, { { 0, top + 1 }, { scrollWidth, top + 1 } }, ColourMapA[colours[0].colour].lightest); } void DrawItem( diff --git a/src/openrct2-ui/windows/Sign.cpp b/src/openrct2-ui/windows/Sign.cpp index 86b59d9f4a..c79839ada3 100644 --- a/src/openrct2-ui/windows/Sign.cpp +++ b/src/openrct2-ui/windows/Sign.cpp @@ -197,10 +197,10 @@ static Widget _signWidgets[] = { switch (widgetIndex) { case WIDX_MAIN_COLOUR: - WindowDropdownShowColour(this, widget, TRANSLUCENT(colours[1]), static_cast(_mainColour)); + WindowDropdownShowColour(this, widget, colours[1].withFlag(ColourFlag::translucent, true), _mainColour); break; case WIDX_TEXT_COLOUR: - WindowDropdownShowColour(this, widget, TRANSLUCENT(colours[1]), static_cast(_textColour)); + WindowDropdownShowColour(this, widget, colours[1].withFlag(ColourFlag::translucent, true), _textColour); break; } } diff --git a/src/openrct2-ui/windows/StaffList.cpp b/src/openrct2-ui/windows/StaffList.cpp index 98af402fda..f8c1a9ea59 100644 --- a/src/openrct2-ui/windows/StaffList.cpp +++ b/src/openrct2-ui/windows/StaffList.cpp @@ -381,7 +381,7 @@ static Widget _staffListWidgets[] = { auto dpiCoords = ScreenCoordsXY{ dpi.x, dpi.y }; GfxFillRect( dpi, { dpiCoords, dpiCoords + ScreenCoordsXY{ dpi.width - 1, dpi.height - 1 } }, - ColourMapA[colours[1]].mid_light); + ColourMapA[colours[1].colour].mid_light); // How much space do we have for the name and action columns? (Discount scroll area and icons.) const int32_t nonIconSpace = widgets[WIDX_STAFF_LIST_LIST].width() - 15 - 68; diff --git a/src/openrct2-ui/windows/TextInput.cpp b/src/openrct2-ui/windows/TextInput.cpp index b6a4407ba1..4730a1b6ad 100644 --- a/src/openrct2-ui/windows/TextInput.cpp +++ b/src/openrct2-ui/windows/TextInput.cpp @@ -266,7 +266,7 @@ namespace OpenRCT2::Ui::Windows if (_cursorBlink > 15) { - uint8_t colour = ColourMapA[colours[1]].mid_light; + uint8_t colour = ColourMapA[colours[1].colour].mid_light; // TODO: palette index addition GfxFillRect( dpi, { { cursorX, screenCoords.y + 9 }, { cursorX + textWidth, screenCoords.y + 9 } }, colour + 5); diff --git a/src/openrct2-ui/windows/Themes.cpp b/src/openrct2-ui/windows/Themes.cpp index 7af9c692dd..bef54652d2 100644 --- a/src/openrct2-ui/windows/Themes.cpp +++ b/src/openrct2-ui/windows/Themes.cpp @@ -613,11 +613,11 @@ static WindowClass window_themes_tab_7_classes[] = { case WIDX_THEMES_LIST: if (selectedIndex != -1) { - const auto newColour = ThemeOverrideExtendedColour(ColourDropDownIndexToColour(selectedIndex)); + ColourWithFlags newColour = { ColourDropDownIndexToColour(selectedIndex) }; WindowClass wc = GetWindowClassTabIndex(_colour_index_1); - uint8_t colour = ThemeGetColour(wc, _colour_index_2); - colour = (colour & COLOUR_FLAG_TRANSLUCENT) | newColour; - ThemeSetColour(wc, _colour_index_2, colour); + auto oldColour = ThemeGetColour(wc, _colour_index_2); + newColour.flags = oldColour.flags; + ThemeSetColour(wc, _colour_index_2, newColour); ColourSchemeUpdateAll(); WindowInvalidateAll(); _colour_index_1 = -1; @@ -716,8 +716,9 @@ static WindowClass window_themes_tab_7_classes[] = { widgets[WIDX_THEMES_COLOURBTN_MASK].right = widgets[WIDX_THEMES_COLOURBTN_MASK].left + 12; widgets[WIDX_THEMES_COLOURBTN_MASK].bottom = widgets[WIDX_THEMES_COLOURBTN_MASK].top + 12; - uint8_t colour = ThemeGetColour(wc, _colour_index_2); - WindowDropdownShowColour(this, &(widgets[WIDX_THEMES_COLOURBTN_MASK]), colours[1], colour); + auto colour = ThemeGetColour(wc, _colour_index_2); + WindowDropdownShowColour( + this, &(widgets[WIDX_THEMES_COLOURBTN_MASK]), colours[1], colour.colour, true); WidgetInvalidate(*this, WIDX_THEMES_LIST); } } @@ -731,15 +732,8 @@ static WindowClass window_themes_tab_7_classes[] = { } else { - uint8_t colour = ThemeGetColour(wc, _colour_index_2); - if (colour & COLOUR_FLAG_TRANSLUCENT) - { - colour &= ~COLOUR_FLAG_TRANSLUCENT; - } - else - { - colour |= COLOUR_FLAG_TRANSLUCENT; - } + auto colour = ThemeGetColour(wc, _colour_index_2); + colour.setFlag(ColourFlag::translucent, !colour.hasFlag(ColourFlag::translucent)); ThemeSetColour(wc, _colour_index_2, colour); ColourSchemeUpdateAll(); WindowInvalidateAll(); @@ -756,10 +750,10 @@ static WindowClass window_themes_tab_7_classes[] = { if (_selected_tab == WINDOW_THEMES_TAB_SETTINGS || _selected_tab == WINDOW_THEMES_TAB_FEATURES) return; - if ((colours[1] & 0x80) == 0) + if (!colours[1].hasFlag(ColourFlag::translucent)) // GfxFillRect(dpi, dpi->x, dpi->y, dpi->x + dpi->width - 1, dpi->y + dpi->height - 1, - // ColourMapA[colours[1]].mid_light); - GfxClear(dpi, ColourMapA[colours[1]].mid_light); + // ColourMapA[colours[1].colour].mid_light); + GfxClear(dpi, ColourMapA[colours[1].colour].mid_light); screenCoords.y = 0; for (int32_t i = 0; i < GetColourSchemeTabCount(); i++) { @@ -771,26 +765,26 @@ static WindowClass window_themes_tab_7_classes[] = { { if (i + 1 < GetColourSchemeTabCount()) { - int32_t colour = colours[1]; + auto colour = colours[1]; auto leftTop = ScreenCoordsXY{ 0, screenCoords.y + _row_height - 2 }; auto rightBottom = ScreenCoordsXY{ widgets[WIDX_THEMES_LIST].right, screenCoords.y + _row_height - 2 }; auto yPixelOffset = ScreenCoordsXY{ 0, 1 }; - if (colour & COLOUR_FLAG_TRANSLUCENT) + if (colour.hasFlag(ColourFlag::translucent)) { - TranslucentWindowPalette windowPalette = TranslucentWindowPalettes[BASE_COLOUR(colour)]; + TranslucentWindowPalette windowPalette = TranslucentWindowPalettes[colour.colour]; GfxFilterRect(dpi, { leftTop, rightBottom }, windowPalette.highlight); GfxFilterRect(dpi, { leftTop + yPixelOffset, rightBottom + yPixelOffset }, windowPalette.shadow); } else { - colour = ColourMapA[colours[1]].mid_dark; - GfxFillRect(dpi, { leftTop, rightBottom }, colour); + colour = ColourMapA[colours[1].colour].mid_dark; + GfxFillRect(dpi, { leftTop, rightBottom }, colour.colour); - colour = ColourMapA[colours[1]].lightest; - GfxFillRect(dpi, { leftTop + yPixelOffset, rightBottom + yPixelOffset }, colour); + colour = ColourMapA[colours[1].colour].lightest; + GfxFillRect(dpi, { leftTop + yPixelOffset, rightBottom + yPixelOffset }, colour.colour); } } @@ -800,20 +794,18 @@ static WindowClass window_themes_tab_7_classes[] = { { DrawTextBasic(dpi, { 2, screenCoords.y + 4 }, ThemeDescGetName(wc), {}, { colours[1] }); - uint8_t colour = ThemeGetColour(wc, j); + auto colour = ThemeGetColour(wc, j); const bool isPressed = (i == _colour_index_1 && j == _colour_index_2); - auto image = ImageId( - isPressed ? SPR_PALETTE_BTN_PRESSED : SPR_PALETTE_BTN, colour & ~COLOUR_FLAG_TRANSLUCENT); + auto image = ImageId(isPressed ? SPR_PALETTE_BTN_PRESSED : SPR_PALETTE_BTN, colour.colour); GfxDrawSprite(dpi, image, { _button_offset_x + 12 * j, screenCoords.y + _button_offset_y }); ScreenCoordsXY topLeft{ _button_offset_x + 12 * j, screenCoords.y + _check_offset_y }; ScreenCoordsXY bottomRight{ _button_offset_x + 12 * j + 9, screenCoords.y + _check_offset_y + 10 }; GfxFillRectInset(dpi, { topLeft, bottomRight }, colours[1], INSET_RECT_F_E0); - if (colour & COLOUR_FLAG_TRANSLUCENT) + if (colour.hasFlag(ColourFlag::translucent)) { DrawText( - dpi, topLeft, - { static_cast(colours[1] & 0x7F), FontStyle::Medium, TextDarkness::Dark }, + dpi, topLeft, { colours[1].colour, FontStyle::Medium, TextDarkness::Dark }, static_cast(CheckBoxMarkString)); } } diff --git a/src/openrct2-ui/windows/TileInspector.cpp b/src/openrct2-ui/windows/TileInspector.cpp index c3fdeb5f01..3101e7deae 100644 --- a/src/openrct2-ui/windows/TileInspector.cpp +++ b/src/openrct2-ui/windows/TileInspector.cpp @@ -1468,10 +1468,10 @@ static uint64_t PageDisabledWidgets[] = { DrawTextBasic(dpi, screenCoords, STR_TILE_INSPECTOR_WALL_ANIMATION_FRAME, {}, { colours[1] }); // Current animation frame - colour_t colour = colours[1]; + auto colour = colours[1]; if (IsWidgetDisabled(WIDX_WALL_SPINNER_ANIMATION_FRAME)) { - colour = colours[0] | COLOUR_FLAG_INSET; + colour = colours[0].withFlag(ColourFlag::inset, true); } screenCoords.x = windowPos.x + widgets[WIDX_WALL_SPINNER_ANIMATION_FRAME].left + 3; ft = Formatter(); @@ -1571,7 +1571,8 @@ static uint64_t PageDisabledWidgets[] = { { const int32_t listWidth = widgets[WIDX_LIST].width(); GfxFillRect( - dpi, { { dpi.x, dpi.y }, { dpi.x + dpi.width - 1, dpi.y + dpi.height - 1 } }, ColourMapA[colours[1]].mid_light); + dpi, { { dpi.x, dpi.y }, { dpi.x + dpi.width - 1, dpi.y + dpi.height - 1 } }, + ColourMapA[colours[1].colour].mid_light); // Show usage hint when nothing is selected if (!_tileSelected) @@ -1605,12 +1606,12 @@ static uint64_t PageDisabledWidgets[] = { auto fillRectangle = ScreenRect{ { 0, screenCoords.y }, { listWidth, screenCoords.y + kScrollableRowHeight - 1 } }; if (selectedRow) - GfxFillRect(dpi, fillRectangle, ColourMapA[colours[1]].mid_dark); + GfxFillRect(dpi, fillRectangle, ColourMapA[colours[1].colour].mid_dark); else if (hoveredRow) - GfxFillRect(dpi, fillRectangle, ColourMapA[colours[1]].mid_dark | 0x1000000); + GfxFillRect(dpi, fillRectangle, ColourMapA[colours[1].colour].mid_dark | 0x1000000); // Zebra stripes else if (((windowTileInspectorElementCount - i) & 1) == 0) - GfxFillRect(dpi, fillRectangle, ColourMapA[colours[1]].light | 0x1000000); + GfxFillRect(dpi, fillRectangle, ColourMapA[colours[1].colour].light | 0x1000000); StringId stringFormat = STR_WINDOW_COLOUR_2_STRINGID; if (selectedRow || hoveredRow) diff --git a/src/openrct2-ui/windows/TitleLogo.cpp b/src/openrct2-ui/windows/TitleLogo.cpp index 16bd5bb8cd..f2709a69c1 100644 --- a/src/openrct2-ui/windows/TitleLogo.cpp +++ b/src/openrct2-ui/windows/TitleLogo.cpp @@ -40,9 +40,9 @@ namespace OpenRCT2::Ui::Windows { widgets = _titleLogoWidgets; WindowInitScrollWidgets(*this); - colours[0] = TRANSLUCENT(COLOUR_GREY); - colours[1] = TRANSLUCENT(COLOUR_GREY); - colours[2] = TRANSLUCENT(COLOUR_GREY); + colours[0] = ColourWithFlags{ COLOUR_GREY }.withFlag(ColourFlag::translucent, true); + colours[1] = ColourWithFlags{ COLOUR_GREY }.withFlag(ColourFlag::translucent, true); + colours[2] = ColourWithFlags{ COLOUR_GREY }.withFlag(ColourFlag::translucent, true); } void OnMouseUp(WidgetIndex widgetIndex) override diff --git a/src/openrct2-ui/windows/TitleMenu.cpp b/src/openrct2-ui/windows/TitleMenu.cpp index d49a5eb53c..4dc075b6b6 100644 --- a/src/openrct2-ui/windows/TitleMenu.cpp +++ b/src/openrct2-ui/windows/TitleMenu.cpp @@ -112,7 +112,7 @@ static Widget _titleMenuWidgets[] = { width = x; widgets[WIDX_NEW_VERSION].right = width; windowPos.x = (ContextGetWidth() - width) / 2; - colours[1] = TRANSLUCENT(COLOUR_LIGHT_ORANGE); + colours[1] = ColourWithFlags{ COLOUR_LIGHT_ORANGE }.withFlag(ColourFlag::translucent, true); InitScrollWidgets(); } @@ -214,7 +214,7 @@ static Widget _titleMenuWidgets[] = { WindowDropdownShowText( windowPos + ScreenCoordsXY{ widget->left, widget->top + yOffset }, widget->height() + 1, - TRANSLUCENT(colours[0]), Dropdown::Flag::StayOpen, i); + colours[0].withFlag(ColourFlag::translucent, true), Dropdown::Flag::StayOpen, i); } } diff --git a/src/openrct2-ui/windows/TopToolbar.cpp b/src/openrct2-ui/windows/TopToolbar.cpp index 5336c39ba3..6183953d61 100644 --- a/src/openrct2-ui/windows/TopToolbar.cpp +++ b/src/openrct2-ui/windows/TopToolbar.cpp @@ -3257,7 +3257,7 @@ namespace OpenRCT2::Ui::Windows // Draw an overlay if clearance checks are disabled if (GetGameState().Cheats.DisableClearanceChecks) { - auto colour = static_cast(EnumValue(COLOUR_DARK_ORANGE) | EnumValue(COLOUR_FLAG_OUTLINE)); + auto colour = ColourWithFlags{ COLOUR_DARK_ORANGE }.withFlag(ColourFlag::withOutline, true); DrawTextBasic( dpi, screenPos + ScreenCoordsXY{ 26, 2 }, STR_OVERLAY_CLEARANCE_CHECKS_DISABLED, {}, { colour, TextAlignment::RIGHT }); @@ -3323,7 +3323,7 @@ namespace OpenRCT2::Ui::Windows // Draw number of players. auto ft = Formatter(); ft.Add(NetworkGetNumVisiblePlayers()); - auto colour = static_cast(EnumValue(COLOUR_WHITE) | EnumValue(COLOUR_FLAG_OUTLINE)); + auto colour = ColourWithFlags{ COLOUR_WHITE }.withFlag(ColourFlag::withOutline, true); DrawTextBasic(dpi, screenPos + ScreenCoordsXY{ 23, 1 }, STR_COMMA16, ft, { colour, TextAlignment::RIGHT }); } } @@ -3433,8 +3433,8 @@ namespace OpenRCT2::Ui::Windows SetItems(items); WindowDropdownShowText( - { windowPos.x + widget.left, windowPos.y + widget.top }, widget.height() + 1, colours[1] | 0x80, 0, - TOP_TOOLBAR_VIEW_MENU_COUNT); + { windowPos.x + widget.left, windowPos.y + widget.top }, widget.height() + 1, + colours[1].withFlag(ColourFlag::translucent, true), 0, TOP_TOOLBAR_VIEW_MENU_COUNT); // Set checkmarks auto* mainViewport = WindowGetMain()->viewport; @@ -3588,7 +3588,8 @@ namespace OpenRCT2::Ui::Windows #endif WindowDropdownShowText( - { windowPos.x + widget.left, windowPos.y + widget.top }, widget.height() + 1, colours[1] | 0x80, 0, i); + { windowPos.x + widget.left, windowPos.y + widget.top }, widget.height() + 1, + colours[1].withFlag(ColourFlag::translucent, true), 0, i); gDropdownDefaultIndex = DDIDX_SHOW_MAP; } @@ -3658,7 +3659,8 @@ namespace OpenRCT2::Ui::Windows gDropdownItems[3].Args = STR_SPEED_TURBO; WindowDropdownShowText( - { windowPos.x + widget.left, windowPos.y + widget.top }, widget.height() + 1, colours[0] | 0x80, 0, num_items); + { windowPos.x + widget.left, windowPos.y + widget.top }, widget.height() + 1, + colours[0].withFlag(ColourFlag::translucent, true), 0, num_items); // Set checkmarks if (gGameSpeed <= 4) @@ -3707,7 +3709,8 @@ namespace OpenRCT2::Ui::Windows gDropdownItems[1].Format = STR_ROTATE_ANTI_CLOCKWISE; WindowDropdownShowText( - { windowPos.x + widget.left, windowPos.y + widget.top }, widget.height() + 1, colours[1] | 0x80, 0, 2); + { windowPos.x + widget.left, windowPos.y + widget.top }, widget.height() + 1, + colours[1].withFlag(ColourFlag::translucent, true), 0, 2); gDropdownDefaultIndex = DDIDX_ROTATE_CLOCKWISE; } @@ -3792,8 +3795,8 @@ namespace OpenRCT2::Ui::Windows } WindowDropdownShowText( - { windowPos.x + widget.left, windowPos.y + widget.top }, widget.height() + 1, colours[0] | 0x80, - Dropdown::Flag::StayOpen, numItems); + { windowPos.x + widget.left, windowPos.y + widget.top }, widget.height() + 1, + colours[0].withFlag(ColourFlag::translucent, true), Dropdown::Flag::StayOpen, numItems); } void TopToolbar::InitCheatsMenu(Widget& widget) @@ -3817,8 +3820,8 @@ namespace OpenRCT2::Ui::Windows SetItems(items); WindowDropdownShowText( - { windowPos.x + widget.left, windowPos.y + widget.top }, widget.height() + 1, colours[0] | 0x80, - Dropdown::Flag::StayOpen, TOP_TOOLBAR_CHEATS_COUNT); + { windowPos.x + widget.left, windowPos.y + widget.top }, widget.height() + 1, + colours[0].withFlag(ColourFlag::translucent, true), Dropdown::Flag::StayOpen, TOP_TOOLBAR_CHEATS_COUNT); // Disable items that are not yet available in multiplayer if (NetworkGetMode() != NETWORK_MODE_NONE) @@ -3896,8 +3899,8 @@ namespace OpenRCT2::Ui::Windows gDropdownItems[DDIDX_DEBUG_PAINT].Args = STR_DEBUG_DROPDOWN_DEBUG_PAINT; WindowDropdownShowText( - { windowPos.x + widget.left, windowPos.y + widget.top }, widget.height() + 1, colours[0] | 0x80, - Dropdown::Flag::StayOpen, TOP_TOOLBAR_DEBUG_COUNT); + { windowPos.x + widget.left, windowPos.y + widget.top }, widget.height() + 1, + colours[0].withFlag(ColourFlag::translucent, true), Dropdown::Flag::StayOpen, TOP_TOOLBAR_DEBUG_COUNT); Dropdown::SetChecked(DDIDX_DEBUG_PAINT, WindowFindByClass(WindowClass::DebugPaint) != nullptr); } @@ -3935,8 +3938,8 @@ namespace OpenRCT2::Ui::Windows gDropdownItems[DDIDX_MULTIPLAYER_RECONNECT].Format = STR_MULTIPLAYER_RECONNECT; WindowDropdownShowText( - { windowPos.x + widget.left, windowPos.y + widget.top }, widget.height() + 1, colours[0] | 0x80, 0, - TOP_TOOLBAR_NETWORK_COUNT); + { windowPos.x + widget.left, windowPos.y + widget.top }, widget.height() + 1, + colours[0].withFlag(ColourFlag::translucent, true), 0, TOP_TOOLBAR_NETWORK_COUNT); Dropdown::SetDisabled(DDIDX_MULTIPLAYER_RECONNECT, !NetworkIsDesynchronised()); diff --git a/src/openrct2-ui/windows/TrackDesignPlace.cpp b/src/openrct2-ui/windows/TrackDesignPlace.cpp index 317c876d3b..be4435abfc 100644 --- a/src/openrct2-ui/windows/TrackDesignPlace.cpp +++ b/src/openrct2-ui/windows/TrackDesignPlace.cpp @@ -302,7 +302,7 @@ static Widget _trackPlaceWidgets[] = { g1temp.height = TRACK_MINI_PREVIEW_HEIGHT; GfxSetG1Element(SPR_TEMP, &g1temp); DrawingEngineInvalidateImage(SPR_TEMP); - GfxDrawSprite(clippedDpi, ImageId(SPR_TEMP, NOT_TRANSLUCENT(this->colours[0])), { 0, 0 }); + GfxDrawSprite(clippedDpi, ImageId(SPR_TEMP, this->colours[0].colour), { 0, 0 }); } // Price diff --git a/src/openrct2-ui/windows/TrackList.cpp b/src/openrct2-ui/windows/TrackList.cpp index 2f9a7cade7..05d55955c7 100644 --- a/src/openrct2-ui/windows/TrackList.cpp +++ b/src/openrct2-ui/windows/TrackList.cpp @@ -466,7 +466,7 @@ static Widget _trackListWidgets[] = { // Track preview auto& tdWidget = widgets[WIDX_TRACK_PREVIEW]; - int32_t colour = ColourMapA[colours[0]].darkest; + int32_t colour = ColourMapA[colours[0].colour].darkest; u8string path = _trackDesigns[trackIndex].path; // Show track file path (in debug mode) @@ -675,7 +675,7 @@ static Widget _trackListWidgets[] = { void OnScrollDraw(const int32_t scrollIndex, DrawPixelInfo& dpi) override { - uint8_t paletteIndex = ColourMapA[colours[0]].mid_light; + uint8_t paletteIndex = ColourMapA[colours[0].colour].mid_light; GfxClear(dpi, paletteIndex); auto screenCoords = ScreenCoordsXY{ 0, 0 }; diff --git a/src/openrct2/drawing/Drawing.String.cpp b/src/openrct2/drawing/Drawing.String.cpp index 86ca97f831..15d97d274c 100644 --- a/src/openrct2/drawing/Drawing.String.cpp +++ b/src/openrct2/drawing/Drawing.String.cpp @@ -257,7 +257,8 @@ int32_t GfxWrapString(u8string_view text, int32_t width, FontStyle fontStyle, u8 /** * Draws text that is left aligned and vertically centred. */ -void GfxDrawStringLeftCentred(DrawPixelInfo& dpi, StringId format, void* args, colour_t colour, const ScreenCoordsXY& coords) +void GfxDrawStringLeftCentred( + DrawPixelInfo& dpi, StringId format, void* args, ColourWithFlags colour, const ScreenCoordsXY& coords) { char buffer[CommonTextBufferSize]; auto bufferPtr = buffer; @@ -294,11 +295,10 @@ static void ColourCharacter(uint8_t colour, const uint16_t* current_font_flags, * Changes the palette so that the next character changes colour * This is specific to changing to a predefined window related colour */ -static void ColourCharacterWindow(uint8_t colour, const uint16_t* current_font_flags, uint8_t* palette_pointer) +static void ColourCharacterWindow(colour_t colour, const uint16_t* current_font_flags, uint8_t* palette_pointer) { int32_t eax; - colour = NOT_TRANSLUCENT(colour); eax = ColourMapA[colour].colour_11; if (*current_font_flags & TEXT_DRAW_FLAG_OUTLINE) { @@ -746,50 +746,48 @@ static void TTFProcessString(DrawPixelInfo& dpi, std::string_view text, TextDraw } } -static void TTFProcessInitialColour(int32_t colour, TextDrawInfo* info) +static void TTFProcessInitialColour(ColourWithFlags colour, TextDrawInfo* info) { - if (colour != TEXT_COLOUR_254 && colour != TEXT_COLOUR_255) + if (colour.colour != TEXT_COLOUR_254 && colour.colour != TEXT_COLOUR_255) { info->flags &= ~(TEXT_DRAW_FLAG_INSET | TEXT_DRAW_FLAG_OUTLINE); - if (colour & COLOUR_FLAG_OUTLINE) + if (colour.hasFlag(ColourFlag::withOutline)) { info->flags |= TEXT_DRAW_FLAG_OUTLINE; } - colour &= ~COLOUR_FLAG_OUTLINE; - if (!(colour & COLOUR_FLAG_INSET)) + if (!colour.hasFlag(ColourFlag::inset)) { if (!(info->flags & TEXT_DRAW_FLAG_INSET)) { uint16_t flags = info->flags; - ColourCharacterWindow(colour, &flags, reinterpret_cast(&info->palette)); + ColourCharacterWindow(colour.colour, &flags, reinterpret_cast(&info->palette)); } } else { info->flags |= TEXT_DRAW_FLAG_INSET; - colour &= ~COLOUR_FLAG_INSET; uint32_t eax; if (info->flags & TEXT_DRAW_FLAG_DARK) { if (info->flags & TEXT_DRAW_FLAG_EXTRA_DARK) { - eax = ColourMapA[colour].mid_light; + eax = ColourMapA[colour.colour].mid_light; eax = eax << 16; - eax = eax | ColourMapA[colour].dark; + eax = eax | ColourMapA[colour.colour].dark; } else { - eax = ColourMapA[colour].light; + eax = ColourMapA[colour.colour].light; eax = eax << 16; - eax = eax | ColourMapA[colour].mid_dark; + eax = eax | ColourMapA[colour.colour].mid_dark; } } else { - eax = ColourMapA[colour].lighter; + eax = ColourMapA[colour.colour].lighter; eax = eax << 16; - eax = eax | ColourMapA[colour].mid_light; + eax = eax | ColourMapA[colour.colour].mid_light; } // Adjust text palette. Store current colour? ; @@ -802,7 +800,7 @@ static void TTFProcessInitialColour(int32_t colour, TextDrawInfo* info) } void TTFDrawString( - DrawPixelInfo& dpi, const_utf8string text, int32_t colour, const ScreenCoordsXY& coords, bool noFormatting, + DrawPixelInfo& dpi, const_utf8string text, ColourWithFlags colour, const ScreenCoordsXY& coords, bool noFormatting, FontStyle fontStyle, TextDarkness darkness) { if (text == nullptr) @@ -877,7 +875,7 @@ static int32_t TTFGetStringWidth(std::string_view text, FontStyle fontStyle, boo * rct2: 0x00682F28 */ void GfxDrawStringWithYOffsets( - DrawPixelInfo& dpi, const utf8* text, int32_t colour, const ScreenCoordsXY& coords, const int8_t* yOffsets, + DrawPixelInfo& dpi, const utf8* text, ColourWithFlags colour, const ScreenCoordsXY& coords, const int8_t* yOffsets, bool forceSpriteFont, FontStyle fontStyle) { TextDrawInfo info; diff --git a/src/openrct2/drawing/Drawing.h b/src/openrct2/drawing/Drawing.h index 88d4a1adae..cd26b80f70 100644 --- a/src/openrct2/drawing/Drawing.h +++ b/src/openrct2/drawing/Drawing.h @@ -547,7 +547,7 @@ void GfxDrawDashedLine( // rect void GfxFillRect(DrawPixelInfo& dpi, const ScreenRect& rect, int32_t colour); -void GfxFillRectInset(DrawPixelInfo& dpi, const ScreenRect& rect, int32_t colour, uint8_t flags); +void GfxFillRectInset(DrawPixelInfo& dpi, const ScreenRect& rect, ColourWithFlags colour, uint8_t flags); void GfxFilterRect(DrawPixelInfo& dpi, const ScreenRect& rect, FilterPaletteID palette); // sprite @@ -577,14 +577,15 @@ void FASTCALL GfxDrawSpriteRawMaskedSoftware( DrawPixelInfo& dpi, const ScreenCoordsXY& scrCoords, const ImageId maskImage, const ImageId colourImage); // string -void GfxDrawStringLeftCentred(DrawPixelInfo& dpi, StringId format, void* args, colour_t colour, const ScreenCoordsXY& coords); +void GfxDrawStringLeftCentred( + DrawPixelInfo& dpi, StringId format, void* args, ColourWithFlags colour, const ScreenCoordsXY& coords); void DrawStringCentredRaw( DrawPixelInfo& dpi, const ScreenCoordsXY& coords, int32_t numLines, const utf8* text, FontStyle fontStyle); void DrawNewsTicker( DrawPixelInfo& dpi, const ScreenCoordsXY& coords, int32_t width, colour_t colour, StringId format, u8string_view args, int32_t ticks); void GfxDrawStringWithYOffsets( - DrawPixelInfo& dpi, const utf8* text, int32_t colour, const ScreenCoordsXY& coords, const int8_t* yOffsets, + DrawPixelInfo& dpi, const utf8* text, ColourWithFlags colour, const ScreenCoordsXY& coords, const int8_t* yOffsets, bool forceSpriteFont, FontStyle fontStyle); int32_t GfxWrapString(u8string_view text, int32_t width, FontStyle fontStyle, u8string* outWrappedText, int32_t* outNumLines); @@ -595,7 +596,7 @@ int32_t StringGetHeightRaw(std::string_view text, FontStyle fontStyle); int32_t GfxClipString(char* buffer, int32_t width, FontStyle fontStyle); u8string ShortenPath(const u8string& path, int32_t availableWidth, FontStyle fontStyle); void TTFDrawString( - DrawPixelInfo& dpi, const_utf8string text, int32_t colour, const ScreenCoordsXY& coords, bool noFormatting, + DrawPixelInfo& dpi, const_utf8string text, ColourWithFlags colour, const ScreenCoordsXY& coords, bool noFormatting, FontStyle fontStyle, TextDarkness darkness); // scrolling text diff --git a/src/openrct2/drawing/Rect.cpp b/src/openrct2/drawing/Rect.cpp index e9044dd5b3..501e9fde68 100644 --- a/src/openrct2/drawing/Rect.cpp +++ b/src/openrct2/drawing/Rect.cpp @@ -24,15 +24,15 @@ * colour (ebp) * flags (si) */ -void GfxFillRectInset(DrawPixelInfo& dpi, const ScreenRect& rect, int32_t colour, uint8_t flags) +void GfxFillRectInset(DrawPixelInfo& dpi, const ScreenRect& rect, ColourWithFlags colour, uint8_t flags) { const auto leftTop = ScreenCoordsXY{ rect.GetLeft(), rect.GetTop() }; const auto leftBottom = ScreenCoordsXY{ rect.GetLeft(), rect.GetBottom() }; const auto rightTop = ScreenCoordsXY{ rect.GetRight(), rect.GetTop() }; const auto rightBottom = ScreenCoordsXY{ rect.GetRight(), rect.GetBottom() }; - if (colour & COLOUR_FLAG_TRANSLUCENT) + if (colour.hasFlag(ColourFlag::translucent)) { - auto palette = TranslucentWindowPalettes[BASE_COLOUR(colour)]; + auto palette = TranslucentWindowPalettes[colour.colour]; if (flags & INSET_RECT_FLAG_BORDER_NONE) { @@ -71,15 +71,15 @@ void GfxFillRectInset(DrawPixelInfo& dpi, const ScreenRect& rect, int32_t colour uint8_t shadow, fill, hilight; if (flags & INSET_RECT_FLAG_FILL_MID_LIGHT) { - shadow = ColourMapA[colour].dark; - fill = ColourMapA[colour].mid_light; - hilight = ColourMapA[colour].lighter; + shadow = ColourMapA[colour.colour].dark; + fill = ColourMapA[colour.colour].mid_light; + hilight = ColourMapA[colour.colour].lighter; } else { - shadow = ColourMapA[colour].mid_dark; - fill = ColourMapA[colour].light; - hilight = ColourMapA[colour].lighter; + shadow = ColourMapA[colour.colour].mid_dark; + fill = ColourMapA[colour.colour].light; + hilight = ColourMapA[colour.colour].lighter; } if (flags & INSET_RECT_FLAG_BORDER_NONE) @@ -104,7 +104,7 @@ void GfxFillRectInset(DrawPixelInfo& dpi, const ScreenRect& rect, int32_t colour } else { - fill = ColourMapA[colour].lighter; + fill = ColourMapA[colour.colour].lighter; } } GfxFillRect(dpi, { leftTop + ScreenCoordsXY{ 1, 1 }, rightBottom - ScreenCoordsXY{ 1, 1 } }, fill); diff --git a/src/openrct2/drawing/Text.h b/src/openrct2/drawing/Text.h index fcf1f28e78..3de584c26c 100644 --- a/src/openrct2/drawing/Text.h +++ b/src/openrct2/drawing/Text.h @@ -39,17 +39,21 @@ enum class TextDarkness struct TextPaint { - colour_t Colour = COLOUR_BLACK; + ColourWithFlags Colour = { COLOUR_BLACK }; ::FontStyle FontStyle = FontStyle::Medium; TextUnderline UnderlineText = TextUnderline::Off; TextAlignment Alignment = TextAlignment::LEFT; TextDarkness Darkness = TextDarkness::Regular; TextPaint() = default; - TextPaint(colour_t colour) + TextPaint(ColourWithFlags colour) : Colour(colour) { } + TextPaint(colour_t colour) + : Colour(ColourWithFlags{ colour }) + { + } TextPaint(::FontStyle fontStyle) : FontStyle(fontStyle) { @@ -63,21 +67,36 @@ struct TextPaint { } - TextPaint(colour_t colour, ::FontStyle fontStyle) + TextPaint(ColourWithFlags colour, ::FontStyle fontStyle) : Colour(colour) , FontStyle(fontStyle) { } - TextPaint(colour_t colour, TextUnderline underlineText) + TextPaint(colour_t colour, ::FontStyle fontStyle) + : Colour(ColourWithFlags{ colour }) + , FontStyle(fontStyle) + { + } + TextPaint(ColourWithFlags colour, TextUnderline underlineText) : Colour(colour) , UnderlineText(underlineText) { } - TextPaint(colour_t colour, TextAlignment alignment) + TextPaint(colour_t colour, TextUnderline underlineText) + : Colour(ColourWithFlags{ colour }) + , UnderlineText(underlineText) + { + } + TextPaint(ColourWithFlags colour, TextAlignment alignment) : Colour(colour) , Alignment(alignment) { } + TextPaint(colour_t colour, TextAlignment alignment) + : Colour(ColourWithFlags{ colour }) + , Alignment(alignment) + { + } TextPaint(::FontStyle fontStyle, TextUnderline underlineText) : FontStyle(fontStyle) @@ -95,30 +114,54 @@ struct TextPaint { } - TextPaint(colour_t colour, ::FontStyle fontStyle, TextUnderline underlineText) + TextPaint(ColourWithFlags colour, ::FontStyle fontStyle, TextUnderline underlineText) : Colour(colour) , FontStyle(fontStyle) , UnderlineText(underlineText) { } - TextPaint(colour_t colour, ::FontStyle fontStyle, TextAlignment alignment) + TextPaint(colour_t colour, ::FontStyle fontStyle, TextUnderline underlineText) + : Colour(ColourWithFlags{ colour }) + , FontStyle(fontStyle) + , UnderlineText(underlineText) + { + } + TextPaint(ColourWithFlags colour, ::FontStyle fontStyle, TextAlignment alignment) : Colour(colour) , FontStyle(fontStyle) , Alignment(alignment) { } - TextPaint(colour_t colour, ::FontStyle fontStyle, TextDarkness darkness) + TextPaint(colour_t colour, ::FontStyle fontStyle, TextAlignment alignment) + : Colour(ColourWithFlags{ colour }) + , FontStyle(fontStyle) + , Alignment(alignment) + { + } + TextPaint(ColourWithFlags colour, ::FontStyle fontStyle, TextDarkness darkness) : Colour(colour) , FontStyle(fontStyle) , Darkness(darkness) { } - TextPaint(colour_t colour, TextUnderline underlineText, TextAlignment alignment) + TextPaint(colour_t colour, ::FontStyle fontStyle, TextDarkness darkness) + : Colour(ColourWithFlags{ colour }) + , FontStyle(fontStyle) + , Darkness(darkness) + { + } + TextPaint(ColourWithFlags colour, TextUnderline underlineText, TextAlignment alignment) : Colour(colour) , UnderlineText(underlineText) , Alignment(alignment) { } + TextPaint(colour_t colour, TextUnderline underlineText, TextAlignment alignment) + : Colour(ColourWithFlags{ colour }) + , UnderlineText(underlineText) + , Alignment(alignment) + { + } TextPaint(::FontStyle fontStyle, TextUnderline underlineText, TextAlignment alignment) : FontStyle(fontStyle) , UnderlineText(underlineText) @@ -126,20 +169,34 @@ struct TextPaint { } - TextPaint(colour_t colour, ::FontStyle fontStyle, TextUnderline underlineText, TextAlignment alignment) + TextPaint(ColourWithFlags colour, ::FontStyle fontStyle, TextUnderline underlineText, TextAlignment alignment) : Colour(colour) , FontStyle(fontStyle) , UnderlineText(underlineText) , Alignment(alignment) { } - TextPaint(colour_t colour, ::FontStyle fontStyle, TextAlignment alignment, TextDarkness darkness) + TextPaint(colour_t colour, ::FontStyle fontStyle, TextUnderline underlineText, TextAlignment alignment) + : Colour(ColourWithFlags{ colour }) + , FontStyle(fontStyle) + , UnderlineText(underlineText) + , Alignment(alignment) + { + } + TextPaint(ColourWithFlags colour, ::FontStyle fontStyle, TextAlignment alignment, TextDarkness darkness) : Colour(colour) , FontStyle(fontStyle) , Alignment(alignment) , Darkness(darkness) { } + TextPaint(colour_t colour, ::FontStyle fontStyle, TextAlignment alignment, TextDarkness darkness) + : Colour(ColourWithFlags{ colour }) + , FontStyle(fontStyle) + , Alignment(alignment) + , Darkness(darkness) + { + } }; void DrawTextBasic(DrawPixelInfo& dpi, const ScreenCoordsXY& coords, StringId format); diff --git a/src/openrct2/interface/Chat.cpp b/src/openrct2/interface/Chat.cpp index f35529b30e..4eb2bef613 100644 --- a/src/openrct2/interface/Chat.cpp +++ b/src/openrct2/interface/Chat.cpp @@ -85,7 +85,7 @@ void ChatUpdate() _chatCaretTicks = (_chatCaretTicks + 1) % 30; } -void ChatDraw(DrawPixelInfo& dpi, uint8_t chatBackgroundColor) +void ChatDraw(DrawPixelInfo& dpi, ColourWithFlags chatBackgroundColor) { thread_local std::string lineBuffer; diff --git a/src/openrct2/interface/Chat.h b/src/openrct2/interface/Chat.h index e55a8fbeed..9612acdbbe 100644 --- a/src/openrct2/interface/Chat.h +++ b/src/openrct2/interface/Chat.h @@ -11,6 +11,7 @@ #include "../common.h" #include "../core/String.hpp" +#include "Colour.h" #include @@ -38,7 +39,7 @@ void ChatToggle(); void ChatInit(); void ChatUpdate(); -void ChatDraw(DrawPixelInfo& dpi, uint8_t chatBackgroundColour); +void ChatDraw(DrawPixelInfo& dpi, ColourWithFlags chatBackgroundColour); void ChatAddHistory(std::string_view s); void ChatInput(ChatInput input); diff --git a/src/openrct2/interface/Colour.cpp b/src/openrct2/interface/Colour.cpp index 7829b74167..6a7ca15c42 100644 --- a/src/openrct2/interface/Colour.cpp +++ b/src/openrct2/interface/Colour.cpp @@ -12,11 +12,16 @@ #include "../core/EnumMap.hpp" #include "../drawing/Drawing.h" #include "../sprites.h" +#include "../util/Util.h" #include ColourShadeMap ColourMapA[COLOUR_COUNT] = {}; +static constexpr uint8_t kLegacyColourMaskBase = 0x1F; +static constexpr uint8_t kLegacyColourFlagOutline = (1 << 5); +static constexpr uint8_t kLegacyColourFlagInset = (1 << 6); + enum { INDEX_COLOUR_0 = 243, @@ -126,6 +131,15 @@ namespace Colour return (result != LookupTable.end()) ? result->second : defaultValue; } + u8string ToString(colour_t colour) + { + auto result = LookupTable.find(colour); + if (result != LookupTable.end()) + return u8string(result->first); + + return "black"; + } + } // namespace Colour #ifndef NO_TTF @@ -194,3 +208,44 @@ BlendColourMapType* GetBlendColourMap() return nullptr; } #endif + +bool ColourWithFlags::hasFlag(ColourFlag flag) const +{ + return flags & EnumToFlag(flag); +} + +void ColourWithFlags::setFlag(ColourFlag flag, bool on) +{ + if (on) + flags |= EnumToFlag(flag); + else + flags &= ~EnumToFlag(flag); +} + +ColourWithFlags ColourWithFlags::withFlag(ColourFlag flag, bool on) const +{ + struct ColourWithFlags result = *this; + result.setFlag(flag, on); + return result; +} + +ColourWithFlags ColourWithFlags::fromLegacy(uint8_t legacy) +{ + ColourWithFlags result{}; + result.colour = legacy & kLegacyColourMaskBase; + if (legacy & kLegacyColourFlagTranslucent) + result.flags |= EnumToFlag(ColourFlag::translucent); + if (legacy & kLegacyColourFlagInset) + result.flags |= EnumToFlag(ColourFlag::inset); + if (legacy & kLegacyColourFlagOutline) + result.flags |= EnumToFlag(ColourFlag::withOutline); + + return result; +} + +ColourWithFlags& ColourWithFlags::operator=(colour_t rhs) +{ + colour = rhs; + flags = 0; + return *this; +} diff --git a/src/openrct2/interface/Colour.h b/src/openrct2/interface/Colour.h index 7b4ce7adab..36eae268ed 100644 --- a/src/openrct2/interface/Colour.h +++ b/src/openrct2/interface/Colour.h @@ -10,6 +10,7 @@ #pragma once #include "../common.h" +#include "../core/String.hpp" #include @@ -209,34 +210,48 @@ constexpr uint8_t PALETTE_LENGTH_ANIMATED = 16; constexpr uint8_t COLOUR_NUM_ORIGINAL = 32; constexpr uint8_t COLOUR_NUM_NORMAL = 54; +static constexpr uint8_t kLegacyColourFlagTranslucent = (1 << 7); + #define TEXT_COLOUR_254 (254) #define TEXT_COLOUR_255 (255) -enum : colour_t +enum class ColourFlag : uint8_t { - COLOUR_FLAG_OUTLINE = (1 << 5), - COLOUR_FLAG_INSET = (1 << 6), // 64, 0x40 - COLOUR_FLAG_TRANSLUCENT = (1 << 7), + translucent, + inset, + withOutline, }; -#define TRANSLUCENT(x) ((x) | static_cast(COLOUR_FLAG_TRANSLUCENT)) -#define NOT_TRANSLUCENT(x) ((x) & ~static_cast(COLOUR_FLAG_TRANSLUCENT)) -#define BASE_COLOUR(x) ((x)&0x1F) +struct ColourWithFlags +{ + colour_t colour{}; + uint8_t flags{}; + + bool hasFlag(ColourFlag flag) const; + + void setFlag(ColourFlag flag, bool on); + + ColourWithFlags withFlag(ColourFlag flag, bool on) const; + + static ColourWithFlags fromLegacy(uint8_t legacy); + + ColourWithFlags& operator=(colour_t rhs); +}; struct ColourShadeMap { - uint8_t colour_0; - uint8_t colour_1; - uint8_t darkest; - uint8_t darker; - uint8_t dark; - uint8_t mid_dark; - uint8_t mid_light; - uint8_t light; - uint8_t lighter; - uint8_t lightest; - uint8_t colour_10; - uint8_t colour_11; + PaletteIndex colour_0; + PaletteIndex colour_1; + PaletteIndex darkest; + PaletteIndex darker; + PaletteIndex dark; + PaletteIndex mid_dark; + PaletteIndex mid_light; + PaletteIndex light; + PaletteIndex lighter; + PaletteIndex lightest; + PaletteIndex colour_10; + PaletteIndex colour_11; }; extern ColourShadeMap ColourMapA[COLOUR_COUNT]; @@ -246,7 +261,8 @@ void ColoursInitMaps(); namespace Colour { colour_t FromString(std::string_view s, colour_t defaultValue = COLOUR_BLACK); -} + u8string ToString(colour_t colour); +} // namespace Colour #ifndef NO_TTF uint8_t BlendColours(const uint8_t paletteIndex1, const uint8_t paletteIndex2); diff --git a/src/openrct2/interface/Window.cpp b/src/openrct2/interface/Window.cpp index c17669cb6b..cf5aa65f3f 100644 --- a/src/openrct2/interface/Window.cpp +++ b/src/openrct2/interface/Window.cpp @@ -47,7 +47,7 @@ WindowBase* gWindowAudioExclusive; WindowCloseModifier gLastCloseModifier = { { WindowClass::Null, 0 }, CloseWindowModifier::None }; uint32_t gWindowUpdateTicks; -colour_t gCurrentWindowColours[4]; +colour_t gCurrentWindowColours[3]; // converted from uint16_t values at 0x009A41EC - 0x009A4230 // these are percentage coordinates of the viewport to centre to, if a window is obscuring a location, the next is tried @@ -1178,10 +1178,9 @@ static void WindowDrawSingle(DrawPixelInfo& dpi, WindowBase& w, int32_t left, in w.OnPrepareDraw(); // Text colouring - gCurrentWindowColours[0] = NOT_TRANSLUCENT(w.colours[0]); - gCurrentWindowColours[1] = NOT_TRANSLUCENT(w.colours[1]); - gCurrentWindowColours[2] = NOT_TRANSLUCENT(w.colours[2]); - gCurrentWindowColours[3] = NOT_TRANSLUCENT(w.colours[3]); + gCurrentWindowColours[0] = w.colours[0].colour; + gCurrentWindowColours[1] = w.colours[1].colour; + gCurrentWindowColours[2] = w.colours[2].colour; w.OnDraw(copy); } diff --git a/src/openrct2/interface/Window.h b/src/openrct2/interface/Window.h index 7a18b7fb2f..a14a524ee6 100644 --- a/src/openrct2/interface/Window.h +++ b/src/openrct2/interface/Window.h @@ -18,6 +18,7 @@ #include "../windows/TileInspectorGlobals.h" #include "../world/Location.hpp" #include "../world/ScenerySelection.h" +#include "Colour.h" #include "Widget.h" #include "WindowClasses.h" #include "ZoomLevel.h" @@ -484,7 +485,7 @@ extern WindowBase* gWindowAudioExclusive; extern uint32_t gWindowUpdateTicks; -extern colour_t gCurrentWindowColours[4]; +extern colour_t gCurrentWindowColours[3]; extern bool gDisableErrorWindowSound; diff --git a/src/openrct2/interface/Window_internal.h b/src/openrct2/interface/Window_internal.h index fd2a3b8cd0..c7770bbe29 100644 --- a/src/openrct2/interface/Window_internal.h +++ b/src/openrct2/interface/Window_internal.h @@ -9,6 +9,7 @@ #pragma once +#include "Colour.h" #include "Window.h" #include @@ -65,7 +66,7 @@ struct WindowBase EntityId viewport_target_sprite{ EntityId::GetNull() }; ScreenCoordsXY savedViewPos{}; WindowClass classification{}; - colour_t colours[6]{}; + ColourWithFlags colours[6]{}; VisibilityCache visibility{}; EntityId viewport_smart_follow_sprite{ EntityId::GetNull() }; // Handles setting viewport target sprite etc diff --git a/src/openrct2/paint/Paint.cpp b/src/openrct2/paint/Paint.cpp index 96f36f517d..546aff8c52 100644 --- a/src/openrct2/paint/Paint.cpp +++ b/src/openrct2/paint/Paint.cpp @@ -921,7 +921,7 @@ void PaintDrawMoneyStructs(DrawPixelInfo& dpi, PaintStringStruct* ps) } GfxDrawStringWithYOffsets( - dpi, buffer, COLOUR_BLACK, ps->ScreenPos, reinterpret_cast(ps->y_offsets), forceSpriteFont, + dpi, buffer, { COLOUR_BLACK }, ps->ScreenPos, reinterpret_cast(ps->y_offsets), forceSpriteFont, FontStyle::Medium); } while ((ps = ps->NextEntry) != nullptr); }