(Core_info) Backport maister patch from two months ago - Start implementing

firmware detection
This commit is contained in:
twinaphex 2013-11-21 23:48:31 +01:00
parent 7f0aafbcba
commit 70f696bc56
3 changed files with 140 additions and 35 deletions

View File

@ -132,9 +132,9 @@ static NSString* build_string_pair(NSString* stringA, NSString* stringB)
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];
[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;

View File

@ -24,10 +24,69 @@
#include "config.h"
#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)
{
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_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));
}
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);
}
core_info_list_resolve_all_extensions(core_info_list);
core_info_list_resolve_all_firmware(core_info_list);
dir_list_free(contents);
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++)
{
free(core_info_list->list[i].path);
free(core_info_list->list[i].display_name);
free(core_info_list->list[i].supported_extensions);
free(core_info_list->list[i].authors);
string_list_free(core_info_list->list[i].supported_extensions_list);
string_list_free(core_info_list->list[i].authors_list);
config_file_free(core_info_list->list[i].data);
core_info_t *info = &core_info_list->list[i];
free(info->path);
free(info->display_name);
free(info->supported_extensions);
free(info->authors);
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);
@ -251,3 +296,49 @@ void core_info_list_get_supported_cores(core_info_list_t *core_info_list, const
*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);
}

View File

@ -24,6 +24,12 @@
extern "C" {
#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 {
char *path;
config_file_t *data;
@ -32,6 +38,9 @@ typedef struct {
char *authors;
struct string_list *supported_extensions_list;
struct string_list *authors_list;
core_info_firmware_t *firmware;
size_t firmware_count;
} core_info_t;
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,
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);
bool core_info_list_get_display_name(core_info_list_t *core_info_list, const char *path, char *buf, size_t size);