diff --git a/projects/openrct2.vcxproj.filters b/projects/openrct2.vcxproj.filters
index f051e825df..e139763e95 100644
--- a/projects/openrct2.vcxproj.filters
+++ b/projects/openrct2.vcxproj.filters
@@ -222,9 +222,6 @@
Source\Util
-
- Source
-
Source
@@ -333,14 +330,12 @@
Source\World
-
Source\World
Source\Windows
-
Source\Windows
@@ -362,11 +357,11 @@
Source\Ride
-
+
Source\Windows
-
+
Source\Interface
@@ -427,6 +422,9 @@
Source\Windows
+
+ Source
+
diff --git a/src/audio/audio.c b/src/audio/audio.c
index 227550767c..544299a363 100644
--- a/src/audio/audio.c
+++ b/src/audio/audio.c
@@ -1545,7 +1545,7 @@ void stop_completed_sounds()
void start_title_music()
{
int musicPathId;
- switch (gGeneral_config.title_music) {
+ switch (gConfigSound.title_music) {
default:
return;
case 1:
@@ -1751,7 +1751,7 @@ void audio_init2(int device)
rct_dsdevice dsdevice = RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_DEVICES, rct_dsdevice*)[device];
RCT2_GLOBAL(RCT2_ADDRESS_DSOUND_GUID, GUID) = dsdevice.guid;
RCT2_GLOBAL(0x009AAC5C, uint8) = 1;
- config_save();
+ config_save_default();
RCT2_GLOBAL(0x014241BC, uint32) = 1;
int successtimer = audio_create_timer();
RCT2_GLOBAL(0x014241BC, uint32) = 0;
@@ -1763,9 +1763,9 @@ void audio_init2(int device)
}
}
if (!(RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & 1 << 4)) {
- gSound_config.forced_software_buffering = RCT2_GLOBAL(0x001425B74, uint32) != RCT2_GLOBAL(0x001425B78, uint32) || RCT2_GLOBAL(0x001425B74, uint32) != RCT2_GLOBAL(0x001425B7C, uint32);
+ gConfigSound.forced_software_buffering = RCT2_GLOBAL(0x001425B74, uint32) != RCT2_GLOBAL(0x001425B78, uint32) || RCT2_GLOBAL(0x001425B74, uint32) != RCT2_GLOBAL(0x001425B7C, uint32);
RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) |= 1 << 4;
- config_save();
+ config_save_default();
}
}
diff --git a/src/common.h b/src/common.h
index 3fb41aac95..b8c710cf63 100644
--- a/src/common.h
+++ b/src/common.h
@@ -24,4 +24,6 @@
#include "diagnostic.h"
#include "rct2.h"
+#define SafeFree(x) if ((x) != NULL) { free(x); (x) = NULL; }
+
#endif
\ No newline at end of file
diff --git a/src/config.c b/src/config.c
index 6b6f479877..dd8dbceb24 100644
--- a/src/config.c
+++ b/src/config.c
@@ -1,358 +1,616 @@
/*****************************************************************************
* Copyright (c) 2014 Ted John
* 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 .
*****************************************************************************/
-#include
#include "addresses.h"
#include "config.h"
#include "localisation/localisation.h"
-#include "platform/platform.h"
-
-// Current keyboard shortcuts
-uint16 gShortcutKeys[SHORTCUT_COUNT];
// Magic number for original game cfg file
static const int MagicNumber = 0x0003113A;
-// Default keyboard shortcuts
-static const uint16 _defaultShortcutKeys[SHORTCUT_COUNT] = {
- SDL_SCANCODE_BACKSPACE, // SHORTCUT_CLOSE_TOP_MOST_WINDOW
- 0x0100 | SDL_SCANCODE_BACKSPACE, // SHORTCUT_CLOSE_ALL_FLOATING_WINDOWS
- SDL_SCANCODE_ESCAPE, // SHORTCUT_CANCEL_CONSTRUCTION_MODE
- SDL_SCANCODE_PAUSE, // SHORTCUT_PAUSE_GAME
- SDL_SCANCODE_PAGEUP, // SHORTCUT_ZOOM_VIEW_OUT
- SDL_SCANCODE_PAGEDOWN, // SHORTCUT_ZOOM_VIEW_IN
- SDL_SCANCODE_RETURN, // SHORTCUT_ROTATE_VIEW
- SDL_SCANCODE_Z, // SHORTCUT_ROTATE_CONSTRUCTION_OBJECT
- SDL_SCANCODE_1, // SHORTCUT_UNDERGROUND_VIEW_TOGGLE
- SDL_SCANCODE_H, // SHORTCUT_REMOVE_BASE_LAND_TOGGLE
- SDL_SCANCODE_V, // SHORTCUT_REMOVE_VERTICAL_LAND_TOGGLE
- SDL_SCANCODE_3, // SHORTCUT_SEE_THROUGH_RIDES_TOGGLE
- SDL_SCANCODE_4, // SHORTCUT_SEE_THROUGH_SCENERY_TOGGLE
- SDL_SCANCODE_5, // SHORTCUT_INVISIBLE_SUPPORTS_TOGGLE
- SDL_SCANCODE_6, // SHORTCUT_INVISIBLE_PEOPLE_TOGGLE
- SDL_SCANCODE_8, // SHORTCUT_HEIGHT_MARKS_ON_LAND_TOGGLE
- SDL_SCANCODE_9, // SHORTCUT_HEIGHT_MARKS_ON_RIDE_TRACKS_TOGGLE
- SDL_SCANCODE_0, // SHORTCUT_HEIGHT_MARKS_ON_PATHS_TOGGLE
- SDL_SCANCODE_F1, // SHORTCUT_ADJUST_LAND
- SDL_SCANCODE_F2, // SHORTCUT_ADJUST_WATER
- SDL_SCANCODE_F3, // SHORTCUT_BUILD_SCENERY
- SDL_SCANCODE_F4, // SHORTCUT_BUILD_PATHS
- SDL_SCANCODE_F5, // SHORTCUT_BUILD_NEW_RIDE
- SDL_SCANCODE_F, // SHORTCUT_SHOW_FINANCIAL_INFORMATION
- SDL_SCANCODE_D, // SHORTCUT_SHOW_RESEARCH_INFORMATION
- SDL_SCANCODE_R, // SHORTCUT_SHOW_RIDES_LIST
- SDL_SCANCODE_P, // SHORTCUT_SHOW_PARK_INFORMATION
- SDL_SCANCODE_G, // SHORTCUT_SHOW_GUEST_LIST
- SDL_SCANCODE_S, // SHORTCUT_SHOW_STAFF_LIST
- SDL_SCANCODE_M, // SHORTCUT_SHOW_RECENT_MESSAGES
- SDL_SCANCODE_TAB, // SHORTCUT_SHOW_MAP
- 0x0200 | SDL_SCANCODE_S, // SHORTCUT_SCREENSHOT
-
- // New
- SDL_SCANCODE_MINUS, // SHORTCUT_REDUCE_GAME_SPEED,
- SDL_SCANCODE_EQUALS, // SHORTCUT_INCREASE_GAME_SPEED,
- 0x0200 | 0x0400 | SDL_SCANCODE_C // SHORTCUT_OPEN_CHEAT_WINDOW,
+enum {
+ CONFIG_VALUE_TYPE_BOOLEAN,
+ CONFIG_VALUE_TYPE_UINT8,
+ CONFIG_VALUE_TYPE_UINT16,
+ CONFIG_VALUE_TYPE_UINT32,
+ CONFIG_VALUE_TYPE_SINT8,
+ CONFIG_VALUE_TYPE_SINT16,
+ CONFIG_VALUE_TYPE_SINT32,
+ CONFIG_VALUE_TYPE_FLOAT,
+ CONFIG_VALUE_TYPE_DOUBLE,
+ CONFIG_VALUE_TYPE_STRING
};
-general_configuration_t gGeneral_config;
-general_configuration_t gGeneral_config_default = {
- 0, // play_intro
- 0, // confirmation_prompt
- SCREENSHOT_FORMAT_PNG, // screenshot_format
- "", // game_path
- MEASUREMENT_FORMAT_IMPERIAL, // measurement_format
- TEMPERATURE_FORMAT_C, // temperature_format
- CURRENCY_POUNDS, // currency_format
- 0, // construction_marker_colour
- 1, // edge_scrolling
- 0, // always_show_gridlines
- 1, // landscape_smoothing
- 0, // show_height_as_units
- 1, // save_plugin_data
- 0, // fullscreen mode (default: windowed)
- -1, // fullscreen_width
- -1, // fullscreen_height
- -1, // window_width
- -1, // window_height
- LANGUAGE_ENGLISH_UK, // language
- 5, // window_snap_proximity
- 2 // title music
+size_t _configValueTypeSize[] = {
+ sizeof(bool),
+ sizeof(uint8),
+ sizeof(uint16),
+ sizeof(uint32),
+ sizeof(sint8),
+ sizeof(sint16),
+ sizeof(sint32),
+ sizeof(float),
+ sizeof(double),
+ sizeof(utf8string)
};
-sound_configuration_t gSound_config;
-static char *config_show_directory_browser();
-static void config_parse_settings(FILE *fp);
-static void config_general(char *setting, char *value);
-static void config_sound(char *setting, char *value);
-static int config_get_line(FILE *fp, char *setting, char *value);
-static int config_parse_setting(FILE *fp, char *setting);
-static int config_parse_value(FILE *fp, char *value);
-static int config_parse_section(FILE *fp, char *setting, char *value);
-static void config_create_default(char *path);
-static int config_parse_currency(char* currency);
-static void config_error(char *msg);
+typedef union {
+ sint32 value_sint32;
-void config_save_ini(char *path);
-void config_write_ini_general(FILE *fp);
-void config_write_ini_sound(FILE *fp);
+ bool value_boolean;
+ sint8 value_sint8;
+ sint16 value_sint16;
+ uint8 value_uint8;
+ uint16 value_uint16;
+ uint32 value_uint32;
+ float value_float;
+ double value_double;
+ utf8string value_string;
+} value_union;
-/**
- *
- * rct2: 0x006E3604
- */
-void config_reset_shortcut_keys()
+typedef struct {
+ const_utf8string key;
+ value_union value;
+} config_enum_definition;
+
+#define END_OF_ENUM { NULL, 0 }
+
+typedef struct {
+ size_t offset;
+ const_utf8string property_name;
+ uint8 type;
+ value_union default_value;
+ config_enum_definition *enum_definitions;
+} config_property_definition;
+
+typedef struct {
+ void *base_address;
+ const_utf8string section_name;
+ config_property_definition *property_definitions;
+ int property_definitions_count;
+} config_section_definition;
+
+#pragma region Enum definitions
+
+config_enum_definition _screenShotFormatEnum[] = {
+ { "BMP", SCREENSHOT_FORMAT_BMP },
+ { "PNG", SCREENSHOT_FORMAT_PNG },
+ END_OF_ENUM
+};
+
+config_enum_definition _measurementFormatEnum[] = {
+ { "IMPERIAL", MEASUREMENT_FORMAT_IMPERIAL },
+ { "METRIC", MEASUREMENT_FORMAT_METRIC },
+ END_OF_ENUM
+};
+
+config_enum_definition _temperatureFormatEnum[] = {
+ { "CELSIUS", TEMPERATURE_FORMAT_C },
+ { "FAHRENHEIT", TEMPERATURE_FORMAT_F },
+ END_OF_ENUM
+};
+
+config_enum_definition _currencyEnum[] = {
+ { "GBP", CURRENCY_POUNDS },
+ { "USD", CURRENCY_DOLLARS },
+ { "FRF", CURRENCY_FRANC },
+ { "DEM", CURRENCY_DEUTSCHMARK },
+ { "JPY", CURRENCY_YEN },
+ { "ESP", CURRENCY_PESETA },
+ { "ITL", CURRENCY_LIRA },
+ { "NLG", CURRENCY_GUILDERS },
+ { "SEK", CURRENCY_KRONA },
+ { "EUR", CURRENCY_EUROS },
+ END_OF_ENUM
+};
+
+config_enum_definition _languageEnum[] = {
+ { "en-GB", LANGUAGE_ENGLISH_UK },
+ { "en-US", LANGUAGE_ENGLISH_US },
+ { "de-DE", LANGUAGE_GERMAN },
+ { "nl-NL", LANGUAGE_DUTCH },
+ { "fr-FR", LANGUAGE_FRENCH },
+ { "hu-HU", LANGUAGE_HUNGARIAN },
+ { "pl-PL", LANGUAGE_POLISH },
+ { "es-ES", LANGUAGE_SPANISH },
+ { "sv-SE", LANGUAGE_SWEDISH },
+ END_OF_ENUM
+};
+
+#pragma endregion
+
+#pragma region Section / property definitions
+
+config_property_definition _generalDefinitions[] = {
+ { offsetof(general_configuration, always_show_gridlines), "always_show_gridlines", CONFIG_VALUE_TYPE_BOOLEAN, false, NULL },
+ { offsetof(general_configuration, confirmation_prompt), "confirmation_prompt", CONFIG_VALUE_TYPE_UINT8, 0, NULL },
+ { offsetof(general_configuration, construction_marker_colour), "construction_marker_colour", CONFIG_VALUE_TYPE_UINT8, false, NULL },
+ { offsetof(general_configuration, currency_format), "currency_format", CONFIG_VALUE_TYPE_UINT8, CURRENCY_POUNDS, _currencyEnum },
+ { offsetof(general_configuration, edge_scrolling), "edge_scrolling", CONFIG_VALUE_TYPE_BOOLEAN, true, NULL },
+ { offsetof(general_configuration, fullscreen_mode), "fullscreen_mode", CONFIG_VALUE_TYPE_UINT8, 0, NULL },
+ { offsetof(general_configuration, fullscreen_height), "fullscreen_height", CONFIG_VALUE_TYPE_SINT32, -1, NULL },
+ { offsetof(general_configuration, fullscreen_width), "fullscreen_width", CONFIG_VALUE_TYPE_SINT32, -1, NULL },
+ { offsetof(general_configuration, game_path), "game_path", CONFIG_VALUE_TYPE_STRING, { .value_string = NULL }, NULL },
+ { offsetof(general_configuration, landscape_smoothing), "landscape_smoothing", CONFIG_VALUE_TYPE_BOOLEAN, true, NULL },
+ { offsetof(general_configuration, language), "language", CONFIG_VALUE_TYPE_UINT16, LANGUAGE_ENGLISH_UK, _languageEnum },
+ { offsetof(general_configuration, measurement_format), "measurement_format", CONFIG_VALUE_TYPE_UINT8, MEASUREMENT_FORMAT_IMPERIAL, _measurementFormatEnum },
+ { offsetof(general_configuration, play_intro), "play_intro", CONFIG_VALUE_TYPE_BOOLEAN, false, NULL },
+ { offsetof(general_configuration, save_plugin_data), "save_plugin_data", CONFIG_VALUE_TYPE_BOOLEAN, false, NULL },
+ { offsetof(general_configuration, screenshot_format), "screenshot_format", CONFIG_VALUE_TYPE_UINT8, SCREENSHOT_FORMAT_PNG, _screenShotFormatEnum },
+ { offsetof(general_configuration, show_height_as_units), "show_height_as_units", CONFIG_VALUE_TYPE_BOOLEAN, false, NULL },
+ { offsetof(general_configuration, temperature_format), "temperature_format", CONFIG_VALUE_TYPE_UINT8, TEMPERATURE_FORMAT_C, _temperatureFormatEnum },
+ { offsetof(general_configuration, window_height), "window_height", CONFIG_VALUE_TYPE_SINT32, -1, NULL },
+ { offsetof(general_configuration, window_snap_proximity), "window_snap_proximity", CONFIG_VALUE_TYPE_UINT8, 5, NULL },
+ { offsetof(general_configuration, window_width), "window_width", CONFIG_VALUE_TYPE_SINT32, -1, NULL },
+};
+
+config_property_definition _soundDefinitions[] = {
+ { offsetof(sound_configuration, forced_software_buffering), "forced_software_buffering", CONFIG_VALUE_TYPE_BOOLEAN, false, NULL },
+ { offsetof(sound_configuration, sound_quality), "sound_quality", CONFIG_VALUE_TYPE_UINT8, 2, NULL },
+ { offsetof(sound_configuration, title_music), "title_music", CONFIG_VALUE_TYPE_UINT8, 2, NULL },
+};
+
+config_section_definition _sectionDefinitions[] = {
+ { &gConfigGeneral, "general", _generalDefinitions, countof(_generalDefinitions) },
+ { &gConfigSound, "sound", _soundDefinitions, countof(_soundDefinitions) }
+};
+
+#pragma endregion
+
+general_configuration gConfigGeneral;
+sound_configuration gConfigSound;
+
+bool config_open(const utf8string path);
+bool config_save(const utf8string path);
+static void config_read_properties(config_section_definition **currentSection, const_utf8string line);
+static void config_save_property_value(FILE *file, uint8 type, value_union *value);
+static bool config_read_enum(void *dest, int destSize, const utf8 *key, int keySize, config_enum_definition *enumDefinitions);
+static void config_write_enum(FILE *file, uint8 type, value_union *value, config_enum_definition *enumDefinitions);
+
+static int utf8_read(utf8 **outch);
+static void utf8_skip_whitespace(utf8 **outch);
+static void utf8_skip_non_whitespace(utf8 **outch);
+
+void config_apply_to_old_addresses();
+
+void config_set_defaults()
{
- memcpy(gShortcutKeys, _defaultShortcutKeys, sizeof(gShortcutKeys));
-}
+ int i, j;
-void config_save_ini(char *path)
-{
- FILE *fp = NULL;
+ for (i = 0; i < countof(_sectionDefinitions); i++) {
+ config_section_definition *section = &_sectionDefinitions[i];
+ for (j = 0; j < section->property_definitions_count; j++) {
+ config_property_definition *property = §ion->property_definitions[j];
-
- fp = fopen(path, "wt+");
-
- config_write_ini_general(fp);
- config_write_ini_sound(fp);
-
- fclose(fp);
-}
-
-void config_write_ini_sound(FILE *fp)
-{
- fprintf(fp, "[sound]\n");
- if (gSound_config.sound_quality == SOUND_QUALITY_LOW) {
- fprintf(fp, "sound_quality = low\n");
- }
- else if (gSound_config.sound_quality == SOUND_QUALITY_MEDIUM) {
- fprintf(fp, "sound_quality = medium\n");
- }
- else{
- fprintf(fp, "sound_quality = high\n");
- }
-
- if (gSound_config.forced_software_buffering){
- fprintf(fp, "forced_software_buffering = true\n");
- }
- else {
- fprintf(fp, "forced_software_buffering = false\n");
+ value_union *destValue = (value_union*)((size_t)section->base_address + (size_t)property->offset);
+ memcpy(destValue, &property->default_value, _configValueTypeSize[property->type]);
+ }
}
}
-void config_write_ini_general(FILE *fp)
+bool config_open_default()
{
- int currencyIterator = 0;
+ utf8 path[MAX_PATH];
- fprintf(fp, "[general]\n");
- fprintf(fp, "game_path = %s\n", gGeneral_config.game_path);
-
- switch (gGeneral_config.screenshot_format)
- {
- case SCREENSHOT_FORMAT_BMP:
- fprintf(fp, "screenshot_format = BMP\n");
- break;
- case SCREENSHOT_FORMAT_PNG:
- fprintf(fp, "screenshot_format = PNG\n");
- break;
- default:
- config_error("error saving config.ini: wrong screenshot_format");
- break;
+ platform_get_user_directory(path, NULL);
+ strcat(path, "config.ini");
+ if (config_open(path)) {
+ config_apply_to_old_addresses();
+ return true;
}
- if (gGeneral_config.play_intro){
- fprintf(fp, "play_intro = true\n");
- }
- else {
- fprintf(fp, "play_intro = false\n");
+ return false;
+}
+
+bool config_save_default()
+{
+ utf8 path[MAX_PATH];
+
+ platform_get_user_directory(path, NULL);
+ strcat(path, "config.ini");
+ if (config_save(path)) {
+ config_apply_to_old_addresses();
+ return true;
}
- if (gGeneral_config.confirmation_prompt){
- fprintf(fp, "confirmation_prompt = true\n");
- }
- else {
- fprintf(fp, "confirmation_prompt = false\n");
- }
+ return false;
+}
- if (gGeneral_config.edge_scrolling){
- fprintf(fp, "edge_scrolling = true\n");
- }
- else {
- fprintf(fp, "edge_scrolling = false\n");
- }
+bool config_open(const utf8string path)
+{
+ FILE *file;
+ uint8 *lineBuffer;
+ size_t lineBufferCapacity;
+ size_t lineLength;
+ int c;
+ config_section_definition *currentSection;
- for (currencyIterator = 0; currencyIterator < countof(_currencyLookupTable); currencyIterator++) {
- if (_currencyLookupTable[currencyIterator].value == gGeneral_config.currency_format) {
- gGeneral_config.currency_format = _currencyLookupTable[currencyIterator].value;
- fprintf(fp, "currency = %s\n", _currencyLookupTable[currencyIterator].key);
- break; // There are more than one valid item for Pound, Euro and Dollar ...
+ file = fopen(path, "rb");
+ if (file == NULL)
+ return false;
+
+ currentSection = NULL;
+ lineBufferCapacity = 64;
+ lineBuffer = malloc(lineBufferCapacity);
+ lineLength = 0;
+ while ((c = fgetc(file)) != EOF) {
+ if (c == '\n' || c == '\r') {
+ lineBuffer[lineLength++] = 0;
+ config_read_properties(¤tSection, (const_utf8string)lineBuffer);
+ lineLength = 0;
+ } else {
+ lineBuffer[lineLength++] = c;
+ }
+
+ if (lineLength >= lineBufferCapacity) {
+ lineBufferCapacity *= 2;
+ lineBuffer = realloc(lineBuffer, lineBufferCapacity);
}
}
- if (gGeneral_config.measurement_format == MEASUREMENT_FORMAT_IMPERIAL) {
- fprintf(fp, "measurement_format = imperial\n");
- }
- else {
- fprintf(fp, "measurement_format = metric\n");
+ if (lineLength > 0) {
+ lineBuffer[lineLength++] = 0;
+ config_read_properties(¤tSection, lineBuffer);
}
- if (gGeneral_config.temperature_format == TEMPERATURE_FORMAT_F) {
- fprintf(fp, "temperature_format = fahrenheit\n");
- }
- else {
- fprintf(fp, "temperature_format = celsius\n");
- }
-
- if (gGeneral_config.always_show_gridlines){
- fprintf(fp, "always_show_gridlines = true\n");
- }
- else {
- fprintf(fp, "always_show_gridlines = false\n");
- }
-
- if (gGeneral_config.landscape_smoothing){
- fprintf(fp, "landscape_smoothing = true\n");
- }
- else {
- fprintf(fp, "landscape_smoothing = false\n");
- }
-
- if (gGeneral_config.show_height_as_units){
- fprintf(fp, "show_height_as_units = true\n");
- }
- else {
- fprintf(fp, "show_height_as_units = false\n");
- }
-
- if (gGeneral_config.save_plugin_data){
- fprintf(fp, "save_plugin_data = true\n");
- }
- else {
- fprintf(fp, "save_plugin_data = false\n");
- }
-
- if (gGeneral_config.fullscreen_mode == 0)
- fprintf(fp, "fullscreen_mode = window\n");
- else if (gGeneral_config.fullscreen_mode == 1)
- fprintf(fp, "fullscreen_mode = fullscreen\n");
- else
- fprintf(fp, "fullscreen_mode = borderless_fullscreen\n");
-
- if (gGeneral_config.fullscreen_width != -1)
- fprintf(fp, "fullscreen_width = %d\n", gGeneral_config.fullscreen_width);
- if (gGeneral_config.fullscreen_height != -1)
- fprintf(fp, "fullscreen_height = %d\n", gGeneral_config.fullscreen_height);
-
- if (gGeneral_config.window_width != -1)
- fprintf(fp, "window_width = %d\n", gGeneral_config.window_width);
- if (gGeneral_config.window_height != -1)
- fprintf(fp, "window_height = %d\n", gGeneral_config.window_height);
-
- fprintf(fp, "language = %d\n", gGeneral_config.language);
-
- fprintf(fp, "window_snap_proximity = %d\n", gGeneral_config.window_snap_proximity);
-
- fprintf(fp, "title_music = %d\n", gGeneral_config.title_music);
+ free(lineBuffer);
+ fclose(file);
+ return true;
}
-/**
- * Any code not implemented in OpenRCT2 will still uses the old configuration option addresses. This function copies all the
- * OpenRCT2 configuration options to those addresses until the process is no longer necessary.
- */
-void config_apply_to_old_addresses()
+bool config_save(const utf8string path)
{
- RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_EDGE_SCROLLING, sint8) = gGeneral_config.edge_scrolling;
- RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_CURRENCY, sint8) = gGeneral_config.currency_format;
- RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_METRIC, sint8) = gGeneral_config.measurement_format;
- RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_TEMPERATURE, sint8) = gGeneral_config.temperature_format;
- RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_CONSTRUCTION_MARKER, uint8) = gGeneral_config.construction_marker_colour;
- RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_QUALITY, sint8) = gSound_config.sound_quality;
- RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_SW_BUFFER, sint8) = gSound_config.forced_software_buffering;
- RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_HEIGHT_MARKERS, sint16) = (gGeneral_config.measurement_format + 1) * 256;
- if (gGeneral_config.show_height_as_units)
- RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_HEIGHT_MARKERS, sint16) = 0;
+ FILE *file;
+ int i, j;
+ value_union *value;
- int configFlags = 0;
- if (gGeneral_config.always_show_gridlines)
- configFlags |= CONFIG_FLAG_ALWAYS_SHOW_GRIDLINES;
- if (!gGeneral_config.landscape_smoothing)
- configFlags |= CONFIG_FLAG_DISABLE_SMOOTH_LANDSCAPE;
- if (gGeneral_config.show_height_as_units)
- configFlags |= CONFIG_FLAG_SHOW_HEIGHT_AS_UNITS;
- if (gGeneral_config.save_plugin_data)
- configFlags |= CONFIG_FLAG_SAVE_PLUGIN_DATA;
+ file = fopen(path, "wb");
+ if (file == NULL) {
+ log_error("Unable to write to config file.");
+ return false;
+ }
- RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) = configFlags;
+ for (i = 0; i < countof(_sectionDefinitions); i++) {
+ config_section_definition *section = &_sectionDefinitions[i];
+
+ fputc('[', file);
+ fwrite(section->section_name, strlen(section->section_name), 1, file);
+ fputc(']', file);
+ fputc('\n', file);
+
+ for (j = 0; j < section->property_definitions_count; j++) {
+ config_property_definition *property = §ion->property_definitions[j];
+
+ fwrite(property->property_name, strlen(property->property_name), 1, file);
+ fwrite(" = ", 3, 1, file);
+
+ value = (value_union*)((size_t)section->base_address + (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);
+ fputc('\n', file);
+ }
+ fputc('\n', file);
+ }
+
+ fclose(file);
+ return true;
}
-static void config_get_path(char *outPath)
+static void config_save_property_value(FILE *file, uint8 type, value_union *value)
{
- platform_get_user_directory(outPath, NULL);
- strcat(outPath, "config.ini");
+ switch (type) {
+ case CONFIG_VALUE_TYPE_BOOLEAN:
+ if (value->value_boolean) fwrite("true", 4, 1, file);
+ else fwrite("false", 5, 1, file);
+ break;
+ case CONFIG_VALUE_TYPE_UINT8:
+ fprintf(file, "%d", value->value_uint8);
+ break;
+ case CONFIG_VALUE_TYPE_UINT16:
+ fprintf(file, "%d", value->value_uint16);
+ break;
+ case CONFIG_VALUE_TYPE_UINT32:
+ fprintf(file, "%d", value->value_uint32);
+ break;
+ case CONFIG_VALUE_TYPE_SINT8:
+ fprintf(file, "%d", value->value_sint8);
+ break;
+ case CONFIG_VALUE_TYPE_SINT16:
+ fprintf(file, "%d", value->value_sint16);
+ break;
+ case CONFIG_VALUE_TYPE_SINT32:
+ fprintf(file, "%d", value->value_sint32);
+ break;
+ case CONFIG_VALUE_TYPE_FLOAT:
+ fprintf(file, "%.3f", value->value_float);
+ break;
+ case CONFIG_VALUE_TYPE_DOUBLE:
+ fprintf(file, "%.6f", value->value_double);
+ break;
+ case CONFIG_VALUE_TYPE_STRING:
+ fputc('"', file);
+ if (value->value_string != NULL)
+ fwrite(value->value_string, strlen(value->value_string), 1, file);
+ fputc('"', file);
+ break;
+ }
}
-/**
- * Initialise the settings.
- * It checks if the OpenRCT2 folder exists and creates it if it does not
- * parsing of the config file is done in config_parse_settings
- */
-void config_load()
-{
- FILE *fp;
- char configPath[MAX_PATH];
+bool config_get_section(const utf8string line, const utf8 **sectionName, int *sectionNameSize)
+{
+ utf8 *ch;
+ int c;
- config_get_path(configPath);
+ ch = line;
+ utf8_skip_whitespace(&ch);
+ if (*ch != '[') return false;
+ *sectionName = ++ch;
- memcpy(&gGeneral_config, &gGeneral_config_default, sizeof(general_configuration_t));
+ while (*ch != 0) {
+ c = utf8_read(&ch);
+ if (c == '#') return false;
+ if (c == '[') return false;
+ if (c == ' ') break;
+ if (c == ']') break;
+ }
- fp = fopen(configPath, "r");
- if (fp == NULL) {
- config_create_default(configPath);
- fp = fopen(configPath, "r");
- if (fp == NULL) {
- config_error("Could not create config file.");
+ *sectionNameSize = ch - *sectionName - 1;
+ return true;
+}
+
+bool config_get_property_name_value(const utf8string line, const utf8 **propertyName, int *propertyNameSize, const utf8 **value, int *valueSize)
+{
+ utf8 *ch;
+ int c, lastC;
+ bool quotes;
+
+ ch = line;
+ utf8_skip_whitespace(&ch);
+
+ if (*ch == 0) return false;
+ *propertyName = ch;
+
+ while (*ch != 0) {
+ c = utf8_read(&ch);
+ if (isspace(c) || c == '=') {
+ *propertyNameSize = ch - *propertyName - 1;
+ break;
+ } else if (c == '#') {
+ return false;
+ }
+ }
+
+ if (*ch == 0) return false;
+ utf8_skip_whitespace(&ch);
+ if (*ch != '=') return false;
+ ch++;
+ utf8_skip_whitespace(&ch);
+ if (*ch == 0) return false;
+
+ if (*ch == '"') {
+ ch++;
+ quotes = true;
+ } else {
+ quotes = false;
+ }
+ *value = ch;
+
+ while (*ch != 0) {
+ c = utf8_read(&ch);
+ if (isspace(c) || c == '#') {
+ if (!quotes) break;
+ }
+ lastC = c;
+ }
+ *valueSize = ch - *value - 1;
+ return true;
+}
+
+config_section_definition *config_get_section_def(const utf8 *name, int size)
+{
+ int i;
+
+ for (i = 0; i < countof(_sectionDefinitions); i++)
+ if (_strnicmp(_sectionDefinitions[i].section_name, name, size) == 0)
+ return &_sectionDefinitions[i];
+
+ return NULL;
+}
+
+config_property_definition *config_get_property_def(config_section_definition *section, const utf8 *name, int size)
+{
+ int i;
+
+ for (i = 0; i < section->property_definitions_count; i++)
+ if (_strnicmp(section->property_definitions[i].property_name, name, size) == 0)
+ return §ion->property_definitions[i];
+
+ return NULL;
+}
+
+void config_set_property(const config_section_definition *section, const config_property_definition *property, const utf8 *value, int valueSize)
+{
+ value_union *destValue = (value_union*)((size_t)section->base_address + (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 void config_read_properties(config_section_definition **currentSection, const_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 = config_get_section_def(sectionName, sectionNameSize);
+ } else {
+ if (*currentSection != NULL) {
+ const utf8 *propertyName, *value;
+ int propertyNameSize, valueSize;
+ if (config_get_property_name_value(ch, &propertyName, &propertyNameSize, &value, &valueSize)) {
+ config_property_definition *property;
+ property = config_get_property_def(*currentSection, propertyName, propertyNameSize);
+ if (property != NULL)
+ config_set_property(*currentSection, property, value, valueSize);
+ }
+ }
+ }
+}
+
+static bool config_read_enum(void *dest, int destSize, const utf8 *key, int keySize, config_enum_definition *enumDefinitions)
+{
+ while (enumDefinitions->key != NULL) {
+ if (_strnicmp(enumDefinitions->key, key, keySize) == 0) {
+ memcpy(dest, &enumDefinitions->value.value_uint32, destSize);
+ return true;
+ }
+ enumDefinitions++;
+ }
+ return false;
+}
+
+static void config_write_enum(FILE *file, uint8 type, value_union *value, config_enum_definition *enumDefinitions)
+{
+ uint32 enumValue = (value->value_uint32) & ((1 << (_configValueTypeSize[type] * 8)) - 1);
+ while (enumDefinitions->key != NULL) {
+ if (enumDefinitions->value.value_uint32 == enumValue) {
+ fwrite(enumDefinitions->key, strlen(enumDefinitions->key), 1, file);
return;
}
+ enumDefinitions++;
+ }
+ config_save_property_value(file, type, value);
+}
+
+static int utf8_read(utf8 **outch)
+{
+ int result;
+ int numBytes;
+
+ utf8 *ch = *outch;
+ if (!(ch[0] & 0x80)) {
+ result = ch[0];
+ numBytes = 1;
+ } else if (!(ch[0] & 0x20)) {
+ result = ((ch[0] & 0x1F) << 6) | (ch[1] & 0x3F);
+ numBytes = 2;
+ } else {
+ numBytes = 1;
}
- config_parse_settings(fp);
- fclose(fp);
-
- config_apply_to_old_addresses();
+ *outch = ch + numBytes;
+ return result;
}
-void config_save()
+static void utf8_skip_whitespace(utf8 **outch)
{
- char configPath[MAX_PATH];
-
- config_get_path(configPath);
- config_save_ini(configPath);
- config_apply_to_old_addresses();
+ utf8 *ch;
+ while (**outch != 0) {
+ ch = *outch;
+ if (!isspace(utf8_read(outch))) {
+ *outch = ch;
+ break;
+ }
+ }
}
+static void utf8_skip_non_whitespace(utf8 **outch)
+{
+ while (**outch != 0) {
+ if (isspace(utf8_read(outch)))
+ break;
+ }
+}
+
+/*
+
+Code reserved for when we want more intelligent saving of config file which preserves comments and layout
+
+enum {
+ CONFIG_LINE_TYPE_WHITESPACE,
+ CONFIG_LINE_TYPE_COMMENT,
+ CONFIG_LINE_TYPE_SECTION,
+ CONFIG_LINE_TYPE_PROPERTY,
+ CONFIG_LINE_TYPE_INVALID
+};
+
+typedef struct {
+ uint8 type;
+ utf8string line;
+} config_line;
+
+static config_line *_configLines = NULL;
+
+*/
+
/**
* Attempts to find the RCT2 installation directory.
* This should be created from some other resource when OpenRCT2 grows.
* @param resultPath Pointer to where the absolute path of the RCT2 installation directory will be copied to.
* @returns 1 if successful, otherwise 0.
*/
-static int config_find_rct2_path(char *resultPath)
+static bool config_find_rct2_path(char *resultPath)
{
int i;
@@ -371,417 +629,67 @@ static int config_find_rct2_path(char *resultPath)
for (i = 0; i < countof(searchLocations); i++) {
if (platform_directory_exists(searchLocations[i]) ) {
strcpy(resultPath, searchLocations[i]);
- return 1;
+ return true;
}
}
- return 0;
+ return false;
}
-int config_find_or_browse_install_directory()
+bool config_find_or_browse_install_directory()
{
+ char path[MAX_PATH];
char *installPath;
- if (!config_find_rct2_path(gGeneral_config.game_path)) {
+ if (config_find_rct2_path(path)) {
+ SafeFree(gConfigGeneral.game_path);
+ gConfigGeneral.game_path = malloc(strlen(path) + 1);
+ strcpy(gConfigGeneral.game_path, path);
+ } else {
platform_show_messagebox("Unable to find RCT2 installation directory. Please select the directory where you installed RCT2!");
installPath = platform_open_directory_browser("Please select your RCT2 directory");
if (installPath == NULL)
- return 0;
+ return false;
- strcpy(gGeneral_config.game_path, installPath);
+ SafeFree(gConfigGeneral.game_path);
+ gConfigGeneral.game_path = installPath;
}
- config_save();
- return 1;
-}
-
-/**
- * Create a new default settings file.
- * This should be created from some other resource when openRCT2 grows
- * @param path The aboslute path of the config file
- */
-static void config_create_default(char *path)
-{
- gGeneral_config = gGeneral_config_default;
- if (!config_find_or_browse_install_directory()) {
- log_fatal("An RCT2 install directory must be specified!");
- exit(-1);
- }
-
- config_save_ini(path);
-}
-
-/**
- * Parse settings and set the game veriables
- * @param fp file pointer to the settings file
- */
-static void config_parse_settings(FILE *fp)
-{
- int pos = 0;
- char *setting;
- char *value;
- char *section;
- setting = (char *)malloc(MAX_CONFIG_LENGTH);
- value = (char *)malloc(MAX_CONFIG_LENGTH);
- section = (char*)malloc(MAX_CONFIG_LENGTH);
-
- while (config_get_line(fp, setting, value) > 0) {
- if (strcmp(setting, "section") == 0){
- strcpy(section, value);
- continue;
- }
-
- if (strcmp(section, "sound") == 0){
- config_sound(setting, value);
- }
- else if (strcmp(section, "general") == 0){
- config_general(setting, value);
- }
-
-
-
- }
- //RCT2_GLOBAL(0x009AACBC, sint8) = CURRENCY_KRONA;
-
-
-
- free(setting);
- free(value);
- free(section);
-}
-
-static void config_sound(char *setting, char *value){
- if (strcmp(setting, "sound_quality") == 0){
- if (strcmp(value, "low") == 0){
- gSound_config.sound_quality = SOUND_QUALITY_LOW;
- }
- else if (strcmp(value, "medium") == 0){
- gSound_config.sound_quality = SOUND_QUALITY_MEDIUM;
- }
- else{
- gSound_config.sound_quality = SOUND_QUALITY_HIGH;
- }
- }
- else if (strcmp(setting, "forced_software_buffering") == 0){
- if (strcmp(value, "true") == 0){
- gSound_config.forced_software_buffering = 1;
- }
- else{
- gSound_config.forced_software_buffering = 0;
- }
- }
-
-}
-
-static void config_general(char *setting, char *value){
- if (strcmp(setting, "game_path") == 0){
- strcpy(gGeneral_config.game_path, value);
- }
- else if (strcmp(setting, "screenshot_format") == 0) {
- if (strcmp(value, "png") == 0) {
- gGeneral_config.screenshot_format = SCREENSHOT_FORMAT_PNG;
- }
- else if (strcmp(value, "1") == 0) { //TODO: REMOVE LINE AT LATER DATE WHEN EVERYONE HAS NEW CONFIG FORMAT
- gGeneral_config.screenshot_format = SCREENSHOT_FORMAT_PNG;
- }
- else {
- gGeneral_config.screenshot_format = SCREENSHOT_FORMAT_BMP;
- }
- }
- else if (strcmp(setting, "play_intro") == 0) {
- gGeneral_config.play_intro = (strcmp(value, "true") == 0);
- }
- else if (strcmp(setting, "confirmation_prompt") == 0) {
- gGeneral_config.confirmation_prompt = (strcmp(value, "true") == 0);
- }
- else if (strcmp(setting, "edge_scrolling") == 0){
- if (strcmp(value, "true") == 0){
- gGeneral_config.edge_scrolling = 1;
- }
- else {
- gGeneral_config.edge_scrolling = 0;
- }
- }
- else if (strcmp(setting, "measurement_format") == 0){
- if (strcmp(value, "imperial") == 0){
- gGeneral_config.measurement_format = MEASUREMENT_FORMAT_IMPERIAL;
- }
- else{
- gGeneral_config.measurement_format = MEASUREMENT_FORMAT_METRIC;
- }
- }
- else if (strcmp(setting, "temperature_format") == 0){
- if (strcmp(value, "fahrenheit") == 0){
- gGeneral_config.temperature_format = TEMPERATURE_FORMAT_F;
- }
- else{
- gGeneral_config.temperature_format = TEMPERATURE_FORMAT_C;
- }
- }
- else if (strcmp(setting, "currency") == 0){
- config_parse_currency(value);
- }
- else if (strcmp(setting, "always_show_gridlines") == 0){
- if (strcmp(value, "true") == 0){
- gGeneral_config.always_show_gridlines = 1;
- }
- else {
- gGeneral_config.always_show_gridlines = 0;
- }
- }
- else if (strcmp(setting, "landscape_smoothing") == 0){
- if (strcmp(value, "true") == 0){
- gGeneral_config.landscape_smoothing = 1;
- }
- else {
- gGeneral_config.landscape_smoothing = 0;
- }
- }
- else if (strcmp(setting, "show_height_as_units") == 0){
- if (strcmp(value, "true") == 0){
- gGeneral_config.show_height_as_units = 1;
- }
- else {
- gGeneral_config.show_height_as_units = 0;
- }
- }
- else if (strcmp(setting, "save_plugin_data") == 0){
- if (strcmp(value, "true") == 0){
- gGeneral_config.save_plugin_data = 1;
- }
- else {
- gGeneral_config.save_plugin_data = 0;
- }
- }
- else if (strcmp(setting, "fullscreen_mode") == 0){
- if (strcmp(value, "window") == 0){
- gGeneral_config.fullscreen_mode = 0;
- }
- else if (strcmp(value, "fullscreen") == 0){
- gGeneral_config.fullscreen_mode = 1;
- }
- else
- gGeneral_config.fullscreen_mode = 2;
- }
- else if (strcmp(setting, "fullscreen_width") == 0) {
- gGeneral_config.fullscreen_width = atoi(value);
- }
- else if (strcmp(setting, "fullscreen_height") == 0) {
- gGeneral_config.fullscreen_height = atoi(value);
- }
- else if (strcmp(setting, "window_width") == 0) {
- gGeneral_config.window_width = atoi(value);
- }
- else if (strcmp(setting, "window_height") == 0) {
- gGeneral_config.window_height = atoi(value);
- }
- else if (strcmp(setting, "language") == 0) {
- gGeneral_config.language = atoi(value);
- }
- else if (strcmp(setting, "window_snap_proximity") == 0) {
- gGeneral_config.window_snap_proximity = clamp(0, atoi(value), 255);
- }
- else if (strcmp(setting, "title_music") == 0) {
- gGeneral_config.title_music = atoi(value);
- }
-}
-
-/**
- * Read one line in the settings file
- * @param fp filepointer to the config file
- * @param setting pointer where to to store the setting
- * @param value pointer to where to store the value
- * @return < 0 if EOF file is reached or other error
- */
-static int config_get_line(FILE *fp, char *setting, char *value)
-{
- int c;
-
- c = fgetc(fp);
- while (isspace(c)){
- c = getc(fp);
- }
-
- if (c == '['){
- return config_parse_section(fp, setting, value);
- }
- else if(c == '#'){
- while (c != '\n'){
- c = fgetc(fp);
- }
- return 1;
- }
- if (c == EOF){
- return -1;
- }
-
- while (!isalpha(c)){
- c = fgetc(fp);
- }
-
- //if the first char is not the '[' char, it belongs to the setting name. We want to leave that for the next fn
- fseek(fp, -1, SEEK_CUR);
-
- config_parse_setting(fp, setting);
-
- c = fgetc(fp);
- while (isspace(c)){
- c = getc(fp);
- }
-
- if (c != '='){
- config_error("There is an error in your configuration file");
- return -1;
- }
-
- config_parse_value(fp, value);
- return 1;
-
-
-}
-
-/**
-* Parse the value of a setting
-* @param fp a filepointer to the config file
-* @param value a pointer to where to store the setting
-* @return < 0 if EOF is reached
-*/
-static int config_parse_setting(FILE *fp, char *setting){
- long start, end;
- int size, c, pos = 0;
-
-
- start = ftell(fp);
- c = fgetc(fp);
-
- while (isspace(c)){
- start = ftell(fp);
- c = fgetc(fp);
-
- }
- if (c == EOF){
- return -1;
- }
-
- while (isalpha(c) || c == '_'){
- c = fgetc(fp);
- }
-
- end = ftell(fp);
- size = end - start;
-
-
- fseek(fp, start, SEEK_SET);
- c = fgetc(fp);
- while (isalpha(c) || c == '_'){
- setting[pos] = (char)c;
- c = fgetc(fp);
- pos++;
- }
- setting[pos] = '\0';
- return 1;
-}
-
-/**
- * Parse the value of a setting
- * @param fp a filepointer to the config file
- * @param value a pointer to where to store the value
- * @return < 0 if EOF is reached
- */
-static int config_parse_value(FILE *fp, char *value)
-{
- long start, end;
- int size, c, pos = 0;
-
- start = ftell(fp);
- c = fgetc(fp);
- while (isspace(c)) {
- start = ftell(fp);
- c = fgetc(fp);
- }
-
- while (c != EOF && c != '\n') {
- c = fgetc(fp);
- }
-
- end = ftell(fp);
- size = end - start;
- if (size > MAX_CONFIG_LENGTH)
- config_error("One of your settings is too long");
-
- fseek(fp, start, SEEK_SET);
- c = fgetc(fp);
- while (c != EOF && c != '\n') {
- value[pos] = (char)tolower(c);
- c = fgetc(fp);
- pos++;
- }
- value[pos] = '\0';
- return 0;
-}
-
-/**
- * Parse the current section
- * @param fp Filepointer to the config file
- * @param setting This is set to contain the string "section"
- * @param value Pointer to where the section name should be put
- * @return < 0 if EOF is reached
- */
-static int config_parse_section(FILE *fp, char *setting, char *value){
- int size, c, pos = 0;
- long start, end;
-
- strcpy(setting, "section\0");
- c = fgetc(fp);
- start = ftell(fp);
- while (c != ']' && c != EOF){
- c = fgetc(fp);
- }
- end = ftell(fp);
- size = end - start;
- fseek(fp, start - 1, SEEK_SET);
- c = fgetc(fp);
- while (c != ']' && c != EOF){
- value[pos] = (char)c;
- c = fgetc(fp);
- pos++;
- }
-
- value[pos] = '\0';
- if (c != ']'){
- config_error("There is an error with the section headers");
- }
- c = fgetc(fp); //devour ']'
-
- return 1;
-}
-
-static int config_parse_currency(char *currency)
-{
- int i;
- for (i = 0; i < countof(_currencyLookupTable); i++) {
- if (_strcmpi(currency, _currencyLookupTable[i].key) == 0) {
- gGeneral_config.currency_format = _currencyLookupTable[i].value;
- return 1;
- }
- }
-
- config_error("Invalid currency set in config file");
- return -1;
-}
-/**
- * Error with config file. Print error message an quit the game
- * @param msg Message to print in message box
- */
-static void config_error(char *msg){
-
- platform_show_messagebox(msg);
- //TODO:SHUT DOWN EVERYTHING!
-
+ return true;
}
#pragma region Obsolete
+/**
+ * Any code not implemented in OpenRCT2 will still uses the old configuration option addresses. This function copies all the
+ * OpenRCT2 configuration options to those addresses until the process is no longer necessary.
+ */
+void config_apply_to_old_addresses()
+{
+ RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_EDGE_SCROLLING, sint8) = gConfigGeneral.edge_scrolling;
+ RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_CURRENCY, sint8) = gConfigGeneral.currency_format;
+ RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_METRIC, sint8) = gConfigGeneral.measurement_format;
+ RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_TEMPERATURE, sint8) = gConfigGeneral.temperature_format;
+ RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_CONSTRUCTION_MARKER, uint8) = gConfigGeneral.construction_marker_colour;
+ RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_QUALITY, sint8) = gConfigSound.sound_quality;
+ RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_SW_BUFFER, sint8) = gConfigSound.forced_software_buffering;
+ RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_HEIGHT_MARKERS, sint16) = (gConfigGeneral.measurement_format + 1) * 256;
+ if (gConfigGeneral.show_height_as_units)
+ RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_HEIGHT_MARKERS, sint16) = 0;
+
+ int configFlags = 0;
+ if (gConfigGeneral.always_show_gridlines)
+ configFlags |= CONFIG_FLAG_ALWAYS_SHOW_GRIDLINES;
+ if (!gConfigGeneral.landscape_smoothing)
+ configFlags |= CONFIG_FLAG_DISABLE_SMOOTH_LANDSCAPE;
+ if (gConfigGeneral.show_height_as_units)
+ configFlags |= CONFIG_FLAG_SHOW_HEIGHT_AS_UNITS;
+ if (gConfigGeneral.save_plugin_data)
+ configFlags |= CONFIG_FLAG_SAVE_PLUGIN_DATA;
+
+ RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) = configFlags;
+}
+
// The following functions are related to the original configuration file. This has now been replaced with a new configuration
// INI file located in the user's OpenRCT2 home directory.
@@ -807,13 +715,13 @@ void config_dat_load()
fclose(fp);
//general configuration
- RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_EDGE_SCROLLING, sint8) = gGeneral_config.edge_scrolling;
- RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_CURRENCY, sint8) = gGeneral_config.currency_format;
- RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_METRIC, sint8) = gGeneral_config.measurement_format;
- RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_TEMPERATURE, sint8) = gGeneral_config.temperature_format;
+ RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_EDGE_SCROLLING, sint8) = gConfigGeneral.edge_scrolling;
+ RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_CURRENCY, sint8) = gConfigGeneral.currency_format;
+ RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_METRIC, sint8) = gConfigGeneral.measurement_format;
+ RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_TEMPERATURE, sint8) = gConfigGeneral.temperature_format;
// always show gridlines
- if (gGeneral_config.always_show_gridlines){
+ if (gConfigGeneral.always_show_gridlines){
RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) |= CONFIG_FLAG_ALWAYS_SHOW_GRIDLINES;
}
else {
@@ -821,7 +729,7 @@ void config_dat_load()
}
// landscape smoothing
- if (!gGeneral_config.landscape_smoothing){
+ if (!gConfigGeneral.landscape_smoothing){
RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) |= CONFIG_FLAG_DISABLE_SMOOTH_LANDSCAPE;
}
else {
@@ -829,7 +737,7 @@ void config_dat_load()
}
// show height as units
- if (gGeneral_config.show_height_as_units){
+ if (gConfigGeneral.show_height_as_units){
RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) |= CONFIG_FLAG_SHOW_HEIGHT_AS_UNITS;
}
else {
@@ -837,7 +745,7 @@ void config_dat_load()
}
// save plugin data
- if (gGeneral_config.save_plugin_data){
+ if (gConfigGeneral.save_plugin_data){
RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) |= CONFIG_FLAG_SAVE_PLUGIN_DATA;
}
else {
@@ -845,8 +753,8 @@ void config_dat_load()
}
//sound configuration
- RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_QUALITY, sint8) = gSound_config.sound_quality;
- RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_SW_BUFFER, sint8) = gSound_config.forced_software_buffering;
+ RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_QUALITY, sint8) = gConfigSound.sound_quality;
+ RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_SOUND_SW_BUFFER, sint8) = gConfigSound.forced_software_buffering;
// Line below is temporaraly disabled until all config is in the new format.
//if (RCT2_GLOBAL(0x009AB4C6, sint8) == 1)
@@ -911,4 +819,61 @@ void config_dat_save()
}
}
+#pragma endregion
+
+#pragma region Shortcuts
+
+// Current keyboard shortcuts
+uint16 gShortcutKeys[SHORTCUT_COUNT];
+
+// Default keyboard shortcuts
+static const uint16 _defaultShortcutKeys[SHORTCUT_COUNT] = {
+ SDL_SCANCODE_BACKSPACE, // SHORTCUT_CLOSE_TOP_MOST_WINDOW
+ 0x0100 | SDL_SCANCODE_BACKSPACE, // SHORTCUT_CLOSE_ALL_FLOATING_WINDOWS
+ SDL_SCANCODE_ESCAPE, // SHORTCUT_CANCEL_CONSTRUCTION_MODE
+ SDL_SCANCODE_PAUSE, // SHORTCUT_PAUSE_GAME
+ SDL_SCANCODE_PAGEUP, // SHORTCUT_ZOOM_VIEW_OUT
+ SDL_SCANCODE_PAGEDOWN, // SHORTCUT_ZOOM_VIEW_IN
+ SDL_SCANCODE_RETURN, // SHORTCUT_ROTATE_VIEW
+ SDL_SCANCODE_Z, // SHORTCUT_ROTATE_CONSTRUCTION_OBJECT
+ SDL_SCANCODE_1, // SHORTCUT_UNDERGROUND_VIEW_TOGGLE
+ SDL_SCANCODE_H, // SHORTCUT_REMOVE_BASE_LAND_TOGGLE
+ SDL_SCANCODE_V, // SHORTCUT_REMOVE_VERTICAL_LAND_TOGGLE
+ SDL_SCANCODE_3, // SHORTCUT_SEE_THROUGH_RIDES_TOGGLE
+ SDL_SCANCODE_4, // SHORTCUT_SEE_THROUGH_SCENERY_TOGGLE
+ SDL_SCANCODE_5, // SHORTCUT_INVISIBLE_SUPPORTS_TOGGLE
+ SDL_SCANCODE_6, // SHORTCUT_INVISIBLE_PEOPLE_TOGGLE
+ SDL_SCANCODE_8, // SHORTCUT_HEIGHT_MARKS_ON_LAND_TOGGLE
+ SDL_SCANCODE_9, // SHORTCUT_HEIGHT_MARKS_ON_RIDE_TRACKS_TOGGLE
+ SDL_SCANCODE_0, // SHORTCUT_HEIGHT_MARKS_ON_PATHS_TOGGLE
+ SDL_SCANCODE_F1, // SHORTCUT_ADJUST_LAND
+ SDL_SCANCODE_F2, // SHORTCUT_ADJUST_WATER
+ SDL_SCANCODE_F3, // SHORTCUT_BUILD_SCENERY
+ SDL_SCANCODE_F4, // SHORTCUT_BUILD_PATHS
+ SDL_SCANCODE_F5, // SHORTCUT_BUILD_NEW_RIDE
+ SDL_SCANCODE_F, // SHORTCUT_SHOW_FINANCIAL_INFORMATION
+ SDL_SCANCODE_D, // SHORTCUT_SHOW_RESEARCH_INFORMATION
+ SDL_SCANCODE_R, // SHORTCUT_SHOW_RIDES_LIST
+ SDL_SCANCODE_P, // SHORTCUT_SHOW_PARK_INFORMATION
+ SDL_SCANCODE_G, // SHORTCUT_SHOW_GUEST_LIST
+ SDL_SCANCODE_S, // SHORTCUT_SHOW_STAFF_LIST
+ SDL_SCANCODE_M, // SHORTCUT_SHOW_RECENT_MESSAGES
+ SDL_SCANCODE_TAB, // SHORTCUT_SHOW_MAP
+ 0x0200 | SDL_SCANCODE_S, // SHORTCUT_SCREENSHOT
+
+ // New
+ SDL_SCANCODE_MINUS, // SHORTCUT_REDUCE_GAME_SPEED,
+ SDL_SCANCODE_EQUALS, // SHORTCUT_INCREASE_GAME_SPEED,
+ 0x0200 | 0x0400 | SDL_SCANCODE_C // SHORTCUT_OPEN_CHEAT_WINDOW,
+};
+
+/**
+ *
+ * rct2: 0x006E3604
+ */
+void config_reset_shortcut_keys()
+{
+ memcpy(gShortcutKeys, _defaultShortcutKeys, sizeof(gShortcutKeys));
+}
+
#pragma endregion
\ No newline at end of file
diff --git a/src/config.h b/src/config.h
index 6193381412..1ab8935edf 100644
--- a/src/config.h
+++ b/src/config.h
@@ -96,30 +96,11 @@ enum{
};
-extern uint16 gShortcutKeys[SHORTCUT_COUNT];
-
-void config_reset_shortcut_keys();
-void config_load();
-void config_save();
-int config_find_or_browse_install_directory();
-
-
-// New config format
-#define MAX_CONFIG_LENGTH 256
-
-typedef struct sound_configuration {
-
- sint8 sound_quality;
- sint8 forced_software_buffering;
-} sound_configuration_t;
-
-
-
typedef struct general_configuration {
uint8 play_intro;
uint8 confirmation_prompt;
uint8 screenshot_format;
- char game_path[MAX_PATH];
+ utf8string game_path;
sint8 measurement_format;
sint8 temperature_format;
sint8 currency_format;
@@ -132,44 +113,35 @@ typedef struct general_configuration {
//new
uint8 fullscreen_mode;
- sint16 fullscreen_width;
- sint16 fullscreen_height;
- sint16 window_width;
- sint16 window_height;
+ sint32 fullscreen_width;
+ sint32 fullscreen_height;
+ sint32 window_width;
+ sint32 window_height;
uint16 language;
uint8 window_snap_proximity;
+} general_configuration;
+
+typedef struct sound_configuration {
+ sint8 forced_software_buffering;
+ sint8 sound_quality;
uint8 title_music;
-} general_configuration_t;
+} sound_configuration;
-static const struct { const char *key; int value; } _currencyLookupTable[] = {
- { "GBP", CURRENCY_POUNDS },
- { "USD", CURRENCY_DOLLARS },
- { "FRF", CURRENCY_FRANC },
- { "DEM", CURRENCY_DEUTSCHMARK },
- { "YEN", CURRENCY_YEN },
- { "ESP", CURRENCY_PESETA },
- { "ITL", CURRENCY_LIRA },
- { "NLG", CURRENCY_GUILDERS },
- { "NOK", CURRENCY_KRONA },
- { "SEK", CURRENCY_KRONA },
- { "DEK", CURRENCY_KRONA },
- { "EUR", CURRENCY_EUROS },
-
- { "\xA3", CURRENCY_POUNDS },
- { "\x24", CURRENCY_DOLLARS },
- { "\xA5", CURRENCY_YEN },
- { "\xB5", CURRENCY_EUROS }
-};
-
-typedef struct shortcut_entry{
+typedef struct shortcut_entry {
uint8 key;
uint8 modifier;
-}shortcut_entry;
+} shortcut_entry;
-//typedef struct hotkey_configuration{
+extern general_configuration gConfigGeneral;
+extern sound_configuration gConfigSound;
-//};
-extern general_configuration_t gGeneral_config;
-extern sound_configuration_t gSound_config;
+extern uint16 gShortcutKeys[SHORTCUT_COUNT];
+
+void config_set_defaults();
+bool config_open_default();
+bool config_save_default();
+
+void config_reset_shortcut_keys();
+bool config_find_or_browse_install_directory();
#endif
diff --git a/src/game.c b/src/game.c
index 47ce26f2ed..4d74314c5c 100644
--- a/src/game.c
+++ b/src/game.c
@@ -286,7 +286,7 @@ void game_update()
if (RCT2_GLOBAL(0x009AAC73, uint8) != 255) {
RCT2_GLOBAL(0x009AAC73, uint8)++;
if (RCT2_GLOBAL(0x009AAC73, uint8) == 255)
- config_save();
+ config_save_default();
}
}
@@ -784,7 +784,7 @@ char save_game()
// Ensure path has .SV6 extension
path_set_extension(path, ".SV6");
- if (scenario_save(path, gGeneral_config.save_plugin_data ? 1 : 0)) {
+ if (scenario_save(path, gConfigGeneral.save_plugin_data ? 1 : 0)) {
game_do_command(0, 1047, 0, -1, GAME_COMMAND_0, 0, 0);
gfx_invalidate_screen();
return 1;
diff --git a/src/input.c b/src/input.c
index e72a5fb393..1bf782fd4a 100644
--- a/src/input.c
+++ b/src/input.c
@@ -351,7 +351,7 @@ static void input_window_position_continue(rct_window *w, int wdx, int wdy, int
{
int snapProximity;
- snapProximity = w->flags & WF_NO_SNAPPING ? 0 : gGeneral_config.window_snap_proximity;
+ snapProximity = w->flags & WF_NO_SNAPPING ? 0 : gConfigGeneral.window_snap_proximity;
window_move_and_snap(w, x - wdx, y - wdy, snapProximity);
}
diff --git a/src/interface/keyboard_shortcut.c b/src/interface/keyboard_shortcut.c
index e6ff26cb8e..0dd3980dc8 100644
--- a/src/interface/keyboard_shortcut.c
+++ b/src/interface/keyboard_shortcut.c
@@ -50,7 +50,7 @@ void keyboard_shortcut_set(int key)
gShortcutKeys[RCT2_GLOBAL(0x009DE511, uint8)] = key;
window_close_by_class(WC_CHANGE_KEYBOARD_SHORTCUT);
window_invalidate_by_class(WC_KEYBOARD_SHORTCUT_LIST);
- config_save();
+ config_save_default();
}
/**
diff --git a/src/interface/screenshot.c b/src/interface/screenshot.c
index 9616dae9ae..13c2c1a571 100644
--- a/src/interface/screenshot.c
+++ b/src/interface/screenshot.c
@@ -50,7 +50,7 @@ void screenshot_check()
if (screenshotIndex != -1) {
char *lang_3165 = (char*)0x009BC677;
- sprintf(lang_3165, "SCR%d%s", screenshotIndex, _screenshot_format_extension[gGeneral_config.screenshot_format]);
+ sprintf(lang_3165, "SCR%d%s", screenshotIndex, _screenshot_format_extension[gConfigGeneral.screenshot_format]);
RCT2_GLOBAL(0x013CE952, uint16) = 3165;
// RCT2_GLOBAL(0x013CE952, uint16) = STR_SCR_BMP;
@@ -96,7 +96,7 @@ static int screenshot_get_next_path(char *path, int format)
int screenshot_dump()
{
- switch (gGeneral_config.screenshot_format) {
+ switch (gConfigGeneral.screenshot_format) {
case SCREENSHOT_FORMAT_BMP:
return screenshot_dump_bmp();
case SCREENSHOT_FORMAT_PNG:
diff --git a/src/interface/viewport.c b/src/interface/viewport.c
index 21ae7f1535..22c2657f65 100644
--- a/src/interface/viewport.c
+++ b/src/interface/viewport.c
@@ -174,7 +174,7 @@ void viewport_create(rct_window *w, int x, int y, int width, int height, int zoo
viewport->zoom = zoom;
viewport->flags = 0;
- if (gGeneral_config.always_show_gridlines)
+ if (gConfigGeneral.always_show_gridlines)
viewport->flags |= VIEWPORT_FLAG_GRIDLINES;
w->viewport = viewport;
@@ -1109,7 +1109,7 @@ void hide_gridlines()
RCT2_GLOBAL(0x009E32B0, uint8)--;
if (RCT2_GLOBAL(0x009E32B0, uint8) == 0) {
if ((mainWindow = window_get_main()) != NULL) {
- if (!gGeneral_config.always_show_gridlines) {
+ if (!gConfigGeneral.always_show_gridlines) {
mainWindow->viewport->flags &= ~VIEWPORT_FLAG_GRIDLINES;
window_invalidate(mainWindow);
}
diff --git a/src/localisation/localisation.c b/src/localisation/localisation.c
index f8dca641b0..4819fdaeed 100644
--- a/src/localisation/localisation.c
+++ b/src/localisation/localisation.c
@@ -277,7 +277,7 @@ void format_comma_separated_fixed_2dp(char **dest, long long value)
void format_currency(char **dest, long long value)
{
- const rct_currency_spec *currencySpec = &g_currency_specs[gGeneral_config.currency_format];
+ const rct_currency_spec *currencySpec = &g_currency_specs[gConfigGeneral.currency_format];
int rate = currencySpec->rate;
value *= rate;
@@ -309,7 +309,7 @@ void format_currency(char **dest, long long value)
void format_currency_2dp(char **dest, long long value)
{
- const rct_currency_spec *currencySpec = &g_currency_specs[gGeneral_config.currency_format];
+ const rct_currency_spec *currencySpec = &g_currency_specs[gConfigGeneral.currency_format];
int rate = currencySpec->rate;
value *= rate;
@@ -355,7 +355,7 @@ void format_length(char **dest, uint16 value)
{
rct_string_id stringId = 2733;
- if (gGeneral_config.measurement_format == MEASUREMENT_FORMAT_IMPERIAL) {
+ if (gConfigGeneral.measurement_format == MEASUREMENT_FORMAT_IMPERIAL) {
value = metres_to_feet(value);
stringId--;
}
@@ -368,7 +368,7 @@ void format_velocity(char **dest, uint16 value)
{
rct_string_id stringId = 2734;
- if (gGeneral_config.measurement_format == MEASUREMENT_FORMAT_METRIC) {
+ if (gConfigGeneral.measurement_format == MEASUREMENT_FORMAT_METRIC) {
value = mph_to_kmph(value);
stringId++;
}
diff --git a/src/openrct2.c b/src/openrct2.c
index 3934e3262b..7bbc3727fe 100644
--- a/src/openrct2.c
+++ b/src/openrct2.c
@@ -120,7 +120,15 @@ void openrct2_launch()
return;
}
- config_load();
+ config_set_defaults();
+ if (!config_open_default()) {
+ if (!config_find_or_browse_install_directory()) {
+ log_fatal("An RCT2 install directory must be specified!");
+ return;
+ }
+ }
+
+ config_save_default();
// TODO add configuration option to allow multiple instances
if (!platform_lock_single_instance()) {
@@ -132,7 +140,7 @@ void openrct2_launch()
audio_init();
audio_get_devices();
get_dsound_devices();
- language_open(gGeneral_config.language);
+ language_open(gConfigGeneral.language);
if (!rct2_init())
return;
diff --git a/src/platform/shared.c b/src/platform/shared.c
index 9e0053d686..24b30c1d43 100644
--- a/src/platform/shared.c
+++ b/src/platform/shared.c
@@ -120,9 +120,9 @@ void platform_update_fullscreen_resolutions()
gNumResolutions = (int)(resPlace - &gResolutions[0]) + 1;
// Update config fullscreen resolution if not set
- if (gGeneral_config.fullscreen_width == -1 || gGeneral_config.fullscreen_height == -1) {
- gGeneral_config.fullscreen_width = gResolutions[gNumResolutions - 1].width;
- gGeneral_config.fullscreen_height = gResolutions[gNumResolutions - 1].height;
+ if (gConfigGeneral.fullscreen_width == -1 || gConfigGeneral.fullscreen_height == -1) {
+ gConfigGeneral.fullscreen_width = gResolutions[gNumResolutions - 1].width;
+ gConfigGeneral.fullscreen_height = gResolutions[gNumResolutions - 1].height;
}
}
@@ -352,10 +352,10 @@ void platform_process_messages()
gLastKeyPressed = e.key.keysym.sym;
gKeysPressed[e.key.keysym.scancode] = 1;
if (e.key.keysym.sym == SDLK_RETURN && e.key.keysym.mod & KMOD_ALT) {
- int targetMode = gGeneral_config.fullscreen_mode == 0 ? 2 : 0;
+ int targetMode = gConfigGeneral.fullscreen_mode == 0 ? 2 : 0;
platform_set_fullscreen_mode(targetMode);
- gGeneral_config.fullscreen_mode = targetMode;
- config_save();
+ gConfigGeneral.fullscreen_mode = targetMode;
+ config_save_default();
break;
}
@@ -473,8 +473,8 @@ static void platform_create_window()
RCT2_CALLPROC_EBPSAFE(0x0068371D);
// Get window size
- width = gGeneral_config.window_width;
- height = gGeneral_config.window_height;
+ width = gConfigGeneral.window_width;
+ height = gConfigGeneral.window_height;
if (width == -1) width = 640;
if (height == -1) height = 480;
@@ -496,7 +496,7 @@ static void platform_create_window()
platform_resize(width, height);
platform_update_fullscreen_resolutions();
- platform_set_fullscreen_mode(gGeneral_config.fullscreen_mode);
+ platform_set_fullscreen_mode(gConfigGeneral.fullscreen_mode);
}
int platform_scancode_to_rct_keycode(int sdl_key)
@@ -555,10 +555,10 @@ void platform_set_fullscreen_mode(int mode)
// Set window size
if (mode == SDL_WINDOW_FULLSCREEN) {
platform_update_fullscreen_resolutions();
- platform_get_closest_resolution(gGeneral_config.fullscreen_width, gGeneral_config.fullscreen_height, &width, &height);
+ platform_get_closest_resolution(gConfigGeneral.fullscreen_width, gConfigGeneral.fullscreen_height, &width, &height);
SDL_SetWindowSize(gWindow, width, height);
} else if (mode == 0) {
- SDL_SetWindowSize(gWindow, gGeneral_config.window_width, gGeneral_config.window_height);
+ SDL_SetWindowSize(gWindow, gConfigGeneral.window_width, gConfigGeneral.window_height);
}
if (SDL_SetWindowFullscreen(gWindow, mode)) {
diff --git a/src/rct2.c b/src/rct2.c
index db2247fc84..f3b0f112e4 100644
--- a/src/rct2.c
+++ b/src/rct2.c
@@ -57,7 +57,7 @@ static void rct2_update_2();
static jmp_buf _end_update_jump;
void rct2_quit() {
- if (gGeneral_config.confirmation_prompt) {
+ if (gConfigGeneral.confirmation_prompt) {
RCT2_GLOBAL(RCT2_ADDRESS_SAVE_PROMPT_MODE, uint16) = PM_QUIT;
window_save_prompt_open();
} else
@@ -116,7 +116,7 @@ int rct2_init()
title_load();
gfx_clear(RCT2_ADDRESS(RCT2_ADDRESS_SCREEN_DPI, rct_drawpixelinfo), 10);
- RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) = gGeneral_config.play_intro ? 8 : 255;
+ RCT2_GLOBAL(RCT2_ADDRESS_RUN_INTRO_TICK_PART, uint8) = gConfigGeneral.play_intro ? 8 : 255;
log_verbose("initialising game finished");
return 1;
@@ -131,15 +131,15 @@ int rct2_init_directories()
// windows_get_registry_install_info((rct2_install_info*)0x009AA10C, "RollerCoaster Tycoon 2 Setup", "MS Sans Serif", 0);
// check install directory
- if (!platform_directory_exists(gGeneral_config.game_path)) {
- log_verbose("install directory does not exist, %s", gGeneral_config.game_path);
+ if (!platform_directory_exists(gConfigGeneral.game_path)) {
+ log_verbose("install directory does not exist, %s", gConfigGeneral.game_path);
if (!config_find_or_browse_install_directory()) {
log_fatal("Invalid RCT2 installation path. Please correct in config.ini.");
return 0;
}
}
- strcpy(RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char), gGeneral_config.game_path);
+ strcpy(RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char), gConfigGeneral.game_path);
strcpy(RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH_SLASH, char), RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH, char));
strcat(RCT2_ADDRESS(RCT2_ADDRESS_APP_PATH_SLASH, char), "\\");
@@ -360,7 +360,7 @@ const char *get_file_path(int pathId)
// The original implementation checks if the file is on CD-ROM here (file_on_cdrom[pathId] @ 0x009AA0B1).
// If so, the CD-ROM path (cdrom_path @ 0x9AA318) is used instead. This has been removed for now for
// the sake of simplicity.
- strcpy(path, gGeneral_config.game_path);
+ strcpy(path, gConfigGeneral.game_path);
// Make sure base path is terminated with a slash
if (strlen(path) == 0 || path[strlen(path) - 1] != '\\')
diff --git a/src/rct2.h b/src/rct2.h
index 0b035a6aea..f3821a7adb 100644
--- a/src/rct2.h
+++ b/src/rct2.h
@@ -44,8 +44,9 @@ typedef unsigned long uint32;
typedef unsigned long long uint64;
typedef char utf8;
-typedef wchar_t utf16;
typedef utf8* utf8string;
+typedef const utf8* const_utf8string;
+typedef wchar_t utf16;
typedef utf16* utf16string;
#define rol8(x, shift) (((uint8)(x) << (shift)) | ((uint8)(x) >> (8 - (shift))))
diff --git a/src/title.c b/src/title.c
index 4adfd8c253..d1daa1eb9a 100644
--- a/src/title.c
+++ b/src/title.c
@@ -295,7 +295,7 @@ void title_update()
if (RCT2_GLOBAL(0x009AAC73, uint8) != 255) {
RCT2_GLOBAL(0x009AAC73, uint8)++;
if (RCT2_GLOBAL(0x009AAC73, uint8) == 255)
- config_save();
+ config_save_default();
}
}
diff --git a/src/windows/editor_bottom_toolbar.c b/src/windows/editor_bottom_toolbar.c
index 0dce89ebbe..bb47d470a1 100644
--- a/src/windows/editor_bottom_toolbar.c
+++ b/src/windows/editor_bottom_toolbar.c
@@ -317,7 +317,7 @@ void window_editor_bottom_toolbar_jump_forward_to_save_scenario()
// Save the scenario
parkFlagsBackup = RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32);
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) &= ~PARK_FLAGS_18;
- success = scenario_save(path, gGeneral_config.save_plugin_data ? 3 : 2);
+ success = scenario_save(path, gConfigGeneral.save_plugin_data ? 3 : 2);
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) = parkFlagsBackup;
if (success) {
diff --git a/src/windows/loadsave.c b/src/windows/loadsave.c
index a755cc1cd8..fa4be0c4d5 100644
--- a/src/windows/loadsave.c
+++ b/src/windows/loadsave.c
@@ -577,7 +577,7 @@ static void window_loadsave_select(rct_window *w, const char *path)
}
break;
case (LOADSAVETYPE_SAVE | LOADSAVETYPE_GAME) :
- if (scenario_save((char*)path, gGeneral_config.save_plugin_data ? 1 : 0)) {
+ if (scenario_save((char*)path, gConfigGeneral.save_plugin_data ? 1 : 0)) {
window_close(w);
game_do_command(0, 1047, 0, -1, GAME_COMMAND_0, 0, 0);
@@ -599,7 +599,7 @@ static void window_loadsave_select(rct_window *w, const char *path)
}
break;
case (LOADSAVETYPE_SAVE | LOADSAVETYPE_LANDSCAPE) :
- if (scenario_save((char*)path, gGeneral_config.save_plugin_data ? 3 : 2)) {
+ if (scenario_save((char*)path, gConfigGeneral.save_plugin_data ? 3 : 2)) {
window_close(w);
gfx_invalidate_screen();
}
@@ -613,7 +613,7 @@ static void window_loadsave_select(rct_window *w, const char *path)
int parkFlagsBackup = RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32);
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) &= ~PARK_FLAGS_18;
s6Info->var_000 = 255;
- int success = scenario_save((char*)path, gGeneral_config.save_plugin_data ? 3 : 2);
+ int success = scenario_save((char*)path, gConfigGeneral.save_plugin_data ? 3 : 2);
RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) = parkFlagsBackup;
if (success) {
diff --git a/src/windows/options.c b/src/windows/options.c
index 61527ed013..fd09d4ef58 100644
--- a/src/windows/options.c
+++ b/src/windows/options.c
@@ -293,8 +293,8 @@ static void window_options_mouseup()
window_shortcut_keys_open();
break;
case WIDX_SCREEN_EDGE_SCROLLING:
- gGeneral_config.edge_scrolling ^= 1;
- config_save();
+ gConfigGeneral.edge_scrolling ^= 1;
+ config_save_default();
window_invalidate(w);
break;
case WIDX_REAL_NAME_CHECKBOX:
@@ -302,30 +302,30 @@ static void window_options_mouseup()
RCT2_CALLPROC_X(0x0069C52F, RCT2_GLOBAL(RCT2_ADDRESS_PARK_FLAGS, uint32) & PARK_FLAGS_SHOW_REAL_GUEST_NAMES ? 0 : 1, 0, 0, 0, 0, 0, 0);
break;
case WIDX_TILE_SMOOTHING_CHECKBOX:
- gGeneral_config.landscape_smoothing ^= 1;
- config_save();
+ gConfigGeneral.landscape_smoothing ^= 1;
+ config_save_default();
gfx_invalidate_screen();
break;
case WIDX_GRIDLINES_CHECKBOX:
- gGeneral_config.always_show_gridlines ^= 1;
- config_save();
+ gConfigGeneral.always_show_gridlines ^= 1;
+ config_save_default();
gfx_invalidate_screen();
if ((w = window_get_main()) != NULL) {
- if (gGeneral_config.always_show_gridlines)
+ if (gConfigGeneral.always_show_gridlines)
w->viewport->flags |= VIEWPORT_FLAG_GRIDLINES;
else
w->viewport->flags &= ~VIEWPORT_FLAG_GRIDLINES;
}
break;
case WIDX_SAVE_PLUGIN_DATA_CHECKBOX:
- gGeneral_config.save_plugin_data ^= 1;
- config_save();
+ gConfigGeneral.save_plugin_data ^= 1;
+ config_save_default();
window_invalidate(w);
break;
case WIDX_SOUND_SW_BUFFER_CHECKBOX:
pause_sounds();
- gSound_config.forced_software_buffering ^= 1;
- config_save();
+ gConfigSound.forced_software_buffering ^= 1;
+ config_save_default();
unpause_sounds();
window_invalidate(w);
break;
@@ -369,7 +369,7 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
window_options_show_dropdown(w, widget, 2);
- gDropdownItemsChecked = gGeneral_config.show_height_as_units ? 1 : 2;
+ gDropdownItemsChecked = gConfigGeneral.show_height_as_units ? 1 : 2;
break;
case WIDX_MUSIC_DROPDOWN:
gDropdownItemsFormat[0] = 1142;
@@ -391,7 +391,7 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
window_options_show_dropdown(w, widget, num_items);
- gDropdownItemsChecked = 1 << gSound_config.sound_quality;
+ gDropdownItemsChecked = 1 << gConfigSound.sound_quality;
break;
case WIDX_TITLE_MUSIC_DROPDOWN:
num_items = 3;
@@ -403,7 +403,7 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
window_options_show_dropdown(w, widget, num_items);
- gDropdownItemsChecked = 1 << gGeneral_config.title_music;
+ gDropdownItemsChecked = 1 << gConfigSound.title_music;
break;
case WIDX_CURRENCY_DROPDOWN:
num_items = 10;
@@ -415,7 +415,7 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
window_options_show_dropdown(w, widget, num_items);
- gDropdownItemsChecked = 1 << gGeneral_config.currency_format;
+ gDropdownItemsChecked = 1 << gConfigGeneral.currency_format;
break;
case WIDX_DISTANCE_DROPDOWN:
gDropdownItemsFormat[0] = 1142;
@@ -425,7 +425,7 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
window_options_show_dropdown(w, widget, 2);
- gDropdownItemsChecked = 1 << gGeneral_config.measurement_format;
+ gDropdownItemsChecked = 1 << gConfigGeneral.measurement_format;
break;
case WIDX_RESOLUTION_DROPDOWN:
{
@@ -442,7 +442,7 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
args[1] = resolution->width;
args[2] = resolution->height;
- if (resolution->width == gGeneral_config.fullscreen_width && resolution->height == gGeneral_config.fullscreen_height)
+ if (resolution->width == gConfigGeneral.fullscreen_width && resolution->height == gConfigGeneral.fullscreen_height)
selectedResolution = i;
}
@@ -463,7 +463,7 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
window_options_show_dropdown(w, widget, 3);
- gDropdownItemsChecked = 1 << gGeneral_config.fullscreen_mode;
+ gDropdownItemsChecked = 1 << gConfigGeneral.fullscreen_mode;
break;
case WIDX_TEMPERATURE_DROPDOWN:
gDropdownItemsFormat[0] = 1142;
@@ -473,7 +473,7 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
window_options_show_dropdown(w, widget, 2);
- gDropdownItemsChecked = 1 << gGeneral_config.temperature_format;
+ gDropdownItemsChecked = 1 << gConfigGeneral.temperature_format;
break;
case WIDX_CONSTRUCTION_MARKER_DROPDOWN:
gDropdownItemsFormat[0] = 1142;
@@ -483,7 +483,7 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget*
window_options_show_dropdown(w, widget, 2);
- gDropdownItemsChecked = 1 << gGeneral_config.construction_marker_colour;
+ gDropdownItemsChecked = 1 << gConfigGeneral.construction_marker_colour;
break;
case WIDX_LANGUAGE_DROPDOWN:
for (i = 1; i < LANGUAGE_COUNT; i++) {
@@ -536,64 +536,64 @@ static void window_options_dropdown()
case WIDX_HEIGHT_LABELS_DROPDOWN:
// reset flag and set it to 1 if height as units is selected
RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) &= ~CONFIG_FLAG_SHOW_HEIGHT_AS_UNITS;
- gGeneral_config.show_height_as_units = 0;
+ gConfigGeneral.show_height_as_units = 0;
if (dropdownIndex == 0) {
RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) |= CONFIG_FLAG_SHOW_HEIGHT_AS_UNITS;
- gGeneral_config.show_height_as_units = 1;
+ gConfigGeneral.show_height_as_units = 1;
}
window_options_update_height_markers();
break;
case WIDX_MUSIC_DROPDOWN:
RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_MUSIC, uint8) = (uint8)dropdownIndex;
- config_save();
+ config_save_default();
stop_ride_music();//RCT2_CALLPROC_EBPSAFE(0x006BCA9F);
window_invalidate(w);
break;
case WIDX_SOUND_QUALITY_DROPDOWN:
RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_MAX_VEHICLE_SOUNDS, uint8) = RCT2_GLOBAL(0x009AF601 + dropdownIndex, uint8);
RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_MAX_NO_SOUNDS, uint8) = RCT2_GLOBAL(0x009AF604 + dropdownIndex, uint8);
- gSound_config.sound_quality = (sint8)dropdownIndex;
- config_save();
+ gConfigSound.sound_quality = (sint8)dropdownIndex;
+ config_save_default();
window_invalidate(w);
break;
case WIDX_TITLE_MUSIC_DROPDOWN:
if (dropdownIndex == 1 && !platform_file_exists(get_file_path(PATH_ID_CSS50))) {
window_error_open(2742, 2743);
} else {
- gGeneral_config.title_music = (sint8)dropdownIndex;
- config_save();
+ gConfigSound.title_music = (sint8)dropdownIndex;
+ config_save_default();
window_invalidate(w);
}
break;
case WIDX_CURRENCY_DROPDOWN:
- gGeneral_config.currency_format = (sint8)dropdownIndex;
- config_save();
+ gConfigGeneral.currency_format = (sint8)dropdownIndex;
+ config_save_default();
gfx_invalidate_screen();
break;
case WIDX_DISTANCE_DROPDOWN:
- gGeneral_config.measurement_format = (sint8)dropdownIndex;
- config_save();
+ gConfigGeneral.measurement_format = (sint8)dropdownIndex;
+ config_save_default();
window_options_update_height_markers();
break;
case WIDX_RESOLUTION_DROPDOWN:
{
resolution *resolution = &gResolutions[dropdownIndex];
- if (resolution->width != gGeneral_config.fullscreen_width || resolution->height != gGeneral_config.fullscreen_height) {
- gGeneral_config.fullscreen_width = resolution->width;
- gGeneral_config.fullscreen_height = resolution->height;
+ if (resolution->width != gConfigGeneral.fullscreen_width || resolution->height != gConfigGeneral.fullscreen_height) {
+ gConfigGeneral.fullscreen_width = resolution->width;
+ gConfigGeneral.fullscreen_height = resolution->height;
- if (gGeneral_config.fullscreen_mode == SDL_WINDOW_FULLSCREEN)
+ if (gConfigGeneral.fullscreen_mode == SDL_WINDOW_FULLSCREEN)
platform_set_fullscreen_mode(SDL_WINDOW_FULLSCREEN);
- config_save();
+ config_save_default();
gfx_invalidate_screen();
}
}
break;
case WIDX_FULLSCREEN_DROPDOWN:
- if (dropdownIndex != gGeneral_config.fullscreen_mode){
+ if (dropdownIndex != gConfigGeneral.fullscreen_mode){
if (dropdownIndex == 2){
w->disabled_widgets |= (1 << WIDX_RESOLUTION_DROPDOWN);
w->disabled_widgets |= (1 << WIDX_RESOLUTION);
@@ -603,29 +603,29 @@ static void window_options_dropdown()
}
platform_set_fullscreen_mode(dropdownIndex);
- gGeneral_config.fullscreen_mode = (uint8)dropdownIndex;
- config_save();
+ gConfigGeneral.fullscreen_mode = (uint8)dropdownIndex;
+ config_save_default();
}
break;
case WIDX_TEMPERATURE_DROPDOWN:
- if (dropdownIndex != gGeneral_config.temperature_format) {
- gGeneral_config.temperature_format = (sint8)dropdownIndex;
- config_save();
+ if (dropdownIndex != gConfigGeneral.temperature_format) {
+ gConfigGeneral.temperature_format = (sint8)dropdownIndex;
+ config_save_default();
gfx_invalidate_screen();
}
break;
case WIDX_CONSTRUCTION_MARKER_DROPDOWN:
- if (dropdownIndex != gGeneral_config.construction_marker_colour) {
- gGeneral_config.construction_marker_colour = (uint8)dropdownIndex;
- config_save();
+ if (dropdownIndex != gConfigGeneral.construction_marker_colour) {
+ gConfigGeneral.construction_marker_colour = (uint8)dropdownIndex;
+ config_save_default();
gfx_invalidate_screen();
}
break;
case WIDX_LANGUAGE_DROPDOWN:
if (dropdownIndex != gCurrentLanguage - 1) {
language_open(dropdownIndex + 1);
- gGeneral_config.language = dropdownIndex + 1;
- config_save();
+ gConfigGeneral.language = dropdownIndex + 1;
+ config_save_default();
gfx_invalidate_screen();
}
break;
@@ -652,9 +652,9 @@ static void window_options_invalidate()
switch (w->page) {
case WINDOW_OPTIONS_PAGE_DISPLAY:
// resolution
- RCT2_GLOBAL(0x013CE952 + 16, uint16) = gGeneral_config.fullscreen_width;
- RCT2_GLOBAL(0x013CE952 + 18, uint16) = gGeneral_config.fullscreen_height;
- RCT2_GLOBAL(0x013CE952 + 12, uint16) = 2773 + gGeneral_config.fullscreen_mode;
+ RCT2_GLOBAL(0x013CE952 + 16, uint16) = (uint16)gConfigGeneral.fullscreen_width;
+ RCT2_GLOBAL(0x013CE952 + 18, uint16) = (uint16)gConfigGeneral.fullscreen_height;
+ RCT2_GLOBAL(0x013CE952 + 12, uint16) = 2773 + gConfigGeneral.fullscreen_mode;
// landscape tile smoothing checkbox
if ((RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_FLAGS, uint8) & CONFIG_FLAG_DISABLE_SMOOTH_LANDSCAPE))
@@ -682,16 +682,16 @@ static void window_options_invalidate()
break;
case WINDOW_OPTIONS_PAGE_CULTURE:
// currency: pounds, dollars, etc. (10 total)
- RCT2_GLOBAL(0x013CE952 + 12, uint16) = STR_POUNDS + gGeneral_config.currency_format;
+ RCT2_GLOBAL(0x013CE952 + 12, uint16) = STR_POUNDS + gConfigGeneral.currency_format;
// distance: metric/imperial
- RCT2_GLOBAL(0x013CE952 + 14, uint16) = STR_IMPERIAL + gGeneral_config.measurement_format;
+ RCT2_GLOBAL(0x013CE952 + 14, uint16) = STR_IMPERIAL + gConfigGeneral.measurement_format;
// temperature: celsius/fahrenheit
- RCT2_GLOBAL(0x013CE952 + 20, uint16) = STR_CELSIUS + gGeneral_config.temperature_format;
+ RCT2_GLOBAL(0x013CE952 + 20, uint16) = STR_CELSIUS + gConfigGeneral.temperature_format;
// height: units/real values
- RCT2_GLOBAL(0x013CE952 + 6, uint16) = gGeneral_config.show_height_as_units ? STR_UNITS : STR_REAL_VALUES;
+ RCT2_GLOBAL(0x013CE952 + 6, uint16) = gConfigGeneral.show_height_as_units ? STR_UNITS : STR_REAL_VALUES;
window_options_widgets[WIDX_LANGUAGE].type = WWT_DROPDOWN;
window_options_widgets[WIDX_LANGUAGE_DROPDOWN].type = WWT_DROPDOWN_BUTTON;
@@ -719,7 +719,7 @@ static void window_options_invalidate()
RCT2_GLOBAL(0x013CE952 + 8, uint16) = STR_OFF + RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_MUSIC, uint8);
// sound quality: low/medium/high
- RCT2_GLOBAL(0x013CE952 + 10, uint16) = STR_SOUND_LOW + gSound_config.sound_quality;
+ RCT2_GLOBAL(0x013CE952 + 10, uint16) = STR_SOUND_LOW + gConfigSound.sound_quality;
//Sound pause checkbox
if (!g_sounds_disabled)
@@ -728,7 +728,7 @@ static void window_options_invalidate()
w->pressed_widgets &= ~(1ULL << WIDX_SOUND_PAUSED_CHECKBOX);
// sound software mixing buffer checkbox
- if (gSound_config.forced_software_buffering)
+ if (gConfigSound.forced_software_buffering)
w->pressed_widgets |= (1ULL << WIDX_SOUND_SW_BUFFER_CHECKBOX);
else
w->pressed_widgets &= ~(1ULL << WIDX_SOUND_SW_BUFFER_CHECKBOX);
@@ -746,7 +746,7 @@ static void window_options_invalidate()
break;
case WINDOW_OPTIONS_PAGE_INPUT:
// screen edge scrolling checkbox
- if (gGeneral_config.edge_scrolling)
+ if (gConfigGeneral.edge_scrolling)
w->pressed_widgets |= (1ULL << WIDX_SCREEN_EDGE_SCROLLING);
else
w->pressed_widgets &= ~(1ULL << WIDX_SCREEN_EDGE_SCROLLING);
@@ -762,7 +762,7 @@ static void window_options_invalidate()
w->pressed_widgets &= ~(1ULL << WIDX_REAL_NAME_CHECKBOX);
// save plugin data checkbox
- if (gGeneral_config.save_plugin_data)
+ if (gConfigGeneral.save_plugin_data)
w->pressed_widgets |= (1ULL << WIDX_SAVE_PLUGIN_DATA_CHECKBOX);
else
w->pressed_widgets &= ~(1ULL << WIDX_SAVE_PLUGIN_DATA_CHECKBOX);
@@ -835,7 +835,7 @@ static void window_options_paint()
gfx_draw_string_left(dpi, 2738, w, 12, w->x + 10, w->y + window_options_widgets[WIDX_TITLE_MUSIC].top + 1);
gfx_draw_string_left(
dpi,
- 2739 + gGeneral_config.title_music,
+ 2739 + gConfigSound.title_music,
NULL,
12,
w->x + window_options_widgets[WIDX_TITLE_MUSIC].left + 1,
@@ -861,9 +861,9 @@ static void window_options_show_dropdown(rct_window *w, rct_widget *widget, int
static void window_options_update_height_markers()
{
- RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_HEIGHT_MARKERS, uint16) = gGeneral_config.show_height_as_units ?
- 0 : (gGeneral_config.measurement_format + 1) * 256;
- config_save();
+ RCT2_GLOBAL(RCT2_ADDRESS_CONFIG_HEIGHT_MARKERS, uint16) = gConfigGeneral.show_height_as_units ?
+ 0 : (gConfigGeneral.measurement_format + 1) * 256;
+ config_save_default();
gfx_invalidate_screen();
}
diff --git a/src/windows/save_prompt.c b/src/windows/save_prompt.c
index f849e37bbd..b9c2baa79e 100644
--- a/src/windows/save_prompt.c
+++ b/src/windows/save_prompt.c
@@ -174,7 +174,7 @@ void window_save_prompt_open()
window_save_prompt_widgets[WIDX_TITLE].image = stringId;
window_save_prompt_widgets[WIDX_LABEL].image = prompt_mode + STR_SAVE_BEFORE_LOADING;
- if (!gGeneral_config.confirmation_prompt) {
+ if (!gConfigGeneral.confirmation_prompt) {
/* game_load_or_quit_no_save_prompt() will exec requested task and close this window
* immediately again.
* TODO restructure these functions when we're sure game_load_or_quit_no_save_prompt()
diff --git a/src/windows/shortcut_keys.c b/src/windows/shortcut_keys.c
index 509dc02afa..a9a34d3f7d 100644
--- a/src/windows/shortcut_keys.c
+++ b/src/windows/shortcut_keys.c
@@ -128,7 +128,7 @@ static void window_shortcut_mouseup()
break;
case WIDX_RESET:
config_reset_shortcut_keys();
- config_save();
+ config_save_default();
window_invalidate(w);
break;
}