diff --git a/source/duke3d/src/config.cpp b/source/duke3d/src/config.cpp index b3ef522b7..fe265fef5 100644 --- a/source/duke3d/src/config.cpp +++ b/source/duke3d/src/config.cpp @@ -282,6 +282,8 @@ void CONFIG_SetDefaults(void) ud.menu_scrollbarz = 65536; ud.menu_scrollcursorz = 65536; ud.autosave = 1; + ud.autosavedeletion = 1; + ud.maxautosaves = 5; ud.config.CheckForUpdates = 1; diff --git a/source/duke3d/src/game.h b/source/duke3d/src/game.h index 48ae14996..d34c15413 100644 --- a/source/duke3d/src/game.h +++ b/source/duke3d/src/game.h @@ -190,6 +190,7 @@ typedef struct { int32_t default_volume, default_skill; int32_t autosave; + int32_t autosavedeletion, maxautosaves; int32_t returnvar[MAX_RETURN_VALUES-1]; diff --git a/source/duke3d/src/menus.cpp b/source/duke3d/src/menus.cpp index 919b8feca..2bd1c482c 100644 --- a/source/duke3d/src/menus.cpp +++ b/source/duke3d/src/menus.cpp @@ -1218,8 +1218,15 @@ static MenuEntry_t *MEL_ADVSOUND[] = { static MenuOption_t MEO_SAVESETUP_AUTOSAVE = MAKE_MENUOPTION( &MF_Redfont, &MEOS_OffOn, &ud.autosave ); static MenuEntry_t ME_SAVESETUP_AUTOSAVE = MAKE_MENUENTRY( "Autosaves:", &MF_Redfont, &MEF_BigOptionsRt, &MEO_SAVESETUP_AUTOSAVE, Option ); +static MenuOption_t MEO_SAVESETUP_AUTOSAVEDELETION = MAKE_MENUOPTION( &MF_Redfont, &MEOS_NoYes, &ud.autosavedeletion ); +static MenuEntry_t ME_SAVESETUP_AUTOSAVEDELETION = MAKE_MENUENTRY( "Auto-Delete:", &MF_Redfont, &MEF_BigOptions_Apply, &MEO_SAVESETUP_AUTOSAVEDELETION, Option ); +static MenuRangeInt32_t MEO_SAVESETUP_MAXAUTOSAVES = MAKE_MENURANGE( &ud.maxautosaves, &MF_Redfont, 1, 10, 0, 10, 1 ); +static MenuEntry_t ME_SAVESETUP_MAXAUTOSAVES = MAKE_MENUENTRY( "Limit:", &MF_Redfont, &MEF_BigOptions_Apply, &MEO_SAVESETUP_MAXAUTOSAVES, RangeInt32 ); + static MenuEntry_t *MEL_SAVESETUP[] = { &ME_SAVESETUP_AUTOSAVE, + &ME_SAVESETUP_AUTOSAVEDELETION, + &ME_SAVESETUP_MAXAUTOSAVES, }; @@ -1976,6 +1983,10 @@ static void Menu_Pre(MenuID_t cm) soundvoices == ud.config.NumVoices); break; + case MENU_SAVESETUP: + MenuEntry_DisableOnCondition(&ME_SAVESETUP_MAXAUTOSAVES, !ud.autosavedeletion); + break; + #ifndef EDUKE32_SIMPLE_MENU case MENU_MOUSESETUP: MenuEntry_DisableOnCondition(&ME_MOUSESETUP_MOUSEAIMING, ud.mouseaiming); diff --git a/source/duke3d/src/osdcmds.cpp b/source/duke3d/src/osdcmds.cpp index a6f9f9f1a..f3f2db7e6 100644 --- a/source/duke3d/src/osdcmds.cpp +++ b/source/duke3d/src/osdcmds.cpp @@ -1722,6 +1722,8 @@ int32_t registerosdcommands(void) { "snd_speech", "enables/disables player speech", (void *)&ud.config.VoiceToggle, CVAR_INT, 0, 5 }, { "sv_autosave", "enable/disable autosaves", (void *)&ud.autosave, CVAR_BOOL, 0, 1 }, + { "sv_autosavedeletion", "enable/disable automatic deletion of autosaves", (void *)&ud.autosavedeletion, CVAR_BOOL, 0, 1 }, + { "sv_maxautosaves", "number of autosaves to keep before deleting the oldest", (void *)&ud.maxautosaves, CVAR_INT, 1, 100 }, { "team","change team in multiplayer", (void *)&ud.team, CVAR_INT|CVAR_MULTI, 0, 3 }, diff --git a/source/duke3d/src/savegame.cpp b/source/duke3d/src/savegame.cpp index 66c69e4b7..6802e0355 100644 --- a/source/duke3d/src/savegame.cpp +++ b/source/duke3d/src/savegame.cpp @@ -196,7 +196,7 @@ static size_t countcache1dfind(CACHE1D_FIND_REC *f) return x; } -void ReadSaveGameHeaders(void) +static void ReadSaveGameHeaders_Internal(void) { static char const DefaultPath[] = "/", SavePattern[] = "*.esv"; @@ -252,6 +252,32 @@ void ReadSaveGameHeaders(void) } } +void ReadSaveGameHeaders(void) +{ + ReadSaveGameHeaders_Internal(); + + if (!ud.autosavedeletion) + return; + + bool didDelete = false; + int32_t numautosaves = 0; + for (size_t x = 0; x < g_nummenusaves; ++x) + { + menusave_t & msv = g_menusaves[x]; + if (!msv.isAutoSave) + continue; + if (numautosaves >= ud.maxautosaves) + { + G_DeleteSave(msv.brief); + didDelete = true; + } + ++numautosaves; + } + + if (didDelete) + ReadSaveGameHeaders_Internal(); +} + int32_t G_LoadSaveHeaderNew(char const *fn, savehead_t *saveh) { int32_t fil = kopen4loadfrommod(fn, 0);