Added image viewer menu view

This commit is contained in:
Mateusz Faderewski 2023-07-25 22:56:00 +02:00
parent 8c71794d6d
commit bc280c7fc6
9 changed files with 130 additions and 8 deletions

View File

@ -41,6 +41,7 @@ SRCS = \
menu/views/file_info.c \ menu/views/file_info.c \
menu/views/fragments/fragments.c \ menu/views/fragments/fragments.c \
menu/views/fragments/widgets.c \ menu/views/fragments/widgets.c \
menu/views/image_viewer.c \
menu/views/load.c \ menu/views/load.c \
menu/views/music_player.c \ menu/views/music_player.c \
menu/views/startup.c \ menu/views/startup.c \

View File

@ -112,6 +112,10 @@ void menu_run (boot_params_t *boot_params) {
view_system_info_display(menu, display); view_system_info_display(menu, display);
break; break;
case MENU_MODE_IMAGE_VIEWER:
view_image_viewer_display(menu, display);
break;
case MENU_MODE_MUSIC_PLAYER: case MENU_MODE_MUSIC_PLAYER:
view_music_player_display(menu, display); view_music_player_display(menu, display);
break; break;
@ -158,6 +162,10 @@ void menu_run (boot_params_t *boot_params) {
view_system_info_init(menu); view_system_info_init(menu);
break; break;
case MENU_MODE_IMAGE_VIEWER:
view_image_viewer_init(menu);
break;
case MENU_MODE_MUSIC_PLAYER: case MENU_MODE_MUSIC_PLAYER:
view_music_player_init(menu); view_music_player_init(menu);
break; break;

View File

@ -24,6 +24,7 @@ typedef enum {
MENU_MODE_BROWSER, MENU_MODE_BROWSER,
MENU_MODE_FILE_INFO, MENU_MODE_FILE_INFO,
MENU_MODE_SYSTEM_INFO, MENU_MODE_SYSTEM_INFO,
MENU_MODE_IMAGE_VIEWER,
MENU_MODE_MUSIC_PLAYER, MENU_MODE_MUSIC_PLAYER,
MENU_MODE_CREDITS, MENU_MODE_CREDITS,
MENU_MODE_LOAD, MENU_MODE_LOAD,
@ -37,6 +38,7 @@ typedef enum {
ENTRY_TYPE_DIR, ENTRY_TYPE_DIR,
ENTRY_TYPE_ROM, ENTRY_TYPE_ROM,
ENTRY_TYPE_SAVE, ENTRY_TYPE_SAVE,
ENTRY_TYPE_IMAGE,
ENTRY_TYPE_MUSIC, ENTRY_TYPE_MUSIC,
ENTRY_TYPE_OTHER, ENTRY_TYPE_OTHER,
} entry_type_t; } entry_type_t;

View File

@ -11,6 +11,7 @@
static const char *rom_extensions[] = { "z64", "n64", "v64", NULL }; static const char *rom_extensions[] = { "z64", "n64", "v64", NULL };
static const char *save_extensions[] = { "sav", NULL }; static const char *save_extensions[] = { "sav", NULL };
static const char *image_extensions[] = { "png", NULL };
static const char *music_extensions[] = { "mp3", NULL }; static const char *music_extensions[] = { "mp3", NULL };
@ -31,6 +32,10 @@ static int compare_entry (const void *pa, const void *pb) {
return -1; return -1;
} else if (b->type == ENTRY_TYPE_SAVE) { } else if (b->type == ENTRY_TYPE_SAVE) {
return 1; return 1;
} else if (a->type == ENTRY_TYPE_IMAGE) {
return -1;
} else if (b->type == ENTRY_TYPE_IMAGE) {
return 1;
} else if (a->type == ENTRY_TYPE_MUSIC) { } else if (a->type == ENTRY_TYPE_MUSIC) {
return -1; return -1;
} else if (b->type == ENTRY_TYPE_MUSIC) { } else if (b->type == ENTRY_TYPE_MUSIC) {
@ -87,6 +92,8 @@ static bool load_directory (menu_t *menu) {
entry->type = ENTRY_TYPE_ROM; entry->type = ENTRY_TYPE_ROM;
} else if (file_has_extensions(info.fname, save_extensions)) { } else if (file_has_extensions(info.fname, save_extensions)) {
entry->type = ENTRY_TYPE_SAVE; entry->type = ENTRY_TYPE_SAVE;
} else if (file_has_extensions(info.fname, image_extensions)) {
entry->type = ENTRY_TYPE_IMAGE;
} else if (file_has_extensions(info.fname, music_extensions)) { } else if (file_has_extensions(info.fname, music_extensions)) {
entry->type = ENTRY_TYPE_MUSIC; entry->type = ENTRY_TYPE_MUSIC;
} else { } else {
@ -208,6 +215,9 @@ static void process (menu_t *menu) {
case ENTRY_TYPE_ROM: case ENTRY_TYPE_ROM:
menu->next_mode = MENU_MODE_LOAD; menu->next_mode = MENU_MODE_LOAD;
break; break;
case ENTRY_TYPE_IMAGE:
menu->next_mode = MENU_MODE_IMAGE_VIEWER;
break;
case ENTRY_TYPE_MUSIC: case ENTRY_TYPE_MUSIC:
menu->next_mode = MENU_MODE_MUSIC_PLAYER; menu->next_mode = MENU_MODE_MUSIC_PLAYER;
break; break;
@ -324,6 +334,9 @@ static void draw (menu_t *menu, surface_t *d) {
case ENTRY_TYPE_ROM: case ENTRY_TYPE_ROM:
fragment_textf(text_x, text_y, "A: Load"); fragment_textf(text_x, text_y, "A: Load");
break; break;
case ENTRY_TYPE_IMAGE:
fragment_textf(text_x, text_y, "A: Show");
break;
case ENTRY_TYPE_MUSIC: case ENTRY_TYPE_MUSIC:
fragment_textf(text_x, text_y, "A: Play"); fragment_textf(text_x, text_y, "A: Play");
break; break;

View File

@ -94,3 +94,15 @@ int fragment_textf (int x, int y, char *fmt, ...) {
return layout.line_height; return layout.line_height;
} }
void fragment_loader (surface_t *d) {
const color_t text_color = RGBA32(0xFF, 0xFF, 0xFF, 0xFF);
const int offset_x = 248;
const int offset_y = 212;
const int text_offset_x = -39;
widget_border(offset_x, offset_y, d->width - offset_x, d->height - offset_y, layout.border_thickness);
fragment_text_start(text_color);
fragment_textf((d->width / 2) + text_offset_x, (d->height / 2) - (layout.line_height / 2), "Loading…");
}

View File

@ -51,6 +51,7 @@ void fragment_progressbar (surface_t *d, float progress);
void fragment_text_start (color_t color); void fragment_text_start (color_t color);
void fragment_text_set_color (color_t color); void fragment_text_set_color (color_t color);
int fragment_textf (int x, int y, char *fmt, ...); int fragment_textf (int x, int y, char *fmt, ...);
void fragment_loader (surface_t *d);
/** @} */ /* view_fragments */ /** @} */ /* view_fragments */

View File

@ -0,0 +1,89 @@
#include <libdragon.h>
#include <stdlib.h>
#include "../png_decoder.h"
#include "fragments/fragments.h"
#include "views.h"
static surface_t *image;
static rspq_block_t *cached_image_dl;
static void process (menu_t *menu) {
if (menu->actions.back) {
menu->next_mode = MENU_MODE_BROWSER;
}
}
static void draw (menu_t *menu, surface_t *d) {
rdpq_attach_clear(d, NULL);
if (image == NULL) {
fragment_loader(d);
} else {
rspq_block_run(cached_image_dl);
}
rdpq_detach_show();
}
static void deffered_image_load (menu_t *menu, surface_t *d) {
image = calloc(1, sizeof(surface_t));
if (image == NULL) {
menu->next_mode = MENU_MODE_ERROR;
return;
}
path_t *path = path_clone(menu->browser.directory);
path_push(path, menu->browser.list[menu->browser.selected].name);
if (png_decode(path_get(path), image, 640, 480) == PNG_OK) {
uint16_t x = (d->width / 2) - (image->width / 2);
uint16_t y = (d->height / 2) - (image->height / 2);
rspq_block_begin();
rdpq_set_mode_copy(false);
rdpq_tex_blit(image, x, y, NULL);
cached_image_dl = rspq_block_end();
} else {
menu->next_mode = MENU_MODE_ERROR;
}
path_free(path);
}
static void dl_free (void *arg) {
rspq_block_free((rspq_block_t *) (arg));
}
static void deinit (menu_t *menu) {
if (image != NULL) {
rdpq_call_deferred(dl_free, cached_image_dl);
surface_free(image);
free(image);
}
}
void view_image_viewer_init (menu_t *menu) {
image = NULL;
cached_image_dl = NULL;
}
void view_image_viewer_display (menu_t *menu, surface_t *display) {
process(menu);
draw(menu, display);
if (image == NULL) {
deffered_image_load(menu, display);
}
if (menu->next_mode != MENU_MODE_IMAGE_VIEWER) {
deinit(menu);
}
}

View File

@ -207,14 +207,7 @@ static void draw (menu_t *menu, surface_t *d) {
rdpq_clear(bg_color); rdpq_clear(bg_color);
if (load_pending) { if (load_pending) {
const int offset_x = 248; fragment_loader(d);
const int offset_y = 212;
const int text_offset_x = -39;
// Loading screen
widget_border(offset_x, offset_y, d->width - offset_x, d->height - offset_y, layout->border_thickness);
fragment_text_start(text_color);
fragment_textf((d->width / 2) + text_offset_x, (d->height / 2) - (layout->line_height / 2), "Loading…");
} else { } else {
// Layout // Layout
fragment_borders(d); fragment_borders(d);

View File

@ -29,6 +29,9 @@ void view_system_info_display (menu_t *menu, surface_t *display);
void view_file_info_init (menu_t *menu); void view_file_info_init (menu_t *menu);
void view_file_info_display (menu_t *menu, surface_t *display); void view_file_info_display (menu_t *menu, surface_t *display);
void view_image_viewer_init (menu_t *menu);
void view_image_viewer_display (menu_t *menu, surface_t *display);
void view_music_player_init (menu_t *menu); void view_music_player_init (menu_t *menu);
void view_music_player_display (menu_t *menu, surface_t *display); void view_music_player_display (menu_t *menu, surface_t *display);