From 892b1f6c68346fa00dc3029ab8bd31178e730509 Mon Sep 17 00:00:00 2001 From: notaz Date: Sun, 10 Jun 2007 20:27:31 +0000 Subject: [PATCH] ips patches, 0.4 r162 rel? git-svn-id: file:///home/notaz/opt/svn/fceu@162 be3aeb3a-fb24-0410-a615-afba39da0efa --- drivers/gp2x/main.c | 2 +- drivers/gp2x_test/minimal.c | 19 +++++ fce.c | 29 +++++-- file.c | 153 +++++++++++++++++++++++++++++++++++- file.h | 3 + out_gp2x/gpfce.man.txt | 17 ++-- out_gp2x/readme.txt | 30 +++++-- 7 files changed, 229 insertions(+), 24 deletions(-) diff --git a/drivers/gp2x/main.c b/drivers/gp2x/main.c index 5926da7..92094c0 100644 --- a/drivers/gp2x/main.c +++ b/drivers/gp2x/main.c @@ -401,7 +401,7 @@ int CLImain(int argc, char *argv[]) { switch(LoadGameLastError) { default: strcpy(menuErrorMsg, "failed to load ROM"); break; - case 2: strcpy(menuErrorMsg, "Can't find a ROM for movie"); break; + case 2: strcpy(menuErrorMsg, "Can't find a ROM for ips/movie"); break; case 10: strcpy(menuErrorMsg, "FDS BIOS ROM is missing, read docs"); break; case 11: strcpy(menuErrorMsg, "Error reading auxillary FDS file"); break; } diff --git a/drivers/gp2x_test/minimal.c b/drivers/gp2x_test/minimal.c index d2a8982..57c98f6 100644 --- a/drivers/gp2x_test/minimal.c +++ b/drivers/gp2x_test/minimal.c @@ -13,6 +13,7 @@ #include "../gp2x/minimal.h" #include "../gp2x/usbjoy.h" +#include "../gp2x/cpuctrl.h" SDL_Surface *screen; void *gp2x_screen; @@ -92,6 +93,10 @@ void gp2x_video_set_offs(int offs) { } +void gp2x_video_flush_cache(void) +{ +} + void gp2x_memcpy_buffers(int buffers, void *data, int offset, int len) { } @@ -262,6 +267,14 @@ void set_gamma(int g100) { } +void set_LCD_custom_rate(lcd_rate_t rate) +{ +} + +void unset_LCD_custom_rate(void) +{ +} + int mmuhack(void) { @@ -283,6 +296,12 @@ void spend_cycles(int c) usleep(c/200); } +void convert2RGB555(unsigned short *dst, unsigned char *src, unsigned short *pal, int count) +{ + while (count--) + *dst++ = pal[*src++]; +} + /* don't scale, just convert */ void soft_scale(void *dst, unsigned short *pal, int line_offs, int lines) { diff --git a/fce.c b/fce.c index d540aff..89a54a3 100644 --- a/fce.c +++ b/fce.c @@ -1109,7 +1109,7 @@ int NSFLoad(int fp); FCEUGI *FCEUI_LoadGame(char *name) { char name2[512]; - int have_movie = 0; + int have_movie = 0, have_ips = 0; int fp; //Exit=1; @@ -1129,24 +1129,39 @@ FCEUGI *FCEUI_LoadGame(char *name) { char *p = name2 + strlen(name2) - 4; - if (strcmp(p, ".fcm") == 0) + if (strcasecmp(p, ".fcm") == 0) printf("movie detected\n"), have_movie = 1; + if (strcasecmp(p, ".ips") == 0) printf("ips detected\n"), have_ips = 1; + if (have_movie || have_ips) { // movie detected - printf("movie detected\n"); FCEU_fclose(fp); *p = 0; fp=FCEU_fopen(name2,"rb"); - if (!fp && p - name2 > 2) p[-2] = 0; - fp=FCEU_fopen(name2,"rb"); + if (!fp && p - name2 > 2) + { + for (p--; p > name2 && *p != '.'; p--); + *p = 0; + fp=FCEU_fopen(name2,"rb"); + } if (!fp) { - printf("no ROM for movie\n"); + printf("no ROM for ips/movie\n"); LoadGameLastError = 2; return 0; } - have_movie = 1; } } + // do IPS patch + if (have_ips) + { + FCEU_fclose(fp); + FILE *ips = fopen(name, "rb"); + if (!ips) return 0; + fp=FCEU_fopen_forcemem(name2); + if (!fp) { fclose(ips); return 0; } + ApplyIPS(ips, fp); // closes ips + } + GetFileBase(name2); if(iNESLoad(name2,fp)) goto endlseq; diff --git a/file.c b/file.c index 0f47c2a..475b8e4 100644 --- a/file.c +++ b/file.c @@ -32,17 +32,129 @@ #include "endian.h" #include "memory.h" #include "driver.h" +#include "svga.h" static void *desctable[8]={0,0,0,0,0,0,0,0}; static int x; -#ifdef ZLIB - +/* +typedef struct { + uint8 *data; + uint32 size; + uint32 location; +} MEMWRAP; +*/ typedef struct { uint8 *data; uint32 size; uint32 location; } ZIPWRAP; +#define MEMWRAP ZIPWRAP + +void ApplyIPS(FILE *ips, int destf) +{ + uint8 header[5]; + uint32 count=0; + MEMWRAP *dest; + + FCEU_printf(" Applying IPS...\n"); + if(!(destf&0x8000)) + { + FCEU_printf("failed (bad destf).\n"); + return; + } + + dest=(MEMWRAP*)desctable[(destf&255)-1]; + + if(fread(header,1,5,ips)!=5) + { + FCEU_printf("failed (bad header).\n"); + fclose(ips); + return; + } + if(memcmp(header,"PATCH",5)) + { + FCEU_printf("failed (bad header).\n"); + fclose(ips); + return; + } + + while(fread(header,1,3,ips)==3) + { + uint32 offset=(header[0]<<16)|(header[1]<<8)|header[2]; + uint16 size; + + if(!memcmp(header,"EOF",3)) + { + FCEU_printf(" IPS EOF: Did %d patches\n\n",count); + fclose(ips); + return; + } + + size=fgetc(ips)<<8; + size|=fgetc(ips); + if(!size) /* RLE */ + { + uint8 *start; + uint8 b; + size=fgetc(ips)<<8; + size|=fgetc(ips); + + //FCEU_printf(" Offset: %8d Size: %5d RLE\n",offset,size); + + if((offset+size)>dest->size) + { + uint8 *tmp; + + // Probably a little slow. + tmp=(uint8 *)realloc(dest->data,offset+size); + if(!tmp) + { + FCEU_printf(" Oops. IPS patch %d(type RLE) goes beyond end of file. Could not allocate memory.\n",count); + fclose(ips); + return; + } + dest->size=offset+size; + dest->data=tmp; + memset(dest->data+dest->size,0,offset+size-dest->size); + } + b=fgetc(ips); + start=dest->data+offset; + do + { + *start=b; + start++; + } while(--size); + } + else /* Normal patch */ + { + //FCEU_printf(" Offset: %8d Size: %5d\n",offset,size); + if((offset+size)>dest->size) + { + uint8 *tmp; + + // Probably a little slow. + tmp=(uint8 *)realloc(dest->data,offset+size); + if(!tmp) + { + FCEU_printf(" Oops. IPS patch %d(type normal) goes beyond end of file. Could not allocate memory.\n",count); + fclose(ips); + return; + } + dest->data=tmp; + memset(dest->data+dest->size,0,offset+size-dest->size); + } + fread(dest->data+offset,1,size,ips); + } + count++; + } + fclose(ips); + FCEU_printf(" Hard IPS end!\n"); +} + + +#ifdef ZLIB + void *MakeZipWrap(void *tz) { @@ -171,6 +283,43 @@ int FASTAPASS(2) FCEU_fopen(char *path, char *mode) return 0; } +int FASTAPASS(1) FCEU_fopen_forcemem(char *path) +{ + MEMWRAP *tmp; + long size; + int fp; + + fp=FCEU_fopen(path, "rb"); + if (!fp) return 0; + + if (fp&0x8000) return fp; + + if (!(tmp=FCEU_malloc(sizeof(*tmp)))) + goto retr; + + size=FCEU_fgetsize(fp); + if (size <= 0) goto retr; + tmp->size=size; + tmp->data=FCEU_malloc(size); + if (!tmp->data) goto retr; + FCEU_fread(tmp->data, 1, size, fp); + FCEU_fclose(fp); fp=0; + tmp->location=0; + + for(x=0;x<8;x++) + if(!desctable[x]) + { + desctable[x]=tmp; + return (x+1)|0x8000; + } + + retr: + if (fp) FCEU_fclose(fp); + if (tmp && tmp->data) FCEU_free(tmp->data); + if (tmp) FCEU_free(tmp); + return 0; +} + int FASTAPASS(1) FCEU_fclose(int stream) { #ifdef ZLIB diff --git a/file.h b/file.h index fcce1ab..233be1a 100644 --- a/file.h +++ b/file.h @@ -10,5 +10,8 @@ int FASTAPASS(1) FCEU_fgetc(int stream); long FASTAPASS(1) FCEU_fgetsize(int stream); int FASTAPASS(1) FCEU_fisarchive(int stream); +void ApplyIPS(FILE *ips, int destf); +int FASTAPASS(1) FCEU_fopen_forcemem(char *path); + #define FCEUD_UTF8fopen fopen diff --git a/out_gp2x/gpfce.man.txt b/out_gp2x/gpfce.man.txt index 8f177f1..61cd3c0 100644 --- a/out_gp2x/gpfce.man.txt +++ b/out_gp2x/gpfce.man.txt @@ -96,14 +96,19 @@ The .cht files fould be placed into /fceultra/cheats/ direc If you have done everything correctly, Cheat option will appear in the main menu after you load the ROM. You can activate/deactivate cheats by pressing B. For description of .cht file format, see http://fceultra.sourceforge.net/cheat.php +[IPS patch support] +Place the IPS files in the same directory as the ROMs to load, and name them filename.ips or filename.something.ips. Examples: -[FCM movies] -Version 0.4 has partial FCM movie support. Most of the movies desync due to different timing, but some of them can be played. There is only playback support. Files should be placed in the ROMs directory along with the ROMs themselves. Naming is a bit different, the fcm files should have full ROM name in them, with additional .fcm extension added. Examples: + File name: IPS file names: + BigBad.nes BigBad.nes.ips BigBad.nes.somehack.ips + BigBad.zip BigBad.zip.ips BigBad.zip.badhack.ips + BigBad.Better.nes BigBad.Better.nes.ips BigBad.Better.nes.evenbetterhack.ips - File name: Palette file name: - BigBad.nes BigBad.nes.fcm - BigBad.zip BigBad.zip.fcm - BigBad.Better.nes BigBad.Better.nes.fcm +Patching is supported for all supported formats (iNES, FDS, UNIF, and NSF), but it will probably only be useful for the iNES and FDS formats. UNIF files can't be patched well with the IPS format because they are chunk-based with no fixed offsets. + + +[FCM movies] +Version 0.4 has partial FCM movie support. Most of the movies desync due to different timing, but some of them can be played. There is only playback support. Files should be placed in the ROMs directory along with the ROMs themselves. Naming is the same as for IPS patches (see previous section), buf use .fcm extension instead of .ips. [Credits/thanks] diff --git a/out_gp2x/readme.txt b/out_gp2x/readme.txt index 94a7e22..a6cf045 100644 --- a/out_gp2x/readme.txt +++ b/out_gp2x/readme.txt @@ -153,6 +153,24 @@ after you load the ROM. You can activate/deactivate cheats by pressing B. For description of .cht file format, see http://fceultra.sourceforge.net/cheat.php +------------------------------------------------------------------ + IPS patch support +------------------------------------------------------------------ + +Place the IPS files in the same directory as the ROM to load, and name them +filename.ips or filename.something.ips. Examples: + + + File name: IPS file names: + BigBad.nes BigBad.nes.ips BigBad.nes.somehack.ips + BigBad.zip BigBad.zip.ips BigBad.zip.badhack.ips + BigBad.Better.nes BigBad.Better.nes.ips BigBad.Better.nes.evenbetterhack.ips + +Patching is supported for all supported formats (iNES, FDS, UNIF, and NSF), but +it will probably only be useful for the iNES and FDS formats. UNIF files can't be +patched well with the IPS format because they are chunk-based with no fixed offsets. + + ------------------------------------------------------------------ FCM movies ------------------------------------------------------------------ @@ -160,13 +178,8 @@ For description of .cht file format, see http://fceultra.sourceforge.net/cheat.p Version 0.4 has partial FCM movie support. Most of the movies desync due to different timing, but some of them can be played. There is only playback support. Files should be placed in the ROMs directory along with the ROMs themselves. -Naming is a bit different, the fcm files should have full ROM name in them, -with additional .fcm extension added. Examples: - - File name: Palette file name: - BigBad.nes BigBad.nes.fcm - BigBad.zip BigBad.zip.fcm - BigBad.Better.nes BigBad.Better.nes.fcm +Naming is the same as for IPS patches (see previous section), buf use .fcm +extension instead of .ips. -------------------------------------------------------------------- @@ -175,7 +188,7 @@ with additional .fcm extension added. Examples: ver 0.4 (by notaz) - rev 15x + rev 162 - Fixed savestate subsections (were causing some mapper data not to be saved). - Fixed an issue of MapIRQHook getting lost after loading a savestate @@ -184,6 +197,7 @@ ver 0.4 (by notaz) - Fixed sound breaking bug after switching it on/off multiple times. - Added "Perfect VSYNC" option, which changes GP2X refresh rate and syncs emu timing to LCD vsync. + - Fixed IPS patch support. rev 153 - Lots of work on the asm core. Timing fixed for some instructions. Some missing undocumented instruction handlers added. Lots of -- 2.39.5