From 844cdbe77d9407c6380e280824cc49d6e9b8a008 Mon Sep 17 00:00:00 2001 From: ekeeke31 Date: Mon, 20 Aug 2007 19:24:03 +0000 Subject: [PATCH] --- source/ngc/gui/filesel.c | 114 ++++---- source/ngc/gui/filesel.c.new | 526 +++++++++++++++++++++++++++++++++++ source/ngc/gui/iso9660.h | 7 +- source/ngc/gui/iso9660.h.new | 45 +++ source/ngc/unzip.c | 13 +- source/ngc/unzip.c.new | 193 +++++++++++++ 6 files changed, 836 insertions(+), 62 deletions(-) create mode 100644 source/ngc/gui/filesel.c.new create mode 100644 source/ngc/gui/iso9660.h.new create mode 100644 source/ngc/unzip.c.new diff --git a/source/ngc/gui/filesel.c b/source/ngc/gui/filesel.c index 75e98c8..3d5549d 100644 --- a/source/ngc/gui/filesel.c +++ b/source/ngc/gui/filesel.c @@ -24,9 +24,6 @@ #include "iso9660.h" #include "font.h" #include "unzip.h" -#include "diskio.h" -#include "vfat.h" - #define PAGESIZE 12 #define PADCAL 70 @@ -35,15 +32,13 @@ static int maxfiles; u8 havedir = 0; u8 haveSDdir = 0; u8 UseSDCARD = 0; +sd_file *filehandle; char rootSDdir[SDCARD_MAX_PATH_LEN]; int LoadFile (unsigned char *buffer); int offset = 0; int selection = 0; int old_selection = 0; int old_offset = 0; -VFATFS fs; -FSDIRENTRY f; - extern void reloadrom (); @@ -53,16 +48,16 @@ extern void reloadrom (); static void ShowFiles (int offset, int selection) { int i, j; - char text[MAX_LONG_NAME+2]; + char text[MAXJOLIET+2]; ClearScreen (); j = 0; for (i = offset; i < (offset + PAGESIZE) && (i < maxfiles); i++) { - memset(text,0,MAX_LONG_NAME+2); - if (filelist[i].flags) sprintf(text, "[%s]", filelist[i].displayname + filelist[i].filename_offset); - else sprintf (text, "%s", filelist[i].displayname + filelist[i].filename_offset); + memset(text,0,MAXJOLIET+2); + if (filelist[i].flags) sprintf(text, "[%s]", filelist[i].filename + filelist[i].filename_offset); + else sprintf (text, "%s", filelist[i].filename + filelist[i].filename_offset); if (j == (selection - offset)) WriteCentre_HL ((j * fheight) + 120, text); else WriteCentre ((j * fheight) + 120, text); @@ -80,31 +75,48 @@ int updateSDdirname() char *test; char temp[1024]; + /* current directory doesn't change */ + if (strcmp(filelist[selection].filename,".") == 0) return 0; /* go up to parent directory */ - if (strcmp(filelist[selection].filename,"..") == 0) + else if (strcmp(filelist[selection].filename,"..") == 0) { /* determine last subdirectory namelength */ sprintf(temp,"%s",rootSDdir); - test= strtok(temp,"/"); + test= strtok(temp,"\\"); while (test != NULL) { size = strlen(test); - test = strtok(NULL,"/"); + test = strtok(NULL,"\\"); } /* remove last subdirectory name */ size = strlen(rootSDdir) - size - 1; rootSDdir[size] = 0; + /* handles root name */ + if (strcmp(rootSDdir,"dev0:") == 0) sprintf(rootSDdir,"dev0:\\genplus\\.."); + return 1; } else { + /* test new directory namelength */ + if ((strlen(rootSDdir)+1+strlen(filelist[selection].filename)) < SDCARD_MAX_PATH_LEN) + { + /* handles root name */ + if (strcmp(rootSDdir,"dev0:\\genplus\\..") == 0) sprintf(rootSDdir,"dev0:"); + /* update current directory name */ - sprintf(rootSDdir, "%s/%s",rootSDdir, filelist[selection].filename); + sprintf(rootSDdir, "%s\\%s",rootSDdir, filelist[selection].filename); return 1; } + else + { + WaitPrompt ("Dirname is too long !"); + return -1; + } + } } /*************************************************************************** @@ -112,26 +124,30 @@ int updateSDdirname() ***************************************************************************/ int parseSDdirectory() { + int entries = 0; int nbfiles = 0; - FSDIRENTRY fsdir; + DIR *sddir = NULL; /* Get a list of files from the actual root directory */ - int res = VFAT_opendir(0, &fsdir, rootSDdir); + entries = SDCARD_ReadDir (rootSDdir, &sddir); - if (res == FS_SUCCESS) - { - while ( VFAT_readdir(&fsdir) == FS_SUCCESS ) + if (entries < 0) entries = 0; + if (entries > MAXFILES) entries = MAXFILES; + + /* Move to DVD structure - this is required for the file selector */ + while (entries) { memset (&filelist[nbfiles], 0, sizeof (FILEENTRIES)); - strcpy(filelist[nbfiles].displayname, fsdir.longname); - strcpy(filelist[nbfiles].filename, fsdir.shortname); - filelist[nbfiles].length = fsdir.fsize; - filelist[nbfiles].flags = fsdir.dirent.attribute & ATTR_DIRECTORY; + strncpy(filelist[nbfiles].filename,sddir[nbfiles].fname,MAXJOLIET); + filelist[nbfiles].filename[MAXJOLIET-1] = 0; + filelist[nbfiles].length = sddir[nbfiles].fsize; + filelist[nbfiles].flags = (char)(sddir[nbfiles].fattr & SDCARD_ATTR_DIR); nbfiles++; + entries--; } - VFAT_closedir(&fsdir); - } + /*** Release memory ***/ + free(sddir); return nbfiles; } @@ -243,7 +259,7 @@ void FileSelector () { filelist[selection].filename_offset = 0; if (((!UseSDCARD) && (basedir == rootdir)) || - (UseSDCARD && strcmp(rootSDdir,"/") == 0)) return; + (UseSDCARD && strcmp(rootSDdir,"dev0:\\genplus\\..") == 0)) return; go_up = 1; } @@ -261,14 +277,13 @@ void FileSelector () if (go_up) { go_up = 0; - selection = UseSDCARD ? 0 : 1; + selection = 1; } /*** This is directory ***/ if (filelist[selection].flags) { - /* SDCARD directory handler */ - if (UseSDCARD) + if (UseSDCARD) /* SDCARD directory handler */ { /* update current directory */ int status = updateSDdirname(); @@ -293,6 +308,7 @@ void FileSelector () offset = 0; } + /* set new entry list */ maxfiles = parseSDdirectory(); if (!maxfiles) @@ -310,8 +326,7 @@ void FileSelector () haveSDdir = 0; } } - /* DVD directory handler */ - else + else /* DVD directory handler */ { /* move to a new directory */ if (selection != 0) @@ -402,7 +417,6 @@ void OpenDVD () int OpenSD () { UseSDCARD = 1; - char msg[20]; if (haveSDdir == 0) { @@ -413,18 +427,10 @@ int OpenSD () old_selection = selection = offset = old_offset = 0; /* Reset SDCARD root directory */ - sprintf(rootSDdir,"/genplus/roms"); + sprintf(rootSDdir,"dev0:\\genplus\\roms"); /* Parse initial root directory and get entries list */ ShowAction("Reading Directory ..."); - int res = VFAT_mount(FS_SLOTA, &fs); - if ( res != FS_TYPE_FAT16 ) - { - sprintf(msg,"Error mounting SDCARD: %d", res); - WaitPrompt (msg); - return 0; - } - if ((maxfiles = parseSDdirectory ())) { /* Select an entry */ @@ -436,7 +442,7 @@ int OpenSD () else { /* no entries found */ - WaitPrompt ("Error reading /genplus/roms"); + WaitPrompt ("Error reading dev0:\\genplus\\roms"); return 0; } } @@ -455,14 +461,22 @@ void GetSDInfo () rootdirlength = 0; /* Check filename length */ - sprintf(fname, "%s/%s",rootSDdir,filelist[selection].filename); + if ((strlen(rootSDdir)+1+strlen(filelist[selection].filename)) < SDCARD_MAX_PATH_LEN) + sprintf(fname, "%s\\%s",rootSDdir,filelist[selection].filename); + + else + { + WaitPrompt ("Maximum Filename Length reached !"); + haveSDdir = 0; // reset everything before next access + } - int res = VFAT_fopen(0, &f, fname, FS_READ); - if (res != FS_SUCCESS ) + filehandle = SDCARD_OpenFile (fname, "rb"); + if (filehandle == NULL) { WaitPrompt ("Unable to open file!"); return; } + rootdirlength = SDCARD_GetFileSize (filehandle); } /**************************************************************************** @@ -493,16 +507,16 @@ int LoadFile (unsigned char *buffer) discoffset = rootdir; ShowAction ("Loading ... Wait"); - if (UseSDCARD) VFAT_fread(&f, readbuffer, 2048); + if (UseSDCARD) SDCARD_ReadFile (filehandle, &readbuffer, 2048); else dvd_read (&readbuffer, 2048, discoffset); if (!IsZipFile ((char *) readbuffer)) { - if (UseSDCARD) VFAT_fseek(&f, 0, SEEK_SET); + if (UseSDCARD) SDCARD_SeekFile (filehandle, 0, SDCARD_SEEK_SET); for (i = 0; i < blocks; i++) { - if (UseSDCARD) VFAT_fread (&f, readbuffer, 2048); + if (UseSDCARD) SDCARD_ReadFile (filehandle, &readbuffer, 2048); else dvd_read(readbuffer, 2048, discoffset); memcpy (buffer + offset, readbuffer, 2048); offset += 2048; @@ -513,14 +527,14 @@ int LoadFile (unsigned char *buffer) if (rootdirlength % 2048) { i = rootdirlength % 2048; - if (UseSDCARD) VFAT_fread (&f, readbuffer, i); + if (UseSDCARD) SDCARD_ReadFile (filehandle, &readbuffer, i); else dvd_read (readbuffer, 2048, discoffset); memcpy (buffer + offset, readbuffer, i); } } else return UnZipBuffer (buffer, discoffset, rootdirlength); - if (UseSDCARD) VFAT_fclose(&f); + if (UseSDCARD) SDCARD_CloseFile (filehandle); return rootdirlength; } diff --git a/source/ngc/gui/filesel.c.new b/source/ngc/gui/filesel.c.new new file mode 100644 index 0000000..75e98c8 --- /dev/null +++ b/source/ngc/gui/filesel.c.new @@ -0,0 +1,526 @@ +/**************************************************************************** + * Genesis Plus 1.2a + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald + * + * 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 + * + * File Selection + ***************************************************************************/ +#include "shared.h" +#include "dvd.h" +#include "iso9660.h" +#include "font.h" +#include "unzip.h" +#include "diskio.h" +#include "vfat.h" + + +#define PAGESIZE 12 +#define PADCAL 70 + +static int maxfiles; +u8 havedir = 0; +u8 haveSDdir = 0; +u8 UseSDCARD = 0; +char rootSDdir[SDCARD_MAX_PATH_LEN]; +int LoadFile (unsigned char *buffer); +int offset = 0; +int selection = 0; +int old_selection = 0; +int old_offset = 0; +VFATFS fs; +FSDIRENTRY f; + + +extern void reloadrom (); + +/*************************************************************************** + * Showfile screen + ***************************************************************************/ +static void ShowFiles (int offset, int selection) +{ + int i, j; + char text[MAX_LONG_NAME+2]; + + ClearScreen (); + j = 0; + + for (i = offset; i < (offset + PAGESIZE) && (i < maxfiles); i++) + { + memset(text,0,MAX_LONG_NAME+2); + if (filelist[i].flags) sprintf(text, "[%s]", filelist[i].displayname + filelist[i].filename_offset); + else sprintf (text, "%s", filelist[i].displayname + filelist[i].filename_offset); + + if (j == (selection - offset)) WriteCentre_HL ((j * fheight) + 120, text); + else WriteCentre ((j * fheight) + 120, text); + j++; + } + SetScreen (); +} + +/*************************************************************************** + * Update SDCARD curent directory name + ***************************************************************************/ +int updateSDdirname() +{ + int size=0; + char *test; + char temp[1024]; + + + /* go up to parent directory */ + if (strcmp(filelist[selection].filename,"..") == 0) + { + /* determine last subdirectory namelength */ + sprintf(temp,"%s",rootSDdir); + test= strtok(temp,"/"); + while (test != NULL) + { + size = strlen(test); + test = strtok(NULL,"/"); + } + + /* remove last subdirectory name */ + size = strlen(rootSDdir) - size - 1; + rootSDdir[size] = 0; + + return 1; + } + else + { + /* update current directory name */ + sprintf(rootSDdir, "%s/%s",rootSDdir, filelist[selection].filename); + return 1; + } +} + +/*************************************************************************** + * Browse SDCARD subdirectories + ***************************************************************************/ +int parseSDdirectory() +{ + int nbfiles = 0; + FSDIRENTRY fsdir; + + /* Get a list of files from the actual root directory */ + int res = VFAT_opendir(0, &fsdir, rootSDdir); + + if (res == FS_SUCCESS) + { + while ( VFAT_readdir(&fsdir) == FS_SUCCESS ) + { + memset (&filelist[nbfiles], 0, sizeof (FILEENTRIES)); + strcpy(filelist[nbfiles].displayname, fsdir.longname); + strcpy(filelist[nbfiles].filename, fsdir.shortname); + filelist[nbfiles].length = fsdir.fsize; + filelist[nbfiles].flags = fsdir.dirent.attribute & ATTR_DIRECTORY; + nbfiles++; + } + + VFAT_closedir(&fsdir); + } + + return nbfiles; +} + +/**************************************************************************** + * FileSelector + * + * Let user select a file from the File listing + ****************************************************************************/ +void FileSelector () +{ + short p; + signed char a,b; + int haverom = 0; + int redraw = 1; + int go_up = 0; + int i,size; + + while (haverom == 0) + { + if (redraw) ShowFiles (offset, selection); + redraw = 0; + p = PAD_ButtonsDown (0); + a = PAD_StickY (0); + b = PAD_StickX (0); + + /* + * check selection screen changes + */ + + /* scroll displayed filename */ + if ((p & PAD_BUTTON_LEFT) || (b < -PADCAL)) + { + if (filelist[selection].filename_offset > 0) + { + filelist[selection].filename_offset --; + redraw = 1; + } + } + else if ((p & PAD_BUTTON_RIGHT) || (b > PADCAL)) + { + size = 0; + for (i=filelist[selection].filename_offset; i back_framewidth) + { + filelist[selection].filename_offset ++; + redraw = 1; + } + } + + /* highlight next item */ + else if ((p & PAD_BUTTON_DOWN) || (a < -PADCAL)) + { + filelist[selection].filename_offset = 0; + selection++; + if (selection == maxfiles) selection = offset = 0; + if ((selection - offset) >= PAGESIZE) offset += PAGESIZE; + redraw = 1; + } + + /* highlight previous item */ + else if ((p & PAD_BUTTON_UP) || (a > PADCAL)) + { + filelist[selection].filename_offset = 0; + selection--; + if (selection < 0) + { + selection = maxfiles - 1; + offset = selection - PAGESIZE + 1; + } + if (selection < offset) offset -= PAGESIZE; + if (offset < 0) offset = 0; + redraw = 1; + } + + /* go back one page */ + else if (p & PAD_TRIGGER_L) + { + filelist[selection].filename_offset = 0; + selection -= PAGESIZE; + if (selection < 0) + { + selection = maxfiles - 1; + offset = selection - PAGESIZE + 1; + } + if (selection < offset) offset -= PAGESIZE; + if (offset < 0) offset = 0; + redraw = 1; + } + + /* go forward one page */ + else if (p & PAD_TRIGGER_R) + { + filelist[selection].filename_offset = 0; + selection += PAGESIZE; + if (selection > maxfiles - 1) selection = offset = 0; + if ((selection - offset) >= PAGESIZE) offset += PAGESIZE; + redraw = 1; + } + + /* + * Check pressed key + */ + + /* go up one directory or quit */ + if (p & PAD_BUTTON_B) + { + filelist[selection].filename_offset = 0; + if (((!UseSDCARD) && (basedir == rootdir)) || + (UseSDCARD && strcmp(rootSDdir,"/") == 0)) return; + go_up = 1; + } + + /* quit */ + if (p & PAD_TRIGGER_Z) + { + filelist[selection].filename_offset = 0; + return; + } + + /* open selected file or directory */ + if ((p & PAD_BUTTON_A) || go_up) + { + filelist[selection].filename_offset = 0; + if (go_up) + { + go_up = 0; + selection = UseSDCARD ? 0 : 1; + } + + /*** This is directory ***/ + if (filelist[selection].flags) + { + /* SDCARD directory handler */ + if (UseSDCARD) + { + /* update current directory */ + int status = updateSDdirname(); + + /* move to new directory */ + if (status == 1) + { + /* reinit selector (previous value is saved for one level) */ + if (selection == 1) + { + 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; + } + + /* set new entry list */ + maxfiles = parseSDdirectory(); + if (!maxfiles) + { + /* quit */ + WaitPrompt ("Error reading directory !"); + haverom = 1; + haveSDdir = 0; + } + } + else if (status == -1) + { + /* quit */ + haverom = 1; + haveSDdir = 0; + } + } + /* DVD directory handler */ + else + { + /* move to a new directory */ + if (selection != 0) + { + /* update current directory */ + rootdir = filelist[selection].offset; + rootdirlength = filelist[selection].length; + + /* reinit selector (previous value is saved for one level) */ + if (selection == 1) + { + 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 new entry list */ + maxfiles = parsedirectory (); + } + } + } + else /*** This is a file ***/ + { + rootdir = filelist[selection].offset; + rootdirlength = filelist[selection].length; + genromsize = LoadFile (cart_rom); + reloadrom (); + haverom = 1; + } + redraw = 1; + } + } +} + +/**************************************************************************** + * OpenDVD + * + * Function to load a DVD directory and display to user. + ****************************************************************************/ +void OpenDVD () +{ + UseSDCARD = 0; + if (!getpvd()) + { + ShowAction("Mounting DVD ... Wait"); + DVD_Mount(); + havedir = 0; + if (!getpvd()) + { + WaitPrompt ("Failed to mount DVD"); + return; + } + } + + if (havedir == 0) + { + /* don't mess with SD entries */ + haveSDdir = 0; + + /* reinit selector */ + rootdir = basedir; + old_selection = selection = offset = old_offset = 0; + + if ((maxfiles = parsedirectory ())) + { + FileSelector (); + havedir = 1; + } + } + else FileSelector (); +} + +/**************************************************************************** + * OpenSD updated to use the new libogc. Written by softdev and pasted + * into this code by Drack. + * Modified for subdirectory browing & quick filelist recovery + * Enjoy! +*****************************************************************************/ +int OpenSD () +{ + UseSDCARD = 1; + char msg[20]; + + if (haveSDdir == 0) + { + /* don't mess with DVD entries */ + havedir = 0; + + /* reinit selector */ + old_selection = selection = offset = old_offset = 0; + + /* Reset SDCARD root directory */ + sprintf(rootSDdir,"/genplus/roms"); + + /* Parse initial root directory and get entries list */ + ShowAction("Reading Directory ..."); + int res = VFAT_mount(FS_SLOTA, &fs); + if ( res != FS_TYPE_FAT16 ) + { + sprintf(msg,"Error mounting SDCARD: %d", res); + WaitPrompt (msg); + return 0; + } + + if ((maxfiles = parseSDdirectory ())) + { + /* Select an entry */ + FileSelector (); + + /* memorize last entries list, actual root directory and selection for next access */ + haveSDdir = 1; + } + else + { + /* no entries found */ + WaitPrompt ("Error reading /genplus/roms"); + return 0; + } + } + /* Retrieve previous entries list and made a new selection */ + else FileSelector (); + + return 1; +} + +/**************************************************************************** + * SDCard Get Info + ****************************************************************************/ +void GetSDInfo () +{ + char fname[SDCARD_MAX_PATH_LEN]; + rootdirlength = 0; + + /* Check filename length */ + sprintf(fname, "%s/%s",rootSDdir,filelist[selection].filename); + + int res = VFAT_fopen(0, &f, fname, FS_READ); + if (res != FS_SUCCESS ) + { + WaitPrompt ("Unable to open file!"); + return; + } +} + +/**************************************************************************** + * LoadFile + * + * This function will load a file from DVD or SDCARD, in BIN, SMD or ZIP format. + * The values for offset and length are inherited from rootdir and + * rootdirlength. + * + * The buffer parameter should re-use the initial ROM buffer. + ****************************************************************************/ +int LoadFile (unsigned char *buffer) +{ + int offset; + int blocks; + int i; + u64 discoffset; + char readbuffer[2048]; + + /* SDCard Addition */ + if (UseSDCARD) GetSDInfo (); + + /* How many 2k blocks to read */ + if (rootdirlength == 0) return 0; + blocks = rootdirlength / 2048; + + offset = 0; + discoffset = rootdir; + ShowAction ("Loading ... Wait"); + + if (UseSDCARD) VFAT_fread(&f, readbuffer, 2048); + else dvd_read (&readbuffer, 2048, discoffset); + + if (!IsZipFile ((char *) readbuffer)) + { + if (UseSDCARD) VFAT_fseek(&f, 0, SEEK_SET); + + for (i = 0; i < blocks; i++) + { + if (UseSDCARD) VFAT_fread (&f, readbuffer, 2048); + else dvd_read(readbuffer, 2048, discoffset); + memcpy (buffer + offset, readbuffer, 2048); + offset += 2048; + discoffset += 2048; + } + + /* And final cleanup */ + if (rootdirlength % 2048) + { + i = rootdirlength % 2048; + if (UseSDCARD) VFAT_fread (&f, readbuffer, i); + else dvd_read (readbuffer, 2048, discoffset); + memcpy (buffer + offset, readbuffer, i); + } + } + else return UnZipBuffer (buffer, discoffset, rootdirlength); + + if (UseSDCARD) VFAT_fclose(&f); + + return rootdirlength; +} diff --git a/source/ngc/gui/iso9660.h b/source/ngc/gui/iso9660.h index 026adda..ae132d6 100644 --- a/source/ngc/gui/iso9660.h +++ b/source/ngc/gui/iso9660.h @@ -22,17 +22,16 @@ * This is not intended as a complete guide to ISO9660. * Here I use the bare minimum! ***************************************************************************/ -#include "vfat.h" -#define MAXFILES 1000 /** Restrict to 1000 files per dir **/ + #define MAXJOLIET 256 +#define MAXFILES 1000 /** Restrict to 1000 files per dir **/ typedef struct { u64 offset; unsigned int length; char flags; - char filename[13]; - char displayname[MAX_LONG_NAME]; + char filename[MAXJOLIET]; u16 filename_offset; } FILEENTRIES; diff --git a/source/ngc/gui/iso9660.h.new b/source/ngc/gui/iso9660.h.new new file mode 100644 index 0000000..026adda --- /dev/null +++ b/source/ngc/gui/iso9660.h.new @@ -0,0 +1,45 @@ +/**************************************************************************** + * Genesis Plus 1.2a + * + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald + * + * 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 + * + * DVD ISO9660/Joliet Parsing + * + * This is not intended as a complete guide to ISO9660. + * Here I use the bare minimum! + ***************************************************************************/ +#include "vfat.h" +#define MAXFILES 1000 /** Restrict to 1000 files per dir **/ +#define MAXJOLIET 256 + +typedef struct +{ + u64 offset; + unsigned int length; + char flags; + char filename[13]; + char displayname[MAX_LONG_NAME]; + u16 filename_offset; +} FILEENTRIES; + +extern u64 basedir; +extern u64 rootdir; +extern int rootdirlength; + +extern int getpvd (); +extern int parsedirectory (); +extern FILEENTRIES filelist[MAXFILES]; diff --git a/source/ngc/unzip.c b/source/ngc/unzip.c index a629279..e7941a1 100644 --- a/source/ngc/unzip.c +++ b/source/ngc/unzip.c @@ -26,11 +26,8 @@ #include "shared.h" #include "dvd.h" #include "font.h" -#include "diskio.h" -#include "vfat.h" -extern VFATFS fs; -extern FSDIRENTRY f; +extern sd_file *filehandle; extern u8 UseSDCARD; /* @@ -114,8 +111,8 @@ int UnZipBuffer (unsigned char *outbuffer, u64 discoffset, int length) /*** Read Zip Header ***/ if ( UseSDCARD ) { - VFAT_fseek(&f, 0, SEEK_SET); - VFAT_fread(&f, readbuffer, 2048); + SDCARD_SeekFile(filehandle, 0, SDCARD_SEEK_SET); + SDCARD_ReadFile(filehandle, &readbuffer, 2048); } else dvd_read (&readbuffer, 2048, discoffset); @@ -174,14 +171,14 @@ int UnZipBuffer (unsigned char *outbuffer, u64 discoffset, int length) zipchunk = ZIPCHUNK; discoffset += 2048; - if (UseSDCARD) VFAT_fread(&f, readbuffer, 2048); + if (UseSDCARD) SDCARD_ReadFile(filehandle, &readbuffer, 2048); else dvd_read (&readbuffer, 2048, discoffset); } while (res != Z_STREAM_END); inflateEnd (&zs); - if ( UseSDCARD ) VFAT_fclose(&f); + if ( UseSDCARD ) SDCARD_CloseFile(filehandle); if (res == Z_STREAM_END) { diff --git a/source/ngc/unzip.c.new b/source/ngc/unzip.c.new new file mode 100644 index 0000000..a629279 --- /dev/null +++ b/source/ngc/unzip.c.new @@ -0,0 +1,193 @@ +/**************************************************************************** + * Genesis Plus 1.2a + * Copyright (C) 1998, 1999, 2000, 2001, 2002, 2003 Charles Mac Donald + * + * 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 + * + * Nintendo Gamecube Zip Support + * + * Only partial support is included, in that only the first file within the archive + * is considered to be a Genesis ROM image. + ***************************************************************************/ +#include +#include +#include "shared.h" +#include "dvd.h" +#include "font.h" +#include "diskio.h" +#include "vfat.h" + +extern VFATFS fs; +extern FSDIRENTRY f; +extern u8 UseSDCARD; + +/* + * PKWare Zip Header - adopted into zip standard + */ +#define PKZIPID 0x504b0304 +#define MAXROM 0x500000 +#define ZIPCHUNK 2048 + +/* + * Zip file header definition + */ +typedef struct +{ + unsigned int zipid __attribute__ ((__packed__)); // 0x04034b50 + unsigned short zipversion __attribute__ ((__packed__)); + unsigned short zipflags __attribute__ ((__packed__)); + unsigned short compressionMethod __attribute__ ((__packed__)); + unsigned short lastmodtime __attribute__ ((__packed__)); + unsigned short lastmoddate __attribute__ ((__packed__)); + unsigned int crc32 __attribute__ ((__packed__)); + unsigned int compressedSize __attribute__ ((__packed__)); + unsigned int uncompressedSize __attribute__ ((__packed__)); + unsigned short filenameLength __attribute__ ((__packed__)); + unsigned short extraDataLength __attribute__ ((__packed__)); +} PKZIPHEADER; + +/* + * Zip files are stored little endian + * Support functions for short and int types + */ +static inline u32 FLIP32 (u32 b) +{ + unsigned int c; + c = (b & 0xff000000) >> 24; + c |= (b & 0xff0000) >> 8; + c |= (b & 0xff00) << 8; + c |= (b & 0xff) << 24; + return c; +} + +static inline u16 FLIP16 (u16 b) +{ + u16 c; + c = (b & 0xff00) >> 8; + c |= (b & 0xff) << 8; + return c; +} + +/**************************************************************************** + * IsZipFile + * + * Returns TRUE when PKZIPID is first four characters of buffer + ****************************************************************************/ +int IsZipFile (char *buffer) +{ + unsigned int *check; + check = (unsigned int *) buffer; + if (check[0] == PKZIPID) return 1; + return 0; +} + + /***************************************************************************** + * UnZipBuffer + * + * It should be noted that there is a limit of 5MB total size for any ROM + ******************************************************************************/ +int UnZipBuffer (unsigned char *outbuffer, u64 discoffset, int length) +{ + PKZIPHEADER pkzip; + int zipoffset = 0; + int zipchunk = 0; + char out[ZIPCHUNK]; + z_stream zs; + int res; + int bufferoffset = 0; + int have = 0; + char readbuffer[2048]; + char msg[128]; + + /*** Read Zip Header ***/ + if ( UseSDCARD ) + { + VFAT_fseek(&f, 0, SEEK_SET); + VFAT_fread(&f, readbuffer, 2048); + } + else dvd_read (&readbuffer, 2048, discoffset); + + /*** Copy PKZip header to local, used as info ***/ + memcpy (&pkzip, &readbuffer, sizeof (PKZIPHEADER)); + + sprintf (msg, "Unzipping %d bytes ... Wait", FLIP32 (pkzip.uncompressedSize)); + ShowAction (msg); + + /*** Prepare the zip stream ***/ + memset (&zs, 0, sizeof (z_stream)); + zs.zalloc = Z_NULL; + zs.zfree = Z_NULL; + zs.opaque = Z_NULL; + zs.avail_in = 0; + zs.next_in = Z_NULL; + res = inflateInit2 (&zs, -MAX_WBITS); + + if (res != Z_OK) return 0; + + /*** Set ZipChunk for first pass ***/ + zipoffset = (sizeof (PKZIPHEADER) + FLIP16 (pkzip.filenameLength) + FLIP16 (pkzip.extraDataLength)); + zipchunk = ZIPCHUNK - zipoffset; + + /*** Now do it! ***/ + do + { + zs.avail_in = zipchunk; + zs.next_in = (Bytef *) & readbuffer[zipoffset]; + + /*** Now inflate until input buffer is exhausted ***/ + do + { + zs.avail_out = ZIPCHUNK; + zs.next_out = (Bytef *) & out; + res = inflate (&zs, Z_NO_FLUSH); + + if (res == Z_MEM_ERROR) + { + inflateEnd (&zs); + return 0; + } + + have = ZIPCHUNK - zs.avail_out; + if (have) + { + /*** Copy to normal block buffer ***/ + memcpy (&outbuffer[bufferoffset], &out, have); + bufferoffset += have; + } + } + while (zs.avail_out == 0); + + /*** Readup the next 2k block ***/ + zipoffset = 0; + zipchunk = ZIPCHUNK; + discoffset += 2048; + + if (UseSDCARD) VFAT_fread(&f, readbuffer, 2048); + else dvd_read (&readbuffer, 2048, discoffset); + } + while (res != Z_STREAM_END); + + inflateEnd (&zs); + + if ( UseSDCARD ) VFAT_fclose(&f); + + if (res == Z_STREAM_END) + { + if (FLIP32 (pkzip.uncompressedSize) == (u32) bufferoffset) return bufferoffset; + else return FLIP32 (pkzip.uncompressedSize); + } + + return 0; +}