From a3df2527b068600b5cc1f7773dd98119d0cc5100 Mon Sep 17 00:00:00 2001 From: IntelOrca Date: Sat, 21 Feb 2015 11:05:15 +0000 Subject: [PATCH] implement autosaving, closes #778 --- data/language/english_uk.txt | 14 ++++++------- src/config.c | 1 + src/config.h | 10 ++++++++++ src/game.c | 10 ++++++++++ src/game.h | 1 + src/scenario.c | 33 +++++++++++++++++++++++++++++++ src/windows/options.c | 38 ++++++++++++++++++++++++++++++++++-- 7 files changed, 98 insertions(+), 9 deletions(-) diff --git a/data/language/english_uk.txt b/data/language/english_uk.txt index c54554b3d2..b0c6413336 100644 --- a/data/language/english_uk.txt +++ b/data/language/english_uk.txt @@ -2702,13 +2702,13 @@ STR_2696 :Place trees STR_2697 :??? STR_2698 :??? STR_2699 :??? -STR_2700 :??? -STR_2701 :??? -STR_2702 :??? -STR_2703 :??? -STR_2704 :??? -STR_2705 :??? -STR_2706 :??? +STR_2700 :Autosave frequency +STR_2701 :Every week +STR_2702 :Every 2 weeks +STR_2703 :Every month +STR_2704 :Every 4 months +STR_2705 :Every year +STR_2706 :Never STR_2707 :Open new window STR_2708 :{WINDOW_COLOUR_1}Are you sure you want to overwrite {STRINGID}? STR_2709 :Overwrite diff --git a/src/config.c b/src/config.c index 9cb38dc80f..9b5d4a2b0f 100644 --- a/src/config.c +++ b/src/config.c @@ -140,6 +140,7 @@ config_enum_definition _languageEnum[] = { config_property_definition _generalDefinitions[] = { { offsetof(general_configuration, always_show_gridlines), "always_show_gridlines", CONFIG_VALUE_TYPE_BOOLEAN, false, NULL }, + { offsetof(general_configuration, autosave_frequency), "autosave", CONFIG_VALUE_TYPE_UINT8, AUTOSAVE_EVERY_MONTH, 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 }, diff --git a/src/config.h b/src/config.h index 1ab8935edf..c42215fea9 100644 --- a/src/config.h +++ b/src/config.h @@ -96,6 +96,15 @@ enum{ }; +enum { + AUTOSAVE_EVERY_WEEK, + AUTOSAVE_EVERY_2_WEEKS, + AUTOSAVE_EVERY_MONTH, + AUTOSAVE_EVERY_4_MONTHS, + AUTOSAVE_EVERY_YEAR, + AUTOSAVE_NEVER +}; + typedef struct general_configuration { uint8 play_intro; uint8 confirmation_prompt; @@ -119,6 +128,7 @@ typedef struct general_configuration { sint32 window_height; uint16 language; uint8 window_snap_proximity; + uint8 autosave_frequency; } general_configuration; typedef struct sound_configuration { diff --git a/src/game.c b/src/game.c index 3053fd4279..e6ee7a00aa 100644 --- a/src/game.c +++ b/src/game.c @@ -793,6 +793,16 @@ char save_game() } } +void game_autosave() +{ + char path[MAX_PATH]; + + platform_get_user_directory(path, "save"); + strcat(path, "autosave.sv6"); + + scenario_save(path, 0); +} + /** * * rct2: 0x006E3879 diff --git a/src/game.h b/src/game.h index 94f54a81a2..87fe2016b7 100644 --- a/src/game.h +++ b/src/game.h @@ -109,5 +109,6 @@ int game_load_save(const char *path); void game_pause_toggle(int *eax, int *ebx, int *ecx, int *edx, int *esi, int *edi, int *ebp); char save_game(); void rct2_exit(); +void game_autosave(); #endif diff --git a/src/scenario.c b/src/scenario.c index 7609e3d68c..0174f17119 100644 --- a/src/scenario.c +++ b/src/scenario.c @@ -19,6 +19,7 @@ *****************************************************************************/ #include "addresses.h" +#include "config.h" #include "game.h" #include "interface/viewport.h" #include "localisation/date.h" @@ -616,6 +617,36 @@ void scenario_entrance_fee_too_high_check() } } +static void scenario_autosave_check() +{ + uint32 next_month_tick = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_TICKS, uint16) + 4; + uint16 month = RCT2_GLOBAL(RCT2_ADDRESS_CURRENT_MONTH_YEAR, uint16); + bool shouldSave = 0; + + switch (gConfigGeneral.autosave_frequency) { + case AUTOSAVE_EVERY_WEEK: + shouldSave = (next_month_tick % 0x4000 == 0); + break; + case AUTOSAVE_EVERY_2_WEEKS: + shouldSave = (next_month_tick % 0x8000 == 0); + break; + case AUTOSAVE_EVERY_MONTH: + shouldSave = (next_month_tick >= 0x10000); + break; + case AUTOSAVE_EVERY_4_MONTHS: + if (next_month_tick >= 0x10000) + shouldSave = (((month + 1) & 3) == 0); + break; + case AUTOSAVE_EVERY_YEAR: + if (next_month_tick >= 0x10000) + shouldSave = (((month + 1) & 7) == 0); + break; + } + + if (shouldSave) + game_autosave(); +} + /* * Scenario and finance related update iteration. * rct2: 0x006C44B1 @@ -632,6 +663,8 @@ void scenario_update() if (screen_flags & (~SCREEN_FLAGS_PLAYING)) // only in normal play mode return; + scenario_autosave_check(); + if ((current_days_in_month * next_month_tick) >> 16 != (current_days_in_month * month_tick) >> 16) { // daily checks finance_update_daily_profit(); diff --git a/src/windows/options.c b/src/windows/options.c index 2bcd8cf8bd..3b2eccdbeb 100644 --- a/src/windows/options.c +++ b/src/windows/options.c @@ -96,6 +96,8 @@ enum WINDOW_OPTIONS_WIDGET_IDX { WIDX_REAL_NAME_CHECKBOX, WIDX_SAVE_PLUGIN_DATA_CHECKBOX, + WIDX_AUTOSAVE, + WIDX_AUTOSAVE_DROPDOWN }; #define WW 310 @@ -153,6 +155,8 @@ static rct_widget window_options_widgets[] = { // Misc { WWT_CHECKBOX, 2, 10, 299, 53, 64, STR_REAL_NAME, STR_REAL_NAME_TIP }, { WWT_CHECKBOX, 2, 10, 299, 68, 79, STR_SAVE_PLUGIN_DATA, STR_SAVE_PLUGIN_DATA_TIP }, + { WWT_DROPDOWN, 0, 155, 299, 83, 94, STR_NONE, STR_NONE }, + { WWT_DROPDOWN_BUTTON, 0, 288, 298, 84, 93, 876, STR_NONE }, { WIDGETS_END }, }; @@ -258,7 +262,9 @@ void window_options_open() (1ULL << WIDX_GRIDLINES_CHECKBOX) | (1ULL << WIDX_SOUND_SW_BUFFER_CHECKBOX) | (1ULL << WIDX_SOUND_PAUSED_CHECKBOX) | - (1ULL << WIDX_SAVE_PLUGIN_DATA_CHECKBOX); // doesn't seem to work? + (1ULL << WIDX_SAVE_PLUGIN_DATA_CHECKBOX) | + (1ULL << WIDX_AUTOSAVE) | + (1ULL << WIDX_AUTOSAVE_DROPDOWN); w->page = WINDOW_OPTIONS_PAGE_DISPLAY; window_init_scroll_widgets(w); @@ -493,6 +499,14 @@ static void window_options_mousedown(int widgetIndex, rct_window*w, rct_widget* window_options_show_dropdown(w, widget, LANGUAGE_COUNT - 1); gDropdownItemsChecked = 1 << (gCurrentLanguage - 1); break; + case WIDX_AUTOSAVE_DROPDOWN: + for (i = AUTOSAVE_EVERY_WEEK; i <= AUTOSAVE_NEVER; i++) { + gDropdownItemsFormat[i] = 1142; + gDropdownItemsArgs[i] = 2701 + i; + } + window_options_show_dropdown(w, widget, AUTOSAVE_NEVER + 1); + gDropdownItemsChecked = 1 << gConfigGeneral.autosave_frequency; + break; } } @@ -627,6 +641,13 @@ static void window_options_dropdown() gfx_invalidate_screen(); } break; + case WIDX_AUTOSAVE_DROPDOWN: + if (dropdownIndex != gConfigGeneral.autosave_frequency) { + gConfigGeneral.autosave_frequency = (uint8)dropdownIndex; + config_save_default(); + window_invalidate(w); + } + break; } } @@ -643,7 +664,7 @@ static void window_options_invalidate() window_get_register(w); window_options_set_pressed_tab(w); - for (i = WIDX_RESOLUTION; i <= WIDX_SAVE_PLUGIN_DATA_CHECKBOX; i++) { + for (i = WIDX_RESOLUTION; i <= WIDX_AUTOSAVE_DROPDOWN; i++) { window_options_widgets[i].type = WWT_EMPTY; } @@ -787,6 +808,8 @@ static void window_options_invalidate() window_options_widgets[WIDX_REAL_NAME_CHECKBOX].type = WWT_CHECKBOX; window_options_widgets[WIDX_SAVE_PLUGIN_DATA_CHECKBOX].type = WWT_CHECKBOX; + window_options_widgets[WIDX_AUTOSAVE].type = WWT_DROPDOWN; + window_options_widgets[WIDX_AUTOSAVE_DROPDOWN].type = WWT_DROPDOWN_BUTTON; break; } } @@ -850,6 +873,17 @@ static void window_options_paint() w->y + window_options_widgets[WIDX_TITLE_MUSIC].top ); break; + case WINDOW_OPTIONS_PAGE_MISC: + gfx_draw_string_left(dpi, 2700, w, 12, w->x + 10, w->y + window_options_widgets[WIDX_AUTOSAVE].top + 1); + gfx_draw_string_left( + dpi, + 2701 + gConfigGeneral.autosave_frequency, + NULL, + 12, + w->x + window_options_widgets[WIDX_AUTOSAVE].left + 1, + w->y + window_options_widgets[WIDX_AUTOSAVE].top + ); + break; } }