# HG changeset patch # User Michael Pavone # Date 1447049014 28800 # Node ID 54ffba3768d62d2387fc6cdc1950f362d6f68dcb # Parent b6842dfb8edfb7ab500ccca9e927f7301e735d29 Make menu stuff work on Android (theoretically) diff -r b6842dfb8edf -r 54ffba3768d6 blastem.c --- a/blastem.c Sun Nov 08 18:38:33 2015 -0800 +++ b/blastem.c Sun Nov 08 22:03:34 2015 -0800 @@ -1061,11 +1061,23 @@ if (!romfname) { romfname = "menu.bin"; } + if (romfname[0] == '/') { + if (!(rom_size = load_rom(romfname))) { + fatal_error("Failed to open UI ROM %s for reading", romfname); + } + } else { + long fsize; + cart = (uint16_t *)read_bundled_file(romfname, &fsize); + if (!cart) { + fatal_error("Failed to open UI ROM %s for reading", romfname); + } + rom_size = nearest_pow2(fsize); + if (rom_size > fsize) { + cart = realloc(cart, rom_size); + } + } //TODO: load relative to executable or from assets depending on platform - if (!(rom_size = load_rom(romfname))) { - fatal_error("Failed to open UI ROM %s for reading", romfname); - } loaded = 1; } tern_node *rom_db = load_rom_db(); diff -r b6842dfb8edf -r 54ffba3768d6 config.c --- a/config.c Sun Nov 08 18:38:33 2015 -0800 +++ b/config.c Sun Nov 08 22:03:34 2015 -0800 @@ -82,13 +82,13 @@ return head; } -tern_node * parse_config(char * config_data) +tern_node *parse_config(char * config_data) { int line = 1; return parse_config_int(&config_data, 0, &line); } -tern_node * parse_config_file(char * config_path) +tern_node *parse_config_file(char *config_path) { tern_node * ret = NULL; FILE * config_file = fopen(config_path, "rb"); @@ -114,85 +114,44 @@ return ret; } -#ifdef __ANDROID__ -#include - -tern_node * parse_config_file_assets(char *config_path) +tern_node *parse_bundled_config(char *config_name) { - tern_node * ret = NULL; - SDL_RWops *rw = SDL_RWFromFile(config_path, "rb"); - if (!rw) { - goto open_fail; - } - size_t config_size = rw->size(rw); - if (!config_size) { - goto config_empty; + long confsize; + char *confdata = read_bundled_file(config_name, &confsize); + tern_node *ret = NULL; + if (confdata) { + confdata[confsize] = 0; + ret = parse_config(confdata); + free(confdata); } - - char * config_data = malloc(config_size+1); - if (SDL_RWread(rw, config_data, 1, config_size) != config_size) { - goto config_read_fail; - } - config_data[config_size] = '\0'; - - ret = parse_config(config_data); -config_read_fail: - free(config_data); -config_empty: - SDL_RWclose(rw); -open_fail: return ret; } -tern_node * load_config() +tern_node *load_config() { - char *path = alloc_concat(SDL_AndroidGetInternalStoragePath(), "/blastem.cfg"); - tern_node * ret = parse_config_file(path); - free(path); - if (ret) { - return ret; - } - - ret = parse_config_file_assets("default.cfg"); - if (ret) { - return ret; - } - - fatal_error("Failed to find a config file in internal storage or in the blastem APK\n"); - //this will never get reached, but the compiler doesn't know that. Let's make it happy - return NULL; -} - -#else - -tern_node * load_config() -{ - char * exe_dir; - char * home = get_home_dir(); + char *confdir = get_config_dir(); + char *confpath = NULL; tern_node *ret; - if (home) { - char * path = alloc_concat(home, "/.config/blastem/blastem.cfg"); - ret = parse_config_file(path); - free(path); + if (confdir) { + confpath = alloc_concat(confdir, "/blastem.cfg"); + ret = parse_config_file(confpath); if (ret) { + free(confpath); return ret; } } - exe_dir = get_exe_dir(); - if (exe_dir) { - char *path = alloc_concat(exe_dir, "/default.cfg"); - ret = parse_config_file(path); - free(path); - if (ret) { - return ret; - } + ret = parse_bundled_config("default.cfg"); + if (ret) { + free(confpath); + return ret; } - fatal_error("Failed to find a config file in ~/.config/blastem/blastem.cfg or in the blastem executable directory\n"); + if (confpath) { + fatal_error("Failed to find a config file at %s or in the blastem executable directory\n", confpath); + } else { + fatal_error("Failed to find a config file in the BlastEm executable directory and the config directory path could not be determined\n"); + } //this will never get reached, but the compiler doesn't know that. Let's make it happy return NULL; } - -#endif - diff -r b6842dfb8edf -r 54ffba3768d6 config.h --- a/config.h Sun Nov 08 18:38:33 2015 -0800 +++ b/config.h Sun Nov 08 22:03:34 2015 -0800 @@ -7,11 +7,9 @@ #define CONFIG_H_ #include "tern.h" -tern_node * parse_config_file(char * config_path); -tern_node * load_config(); -#ifdef __ANDROID__ -tern_node * parse_config_file_assets(char *config_path); -#endif +tern_node *parse_config_file(char *config_path); +tern_node *parse_bundled_config(char *config_name); +tern_node *load_config(); #endif //CONFIG_H_ diff -r b6842dfb8edf -r 54ffba3768d6 menu.c --- a/menu.c Sun Nov 08 18:38:33 2015 -0800 +++ b/menu.c Sun Nov 08 22:03:34 2015 -0800 @@ -59,7 +59,15 @@ if (!menu) { gen->extra = menu = calloc(1, sizeof(menu_context)); menu->curpath = tern_find_path(config, "ui\0initial_path\0").ptrval; - menu->curpath = menu->curpath ? strdup(menu->curpath) : strdup(get_home_dir()); + if (menu->curpath) { + menu->curpath = strdup(menu->curpath); + } else { +#ifdef __ANDROID__ + menu->curpath = strdup(SDL_AndroidGetExternalStoragePath()); +#else + menu->curpath = strdup(get_home_dir()); +#endif + } } if (menu->state) { uint32_t dst = menu->latch << 16 | value; @@ -141,7 +149,6 @@ char *pieces[] = {menu->curpath, "/", buf}; gen->next_rom = alloc_concat_m(3, pieces); m68k->should_return = 1; - fprintf(stderr, "MENU: Selected ROM %s\n", buf); break; } default: diff -r b6842dfb8edf -r 54ffba3768d6 romdb.c --- a/romdb.c Sun Nov 08 18:38:33 2015 -0800 +++ b/romdb.c Sun Nov 08 22:03:34 2015 -0800 @@ -385,17 +385,7 @@ tern_node *load_rom_db() { -#ifdef __ANDROID__ - tern_node *db = parse_config_file_assets("rom.db"); -#else - char *exe_dir = get_exe_dir(); - if (!exe_dir) { - fatal_error("Failed to find executable path\n"); - } - char *path = alloc_concat(exe_dir, "/rom.db"); - tern_node *db = parse_config_file(path); - free(path); -#endif + tern_node *db = parse_bundled_config("rom.db"); if (!db) { fatal_error("Failed to load ROM DB\n"); } diff -r b6842dfb8edf -r 54ffba3768d6 util.c --- a/util.c Sun Nov 08 18:38:33 2015 -0800 +++ b/util.c Sun Nov 08 22:03:34 2015 -0800 @@ -321,3 +321,94 @@ } #endif + +#ifdef __ANDROID__ + +#include +char *read_bundled_file(char *name, long *sizeret) +{ + SDL_RWops *rw = SDL_RWFromFile(config_path, "rb"); + if (!rw) { + if (sizeret) { + *sizeret = -1; + } + return NULL; + } + + long fsize = rw->size(rw); + if (sizeret) { + *sizeret = fsize; + } + char *ret; + if (fsize) { + ret = malloc(fsize); + if (SDL_RWread(rw, ret, 1, fsize) != fsize) { + free(ret); + ret = NULL; + } + } else { + ret = NULL; + } + SDL_RWclose(rw); + return ret; +} + +char *get_config_dir() +{ + return SDL_AndroidGetInternalStoragePath(); +} + +#else + +char *read_bundled_file(char *name, long *sizeret) +{ + char *exe_dir = get_exe_dir(); + if (!exe_dir) { + if (sizeret) { + *sizeret = -1; + } + return NULL; + } + char *pieces[] = {exe_dir, "/", name}; + char *path = alloc_concat_m(3, pieces); + FILE *f = fopen(path, "rb"); + free(path); + if (!f) { + if (sizeret) { + *sizeret = -1; + } + return NULL; + } + + long fsize = file_size(f); + if (sizeret) { + *sizeret = fsize; + } + char *ret; + if (fsize) { + //reserve an extra byte in case caller wants + //to null terminate the data + ret = malloc(fsize+1); + if (fread(ret, 1, fsize, f) != fsize) { + free(ret); + ret = NULL; + } + } else { + ret = NULL; + } + return ret; +} + +char *get_config_dir() +{ + static char* confdir; + if (!confdir) { + char *homedir = get_home_dir(); + if (homedir) { + confdir = alloc_concat(homedir, "/.config/blastem"); + } + } + return confdir; +} + +#endif diff -r b6842dfb8edf -r 54ffba3768d6 util.h --- a/util.h Sun Nov 08 18:38:33 2015 -0800 +++ b/util.h Sun Nov 08 22:03:34 2015 -0800 @@ -28,6 +28,10 @@ char * get_exe_dir(); //Returns the user's home directory char * get_home_dir(); +//Returns an appropriate path for storing config files +char *get_config_dir(); +//Reads a file bundled with the executable +char *read_bundled_file(char *name, long *sizeret); //Retunrs an array of normal files and directories residing in a directory dir_entry *get_dir_list(char *path, size_t *numret); //Frees a dir list returned by get_dir_list