Delay game saves until add-in exit to avoid quitting

This commit is contained in:
Lephenixnoir 2021-09-19 17:04:28 +02:00
parent 3205bc21bd
commit 6742defa3d
Signed by: Lephenixnoir
GPG Key ID: 1BBA026E13FC0495
8 changed files with 77 additions and 19 deletions

View File

@ -169,11 +169,11 @@ void UI_Checkbox(int x, int y, int checked)
}
}
void UI_FileMappingProgressBar(int size_mapped, int size_total)
void UI_ProgressBar(int y0, int current, int total)
{
const int w=192, h=5;
const int x0=(WIDTH-w)/2, y0=HEIGHT-10;
const int pos = x0 + (w * size_mapped) / size_total;
const int x0=(WIDTH-w)/2;
const int pos = x0 + (w * current) / total;
for(int x = x0; x < x0+w; x++)
{

View File

@ -14,8 +14,8 @@ enum {
UI_RIGHT = 2,
};
/* Show a progress bar of file mapping at the bottom of the screen. */
void UI_FileMappingProgressBar(int size_mapped, int size_total);
/* Show a progress bar at the bottom of the screen. */
void UI_ProgressBar(int y, int current, int total);
/* Print text with a cleaner font. */
void UI_Print(int x, int y, int fg, int halign, char const *text, int length);

View File

@ -3,7 +3,9 @@
#include "cgdoom.h"
#include <stdlib.h>
#include "libprof.h"
#include "doomtype.h"
#include "m_misc.h"
#ifndef CG_EMULATOR
# include "cgdoom-alloc.h"
@ -387,6 +389,9 @@ int CGD_2MBLineMemory = 0;
int CGD_Frameskip = 1;
const char *CGD_WADFileName = NULL;
/* Delayed file accesses */
CGD_DelayedFileWrite CGD_DelayedSaves[6] = { 0 };
/* Performance counters */
struct CGD_Perf CGD_Perf;
/* Developer statistics */
@ -499,7 +504,7 @@ int CreateFileMapping(int fd, FileMapping *pMap)
{
/* Don't show this too often, or it will eat several seconds */
if((pMap->miTotalLength - iLastProgress) * 20 > iFileSize) {
UI_FileMappingProgressBar(pMap->miTotalLength, iFileSize);
UI_ProgressBar(HEIGHT-10, pMap->miTotalLength, iFileSize);
iLastProgress = pMap->miTotalLength;
}
@ -732,7 +737,7 @@ int main(void)
int fd = Bfile_OpenFile_OS(wads[choice].path, 0, 0);
int size = CreateFileMapping(fd, &gWADMap);
Bfile_CloseFile_OS(fd);
UI_FileMappingProgressBar(1, 1);
UI_ProgressBar(HEIGHT-10, 1, 1);
ms_mmap = (RTC_GetTicks() - time) * 8;
if(size == -1) {
@ -782,6 +787,14 @@ int main(void)
if(gWADfd >= 0)
Bfile_CloseFile_OS(gWADfd);
int delayed_writes = sizeof(CGD_DelayedSaves) / sizeof(CGD_DelayedSaves[0]);
for(int i = 0; i < delayed_writes; i++) {
CGD_DelayedFileWrite *dfw = &CGD_DelayedSaves[i];
if(dfw->data != NULL) {
M_WriteFile(dfw->filename, dfw->data, dfw->size);
}
}
if(dev_info) {
Layout l;
Layout_Init(&l);

View File

@ -19,6 +19,17 @@ typedef struct
int size;
} WADFileInfo;
/* Description of a file write that has been delated. */
typedef struct
{
char filename[32];
const void *data;
int size;
} CGD_DelayedFileWrite;
/* Delay file saves until exit to avoid quitting immediately */
#define CGDOOM_DELAY_SAVES
/* CGDoom statistics */
extern struct CGD_Perf CGD_Perf;
extern struct CGD_Stats CGD_Stats;
@ -32,13 +43,16 @@ extern int CGD_EnableDemos;
extern int CGD_SingleEpisodeUltimate;
/* Skip this amount of frames after every rendered frame (default 1) */
extern int CGD_Frameskip;
/* WAD file name (without .wad), used to avoid save file conflicts */
extern const char *CGD_WADFileName;
// Global variables interfacing with Doom itself.
/* Map and episode to start at when loading the game. */
extern int startmap, startepisode;
/* WAD file name (without .wad), used to avoid save file conflicts */
extern const char *CGD_WADFileName;
/* Save Game operations delayed until closing the add-in (one per save) */
extern CGD_DelayedFileWrite CGD_DelayedSaves[6];
// Keyboard interface.

View File

@ -135,7 +135,7 @@
//
// G_game.C
//
#define GGSAVED "game saved."
#define GGSAVED "Game will save on exit"
//
// HU_stuff.C

View File

@ -88,7 +88,7 @@ void G_DoPlayDemo (void);
void G_DoCompleted (void);
void G_DoVictory (void);
void G_DoWorldDone (void);
void G_DoSaveGame (void);
boolean G_DoSaveGame (void);
gameaction_t gameaction;
@ -460,11 +460,13 @@ void G_Ticker (void)
G_DoLoadGame ();
break;
case ga_savegame:
G_DoSaveGame ();
/* After saving the game, the storage memory is shuffled, we need to
leave and we need to do it quickly */
I_Quit();
return;
if (G_DoSaveGame ()) {
I_Quit();
return;
}
break;
case ga_playdemo:
G_DoPlayDemo ();
break;
@ -999,7 +1001,7 @@ void G_SaveGame( int slot, char* description )
sendsave = true;
}
void G_DoSaveGame (void)
boolean G_DoSaveGame (void)
{
char name[50];
char name2[VERSIONSIZE];
@ -1039,14 +1041,43 @@ void G_DoSaveGame (void)
if (length > SAVEGAMESIZE)
I_Error ("Savegame buffer overrun");
M_WriteFile (name, savebuffer, length);
boolean save_now = false;
void *delayed_copy = NULL;
#ifndef CGDOOM_DELAY_SAVES
save_now = true;
#endif
/* Allocate memory to hold the data while delaying */
if (!save_now) {
delayed_copy = Z_Malloc(length, PU_STATIC, 0);
if (delayed_copy == NULL)
save_now = true;
else
memcpy(delayed_copy, savebuffer, length);
}
if (save_now) {
M_WriteFile (name, savebuffer, length);
}
else {
CGD_DelayedFileWrite *dfw = &CGD_DelayedSaves[savegameslot];
if (dfw->data)
Z_Free(dfw->data);
CGDstrcpy(dfw->filename, name);
dfw->data = delayed_copy;
dfw->size = length;
}
gameaction = ga_nothing;
savedescription[0] = 0;
static char msg[32];
static char msg[40];
sprintf(msg, GGSAVED " (%d kB)", length >> 10);
players[consoleplayer].message = msg;
return save_now;
}
//

View File

@ -90,7 +90,7 @@ int M_DrawText ( int x, int y, boolean direct, char* string )
//
// M_WriteFile
//
boolean M_WriteFile(char const *name, void *source, int length)
boolean M_WriteFile(char const *name, const void *source, int length)
{
uint16_t fc_path[100] = u"\\\\fls0\\";
size_t size = length;

View File

@ -29,7 +29,7 @@
//
// MISC
//
boolean M_WriteFile ( char const* name, void* source, int length );
boolean M_WriteFile ( char const* name, const void* source, int length );
int M_ReadFile ( char const* name, byte** buffer );