(PS3) More refactoring of filebrowser - should be mostly platform-

agnostic now
This commit is contained in:
Twinaphex 2012-06-18 05:31:43 +02:00
parent 0b84f1744e
commit 805ca7e027
4 changed files with 43 additions and 224 deletions

View File

@ -19,204 +19,35 @@
#endif
#include "file_browser.h"
static int less_than_key(const void * a, const void * b)
{
DirectoryEntry * a_dir = (DirectoryEntry*)a;
DirectoryEntry * b_dir = (DirectoryEntry*)b;
/* compare a directory to a file directory is always lesser than*/
if ((a_dir->d_type == FS_TYPES_DIRECTORY && b_dir->d_type == FS_TYPES_FILE))
return -1;
else if (a_dir->d_type == FS_TYPES_FILE && b_dir->d_type == FS_TYPES_DIRECTORY)
return 1;
return strcasecmp(a_dir->d_name, b_dir->d_name);
}
static const char * filebrowser_get_extension(const char * filename)
{
const char * ext = strrchr(filename, '.');
if (ext)
return ext+1;
else
return "";
}
static void filebrowser_clear_current_entries(filebrowser_t * filebrowser)
{
for(uint32_t i = 0; i < MAX_FILE_LIMIT; i++)
{
filebrowser->current_dir.files[i].d_type = 0;
filebrowser->current_dir.files[i].d_namlen = 0;
strlcpy(filebrowser->current_dir.files[i].d_name, "\0", sizeof(filebrowser->current_dir.files[i].d_name));
}
}
static void filebrowser_parse_directory(filebrowser_t * filebrowser,
const char * path, const char * extensions)
{
int error = 0;
#if defined(_XBOX)
filebrowser->current_dir.size = 0;
strlcpy(filebrowser->dir[filebrowser->directory_stack_size], path, sizeof(filebrowser->dir[filebrowser->directory_stack_size]));
WIN32_FIND_DATA ffd;
HANDLE hFind = INVALID_HANDLE_VALUE;
filebrowser->current_dir.elems = dir_list_new(path, extensions, true);
filebrowser->current_dir.size = dir_list_size(filebrowser->current_dir.elems);
filebrowser->current_dir.ptr = 0;
char path_buf[PATH_MAX];
if (strlcpy(path_buf, path, sizeof(path_buf)) >= sizeof(path_buf))
{
error = 1;
goto error;
}
if (strlcat(path_buf, "\\*", sizeof(path_buf)) >= sizeof(path_buf))
{
error = 1;
goto error;
}
hFind = FindFirstFile(path_buf, &ffd);
if (hFind == INVALID_HANDLE_VALUE)
{
error = 1;
goto error;
}
do
{
strlcpy(filebrowser->dir[filebrowser->directory_stack_size], path, sizeof(filebrowser->dir[filebrowser->directory_stack_size]));
bool found_dir = false;
if(!(ffd.dwFileAttributes & FS_TYPES_DIRECTORY))
{
char tmp_extensions[512];
strlcpy(tmp_extensions, extensions, sizeof(tmp_extensions));
const char * current_extension = filebrowser_get_extension(ffd.cFileName);
bool found_rom = false;
if(current_extension)
{
char * pch = strtok(tmp_extensions, "|");
while (pch != NULL)
{
if(strcmp(current_extension, pch) == 0)
{
found_rom = true;
break;
}
pch = strtok(NULL, "|");
}
}
if(!found_rom)
continue;
}
else if (ffd.dwFileAttributes & FS_TYPES_DIRECTORY)
found_dir = true;
filebrowser->current_dir.files[filebrowser->current_dir.ptr].d_type = found_dir ? FS_TYPES_DIRECTORY : FS_TYPES_FILE;
snprintf(filebrowser->current_dir.files[filebrowser->current_dir.ptr].d_name, sizeof(filebrowser->current_dir.files[filebrowser->current_dir.ptr].d_name), ffd.cFileName);
filebrowser->current_dir.ptr++;
filebrowser->current_dir.size++;
}while (FindNextFile(hFind, &ffd) != 0 && (filebrowser->current_dir.ptr + 1) < MAX_FILE_LIMIT);
#elif defined(__CELLOS_LV2__)
int fd;
/* bad path*/
if (strcmp(path,"") == 0)
{
error = 1;
goto error;
}
/* delete old path*/
filebrowser_clear_current_entries(filebrowser);
if (cellFsOpendir(path, &fd) == CELL_FS_SUCCEEDED)
{
uint64_t nread = 0;
strlcpy(filebrowser->dir[filebrowser->directory_stack_size], path, sizeof(filebrowser->dir[filebrowser->directory_stack_size]));
filebrowser->current_dir.size = 0;
filebrowser->current_dir.ptr = 0;
CellFsDirent dirent;
while (cellFsReaddir(fd, &dirent, &nread) == CELL_FS_SUCCEEDED)
{
if (nread == 0)
break;
if ((dirent.d_type != FS_TYPES_FILE) && (dirent.d_type != FS_TYPES_DIRECTORY))
continue;
if (dirent.d_type == FS_TYPES_DIRECTORY && !(strcmp(dirent.d_name, ".")))
continue;
if (dirent.d_type == FS_TYPES_FILE)
{
char tmp_extensions[512];
strlcpy(tmp_extensions, extensions, sizeof(tmp_extensions));
const char * current_extension = filebrowser_get_extension(dirent.d_name);
bool found_rom = false;
if(current_extension)
{
char * pch = strtok(tmp_extensions, "|");
while (pch != NULL)
{
if(strcmp(current_extension, pch) == 0)
{
found_rom = true;
break;
}
pch = strtok(NULL, "|");
}
}
if(!found_rom)
continue;
}
filebrowser->current_dir.files[filebrowser->current_dir.ptr].d_type = dirent.d_type;
filebrowser->current_dir.files[filebrowser->current_dir.ptr].d_namlen = dirent.d_namlen;
strlcpy(filebrowser->current_dir.files[filebrowser->current_dir.ptr].d_name, dirent.d_name, sizeof(filebrowser->current_dir.files[filebrowser->current_dir.ptr].d_name));
++filebrowser->current_dir.ptr;
++filebrowser->current_dir.size;
}
cellFsClosedir(fd);
}
else
{
error = 1;
goto error;
}
#endif
qsort(filebrowser->current_dir.files, filebrowser->current_dir.size, sizeof(DirectoryEntry), less_than_key);
filebrowser->current_dir.ptr = 0;
error:
if(error)
{
RARCH_ERR("Failed to open directory: \"%s\"\n", path);
}
#ifdef _XBOX
FindClose(hFind);
#endif
dir_list_sort(filebrowser->current_dir.elems);
}
void filebrowser_new(filebrowser_t * filebrowser, const char * start_dir,
const char * extensions)
{
filebrowser_clear_current_entries(filebrowser);
filebrowser->directory_stack_size = 0;
strlcpy(filebrowser->extensions, extensions, sizeof(filebrowser->extensions));
filebrowser_parse_directory(filebrowser, start_dir, filebrowser->extensions);
filebrowser_parse_directory(filebrowser, start_dir, extensions);
}
void filebrowser_free(filebrowser_t * filebrowser)
{
dir_list_free(filebrowser->current_dir.elems);
filebrowser->current_dir.elems = NULL;
filebrowser->current_dir.size = 0;
filebrowser->current_dir.ptr = 0;
}
@ -226,7 +57,7 @@ const char * extensions)
filebrowser->directory_stack_size = 0;
strlcpy(filebrowser->extensions, extensions, sizeof(filebrowser->extensions));
filebrowser_parse_directory(filebrowser, start_dir, filebrowser->extensions);
filebrowser_parse_directory(filebrowser, start_dir, extensions);
}
void filebrowser_push_directory(filebrowser_t * filebrowser, const char * path,
@ -247,3 +78,8 @@ void filebrowser_pop_directory (filebrowser_t * filebrowser)
filebrowser_parse_directory(filebrowser, filebrowser->dir[filebrowser->directory_stack_size],
filebrowser->extensions);
}
const char * filebrowser_get_current_path (filebrowser_t *filebrowser)
{
return filebrowser->current_dir.elems[filebrowser->current_dir.ptr];
}

View File

@ -25,44 +25,28 @@
#ifdef __CELLOS_LV2__
#include <stdbool.h>
#include <cell/cell_fs.h>
#include <sys/types.h>
#define FS_MAX_PATH 256
#define FS_MAX_FS_PATH_LENGTH 255
#define MAX_FILE_LIMIT 8192
#elif defined(_XBOX)
#define FS_MAX_PATH MAX_PATH
#define FS_MAX_FS_PATH_LENGTH 2048
#define MAX_FILE_LIMIT 4096
#endif
#if defined(_XBOX)
#define FS_TYPES_DIRECTORY (FILE_ATTRIBUTE_DIRECTORY)
#define FS_TYPES_FILE (FILE_ATTRIBUTE_NORMAL)
#elif defined(__CELLOS_LV2__)
#define FS_TYPES_DIRECTORY (CELL_FS_TYPE_DIRECTORY)
#define FS_TYPES_FILE (CELL_FS_TYPE_REGULAR)
#endif
typedef struct {
uint8_t d_type;
uint8_t d_namlen;
char d_name[FS_MAX_PATH];
} DirectoryEntry;
typedef struct
{
uint32_t directory_stack_size;
char dir[MAX_DIR_STACK][FS_MAX_FS_PATH_LENGTH];
struct {
DirectoryEntry files[MAX_FILE_LIMIT];
char **elems;
size_t size;
size_t ptr;
} current_dir;
char extensions[FS_MAX_PATH]; /* allowed extensions*/
char extensions[FS_MAX_PATH];
} filebrowser_t;
void filebrowser_new(filebrowser_t * filebrowser, const char * start_dir, const char * extensions);
void filebrowser_new(filebrowser_t *filebrowser, const char * start_dir, const char * extensions);
void filebrowser_free(filebrowser_t *filebrowser);
void filebrowser_reset_start_directory(filebrowser_t * filebrowser, const char * start_dir, const char * extensions);
void filebrowser_push_directory(filebrowser_t * filebrowser, const char * path, bool with_extension);
void filebrowser_pop_directory (filebrowser_t * filebrowser);
@ -99,9 +83,9 @@ void filebrowser_pop_directory (filebrowser_t * filebrowser);
filebrowser->current_dir.ptr = filebrowser->current_dir.size - 1; \
}
#define FILEBROWSER_GET_CURRENT_FILENAME(filebrowser) (filebrowser.current_dir.files[filebrowser.current_dir.ptr].d_name)
#define FILEBROWSER_GET_CURRENT_FILENAME(filebrowser) (filebrowser.current_dir.elems[filebrowser.current_dir.ptr])
#define FILEBROWSER_GET_CURRENT_ENTRY_INDEX(filebrowser) (filebrowser.current_dir.ptr)
#define FILEBROWSER_IS_CURRENT_A_FILE(filebrowser) (filebrowser.current_dir.files[filebrowser.current_dir.ptr].d_type == CELL_FS_TYPE_REGULAR)
#define FILEBROWSER_IS_CURRENT_A_DIRECTORY(filebrowser) (filebrowser.current_dir.files[filebrowser.current_dir.ptr].d_type == CELL_FS_TYPE_DIRECTORY)
#define FILEBROWSER_IS_CURRENT_A_FILE(filebrowser) (path_file_exists(filebrowser.current_dir.elems[filebrowser.current_dir.ptr]))
#define FILEBROWSER_IS_CURRENT_A_DIRECTORY(filebrowser) (path_is_directory(filebrowser.current_dir.elems[filebrowser.current_dir.ptr]))
#endif /* FILEBROWSER_H_ */

View File

@ -264,8 +264,10 @@ char **dir_list_new(const char *dir, const char *ext, bool include_dirs)
if (!include_dirs && path_is_directory(name))
continue;
#ifndef __CELLOS_LV2__
if (!path_is_directory(name) && !string_list_find_elem(ext_list, file_ext))
continue;
#endif
char file_path[PATH_MAX];
snprintf(file_path, sizeof(file_path), "%s/%s", dir, name);

View File

@ -344,8 +344,10 @@ static void browser_render(filebrowser_t * b)
for ( i = page_base; i < file_count && i < page_base + NUM_ENTRY_PER_PAGE; ++i)
{
char fname_tmp[256];
fill_pathname_base(fname_tmp, b->current_dir.elems[i], sizeof(fname_tmp));
currentY = currentY + ySpacing;
cellDbgFontPuts(currentX, currentY, FONT_SIZE, i == current_index ? RED : b->current_dir.files[i].d_type == CELL_FS_TYPE_DIRECTORY ? GREEN : WHITE, b->current_dir.files[i].d_name);
cellDbgFontPuts(currentX, currentY, FONT_SIZE, i == current_index ? RED : WHITE, fname_tmp);
gl_render_msg_post(gl);
}
gl_render_msg_post(gl);
@ -818,8 +820,7 @@ static void apply_scaling (unsigned init_mode)
static void select_file(uint32_t menu_id)
{
char extensions[256], title[256], object[256], comment[256], dir_path[PATH_MAX],
path[PATH_MAX], *separatorslash;
char extensions[256], title[256], object[256], comment[256], dir_path[PATH_MAX], path[PATH_MAX];
uint64_t state, diff_state, button_was_pressed;
gl_t * gl = driver.video_data;
@ -893,15 +894,13 @@ static void select_file(uint32_t menu_id)
filebrowser_pop_directory(&tmpBrowser);
else
{
separatorslash = (strcmp(FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(tmpBrowser),"/") == 0) ? "" : "/";
snprintf(path, sizeof(path), "%s%s%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(tmpBrowser), separatorslash, FILEBROWSER_GET_CURRENT_FILENAME(tmpBrowser));
snprintf(path, sizeof(path), FILEBROWSER_GET_CURRENT_FILENAME(tmpBrowser));
filebrowser_push_directory(&tmpBrowser, path, true);
}
}
else if (FILEBROWSER_IS_CURRENT_A_FILE(tmpBrowser))
{
snprintf(path, sizeof(path), "%s/%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(tmpBrowser), FILEBROWSER_GET_CURRENT_FILENAME(tmpBrowser));
printf("path: %s\n", path);
snprintf(path, sizeof(path), FILEBROWSER_GET_CURRENT_FILENAME(tmpBrowser));
switch(menu_id)
{
@ -962,7 +961,7 @@ static void select_file(uint32_t menu_id)
static void select_directory(uint32_t menu_id)
{
char path[1024], newpath[1024], *separatorslash;
char path[1024], newpath[1024];
uint64_t state, diff_state, button_was_pressed;
gl_t * gl = driver.video_data;
@ -987,7 +986,7 @@ static void select_directory(uint32_t menu_id)
{
if(FILEBROWSER_IS_CURRENT_A_DIRECTORY(tmpBrowser))
{
snprintf(path, sizeof(path), "%s/%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(tmpBrowser), FILEBROWSER_GET_CURRENT_FILENAME(tmpBrowser));
snprintf(path, sizeof(path), FILEBROWSER_GET_CURRENT_FILENAME(tmpBrowser));
switch(menu_id)
{
case PATH_SAVESTATES_DIR_CHOICE:
@ -1039,8 +1038,7 @@ static void select_directory(uint32_t menu_id)
filebrowser_pop_directory(&tmpBrowser);
else
{
separatorslash = (strcmp(FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(tmpBrowser),"/") == 0) ? "" : "/";
snprintf(newpath, sizeof(newpath), "%s%s%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(tmpBrowser), separatorslash, FILEBROWSER_GET_CURRENT_FILENAME(tmpBrowser));
snprintf(newpath, sizeof(newpath), FILEBROWSER_GET_CURRENT_FILENAME(tmpBrowser));
filebrowser_push_directory(&tmpBrowser, newpath, false);
}
}
@ -1895,7 +1893,7 @@ static void select_setting(menu * menu_obj)
static void select_rom(void)
{
char newpath[1024], *separatorslash;
char newpath[1024];
uint64_t state, diff_state, button_was_pressed;
gl_t * gl = driver.video_data;
@ -1928,8 +1926,7 @@ static void select_rom(void)
}
else
{
separatorslash = (strcmp(FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(browser),"/") == 0) ? "" : "/";
snprintf(newpath, sizeof(newpath), "%s%s%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(browser), separatorslash, FILEBROWSER_GET_CURRENT_FILENAME(browser));
snprintf(newpath, sizeof(newpath), FILEBROWSER_GET_CURRENT_FILENAME(browser));
filebrowser_push_directory(&browser, newpath, true);
}
}
@ -1940,13 +1937,13 @@ static void select_rom(void)
retro_get_system_info(&info);
bool block_zip_extract = info.block_extract;
snprintf(rom_path_temp, sizeof(rom_path_temp), "%s/%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(browser), FILEBROWSER_GET_CURRENT_FILENAME(browser));
snprintf(rom_path_temp, sizeof(rom_path_temp), FILEBROWSER_GET_CURRENT_FILENAME(browser));
if((strstr(rom_path_temp, ".zip") || strstr(rom_path_temp, ".ZIP")) && !block_zip_extract)
rarch_extract_zipfile(rom_path_temp);
else
{
snprintf(g_console.rom_path, sizeof(g_console.rom_path), "%s/%s", FILEBROWSER_GET_CURRENT_DIRECTORY_NAME(browser), FILEBROWSER_GET_CURRENT_FILENAME(browser));
snprintf(g_console.rom_path, sizeof(g_console.rom_path), FILEBROWSER_GET_CURRENT_FILENAME(browser));
rarch_settings_change(S_START_RARCH);
}
}