summaryrefslogtreecommitdiff
path: root/menu.c
diff options
context:
space:
mode:
Diffstat (limited to 'menu.c')
-rw-r--r--menu.c292
1 files changed, 26 insertions, 266 deletions
diff --git a/menu.c b/menu.c
index 864edd4..57dc827 100644
--- a/menu.c
+++ b/menu.c
@@ -8,71 +8,16 @@
#include "backend.h"
#include "util.h"
#include "gst.h"
-#include "m68k_internal.h" //needed for get_native_address_trans, should be eliminated once handling of PC is cleaned up
-
-static menu_context *persist_path_menu;
-static void persist_path(void)
-{
- char const *parts[] = {get_userdata_dir(), PATH_SEP, "sticky_path"};
- char *pathfname = alloc_concat_m(3, parts);
- FILE *f = fopen(pathfname, "wb");
- if (f) {
- if (fwrite(persist_path_menu->curpath, 1, strlen(persist_path_menu->curpath), f) != strlen(persist_path_menu->curpath)) {
- warning("Failed to save menu path");
- }
- fclose(f);
- } else {
- warning("Failed to save menu path: Could not open %s for writing\n", pathfname);
-
- }
- free(pathfname);
-}
+#include "paths.h"
+#include "saves.h"
+#include "config.h"
static menu_context *get_menu(genesis_context *gen)
{
menu_context *menu = gen->extra;
if (!menu) {
gen->extra = menu = calloc(1, sizeof(menu_context));
- menu->curpath = NULL;
- char *remember_path = tern_find_path(config, "ui\0remember_path\0", TVAL_PTR).ptrval;
- if (!remember_path || !strcmp("on", remember_path)) {
- char const *parts[] = {get_userdata_dir(), PATH_SEP, "sticky_path"};
- char *pathfname = alloc_concat_m(3, parts);
- FILE *f = fopen(pathfname, "rb");
- if (f) {
- long pathsize = file_size(f);
- if (pathsize > 0) {
- menu->curpath = malloc(pathsize + 1);
- if (fread(menu->curpath, 1, pathsize, f) != pathsize) {
- warning("Error restoring saved menu path");
- free(menu->curpath);
- menu->curpath = NULL;
- } else {
- menu->curpath[pathsize] = 0;
- }
- }
- fclose(f);
- }
- free(pathfname);
- if (!persist_path_menu) {
- atexit(persist_path);
- }
- persist_path_menu = menu;
- }
- if (!menu->curpath) {
- menu->curpath = tern_find_path(config, "ui\0initial_path\0", TVAL_PTR).ptrval;
- }
- if (!menu->curpath){
-#ifdef __ANDROID__
- menu->curpath = get_external_storage_path();
-#else
- menu->curpath = "$HOME";
-#endif
- }
- tern_node *vars = tern_insert_ptr(NULL, "HOME", get_home_dir());
- vars = tern_insert_ptr(vars, "EXEDIR", get_exe_dir());
- menu->curpath = replace_vars(menu->curpath, vars, 1);
- tern_free(vars);
+ get_initial_browse_path(&menu->curpath);
}
return menu;
}
@@ -97,17 +42,6 @@ uint16_t menu_read_w(uint32_t address, void * vcontext)
}
}
-int menu_dir_sort(const void *a, const void *b)
-{
- const dir_entry *da, *db;
- da = a;
- db = b;
- if (da->is_dir != db->is_dir) {
- return db->is_dir - da->is_dir;
- }
- return strcasecmp(((dir_entry *)a)->name, ((dir_entry *)b)->name);
-}
-
void copy_string_from_guest(m68k_context *m68k, uint32_t guest_addr, char *buf, size_t maxchars)
{
char *cur;
@@ -150,54 +84,6 @@ void copy_to_guest(m68k_context *m68k, uint32_t guest_addr, char *src, size_t to
#define SAVE_INFO_BUFFER_SIZE (11*40)
-#ifdef __ANDROID__
-#include <SDL.h>
-#include <jni.h>
-char *get_external_storage_path()
-{
- static char *ret;
- if (ret) {
- return ret;
- }
- JNIEnv *env = SDL_AndroidGetJNIEnv();
- if ((*env)->PushLocalFrame(env, 8) < 0) {
- return NULL;
- }
-
- jclass Environment = (*env)->FindClass(env, "android/os/Environment");
- jmethodID getExternalStorageDirectory =
- (*env)->GetStaticMethodID(env, Environment, "getExternalStorageDirectory", "()Ljava/io/File;");
- jobject file = (*env)->CallStaticObjectMethod(env, Environment, getExternalStorageDirectory);
- if (!file) {
- goto cleanup;
- }
-
- jmethodID getAbsolutePath = (*env)->GetMethodID(env, (*env)->GetObjectClass(env, file),
- "getAbsolutePath", "()Ljava/lang/String;");
- jstring path = (*env)->CallObjectMethod(env, file, getAbsolutePath);
-
- char const *tmp = (*env)->GetStringUTFChars(env, path, NULL);
- ret = strdup(tmp);
- (*env)->ReleaseStringUTFChars(env, path, tmp);
-
-cleanup:
- (*env)->PopLocalFrame(env, NULL);
- return ret;
-}
-#endif
-
-#ifdef _WIN32
-#define localtime_r(a,b) localtime(a)
-//windows inclues seem not to like certain single letter defines from m68k_internal.h
-//get rid of them here
-#undef X
-#undef N
-#undef Z
-#undef V
-#undef C
-#include <windows.h>
-#endif
-
uint32_t copy_dir_entry_to_guest(uint32_t dst, m68k_context *m68k, char *name, uint8_t is_dir)
{
uint8_t *dest = get_native_pointer(dst, (void **)m68k->mem_pointers, &m68k->options->gen);
@@ -235,7 +121,9 @@ uint32_t copy_dir_entry_to_guest(uint32_t dst, m68k_context *m68k, char *name, u
}
return dst;
}
-
+#ifdef _WIN32
+#include <windows.h>
+#endif
void * menu_write_w(uint32_t address, void * context, uint16_t value)
{
m68k_context *m68k = context;
@@ -246,7 +134,7 @@ void * menu_write_w(uint32_t address, void * context, uint16_t value)
switch (address >> 2)
{
case 0: {
-#ifdef _WIN32
+#if _WIN32
//handle virtual "drives" directory
if (menu->curpath[0] == PATH_SEP[0]) {
char drivestrings[4096];
@@ -267,7 +155,7 @@ void * menu_write_w(uint32_t address, void * context, uint16_t value)
size_t num_entries;
dir_entry *entries = get_dir_list(menu->curpath, &num_entries);
if (entries) {
- qsort(entries, num_entries, sizeof(dir_entry), menu_dir_sort);
+ sort_dir_list(entries, num_entries);
} else {
warning("Failed to open directory %s: %s\n", menu->curpath, strerror(errno));
entries = malloc(sizeof(dir_entry));
@@ -281,40 +169,17 @@ void * menu_write_w(uint32_t address, void * context, uint16_t value)
dst = copy_dir_entry_to_guest(dst, m68k, "..", 1);
}
#endif
- char *ext_filter = strdup(tern_find_path_default(config, "ui\0extensions\0", (tern_val){.ptrval = "bin gen md smd sms gg"}, TVAL_PTR).ptrval);
- uint32_t num_exts = 0, ext_storage = 5;
- char **ext_list = malloc(sizeof(char *) * ext_storage);
- char *cur_filter = ext_filter;
- while (*cur_filter)
- {
- if (num_exts == ext_storage) {
- ext_storage *= 2;
- ext_list = realloc(ext_list, sizeof(char *) * ext_storage);
- }
- ext_list[num_exts++] = cur_filter;
- cur_filter = split_keyval(cur_filter);
- }
+ uint32_t num_exts;
+ char **ext_list = get_extension_list(config, &num_exts);
for (size_t i = 0; dst && i < num_entries; i++)
{
if (num_exts && !entries[i].is_dir) {
- char *ext = path_extension(entries[i].name);
- if (!ext) {
- continue;
- }
- uint32_t extidx;
- for (extidx = 0; extidx < num_exts; extidx++)
- {
- if (!strcasecmp(ext, ext_list[extidx])) {
- break;
- }
- }
- if (extidx == num_exts) {
+ if (!path_matches_extensions(entries[i].name, ext_list, num_exts)) {
continue;
}
}
dst = copy_dir_entry_to_guest(dst, m68k, entries[i].name, entries[i].is_dir);
}
- free(ext_filter);
free(ext_list);
//terminate list
uint8_t *dest = get_native_pointer(dst, (void **)m68k->mem_pointers, &m68k->options->gen);
@@ -327,42 +192,10 @@ void * menu_write_w(uint32_t address, void * context, uint16_t value)
case 1: {
char buf[4096];
copy_string_from_guest(m68k, dst, buf, sizeof(buf));
- if (!strcmp(buf, "..")) {
-#ifdef _WIN32
- if (menu->curpath[1] == ':' && !menu->curpath[2]) {
- menu->curpath[0] = PATH_SEP[0];
- menu->curpath[1] = 0;
- break;
- }
-#endif
- size_t len = strlen(menu->curpath);
- while (len > 0) {
- --len;
- if (is_path_sep(menu->curpath[len])) {
- if (!len) {
- //special handling for /
- menu->curpath[len+1] = 0;
- } else {
- menu->curpath[len] = 0;
- }
- break;
- }
- }
- } else {
- char *tmp = menu->curpath;
-#ifdef _WIN32
- if (menu->curpath[0] == PATH_SEP[0] && !menu->curpath[1]) {
- menu->curpath = strdup(buf);
- } else
-#endif
- if (is_path_sep(menu->curpath[strlen(menu->curpath) - 1])) {
- menu->curpath = alloc_concat(menu->curpath, buf);
- } else {
- char const *pieces[] = {menu->curpath, PATH_SEP, buf};
- menu->curpath = alloc_concat_m(3, pieces);
- }
- free(tmp);
- }
+ buf[sizeof(buf)-1] = 0;
+ char *tmp = menu->curpath;
+ menu->curpath = path_append(tmp, buf);
+ free(tmp);
break;
}
case 2:
@@ -399,63 +232,19 @@ void * menu_write_w(uint32_t address, void * context, uint16_t value)
char *cur = buffer;
if (gen->header.next_context && gen->header.next_context->save_dir) {
char *end = buffer + SAVE_INFO_BUFFER_SIZE;
- char slotfile[] = "slot_0.state";
- char slotfilegst[] = "slot_0.gst";
- char const * parts[3] = {gen->header.next_context->save_dir, PATH_SEP, slotfile};
- char const * partsgst[3] = {gen->header.next_context->save_dir, PATH_SEP, slotfilegst};
- struct tm ltime;
- char *fname;
- time_t modtime;
- for (int i = 0; i < 10 && cur < end; i++)
+ uint32_t num_slots;
+ save_slot_info *slots = get_slot_info(gen->header.next_context, &num_slots);
+ for (uint32_t i = 0; i < num_slots; i++)
{
- slotfile[5] = i + '0';
- fname = alloc_concat_m(3, parts);
- modtime = get_modification_time(fname);
- free(fname);
- if (modtime) {
- cur += snprintf(cur, end-cur, "Slot %d - ", i);
- cur += strftime(cur, end-cur, "%c", localtime_r(&modtime, &ltime));
-
- } else {
- slotfilegst[5] = i + '0';
- fname = alloc_concat_m(3, partsgst);
- modtime = get_modification_time(fname);
- free(fname);
- if (modtime) {
- cur += snprintf(cur, end-cur, "Slot %d - ", i);
- cur += strftime(cur, end-cur, "%c", localtime_r(&modtime, &ltime));
- } else {
- cur += snprintf(cur, end-cur, "Slot %d - EMPTY", i);
- }
- }
- //advance past the null terminator for this entry
- cur++;
- }
- if (cur < end) {
- parts[2] = "quicksave.state";
- fname = alloc_concat_m(3, parts);
- modtime = get_modification_time(fname);
- free(fname);
- if (modtime) {
- cur += strftime(cur, end-cur, "Quick - %c", localtime_r(&modtime, &ltime));
- } else {
- parts[2] = "quicksave.gst";
- fname = alloc_concat_m(3, parts);
- modtime = get_modification_time(fname);
- free(fname);
- if (modtime) {
- cur += strftime(cur, end-cur, "Quick - %c", localtime_r(&modtime, &ltime));
- } else if ((end-cur) > strlen("Quick - EMPTY")){
- cur += strlen(strcpy(cur, "Quick - EMPTY"));
- }
- }
- //advance past the null terminator for this entry
- cur++;
- if (cur < end) {
- //terminate the list
- *(cur++) = 0;
+ size_t desc_len = strlen(slots[i].desc) + 1;//+1 for string terminator
+ char *after = cur + desc_len + 1;//+1 for list terminator
+ if (after > cur) {
+ desc_len -= after - cur;
}
+ memcpy(cur, slots[i].desc, desc_len);
+ cur = after;
}
+ *cur = 0;//terminate list
} else {
*(cur++) = 0;
*(cur++) = 0;
@@ -475,36 +264,7 @@ void * menu_write_w(uint32_t address, void * context, uint16_t value)
if (gen->header.next_context && gen->header.next_context->save_dir) {
if (!gen->header.next_context->load_state(gen->header.next_context, dst)) {
break;
- }/*
- char numslotname[] = "slot_0.state";
- char *slotname;
- if (dst == QUICK_SAVE_SLOT) {
- slotname = "quicksave.state";
- } else {
- numslotname[5] = '0' + dst;
- slotname = numslotname;
- }
- char const *parts[] = {gen->header.next_context->save_dir, PATH_SEP, slotname};
- char *statepath = alloc_concat_m(3, parts);
- gen->header.next_context->load_state
- genesis_context *next = (genesis_context *)gen->header.next_context;
- deserialize_buffer state;
- uint32_t pc = 0;
- if (load_from_file(&state, statepath)) {
- genesis_deserialize(&state, next);
- free(state.data);
- //HACK
- pc = next->m68k->last_prefetch_address;
- } else {
- strcpy(statepath + strlen(statepath)-strlen("state"), "gst");
- pc = load_gst(next, statepath);
- }
- free(statepath);
- if (!pc) {
- break;
}
- next->m68k->resume_pc = get_native_address_trans(next->m68k, pc);
- */
}
m68k->should_return = 1;
break;