This commit is contained in:
twinaphex 2020-07-07 05:58:32 +02:00
parent a4841d4d50
commit da214647fe
7 changed files with 163 additions and 113 deletions

View file

@ -46,7 +46,8 @@
#endif
#endif
struct sevenzip_context_t {
struct sevenzip_context_t
{
CFileInStream archiveStream;
CLookToRead lookStream;
ISzAlloc allocImp;

View file

@ -109,6 +109,7 @@
#endif
/* TODO/FIXME - globals */
static retro_vfs_stat_t path_stat_cb = retro_vfs_stat_impl;
static retro_vfs_mkdir_t path_mkdir_cb = retro_vfs_mkdir_impl;

View file

@ -31,35 +31,39 @@
#define VFS_FRONTEND
#include <vfs/vfs_implementation.h>
static retro_vfs_opendir_t dirent_opendir_cb = NULL;
static retro_vfs_readdir_t dirent_readdir_cb = NULL;
/* TODO/FIXME - static globals */
static retro_vfs_opendir_t dirent_opendir_cb = NULL;
static retro_vfs_readdir_t dirent_readdir_cb = NULL;
static retro_vfs_dirent_get_name_t dirent_dirent_get_name_cb = NULL;
static retro_vfs_dirent_is_dir_t dirent_dirent_is_dir_cb = NULL;
static retro_vfs_closedir_t dirent_closedir_cb = NULL;
static retro_vfs_dirent_is_dir_t dirent_dirent_is_dir_cb = NULL;
static retro_vfs_closedir_t dirent_closedir_cb = NULL;
void dirent_vfs_init(const struct retro_vfs_interface_info* vfs_info)
{
const struct retro_vfs_interface* vfs_iface;
dirent_opendir_cb = NULL;
dirent_readdir_cb = NULL;
dirent_opendir_cb = NULL;
dirent_readdir_cb = NULL;
dirent_dirent_get_name_cb = NULL;
dirent_dirent_is_dir_cb = NULL;
dirent_closedir_cb = NULL;
dirent_dirent_is_dir_cb = NULL;
dirent_closedir_cb = NULL;
vfs_iface = vfs_info->iface;
vfs_iface = vfs_info->iface;
if (vfs_info->required_interface_version < DIRENT_REQUIRED_VFS_VERSION || !vfs_iface)
if (
vfs_info->required_interface_version < DIRENT_REQUIRED_VFS_VERSION ||
!vfs_iface)
return;
dirent_opendir_cb = vfs_iface->opendir;
dirent_readdir_cb = vfs_iface->readdir;
dirent_opendir_cb = vfs_iface->opendir;
dirent_readdir_cb = vfs_iface->readdir;
dirent_dirent_get_name_cb = vfs_iface->dirent_get_name;
dirent_dirent_is_dir_cb = vfs_iface->dirent_is_dir;
dirent_closedir_cb = vfs_iface->closedir;
dirent_dirent_is_dir_cb = vfs_iface->dirent_is_dir;
dirent_closedir_cb = vfs_iface->closedir;
}
struct RDIR *retro_opendir_include_hidden(const char *name, bool include_hidden)
struct RDIR *retro_opendir_include_hidden(
const char *name, bool include_hidden)
{
if (dirent_opendir_cb)
return (struct RDIR *)dirent_opendir_cb(name, include_hidden);

View file

@ -57,15 +57,27 @@ struct retro_task_impl
void (*deinit)(void);
};
static retro_task_queue_msg_t msg_push_bak;
static task_queue_t tasks_running = {NULL, NULL};
static task_queue_t tasks_finished = {NULL, NULL};
/* TODO/FIXME - static globals */
static retro_task_queue_msg_t msg_push_bak = NULL;
static task_queue_t tasks_running = {NULL, NULL};
static task_queue_t tasks_finished = {NULL, NULL};
static struct retro_task_impl *impl_current = NULL;
static bool task_threaded_enable = false;
static uint32_t task_count = 0;
#ifdef HAVE_THREADS
static slock_t *running_lock = NULL;
static slock_t *finished_lock = NULL;
static slock_t *property_lock = NULL;
static slock_t *queue_lock = NULL;
static scond_t *worker_cond = NULL;
static sthread_t *worker_thread = NULL;
static bool worker_continue = true;
/* use running_lock when touching it */
#endif
static void task_queue_msg_push(retro_task_t *task,
unsigned prio, unsigned duration,
bool flush, const char *fmt, ...)
@ -266,7 +278,8 @@ static void retro_task_regular_retrieve(task_retriever_data_t *data)
continue;
/* Create new link */
info = (task_retriever_info_t*)malloc(sizeof(task_retriever_info_t));
info = (task_retriever_info_t*)
malloc(sizeof(task_retriever_info_t));
info->data = malloc(data->element_size);
info->next = NULL;
@ -311,13 +324,6 @@ static struct retro_task_impl impl_regular = {
};
#ifdef HAVE_THREADS
static slock_t *running_lock = NULL;
static slock_t *finished_lock = NULL;
static slock_t *property_lock = NULL;
static slock_t *queue_lock = NULL;
static scond_t *worker_cond = NULL;
static sthread_t *worker_thread = NULL;
static bool worker_continue = true; /* use running_lock when touching it */
/* 'queue_lock' must be held for the duration of this function */
static void task_queue_remove(task_queue_t *queue, retro_task_t *task)
@ -489,7 +495,7 @@ static void threaded_worker(void *userdata)
if (task->when)
{
retro_time_t now = cpu_features_get_time_usec();
retro_time_t now = cpu_features_get_time_usec();
retro_time_t delay = task->when - now - 500; /* allow half a millisecond for context switching */
if (delay > 0)
{
@ -511,10 +517,13 @@ static void threaded_worker(void *userdata)
if (!finished)
{
/* Move the task to the back of the queue */
/* mimics retro_task_threaded_push_running, but also includes a task_queue_remove */
/* mimics retro_task_threaded_push_running,
* but also includes a task_queue_remove */
slock_lock(running_lock);
slock_lock(queue_lock);
if (task->next != NULL) /* do nothing if only item in queue */
/* do nothing if only item in queue */
if (task->next)
{
task_queue_remove(&tasks_running, task);
task_queue_put(&tasks_running, task);
@ -542,17 +551,17 @@ static void threaded_worker(void *userdata)
static void retro_task_threaded_init(void)
{
running_lock = slock_new();
finished_lock = slock_new();
property_lock = slock_new();
queue_lock = slock_new();
worker_cond = scond_new();
running_lock = slock_new();
finished_lock = slock_new();
property_lock = slock_new();
queue_lock = slock_new();
worker_cond = scond_new();
slock_lock(running_lock);
worker_continue = true;
slock_unlock(running_lock);
worker_thread = sthread_create(threaded_worker, NULL);
worker_thread = sthread_create(threaded_worker, NULL);
}
static void retro_task_threaded_deinit(void)
@ -570,12 +579,12 @@ static void retro_task_threaded_deinit(void)
slock_free(property_lock);
slock_free(queue_lock);
worker_thread = NULL;
worker_cond = NULL;
running_lock = NULL;
finished_lock = NULL;
property_lock = NULL;
queue_lock = NULL;
worker_thread = NULL;
worker_cond = NULL;
running_lock = NULL;
finished_lock = NULL;
property_lock = NULL;
queue_lock = NULL;
}
static struct retro_task_impl impl_threaded = {

View file

@ -39,7 +39,14 @@
#define VFS_FRONTEND
#include <vfs/vfs_implementation.h>
static const int64_t vfs_error_return_value = -1;
#define VFS_ERROR_RETURN_VALUE -1
struct RFILE
{
struct retro_vfs_file_handle *hfile;
bool error_flag;
bool eof_flag;
};
static retro_vfs_get_path_t filestream_get_path_cb = NULL;
static retro_vfs_open_t filestream_open_cb = NULL;
@ -54,18 +61,12 @@ static retro_vfs_flush_t filestream_flush_cb = NULL;
static retro_vfs_remove_t filestream_remove_cb = NULL;
static retro_vfs_rename_t filestream_rename_cb = NULL;
struct RFILE
{
struct retro_vfs_file_handle *hfile;
bool error_flag;
bool eof_flag;
};
/* VFS Initialization */
void filestream_vfs_init(const struct retro_vfs_interface_info* vfs_info)
{
const struct retro_vfs_interface* vfs_iface;
const struct retro_vfs_interface *
vfs_iface = vfs_info->iface;
filestream_get_path_cb = NULL;
filestream_open_cb = NULL;
@ -80,9 +81,9 @@ void filestream_vfs_init(const struct retro_vfs_interface_info* vfs_info)
filestream_remove_cb = NULL;
filestream_rename_cb = NULL;
vfs_iface = vfs_info->iface;
if (vfs_info->required_interface_version < FILESTREAM_REQUIRED_VFS_VERSION
if (
(vfs_info->required_interface_version <
FILESTREAM_REQUIRED_VFS_VERSION)
|| !vfs_iface)
return;
@ -103,12 +104,13 @@ void filestream_vfs_init(const struct retro_vfs_interface_info* vfs_info)
/* Callback wrappers */
bool filestream_exists(const char *path)
{
RFILE *dummy = NULL;
RFILE *dummy = NULL;
if (!path || !*path)
return false;
dummy = filestream_open(path,
dummy = filestream_open(
path,
RETRO_VFS_FILE_ACCESS_READ,
RETRO_VFS_FILE_ACCESS_HINT_NONE);
@ -130,9 +132,10 @@ int64_t filestream_get_size(RFILE *stream)
if (filestream_size_cb)
output = filestream_size_cb(stream->hfile);
else
output = retro_vfs_file_size_impl((libretro_vfs_implementation_file*)stream->hfile);
output = retro_vfs_file_size_impl(
(libretro_vfs_implementation_file*)stream->hfile);
if (output == vfs_error_return_value)
if (output == VFS_ERROR_RETURN_VALUE)
stream->error_flag = true;
return output;
@ -145,9 +148,10 @@ int64_t filestream_truncate(RFILE *stream, int64_t length)
if (filestream_truncate_cb)
output = filestream_truncate_cb(stream->hfile, length);
else
output = retro_vfs_file_truncate_impl((libretro_vfs_implementation_file*)stream->hfile, length);
output = retro_vfs_file_truncate_impl(
(libretro_vfs_implementation_file*)stream->hfile, length);
if (output == vfs_error_return_value)
if (output == VFS_ERROR_RETURN_VALUE)
stream->error_flag = true;
return output;
@ -222,8 +226,8 @@ int filestream_scanf(RFILE *stream, const char* format, ...)
char subfmt[64];
va_list args;
const char * bufiter = buf;
int64_t startpos = filestream_tell(stream);
int ret = 0;
int64_t startpos = filestream_tell(stream);
int64_t maxlen = filestream_read(stream, buf, sizeof(buf)-1);
if (maxlen <= 0)
@ -284,20 +288,24 @@ int filestream_scanf(RFILE *stream, const char* format, ...)
*subfmtiter++ = 'n';
*subfmtiter++ = '\0';
if (sizeof(void*) != sizeof(long*)) abort(); /* all pointers must have the same size */
if (sizeof(void*) != sizeof(long*))
abort(); /* all pointers must have the same size */
if (asterisk)
{
int v = sscanf(bufiter, subfmt, &sublen);
if (v == EOF)
return EOF;
if (v != 0) break;
if (v != 0)
break;
}
else
{
int v = sscanf(bufiter, subfmt, va_arg(args, void*), &sublen);
if (v == EOF)
return EOF;
if (v != 1) break;
if (v != 1)
break;
}
ret++;
@ -305,7 +313,8 @@ int filestream_scanf(RFILE *stream, const char* format, ...)
}
else if (isspace(*format))
{
while (isspace(*bufiter)) bufiter++;
while (isspace(*bufiter))
bufiter++;
format++;
}
else
@ -318,7 +327,8 @@ int filestream_scanf(RFILE *stream, const char* format, ...)
}
va_end(args);
filestream_seek(stream, startpos+(bufiter-buf), RETRO_VFS_SEEK_POSITION_START);
filestream_seek(stream, startpos+(bufiter-buf),
RETRO_VFS_SEEK_POSITION_START);
return ret;
}
@ -330,11 +340,14 @@ int64_t filestream_seek(RFILE *stream, int64_t offset, int seek_position)
if (filestream_seek_cb)
output = filestream_seek_cb(stream->hfile, offset, seek_position);
else
output = retro_vfs_file_seek_impl((libretro_vfs_implementation_file*)stream->hfile, offset, seek_position);
output = retro_vfs_file_seek_impl(
(libretro_vfs_implementation_file*)stream->hfile,
offset, seek_position);
if (output == vfs_error_return_value)
if (output == VFS_ERROR_RETURN_VALUE)
stream->error_flag = true;
stream->eof_flag = false;
stream->eof_flag = false;
return output;
}
@ -351,9 +364,10 @@ int64_t filestream_tell(RFILE *stream)
if (filestream_size_cb)
output = filestream_tell_cb(stream->hfile);
else
output = retro_vfs_file_tell_impl((libretro_vfs_implementation_file*)stream->hfile);
output = retro_vfs_file_tell_impl(
(libretro_vfs_implementation_file*)stream->hfile);
if (output == vfs_error_return_value)
if (output == VFS_ERROR_RETURN_VALUE)
stream->error_flag = true;
return output;
@ -365,7 +379,7 @@ void filestream_rewind(RFILE *stream)
return;
filestream_seek(stream, 0L, RETRO_VFS_SEEK_POSITION_START);
stream->error_flag = false;
stream->eof_flag = false;
stream->eof_flag = false;
}
int64_t filestream_read(RFILE *stream, void *s, int64_t len)
@ -378,10 +392,10 @@ int64_t filestream_read(RFILE *stream, void *s, int64_t len)
output = retro_vfs_file_read_impl(
(libretro_vfs_implementation_file*)stream->hfile, s, len);
if (output == vfs_error_return_value)
if (output == VFS_ERROR_RETURN_VALUE)
stream->error_flag = true;
if (output < len)
stream->eof_flag = true;
stream->eof_flag = true;
return output;
}
@ -393,9 +407,10 @@ int filestream_flush(RFILE *stream)
if (filestream_flush_cb)
output = filestream_flush_cb(stream->hfile);
else
output = retro_vfs_file_flush_impl((libretro_vfs_implementation_file*)stream->hfile);
output = retro_vfs_file_flush_impl(
(libretro_vfs_implementation_file*)stream->hfile);
if (output == vfs_error_return_value)
if (output == VFS_ERROR_RETURN_VALUE)
stream->error_flag = true;
return output;
@ -422,7 +437,8 @@ const char* filestream_get_path(RFILE *stream)
if (filestream_get_path_cb)
return filestream_get_path_cb(stream->hfile);
return retro_vfs_file_get_path_impl((libretro_vfs_implementation_file*)stream->hfile);
return retro_vfs_file_get_path_impl(
(libretro_vfs_implementation_file*)stream->hfile);
}
int64_t filestream_write(RFILE *stream, const void *s, int64_t len)
@ -432,9 +448,10 @@ int64_t filestream_write(RFILE *stream, const void *s, int64_t len)
if (filestream_write_cb)
output = filestream_write_cb(stream->hfile, s, len);
else
output = retro_vfs_file_write_impl((libretro_vfs_implementation_file*)stream->hfile, s, len);
output = retro_vfs_file_write_impl(
(libretro_vfs_implementation_file*)stream->hfile, s, len);
if (output == vfs_error_return_value)
if (output == VFS_ERROR_RETURN_VALUE)
stream->error_flag = true;
return output;
@ -445,7 +462,9 @@ int filestream_putc(RFILE *stream, int c)
char c_char = (char)c;
if (!stream)
return EOF;
return filestream_write(stream, &c_char, 1)==1 ? (int)(unsigned char)c : EOF;
return filestream_write(stream, &c_char, 1) == 1
? (int)(unsigned char)c
: EOF;
}
int filestream_vprintf(RFILE *stream, const char* format, va_list args)
@ -487,7 +506,8 @@ int filestream_close(RFILE *stream)
if (filestream_close_cb)
output = filestream_close_cb(fp);
else
output = retro_vfs_file_close_impl((libretro_vfs_implementation_file*)fp);
output = retro_vfs_file_close_impl(
(libretro_vfs_implementation_file*)fp);
if (output == 0)
free(stream);

View file

@ -77,12 +77,16 @@ struct rzipstream
* file/chunk sizes */
static bool rzipstream_read_file_header(rzipstream_t *stream)
{
uint8_t header_bytes[RZIP_HEADER_SIZE] = {0};
unsigned i;
int64_t length;
uint8_t header_bytes[RZIP_HEADER_SIZE];
if (!stream)
return false;
for (i = 0; i < RZIP_HEADER_SIZE; i++)
header_bytes[i] = 0;
/* Attempt to read header bytes */
length = filestream_read(stream->file, header_bytes, sizeof(header_bytes));
if (length <= 0)
@ -145,45 +149,49 @@ file_uncompressed:
* file/chunk sizes */
static bool rzipstream_write_file_header(rzipstream_t *stream)
{
uint8_t header_bytes[RZIP_HEADER_SIZE] = {0};
unsigned i;
int64_t length;
uint8_t header_bytes[RZIP_HEADER_SIZE];
if (!stream)
return false;
/* Populate header array */
for (i = 0; i < RZIP_HEADER_SIZE; i++)
header_bytes[i] = 0;
/* > 'Magic numbers' - first 8 bytes */
header_bytes[0] = 35; /* # */
header_bytes[1] = 82; /* R */
header_bytes[2] = 90; /* Z */
header_bytes[3] = 73; /* I */
header_bytes[4] = 80; /* P */
header_bytes[5] = 118; /* v */
header_bytes[6] = RZIP_VERSION; /* file format version number */
header_bytes[7] = 35; /* # */
header_bytes[0] = 35; /* # */
header_bytes[1] = 82; /* R */
header_bytes[2] = 90; /* Z */
header_bytes[3] = 73; /* I */
header_bytes[4] = 80; /* P */
header_bytes[5] = 118; /* v */
header_bytes[6] = RZIP_VERSION; /* file format version number */
header_bytes[7] = 35; /* # */
/* > Uncompressed chunk size - next 4 bytes */
header_bytes[11] = (stream->chunk_size >> 24) & 0xFF;
header_bytes[10] = (stream->chunk_size >> 16) & 0xFF;
header_bytes[9] = (stream->chunk_size >> 8) & 0xFF;
header_bytes[8] = stream->chunk_size & 0xFF;
header_bytes[11] = (stream->chunk_size >> 24) & 0xFF;
header_bytes[10] = (stream->chunk_size >> 16) & 0xFF;
header_bytes[9] = (stream->chunk_size >> 8) & 0xFF;
header_bytes[8] = stream->chunk_size & 0xFF;
/* > Total uncompressed data size - next 8 bytes */
header_bytes[19] = (stream->size >> 56) & 0xFF;
header_bytes[18] = (stream->size >> 48) & 0xFF;
header_bytes[17] = (stream->size >> 40) & 0xFF;
header_bytes[16] = (stream->size >> 32) & 0xFF;
header_bytes[15] = (stream->size >> 24) & 0xFF;
header_bytes[14] = (stream->size >> 16) & 0xFF;
header_bytes[13] = (stream->size >> 8) & 0xFF;
header_bytes[12] = stream->size & 0xFF;
header_bytes[19] = (stream->size >> 56) & 0xFF;
header_bytes[18] = (stream->size >> 48) & 0xFF;
header_bytes[17] = (stream->size >> 40) & 0xFF;
header_bytes[16] = (stream->size >> 32) & 0xFF;
header_bytes[15] = (stream->size >> 24) & 0xFF;
header_bytes[14] = (stream->size >> 16) & 0xFF;
header_bytes[13] = (stream->size >> 8) & 0xFF;
header_bytes[12] = stream->size & 0xFF;
/* Reset file to start */
filestream_seek(stream->file, 0, SEEK_SET);
/* Write header bytes */
length = filestream_write(stream->file, header_bytes, sizeof(header_bytes));
length = filestream_write(stream->file,
header_bytes, sizeof(header_bytes));
if (length != RZIP_HEADER_SIZE)
return false;
@ -447,15 +455,19 @@ rzipstream_t* rzipstream_open(const char *path, unsigned mode)
* in the RZIP file */
static bool rzipstream_read_chunk(rzipstream_t *stream)
{
uint8_t chunk_header_bytes[RZIP_CHUNK_HEADER_SIZE] = {0};
unsigned i;
int64_t length;
uint8_t chunk_header_bytes[RZIP_CHUNK_HEADER_SIZE];
uint32_t compressed_chunk_size;
uint32_t inflate_read;
uint32_t inflate_written;
int64_t length;
if (!stream || !stream->inflate_backend || !stream->inflate_stream)
return false;
for (i = 0; i < RZIP_CHUNK_HEADER_SIZE; i++)
chunk_header_bytes[i] = 0;
/* Attempt to read chunk header bytes */
length = filestream_read(
stream->file, chunk_header_bytes, sizeof(chunk_header_bytes));
@ -613,9 +625,9 @@ int rzipstream_getc(rzipstream_t *stream)
* have been read, returns NULL. */
char* rzipstream_gets(rzipstream_t *stream, char *s, size_t len)
{
size_t str_len;
int c = 0;
char *str_ptr = s;
size_t str_len;
if (!stream || stream->is_writing || (len == 0))
return NULL;
@ -732,14 +744,18 @@ error:
* as the next RZIP file chunk */
static bool rzipstream_write_chunk(rzipstream_t *stream)
{
uint8_t chunk_header_bytes[RZIP_CHUNK_HEADER_SIZE] = {0};
unsigned i;
int64_t length;
uint8_t chunk_header_bytes[RZIP_CHUNK_HEADER_SIZE];
uint32_t deflate_read;
uint32_t deflate_written;
int64_t length;
if (!stream || !stream->deflate_backend || !stream->deflate_stream)
return false;
for (i = 0; i < RZIP_CHUNK_HEADER_SIZE; i++)
chunk_header_bytes[i] = 0;
/* Compress data currently held in input buffer */
stream->deflate_backend->set_in(
stream->deflate_stream,
@ -1030,8 +1046,7 @@ int64_t rzipstream_get_size(rzipstream_t *stream)
if (stream->is_compressed)
return stream->size;
else
return filestream_get_size(stream->file);
return filestream_get_size(stream->file);
}
/* Returns EOF when no further *uncompressed* data
@ -1044,8 +1059,7 @@ int rzipstream_eof(rzipstream_t *stream)
if (stream->is_compressed)
return (stream->virtual_ptr >= stream->size) ?
EOF : 0;
else
return filestream_eof(stream->file);
return filestream_eof(stream->file);
}
/* Returns the offset of the current byte of *uncompressed*

View file

@ -30,6 +30,7 @@
#include <time/rtime.h>
#ifdef HAVE_THREADS
/* TODO/FIXME - global */
slock_t *rtime_localtime_lock = NULL;
#endif