From 5d45b5911762814a543f274086b0ea06a3877b4f Mon Sep 17 00:00:00 2001 From: sorgelig Date: Mon, 29 Mar 2021 04:33:10 +0800 Subject: [PATCH] Progress bar for arcades. Update NeoGeo progress bar. --- menu.cpp | 38 +++++++++++++++++++ menu.h | 1 + support/arcade/mra_loader.cpp | 24 ++++++++++-- support/neogeo/neogeo_loader.cpp | 64 ++++++-------------------------- sxmlc.c | 1 + sxmlc.h | 1 + user_io.cpp | 56 +++------------------------- 7 files changed, 79 insertions(+), 106 deletions(-) diff --git a/menu.cpp b/menu.cpp index 711b47a..29c3303 100644 --- a/menu.cpp +++ b/menu.cpp @@ -6570,3 +6570,41 @@ void menu_process_save() { menu_save_timer = GetTimer(1000); } + +static char pchar[] = { 0x8C, 0x8E, 0x8F, 0x90, 0x91, 0x7F }; + +#define PROGRESS_CNT 28 +#define PROGRESS_CHARS (int)(sizeof(pchar)/sizeof(pchar[0])) +#define PROGRESS_MAX ((PROGRESS_CHARS*PROGRESS_CNT)-1) + +void ProgressMessage(const char* title, const char* text, int current, int max) +{ + static int progress; + if (!current && !max) + { + progress = -1; + MenuHide(); + return; + } + + int new_progress = (((uint64_t)current)*PROGRESS_MAX) / max; + if (progress != new_progress) + { + progress = new_progress; + static char progress_buf[128]; + memset(progress_buf, 0, sizeof(progress_buf)); + + if (new_progress > PROGRESS_MAX) new_progress = PROGRESS_MAX; + char c = pchar[new_progress % PROGRESS_CHARS]; + new_progress /= PROGRESS_CHARS; + + char *buf = progress_buf; + sprintf(buf, "\n\n %.27s\n ", text); + buf += strlen(buf); + + for (int i = 0; i <= new_progress; i++) buf[i] = (i < new_progress) ? 0x7F : c; + buf[PROGRESS_CNT] = 0; + + InfoMessage(progress_buf, 2000, title); + } +} diff --git a/menu.h b/menu.h index d8354c6..4e5255f 100644 --- a/menu.h +++ b/menu.h @@ -9,6 +9,7 @@ void menu_process_save(); void PrintDirectory(int expand = 0); void ScrollLongName(void); +void ProgressMessage(const char* title = 0, const char* text = 0, int current = 0, int max = 0); void ErrorMessage(const char *message, unsigned char code); void InfoMessage(const char *message, int timeout = 2000, const char *title = "Message"); void Info(const char *message, int timeout = 2000, int width = 0, int height = 0, int frame = 0); diff --git a/support/arcade/mra_loader.cpp b/support/arcade/mra_loader.cpp index 587ea33..fb049c0 100644 --- a/support/arcade/mra_loader.cpp +++ b/support/arcade/mra_loader.cpp @@ -38,6 +38,7 @@ struct arc_struct { int ifrom; int ito; int imap; + int file_size; uint32_t address; uint32_t crc; buffer_data *data; @@ -318,7 +319,7 @@ static void send_to_ddr(uint32_t address, void* buf, uint32_t len) return; } -static void rom_finish(int send, uint32_t address) +static void rom_finish(int send, uint32_t address, int index) { if (romlen[0] && romdata) { @@ -339,14 +340,21 @@ static void rom_finish(int send, uint32_t address) } else { + char str[32]; + sprintf(str, "ROM #%d", index); + + ProgressMessage(0, 0, 0, 0); while (romlen[0] > 0) { + ProgressMessage("Sending", str, len - romlen[0], len); + uint16_t chunk = (romlen[0] > 4096) ? 4096 : romlen[0]; user_io_file_tx_data(data, chunk); romlen[0] -= chunk; data += chunk; } + ProgressMessage(0, 0, 0, 0); } // signal end of transmission @@ -427,12 +435,13 @@ unsigned char* hexstr_to_char(const char* hexstr, size_t *out_len) * */ static int xml_send_rom(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, const int n, SAX_Data* sd) { + static char message[32]; struct arc_struct *arc_info = (struct arc_struct *)sd->user; - (void)(sd); switch (evt) { case XML_EVENT_START_DOC: + message[0] = 0; arc_info->insiderom = 0; arc_info->insidesw = 0; break; @@ -463,6 +472,7 @@ static int xml_send_rom(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, cons arc_info->address = 0; arc_info->insideinterleave = 0; MD5Init(&arc_info->context); + ProgressMessage(0, 0, 0, 0); } if (!strcasecmp(node->tag, "switches")) @@ -515,6 +525,7 @@ static int xml_send_rom(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, cons if (!strcasecmp(node->attributes[i].name, "index") && !strcasecmp(node->tag, "rom")) { arc_info->romindex = atoi(node->attributes[i].value); + sprintf(message, "Assembling ROM #%d", arc_info->romindex); } if (!strcasecmp(node->attributes[i].name, "address") && !strcasecmp(node->tag, "rom")) { @@ -721,6 +732,8 @@ static int xml_send_rom(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, cons for (int i = 1; i < 8; i++) romlen[i] = romlen[0]; } + + ProgressMessage("Loading", message, ftell(sd->file), arc_info->file_size); break; case XML_EVENT_TEXT: @@ -746,6 +759,8 @@ static int xml_send_rom(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, cons // At the end of a rom node (when it is closed) we need to calculate hash values and clean up if (!strcasecmp(node->tag, "rom")) { + message[0] = 0; + if (arc_info->insiderom) { unsigned char checksum[16]; @@ -785,7 +800,7 @@ static int xml_send_rom(XMLEvent evt, const XMLNode* node, SXML_CHAR* text, cons } } - rom_finish(checksumsame, arc_info->address); + rom_finish(checksumsame, arc_info->address, arc_info->romindex); } arc_info->insiderom = 0; } @@ -1032,6 +1047,9 @@ int arcade_send_rom(const char *xml) arc_info.data = buffer_init(kBigTextSize); arc_info.error_msg[0] = 0; arc_info.validrom0 = 0; + struct stat64 *st = getPathStat(xml); + if (st) arc_info.file_size = (int)st->st_size; + ProgressMessage(0, 0, 0, 0); // parse XMLDoc_parse_file_SAX(xml, &sax, &arc_info); diff --git a/support/neogeo/neogeo_loader.cpp b/support/neogeo/neogeo_loader.cpp index 337bac8..c193193 100644 --- a/support/neogeo/neogeo_loader.cpp +++ b/support/neogeo/neogeo_loader.cpp @@ -107,36 +107,6 @@ static void fix_convert(uint8_t* buf_in, uint8_t* buf_out, uint32_t size) for (uint32_t i = 0; i < size; i++) buf_out[i] = buf_in[(i & ~0x1F) | ((i >> 2) & 7) | ((i & 1) << 3) | (((i & 2) << 3) ^ 0x10)]; } -static char pchar[] = { 0x8C, 0x8E, 0x8F, 0x90, 0x91, 0x7F }; - -#define PROGRESS_CNT 10 -#define PROGRESS_CHARS (sizeof(pchar)/sizeof(pchar[0])) -#define PROGRESS_MAX ((PROGRESS_CHARS*PROGRESS_CNT)-1) - -static void neogeo_osd_progress(const char* name, unsigned int progress) -{ - static char progress_buf[64]; - memset(progress_buf, ' ', sizeof(progress_buf)); - - if (progress > PROGRESS_MAX) progress = PROGRESS_MAX; - char c = pchar[progress % PROGRESS_CHARS]; - progress /= PROGRESS_CHARS; - - const char* p = strrchr(name, '/'); - if (p) p++; - else p = name; - if (strlen(p) > 16) p = p + strlen(p) - 16; - - strcpy(progress_buf, p); - char *buf = progress_buf + strlen(progress_buf); - *buf++ = ' '; - - for (unsigned int i = 0; i <= progress; i++) buf[i] = (i < progress) ? 0x7F : c; - buf[PROGRESS_CNT] = 0; - - Info(progress_buf); -} - static uint32_t neogeo_file_tx(const char* path, const char* name, uint8_t neo_file_type, uint8_t index, uint32_t offset, uint32_t size) { fileTYPE f = {}; @@ -162,8 +132,7 @@ static uint32_t neogeo_file_tx(const char* path, const char* name, uint8_t neo_f // prepare transmission of new file user_io_set_download(1); - int progress = -1; - + ProgressMessage(); while (bytes2send) { uint16_t chunk = (bytes2send > sizeof(buf)) ? sizeof(buf) : bytes2send; @@ -194,16 +163,13 @@ static uint32_t neogeo_file_tx(const char* path, const char* name, uint8_t neo_f } DisableFpga(); - int new_progress = PROGRESS_MAX - ((((uint64_t)bytes2send)*PROGRESS_MAX) / size); - if (progress != new_progress) - { - progress = new_progress; - neogeo_osd_progress(name, progress); - } + + ProgressMessage("Loading", name, size - bytes2send, size); bytes2send -= chunk; } FileClose(&f); + ProgressMessage(); // signal end of transmission user_io_set_download(0); @@ -252,11 +218,11 @@ static uint32_t load_crom_to_mem(const char* path, const char* name, uint8_t ind printf("CROM %s (offset %u, size %u) with index %u\n", name, offset, size, index); // Put pairs of bitplanes in the correct order for the core - int progress = -1; uint32_t remain = size; uint32_t map_addr = 0x38000000 + (((index - 64) >> 1) * 1024 * 1024); + ProgressMessage(); while (remain) { uint32_t partsz = remain; @@ -275,12 +241,7 @@ static uint32_t load_crom_to_mem(const char* path, const char* name, uint8_t ind FileReadAdv(&f, loadbuf, partsz/2); spr_convert_skp((uint16_t*)loadbuf, ((uint16_t*)base) + ((index ^ 1) & 1), partsz / 4); - int new_progress = PROGRESS_MAX - ((((uint64_t)(remain - partsz))*PROGRESS_MAX) / size); - if (progress != new_progress) - { - progress = new_progress; - neogeo_osd_progress(name, progress); - } + ProgressMessage("Loading", name, size - (remain - partsz), size); munmap(base, partsz); remain -= partsz; @@ -289,6 +250,7 @@ static uint32_t load_crom_to_mem(const char* path, const char* name, uint8_t ind close(memfd); FileClose(&f); + ProgressMessage(); return map_addr - 0x38000000; } @@ -323,8 +285,6 @@ static uint32_t load_rom_to_mem(const char* path, const char* name, uint8_t neo_ FileSeek(&f, offset, SEEK_SET); printf("ROM %s (offset %u, size %u, exp %u, type %u, addr %u) with index %u\n", name, offset, size, expand, neo_file_type, addr, index); - int progress = -1; - uint32_t remainf = size; if(expand) size = expand; @@ -332,6 +292,7 @@ static uint32_t load_rom_to_mem(const char* path, const char* name, uint8_t neo_ uint32_t map_addr = 0x30000000 + (addr ? addr : ((index >= 16) && (index < 64)) ? (index - 16) * 0x80000 : (index == 9) ? 0x2000000 : 0x8000000); + ProgressMessage(); while (remain) { uint32_t partsz = remain; @@ -369,12 +330,8 @@ static uint32_t load_rom_to_mem(const char* path, const char* name, uint8_t neo_ if (partszf) FileReadAdv(&f, base, partszf); } - int new_progress = PROGRESS_MAX - ((((uint64_t)(remain - partsz))*PROGRESS_MAX) / size); - if (progress != new_progress) - { - progress = new_progress; - neogeo_osd_progress(name, progress); - } + ProgressMessage("Loading", name, size - (remain - partsz), size); + munmap(base, partsz); remain -= partsz; map_addr += partsz; @@ -382,6 +339,7 @@ static uint32_t load_rom_to_mem(const char* path, const char* name, uint8_t neo_ close(memfd); FileClose(&f); + ProgressMessage(); return size; } diff --git a/sxmlc.c b/sxmlc.c index a3f86fe..10833f9 100644 --- a/sxmlc.c +++ b/sxmlc.c @@ -1605,6 +1605,7 @@ int XMLDoc_parse_file_SAX(const SXML_CHAR* filename, const SAX_Callbacks* sax, v sd.name = (SXML_CHAR*)filename; sd.user = user; + sd.file = f; #ifdef SXMLC_UNICODE bom = freadBOM(f, NULL, NULL); /* Skip BOM, if any */ /* In Unicode, re-open the file in text-mode if there is no BOM (or UTF-8) as we assume that diff --git a/sxmlc.h b/sxmlc.h index eec0c9a..d95fc83 100644 --- a/sxmlc.h +++ b/sxmlc.h @@ -269,6 +269,7 @@ typedef enum _XMLEvent { */ typedef struct _SAX_Data { const SXML_CHAR* name; + FILE *file; int line_num; void* user; } SAX_Data; diff --git a/user_io.cpp b/user_io.cpp index df0eec9..2ce5075 100644 --- a/user_io.cpp +++ b/user_io.cpp @@ -1928,31 +1928,6 @@ static void check_status_change() } } -static char pchar[] = { 0x8C, 0x8F, 0x7F }; - -#define PROGRESS_CNT 28 -#define PROGRESS_CHARS (sizeof(pchar)/sizeof(pchar[0])) -#define PROGRESS_MAX ((PROGRESS_CHARS*PROGRESS_CNT)-1) - -static void tx_progress(const char* name, unsigned int progress) -{ - static char progress_buf[128]; - memset(progress_buf, 0, sizeof(progress_buf)); - - if (progress > PROGRESS_MAX) progress = PROGRESS_MAX; - char c = pchar[progress % PROGRESS_CHARS]; - progress /= PROGRESS_CHARS; - - char *buf = progress_buf; - sprintf(buf, "\n\n %.27s\n ", name); - buf += strlen(buf); - - for (unsigned int i = 0; i <= progress; i++) buf[i] = (i < progress) ? 0x7F : c; - buf[PROGRESS_CNT] = 0; - - InfoMessage(progress_buf, 2000, "Loading"); -} - static void show_core_info(int info_n) { int i = 2; @@ -2125,9 +2100,7 @@ int user_io_file_tx_a(const char* name, uint16_t index) int use_progress = 1; int size = bytes2send; - int progress = -1; - if (use_progress) MenuHide(); - + if (use_progress) ProgressMessage(0, 0, 0, 0); while (bytes2send) { uint16_t chunk = (bytes2send > sizeof(buf)) ? sizeof(buf) : bytes2send; @@ -2135,15 +2108,7 @@ int user_io_file_tx_a(const char* name, uint16_t index) FileReadAdv(&f, buf, chunk); user_io_file_tx_data(buf, chunk); - if (use_progress) - { - int new_progress = PROGRESS_MAX - ((((uint64_t)bytes2send)*PROGRESS_MAX) / size); - if (progress != new_progress) - { - progress = new_progress; - tx_progress(f.name, progress); - } - } + if (use_progress) ProgressMessage("Loading", f.name, size - bytes2send, size); bytes2send -= chunk; } @@ -2155,7 +2120,7 @@ int user_io_file_tx_a(const char* name, uint16_t index) // signal end of transmission user_io_set_download(0); - MenuHide(); + ProgressMessage(0, 0, 0, 0); return 1; } @@ -2274,8 +2239,7 @@ int user_io_file_tx(const char* name, unsigned char index, char opensave, char m int use_progress = 1; // (bytes2send > (1024 * 1024)) ? 1 : 0; int size = bytes2send; - int progress = -1; - if (use_progress) MenuHide(); + if (use_progress) ProgressMessage(0, 0, 0, 0); if(ss_base && opensave) process_ss(name); @@ -2313,15 +2277,7 @@ int user_io_file_tx(const char* name, unsigned char index, char opensave, char m if (is_snes() && is_snes_bs) snes_patch_bs_header(&f, buf); user_io_file_tx_data(buf, chunk); - if (use_progress) - { - int new_progress = PROGRESS_MAX - ((((uint64_t)bytes2send)*PROGRESS_MAX) / size); - if (progress != new_progress) - { - progress = new_progress; - tx_progress(f.name, progress); - } - } + if (use_progress) ProgressMessage("Loading", f.name, size - bytes2send, size); bytes2send -= chunk; if (skip >= chunk) skip -= chunk; @@ -2356,7 +2312,7 @@ int user_io_file_tx(const char* name, unsigned char index, char opensave, char m send_pcolchr(name, (index & 0x1F) | 0x60, 1); } - MenuHide(); + ProgressMessage(0, 0, 0, 0); return 1; }