mirror of
https://github.com/ekeeke/Genesis-Plus-GX.git
synced 2024-12-26 11:11:48 +01:00
863 lines
23 KiB
C
863 lines
23 KiB
C
/*
|
|
* filesel.c
|
|
*
|
|
* File Browser
|
|
*
|
|
* Copyright Eke-Eke (2009-2014)
|
|
*
|
|
* Redistribution and use of this code or any derivative works are permitted
|
|
* provided that the following conditions are met:
|
|
*
|
|
* - Redistributions may not be sold, nor may they be used in a commercial
|
|
* product or activity.
|
|
*
|
|
* - Redistributions that are modified from the original source must include the
|
|
* complete source code, including the source code for all components used by a
|
|
* binary built from the modified sources. However, as a special exception, the
|
|
* source code distributed need not include anything that is normally distributed
|
|
* (in either source or binary form) with the major components (compiler, kernel,
|
|
* and so on) of the operating system on which the executable runs, unless that
|
|
* component itself accompanies the executable.
|
|
*
|
|
* - Redistributions must reproduce the above copyright notice, this list of
|
|
* conditions and the following disclaimer in the documentation and/or other
|
|
* materials provided with the distribution.
|
|
*
|
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
|
|
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
|
|
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
|
|
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
|
|
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
|
|
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
|
|
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
|
|
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
|
|
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
|
|
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
|
|
* POSSIBILITY OF SUCH DAMAGE.
|
|
*
|
|
****************************************************************************************/
|
|
|
|
#include "shared.h"
|
|
#include "filesel.h"
|
|
#include "font.h"
|
|
#include "gui.h"
|
|
#include "file_load.h"
|
|
#include "history.h"
|
|
|
|
#define BG_COLOR_1 {0x49,0x49,0x49,0xff}
|
|
#define BG_COLOR_2 {0x66,0x66,0x66,0xff}
|
|
|
|
#define SCROLL_SPEED 10
|
|
|
|
#include "Browser_dir_png.h"
|
|
#include "Snap_empty_png.h"
|
|
#include "Cart_md_png.h"
|
|
#include "Cart_ms_png.h"
|
|
#include "Cart_gg_png.h"
|
|
#include "Cart_sg_png.h"
|
|
|
|
FILEENTRIES filelist[MAXFILES];
|
|
|
|
static int offset = 0;
|
|
static int selection = 0;
|
|
static int maxfiles = 0;
|
|
static int string_offset = 0;
|
|
static char prev_folder[MAXJOLIET];
|
|
static void selector_cb(void);
|
|
|
|
/*****************************************************************************/
|
|
/* GUI Buttons data */
|
|
/*****************************************************************************/
|
|
static butn_data arrow_up_data =
|
|
{
|
|
{NULL,NULL},
|
|
{Button_up_png,Button_up_over_png}
|
|
};
|
|
|
|
static butn_data arrow_down_data =
|
|
{
|
|
{NULL,NULL},
|
|
{Button_down_png,Button_down_over_png}
|
|
};
|
|
|
|
/*****************************************************************************/
|
|
/* GUI Arrows button */
|
|
/*****************************************************************************/
|
|
|
|
static gui_butn arrow_up = {&arrow_up_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX,{0,0,0,0},14,76,360,32};
|
|
static gui_butn arrow_down = {&arrow_down_data,BUTTON_VISIBLE|BUTTON_ACTIVE|BUTTON_OVER_SFX,{0,0,0,0},14,368,360,32};
|
|
|
|
/*****************************************************************************/
|
|
/* GUI helpers */
|
|
/*****************************************************************************/
|
|
static gui_item action_cancel =
|
|
{
|
|
NULL,Key_B_png,"","Previous Directory",10,422,28,28
|
|
};
|
|
|
|
static gui_item action_select =
|
|
{
|
|
NULL,Key_A_png,"","Load file",602,422,28,28
|
|
};
|
|
|
|
/*****************************************************************************/
|
|
/* GUI Background images */
|
|
/*****************************************************************************/
|
|
static gui_image bg_filesel[14] =
|
|
{
|
|
{NULL,Bg_layer_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
|
|
{NULL,Bg_overlay_png,IMAGE_VISIBLE|IMAGE_REPEAT,0,0,640,480,255},
|
|
{NULL,Banner_top_png,IMAGE_VISIBLE,0,0,640,108,255},
|
|
{NULL,Banner_bottom_png,IMAGE_VISIBLE,0,380,640,100,255},
|
|
{NULL,Main_logo_png,IMAGE_VISIBLE,466,40,152,44,255},
|
|
{NULL,Frame_s1_png,IMAGE_VISIBLE,8,70,372,336,152},
|
|
{NULL,Frame_s2_png,0,384,264,248,140,152},
|
|
{NULL,Snap_empty_png,IMAGE_VISIBLE,424,148,160,112,255},
|
|
{NULL,NULL,0,424,148,160,112,255},
|
|
{NULL,NULL,0,388,147,240,152,255},
|
|
{NULL,NULL,0,388,147,240,152,255},
|
|
{NULL,NULL,0,392,118,232,148,255},
|
|
{NULL,NULL,0,414,116,184,188,255},
|
|
{NULL,NULL,0,416,144,180,228,255}
|
|
};
|
|
|
|
static const u8 *Cart_png[FILETYPE_MAX] =
|
|
{
|
|
Cart_md_png,
|
|
Cart_md_png,
|
|
Cart_ms_png,
|
|
Cart_gg_png,
|
|
Cart_sg_png
|
|
};
|
|
|
|
static const char *Cart_dir[FILETYPE_MAX] =
|
|
{
|
|
"md",
|
|
"cd",
|
|
"ms",
|
|
"gg",
|
|
"sg"
|
|
};
|
|
|
|
static gui_image dir_icon;
|
|
static gui_image bar_over;
|
|
|
|
/*****************************************************************************/
|
|
/* GUI Descriptor */
|
|
/*****************************************************************************/
|
|
static gui_menu menu_selector =
|
|
{
|
|
"Game Selection",
|
|
-1,-1,
|
|
0,0,14,0,
|
|
NULL,
|
|
NULL,
|
|
bg_filesel,
|
|
{&action_cancel, &action_select},
|
|
{&arrow_up,&arrow_down},
|
|
selector_cb
|
|
};
|
|
|
|
|
|
static void selector_cb(void)
|
|
{
|
|
int i;
|
|
char text[MAXPATHLEN];
|
|
int yoffset = 108;
|
|
|
|
/* Draw browser array */
|
|
gxDrawRectangle(15, 108, 358, 26, 127, (GXColor)BG_COLOR_1);
|
|
gxDrawRectangle(15, 134, 358, 26, 127, (GXColor)BG_COLOR_2);
|
|
gxDrawRectangle(15, 160, 358, 26, 127, (GXColor)BG_COLOR_1);
|
|
gxDrawRectangle(15, 186, 358, 26, 127, (GXColor)BG_COLOR_2);
|
|
gxDrawRectangle(15, 212, 358, 26, 127, (GXColor)BG_COLOR_1);
|
|
gxDrawRectangle(15, 238, 358, 26, 127, (GXColor)BG_COLOR_2);
|
|
gxDrawRectangle(15, 264, 358, 26, 127, (GXColor)BG_COLOR_1);
|
|
gxDrawRectangle(15, 290, 358, 26, 127, (GXColor)BG_COLOR_2);
|
|
gxDrawRectangle(15, 316, 358, 26, 127, (GXColor)BG_COLOR_1);
|
|
gxDrawRectangle(15, 342, 358, 26, 127, (GXColor)BG_COLOR_2);
|
|
|
|
/* Draw Files list */
|
|
for (i = offset; (i < (offset + 10)) && (i < maxfiles); i++)
|
|
{
|
|
if (i == selection)
|
|
{
|
|
/* selection bar */
|
|
gxDrawTexture(bar_over.texture,bar_over.x,yoffset+bar_over.y,bar_over.w,bar_over.h,255);
|
|
|
|
/* scrolling text */
|
|
if ((string_offset/SCROLL_SPEED) >= strlen(filelist[i].filename))
|
|
{
|
|
string_offset = 0;
|
|
}
|
|
|
|
if (string_offset)
|
|
{
|
|
sprintf(text,"%s ",filelist[i].filename+string_offset/SCROLL_SPEED);
|
|
strncat(text, filelist[i].filename, string_offset/SCROLL_SPEED);
|
|
}
|
|
else
|
|
{
|
|
strcpy(text, filelist[i].filename);
|
|
}
|
|
|
|
/* print text */
|
|
if (filelist[i].flags)
|
|
{
|
|
/* directory icon */
|
|
gxDrawTexture(dir_icon.texture,dir_icon.x,yoffset+dir_icon.y,dir_icon.w,dir_icon.h,255);
|
|
if (FONT_write(text,18,dir_icon.x+dir_icon.w+6,yoffset+22,bar_over.w-dir_icon.w-26,(GXColor)WHITE))
|
|
{
|
|
/* text scrolling */
|
|
string_offset ++;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (FONT_write(text,18,26,yoffset+22,bar_over.w-20,(GXColor)WHITE))
|
|
{
|
|
/* text scrolling */
|
|
string_offset ++;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
if (filelist[i].flags)
|
|
{
|
|
/* directory icon */
|
|
gxDrawTexture(dir_icon.texture,dir_icon.x,yoffset+dir_icon.y,dir_icon.w,dir_icon.h,255);
|
|
FONT_write(filelist[i].filename,18,dir_icon.x+dir_icon.w+6,yoffset+22,bar_over.w-dir_icon.w-26,(GXColor)WHITE);
|
|
}
|
|
else
|
|
{
|
|
FONT_write(filelist[i].filename,18,26,yoffset+22,bar_over.w-20,(GXColor)WHITE);
|
|
}
|
|
}
|
|
|
|
yoffset += 26;
|
|
}
|
|
}
|
|
|
|
|
|
/****************************************************************************
|
|
* FileSelector
|
|
*
|
|
* Browse directories and select a file from the file listing
|
|
* return ROM size
|
|
*
|
|
****************************************************************************/
|
|
int FileSelector(int type)
|
|
{
|
|
short p;
|
|
int i;
|
|
int old = -1;
|
|
char fname[MAXPATHLEN];
|
|
FILE *snap;
|
|
gui_menu *m = &menu_selector;
|
|
|
|
int offset_ = -1;
|
|
int selection_ = -1;
|
|
int maxfiles_ = -1;
|
|
|
|
#ifdef HW_RVL
|
|
int x,y;
|
|
gui_butn *button;
|
|
#endif
|
|
|
|
/* Background overlay */
|
|
if (config.bg_overlay)
|
|
{
|
|
bg_filesel[1].state |= IMAGE_VISIBLE;
|
|
}
|
|
else
|
|
{
|
|
bg_filesel[1].state &= ~IMAGE_VISIBLE;
|
|
}
|
|
|
|
/* Hide all cartridge labels */
|
|
for (i=0; i<FILETYPE_MAX; i++)
|
|
{
|
|
bg_filesel[9+i].data = NULL;
|
|
bg_filesel[9+i].state &= ~IMAGE_VISIBLE;
|
|
}
|
|
|
|
/* System ROM selection */
|
|
if (type >= FILETYPE_MAX)
|
|
{
|
|
/* Save current ROM browser */
|
|
offset_ = offset;
|
|
maxfiles_ = maxfiles;
|
|
selection_ = selection;
|
|
|
|
/* Initialize ROM browser */
|
|
maxfiles = ParseDirectory();
|
|
selection = offset = 0;
|
|
while (selection < maxfiles)
|
|
{
|
|
if (strstr(config.sys_rom[type-FILETYPE_MAX], filelist[selection].filename))
|
|
{
|
|
offset = selection;
|
|
while ((offset > (maxfiles - 10)) && (offset > 0))
|
|
{
|
|
offset--;
|
|
}
|
|
break;
|
|
}
|
|
selection++;
|
|
}
|
|
|
|
/* By default, select first file in directory if ROM is not found */
|
|
if (selection >= maxfiles)
|
|
{
|
|
selection = 0;
|
|
}
|
|
|
|
/* Set menu title and cartridge label type */
|
|
switch (type - FILETYPE_MAX)
|
|
{
|
|
case 0:
|
|
{
|
|
strcpy(m->title,"Sega CD (USA) BIOS Selection");
|
|
type = FILETYPE_MD;
|
|
break;
|
|
}
|
|
|
|
case 1:
|
|
{
|
|
strcpy(m->title,"Mega CD (PAL) BIOS Selection");
|
|
type = FILETYPE_MD;
|
|
break;
|
|
}
|
|
|
|
case 2:
|
|
{
|
|
strcpy(m->title,"Mega CD (JAP) BIOS Selection");
|
|
type = FILETYPE_MD;
|
|
break;
|
|
}
|
|
|
|
case 3:
|
|
{
|
|
strcpy(m->title,"Mega Drive/Genesis BootROM Selection");
|
|
type = FILETYPE_MD;
|
|
break;
|
|
}
|
|
|
|
case 4:
|
|
{
|
|
strcpy(m->title,"Master System (USA) BootROM Selection");
|
|
type = FILETYPE_MS;
|
|
break;
|
|
}
|
|
|
|
case 5:
|
|
{
|
|
strcpy(m->title,"Master System (PAL) BootROM Selection");
|
|
type = FILETYPE_MS;
|
|
break;
|
|
}
|
|
|
|
case 6:
|
|
{
|
|
strcpy(m->title,"Master System (JAP) BootROM Selection");
|
|
type = FILETYPE_MS;
|
|
break;
|
|
}
|
|
|
|
case 7:
|
|
{
|
|
strcpy(m->title,"Game Gear BootROM Selection");
|
|
type = FILETYPE_GG;
|
|
break;
|
|
}
|
|
|
|
case 8:
|
|
{
|
|
strcpy(m->title,"Game Genie ROM Selection");
|
|
type = FILETYPE_MD;
|
|
break;
|
|
}
|
|
|
|
case 9:
|
|
{
|
|
strcpy(m->title,"Action Replay (Pro) ROM Selection");
|
|
type = FILETYPE_MD;
|
|
break;
|
|
}
|
|
|
|
case 10:
|
|
{
|
|
strcpy(m->title,"Sonic & Knuckles ROM Selection");
|
|
type = FILETYPE_MD;
|
|
break;
|
|
}
|
|
|
|
case 11:
|
|
{
|
|
strcpy(m->title,"Sonic 2 & Knuckles ROM Selection");
|
|
type = FILETYPE_MD;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* reset menu title */
|
|
strcpy(m->title, "Game Selection");
|
|
}
|
|
|
|
/* Set default helper for Back button */
|
|
strcpy(m->helpers[0]->comment, "Exit");
|
|
|
|
/* Check if we are not browsing recent file list */
|
|
if (type >= 0)
|
|
{
|
|
/* Select cartridge type */
|
|
bg_filesel[9 + type].data = Cart_png[type];
|
|
bg_filesel[9 + type].state |= IMAGE_VISIBLE;
|
|
|
|
/* Get current directory */
|
|
char *dir = GetCurrentDirectory();
|
|
|
|
/* Get current directory name length */
|
|
int size = strlen(dir);
|
|
|
|
/* Check if we are not in Root directory */
|
|
if (size > 1)
|
|
{
|
|
if (dir[size - 2] != ':')
|
|
{
|
|
/* Update helper for Back button */
|
|
strcpy(m->helpers[0]->comment, "Previous Directory");
|
|
}
|
|
}
|
|
|
|
/* Initialize directory icon */
|
|
dir_icon.texture = gxTextureOpenPNG(Browser_dir_png,0);
|
|
dir_icon.w = dir_icon.texture->width;
|
|
dir_icon.h = dir_icon.texture->height;
|
|
dir_icon.x = 26;
|
|
dir_icon.y = (26 - dir_icon.h)/2;
|
|
}
|
|
|
|
/* Initialize selection bar */
|
|
bar_over.texture = gxTextureOpenPNG(Overlay_bar_png,0);
|
|
bar_over.w = bar_over.texture->width;
|
|
bar_over.h = bar_over.texture->height;
|
|
bar_over.x = 16;
|
|
bar_over.y = (26 - bar_over.h)/2;
|
|
|
|
/* Initialize Menu */
|
|
GUI_InitMenu(m);
|
|
string_offset = 0;
|
|
|
|
while (1)
|
|
{
|
|
/* ROM file snapshot/database */
|
|
if (old != selection)
|
|
{
|
|
/* close any screenshot texture first */
|
|
gxTextureClose(&bg_filesel[8].texture);
|
|
bg_filesel[8].state &= ~IMAGE_VISIBLE;
|
|
|
|
old = selection;
|
|
string_offset = 0;
|
|
|
|
if (!filelist[selection].flags)
|
|
{
|
|
/* recent game list -> variable game types */
|
|
if (type < 0)
|
|
{
|
|
/* check if game type has changed */
|
|
type = history.entries[selection].filetype;
|
|
if (!(bg_filesel[9 + type].state & IMAGE_VISIBLE))
|
|
{
|
|
/* hide all cartridge labels */
|
|
for (i=0; i<FILETYPE_MAX; i++)
|
|
{
|
|
gxTextureClose(&bg_filesel[9 + i].texture);
|
|
bg_filesel[9 + i].state &= ~IMAGE_VISIBLE;
|
|
}
|
|
|
|
/* open cartridge label texture */
|
|
bg_filesel[9 + type].texture = gxTextureOpenPNG(Cart_png[type],0);
|
|
|
|
/* show selected cartridge label */
|
|
bg_filesel[9 + type].state |= IMAGE_VISIBLE;
|
|
}
|
|
|
|
/* default screenshot file path */
|
|
sprintf(fname,"%s/snaps/%s/%s", DEFAULT_PATH, Cart_dir[type], filelist[selection].filename);
|
|
|
|
/* restore recent type flag */
|
|
type = -1;
|
|
}
|
|
else
|
|
{
|
|
/* default screenshot file path */
|
|
sprintf(fname,"%s/snaps/%s/%s", DEFAULT_PATH, Cart_dir[type], filelist[selection].filename);
|
|
}
|
|
|
|
/* remove original file extension */
|
|
i = strlen(fname) - 1;
|
|
while ((i > 0) && (fname[i] != '.')) i--;
|
|
if (i > 0) fname[i] = 0;
|
|
|
|
/* add PNG file extension */
|
|
strcat(fname, ".png");
|
|
|
|
/* try to load screenshot file */
|
|
snap = fopen(fname, "rb");
|
|
if (snap)
|
|
{
|
|
bg_filesel[8].texture = gxTextureOpenPNG(0,snap);
|
|
if (bg_filesel[8].texture)
|
|
{
|
|
bg_filesel[8].state |= IMAGE_VISIBLE;
|
|
}
|
|
fclose(snap);
|
|
}
|
|
}
|
|
}
|
|
|
|
/* update Action button helper */
|
|
if (m->selected != -1)
|
|
{
|
|
/* out of focus */
|
|
strcpy(action_select.comment,"");
|
|
}
|
|
else if (filelist[selection].flags)
|
|
{
|
|
/* this is a directory */
|
|
strcpy(action_select.comment,"Open Directory");
|
|
}
|
|
else
|
|
{
|
|
/* this is a ROM file */
|
|
if (offset_ != -1)
|
|
{
|
|
/* System ROM browser */
|
|
strcpy(action_select.comment,"Select File");
|
|
}
|
|
else
|
|
{
|
|
/* Normal ROM browser */
|
|
strcpy(action_select.comment,"Load File");
|
|
}
|
|
}
|
|
|
|
/* Draw menu*/
|
|
GUI_DrawMenu(m);
|
|
|
|
#ifdef HW_RVL
|
|
if (Shutdown)
|
|
{
|
|
gxTextureClose(&bar_over.texture);
|
|
gxTextureClose(&dir_icon.texture);
|
|
gxTextureClose(&w_pointer);
|
|
GUI_DeleteMenu(m);
|
|
GUI_FadeOut();
|
|
shutdown();
|
|
SYS_ResetSystem(SYS_POWEROFF, 0, 0);
|
|
}
|
|
else if (m_input.ir.valid)
|
|
{
|
|
/* get cursor position */
|
|
x = m_input.ir.x;
|
|
y = m_input.ir.y;
|
|
|
|
/* draw wiimote pointer */
|
|
gxDrawTextureRotate(w_pointer, x-w_pointer->width/2, y-w_pointer->height/2, w_pointer->width, w_pointer->height,m_input.ir.angle,255);
|
|
|
|
/* ensure we are in the selectable area */
|
|
if ((x < 380) && (y >= 108) && (y <= 368))
|
|
{
|
|
/* find selected item */
|
|
selection = (y - 108) / 26;
|
|
if (selection > 9) selection = 9;
|
|
selection += offset;
|
|
if (selection >= maxfiles) selection = old;
|
|
|
|
/* reset selection */
|
|
m->selected = -1;
|
|
}
|
|
else
|
|
{
|
|
/* disable selection */
|
|
m->selected = m->max_buttons + 2;
|
|
|
|
/* find selected button */
|
|
for (i=0; i<2; i++)
|
|
{
|
|
button = m->arrows[i];
|
|
if (button)
|
|
{
|
|
if (button->state & BUTTON_VISIBLE)
|
|
{
|
|
if ((x>=button->x)&&(x<=(button->x+button->w))&&(y>=button->y)&&(y<=(button->y+button->h)))
|
|
{
|
|
m->selected = m->max_buttons + i;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* reset selection */
|
|
m->selected = -1;
|
|
}
|
|
#endif
|
|
|
|
/* copy EFB to XFB */
|
|
gxSetScreen();
|
|
|
|
p = m_input.keys;
|
|
|
|
/* highlight next item */
|
|
if (p & PAD_BUTTON_DOWN)
|
|
{
|
|
selection++;
|
|
if (selection >= maxfiles)
|
|
selection = offset = 0;
|
|
else if (selection >= (offset + 10))
|
|
offset++;
|
|
}
|
|
|
|
/* highlight previous item */
|
|
else if (p & PAD_BUTTON_UP)
|
|
{
|
|
selection--;
|
|
if (selection < 0)
|
|
{
|
|
selection = maxfiles - 1;
|
|
offset = maxfiles - 10;
|
|
if (offset < 0) offset = 0;
|
|
}
|
|
else if (selection < offset)
|
|
offset --;
|
|
}
|
|
|
|
/* go back one page */
|
|
else if (p & (PAD_TRIGGER_L | PAD_BUTTON_LEFT))
|
|
{
|
|
if (maxfiles >= 10)
|
|
{
|
|
selection -= 10;
|
|
if (selection < 0)
|
|
{
|
|
/* first page */
|
|
selection = offset = 0;
|
|
}
|
|
else if (selection < offset)
|
|
{
|
|
/* previous page */
|
|
offset -= 10;
|
|
if (offset < 0) offset = 0;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* go forward one page */
|
|
else if (p & (PAD_TRIGGER_R | PAD_BUTTON_RIGHT))
|
|
{
|
|
if (maxfiles >= 10)
|
|
{
|
|
selection += 10;
|
|
if (selection > maxfiles - 1)
|
|
{
|
|
/* last page */
|
|
selection = maxfiles - 1;
|
|
offset = maxfiles - 10;
|
|
}
|
|
else if (selection >= (offset + 10))
|
|
{
|
|
/* next page */
|
|
offset += 10;
|
|
if (offset > (maxfiles - 10)) offset = maxfiles - 10;
|
|
}
|
|
}
|
|
}
|
|
|
|
/* quit */
|
|
else if (p & PAD_TRIGGER_Z)
|
|
{
|
|
/* System ROM selection */
|
|
if (offset_ != -1)
|
|
{
|
|
/* restore current ROM browser */
|
|
offset = offset_;
|
|
maxfiles = maxfiles_;
|
|
selection = selection_;
|
|
}
|
|
|
|
gxTextureClose(&bar_over.texture);
|
|
gxTextureClose(&dir_icon.texture);
|
|
GUI_DeleteMenu(m);
|
|
return -1;
|
|
}
|
|
|
|
/* previous directory */
|
|
else if (p & PAD_BUTTON_B)
|
|
{
|
|
string_offset = 0;
|
|
|
|
/* recent ROM list */
|
|
if (type < 0)
|
|
{
|
|
/* exit */
|
|
gxTextureClose(&bar_over.texture);
|
|
gxTextureClose(&dir_icon.texture);
|
|
GUI_DeleteMenu(m);
|
|
return -1;
|
|
}
|
|
|
|
/* update browser directory (and get current folder)*/
|
|
if (UpdateDirectory(1, prev_folder))
|
|
{
|
|
/* get directory entries */
|
|
maxfiles = ParseDirectory();
|
|
|
|
/* Get current directory */
|
|
char *dir = GetCurrentDirectory();
|
|
|
|
/* current directory name length */
|
|
int size = strlen(dir);
|
|
|
|
/* Adjust helper for back button */
|
|
if ((size > 1) && (dir[size - 2] != ':'))
|
|
{
|
|
/* Back button goes up one directory */
|
|
strcpy(m->helpers[0]->comment, "Previous Directory");
|
|
}
|
|
else
|
|
{
|
|
/* Back button exits from root directory */
|
|
strcpy(m->helpers[0]->comment, "Exit");
|
|
}
|
|
|
|
/* clear selection by default */
|
|
selection = offset = 0;
|
|
old = -1;
|
|
|
|
/* select previous directory */
|
|
for (i=0; i<maxfiles; i++)
|
|
{
|
|
if ((filelist[i].flags) && !strcmp(prev_folder,filelist[i].filename))
|
|
{
|
|
selection = i;
|
|
while (i >= (offset + 10))
|
|
{
|
|
offset += 10;
|
|
if (offset > (maxfiles - 10)) offset = maxfiles - 10;
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
else
|
|
{
|
|
/* System ROM selection */
|
|
if (offset_ != -1)
|
|
{
|
|
/* restore current ROM browser */
|
|
offset = offset_;
|
|
maxfiles = maxfiles_;
|
|
selection = selection_;
|
|
}
|
|
|
|
/* Exit */
|
|
gxTextureClose(&bar_over.texture);
|
|
gxTextureClose(&dir_icon.texture);
|
|
GUI_DeleteMenu(m);
|
|
return -1;
|
|
}
|
|
}
|
|
|
|
/* open selected file or directory */
|
|
else if (p & PAD_BUTTON_A)
|
|
{
|
|
string_offset = 0;
|
|
|
|
/* ensure we are in focus area */
|
|
if (m->selected < m->max_buttons)
|
|
{
|
|
if (filelist[selection].flags)
|
|
{
|
|
/* get new directory */
|
|
UpdateDirectory(0, filelist[selection].filename);
|
|
|
|
/* get directory entries */
|
|
maxfiles = ParseDirectory();
|
|
|
|
/* clear selection by default */
|
|
selection = offset = 0;
|
|
old = -1;
|
|
}
|
|
else
|
|
{
|
|
int ret;
|
|
|
|
/* System ROM selection */
|
|
if (offset_ != -1)
|
|
{
|
|
/* return ROM file index */
|
|
ret = selection;
|
|
|
|
/* restore current ROM browser */
|
|
offset = offset_;
|
|
maxfiles = maxfiles_;
|
|
selection = selection_;
|
|
}
|
|
else
|
|
{
|
|
/* load ROM file from device then return ROM size (zero if an error occured) */
|
|
ret = LoadFile(selection);
|
|
}
|
|
|
|
/* exit menu */
|
|
gxTextureClose(&bar_over.texture);
|
|
gxTextureClose(&dir_icon.texture);
|
|
GUI_DeleteMenu(m);
|
|
return ret;
|
|
}
|
|
}
|
|
|
|
#ifdef HW_RVL
|
|
/* arrow buttons selected */
|
|
else if (m->selected == m->max_buttons)
|
|
{
|
|
/* up arrow */
|
|
selection--;
|
|
if (selection < 0)
|
|
{
|
|
selection = maxfiles - 1;
|
|
offset = selection - 10 + 1;
|
|
}
|
|
if (selection < offset) offset -= 10;
|
|
if (offset < 0) offset = 0;
|
|
}
|
|
else if (m->selected == (m->max_buttons+1))
|
|
{
|
|
/* down arrow */
|
|
selection++;
|
|
if (selection == maxfiles)
|
|
selection = offset = 0;
|
|
if ((selection - offset) >= 10)
|
|
offset += 10;
|
|
}
|
|
#endif
|
|
}
|
|
}
|
|
}
|
|
|
|
void ClearSelector(u32 max)
|
|
{
|
|
maxfiles = max;
|
|
offset = 0;
|
|
selection = 0;
|
|
}
|