support for zipped ISOs
authornotaz <notasas@gmail.com>
Sat, 10 Mar 2007 23:50:03 +0000 (23:50 +0000)
committernotaz <notasas@gmail.com>
Sat, 10 Mar 2007 23:50:03 +0000 (23:50 +0000)
git-svn-id: file:///home/notaz/opt/svn/PicoDrive@65 be3aeb3a-fb24-0410-a615-afba39da0efa

17 files changed:
Pico/Area.c
Pico/Cart.c
Pico/Pico.h
Pico/PicoInt.h
Pico/cd/Area.c
Pico/cd/cd_file.c
Pico/cd/cd_sys.h
platform/gp2x/Makefile
platform/gp2x/emu.c
platform/gp2x/menu.c
platform/linux/Makefile
platform/linux/gp2x.c
unzip/unzip.c
unzip/unzip.h
unzip/unzip_stream.c [new file with mode: 0644]
unzip/unzip_stream.h [new file with mode: 0644]
zlib/gzio.c

index e4f680b..158c111 100644 (file)
@@ -63,11 +63,13 @@ int PicoAreaPackCpu(unsigned char *cpu, int is_sub)
 #endif\r
 \r
 #ifdef EMU_M68K\r
-  m68ki_cpu_core *context = is_sub ? &PicoS68kCPU : &PicoM68kCPU;\r
-  memcpy(cpu,context->dar,0x40);\r
-  pc=context->pc;\r
+  void *oldcontext = m68ki_cpu_p;\r
+  m68k_set_context(is_sub ? &PicoS68kCPU : &PicoM68kCPU);\r
+  memcpy(cpu,m68ki_cpu_p->dar,0x40);\r
+  pc=m68ki_cpu_p->pc;\r
   *(unsigned int  *)(cpu+0x44)=m68k_get_reg(NULL, M68K_REG_SR);\r
-  *(unsigned int  *)(cpu+0x48)=context->sp[0];\r
+  *(unsigned int  *)(cpu+0x48)=m68ki_cpu_p->sp[0];\r
+  m68k_set_context(oldcontext);\r
 #endif\r
 \r
   *(unsigned int *)(cpu+0x40)=pc;\r
@@ -94,11 +96,13 @@ int PicoAreaUnpackCpu(unsigned char *cpu, int is_sub)
 #endif\r
 \r
 #ifdef EMU_M68K\r
-  m68ki_cpu_core *context = is_sub ? &PicoS68kCPU : &PicoM68kCPU;\r
-  memcpy(context->dar,cpu,0x40);\r
-  context->pc=*(unsigned int *)(cpu+0x40);\r
+  void *oldcontext = m68ki_cpu_p;\r
+  m68k_set_context(is_sub ? &PicoS68kCPU : &PicoM68kCPU);\r
+  memcpy(m68ki_cpu_p->dar,cpu,0x40);\r
+  m68ki_cpu_p->pc=*(unsigned int *)(cpu+0x40);\r
   m68k_set_reg(M68K_REG_SR, *(unsigned int *)(cpu+0x44));\r
-  context->sp[0]=*(unsigned int *)(cpu+0x48);\r
+  m68ki_cpu_p->sp[0]=*(unsigned int *)(cpu+0x48);\r
+  m68k_set_context(oldcontext);\r
 #endif\r
   return 0;\r
 }\r
index d3e7743..0762473 100644 (file)
@@ -8,6 +8,152 @@
 \r
 \r
 #include "PicoInt.h"\r
+#include "../zlib/zlib.h"\r
+#include "../unzip/unzip.h"\r
+#include "../unzip/unzip_stream.h"\r
+\r
+static char *rom_exts[] = { "bin", "gen", "smd", "iso" };\r
+\r
+\r
+pm_file *pm_open(const char *path)\r
+{\r
+  pm_file *file = NULL;\r
+  const char *ext;\r
+  FILE *f;\r
+\r
+  if (path == NULL) return NULL;\r
+\r
+  if (strlen(path) < 5) ext = NULL; // no ext\r
+  else ext = path + strlen(path) - 3;\r
+\r
+  if (ext && strcasecmp(ext, "zip") == 0)\r
+  {\r
+    struct zipent *zipentry;\r
+    gzFile gzf = NULL;\r
+    ZIP *zipfile;\r
+    int i;\r
+\r
+    zipfile = openzip(path);\r
+\r
+    if (zipfile != NULL)\r
+    {\r
+      /* search for suitable file (right extension or large enough file) */\r
+      while ((zipentry = readzip(zipfile)) != NULL)\r
+      {\r
+        if (zipentry->uncompressed_size >= 128*1024) goto found_rom_zip;\r
+        if (strlen(zipentry->name) < 5) continue;\r
+\r
+        ext = zipentry->name+strlen(zipentry->name)-3;\r
+        for (i = 0; i < sizeof(rom_exts)/sizeof(rom_exts[0]); i++)\r
+          if (!strcasecmp(ext, rom_exts[i]) == 0) goto found_rom_zip;\r
+      }\r
+\r
+      /* zipfile given, but nothing found suitable for us inside */\r
+      goto zip_failed;\r
+\r
+found_rom_zip:\r
+      /* try to convert to gzip stream, so we could use standard gzio functions from zlib */\r
+      gzf = zip2gz(zipfile, zipentry);\r
+      if (gzf == NULL)  goto zip_failed;\r
+\r
+      file = malloc(sizeof(*file));\r
+      if (file == NULL) goto zip_failed;\r
+      file->file  = zipfile;\r
+      file->param = gzf;\r
+      file->size  = zipentry->uncompressed_size;\r
+      file->type  = PMT_ZIP;\r
+      return file;\r
+\r
+zip_failed:\r
+      if (gzf) {\r
+        gzclose(gzf);\r
+        zipfile->fp = NULL; // gzclose() closed it\r
+      }\r
+      closezip(zipfile);\r
+      return NULL;\r
+    }\r
+  }\r
+\r
+  /* not a zip, treat as uncompressed file */\r
+  f = fopen(path, "rb");\r
+  if (f == NULL) return NULL;\r
+\r
+  file = malloc(sizeof(*file));\r
+  if (file == NULL) {\r
+    fclose(f);\r
+    return NULL;\r
+  }\r
+  fseek(f, 0, SEEK_END);\r
+  file->file  = f;\r
+  file->param = NULL;\r
+  file->size  = ftell(f);\r
+  file->type  = PMT_UNCOMPRESSED;\r
+  fseek(f, 0, SEEK_SET);\r
+  return file;\r
+}\r
+\r
+size_t pm_read(void *ptr, size_t bytes, pm_file *stream)\r
+{\r
+  int ret;\r
+\r
+  if (stream->type == PMT_UNCOMPRESSED)\r
+  {\r
+    ret = fread(ptr, 1, bytes, stream->file);\r
+  }\r
+  else if (stream->type == PMT_ZIP)\r
+  {\r
+    gzFile gf = stream->param;\r
+    int err;\r
+    ret = gzread(gf, ptr, bytes);\r
+    err = gzerror2(gf);\r
+    if (ret > 0 && (err == Z_DATA_ERROR || err == Z_STREAM_END))\r
+      /* we must reset stream pointer or else next seek/read fails */\r
+      gzrewind(gf);\r
+  }\r
+  else\r
+    ret = 0;\r
+\r
+  return ret;\r
+}\r
+\r
+int pm_seek(pm_file *stream, long offset, int whence)\r
+{\r
+  if (stream->type == PMT_UNCOMPRESSED)\r
+  {\r
+    return fseek(stream->file, offset, whence);\r
+  }\r
+  else if (stream->type == PMT_ZIP)\r
+  {\r
+    return gzseek((gzFile) stream->param, offset, whence);\r
+  }\r
+  else\r
+    return -1;\r
+}\r
+\r
+int pm_close(pm_file *fp)\r
+{\r
+  int ret = 0;\r
+\r
+  if (fp == NULL) return EOF;\r
+\r
+  if (fp->type == PMT_UNCOMPRESSED)\r
+  {\r
+    fclose(fp->file);\r
+  }\r
+  else if (fp->type == PMT_ZIP)\r
+  {\r
+    ZIP *zipfile = fp->file;\r
+    gzclose((gzFile) fp->param);\r
+    zipfile->fp = NULL; // gzclose() closed it\r
+    closezip(zipfile);\r
+  }\r
+  else\r
+    ret = EOF;\r
+\r
+  free(fp);\r
+  return ret;\r
+}\r
+\r
 \r
 void Byteswap(unsigned char *data,int len)\r
 {\r
@@ -86,12 +232,12 @@ static unsigned char *PicoCartAlloc(int filesize)
   return rom;\r
 }\r
 \r
-int PicoCartLoad(FILE *f,unsigned char **prom,unsigned int *psize)\r
+int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize)\r
 {\r
   unsigned char *rom=NULL; int size;\r
   if (f==NULL) return 1;\r
 \r
-  fseek(f,0,SEEK_END); size=ftell(f); fseek(f,0,SEEK_SET);\r
+  size=f->size;\r
   if (size <= 0) return 1;\r
   size=(size+3)&~3; // Round up to a multiple of 4\r
 \r
@@ -99,7 +245,7 @@ int PicoCartLoad(FILE *f,unsigned char **prom,unsigned int *psize)
   rom=PicoCartAlloc(size);\r
   if (rom==NULL) return 1; // { fclose(f); return 1; }\r
 \r
-  fread(rom,1,size,f); // Load up the rom\r
+  pm_read(rom,size,f); // Load up the rom\r
 \r
   // maybe we are loading MegaCD BIOS?\r
   if (!(PicoMCD&1) && size == 0x20000 && (!strncmp((char *)rom+0x124, "BOOT", 4) || !strncmp((char *)rom+0x128, "BOOT", 4))) {\r
@@ -139,69 +285,3 @@ int PicoUnloadCart(unsigned char* romdata)
   return 0;\r
 }\r
 \r
-\r
-#ifdef _UNZIP_SUPPORT\r
-\r
-// notaz\r
-#include "../unzip/unzip.h"\r
-\r
-// nearly same as PicoCartLoad, but works with zipfiles\r
-int CartLoadZip(const char *fname, unsigned char **prom, unsigned int *psize)\r
-{\r
-       unsigned char *rom=0;\r
-       struct zipent* zipentry;\r
-       int size;\r
-       ZIP *zipfile = openzip(fname);\r
-\r
-       if(!zipfile) return 1;\r
-\r
-       // find first bin or smd\r
-       while((zipentry = readzip(zipfile)) != 0)\r
-       {\r
-               char *ext;\r
-               if(strlen(zipentry->name) < 5) continue;\r
-               ext = zipentry->name+strlen(zipentry->name)-4;\r
-\r
-               if(!strcasecmp(ext, ".bin") || !strcasecmp(ext, ".smd") || !strcasecmp(ext, ".gen")) break;\r
-       }\r
-\r
-       if(!zipentry) {\r
-               closezip(zipfile);\r
-               return 4; // no roms\r
-       }\r
-\r
-       size = zipentry->uncompressed_size;\r
-\r
-       size=(size+3)&~3; // Round up to a multiple of 4\r
-\r
-       // Allocate space for the rom plus padding\r
-       rom=PicoCartAlloc(size);\r
-       if (rom==NULL) { closezip(zipfile); return 2; }\r
-\r
-       if(readuncompresszip(zipfile, zipentry, (char *)rom) != 0) {\r
-               free(rom);\r
-               rom = 0;\r
-               closezip(zipfile);\r
-               return 5; // unzip failed\r
-       }\r
-\r
-       closezip(zipfile);\r
-\r
-        // maybe we are loading MegaCD BIOS?\r
-        if (!(PicoMCD&1) && size == 0x20000 &&\r
-                       (!strncmp((char *)rom+0x124, "BOOT", 4) || !strncmp((char *)rom+0x128, "BOOT", 4))) {\r
-               PicoMCD |= 1;\r
-               rom = cd_realloc(rom, size);\r
-        }\r
-\r
-       // Check for SMD:\r
-       if ((size&0x3fff)==0x200) { DecodeSmd(rom,size); size-=0x200; } // Decode and byteswap SMD\r
-       else Byteswap(rom,size); // Just byteswap\r
-\r
-       if (prom)  *prom=rom;\r
-       if (psize) *psize=size;\r
-\r
-       return 0;\r
-}\r
-\r
-#endif\r
index e7dd52a..f997c5c 100644 (file)
@@ -62,10 +62,24 @@ extern areaclose *areaClose;
 extern void (*PicoStateProgressCB)(const char *str);\r
 \r
 // Cart.c\r
-int PicoCartLoad(FILE *f,unsigned char **prom,unsigned int *psize);\r
+typedef enum\r
+{\r
+       PMT_UNCOMPRESSED = 0,\r
+       PMT_ZIP\r
+} pm_type;\r
+typedef struct\r
+{\r
+       void *file;             /* file handle */\r
+       void *param;            /* additional file related field */\r
+       unsigned int size;      /* size */\r
+       pm_type type;\r
+} pm_file;\r
+pm_file *pm_open(const char *path);\r
+size_t   pm_read(void *ptr, size_t bytes, pm_file *stream);\r
+int      pm_seek(pm_file *stream, long offset, int whence);\r
+int      pm_close(pm_file *fp);\r
+int PicoCartLoad(pm_file *f,unsigned char **prom,unsigned int *psize);\r
 int PicoCartInsert(unsigned char *rom,unsigned int romsize);\r
-// notaz\r
-int CartLoadZip(const char *fname, unsigned char **prom, unsigned int *psize);\r
 void Byteswap(unsigned char *data,int len);\r
 // anotherguest\r
 int PicoUnloadCart(unsigned char* romdata);\r
index 0b06756..832664d 100644 (file)
@@ -257,7 +257,7 @@ void z80_write(unsigned char data, unsigned short a);
 void z80_write16(unsigned short data, unsigned short a);\r
 \r
 // cd/Memory.c\r
-void PicoMemSetupCD();\r
+void PicoMemSetupCD(void);\r
 unsigned char  PicoReadCD8 (unsigned int a);\r
 unsigned short PicoReadCD16(unsigned int a);\r
 unsigned int   PicoReadCD32(unsigned int a);\r
index 51da616..bfc1ffa 100644 (file)
@@ -243,7 +243,8 @@ int PicoCdLoadState(void *file)
        /* after load events */
        if (Pico_mcd->s68k_regs[3]&4) // 1M mode?
                wram_2M_to_1M(Pico_mcd->word_ram2M);
-       mp3_start_play(Pico_mcd->TOC.Tracks[Pico_mcd->m.audio_track].F, Pico_mcd->m.audio_offset);
+       if (Pico_mcd->m.audio_track > 0 && Pico_mcd->m.audio_track < Pico_mcd->TOC.Last_Track)
+               mp3_start_play(Pico_mcd->TOC.Tracks[Pico_mcd->m.audio_track].F, Pico_mcd->m.audio_offset);
        // restore hint vector
         *(unsigned short *)(Pico_mcd->bios + 0x72) = Pico_mcd->m.hint_vector;
 
index 0614140..a827a0c 100644 (file)
@@ -16,11 +16,10 @@ void FILE_End(void)
 
 int Load_ISO(const char *iso_name, int is_bin)
 {
-       struct stat file_stat;
        int i, j, num_track, Cur_LBA, index, ret, iso_name_len;
        _scd_track *Tracks = Pico_mcd->TOC.Tracks;
-       FILE *tmp_file;
        char tmp_name[1024], tmp_ext[10];
+       pm_file *pmf;
        static char *exts[] = {
                "%02d.mp3", " %02d.mp3", "-%02d.mp3", "_%02d.mp3", " - %02d.mp3",
                "%d.mp3", " %d.mp3", "-%d.mp3", "_%d.mp3", " - %d.mp3",
@@ -33,16 +32,7 @@ int Load_ISO(const char *iso_name, int is_bin)
 
        Tracks[0].ftype = is_bin ? TYPE_BIN : TYPE_ISO;
 
-       ret = stat(iso_name, &file_stat);
-       if (ret != 0) return -1;
-
-       Tracks[0].Length = file_stat.st_size;
-
-       if (Tracks[0].ftype == TYPE_ISO) Tracks[0].Length >>= 11;       // size in sectors
-       else Tracks[0].Length /= 2352;                                  // size in sectors
-
-
-       Tracks[0].F = fopen(iso_name, "rb");
+       Tracks[0].F = pmf = pm_open(iso_name);
        if (Tracks[0].F == NULL)
        {
                Tracks[0].ftype = 0;
@@ -50,11 +40,9 @@ int Load_ISO(const char *iso_name, int is_bin)
                return -1;
        }
 
-       if (Tracks[0].ftype == TYPE_ISO) fseek(Tracks[0].F, 0x100, SEEK_SET);
-       else fseek(Tracks[0].F, 0x110, SEEK_SET);
-
-       // fread(buf, 1, 0x200, Tracks[0].F);
-       fseek(Tracks[0].F, 0, SEEK_SET);
+       if (Tracks[0].ftype == TYPE_ISO)
+               Tracks[0].Length = pmf->size >>= 11;    // size in sectors
+       else    Tracks[0].Length = pmf->size /= 2352;
 
        Tracks[0].MSF.M = 0; // minutes
        Tracks[0].MSF.S = 2; // seconds
@@ -64,7 +52,6 @@ int Load_ISO(const char *iso_name, int is_bin)
 
        Cur_LBA = Tracks[0].Length;                             // Size in sectors
 
-       strcpy(tmp_name, iso_name);
        iso_name_len = strlen(iso_name);
 
        for (num_track = 2, i = 0; i < 100; i++)
@@ -72,6 +59,7 @@ int Load_ISO(const char *iso_name, int is_bin)
                for(j = 0; j < sizeof(exts)/sizeof(char *); j++)
                {
                        int ext_len;
+                       FILE *tmp_file;
                        sprintf(tmp_ext, exts[j], i);
                        ext_len = strlen(tmp_ext);
 
@@ -88,8 +76,8 @@ int Load_ISO(const char *iso_name, int is_bin)
 
                        if (tmp_file)
                        {
-                               // float fs;
                                int fs;
+                               struct stat file_stat;
                                index = num_track - 1;
 
                                ret = stat(tmp_name, &file_stat);
@@ -143,13 +131,13 @@ void Unload_ISO(void)
 
        if (Pico_mcd == NULL) return;
 
-       for(i = 0; i < 100; i++)
+       if (Pico_mcd->TOC.Tracks[0].F) pm_close(Pico_mcd->TOC.Tracks[0].F);
+
+       for(i = 1; i < 100; i++)
        {
                if (Pico_mcd->TOC.Tracks[i].F) fclose(Pico_mcd->TOC.Tracks[i].F);
-               Pico_mcd->TOC.Tracks[i].F = NULL;
-               Pico_mcd->TOC.Tracks[i].Length = 0;
-               Pico_mcd->TOC.Tracks[i].ftype = 0;
        }
+       memset(Pico_mcd->TOC.Tracks, 0, sizeof(Pico_mcd->TOC.Tracks));
 }
 
 
@@ -208,11 +196,11 @@ int FILE_Read_One_LBA_CDC(void)
                                Pico_mcd->cdc.WA.N = (Pico_mcd->cdc.WA.N + 2352) & 0x7FFF;              // add one sector to WA
                                Pico_mcd->cdc.PT.N = (Pico_mcd->cdc.PT.N + 2352) & 0x7FFF;
 
-                               memcpy(&Pico_mcd->cdc.Buffer[Pico_mcd->cdc.PT.N], &Pico_mcd->cdc.HEAD, 4);
+                               *(unsigned int *)(Pico_mcd->cdc.Buffer + Pico_mcd->cdc.PT.N) = Pico_mcd->cdc.HEAD.N;
                                //memcpy(&Pico_mcd->cdc.Buffer[Pico_mcd->cdc.PT.N + 4], cp_buf, 2048);
 
-                               fseek(Pico_mcd->TOC.Tracks[0].F, where_read, SEEK_SET);
-                               fread(Pico_mcd->cdc.Buffer + Pico_mcd->cdc.PT.N + 4, 1, 2048, Pico_mcd->TOC.Tracks[0].F);
+                               pm_seek(Pico_mcd->TOC.Tracks[0].F, where_read, SEEK_SET);
+                               pm_read(Pico_mcd->cdc.Buffer + Pico_mcd->cdc.PT.N + 4, 2048, Pico_mcd->TOC.Tracks[0].F);
 
 #ifdef DEBUG_CD
                                cdprintf("Read -> WA = %d  Buffer[%d] =", Pico_mcd->cdc.WA.N, Pico_mcd->cdc.PT.N & 0x3FFF);
index f7be7d5..a71f5d2 100644 (file)
@@ -3,8 +3,6 @@
 \r
 #include "cd_file.h"\r
 \r
-#include <stdio.h> // FILE\r
-\r
 #ifdef __cplusplus\r
 extern "C" {\r
 #endif\r
@@ -37,7 +35,7 @@ typedef struct
        _msf MSF;\r
        //\r
        char ftype; // TYPE_ISO, TYPE_BIN, TYPE_MP3\r
-       FILE *F;\r
+       void *F;\r
        int Length;\r
        short KBtps; // kbytes per sec for mp3s (bitrate / 1000 / 8)\r
        short pad;\r
@@ -94,9 +92,6 @@ int Open_Tray_CDD_cD(void);
 \r
 int CDD_Def(void);\r
 \r
-//void Write_CD_Audio(short *Buf, int rate, int channel, int lenght);\r
-//void Update_CD_Audio(int **Buf, int lenght);\r
-\r
 \r
 #ifdef __cplusplus\r
 };\r
index a3c6961..081715a 100644 (file)
@@ -68,7 +68,7 @@ OBJS += ../../Pico/sound/sound.o ../../Pico/sound/sn76496.o ../../Pico/sound/ym2
 OBJS += ../../zlib/gzio.o ../../zlib/inffast.o ../../zlib/inflate.o ../../zlib/inftrees.o ../../zlib/trees.o \\r
        ../../zlib/deflate.o ../../zlib/crc32.o ../../zlib/adler32.o ../../zlib/zutil.o ../../zlib/compress.o\r
 # unzip\r
-OBJS += ../../unzip/unzip.o\r
+OBJS += ../../unzip/unzip.o ../../unzip/unzip_stream.o\r
 # mp3\r
 OBJS += mp3.o\r
 # CPU cores\r
index c8c4f8a..3d6cd3a 100644 (file)
@@ -169,31 +169,31 @@ int find_bios(int region, char **bios_file)
 \r
 /* checks if romFileName points to valid MegaCD image\r
  * if so, checks for suitable BIOS */\r
-static int cd_check(char *ext, char **bios_file)\r
+static int cd_check(char **bios_file)\r
 {\r
        unsigned char buf[32];\r
-       FILE *cd_f;\r
+       pm_file *cd_f;\r
        int type = 0, region = 4; // 1: Japan, 4: US, 8: Europe\r
 \r
-       cd_f = fopen(romFileName, "rb");\r
+       cd_f = pm_open(romFileName);\r
        if (!cd_f) return 0; // let the upper level handle this\r
 \r
-       if (fread(buf, 1, 32, cd_f) != 32) {\r
-               fclose(cd_f);\r
+       if (pm_read(buf, 32, cd_f) != 32) {\r
+               pm_close(cd_f);\r
                return 0;\r
        }\r
 \r
        if (!strncasecmp("SEGADISCSYSTEM", (char *)buf+0x00, 14)) type = 1;       // Sega CD (ISO)\r
        if (!strncasecmp("SEGADISCSYSTEM", (char *)buf+0x10, 14)) type = 2;       // Sega CD (BIN)\r
        if (type == 0) {\r
-               fclose(cd_f);\r
+               pm_close(cd_f);\r
                return 0;\r
        }\r
 \r
        /* it seems we have a CD image here. Try to detect region and load a suitable BIOS now.. */\r
-       fseek(cd_f, (type == 1) ? 0x100+0x10B : 0x110+0x10B, SEEK_SET);\r
-       fread(buf, 1, 1, cd_f);\r
-       fclose(cd_f);\r
+       pm_seek(cd_f, (type == 1) ? 0x100+0x10B : 0x110+0x10B, SEEK_SET);\r
+       pm_read(buf, 1, cd_f);\r
+       pm_close(cd_f);\r
 \r
        if (buf[0] == 0x64) region = 8; // EU\r
        if (buf[0] == 0xa1) region = 1; // JAP\r
@@ -217,7 +217,7 @@ int emu_ReloadRom(void)
        unsigned int rom_size = 0;\r
        char *used_rom_name = romFileName;\r
        char ext[5];\r
-       FILE *rom;\r
+       pm_file *rom;\r
        int ret, cd_state;\r
 \r
        printf("emu_ReloadRom(%s)\n", romFileName);\r
@@ -284,7 +284,7 @@ int emu_ReloadRom(void)
        }\r
 \r
        // check for MegaCD image\r
-       cd_state = cd_check(ext, &used_rom_name);\r
+       cd_state = cd_check(&used_rom_name);\r
        if (cd_state > 0) {\r
                PicoMCD |= 1;\r
                get_ext(used_rom_name, ext);\r
@@ -296,7 +296,7 @@ int emu_ReloadRom(void)
                PicoMCD &= ~1;\r
        }\r
 \r
-       rom = fopen(used_rom_name, "rb");\r
+       rom = pm_open(used_rom_name);\r
        if(!rom) {\r
                sprintf(menuErrorMsg, "Failed to open rom.");\r
                return 0;\r
@@ -308,25 +308,13 @@ int emu_ReloadRom(void)
                rom_size = 0;\r
        }\r
 \r
-       // zipfile support\r
-       if(!strcasecmp(ext, ".zip")) {\r
-               fclose(rom);\r
-               ret = CartLoadZip(used_rom_name, &rom_data, &rom_size);\r
-               if(ret) {\r
-                       if (ret == 4) strcpy(menuErrorMsg, "No ROMs found in zip.");\r
-                       else sprintf(menuErrorMsg, "Unzip failed with code %i", ret);\r
-                       printf("%s\n", menuErrorMsg);\r
-                       return 0;\r
-               }\r
-       } else {\r
-               if( (ret = PicoCartLoad(rom, &rom_data, &rom_size)) ) {\r
-                       sprintf(menuErrorMsg, "PicoCartLoad() failed.");\r
-                       printf("%s\n", menuErrorMsg);\r
-                       fclose(rom);\r
-                       return 0;\r
-               }\r
-               fclose(rom);\r
+       if( (ret = PicoCartLoad(rom, &rom_data, &rom_size)) ) {\r
+               sprintf(menuErrorMsg, "PicoCartLoad() failed.");\r
+               printf("%s\n", menuErrorMsg);\r
+               pm_close(rom);\r
+               return 0;\r
        }\r
+       pm_close(rom);\r
 \r
        // detect wrong files (Pico crashes on very small files), also see if ROM EP is good\r
        if(rom_size <= 0x200 || strncmp((char *)rom_data, "Pico", 4) == 0 ||\r
index 032616a..40eee48 100644 (file)
@@ -407,7 +407,7 @@ static void draw_patchlist(int sel)
                if (pos < 0)  continue;\r
                if (pos > 23) break;\r
                gp2x_smalltext8_lim(14,     pos*10, PicoPatches[i].active ? "ON " : "OFF", 3);\r
-               gp2x_smalltext8_lim(14+6*4, pos*10, PicoPatches[i].name, 53-5);\r
+               gp2x_smalltext8_lim(14+6*4, pos*10, PicoPatches[i].name, 53-6);\r
        }\r
        pos = start + i;\r
        if (pos < 24) gp2x_smalltext8_lim(14, pos*10, "done", 4);\r
index fc5ff06..cd18159 100644 (file)
@@ -39,7 +39,7 @@ OBJS += ../../Pico/sound/sound.o ../../Pico/sound/sn76496.o ../../Pico/sound/ym2
 OBJS += ../../zlib/gzio.o ../../zlib/inffast.o ../../zlib/inflate.o ../../zlib/inftrees.o ../../zlib/trees.o \
        ../../zlib/deflate.o ../../zlib/crc32.o ../../zlib/adler32.o ../../zlib/zutil.o ../../zlib/compress.o
 # unzip
-OBJS += ../../unzip/unzip.o
+OBJS += ../../unzip/unzip.o ../../unzip/unzip_stream.o
 # mp3
 OBJS += ../gp2x/mp3.o
 # CPU cores
index e4e3421..cc4db98 100644 (file)
@@ -164,6 +164,7 @@ void gp2x_init(void)
        printf("entering init()\n"); fflush(stdout);
 
        gp2x_screen = malloc(320*240*2 + 320*2);
+       memset(gp2x_screen, 0, 320*240*2 + 320*2);
 
        // snd
        mixerdev = open("/dev/mixer", O_RDWR);
index 4f1786c..c055969 100644 (file)
 \r
 \r
 // notaz\r
-#ifdef __DEBUG_PRINT\r
-void dprintf(char *format, ...);\r
-#define logerror dprintf\r
-void errormsg(const char* extmsg, const char* usermsg, const char* zipname)\r
-{\r
-       dprintf("Error in zipfile %s: %s", zipname, extmsg);\r
-}\r
+#if 1 //def __DEBUG_PRINT\r
+#define logerror printf\r
+#define errormsg(str1,def,fname) printf("%s: " #def ": " str1 "\n", fname);\r
 #else\r
 #define logerror(x...)\r
 #define errormsg(x...)\r
index d44f963..8d15d05 100644 (file)
@@ -127,6 +127,8 @@ int readcompresszip(ZIP* zip, struct zipent* ent, char* data);
 */\r
 int readuncompresszip(ZIP* zip, struct zipent* ent, char* data);\r
 \r
+int seekcompresszip(ZIP* zip, struct zipent* ent);\r
+\r
 /* public functions */\r
 int /* error */ load_zipped_file (const char *zipfile, const char *filename,\r
        unsigned char **buf, unsigned int *length);\r
diff --git a/unzip/unzip_stream.c b/unzip/unzip_stream.c
new file mode 100644 (file)
index 0000000..3e7919b
--- /dev/null
@@ -0,0 +1,182 @@
+/* seekable zip */
+
+#include "unzip.h"
+
+#include <stdlib.h>
+#include <string.h>
+#include <errno.h>
+
+#ifdef __SYMBIAN32__
+#include <ezlib.h>
+#else
+#include "zlib/zlib.h"
+#endif
+
+
+#define errormsg(str1,def,fname) printf("%s: " #def ": " str1 "\n", fname);
+
+
+/* from gzio.c . Be careful with binary compatibility */
+typedef struct gz_stream {
+    z_stream stream;
+    int      z_err;   /* error code for last stream operation */
+    int      z_eof;   /* set if end of input file */
+    FILE     *file;   /* .gz file */
+    Byte     *inbuf;  /* input buffer */
+    Byte     *outbuf; /* output buffer */
+    uLong    crc;     /* crc32 of uncompressed data */
+    char     *msg;    /* error message */
+    char     *path;   /* path name for debugging only */
+    int      transparent; /* 1 if input file is not a .gz file */
+    char     mode;    /* 'w' or 'r' */
+    z_off_t  start;   /* start of compressed data in file (header skipped) */
+    z_off_t  in;      /* bytes into deflate or inflate */
+    z_off_t  out;     /* bytes out of deflate or inflate */
+    int      back;    /* one character push-back */
+    int      last;    /* true if push-back is last character */
+} gz_stream;
+
+#ifndef Z_BUFSIZE
+#  ifdef MAXSEG_64K
+#    define Z_BUFSIZE 4096 /* minimize memory usage for 16-bit DOS */
+#  else
+#    define Z_BUFSIZE 16384
+#  endif
+#endif
+#ifndef Z_PRINTF_BUFSIZE
+#  define Z_PRINTF_BUFSIZE 4096
+#endif
+
+#define ALLOC(size) malloc(size)
+
+int    destroy      OF((gz_stream *s));
+
+
+gzFile zip2gz(ZIP* zip, struct zipent* ent)
+{
+    int err;
+    gz_stream *s;
+    const char *path;
+    int transparent = 0;
+    uInt len;
+
+    if (!zip || !ent)
+        return NULL;
+
+    /* zip stuff */
+    if (ent->compression_method == 0x0000)
+    {
+        /* file is not compressed, simply stored */
+
+        /* check if size are equal */
+        if (ent->compressed_size != ent->uncompressed_size) {
+            errormsg("Wrong uncompressed size in store compression", ERROR_CORRUPT,zip->zip);
+            return NULL;
+        }
+
+        transparent = 1;
+    }
+    else if (ent->compression_method == 0x0008)
+    {
+        /* file is compressed using "Deflate" method */
+        if (ent->version_needed_to_extract > 0x14) {
+            errormsg("Version too new", ERROR_UNSUPPORTED,zip->zip);
+            return NULL;
+        }
+
+        if (ent->os_needed_to_extract != 0x00) {
+            errormsg("OS not supported", ERROR_UNSUPPORTED,zip->zip);
+            return NULL;
+        }
+
+        if (ent->disk_number_start != zip->number_of_this_disk) {
+            errormsg("Cannot span disks", ERROR_UNSUPPORTED,zip->zip);
+            return NULL;
+        }
+
+    } else {
+        errormsg("Compression method unsupported", ERROR_UNSUPPORTED, zip->zip);
+        return NULL;
+    }
+
+    /* seek to compressed data */
+    if (seekcompresszip(zip,ent) != 0) {
+        return NULL;
+    }
+
+    path = zip->zip;
+
+    /* normal gzip init for read */
+    s = (gz_stream *)ALLOC(sizeof(gz_stream));
+    if (!s) return Z_NULL;
+
+    s->stream.zalloc = (alloc_func)0;
+    s->stream.zfree = (free_func)0;
+    s->stream.opaque = (voidpf)0;
+    s->stream.next_in = s->inbuf = Z_NULL;
+    s->stream.next_out = s->outbuf = Z_NULL;
+    s->stream.avail_in = s->stream.avail_out = 0;
+    s->file = NULL;
+    s->z_err = Z_OK;
+    s->z_eof = 0;
+    s->in = 0;
+    s->out = 0;
+    s->back = EOF;
+    s->crc = crc32(0L, Z_NULL, 0);
+    s->msg = NULL;
+    s->transparent = transparent;
+    s->mode = 'r';
+
+    s->path = (char*)ALLOC(strlen(path)+1);
+    if (s->path == NULL) {
+        return destroy(s), (gzFile)Z_NULL;
+    }
+    strcpy(s->path, path); /* do this early for debugging */
+
+    s->stream.next_in  = s->inbuf = (Byte*)ALLOC(Z_BUFSIZE);
+
+    err = inflateInit2(&(s->stream), -MAX_WBITS);
+    /* windowBits is passed < 0 to tell that there is no zlib header.
+     * Note that in this case inflate *requires* an extra "dummy" byte
+     * after the compressed stream in order to complete decompression and
+     * return Z_STREAM_END. Here the gzip CRC32 ensures that 4 bytes are
+     * present after the compressed stream.
+     */
+    if (err != Z_OK || s->inbuf == Z_NULL) {
+        return destroy(s), (gzFile)Z_NULL;
+    }
+    s->stream.avail_out = Z_BUFSIZE;
+
+    errno = 0;
+    s->file = zip->fp;
+    if (s->file == NULL) {
+        return destroy(s), (gzFile)Z_NULL;
+    }
+
+    /* check_header(s); */
+    errno = 0;
+    len = (uInt)fread(s->inbuf, 1, Z_BUFSIZE, s->file);
+    if (len == 0 && ferror(s->file)) s->z_err = Z_ERRNO;
+    s->stream.avail_in += len;
+    s->stream.next_in = s->inbuf;
+    if (s->stream.avail_in < 2) {
+        return destroy(s), (gzFile)Z_NULL;
+    }
+
+    s->start = ftell(s->file) - s->stream.avail_in;
+
+    return (gzFile)s;
+}
+
+
+int gzerror2(gzFile file)
+{
+    gz_stream *s = (gz_stream*)file;
+
+    if (s == NULL)
+        return Z_STREAM_ERROR;
+
+    return s->z_err;
+}
+
+
diff --git a/unzip/unzip_stream.h b/unzip/unzip_stream.h
new file mode 100644 (file)
index 0000000..59ff2fa
--- /dev/null
@@ -0,0 +1,4 @@
+
+gzFile zip2gz(ZIP* zip, struct zipent* ent);
+int gzerror2(gzFile file);
+
index 7e90f49..02a0a01 100644 (file)
@@ -77,7 +77,8 @@ local gzFile gz_open      OF((const char *path, const char *mode, int  fd));
 local int do_flush        OF((gzFile file, int flush));
 local int    get_byte     OF((gz_stream *s));
 local void   check_header OF((gz_stream *s));
-local int    destroy      OF((gz_stream *s));
+//local
+      int    destroy      OF((gz_stream *s));
 local void   putLong      OF((FILE *file, uLong x));
 local uLong  getLong      OF((gz_stream *s));
 
@@ -352,7 +353,8 @@ local void check_header(s)
  * Cleanup then free the given gz_stream. Return a zlib error code.
    Try freeing in the reverse order of allocations.
  */
-local int destroy (s)
+//local
+int destroy (s)
     gz_stream *s;
 {
     int err = Z_OK;