changeset 875:54ffba3768d6

Make menu stuff work on Android (theoretically)
author Michael Pavone <pavone@retrodev.com>
date Sun, 08 Nov 2015 22:03:34 -0800
parents b6842dfb8edf
children 540cc4a7d626
files blastem.c config.c config.h menu.c romdb.c util.c util.h
diffstat 7 files changed, 149 insertions(+), 88 deletions(-) [+]
line wrap: on
line diff
--- 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();
--- 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 <SDL.h>
-
-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
-
--- 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_
 
--- 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:
--- 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");
 	}
--- 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 <SDL.h>
+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
--- 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