From 380a64f9895a360b172d11e9b2a6e16e6082048d Mon Sep 17 00:00:00 2001 From: Lephenixnoir Date: Sun, 19 Sep 2021 17:33:33 +0200 Subject: [PATCH] Add progress bar to game saves on exit --- cgdoom/cgdoom-ui.c | 36 ++++++++++++++++++++++++++++++++++ cgdoom/cgdoom-ui.h | 4 ++++ cgdoom/cgdoom.c | 49 +++++++++++++++++++++++++++++++++++++++++++--- 3 files changed, 86 insertions(+), 3 deletions(-) diff --git a/cgdoom/cgdoom-ui.c b/cgdoom/cgdoom-ui.c index 4474615..e9db7fd 100644 --- a/cgdoom/cgdoom-ui.c +++ b/cgdoom/cgdoom-ui.c @@ -510,3 +510,39 @@ void UI_Error(const char *fmt, va_list args) while(PRGM_GetKey()); GetKey(&key); } + +void UI_DelayedWrites(CGD_DelayedFileWrite const *dfw, int count, + int current_file, int current_file_done) +{ + int total = 0; + int current = 0; + + for(int i = 0; i < count; i++) { + if(dfw[i].data == NULL) + continue; + + total += dfw[i].size; + if(i < current_file) + current += dfw[i].size; + else if(i == current_file) + current += current_file_done; + } + + Bdisp_AllClr_VRAM(); + + UI_Printf(WIDTH / 2, 10, 0x0000, UI_CENTER, + "Game saves"); + if(current_file_done == -1) + UI_Printf(WIDTH / 2, HEIGHT / 2 - 12, 0x0000, UI_CENTER, + "Creating %s... (%d kB)", dfw[current_file].filename, + dfw[current_file].size >> 10); + else + UI_Printf(WIDTH / 2, HEIGHT / 2 - 12, 0x0000, UI_CENTER, + "Saving %s... (%d/%d kB)", dfw[current_file].filename, + current_file_done >> 10, dfw[current_file].size >> 10); + UI_ProgressBar(HEIGHT / 2 + 7, current, total); + + Bdisp_FrameAndColor(3, 16); + Bdisp_FrameAndColor(1, 0); + Bdisp_PutDisp_DD(); +} diff --git a/cgdoom/cgdoom-ui.h b/cgdoom/cgdoom-ui.h index a5f9c07..d50961f 100644 --- a/cgdoom/cgdoom-ui.h +++ b/cgdoom/cgdoom-ui.h @@ -76,4 +76,8 @@ int UI_Main(WADFileInfo *wads, int wad_count, /* Show an error with custom formatting. */ void UI_Error(const char *fmt, va_list args); +/* Show a file save with a progress bar. */ +void UI_DelayedWrites(CGD_DelayedFileWrite const *dfw, int count, + int current_file, int current_amount); + #endif /* CGDOOM_UI_H */ diff --git a/cgdoom/cgdoom.c b/cgdoom/cgdoom.c index b278ccd..a5c8779 100644 --- a/cgdoom/cgdoom.c +++ b/cgdoom/cgdoom.c @@ -643,6 +643,50 @@ static int FindZeroedMemory(void *start) return size & ~0xfff; } +static void DelayedWriteFile(int i) +{ + CGD_DelayedFileWrite const *dfw = &CGD_DelayedSaves[i]; + + uint16_t fc_path[100] = u"\\\\fls0\\"; + int j=7, rc, fd; + + for (int i = 0; dfw->filename[i]; i++) + fc_path[j++] = dfw->filename[i]; + fc_path[j++] = 0x0000; + + UI_DelayedWrites(CGD_DelayedSaves, 6, i, -1); + + Bfile_DeleteEntry(fc_path); + + rc = Bfile_CreateEntry_OS(fc_path, CREATEMODE_FILE, (size_t *)&dfw->size); + if (rc < 0) { + I_Error("Bfile_CreateEntry_OS(%s, %d bytes): %d", dfw->filename, + dfw->size, rc); + return; + } + + fd = Bfile_OpenFile_OS(fc_path, WRITE, 0); + if (fd < 0) { + I_Error("Bfile_OpenFile_OS(%s): %d", dfw->filename, fd); + return; + } + + /* Write chunks of 4096 bytes and show progress in-between chunks */ + int size = dfw->size; + const void *source = dfw->data; + + while(size > 0) { + int chunk_size = (size >= 4096) ? 4096 : size; + Bfile_WriteFile_OS(fd, source, chunk_size); + source += chunk_size; + size -= chunk_size; + + UI_DelayedWrites(CGD_DelayedSaves, 6, i, dfw->size - size); + } + + Bfile_CloseFile_OS(fd); +} + /////////////////////////////////////////////////////////////////////////////////////////////////// int main(void) { @@ -790,9 +834,8 @@ int main(void) 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(dfw->data != NULL) + DelayedWriteFile(i); } if(dev_info) {