mirror of
https://github.com/libretro/RetroArch
synced 2025-02-22 12:40:09 +00:00
(Core_info) Backport maister patch from two months ago - Start implementing
firmware detection
This commit is contained in:
parent
7f0aafbcba
commit
70f696bc56
@ -132,9 +132,9 @@ static NSString* build_string_pair(NSString* stringA, NSString* stringB)
|
|||||||
|
|
||||||
for (int i = 0; i < firmwareCount; i ++)
|
for (int i = 0; i < firmwareCount; i ++)
|
||||||
{
|
{
|
||||||
NSString* path = objc_get_value_from_config(_data.data, [NSString stringWithFormat:@"firmware%d_path", i + 1], @"Unspecified");
|
NSString* path = objc_get_value_from_config(_data.data, [NSString stringWithFormat:@"firmware%d_path", i], @"Unspecified");
|
||||||
path = [path stringByReplacingOccurrencesOfString:@"%sysdir%" withString:[RetroArch_iOS get].systemDirectory];
|
path = [path stringByReplacingOccurrencesOfString:@"%sysdir%" withString:[RetroArch_iOS get].systemDirectory];
|
||||||
[firmwareSection addObject:build_string_pair(objc_get_value_from_config(_data.data, [NSString stringWithFormat:@"firmware%d_desc", i + 1], @"Unspecified"), path)];
|
[firmwareSection addObject:build_string_pair(objc_get_value_from_config(_data.data, [NSString stringWithFormat:@"firmware%d_desc", i], @"Unspecified"), path)];
|
||||||
}
|
}
|
||||||
|
|
||||||
_firmwareSectionIndex = self.sections.count;
|
_firmwareSectionIndex = self.sections.count;
|
||||||
|
157
core_info.c
157
core_info.c
@ -24,10 +24,69 @@
|
|||||||
#include "config.h"
|
#include "config.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
static void core_info_list_resolve_all_extensions(core_info_list_t *core_info_list)
|
||||||
|
{
|
||||||
|
size_t i, all_ext_len = 0;
|
||||||
|
for (i = 0; i < core_info_list->count; i++)
|
||||||
|
{
|
||||||
|
all_ext_len += core_info_list->list[i].supported_extensions ?
|
||||||
|
(strlen(core_info_list->list[i].supported_extensions) + 2) : 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (all_ext_len)
|
||||||
|
{
|
||||||
|
all_ext_len += strlen("|zip");
|
||||||
|
core_info_list->all_ext = (char*)calloc(1, all_ext_len);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (core_info_list->all_ext)
|
||||||
|
{
|
||||||
|
for (i = 0; i < core_info_list->count; i++)
|
||||||
|
{
|
||||||
|
if (core_info_list->list[i].supported_extensions)
|
||||||
|
{
|
||||||
|
strlcat(core_info_list->all_ext, core_info_list->list[i].supported_extensions, all_ext_len);
|
||||||
|
strlcat(core_info_list->all_ext, "|", all_ext_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
strlcat(core_info_list->all_ext, "|zip", all_ext_len);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void core_info_list_resolve_all_firmware(core_info_list_t *core_info_list)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < core_info_list->count; i++)
|
||||||
|
{
|
||||||
|
core_info_t *info = &core_info_list->list[i];
|
||||||
|
|
||||||
|
if (!info->data)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
unsigned count;
|
||||||
|
if (!config_get_uint(info->data, "firmware_count", &count))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
info->firmware = (core_info_firmware_t*)calloc(count, sizeof(*info->firmware));
|
||||||
|
if (!info->firmware)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
for (unsigned c = 0; c < count; c++)
|
||||||
|
{
|
||||||
|
char path_key[64];
|
||||||
|
char desc_key[64];
|
||||||
|
snprintf(path_key, sizeof(path_key), "firmware%u_path", c);
|
||||||
|
snprintf(desc_key, sizeof(desc_key), "firmware%u_desc", c);
|
||||||
|
|
||||||
|
config_get_string(info->data, path_key, &info->firmware[c].path);
|
||||||
|
config_get_string(info->data, path_key, &info->firmware[c].desc);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
core_info_list_t *core_info_list_new(const char *modules_path)
|
core_info_list_t *core_info_list_new(const char *modules_path)
|
||||||
{
|
{
|
||||||
struct string_list *contents = dir_list_new(modules_path, EXT_EXECUTABLES, false);
|
struct string_list *contents = dir_list_new(modules_path, EXT_EXECUTABLES, false);
|
||||||
size_t all_ext_len, i;
|
size_t i;
|
||||||
|
|
||||||
core_info_t *core_info = NULL;
|
core_info_t *core_info = NULL;
|
||||||
core_info_list_t *core_info_list = NULL;
|
core_info_list_t *core_info_list = NULL;
|
||||||
@ -86,31 +145,8 @@ core_info_list_t *core_info_list_new(const char *modules_path)
|
|||||||
core_info[i].display_name = strdup(path_basename(core_info[i].path));
|
core_info[i].display_name = strdup(path_basename(core_info[i].path));
|
||||||
}
|
}
|
||||||
|
|
||||||
all_ext_len = 0;
|
core_info_list_resolve_all_extensions(core_info_list);
|
||||||
for (i = 0; i < core_info_list->count; i++)
|
core_info_list_resolve_all_firmware(core_info_list);
|
||||||
{
|
|
||||||
all_ext_len += core_info_list->list[i].supported_extensions ?
|
|
||||||
(strlen(core_info_list->list[i].supported_extensions) + 2) : 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (all_ext_len)
|
|
||||||
{
|
|
||||||
all_ext_len += strlen("|zip");
|
|
||||||
core_info_list->all_ext = (char*)calloc(1, all_ext_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (core_info_list->all_ext)
|
|
||||||
{
|
|
||||||
for (i = 0; i < core_info_list->count; i++)
|
|
||||||
{
|
|
||||||
if (core_info_list->list[i].supported_extensions)
|
|
||||||
{
|
|
||||||
strlcat(core_info_list->all_ext, core_info_list->list[i].supported_extensions, all_ext_len);
|
|
||||||
strlcat(core_info_list->all_ext, "|", all_ext_len);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
strlcat(core_info_list->all_ext, "|zip", all_ext_len);
|
|
||||||
}
|
|
||||||
|
|
||||||
dir_list_free(contents);
|
dir_list_free(contents);
|
||||||
return core_info_list;
|
return core_info_list;
|
||||||
@ -130,13 +166,22 @@ void core_info_list_free(core_info_list_t *core_info_list)
|
|||||||
|
|
||||||
for (i = 0; i < core_info_list->count; i++)
|
for (i = 0; i < core_info_list->count; i++)
|
||||||
{
|
{
|
||||||
free(core_info_list->list[i].path);
|
core_info_t *info = &core_info_list->list[i];
|
||||||
free(core_info_list->list[i].display_name);
|
|
||||||
free(core_info_list->list[i].supported_extensions);
|
free(info->path);
|
||||||
free(core_info_list->list[i].authors);
|
free(info->display_name);
|
||||||
string_list_free(core_info_list->list[i].supported_extensions_list);
|
free(info->supported_extensions);
|
||||||
string_list_free(core_info_list->list[i].authors_list);
|
free(info->authors);
|
||||||
config_file_free(core_info_list->list[i].data);
|
string_list_free(info->supported_extensions_list);
|
||||||
|
string_list_free(info->authors_list);
|
||||||
|
config_file_free(info->data);
|
||||||
|
|
||||||
|
for (size_t j = 0; j < info->firmware_count; j++)
|
||||||
|
{
|
||||||
|
free(info->firmware[j].path);
|
||||||
|
free(info->firmware[j].desc);
|
||||||
|
}
|
||||||
|
free(info->firmware);
|
||||||
}
|
}
|
||||||
|
|
||||||
free(core_info_list->all_ext);
|
free(core_info_list->all_ext);
|
||||||
@ -251,3 +296,49 @@ void core_info_list_get_supported_cores(core_info_list_t *core_info_list, const
|
|||||||
*num_infos = supported;
|
*num_infos = supported;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static core_info_t *find_core_info(core_info_list_t *list, const char *core)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < list->count; i++)
|
||||||
|
{
|
||||||
|
core_info_t *info = &list->list[i];
|
||||||
|
if (info->path && !strcmp(info->path, core))
|
||||||
|
return info;
|
||||||
|
}
|
||||||
|
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int core_info_firmware_cmp(const void *a_, const void *b_)
|
||||||
|
{
|
||||||
|
const core_info_firmware_t *a = (const core_info_firmware_t*)a_;
|
||||||
|
const core_info_firmware_t *b = (const core_info_firmware_t*)b_;
|
||||||
|
int order = b->missing - a->missing;
|
||||||
|
if (order)
|
||||||
|
return order;
|
||||||
|
else
|
||||||
|
return strcasecmp(a->path, b->path);
|
||||||
|
}
|
||||||
|
|
||||||
|
void core_info_list_get_missing_firmware(core_info_list_t *core_info_list,
|
||||||
|
const char *core, const char *systemdir,
|
||||||
|
const core_info_firmware_t **firmware, size_t *num_firmware)
|
||||||
|
{
|
||||||
|
*firmware = NULL;
|
||||||
|
*num_firmware = 0;
|
||||||
|
|
||||||
|
core_info_t *info = find_core_info(core_info_list, core);
|
||||||
|
if (!info)
|
||||||
|
return;
|
||||||
|
|
||||||
|
*firmware = info->firmware;
|
||||||
|
|
||||||
|
char path[PATH_MAX];
|
||||||
|
for (size_t i = 0; i < info->firmware_count; i++)
|
||||||
|
{
|
||||||
|
fill_pathname_join(path, systemdir, info->firmware[i].path, sizeof(path));
|
||||||
|
info->firmware[i].missing = !path_file_exists(path);
|
||||||
|
*num_firmware += info->firmware[i].missing;
|
||||||
|
}
|
||||||
|
|
||||||
|
qsort(info->firmware, info->firmware_count, sizeof(*info->firmware), core_info_firmware_cmp);
|
||||||
|
}
|
||||||
|
14
core_info.h
14
core_info.h
@ -24,6 +24,12 @@
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
char *path;
|
||||||
|
char *desc;
|
||||||
|
bool missing; // Set once to avoid opening the same file several times.
|
||||||
|
} core_info_firmware_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
char *path;
|
char *path;
|
||||||
config_file_t *data;
|
config_file_t *data;
|
||||||
@ -32,6 +38,9 @@ typedef struct {
|
|||||||
char *authors;
|
char *authors;
|
||||||
struct string_list *supported_extensions_list;
|
struct string_list *supported_extensions_list;
|
||||||
struct string_list *authors_list;
|
struct string_list *authors_list;
|
||||||
|
|
||||||
|
core_info_firmware_t *firmware;
|
||||||
|
size_t firmware_count;
|
||||||
} core_info_t;
|
} core_info_t;
|
||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
@ -52,6 +61,11 @@ bool core_info_does_support_any_file(const core_info_t *core, const struct strin
|
|||||||
void core_info_list_get_supported_cores(core_info_list_t *core_info_list, const char *path,
|
void core_info_list_get_supported_cores(core_info_list_t *core_info_list, const char *path,
|
||||||
const core_info_t **infos, size_t *num_infos);
|
const core_info_t **infos, size_t *num_infos);
|
||||||
|
|
||||||
|
// Non-reentrant, does not allocate. Returns pointer to internal state.
|
||||||
|
void core_info_list_get_missing_firmware(core_info_list_t *core_info_list,
|
||||||
|
const char *core, const char *systemdir,
|
||||||
|
const core_info_firmware_t **firmware, size_t *num_firmware);
|
||||||
|
|
||||||
const char *core_info_list_get_all_extensions(core_info_list_t *core_info_list);
|
const char *core_info_list_get_all_extensions(core_info_list_t *core_info_list);
|
||||||
|
|
||||||
bool core_info_list_get_display_name(core_info_list_t *core_info_list, const char *path, char *buf, size_t size);
|
bool core_info_list_get_display_name(core_info_list_t *core_info_list, const char *path, char *buf, size_t size);
|
||||||
|
Loading…
x
Reference in New Issue
Block a user