Refactor selection of file names

This commit is contained in:
simon.kagstrom 2009-04-18 10:15:08 +00:00
parent 218fba704c
commit f7f838d04d
4 changed files with 291 additions and 142 deletions

View File

@ -101,132 +101,61 @@ void C64::c64_dtor(void)
{
}
static int cmpstringp(const void *p1, const void *p2)
{
return strcmp(* (char * const *) p1, * (char * const *) p2);
}
/* Return true if name ends with ext (for filenames) */
static bool ext_matches(const char *name, const char *ext)
{
int len = strlen(name);
int ext_len = strlen(ext);
if (len <= ext_len)
return false;
return (strcmp(name + len - ext_len, ext) == 0);
}
static const char **get_file_list(const char *base_dir)
{
DIR *d = opendir(base_dir);
const char **file_list;
int cur = 0;
struct dirent *de;
int cnt = 16;
if (!d)
return NULL;
file_list = (const char**)malloc(cnt * sizeof(char*));
file_list[cur++] = strdup("None");
file_list[cur] = NULL;
for (de = readdir(d);
de;
de = readdir(d))
{
if (ext_matches(de->d_name, ".d64") || ext_matches(de->d_name, ".D64") ||
ext_matches(de->d_name, ".prg") || ext_matches(de->d_name, ".PRG") ||
ext_matches(de->d_name, ".p00") || ext_matches(de->d_name, ".P00") ||
ext_matches(de->d_name, ".s00") || ext_matches(de->d_name, ".S00") ||
ext_matches(de->d_name, ".t64") || ext_matches(de->d_name, ".T64") ||
ext_matches(de->d_name, ".sav"))
{
char *p;
p = strdup(de->d_name);
file_list[cur++] = p;
file_list[cur] = NULL;
if (cur > cnt - 2)
{
cnt = cnt + 32;
file_list = (const char**)realloc(file_list, cnt * sizeof(char*));
if (!file_list)
return NULL;
}
}
}
closedir(d);
qsort(&file_list[1], cur-1, sizeof(const char *), cmpstringp);
return file_list;
}
void C64::select_disc(Prefs *np)
{
const char **file_list = get_file_list(IMAGE_PATH);
const char *name = menu_select_file(IMAGE_PATH);
if (file_list == NULL)
if (name== NULL)
return;
int opt = menu_select(file_list, NULL);
if (opt >= 0)
if (strcmp(name, "None") == 0)
{
const char *name = file_list[opt];
if (strcmp(file_list[opt], "None") == 0)
{
strcpy(np->DrivePath[0], "\0");
strcpy(this->save_game_name, "unknown");
}
else
{
snprintf(np->DrivePath[0], 255, "%s/%s",
IMAGE_PATH, name);
strncpy(this->save_game_name, name, 255);
if (strstr(name, ".prg") || strstr(name, ".PRG") ||
strstr(name, ".p00") || strstr(name, ".P00") ||
strstr(name, ".s00") || strstr(name, ".S00")) {
FILE *src, *dst;
/* Clean temp dir first (we only want one file) */
unlink(TMP_PATH"/a");
src = fopen(np->DrivePath[0], "r");
if (src != NULL)
{
snprintf(np->DrivePath[0], 255, "%s", TMP_PATH);
/* Special handling of .prg: Copy to TMP_PATH and
* load that as a dir */
dst = fopen(TMP_PATH"/a", "w");
if (dst)
{
Uint8 buf[1024];
size_t v;
do {
v = fread(buf, 1, 1024, src);
fwrite(buf, 1, v, dst);
} while (v > 0);
fclose(dst);
}
fclose(src);
}
}
NewPrefs(np);
ThePrefs = *np;
}
this->prefs_changed = true;
strcpy(np->DrivePath[0], "\0");
strcpy(this->save_game_name, "unknown");
}
else
{
snprintf(np->DrivePath[0], 255, "%s/%s",
IMAGE_PATH, name);
strncpy(this->save_game_name, name, 255);
if (strstr(name, ".prg") || strstr(name, ".PRG") ||
strstr(name, ".p00") || strstr(name, ".P00") ||
strstr(name, ".s00") || strstr(name, ".S00")) {
FILE *src, *dst;
/* Cleanup everything */
for ( int i = 0; file_list[i]; i++ )
free((void*)file_list[i]);
free(file_list);
/* Clean temp dir first (we only want one file) */
unlink(TMP_PATH"/a");
src = fopen(np->DrivePath[0], "r");
if (src != NULL)
{
snprintf(np->DrivePath[0], 255, "%s", TMP_PATH);
/* Special handling of .prg: Copy to TMP_PATH and
* load that as a dir */
dst = fopen(TMP_PATH"/a", "w");
if (dst)
{
Uint8 buf[1024];
size_t v;
do {
v = fread(buf, 1, 1024, src);
fwrite(buf, 1, v, dst);
} while (v > 0);
fclose(dst);
}
fclose(src);
}
}
NewPrefs(np);
ThePrefs = *np;
}
this->prefs_changed = true;
/* Cleanup*/
free((void*)name);
}
@ -469,35 +398,28 @@ void C64::save_load_state(Prefs *np)
case 0: /* load/delete */
case 2:
{
const char **file_list = get_file_list(SAVES_PATH);
const char *name = menu_select_file(SAVES_PATH);
char save_buf[255];
char prefs_buf[255];
if (file_list == NULL)
if (name == NULL)
break;
int save = menu_select(file_list, NULL);
if (save >= 0)
{
char save_buf[255];
char prefs_buf[255];
snprintf(save_buf, 255, "%s/%s", SAVES_PATH, file_list[save]);
snprintf(prefs_buf, 255, "%s.prefs", save_buf);
if (opt == 2)
{
unlink(save_buf);
unlink(prefs_buf);
}
else /* Load the snapshot */
{
this->LoadSnapshot(save_buf);
np->Load(prefs_buf);
this->prefs_changed = true;
}
snprintf(save_buf, 255, "%s/%s", SAVES_PATH, name);
snprintf(prefs_buf, 255, "%s.prefs", save_buf);
if (opt == 2)
{
unlink(save_buf);
unlink(prefs_buf);
}
else /* Load the snapshot */
{
this->LoadSnapshot(save_buf);
np->Load(prefs_buf);
this->prefs_changed = true;
}
/* Cleanup everything */
for ( int i = 0; file_list[i]; i++ )
free((void*)file_list[i]);
free(file_list);
free((void*)name);
} break;
default:
break;

View File

@ -204,6 +204,71 @@ bool msgYesNo(char *text, bool default_opt, int x, int y)
}
static int cmpstringp(const void *p1, const void *p2)
{
return strcmp(* (char * const *) p1, * (char * const *) p2);
}
/* Return true if name ends with ext (for filenames) */
static bool ext_matches(const char *name, const char *ext)
{
int len = strlen(name);
int ext_len = strlen(ext);
if (len <= ext_len)
return false;
return (strcmp(name + len - ext_len, ext) == 0);
}
static const char **get_file_list(const char *base_dir)
{
DIR *d = opendir(base_dir);
const char **file_list;
int cur = 0;
struct dirent *de;
int cnt = 16;
if (!d)
return NULL;
file_list = (const char**)malloc(cnt * sizeof(char*));
file_list[cur++] = strdup("None");
file_list[cur] = NULL;
for (de = readdir(d);
de;
de = readdir(d))
{
if (ext_matches(de->d_name, ".d64") || ext_matches(de->d_name, ".D64") ||
ext_matches(de->d_name, ".prg") || ext_matches(de->d_name, ".PRG") ||
ext_matches(de->d_name, ".p00") || ext_matches(de->d_name, ".P00") ||
ext_matches(de->d_name, ".s00") || ext_matches(de->d_name, ".S00") ||
ext_matches(de->d_name, ".t64") || ext_matches(de->d_name, ".T64") ||
ext_matches(de->d_name, ".sav"))
{
char *p;
p = strdup(de->d_name);
file_list[cur++] = p;
file_list[cur] = NULL;
if (cur > cnt - 2)
{
cnt = cnt + 32;
file_list = (const char**)realloc(file_list, cnt * sizeof(char*));
if (!file_list)
return NULL;
}
}
}
closedir(d);
qsort(&file_list[1], cur-1, sizeof(const char *), cmpstringp);
return file_list;
}
static submenu_t *find_submenu(menu_t *p_menu, int index)
{
int i;
@ -838,6 +903,29 @@ int menu_select_sized(char *title, SDL_Rect *rc, const char **msgs, int *submenu
return out;
}
const char *menu_select_file(const char *dir_path)
{
const char **file_list = get_file_list(dir_path);
const char *out;
int opt;
if (file_list == NULL)
return NULL;
opt = menu_select(file_list, NULL, 0);
if (opt < 0)
return NULL;
out = strdup(file_list[opt]);
/* Cleanup everything - file_list is NULL-terminated */
for ( int i = 0; file_list[i]; i++ )
free((void*)file_list[i]);
free(file_list);
return out;
}
static TTF_Font *read_font(const char *path)
{
TTF_Font *out;

View File

@ -33,8 +33,10 @@ extern "C" {
void menu_print_font(SDL_Surface *screen, int r, int g, int b, int x, int y, const char *msg);
void menu_print_font64(SDL_Surface *screen, int r, int g, int b, int x, int y, const char *msg);
/* Various option selects */
int menu_select(const char **pp_msgs, int *p_submenus);
int menu_select_sized(char *title, SDL_Rect *rc, const char **msgs, int *submenus, int sel);
const char *menu_select_file(const char *dir_path);
uint32_t menu_wait_key_press(void);

137
Src/menutexts.c Normal file
View File

@ -0,0 +1,137 @@
#include <stdlib.h>
#include "menutexts.h"
const char *welcome[] = {
/*01*/ "#1 WELCOME TO FRODO ON WII ",
/*02*/ " ------------------------------------------------- ",
/*03*/ " In the system, hit HOME on the Wiimote to get to ",
/*04*/ " the config-page. Load or autostart a D64, T64, or ",
/*05*/ " PRG image. Use the virtual keyboard or assign the ",
/*06*/ " key strokes to buttons on the Wiimote. ",
/*07*/ " Save the game state in the main menu of the game. ",
/*08*/ " Next time you can load that state instead of the ",
/*09*/ " game to have all configured stuff along with that ",
/*10*/ " game. ",
/*11*/ " ",
/*12*/ " This version features USB-keyboard support and ",
/*13*/ " D64 content listing. Use first Wiimote as port 1 ",
/*14*/ " joystick and the second as port 2 joystick. ",
/*15*/ " ",
/*16*/ ".-------------------------------------------------.",
/*17*/ "^| Enter Frodo | Don't show again ",
NULL
};
const char *new_main_menu_messages[] = {
/*00*/ "#1.MAIN MENU ",
/*01*/ "#1-------------------------------------",
/*02*/ ".Image",
/*03*/ "^|Load|Start|Remove",
/*04*/ ".States",
/*05*/ "^|Load|Save|Delete|Rename ",
/*06*/ ".Keyboard",
/*07*/ "^|Type|Macro|Bind",
/*08*/ "#1-------------------------------------",
/*09*/ ".Reset the C=64",
/*10*/ ".Options",
/*11*/ ".Advanced Options",
/*12*/ ".Controls",
/*13*/ "#1-------------------------------------",
/*14*/ ".Quit",
/*15*/ "#1-------------------------------------",
/*16*/ "#1'2'=SELECT, '1'=CANCEL",
NULL
};
const char *new_options_menu_messages[] = {
/*00*/ "#1.OPTIONS MENU ",
/*01*/ "#1-------------------------------------",
/*02*/ ".Map Wiimote 1 to:",
/*03*/ "^|Port 1|Port 2",
/*04*/ " ",
/*05*/ ".True 1541 emulation",
/*06*/ "^|NO|YES",
/*07*/ " ",
/*08*/ ".1541 Floppy Drive LED", /* 0 */
/*09*/ "^|OFF|ON",
/*10*/ "#1-------------------------------------",
/*11*/ "#1'2'=SELECT, '1'=CANCEL",
NULL
};
const char *new_advanced_options_menu_messages[] = {
/*00*/ "#1.ADVANCED OPTIONS MENU ",
/*01*/ "#1-------------------------------------",
/*02*/ ".Display resolution", /* 0 */
/*03*/ "^|double-center|stretched",
/*04*/ " ",
/*05*/ ".Speed (approx.)", /* 2 */
/*06*/ "^|95|100|110",
/*07*/ " ",
/*08*/ ".Sprite collisions", /* 0 */
/*09*/ "^|OFF|ON",
/*10*/ " ",
/*11*/ ".Autostart", /* 0 */
/*12*/ "^|Save|Clear", /* 0 */
/*13*/ "#1-------------------------------------",
/*14*/ "#1'2'=SELECT, '1'=CANCEL",
NULL
};
const char *new_help_menu_messages[] = {
/*00*/ "#1.CONTROLS MENU ",
/*01*/ "#1-------------------------------------",
/*02*/ ".Wiimote key mappings", /* 0 */
/*03*/ "^|Wiimote Info|Set Default", /* 0 */
/*04*/ " ",
/*05*/ ".Show USB-keyboard layout", /* 0 */
/*06*/ "#1-------------------------------------",
/*07*/ "#1'2'=SELECT, '1'=CANCEL",
NULL
};
const char *layout_messages[] = {
"#1.USB-Keyboard Layout ",
"#1-------------------------------------",
"#2ESC = Run/Stop",
"#2F9 = QuickSave",
"#2F10 = QuickLoad",
"#2F11 = Restore",
"#2TAB = CTRL",
"#2INS = Clr/Home",
"#2PGU = ¤",
"#2AGR = C=",
"#2HOM = Menu",
"#1-------------------------------------",
"Back",
NULL,
};
const char *main_menu_messages[] = {
"Invoke key sequence", /* 0 */
"Insert disc or tape", /* 1 */
"Bind key to joystick",/* 2 */
"Other options", /* 3 */
"Networking", /* 4 */
"Controller 1 joystick port", /* 5 */
"^|1|2",
"Save/Load state", /* 7 */
" ",
"Quit", /* 9 */
NULL,
};
const char *save_load_state_messages[] = {
"Load saved state", /* 0 */
"Save current state", /* 1 */
"Delete state", /* 2 */
NULL,
};
const char *other_options_messages[] = {
"Display resolution", /* 0 */
"^|double-center|stretched",
"Speed (approx)", /* 2 */
"^|95|100|110",
"Emulate 1541", /* 4 */
"^|On|Off",
"Reset C64", /* 6 */
NULL,
};