-redesigned cheats manager menu, added Action Replay codes support
-added libiso9660 support -improved ROM browser and history -fixed missing MODE button support on Game Cube controller
@ -35,7 +35,7 @@ LDFLAGS = $(MACHDEP) -Wl,-Map,$(notdir $@).map
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# any extra libraries we wish to link with the project
|
# any extra libraries we wish to link with the project
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
LIBS := -lpng -lfat -lvorbisidec -lasnd -logc -lm -lz
|
LIBS := -lpng -lfat -liso9660 -lvorbisidec -lasnd -logc -lm -lz
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# list of directories containing libraries, this must be the top level containing
|
# list of directories containing libraries, this must be the top level containing
|
||||||
|
@ -35,7 +35,7 @@ LDFLAGS = $(MACHDEP) -Wl,-Map,$(notdir $@).map
|
|||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# any extra libraries we wish to link with the project
|
# any extra libraries we wish to link with the project
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
LIBS := -lpng -ldi -lfat -lvorbisidec -lasnd -lwiiuse -lbte -logc -lm -lz
|
LIBS := -lpng -ldi -lfat -liso9660 -lvorbisidec -lasnd -lwiiuse -lbte -logc -lm -lz
|
||||||
|
|
||||||
#---------------------------------------------------------------------------------
|
#---------------------------------------------------------------------------------
|
||||||
# list of directories containing libraries, this must be the top level containing
|
# list of directories containing libraries, this must be the top level containing
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
#include "shared.h"
|
#include "shared.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
|
#include "file_load.h"
|
||||||
|
|
||||||
void config_save(void)
|
void config_save(void)
|
||||||
{
|
{
|
||||||
@ -49,7 +50,7 @@ void config_load(void)
|
|||||||
char version[16];
|
char version[16];
|
||||||
fread(version, 16, 1, fp);
|
fread(version, 16, 1, fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
if (strcmp(version,VERSION))
|
if (strcmp(version,CONFIG_VERSION))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
/* read file */
|
/* read file */
|
||||||
@ -65,7 +66,7 @@ void config_load(void)
|
|||||||
void config_default(void)
|
void config_default(void)
|
||||||
{
|
{
|
||||||
/* version TAG */
|
/* version TAG */
|
||||||
strncpy(config.version,VERSION,16);
|
strncpy(config.version,CONFIG_VERSION,16);
|
||||||
|
|
||||||
/* sound options */
|
/* sound options */
|
||||||
config.psg_preamp = 150;
|
config.psg_preamp = 150;
|
||||||
@ -143,10 +144,12 @@ void config_default(void)
|
|||||||
|
|
||||||
/* default ROM directories */
|
/* default ROM directories */
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
sprintf (config.sddir, "sd:%s/roms/", DEFAULT_PATH);
|
sprintf (config.lastdir[TYPE_SD], "sd:%s/roms/", DEFAULT_PATH);
|
||||||
sprintf (config.usbdir, "usb:%s/roms/", DEFAULT_PATH);
|
sprintf (config.lastdir[TYPE_USB], "usb:%s/roms/", DEFAULT_PATH);
|
||||||
|
sprintf (config.lastdir[TYPE_DVD], "dvd:%s/roms/", DEFAULT_PATH);
|
||||||
#else
|
#else
|
||||||
sprintf (config.sddir, "%s/roms/", DEFAULT_PATH);
|
sprintf (config.lastdir[TYPE_SD], "%s/roms/", DEFAULT_PATH);
|
||||||
|
sprintf (config.lastdir[TYPE_DVD], "dvd:%s/roms/", DEFAULT_PATH);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* restore from config file */
|
/* restore from config file */
|
||||||
|
@ -24,6 +24,8 @@
|
|||||||
#ifndef _CONFIG_H_
|
#ifndef _CONFIG_H_
|
||||||
#define _CONFIG_H_
|
#define _CONFIG_H_
|
||||||
|
|
||||||
|
#define CONFIG_VERSION "GENPLUS-GX 1.4.0"
|
||||||
|
|
||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* Config Option
|
* Config Option
|
||||||
*
|
*
|
||||||
@ -81,9 +83,10 @@ typedef struct
|
|||||||
int16 screen_w;
|
int16 screen_w;
|
||||||
float bgm_volume;
|
float bgm_volume;
|
||||||
float sfx_volume;
|
float sfx_volume;
|
||||||
char sddir[MAXPATHLEN];
|
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
char usbdir[MAXPATHLEN];
|
char lastdir[3][MAXPATHLEN];
|
||||||
|
#else
|
||||||
|
char lastdir[2][MAXPATHLEN];
|
||||||
#endif
|
#endif
|
||||||
} t_config;
|
} t_config;
|
||||||
|
|
||||||
|
@ -1,177 +0,0 @@
|
|||||||
/*
|
|
||||||
* dvd.c
|
|
||||||
*
|
|
||||||
* Low-level DVD access
|
|
||||||
*
|
|
||||||
* Softdev (2006)
|
|
||||||
* Eke-Eke (2007,2008,2009)
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*
|
|
||||||
********************************************************************************/
|
|
||||||
|
|
||||||
#include "shared.h"
|
|
||||||
#include "file_dvd.h"
|
|
||||||
#include "gui.h"
|
|
||||||
|
|
||||||
#ifndef HW_RVL
|
|
||||||
static u64 DvdMaxOffset = 0x57057C00; /* 1.4 GB max. by default */
|
|
||||||
static vu32* const dvd = (u32*)0xCC006000; /* DVD I/O Address base */
|
|
||||||
static u8 *inquiry=(unsigned char *)0x80000004; /* pointer to drive ID */
|
|
||||||
#else
|
|
||||||
static u64 DvdMaxOffset = 0x118244F00LL; /* 4.7 GB max. */
|
|
||||||
#endif
|
|
||||||
|
|
||||||
static u8 DVDreadbuffer[2048] ATTRIBUTE_ALIGN (32); /* data buffer for all DVD operations */
|
|
||||||
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* dvd_read
|
|
||||||
*
|
|
||||||
* Read DVD disc sectors
|
|
||||||
***************************************************************************/
|
|
||||||
u32 dvd_read (void *dst, u32 len, u64 offset)
|
|
||||||
{
|
|
||||||
/*** We only allow 2k reads **/
|
|
||||||
if (len > DVDCHUNK)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/*** Let's not read past end of DVD ***/
|
|
||||||
if(offset < DvdMaxOffset)
|
|
||||||
{
|
|
||||||
unsigned char *buffer = (unsigned char *) (unsigned int) DVDreadbuffer;
|
|
||||||
DCInvalidateRange((void *)buffer, len);
|
|
||||||
|
|
||||||
#ifndef HW_RVL
|
|
||||||
dvd[0] = 0x2E;
|
|
||||||
dvd[1] = 0;
|
|
||||||
dvd[2] = 0xA8000000;
|
|
||||||
dvd[3] = (u32)(offset >> 2);
|
|
||||||
dvd[4] = len;
|
|
||||||
dvd[5] = (u32) buffer;
|
|
||||||
dvd[6] = len;
|
|
||||||
dvd[7] = 3;
|
|
||||||
|
|
||||||
/*** Enable reading with DMA ***/
|
|
||||||
while (dvd[7] & 1)
|
|
||||||
usleep(10);
|
|
||||||
memcpy (dst, buffer, len);
|
|
||||||
|
|
||||||
/*** Ensure it has completed ***/
|
|
||||||
if (dvd[0] & 0x4)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
#else
|
|
||||||
if (DI_ReadDVD(buffer, len >> 11, (u32)(offset >> 11)))
|
|
||||||
return 0;
|
|
||||||
memcpy (dst, buffer, len);
|
|
||||||
#endif
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* dvd_motor_off
|
|
||||||
*
|
|
||||||
* Stop the DVD Motor
|
|
||||||
*
|
|
||||||
* This can be used to prevent the Disc from spinning during playtime
|
|
||||||
****************************************************************************/
|
|
||||||
void dvd_motor_off( )
|
|
||||||
{
|
|
||||||
GUI_MsgBoxOpen("Information", "Stopping DVD drive ...", 1);
|
|
||||||
|
|
||||||
#ifndef HW_RVL
|
|
||||||
dvd[0] = 0x2e;
|
|
||||||
dvd[1] = 0;
|
|
||||||
dvd[2] = 0xe3000000;
|
|
||||||
dvd[3] = 0;
|
|
||||||
dvd[4] = 0;
|
|
||||||
dvd[5] = 0;
|
|
||||||
dvd[6] = 0;
|
|
||||||
dvd[7] = 1; // Do immediate
|
|
||||||
while (dvd[7] & 1)
|
|
||||||
usleep(10);
|
|
||||||
|
|
||||||
/*** PSO Stops blackscreen at reload ***/
|
|
||||||
dvd[0] = 0x14;
|
|
||||||
dvd[1] = 0;
|
|
||||||
|
|
||||||
#else
|
|
||||||
DI_StopMotor();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
GUI_MsgBoxClose();
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifndef HW_RVL
|
|
||||||
/****************************************************************************
|
|
||||||
* uselessinquiry
|
|
||||||
*
|
|
||||||
* As the name suggests, this function is quite useless.
|
|
||||||
* It's only purpose is to stop any pending DVD interrupts while we use the
|
|
||||||
* memcard interface.
|
|
||||||
*
|
|
||||||
* libOGC tends to foul up if you don't, and sometimes does if you do!
|
|
||||||
****************************************************************************/
|
|
||||||
void uselessinquiry ()
|
|
||||||
{
|
|
||||||
dvd[0] = 0;
|
|
||||||
dvd[1] = 0;
|
|
||||||
dvd[2] = 0x12000000;
|
|
||||||
dvd[3] = 0;
|
|
||||||
dvd[4] = 0x20;
|
|
||||||
dvd[5] = 0x80000000;
|
|
||||||
dvd[6] = 0x20;
|
|
||||||
dvd[7] = 1;
|
|
||||||
while (dvd[7] & 1)
|
|
||||||
usleep(10);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* dvd_drive_detect()
|
|
||||||
*
|
|
||||||
* Detect the DVD Drive Type
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
void dvd_drive_detect()
|
|
||||||
{
|
|
||||||
dvd[0] = 0x2e;
|
|
||||||
dvd[1] = 0;
|
|
||||||
dvd[2] = 0x12000000;
|
|
||||||
dvd[3] = 0;
|
|
||||||
dvd[4] = 0x20;
|
|
||||||
dvd[5] = 0x80000000;
|
|
||||||
dvd[6] = 0x20;
|
|
||||||
dvd[7] = 3;
|
|
||||||
while (dvd[7] & 1)
|
|
||||||
usleep(10);
|
|
||||||
|
|
||||||
DCFlushRange((void *)0x80000000, 32);
|
|
||||||
int driveid = (int)inquiry[2];
|
|
||||||
if ((driveid == 4) || (driveid == 6) || (driveid == 8))
|
|
||||||
{
|
|
||||||
/* Gamecube DVD Drive (1.4 GB)*/
|
|
||||||
DvdMaxOffset = 0x57057C00;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Wii DVD Drive (4.7GB) */
|
|
||||||
DvdMaxOffset = 0x118244F00LL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
@ -1,37 +0,0 @@
|
|||||||
/*
|
|
||||||
* dvd.c
|
|
||||||
*
|
|
||||||
* Low-level DVD access
|
|
||||||
*
|
|
||||||
* Softdev (2006)
|
|
||||||
* Eke-Eke (2007,2008,2009)
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*
|
|
||||||
********************************************************************************/
|
|
||||||
|
|
||||||
|
|
||||||
#ifndef _DVD_H_
|
|
||||||
#define _DVD_H_
|
|
||||||
|
|
||||||
extern u32 dvd_read (void *dst, u32 len, u64 offset);
|
|
||||||
extern void dvd_motor_off ();
|
|
||||||
|
|
||||||
#ifndef HW_RVL
|
|
||||||
extern void uselessinquiry ();
|
|
||||||
extern void dvd_drive_detect();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,432 +0,0 @@
|
|||||||
/*
|
|
||||||
* file_dvd.c
|
|
||||||
*
|
|
||||||
* ISO9660/Joliet DVD loading support
|
|
||||||
*
|
|
||||||
* Softdev (2006)
|
|
||||||
* Eke-Eke (2007,2008,2009)
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*
|
|
||||||
********************************************************************************/
|
|
||||||
|
|
||||||
#include "shared.h"
|
|
||||||
#include "gui.h"
|
|
||||||
#include "dvd.h"
|
|
||||||
#include "unzip.h"
|
|
||||||
#include "filesel.h"
|
|
||||||
#include "file_fat.h"
|
|
||||||
#include "file_dvd.h"
|
|
||||||
|
|
||||||
/** Minimal ISO Directory Definition **/
|
|
||||||
#define RECLEN 0 /* Record length */
|
|
||||||
#define EXTENT 6 /* Extent */
|
|
||||||
#define FILE_LENGTH 14 /* File length (BIG ENDIAN) */
|
|
||||||
#define FILE_FLAGS 25 /* File flags */
|
|
||||||
#define FILENAME_LENGTH 32 /* Filename length */
|
|
||||||
#define FILENAME 33 /* ASCIIZ filename */
|
|
||||||
|
|
||||||
/** Minimal Primary Volume Descriptor **/
|
|
||||||
#define PVDROOT 0x9c
|
|
||||||
|
|
||||||
/** Static Variables **/
|
|
||||||
static u64 rootdir = 0;
|
|
||||||
static u64 basedir = 0;
|
|
||||||
static int rootdirlength = 0;
|
|
||||||
static int IsJoliet = 0;
|
|
||||||
static int diroffset = 0;
|
|
||||||
static int haveDVDdir = 0;
|
|
||||||
static char dvdbuffer[DVDCHUNK];
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Primary Volume Descriptor
|
|
||||||
*
|
|
||||||
* The PVD should reside between sector 16 and 31.
|
|
||||||
* This is for single session DVD only.
|
|
||||||
****************************************************************************/
|
|
||||||
static int getpvd()
|
|
||||||
{
|
|
||||||
int sector = 16;
|
|
||||||
u32 rootdir32;
|
|
||||||
|
|
||||||
basedir = rootdirlength = 0;
|
|
||||||
IsJoliet = -1;
|
|
||||||
|
|
||||||
/** Look for Joliet PVD first **/
|
|
||||||
while (sector < 32)
|
|
||||||
{
|
|
||||||
if (dvd_read (&dvdbuffer, DVDCHUNK, (u64)(sector << 11)))
|
|
||||||
{
|
|
||||||
if (memcmp (&dvdbuffer, "\2CD001\1", 8) == 0)
|
|
||||||
{
|
|
||||||
memcpy(&rootdir32, &dvdbuffer[PVDROOT + EXTENT], 4);
|
|
||||||
basedir = (u64)rootdir32;
|
|
||||||
memcpy (&rootdirlength, &dvdbuffer[PVDROOT + FILE_LENGTH], 4);
|
|
||||||
basedir <<= 11;
|
|
||||||
IsJoliet = 1;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return 0; /*** Can't read sector! ***/
|
|
||||||
|
|
||||||
sector++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (IsJoliet > 0)
|
|
||||||
return 1; /*** Joliet PVD Found ? ***/
|
|
||||||
|
|
||||||
/*** Look for standard ISO9660 PVD ***/
|
|
||||||
sector = 16;
|
|
||||||
while (sector < 32)
|
|
||||||
{
|
|
||||||
if (dvd_read (&dvdbuffer, DVDCHUNK, (u64)(sector << 11)))
|
|
||||||
{
|
|
||||||
if (memcmp (&dvdbuffer, "\1CD001\1", 8) == 0)
|
|
||||||
{
|
|
||||||
memcpy (&rootdir32, &dvdbuffer[PVDROOT + EXTENT], 4);
|
|
||||||
basedir = (u64)rootdir32;
|
|
||||||
memcpy (&rootdirlength, &dvdbuffer[PVDROOT + FILE_LENGTH], 4);
|
|
||||||
IsJoliet = 0;
|
|
||||||
basedir <<= 11;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return 0; /*** Can't read sector! ***/
|
|
||||||
|
|
||||||
sector++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return (IsJoliet == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* getentry
|
|
||||||
*
|
|
||||||
* Support function to return the next file entry, if any
|
|
||||||
* Declared static to avoid accidental external entry.
|
|
||||||
****************************************************************************/
|
|
||||||
static int getentry(int entrycount)
|
|
||||||
{
|
|
||||||
char fname[512]; /* Huge, but experience has determined this */
|
|
||||||
char *ptr;
|
|
||||||
char *filename;
|
|
||||||
char *filenamelength;
|
|
||||||
char *rr;
|
|
||||||
int j;
|
|
||||||
u32 offset32;
|
|
||||||
|
|
||||||
/* Basic checks */
|
|
||||||
if (entrycount >= MAXFILES)
|
|
||||||
return 0;
|
|
||||||
if (diroffset >= DVDCHUNK)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/** Decode this entry **/
|
|
||||||
if (dvdbuffer[diroffset]) /* Record length available */
|
|
||||||
{
|
|
||||||
/* Update offsets into sector buffer */
|
|
||||||
ptr = (char *) &dvdbuffer[0];
|
|
||||||
ptr += diroffset;
|
|
||||||
filename = ptr + FILENAME;
|
|
||||||
filenamelength = ptr + FILENAME_LENGTH;
|
|
||||||
|
|
||||||
/* Check for wrap round - illegal in ISO spec,
|
|
||||||
* but certain crap writers do it! */
|
|
||||||
if ((diroffset + dvdbuffer[diroffset]) > DVDCHUNK)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (*filenamelength)
|
|
||||||
{
|
|
||||||
memset (&fname, 0, 512);
|
|
||||||
|
|
||||||
/** Do ISO 9660 first **/
|
|
||||||
if (!IsJoliet)
|
|
||||||
strcpy (fname, filename);
|
|
||||||
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/** The more tortuous unicode joliet entries **/
|
|
||||||
for (j = 0; j < (*filenamelength >> 1); j++)
|
|
||||||
fname[j] = filename[j * 2 + 1];
|
|
||||||
fname[j] = 0;
|
|
||||||
|
|
||||||
if (strlen (fname) >= MAXJOLIET)
|
|
||||||
fname[MAXJOLIET - 1] = 0;
|
|
||||||
if (strlen (fname) == 0)
|
|
||||||
fname[0] = filename[0];
|
|
||||||
}
|
|
||||||
|
|
||||||
if (strlen (fname) == 0)
|
|
||||||
strcpy (fname, ".");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
if (fname[0] == 1)
|
|
||||||
strcpy (fname, "..");
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/*
|
|
||||||
* Move *filenamelength to t,
|
|
||||||
* Only to stop gcc warning for noobs :)
|
|
||||||
*/
|
|
||||||
int t = *filenamelength;
|
|
||||||
fname[t] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Rockridge Check */
|
|
||||||
rr = strstr (fname, ";");
|
|
||||||
if (rr != NULL)
|
|
||||||
*rr = 0;
|
|
||||||
|
|
||||||
strcpy (filelist[entrycount].filename, fname);
|
|
||||||
memcpy (&offset32, &dvdbuffer[diroffset + EXTENT], 4);
|
|
||||||
filelist[entrycount].offset = (u64)offset32;
|
|
||||||
memcpy (&filelist[entrycount].length, &dvdbuffer[diroffset + FILE_LENGTH], 4);
|
|
||||||
memcpy (&filelist[entrycount].flags, &dvdbuffer[diroffset + FILE_FLAGS], 1);
|
|
||||||
filelist[entrycount].offset <<= 11;
|
|
||||||
filelist[entrycount].flags = filelist[entrycount].flags & 2;
|
|
||||||
|
|
||||||
/* Prepare for next entry */
|
|
||||||
diroffset += dvdbuffer[diroffset];
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* DVD_ClearDirectory
|
|
||||||
*
|
|
||||||
* Clear DVD directory flag
|
|
||||||
***************************************************************************/
|
|
||||||
void DVD_ClearDirectory(void)
|
|
||||||
{
|
|
||||||
haveDVDdir = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* DVD_UpdateDirectory
|
|
||||||
*
|
|
||||||
* Update DVD current root directory
|
|
||||||
***************************************************************************/
|
|
||||||
int DVD_UpdateDirectory(bool go_up, u64 offset, u32 length)
|
|
||||||
{
|
|
||||||
/* root has no parent directory */
|
|
||||||
if ((basedir == rootdir) && (go_up || (offset == basedir)))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* simply update current root directory */
|
|
||||||
rootdir = offset;
|
|
||||||
rootdirlength = length;
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* DVD_ParseDirectory
|
|
||||||
*
|
|
||||||
* This function will parse the directory tree.
|
|
||||||
* It relies on rootdir and rootdirlength being pre-populated by a call to
|
|
||||||
* getpvd, a previous parse or a menu selection.
|
|
||||||
*
|
|
||||||
* The return value is number of files collected, or 0 on failure.
|
|
||||||
****************************************************************************/
|
|
||||||
int DVD_ParseDirectory(void)
|
|
||||||
{
|
|
||||||
int pdlength;
|
|
||||||
u64 pdoffset;
|
|
||||||
u64 rdoffset;
|
|
||||||
int len = 0;
|
|
||||||
int filecount = 0;
|
|
||||||
|
|
||||||
pdoffset = rdoffset = rootdir;
|
|
||||||
pdlength = rootdirlength;
|
|
||||||
filecount = 0;
|
|
||||||
|
|
||||||
/** Clear any existing values ***/
|
|
||||||
memset (&filelist, 0, sizeof (FILEENTRIES) * MAXFILES);
|
|
||||||
|
|
||||||
/*** Get as many files as possible ***/
|
|
||||||
while (len < pdlength)
|
|
||||||
{
|
|
||||||
if (dvd_read (&dvdbuffer, DVDCHUNK, pdoffset) == 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
diroffset = 0;
|
|
||||||
|
|
||||||
while (getentry (filecount))
|
|
||||||
{
|
|
||||||
if (strcmp(filelist[filecount].filename,".") && (filecount < MAXFILES))
|
|
||||||
filecount++;
|
|
||||||
}
|
|
||||||
|
|
||||||
len += DVDCHUNK;
|
|
||||||
pdoffset = rdoffset + len;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Sort the file list */
|
|
||||||
qsort(filelist, filecount, sizeof(FILEENTRIES), FileSortCallback);
|
|
||||||
|
|
||||||
return filecount;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* DVD_LoadFile
|
|
||||||
*
|
|
||||||
* This function will load a BIN, SMD or ZIP file from DVD into the ROM buffer.
|
|
||||||
* The index values indicates the file position in filentry list
|
|
||||||
* This functions return the actual size of data copied into the buffer
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
int DVD_LoadFile(u8 *buffer, u32 selection)
|
|
||||||
{
|
|
||||||
/* file size */
|
|
||||||
int length = filelist[selection].length;
|
|
||||||
|
|
||||||
if (length > 0)
|
|
||||||
{
|
|
||||||
/* Read first data chunk */
|
|
||||||
char readbuffer[DVDCHUNK];
|
|
||||||
u64 discoffset = filelist[selection].offset;
|
|
||||||
dvd_read (&readbuffer, DVDCHUNK, discoffset);
|
|
||||||
|
|
||||||
/* determine file type */
|
|
||||||
if (!IsZipFile ((char *) readbuffer))
|
|
||||||
{
|
|
||||||
if (length > MAXROMSIZE)
|
|
||||||
{
|
|
||||||
GUI_WaitPrompt("Error","File size not supported !");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
char msg[64];
|
|
||||||
sprintf(msg,"Loading %d bytes...", length);
|
|
||||||
GUI_MsgBoxOpen("Information",msg,1);
|
|
||||||
|
|
||||||
/* How many 2k blocks to read */
|
|
||||||
int blocks = length / DVDCHUNK;
|
|
||||||
int readoffset = 0;
|
|
||||||
int i;
|
|
||||||
|
|
||||||
/* read data chunks */
|
|
||||||
for (i = 0; i < blocks; i++)
|
|
||||||
{
|
|
||||||
dvd_read(readbuffer, DVDCHUNK, discoffset);
|
|
||||||
discoffset += DVDCHUNK;
|
|
||||||
memcpy (buffer + readoffset, readbuffer, DVDCHUNK);
|
|
||||||
readoffset += DVDCHUNK;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* final read */
|
|
||||||
i = length % DVDCHUNK;
|
|
||||||
if (i)
|
|
||||||
{
|
|
||||||
dvd_read (readbuffer, DVDCHUNK, discoffset);
|
|
||||||
memcpy (buffer + readoffset, readbuffer, i);
|
|
||||||
}
|
|
||||||
|
|
||||||
return length;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
return UnZipBuffer (buffer, discoffset, NULL);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* DVD_Open
|
|
||||||
*
|
|
||||||
* Function to load a DVD directory and display to user.
|
|
||||||
****************************************************************************/
|
|
||||||
|
|
||||||
int DVD_Open(void)
|
|
||||||
{
|
|
||||||
/* is DVD mounted ? */
|
|
||||||
if (!getpvd())
|
|
||||||
{
|
|
||||||
/* remount DVD */
|
|
||||||
GUI_MsgBoxOpen("Information", "Mounting DVD ...",1);
|
|
||||||
haveDVDdir = 0;
|
|
||||||
|
|
||||||
#ifdef HW_RVL
|
|
||||||
u32 val;
|
|
||||||
DI_GetCoverRegister(&val);
|
|
||||||
|
|
||||||
if(val & 0x1)
|
|
||||||
{
|
|
||||||
GUI_WaitPrompt("Error","No Disc inserted !");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
DI_Mount();
|
|
||||||
while(DI_GetStatus() & DVD_INIT) usleep(10);
|
|
||||||
if (!(DI_GetStatus() & DVD_READY))
|
|
||||||
{
|
|
||||||
char msg[64];
|
|
||||||
sprintf(msg, "DI Status Error: 0x%08X !\n",DI_GetStatus());
|
|
||||||
GUI_WaitPrompt("Error",msg);
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
#else
|
|
||||||
DVD_Mount();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!getpvd())
|
|
||||||
{
|
|
||||||
GUI_WaitPrompt("Error","Disc can not be read !");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* reset current directory */
|
|
||||||
rootdir = basedir;
|
|
||||||
|
|
||||||
GUI_MsgBoxClose();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!haveDVDdir)
|
|
||||||
{
|
|
||||||
/* parse current directory */
|
|
||||||
int max = DVD_ParseDirectory ();
|
|
||||||
|
|
||||||
if (max)
|
|
||||||
{
|
|
||||||
/* set DVD access flag */
|
|
||||||
haveDVDdir = 1;
|
|
||||||
|
|
||||||
/* reset File selector */
|
|
||||||
ClearSelector(max);
|
|
||||||
|
|
||||||
/* clear FAT access flag */
|
|
||||||
FAT_ClearDirectory();
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* no entries found */
|
|
||||||
GUI_WaitPrompt("Error","No files found !");
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
@ -1,36 +0,0 @@
|
|||||||
/*
|
|
||||||
* file_dvd.c
|
|
||||||
*
|
|
||||||
* ISO9660/Joliet DVD loading support
|
|
||||||
*
|
|
||||||
* Softdev (2006)
|
|
||||||
* Eke-Eke (2007,2008,2009)
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*
|
|
||||||
********************************************************************************/
|
|
||||||
|
|
||||||
#ifndef _FILE_DVD_H
|
|
||||||
#define _FILE_DVD_H
|
|
||||||
|
|
||||||
#define DVDCHUNK (2048)
|
|
||||||
|
|
||||||
extern void DVD_ClearDirectory(void);
|
|
||||||
extern int DVD_UpdateDirectory(bool go_up,u64 offset, u32 length);
|
|
||||||
extern int DVD_ParseDirectory(void);
|
|
||||||
extern int DVD_LoadFile(u8 *buffer,u32 selection);
|
|
||||||
extern int DVD_Open(void);
|
|
||||||
|
|
||||||
#endif
|
|
@ -1,305 +0,0 @@
|
|||||||
/*
|
|
||||||
* file_fat.c
|
|
||||||
*
|
|
||||||
* FAT loading support
|
|
||||||
*
|
|
||||||
* Eke-Eke (2008,2009)
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*
|
|
||||||
********************************************************************************/
|
|
||||||
|
|
||||||
#include "shared.h"
|
|
||||||
#include "gui.h"
|
|
||||||
#include "history.h"
|
|
||||||
#include "unzip.h"
|
|
||||||
#include "filesel.h"
|
|
||||||
#include "file_fat.h"
|
|
||||||
#include "file_dvd.h"
|
|
||||||
|
|
||||||
/* current FAT directory */
|
|
||||||
static char *fatdir;
|
|
||||||
|
|
||||||
/* current FAT device */
|
|
||||||
static int fatType = -1;
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* FAT_ClearDirectory
|
|
||||||
*
|
|
||||||
* Clear FAT access flag
|
|
||||||
***************************************************************************/
|
|
||||||
void FAT_ClearDirectory(void)
|
|
||||||
{
|
|
||||||
fatType = -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* FAT_UpdateDirectory
|
|
||||||
*
|
|
||||||
* Update FAT current directory
|
|
||||||
* return zero if exiting root
|
|
||||||
***************************************************************************/
|
|
||||||
int FAT_UpdateDirectory(bool go_up, char *dirname)
|
|
||||||
{
|
|
||||||
int size=0;
|
|
||||||
char *test;
|
|
||||||
char temp[MAXPATHLEN];
|
|
||||||
|
|
||||||
/* go up to parent directory */
|
|
||||||
if (strcmp(dirname,"..") == 0)
|
|
||||||
{
|
|
||||||
/* determine last subdirectory namelength */
|
|
||||||
sprintf(temp,"%s",fatdir);
|
|
||||||
test= strtok(temp,"/");
|
|
||||||
while (test != NULL)
|
|
||||||
{
|
|
||||||
size = strlen(test);
|
|
||||||
test = strtok(NULL,"/");
|
|
||||||
}
|
|
||||||
|
|
||||||
/* remove last subdirectory name */
|
|
||||||
size = strlen(fatdir) - size;
|
|
||||||
fatdir[size-1] = 0;
|
|
||||||
}
|
|
||||||
else if (go_up)
|
|
||||||
{
|
|
||||||
/* root has no parent directory */
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* by default, simply append folder name */
|
|
||||||
sprintf(fatdir, "%s%s/",fatdir, dirname);
|
|
||||||
}
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* FAT_ParseDirectory
|
|
||||||
*
|
|
||||||
* List files into one FAT directory
|
|
||||||
***************************************************************************/
|
|
||||||
int FAT_ParseDirectory(void)
|
|
||||||
{
|
|
||||||
int nbfiles = 0;
|
|
||||||
char filename[MAXPATHLEN];
|
|
||||||
struct stat filestat;
|
|
||||||
|
|
||||||
/* open directory */
|
|
||||||
DIR_ITER *dir = diropen (fatdir);
|
|
||||||
if (dir == NULL)
|
|
||||||
{
|
|
||||||
GUI_WaitPrompt("Error","Unable to open directory !");
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
while ((dirnext(dir, filename, &filestat) == 0) && (nbfiles < MAXFILES))
|
|
||||||
{
|
|
||||||
if (strcmp(filename,".") != 0)
|
|
||||||
{
|
|
||||||
memset(&filelist[nbfiles], 0, sizeof (FILEENTRIES));
|
|
||||||
sprintf(filelist[nbfiles].filename,"%s",filename);
|
|
||||||
filelist[nbfiles].length = filestat.st_size;
|
|
||||||
filelist[nbfiles].flags = (filestat.st_mode & S_IFDIR) ? 1 : 0;
|
|
||||||
nbfiles++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
dirclose(dir);
|
|
||||||
|
|
||||||
/* Sort the file list */
|
|
||||||
qsort(filelist, nbfiles, sizeof(FILEENTRIES), FileSortCallback);
|
|
||||||
|
|
||||||
return nbfiles;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* FAT_LoadFile
|
|
||||||
*
|
|
||||||
* This function will load a BIN, SMD or ZIP file from DVD into the ROM buffer.
|
|
||||||
* This functions return the actual size of data copied into the buffer
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
int FAT_LoadFile(u8 *buffer, u32 selection)
|
|
||||||
{
|
|
||||||
char fname[MAXPATHLEN];
|
|
||||||
int length = 0;
|
|
||||||
|
|
||||||
/* Loading from history */
|
|
||||||
if(fatType == TYPE_RECENT)
|
|
||||||
{
|
|
||||||
/* full filename */
|
|
||||||
sprintf(fname,"%s%s",history.entries[selection].filepath,filelist[selection].filename);
|
|
||||||
|
|
||||||
/* get the length of the file */
|
|
||||||
struct stat filestat;
|
|
||||||
if(stat(fname, &filestat) == 0)
|
|
||||||
length = filestat.st_size;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* full filename */
|
|
||||||
sprintf(fname, "%s%s",fatdir,filelist[selection].filename);
|
|
||||||
|
|
||||||
/* get the length of the file */
|
|
||||||
length = filelist[selection].length;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (length > 0)
|
|
||||||
{
|
|
||||||
/* Open file */
|
|
||||||
FILE *sdfile = fopen(fname, "rb");
|
|
||||||
if (sdfile == NULL)
|
|
||||||
{
|
|
||||||
GUI_WaitPrompt("Error","Unable to open file !");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Add/move the file to the top of the history. */
|
|
||||||
if(fatType == TYPE_RECENT)
|
|
||||||
history_add_file(history.entries[selection].filepath, filelist[selection].filename);
|
|
||||||
else
|
|
||||||
history_add_file(fatdir, filelist[selection].filename);
|
|
||||||
|
|
||||||
/* file browser should be reinitialized */
|
|
||||||
if(fatType == TYPE_RECENT)
|
|
||||||
fatType = -1;
|
|
||||||
|
|
||||||
/* Read first data chunk */
|
|
||||||
unsigned char temp[FATCHUNK];
|
|
||||||
fread(temp, FATCHUNK, 1, sdfile);
|
|
||||||
fclose(sdfile);
|
|
||||||
|
|
||||||
/* Determine file type */
|
|
||||||
if (!IsZipFile ((char *) temp))
|
|
||||||
{
|
|
||||||
if (length > MAXROMSIZE)
|
|
||||||
{
|
|
||||||
GUI_WaitPrompt("Error","File size not supported !");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* re-open and read file */
|
|
||||||
sdfile = fopen(fname, "rb");
|
|
||||||
if (sdfile)
|
|
||||||
{
|
|
||||||
char msg[64];
|
|
||||||
sprintf(msg,"Loading %d bytes ...", length);
|
|
||||||
GUI_MsgBoxOpen("Information",msg,1);
|
|
||||||
int done = 0;
|
|
||||||
while (length > FATCHUNK)
|
|
||||||
{
|
|
||||||
fread(buffer + done, FATCHUNK, 1, sdfile);
|
|
||||||
length -= FATCHUNK;
|
|
||||||
done += FATCHUNK;
|
|
||||||
}
|
|
||||||
fread(buffer + done, length, 1, sdfile);
|
|
||||||
done += length;
|
|
||||||
fclose(sdfile);
|
|
||||||
return done;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* unzip file */
|
|
||||||
return UnZipBuffer(buffer, 0, fname);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* OpenFAT
|
|
||||||
*
|
|
||||||
* Function to load a FAT directory and display to user.
|
|
||||||
****************************************************************************/
|
|
||||||
int FAT_Open(int type)
|
|
||||||
{
|
|
||||||
int max = 0;
|
|
||||||
|
|
||||||
if (type == TYPE_RECENT)
|
|
||||||
{
|
|
||||||
/* fetch history list */
|
|
||||||
int i;
|
|
||||||
for(i=0; i < NUM_HISTORY_ENTRIES; i++)
|
|
||||||
{
|
|
||||||
if(history.entries[i].filepath[0] > 0)
|
|
||||||
{
|
|
||||||
filelist[i].offset = 0;
|
|
||||||
filelist[i].length = 0;
|
|
||||||
filelist[i].flags = 0;
|
|
||||||
strncpy(filelist[i].filename,history.entries[i].filename, MAXJOLIET-1);
|
|
||||||
filelist[i].filename[MAXJOLIET-1] = '\0';
|
|
||||||
max++;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* Found the end of the list. */
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* default directory */
|
|
||||||
fatdir = config.sddir;
|
|
||||||
#ifdef HW_RVL
|
|
||||||
if (type == TYPE_USB)
|
|
||||||
fatdir = config.usbdir;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* verify current dir exists, otherwise browse from root */
|
|
||||||
DIR_ITER *dir = diropen(fatdir);
|
|
||||||
if (dir)
|
|
||||||
dirclose(dir);
|
|
||||||
#ifdef HW_RVL
|
|
||||||
else if (type == TYPE_USB)
|
|
||||||
sprintf (fatdir, "usb:/");
|
|
||||||
else
|
|
||||||
sprintf (fatdir, "sd:/");
|
|
||||||
#else
|
|
||||||
else
|
|
||||||
sprintf (fatdir, "/");
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* parse current directory */
|
|
||||||
max = FAT_ParseDirectory ();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (max < 0)
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
if (max == 0)
|
|
||||||
{
|
|
||||||
GUI_WaitPrompt("Error","No files found !");
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* check if access type has changed */
|
|
||||||
if (type != fatType)
|
|
||||||
{
|
|
||||||
/* set current access type */
|
|
||||||
fatType = type;
|
|
||||||
|
|
||||||
/* reset File selector */
|
|
||||||
ClearSelector(max);
|
|
||||||
|
|
||||||
/* clear DVD access flag */
|
|
||||||
DVD_ClearDirectory();
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
375
source/gx/fileio/file_load.c
Normal file
@ -0,0 +1,375 @@
|
|||||||
|
/*
|
||||||
|
* file_load.c
|
||||||
|
*
|
||||||
|
* ROM File loading support
|
||||||
|
*
|
||||||
|
* Eke-Eke (2010)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
********************************************************************************/
|
||||||
|
|
||||||
|
#include "shared.h"
|
||||||
|
#include "file_load.h"
|
||||||
|
#include "gui.h"
|
||||||
|
#include "history.h"
|
||||||
|
#include "unzip.h"
|
||||||
|
#include "filesel.h"
|
||||||
|
|
||||||
|
#include <iso9660.h>
|
||||||
|
#ifdef HW_RVL
|
||||||
|
#include <di/di.h>
|
||||||
|
#else
|
||||||
|
#include <ogc/dvd.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* device root directories */
|
||||||
|
#ifdef HW_RVL
|
||||||
|
static const char rootdir[TYPE_RECENT][10] = {"sd:/","usb:/","dvd:/"};
|
||||||
|
#else
|
||||||
|
static const char rootdir[TYPE_RECENT][10] = {"/","dvd:/"};
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* DVD interface */
|
||||||
|
#ifdef HW_RVL
|
||||||
|
static const DISC_INTERFACE* dvd = &__io_wiidvd;
|
||||||
|
#else
|
||||||
|
static const DISC_INTERFACE* dvd = &__io_gcdvd;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/* current directory */
|
||||||
|
static char *fileDir;
|
||||||
|
|
||||||
|
/* current device */
|
||||||
|
static int deviceType = -1;
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* MountDVD
|
||||||
|
*
|
||||||
|
* return 0 on error, 1 on success
|
||||||
|
***************************************************************************/
|
||||||
|
static int MountDVD(void)
|
||||||
|
{
|
||||||
|
GUI_MsgBoxOpen("Information", "Mounting DVD ...",1);
|
||||||
|
|
||||||
|
if(!dvd->isInserted())
|
||||||
|
{
|
||||||
|
GUI_WaitPrompt("Error","No Disc inserted !");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!ISO9660_Mount())
|
||||||
|
{
|
||||||
|
GUI_WaitPrompt("Error","Disc can not be read !");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
GUI_MsgBoxClose();
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* FileSortCallback (code by Marty Disibio)
|
||||||
|
*
|
||||||
|
* Quick sort callback to sort file entries with the following order:
|
||||||
|
* .
|
||||||
|
* ..
|
||||||
|
* <dirs>
|
||||||
|
* <files>
|
||||||
|
***************************************************************************/
|
||||||
|
static int FileSortCallback(const void *f1, const void *f2)
|
||||||
|
{
|
||||||
|
/* Special case for implicit directories */
|
||||||
|
if(((FILEENTRIES *)f1)->filename[0] == '.' || ((FILEENTRIES *)f2)->filename[0] == '.')
|
||||||
|
{
|
||||||
|
if(strcmp(((FILEENTRIES *)f1)->filename, ".") == 0) { return -1; }
|
||||||
|
if(strcmp(((FILEENTRIES *)f2)->filename, ".") == 0) { return 1; }
|
||||||
|
if(strcmp(((FILEENTRIES *)f1)->filename, "..") == 0) { return -1; }
|
||||||
|
if(strcmp(((FILEENTRIES *)f2)->filename, "..") == 0) { return 1; }
|
||||||
|
}
|
||||||
|
|
||||||
|
/* If one is a file and one is a directory the directory is first. */
|
||||||
|
if(((FILEENTRIES *)f1)->flags == 1 && ((FILEENTRIES *)f2)->flags == 0) return -1;
|
||||||
|
if(((FILEENTRIES *)f1)->flags == 0 && ((FILEENTRIES *)f2)->flags == 1) return 1;
|
||||||
|
|
||||||
|
return stricmp(((FILEENTRIES *)f1)->filename, ((FILEENTRIES *)f2)->filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* UpdateDirectory
|
||||||
|
*
|
||||||
|
* Update current browser directory
|
||||||
|
* return zero if going up while in root
|
||||||
|
* when going up, return previous dir name
|
||||||
|
***************************************************************************/
|
||||||
|
int UpdateDirectory(bool go_up, char *dirname)
|
||||||
|
{
|
||||||
|
/* go up to parent directory */
|
||||||
|
if (go_up)
|
||||||
|
{
|
||||||
|
/* special case */
|
||||||
|
if (deviceType == TYPE_RECENT) return 0;
|
||||||
|
|
||||||
|
/* check if we already are at root directory */
|
||||||
|
if (!strcmp(rootdir[deviceType], (const char *)fileDir)) return 0;
|
||||||
|
|
||||||
|
int size=0;
|
||||||
|
char temp[MAXPATHLEN];
|
||||||
|
|
||||||
|
/* determine last folder name length */
|
||||||
|
strcpy(temp, fileDir);
|
||||||
|
char *test= strtok(temp,"/");
|
||||||
|
while (test != NULL)
|
||||||
|
{
|
||||||
|
size = strlen(test);
|
||||||
|
strncpy(dirname,test,size);
|
||||||
|
dirname[size] = 0;
|
||||||
|
test = strtok(NULL,"/");
|
||||||
|
}
|
||||||
|
|
||||||
|
/* remove last folder from path */
|
||||||
|
size = strlen(fileDir) - size;
|
||||||
|
fileDir[size - 1] = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* by default, simply append folder name */
|
||||||
|
sprintf(fileDir, "%s%s/",fileDir, dirname);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/***************************************************************************
|
||||||
|
* ParseDirectory
|
||||||
|
*
|
||||||
|
* List files into one directory
|
||||||
|
***************************************************************************/
|
||||||
|
int ParseDirectory(void)
|
||||||
|
{
|
||||||
|
int nbfiles = 0;
|
||||||
|
char filename[MAXPATHLEN];
|
||||||
|
struct stat filestat;
|
||||||
|
|
||||||
|
/* open directory */
|
||||||
|
DIR_ITER *dir = diropen(fileDir);
|
||||||
|
if (dir == NULL)
|
||||||
|
{
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* list files */
|
||||||
|
while ((dirnext(dir, filename, &filestat) == 0) && (nbfiles < MAXFILES))
|
||||||
|
{
|
||||||
|
if (filename[0] != '.')
|
||||||
|
{
|
||||||
|
memset(&filelist[nbfiles], 0, sizeof (FILEENTRIES));
|
||||||
|
sprintf(filelist[nbfiles].filename,"%s",filename);
|
||||||
|
filelist[nbfiles].flags = (filestat.st_mode & S_IFDIR) ? 1 : 0;
|
||||||
|
nbfiles++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* close directory */
|
||||||
|
dirclose(dir);
|
||||||
|
|
||||||
|
/* Sort the file list */
|
||||||
|
qsort(filelist, nbfiles, sizeof(FILEENTRIES), FileSortCallback);
|
||||||
|
|
||||||
|
return nbfiles;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* LoadFile
|
||||||
|
*
|
||||||
|
* This function will load a BIN, SMD or ZIP file into the ROM buffer.
|
||||||
|
* This functions return the actual size of data copied into the buffer
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
int LoadFile(u8 *buffer, u32 selection)
|
||||||
|
{
|
||||||
|
char fname[MAXPATHLEN];
|
||||||
|
char *filepath;
|
||||||
|
int done = 0;
|
||||||
|
struct stat filestat;
|
||||||
|
|
||||||
|
/* file path */
|
||||||
|
filepath = (deviceType == TYPE_RECENT) ? history.entries[selection].filepath : fileDir;
|
||||||
|
|
||||||
|
/* full filename */
|
||||||
|
sprintf(fname, "%s%s", filepath, filelist[selection].filename);
|
||||||
|
|
||||||
|
/* retrieve file status */
|
||||||
|
if(stat(fname, &filestat) != 0)
|
||||||
|
{
|
||||||
|
/* only DVD hot swap is supported */
|
||||||
|
if (!strncmp(filepath, rootdir[TYPE_DVD], strlen(rootdir[TYPE_DVD])))
|
||||||
|
{
|
||||||
|
/* mount DVD */
|
||||||
|
if (!MountDVD()) return 0;
|
||||||
|
|
||||||
|
/* retrieve file status */
|
||||||
|
stat(fname, &filestat);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* get file length */
|
||||||
|
int length = filestat.st_size;
|
||||||
|
|
||||||
|
if (length > 0)
|
||||||
|
{
|
||||||
|
/* open file */
|
||||||
|
FILE *fd = fopen(fname, "rb");
|
||||||
|
if (!fd)
|
||||||
|
{
|
||||||
|
GUI_WaitPrompt("Error","Unable to open file !");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read first data chunk */
|
||||||
|
unsigned char temp[FILECHUNK];
|
||||||
|
fread(temp, FILECHUNK, 1, fd);
|
||||||
|
fseek(fd, 0, SEEK_SET);
|
||||||
|
|
||||||
|
/* Determine file type */
|
||||||
|
if (!IsZipFile ((char *) temp))
|
||||||
|
{
|
||||||
|
if (length > MAXROMSIZE)
|
||||||
|
{
|
||||||
|
GUI_WaitPrompt("Error","File is too large !");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* Read file */
|
||||||
|
sprintf((char *)temp,"Loading %d bytes ...", length);
|
||||||
|
GUI_MsgBoxOpen("Information", (char *)temp, 1);
|
||||||
|
while (length > FILECHUNK)
|
||||||
|
{
|
||||||
|
fread(buffer + done, FILECHUNK, 1, fd);
|
||||||
|
length -= FILECHUNK;
|
||||||
|
done += FILECHUNK;
|
||||||
|
}
|
||||||
|
fread(buffer + done, length, 1, fd);
|
||||||
|
done += length;
|
||||||
|
GUI_MsgBoxClose();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* unzip file */
|
||||||
|
done = UnZipBuffer(buffer, fd);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* close file */
|
||||||
|
fclose(fd);
|
||||||
|
|
||||||
|
if (done)
|
||||||
|
{
|
||||||
|
/* add/move the file to the top of the history. */
|
||||||
|
history_add_file(filepath, filelist[selection].filename);
|
||||||
|
|
||||||
|
/* recent file list has changed */
|
||||||
|
if (deviceType == TYPE_RECENT) deviceType = -1;
|
||||||
|
|
||||||
|
/* return loaded size */
|
||||||
|
return done;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/****************************************************************************
|
||||||
|
* OpenDir
|
||||||
|
*
|
||||||
|
* Function to open a directory and load ROM file list.
|
||||||
|
****************************************************************************/
|
||||||
|
int OpenDirectory(int device)
|
||||||
|
{
|
||||||
|
int max = 0;
|
||||||
|
|
||||||
|
if (device == TYPE_RECENT)
|
||||||
|
{
|
||||||
|
/* fetch history list */
|
||||||
|
int i;
|
||||||
|
for(i=0; i < NUM_HISTORY_ENTRIES; i++)
|
||||||
|
{
|
||||||
|
if(history.entries[i].filepath[0] > 0)
|
||||||
|
{
|
||||||
|
filelist[i].flags = 0;
|
||||||
|
strncpy(filelist[i].filename,history.entries[i].filename, MAXJOLIET-1);
|
||||||
|
filelist[i].filename[MAXJOLIET-1] = '\0';
|
||||||
|
max++;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* Found the end of the list. */
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* only DVD hot swap is supported */
|
||||||
|
if (device == TYPE_DVD)
|
||||||
|
{
|
||||||
|
/* try to access root directory */
|
||||||
|
DIR_ITER *dir = diropen(rootdir[TYPE_DVD]);
|
||||||
|
if (dir == NULL)
|
||||||
|
{
|
||||||
|
/* mount DVD */
|
||||||
|
if (!MountDVD()) return 0;
|
||||||
|
deviceType = -1;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
dirclose(dir);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/* parse last directory */
|
||||||
|
fileDir = config.lastdir[device];
|
||||||
|
max = ParseDirectory();
|
||||||
|
if (max <= 0)
|
||||||
|
{
|
||||||
|
/* parse root directory */
|
||||||
|
strcpy(fileDir, rootdir[device]);
|
||||||
|
max = ParseDirectory();
|
||||||
|
if (max < 0)
|
||||||
|
{
|
||||||
|
GUI_WaitPrompt("Error","Unable to open directory !");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
deviceType = -1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (max == 0)
|
||||||
|
{
|
||||||
|
GUI_WaitPrompt("Error","No files found !");
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/* check if device type has changed */
|
||||||
|
if (device != deviceType)
|
||||||
|
{
|
||||||
|
/* reset current device type */
|
||||||
|
deviceType = device;
|
||||||
|
|
||||||
|
/* reset File selector */
|
||||||
|
ClearSelector(max);
|
||||||
|
}
|
||||||
|
|
||||||
|
return 1;
|
||||||
|
}
|
@ -24,18 +24,21 @@
|
|||||||
#ifndef _FILE_FAT_H
|
#ifndef _FILE_FAT_H
|
||||||
#define _FILE_FAT_H
|
#define _FILE_FAT_H
|
||||||
|
|
||||||
#define TYPE_RECENT 0
|
|
||||||
#define TYPE_SD 1
|
#define TYPE_SD (0)
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
#define TYPE_USB 2
|
#define TYPE_USB (1)
|
||||||
|
#define TYPE_DVD (2)
|
||||||
|
#else
|
||||||
|
#define TYPE_DVD (1)
|
||||||
#endif
|
#endif
|
||||||
|
#define TYPE_RECENT (TYPE_DVD + 1)
|
||||||
|
|
||||||
#define FATCHUNK (2048)
|
#define FILECHUNK (2048)
|
||||||
|
|
||||||
extern void FAT_ClearDirectory(void);
|
extern int OpenDirectory(int device);
|
||||||
extern int FAT_UpdateDirectory(bool go_up, char *filename);
|
extern int UpdateDirectory(bool go_up, char *filename);
|
||||||
extern int FAT_ParseDirectory(void);
|
extern int ParseDirectory(void);
|
||||||
extern int FAT_LoadFile(u8* buffer,u32 selection);
|
extern int LoadFile(u8* buffer,u32 selection);
|
||||||
extern int FAT_Open(int type);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
@ -24,8 +24,7 @@
|
|||||||
|
|
||||||
#include "shared.h"
|
#include "shared.h"
|
||||||
#include "file_slot.h"
|
#include "file_slot.h"
|
||||||
#include "file_fat.h"
|
#include "file_load.h"
|
||||||
#include "dvd.h"
|
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
#include "filesel.h"
|
#include "filesel.h"
|
||||||
#include "saveicon.h"
|
#include "saveicon.h"
|
||||||
@ -49,7 +48,6 @@ static int CardMount(int slot)
|
|||||||
int tries = 0;
|
int tries = 0;
|
||||||
#if defined(HW_DOL)
|
#if defined(HW_DOL)
|
||||||
*(unsigned long *) (0xCC006800) |= 1 << 13; /*** Disable Encryption ***/
|
*(unsigned long *) (0xCC006800) |= 1 << 13; /*** Disable Encryption ***/
|
||||||
uselessinquiry ();
|
|
||||||
#elif defined(HW_RVL)
|
#elif defined(HW_RVL)
|
||||||
*(unsigned long *) (0xCD006800) |= 1 << 13; /*** Disable Encryption ***/
|
*(unsigned long *) (0xCD006800) |= 1 << 13; /*** Disable Encryption ***/
|
||||||
#endif
|
#endif
|
||||||
@ -270,11 +268,11 @@ int slot_load(int slot, int device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Read into buffer (2k blocks) */
|
/* Read into buffer (2k blocks) */
|
||||||
while (filesize > FATCHUNK)
|
while (filesize > FILECHUNK)
|
||||||
{
|
{
|
||||||
fread(savebuffer + done, FATCHUNK, 1, fp);
|
fread(savebuffer + done, FILECHUNK, 1, fp);
|
||||||
done += FATCHUNK;
|
done += FILECHUNK;
|
||||||
filesize -= FATCHUNK;
|
filesize -= FILECHUNK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Read remaining bytes */
|
/* Read remaining bytes */
|
||||||
@ -438,11 +436,11 @@ int slot_save(int slot, int device)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* Write from buffer (2k blocks) */
|
/* Write from buffer (2k blocks) */
|
||||||
while (filesize > FATCHUNK)
|
while (filesize > FILECHUNK)
|
||||||
{
|
{
|
||||||
fwrite(savebuffer + done, FATCHUNK, 1, fp);
|
fwrite(savebuffer + done, FILECHUNK, 1, fp);
|
||||||
done += FATCHUNK;
|
done += FILECHUNK;
|
||||||
filesize -= FATCHUNK;
|
filesize -= FILECHUNK;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Write remaining bytes */
|
/* Write remaining bytes */
|
||||||
|
@ -27,9 +27,6 @@
|
|||||||
********************************************************************************/
|
********************************************************************************/
|
||||||
|
|
||||||
#include "shared.h"
|
#include "shared.h"
|
||||||
#include "dvd.h"
|
|
||||||
#include "file_dvd.h"
|
|
||||||
#include "file_fat.h"
|
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -97,7 +94,7 @@ int IsZipFile (char *buffer)
|
|||||||
*
|
*
|
||||||
* It should be noted that there is a limit of 5MB total size for any ROM
|
* It should be noted that there is a limit of 5MB total size for any ROM
|
||||||
******************************************************************************/
|
******************************************************************************/
|
||||||
int UnZipBuffer (unsigned char *outbuffer, u64 discoffset, char *filename)
|
int UnZipBuffer (unsigned char *outbuffer, FILE *fd)
|
||||||
{
|
{
|
||||||
PKZIPHEADER pkzip;
|
PKZIPHEADER pkzip;
|
||||||
int zipoffset = 0;
|
int zipoffset = 0;
|
||||||
@ -107,35 +104,18 @@ int UnZipBuffer (unsigned char *outbuffer, u64 discoffset, char *filename)
|
|||||||
int res;
|
int res;
|
||||||
int bufferoffset = 0;
|
int bufferoffset = 0;
|
||||||
int have = 0;
|
int have = 0;
|
||||||
char readbuffer[2048];
|
char readbuffer[ZIPCHUNK];
|
||||||
char msg[64];
|
char msg[64];
|
||||||
FILE *fatfile = NULL;
|
|
||||||
|
|
||||||
/*** FAT file support ***/
|
|
||||||
if (filename)
|
|
||||||
{
|
|
||||||
fatfile = fopen(filename, "rb");
|
|
||||||
if (fatfile == NULL)
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** Read Zip Header ***/
|
/*** Read Zip Header ***/
|
||||||
if (fatfile)
|
fread(readbuffer, ZIPCHUNK, 1, fd);
|
||||||
{
|
|
||||||
fseek(fatfile, 0, SEEK_SET);
|
|
||||||
fread(readbuffer, 2048, 1, fatfile);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
dvd_read (&readbuffer, 2048, discoffset);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** Copy PKZip header to local, used as info ***/
|
/*** Copy PKZip header to local, used as info ***/
|
||||||
memcpy (&pkzip, &readbuffer, sizeof (PKZIPHEADER));
|
memcpy (&pkzip, &readbuffer, sizeof (PKZIPHEADER));
|
||||||
|
|
||||||
if (FLIP32 (pkzip.uncompressedSize) > MAXROMSIZE)
|
if (FLIP32 (pkzip.uncompressedSize) > MAXROMSIZE)
|
||||||
{
|
{
|
||||||
GUI_WaitPrompt("Error","File size not supported !");
|
GUI_WaitPrompt("Error","File is too large !");
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,24 +174,12 @@ int UnZipBuffer (unsigned char *outbuffer, u64 discoffset, char *filename)
|
|||||||
/*** Readup the next 2k block ***/
|
/*** Readup the next 2k block ***/
|
||||||
zipoffset = 0;
|
zipoffset = 0;
|
||||||
zipchunk = ZIPCHUNK;
|
zipchunk = ZIPCHUNK;
|
||||||
|
fread(readbuffer, ZIPCHUNK, 1, fd);
|
||||||
if (fatfile)
|
|
||||||
{
|
|
||||||
fread(readbuffer, 2048, 1, fatfile);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
discoffset += 2048;
|
|
||||||
dvd_read (&readbuffer, 2048, discoffset);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
while (res != Z_STREAM_END);
|
while (res != Z_STREAM_END);
|
||||||
|
|
||||||
inflateEnd (&zs);
|
inflateEnd (&zs);
|
||||||
|
GUI_MsgBoxClose();
|
||||||
/* close file */
|
|
||||||
if (fatfile)
|
|
||||||
fclose(fatfile);
|
|
||||||
|
|
||||||
if (res == Z_STREAM_END)
|
if (res == Z_STREAM_END)
|
||||||
{
|
{
|
||||||
@ -220,6 +188,7 @@ int UnZipBuffer (unsigned char *outbuffer, u64 discoffset, char *filename)
|
|||||||
else
|
else
|
||||||
return FLIP32 (pkzip.uncompressedSize);
|
return FLIP32 (pkzip.uncompressedSize);
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -30,6 +30,6 @@
|
|||||||
#define _UNZIP_H_
|
#define _UNZIP_H_
|
||||||
|
|
||||||
extern int IsZipFile (char *buffer);
|
extern int IsZipFile (char *buffer);
|
||||||
int UnZipBuffer (unsigned char *outbuffer, u64 discoffset, char *filename);
|
int UnZipBuffer (unsigned char *outbuffer, FILE *fd);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
1189
source/gx/gui/cheats.c
Normal file
32
source/gx/gui/cheats.h
Normal file
@ -0,0 +1,32 @@
|
|||||||
|
/*
|
||||||
|
* cheats.c
|
||||||
|
*
|
||||||
|
* Cheats menu
|
||||||
|
*
|
||||||
|
* Softdev (2006)
|
||||||
|
* Eke-Eke (2010)
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU General Public License as published by
|
||||||
|
* the Free Software Foundation; either version 2 of the License, or
|
||||||
|
* (at your option) any later version.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the Free Software
|
||||||
|
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
||||||
|
*
|
||||||
|
********************************************************************************/
|
||||||
|
|
||||||
|
#ifndef _CHEATS_H
|
||||||
|
#define _CHEATS_H
|
||||||
|
|
||||||
|
extern void CheatMenu(void);
|
||||||
|
extern void CheatLoad(void);
|
||||||
|
extern void CheatUpdate(void);
|
||||||
|
|
||||||
|
#endif
|
@ -1,10 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
* filesel.c
|
* filesel.c
|
||||||
*
|
*
|
||||||
* File Selection menu
|
* ROM File Browser
|
||||||
*
|
*
|
||||||
* Softdev (2006)
|
* Eke-Eke (2009,2010)
|
||||||
* Eke-Eke (2007,2008,2009)
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -24,28 +23,29 @@
|
|||||||
|
|
||||||
#include "shared.h"
|
#include "shared.h"
|
||||||
#include "filesel.h"
|
#include "filesel.h"
|
||||||
#include "menu.h"
|
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
#include "file_dvd.h"
|
#include "file_load.h"
|
||||||
#include "file_fat.h"
|
|
||||||
#include "file_slot.h"
|
#include "file_slot.h"
|
||||||
|
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
#include <wiiuse/wpad.h>
|
#include <wiiuse/wpad.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#define PAGESIZE 11
|
#define BG_COLOR_1 {0x49,0x49,0x49,0xff}
|
||||||
#define PAGEOFFSET 120
|
#define BG_COLOR_2 {0x66,0x66,0x66,0xff}
|
||||||
|
|
||||||
|
extern const u8 Browser_dir_png[];
|
||||||
|
extern const u8 Snap_empty_png[];
|
||||||
|
extern const u8 Snap_frame_png[];
|
||||||
|
|
||||||
FILEENTRIES filelist[MAXFILES];
|
FILEENTRIES filelist[MAXFILES];
|
||||||
|
|
||||||
static int offset = 0;
|
static int offset = 0;
|
||||||
static int selection = 0;
|
static int selection = 0;
|
||||||
static int old_selection = 0;
|
|
||||||
static int old_offset = 0;
|
|
||||||
static int maxfiles = 0;
|
static int maxfiles = 0;
|
||||||
static int string_offset = 0;
|
static int string_offset = 0;
|
||||||
|
static char prev_folder[MAXJOLIET];
|
||||||
static void selector_cb(void);
|
static void selector_cb(void);
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -93,8 +93,8 @@ static gui_image bg_filesel[10] =
|
|||||||
{NULL,Banner_top_png,IMAGE_VISIBLE,0,0,640,108,255},
|
{NULL,Banner_top_png,IMAGE_VISIBLE,0,0,640,108,255},
|
||||||
{NULL,Banner_bottom_png,IMAGE_VISIBLE,0,380,640,100,255},
|
{NULL,Banner_bottom_png,IMAGE_VISIBLE,0,380,640,100,255},
|
||||||
{NULL,Main_logo_png,IMAGE_VISIBLE,466,40,152,44,255},
|
{NULL,Main_logo_png,IMAGE_VISIBLE,466,40,152,44,255},
|
||||||
{NULL,Frame_s1_png,IMAGE_VISIBLE,8,70,372,336,150},
|
{NULL,Frame_s1_png,IMAGE_VISIBLE,8,70,372,336,152},
|
||||||
{NULL,Frame_s2_png,0,384,264,248,140,200},
|
{NULL,Frame_s2_png,0,384,264,248,140,152},
|
||||||
{NULL,Snap_empty_png,IMAGE_VISIBLE,422,114,164,116,255},
|
{NULL,Snap_empty_png,IMAGE_VISIBLE,422,114,164,116,255},
|
||||||
{NULL,NULL,0,424,116,160,112,255},
|
{NULL,NULL,0,424,116,160,112,255},
|
||||||
{NULL,Snap_frame_png,IMAGE_VISIBLE,388,112,236,148,255}
|
{NULL,Snap_frame_png,IMAGE_VISIBLE,388,112,236,148,255}
|
||||||
@ -103,7 +103,7 @@ static gui_image bg_filesel[10] =
|
|||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* GUI Descriptor */
|
/* GUI Descriptor */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
static gui_menu menu_browser =
|
static gui_menu menu_selector =
|
||||||
{
|
{
|
||||||
"Game Selection",
|
"Game Selection",
|
||||||
-1,-1,
|
-1,-1,
|
||||||
@ -116,46 +116,12 @@ static gui_menu menu_browser =
|
|||||||
selector_cb
|
selector_cb
|
||||||
};
|
};
|
||||||
|
|
||||||
/***************************************************************************
|
|
||||||
* FileSortCallback (Marty Disibio)
|
|
||||||
*
|
|
||||||
* Quick sort callback to sort file entries with the following order:
|
|
||||||
* .
|
|
||||||
* ..
|
|
||||||
* <dirs>
|
|
||||||
* <files>
|
|
||||||
***************************************************************************/
|
|
||||||
int FileSortCallback(const void *f1, const void *f2)
|
|
||||||
{
|
|
||||||
/* Special case for implicit directories */
|
|
||||||
if(((FILEENTRIES *)f1)->filename[0] == '.' || ((FILEENTRIES *)f2)->filename[0] == '.')
|
|
||||||
{
|
|
||||||
if(strcmp(((FILEENTRIES *)f1)->filename, ".") == 0) { return -1; }
|
|
||||||
if(strcmp(((FILEENTRIES *)f2)->filename, ".") == 0) { return 1; }
|
|
||||||
if(strcmp(((FILEENTRIES *)f1)->filename, "..") == 0) { return -1; }
|
|
||||||
if(strcmp(((FILEENTRIES *)f2)->filename, "..") == 0) { return 1; }
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If one is a file and one is a directory the directory is first. */
|
|
||||||
if(((FILEENTRIES *)f1)->flags == 1 && ((FILEENTRIES *)f2)->flags == 0) return -1;
|
|
||||||
if(((FILEENTRIES *)f1)->flags == 0 && ((FILEENTRIES *)f2)->flags == 1) return 1;
|
|
||||||
|
|
||||||
return stricmp(((FILEENTRIES *)f1)->filename, ((FILEENTRIES *)f2)->filename);
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* FileSelector
|
|
||||||
*
|
|
||||||
* Let user select a file from the File listing
|
|
||||||
..* ROM file buffer is provided as input
|
|
||||||
* ROM size is returned
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
static void selector_cb(void)
|
static void selector_cb(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
char text[MAXPATHLEN];
|
char text[MAXPATHLEN];
|
||||||
int yoffset = PAGEOFFSET;
|
int yoffset = 108;
|
||||||
|
|
||||||
/* Initialize directory icon */
|
/* Initialize directory icon */
|
||||||
gui_image dir_icon;
|
gui_image dir_icon;
|
||||||
@ -163,18 +129,30 @@ static void selector_cb(void)
|
|||||||
dir_icon.w = dir_icon.texture->width;
|
dir_icon.w = dir_icon.texture->width;
|
||||||
dir_icon.h = dir_icon.texture->height;
|
dir_icon.h = dir_icon.texture->height;
|
||||||
dir_icon.x = 26;
|
dir_icon.x = 26;
|
||||||
dir_icon.y = PAGEOFFSET;
|
dir_icon.y = (26 - dir_icon.h)/2;
|
||||||
|
|
||||||
/* Initialize selection bar */
|
/* Initialize selection bar */
|
||||||
gui_image bar_over;
|
gui_image bar_over;
|
||||||
bar_over.texture = gxTextureOpenPNG(Overlay_bar_png,0);
|
bar_over.texture = gxTextureOpenPNG(Overlay_bar_png,0);
|
||||||
bar_over.w = bar_over.texture->width;
|
bar_over.w = bar_over.texture->width;
|
||||||
bar_over.h = bar_over.texture->height;
|
bar_over.h = bar_over.texture->height;
|
||||||
bar_over.x = 22;
|
bar_over.x = 16;
|
||||||
bar_over.y = -(bar_over.h - dir_icon.h)/2;
|
bar_over.y = (26 - bar_over.h)/2;
|
||||||
|
|
||||||
|
/* 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 */
|
/* Draw Files list */
|
||||||
for (i = offset; i < (offset + PAGESIZE) && (i < maxfiles); i++)
|
for (i = offset; (i < (offset + 10)) && (i < maxfiles); i++)
|
||||||
{
|
{
|
||||||
if (i == selection)
|
if (i == selection)
|
||||||
{
|
{
|
||||||
@ -183,14 +161,26 @@ static void selector_cb(void)
|
|||||||
|
|
||||||
/* scrolling text */
|
/* scrolling text */
|
||||||
if ((string_offset/10) >= strlen(filelist[i].filename))
|
if ((string_offset/10) >= strlen(filelist[i].filename))
|
||||||
|
{
|
||||||
string_offset = 0;
|
string_offset = 0;
|
||||||
sprintf(text, "%s ",filelist[i].filename + string_offset/10);
|
}
|
||||||
|
|
||||||
|
if (string_offset)
|
||||||
|
{
|
||||||
|
sprintf(text,"%s ",filelist[i].filename+string_offset/10);
|
||||||
strncat(text, filelist[i].filename, string_offset/10);
|
strncat(text, filelist[i].filename, string_offset/10);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
strcpy(text, filelist[i].filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* print text */
|
||||||
if (filelist[i].flags)
|
if (filelist[i].flags)
|
||||||
{
|
{
|
||||||
/* directory icon */
|
/* directory icon */
|
||||||
gxDrawTexture(dir_icon.texture,dir_icon.x-1,yoffset-1,dir_icon.w+2,dir_icon.h+2,255);
|
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+16,bar_over.w-dir_icon.w-14,(GXColor)WHITE))
|
if (FONT_write(text,18,dir_icon.x+dir_icon.w+6,yoffset+22,bar_over.w-dir_icon.w-26,(GXColor)WHITE))
|
||||||
{
|
{
|
||||||
/* string is too large -> scroll text */
|
/* string is too large -> scroll text */
|
||||||
string_offset ++;
|
string_offset ++;
|
||||||
@ -198,7 +188,7 @@ static void selector_cb(void)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (FONT_write(text,18,dir_icon.x,yoffset+16,bar_over.w-8,(GXColor)WHITE))
|
if (FONT_write(text,18,dir_icon.x,yoffset+22,bar_over.w-20,(GXColor)WHITE))
|
||||||
{
|
{
|
||||||
/* text scrolling */
|
/* text scrolling */
|
||||||
string_offset ++;
|
string_offset ++;
|
||||||
@ -210,16 +200,16 @@ static void selector_cb(void)
|
|||||||
if (filelist[i].flags)
|
if (filelist[i].flags)
|
||||||
{
|
{
|
||||||
/* directory icon */
|
/* directory icon */
|
||||||
gxDrawTexture(dir_icon.texture,dir_icon.x,yoffset,dir_icon.w,dir_icon.h,255);
|
gxDrawTexture(dir_icon.texture,dir_icon.x,yoffset+dir_icon.y,dir_icon.w,dir_icon.h,255);
|
||||||
FONT_write(filelist[i].filename,16,dir_icon.x+dir_icon.w+6,yoffset+16,bar_over.w-dir_icon.w-14,(GXColor)WHITE);
|
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
|
else
|
||||||
{
|
{
|
||||||
FONT_write(filelist[i].filename,16,dir_icon.x,yoffset+16,bar_over.w-8,(GXColor)WHITE);
|
FONT_write(filelist[i].filename,18,dir_icon.x,yoffset+22,bar_over.w-20,(GXColor)WHITE);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
yoffset += 22;
|
yoffset += 26;
|
||||||
}
|
}
|
||||||
|
|
||||||
gxTextureClose(&bar_over.texture);
|
gxTextureClose(&bar_over.texture);
|
||||||
@ -227,19 +217,26 @@ static void selector_cb(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int FileSelector(unsigned char *buffer, bool useFAT)
|
/****************************************************************************
|
||||||
|
* FileSelector
|
||||||
|
*
|
||||||
|
* Browse directories and select a file from the file listing
|
||||||
|
* return ROM size
|
||||||
|
*
|
||||||
|
****************************************************************************/
|
||||||
|
int FileSelector(void)
|
||||||
{
|
{
|
||||||
short p;
|
short p;
|
||||||
int ret;
|
int i;
|
||||||
int size = 0;
|
int size = 0;
|
||||||
int go_up = 0;
|
|
||||||
int old = -1;
|
int old = -1;
|
||||||
char fname[MAXPATHLEN];
|
char fname[MAXPATHLEN];
|
||||||
char text[MAXPATHLEN];
|
char text[MAXPATHLEN];
|
||||||
FILE *xml,*snap;
|
FILE *xml,*snap;
|
||||||
|
gui_menu *m = &menu_selector;
|
||||||
|
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
int x,y,i,yoffset;
|
int x,y;
|
||||||
gui_butn *button;
|
gui_butn *button;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -247,8 +244,7 @@ int FileSelector(unsigned char *buffer, bool useFAT)
|
|||||||
if (config.bg_type > 0)
|
if (config.bg_type > 0)
|
||||||
{
|
{
|
||||||
bg_filesel[0].state &= ~IMAGE_REPEAT;
|
bg_filesel[0].state &= ~IMAGE_REPEAT;
|
||||||
if (config.bg_type > 1) bg_filesel[0].data = Bg_main_png;
|
bg_filesel[0].data = (config.bg_type > 1) ? Bg_main_png : Bg_main_2_png;
|
||||||
else bg_filesel[0].data = Bg_main_2_png;
|
|
||||||
bg_filesel[0].x = 374;
|
bg_filesel[0].x = 374;
|
||||||
bg_filesel[0].y = 140;
|
bg_filesel[0].y = 140;
|
||||||
bg_filesel[0].w = 284;
|
bg_filesel[0].w = 284;
|
||||||
@ -265,11 +261,16 @@ int FileSelector(unsigned char *buffer, bool useFAT)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* background overlay */
|
/* background overlay */
|
||||||
if (config.bg_overlay) bg_filesel[1].state |= IMAGE_VISIBLE;
|
if (config.bg_overlay)
|
||||||
else bg_filesel[1].state &= ~IMAGE_VISIBLE;
|
{
|
||||||
|
bg_filesel[1].state |= IMAGE_VISIBLE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
bg_filesel[1].state &= ~IMAGE_VISIBLE;
|
||||||
|
}
|
||||||
|
|
||||||
/* Initialize Menu */
|
/* Initialize Menu */
|
||||||
gui_menu *m = &menu_browser;
|
|
||||||
GUI_InitMenu(m);
|
GUI_InitMenu(m);
|
||||||
string_offset = 0;
|
string_offset = 0;
|
||||||
|
|
||||||
@ -321,18 +322,15 @@ int FileSelector(unsigned char *buffer, bool useFAT)
|
|||||||
/* out of focus */
|
/* out of focus */
|
||||||
strcpy(action_select.comment,"");
|
strcpy(action_select.comment,"");
|
||||||
}
|
}
|
||||||
else if (!filelist[selection].flags)
|
else if (filelist[selection].flags)
|
||||||
{
|
{
|
||||||
/* this is a file */
|
/* this is a directory */
|
||||||
strcpy(action_select.comment,"Load ROM File");
|
strcpy(action_select.comment,"Open Directory");
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* this is a directory */
|
/* this is a file */
|
||||||
if (!strcmp(filelist[selection].filename,".."))
|
strcpy(action_select.comment,"Load ROM File");
|
||||||
strcpy(action_select.comment,"Previous Directory");
|
|
||||||
else
|
|
||||||
strcpy(action_select.comment,"Open Directory");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Draw menu*/
|
/* Draw menu*/
|
||||||
@ -356,19 +354,22 @@ int FileSelector(unsigned char *buffer, bool useFAT)
|
|||||||
/* draw wiimote pointer */
|
/* 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);
|
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 */
|
/* find selected item */
|
||||||
yoffset = PAGEOFFSET - 4;
|
selection = (y - 108) / 26;
|
||||||
m->selected = m->max_buttons + 2;
|
if (selection > 9) selection = 9;
|
||||||
for (i = offset; i < (offset + PAGESIZE) && (i < maxfiles); i++)
|
selection += offset;
|
||||||
{
|
if (selection >= maxfiles) selection = old;
|
||||||
if ((x<=380)&&(y>=yoffset)&&(y<(yoffset+24)))
|
|
||||||
{
|
/* reset selection */
|
||||||
selection = i;
|
|
||||||
m->selected = -1;
|
m->selected = -1;
|
||||||
break;
|
|
||||||
}
|
|
||||||
yoffset += 24;
|
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
/* disable selection */
|
||||||
|
m->selected = m->max_buttons + 2;
|
||||||
|
|
||||||
/* find selected button */
|
/* find selected button */
|
||||||
for (i=0; i<2; i++)
|
for (i=0; i<2; i++)
|
||||||
@ -387,9 +388,10 @@ int FileSelector(unsigned char *buffer, bool useFAT)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* reset indicator */
|
/* reset selection */
|
||||||
m->selected = -1;
|
m->selected = -1;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
@ -405,8 +407,8 @@ int FileSelector(unsigned char *buffer, bool useFAT)
|
|||||||
selection++;
|
selection++;
|
||||||
if (selection == maxfiles)
|
if (selection == maxfiles)
|
||||||
selection = offset = 0;
|
selection = offset = 0;
|
||||||
if ((selection - offset) >= PAGESIZE)
|
if ((selection - offset) >= 10)
|
||||||
offset += PAGESIZE;
|
offset += 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* highlight previous item */
|
/* highlight previous item */
|
||||||
@ -416,10 +418,10 @@ int FileSelector(unsigned char *buffer, bool useFAT)
|
|||||||
if (selection < 0)
|
if (selection < 0)
|
||||||
{
|
{
|
||||||
selection = maxfiles - 1;
|
selection = maxfiles - 1;
|
||||||
offset = selection - PAGESIZE + 1;
|
offset = selection - 10 + 1;
|
||||||
}
|
}
|
||||||
if (selection < offset)
|
if (selection < offset)
|
||||||
offset -= PAGESIZE;
|
offset -= 10;
|
||||||
if (offset < 0)
|
if (offset < 0)
|
||||||
offset = 0;
|
offset = 0;
|
||||||
}
|
}
|
||||||
@ -427,14 +429,14 @@ int FileSelector(unsigned char *buffer, bool useFAT)
|
|||||||
/* go back one page */
|
/* go back one page */
|
||||||
else if (p & PAD_TRIGGER_L)
|
else if (p & PAD_TRIGGER_L)
|
||||||
{
|
{
|
||||||
selection -= PAGESIZE;
|
selection -= 10;
|
||||||
if (selection < 0)
|
if (selection < 0)
|
||||||
{
|
{
|
||||||
selection = maxfiles - 1;
|
selection = maxfiles - 1;
|
||||||
offset = selection - PAGESIZE + 1;
|
offset = selection - 10 + 1;
|
||||||
}
|
}
|
||||||
if (selection < offset)
|
if (selection < offset)
|
||||||
offset -= PAGESIZE;
|
offset -= 10;
|
||||||
if (offset < 0)
|
if (offset < 0)
|
||||||
offset = 0;
|
offset = 0;
|
||||||
}
|
}
|
||||||
@ -442,11 +444,11 @@ int FileSelector(unsigned char *buffer, bool useFAT)
|
|||||||
/* go forward one page */
|
/* go forward one page */
|
||||||
else if (p & PAD_TRIGGER_R)
|
else if (p & PAD_TRIGGER_R)
|
||||||
{
|
{
|
||||||
selection += PAGESIZE;
|
selection += 10;
|
||||||
if (selection > maxfiles - 1)
|
if (selection > maxfiles - 1)
|
||||||
selection = offset = 0;
|
selection = offset = 0;
|
||||||
if ((selection - offset) >= PAGESIZE)
|
if ((selection - offset) >= 10)
|
||||||
offset += PAGESIZE;
|
offset += 10;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* quit */
|
/* quit */
|
||||||
@ -456,111 +458,106 @@ int FileSelector(unsigned char *buffer, bool useFAT)
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* open selected file or directory */
|
/* previous directory */
|
||||||
else if ((p & PAD_BUTTON_A) || (p & PAD_BUTTON_B))
|
else if (p & PAD_BUTTON_B)
|
||||||
{
|
{
|
||||||
string_offset = 0;
|
string_offset = 0;
|
||||||
go_up = 0;
|
|
||||||
|
|
||||||
if (p & PAD_BUTTON_B)
|
/* update browser directory (and get current folder)*/
|
||||||
|
if (UpdateDirectory(1, prev_folder))
|
||||||
{
|
{
|
||||||
/* go up one directory or quit */
|
|
||||||
go_up = 1;
|
|
||||||
selection = 0;
|
|
||||||
}
|
|
||||||
#ifdef HW_RVL
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* arrow buttons selected */
|
|
||||||
if (m->selected == m->max_buttons) /* up arrow */
|
|
||||||
{
|
|
||||||
selection--;
|
|
||||||
if (selection < 0)
|
|
||||||
{
|
|
||||||
selection = maxfiles - 1;
|
|
||||||
offset = selection - PAGESIZE + 1;
|
|
||||||
}
|
|
||||||
if (selection < offset)
|
|
||||||
offset -= PAGESIZE;
|
|
||||||
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) >= PAGESIZE)
|
|
||||||
offset += PAGESIZE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* ensure we are in focus area */
|
|
||||||
if (go_up || (m->selected < m->max_buttons))
|
|
||||||
{
|
|
||||||
if (go_up || filelist[selection].flags)
|
|
||||||
{
|
|
||||||
/* get new directory */
|
|
||||||
if (useFAT)
|
|
||||||
ret = FAT_UpdateDirectory(go_up,filelist[selection].filename);
|
|
||||||
else
|
|
||||||
ret = DVD_UpdateDirectory(go_up,filelist[selection].offset,filelist[selection].length);
|
|
||||||
|
|
||||||
/* get new entry list or quit */
|
|
||||||
if (ret)
|
|
||||||
{
|
|
||||||
/* reinit selector (previous value is saved for one level) */
|
|
||||||
if (selection == 0)
|
|
||||||
{
|
|
||||||
selection = old_selection;
|
|
||||||
offset = old_offset;
|
|
||||||
old_selection = 0;
|
|
||||||
old_offset = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
/* save current selector value */
|
|
||||||
old_selection = selection;
|
|
||||||
old_offset = offset;
|
|
||||||
selection = 0;
|
|
||||||
offset = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* get directory entries */
|
/* get directory entries */
|
||||||
if (useFAT)
|
maxfiles = ParseDirectory();
|
||||||
maxfiles = FAT_ParseDirectory();
|
|
||||||
else
|
/* clear selection by default */
|
||||||
maxfiles = DVD_ParseDirectory();
|
selection = offset = 0;
|
||||||
|
|
||||||
|
/* select previous directory */
|
||||||
|
for (i=0; i<maxfiles; i++)
|
||||||
|
{
|
||||||
|
if (filelist[i].flags && !strcmp(prev_folder,filelist[i].filename))
|
||||||
|
{
|
||||||
|
selection = i;
|
||||||
|
offset = (i / 10) * 10;
|
||||||
|
i = maxfiles;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
/* exit */
|
||||||
GUI_DeleteMenu(m);
|
GUI_DeleteMenu(m);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* open selected file or directory */
|
||||||
|
else if (p & PAD_BUTTON_A)
|
||||||
|
{
|
||||||
|
string_offset = 0;
|
||||||
|
|
||||||
|
#ifdef HW_RVL
|
||||||
|
/* arrow buttons selected */
|
||||||
|
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
|
||||||
|
|
||||||
|
/* 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;
|
||||||
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
/* Load ROM file from device */
|
/* clear existing patches before loading new ROM file */
|
||||||
if (useFAT)
|
ggenie_shutdown();
|
||||||
size = FAT_LoadFile(buffer,selection);
|
areplay_shutdown();
|
||||||
else
|
|
||||||
size = DVD_LoadFile(buffer,selection);
|
|
||||||
|
|
||||||
/* Exit menu */
|
/* load ROM file from device */
|
||||||
GUI_MsgBoxClose();
|
size = LoadFile(cart.rom, selection);
|
||||||
|
|
||||||
|
/* exit menu */
|
||||||
GUI_DeleteMenu(m);
|
GUI_DeleteMenu(m);
|
||||||
|
|
||||||
/* Init emulation */
|
/* load new game */
|
||||||
if (size)
|
if (size)
|
||||||
{
|
{
|
||||||
|
/* save previous game state */
|
||||||
if (config.s_auto & 2)
|
if (config.s_auto & 2)
|
||||||
|
{
|
||||||
slot_autosave(config.s_default,config.s_device);
|
slot_autosave(config.s_default,config.s_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* reinitialize emulation */
|
||||||
reloadrom(size,filelist[selection].filename);
|
reloadrom(size,filelist[selection].filename);
|
||||||
if (config.s_auto & 1)
|
|
||||||
slot_autoload(0,config.s_device);
|
|
||||||
if (config.s_auto & 2)
|
|
||||||
slot_autoload(config.s_default,config.s_device);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return size;
|
return size;
|
||||||
@ -575,6 +572,4 @@ void ClearSelector(u32 max)
|
|||||||
maxfiles = max;
|
maxfiles = max;
|
||||||
offset = 0;
|
offset = 0;
|
||||||
selection = 0;
|
selection = 0;
|
||||||
old_offset = 0;
|
|
||||||
old_selection = 0;
|
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
/*
|
/*
|
||||||
* filesel.c
|
* filesel.c
|
||||||
*
|
*
|
||||||
* File Selection menu
|
* ROM File Browser
|
||||||
*
|
*
|
||||||
* Softdev (2006)
|
* Eke-Eke (2009,2010)
|
||||||
* Eke-Eke (2007,2008,2009)
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -31,15 +30,12 @@
|
|||||||
/* Filelist structure */
|
/* Filelist structure */
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
u64 offset;
|
|
||||||
u32 length;
|
|
||||||
char flags;
|
char flags;
|
||||||
char filename[MAXJOLIET];
|
char filename[MAXJOLIET];
|
||||||
}FILEENTRIES;
|
}FILEENTRIES;
|
||||||
|
|
||||||
/* Globals */
|
/* Globals */
|
||||||
extern int FileSelector(unsigned char *buffer, bool useFAT);
|
extern int FileSelector(void);
|
||||||
extern int FileSortCallback(const void *f1, const void *f2);
|
|
||||||
extern void ClearSelector(u32 max);
|
extern void ClearSelector(u32 max);
|
||||||
extern FILEENTRIES filelist[MAXFILES];
|
extern FILEENTRIES filelist[MAXFILES];
|
||||||
|
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* font.c
|
* font.c
|
||||||
*
|
*
|
||||||
* IPL font engine
|
* IPL font engine (using GX rendering)
|
||||||
*
|
*
|
||||||
* original font support by Softdev (2006)
|
* Eke-Eke (2009,2010)
|
||||||
* GX rendering by Eke-Eke (2008,2009)
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -24,7 +23,6 @@
|
|||||||
|
|
||||||
#include "shared.h"
|
#include "shared.h"
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
#include "menu.h"
|
|
||||||
|
|
||||||
#define _SHIFTR(v, s, w) \
|
#define _SHIFTR(v, s, w) \
|
||||||
((u32)(((u32)(v) >> (s)) & ((0x01 << (w)) - 1)))
|
((u32)(((u32)(v) >> (s)) & ((0x01 << (w)) - 1)))
|
||||||
@ -296,124 +294,79 @@ int FONT_write(char *string, int size, int x, int y, int max_width, GXColor colo
|
|||||||
y -= (vmode->efbHeight / 2);
|
y -= (vmode->efbHeight / 2);
|
||||||
int w, ox = x;
|
int w, ox = x;
|
||||||
|
|
||||||
while (*string)
|
while (*string && (*string != '\n'))
|
||||||
{
|
{
|
||||||
w = (font_size[(u8)*string] * size) / fheight;
|
w = (font_size[(u8)*string] * size) / fheight;
|
||||||
if ((x + w) <= (ox + max_width))
|
if ((x + w) > (ox + max_width)) return strlen(string);
|
||||||
{
|
|
||||||
DrawChar(*string, x, y, size,color);
|
DrawChar(*string, x, y, size,color);
|
||||||
x += w;
|
x += w;
|
||||||
string++;
|
string++;
|
||||||
}
|
}
|
||||||
else return 1;
|
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
void FONT_writeCenter(char *string, int size, int x1, int x2, int y, GXColor color)
|
|
||||||
{
|
|
||||||
int i=0;
|
|
||||||
u16 width = 0;
|
|
||||||
|
|
||||||
while (string[i] && (string[i] != '\n'))
|
|
||||||
width += (font_size[(u8)string[i++]] * size) / fheight;
|
|
||||||
|
|
||||||
int x = x1 + (x2 - x1 - width - vmode->fbWidth) / 2;
|
|
||||||
y -= (vmode->efbHeight / 2);
|
|
||||||
|
|
||||||
while (*string && (*string != '\n'))
|
|
||||||
{
|
|
||||||
DrawChar(*string, x, y, size,color);
|
|
||||||
x += (font_size[(u8)*string++] * size) / fheight;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (*string == '\n')
|
if (*string == '\n')
|
||||||
{
|
{
|
||||||
string++;
|
string++;
|
||||||
i = 0;
|
return FONT_write(string, size, ox + (vmode->fbWidth / 2), y + size + (vmode->efbHeight / 2), max_width, color);
|
||||||
width = 0;
|
|
||||||
while (string[i])
|
|
||||||
width += (font_size[(u8)string[i++]] * size) / fheight;
|
|
||||||
x = x1 + (x2 - x1 - width - vmode->fbWidth) / 2;
|
|
||||||
y += size;
|
|
||||||
while (*string)
|
|
||||||
{
|
|
||||||
DrawChar(*string, x, y, size,color);
|
|
||||||
x += (font_size[(u8)*string++] * size) / fheight;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
void FONT_alignRight(char *string, int size, int x, int y, GXColor color)
|
int FONT_writeCenter(char *string, int size, int x1, int x2, int y, GXColor color)
|
||||||
{
|
{
|
||||||
int i;
|
int i=0;
|
||||||
u16 width = 0;
|
int w = 0;
|
||||||
|
while (string[i] && (string[i] != '\n'))
|
||||||
|
{
|
||||||
|
w += (font_size[(u8)string[i++]] * size) / fheight;
|
||||||
|
}
|
||||||
|
|
||||||
for (i=0; i<strlen(string); i++)
|
if ((x1 + w) > x2) w = x2 - x1;
|
||||||
width += (font_size[(u8)string[i]] * size) / fheight;
|
int x = x1 + (x2 - x1 - w - vmode->fbWidth) / 2;
|
||||||
|
|
||||||
x -= (vmode->fbWidth / 2) + width;
|
|
||||||
y -= (vmode->efbHeight / 2);
|
y -= (vmode->efbHeight / 2);
|
||||||
|
x2 -= (vmode->fbWidth / 2);
|
||||||
|
|
||||||
while (*string)
|
while (*string && (*string != '\n'))
|
||||||
{
|
{
|
||||||
|
w = (font_size[(u8)*string] * size) / fheight;
|
||||||
|
if ((x + w) > x2) return strlen(string);
|
||||||
DrawChar(*string, x, y, size,color);
|
DrawChar(*string, x, y, size,color);
|
||||||
x += (font_size[(u8)*string++] * size) / fheight;
|
x += w;
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Write functions (OLD)
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
void write_font(int x, int y, char *string)
|
|
||||||
{
|
|
||||||
int ox = x;
|
|
||||||
while (*string && (x < (ox + 640)))
|
|
||||||
{
|
|
||||||
DrawChar(*string, x -(vmode->fbWidth/2), y-(vmode->efbHeight/2),fontHeader->cell_height,(GXColor)WHITE);
|
|
||||||
x += font_size[(u8)*string];
|
|
||||||
string++;
|
string++;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
void WriteCentre( int y, char *string)
|
if (*string == '\n')
|
||||||
{
|
|
||||||
int x, t;
|
|
||||||
for (x=t=0; t<strlen(string); t++) x += font_size[(u8)string[t]];
|
|
||||||
if (x>640) x=640;
|
|
||||||
x = (640 - x) >> 1;
|
|
||||||
write_font(x, y, string);
|
|
||||||
}
|
|
||||||
|
|
||||||
void WriteCentre_HL( int y, char *string)
|
|
||||||
{
|
|
||||||
gx_texture *texture = gxTextureOpenPNG(Overlay_bar_png,0);
|
|
||||||
if (texture)
|
|
||||||
{
|
{
|
||||||
gxDrawTexture(texture, 0, y-fheight, 640, fheight,240);
|
string++;
|
||||||
if (texture->data) free(texture->data);
|
return FONT_writeCenter(string, size, x1, x2 + (vmode->fbWidth / 2), y + size + (vmode->efbHeight / 2), color);
|
||||||
free(texture);
|
|
||||||
}
|
}
|
||||||
WriteCentre(y, string);
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/****************************************************************************
|
int FONT_alignRight(char *string, int size, int x, int y, GXColor color)
|
||||||
* Draw functions (FrameBuffer)
|
|
||||||
*
|
|
||||||
****************************************************************************/
|
|
||||||
static void fntDrawHLine (int x1, int x2, int y, int color)
|
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
y = 320 * y;
|
int w = 0;
|
||||||
x1 >>= 1;
|
|
||||||
x2 >>= 1;
|
|
||||||
for (i = x1; i <= x2; i++) xfb[whichfb][y + i] = color;
|
|
||||||
}
|
|
||||||
|
|
||||||
void fntDrawBoxFilled (int x1, int y1, int x2, int y2, int color)
|
x -= (vmode->fbWidth / 2);
|
||||||
{
|
y -= (vmode->efbHeight / 2);
|
||||||
int h;
|
|
||||||
for (h = y1; h <= y2; h++) fntDrawHLine (x1, x2, h, color);
|
int ox = x;
|
||||||
|
|
||||||
|
for (i=0; i<strlen(string); i++)
|
||||||
|
{
|
||||||
|
w += (font_size[(u8)string[i]] * size) / fheight;
|
||||||
|
}
|
||||||
|
|
||||||
|
x = ox - w;
|
||||||
|
|
||||||
|
while (*string)
|
||||||
|
{
|
||||||
|
w = (font_size[(u8)*string] * size) / fheight;
|
||||||
|
if ((x + w) > ox) return strlen(string);
|
||||||
|
DrawChar(*string, x, y, size,color);
|
||||||
|
x += w;
|
||||||
|
string++;
|
||||||
|
}
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
/*****************************************************************************
|
/*****************************************************************************
|
||||||
* font.c
|
* font.c
|
||||||
*
|
*
|
||||||
* IPL Font Engine, powered by GX hardware
|
* IPL font engine (using GX rendering)
|
||||||
*
|
*
|
||||||
* Softdev (2006)
|
* Eke-Eke (2009,2010)
|
||||||
* Eke-Eke (2007,2008,2009)
|
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -28,15 +27,7 @@
|
|||||||
extern int FONT_Init(void);
|
extern int FONT_Init(void);
|
||||||
extern void FONT_Shutdown(void);
|
extern void FONT_Shutdown(void);
|
||||||
extern int FONT_write(char *string, int size, int x, int y, int max_width, GXColor color);
|
extern int FONT_write(char *string, int size, int x, int y, int max_width, GXColor color);
|
||||||
extern void FONT_writeCenter(char *string, int size, int x1, int x2, int y, GXColor color);
|
extern int FONT_writeCenter(char *string, int size, int x1, int x2, int y, GXColor color);
|
||||||
extern void FONT_alignRight(char *string, int size, int x, int y, GXColor color);
|
extern int FONT_alignRight(char *string, int size, int x, int y, GXColor color);
|
||||||
|
|
||||||
extern void WriteCentre_HL( int y, char *string);
|
|
||||||
extern void WriteCentre (int y, char *string);
|
|
||||||
extern void write_font (int x, int y, char *string);
|
|
||||||
extern void WriteText(char *text, int size, int x, int y);
|
|
||||||
extern void fntDrawBoxFilled (int x1, int y1, int x2, int y2, int color);
|
|
||||||
extern int fheight;
|
|
||||||
extern u8 font_size[256];
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
@ -1,345 +0,0 @@
|
|||||||
/****************************************************************************
|
|
||||||
* ggentry.c
|
|
||||||
*
|
|
||||||
* Genesis Plus GX Game Genie
|
|
||||||
*
|
|
||||||
* Softdev (2006)
|
|
||||||
* Eke-Eke (2007,2008,2009)
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU General Public License as published by
|
|
||||||
* the Free Software Foundation; either version 2 of the License, or
|
|
||||||
* (at your option) any later version.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the Free Software
|
|
||||||
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
|
|
||||||
*
|
|
||||||
***************************************************************************/
|
|
||||||
|
|
||||||
#include "shared.h"
|
|
||||||
#include "font.h"
|
|
||||||
#include "gui.h"
|
|
||||||
|
|
||||||
#define MAXCODES 8
|
|
||||||
|
|
||||||
typedef struct
|
|
||||||
{
|
|
||||||
int address;
|
|
||||||
unsigned short data;
|
|
||||||
} GGPATCH;
|
|
||||||
|
|
||||||
/*** Game Genie Codes Array ***/
|
|
||||||
unsigned char ggcodes[MAXCODES][10]; /*** Codes are entered as XXXX-XXXX ***/
|
|
||||||
int gghpos[MAXCODES]; /*** Edit positions ***/
|
|
||||||
int ggrow = 0;
|
|
||||||
int editing = 0;
|
|
||||||
char ggvalidchars[] = "ABCDEFGHJKLMNPRSTVWXYZ0123456789*";
|
|
||||||
GGPATCH ggpatch[8];
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* Decode Game Genie entries to memory patches
|
|
||||||
****************************************************************************/
|
|
||||||
void decode_genie (char *code, int which)
|
|
||||||
{
|
|
||||||
char *p;
|
|
||||||
int n, i;
|
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
/*** This should only happen if memory is corrupt! ***/
|
|
||||||
p = strchr (ggvalidchars, code[i]);
|
|
||||||
if (p == NULL)
|
|
||||||
{
|
|
||||||
ggpatch[which].address = ggpatch[which].data = 0;
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
n = p - ggvalidchars;
|
|
||||||
|
|
||||||
switch (i)
|
|
||||||
{
|
|
||||||
case 0:
|
|
||||||
ggpatch[which].data |= n << 3;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 1:
|
|
||||||
ggpatch[which].data |= n >> 2;
|
|
||||||
ggpatch[which].address |= (n & 3) << 14;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 2:
|
|
||||||
ggpatch[which].address |= n << 9;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 3:
|
|
||||||
ggpatch[which].address |= (n & 0xF) << 20 | (n >> 4) << 8;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 4:
|
|
||||||
ggpatch[which].data |= (n & 1) << 12;
|
|
||||||
ggpatch[which].address |= (n >> 1) << 16;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 5:
|
|
||||||
ggpatch[which].data |= (n & 1) << 15 | (n >> 1) << 8;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 6:
|
|
||||||
ggpatch[which].data |= (n >> 3) << 13;
|
|
||||||
ggpatch[which].address |= (n & 7) << 5;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case 7:
|
|
||||||
ggpatch[which].address |= n;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void decode_ggcodes ()
|
|
||||||
{
|
|
||||||
int i, j;
|
|
||||||
char thiscode[10];
|
|
||||||
|
|
||||||
/*** Clear out any old patches ***/
|
|
||||||
memset (&ggpatch[0], 0, 8 * sizeof (GGPATCH));
|
|
||||||
memset (&thiscode, 0, 10);
|
|
||||||
|
|
||||||
j = 0;
|
|
||||||
for (i = 0; i < 8; i++)
|
|
||||||
{
|
|
||||||
if (strcmp ((char *)ggcodes[i], "AAAA-AAAA"))
|
|
||||||
{
|
|
||||||
/*** Move the code into thiscode ***/
|
|
||||||
memcpy (&thiscode, &ggcodes[i], 4);
|
|
||||||
memcpy (&thiscode[4], &ggcodes[i][5], 4);
|
|
||||||
|
|
||||||
decode_genie (thiscode, j);
|
|
||||||
j++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*** And now apply the patches ***/
|
|
||||||
if (j)
|
|
||||||
{
|
|
||||||
for (i = 0; i < j; i++)
|
|
||||||
{
|
|
||||||
if (ggpatch[i].address < 0x400000)
|
|
||||||
{
|
|
||||||
/*** Patching ROM space ONLY (Game Genie does NOT have access to other memory areas) ***/
|
|
||||||
if (cart.rom) *(uint16 *)(cart.rom + ggpatch[i].address) = ggpatch[i].data & 0xffff;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* ClearGGCodes
|
|
||||||
*
|
|
||||||
* Should be called whenever a new rom is loaded
|
|
||||||
****************************************************************************/
|
|
||||||
void ClearGGCodes ()
|
|
||||||
{
|
|
||||||
int i;
|
|
||||||
|
|
||||||
for (i = 0; i < MAXCODES; i++)
|
|
||||||
{
|
|
||||||
strcpy ((char *)ggcodes[i], "AAAA-AAAA");
|
|
||||||
gghpos[i] = 0;
|
|
||||||
}
|
|
||||||
ggrow = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* DrawGGCodes
|
|
||||||
*
|
|
||||||
* Just draw the codes, with the current one highlighted.
|
|
||||||
****************************************************************************/
|
|
||||||
void DrawGGCodes ()
|
|
||||||
{
|
|
||||||
int i,j;
|
|
||||||
unsigned char c[2] = { 0, 0 };
|
|
||||||
|
|
||||||
gxClearScreen ((GXColor)BLACK);
|
|
||||||
WriteCentre (134, "Game Genie Entry");
|
|
||||||
|
|
||||||
for (i = 0; i < MAXCODES; i++)
|
|
||||||
{
|
|
||||||
if (i == ggrow)
|
|
||||||
{
|
|
||||||
/*** Highlight selected ***/
|
|
||||||
WriteCentre_HL (i * fheight + 190, (char *)ggcodes[i]);
|
|
||||||
|
|
||||||
/*** If editing, highlight the current character ***/
|
|
||||||
if (editing)
|
|
||||||
{
|
|
||||||
int hpos = 0;
|
|
||||||
|
|
||||||
for (j=0; j<strlen ((char *)ggcodes[i]); j++) hpos += font_size[ggcodes[i][j]];
|
|
||||||
hpos = ((640 - hpos) >> 1);
|
|
||||||
for (j=0; j<gghpos[i]; j++) hpos += font_size[ggcodes[i][j]];
|
|
||||||
|
|
||||||
c[0] = ggcodes[i][gghpos[i]];
|
|
||||||
fntDrawBoxFilled (hpos, (i * fheight) + 190, hpos + font_size[c[0]],
|
|
||||||
((i + 1) * fheight) + 190, COLOR_YELLOW);
|
|
||||||
write_font (hpos, (i * fheight) + 190, (char *)c);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else WriteCentre ((i * fheight) + 190, (char *)ggcodes[i]);
|
|
||||||
}
|
|
||||||
gxSetScreen();
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* GGEditLine
|
|
||||||
*
|
|
||||||
* Up/Down traverses valid character array
|
|
||||||
* Left/Right moves along current line
|
|
||||||
* A exits edit mode
|
|
||||||
****************************************************************************/
|
|
||||||
void GGEditLine ()
|
|
||||||
{
|
|
||||||
short p;
|
|
||||||
char c[2] = { 0, 0 };
|
|
||||||
char *v;
|
|
||||||
int redraw = 1;
|
|
||||||
int quit = 0;
|
|
||||||
|
|
||||||
editing = 1;
|
|
||||||
|
|
||||||
while (quit == 0)
|
|
||||||
{
|
|
||||||
if (redraw)
|
|
||||||
{
|
|
||||||
DrawGGCodes ();
|
|
||||||
redraw = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
p = m_input.keys;
|
|
||||||
|
|
||||||
if (p & PAD_BUTTON_UP)
|
|
||||||
{
|
|
||||||
/*** Increment the entry ***/
|
|
||||||
redraw = 1;
|
|
||||||
c[0] = ggcodes[ggrow][gghpos[ggrow]];
|
|
||||||
v = strstr (ggvalidchars, c);
|
|
||||||
v++;
|
|
||||||
if (*v == '*') ggcodes[ggrow][gghpos[ggrow]] = 'A';
|
|
||||||
else ggcodes[ggrow][gghpos[ggrow]] = *v;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p & PAD_BUTTON_DOWN)
|
|
||||||
{
|
|
||||||
/*** Decrement entry ***/
|
|
||||||
redraw = 1;
|
|
||||||
c[0] = ggcodes[ggrow][gghpos[ggrow]];
|
|
||||||
v = strstr (ggvalidchars, c);
|
|
||||||
if (*v == 'A') ggcodes[ggrow][gghpos[ggrow]] = '9';
|
|
||||||
else
|
|
||||||
{
|
|
||||||
v--;
|
|
||||||
ggcodes[ggrow][gghpos[ggrow]] = *v;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p & PAD_BUTTON_LEFT)
|
|
||||||
{
|
|
||||||
redraw = 1;
|
|
||||||
gghpos[ggrow]--;
|
|
||||||
if (gghpos[ggrow] == 4) gghpos[ggrow]--;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p & PAD_BUTTON_RIGHT)
|
|
||||||
{
|
|
||||||
redraw = 1;
|
|
||||||
gghpos[ggrow]++;
|
|
||||||
if (gghpos[ggrow] == 4) gghpos[ggrow]++;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (gghpos[ggrow] < 0) gghpos[ggrow] = 8;
|
|
||||||
if (gghpos[ggrow] > 8) gghpos[ggrow] = 0;
|
|
||||||
|
|
||||||
if (p & PAD_BUTTON_A) quit = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
editing = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* GGSelectLine
|
|
||||||
*
|
|
||||||
* Select which line to edit
|
|
||||||
****************************************************************************/
|
|
||||||
void GGSelectLine ()
|
|
||||||
{
|
|
||||||
int redraw = 1;
|
|
||||||
int quit = 0;
|
|
||||||
short j;
|
|
||||||
|
|
||||||
/*** To select a line, just move up or down.
|
|
||||||
Pressing A will enter edit mode.
|
|
||||||
Pressing B will exit to caller. ***/
|
|
||||||
|
|
||||||
while (quit == 0)
|
|
||||||
{
|
|
||||||
if (redraw)
|
|
||||||
{
|
|
||||||
DrawGGCodes ();
|
|
||||||
redraw = 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
j = m_input.keys;
|
|
||||||
|
|
||||||
if (j & PAD_BUTTON_UP)
|
|
||||||
{
|
|
||||||
ggrow--;
|
|
||||||
redraw = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j & PAD_BUTTON_DOWN)
|
|
||||||
{
|
|
||||||
ggrow++;
|
|
||||||
redraw = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (ggrow < 0) ggrow = MAXCODES - 1;
|
|
||||||
if (ggrow == MAXCODES) ggrow = 0;
|
|
||||||
|
|
||||||
if (j & PAD_BUTTON_B) quit = 1;
|
|
||||||
|
|
||||||
if (j & PAD_BUTTON_A)
|
|
||||||
{
|
|
||||||
GGEditLine ();
|
|
||||||
redraw = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (j & PAD_TRIGGER_Z)
|
|
||||||
{
|
|
||||||
/* reset code */
|
|
||||||
strcpy ((char *)ggcodes[ggrow], "AAAA-AAAA");
|
|
||||||
gghpos[ggrow] = 0;
|
|
||||||
redraw = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/****************************************************************************
|
|
||||||
* GetGGEntries
|
|
||||||
*
|
|
||||||
* Screen to return encoded Game Genie codes.
|
|
||||||
* No keyboard is available, so it's just a simple wrap round each line kind
|
|
||||||
* of thing.
|
|
||||||
****************************************************************************/
|
|
||||||
void GetGGEntries ()
|
|
||||||
{
|
|
||||||
editing = 0;
|
|
||||||
GGSelectLine ();
|
|
||||||
|
|
||||||
/* Apply Game Genie patches */
|
|
||||||
decode_ggcodes ();
|
|
||||||
}
|
|
@ -1,9 +1,9 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* gui.c
|
* gui.c
|
||||||
*
|
*
|
||||||
* generic GUI Engine, using GX hardware
|
* generic GUI Engine (using GX rendering)
|
||||||
*
|
*
|
||||||
* Eke-Eke (2009)
|
* Eke-Eke (2009,2010)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -176,6 +176,7 @@ void GUI_DeleteMenu(gui_menu *menu)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
extern void gxSnapshot(void);
|
||||||
|
|
||||||
/* Draw Menu */
|
/* Draw Menu */
|
||||||
void GUI_DrawMenu(gui_menu *menu)
|
void GUI_DrawMenu(gui_menu *menu)
|
||||||
@ -237,7 +238,7 @@ void GUI_DrawMenu(gui_menu *menu)
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
FONT_writeCenter(item->text,18,item->x+2,item->x+item->w+2,button->y+(button->h-18)/2+18,(GXColor)DARK_GREY);
|
FONT_writeCenter(item->text,18,item->x-4,item->x+item->w+4,button->y+(button->h-18)/2+18,(GXColor)DARK_GREY);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -422,7 +423,7 @@ void GUI_DrawMenuFX(gui_menu *menu, u8 speed, u8 out)
|
|||||||
|
|
||||||
/* menu title */
|
/* menu title */
|
||||||
if ((menu->bg_images[2].state & IMAGE_SLIDE_TOP) || (menu->bg_images[3].state & IMAGE_SLIDE_TOP))
|
if ((menu->bg_images[2].state & IMAGE_SLIDE_TOP) || (menu->bg_images[3].state & IMAGE_SLIDE_TOP))
|
||||||
FONT_write(menu->title, 22,10,out ? (56 + temp - max_offset) : (56 -temp),640,(GXColor)WHITE);
|
FONT_write(menu->title, 22,10,out ? (56 + temp - max_offset) : (56 - temp),640,(GXColor)WHITE);
|
||||||
else
|
else
|
||||||
FONT_write(menu->title, 22,10,56,640,(GXColor)WHITE);
|
FONT_write(menu->title, 22,10,56,640,(GXColor)WHITE);
|
||||||
|
|
||||||
@ -465,6 +466,26 @@ void GUI_DrawMenuFX(gui_menu *menu, u8 speed, u8 out)
|
|||||||
item = (menu->items) ? (&menu->items[menu->offset + i]) : NULL;
|
item = (menu->items) ? (&menu->items[menu->offset + i]) : NULL;
|
||||||
|
|
||||||
/* draw button + items */
|
/* draw button + items */
|
||||||
|
if ((i == menu->selected) || (button->state & BUTTON_SELECTED))
|
||||||
|
{
|
||||||
|
if (button->data)
|
||||||
|
gxDrawTexture(button->data->texture[1],button->x+xoffset-4,button->y+yoffset-4,button->w+8,button->h+8,item_alpha);
|
||||||
|
|
||||||
|
if (item)
|
||||||
|
{
|
||||||
|
if (item->texture)
|
||||||
|
{
|
||||||
|
gxDrawTexture(item->texture, item->x+xoffset-4,item->y+yoffset-4,item->w+8,item->h+8,item_alpha);
|
||||||
|
FONT_writeCenter(item->text,18,button->x+xoffset+4,item->x+xoffset-4,button->y+yoffset+(button->h - 36)/2+18,text_color);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
FONT_writeCenter(item->text,18,item->x+xoffset+2,item->x+item->w+xoffset+2,button->y+yoffset+(button->h-18)/2+18,text_color);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
if (button->data)
|
if (button->data)
|
||||||
gxDrawTexture(button->data->texture[0],button->x+xoffset,button->y+yoffset,button->w, button->h,item_alpha);
|
gxDrawTexture(button->data->texture[0],button->x+xoffset,button->y+yoffset,button->w, button->h,item_alpha);
|
||||||
|
|
||||||
@ -482,6 +503,7 @@ void GUI_DrawMenuFX(gui_menu *menu, u8 speed, u8 out)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/* draw arrow */
|
/* draw arrow */
|
||||||
for (i=0; i<2; i++)
|
for (i=0; i<2; i++)
|
||||||
@ -688,7 +710,9 @@ int GUI_UpdateMenu(gui_menu *menu)
|
|||||||
if (selected >= menu->max_buttons)
|
if (selected >= menu->max_buttons)
|
||||||
{
|
{
|
||||||
selected = 0;
|
selected = 0;
|
||||||
while (!(menu->buttons[selected].state & BUTTON_ACTIVE))
|
while ((selected < (menu->max_buttons + 2)) &&
|
||||||
|
(!(menu->buttons[selected].state & BUTTON_ACTIVE) ||
|
||||||
|
!(menu->buttons[selected].state & BUTTON_VISIBLE)))
|
||||||
selected++;
|
selected++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1140,12 +1164,12 @@ int GUI_OptionWindow(gui_menu *parent, char *title, char *items[], u8 nb_items)
|
|||||||
gxSetScreen();
|
gxSetScreen();
|
||||||
|
|
||||||
/* update selection */
|
/* update selection */
|
||||||
if (p&PAD_BUTTON_UP)
|
if (p & PAD_BUTTON_UP)
|
||||||
{
|
{
|
||||||
if (selected > 0)
|
if (selected > 0)
|
||||||
selected --;
|
selected --;
|
||||||
}
|
}
|
||||||
else if (p&PAD_BUTTON_DOWN)
|
else if (p & PAD_BUTTON_DOWN)
|
||||||
{
|
{
|
||||||
if (selected < (nb_items -1))
|
if (selected < (nb_items -1))
|
||||||
selected ++;
|
selected ++;
|
||||||
@ -1227,8 +1251,8 @@ void GUI_OptionBox(gui_menu *parent, optioncallback cb, char *title, void *optio
|
|||||||
gx_texture *arrow[2];
|
gx_texture *arrow[2];
|
||||||
arrow[0] = gxTextureOpenPNG(Button_arrow_png,0);
|
arrow[0] = gxTextureOpenPNG(Button_arrow_png,0);
|
||||||
arrow[1] = gxTextureOpenPNG(Button_arrow_over_png,0);
|
arrow[1] = gxTextureOpenPNG(Button_arrow_over_png,0);
|
||||||
gx_texture *window = gxTextureOpenPNG(Frame_s4_png,0);
|
gx_texture *window = gxTextureOpenPNG(Frame_s2_png,0);
|
||||||
gx_texture *top = gxTextureOpenPNG(Frame_s4_title_png,0);
|
gx_texture *top = gxTextureOpenPNG(Frame_s2_title_png,0);
|
||||||
|
|
||||||
/* window position */
|
/* window position */
|
||||||
int xwindow = 166;
|
int xwindow = 166;
|
||||||
@ -1476,7 +1500,7 @@ void GUI_OptionBox2(gui_menu *parent, char *text_1, char *text_2, s16 *option_1,
|
|||||||
gx_texture *arrow[2];
|
gx_texture *arrow[2];
|
||||||
arrow[0] = gxTextureOpenPNG(Button_arrow_png,0);
|
arrow[0] = gxTextureOpenPNG(Button_arrow_png,0);
|
||||||
arrow[1] = gxTextureOpenPNG(Button_arrow_over_png,0);
|
arrow[1] = gxTextureOpenPNG(Button_arrow_over_png,0);
|
||||||
gx_texture *window = gxTextureOpenPNG(Frame_s4_png,0);
|
gx_texture *window = gxTextureOpenPNG(Frame_s2_png,0);
|
||||||
|
|
||||||
/* window position */
|
/* window position */
|
||||||
int xwindow = 166;
|
int xwindow = 166;
|
||||||
@ -1775,8 +1799,8 @@ void GUI_MsgBoxOpen(char *title, char *msg, bool throbber)
|
|||||||
if (!message_box.refresh)
|
if (!message_box.refresh)
|
||||||
{
|
{
|
||||||
/* initialize default textures */
|
/* initialize default textures */
|
||||||
message_box.window = gxTextureOpenPNG(Frame_s4_png,0);
|
message_box.window = gxTextureOpenPNG(Frame_s2_png,0);
|
||||||
message_box.top = gxTextureOpenPNG(Frame_s4_title_png,0);
|
message_box.top = gxTextureOpenPNG(Frame_s2_title_png,0);
|
||||||
if (throbber)
|
if (throbber)
|
||||||
message_box.throbber = gxTextureOpenPNG(Frame_throbber_png,0);
|
message_box.throbber = gxTextureOpenPNG(Frame_throbber_png,0);
|
||||||
|
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
/****************************************************************************
|
/****************************************************************************
|
||||||
* gui.c
|
* gui.c
|
||||||
*
|
*
|
||||||
* generic GUI engine, using GX hardware
|
* generic GUI Engine (using GX rendering)
|
||||||
*
|
*
|
||||||
* Eke-Eke (2009)
|
* Eke-Eke (2009,2010)
|
||||||
*
|
*
|
||||||
* This program is free software; you can redistribute it and/or modify
|
* This program is free software; you can redistribute it and/or modify
|
||||||
* it under the terms of the GNU General Public License as published by
|
* it under the terms of the GNU General Public License as published by
|
||||||
@ -28,6 +28,8 @@
|
|||||||
#include <wiiuse/wpad.h>
|
#include <wiiuse/wpad.h>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define BG_COLOR_MAX 15
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* GUI Buttons state */
|
/* GUI Buttons state */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -53,8 +55,6 @@
|
|||||||
#define IMAGE_SLIDE_TOP 0x20
|
#define IMAGE_SLIDE_TOP 0x20
|
||||||
#define IMAGE_SLIDE_BOTTOM 0x40
|
#define IMAGE_SLIDE_BOTTOM 0x40
|
||||||
|
|
||||||
#define BG_COLOR_MAX 15
|
|
||||||
|
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
/* Generic GUI structures */
|
/* Generic GUI structures */
|
||||||
/*****************************************************************************/
|
/*****************************************************************************/
|
||||||
@ -169,9 +169,8 @@ extern const u8 Main_logo_png[];
|
|||||||
extern const u8 Frame_s1_png[];
|
extern const u8 Frame_s1_png[];
|
||||||
extern const u8 Frame_s2_png[];
|
extern const u8 Frame_s2_png[];
|
||||||
extern const u8 Frame_s3_png[];
|
extern const u8 Frame_s3_png[];
|
||||||
extern const u8 Frame_s4_png[];
|
|
||||||
extern const u8 Frame_s1_title_png[];
|
extern const u8 Frame_s1_title_png[];
|
||||||
extern const u8 Frame_s4_title_png[];
|
extern const u8 Frame_s2_title_png[];
|
||||||
extern const u8 Frame_throbber_png[];
|
extern const u8 Frame_throbber_png[];
|
||||||
|
|
||||||
/* Generic Buttons */
|
/* Generic Buttons */
|
||||||
@ -187,6 +186,8 @@ extern const u8 Button_down_png[];
|
|||||||
extern const u8 Button_down_over_png[];
|
extern const u8 Button_down_over_png[];
|
||||||
extern const u8 Button_arrow_png[];
|
extern const u8 Button_arrow_png[];
|
||||||
extern const u8 Button_arrow_over_png[];
|
extern const u8 Button_arrow_over_png[];
|
||||||
|
extern const u8 Button_digit_png[];
|
||||||
|
extern const u8 Button_digit_over_png[];
|
||||||
|
|
||||||
/* Generic images*/
|
/* Generic images*/
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
@ -200,9 +201,10 @@ extern const u8 Key_B_wii_png[];
|
|||||||
#define Key_B_png Key_B_gcn_png
|
#define Key_B_png Key_B_gcn_png
|
||||||
extern const u8 Key_A_gcn_png[];
|
extern const u8 Key_A_gcn_png[];
|
||||||
extern const u8 Key_B_gcn_png[];
|
extern const u8 Key_B_gcn_png[];
|
||||||
extern const u8 Star_empty_png[];
|
|
||||||
extern const u8 Star_full_png[];
|
|
||||||
#endif
|
#endif
|
||||||
|
extern const u8 Star_full_png[];
|
||||||
|
extern const u8 Star_empty_png[];
|
||||||
|
extern const u8 Overlay_bar_png[];
|
||||||
|
|
||||||
/* Generic Sounds */
|
/* Generic Sounds */
|
||||||
extern const u8 button_over_pcm[];
|
extern const u8 button_over_pcm[];
|
||||||
|
@ -24,86 +24,6 @@
|
|||||||
#ifndef _MENU_H
|
#ifndef _MENU_H
|
||||||
#define _MENU_H
|
#define _MENU_H
|
||||||
|
|
||||||
/* PNG images */
|
|
||||||
/* Intro */
|
|
||||||
extern const u8 Bg_intro_c1_png[];
|
|
||||||
extern const u8 Bg_intro_c2_png[];
|
|
||||||
extern const u8 Bg_intro_c3_png[];
|
|
||||||
extern const u8 Bg_intro_c4_png[];
|
|
||||||
extern const u8 Bg_intro_c5_png[];
|
|
||||||
extern const u8 Bg_credits_png[];
|
|
||||||
|
|
||||||
/* ROM Browser */
|
|
||||||
extern const u8 Overlay_bar_png[];
|
|
||||||
extern const u8 Browser_dir_png[];
|
|
||||||
extern const u8 Star_full_png[];
|
|
||||||
extern const u8 Star_empty_png[];
|
|
||||||
extern const u8 Snap_empty_png[];
|
|
||||||
extern const u8 Snap_frame_png[];
|
|
||||||
|
|
||||||
/* Main menu */
|
|
||||||
extern const u8 Main_load_png[];
|
|
||||||
extern const u8 Main_options_png[];
|
|
||||||
extern const u8 Main_quit_png[];
|
|
||||||
extern const u8 Main_file_png[];
|
|
||||||
extern const u8 Main_reset_png[];
|
|
||||||
extern const u8 Main_ggenie_png[];
|
|
||||||
extern const u8 Main_showinfo_png[];
|
|
||||||
extern const u8 Main_takeshot_png[];
|
|
||||||
#ifdef HW_RVL
|
|
||||||
extern const u8 Main_play_wii_png[];
|
|
||||||
#else
|
|
||||||
extern const u8 Main_play_gcn_png[];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Options menu */
|
|
||||||
extern const u8 Option_menu_png[];
|
|
||||||
extern const u8 Option_ctrl_png[];
|
|
||||||
extern const u8 Option_sound_png[];
|
|
||||||
extern const u8 Option_video_png[];
|
|
||||||
extern const u8 Option_system_png[];
|
|
||||||
|
|
||||||
/* Load ROM menu */
|
|
||||||
extern const u8 Load_recent_png[];
|
|
||||||
extern const u8 Load_sd_png[];
|
|
||||||
extern const u8 Load_dvd_png[];
|
|
||||||
#ifdef HW_RVL
|
|
||||||
extern const u8 Load_usb_png[];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* Save Manager menu */
|
|
||||||
extern const u8 Button_load_png[];
|
|
||||||
extern const u8 Button_load_over_png[];
|
|
||||||
extern const u8 Button_save_png[];
|
|
||||||
extern const u8 Button_save_over_png[];
|
|
||||||
extern const u8 Button_special_png[];
|
|
||||||
extern const u8 Button_special_over_png[];
|
|
||||||
extern const u8 Button_delete_png[];
|
|
||||||
extern const u8 Button_delete_over_png[];
|
|
||||||
|
|
||||||
/* Controller Settings */
|
|
||||||
extern const u8 Ctrl_4wayplay_png[];
|
|
||||||
extern const u8 Ctrl_gamepad_png[];
|
|
||||||
extern const u8 Ctrl_justifiers_png[];
|
|
||||||
extern const u8 Ctrl_menacer_png[];
|
|
||||||
extern const u8 Ctrl_mouse_png[];
|
|
||||||
extern const u8 Ctrl_none_png[];
|
|
||||||
extern const u8 Ctrl_teamplayer_png[];
|
|
||||||
extern const u8 Ctrl_pad3b_png[];
|
|
||||||
extern const u8 Ctrl_pad6b_png[];
|
|
||||||
extern const u8 Ctrl_config_png[];
|
|
||||||
extern const u8 Ctrl_player_png[];
|
|
||||||
extern const u8 Ctrl_player_over_png[];
|
|
||||||
extern const u8 Ctrl_player_none_png[];
|
|
||||||
extern const u8 ctrl_option_off_png[];
|
|
||||||
extern const u8 ctrl_option_on_png[];
|
|
||||||
extern const u8 ctrl_gamecube_png[];
|
|
||||||
#ifdef HW_RVL
|
|
||||||
extern const u8 ctrl_classic_png[];
|
|
||||||
extern const u8 ctrl_nunchuk_png[];
|
|
||||||
extern const u8 ctrl_wiimote_png[];
|
|
||||||
#endif
|
|
||||||
|
|
||||||
extern void menu_execute(void);
|
extern void menu_execute(void);
|
||||||
extern void menu_configure(void);
|
extern void menu_configure(void);
|
||||||
|
|
||||||
|
@ -24,6 +24,7 @@
|
|||||||
#include "shared.h"
|
#include "shared.h"
|
||||||
#include "font.h"
|
#include "font.h"
|
||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
|
#include "cheats.h"
|
||||||
|
|
||||||
/* Analog sticks sensitivity */
|
/* Analog sticks sensitivity */
|
||||||
#define ANALOG_SENSITIVITY 30
|
#define ANALOG_SENSITIVITY 30
|
||||||
@ -173,9 +174,15 @@ static void pad_update(s8 chan, u8 i)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Menu Request */
|
if ((p & PAD_TRIGGER_Z) && (p & PAD_BUTTON_START))
|
||||||
if (p & PAD_TRIGGER_Z)
|
|
||||||
{
|
{
|
||||||
|
/* MODE button */
|
||||||
|
input.pad[i] |= INPUT_MODE;
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
else if (p & PAD_TRIGGER_Z)
|
||||||
|
{
|
||||||
|
/* Menu Request */
|
||||||
ConfigRequested = 1;
|
ConfigRequested = 1;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
@ -825,9 +832,6 @@ void gx_input_Config(u8 chan, u8 type, u8 max)
|
|||||||
|
|
||||||
void gx_input_UpdateEmu(void)
|
void gx_input_UpdateEmu(void)
|
||||||
{
|
{
|
||||||
int i;
|
|
||||||
int player = 0;
|
|
||||||
|
|
||||||
/* Update controllers */
|
/* Update controllers */
|
||||||
PAD_ScanPads();
|
PAD_ScanPads();
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
@ -848,6 +852,7 @@ void gx_input_UpdateEmu(void)
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int i, player = 0;
|
||||||
for (i=0; i<MAX_DEVICES; i++)
|
for (i=0; i<MAX_DEVICES; i++)
|
||||||
{
|
{
|
||||||
/* update inputs */
|
/* update inputs */
|
||||||
@ -868,6 +873,9 @@ void gx_input_UpdateEmu(void)
|
|||||||
player ++;
|
player ++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Update RAM patches */
|
||||||
|
CheatUpdate();
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Menu inputs update function (done by Video Interrupt callback) */
|
/* Menu inputs update function (done by Video Interrupt callback) */
|
||||||
|
@ -48,8 +48,6 @@ extern const u8 Crosshair_p1_png[];
|
|||||||
extern const u8 Crosshair_p2_png[];
|
extern const u8 Crosshair_p2_png[];
|
||||||
|
|
||||||
/*** VI ***/
|
/*** VI ***/
|
||||||
u32 *xfb[2]; /* External Framebuffers */
|
|
||||||
u32 whichfb = 0; /* Current Framebuffer */
|
|
||||||
GXRModeObj *vmode; /* Default Video Mode */
|
GXRModeObj *vmode; /* Default Video Mode */
|
||||||
u8 *texturemem; /* Texture Data */
|
u8 *texturemem; /* Texture Data */
|
||||||
u8 *screenshot; /* Texture Data */
|
u8 *screenshot; /* Texture Data */
|
||||||
@ -68,6 +66,10 @@ static u8 gp_fifo[DEFAULT_FIFO_SIZE] ATTRIBUTE_ALIGN (32);
|
|||||||
static u32 vwidth,vheight;
|
static u32 vwidth,vheight;
|
||||||
static gx_texture *crosshair[2];
|
static gx_texture *crosshair[2];
|
||||||
|
|
||||||
|
/*** Framebuffers ***/
|
||||||
|
static u32 *xfb[2];
|
||||||
|
static u32 whichfb = 0;
|
||||||
|
|
||||||
/***************************************************************************************/
|
/***************************************************************************************/
|
||||||
/* Emulation video modes */
|
/* Emulation video modes */
|
||||||
/***************************************************************************************/
|
/***************************************************************************************/
|
||||||
|
@ -43,8 +43,6 @@ typedef struct
|
|||||||
} gx_texture;
|
} gx_texture;
|
||||||
|
|
||||||
/* Global variables */
|
/* Global variables */
|
||||||
extern u32 *xfb[2];
|
|
||||||
extern u32 whichfb;
|
|
||||||
extern GXRModeObj *vmode;
|
extern GXRModeObj *vmode;
|
||||||
extern u8 *texturemem;
|
extern u8 *texturemem;
|
||||||
extern u32 gc_pal;
|
extern u32 gc_pal;
|
||||||
|
Before Width: | Height: | Size: 341 KiB After Width: | Height: | Size: 285 KiB |
BIN
source/gx/images/Button_digit.png
Normal file
After Width: | Height: | Size: 1.7 KiB |
BIN
source/gx/images/Button_digit_over.png
Normal file
After Width: | Height: | Size: 2.2 KiB |
BIN
source/gx/images/Button_sm_blue.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
BIN
source/gx/images/Button_sm_grey.png
Normal file
After Width: | Height: | Size: 2.5 KiB |
BIN
source/gx/images/Button_sm_yellow.png
Normal file
After Width: | Height: | Size: 2.8 KiB |
Before Width: | Height: | Size: 3.6 KiB |
Before Width: | Height: | Size: 3.3 KiB |
Before Width: | Height: | Size: 3.5 KiB |
Before Width: | Height: | Size: 1.9 KiB After Width: | Height: | Size: 3.8 KiB |
Before Width: | Height: | Size: 2.2 KiB After Width: | Height: | Size: 2.2 KiB |
Before Width: | Height: | Size: 3.8 KiB |
BIN
source/gx/images/Key_DPAD.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
source/gx/images/Key_L_gcn.png
Normal file
After Width: | Height: | Size: 1.8 KiB |
BIN
source/gx/images/Key_Minus_wii.png
Normal file
After Width: | Height: | Size: 1.2 KiB |
BIN
source/gx/images/Key_Plus_wii.png
Normal file
After Width: | Height: | Size: 1.3 KiB |
BIN
source/gx/images/Key_R_gcn.png
Normal file
After Width: | Height: | Size: 2.1 KiB |
Before Width: | Height: | Size: 1.4 KiB |
Before Width: | Height: | Size: 2.1 KiB After Width: | Height: | Size: 2.3 KiB |
@ -27,17 +27,16 @@
|
|||||||
#include "gui.h"
|
#include "gui.h"
|
||||||
#include "menu.h"
|
#include "menu.h"
|
||||||
#include "aram.h"
|
#include "aram.h"
|
||||||
#include "dvd.h"
|
|
||||||
#include "history.h"
|
#include "history.h"
|
||||||
#include "file_slot.h"
|
#include "file_slot.h"
|
||||||
#include "file_fat.h"
|
#include "file_load.h"
|
||||||
#include "filesel.h"
|
#include "filesel.h"
|
||||||
|
#include "cheats.h"
|
||||||
|
|
||||||
#include <fat.h>
|
#include <fat.h>
|
||||||
|
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
#include <wiiuse/wpad.h>
|
#include <wiiuse/wpad.h>
|
||||||
extern u32 __di_check_ahbprot(void);
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
u32 Shutdown = 0;
|
u32 Shutdown = 0;
|
||||||
@ -81,7 +80,7 @@ static void load_bios(void)
|
|||||||
|
|
||||||
static void init_machine(void)
|
static void init_machine(void)
|
||||||
{
|
{
|
||||||
/* Allocate cart_rom here ( 10 MBytes ) */
|
/* allocate cart.rom here (10 MBytes) */
|
||||||
cart.rom = memalign(32, MAXROMSIZE);
|
cart.rom = memalign(32, MAXROMSIZE);
|
||||||
if (!cart.rom)
|
if (!cart.rom)
|
||||||
{
|
{
|
||||||
@ -184,8 +183,7 @@ static void run_emulation(void)
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* wait for next frame */
|
/* wait for next frame */
|
||||||
while (frameticker < 1)
|
while (frameticker < 1) usleep(1);
|
||||||
usleep(1);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -194,14 +192,10 @@ static void run_emulation(void)
|
|||||||
***************************************************/
|
***************************************************/
|
||||||
void reloadrom (int size, char *name)
|
void reloadrom (int size, char *name)
|
||||||
{
|
{
|
||||||
/* cartridge hot-swap support */
|
/* hot-swap previous & current cartridge */
|
||||||
uint8 hotswap = 0;
|
bool hotswap = config.hot_swap && cart.romsize;
|
||||||
if (cart.romsize)
|
|
||||||
{
|
|
||||||
hotswap = config.hot_swap;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* Load ROM */
|
/* load ROM file */
|
||||||
cart.romsize = size;
|
cart.romsize = size;
|
||||||
load_rom(name);
|
load_rom(name);
|
||||||
|
|
||||||
@ -220,9 +214,23 @@ void reloadrom (int size, char *name)
|
|||||||
|
|
||||||
/* System Power ON */
|
/* System Power ON */
|
||||||
system_init ();
|
system_init ();
|
||||||
ClearGGCodes ();
|
|
||||||
system_reset ();
|
system_reset ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* load Cheats */
|
||||||
|
CheatLoad();
|
||||||
|
|
||||||
|
/* load SRAM */
|
||||||
|
if (config.s_auto & 1)
|
||||||
|
{
|
||||||
|
slot_autoload(0,config.s_device);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* load State */
|
||||||
|
if (config.s_auto & 2)
|
||||||
|
{
|
||||||
|
slot_autoload(config.s_default,config.s_device);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**************************************************
|
/**************************************************
|
||||||
@ -230,11 +238,16 @@ void reloadrom (int size, char *name)
|
|||||||
***************************************************/
|
***************************************************/
|
||||||
void shutdown(void)
|
void shutdown(void)
|
||||||
{
|
{
|
||||||
|
/* save current config */
|
||||||
config_save();
|
config_save();
|
||||||
|
|
||||||
|
/* save current game state */
|
||||||
if (config.s_auto & 2)
|
if (config.s_auto & 2)
|
||||||
{
|
{
|
||||||
slot_autosave(config.s_default,config.s_device);
|
slot_autosave(config.s_default,config.s_device);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* shutdown emulation */
|
||||||
system_shutdown();
|
system_shutdown();
|
||||||
audio_shutdown();
|
audio_shutdown();
|
||||||
free(cart.rom);
|
free(cart.rom);
|
||||||
@ -249,26 +262,18 @@ void shutdown(void)
|
|||||||
* M A I N
|
* M A I N
|
||||||
*
|
*
|
||||||
***************************************************************************/
|
***************************************************************************/
|
||||||
u32 fat_enabled = 0;
|
|
||||||
u32 frameticker = 0;
|
u32 frameticker = 0;
|
||||||
|
|
||||||
int main (int argc, char *argv[])
|
int main (int argc, char *argv[])
|
||||||
{
|
{
|
||||||
#ifdef HW_RVL
|
|
||||||
/* if HW_AHBPROT flag is not set (DVD support), try to reload IOS 58 (USB2 support) */
|
|
||||||
if ((IOS_GetVersion() != 58) && (__di_check_ahbprot() != 1)) IOS_ReloadIOS(58);
|
|
||||||
|
|
||||||
/* initialize DVD device */
|
|
||||||
DI_Init();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
/* initialize video engine */
|
/* initialize video engine */
|
||||||
gx_video_Init();
|
gx_video_Init();
|
||||||
|
|
||||||
|
/* initialize DVD interface */
|
||||||
#ifdef HW_DOL
|
#ifdef HW_DOL
|
||||||
/* initialize DVD device */
|
|
||||||
DVD_Init ();
|
DVD_Init ();
|
||||||
dvd_drive_detect();
|
#else
|
||||||
|
DI_Init();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* initialize FAT devices */
|
/* initialize FAT devices */
|
||||||
@ -292,12 +297,18 @@ int main (int argc, char *argv[])
|
|||||||
dir = diropen(pathname);
|
dir = diropen(pathname);
|
||||||
if (dir) dirclose(dir);
|
if (dir) dirclose(dir);
|
||||||
else mkdir(pathname,S_IRWXU);
|
else mkdir(pathname,S_IRWXU);
|
||||||
|
|
||||||
|
/* default Cheat files directory */
|
||||||
|
sprintf (pathname, "%s/cheats",DEFAULT_PATH);
|
||||||
|
dir = diropen(pathname);
|
||||||
|
if (dir) dirclose(dir);
|
||||||
|
else mkdir(pathname,S_IRWXU);
|
||||||
}
|
}
|
||||||
|
|
||||||
/* initialize input engine */
|
/* initialize input engine */
|
||||||
gx_input_Init();
|
gx_input_Init();
|
||||||
|
|
||||||
/* initialize sound engine (need libfat) */
|
/* initialize sound engine */
|
||||||
gx_audio_Init();
|
gx_audio_Init();
|
||||||
|
|
||||||
/* initialize genesis plus core */
|
/* initialize genesis plus core */
|
||||||
@ -321,16 +332,12 @@ int main (int argc, char *argv[])
|
|||||||
else if (config.autoload)
|
else if (config.autoload)
|
||||||
{
|
{
|
||||||
SILENT = 1;
|
SILENT = 1;
|
||||||
if (FAT_Open(TYPE_RECENT))
|
if (OpenDirectory(TYPE_RECENT))
|
||||||
{
|
{
|
||||||
int size = FAT_LoadFile(cart.rom,0);
|
int size = LoadFile(cart.rom,0);
|
||||||
if (size)
|
if (size)
|
||||||
{
|
{
|
||||||
reloadrom(size,filelist[0].filename);
|
reloadrom(size,filelist[0].filename);
|
||||||
if (config.s_auto & 1)
|
|
||||||
slot_autoload(0,config.s_device);
|
|
||||||
if (config.s_auto & 2)
|
|
||||||
slot_autoload(config.s_default,config.s_device);
|
|
||||||
gx_video_Start();
|
gx_video_Start();
|
||||||
gx_audio_Start();
|
gx_audio_Start();
|
||||||
frameticker = 1;
|
frameticker = 1;
|
||||||
@ -341,12 +348,13 @@ int main (int argc, char *argv[])
|
|||||||
}
|
}
|
||||||
|
|
||||||
#ifdef HW_RVL
|
#ifdef HW_RVL
|
||||||
/* Power button callback */
|
/* power button callback */
|
||||||
SYS_SetPowerCallback(Power_Off);
|
SYS_SetPowerCallback(Power_Off);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* main emulation loop */
|
/* main emulation loop */
|
||||||
run_emulation();
|
run_emulation();
|
||||||
|
|
||||||
|
/* we should never return anyway */
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|