dep/libchdr: Re-add progress precaching

This commit is contained in:
Stenzek 2023-08-12 13:47:08 +10:00
parent 4b70853daa
commit 06a8349162
3 changed files with 53 additions and 22 deletions

View file

@ -379,6 +379,7 @@ CHD_EXPORT chd_error chd_open(const char *filename, int mode, chd_file *parent,
/* precache underlying file */ /* precache underlying file */
CHD_EXPORT chd_error chd_precache(chd_file *chd); CHD_EXPORT chd_error chd_precache(chd_file *chd);
CHD_EXPORT chd_error chd_precache_progress(chd_file* chd, void(*progress)(size_t pos, size_t total, void* param), void* param);
/* close a CHD file */ /* close a CHD file */
CHD_EXPORT void chd_close(chd_file *chd); CHD_EXPORT void chd_close(chd_file *chd);

View file

@ -42,6 +42,7 @@
#include <stdlib.h> #include <stdlib.h>
#include <string.h> #include <string.h>
#include <time.h> #include <time.h>
#include <limits.h>
#include <libchdr/chd.h> #include <libchdr/chd.h>
#include <libchdr/cdrom.h> #include <libchdr/cdrom.h>
@ -1733,30 +1734,60 @@ cleanup:
memory memory
-------------------------------------------------*/ -------------------------------------------------*/
CHD_EXPORT chd_error chd_precache(chd_file *chd) CHD_EXPORT chd_error chd_precache(chd_file* chd)
{ {
INT64 count; return chd_precache_progress(chd, NULL, NULL);
UINT64 size; }
if (chd->file_cache == NULL) CHD_EXPORT chd_error chd_precache_progress(chd_file* chd, void(*progress)(size_t pos, size_t total, void* param), void* param)
{ {
size = core_fsize(chd->file); #define PRECACHE_CHUNK_SIZE 16 * 1024 * 1024
if ((INT64)size <= 0)
return CHDERR_INVALID_DATA; size_t count;
chd->file_cache = malloc(size); UINT64 size, done, req_count, last_update_done, update_interval;
if (chd->file_cache == NULL)
if (chd->file_cache == NULL)
{
size = core_fsize(chd->file);
if ((INT64)size <= 0)
return CHDERR_INVALID_DATA;
if (size > SIZE_MAX)
return CHDERR_OUT_OF_MEMORY; return CHDERR_OUT_OF_MEMORY;
core_fseek(chd->file, 0, SEEK_SET);
count = core_fread(chd->file, chd->file_cache, size);
if (count != size)
{
free(chd->file_cache);
chd->file_cache = NULL;
return CHDERR_READ_ERROR;
}
}
return CHDERR_NONE; chd->file_cache = malloc(size);
if (chd->file_cache == NULL)
return CHDERR_OUT_OF_MEMORY;
core_fseek(chd->file, 0, SEEK_SET);
done = 0;
last_update_done = 0;
update_interval = ((size + 99) / 100);
while (done < size)
{
req_count = size - done;
if (req_count > PRECACHE_CHUNK_SIZE)
req_count = PRECACHE_CHUNK_SIZE;
count = core_fread(chd->file, chd->file_cache + (size_t)done, (size_t)req_count);
if (count != (size_t)req_count)
{
free(chd->file_cache);
chd->file_cache = NULL;
return CHDERR_READ_ERROR;
}
done += req_count;
if (progress != NULL && (done - last_update_done) >= update_interval && done != size)
{
last_update_done = done;
progress(done, size, param);
}
}
}
return CHDERR_NONE;
} }
/*------------------------------------------------- /*-------------------------------------------------

View file

@ -320,8 +320,7 @@ CDImage::PrecacheResult CDImageCHD::Precache(ProgressCallback* progress)
static_cast<ProgressCallback*>(param)->SetProgressValue(std::min<u32>(percent, 100)); static_cast<ProgressCallback*>(param)->SetProgressValue(std::min<u32>(percent, 100));
}; };
//if (chd_precache_progress(m_chd, callback, progress) != CHDERR_NONE) if (chd_precache_progress(m_chd, callback, progress) != CHDERR_NONE)
if (chd_precache(m_chd) != CHDERR_NONE)
return CDImage::PrecacheResult::ReadError; return CDImage::PrecacheResult::ReadError;
m_precached = true; m_precached = true;