big refactor

refactored most of the history / favorite code to now be "bookkeeping".
this now uses a common struct to hold the required paths and the record type (to open up future work for emus).
This commit is contained in:
Ross Gouldthorpe 2024-12-06 23:10:25 +00:00
parent c2be0c2f20
commit 1fecd26f0b
18 changed files with 451 additions and 322 deletions

View File

@ -57,6 +57,7 @@ SRCS = \
menu/ui_components/common.c \
menu/ui_components/context_menu.c \
menu/ui_components/file_list.c \
menu/ui_components/tabs.c \
menu/usb_comm.c \
menu/views/browser.c \
menu/views/credits.c \

0
New Text Document.txt Normal file
View File

View File

@ -22,8 +22,8 @@ static void actions_clear (menu_t *menu) {
menu->actions.options = false;
menu->actions.settings = false;
menu->actions.lz_context = false;
menu->actions.favorite = false;
menu->actions.load_last = false;
menu->actions.previous_tab = false;
menu->actions.next_tab = false;
}
static void actions_update_direction (menu_t *menu) {
@ -112,9 +112,9 @@ static void actions_update_buttons (menu_t *menu) {
} else if (pressed.l || pressed.z) {
menu->actions.lz_context = true;
} else if (pressed.c_left) {
menu->actions.load_last = true;
menu->actions.previous_tab = true;
} else if (pressed.c_right) {
menu->actions.favorite = true;
menu->actions.next_tab = true;
}
}

View File

@ -72,9 +72,9 @@ static void menu_init (boot_params_t *boot_params) {
path_pop(path);
path_push(path, MENU_HISTORY_FILE);
history_init(path_get(path));
history_load(&menu->history);
menu->load.load_last = false;
bookkeeping_init(path_get(path));
bookkeeping_load(&menu->history);
menu->load.load_history = -1;
menu->load.load_favorite = -1;
path_pop(path);
@ -158,7 +158,8 @@ static view_t menu_views[] = {
{ MENU_MODE_LOAD_EMULATOR, view_load_emulator_init, view_load_emulator_display },
{ MENU_MODE_ERROR, view_error_init, view_error_display },
{ MENU_MODE_FAULT, view_fault_init, view_fault_display },
{ MENU_MODE_FAVORITE, view_favorite_init, view_favorite_display }
{ MENU_MODE_FAVORITE, view_favorite_init, view_favorite_display },
{ MENU_MODE_HISTORY, view_history_init, view_history_display }
};
static view_t *menu_get_view (menu_mode_t id) {

View File

@ -39,7 +39,8 @@ typedef enum {
MENU_MODE_ERROR,
MENU_MODE_FAULT,
MENU_MODE_BOOT,
MENU_MODE_FAVORITE
MENU_MODE_FAVORITE,
MENU_MODE_HISTORY
} menu_mode_t;
/** @brief File entry type enumeration */
@ -69,7 +70,7 @@ typedef struct {
const char *storage_prefix;
settings_t settings;
history_t history;
bookkeeping_t history;
boot_params_t *boot_params;
char *error_message;
@ -89,8 +90,8 @@ typedef struct {
bool options;
bool settings;
bool lz_context;
bool favorite;
bool load_last;
bool previous_tab;
bool next_tab;
} actions;
struct {
@ -108,7 +109,7 @@ typedef struct {
rom_info_t rom_info;
path_t *disk_path;
disk_info_t disk_info;
bool load_last;
int load_history;
int load_favorite;
} load;

View File

@ -149,4 +149,14 @@ bool path_has_value(path_t *path) {
}
}
return false;
}
bool path_are_match(path_t *left, path_t *right) {
if(!path_has_value(left) && !path_has_value(right)) {
return true;
} else if(path_has_value(left) && path_has_value(right)) {
return (strcmp(path_get(left), path_get(right)) == 0);
} else {
return false;
}
}

View File

@ -34,5 +34,6 @@ char *path_ext_get (path_t *path);
void path_ext_remove (path_t *path);
void path_ext_replace (path_t *path, char *ext);
bool path_has_value(path_t *path);
bool path_are_match(path_t *left, path_t *right);
#endif

View File

@ -10,10 +10,10 @@
static char *history_path = NULL;
static path_t* empty_path = NULL;
static history_t init;
static bookkeeping_t init;
/** @brief Init history path */
void history_init (char *path) {
void bookkeeping_init (char *path) {
if (history_path) {
free(history_path);
}
@ -21,213 +21,151 @@ void history_init (char *path) {
empty_path = path_create("");
}
void bookkeeping_ini_load_list(bookkeeping_item_t* list, int count, mini_t* ini, const char* group)
{
char buf[64];
for(int i=0;i<count; i++) {
sprintf(buf,"%d_primary_path", i);
list[i].primary_path = path_create(mini_get_string(ini, group, buf, ""));
sprintf(buf,"%d_secondary_path", i);
list[i].secondary_path = path_create(mini_get_string(ini, group, buf, ""));
sprintf(buf,"%d_type", i);
list[i].bookkeeping_type = mini_get_int(ini, group, buf, HISTORY_TYPE_EMPTY);
}
}
/** @brief The history to load */
void history_load (history_t *history) {
void bookkeeping_load (bookkeeping_t *history) {
if (!file_exists(history_path)) {
history_save(&init);
bookkeeping_save(&init);
}
mini_t *ini = mini_try_load(history_path);
history->last_rom = path_create(mini_get_string(ini, "history", "last_rom", ""));
history->last_disk = path_create(mini_get_string(ini, "history", "last_disk", ""));
bookkeeping_ini_load_list(history->history_items, HISTORY_COUNT, ini, "history");
bookkeeping_ini_load_list(history->favorite_items, HISTORY_COUNT, ini, "favorite");
char buffer[1024];
for(int i=0;i<FAVORITES_COUNT;i++) {
#if EMULATOR_TEST
sprintf(buffer, "test:\\somepaths\\blah\\rom - %d.n64", i);
history->favorites_rom[i] = path_create(buffer);
#else
sprintf(buffer,"%dfavorite_rom", i);
history->favorites_rom[i] = path_create(mini_get_string(ini, "favorite", buffer, ""));
#endif
}
for(int i=0;i<FAVORITES_COUNT;i++) {
#if EMULATOR_TEST
sprintf(buffer, "test:\\aother\\foo\\disk - %d.dd", i);
history->favorites_disk[i] = path_create(buffer);
#else
sprintf(buffer,"%dfavorite_disk", i);
history->favorites_disk[i] = path_create(mini_get_string(ini, "favorite", buffer, ""));
#endif
}
mini_free(ini);
}
static void bookkeeping_ini_save_list(bookkeeping_item_t* list, int count, mini_t* ini, const char* group)
{
char buf[64];
for(int i=0;i<count; i++) {
sprintf(buf,"%d_primary_path", i);
path_t* path = list[i].primary_path;
mini_set_string(ini, group, buf, path != NULL ? path_get(path) : "");
sprintf(buf,"%d_secondary_path", i);
path = list[i].secondary_path;
mini_set_string(ini, group, buf, path != NULL ? path_get(path) : "");
sprintf(buf,"%d_type", i);
mini_set_int(ini, group, buf, list[i].bookkeeping_type);
}
}
/** @brief The history to save */
void history_save (history_t *history)
void bookkeeping_save (bookkeeping_t *history)
{
mini_t *ini = mini_create(history_path);
mini_set_string(ini, "history", "last_rom", history->last_rom != NULL ? path_get(history->last_rom) : "");
mini_set_string(ini, "history", "last_disk", history->last_disk != NULL ? path_get(history->last_disk) : "");
char buf[20];
for(int i=0;i<FAVORITES_COUNT;i++) {
sprintf(buf,"%dfavorite_rom", i);
path_t* path = history->favorites_rom[i];
mini_set_string(ini, "favorite", buf, path != NULL ? path_get(path) : "");
}
for(int i=0;i<FAVORITES_COUNT;i++) {
sprintf(buf,"%dfavorite_disk", i);
path_t* path = history->favorites_disk[i];
mini_set_string(ini, "favorite", buf, path != NULL ? path_get(path) : "");
}
bookkeeping_ini_save_list(history->history_items, HISTORY_COUNT, ini, "history");
bookkeeping_ini_save_list(history->favorite_items, FAVORITES_COUNT, ini, "favorite");
mini_save(ini, MINI_FLAGS_SKIP_EMPTY_GROUPS);
mini_free(ini);
}
static void history_last_rom_update(history_t *history, path_t* path) {
if(history->last_rom != NULL) {
path_free(history->last_rom);
}
if(path != NULL) {
history->last_rom = path_clone(path);
} else {
history->last_rom = path_create("");
}
}
static void history_last_disk_update(history_t *history, path_t* path) {
if(history->last_disk != NULL) {
path_free(history->last_disk);
}
if(path != NULL) {
history->last_disk = path_clone(path);
} else {
history->last_disk = path_create("");
}
}
void history_last_rom_set(history_t *history, path_t* disk_path, path_t* rom_path)
{
history_last_rom_update(history, rom_path);
history_last_disk_update(history, disk_path);
history_save(history);
}
static void history_favorite_insert(history_t *history, int location, path_t* rom, path_t* disk) {
if(history->favorites_rom[location]) {
path_free(history->favorites_rom[location]);
}
if(history->favorites_disk[location]) {
path_free(history->favorites_disk[location]);
}
history->favorites_rom[location] = rom != NULL ? path_clone(rom) : path_create("");
history->favorites_disk[location] = rom != NULL ? path_clone(disk) : path_create("");
}
static void history_favorite_replace(history_t *history, int toReplace, path_t* rom, path_t* disk) {
if(history->favorites_rom[toReplace]) {
path_free(history->favorites_rom[toReplace]);
history->favorites_rom[toReplace] = NULL;
}
if(rom != NULL) {
history->favorites_rom[toReplace] = path_clone(rom);
}
if(history->favorites_disk[toReplace]) {
path_free(history->favorites_disk[toReplace]);
history->favorites_disk[toReplace] = NULL;
}
if(disk != NULL) {
history->favorites_disk[toReplace] = path_clone(disk);
}
}
static void history_favorite_rotate(history_t *history)
{
for(int i=1;i<FAVORITES_COUNT-1;i++) {
int previous = i-1;
history_favorite_replace(history, previous, history->favorites_rom[i], history->favorites_disk[i]);
}
history_favorite_replace(history, FAVORITES_COUNT -1, NULL, NULL);
}
static bool history_favorite_check_match(path_t* left, path_t* right) {
bool matches = false;
if(left == NULL && right == NULL) {
matches = true;
} else {
if(left != NULL && right != NULL) {
matches = (strcmp(path_get(left), path_get(right)) == 0);
}
}
return matches;
}
static bool history_favorite_exists(history_t *history, path_t* rom, path_t* disk) {
for(int i=0;i<FAVORITES_COUNT;i++) {
bool romMatch = history_favorite_check_match(history->favorites_rom[i], rom);
bool diskMatch = history_favorite_check_match(history->favorites_disk[i], disk);
if(romMatch && diskMatch) {
return true;
}
static bool bookkeeping_item_match(bookkeeping_item_t* left, bookkeeping_item_t* right) {
if(left != NULL && right != NULL) {
return path_are_match(left->primary_path, right->primary_path) && path_are_match(left->secondary_path, right->secondary_path) && left->bookkeeping_type == right->bookkeeping_type;
}
return false;
}
void history_favorite_add(history_t *history, path_t* rom, path_t* disk) {
// if the game is already in the favorite list then don't add again
if(rom == NULL) {
rom = empty_path;
static void bookkeeping_clear_item(bookkeeping_item_t* item) {
if(item->primary_path != NULL){
path_free(item->primary_path);
}
if(disk == NULL) {
disk = empty_path;
if(item->secondary_path != NULL){
path_free(item->secondary_path);
}
item->bookkeeping_type = HISTORY_TYPE_EMPTY;
}
if(history_favorite_exists(history, rom, disk)) {
static void bookkeeping_copy_item(bookkeeping_item_t* source, bookkeeping_item_t* destination){
bookkeeping_clear_item(destination);
destination->primary_path = path_clone(source->primary_path);
destination->secondary_path = source->secondary_path != NULL ? path_clone(source->secondary_path) : path_create("");
destination->bookkeeping_type = source->bookkeeping_type;
}
static void bookkeeping_move_items_down(bookkeeping_item_t* list, int start, int end) {
int current = end;
do {
if(current <= start || current < 0) {
break;
}
bookkeeping_copy_item(&list[current - 1], &list[current]);
current--;
} while(true);
}
static void bookkeeping_insert_top(bookkeeping_item_t* list, int count, bookkeeping_item_t* new_item) {
// if it matches the top of the list already then nothing to do
if(bookkeeping_item_match(&list[0], new_item)) {
return;
}
// look for a free space in the list
int place = -1;
for(int i=0;i < FAVORITES_COUNT;i++) {
if(!(path_has_value(history->favorites_rom[i]) || path_has_value(history->favorites_disk[i]))) {
place = i;
break;
// if the top isn't empty then we need to move things around
if(list[0].bookkeeping_type != HISTORY_TYPE_EMPTY) {
int found_at = -1;
for(int i=1; i < count; i++) {
if(bookkeeping_item_match(&list[i], new_item)){
found_at = i;
break;
}
}
if(found_at == -1) {
bookkeeping_move_items_down(list, 0, count - 1);
} else {
bookkeeping_move_items_down(list, 0, found_at);
}
}
// if no free space then rotate the favorite list (first in first out)
// and set the place to add at the end of the list
if(place == -1) {
history_favorite_rotate(history);
place = FAVORITES_COUNT - 1;
}
history_favorite_insert(history, place, rom, disk);
history_save(history);
bookkeeping_copy_item(new_item, &list[0]);
}
void history_favorite_remove(history_t *history, int location)
{
if(location >= 0 && location < FAVORITES_COUNT) {
if(path_has_value(history->favorites_rom[location])) {
path_free(history->favorites_rom[location]);
history->favorites_rom[location] = path_create("");
}
if(path_has_value(history->favorites_disk[location])) {
path_free(history->favorites_disk[location]);
history->favorites_disk[location] = path_create("");
}
}
void bookkeeping_history_add(bookkeeping_t *bookkeeping, path_t* primary_path, path_t* secondary_path, bookkeeping_item_types_t type ) {
bookkeeping_item_t new_item = {
.primary_path = primary_path,
.secondary_path = secondary_path,
.bookkeeping_type = type
};
bookkeeping_insert_top(bookkeeping->history_items, HISTORY_COUNT, &new_item);
bookkeeping_save(bookkeeping);
}
void bookkeeping_favorite_add(bookkeeping_t *bookkeeping, path_t* primary_path, path_t* secondary_path, bookkeeping_item_types_t type ) {
bookkeeping_item_t new_item = {
.primary_path = primary_path,
.secondary_path = secondary_path,
.bookkeeping_type = type
};
bookkeeping_insert_top(bookkeeping->favorite_items, FAVORITES_COUNT, &new_item);
bookkeeping_save(bookkeeping);
}

View File

@ -9,27 +9,48 @@
#include "path.h"
#define FAVORITES_COUNT 5
#define HISTORY_COUNT 5
typedef enum {
HISTORY_TYPE_EMPTY,
HISTORY_TYPE_ROM,
HISTORY_TYPE_DISK,
} bookkeeping_item_types_t;
/** @brief Settings Structure */
typedef struct {
path_t* last_rom;
path_t* last_disk;
path_t* primary_path;
path_t* secondary_path;
bookkeeping_item_types_t bookkeeping_type;
} bookkeeping_item_t;
/** @brief history Structure */
typedef struct {
bookkeeping_item_t history_items[HISTORY_COUNT];
bookkeeping_item_t favorite_items[HISTORY_COUNT];
} bookkeeping_t;
path_t* favorites_rom[FAVORITES_COUNT];
path_t* favorites_disk[FAVORITES_COUNT];
} history_t;
/** @brief Init history path */
void history_init (char *path);
void bookkeeping_init (char *path);
/** @brief The history to load */
void history_load (history_t *history);
void bookkeeping_load (bookkeeping_t *history);
/** @brief The history to save */
void history_save (history_t *history);
void bookkeeping_save (bookkeeping_t *history);
void history_last_rom_set(history_t *history, path_t* disk_path, path_t* rom_path);
//void history_last_rom_set(bookkeeping_t *history, path_t* disk_path, path_t* rom_path);
void history_favorite_add(history_t *history, path_t* rom, path_t* disk);
void history_favorite_remove(history_t *history, int location);
//void history_favorite_add(bookkeeping_t *history, path_t* rom, path_t* disk);
//void history_favorite_remove(bookkeeping_t *history, int location);
void bookkeeping_history_add(bookkeeping_t *bookkeeping, path_t* primary_path, path_t* secondary_path, bookkeeping_item_types_t type );
void bookkeeping_favorite_add(bookkeeping_t *bookkeeping, path_t* primary_path, path_t* secondary_path, bookkeeping_item_types_t type );
#endif

View File

@ -253,5 +253,18 @@ void ui_components_boxart_free(component_boxart_t *b);
void ui_components_boxart_draw(component_boxart_t *b);
/**
*
*/
void ui_components_main_text_draw_location (float x, float y, char *fmt, ...);
/**
*
*/
void ui_components_tabs_draw(const char** text, int count, int selected );
/**
*
*/
void ui_compontents_tabs_common_draw(int selected);
#endif /* UI_COMPONENTS_H__ */

View File

@ -13,9 +13,10 @@ void ui_components_box_draw (int x0, int y0, int x1, int y1, color_t color) {
rdpq_mode_pop();
}
void ui_components_border_draw (int x0, int y0, int x1, int y1) {
static void ui_components_border_draw_interal (int x0, int y0, int x1, int y1, color_t color) {
rdpq_mode_push();
rdpq_set_mode_fill(BORDER_COLOR);
rdpq_set_mode_fill(color);
rdpq_fill_rectangle(x0 - BORDER_THICKNESS, y0 - BORDER_THICKNESS, x1 + BORDER_THICKNESS, y0);
rdpq_fill_rectangle(x0 - BORDER_THICKNESS, y1, x1 + BORDER_THICKNESS, y1 + BORDER_THICKNESS);
@ -25,6 +26,10 @@ void ui_components_border_draw (int x0, int y0, int x1, int y1) {
rdpq_mode_pop();
}
void ui_components_border_draw (int x0, int y0, int x1, int y1) {
ui_components_border_draw_interal(x0, y0, x1, y1, BORDER_COLOR);
}
void ui_components_layout_draw (void) {
ui_components_border_draw(
VISIBLE_AREA_X0,
@ -215,8 +220,10 @@ void ui_components_main_text_draw_location (float x, float y, char *fmt, ...) {
.line_spacing = TEXT_LINE_SPACING_ADJUST,
},
FNT_DEFAULT,
VISIBLE_AREA_X0 + TEXT_MARGIN_HORIZONTAL + x,
VISIBLE_AREA_Y0 + TEXT_MARGIN_VERTICAL + TEXT_OFFSET_VERTICAL + y,
x,
y,
///VISIBLE_AREA_X0 + TEXT_MARGIN_HORIZONTAL + x,
//VISIBLE_AREA_Y0 + TEXT_MARGIN_VERTICAL + TEXT_OFFSET_VERTICAL + y,
formatted,
nbytes
);
@ -225,3 +232,69 @@ void ui_components_main_text_draw_location (float x, float y, char *fmt, ...) {
free(formatted);
}
}
void ui_components_tabs_draw(const char** text, int count, int selected ) {
ui_components_box_draw(
VISIBLE_AREA_X0,
LAYOUT_ACTIONS_SEPARATOR_Y,
VISIBLE_AREA_X1,
LAYOUT_ACTIONS_SEPARATOR_Y + BORDER_THICKNESS,
BORDER_COLOR
);
int x = VISIBLE_AREA_X0;
int y = OVERSCAN_HEIGHT;
int width = 14 * 8;
int height = TAB_HEIGHT;
// first draw the tabs that are not selected
for(int i=0;i< count;i++) {
if(i != selected) {
ui_components_box_draw(
x,
y,
x + width,
y + height,
TAB_INACTIVE_BACKGROUND_COLOR
);
ui_components_border_draw_interal(
x,
y,
x + width,
y + height,
TAB_INACTIVE_BORDER_COLOR
);
ui_components_main_text_draw_location(x + 8, y, (char*)text[i]);
}
x += width;
}
// draw the selected tab
if(selected >= 0 && selected < count) {
x = VISIBLE_AREA_X0 + (width * selected);
ui_components_box_draw(
x,
y,
x + width,
y + height,
TAB_ACTIVE_BACKGROUND_COLOR
);
ui_components_border_draw_interal(
x,
y,
x + width,
y + height,
TAB_ACTIVE_BORDER_COLOR
);
ui_components_main_text_draw_location(x + 8, y, (char*)text[selected]);
}
}

View File

@ -7,6 +7,10 @@
#ifndef COMPONENTS_CONSTANTS_H__
#define COMPONENTS_CONSTANTS_H__
#define TAB_HEIGHT (20)
/** @brief The thickness of borders. */
#define BORDER_THICKNESS (4)
/** @brief The display width. */
#define DISPLAY_WIDTH (640)
/** @brief The display height. */
@ -25,7 +29,7 @@
/** @brief The start position of the visible display on the X axis. */
#define VISIBLE_AREA_X0 (OVERSCAN_WIDTH)
/** @brief The start position of the visible display on the Y axis. */
#define VISIBLE_AREA_Y0 (OVERSCAN_HEIGHT)
#define VISIBLE_AREA_Y0 (OVERSCAN_HEIGHT + TAB_HEIGHT + BORDER_THICKNESS)
/** @brief The end position of the visible display on the X axis. */
#define VISIBLE_AREA_X1 (DISPLAY_WIDTH - OVERSCAN_WIDTH)
/** @brief The end position of the visible display on the Y axis. */
@ -36,8 +40,7 @@
/** @brief The height of the visible display. */
#define VISIBLE_AREA_HEIGHT (VISIBLE_AREA_Y1 - VISIBLE_AREA_Y0)
/** @brief The thickness of borders. */
#define BORDER_THICKNESS (4)
#define LAYOUT_ACTIONS_SEPARATOR_Y (400)
@ -101,14 +104,14 @@
/** @brief The scroll bar width. */
#define LIST_SCROLLBAR_WIDTH (12)
/** @brief The scroll bar height. */
#define LIST_SCROLLBAR_HEIGHT (LAYOUT_ACTIONS_SEPARATOR_Y - OVERSCAN_HEIGHT)
#define LIST_SCROLLBAR_HEIGHT (LAYOUT_ACTIONS_SEPARATOR_Y - OVERSCAN_HEIGHT - TAB_HEIGHT)
/** @brief The scroll bar position on the X axis. */
#define LIST_SCROLLBAR_X (VISIBLE_AREA_X1 - LIST_SCROLLBAR_WIDTH)
/** @brief The scroll bar position on the Y axis. */
#define LIST_SCROLLBAR_Y (VISIBLE_AREA_Y0)
/** @brief The maximum amount of file list entries. */
#define LIST_ENTRIES (19)
#define LIST_ENTRIES (18)
/** @brief The maximum width available for a file list entry. */
#define FILE_LIST_MAX_WIDTH (480)
#define FILE_LIST_HIGHLIGHT_WIDTH (VISIBLE_AREA_X1 - VISIBLE_AREA_X0 - LIST_SCROLLBAR_WIDTH)
@ -147,4 +150,10 @@
#define CONTEXT_MENU_HIGHLIGHT_COLOR RGBA32(0x3F, 0x3F, 0x3F, 0xFF)
#define TAB_INACTIVE_BORDER_COLOR RGBA32(0x5F, 0x5F, 0x5F, 0xFF)
#define TAB_ACTIVE_BORDER_COLOR RGBA32(0x00, 0x00, 0xFF, 0xFF)
#define TAB_INACTIVE_BACKGROUND_COLOR RGBA32(0x3F, 0x3F, 0x3F, 0xFF)
#define TAB_ACTIVE_BACKGROUND_COLOR RGBA32(0x6F, 0x6F, 0x6F, 0xFF)
#endif

View File

@ -0,0 +1,15 @@
#include "../ui_components.h"
static const char* tabs[3] =
{
"Browser",
"History",
"Favorites"
};
void ui_compontents_tabs_common_draw(int selected)
{
ui_components_tabs_draw(tabs, 3, selected);
}

View File

@ -358,32 +358,24 @@ static void process (menu_t *menu) {
} else if (menu->actions.settings) {
ui_components_context_menu_show(&settings_context_menu);
sound_play_effect(SFX_SETTING);
} else if (menu->actions.favorite) {
} else if (menu->actions.next_tab) {
menu->next_mode = MENU_MODE_HISTORY;
} else if (menu->actions.previous_tab) {
menu->next_mode = MENU_MODE_FAVORITE;
sound_play_effect(SFX_ENTER);
} else if (menu->actions.load_last) {
if(path_has_value(menu->history.last_disk)) {
menu->load.load_last = true;
menu->next_mode = MENU_MODE_LOAD_DISK;
sound_play_effect(SFX_ENTER);
} else if (path_has_value(menu->history.last_rom)) {
menu->load.load_last = true;
menu->next_mode = MENU_MODE_LOAD_ROM;
sound_play_effect(SFX_ENTER);
}
}
}
static void draw (menu_t *menu, surface_t *d) {
rdpq_attach(d, NULL);
ui_components_background_draw();
ui_components_layout_draw();
ui_components_layout_draw();
ui_components_file_list_draw(menu->browser.list, menu->browser.entries, menu->browser.selected);
ui_compontents_tabs_common_draw(0);
const char *action = NULL;
if (menu->browser.entry) {
@ -417,14 +409,14 @@ static void draw (menu_t *menu, surface_t *d) {
ui_components_actions_bar_text_draw(
ALIGN_CENTER, VALIGN_TOP,
"%s" //ctime includes a newline
"<C Load Last | C> Favorite",
"<C Change Tabs C>",
ctime(&menu->current_time)
);
} else {
ui_components_actions_bar_text_draw(
ALIGN_CENTER, VALIGN_TOP,
"\n"
"<C Load Last | C> Favorite"
"<C Tabs C>"
);
}

View File

@ -5,99 +5,139 @@
#include "../ui_components/constants.h"
#include "../sound.h"
static int selected_favorite = -1;
static void favorite_reset_selected(menu_t* menu) {
selected_favorite = -1;
typedef enum {
BOOKKEEPING_SCREEN_MODE_HISTORY,
BOOKKEEPING_SCREEN_MODE_FAVORITE
} bookkeeping_screen_modes_t;
for(int i=0;i<FAVORITES_COUNT;i++) {
if(path_has_value(menu->history.favorites_rom[i]) || path_has_value(menu->history.favorites_disk[i])) {
selected_favorite = i;
static bookkeeping_screen_modes_t screen_mode = -1;
static int selected_item = -1;
static bookkeeping_item_t* item_list;
static int item_max;
static void reset_selected(menu_t* menu) {
selected_item = -1;
for(int i=0;i<item_max;i++) {
if(item_list[selected_item].bookkeeping_type != HISTORY_TYPE_EMPTY) {
selected_item = i;
break;
}
}
}
static void move_next() {
int last = selected_item;
do
{
selected_item++;
if(selected_item >= item_max) {
selected_item = last;
break;
} else if(item_list[selected_item].bookkeeping_type != HISTORY_TYPE_EMPTY) {
sound_play_effect(SFX_CURSOR);
break;
}
} while (true);
}
static void move_back() {
int last = selected_item;
do
{
selected_item--;
if(selected_item < 0) {
selected_item = last;
break;
} else if(item_list[selected_item].bookkeeping_type != HISTORY_TYPE_EMPTY) {
sound_play_effect(SFX_CURSOR);
break;
}
} while (true);
}
static void process(menu_t* menu) {
if (menu->actions.back) {
menu->next_mode = MENU_MODE_BROWSER;
} else if(menu->actions.go_down) {
int last_favorite = selected_favorite;
do
{
selected_favorite++;
if(selected_favorite >= FAVORITES_COUNT) {
selected_favorite = last_favorite;
break;
} else if(path_has_value(menu->history.favorites_rom[selected_favorite]) || path_has_value(menu->history.favorites_disk[selected_favorite])) {
sound_play_effect(SFX_CURSOR);
break;
}
} while (true);
if(menu->actions.go_down) {
move_next();
} else if(menu->actions.go_up) {
int last_favorite = selected_favorite;
move_back();
} else if(menu->actions.enter && selected_item != -1) {
if(screen_mode == BOOKKEEPING_SCREEN_MODE_FAVORITE) {
menu->load.load_favorite = selected_item;
} else if(screen_mode == BOOKKEEPING_SCREEN_MODE_HISTORY) {
menu->load.load_history = selected_item;
}
do
{
selected_favorite--;
if(selected_favorite < 0) {
selected_favorite = last_favorite;
break;
} else if(path_has_value(menu->history.favorites_rom[selected_favorite]) || path_has_value(menu->history.favorites_disk[selected_favorite])) {
sound_play_effect(SFX_CURSOR);
break;
}
} while (true);
} else if(menu->actions.enter && selected_favorite != -1) {
menu->load.load_favorite = selected_favorite;
if(path_has_value(menu->history.favorites_disk[selected_favorite])) {
if(item_list[selected_item].bookkeeping_type == HISTORY_TYPE_DISK) {
menu->next_mode = MENU_MODE_LOAD_DISK;
sound_play_effect(SFX_ENTER);
} else if(path_has_value(menu->history.favorites_rom[selected_favorite])) {
} else if(item_list[selected_item].bookkeeping_type == HISTORY_TYPE_ROM) {
menu->next_mode = MENU_MODE_LOAD_ROM;
sound_play_effect(SFX_ENTER);
}
} else if(menu->actions.options && selected_favorite != -1) {
history_favorite_remove(&menu->history, selected_favorite);
favorite_reset_selected(menu);
} else if (menu->actions.previous_tab) {
if(screen_mode == BOOKKEEPING_SCREEN_MODE_FAVORITE) {
menu->next_mode = MENU_MODE_HISTORY;
} else if(screen_mode == BOOKKEEPING_SCREEN_MODE_HISTORY) {
menu->next_mode = MENU_MODE_BROWSER;
}
} else if (menu->actions.next_tab) {
if(screen_mode == BOOKKEEPING_SCREEN_MODE_FAVORITE) {
menu->next_mode = MENU_MODE_BROWSER;
} else if(screen_mode == BOOKKEEPING_SCREEN_MODE_HISTORY) {
menu->next_mode = MENU_MODE_FAVORITE;
}
}else if(screen_mode == BOOKKEEPING_SCREEN_MODE_FAVORITE && menu->actions.options && selected_item != -1) {
//history_favorite_remove(&menu->history, selected_item);
reset_selected(menu);
sound_play_effect(SFX_SETTING);
}
}
static void draw_favorites(menu_t *menu, surface_t *display) {
float y = 24;
float x = 10;
float y = VISIBLE_AREA_Y0;
float x = 10 + VISIBLE_AREA_X0;
if(selected_favorite != -1) {
float highlight_y = 32 + y + (selected_favorite * 16 * 2);
if(selected_item != -1) {
float highlight_y = y + (selected_item * 18 * 2);
ui_components_box_draw(
VISIBLE_AREA_X0,
highlight_y,
VISIBLE_AREA_X0 + FILE_LIST_HIGHLIGHT_WIDTH,
highlight_y + 32,
highlight_y + 36,
FILE_LIST_HIGHLIGHT_COLOR
);
}
for(int i=0;i < FAVORITES_COUNT; i++)
{
ui_components_main_text_draw_location(x, y, "%d :", (i+1));
if(path_has_value(menu->history.favorites_rom[i])) {
ui_components_main_text_draw_location(x + 64, y, "%s", path_last_get(menu->history.favorites_rom[i]));
for(int i=0;i < FAVORITES_COUNT; i++) {
if(path_has_value(item_list[i].primary_path)) {
ui_components_main_text_draw_location(x, y, "%d : %s",(i+1), path_last_get(item_list[i].primary_path));
} else {
ui_components_main_text_draw_location(x, y, "%d :", (i+1));
}
y += 16;
if(path_has_value(menu->history.favorites_disk[i])) {
ui_components_main_text_draw_location(x + 64, y,"%s", path_last_get(menu->history.favorites_disk[i]));
if(path_has_value(item_list[i].secondary_path)) {
ui_components_main_text_draw_location(x, y," %s", path_last_get(item_list[i].secondary_path));
}
y += 20;
}
if(screen_mode == BOOKKEEPING_SCREEN_MODE_FAVORITE) {
ui_compontents_tabs_common_draw(2);
} else if(screen_mode == BOOKKEEPING_SCREEN_MODE_HISTORY) {
ui_compontents_tabs_common_draw(1);
}
}
static void draw(menu_t *menu, surface_t *display) {
@ -107,32 +147,22 @@ static void draw(menu_t *menu, surface_t *display) {
ui_components_layout_draw();
ui_components_main_text_draw(
ALIGN_CENTER, VALIGN_TOP,
"Favorites");
draw_favorites(menu, display);
if(selected_favorite != -1) {
if(selected_item != -1) {
ui_components_actions_bar_text_draw(
ALIGN_LEFT, VALIGN_TOP,
"A: Load Favorite\n"
"B: Exit"
);
ui_components_actions_bar_text_draw(
ALIGN_RIGHT, VALIGN_TOP,
"R: Remove Favorite"
);
} else {
ui_components_actions_bar_text_draw(
ALIGN_LEFT, VALIGN_TOP,
"\n"
"B: Exit"
"A: Load Game"
);
if(screen_mode == BOOKKEEPING_SCREEN_MODE_FAVORITE) {
ui_components_actions_bar_text_draw(
ALIGN_RIGHT, VALIGN_TOP,
"R: Remove Favorite"
);
}
}
rdpq_detach_show();
}
@ -140,10 +170,29 @@ static void draw(menu_t *menu, surface_t *display) {
void view_favorite_init (menu_t *menu) {
favorite_reset_selected(menu);
screen_mode = BOOKKEEPING_SCREEN_MODE_FAVORITE;
item_list = menu->history.favorite_items;
item_max = FAVORITES_COUNT;
reset_selected(menu);
}
void view_favorite_display (menu_t *menu, surface_t *display) {
process(menu);
draw(menu, display);
}
void view_history_init (menu_t *menu) {
screen_mode = BOOKKEEPING_SCREEN_MODE_HISTORY;
item_list = menu->history.history_items;
item_max = HISTORY_COUNT;
reset_selected(menu);
}
void view_history_display (menu_t *menu, surface_t *display) {
process(menu);
draw(menu, display);
}

View File

@ -40,9 +40,6 @@ static void process (menu_t *menu) {
} else if (menu->actions.back) {
sound_play_effect(SFX_EXIT);
menu->next_mode = MENU_MODE_BROWSER;
} else if (menu->actions.favorite) {
history_favorite_add(&menu->history, menu->load.rom_path, menu->load.disk_path);
sound_play_effect(SFX_SETTING);
}
}
@ -142,7 +139,7 @@ static void load (menu_t *menu) {
return;
}
history_last_rom_set(&menu->history, menu->load.disk_path, menu->load.rom_path);
bookkeeping_history_add(&menu->history, menu->load.disk_path, menu->load.rom_path, HISTORY_TYPE_DISK);
menu->next_mode = MENU_MODE_BOOT;
if (load_disk_with_rom) {
@ -196,24 +193,29 @@ void view_load_disk_init (menu_t *menu) {
menu->boot_pending.disk_file = false;
if(menu->load.load_last) {
menu->load.disk_path = path_clone(menu->history.last_disk);
if(menu->load.load_history != -1 || menu->load.load_favorite != -1) {
int id = -1;
bookkeeping_item_t* items;
if(!load_rom(menu, menu->history.last_rom)) {
if(menu->load.load_history != -1) {
id = menu->load.load_history;
items = menu->history.history_items;
} else if (menu->load.load_favorite != -1) {
id = menu->load.load_favorite;
items = menu->history.favorite_items;
}
menu->load.disk_path = path_clone(items[id].primary_path);
if(!load_rom(menu, items[id].secondary_path)) {
return;
}
} else if(menu->load.load_favorite != -1) {
menu->load.disk_path = path_clone(menu->history.favorites_disk[menu->load.load_favorite]);
if(!load_rom(menu, menu->history.favorites_rom[menu->load.load_favorite])) {
return;
}
} else {
menu->load.disk_path = path_clone_push(menu->browser.directory, menu->browser.entry->name);
}
menu->load.load_favorite = -1;
menu->load.load_last = false;
menu->load.load_history = -1;
name = path_last_get(menu->load.disk_path);
disk_err_t err = disk_info_load(menu->load.disk_path, &menu->load.disk_info);

View File

@ -159,7 +159,7 @@ static void set_autoload_type (menu_t *menu, void *arg) {
}
static void add_favorite (menu_t *menu, void *arg) {
history_favorite_add(&menu->history, menu->load.rom_path, NULL);
bookkeeping_favorite_add(&menu->history, menu->load.rom_path, NULL, HISTORY_TYPE_ROM);
}
static component_context_menu_t set_cic_type_context_menu = { .list = {
@ -341,7 +341,7 @@ static void load (menu_t *menu) {
return;
}
history_last_rom_set(&menu->history, NULL, menu->load.rom_path);
bookkeeping_history_add(&menu->history, menu->load.rom_path, NULL, HISTORY_TYPE_ROM);
menu->next_mode = MENU_MODE_BOOT;
@ -368,10 +368,10 @@ void view_load_rom_init (menu_t *menu) {
path_free(menu->load.rom_path);
}
if(menu->load.load_last) {
menu->load.rom_path = path_clone(menu->history.last_rom);
if(menu->load.load_history != -1) {
menu->load.rom_path = path_clone(menu->history.history_items[menu->load.load_history].primary_path);
} else if(menu->load.load_favorite != -1) {
menu->load.rom_path = path_clone(menu->history.favorites_rom[menu->load.load_favorite]);
menu->load.rom_path = path_clone(menu->history.favorite_items[menu->load.load_history].primary_path);
} else {
menu->load.rom_path = path_clone_push(menu->browser.directory, menu->browser.entry->name);
}
@ -380,7 +380,7 @@ void view_load_rom_init (menu_t *menu) {
}
menu->load.load_favorite = -1;
menu->load.load_last = false;
menu->load.load_history = -1;
rom_err_t err = rom_info_load(menu->load.rom_path, &menu->load.rom_info);
if (err != ROM_OK) {

View File

@ -68,7 +68,10 @@ void view_fault_display (menu_t *menu, surface_t *display);
void view_favorite_init (menu_t *menu);
void view_favorite_display (menu_t *menu, surface_t *display);
void view_history_init (menu_t *menu);
void menu_show_error (menu_t *menu, char *error_message);
void view_history_display (menu_t *menu, surface_t *display);
/** @} */ /* view */