mirror of https://github.com/OpenRCT2/OpenRCT2.git
commit
2ae6f1466e
|
@ -51,6 +51,7 @@ if (NOT PNG_FOUND)
|
|||
endif (NOT PNG_FOUND)
|
||||
|
||||
PKG_CHECK_MODULES(ZLIB REQUIRED zlib)
|
||||
PKG_CHECK_MODULES(JANSSON REQUIRED jansson>=2.7)
|
||||
|
||||
# Handle creating the rct2 text and data files on OS X and Linux
|
||||
# See details in src/openrct2.c:openrct2_setup_rct2_segment for how the values
|
||||
|
@ -143,23 +144,22 @@ else (STATIC)
|
|||
endif (STATIC)
|
||||
|
||||
if (STATIC)
|
||||
SET(REQUIREDLIBS ${PNG_STATIC_LIBRARIES} ${ZLIB_STATIC_LIBRARIES})
|
||||
SET(REQUIREDLIBS ${PNG_STATIC_LIBRARIES} ${JANSSON_STATIC_LIBRARIES} ${ZLIB_STATIC_LIBRARIES})
|
||||
else (STATIC)
|
||||
SET(REQUIREDLIBS ${PNG_LIBRARIES} ${ZLIB_LIBRARIES})
|
||||
SET(REQUIREDLIBS ${PNG_LIBRARIES} ${JANSSON_LIBRARIES} ${ZLIB_LIBRARIES})
|
||||
endif (STATIC)
|
||||
|
||||
if (NOT DISABLE_HTTP_TWITCH)
|
||||
PKG_CHECK_MODULES(LIBCURL REQUIRED libcurl)
|
||||
PKG_CHECK_MODULES(JANSSON REQUIRED jansson>=2.7)
|
||||
if (WIN32)
|
||||
# Curl depends on openssl and ws2 in mingw builds, but is not wired up in pkg-config
|
||||
PKG_CHECK_MODULES(SSL REQUIRED openssl)
|
||||
set(WSLIBS ws2_32)
|
||||
endif (WIN32)
|
||||
if (STATIC)
|
||||
SET(HTTPLIBS ${LIBCURL_STATIC_LIBRARIES} ${JANSSON_STATIC_LIBRARIES} ${SSL_STATIC_LIBRARIES} ${WSLIBS})
|
||||
SET(HTTPLIBS ${LIBCURL_STATIC_LIBRARIES} ${SSL_STATIC_LIBRARIES} ${WSLIBS})
|
||||
else (STATIC)
|
||||
SET(HTTPLIBS ${LIBCURL_LIBRARIES} ${JANSSON_LIBRARIES} ${SSL_LIBRARIES} ${WSLIBS})
|
||||
SET(HTTPLIBS ${LIBCURL_LIBRARIES} ${SSL_LIBRARIES} ${WSLIBS})
|
||||
endif (STATIC)
|
||||
endif (NOT DISABLE_HTTP_TWITCH)
|
||||
|
||||
|
|
|
@ -15,6 +15,8 @@
|
|||
D43532601C34730200BA219B /* libpng.dylib in Embed Frameworks */ = {isa = PBXBuildFile; fileRef = D435325E1C3472E500BA219B /* libpng.dylib */; settings = {ATTRIBUTES = (CodeSignOnCopy, ); }; };
|
||||
D46105CE1C38828D00DB1EE3 /* scenario_sources.c in Sources */ = {isa = PBXBuildFile; fileRef = D46105CD1C38828D00DB1EE3 /* scenario_sources.c */; };
|
||||
D47304D51C4FF8250015C0EA /* libz.tbd in Frameworks */ = {isa = PBXBuildFile; fileRef = D47304D41C4FF8250015C0EA /* libz.tbd */; };
|
||||
D4A3511E1C6067C400CBCBA4 /* Json.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D4A3511C1C6067C400CBCBA4 /* Json.cpp */; };
|
||||
D4A351211C60680300CBCBA4 /* Theme.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D4A351201C60680300CBCBA4 /* Theme.cpp */; };
|
||||
D4ABAB061C2F812B0080CAD9 /* news_options.c in Sources */ = {isa = PBXBuildFile; fileRef = D4ABAB051C2F812B0080CAD9 /* news_options.c */; };
|
||||
D4B63B8F1C43025600367A37 /* CommandLine.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D4B63B8A1C43025600367A37 /* CommandLine.cpp */; };
|
||||
D4B63B901C43025600367A37 /* RootCommands.cpp in Sources */ = {isa = PBXBuildFile; fileRef = D4B63B8C1C43025600367A37 /* RootCommands.cpp */; };
|
||||
|
@ -54,7 +56,6 @@
|
|||
D4EC47F81C26342F0024B507 /* graph.c in Sources */ = {isa = PBXBuildFile; fileRef = D4EC470F1C26342F0024B507 /* graph.c */; };
|
||||
D4EC47F91C26342F0024B507 /* keyboard_shortcut.c in Sources */ = {isa = PBXBuildFile; fileRef = D4EC47111C26342F0024B507 /* keyboard_shortcut.c */; };
|
||||
D4EC47FA1C26342F0024B507 /* screenshot.c in Sources */ = {isa = PBXBuildFile; fileRef = D4EC47131C26342F0024B507 /* screenshot.c */; };
|
||||
D4EC47FB1C26342F0024B507 /* themes.c in Sources */ = {isa = PBXBuildFile; fileRef = D4EC47151C26342F0024B507 /* themes.c */; };
|
||||
D4EC47FC1C26342F0024B507 /* title_sequences.c in Sources */ = {isa = PBXBuildFile; fileRef = D4EC47171C26342F0024B507 /* title_sequences.c */; };
|
||||
D4EC47FD1C26342F0024B507 /* viewport.c in Sources */ = {isa = PBXBuildFile; fileRef = D4EC47191C26342F0024B507 /* viewport.c */; };
|
||||
D4EC47FE1C26342F0024B507 /* viewport_interaction.c in Sources */ = {isa = PBXBuildFile; fileRef = D4EC471B1C26342F0024B507 /* viewport_interaction.c */; };
|
||||
|
@ -229,6 +230,12 @@
|
|||
D47304D41C4FF8250015C0EA /* libz.tbd */ = {isa = PBXFileReference; lastKnownFileType = "sourcecode.text-based-dylib-definition"; name = libz.tbd; path = usr/lib/libz.tbd; sourceTree = SDKROOT; };
|
||||
D4895D321C23EFDD000CD788 /* Info.plist */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = text.plist.xml; name = Info.plist; path = distribution/osx/Info.plist; sourceTree = SOURCE_ROOT; };
|
||||
D497D0781C20FD52002BF46A /* OpenRCT2.app */ = {isa = PBXFileReference; explicitFileType = wrapper.application; includeInIndex = 0; path = OpenRCT2.app; sourceTree = BUILT_PRODUCTS_DIR; };
|
||||
D4A3511A1C6067B000CBCBA4 /* Diagnostics.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Diagnostics.hpp; sourceTree = "<group>"; };
|
||||
D4A3511B1C6067B900CBCBA4 /* Guard.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = Guard.hpp; sourceTree = "<group>"; };
|
||||
D4A3511C1C6067C400CBCBA4 /* Json.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Json.cpp; sourceTree = "<group>"; };
|
||||
D4A3511D1C6067C400CBCBA4 /* Json.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = Json.hpp; sourceTree = "<group>"; };
|
||||
D4A3511F1C6067E500CBCBA4 /* List.hpp */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.cpp.h; path = List.hpp; sourceTree = "<group>"; };
|
||||
D4A351201C60680300CBCBA4 /* Theme.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = Theme.cpp; sourceTree = "<group>"; };
|
||||
D4ABAB051C2F812B0080CAD9 /* news_options.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = news_options.c; sourceTree = "<group>"; };
|
||||
D4B63B8A1C43025600367A37 /* CommandLine.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; path = CommandLine.cpp; sourceTree = "<group>"; };
|
||||
D4B63B8B1C43025600367A37 /* CommandLine.hpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.h; path = CommandLine.hpp; sourceTree = "<group>"; };
|
||||
|
@ -304,7 +311,6 @@
|
|||
D4EC47121C26342F0024B507 /* keyboard_shortcut.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = keyboard_shortcut.h; sourceTree = "<group>"; };
|
||||
D4EC47131C26342F0024B507 /* screenshot.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = screenshot.c; sourceTree = "<group>"; };
|
||||
D4EC47141C26342F0024B507 /* screenshot.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = screenshot.h; sourceTree = "<group>"; };
|
||||
D4EC47151C26342F0024B507 /* themes.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = themes.c; sourceTree = "<group>"; };
|
||||
D4EC47161C26342F0024B507 /* themes.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = themes.h; sourceTree = "<group>"; };
|
||||
D4EC47171C26342F0024B507 /* title_sequences.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = title_sequences.c; sourceTree = "<group>"; };
|
||||
D4EC47181C26342F0024B507 /* title_sequences.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = title_sequences.h; sourceTree = "<group>"; };
|
||||
|
@ -728,10 +734,15 @@
|
|||
children = (
|
||||
D4B63B931C43028200367A37 /* Console.cpp */,
|
||||
D4B63B941C43028200367A37 /* Console.hpp */,
|
||||
D4A3511A1C6067B000CBCBA4 /* Diagnostics.hpp */,
|
||||
D4EC46E61C26342F0024B507 /* Exception.hpp */,
|
||||
D4EC46E71C26342F0024B507 /* FileStream.hpp */,
|
||||
D4A3511B1C6067B900CBCBA4 /* Guard.hpp */,
|
||||
D4EC46E81C26342F0024B507 /* IDisposable.hpp */,
|
||||
D4EC46E91C26342F0024B507 /* IStream.hpp */,
|
||||
D4A3511C1C6067C400CBCBA4 /* Json.cpp */,
|
||||
D4A3511D1C6067C400CBCBA4 /* Json.hpp */,
|
||||
D4A3511F1C6067E500CBCBA4 /* List.hpp */,
|
||||
D4EC46EA1C26342F0024B507 /* Math.hpp */,
|
||||
D4EC46EB1C26342F0024B507 /* Memory.hpp */,
|
||||
D4D35E2A1C45BD9B00AAFCB4 /* Path.cpp */,
|
||||
|
@ -781,7 +792,7 @@
|
|||
D4EC47121C26342F0024B507 /* keyboard_shortcut.h */,
|
||||
D4EC47131C26342F0024B507 /* screenshot.c */,
|
||||
D4EC47141C26342F0024B507 /* screenshot.h */,
|
||||
D4EC47151C26342F0024B507 /* themes.c */,
|
||||
D4A351201C60680300CBCBA4 /* Theme.cpp */,
|
||||
D4EC47161C26342F0024B507 /* themes.h */,
|
||||
D4EC47171C26342F0024B507 /* title_sequences.c */,
|
||||
D4EC47181C26342F0024B507 /* title_sequences.h */,
|
||||
|
@ -1351,6 +1362,7 @@
|
|||
D4EC48401C26342F0024B507 /* guest_list.c in Sources */,
|
||||
D4EC482F1C26342F0024B507 /* banner.c in Sources */,
|
||||
D4EC47E91C26342F0024B507 /* font.c in Sources */,
|
||||
D4A3511E1C6067C400CBCBA4 /* Json.cpp in Sources */,
|
||||
D4EC48021C26342F0024B507 /* convert.c in Sources */,
|
||||
D4EC48481C26342F0024B507 /* mapgen.c in Sources */,
|
||||
D4EC48441C26342F0024B507 /* loadsave.c in Sources */,
|
||||
|
@ -1368,6 +1380,7 @@
|
|||
D4EC481A1C26342F0024B507 /* posix.c in Sources */,
|
||||
D4D35E2C1C45BD9B00AAFCB4 /* Path.cpp in Sources */,
|
||||
D4B63B981C43028F00367A37 /* String.cpp in Sources */,
|
||||
D4A351211C60680300CBCBA4 /* Theme.cpp in Sources */,
|
||||
D4EC47E31C26342F0024B507 /* cmdline_sprite.c in Sources */,
|
||||
D4EC48611C26342F0024B507 /* text_input.c in Sources */,
|
||||
D4EC48431C26342F0024B507 /* land_rights.c in Sources */,
|
||||
|
@ -1481,7 +1494,6 @@
|
|||
D4EC480D1C26342F0024B507 /* marketing.c in Sources */,
|
||||
D4EC48721C26342F0024B507 /* balloon.c in Sources */,
|
||||
D4EC48571C26342F0024B507 /* save_prompt.c in Sources */,
|
||||
D4EC47FB1C26342F0024B507 /* themes.c in Sources */,
|
||||
D4EC48701C26342F0024B507 /* viewport.c in Sources */,
|
||||
);
|
||||
runOnlyForDeploymentPostprocessing = 0;
|
||||
|
@ -1515,9 +1527,7 @@
|
|||
GCC_DYNAMIC_NO_PIC = NO;
|
||||
GCC_NO_COMMON_BLOCKS = YES;
|
||||
GCC_OPTIMIZATION_LEVEL = 0;
|
||||
GCC_PREPROCESSOR_DEFINITIONS = (
|
||||
"DEBUG=1",
|
||||
);
|
||||
GCC_PREPROCESSOR_DEFINITIONS = "DEBUG=1";
|
||||
GCC_WARN_64_TO_32_BIT_CONVERSION = YES;
|
||||
GCC_WARN_ABOUT_RETURN_TYPE = YES_ERROR;
|
||||
GCC_WARN_FOUR_CHARACTER_CONSTANTS = YES;
|
||||
|
|
|
@ -4039,6 +4039,8 @@ STR_5732 :Anisotropic
|
|||
STR_5733 :Use NN scaling at integer scales
|
||||
# tooltip for tab in options window
|
||||
STR_5734 :{SMALLFONT}{BLACK}Rendering
|
||||
STR_5735 :Network Status
|
||||
STR_5736 :Player
|
||||
|
||||
#############
|
||||
# Scenarios #
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
<ClCompile Include="src\cmdline_sprite.c" />
|
||||
<ClCompile Include="src\config.c" />
|
||||
<ClCompile Include="src\core\Console.cpp" />
|
||||
<ClCompile Include="src\core\Json.cpp" />
|
||||
<ClCompile Include="src\core\Path.cpp" />
|
||||
<ClCompile Include="src\core\Stopwatch.cpp" />
|
||||
<ClCompile Include="src\core\String.cpp" />
|
||||
|
@ -51,7 +52,7 @@
|
|||
<ClCompile Include="src\input.c" />
|
||||
<ClCompile Include="src\interface\chat.c" />
|
||||
<ClCompile Include="src\interface\colour.c" />
|
||||
<ClCompile Include="src\interface\themes.c" />
|
||||
<ClCompile Include="src\interface\Theme.cpp" />
|
||||
<ClCompile Include="src\interface\console.c" />
|
||||
<ClCompile Include="src\interface\graph.c" />
|
||||
<ClCompile Include="src\interface\keyboard_shortcut.c" />
|
||||
|
@ -108,6 +109,7 @@
|
|||
<ClCompile Include="src\windows\player.c" />
|
||||
<ClCompile Include="src\windows\server_list.c" />
|
||||
<ClCompile Include="src\windows\server_start.c" />
|
||||
<ClCompile Include="src\windows\themes.c" />
|
||||
<ClCompile Include="src\windows\title_command_editor.c" />
|
||||
<ClCompile Include="src\windows\title_editor.c" />
|
||||
<ClCompile Include="src\windows\maze_construction.c" />
|
||||
|
@ -177,7 +179,6 @@
|
|||
<ClCompile Include="src\windows\track_place.c" />
|
||||
<ClCompile Include="src\windows\viewport.c" />
|
||||
<ClCompile Include="src\windows\water.c" />
|
||||
<ClCompile Include="src\windows\themes.c" />
|
||||
<ClCompile Include="src\world\banner.c" />
|
||||
<ClCompile Include="src\world\climate.c" />
|
||||
<ClCompile Include="src\world\footpath.c" />
|
||||
|
@ -199,10 +200,14 @@
|
|||
<ClInclude Include="src\common.h" />
|
||||
<ClInclude Include="src\config.h" />
|
||||
<ClInclude Include="src\core\Console.hpp" />
|
||||
<ClInclude Include="src\core\Diagnostics.hpp" />
|
||||
<ClInclude Include="src\core\Exception.hpp" />
|
||||
<ClInclude Include="src\core\FileStream.hpp" />
|
||||
<ClInclude Include="src\core\Guard.hpp" />
|
||||
<ClInclude Include="src\core\IDisposable.hpp" />
|
||||
<ClInclude Include="src\core\IStream.hpp" />
|
||||
<ClInclude Include="src\core\Json.hpp" />
|
||||
<ClInclude Include="src\core\List.hpp" />
|
||||
<ClInclude Include="src\core\Math.hpp" />
|
||||
<ClInclude Include="src\core\Memory.hpp" />
|
||||
<ClInclude Include="src\core\Path.hpp" />
|
||||
|
@ -380,4 +385,4 @@
|
|||
</ItemDefinitionGroup>
|
||||
<Import Project="$(VCTargetsPath)\Microsoft.Cpp.targets" />
|
||||
<ImportGroup Label="ExtensionTargets" />
|
||||
</Project>
|
||||
</Project>
|
|
@ -453,12 +453,6 @@
|
|||
<ClCompile Include="src\network\http.cpp">
|
||||
<Filter>Source\Network</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\interface\themes.c">
|
||||
<Filter>Source\Interface</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\windows\themes.c">
|
||||
<Filter>Source\Windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\windows\tile_inspector.c">
|
||||
<Filter>Source\Windows</Filter>
|
||||
</ClCompile>
|
||||
|
@ -582,6 +576,11 @@
|
|||
<ClCompile Include="src\windows\multiplayer.c">
|
||||
<Filter>Source\Windows</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\interface\Theme.cpp">
|
||||
<Filter>Source\Interface</Filter>
|
||||
</ClCompile>
|
||||
<ClCompile Include="src\core\Json.cpp" />
|
||||
<ClCompile Include="src\windows\themes.c" />
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<ClInclude Include="src\management\award.h">
|
||||
|
@ -884,5 +883,9 @@
|
|||
<ClInclude Include="src\core\Path.hpp">
|
||||
<Filter>Source\Core</Filter>
|
||||
</ClInclude>
|
||||
<ClInclude Include="src\core\List.hpp" />
|
||||
<ClInclude Include="src\core\Guard.hpp" />
|
||||
<ClInclude Include="src\core\Diagnostics.hpp" />
|
||||
<ClInclude Include="src\core\Json.hpp" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -19,6 +19,7 @@
|
|||
*****************************************************************************/
|
||||
|
||||
extern "C" {
|
||||
#include "../addresses.h"
|
||||
#include "../config.h"
|
||||
#include "../platform/platform.h"
|
||||
#include "../localisation/localisation.h"
|
||||
|
|
391
src/config.c
391
src/config.c
|
@ -299,7 +299,6 @@ sound_configuration gConfigSound;
|
|||
twitch_configuration gConfigTwitch;
|
||||
network_configuration gConfigNetwork;
|
||||
notification_configuration gConfigNotifications;
|
||||
themes_configuration gConfigThemes;
|
||||
title_sequences_configuration gConfigTitleSequences;
|
||||
|
||||
static bool config_open(const utf8string path);
|
||||
|
@ -1044,396 +1043,6 @@ bool config_shortcut_keys_save()
|
|||
|
||||
#pragma endregion
|
||||
|
||||
|
||||
#pragma region Themes
|
||||
|
||||
typedef struct {
|
||||
size_t offset;
|
||||
const_utf8string property_name;
|
||||
uint8 type;
|
||||
value_union default_value;
|
||||
config_enum_definition *enum_definitions;
|
||||
} theme_property_definition;
|
||||
|
||||
typedef struct {
|
||||
size_t offset;
|
||||
const_utf8string section_name;
|
||||
theme_property_definition *property_definitions;
|
||||
int property_definitions_count;
|
||||
} theme_section_definition;
|
||||
|
||||
|
||||
theme_property_definition _themeWindowDefinitions[] = {
|
||||
{ offsetof(theme_window, colours[0]), "colour_0", CONFIG_VALUE_TYPE_UINT8, 0, NULL },
|
||||
{ offsetof(theme_window, colours[1]), "colour_1", CONFIG_VALUE_TYPE_UINT8, 0, NULL },
|
||||
{ offsetof(theme_window, colours[2]), "colour_2", CONFIG_VALUE_TYPE_UINT8, 0, NULL },
|
||||
{ offsetof(theme_window, colours[3]), "colour_3", CONFIG_VALUE_TYPE_UINT8, 0, NULL },
|
||||
{ offsetof(theme_window, colours[4]), "colour_4", CONFIG_VALUE_TYPE_UINT8, 0, NULL },
|
||||
{ offsetof(theme_window, colours[5]), "colour_5", CONFIG_VALUE_TYPE_UINT8, 0, NULL },
|
||||
};
|
||||
|
||||
theme_property_definition _themeFeaturesDefinitions[] = {
|
||||
{ offsetof(theme_features, rct1_ride_lights), "rct1_ride_lights", CONFIG_VALUE_TYPE_BOOLEAN, false, NULL },
|
||||
{ offsetof(theme_features, rct1_park_lights), "rct1_park_lights", CONFIG_VALUE_TYPE_BOOLEAN, false, NULL },
|
||||
{ offsetof(theme_features, rct1_scenario_font), "rct1_scenario_font", CONFIG_VALUE_TYPE_BOOLEAN, false, NULL },
|
||||
};
|
||||
|
||||
|
||||
theme_section_definition _themeSectionDefinitions[] = {
|
||||
// Special definition for theme windows
|
||||
{ 0, "", _themeWindowDefinitions, countof(_themeWindowDefinitions) },
|
||||
{ offsetof(theme_preset, features), "features", _themeFeaturesDefinitions, countof(_themeFeaturesDefinitions) },
|
||||
};
|
||||
|
||||
static bool themes_open(const_utf8string path);
|
||||
static bool themes_save(const_utf8string path, int preset);
|
||||
static void themes_read_properties(theme_preset *theme, theme_section_definition **currentSection, utf8string line);
|
||||
static void themes_set_property(theme_preset *theme, const theme_section_definition *section, const theme_property_definition *property, utf8string value, int valueSize);
|
||||
static theme_section_definition* themes_get_section_def(utf8string name, int size);
|
||||
static theme_property_definition *themes_get_property_def(theme_section_definition *section, utf8string name, int size);
|
||||
|
||||
void themes_set_default()
|
||||
{
|
||||
utf8 path[MAX_PATH];
|
||||
|
||||
platform_get_user_directory(path, "themes");
|
||||
platform_ensure_directory_exists(path);
|
||||
|
||||
gConfigThemes.num_presets = 2;
|
||||
gConfigThemes.presets = malloc(sizeof(theme_preset) * gConfigThemes.num_presets);
|
||||
|
||||
// Set RCT2 theme
|
||||
safe_strcpy(gConfigThemes.presets[0].name, language_get_string(2741), THEME_PRESET_NAME_SIZE);
|
||||
gConfigThemes.presets[0].windows = malloc(sizeof(theme_window) * gNumThemeWindows);
|
||||
|
||||
// Define the defaults for RCT2 here
|
||||
gConfigThemes.presets[0].features.rct1_ride_lights = false;
|
||||
gConfigThemes.presets[0].features.rct1_park_lights = false;
|
||||
gConfigThemes.presets[0].features.rct1_scenario_font = false;
|
||||
|
||||
|
||||
for (int i = 0; i < (int)gNumThemeWindows; i++) {
|
||||
gConfigThemes.presets[0].windows[i] = gThemeWindowDefinitions[i].window;
|
||||
}
|
||||
|
||||
// Set RCT1 theme
|
||||
safe_strcpy(gConfigThemes.presets[1].name, language_get_string(2740), THEME_PRESET_NAME_SIZE);
|
||||
gConfigThemes.presets[1].windows = malloc(sizeof(theme_window) * gNumThemeWindows);
|
||||
|
||||
// Define the defaults for RCT1 here
|
||||
gConfigThemes.presets[1].features.rct1_ride_lights = true;
|
||||
gConfigThemes.presets[1].features.rct1_park_lights = true;
|
||||
gConfigThemes.presets[1].features.rct1_scenario_font = true;
|
||||
|
||||
|
||||
for (int i = 0; i < (int)gNumThemeWindows; i++) {
|
||||
uint8 changed_colour = 0xFF;
|
||||
for (int k = 0; gThemeWindowsRCT1[k].classification != 0xFF; k++) {
|
||||
if (gThemeWindowsRCT1[k].classification == gThemeWindowDefinitions[i].classification) {
|
||||
changed_colour = (uint8)k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
gConfigThemes.presets[1].windows[i] = (changed_colour != 0xFF ? gThemeWindowsRCT1[changed_colour].window : gThemeWindowDefinitions[i].window);
|
||||
}
|
||||
}
|
||||
|
||||
void themes_load_presets()
|
||||
{
|
||||
utf8 path[MAX_PATH];
|
||||
file_info file;
|
||||
int fileEnumHandle, i;
|
||||
|
||||
platform_get_user_directory(path, "themes");
|
||||
strcat(path, "*.ini");
|
||||
fileEnumHandle = platform_enumerate_files_begin(path);
|
||||
while (platform_enumerate_files_next(fileEnumHandle, &file)) {
|
||||
platform_get_user_directory(path, "themes");
|
||||
strcat(path, file.path);
|
||||
themes_open(path);
|
||||
}
|
||||
platform_enumerate_files_end(fileEnumHandle);
|
||||
|
||||
if (strcmp(gConfigInterface.current_theme_preset, "*RCT2") == 0) {
|
||||
theme_change_preset(0);
|
||||
}
|
||||
else if (strcmp(gConfigInterface.current_theme_preset, "*RCT1") == 0) {
|
||||
theme_change_preset(1);
|
||||
}
|
||||
else {
|
||||
for (i = 2; i < gConfigThemes.num_presets; i++) {
|
||||
if (strcmp(gConfigInterface.current_theme_preset, gConfigThemes.presets[i].name) == 0) {
|
||||
theme_change_preset(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (i == gConfigThemes.num_presets) {
|
||||
theme_change_preset(0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
bool themes_save_preset(int preset)
|
||||
{
|
||||
utf8 path[MAX_PATH];
|
||||
|
||||
platform_get_user_directory(path, "themes");
|
||||
strcat(path, gConfigThemes.presets[preset].name);
|
||||
strcat(path, ".ini");
|
||||
if (themes_save(path, preset)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool themes_open(const_utf8string path)
|
||||
{
|
||||
SDL_RWops *file;
|
||||
utf8string lineBuffer;
|
||||
size_t lineBufferCapacity;
|
||||
size_t lineLength;
|
||||
int c, preset;
|
||||
theme_section_definition *currentSection;
|
||||
|
||||
file = SDL_RWFromFile(path, "rb");
|
||||
if (file == NULL)
|
||||
return false;
|
||||
|
||||
// Check if the colour scheme is already loaded
|
||||
// No nead to read the first two presets as they're hardcoded in
|
||||
for (preset = 2; preset < gConfigThemes.num_presets; preset++) {
|
||||
if (strcmp(path, gConfigThemes.presets[preset].name) == 0) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
// Otherwise allocate one
|
||||
if (preset == gConfigThemes.num_presets) {
|
||||
gConfigThemes.num_presets++;
|
||||
gConfigThemes.presets = realloc(gConfigThemes.presets, sizeof(theme_preset) * gConfigThemes.num_presets);
|
||||
safe_strcpy(gConfigThemes.presets[preset].name, path_get_filename(path), THEME_PRESET_NAME_SIZE);
|
||||
path_remove_extension(gConfigThemes.presets[preset].name);
|
||||
gConfigThemes.presets[preset].windows = malloc(sizeof(theme_window) * gNumThemeWindows);
|
||||
gConfigThemes.presets[preset].features.rct1_ride_lights = false;
|
||||
gConfigThemes.presets[preset].features.rct1_park_lights = false;
|
||||
gConfigThemes.presets[preset].features.rct1_scenario_font = false;
|
||||
for (int i = 0; i < (int)gNumThemeWindows; i++) {
|
||||
gConfigThemes.presets[preset].windows[i] = gThemeWindowDefinitions[i].window;
|
||||
}
|
||||
}
|
||||
|
||||
currentSection = NULL;
|
||||
lineBufferCapacity = 64;
|
||||
lineBuffer = malloc(lineBufferCapacity);
|
||||
lineLength = 0;
|
||||
|
||||
// Skim UTF-8 byte order mark
|
||||
SDL_RWread(file, lineBuffer, 3, 1);
|
||||
if (!(lineBuffer[0] == (utf8)0xEF && lineBuffer[1] == (utf8)0xBB && lineBuffer[2] == (utf8)0xBF))
|
||||
SDL_RWseek(file, 0, SEEK_SET);
|
||||
|
||||
while ((c = rwopsreadc(file)) != EOF) {
|
||||
if (c == '\n' || c == '\r') {
|
||||
lineBuffer[lineLength++] = 0;
|
||||
themes_read_properties(&gConfigThemes.presets[preset], ¤tSection, (utf8string)lineBuffer);
|
||||
lineLength = 0;
|
||||
}
|
||||
else {
|
||||
lineBuffer[lineLength++] = c;
|
||||
}
|
||||
|
||||
if (lineLength >= lineBufferCapacity) {
|
||||
lineBufferCapacity *= 2;
|
||||
lineBuffer = realloc(lineBuffer, lineBufferCapacity);
|
||||
}
|
||||
}
|
||||
|
||||
if (lineLength > 0) {
|
||||
lineBuffer[lineLength++] = 0;
|
||||
themes_read_properties(&gConfigThemes.presets[preset], ¤tSection, lineBuffer);
|
||||
}
|
||||
|
||||
free(lineBuffer);
|
||||
SDL_RWclose(file);
|
||||
return true;
|
||||
}
|
||||
|
||||
static bool themes_save(const_utf8string path, int preset)
|
||||
{
|
||||
SDL_RWops *file;
|
||||
int i, j;
|
||||
value_union *value;
|
||||
|
||||
file = SDL_RWFromFile(path, "wb");
|
||||
if (file == NULL) {
|
||||
log_error("Unable to write to theme file.");
|
||||
return false;
|
||||
}
|
||||
|
||||
// Skip the window definition, we'll do that after
|
||||
for (i = 1; i < countof(_themeSectionDefinitions); i++) {
|
||||
theme_section_definition *section = &_themeSectionDefinitions[i];
|
||||
|
||||
rwopswritec(file, '[');
|
||||
rwopswritestr(file, section->section_name);
|
||||
rwopswritec(file, ']');
|
||||
rwopswritenewline(file);
|
||||
|
||||
for (j = 0; j < section->property_definitions_count; j++) {
|
||||
theme_property_definition *property = §ion->property_definitions[j];
|
||||
|
||||
rwopswritestr(file, property->property_name);
|
||||
rwopswritestr(file, " = ");
|
||||
|
||||
value = (value_union*)((size_t)&gConfigThemes.presets[preset] + (size_t)section->offset + (size_t)property->offset);
|
||||
|
||||
if (property->enum_definitions != NULL)
|
||||
config_write_enum(file, property->type, value, property->enum_definitions);
|
||||
else
|
||||
config_save_property_value(file, property->type, value);
|
||||
rwopswritenewline(file);
|
||||
}
|
||||
rwopswritenewline(file);
|
||||
}
|
||||
|
||||
for (i = 0; i < (int)gNumThemeWindows; i++) {
|
||||
theme_section_definition *section = &_themeSectionDefinitions[0];
|
||||
|
||||
rwopswritec(file, '[');
|
||||
rwopswritestr(file, gThemeWindowDefinitions[i].section_name);
|
||||
rwopswritec(file, ']');
|
||||
rwopswritenewline(file);
|
||||
|
||||
for (j = 0; j < section->property_definitions_count; j++) {
|
||||
theme_property_definition *property = §ion->property_definitions[j];
|
||||
|
||||
rwopswritestr(file, property->property_name);
|
||||
rwopswritestr(file, " = ");
|
||||
|
||||
value = (value_union*)((size_t)gConfigThemes.presets[preset].windows + (size_t)(sizeof(theme_window) * i) + (size_t)property->offset);
|
||||
|
||||
if (property->enum_definitions != NULL)
|
||||
config_write_enum(file, property->type, value, property->enum_definitions);
|
||||
else
|
||||
config_save_property_value(file, property->type, value);
|
||||
rwopswritenewline(file);
|
||||
}
|
||||
}
|
||||
|
||||
SDL_RWclose(file);
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
static void themes_read_properties(theme_preset *theme, theme_section_definition **currentSection, utf8string line)
|
||||
{
|
||||
utf8 *ch = (utf8*)line;
|
||||
utf8_skip_whitespace(&ch);
|
||||
|
||||
if (*ch == '[') {
|
||||
const utf8 *sectionName;
|
||||
int sectionNameSize;
|
||||
if (config_get_section(ch, §ionName, §ionNameSize))
|
||||
*currentSection = themes_get_section_def((utf8string)sectionName, sectionNameSize);
|
||||
} else {
|
||||
if (*currentSection != NULL) {
|
||||
utf8 *propertyName, *value;
|
||||
int propertyNameSize, valueSize;
|
||||
if (config_get_property_name_value(ch, &propertyName, &propertyNameSize, &value, &valueSize)) {
|
||||
theme_property_definition *property;
|
||||
property = themes_get_property_def(*currentSection, propertyName, propertyNameSize);
|
||||
if (property != NULL)
|
||||
themes_set_property(theme, *currentSection, property, value, valueSize);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
static void themes_set_property(theme_preset *theme, const theme_section_definition *section, const theme_property_definition *property, utf8string value, int valueSize)
|
||||
{
|
||||
value_union *destValue = (value_union*)((size_t)theme + (size_t)section->offset + (size_t)property->offset);
|
||||
|
||||
// Get getting the address from the windows pointer instead
|
||||
if (section == &_themeSectionDefinitions[0])
|
||||
destValue = (value_union*)((size_t)theme->windows + (size_t)section->offset + (size_t)property->offset);
|
||||
|
||||
if (property->enum_definitions != NULL)
|
||||
if (config_read_enum(destValue, _configValueTypeSize[property->type], value, valueSize, property->enum_definitions))
|
||||
return;
|
||||
|
||||
switch (property->type) {
|
||||
case CONFIG_VALUE_TYPE_BOOLEAN:
|
||||
if (_strnicmp(value, "false", valueSize) == 0) destValue->value_boolean = false;
|
||||
else if (_strnicmp(value, "true", valueSize) == 0) destValue->value_boolean = true;
|
||||
else destValue->value_boolean = strtol(value, NULL, 0) != 0;
|
||||
break;
|
||||
case CONFIG_VALUE_TYPE_UINT8:
|
||||
destValue->value_uint8 = (uint8)strtol(value, NULL, 0);
|
||||
break;
|
||||
case CONFIG_VALUE_TYPE_UINT16:
|
||||
destValue->value_uint16 = (uint16)strtol(value, NULL, 0);
|
||||
break;
|
||||
case CONFIG_VALUE_TYPE_UINT32:
|
||||
destValue->value_uint32 = (uint32)strtol(value, NULL, 0);
|
||||
break;
|
||||
case CONFIG_VALUE_TYPE_SINT8:
|
||||
destValue->value_sint8 = (sint8)strtol(value, NULL, 0);
|
||||
break;
|
||||
case CONFIG_VALUE_TYPE_SINT16:
|
||||
destValue->value_sint16 = (sint16)strtol(value, NULL, 0);
|
||||
break;
|
||||
case CONFIG_VALUE_TYPE_SINT32:
|
||||
destValue->value_sint32 = (sint32)strtol(value, NULL, 0);
|
||||
break;
|
||||
case CONFIG_VALUE_TYPE_FLOAT:
|
||||
destValue->value_float = strtof(value, NULL);
|
||||
break;
|
||||
case CONFIG_VALUE_TYPE_DOUBLE:
|
||||
destValue->value_double = strtod(value, NULL);
|
||||
break;
|
||||
case CONFIG_VALUE_TYPE_STRING:
|
||||
SafeFree(destValue->value_string);
|
||||
destValue->value_string = malloc(valueSize + 1);
|
||||
memcpy(destValue->value_string, value, valueSize);
|
||||
destValue->value_string[valueSize] = 0;
|
||||
break;
|
||||
}
|
||||
}
|
||||
static theme_section_definition* themes_get_section_def(utf8string name, int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
// Skip the special definition
|
||||
for (i = 1; i < countof(_themeSectionDefinitions); i++) {
|
||||
const_utf8string sectionName = _themeSectionDefinitions[i].section_name;
|
||||
if (sectionName[size] == 0 && _strnicmp(sectionName, name, size) == 0)
|
||||
return &_themeSectionDefinitions[i];
|
||||
}
|
||||
// Check for window definitions
|
||||
for (i = 0; i < (int)gNumThemeWindows; i++) {
|
||||
const_utf8string sectionName = gThemeWindowDefinitions[i].section_name;
|
||||
if (sectionName[size] == 0 && _strnicmp(sectionName, name, size) == 0) {
|
||||
_themeSectionDefinitions[0].offset = (size_t)(sizeof(theme_window) * i);
|
||||
return &_themeSectionDefinitions[0];
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
static theme_property_definition *themes_get_property_def(theme_section_definition *section, utf8string name, int size)
|
||||
{
|
||||
int i;
|
||||
|
||||
for (i = 0; i < section->property_definitions_count; i++) {
|
||||
const_utf8string propertyName = section->property_definitions[i].property_name;
|
||||
if (propertyName[size] == 0 && _strnicmp(propertyName, name, size) == 0)
|
||||
return §ion->property_definitions[i];
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Title Sequences
|
||||
|
||||
static void title_sequence_open(const char *path, const char *customName);
|
||||
|
|
28
src/config.h
28
src/config.h
|
@ -253,13 +253,6 @@ typedef struct {
|
|||
bool guest_died;
|
||||
} notification_configuration;
|
||||
|
||||
typedef struct theme_window {
|
||||
uint8 colours[6];
|
||||
|
||||
// Define any other settings for all windows here
|
||||
|
||||
} theme_window;
|
||||
|
||||
// Define structures for any other settings here
|
||||
typedef struct {
|
||||
uint8 rct1_ride_lights;
|
||||
|
@ -267,22 +260,6 @@ typedef struct {
|
|||
uint8 rct1_scenario_font;
|
||||
} theme_features;
|
||||
|
||||
#define THEME_PRESET_NAME_SIZE 256
|
||||
|
||||
typedef struct theme_preset {
|
||||
char name[THEME_PRESET_NAME_SIZE];
|
||||
theme_window *windows;
|
||||
|
||||
// Add structures for any other settings here
|
||||
theme_features features;
|
||||
|
||||
} theme_preset;
|
||||
|
||||
typedef struct {
|
||||
theme_preset *presets;
|
||||
uint16 num_presets;
|
||||
} themes_configuration;
|
||||
|
||||
#define TITLE_SEQUENCE_MAX_SAVE_LENGTH 51
|
||||
|
||||
typedef struct {
|
||||
|
@ -327,7 +304,6 @@ extern sound_configuration gConfigSound;
|
|||
extern twitch_configuration gConfigTwitch;
|
||||
extern network_configuration gConfigNetwork;
|
||||
extern notification_configuration gConfigNotifications;
|
||||
extern themes_configuration gConfigThemes;
|
||||
extern title_sequences_configuration gConfigTitleSequences;
|
||||
|
||||
extern uint16 gShortcutKeys[SHORTCUT_COUNT];
|
||||
|
@ -346,10 +322,6 @@ bool config_shortcut_keys_save();
|
|||
|
||||
bool config_find_or_browse_install_directory();
|
||||
|
||||
void themes_set_default();
|
||||
void themes_load_presets();
|
||||
bool themes_save_preset(int preset);
|
||||
|
||||
void title_sequences_set_default();
|
||||
void title_sequences_load_presets();
|
||||
void title_sequence_save_preset_script(int preset);
|
||||
|
|
|
@ -0,0 +1,22 @@
|
|||
#pragma once
|
||||
|
||||
#if _WIN32
|
||||
#include <debugapi.h>
|
||||
#endif
|
||||
|
||||
/**
|
||||
* Utility methods for asserting and logging.
|
||||
*/
|
||||
namespace Debug
|
||||
{
|
||||
void Break()
|
||||
{
|
||||
#if DEBUG
|
||||
#if _WIN32
|
||||
if (IsDebuggerPresent()) {
|
||||
DebugBreak();
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
}
|
|
@ -0,0 +1,40 @@
|
|||
#pragma once
|
||||
|
||||
#include <cassert>
|
||||
#include <stdio.h>
|
||||
|
||||
#include "Console.hpp"
|
||||
#include "Diagnostics.hpp"
|
||||
|
||||
/**
|
||||
* Utility methods for asserting function parameters.
|
||||
*/
|
||||
namespace Guard
|
||||
{
|
||||
void Assert(bool expression, const char * message = nullptr)
|
||||
{
|
||||
if (expression) return;
|
||||
|
||||
if (message != nullptr)
|
||||
{
|
||||
Console::Error::WriteLine(message);
|
||||
}
|
||||
|
||||
#if DEBUG
|
||||
Debug::Break();
|
||||
#endif
|
||||
assert(false);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void ArgumentNotNull(T * argument, const char * message = nullptr)
|
||||
{
|
||||
Assert(argument != nullptr, message);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void ArgumentInRange(T argument, T min, T max, const char * message = nullptr)
|
||||
{
|
||||
Assert(argument >= min && argument <= max, message);
|
||||
}
|
||||
};
|
|
@ -0,0 +1,45 @@
|
|||
#include "FileStream.hpp"
|
||||
#include "Json.hpp"
|
||||
#include "Memory.hpp"
|
||||
#include "String.hpp"
|
||||
|
||||
namespace Json
|
||||
{
|
||||
json_t * ReadFromFile(const utf8 * path, size_t maxSize)
|
||||
{
|
||||
json_t * json = nullptr;
|
||||
auto fs = FileStream(path, FILE_MODE_OPEN);
|
||||
|
||||
size_t fileLength = (size_t)fs.GetLength();
|
||||
if (fileLength > maxSize)
|
||||
{
|
||||
throw IOException("Json file too large.");
|
||||
}
|
||||
|
||||
utf8 * fileData = Memory::Allocate<utf8>(fileLength + 1);
|
||||
fs.Read(fileData, fileLength);
|
||||
fileData[fileLength] = '\0';
|
||||
|
||||
json_error_t jsonLoadError;
|
||||
json = json_loads(fileData, 0, &jsonLoadError);
|
||||
Memory::Free(fileData);
|
||||
|
||||
if (json == nullptr)
|
||||
{
|
||||
throw JsonException(&jsonLoadError);
|
||||
}
|
||||
|
||||
return json;
|
||||
}
|
||||
|
||||
void WriteToFile(const utf8 * path, const json_t * json, size_t flags)
|
||||
{
|
||||
// Serialise JSON
|
||||
const char * jsonOutput = json_dumps(json, flags);
|
||||
|
||||
// Write to file
|
||||
auto fs = FileStream(path, FILE_MODE_WRITE);
|
||||
size_t jsonOutputSize = String::SizeOf(jsonOutput);
|
||||
fs.Write(jsonOutput, jsonOutputSize);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,29 @@
|
|||
#pragma once
|
||||
|
||||
#include <jansson.h>
|
||||
|
||||
#include "../common.h"
|
||||
#include "Exception.hpp"
|
||||
|
||||
namespace Json
|
||||
{
|
||||
// Don't try to load JSON files that exceed 64 MiB
|
||||
constexpr uint64 MAX_JSON_SIZE = 64 * 1024 * 1024;
|
||||
|
||||
json_t * ReadFromFile(const utf8 * path, size_t maxSize = MAX_JSON_SIZE);
|
||||
void WriteToFile(const utf8 * path, const json_t * json, size_t flags = 0);
|
||||
}
|
||||
|
||||
class JsonException : public Exception
|
||||
{
|
||||
private:
|
||||
json_error_t _jsonError;
|
||||
|
||||
public:
|
||||
JsonException(const char * message) : Exception(message) { }
|
||||
|
||||
JsonException(const json_error_t * jsonError) : JsonException(jsonError->text)
|
||||
{
|
||||
_jsonError = *jsonError;
|
||||
}
|
||||
};
|
|
@ -0,0 +1,90 @@
|
|||
#pragma once
|
||||
|
||||
#include <vector>
|
||||
|
||||
#include "../common.h"
|
||||
#include "Guard.hpp"
|
||||
#include "Memory.hpp"
|
||||
|
||||
/**
|
||||
* A container that stores elements in contiguous memory. Automatically reallocates memory when required. Equivalent to
|
||||
* std::vector.
|
||||
*/
|
||||
template<typename T>
|
||||
class List : public std::vector<T>
|
||||
{
|
||||
public:
|
||||
typedef typename std::vector<T>::const_reference const_reference;
|
||||
typedef typename std::vector<T>::reference reference;
|
||||
size_t GetCapacity() const { return this->capacity(); }
|
||||
size_t GetCount() const { return this->size(); }
|
||||
const T * GetItems() const { return this->data(); }
|
||||
|
||||
List() : std::vector<T>() { }
|
||||
|
||||
List(size_t capacity) : std::vector<T>(capacity) { }
|
||||
|
||||
List(const T * items, size_t count) : std::vector<T>(items, items + count) { }
|
||||
|
||||
void EnsureCapacity(size_t capacity)
|
||||
{
|
||||
this->reserve(capacity);
|
||||
}
|
||||
|
||||
void ShrinkToLength()
|
||||
{
|
||||
this->shrink_to_fit();
|
||||
}
|
||||
|
||||
void Clear()
|
||||
{
|
||||
this->clear();
|
||||
}
|
||||
|
||||
void Add(T item)
|
||||
{
|
||||
this->push_back(item);
|
||||
}
|
||||
|
||||
void Insert(T item, size_t index)
|
||||
{
|
||||
Guard::ArgumentInRange(index, (size_t)0, this->size());
|
||||
this->insert(this->begin() + index, item);
|
||||
}
|
||||
|
||||
bool Remove(T item)
|
||||
{
|
||||
for (size_t i = 0; i < this->size(); i++)
|
||||
{
|
||||
if (*this[i] == item)
|
||||
{
|
||||
RemoveAt(i);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void RemoveAt(size_t index)
|
||||
{
|
||||
Guard::ArgumentInRange(index, (size_t)0, this->size() - 1);
|
||||
this->erase(this->begin() + index);
|
||||
}
|
||||
|
||||
const T * ToArray() const
|
||||
{
|
||||
return Memory::DuplicateArray(this->data(), this->size());
|
||||
}
|
||||
|
||||
const_reference operator[](size_t index) const
|
||||
{
|
||||
Guard::ArgumentInRange(index, (size_t)0, this->size() - 1);
|
||||
return std::vector<T>::operator[](index);
|
||||
}
|
||||
|
||||
reference operator[](size_t index)
|
||||
{
|
||||
Guard::ArgumentInRange(index, (size_t)0, this->size() - 1);
|
||||
return std::vector<T>::operator[](index);
|
||||
}
|
||||
};
|
|
@ -31,7 +31,7 @@ namespace Memory
|
|||
template<typename T>
|
||||
T * Reallocate(T * ptr, size_t size)
|
||||
{
|
||||
if (ptr == NULL)
|
||||
if (ptr == nullptr)
|
||||
{
|
||||
return (T*)malloc(size);
|
||||
}
|
||||
|
@ -44,7 +44,7 @@ namespace Memory
|
|||
template<typename T>
|
||||
T * ReallocateArray(T * ptr, size_t count)
|
||||
{
|
||||
if (ptr == NULL)
|
||||
if (ptr == nullptr)
|
||||
{
|
||||
return (T*)malloc(count * sizeof(T));
|
||||
}
|
||||
|
@ -67,13 +67,6 @@ namespace Memory
|
|||
return (T*)memcpy((void*)dst, (const void*)src, size);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T * CopyArray(T *dst, const T * src, size_t count)
|
||||
{
|
||||
if (count == 0) return (T*)dst;
|
||||
return (T*)memcpy((void*)dst, (const void*)src, count * sizeof(T));
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T * Duplicate(const T * src, size_t size)
|
||||
{
|
||||
|
@ -81,16 +74,39 @@ namespace Memory
|
|||
return Copy(result, src, size);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T * DuplicateArray(const T * src, size_t count)
|
||||
{
|
||||
T *result = AllocateArray<T>(count);
|
||||
return CopyArray(result, src, count);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T * Set(T * dst, uint8 value, size_t size)
|
||||
{
|
||||
return (T*)memset((void*)dst, (int)value, size);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T * CopyArray(T * dst, const T * src, size_t count)
|
||||
{
|
||||
// Use a loop so that copy constructors are called
|
||||
// compiler should optimise to memcpy if possible
|
||||
T * result = dst;
|
||||
for (; count > 0; count--)
|
||||
{
|
||||
*dst++ = *src++;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
T * DuplicateArray(const T * src, size_t count)
|
||||
{
|
||||
T * result = AllocateArray<T>(count);
|
||||
return CopyArray(result, src, count);
|
||||
}
|
||||
|
||||
template<typename T>
|
||||
void FreeArray(T * ptr, size_t count)
|
||||
{
|
||||
for (size_t i = 0; i < count; i++)
|
||||
{
|
||||
ptr[i].~T();
|
||||
}
|
||||
Free(ptr);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@ extern "C"
|
|||
#include "../util/util.h"
|
||||
}
|
||||
|
||||
#include "Math.hpp"
|
||||
#include "Memory.hpp"
|
||||
#include "Path.hpp"
|
||||
#include "String.hpp"
|
||||
|
@ -17,6 +18,44 @@ namespace Path
|
|||
return safe_strcat_path(buffer, src, bufferSize);
|
||||
}
|
||||
|
||||
utf8 * GetDirectory(utf8 * buffer, size_t bufferSize, const utf8 * path)
|
||||
{
|
||||
const char pathSeperator = platform_get_path_separator();
|
||||
size_t lastPathSepIndex = String::LastIndexOf(path, pathSeperator);
|
||||
if (lastPathSepIndex == SIZE_MAX)
|
||||
{
|
||||
return String::Set(buffer, bufferSize, String::Empty);
|
||||
}
|
||||
|
||||
size_t copyLength = Math::Min(lastPathSepIndex, bufferSize - 1);
|
||||
Memory::Copy(buffer, path, copyLength);
|
||||
buffer[copyLength] = '\0';
|
||||
return buffer;
|
||||
}
|
||||
|
||||
utf8 * GetFileNameWithoutExtension(utf8 * buffer, size_t bufferSize, const utf8 * path)
|
||||
{
|
||||
const utf8 * lastDot = nullptr;
|
||||
const utf8 * ch = path;
|
||||
for (; *ch != '\0'; ch++)
|
||||
{
|
||||
if (*ch == '.')
|
||||
{
|
||||
lastDot = ch;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastDot == nullptr)
|
||||
{
|
||||
return String::Set(buffer, bufferSize, path);
|
||||
}
|
||||
|
||||
size_t truncatedLength = Math::Min<size_t>(bufferSize - 1, lastDot - path);
|
||||
Memory::Copy(buffer, path, truncatedLength);
|
||||
buffer[truncatedLength] = '\0';
|
||||
return buffer;
|
||||
}
|
||||
|
||||
utf8 * GetAbsolute(utf8 *buffer, size_t bufferSize, const utf8 * relativePath)
|
||||
{
|
||||
#if __WINDOWS__
|
||||
|
@ -49,4 +88,13 @@ namespace Path
|
|||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
bool Equals(const utf8 * a, const utf8 * b)
|
||||
{
|
||||
bool ignoreCase = false;
|
||||
#if __WINDOWS__
|
||||
ignoreCase = true;
|
||||
#endif
|
||||
return String::Equals(a, b, ignoreCase);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -8,5 +8,8 @@ extern "C"
|
|||
namespace Path
|
||||
{
|
||||
utf8 * Append(utf8 * buffer, size_t bufferSize, const utf8 * src);
|
||||
utf8 * GetAbsolute(utf8 *buffer, size_t bufferSize, const utf8 * relativePath);
|
||||
utf8 * GetDirectory(utf8 * buffer, size_t bufferSize, const utf8 * path);
|
||||
utf8 * GetFileNameWithoutExtension(utf8 * buffer, size_t bufferSize, const utf8 * path);
|
||||
utf8 * GetAbsolute(utf8 * buffer, size_t bufferSize, const utf8 * relativePath);
|
||||
bool Equals(const utf8 * a, const utf8 * b);
|
||||
}
|
||||
|
|
|
@ -10,6 +10,11 @@ extern "C"
|
|||
|
||||
namespace String
|
||||
{
|
||||
bool IsNullOrEmpty(const utf8 * str)
|
||||
{
|
||||
return str == nullptr || str[0] == '\0';
|
||||
}
|
||||
|
||||
bool Equals(const utf8 * a, const utf8 * b, bool ignoreCase)
|
||||
{
|
||||
if (a == b) return true;
|
||||
|
@ -51,6 +56,28 @@ namespace String
|
|||
}
|
||||
}
|
||||
|
||||
size_t LastIndexOf(const utf8 * str, utf8 match)
|
||||
{
|
||||
const utf8 * lastOccurance = nullptr;
|
||||
const utf8 * ch = str;
|
||||
for (; *ch != '\0'; ch++)
|
||||
{
|
||||
if (*ch == match)
|
||||
{
|
||||
lastOccurance = ch;
|
||||
}
|
||||
}
|
||||
|
||||
if (lastOccurance == nullptr)
|
||||
{
|
||||
return SIZE_MAX;
|
||||
}
|
||||
else
|
||||
{
|
||||
return (size_t)(lastOccurance - str);
|
||||
}
|
||||
}
|
||||
|
||||
size_t LengthOf(const utf8 * str)
|
||||
{
|
||||
return utf8_length(str);
|
||||
|
@ -137,14 +164,14 @@ namespace String
|
|||
return replacement;
|
||||
}
|
||||
|
||||
utf8 * DiscardDuplicate(utf8 * * ptr, utf8 * replacement)
|
||||
utf8 * DiscardDuplicate(utf8 * * ptr, const utf8 * replacement)
|
||||
{
|
||||
return DiscardUse(ptr, String::Duplicate(replacement));
|
||||
}
|
||||
|
||||
utf8 * SkipBOM(utf8 * buffer)
|
||||
{
|
||||
return (utf8*)SkipBOM(buffer);
|
||||
return (utf8*)SkipBOM((const utf8 *)buffer);
|
||||
}
|
||||
|
||||
const utf8 * SkipBOM(const utf8 * buffer)
|
||||
|
|
|
@ -7,8 +7,12 @@ extern "C"
|
|||
|
||||
namespace String
|
||||
{
|
||||
constexpr const utf8 * Empty = "";
|
||||
|
||||
bool IsNullOrEmpty(const utf8 * str);
|
||||
bool Equals(const utf8 * a, const utf8 * b, bool ignoreCase = false);
|
||||
bool StartsWith(const utf8 * str, const utf8 * match, bool ignoreCase = false);
|
||||
size_t LastIndexOf(const utf8 * str, utf8 match);
|
||||
|
||||
/**
|
||||
* Gets the length of the given string in codepoints.
|
||||
|
@ -35,7 +39,7 @@ namespace String
|
|||
/**
|
||||
* Helper method to free the string a string pointer points to and set it to a copy of a replacement string.
|
||||
*/
|
||||
utf8 * DiscardDuplicate(utf8 * * ptr, utf8 * replacement);
|
||||
utf8 * DiscardDuplicate(utf8 * * ptr, const utf8 * replacement);
|
||||
|
||||
utf8 * SkipBOM(utf8 * buffer);
|
||||
const utf8 * SkipBOM(const utf8 * buffer);
|
||||
|
|
|
@ -0,0 +1,830 @@
|
|||
#include <jansson.h>
|
||||
|
||||
extern "C"
|
||||
{
|
||||
#include "../common.h"
|
||||
#include "../config.h"
|
||||
#include "themes.h"
|
||||
#include "window.h"
|
||||
}
|
||||
|
||||
#include "../core/Json.hpp"
|
||||
#include "../core/List.hpp"
|
||||
#include "../core/Math.hpp"
|
||||
#include "../core/Memory.hpp"
|
||||
#include "../core/Path.hpp"
|
||||
#include "../core/String.hpp"
|
||||
#include "../core/Util.hpp"
|
||||
|
||||
struct WindowThemeDesc;
|
||||
|
||||
// Don't try to load theme files that exceed 64 MiB
|
||||
constexpr uint64 MAX_THEME_SIZE = 64 * 1024 * 1024;
|
||||
|
||||
/**
|
||||
* Represents a window theming style such as the colour scheme.
|
||||
*/
|
||||
struct WindowTheme
|
||||
{
|
||||
colour_t Colours[6];
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents the style for a particular type of window.
|
||||
*/
|
||||
struct UIThemeWindowEntry
|
||||
{
|
||||
rct_windowclass WindowClass;
|
||||
WindowTheme Theme;
|
||||
|
||||
|
||||
json_t * ToJson() const;
|
||||
static UIThemeWindowEntry FromJson(const WindowThemeDesc * wtDesc, const json_t * json);
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents a user interface theme. Contains window colour schemes and appearance features.
|
||||
*/
|
||||
class UITheme
|
||||
{
|
||||
public:
|
||||
utf8 * Name;
|
||||
List<UIThemeWindowEntry> Entries;
|
||||
uint8 Flags;
|
||||
|
||||
UITheme(const utf8 * name);
|
||||
UITheme(const UITheme & copy);
|
||||
~UITheme();
|
||||
|
||||
void SetName(const utf8 * name);
|
||||
const UIThemeWindowEntry * GetEntry(rct_windowclass windowClass) const;
|
||||
void SetEntry(const UIThemeWindowEntry * entry);
|
||||
void RemoveEntry(rct_windowclass windowClass);
|
||||
|
||||
json_t * ToJson() const;
|
||||
bool WriteToFile(const utf8 * path) const;
|
||||
|
||||
static UITheme * FromJson(const json_t * json);
|
||||
static UITheme * FromFile(const utf8 * path);
|
||||
static UITheme CreatePredefined(const utf8 * name, const UIThemeWindowEntry * entries, uint8 flags);
|
||||
};
|
||||
|
||||
/**
|
||||
* Represents the theme descriptor for a specific window type including the default colour scheme.
|
||||
*/
|
||||
struct WindowThemeDesc
|
||||
{
|
||||
rct_windowclass WindowClass;
|
||||
const utf8 * WindowClassSZ;
|
||||
rct_string_id WindowName;
|
||||
uint8 NumColours;
|
||||
WindowTheme DefaultTheme;
|
||||
};
|
||||
|
||||
#pragma region Window Theme Descriptors
|
||||
|
||||
#define COLOURS_1(c0) 1, { { (c0), 0, 0, 0, 0, 0 } }
|
||||
#define COLOURS_2(c0, c1) 2, { { (c0), (c1), 0, 0, 0, 0 } }
|
||||
#define COLOURS_3(c0, c1, c2) 3, { { (c0), (c1), (c2), 0, 0, 0 } }
|
||||
#define COLOURS_4(c0, c1, c2, c3) 4, { { (c0), (c1), (c2), (c3), 0, 0 } }
|
||||
#define COLOURS_5(c0, c1, c2, c3, c4) 5, { { (c0), (c1), (c2), (c3), (c4), 0 } }
|
||||
#define COLOURS_6(c0, c1, c2, c3, c4, c5) 6, { { (c0), (c1), (c2), (c3), (c4), (c5) } }
|
||||
|
||||
#define THEME_DEF_END { 0xFF, { 0, 0, 0, 0, 0, 0 } }
|
||||
|
||||
#define TWINDOW(window_class, window_name, window_string_id, theme) { window_class, window_name, window_string_id, theme }
|
||||
|
||||
#define THEME_WC(wc) wc, #wc
|
||||
|
||||
WindowThemeDesc WindowThemeDescriptors[] =
|
||||
{
|
||||
// WindowClass, WindowClassSZ WindowName NumColours, DefaultTheme
|
||||
{ THEME_WC(WC_TOP_TOOLBAR), 5245, COLOURS_4(COLOUR_LIGHT_BLUE, COLOUR_DARK_GREEN, COLOUR_DARK_BROWN, COLOUR_GREY ) },
|
||||
{ THEME_WC(WC_BOTTOM_TOOLBAR), 5246, COLOURS_4(TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN), COLOUR_BLACK, COLOUR_BRIGHT_GREEN ) },
|
||||
{ THEME_WC(WC_RIDE), 5203, COLOURS_3(COLOUR_GREY, COLOUR_BORDEAUX_RED, COLOUR_GREY ) },
|
||||
{ THEME_WC(WC_RIDE_CONSTRUCTION), 5199, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
|
||||
{ THEME_WC(WC_RIDE_LIST), 5204, COLOURS_3(COLOUR_GREY, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) },
|
||||
{ THEME_WC(WC_SAVE_PROMPT), 5223, COLOURS_1(TRANSLUCENT(COLOUR_BORDEAUX_RED) ) },
|
||||
{ THEME_WC(WC_CONSTRUCT_RIDE), 5201, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) },
|
||||
{ THEME_WC(WC_DEMOLISH_RIDE_PROMPT), 5224, COLOURS_1(TRANSLUCENT(COLOUR_BORDEAUX_RED) ) },
|
||||
{ THEME_WC(WC_SCENERY), 5197, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_GREEN, COLOUR_DARK_GREEN ) },
|
||||
{ THEME_WC(WC_OPTIONS), 5219, COLOURS_3(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) },
|
||||
{ THEME_WC(WC_FOOTPATH), 5198, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
|
||||
{ THEME_WC(WC_LAND), 5193, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
|
||||
{ THEME_WC(WC_WATER), 5194, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
|
||||
{ THEME_WC(WC_PEEP), 5205, COLOURS_3(COLOUR_GREY, COLOUR_OLIVE_GREEN, COLOUR_OLIVE_GREEN ) },
|
||||
{ THEME_WC(WC_GUEST_LIST), 5206, COLOURS_3(COLOUR_GREY, COLOUR_OLIVE_GREEN, COLOUR_OLIVE_GREEN ) },
|
||||
{ THEME_WC(WC_STAFF_LIST), 5208, COLOURS_3(COLOUR_GREY, COLOUR_LIGHT_PURPLE, COLOUR_LIGHT_PURPLE ) },
|
||||
{ THEME_WC(WC_FIRE_PROMPT), 5225, COLOURS_1(TRANSLUCENT(COLOUR_BORDEAUX_RED) ) },
|
||||
{ THEME_WC(WC_PARK_INFORMATION), 5253, COLOURS_3(COLOUR_GREY, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) },
|
||||
{ THEME_WC(WC_FINANCES), 5187, COLOURS_3(COLOUR_GREY, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) },
|
||||
{ THEME_WC(WC_TITLE_MENU), 5249, COLOURS_3(TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN) ) },
|
||||
{ THEME_WC(WC_TITLE_EXIT), 5250, COLOURS_3(TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN) ) },
|
||||
{ THEME_WC(WC_RECENT_NEWS), 5192, COLOURS_3(COLOUR_GREY, COLOUR_GREY, COLOUR_BLACK ) },
|
||||
{ THEME_WC(WC_SCENARIO_SELECT), 5252, COLOURS_3(COLOUR_GREY, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) },
|
||||
{ THEME_WC(WC_TRACK_DESIGN_LIST), 5202, COLOURS_3(COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) },
|
||||
{ THEME_WC(WC_TRACK_DESIGN_PLACE), 5200, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
|
||||
{ THEME_WC(WC_NEW_CAMPAIGN), 5188, COLOURS_3(COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) },
|
||||
{ THEME_WC(WC_KEYBOARD_SHORTCUT_LIST), 5220, COLOURS_3(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) },
|
||||
{ THEME_WC(WC_CHANGE_KEYBOARD_SHORTCUT), 5221, COLOURS_3(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) },
|
||||
{ THEME_WC(WC_MAP), 5190, COLOURS_2(COLOUR_DARK_GREEN, COLOUR_DARK_BROWN ) },
|
||||
{ THEME_WC(WC_BANNER), 5209, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
|
||||
{ THEME_WC(WC_EDITOR_OBJECT_SELECTION), 5210, COLOURS_3(COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_GREY ) },
|
||||
{ THEME_WC(WC_EDITOR_INVENTION_LIST), 5211, COLOURS_3(COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_GREY ) },
|
||||
{ THEME_WC(WC_EDITOR_SCENARIO_OPTIONS), 5212, COLOURS_3(COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_GREY ) },
|
||||
{ THEME_WC(WC_EDTIOR_OBJECTIVE_OPTIONS), 5213, COLOURS_3(COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_GREY ) },
|
||||
{ THEME_WC(WC_MANAGE_TRACK_DESIGN), 5215, COLOURS_3(COLOUR_GREY, COLOUR_GREY, COLOUR_GREY ) },
|
||||
{ THEME_WC(WC_TRACK_DELETE_PROMPT), 5226, COLOURS_3(COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) },
|
||||
{ THEME_WC(WC_INSTALL_TRACK), 5216, COLOURS_3(COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) },
|
||||
{ THEME_WC(WC_CLEAR_SCENERY), 5195, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
|
||||
{ THEME_WC(WC_CHEATS), 5217, COLOURS_3(COLOUR_GREY, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) },
|
||||
{ THEME_WC(WC_RESEARCH), 5189, COLOURS_3(COLOUR_GREY, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) },
|
||||
{ THEME_WC(WC_VIEWPORT), 5191, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
|
||||
{ THEME_WC(WC_MAPGEN), 5214, COLOURS_3(COLOUR_DARK_GREEN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
|
||||
{ THEME_WC(WC_LOADSAVE), 5222, COLOURS_3(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) },
|
||||
{ THEME_WC(WC_LOADSAVE_OVERWRITE_PROMPT), 5227, COLOURS_1(TRANSLUCENT(COLOUR_BORDEAUX_RED) ) },
|
||||
{ THEME_WC(WC_TITLE_OPTIONS), 5251, COLOURS_3(TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN) ) },
|
||||
{ THEME_WC(WC_LAND_RIGHTS), 5196, COLOURS_3(COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) },
|
||||
{ THEME_WC(WC_THEMES), 5218, COLOURS_3(COLOUR_GREY, COLOUR_DARK_GREEN, COLOUR_DARK_GREEN ) },
|
||||
{ THEME_WC(WC_STAFF), 5207, COLOURS_3(COLOUR_GREY, COLOUR_LIGHT_PURPLE, COLOUR_LIGHT_PURPLE ) },
|
||||
{ THEME_WC(WC_EDITOR_TRACK_BOTTOM_TOOLBAR), 5247, COLOURS_3(TRANSLUCENT(COLOUR_LIGHT_BLUE), TRANSLUCENT(COLOUR_LIGHT_BLUE), TRANSLUCENT(COLOUR_LIGHT_BLUE) ) },
|
||||
{ THEME_WC(WC_EDITOR_SCENARIO_BOTTOM_TOOLBAR), 5248, COLOURS_3(TRANSLUCENT(COLOUR_LIGHT_BROWN), TRANSLUCENT(COLOUR_LIGHT_BROWN), TRANSLUCENT(COLOUR_MOSS_GREEN) ) },
|
||||
{ THEME_WC(WC_TITLE_EDITOR), 5433, COLOURS_3(COLOUR_GREY, COLOUR_OLIVE_GREEN, COLOUR_OLIVE_GREEN ) },
|
||||
{ THEME_WC(WC_TILE_INSPECTOR), 5314, COLOURS_2(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) },
|
||||
{ THEME_WC(WC_CHANGELOG), 5344, COLOURS_2(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) },
|
||||
{ THEME_WC(WC_MULTIPLAYER), 5502, COLOURS_3(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) },
|
||||
{ THEME_WC(WC_PLAYER), 5736, COLOURS_3(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) },
|
||||
{ THEME_WC(WC_NETWORK_STATUS), 5735, COLOURS_1(COLOUR_LIGHT_BLUE ) },
|
||||
{ THEME_WC(WC_SERVER_LIST), 5498, COLOURS_2(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) },
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region Pre-defined Themes
|
||||
|
||||
#define COLOURS_RCT1(c0, c1, c2, c3, c4, c5) { { (c0), (c1), (c2), (c3), (c4), (c5) } }
|
||||
|
||||
UIThemeWindowEntry PredefinedThemeRCT1_Entries[] =
|
||||
{
|
||||
{ WC_TOP_TOOLBAR, COLOURS_RCT1(COLOUR_GREY, COLOUR_GREY, COLOUR_GREY, COLOUR_GREY, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_BOTTOM_TOOLBAR, COLOURS_RCT1(TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), COLOUR_BLACK, COLOUR_YELLOW, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_RIDE, COLOURS_RCT1(COLOUR_BORDEAUX_RED, COLOUR_GREY, COLOUR_SATURATED_GREEN, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_RIDE_LIST, COLOURS_RCT1(COLOUR_BORDEAUX_RED, COLOUR_GREY, COLOUR_GREY, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_CONSTRUCT_RIDE, COLOURS_RCT1(COLOUR_BORDEAUX_RED, COLOUR_GREY, COLOUR_GREY, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_PEEP, COLOURS_RCT1(COLOUR_LIGHT_BROWN, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_GUEST_LIST, COLOURS_RCT1(COLOUR_LIGHT_BROWN, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_STAFF_LIST, COLOURS_RCT1(COLOUR_DARK_GREEN, COLOUR_LIGHT_PURPLE, COLOUR_LIGHT_PURPLE, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_FINANCES, COLOURS_RCT1(COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_GREY, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_TITLE_MENU, COLOURS_RCT1(TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_TITLE_EXIT, COLOURS_RCT1(TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_NEW_CAMPAIGN, COLOURS_RCT1(COLOUR_LIGHT_PURPLE, COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_TITLE_OPTIONS, COLOURS_RCT1(TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_STAFF, COLOURS_RCT1(COLOUR_DARK_GREEN, COLOUR_LIGHT_PURPLE, COLOUR_LIGHT_PURPLE, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
THEME_DEF_END
|
||||
};
|
||||
|
||||
UIThemeWindowEntry PredefinedThemeRCT2_Entries[] =
|
||||
{
|
||||
THEME_DEF_END
|
||||
};
|
||||
|
||||
const UITheme PredefinedThemeRCT1 = UITheme::CreatePredefined(
|
||||
"RCT1", PredefinedThemeRCT1_Entries, UITHEME_FLAG_USE_LIGHTS_RIDE |
|
||||
UITHEME_FLAG_USE_LIGHTS_PARK |
|
||||
UITHEME_FLAG_USE_ALTERNATIVE_SCENARIO_SELECT_FONT);
|
||||
|
||||
const UITheme PredefinedThemeRCT2 = UITheme::CreatePredefined(
|
||||
"RCT2", PredefinedThemeRCT2_Entries, 0);
|
||||
|
||||
const UITheme * PredefinedThemes[] = {
|
||||
&PredefinedThemeRCT1,
|
||||
&PredefinedThemeRCT2,
|
||||
nullptr
|
||||
};
|
||||
|
||||
#pragma endregion
|
||||
|
||||
static const WindowThemeDesc * GetWindowThemeDescriptor(rct_windowclass windowClass)
|
||||
{
|
||||
for (size_t i = 0; i < Util::CountOf(WindowThemeDescriptors); i++)
|
||||
{
|
||||
const WindowThemeDesc * desc = &WindowThemeDescriptors[i];
|
||||
if (desc->WindowClass == windowClass)
|
||||
{
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static const WindowThemeDesc * GetWindowThemeDescriptor(const utf8 * windowClassSZ)
|
||||
{
|
||||
for (size_t i = 0; i < Util::CountOf(WindowThemeDescriptors); i++)
|
||||
{
|
||||
const WindowThemeDesc * desc = &WindowThemeDescriptors[i];
|
||||
if (String::Equals(desc->WindowClassSZ, windowClassSZ))
|
||||
{
|
||||
return desc;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
static void ThrowThemeLoadException()
|
||||
{
|
||||
throw Exception("Invalid JSON UI theme entry.");
|
||||
}
|
||||
|
||||
#pragma region UIThemeEntry
|
||||
|
||||
json_t * UIThemeWindowEntry::ToJson() const
|
||||
{
|
||||
const WindowThemeDesc * wtDesc = GetWindowThemeDescriptor(WindowClass);
|
||||
|
||||
json_t * jsonColours = json_array();
|
||||
for (uint8 i = 0; i < wtDesc->NumColours; i++) {
|
||||
colour_t colour = Theme.Colours[i];
|
||||
json_array_append_new(jsonColours, json_integer(colour));
|
||||
}
|
||||
|
||||
json_t * jsonEntry = json_object();
|
||||
json_object_set_new(jsonEntry, "colours", jsonColours);
|
||||
|
||||
return jsonEntry;
|
||||
}
|
||||
|
||||
UIThemeWindowEntry UIThemeWindowEntry::FromJson(const WindowThemeDesc * wtDesc, const json_t * json)
|
||||
{
|
||||
json_t * jsonColours = json_object_get(json, "colours");
|
||||
if (jsonColours == nullptr)
|
||||
{
|
||||
ThrowThemeLoadException();
|
||||
}
|
||||
|
||||
uint8 numColours = (uint8)json_array_size(jsonColours);
|
||||
numColours = Math::Min(numColours, wtDesc->NumColours);
|
||||
|
||||
UIThemeWindowEntry result;
|
||||
result.WindowClass = wtDesc->WindowClass;
|
||||
result.Theme = wtDesc->DefaultTheme;
|
||||
|
||||
for (uint8 i = 0; i < numColours; i++)
|
||||
{
|
||||
result.Theme.Colours[i] = (colour_t)json_integer_value(json_array_get(jsonColours, i));
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
#pragma region UITheme
|
||||
|
||||
UITheme::UITheme(const utf8 * name)
|
||||
{
|
||||
Name = String::Duplicate(name);
|
||||
Flags = 0;
|
||||
}
|
||||
|
||||
UITheme::UITheme(const UITheme & copy)
|
||||
{
|
||||
Name = String::Duplicate(copy.Name);
|
||||
Flags = copy.Flags;
|
||||
Entries = copy.Entries;
|
||||
}
|
||||
|
||||
UITheme::~UITheme()
|
||||
{
|
||||
Memory::Free(Name);
|
||||
}
|
||||
|
||||
void UITheme::SetName(const utf8 * name)
|
||||
{
|
||||
String::DiscardDuplicate(&Name, name);
|
||||
}
|
||||
|
||||
const UIThemeWindowEntry * UITheme::GetEntry(rct_windowclass windowClass) const
|
||||
{
|
||||
for (size_t i = 0; i < Entries.GetCount(); i++)
|
||||
{
|
||||
const UIThemeWindowEntry * entry = &Entries[i];
|
||||
if (entry->WindowClass == windowClass)
|
||||
{
|
||||
return entry;
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
void UITheme::SetEntry(const UIThemeWindowEntry * newEntry)
|
||||
{
|
||||
// Try to replace existing entry
|
||||
for (size_t i = 0; i < Entries.GetCount(); i++)
|
||||
{
|
||||
UIThemeWindowEntry * entry = &Entries[i];
|
||||
if (entry->WindowClass == newEntry->WindowClass)
|
||||
{
|
||||
*entry = *newEntry;
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
Entries.Add(*newEntry);
|
||||
}
|
||||
|
||||
void UITheme::RemoveEntry(rct_windowclass windowClass)
|
||||
{
|
||||
// Remove existing entry
|
||||
for (size_t i = 0; i < Entries.GetCount(); i++)
|
||||
{
|
||||
UIThemeWindowEntry * entry = &Entries[i];
|
||||
if (entry->WindowClass == windowClass)
|
||||
{
|
||||
Entries.RemoveAt(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
json_t * UITheme::ToJson() const
|
||||
{
|
||||
// Create entries
|
||||
json_t * jsonEntries = json_object();
|
||||
for (const UIThemeWindowEntry & entry : Entries)
|
||||
{
|
||||
const WindowThemeDesc * wtDesc = GetWindowThemeDescriptor(entry.WindowClass);
|
||||
json_object_set_new(jsonEntries, wtDesc->WindowClassSZ, entry.ToJson());
|
||||
}
|
||||
|
||||
// Create theme object
|
||||
json_t * jsonTheme = json_object();
|
||||
json_object_set_new(jsonTheme, "name", json_string(Name));
|
||||
json_object_set_new(jsonTheme, "entries", jsonEntries);
|
||||
|
||||
json_object_set_new(jsonTheme, "useLightsRide", json_boolean(Flags & UITHEME_FLAG_USE_LIGHTS_RIDE));
|
||||
json_object_set_new(jsonTheme, "useLightsPark", json_boolean(Flags & UITHEME_FLAG_USE_LIGHTS_PARK));
|
||||
json_object_set_new(jsonTheme,
|
||||
"useAltScenarioSelectFont",
|
||||
json_boolean(Flags & UITHEME_FLAG_USE_ALTERNATIVE_SCENARIO_SELECT_FONT));
|
||||
|
||||
return jsonTheme;
|
||||
}
|
||||
|
||||
bool UITheme::WriteToFile(const utf8 * path) const
|
||||
{
|
||||
json_t * jsonTheme = ToJson();
|
||||
bool result;
|
||||
try
|
||||
{
|
||||
Json::WriteToFile(path, jsonTheme, JSON_INDENT(4) | JSON_PRESERVE_ORDER);
|
||||
result = true;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log_error("Unable to save %s: %s", path, ex.GetMessage());
|
||||
result = false;
|
||||
}
|
||||
|
||||
json_decref(jsonTheme);
|
||||
return result;
|
||||
}
|
||||
|
||||
UITheme * UITheme::FromJson(const json_t * json)
|
||||
{
|
||||
const char * themeName = json_string_value(json_object_get(json, "name"));
|
||||
if (themeName == nullptr)
|
||||
{
|
||||
ThrowThemeLoadException();
|
||||
}
|
||||
|
||||
json_t * jsonEntries = json_object_get(json, "entries");
|
||||
size_t numEntries = json_object_size(jsonEntries);
|
||||
|
||||
UITheme * result = nullptr;
|
||||
try
|
||||
{
|
||||
result = new UITheme(themeName);
|
||||
|
||||
if (json_is_true(json_object_get(json, "useLightsRide")))
|
||||
{
|
||||
result->Flags |= UITHEME_FLAG_USE_LIGHTS_RIDE;
|
||||
}
|
||||
if (json_is_true(json_object_get(json, "useLightsPark")))
|
||||
{
|
||||
result->Flags |= UITHEME_FLAG_USE_LIGHTS_PARK;
|
||||
}
|
||||
if (json_is_true(json_object_get(json, "useAltScenarioSelectFont")))
|
||||
{
|
||||
result->Flags |= UITHEME_FLAG_USE_ALTERNATIVE_SCENARIO_SELECT_FONT;
|
||||
}
|
||||
|
||||
const char * jkey;
|
||||
json_t * jvalue;
|
||||
size_t i = 0;
|
||||
json_object_foreach(jsonEntries, jkey, jvalue)
|
||||
{
|
||||
const WindowThemeDesc * wtDesc = GetWindowThemeDescriptor(jkey);
|
||||
if (wtDesc == nullptr) continue;
|
||||
|
||||
UIThemeWindowEntry entry = UIThemeWindowEntry::FromJson(wtDesc, jvalue);
|
||||
result->SetEntry(&entry);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
delete result;
|
||||
throw ex;
|
||||
}
|
||||
}
|
||||
|
||||
UITheme * UITheme::FromFile(const utf8 * path)
|
||||
{
|
||||
json_t * json = nullptr;
|
||||
UITheme * result = nullptr;
|
||||
try
|
||||
{
|
||||
json = Json::ReadFromFile(path);
|
||||
result = UITheme::FromJson(json);
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
log_error("Unable to read theme: %s", path);
|
||||
result = nullptr;
|
||||
}
|
||||
|
||||
json_decref(json);
|
||||
return result;
|
||||
}
|
||||
|
||||
UITheme UITheme::CreatePredefined(const utf8 * name, const UIThemeWindowEntry * entries, uint8 flags)
|
||||
{
|
||||
auto theme = UITheme(name);
|
||||
theme.Flags = flags | UITHEME_FLAG_PREDEFINED;
|
||||
|
||||
size_t numEntries = 0;
|
||||
for (const UIThemeWindowEntry * entry = entries; entry->WindowClass != 255; entry++)
|
||||
{
|
||||
numEntries++;
|
||||
}
|
||||
|
||||
theme.Entries = List<UIThemeWindowEntry>(entries, numEntries);
|
||||
return theme;
|
||||
}
|
||||
|
||||
#pragma endregion
|
||||
|
||||
namespace ThemeManager
|
||||
{
|
||||
struct AvailableTheme
|
||||
{
|
||||
utf8 Path[MAX_PATH];
|
||||
utf8 Name[96];
|
||||
};
|
||||
|
||||
utf8 * CurrentThemePath;
|
||||
UITheme * CurrentTheme;
|
||||
List<AvailableTheme> AvailableThemes;
|
||||
size_t ActiveAvailableThemeIndex = SIZE_MAX;
|
||||
size_t NumPredefinedThemes = 0;
|
||||
|
||||
void GetThemeFileName(utf8 * buffer, size_t bufferSize, const utf8 * name);
|
||||
|
||||
void GetAvailableThemes(List<AvailableTheme> * outThemes)
|
||||
{
|
||||
Guard::ArgumentNotNull(outThemes);
|
||||
|
||||
outThemes->Clear();
|
||||
|
||||
NumPredefinedThemes = 0;
|
||||
for (const UITheme * * predefinedTheme = PredefinedThemes; *predefinedTheme != nullptr; predefinedTheme++)
|
||||
{
|
||||
AvailableTheme theme;
|
||||
String::Set(theme.Path, sizeof(theme.Path), String::Empty);
|
||||
String::Set(theme.Name, sizeof(theme.Name), (*predefinedTheme)->Name);
|
||||
outThemes->Add(theme);
|
||||
|
||||
NumPredefinedThemes++;
|
||||
}
|
||||
|
||||
utf8 themesPattern[MAX_PATH];
|
||||
platform_get_user_directory(themesPattern, "themes");
|
||||
Path::Append(themesPattern, sizeof(themesPattern), "*.json");
|
||||
|
||||
int handle = platform_enumerate_files_begin(themesPattern);
|
||||
if (handle != INVALID_HANDLE)
|
||||
{
|
||||
file_info fileInfo;
|
||||
while (platform_enumerate_files_next(handle, &fileInfo))
|
||||
{
|
||||
AvailableTheme theme;
|
||||
Path::GetFileNameWithoutExtension(theme.Name, sizeof(theme.Name), fileInfo.path);
|
||||
GetThemeFileName(theme.Path, sizeof(theme.Path), theme.Name);
|
||||
|
||||
outThemes->Add(theme);
|
||||
|
||||
if (Path::Equals(CurrentThemePath, fileInfo.path))
|
||||
{
|
||||
ActiveAvailableThemeIndex = outThemes->GetCount() - 1;
|
||||
}
|
||||
}
|
||||
platform_enumerate_files_end(handle);
|
||||
}
|
||||
}
|
||||
|
||||
void LoadTheme(UITheme * theme)
|
||||
{
|
||||
if (CurrentTheme == theme)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
if (CurrentTheme != nullptr)
|
||||
{
|
||||
if (!(CurrentTheme->Flags & UITHEME_FLAG_PREDEFINED))
|
||||
{
|
||||
delete CurrentTheme;
|
||||
}
|
||||
}
|
||||
|
||||
CurrentTheme = theme;
|
||||
String::DiscardUse(&CurrentThemePath, nullptr);
|
||||
|
||||
gfx_invalidate_screen();
|
||||
}
|
||||
|
||||
void LoadTheme(const utf8 * path)
|
||||
{
|
||||
UITheme * theme = UITheme::FromFile(path);
|
||||
if (theme == nullptr)
|
||||
{
|
||||
// Fall-back to default
|
||||
theme = (UITheme *)&PredefinedThemeRCT2;
|
||||
LoadTheme(theme);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoadTheme(theme);
|
||||
String::DiscardDuplicate(&CurrentThemePath, path);
|
||||
}
|
||||
}
|
||||
|
||||
bool LoadThemeByName(const utf8 * name)
|
||||
{
|
||||
for (size_t i = 0; i < ThemeManager::AvailableThemes.GetCount(); i++)
|
||||
{
|
||||
if (String::Equals(name, ThemeManager::AvailableThemes[i].Name))
|
||||
{
|
||||
const utf8 * path = ThemeManager::AvailableThemes[i].Path;
|
||||
if (String::IsNullOrEmpty(path))
|
||||
{
|
||||
LoadTheme((UITheme *)PredefinedThemes[i]);
|
||||
}
|
||||
else
|
||||
{
|
||||
LoadTheme(ThemeManager::AvailableThemes[i].Path);
|
||||
}
|
||||
ActiveAvailableThemeIndex = i;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
void Initialise()
|
||||
{
|
||||
ThemeManager::GetAvailableThemes(&ThemeManager::AvailableThemes);
|
||||
LoadTheme((UITheme *)&PredefinedThemeRCT2);
|
||||
ActiveAvailableThemeIndex = 1;
|
||||
|
||||
bool configValid = false;
|
||||
if (!String::IsNullOrEmpty(gConfigInterface.current_theme_preset))
|
||||
{
|
||||
if (LoadThemeByName(gConfigInterface.current_theme_preset))
|
||||
{
|
||||
configValid = true;
|
||||
}
|
||||
}
|
||||
|
||||
if (!configValid)
|
||||
{
|
||||
String::DiscardDuplicate(&gConfigInterface.current_theme_preset, theme_manager_get_available_theme_name(1));
|
||||
}
|
||||
}
|
||||
|
||||
void GetThemeFileName(utf8 * buffer, size_t bufferSize, const utf8 * name)
|
||||
{
|
||||
platform_get_user_directory(buffer, "themes");
|
||||
Path::Append(buffer, bufferSize, name);
|
||||
String::Append(buffer, bufferSize, ".json");
|
||||
}
|
||||
}
|
||||
|
||||
extern "C"
|
||||
{
|
||||
void theme_manager_load_available_themes()
|
||||
{
|
||||
ThemeManager::GetAvailableThemes(&ThemeManager::AvailableThemes);
|
||||
}
|
||||
|
||||
size_t theme_manager_get_num_available_themes()
|
||||
{
|
||||
return ThemeManager::AvailableThemes.GetCount();
|
||||
}
|
||||
|
||||
const utf8 * theme_manager_get_available_theme_path(size_t index)
|
||||
{
|
||||
return ThemeManager::AvailableThemes[index].Path;
|
||||
}
|
||||
|
||||
const utf8 * theme_manager_get_available_theme_name(size_t index)
|
||||
{
|
||||
return ThemeManager::AvailableThemes[index].Name;
|
||||
}
|
||||
|
||||
size_t theme_manager_get_active_available_theme_index()
|
||||
{
|
||||
return ThemeManager::ActiveAvailableThemeIndex;
|
||||
}
|
||||
|
||||
void theme_manager_set_active_available_theme(size_t index)
|
||||
{
|
||||
if (index < ThemeManager::NumPredefinedThemes)
|
||||
{
|
||||
ThemeManager::LoadTheme((UITheme *)PredefinedThemes[index]);
|
||||
}
|
||||
else
|
||||
{
|
||||
const utf8 * path = ThemeManager::AvailableThemes[index].Path;
|
||||
ThemeManager::LoadTheme(path);
|
||||
|
||||
// HACK Check if theme load failed and fell back to RCT2
|
||||
if (ThemeManager::CurrentThemePath == nullptr)
|
||||
{
|
||||
index = 1;
|
||||
}
|
||||
}
|
||||
ThemeManager::ActiveAvailableThemeIndex = index;
|
||||
String::DiscardDuplicate(&gConfigInterface.current_theme_preset, theme_manager_get_available_theme_name(index));
|
||||
}
|
||||
|
||||
uint8 theme_get_colour(rct_windowclass wc, uint8 index)
|
||||
{
|
||||
const UIThemeWindowEntry * entry = ThemeManager::CurrentTheme->GetEntry(wc);
|
||||
if (entry == nullptr)
|
||||
{
|
||||
const WindowThemeDesc * desc = GetWindowThemeDescriptor(wc);
|
||||
return desc->DefaultTheme.Colours[index];
|
||||
}
|
||||
else
|
||||
{
|
||||
return entry->Theme.Colours[index];
|
||||
}
|
||||
}
|
||||
|
||||
void theme_set_colour(rct_windowclass wc, uint8 index, colour_t colour)
|
||||
{
|
||||
UIThemeWindowEntry entry;
|
||||
entry.WindowClass = wc;
|
||||
|
||||
auto currentEntry = (UIThemeWindowEntry *)ThemeManager::CurrentTheme->GetEntry(wc);
|
||||
if (currentEntry != nullptr)
|
||||
{
|
||||
entry.Theme = currentEntry->Theme;
|
||||
}
|
||||
else
|
||||
{
|
||||
const WindowThemeDesc * desc = GetWindowThemeDescriptor(wc);
|
||||
entry.Theme = desc->DefaultTheme;
|
||||
}
|
||||
|
||||
entry.Theme.Colours[index] = colour;
|
||||
ThemeManager::CurrentTheme->SetEntry(&entry);
|
||||
|
||||
theme_save();
|
||||
}
|
||||
|
||||
uint8 theme_get_flags()
|
||||
{
|
||||
return ThemeManager::CurrentTheme->Flags;
|
||||
}
|
||||
|
||||
void theme_set_flags(uint8 flags)
|
||||
{
|
||||
ThemeManager::CurrentTheme->Flags = flags;
|
||||
theme_save();
|
||||
}
|
||||
|
||||
void theme_save()
|
||||
{
|
||||
ThemeManager::CurrentTheme->WriteToFile(ThemeManager::CurrentThemePath);
|
||||
}
|
||||
|
||||
void theme_rename(const utf8 * name)
|
||||
{
|
||||
const utf8 * oldPath = ThemeManager::CurrentThemePath;
|
||||
utf8 newPath[MAX_PATH];
|
||||
|
||||
ThemeManager::GetThemeFileName(newPath, sizeof(newPath), name);
|
||||
platform_file_move(oldPath, newPath);
|
||||
String::DiscardDuplicate(&ThemeManager::CurrentThemePath, newPath);
|
||||
|
||||
ThemeManager::CurrentTheme->SetName(name);
|
||||
ThemeManager::CurrentTheme->WriteToFile(ThemeManager::CurrentThemePath);
|
||||
|
||||
theme_manager_load_available_themes();
|
||||
for (size_t i = 0; i < ThemeManager::AvailableThemes.GetCount(); i++)
|
||||
{
|
||||
if (Path::Equals(newPath, ThemeManager::AvailableThemes[i].Path))
|
||||
{
|
||||
ThemeManager::ActiveAvailableThemeIndex = i;
|
||||
String::DiscardDuplicate(&gConfigInterface.current_theme_preset, theme_manager_get_available_theme_name(1));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void theme_duplicate(const utf8 * name)
|
||||
{
|
||||
utf8 newPath[MAX_PATH];
|
||||
|
||||
ThemeManager::GetThemeFileName(newPath, sizeof(newPath), name);
|
||||
|
||||
// Copy the theme, save it and then load it back in
|
||||
UITheme * newTheme = new UITheme(*ThemeManager::CurrentTheme);
|
||||
newTheme->SetName(name);
|
||||
newTheme->Flags &= ~UITHEME_FLAG_PREDEFINED;
|
||||
newTheme->WriteToFile(newPath);
|
||||
delete newTheme;
|
||||
|
||||
ThemeManager::LoadTheme(newPath);
|
||||
|
||||
theme_manager_load_available_themes();
|
||||
for (size_t i = 0; i < ThemeManager::AvailableThemes.GetCount(); i++)
|
||||
{
|
||||
if (Path::Equals(newPath, ThemeManager::AvailableThemes[i].Path))
|
||||
{
|
||||
ThemeManager::ActiveAvailableThemeIndex = i;
|
||||
String::DiscardDuplicate(&gConfigInterface.current_theme_preset, theme_manager_get_available_theme_name(i));
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void theme_delete()
|
||||
{
|
||||
platform_file_delete(ThemeManager::CurrentThemePath);
|
||||
ThemeManager::LoadTheme((UITheme *)&PredefinedThemeRCT2);
|
||||
ThemeManager::ActiveAvailableThemeIndex = 1;
|
||||
String::DiscardDuplicate(&gConfigInterface.current_theme_preset, theme_manager_get_available_theme_name(1));
|
||||
}
|
||||
|
||||
void theme_manager_initialise()
|
||||
{
|
||||
ThemeManager::Initialise();
|
||||
}
|
||||
|
||||
uint8 theme_desc_get_num_colours(rct_windowclass wc)
|
||||
{
|
||||
const WindowThemeDesc * desc = GetWindowThemeDescriptor(wc);
|
||||
return desc->NumColours;
|
||||
}
|
||||
|
||||
rct_string_id theme_desc_get_name(rct_windowclass wc)
|
||||
{
|
||||
const WindowThemeDesc * desc = GetWindowThemeDescriptor(wc);
|
||||
return desc->WindowName;
|
||||
}
|
||||
|
||||
void colour_scheme_update(rct_window * window)
|
||||
{
|
||||
colour_scheme_update_by_class(window, window->classification);
|
||||
}
|
||||
|
||||
void colour_scheme_update_by_class(rct_window * window, rct_windowclass classification)
|
||||
{
|
||||
const WindowTheme * windowTheme;
|
||||
const UIThemeWindowEntry * entry = ThemeManager::CurrentTheme->GetEntry(classification);
|
||||
if (entry != nullptr)
|
||||
{
|
||||
windowTheme = &entry->Theme;
|
||||
}
|
||||
else
|
||||
{
|
||||
const WindowThemeDesc * desc = GetWindowThemeDescriptor(classification);
|
||||
windowTheme = &desc->DefaultTheme;
|
||||
}
|
||||
|
||||
bool transparent = false;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
window->colours[i] = windowTheme->Colours[i];
|
||||
if (windowTheme->Colours[i] & COLOUR_FLAG_TRANSLUCENT) {
|
||||
transparent = true;
|
||||
}
|
||||
}
|
||||
// Some windows need to be transparent even if the colours aren't.
|
||||
// There doesn't seem to be any side-effects for all windows being transparent
|
||||
window->flags |= WF_TRANSPARENT;
|
||||
}
|
||||
}
|
|
@ -1,251 +0,0 @@
|
|||
/*****************************************************************************
|
||||
* Copyright (c) 2014 Ted John, Peter Hill
|
||||
* OpenRCT2, an open source clone of Roller Coaster Tycoon 2.
|
||||
*
|
||||
* This file is part of OpenRCT2.
|
||||
*
|
||||
* OpenRCT2 is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
|
||||
* This program is distributed in the hope that it will be useful,
|
||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||
* GNU General Public License for more details.
|
||||
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "../localisation/string_ids.h"
|
||||
#include "../util/util.h"
|
||||
#include "colour.h"
|
||||
#include "window.h"
|
||||
#include "themes.h"
|
||||
|
||||
#define COLOURS_1(c0) 1, { { (c0), 0, 0, 0, 0, 0 } }
|
||||
#define COLOURS_2(c0, c1) 2, { { (c0), (c1), 0, 0, 0, 0 } }
|
||||
#define COLOURS_3(c0, c1, c2) 3, { { (c0), (c1), (c2), 0, 0, 0 } }
|
||||
#define COLOURS_4(c0, c1, c2, c3) 4, { { (c0), (c1), (c2), (c3), 0, 0 } }
|
||||
#define COLOURS_5(c0, c1, c2, c3, c4) 5, { { (c0), (c1), (c2), (c3), (c4), 0 } }
|
||||
#define COLOURS_6(c0, c1, c2, c3, c4, c5) 6, { { (c0), (c1), (c2), (c3), (c4), (c5) } }
|
||||
|
||||
#define THEME_DEF_END { 0xFF, { 0, 0, 0, 0, 0, 0 } }
|
||||
|
||||
#define TWINDOW(window_class, window_name, window_string_id, theme) { window_class, window_name, window_string_id, theme }
|
||||
|
||||
theme_window_definition gThemeWindowDefinitions[] = {
|
||||
/* Window Class ini section name stringid window defaults */
|
||||
{ WC_TOP_TOOLBAR, "top_toolbar", 5245, COLOURS_4(COLOUR_LIGHT_BLUE, COLOUR_DARK_GREEN, COLOUR_DARK_BROWN, COLOUR_GREY ) },
|
||||
{ WC_BOTTOM_TOOLBAR, "bottom_toolbar", 5246, COLOURS_4(TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN), COLOUR_BLACK, COLOUR_BRIGHT_GREEN ) },
|
||||
{ WC_RIDE, "ride", 5203, COLOURS_3(COLOUR_GREY, COLOUR_BORDEAUX_RED, COLOUR_GREY ) },
|
||||
{ WC_RIDE_CONSTRUCTION, "ride_construction", 5199, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
|
||||
{ WC_RIDE_LIST, "ride_list", 5204, COLOURS_3(COLOUR_GREY, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) },
|
||||
{ WC_SAVE_PROMPT, "save_prompt", 5223, COLOURS_1(TRANSLUCENT(COLOUR_BORDEAUX_RED) ) },
|
||||
{ WC_CONSTRUCT_RIDE, "new_ride", 5201, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) },
|
||||
{ WC_DEMOLISH_RIDE_PROMPT, "demolish_ride_prompt", 5224, COLOURS_1(TRANSLUCENT(COLOUR_BORDEAUX_RED) ) },
|
||||
{ WC_SCENERY, "scenery", 5197, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_GREEN, COLOUR_DARK_GREEN ) },
|
||||
{ WC_OPTIONS, "options", 5219, COLOURS_3(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) },
|
||||
{ WC_FOOTPATH, "footpath", 5198, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
|
||||
{ WC_LAND, "land", 5193, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
|
||||
{ WC_WATER, "water", 5194, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
|
||||
{ WC_PEEP, "guest", 5205, COLOURS_3(COLOUR_GREY, COLOUR_OLIVE_GREEN, COLOUR_OLIVE_GREEN ) },
|
||||
{ WC_GUEST_LIST, "guest_list", 5206, COLOURS_3(COLOUR_GREY, COLOUR_OLIVE_GREEN, COLOUR_OLIVE_GREEN ) },
|
||||
{ WC_STAFF_LIST, "staff_list", 5208, COLOURS_3(COLOUR_GREY, COLOUR_LIGHT_PURPLE, COLOUR_LIGHT_PURPLE ) },
|
||||
{ WC_FIRE_PROMPT, "staff_fire_prompt", 5225, COLOURS_1(TRANSLUCENT(COLOUR_BORDEAUX_RED) ) },
|
||||
{ WC_PARK_INFORMATION, "park_information", 5253, COLOURS_3(COLOUR_GREY, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) },
|
||||
{ WC_FINANCES, "finances", 5187, COLOURS_3(COLOUR_GREY, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) },
|
||||
{ WC_TITLE_MENU, "title_menu", 5249, COLOURS_3(TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN) ) },
|
||||
{ WC_TITLE_EXIT, "title_exit", 5250, COLOURS_3(TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN) ) },
|
||||
{ WC_RECENT_NEWS, "recent_news", 5192, COLOURS_3(COLOUR_GREY, COLOUR_GREY, COLOUR_BLACK ) },
|
||||
{ WC_SCENARIO_SELECT, "scenario_select", 5252, COLOURS_3(COLOUR_GREY, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) },
|
||||
{ WC_TRACK_DESIGN_LIST, "track_design_list", 5202, COLOURS_3(COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) },
|
||||
{ WC_TRACK_DESIGN_PLACE, "track_design_place", 5200, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
|
||||
{ WC_NEW_CAMPAIGN, "new_campaign", 5188, COLOURS_3(COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) },
|
||||
{ WC_KEYBOARD_SHORTCUT_LIST, "keyboard_shortcuts", 5220, COLOURS_3(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) },
|
||||
{ WC_CHANGE_KEYBOARD_SHORTCUT, "change_keyboard_shortcut", 5221, COLOURS_3(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) },
|
||||
{ WC_MAP, "map", 5190, COLOURS_2(COLOUR_DARK_GREEN, COLOUR_DARK_BROWN ) },
|
||||
{ WC_BANNER, "banner", 5209, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
|
||||
{ WC_EDITOR_OBJECT_SELECTION, "editor_object_selection", 5210, COLOURS_3(COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_GREY ) },
|
||||
{ WC_EDITOR_INVENTION_LIST, "editor_invention_list", 5211, COLOURS_3(COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_GREY ) },
|
||||
{ WC_EDITOR_SCENARIO_OPTIONS, "editor_scenario_options", 5212, COLOURS_3(COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_GREY ) },
|
||||
{ WC_EDTIOR_OBJECTIVE_OPTIONS, "editor_objection_options", 5213, COLOURS_3(COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_GREY ) },
|
||||
{ WC_MANAGE_TRACK_DESIGN, "manage_track_design", 5215, COLOURS_3(COLOUR_GREY, COLOUR_GREY, COLOUR_GREY ) },
|
||||
{ WC_TRACK_DELETE_PROMPT, "track_delete_prompt", 5226, COLOURS_3(COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) },
|
||||
{ WC_INSTALL_TRACK, "install_track", 5216, COLOURS_3(COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED ) },
|
||||
{ WC_CLEAR_SCENERY, "clear_scenery", 5195, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
|
||||
{ WC_CHEATS, "cheats", 5217, COLOURS_3(COLOUR_GREY, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) },
|
||||
{ WC_RESEARCH, "research", 5189, COLOURS_3(COLOUR_GREY, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) },
|
||||
{ WC_VIEWPORT, "viewport", 5191, COLOURS_3(COLOUR_DARK_BROWN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
|
||||
{ WC_MAPGEN, "map_generation", 5214, COLOURS_3(COLOUR_DARK_GREEN, COLOUR_DARK_BROWN, COLOUR_DARK_BROWN ) },
|
||||
{ WC_LOADSAVE, "loadsave", 5222, COLOURS_3(COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE, COLOUR_LIGHT_BLUE ) },
|
||||
{ WC_LOADSAVE_OVERWRITE_PROMPT, "loadsave_overwrite_prompt", 5227, COLOURS_1(TRANSLUCENT(COLOUR_BORDEAUX_RED) ) },
|
||||
{ WC_TITLE_OPTIONS, "title_options", 5251, COLOURS_3(TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN), TRANSLUCENT(COLOUR_DARK_GREEN) ) },
|
||||
{ WC_LAND_RIGHTS, "land_rights", 5196, COLOURS_3(COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW, COLOUR_DARK_YELLOW ) },
|
||||
{ WC_THEMES, "themes", 5218, COLOURS_3(COLOUR_GREY, COLOUR_DARK_GREEN, COLOUR_DARK_GREEN ) },
|
||||
{ WC_STAFF, "staff", 5207, COLOURS_3(COLOUR_GREY, COLOUR_LIGHT_PURPLE, COLOUR_LIGHT_PURPLE ) },
|
||||
{ WC_EDITOR_TRACK_BOTTOM_TOOLBAR, "editor_track_bottom_toolbar", 5247, COLOURS_3(TRANSLUCENT(COLOUR_LIGHT_BLUE), TRANSLUCENT(COLOUR_LIGHT_BLUE), TRANSLUCENT(COLOUR_LIGHT_BLUE) ) },
|
||||
{ WC_EDITOR_SCENARIO_BOTTOM_TOOLBAR, "editor_scenario_bottom_toolbar", 5248, COLOURS_3(TRANSLUCENT(COLOUR_LIGHT_BROWN), TRANSLUCENT(COLOUR_LIGHT_BROWN), TRANSLUCENT(COLOUR_MOSS_GREEN) ) },
|
||||
{ WC_TITLE_EDITOR, "title_sequences", 5433, COLOURS_3(COLOUR_GREY, COLOUR_OLIVE_GREEN, COLOUR_OLIVE_GREEN ) },
|
||||
};
|
||||
|
||||
#define COLOURS_RCT1(c0, c1, c2, c3, c4, c5) { { (c0), (c1), (c2), (c3), (c4), (c5) } }
|
||||
|
||||
theme_window_preset gThemeWindowsRCT1[] = {
|
||||
{ WC_TOP_TOOLBAR, COLOURS_RCT1(COLOUR_GREY, COLOUR_GREY, COLOUR_GREY, COLOUR_GREY, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_BOTTOM_TOOLBAR, COLOURS_RCT1(TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), COLOUR_BLACK, COLOUR_YELLOW, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_RIDE, COLOURS_RCT1(COLOUR_BORDEAUX_RED, COLOUR_GREY, COLOUR_SATURATED_GREEN, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_RIDE_LIST, COLOURS_RCT1(COLOUR_BORDEAUX_RED, COLOUR_GREY, COLOUR_GREY, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_CONSTRUCT_RIDE, COLOURS_RCT1(COLOUR_BORDEAUX_RED, COLOUR_GREY, COLOUR_GREY, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_PEEP, COLOURS_RCT1(COLOUR_LIGHT_BROWN, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_GUEST_LIST, COLOURS_RCT1(COLOUR_LIGHT_BROWN, COLOUR_BORDEAUX_RED, COLOUR_BORDEAUX_RED, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_STAFF_LIST, COLOURS_RCT1(COLOUR_DARK_GREEN, COLOUR_LIGHT_PURPLE, COLOUR_LIGHT_PURPLE, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_FINANCES, COLOURS_RCT1(COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_GREY, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_TITLE_MENU, COLOURS_RCT1(TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_TITLE_EXIT, COLOURS_RCT1(TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_NEW_CAMPAIGN, COLOURS_RCT1(COLOUR_LIGHT_PURPLE, COLOUR_LIGHT_PURPLE, COLOUR_GREY, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_TITLE_OPTIONS, COLOURS_RCT1(TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), TRANSLUCENT(COLOUR_GREY), COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
{ WC_STAFF, COLOURS_RCT1(COLOUR_DARK_GREEN, COLOUR_LIGHT_PURPLE, COLOUR_LIGHT_PURPLE, COLOUR_BLACK, COLOUR_BLACK, COLOUR_BLACK) },
|
||||
THEME_DEF_END
|
||||
};
|
||||
|
||||
uint16 gCurrentTheme = 0;
|
||||
uint32 gNumThemeWindows = sizeof(gThemeWindowDefinitions) / sizeof(theme_window_definition);
|
||||
|
||||
|
||||
theme_preset* theme_get_preset()
|
||||
{
|
||||
return &gConfigThemes.presets[gCurrentTheme];
|
||||
}
|
||||
|
||||
theme_window_definition* theme_window_definition_get_by_class(rct_windowclass classification)
|
||||
{
|
||||
for (int i = 0; i < (int)gNumThemeWindows; i++) {
|
||||
if (gThemeWindowDefinitions[i].classification == classification) {
|
||||
return &gThemeWindowDefinitions[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
theme_window* theme_window_get_by_class(rct_windowclass classification)
|
||||
{
|
||||
for (int i = 0; i < (int)gNumThemeWindows; i++) {
|
||||
if (gThemeWindowDefinitions[i].classification == classification) {
|
||||
return &gConfigThemes.presets[gCurrentTheme].windows[i];
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void colour_scheme_update(rct_window *window)
|
||||
{
|
||||
theme_window* theme = theme_window_get_by_class(window->classification);
|
||||
|
||||
bool transparent = false;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
window->colours[i] = theme->colours[i];
|
||||
if (theme->colours[i] & 0x80) {
|
||||
transparent = true;
|
||||
}
|
||||
}
|
||||
// Some windows need to be transparent even if the colours aren't.
|
||||
// There doesn't seem to be any side-effects for all windows being transparent
|
||||
window->flags |= WF_TRANSPARENT;
|
||||
}
|
||||
|
||||
void colour_scheme_update_by_class(rct_window *window, rct_windowclass classification)
|
||||
{
|
||||
theme_window* theme = theme_window_get_by_class(classification);
|
||||
|
||||
bool transparent = false;
|
||||
for (int i = 0; i < 6; i++) {
|
||||
window->colours[i] = theme->colours[i];
|
||||
if (theme->colours[i] & 0x80) {
|
||||
transparent = true;
|
||||
}
|
||||
}
|
||||
// Some windows need to be transparent even if the colours aren't.
|
||||
// There doesn't seem to be any side-effects for all windows being transparent
|
||||
window->flags |= WF_TRANSPARENT;
|
||||
}
|
||||
|
||||
static void theme_set_preset_string(const utf8string preset)
|
||||
{
|
||||
SafeFree(gConfigInterface.current_theme_preset);
|
||||
gConfigInterface.current_theme_preset = _strdup(preset);
|
||||
}
|
||||
|
||||
void theme_change_preset(int preset)
|
||||
{
|
||||
if (preset >= 0 && preset < gConfigThemes.num_presets) {
|
||||
switch (preset) {
|
||||
case 0:
|
||||
theme_set_preset_string("*RCT2");
|
||||
break;
|
||||
case 1:
|
||||
theme_set_preset_string("*RCT1");
|
||||
break;
|
||||
default:
|
||||
theme_set_preset_string(gConfigThemes.presets[preset].name);
|
||||
break;
|
||||
}
|
||||
gCurrentTheme = preset;
|
||||
}
|
||||
window_invalidate_all();
|
||||
}
|
||||
|
||||
void theme_create_preset(int duplicate, const char *name)
|
||||
{
|
||||
int preset = gConfigThemes.num_presets;
|
||||
gConfigThemes.num_presets++;
|
||||
gConfigThemes.presets = realloc(gConfigThemes.presets, sizeof(theme_preset) * gConfigThemes.num_presets);
|
||||
safe_strcpy(gConfigThemes.presets[preset].name, name, THEME_PRESET_NAME_SIZE);
|
||||
gConfigThemes.presets[preset].windows = malloc(sizeof(theme_window) * gNumThemeWindows);
|
||||
for (int i = 0; i < (int)gNumThemeWindows; i++) {
|
||||
gConfigThemes.presets[preset].windows[i] = gConfigThemes.presets[duplicate].windows[i];
|
||||
}
|
||||
gConfigThemes.presets[preset].features = gConfigThemes.presets[duplicate].features;
|
||||
themes_save_preset(preset);
|
||||
theme_change_preset(preset);
|
||||
}
|
||||
|
||||
void theme_delete_preset(int preset)
|
||||
{
|
||||
if (preset >= 2) {
|
||||
utf8 path[MAX_PATH];
|
||||
platform_get_user_directory(path, "themes");
|
||||
strcat(path, gConfigThemes.presets[preset].name);
|
||||
strcat(path, ".ini");
|
||||
platform_file_delete(path);
|
||||
|
||||
free(gConfigThemes.presets[preset].windows);
|
||||
|
||||
for (int i = preset; i < gConfigThemes.num_presets - 1; i++) {
|
||||
gConfigThemes.presets[i] = gConfigThemes.presets[i + 1];
|
||||
}
|
||||
gConfigThemes.num_presets--;
|
||||
theme_change_preset(0);
|
||||
}
|
||||
}
|
||||
|
||||
void theme_rename_preset(int preset, const char *newName)
|
||||
{
|
||||
if (preset >= 2) {
|
||||
utf8 src[MAX_PATH], dest[MAX_PATH];
|
||||
platform_get_user_directory(src, "themes");
|
||||
platform_get_user_directory(dest, "themes");
|
||||
strcat(src, gConfigThemes.presets[preset].name);
|
||||
strcat(dest, newName);
|
||||
strcat(src, ".ini");
|
||||
strcat(dest, ".ini");
|
||||
platform_file_move(src, dest);
|
||||
|
||||
safe_strcpy(gConfigThemes.presets[preset].name, newName, THEME_PRESET_NAME_SIZE);
|
||||
|
||||
if (preset == gCurrentTheme) {
|
||||
gConfigInterface.current_theme_preset = gConfigThemes.presets[preset].name;
|
||||
}
|
||||
}
|
||||
}
|
|
@ -18,47 +18,40 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#ifndef _COLOUR_SCHEMES_H_
|
||||
#define _COLOUR_SCHEMES_H_
|
||||
#ifndef _THEMES_H_
|
||||
#define _THEMES_H_
|
||||
|
||||
#include "../common.h"
|
||||
#include "window.h"
|
||||
#include "../config.h"
|
||||
|
||||
typedef struct {
|
||||
rct_windowclass classification;
|
||||
char *section_name;
|
||||
rct_string_id name;
|
||||
uint8 num_colours;
|
||||
theme_window window;
|
||||
} theme_window_definition;
|
||||
|
||||
typedef struct {
|
||||
rct_windowclass classification;
|
||||
theme_window window;
|
||||
} theme_window_preset;
|
||||
|
||||
// The definitions for window themes as well as the RCT2 preset
|
||||
extern theme_window_definition gThemeWindowDefinitions[];
|
||||
// The preset for RCT1 window themes
|
||||
extern theme_window_preset gThemeWindowsRCT1[];
|
||||
|
||||
// The index of the current theme
|
||||
extern uint16 gCurrentTheme;
|
||||
// The number of theme-able windows
|
||||
extern uint32 gNumThemeWindows;
|
||||
|
||||
theme_preset* theme_get_preset();
|
||||
theme_window_definition* theme_window_definition_get_by_class(rct_windowclass classification);
|
||||
theme_window* theme_window_get_by_class(rct_windowclass classification);
|
||||
enum {
|
||||
UITHEME_FLAG_PREDEFINED = 1 << 0,
|
||||
UITHEME_FLAG_USE_LIGHTS_RIDE = 1 << 1,
|
||||
UITHEME_FLAG_USE_LIGHTS_PARK = 1 << 2,
|
||||
UITHEME_FLAG_USE_ALTERNATIVE_SCENARIO_SELECT_FONT = 1 << 3,
|
||||
};
|
||||
|
||||
void colour_scheme_update(rct_window *window);
|
||||
void colour_scheme_update_by_class(rct_window *window, rct_windowclass classification);
|
||||
|
||||
void theme_change_preset(int preset);
|
||||
void theme_create_preset(int duplicate, const char *name);
|
||||
void theme_delete_preset(int preset);
|
||||
void theme_rename_preset(int preset, const char *newName);
|
||||
void theme_manager_initialise();
|
||||
void theme_manager_load_available_themes();
|
||||
size_t theme_manager_get_num_available_themes();
|
||||
const utf8 * theme_manager_get_available_theme_path(size_t index);
|
||||
const utf8 * theme_manager_get_available_theme_name(size_t index);
|
||||
size_t theme_manager_get_active_available_theme_index();
|
||||
void theme_manager_set_active_available_theme(size_t index);
|
||||
|
||||
colour_t theme_get_colour(rct_windowclass wc, uint8 index);
|
||||
void theme_set_colour(rct_windowclass wc, uint8 index, colour_t colour);
|
||||
uint8 theme_get_flags();
|
||||
void theme_set_flags(uint8 flags);
|
||||
void theme_save();
|
||||
void theme_rename(const utf8 * name);
|
||||
void theme_duplicate(const utf8 * name);
|
||||
void theme_delete();
|
||||
|
||||
uint8 theme_desc_get_num_colours(rct_windowclass wc);
|
||||
rct_string_id theme_desc_get_name(rct_windowclass wc);
|
||||
|
||||
#endif
|
||||
|
|
|
@ -662,8 +662,10 @@ void format_string_code(unsigned int format_code, char **dest, char **args)
|
|||
value = *((uint32*)*args);
|
||||
*args += 4;
|
||||
|
||||
strcpy(*dest, (char*)value);
|
||||
*dest += strlen(*dest);
|
||||
if (value != 0) {
|
||||
strcpy(*dest, (char*)value);
|
||||
*dest += strlen(*dest);
|
||||
}
|
||||
break;
|
||||
case FORMAT_MONTHYEAR:
|
||||
// Pop argument
|
||||
|
|
|
@ -26,6 +26,7 @@
|
|||
#include "game.h"
|
||||
#include "hook.h"
|
||||
#include "interface/chat.h"
|
||||
#include "interface/themes.h"
|
||||
#include "interface/window.h"
|
||||
#include "interface/viewport.h"
|
||||
#include "localisation/localisation.h"
|
||||
|
@ -229,8 +230,7 @@ bool openrct2_initialise()
|
|||
}
|
||||
http_init();
|
||||
|
||||
themes_set_default();
|
||||
themes_load_presets();
|
||||
theme_manager_initialise();
|
||||
title_sequences_set_default();
|
||||
title_sequences_load_presets();
|
||||
|
||||
|
|
|
@ -59,6 +59,7 @@ typedef wchar_t utf16;
|
|||
typedef utf16* utf16string;
|
||||
|
||||
typedef uint32 codepoint_t;
|
||||
typedef uint8 colour_t;
|
||||
|
||||
#define rol8(x, shift) (((uint8)(x) << (shift)) | ((uint8)(x) >> (8 - (shift))))
|
||||
#define ror8(x, shift) (((uint8)(x) >> (shift)) | ((uint8)(x) << (8 - (shift))))
|
||||
|
|
|
@ -1,14 +1,15 @@
|
|||
#include "../addresses.h"
|
||||
#include "../localisation/localisation.h"
|
||||
#include "../interface/themes.h"
|
||||
#include "../interface/widget.h"
|
||||
#include "../interface/window.h"
|
||||
#include "../interface/viewport.h"
|
||||
#include "../world/scenery.h"
|
||||
#include "../world/map.h"
|
||||
#include "../world/footpath.h"
|
||||
#include "../util/util.h"
|
||||
#include "../openrct2.h"
|
||||
#include "../platform/platform.h"
|
||||
#include "../util/util.h"
|
||||
#include "../world/footpath.h"
|
||||
#include "../world/map.h"
|
||||
#include "../world/scenery.h"
|
||||
|
||||
enum {
|
||||
WIDX_BACKGROUND,
|
||||
|
@ -105,9 +106,6 @@ rct_window *window_changelog_open()
|
|||
window->enabled_widgets = (1 << WIDX_CLOSE);
|
||||
|
||||
window_init_scroll_widgets(window);
|
||||
window->colours[0] = 7;
|
||||
window->colours[1] = 7;
|
||||
window->colours[2] = 7;
|
||||
window->min_width = MIN_WW;
|
||||
window->min_height = MIN_WH;
|
||||
window->max_width = MIN_WW;
|
||||
|
@ -157,6 +155,8 @@ static void window_changelog_scrollgetsize(rct_window *w, int scrollIndex, int *
|
|||
|
||||
static void window_changelog_invalidate(rct_window *w)
|
||||
{
|
||||
colour_scheme_update(w);
|
||||
|
||||
window_changelog_widgets[WIDX_BACKGROUND].right = w->width - 1;
|
||||
window_changelog_widgets[WIDX_BACKGROUND].bottom = w->height - 1;
|
||||
window_changelog_widgets[WIDX_TITLE].right = w->width - 2;
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
|
||||
#include "../addresses.h"
|
||||
#include "../audio/audio.h"
|
||||
#include "../config.h"
|
||||
#include "../game.h"
|
||||
#include "../interface/themes.h"
|
||||
#include "../interface/widget.h"
|
||||
|
@ -33,10 +34,10 @@
|
|||
#include "../ride/ride_data.h"
|
||||
#include "../ride/track.h"
|
||||
#include "../scenario.h"
|
||||
#include "dropdown.h"
|
||||
#include "error.h"
|
||||
#include "../util/util.h"
|
||||
#include "../world/footpath.h"
|
||||
#include "dropdown.h"
|
||||
#include "error.h"
|
||||
|
||||
enum {
|
||||
FILTER_RCT2 = (1 << 0),
|
||||
|
|
|
@ -205,9 +205,6 @@ void window_multiplayer_open()
|
|||
|
||||
window->page = WINDOW_MULTIPLAYER_PAGE_PLAYERS;
|
||||
window->list_information_type = 0;
|
||||
window->colours[0] = 7;
|
||||
window->colours[1] = 7;
|
||||
window->colours[2] = 7;
|
||||
}
|
||||
|
||||
static void window_multiplayer_set_page(rct_window* w, int page){
|
||||
|
@ -366,6 +363,8 @@ static void window_multiplayer_players_scrollmouseover(rct_window *w, int scroll
|
|||
|
||||
static void window_multiplayer_players_invalidate(rct_window *w)
|
||||
{
|
||||
colour_scheme_update(w);
|
||||
|
||||
window_multiplayer_set_pressed_tab(w);
|
||||
window_multiplayer_anchor_border_widgets(w);
|
||||
window_multiplayer_players_widgets[WIDX_LIST].right = w->width - 4;
|
||||
|
|
|
@ -106,9 +106,6 @@ void window_network_status_open(const char* text)
|
|||
|
||||
window->page = 0;
|
||||
window->list_information_type = 0;
|
||||
window->colours[0] = 7;
|
||||
window->colours[1] = 7;
|
||||
window->colours[2] = 7;
|
||||
}
|
||||
|
||||
void window_network_status_close()
|
||||
|
@ -158,6 +155,8 @@ static void window_network_status_textinput(rct_window *w, int widgetIndex, char
|
|||
|
||||
static void window_network_status_invalidate(rct_window *w)
|
||||
{
|
||||
colour_scheme_update(w);
|
||||
|
||||
window_network_status_widgets[WIDX_BACKGROUND].right = w->width - 1;
|
||||
window_network_status_widgets[WIDX_BACKGROUND].bottom = w->height - 1;
|
||||
window_network_status_widgets[WIDX_TITLE].right = w->width - 2;
|
||||
|
|
|
@ -989,16 +989,12 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
|
|||
case WINDOW_OPTIONS_PAGE_CONTROLS_AND_INTERFACE:
|
||||
switch (widgetIndex) {
|
||||
case WIDX_THEMES_DROPDOWN:
|
||||
num_items = gConfigThemes.num_presets;
|
||||
theme_manager_get_num_available_themes();
|
||||
num_items = (int)theme_manager_get_num_available_themes();
|
||||
|
||||
gDropdownItemsFormat[0] = 2777;
|
||||
gDropdownItemsArgs[0] = (uint32)&gConfigThemes.presets[1].name;
|
||||
gDropdownItemsFormat[1] = 2777;
|
||||
gDropdownItemsArgs[1] = (uint32)&gConfigThemes.presets[0].name;
|
||||
|
||||
for (i = 2; i < num_items; i++) {
|
||||
for (int i = 0; i < num_items; i++) {
|
||||
gDropdownItemsFormat[i] = 2777;
|
||||
gDropdownItemsArgs[i] = (uint32)&gConfigThemes.presets[i].name;
|
||||
gDropdownItemsArgs[i] = (uint32)theme_manager_get_available_theme_name(i);
|
||||
}
|
||||
|
||||
window_dropdown_show_text_custom_width(
|
||||
|
@ -1009,13 +1005,10 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
|
|||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
num_items,
|
||||
widget->right - widget->left - 3
|
||||
);
|
||||
);
|
||||
|
||||
if (gCurrentTheme == 0 || gCurrentTheme == 1) {
|
||||
dropdown_set_checked(gCurrentTheme ^ 1, true);
|
||||
} else {
|
||||
dropdown_set_checked(gCurrentTheme, true);
|
||||
}
|
||||
dropdown_set_checked(theme_manager_get_active_available_theme_index(), true);
|
||||
widget_invalidate(w, WIDX_THEMES_DROPDOWN);
|
||||
break;
|
||||
|
||||
case WIDX_SCENARIO_GROUPING_DROPDOWN:
|
||||
|
@ -1243,9 +1236,7 @@ static void window_options_dropdown(rct_window *w, int widgetIndex, int dropdown
|
|||
switch (widgetIndex) {
|
||||
case WIDX_THEMES_DROPDOWN:
|
||||
if (dropdownIndex != -1) {
|
||||
if (dropdownIndex == 0 || dropdownIndex == 1)
|
||||
dropdownIndex ^= 1;
|
||||
theme_change_preset(dropdownIndex);
|
||||
theme_manager_set_active_available_theme(dropdownIndex);
|
||||
}
|
||||
config_save_default();
|
||||
break;
|
||||
|
@ -1642,7 +1633,11 @@ static void window_options_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|||
break;
|
||||
case WINDOW_OPTIONS_PAGE_CONTROLS_AND_INTERFACE:
|
||||
gfx_draw_string_left(dpi, STR_SHOW_TOOLBAR_BUTTONS_FOR, w, w->colours[1], w->x + 10, w->y + window_options_controls_and_interface_widgets[WIDX_TOOLBAR_BUTTONS_GROUP].top + 15);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 0, uint32) = (uint32)&gConfigThemes.presets[gCurrentTheme].name;
|
||||
|
||||
int activeAvailableThemeIndex = theme_manager_get_active_available_theme_index();
|
||||
const utf8 * activeThemeName = theme_manager_get_available_theme_name(activeAvailableThemeIndex);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 0, uint32) = (uint32)activeThemeName;
|
||||
|
||||
gfx_draw_string_left(dpi, 5238, NULL, w->colours[1], w->x + 10, w->y + window_options_controls_and_interface_widgets[WIDX_THEMES].top + 1);
|
||||
gfx_draw_string_left_clipped(
|
||||
dpi,
|
||||
|
|
|
@ -979,7 +979,7 @@ static void window_park_entrance_invalidate(rct_window *w)
|
|||
window_park_entrance_widgets[WIDX_STATUS].top = w->height - 13;
|
||||
window_park_entrance_widgets[WIDX_STATUS].bottom = w->height - 3;
|
||||
|
||||
if (theme_get_preset()->features.rct1_park_lights) {
|
||||
if (theme_get_flags() & UITHEME_FLAG_USE_LIGHTS_PARK) {
|
||||
window_park_entrance_widgets[WIDX_OPEN_OR_CLOSE].type = WWT_EMPTY;
|
||||
if (RCT2_GLOBAL(RCT2_ADDRESS_OBJECTIVE_TYPE, uint8) == OBJECTIVE_GUESTS_AND_RATING) {
|
||||
window_park_entrance_widgets[WIDX_CLOSE_LIGHT].type = WWT_FLATBTN;
|
||||
|
|
|
@ -376,9 +376,7 @@ void window_player_overview_invalidate(rct_window *w)
|
|||
window_init_scroll_widgets(w);
|
||||
}
|
||||
|
||||
w->colours[0] = 7;
|
||||
w->colours[1] = 7;
|
||||
w->colours[2] = 7;
|
||||
colour_scheme_update(w);
|
||||
|
||||
w->pressed_widgets &= ~(WIDX_TAB_1);
|
||||
w->pressed_widgets |= 1ULL << (w->page + WIDX_TAB_1);
|
||||
|
|
|
@ -1696,7 +1696,7 @@ static void window_ride_main_resize(rct_window *w)
|
|||
|
||||
w->flags |= WF_RESIZABLE;
|
||||
int minHeight = 180;
|
||||
if (theme_get_preset()->features.rct1_ride_lights)
|
||||
if (theme_get_flags() & UITHEME_FLAG_USE_LIGHTS_RIDE)
|
||||
minHeight = 200 + RCT1_LIGHT_OFFSET - (ride_type_has_flag(get_ride(w->number)->type, RIDE_TYPE_FLAG_NO_TEST_MODE) ? 14 : 0);
|
||||
window_set_resize(w, 316, minHeight, 500, 450);
|
||||
|
||||
|
@ -2037,7 +2037,7 @@ static void window_ride_main_invalidate(rct_window *w)
|
|||
|
||||
window_align_tabs(w, WIDX_TAB_1, WIDX_TAB_10);
|
||||
|
||||
if (theme_get_preset()->features.rct1_ride_lights) {
|
||||
if (theme_get_flags() & UITHEME_FLAG_USE_LIGHTS_RIDE) {
|
||||
window_ride_main_widgets[WIDX_OPEN].type = WWT_EMPTY;
|
||||
window_ride_main_widgets[WIDX_CLOSE_LIGHT].type = WWT_IMGBTN;
|
||||
window_ride_main_widgets[WIDX_TEST_LIGHT].type = (ride_type_has_flag(ride->type, RIDE_TYPE_FLAG_NO_TEST_MODE) ? WWT_EMPTY : WWT_IMGBTN);
|
||||
|
|
|
@ -21,6 +21,7 @@
|
|||
#include "../addresses.h"
|
||||
#include "../audio/audio.h"
|
||||
#include "../cheats.h"
|
||||
#include "../config.h"
|
||||
#include "../drawing/drawing.h"
|
||||
#include "../game.h"
|
||||
#include "../input.h"
|
||||
|
|
|
@ -403,7 +403,7 @@ static void window_ride_list_invalidate(rct_window *w)
|
|||
w->widgets[WIDX_OPEN_LIGHT].right = w->width - 7;
|
||||
w->widgets[WIDX_OPEN_LIGHT].left = w->width - 20;
|
||||
|
||||
if (theme_get_preset()->features.rct1_ride_lights) {
|
||||
if (theme_get_flags() & UITHEME_FLAG_USE_LIGHTS_RIDE) {
|
||||
w->widgets[WIDX_OPEN_CLOSE_ALL].type = WWT_EMPTY;
|
||||
w->widgets[WIDX_CLOSE_LIGHT].type = WWT_IMGBTN;
|
||||
w->widgets[WIDX_OPEN_LIGHT].type = WWT_IMGBTN;
|
||||
|
|
|
@ -18,6 +18,7 @@
|
|||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*****************************************************************************/
|
||||
|
||||
#include "../config.h"
|
||||
#include "../interface/colour.h"
|
||||
#include "../interface/themes.h"
|
||||
#include "../interface/widget.h"
|
||||
|
@ -366,6 +367,8 @@ static void window_server_list_textinput(rct_window *w, int widgetIndex, char *t
|
|||
|
||||
static void window_server_list_invalidate(rct_window *w)
|
||||
{
|
||||
colour_scheme_update(w);
|
||||
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS, char *) = gVersion;
|
||||
window_server_list_widgets[WIDX_BACKGROUND].right = w->width - 1;
|
||||
window_server_list_widgets[WIDX_BACKGROUND].bottom = w->height - 1;
|
||||
|
|
|
@ -136,9 +136,6 @@ void window_server_start_open()
|
|||
|
||||
window->page = 0;
|
||||
window->list_information_type = 0;
|
||||
window->colours[0] = 1;
|
||||
window->colours[1] = 26;
|
||||
window->colours[2] = 26;
|
||||
|
||||
sprintf(_port, "%u", gConfigNetwork.default_port);
|
||||
safe_strcpy(_name, gConfigNetwork.server_name, sizeof(_name));
|
||||
|
@ -251,6 +248,8 @@ static void window_server_start_textinput(rct_window *w, int widgetIndex, char *
|
|||
|
||||
static void window_server_start_invalidate(rct_window *w)
|
||||
{
|
||||
colour_scheme_update_by_class(w, WC_SERVER_LIST);
|
||||
|
||||
widget_set_checkbox_value(w, WIDX_ADVERTISE_CHECKBOX, gConfigNetwork.advertise);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 18, uint16) = gConfigNetwork.maxplayers;
|
||||
}
|
||||
|
|
|
@ -238,12 +238,17 @@ static rct_windowclass window_themes_tab_5_classes[] = {
|
|||
|
||||
static rct_windowclass window_themes_tab_6_classes[] = {
|
||||
WC_CHEATS,
|
||||
WC_TILE_INSPECTOR,
|
||||
WC_THEMES,
|
||||
WC_TITLE_EDITOR,
|
||||
WC_OPTIONS,
|
||||
WC_KEYBOARD_SHORTCUT_LIST,
|
||||
WC_CHANGE_KEYBOARD_SHORTCUT,
|
||||
WC_LOADSAVE
|
||||
WC_LOADSAVE,
|
||||
WC_CHANGELOG,
|
||||
WC_SERVER_LIST,
|
||||
WC_MULTIPLAYER,
|
||||
WC_PLAYER,
|
||||
};
|
||||
|
||||
static rct_windowclass window_themes_tab_7_classes[] = {
|
||||
|
@ -251,7 +256,19 @@ static rct_windowclass window_themes_tab_7_classes[] = {
|
|||
WC_DEMOLISH_RIDE_PROMPT,
|
||||
WC_FIRE_PROMPT,
|
||||
WC_TRACK_DELETE_PROMPT,
|
||||
WC_LOADSAVE_OVERWRITE_PROMPT
|
||||
WC_LOADSAVE_OVERWRITE_PROMPT,
|
||||
WC_NETWORK_STATUS,
|
||||
};
|
||||
|
||||
static rct_windowclass *window_themes_tab_classes[] = {
|
||||
NULL,
|
||||
window_themes_tab_1_classes,
|
||||
window_themes_tab_2_classes,
|
||||
window_themes_tab_3_classes,
|
||||
window_themes_tab_4_classes,
|
||||
window_themes_tab_5_classes,
|
||||
window_themes_tab_6_classes,
|
||||
window_themes_tab_7_classes,
|
||||
};
|
||||
|
||||
static uint8 _selected_tab = 0;
|
||||
|
@ -267,57 +284,10 @@ void window_themes_init_vars()
|
|||
_selected_tab = WINDOW_THEMES_TAB_SETTINGS;
|
||||
}
|
||||
|
||||
static theme_window_definition* get_colour_scheme_tab_definition()
|
||||
static rct_windowclass get_window_class_tab_index(int index)
|
||||
{
|
||||
switch (_selected_tab) {
|
||||
case 1: return theme_window_definition_get_by_class(window_themes_tab_1_classes[_color_index_1]);
|
||||
case 2: return theme_window_definition_get_by_class(window_themes_tab_2_classes[_color_index_1]);
|
||||
case 3: return theme_window_definition_get_by_class(window_themes_tab_3_classes[_color_index_1]);
|
||||
case 4: return theme_window_definition_get_by_class(window_themes_tab_4_classes[_color_index_1]);
|
||||
case 5: return theme_window_definition_get_by_class(window_themes_tab_5_classes[_color_index_1]);
|
||||
case 6: return theme_window_definition_get_by_class(window_themes_tab_6_classes[_color_index_1]);
|
||||
case 7: return theme_window_definition_get_by_class(window_themes_tab_7_classes[_color_index_1]);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
static theme_window_definition* get_colour_scheme_tab_definition_by_index(int index)
|
||||
{
|
||||
switch (_selected_tab) {
|
||||
case 1: return theme_window_definition_get_by_class(window_themes_tab_1_classes[index]);
|
||||
case 2: return theme_window_definition_get_by_class(window_themes_tab_2_classes[index]);
|
||||
case 3: return theme_window_definition_get_by_class(window_themes_tab_3_classes[index]);
|
||||
case 4: return theme_window_definition_get_by_class(window_themes_tab_4_classes[index]);
|
||||
case 5: return theme_window_definition_get_by_class(window_themes_tab_5_classes[index]);
|
||||
case 6: return theme_window_definition_get_by_class(window_themes_tab_6_classes[index]);
|
||||
case 7: return theme_window_definition_get_by_class(window_themes_tab_7_classes[index]);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
static theme_window* get_colour_scheme_tab()
|
||||
{
|
||||
switch (_selected_tab) {
|
||||
case 1: return theme_window_get_by_class(window_themes_tab_1_classes[_color_index_1]);
|
||||
case 2: return theme_window_get_by_class(window_themes_tab_2_classes[_color_index_1]);
|
||||
case 3: return theme_window_get_by_class(window_themes_tab_3_classes[_color_index_1]);
|
||||
case 4: return theme_window_get_by_class(window_themes_tab_4_classes[_color_index_1]);
|
||||
case 5: return theme_window_get_by_class(window_themes_tab_5_classes[_color_index_1]);
|
||||
case 6: return theme_window_get_by_class(window_themes_tab_6_classes[_color_index_1]);
|
||||
case 7: return theme_window_get_by_class(window_themes_tab_7_classes[_color_index_1]);
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
static theme_window* get_colour_scheme_tab_by_index(int index)
|
||||
{
|
||||
switch (_selected_tab) {
|
||||
case 1: return theme_window_get_by_class(window_themes_tab_1_classes[index]);
|
||||
case 2: return theme_window_get_by_class(window_themes_tab_2_classes[index]);
|
||||
case 3: return theme_window_get_by_class(window_themes_tab_3_classes[index]);
|
||||
case 4: return theme_window_get_by_class(window_themes_tab_4_classes[index]);
|
||||
case 5: return theme_window_get_by_class(window_themes_tab_5_classes[index]);
|
||||
case 6: return theme_window_get_by_class(window_themes_tab_6_classes[index]);
|
||||
case 7: return theme_window_get_by_class(window_themes_tab_7_classes[index]);
|
||||
}
|
||||
return NULL;
|
||||
rct_windowclass * classes = window_themes_tab_classes[_selected_tab];
|
||||
return classes[index];
|
||||
}
|
||||
|
||||
static int get_colour_scheme_tab_count()
|
||||
|
@ -334,19 +304,6 @@ static int get_colour_scheme_tab_count()
|
|||
return 0;
|
||||
}
|
||||
|
||||
/*static int get_colour_scheme_index() {
|
||||
switch (_selected_tab) {
|
||||
case 1: return theme_window_get_index_by_class(window_themes_tab_1_classes[_color_index_1]);
|
||||
case 2: return theme_window_get_index_by_class(window_themes_tab_2_classes[_color_index_1]);
|
||||
case 3: return theme_window_get_index_by_class(window_themes_tab_3_classes[_color_index_1]);
|
||||
case 4: return theme_window_get_index_by_class(window_themes_tab_4_classes[_color_index_1]);
|
||||
case 5: return theme_window_get_index_by_class(window_themes_tab_5_classes[_color_index_1]);
|
||||
case 6: return theme_window_get_index_by_class(window_themes_tab_6_classes[_color_index_1]);
|
||||
case 7: return theme_window_get_index_by_class(window_themes_tab_7_classes[_color_index_1]);
|
||||
}
|
||||
return -1;
|
||||
}*/
|
||||
|
||||
static void window_themes_draw_tab_images(rct_drawpixelinfo *dpi, rct_window *w)
|
||||
{
|
||||
int sprite_idx;
|
||||
|
@ -405,27 +362,32 @@ void window_themes_open()
|
|||
|
||||
static void window_themes_mouseup(rct_window *w, int widgetIndex)
|
||||
{
|
||||
int activeAvailableThemeIndex;
|
||||
const utf8 * activeThemeName;
|
||||
|
||||
switch (widgetIndex) {
|
||||
case WIDX_THEMES_CLOSE:
|
||||
window_close(w);
|
||||
break;
|
||||
case WIDX_THEMES_DUPLICATE_BUTTON:
|
||||
window_text_input_open(w, widgetIndex, 5239, 5240, 1170, (uint32)&gConfigThemes.presets[gCurrentTheme].name, 64);
|
||||
case WIDX_THEMES_DUPLICATE_BUTTON:;
|
||||
activeAvailableThemeIndex = theme_manager_get_active_available_theme_index();
|
||||
activeThemeName = theme_manager_get_available_theme_name(activeAvailableThemeIndex);
|
||||
window_text_input_open(w, widgetIndex, 5239, 5240, 1170, (uint32)activeThemeName, 64);
|
||||
break;
|
||||
case WIDX_THEMES_DELETE_BUTTON:
|
||||
if (gCurrentTheme >= 2) {
|
||||
theme_delete_preset(gCurrentTheme);
|
||||
}
|
||||
else {
|
||||
if (theme_get_flags() & UITHEME_FLAG_PREDEFINED) {
|
||||
window_error_open(5241, STR_NONE);
|
||||
} else {
|
||||
theme_delete();
|
||||
}
|
||||
break;
|
||||
case WIDX_THEMES_RENAME_BUTTON:
|
||||
if (gCurrentTheme >= 2) {
|
||||
window_text_input_open(w, widgetIndex, 3348, 5240, 1170, (uint32)&gConfigThemes.presets[gCurrentTheme].name, 64);
|
||||
}
|
||||
else {
|
||||
if (theme_get_flags() & UITHEME_FLAG_PREDEFINED) {
|
||||
window_error_open(5241, STR_NONE);
|
||||
} else {
|
||||
activeAvailableThemeIndex = theme_manager_get_active_available_theme_index();
|
||||
activeThemeName = theme_manager_get_available_theme_name(activeAvailableThemeIndex);
|
||||
window_text_input_open(w, widgetIndex, 3348, 5240, 1170, (uint32)activeThemeName, 64);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -507,7 +469,7 @@ static void window_themes_resize(rct_window *w)
|
|||
static void window_themes_mousedown(int widgetIndex, rct_window* w, rct_widget* widget)
|
||||
{
|
||||
short newSelectedTab;
|
||||
int num_items, i;
|
||||
int num_items;
|
||||
|
||||
switch (widgetIndex) {
|
||||
case WIDX_THEMES_SETTINGS_TAB:
|
||||
|
@ -529,19 +491,15 @@ static void window_themes_mousedown(int widgetIndex, rct_window* w, rct_widget*
|
|||
window_invalidate(w);
|
||||
break;
|
||||
case WIDX_THEMES_PRESETS_DROPDOWN:
|
||||
num_items = gConfigThemes.num_presets;
|
||||
theme_manager_load_available_themes();
|
||||
num_items = (int)theme_manager_get_num_available_themes();
|
||||
|
||||
widget--;
|
||||
gDropdownItemsFormat[0] = 2777;
|
||||
gDropdownItemsArgs[0] = (uint32)&gConfigThemes.presets[1].name;
|
||||
gDropdownItemsFormat[1] = 2777;
|
||||
gDropdownItemsArgs[1] = (uint32)&gConfigThemes.presets[0].name;
|
||||
|
||||
for (i = 2; i < num_items; i++) {
|
||||
for (int i = 0; i < num_items; i++) {
|
||||
gDropdownItemsFormat[i] = 2777;
|
||||
gDropdownItemsArgs[i] = (uint32)&gConfigThemes.presets[i].name;
|
||||
gDropdownItemsArgs[i] = (uint32)theme_manager_get_available_theme_name(i);
|
||||
}
|
||||
|
||||
|
||||
window_dropdown_show_text_custom_width(
|
||||
w->x + widget->left,
|
||||
w->y + widget->top,
|
||||
|
@ -550,42 +508,35 @@ static void window_themes_mousedown(int widgetIndex, rct_window* w, rct_widget*
|
|||
DROPDOWN_FLAG_STAY_OPEN,
|
||||
num_items,
|
||||
widget->right - widget->left - 3
|
||||
);
|
||||
);
|
||||
|
||||
if (gCurrentTheme == 0 || gCurrentTheme == 1) {
|
||||
dropdown_set_checked(gCurrentTheme ^ 1, true);
|
||||
} else {
|
||||
dropdown_set_checked(gCurrentTheme, true);
|
||||
}
|
||||
dropdown_set_checked(theme_manager_get_active_available_theme_index(), true);
|
||||
break;
|
||||
case WIDX_THEMES_RCT1_RIDE_LIGHTS:
|
||||
if (gCurrentTheme >= 2) {
|
||||
theme_get_preset()->features.rct1_ride_lights ^= 1;
|
||||
themes_save_preset(gCurrentTheme);
|
||||
window_invalidate_all();
|
||||
}
|
||||
else {
|
||||
if (theme_get_flags() & UITHEME_FLAG_PREDEFINED) {
|
||||
window_error_open(5241, STR_NONE);
|
||||
} else {
|
||||
theme_set_flags(theme_get_flags() ^ UITHEME_FLAG_USE_LIGHTS_RIDE);
|
||||
theme_save();
|
||||
window_invalidate_all();
|
||||
}
|
||||
break;
|
||||
case WIDX_THEMES_RCT1_PARK_LIGHTS:
|
||||
if (gCurrentTheme >= 2) {
|
||||
theme_get_preset()->features.rct1_park_lights ^= 1;
|
||||
themes_save_preset(gCurrentTheme);
|
||||
window_invalidate_all();
|
||||
}
|
||||
else {
|
||||
if (theme_get_flags() & UITHEME_FLAG_PREDEFINED) {
|
||||
window_error_open(5241, STR_NONE);
|
||||
} else {
|
||||
theme_set_flags(theme_get_flags() ^ UITHEME_FLAG_USE_LIGHTS_PARK);
|
||||
theme_save();
|
||||
window_invalidate_all();
|
||||
}
|
||||
break;
|
||||
case WIDX_THEMES_RCT1_SCENARIO_FONT:
|
||||
if (gCurrentTheme >= 2) {
|
||||
theme_get_preset()->features.rct1_scenario_font ^= 1;
|
||||
themes_save_preset(gCurrentTheme);
|
||||
window_invalidate_all();
|
||||
}
|
||||
else {
|
||||
if (theme_get_flags() & UITHEME_FLAG_PREDEFINED) {
|
||||
window_error_open(5241, STR_NONE);
|
||||
} else {
|
||||
theme_set_flags(theme_get_flags() ^ UITHEME_FLAG_USE_ALTERNATIVE_SCENARIO_SELECT_FONT);
|
||||
theme_save();
|
||||
window_invalidate_all();
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
@ -596,22 +547,22 @@ static void window_themes_dropdown(rct_window *w, int widgetIndex, int dropdownI
|
|||
switch (widgetIndex) {
|
||||
case WIDX_THEMES_LIST:
|
||||
if (dropdownIndex != -1) {
|
||||
get_colour_scheme_tab()->colours[_color_index_2] = dropdownIndex | (get_colour_scheme_tab()->colours[_color_index_2] & 0x80);
|
||||
rct_windowclass wc = get_window_class_tab_index(_color_index_1);
|
||||
uint8 colour = theme_get_colour(wc, _color_index_2);
|
||||
colour = (colour & COLOUR_FLAG_TRANSLUCENT) | dropdownIndex;
|
||||
theme_set_colour(wc, _color_index_2, colour);
|
||||
window_invalidate_all();
|
||||
_color_index_1 = -1;
|
||||
_color_index_2 = -1;
|
||||
|
||||
if (gCurrentTheme >= 2)
|
||||
themes_save_preset(gCurrentTheme);
|
||||
// if (gCurrentTheme >= 2)
|
||||
// themes_save_preset(gCurrentTheme);
|
||||
}
|
||||
break;
|
||||
case WIDX_THEMES_PRESETS_DROPDOWN:
|
||||
if (dropdownIndex != -1) {
|
||||
if (dropdownIndex == 0 || dropdownIndex == 1)
|
||||
dropdownIndex ^= 1;
|
||||
theme_change_preset(dropdownIndex);
|
||||
theme_manager_set_active_available_theme(dropdownIndex);
|
||||
}
|
||||
config_save_default();
|
||||
break;
|
||||
}
|
||||
|
||||
|
@ -651,33 +602,36 @@ void window_themes_scrollmousedown(rct_window *w, int scrollIndex, int x, int y)
|
|||
int y2 = y % _row_height;
|
||||
_color_index_1 = y / _row_height;
|
||||
_color_index_2 = ((x - _button_offset_x) / 12);
|
||||
if (_color_index_2 < get_colour_scheme_tab_definition()->num_colours) {
|
||||
|
||||
rct_windowclass wc = get_window_class_tab_index(_color_index_1);
|
||||
int numColours = theme_desc_get_num_colours(wc);
|
||||
if (_color_index_2 < numColours) {
|
||||
if (x >= _button_offset_x && x < _button_offset_x + 12 * 6 && y2 >= _button_offset_y && y2 < _button_offset_y + 11) {
|
||||
if (gCurrentTheme >= 2) {
|
||||
if (theme_get_flags() & UITHEME_FLAG_PREDEFINED) {
|
||||
window_error_open(5241, 5256);
|
||||
} else {
|
||||
window_themes_widgets[WIDX_THEMES_COLORBTN_MASK].left = _button_offset_x + _color_index_2 * 12 + window_themes_widgets[WIDX_THEMES_LIST].left;
|
||||
window_themes_widgets[WIDX_THEMES_COLORBTN_MASK].top = _color_index_1 * _row_height + _button_offset_y - w->scrolls[0].v_top + window_themes_widgets[WIDX_THEMES_LIST].top;
|
||||
window_themes_widgets[WIDX_THEMES_COLORBTN_MASK].right = window_themes_widgets[WIDX_THEMES_COLORBTN_MASK].left + 12;
|
||||
window_themes_widgets[WIDX_THEMES_COLORBTN_MASK].bottom = window_themes_widgets[WIDX_THEMES_COLORBTN_MASK].top + 12;
|
||||
window_dropdown_show_colour(w, &(window_themes_widgets[WIDX_THEMES_COLORBTN_MASK]), w->colours[1], get_colour_scheme_tab()->colours[_color_index_2]);
|
||||
|
||||
uint8 colour = theme_get_colour(wc, _color_index_2);
|
||||
window_dropdown_show_colour(w, &(window_themes_widgets[WIDX_THEMES_COLORBTN_MASK]), w->colours[1], colour);
|
||||
widget_invalidate(w, WIDX_THEMES_LIST);
|
||||
}
|
||||
else {
|
||||
window_error_open(5241, 5256);
|
||||
}
|
||||
}
|
||||
else if (x >= _button_offset_x && x < _button_offset_x + 12 * 6 - 1 && y2 >= _check_offset_y && y2 < _check_offset_y + 11) {
|
||||
if (gCurrentTheme >= 2) {
|
||||
if (get_colour_scheme_tab()->colours[_color_index_2] & 0x80) {
|
||||
get_colour_scheme_tab()->colours[_color_index_2] &= 0x7F;
|
||||
}
|
||||
else {
|
||||
get_colour_scheme_tab()->colours[_color_index_2] |= 0x80;
|
||||
}
|
||||
themes_save_preset(gCurrentTheme);
|
||||
window_invalidate_all();
|
||||
}
|
||||
else {
|
||||
if (theme_get_flags() & UITHEME_FLAG_PREDEFINED) {
|
||||
window_error_open(5241, 5256);
|
||||
} else {
|
||||
uint8 colour = theme_get_colour(wc, _color_index_2);
|
||||
if (colour & COLOUR_FLAG_TRANSLUCENT) {
|
||||
colour &= ~COLOUR_FLAG_TRANSLUCENT;
|
||||
} else {
|
||||
colour |= COLOUR_FLAG_TRANSLUCENT;
|
||||
}
|
||||
theme_set_colour(wc, _color_index_2, colour);
|
||||
window_invalidate_all();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -700,25 +654,26 @@ static void window_themes_textinput(rct_window *w, int widgetIndex, char *text)
|
|||
case WIDX_THEMES_RENAME_BUTTON:
|
||||
if (filename_valid_characters(text)) {
|
||||
bool nameTaken = false;
|
||||
for (int i = 0; i < gConfigThemes.num_presets; i++) {
|
||||
if (strcmp(gConfigThemes.presets[i].name, text) == 0) {
|
||||
window_error_open(5242, STR_NONE);
|
||||
int numAvailableThemes = (int)theme_manager_get_num_available_themes();
|
||||
for (int i = 0; i < numAvailableThemes; i++) {
|
||||
const utf8 * themeName = theme_manager_get_available_theme_name(i);
|
||||
if (strcmp(themeName, text) == 0) {
|
||||
if (widgetIndex != WIDX_THEMES_RENAME_BUTTON) {
|
||||
window_error_open(5242, STR_NONE);
|
||||
}
|
||||
nameTaken = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!nameTaken) {
|
||||
if (widgetIndex == WIDX_THEMES_DUPLICATE_BUTTON) {
|
||||
theme_create_preset(gCurrentTheme, text);
|
||||
theme_duplicate(text);
|
||||
} else {
|
||||
theme_rename(text);
|
||||
}
|
||||
else {
|
||||
theme_rename_preset(gCurrentTheme, text);
|
||||
}
|
||||
config_save_default();
|
||||
window_invalidate(w);
|
||||
}
|
||||
}
|
||||
else {
|
||||
} else {
|
||||
window_error_open(5243, STR_NONE);
|
||||
}
|
||||
break;
|
||||
|
@ -787,9 +742,9 @@ void window_themes_invalidate(rct_window *w)
|
|||
window_themes_widgets[WIDX_THEMES_PRESETS].type = WWT_EMPTY;
|
||||
window_themes_widgets[WIDX_THEMES_PRESETS_DROPDOWN].type = WWT_EMPTY;
|
||||
|
||||
widget_set_checkbox_value(w, WIDX_THEMES_RCT1_RIDE_LIGHTS, theme_get_preset()->features.rct1_ride_lights);
|
||||
widget_set_checkbox_value(w, WIDX_THEMES_RCT1_PARK_LIGHTS, theme_get_preset()->features.rct1_park_lights);
|
||||
widget_set_checkbox_value(w, WIDX_THEMES_RCT1_SCENARIO_FONT, theme_get_preset()->features.rct1_scenario_font);
|
||||
widget_set_checkbox_value(w, WIDX_THEMES_RCT1_RIDE_LIGHTS, theme_get_flags() & UITHEME_FLAG_USE_LIGHTS_RIDE);
|
||||
widget_set_checkbox_value(w, WIDX_THEMES_RCT1_PARK_LIGHTS, theme_get_flags() & UITHEME_FLAG_USE_LIGHTS_PARK);
|
||||
widget_set_checkbox_value(w, WIDX_THEMES_RCT1_SCENARIO_FONT, theme_get_flags() & UITHEME_FLAG_USE_ALTERNATIVE_SCENARIO_SELECT_FONT);
|
||||
}
|
||||
else {
|
||||
window_themes_widgets[WIDX_THEMES_LIST].type = WWT_SCROLL;
|
||||
|
@ -811,7 +766,9 @@ void window_themes_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|||
window_themes_draw_tab_images(dpi, w);
|
||||
|
||||
if (_selected_tab == WINDOW_THEMES_TAB_SETTINGS) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 0, uint32) = (uint32)&gConfigThemes.presets[gCurrentTheme].name;
|
||||
int activeAvailableThemeIndex = theme_manager_get_active_available_theme_index();
|
||||
const utf8 * activeThemeName = theme_manager_get_available_theme_name(activeAvailableThemeIndex);
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_COMMON_FORMAT_ARGS + 0, uint32) = (uint32)activeThemeName;
|
||||
gfx_draw_string_left(dpi, 5238, NULL, w->colours[1], w->x + 10, w->y + window_themes_widgets[WIDX_THEMES_PRESETS].top + 1);
|
||||
gfx_draw_string_left_clipped(
|
||||
dpi,
|
||||
|
@ -821,7 +778,7 @@ void window_themes_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|||
w->x + window_themes_widgets[WIDX_THEMES_PRESETS].left + 1,
|
||||
w->y + window_themes_widgets[WIDX_THEMES_PRESETS].top,
|
||||
w->x + window_themes_widgets[WIDX_THEMES_PRESETS_DROPDOWN].left - window_themes_widgets[WIDX_THEMES_PRESETS].left - 4
|
||||
);
|
||||
);
|
||||
}
|
||||
else if (_selected_tab == WINDOW_THEMES_TAB_FEATURES) {
|
||||
|
||||
|
@ -869,18 +826,20 @@ void window_themes_scrollpaint(rct_window *w, rct_drawpixelinfo *dpi, int scroll
|
|||
}
|
||||
}
|
||||
|
||||
for (int j = 0; j < get_colour_scheme_tab_definition_by_index(i)->num_colours; j++) {
|
||||
rct_windowclass wc = get_window_class_tab_index(i);
|
||||
int numColours = theme_desc_get_num_colours(wc);
|
||||
for (uint8 j = 0; j < numColours; j++) {
|
||||
gfx_draw_string_left(dpi, theme_desc_get_name(wc), NULL, w->colours[1], 2, y + 4);
|
||||
|
||||
gfx_draw_string_left(dpi, get_colour_scheme_tab_definition_by_index(i)->name, NULL, w->colours[1], 2, y + 4);
|
||||
|
||||
uint32 image = ((get_colour_scheme_tab_by_index(i)->colours[j] & 0x7F) << 19) + 0x600013C3;
|
||||
uint8 colour = theme_get_colour(wc, j);
|
||||
uint32 image = ((colour & ~COLOUR_FLAG_TRANSLUCENT) << 19) + 0x600013C3;
|
||||
if (i == _color_index_1 && j == _color_index_2) {
|
||||
image = ((get_colour_scheme_tab_by_index(i)->colours[j] & 0x7F) << 19) + 0x600013C4;
|
||||
image = ((colour & ~COLOUR_FLAG_TRANSLUCENT) << 19) + 0x600013C4;
|
||||
}
|
||||
gfx_draw_sprite(dpi, image, _button_offset_x + 12 * j, y + _button_offset_y, 0);
|
||||
|
||||
gfx_fill_rect_inset(dpi, _button_offset_x + 12 * j, y + _check_offset_y, _button_offset_x + 12 * j + 9, y + _check_offset_y + 10, w->colours[1], 0xE0);
|
||||
if (get_colour_scheme_tab_by_index(i)->colours[j] & 0x80) {
|
||||
if (colour & COLOUR_FLAG_TRANSLUCENT) {
|
||||
RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_FONT_SPRITE_BASE, sint16) = -1;
|
||||
gfx_draw_string(dpi, (char*)CheckBoxMarkString, w->colours[1] & 0x7F, _button_offset_x + 12 * j, y + _check_offset_y);
|
||||
}
|
||||
|
|
|
@ -20,6 +20,7 @@
|
|||
|
||||
#include "../addresses.h"
|
||||
#include "../localisation/localisation.h"
|
||||
#include "../interface/themes.h"
|
||||
#include "../interface/widget.h"
|
||||
#include "../interface/window.h"
|
||||
#include "../interface/viewport.h"
|
||||
|
@ -170,9 +171,6 @@ void window_tile_inspector_open()
|
|||
window->disabled_widgets = (1 << WIDX_CORRUPT) | (1 << WIDX_MOVE_UP) | (1 << WIDX_MOVE_DOWN) | (1 << WIDX_REMOVE);
|
||||
|
||||
window_init_scroll_widgets(window);
|
||||
window->colours[0] = 7;
|
||||
window->colours[1] = 7;
|
||||
window->colours[2] = 7;
|
||||
window->min_width = MIN_WW;
|
||||
window->min_height = MIN_WH;
|
||||
window->max_width = MAX_WW;
|
||||
|
@ -433,6 +431,8 @@ static void window_tile_inspector_scrollmouseover(rct_window *w, int scrollIndex
|
|||
|
||||
static void window_tile_inspector_invalidate(rct_window *w)
|
||||
{
|
||||
colour_scheme_update(w);
|
||||
|
||||
window_tile_inspector_widgets[WIDX_BACKGROUND].right = w->width - 1;
|
||||
window_tile_inspector_widgets[WIDX_BACKGROUND].bottom = w->height - 1;
|
||||
window_tile_inspector_widgets[WIDX_CLOSE].left = w->width - 13;
|
||||
|
|
|
@ -351,7 +351,7 @@ static void window_scenarioselect_paint(rct_window *w, rct_drawpixelinfo *dpi)
|
|||
|
||||
window_draw_widgets(w, dpi);
|
||||
|
||||
format = (theme_get_preset()->features.rct1_scenario_font) ? 5138 : 1193;
|
||||
format = (theme_get_flags() & UITHEME_FLAG_USE_ALTERNATIVE_SCENARIO_SELECT_FONT) ? 5138 : 1193;
|
||||
|
||||
// Text for each tab
|
||||
for (i = 0; i < 8; i++) {
|
||||
|
@ -426,8 +426,8 @@ static void window_scenarioselect_scrollpaint(rct_window *w, rct_drawpixelinfo *
|
|||
colour = (colour << 24) | (colour << 16) | (colour << 8) | colour;
|
||||
gfx_clear(dpi, colour);
|
||||
|
||||
int highlighted_format = (theme_get_preset()->features.rct1_scenario_font) ? 5139 : 1193;
|
||||
int unhighlighted_format = (theme_get_preset()->features.rct1_scenario_font) ? 5139 : 1191;
|
||||
int highlighted_format = (theme_get_flags() & UITHEME_FLAG_USE_ALTERNATIVE_SCENARIO_SELECT_FONT) ? 5139 : 1193;
|
||||
int unhighlighted_format = (theme_get_flags() & UITHEME_FLAG_USE_ALTERNATIVE_SCENARIO_SELECT_FONT) ? 5139 : 1191;
|
||||
|
||||
bool wide = gConfigGeneral.scenario_select_mode == SCENARIO_SELECT_MODE_ORIGIN;
|
||||
|
||||
|
|
Loading…
Reference in New Issue