diff --git a/Makefile.gc b/Makefile.gc index 2786675f..58cf2f06 100644 --- a/Makefile.gc +++ b/Makefile.gc @@ -21,7 +21,7 @@ BUILD := build_gc SOURCES := source/fceultra source/fceultra/boards \ source/fceultra/drivers/common source/fceultra/input \ source/fceultra/mappers source/fceultra/mbshare \ - source/ngc source/sz + source/ngc DATA := data INCLUDES := source/fceultra source/ngc LANG := ENGLISH # Supported languages: ENGLISH @@ -29,7 +29,7 @@ LANG := ENGLISH # Supported languages: ENGLISH #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) -DNGC \ +CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE) -DNGC \ -DHAVE_ASPRINTF -DSTDC -DFCEU_VERSION_NUMERIC=9812 \ -D_SZ_ONE_DIRECTORY -D_LZMA_IN_CB -D_LZMA_OUT_READ \ -DLANG_$(LANG) @@ -40,7 +40,7 @@ LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref #--------------------------------------------------------------------------------- # any extra libraries we wish to link with the project #--------------------------------------------------------------------------------- -LIBS := -lmxml -lbba -ltinysmb -lfat -lz -logc -lm -lfreetype +LIBS := -lpng -lmxml -lbba -ltinysmb -lfat -lz -logc -lm -lfreetype #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing diff --git a/Makefile.wii b/Makefile.wii index 874ade77..82be63fd 100644 --- a/Makefile.wii +++ b/Makefile.wii @@ -21,7 +21,7 @@ BUILD := build_wii SOURCES := source/fceultra source/fceultra/boards \ source/fceultra/drivers/common source/fceultra/input \ source/fceultra/mappers source/fceultra/mbshare \ - source/ngc source/sz + source/ngc DATA := data INCLUDES := source/fceultra source/ngc LANG := ENGLISH # Supported languages: ENGLISH @@ -29,7 +29,7 @@ LANG := ENGLISH # Supported languages: ENGLISH #--------------------------------------------------------------------------------- # options for code generation #--------------------------------------------------------------------------------- -CFLAGS = -g -O3 -Wall $(MACHDEP) $(INCLUDE) -DNGC -DWII_DVD \ +CFLAGS = -g -O2 -Wall $(MACHDEP) $(INCLUDE) -DNGC -DWII_DVD \ -DHAVE_ASPRINTF -DSTDC -DFCEU_VERSION_NUMERIC=9812 \ -D_SZ_ONE_DIRECTORY -D_LZMA_IN_CB -D_LZMA_OUT_READ \ -DLANG_$(LANG) @@ -40,7 +40,7 @@ LDFLAGS = -g $(MACHDEP) -Wl,-Map,$(notdir $@).map -Wl,--cref #--------------------------------------------------------------------------------- # any extra libraries we wish to link with the project #--------------------------------------------------------------------------------- -LIBS := -ldi -lmxml -lfat -lwiiuse -lz -lbte -logc -lm -lfreetype -ltinysmb +LIBS := -ldi -lpng -lmxml -lfat -lwiiuse -lz -lbte -logc -lm -lfreetype -ltinysmb #--------------------------------------------------------------------------------- # list of directories containing libraries, this must be the top level containing diff --git a/readme.txt b/readme.txt index bd8e4771..1af56eff 100644 --- a/readme.txt +++ b/readme.txt @@ -1,26 +1,26 @@ ¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤ - FCE Ultra GX - - Version 2.0.4 - http://code.google.com/p/fceugc + Version 2.0.2 (Under GPL License) ¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤ - + +-=[ Explanation ]=- + FCE Ultra GX is a modified port of the FCE Ultra 0.98.12 Nintendo Entertainment system for x86 (Windows/Linux) PC's. With it you can play NES games on your Wii/GameCube. Version 2 is a complete rewrite based on code from the -SNES9x GX project. +SNES9x GX and Genesis Plus GX projects. -=[ Features ]=- * Wiimote, Nunchuk, Classic, and Gamecube controller support -* iNES, FDS, VS, UNIF, and NSF ROM support -* 1-4 Player Support +* 1-2 Player Support * Zapper support * RAM and State saving * Custom controller configurations -* SD, USB, DVD, SMB, GC Memory Card, Zip, and 7z support +* SD, USB, DVD, SMB, GC Memory Card, and Zip support * NES Compatibility Based on v0.98.12 * Sound Filters * Graphics Filters (GX Chipset, Cheesy and 2x) @@ -29,32 +29,14 @@ SNES9x GX project. |0O×øo· UPDATE HISTORY ·oø×O0| `¨•¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨' -[What's New 2.0.4 - October 15, 2008] -* Wii DVD fixed -* FDS BIOS loading works now -* FDS disk switching now consistently works with one button press -* FDS saving implemented -* 7z support -* Faster SD/USB (readahead cache enabled) -* VS coin now mapped to 1 button for VS zapper games -* Changed GC controller mappings - Select - Z, Start - Start, - Home - Start+A, Special - L - -[What's New 2.0.3 - October 1, 2008] -* Complete rewrite of loading code - FDS / UNIF / NSF support added! -* VS games work (coin insert submitted by pakitovic) -* Mapping of 'Special' commands - VS coin insert, FDS switch disk (default A) -* 480p and DVD now available for GameCube -* Improved stability - less crashes! - -[What's New 2.0.2 - September 19, 2008] +[What's New 2.0.2] * Fixed network freeze-up problem * Zapper now mapped to A and B * Fixed auto-save feature * Performance slowdowns on Gamecube should be fixed * Will now attempt to load old save states with CRC filename -[What's New 2.0.1 - September 6, 2008] +[What's New 2.0.1] * Zapper support! Turn this on in the Controller Settings - most games require you to have the Zapper on Port 2. Thanks go to aksommerville whose previous work on the Zapper helped, and michniewski's cursor code @@ -64,7 +46,7 @@ SNES9x GX project. * Start/Select reversed mapping fixed for Wii controllers * Small bug fixes / improvements / tweaks -[What's New 2.0.0 - September 1, 2008] +[What's New 2.0.0] * Complete rewrite based on code from SNES9x GX and Genesis Plus GX * Wiimote, Nunchuk, and Classic controller support @@ -105,8 +87,8 @@ Loading / Running the Emulator: Wii - Via Homebrew Channel: -------------------- The most popular method of running homebrew on the Wii is through the Homebrew -Channel. If you already have the channel installed, just copy over the apps -folder included in the archive into the root of your SD card. +Channel. If you already have the channel installed, just copy over the apps folder +included in the archive into the root of your SD card. Remember to also create the fceugx directory structure required. See above. @@ -144,15 +126,6 @@ You can load roms from DVD or SD card. If you create a bootable DVD of FCEUGX you can put roms on the same DVD. You may save preferences and game data to SD or Memory Card. --=[ Famicom Disk System (FDS) ]=- - -FCE Ultra GX supports loading FDS games. The FDS BIOS is required - put it -in your roms folder, and name it disksys.rom (should be 8 KB in size). -You can switch disks using the A button (by default). The mapped button -can be changed under Controller Configuration ('Special' button). -Compatibility is limited, so check that the game in question works on -FCE Ultra 0.98.12 for Windows before asking for help. - -=[ Supported Mappers ]=- Mappers are the way the Nintendo handles switching from ROM/VROM so the more @@ -175,6 +148,59 @@ Palette - The colors used while viewing the game: zaphod-smb . vs-drmar . vs-cv . vs-smb Timing - NTSC or PAL (Depends if you're running a PAL or NTSC game) + +×—–­—–­—–­—–­ –­—–­—–­—–­—–­—–­—–­—–­—–­—–­— ­—–­—–­—–­—–­—–­—–­—–­—-­—–­-–•¬ +|0O×øo· UPDATE HISTORY (1.0.x) ·oø×O0| +`¨•¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨¨ ¨¨¨¨¨¨¨¨¨¨¨¨¨' + +What's new [20080331] + ++[Askot] +- Fixed/changed SDCARD slot selection for searching roms, at + start you will be prompted for this option. +- Code cleanup. + ++[dsbomb] +- Added Wii mode support. +- Give a "Bad cartridge" error instead of locking up. +- Joystick fixes due to libogc r14's changed stick values +- Rearranged menu to make more sense, and consistent with Snes9x +- Add "Reboot" menu option +- Removed "." directory from SD card listing, it's pointless +- Expand DVD reading to DVD9 size (once DVDs are working again) +- Added option to go back a menu by pressing B. + +What's new? Askot [20080326] +- Added saving state in SD Card (State files will be saved in root of SDCARD). + *Note: I can't make it work to save in root:\fceu\saves, so help needed. +- Added SDCARD slot selection for searching roms, meaning, you can search roms + from SDCARD SLOT A & SLOT B (Beta, meaning, buggy, but works). +- For standarization, you must create folders root:\fceu\roms to read NES + roms files from SDCARD. +- Added C-Left to call Menu. +- Reading files from SD Card it's faster, now they're called from cache + after first reading. +- Menu in saving STATE file changed to choose SLOT, DEVICE, Save STATE, + Load STATE, Return to previous. +- Added option PSO/SD Reload to menu, still works (START+B+X) +- Modified controls when going into the rom selection menu (DVD or + SDCARD): + + Use B to quit selection list. + + Use L/R triggrers or Pad Left/Right to go down/up one full page. +- Some menu rearrangment and a little of sourcecode cleanup: + + Everytime you pressed B button on any option, playgame started, not anymore + until you select Play Game option. + +What's new? asako [20070831] +- modify mmc3 code for Chinese pirated rom +- add some Chinese pirated rom mappers + +What's new? _svpe_ [20070607] +- Wii support (PAL50 fix, 1.35GiB restriction removed) +- 7zip ROM loading support from the DVD (not from a SD card!!) +- dvd_read fix (the read data was always copied to readbuffer instead of *dst) +- slower file selection when using the D-Pad (I didn't like the selection to go +as fast as in the latest release) ¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤°`°¤ø,¸,ø¤°`°¤ø,¸¸,ø¤ diff --git a/source/fceultra/fceu.c b/source/fceultra/fceu.c index 6fe6db9d..4f2c856f 100644 --- a/source/fceultra/fceu.c +++ b/source/fceultra/fceu.c @@ -424,7 +424,7 @@ FCEUS FSettings; void FCEU_printf(char *format, ...) { - /*char temp[2048]; + char temp[2048]; va_list ap; @@ -432,12 +432,12 @@ void FCEU_printf(char *format, ...) vsprintf(temp,format,ap); FCEUD_Message(temp); - va_end(ap);*/ + va_end(ap); } void FCEU_PrintError(char *format, ...) { -/* char temp[2048]; + char temp[2048]; va_list ap; @@ -445,7 +445,7 @@ void FCEU_PrintError(char *format, ...) vsprintf(temp,format,ap); FCEUD_PrintError(temp); - va_end(ap);*/ + va_end(ap); } void FCEUI_SetRenderedLines(int ntscf, int ntscl, int palf, int pall) diff --git a/source/fceultra/fds.c b/source/fceultra/fds.c index 66c5e8a4..5a98d6b5 100644 --- a/source/fceultra/fds.c +++ b/source/fceultra/fds.c @@ -67,7 +67,7 @@ static int32 IRQLatch,IRQCount; static uint8 IRQa; static void FDSClose(void); -uint8 FDSBIOS[8192]; +static uint8 FDSBIOS[8192]; /* Original disk data backup, to help in creating save states. */ static uint8 *diskdatao[8]={0,0,0,0,0,0,0,0}; @@ -93,7 +93,7 @@ void FDSGI(int h) } static void FDSStateRestore(int version) -{ +{ int x; setmirror(((FDSRegs[5]&8)>>3)^1); @@ -132,7 +132,7 @@ static void FDSInit(void) SetReadHandler(0x4032,0x4032,FDSRead4032); SetReadHandler(0x4033,0x4033,FDSRead4033); - SetWriteHandler(0x4020,0x4025,FDSWrite); + SetWriteHandler(0x4020,0x4025,FDSWrite); SetWriteHandler(0x6000,0xdfff,FDSRAMWrite); SetReadHandler(0x6000,0xdfff,FDSRAMRead); @@ -148,10 +148,10 @@ void FCEU_FDSInsert(int oride) { if(InDisk==255) { - FCEU_DispMessage("Disk %d Side %s Inserted",SelectDisk>>1,(SelectDisk&1)?"B":"A"); + FCEU_DispMessage("Disk %d Side %s Inserted",SelectDisk>>1,(SelectDisk&1)?"B":"A"); InDisk=SelectDisk; } - else + else { FCEU_DispMessage("Disk %d Side %s Ejected",SelectDisk>>1,(SelectDisk&1)?"B":"A"); InDisk=255; @@ -187,14 +187,14 @@ static void FP_FASTAPASS(1) FDSFix(int a) IRQCount=IRQLatch=0; } else - IRQCount=IRQLatch; + IRQCount=IRQLatch; //IRQCount=IRQLatch; //0xFFFF; X6502_IRQBegin(FCEU_IQEXT); //printf("IRQ: %d\n",timestamp); // printf("IRQ: %d\n",scanline); } } - if(DiskSeekIRQ>0) + if(DiskSeekIRQ>0) { DiskSeekIRQ-=a; if(DiskSeekIRQ<=0) @@ -239,14 +239,14 @@ static DECLFR(FDSRead4031) return z; } static DECLFR(FDSRead4032) -{ +{ uint8 ret; ret=X.DB&~7; if(InDisk==255) ret|=5; - if(InDisk==255 || !(FDSRegs[5]&1) || (FDSRegs[5]&2)) + if(InDisk==255 || !(FDSRegs[5]&1) || (FDSRegs[5]&2)) ret|=2; return ret; } @@ -345,7 +345,7 @@ static DECLFW(FDSSWrite) A-=0x4080; switch(A) { - case 0x0: + case 0x0: case 0x4: if(V&0x80) amplitude[(A&0xF)>>2]=V&0x3F; //)>0x20?0x20:(V&0x3F); break; @@ -361,7 +361,7 @@ static DECLFW(FDSSWrite) break; } //if(A>=0x7 && A!=0x8 && A<=0xF) - //if(A==0xA || A==0x9) + //if(A==0xA || A==0x9) //printf("$%04x:$%02x\n",A,V); SPSG[A]=V; } @@ -428,7 +428,7 @@ static INLINE void ClockRise(void) b19shiftreg60=(SPSG[0x2]|((SPSG[0x3]&0xF)<<8)); b17latch76=(SPSG[0x6]|((SPSG[0x07]&0xF)<<8))+b17latch76; - if(!(SPSG[0x7]&0x80)) + if(!(SPSG[0x7]&0x80)) { int t=fdso.mwave[(b17latch76>>13)&0x1F]&7; int t2=amplitude[1]; @@ -448,13 +448,13 @@ static INLINE void ClockRise(void) b8shiftreg88=0x80 + adj; } else - { + { b8shiftreg88=0x80; } } else { - b19shiftreg60<<=1; + b19shiftreg60<<=1; b8shiftreg88>>=1; } // b24adder66=(b24latch68+b19shiftreg60)&0x3FFFFFF; @@ -484,7 +484,7 @@ static INLINE int32 FDSDoSound(void) if(fdso.envcount<=0) { fdso.envcount+=SPSG[0xA]*3; - DoEnv(); + DoEnv(); } } if(fdso.count>=32768) goto dogk; @@ -523,7 +523,7 @@ static void RenderSound(void) static void RenderSoundHQ(void) { int32 x; - + if(!(SPSG[0x9]&0x80)) for(x=FBC;xtype=GIT_FDS; @@ -815,7 +817,7 @@ int FDSLoad(const char *name, FCEUFILE *fp) for(x=0;x>4); + MapperNo|=(head.ROM_type2&0xF0); + Mirroring = (head.ROM_type&1); + + if(head.ROM_type&8) Mirroring=2; + + if(!(ROM=(uint8 *)FCEU_malloc(ROM_size<<14))) + return 0; + + if (VROM_size) + if(!(VROM=(uint8 *)FCEU_malloc(VROM_size<<13))) + { + free(ROM); + return 0; + } + + memset(ROM,0xFF,ROM_size<<14); + if(VROM_size) memset(VROM,0xFF,VROM_size<<13); + if(head.ROM_type&4) /* Trainer */ + { + trainerpoo=(uint8 *)FCEU_gmalloc(512); + memcpy(trainerpoo, &nesrom[memoffs], 512); + memoffs+=512; + //FCEU_fread(trainerpoo,512,1,fp); + } + + ResetCartMapping(); + ResetExState(0,0); + + SetupCartPRGMapping(0,ROM,ROM_size*0x4000,0); + SetupCartPRGMapping(1,WRAM,8192,1); + + //FCEU_fread(ROM,0x4000,head.ROM_size,fp); + memcpy(ROM, &nesrom[memoffs], head.ROM_size * 0x4000); + memoffs += ( head.ROM_size * 0x4000 ); + + if(VROM_size){ + //FCEU_fread(VROM,0x2000,head.VROM_size,fp); + memcpy(VROM, &nesrom[memoffs], 0x2000 * head.VROM_size); + memoffs += ( head.VROM_size * 0x2000 ); + } + + md5_starts(&md5); + md5_update(&md5,ROM,ROM_size<<14); + + iNESGameCRC32=CalcCRC32(0,ROM,ROM_size<<14); + + if(VROM_size) + { + iNESGameCRC32=CalcCRC32(iNESGameCRC32,VROM,VROM_size<<13); + md5_update(&md5,VROM,VROM_size<<13); + } + + md5_finish(&md5,iNESCart.MD5); + memcpy(FCEUGameInfo->MD5,iNESCart.MD5,sizeof(iNESCart.MD5)); + + iNESCart.CRC32=iNESGameCRC32; + + SetInput(); + CheckHInfo(); + + { + int x; + uint64 partialmd5=0; + + for(x=0;x<8;x++) + { + partialmd5 |= (uint64)iNESCart.MD5[7-x] << (x*8); + } + + FCEU_VSUniCheck(partialmd5, &MapperNo, &Mirroring); + } + + /* Must remain here because above functions might change value of + VROM_size and free(VROM). + */ + if(VROM_size) + SetupCartCHRMapping(0,VROM,VROM_size*0x2000,0); + + if(Mirroring==2) + SetupCartMirroring(4,1,ExtraNTARAM); + else if(Mirroring>=0x10) + SetupCartMirroring(2+(Mirroring&1),1,0); + else + SetupCartMirroring(Mirroring&1,(Mirroring&4)>>2,0); + + iNESCart.battery=(head.ROM_type&2)?1:0; + iNESCart.mirror=Mirroring; + + if(NewiNES_Init(MapperNo)) + { + + } + else + { + iNESCart.Power=iNESPower; + if(head.ROM_type&2) + { + iNESCart.SaveGame[0]=WRAM; + iNESCart.SaveGameLen[0]=8192; + } + } + + GameInterface=iNESGI; + return 1; +} + diff --git a/source/fceultra/input/cursor.c b/source/fceultra/input/cursor.c index 47db6d8b..f7a5b875 100644 --- a/source/fceultra/input/cursor.c +++ b/source/fceultra/input/cursor.c @@ -1,5 +1,4 @@ #include "share.h" -#include "fceuconfig.h" static uint8 GunSight[]={ 0,0,0,0,0,0,1,0,0,0,0,0,0, @@ -39,27 +38,29 @@ static uint8 FCEUcursor[11*19]= 0,0,0,0,0,0,0,1,1,0,0, }; -void FCEU_DrawGunSight(uint8 *buf, int xc, int yc) { - if (GCSettings.crosshair) { - int x, y; - int c, d; +void FCEU_DrawGunSight(uint8 *buf, int xc, int yc) +{ + int x,y; + int c,d; - for (y = 0; y < 13; y++) - for (x = 0; x < 13; x++) { - uint8 a; - a = GunSight[y * 13 + x]; - if (a) { - c = (yc + y - 7); - d = (xc + x - 7); - if (c >= 0 && d >= 0 && d < 256 && c < 240) { - if (a == 3) - buf[c * 256 + d] = 0xBF - (buf[c * 256 + d] & 0x3F); - else - buf[c * 256 + d] = a - 1; - } - } - } - } + for(y=0;y<13;y++) + for(x=0;x<13;x++) + { + uint8 a; + a=GunSight[y*13+x]; + if(a) + { + c=(yc+y-7); + d=(xc+x-7); + if(c>=0 && d>=0 && d<256 && c<240) + { + if(a==3) + buf[c*256+d]=0xBF-(buf[c*256+d]&0x3F); + else + buf[c*256+d]=a-1; + } + } + } } diff --git a/source/fceultra/state.c b/source/fceultra/state.c index b225ab42..619bf0b1 100644 --- a/source/fceultra/state.c +++ b/source/fceultra/state.c @@ -41,8 +41,8 @@ #include "video.h" -void (*SPreSave)(void); -void (*SPostSave)(void); +static void (*SPreSave)(void); +static void (*SPostSave)(void); static int SaveStateStatus[10]; static int StateShow; @@ -113,15 +113,15 @@ static int SubWrite(FILE *st, SFORMAT *sf) if(sf->s&RLSB) FlipByteOrder(sf->v,sf->s&(~RLSB)); #endif - + fwrite((uint8 *)sf->v,1,sf->s&(~RLSB),st); /* Now restore the original byte order. */ #ifndef LSB_FIRST - if(sf->s&RLSB) + if(sf->s&RLSB) FlipByteOrder(sf->v,sf->s&(~RLSB)); #endif } - sf++; + sf++; } return(acc); @@ -132,9 +132,9 @@ static int WriteStateChunk(FILE *st, int type, SFORMAT *sf) int bsize; fputc(type,st); - + bsize=SubWrite(0,sf); - write32le(bsize,st); + write32le(bsize,st); if(!SubWrite(st,sf)) return(0); return (bsize+5); @@ -235,11 +235,11 @@ int FCEUSS_SaveFP(FILE *st) { static uint32 totalsize; static uint8 header[16]="FCS"; - + memset(header+4,0,13); header[3]=0xFF; FCEU_en32lsb(header + 8, FCEU_VERSION_NUMERIC); - fwrite(header,1,16,st); + fwrite(header,1,16,st); FCEUPPU_SaveState(); FCEUSND_SaveState(); totalsize=WriteStateChunk(st,1,SFCPU); @@ -305,12 +305,12 @@ int FCEUSS_LoadFP(FILE *st) x=ReadStateChunks(st,*(uint32*)(header+4)); if(stateversion<9500) X.IRQlow=0; - + if(GameStateRestore) GameStateRestore(stateversion); if(x) { FCEUPPU_LoadState(stateversion); - FCEUSND_LoadState(stateversion); + FCEUSND_LoadState(stateversion); } return(x); } @@ -348,7 +348,7 @@ int FCEUSS_Load(char *fname) SaveStateStatus[CurrentState]=1; fclose(st); return(1); - } + } else { SaveStateStatus[CurrentState]=1; @@ -418,7 +418,7 @@ void FCEUI_SelectState(int w) CurrentState=w; StateShow=180; FCEU_DispMessage("-select state-"); -} +} void FCEUI_SaveState(char *fname) { @@ -448,7 +448,7 @@ void FCEUI_LoadState(char *fname) if(FCEUSS_SaveFP(fp)) { fclose(fp); - FCEUNET_SendFile(FCEUNPCMD_LOADSTATE, fn); + FCEUNET_SendFile(FCEUNPCMD_LOADSTATE, fn); } else fclose(fp); /*** REMOVED GC V1.0 diff --git a/source/fceultra/unif.c b/source/fceultra/unif.c index 888693ad..a6bfd6a7 100644 --- a/source/fceultra/unif.c +++ b/source/fceultra/unif.c @@ -57,7 +57,7 @@ typedef struct { int (*init)(FCEUFILE *fp); } BFMAPPING; -CartInfo UNIFCart; +static CartInfo UNIFCart; static int vramo; static int mirrortodo; @@ -130,7 +130,7 @@ static int DoMirroring(FCEUFILE *fp) { uint8 t; t=FCEU_fgetc(fp); - mirrortodo=t; + mirrortodo=t; { static char *stuffo[6]={"Horizontal","Vertical","$2000","$2400","\"Four-screen\"","Controlled by Mapper Hardware"}; @@ -268,7 +268,7 @@ static int LoadPRG(FCEUFILE *fp) else FCEU_printf("\n"); - SetupCartPRGMapping(z,malloced[z],t,0); + SetupCartPRGMapping(z,malloced[z],t,0); return(1); } @@ -371,14 +371,14 @@ static BMAPPING bmap[] = { { "CPROM", CPROM_Init,0}, { "CNROM", CNROM_Init,0}, - + //{ "GNROM", GNROM_Init,0}, //{ "NROM", NROM256_Init,0 }, //{ "RROM", NROM128_Init,0 }, //{ "RROM-128", NROM128_Init,0 }, //{ "NROM-128", NROM128_Init,0 }, //{ "NROM-256", NROM256_Init,0 }, - + { "MHROM", MHROM_Init,0}, { "UNROM", UNROM_Init,0}, { "MARIO1-MALEE2", MALEE_Init,0}, @@ -410,13 +410,13 @@ int LoadUNIFChunks(FCEUFILE *fp) for(;;) { t=FCEU_fread(&uchead,1,4,fp); - if(t<4) + if(t<4) { if(t>0) - return 0; + return 0; return 1; } - if(!(FCEU_read32le(&uchead.info,fp))) + if(!(FCEU_read32le(&uchead.info,fp))) return 0; t=0; x=0; @@ -428,7 +428,7 @@ int LoadUNIFChunks(FCEUFILE *fp) if(!bfunc[x].init(fp)) return 0; t=1; - break; + break; } x++; } @@ -484,7 +484,7 @@ static void UNIFGI(int h) if(UNIFchrrama) memset(UNIFchrrama,0,8192); break; case GI_CLOSE: - //FCEU_SaveGameSave(&UNIFCart); + FCEU_SaveGameSave(&UNIFCart); if(UNIFCart.Close) UNIFCart.Close(); FreeUNIF(); @@ -497,7 +497,7 @@ int UNIFLoad(const char *name, FCEUFILE *fp) FCEU_fseek(fp,0,SEEK_SET); FCEU_fread(&unhead,1,4,fp); if(memcmp(&unhead,"UNIF",4)) - return 0; + return 0; ResetCartMapping(); @@ -512,7 +512,7 @@ int UNIFLoad(const char *name, FCEUFILE *fp) { int x; struct md5_context md5; - + md5_starts(&md5); for(x=0;x<32;x++) @@ -531,10 +531,10 @@ int UNIFLoad(const char *name, FCEUFILE *fp) if(!InitializeBoard()) goto aborto; - //FCEU_LoadGameSave(&UNIFCart); + FCEU_LoadGameSave(&UNIFCart); GameInterface=UNIFGI; return 1; - + aborto: FreeUNIF(); diff --git a/source/fceultra/video.c b/source/fceultra/video.c index e0913937..96981f6d 100644 --- a/source/fceultra/video.c +++ b/source/fceultra/video.c @@ -144,13 +144,13 @@ void FCEU_PutImage(void) void FCEU_DispMessage(char *format, ...) { -/* va_list ap; + va_list ap; va_start(ap,format); vsprintf(errmsg,format,ap); va_end(ap); - howlong=180;*/ + howlong=180; } void FCEU_ResetMessages(void) diff --git a/source/ngc/common.h b/source/ngc/common.h index f88a3ea0..22a06336 100644 --- a/source/ngc/common.h +++ b/source/ngc/common.h @@ -35,4 +35,4 @@ extern int eoptions; #define EO_FORCEISCALE 16384 #define EO_NOFOURSCORE 32768 -extern unsigned char * nesrom; +extern unsigned char * nesromptr; diff --git a/source/ngc/dvd.c b/source/ngc/dvd.c index 05f0b19f..765e8a2d 100644 --- a/source/ngc/dvd.c +++ b/source/ngc/dvd.c @@ -14,7 +14,6 @@ #include #include #include -#include #ifdef WII_DVD #include @@ -22,204 +21,77 @@ #include "menudraw.h" #include "gcunzip.h" -#include "fceuconfig.h" -u64 dvddir = 0; // offset of currently selected file or folder -int dvddirlength = 0; // length of currently selected file or folder -u64 dvdrootdir = 0; // offset of DVD root -bool isWii = false; +extern bool isWii; +extern int offset; +extern int selection; +extern FILEENTRIES filelist[MAXFILES]; +extern int maxfiles; +u64 dvddir = 0; +u64 dvdrootdir = 0; +int dvddirlength = 0; #ifdef HW_DOL /** DVD I/O Address base **/ volatile unsigned long *dvd = (volatile unsigned long *) 0xCC006000; #endif -/**************************************************************************** - * dvd_read - * - * Main DVD function, everything else uses this! - * returns: 1 - ok ; 0 - error - ***************************************************************************/ -#define ALIGN_FORWARD(x,align) ((typeof(x))((((uint32_t)(x)) + (align) - 1) & (~(align-1)))) -#define ALIGN_BACKWARD(x,align) ((typeof(x))(((uint32_t)(x)) & (~(align-1)))) + /** Due to lack of memory, we'll use this little 2k keyhole for all DVD operations **/ +unsigned char DVDreadbuffer[2048] ATTRIBUTE_ALIGN (32); +unsigned char dvdbuffer[2048]; + + /** + * dvd_read + * + * The only DVD function we need - you gotta luv gc-linux self-boots! + * returns: 1 - ok ; 0 - error + */ int dvd_read (void *dst, unsigned int len, u64 offset) { + + unsigned char *buffer = (unsigned char *) (unsigned int) DVDreadbuffer; + if (len > 2048) return 0; /*** We only allow 2k reads **/ - // don't read past the end of the DVD (1.5 GB for GC DVD, 4.7 GB for DVD) - if((offset < 0x57057C00) || (isWii && (offset < 0x118244F00LL))) + DCInvalidateRange ((void *) buffer, len); + + if(offset < 0x57057C00 || (isWii == true && offset < 0x118244F00LL)) // don't read past the end of the DVD { - u8 * buffer = (u8 *)memalign(32, 0x8000); - u32 off_size = 0; - DCInvalidateRange ((void *) buffer, len); + #ifdef HW_DOL - #ifdef HW_DOL - 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); - - // Ensure it has completed - if (dvd[0] & 0x4) - return 0; - #else - off_size = offset - ALIGN_BACKWARD(offset,0x800); - if (DI_ReadDVD( - buffer, - (ALIGN_FORWARD(offset + len,0x800) - ALIGN_BACKWARD(offset,0x800)) >> 11, - (u32)(ALIGN_BACKWARD(offset, 0x800) >> 11) - )) - return 0; - #endif + 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); + memcpy (dst, buffer, len); + + if (dvd[0] & 0x4) /* Ensure it has completed */ + return 0; - memcpy (dst, buffer+off_size, len); - free(buffer); return 1; + + #elif WII_DVD + int ret = 1; + ret = DI_ReadDVD(dst, len >> 11, (u32)(offset >> 11)); + if (ret==0) + return 1; + else + return 0; + #endif } return 0; } -/**************************************************************************** - * dvd_buffered_read - * - * the GC's dvd drive only supports offsets and length which are a multiple - * of 32 bytes additionally the max length of a read is 2048 bytes - * this function removes these limitations - * additionally the 7zip SDK does often read data in 1 byte parts from the - * DVD even when it could read 32 bytes. the dvdsf_buffer has been added to - * avoid having to read the same sector over and over again - ***************************************************************************/ - -#define DVD_LENGTH_MULTIPLY 32 -#define DVD_OFFSET_MULTIPLY 32 -#define DVD_MAX_READ_LENGTH 2048 -#define DVD_SECTOR_SIZE 2048 - -unsigned char dvdsf_buffer[DVD_SECTOR_SIZE]; -u64 dvdsf_last_offset = 0; -u64 dvdsf_last_length = 0; - -int dvd_buffered_read(void *dst, u32 len, u64 offset) -{ - int ret = 0; - - // only read data if the data inside dvdsf_buffer cannot be used - if(offset != dvdsf_last_offset || len > dvdsf_last_length) - { - memset(&dvdsf_buffer, '\0', DVD_SECTOR_SIZE); - ret = dvd_read(&dvdsf_buffer, len, offset); - dvdsf_last_offset = offset; - dvdsf_last_length = len; - } - - memcpy(dst, &dvdsf_buffer, len); - return ret; -} - -int dvd_safe_read(void *dst_v, u32 len, u64 offset) -{ - unsigned char buffer[DVD_SECTOR_SIZE]; // buffer for one dvd sector - - // if read size and length are a multiply of DVD_(OFFSET,LENGTH)_MULTIPLY and length < DVD_MAX_READ_LENGTH - // we don't need to fix anything - if(len % DVD_LENGTH_MULTIPLY == 0 && offset % DVD_OFFSET_MULTIPLY == 0 && len <= DVD_MAX_READ_LENGTH) - { - int ret = dvd_buffered_read(buffer, len, offset); - memcpy(dst_v, &buffer, len); - return ret; - } - else - { - // no errors yet -> ret = 0 - // the return value of dvd_read will be OR'd with ret - // because dvd_read does return 1 on error and 0 on success and - // because 0 | 1 = 1 ret will also contain 1 if at least one error - // occured and 0 otherwise ;) - int ret = 0; // return value of dvd_read - - // we might need to fix all 3 issues - unsigned char *dst = (unsigned char *)dst_v; // gcc will not allow to use var[num] on void* types - u64 bytesToRead; // the number of bytes we still need to read & copy to the output buffer - u64 currentOffset; // the current dvd offset - u64 bufferOffset; // the current buffer offset - u64 i, j, k; // temporary variables which might be used for different stuff - // unsigned char buffer[DVD_SECTOR_SIZE]; // buffer for one dvd sector - - currentOffset = offset; - bytesToRead = len; - bufferOffset = 0; - - // fix first issue (offset is not a multiply of 32) - if(offset % DVD_OFFSET_MULTIPLY) - { - // calculate offset of the prior 32 byte position - i = currentOffset - (currentOffset % DVD_OFFSET_MULTIPLY); - - // calculate the offset from which the data of the dvd buffer will be copied - j = currentOffset % DVD_OFFSET_MULTIPLY; - - // calculate the number of bytes needed to reach the next DVD_OFFSET_MULTIPLY byte mark - k = DVD_OFFSET_MULTIPLY - j; - - // maybe we'll only need to copy a few bytes and we therefore don't even reach the next sector - if(k > len) - { - k = len; - } - - // read 32 bytes from the last 32 byte position - ret |= dvd_buffered_read(buffer, DVD_OFFSET_MULTIPLY, i); - - // copy the bytes to the output buffer and update currentOffset, bufferOffset and bytesToRead - memcpy(&dst[bufferOffset], &buffer[j], k); - currentOffset += k; - bufferOffset += k; - bytesToRead -= k; - } - - // fix second issue (more than 2048 bytes are needed) - if(bytesToRead > DVD_MAX_READ_LENGTH) - { - // calculate the number of 2048 bytes sector needed to get all data - i = (bytesToRead - (bytesToRead % DVD_MAX_READ_LENGTH)) / DVD_MAX_READ_LENGTH; - - // read data in 2048 byte sector - for(j = 0; j < i; j++) - { - ret |= dvd_buffered_read(buffer, DVD_MAX_READ_LENGTH, currentOffset); // read sector - memcpy(&dst[bufferOffset], buffer, DVD_MAX_READ_LENGTH); // copy to output buffer - - // update currentOffset, bufferOffset and bytesToRead - currentOffset += DVD_MAX_READ_LENGTH; - bufferOffset += DVD_MAX_READ_LENGTH; - bytesToRead -= DVD_MAX_READ_LENGTH; - } - } - - // fix third issue (length is not a multiply of 32) - if(bytesToRead) - { - ret |= dvd_buffered_read(buffer, DVD_MAX_READ_LENGTH, currentOffset); // read 32 byte from the dvd - memcpy(&dst[bufferOffset], buffer, bytesToRead); // copy bytes to output buffer - } - - //free(tmp); - return ret; - } -} - /** Minimal ISO Directory Definition **/ #define RECLEN 0 /* Record length */ #define EXTENT 6 /* Extent */ @@ -232,18 +104,17 @@ int dvd_safe_read(void *dst_v, u32 len, u64 offset) #define PVDROOT 0x9c static int IsJoliet = 0; -/**************************************************************************** +/** * Primary Volume Descriptor * * The PVD should reside between sector 16 and 31. * This is for single session DVD only. - ***************************************************************************/ + */ int getpvd () { int sector = 16; u32 rootdir32; - unsigned char dvdbuffer[2048]; dvddir = dvddirlength = 0; IsJoliet = -1; @@ -301,7 +172,7 @@ getpvd () * TestDVD() * * Tests if a ISO9660 DVD is inserted and available - ***************************************************************************/ + ****************************************************************************/ bool TestDVD() { @@ -320,15 +191,15 @@ bool TestDVD() return true; } -/**************************************************************************** +/** * getentry * * Support function to return the next file entry, if any * Declared static to avoid accidental external entry. - ***************************************************************************/ + */ static int diroffset = 0; static int -getentry (int entrycount, unsigned char dvdbuffer[]) +getentry (int entrycount) { char fname[512]; /* Huge, but experience has determined this */ char *ptr; @@ -431,7 +302,7 @@ getentry (int entrycount, unsigned char dvdbuffer[]) return 0; } -/**************************************************************************** +/** * parseDVDdirectory * * This function will parse the directory tree. @@ -439,7 +310,7 @@ getentry (int entrycount, unsigned char dvdbuffer[]) * getpvd, a previous parse or a menu selection. * * The return value is number of files collected, or 0 on failure. - ***************************************************************************/ + */ int ParseDVDdirectory () { @@ -448,7 +319,6 @@ ParseDVDdirectory () u64 rdoffset; int len = 0; int filecount = 0; - unsigned char dvdbuffer[2048]; // initialize selection selection = offset = 0; @@ -468,7 +338,7 @@ ParseDVDdirectory () diroffset = 0; - while (getentry (filecount, dvdbuffer)) + while (getentry (filecount)) { if(strlen(filelist[filecount].filename) > 0 && filecount < MAXFILES) filecount++; @@ -484,12 +354,12 @@ ParseDVDdirectory () return filecount; } -/**************************************************************************** - * DirectorySearch - * - * Searches for the directory name specified within the current directory - * Returns the index of the directory, or -1 if not found - ***************************************************************************/ +/** +* DirectorySearch +* +* Searches for the directory name specified within the current directory +* Returns the index of the directory, or -1 if not found +*/ int DirectorySearch(char dir[512]) { int i; @@ -499,14 +369,14 @@ int DirectorySearch(char dir[512]) return -1; } -/**************************************************************************** - * SwitchDVDFolder - * - * Recursively searches for any directory path 'dir' specified - * Also loads the directory contents via ParseDVDdirectory() - * It relies on dvddir, dvddirlength, and filelist being pre-populated - ***************************************************************************/ -bool SwitchDVDFolderR(char * dir, int maxDepth) +/** +* SwitchDVDFolder +* +* Recursively searches for any directory path 'dir' specified +* Also loads the directory contents via ParseDVDdirectory() +* It relies on dvddir, dvddirlength, and filelist being pre-populated +*/ +bool DoSwitchDVDFolder(char * dir, int maxDepth) { if(maxDepth > 8) // only search to a max depth of 8 levels return false; @@ -533,7 +403,7 @@ bool SwitchDVDFolderR(char * dir, int maxDepth) if(lastdir) return true; else - return SwitchDVDFolderR(nextdir, maxDepth++); + return DoSwitchDVDFolder(nextdir, maxDepth++); } return false; } @@ -553,20 +423,20 @@ bool SwitchDVDFolder(char origdir[]) if(dir[strlen(dir)-1] == '/') dir[strlen(dir)-1] = 0; - return SwitchDVDFolderR(dirptr, 0); + return DoSwitchDVDFolder(dirptr, 0); } /**************************************************************************** * LoadDVDFile - * This function will load a file from DVD + * This function will load a file from DVD, in BIN, SMD or ZIP format. * The values for offset and length are inherited from dvddir and * dvddirlength. * - * The buffer parameter should re-use the initial ROM buffer - ***************************************************************************/ + * The buffer parameter should re-use the initial ROM buffer. + ****************************************************************************/ int -LoadDVDFile (unsigned char *buffer, int length) +LoadDVDFile (unsigned char *buffer) { int offset; int blocks; @@ -574,46 +444,35 @@ LoadDVDFile (unsigned char *buffer, int length) u64 discoffset; char readbuffer[2048]; - dvddir = filelist[selection].offset; - dvddirlength = filelist[selection].length; - // How many 2k blocks to read blocks = dvddirlength / 2048; offset = 0; discoffset = dvddir; ShowAction ((char*) "Loading..."); + dvd_read (readbuffer, 2048, discoffset); - if(length > 0) // do a partial read (eg: to check file header) - { - dvd_read (buffer, length, discoffset); - } - else // load whole file + if (!IsZipFile (readbuffer)) { - dvd_read (readbuffer, 2048, discoffset); - - if (IsZipFile (readbuffer)) + for (i = 0; i < blocks; i++) { - return UnZipBuffer (buffer, METHOD_DVD); // unzip from dvd + dvd_read (readbuffer, 2048, discoffset); + memcpy (buffer + offset, readbuffer, 2048); + offset += 2048; + discoffset += 2048; } - else - { - for (i = 0; i < blocks; i++) - { - dvd_read (readbuffer, 2048, discoffset); - memcpy (buffer + offset, readbuffer, 2048); - offset += 2048; - discoffset += 2048; - } - /*** And final cleanup ***/ - if (dvddirlength % 2048) - { - i = dvddirlength % 2048; - dvd_read (readbuffer, 2048, discoffset); - memcpy (buffer + offset, readbuffer, i); - } + /*** And final cleanup ***/ + if (dvddirlength % 2048) + { + i = dvddirlength % 2048; + dvd_read (readbuffer, 2048, discoffset); + memcpy (buffer + offset, readbuffer, i); } } + else + { + return UnZipDVDFile (buffer, discoffset); // unzip from dvd + } return dvddirlength; } @@ -625,7 +484,7 @@ LoadDVDFile (unsigned char *buffer, int length) * memcard interface. * * libOGC tends to foul up if you don't, and sometimes does if you do! - ***************************************************************************/ + ****************************************************************************/ #ifdef HW_DOL void uselessinquiry () { @@ -641,11 +500,7 @@ void uselessinquiry () while (dvd[7] & 1); } -/**************************************************************************** - * dvd_motor_off( ) - * Turns off DVD drive motor so it doesn't make noise (Gamecube only) - ***************************************************************************/ -void dvd_motor_off () +void dvd_motor_off( ) { dvd[0] = 0x2e; dvd[1] = 0; @@ -662,11 +517,11 @@ void dvd_motor_off () dvd[1] = 0; } -/**************************************************************************** - * dvd_driveid - * - * Gets and returns the dvd driveid - ***************************************************************************/ +/** + * dvd_driveid + * + * Gets and returns the dvd driveid +**/ int dvd_driveid() { @@ -690,20 +545,3 @@ int dvd_driveid() #endif -/**************************************************************************** - * SetDVDDriveType() - * - * Sets the DVD drive ID for use to determine disc size (1.5 GB or 4.7 GB) - ***************************************************************************/ -void SetDVDDriveType() -{ - #ifdef HW_RVL - isWii = true; - #else - int drvid = dvd_driveid (); - if ( drvid == 4 || drvid == 6 || drvid == 8 ) - isWii = false; - else - isWii = true; - #endif -} diff --git a/source/ngc/dvd.h b/source/ngc/dvd.h index 2eb6bb48..20d52a29 100644 --- a/source/ngc/dvd.h +++ b/source/ngc/dvd.h @@ -14,16 +14,9 @@ int getpvd (); int ParseDVDdirectory (); -int LoadDVDFile (unsigned char *buffer, int length); +int LoadDVDFile (unsigned char *buffer); bool TestDVD(); int dvd_read (void *dst, unsigned int len, u64 offset); -int dvd_safe_read (void *dst, unsigned int len, u64 offset); bool SwitchDVDFolder(char dir[]); -#ifdef HW_DOL -void dvd_motor_off (); -#endif - -extern u64 dvddir; -extern int dvddirlength; #endif diff --git a/source/ngc/fceuconfig.c b/source/ngc/fceuconfig.c index c0fba05f..b64973fd 100644 --- a/source/ngc/fceuconfig.c +++ b/source/ngc/fceuconfig.c @@ -26,7 +26,6 @@ DefaultSettings () GCSettings.timing = 0; GCSettings.FSDisable = 1; GCSettings.zapper = 0; - GCSettings.crosshair = 1; GCSettings.slimit = 1; GCSettings.screenscaler = 2; diff --git a/source/ngc/fceuconfig.h b/source/ngc/fceuconfig.h index 720686d9..f6b031df 100644 --- a/source/ngc/fceuconfig.h +++ b/source/ngc/fceuconfig.h @@ -15,8 +15,8 @@ void DefaultSettings (); -#define VERSIONNUM "2.0.4" -#define VERSIONSTR "FCE Ultra GX 2.0.4" +#define VERSIONNUM "2.0.2" +#define VERSIONSTR "FCE Ultra GX 2.0.2" #define NOTSILENT 0 #define SILENT 1 @@ -53,7 +53,6 @@ struct SGCSettings{ int timing; int FSDisable; int zapper; - int crosshair; int slimit; int screenscaler; }; diff --git a/source/ngc/fceugc.c b/source/ngc/fceugc.c index 09efb314..22b3fd01 100644 --- a/source/ngc/fceugc.c +++ b/source/ngc/fceugc.c @@ -11,7 +11,6 @@ #include #include -#include #include #include #include @@ -34,7 +33,6 @@ #include #endif -unsigned char * nesrom = NULL; extern bool romLoaded; bool isWii; @@ -42,7 +40,6 @@ uint8 *xbsave=NULL; extern int cleanSFMDATA(); extern void ResetNES(void); -extern uint8 FDSBIOS[8192]; void FCEUD_Update(uint8 *XBuf, int32 *Buffer, int Count); @@ -72,14 +69,11 @@ int main(int argc, char *argv[]) } InitialiseSound(); - fatInit (8, false); + fatInitDefault(); #ifndef HW_RVL DVD_Init(); #endif - // allocate memory to store rom - nesrom = (unsigned char *)malloc(1024*1024*3); // 3 MB should be plenty - /*** Minimal Emulation Loop ***/ if ( !FCEUI_Initialize() ) { printf("Unable to initialize system\n"); @@ -89,8 +83,9 @@ int main(int argc, char *argv[]) FCEUI_SetVidSystem(0); // 0 - NTSC, 1 - PAL FCEUI_SetGameGenie(0); // 0 - OFF, 1 - ON - memset(FDSBIOS, 0, sizeof(FDSBIOS)); // clear FDS BIOS memory cleanSFMDATA(); // clear state data + GCMemROM(); // load color test ROM + romLoaded = false; // we start off with only the color test rom // Set Defaults DefaultSettings(); @@ -123,14 +118,15 @@ int main(int argc, char *argv[]) /**************************************************************************** * FCEU Support Functions to be written ****************************************************************************/ -// File Control +/*** File Control ***/ + + FILE *FCEUD_UTF8fopen(const char *n, const char *m) { - return NULL; - //return(fopen(n,m)); + return(fopen(n,m)); } -// General Logging +/*** General Logging ***/ void FCEUD_PrintError(char *s) { } @@ -139,15 +135,15 @@ void FCEUD_Message(char *text) { } -// main interface to FCE Ultra -void FCEUD_Update(uint8 *XBuf, int32 *Buffer, int32 Count) +/*** VIDEO ***/ +void FCEUD_Update(uint8 *XBuf, int32 *Buffer, int Count) { - PlaySound(Buffer, Count); // play sound - RenderFrame( (char *)XBuf, GCSettings.screenscaler); // output video frame - GetJoy(); // check controller input + PlaySound(Buffer, Count); + RenderFrame( (char *)XBuf, GCSettings.screenscaler ); + GetJoy(); } -// Netplay +/*** Netplay ***/ int FCEUD_SendData(void *data, uint32 len) { return 1; diff --git a/source/ngc/fceuload.c b/source/ngc/fceuload.c index cce6c2d2..cfc1e030 100644 --- a/source/ngc/fceuload.c +++ b/source/ngc/fceuload.c @@ -22,58 +22,25 @@ #include "palette.h" #include "fceu.h" #include "sound.h" -#include "file.h" #include "common.h" #include "pad.h" #include "menudraw.h" -#include "fceuconfig.h" -#include "fileop.h" -#include "filesel.h" -#include "smbop.h" -unsigned char *nesrom; +unsigned char *nesromptr; bool romLoaded = false; extern FCEUGI *FCEUGameInfo; +extern int iNESMemLoad( char *rom ); -#define SAMPLERATE 48000 +extern unsigned char nesrom[]; -FCEUFILE *fceufp = NULL; -MEMWRAP *fceumem = NULL; -unsigned char * fceuFileData = NULL; +#define SAMPLERATE 48000 -void MakeFCEUFile(char * membuffer, int length) +int GCMemROM() { - if(fceufp != NULL) - { - free(fceuFileData); - free(fceumem); - free(fceufp); - fceuFileData = NULL; - fceumem = NULL; - fceufp = NULL; - } - - fceufp =(FCEUFILE *)malloc(sizeof(FCEUFILE)); - fceufp->type=3; - fceumem = (MEMWRAP *)malloc(sizeof(MEMWRAP)); - fceumem->location=0; - fceumem->size=length; - fceuFileData = (unsigned char *)malloc(length); - memcpy(fceuFileData, membuffer, length); - fceumem->data=fceuFileData; - fceufp->fp = fceumem; -} - -extern int FDSLoad(const char *name, FCEUFILE *fp); -extern int iNESLoad(const char *name, FCEUFILE *fp); -extern int UNIFLoad(const char *name, FCEUFILE *fp); -extern int NSFLoad(FCEUFILE *fp); -extern uint8 FDSBIOS[8192]; + nesromptr = &nesrom[0]; -int GCMemROM(int method, int size) -{ ResetGameLoaded(); /*** Allocate and clear GameInfo ***/ @@ -99,58 +66,7 @@ int GCMemROM(int method, int size) InitialisePads(); - MakeFCEUFile((char *)nesrom, size); - - nesGameType = 0; - - if(iNESLoad(NULL, fceufp)) - nesGameType = 1; - else if(UNIFLoad(NULL,fceufp)) - nesGameType = 2; - else if(NSFLoad(fceufp)) - nesGameType = 3; - else - { - // read FDS BIOS into FDSBIOS - should be 8192 bytes - if(FDSBIOS[1] == 0) - { - int biosSize = 0; - char * tmpbuffer = (char *)malloc(64 * 1024); - - char filepath[1024]; - - switch (method) - { - case METHOD_SD: - case METHOD_USB: - sprintf(filepath, "%s/%s/disksys.rom", ROOTFATDIR, GCSettings.LoadFolder); - biosSize = LoadBufferFromFAT(tmpbuffer, filepath, NOTSILENT); - break; - case METHOD_SMB: - sprintf(filepath, "%s/disksys.rom", GCSettings.LoadFolder); - biosSize = LoadBufferFromSMB(tmpbuffer, filepath, 0, NOTSILENT); - break; - } - - if(biosSize == 8192) - { - memcpy(FDSBIOS, tmpbuffer, 8192); - } - else - { - if(biosSize > 0) - WaitPrompt("FDS BIOS file is invalid!"); - - return 0; // BIOS not loaded, do not load game - } - free(tmpbuffer); - } - // load game - if(FDSLoad(NULL,fceufp)) - nesGameType = 4; - } - - if (nesGameType > 0) + if ( iNESMemLoad( (char *)nesromptr ) ) { FCEU_ResetVidSys(); PowerNES(); @@ -158,7 +74,6 @@ int GCMemROM(int method, int size) FCEU_ResetMessages(); // Save state, status messages, etc. SetSoundVariables(); romLoaded = true; - return 1; } else { @@ -166,4 +81,7 @@ int GCMemROM(int method, int size) romLoaded = false; return 0; } + + return 1; } + diff --git a/source/ngc/fceuload.h b/source/ngc/fceuload.h index 6b44b809..138a10d7 100644 --- a/source/ngc/fceuload.h +++ b/source/ngc/fceuload.h @@ -9,4 +9,4 @@ * NES Memory Load Game ****************************************************************************/ -int GCMemROM(int method, int size); +int GCMemROM(); diff --git a/source/ngc/fceuram.c b/source/ngc/fceuram.c index 59fdd7a2..d53e4aee 100644 --- a/source/ngc/fceuram.c +++ b/source/ngc/fceuram.c @@ -41,7 +41,9 @@ extern u32 iNESGameCRC32; extern CartInfo iNESCart; -extern CartInfo UNIFCart; + +extern unsigned char savebuffer[SAVEBUFFERSIZE]; +extern char romFilename[]; int NGCFCEU_GameSave(CartInfo *LocalHWInfo, int operation) { @@ -71,13 +73,6 @@ int NGCFCEU_GameSave(CartInfo *LocalHWInfo, int operation) bool SaveRAM (int method, bool silent) { - if(nesGameType == 4) - { - if(!silent) - WaitPrompt((char *)"Saving is not available for FDS games!"); - return false; - } - ShowAction ((char*) "Saving..."); if(method == METHOD_AUTO) @@ -85,14 +80,10 @@ bool SaveRAM (int method, bool silent) bool retval = false; char filepath[1024]; - int datasize = 0; + int datasize; int offset = 0; - // save game save to savebuffer - if(nesGameType == 1) - datasize = NGCFCEU_GameSave(&iNESCart, 0); - else if(nesGameType == 2) - datasize = NGCFCEU_GameSave(&UNIFCart, 0); + datasize = NGCFCEU_GameSave(&iNESCart, 0); // save game save to savebuffer if ( datasize ) { @@ -136,13 +127,6 @@ bool SaveRAM (int method, bool silent) bool LoadRAM (int method, bool silent) { - if(nesGameType == 4) - { - if(!silent) - WaitPrompt((char *)"Saving is not available for FDS games!"); - return false; - } - ShowAction ((char*) "Loading..."); if(method == METHOD_AUTO) @@ -153,11 +137,9 @@ bool LoadRAM (int method, bool silent) if(method == METHOD_SD || method == METHOD_USB) { - if(ChangeFATInterface(method, NOTSILENT)) - { - sprintf (filepath, "%s/%s/%s.sav", ROOTFATDIR, GCSettings.SaveFolder, romFilename); - offset = LoadSaveBufferFromFAT (filepath, silent); - } + ChangeFATInterface(method, NOTSILENT); + sprintf (filepath, "%s/%s/%s.sav", ROOTFATDIR, GCSettings.SaveFolder, romFilename); + offset = LoadBufferFromFAT (filepath, silent); } else if(method == METHOD_SMB) { @@ -176,11 +158,7 @@ bool LoadRAM (int method, bool silent) if (offset > 0) { - if(nesGameType == 1) - NGCFCEU_GameSave(&iNESCart, 1); - else if(nesGameType == 2) - NGCFCEU_GameSave(&UNIFCart, 1); - + NGCFCEU_GameSave(&iNESCart, 1); // load game save from savebuffer ResetNES(); return 1; } diff --git a/source/ngc/fceustate.c b/source/ngc/fceustate.c index 170d9889..08e74e9f 100644 --- a/source/ngc/fceustate.c +++ b/source/ngc/fceustate.c @@ -52,6 +52,9 @@ extern u32 iNESGameCRC32; int sboffset; /*** Used as a basic fileptr ***/ int mcversion = 0x981211; +extern unsigned char savebuffer[SAVEBUFFERSIZE]; +extern char romFilename[]; + /**************************************************************************** * Memory based file functions ****************************************************************************/ @@ -59,7 +62,7 @@ int mcversion = 0x981211; /*** Open a file ***/ void memopen() { sboffset = 0; - memset(savebuffer, 0, SAVEBUFFERSIZE); + memset(savebuffer, 0, sizeof(savebuffer)); } /*** Close a file ***/ @@ -69,7 +72,7 @@ void memclose() { /*** Write to the file ***/ void memfwrite( void *buffer, int len ) { - if ( (sboffset + len ) > SAVEBUFFERSIZE) + if ( (sboffset + len ) > sizeof(savebuffer)) WaitPrompt("Buffer Exceeded"); if ( len > 0 ) { @@ -81,7 +84,7 @@ void memfwrite( void *buffer, int len ) { /*** Read from a file ***/ void memfread( void *buffer, int len ) { - if ( ( sboffset + len ) > SAVEBUFFERSIZE) + if ( ( sboffset + len ) > sizeof(savebuffer)) WaitPrompt("Buffer exceeded"); if ( len > 0 ) { @@ -221,9 +224,6 @@ int GCSaveChunk(int chunkid, SFORMAT *sf) { * It uses memory for it's I/O and has an added CHNK block. * The file is terminated with CHNK length of 0. ****************************************************************************/ -extern void (*SPreSave)(void); -extern void (*SPostSave)(void); - int GCFCEUSS_Save() { int totalsize = 0; @@ -247,7 +247,6 @@ int GCFCEUSS_Save() /*** And Comments ***/ strncpy (Comment[1],romFilename,31); // we only have 32 chars to work with! - Comment[1][31] = 0; memfwrite(&Comment[0], 64); totalsize += 64; @@ -259,15 +258,8 @@ int GCFCEUSS_Save() totalsize += GCSaveChunk(3, FCEUPPU_STATEINFO); totalsize += GCSaveChunk(4, FCEUCTRL_STATEINFO); totalsize += GCSaveChunk(5, FCEUSND_STATEINFO); - - if(nesGameType == 4) // FDS - SPreSave(); - totalsize += GCSaveChunk(0x10, SFMDATA); - if(nesGameType == 4) // FDS - SPostSave(); - /*** Add terminating CHNK ***/ memfwrite(&chunk,4); memfwrite(&zero,4); @@ -342,13 +334,13 @@ bool LoadState (int method, bool silent) { ChangeFATInterface(method, NOTSILENT); sprintf (filepath, "%s/%s/%s.fcs", ROOTFATDIR, GCSettings.SaveFolder, romFilename); - offset = LoadSaveBufferFromFAT (filepath, silent); + offset = LoadBufferFromFAT (filepath, silent); if(offset == 0) // file not found { // look for CRC save sprintf (filepath, "%08x.fcs", iNESGameCRC32); - offset = LoadSaveBufferFromFAT (filepath, silent); + offset = LoadBufferFromFAT (filepath, silent); } } else if(method == METHOD_SMB) diff --git a/source/ngc/fileop.c b/source/ngc/fileop.c index 42ce9baa..9ad57728 100644 --- a/source/ngc/fileop.c +++ b/source/ngc/fileop.c @@ -23,8 +23,14 @@ #include "menudraw.h" #include "filesel.h" -// FAT file pointer - the only one we should ever use! -FILE * fatfile; +FILE * filehandle; + +extern unsigned char savebuffer[]; +extern char output[16384]; +extern int offset; +extern int selection; +extern char currentdir[MAXPATHLEN]; +extern FILEENTRIES filelist[MAXFILES]; /**************************************************************************** * fat_is_mounted @@ -60,7 +66,6 @@ bool ChangeFATInterface(int method, bool silent) { devFound = true; fatSetDefaultInterface(PI_INTERNAL_SD); - fatEnableReadAhead (PI_INTERNAL_SD, 6, 64); } #endif @@ -87,7 +92,6 @@ bool ChangeFATInterface(int method, bool silent) { devFound = true; fatSetDefaultInterface(PI_USBSTORAGE); - fatEnableReadAhead (PI_USBSTORAGE, 6, 64); } else { @@ -148,7 +152,6 @@ ParseFATdirectory(int method) strncpy(filelist[nbfiles].displayname, filename, MAXDISPLAY+1); // crop name for display filelist[nbfiles].length = filestat.st_size; filelist[nbfiles].flags = (filestat.st_mode & _IFDIR) == 0 ? 0 : 1; // flag this as a dir - filelist[nbfiles].offset = 0; nbfiles++; } } @@ -164,49 +167,44 @@ ParseFATdirectory(int method) /**************************************************************************** * LoadFATFile - * length > 0 - partial file read (starting from start) - * length = 0 - full read - ***************************************************************************/ + ****************************************************************************/ int -LoadFATFile (char * rbuffer, int length) +LoadFATFile (char *filename, int length) { char zipbuffer[2048]; char filepath[MAXPATHLEN]; + FILE *handle; u32 size; - if (!MakeROMPath(filepath, METHOD_SD)) + /* Check filename length */ + if ((strlen(currentdir)+1+strlen(filelist[selection].filename)) < MAXPATHLEN) + sprintf(filepath, "%s/%s",currentdir,filelist[selection].filename); + else { WaitPrompt((char*) "Maximum filepath length reached!"); return -1; } - fatfile = fopen (filepath, "rb"); - if (fatfile > 0) + handle = fopen (filepath, "rb"); + if (handle > 0) { - if(length > 0) // do a partial read (eg: to check file header) + fread (zipbuffer, 1, 2048, handle); + + if (IsZipFile (zipbuffer)) { - fread (rbuffer, 1, length, fatfile); - size = length; + size = UnZipFATFile (nesromptr, handle); // unzip from FAT } - else // load whole file + else { - fread (zipbuffer, 1, 2048, fatfile); - - if (IsZipFile (zipbuffer)) - { - size = UnZipBuffer ((unsigned char *)rbuffer, METHOD_SD); // unzip from FAT - } - else - { - // Just load the file up - fseek(fatfile, 0, SEEK_END); - size = ftell(fatfile); // get filesize - fseek(fatfile, 2048, SEEK_SET); // seek back to point where we left off - memcpy (rbuffer, zipbuffer, 2048); // copy what we already read - fread (rbuffer + 2048, 1, size - 2048, fatfile); - } + // Just load the file up + fseek(handle, 0, SEEK_END); + length = ftell(handle); // get filesize + fseek(handle, 2048, SEEK_SET); // seek back to point where we left off + memcpy (nesromptr, zipbuffer, 2048); // copy what we already read + fread (nesromptr + 2048, 1, length - 2048, handle); + size = length; } - fclose (fatfile); + fclose (handle); return size; } else @@ -214,50 +212,25 @@ LoadFATFile (char * rbuffer, int length) WaitPrompt((char*) "Error opening file"); return 0; } -} -/**************************************************************************** - * LoadFATSzFile - * Loads the selected file # from the specified 7z into rbuffer - * Returns file size - ***************************************************************************/ -int -LoadFATSzFile(char * filepath, unsigned char * rbuffer) -{ - u32 size; - fatfile = fopen (filepath, "rb"); - if (fatfile > 0) - { - size = SzExtractFile(filelist[selection].offset, rbuffer); - fclose (fatfile); - return size; - } - else - { - WaitPrompt((char*) "Error opening file"); - return 0; - } + return 0; } /**************************************************************************** * Load savebuffer from FAT file - ***************************************************************************/ - -// no buffer is specified - so use savebuffer + ****************************************************************************/ int -LoadSaveBufferFromFAT (char *filepath, bool silent) +LoadBufferFromFAT (char *filepath, bool silent) { - return LoadBufferFromFAT((char *)savebuffer, filepath, silent); -} + FILE *handle; + int boffset = 0; + int read = 0; -int -LoadBufferFromFAT (char * sbuffer, char *filepath, bool silent) -{ - int size = 0; + ClearSaveBuffer (); - fatfile = fopen (filepath, "rb"); + handle = fopen (filepath, "rb"); - if (fatfile <= 0) + if (handle <= 0) { if ( !silent ) { @@ -268,14 +241,15 @@ LoadBufferFromFAT (char * sbuffer, char *filepath, bool silent) return 0; } - // Just load the file up - fseek(fatfile, 0, SEEK_END); // go to end of file - size = ftell(fatfile); // get filesize - fseek(fatfile, 0, SEEK_SET); // go to start of file - fread (sbuffer, 1, size, fatfile); - fclose (fatfile); + /*** This is really nice, just load the file and decode it ***/ + while ((read = fread (savebuffer + boffset, 1, 1024, handle)) > 0) + { + boffset += read; + } + + fclose (handle); - return size; + return boffset; } /**************************************************************************** @@ -284,11 +258,13 @@ LoadBufferFromFAT (char * sbuffer, char *filepath, bool silent) int SaveBufferToFAT (char *filepath, int datasize, bool silent) { + FILE *handle; + if (datasize) { - fatfile = fopen (filepath, "wb"); + handle = fopen (filepath, "wb"); - if (fatfile <= 0) + if (handle <= 0) { char msg[100]; sprintf(msg, "Couldn't save %s", filepath); @@ -296,8 +272,10 @@ SaveBufferToFAT (char *filepath, int datasize, bool silent) return 0; } - fwrite (savebuffer, 1, datasize, fatfile); - fclose (fatfile); + fwrite (savebuffer, 1, datasize, handle); + fclose (handle); } + + ClearSaveBuffer (); return datasize; } diff --git a/source/ngc/fileop.h b/source/ngc/fileop.h index 754fa58d..2c6c1848 100644 --- a/source/ngc/fileop.h +++ b/source/ngc/fileop.h @@ -24,13 +24,10 @@ bool ChangeFATInterface(int method, bool silent); int ParseFATdirectory(int method); -int LoadFATFile (char * fbuffer, int length); -int LoadFATSzFile(char * filepath, unsigned char * rbuffer); +int LoadFATFile (char *filename, int length); int SaveBufferToFAT (char *filepath, int datasize, bool silent); -int LoadSaveBufferFromFAT (char *filepath, bool silent); -int LoadBufferFromFAT (char * buffer, char *filepath, bool silent); +int LoadBufferFromFAT (char *filepath, bool silent); extern char currFATdir[MAXPATHLEN]; -extern FILE * fatfile; #endif diff --git a/source/ngc/filesel.c b/source/ngc/filesel.c index f06cf5b8..8f2aba3d 100644 --- a/source/ngc/filesel.c +++ b/source/ngc/filesel.c @@ -29,22 +29,24 @@ #include "memcardop.h" #include "pad.h" #include "fceuload.h" -#include "gcunzip.h" int offset; int selection; char currentdir[MAXPATHLEN]; -char szpath[MAXPATHLEN]; char romFilename[200]; -int nesGameType; int maxfiles; extern int screenheight; +int havedir = -1; +extern u64 dvddir; +extern int dvddirlength; + +int hasloaded = 0; + // Global file entry table FILEENTRIES filelist[MAXFILES]; -bool inSz = false; -unsigned char savebuffer[SAVEBUFFERSIZE]; +unsigned char savebuffer[SAVEBUFFERSIZE] ATTRIBUTE_ALIGN (32); /**************************************************************************** * Clear the savebuffer @@ -163,28 +165,6 @@ int UpdateDirName(int method) } } -bool MakeROMPath(char filepath[], int method) -{ - char temppath[MAXPATHLEN]; - - // Check filename length - if ((strlen(currentdir)+1+strlen(filelist[selection].filename)) < MAXPATHLEN) - { - sprintf(temppath, "%s/%s",currentdir,filelist[selection].filename); - - if(method == METHOD_SMB) - strcpy(filepath, SMBPath(temppath)); - else - strcpy(filepath, temppath); - return true; - } - else - { - filepath[0] = 0; - return false; - } -} - /*************************************************************************** * FileSortCallback * @@ -212,83 +192,6 @@ int FileSortCallback(const void *f1, const void *f2) return stricmp(((FILEENTRIES *)f1)->filename, ((FILEENTRIES *)f2)->filename); } -/**************************************************************************** - * IsValidROM - * - * Checks if the specified file is a valid ROM - * For now we will just check the file extension and file size - * If the file is a zip, we will check the file extension / file size of the - * first file inside - ***************************************************************************/ - -bool IsValidROM(int method) -{ - // file size should be between 10K and 3MB - if(filelist[selection].length < (1024*10) || - filelist[selection].length > (1024*1024*3)) - { - WaitPrompt((char *)"Invalid file size!"); - return false; - } - - if (strlen(filelist[selection].filename) > 4) - { - char * p = strrchr(filelist[selection].filename, '.'); - - if (p != NULL) - { - if(stricmp(p, ".zip") == 0 && !inSz) - { - // we need to check the file extension of the first file in the archive - char * zippedFilename = GetFirstZipFilename (method); - - if(zippedFilename == NULL) // we don't want to run strlen on NULL - p = NULL; - else if(strlen(zippedFilename) > 4) - p = strrchr(zippedFilename, '.'); - else - p = NULL; - } - - if(p != NULL) - { - if ( - stricmp(p, ".nes") == 0 || - stricmp(p, ".fds") == 0 || - stricmp(p, ".nsf") == 0 || - stricmp(p, ".unf") == 0 || - stricmp(p, ".nez") == 0 || - stricmp(p, ".unif") == 0 - ) - { - return true; - } - } - } - } - WaitPrompt((char *)"Unknown file type!"); - return false; -} - -/**************************************************************************** - * IsSz - * - * Checks if the specified file is a 7z - ***************************************************************************/ - -bool IsSz() -{ - if (strlen(filelist[selection].filename) > 4) - { - char * p = strrchr(filelist[selection].filename, '.'); - - if (p != NULL) - if(stricmp(p, ".7z") == 0) - return true; - } - return false; -} - /**************************************************************************** * StripExt * @@ -360,30 +263,10 @@ int FileSelector (int method) { if ( selectit ) selectit = 0; - if (filelist[selection].flags) // This is directory { /* update current directory and set new entry list if directory has changed */ - - int status; - - if(inSz && selection == 0) // inside a 7z, requesting to leave - { - if(method == METHOD_DVD) - { - // go to directory the 7z was in - dvddir = filelist[0].offset; - dvddirlength = filelist[0].length; - } - inSz = false; - status = 1; - SzClose(); - } - else - { - status = UpdateDirName(method); - } - + int status = UpdateDirName(method); if (status == 1) // ok, open directory { switch (method) @@ -413,77 +296,40 @@ int FileSelector (int method) haverom = 1; // quit menu } } - else // this is a file + else // this is a file { - // 7z file - let's open it up to select a file inside - if(IsSz()) + // store the filename (w/o ext) - used for state saving + StripExt(romFilename, filelist[selection].filename); + + ShowAction ((char *)"Loading..."); + + switch (method) { - // we'll store the 7z filepath for extraction later - if(!MakeROMPath(szpath, method)) - { - WaitPrompt((char*) "Maximum filepath length reached!"); - return -1; - } - int szfiles = SzParse(szpath, method); - if(szfiles) - { - maxfiles = szfiles; - inSz = true; - } - else - WaitPrompt((char*) "Error opening archive!"); + case METHOD_SD: + case METHOD_USB: + LoadFATFile (filelist[selection].filename, + filelist[selection].length); + break; + + case METHOD_DVD: + dvddir = filelist[selection].offset; + dvddirlength = filelist[selection].length; + LoadDVDFile (nesromptr); + break; + + case METHOD_SMB: + LoadSMBFile (filelist[selection].filename, + filelist[selection].length); + break; + } + + if (GCMemROM() >= 0) + { + return 1; } else { - // check that this is a valid ROM - if(!IsValidROM(method)) - return 0; - - // store the filename (w/o ext) - used for state saving - StripExt(romFilename, filelist[selection].filename); - - ShowAction ((char *)"Loading..."); - - int size = 0; - - switch (method) - { - case METHOD_SD: - case METHOD_USB: - if(inSz) - size = LoadFATSzFile(szpath, nesrom); - else - size = LoadFATFile((char *)nesrom, 0); - break; - - case METHOD_DVD: - if(inSz) - size = SzExtractFile(filelist[selection].offset, nesrom); - else - size = LoadDVDFile(nesrom, 0); - break; - - case METHOD_SMB: - if(inSz) - size = LoadSMBSzFile(szpath, nesrom); - else - size = LoadSMBFile((char *)nesrom, 0); - break; - } - inSz = false; - - if (size > 0) - { - if(GCMemROM(method, size) > 0) - return 1; - else - return 0; - } - else - { - WaitPrompt((char*) "Error loading ROM!"); - return 0; - } + WaitPrompt((char*) "Error loading ROM!"); } } redraw = 1; @@ -504,8 +350,7 @@ int FileSelector (int method) else if ( strcmp(filelist[1].filename,"..") == 0 ) { selection = selectit = 1; - } else - { + } else { return 0; } } // End of B diff --git a/source/ngc/filesel.h b/source/ngc/filesel.h index 7205807f..c5925dab 100644 --- a/source/ngc/filesel.h +++ b/source/ngc/filesel.h @@ -12,11 +12,9 @@ #ifndef _NGCFILESEL_ #define _NGCFILESEL_ -#include - -#define SAVEBUFFERSIZE (512 * 1024) +#define SAVEBUFFERSIZE (64 * 1024) #define MAXJOLIET 255 -#define MAXDISPLAY 50 +#define MAXDISPLAY 54 typedef struct { @@ -29,17 +27,8 @@ typedef struct #define MAXFILES 2000 // Restrict to 2000 files per dir extern FILEENTRIES filelist[MAXFILES]; -extern bool isWii; -extern int offset; -extern int selection; -extern char currentdir[MAXPATHLEN]; -extern int maxfiles; -extern unsigned char savebuffer[]; -extern char romFilename[]; -extern int nesGameType; void ClearSaveBuffer (); -bool MakeROMPath(char filepath[], int method); int OpenROM (int method); int autoLoadMethod(); int autoSaveMethod(); diff --git a/source/ngc/gcaudio.c b/source/ngc/gcaudio.c index d17dcb5f..2b2feb0c 100644 --- a/source/ngc/gcaudio.c +++ b/source/ngc/gcaudio.c @@ -10,7 +10,6 @@ ****************************************************************************/ #include -#include #define SAMPLERATE 48000 unsigned char audiobuffer[2][64 * 1024] ATTRIBUTE_ALIGN(32); @@ -45,7 +44,7 @@ void InitialiseSound() AUDIO_Init(NULL); /*** Start audio subsystem ***/ AUDIO_SetDSPSampleRate(AI_SAMPLERATE_48KHZ); AUDIO_RegisterDMACallback( AudioSwitchBuffers ); - memset(audiobuffer, 0, (64 * 1024 * 2)); + buffSize[0] = buffSize[1] = 0; } diff --git a/source/ngc/gcunzip.c b/source/ngc/gcunzip.c index 95f8eb47..1b629ce2 100644 --- a/source/ngc/gcunzip.c +++ b/source/ngc/gcunzip.c @@ -14,21 +14,14 @@ #include #include #include - -#include "../sz/7zCrc.h" -#include "../sz/7zIn.h" -#include "../sz/7zExtract.h" - -#include "fceuconfig.h" #include "dvd.h" -#include "smbop.h" -#include "fileop.h" #include "menudraw.h" #include "gcunzip.h" /* * PKWare Zip Header - adopted into zip standard */ +#define PKZIPID 0x504b0304 #define MAXROM 0x500000 #define ZIPCHUNK 2048 @@ -63,28 +56,32 @@ FLIP16 (u16 b) /**************************************************************************** * IsZipFile * - * Returns 1 when Zip signature is found + * Returns TRUE when PKZIPID is first four characters of buffer ****************************************************************************/ int IsZipFile (char *buffer) { unsigned int *check; + check = (unsigned int *) buffer; - if (check[0] == 0x504b0304) // ZIP file + if (check[0] == PKZIPID) return 1; return 0; } /***************************************************************************** - * UnZipBuffer + * unzip * * It should be noted that there is a limit of 5MB total size for any ROM ******************************************************************************/ +FILE* fatfile; // FAT +u64 discoffset; // DVD +SMBFILE smbfile; // SMB int -UnZipBuffer (unsigned char *outbuffer, int method) +UnZipBuffer (unsigned char *outbuffer, short where) { PKZIPHEADER pkzip; int zipoffset = 0; @@ -97,25 +94,22 @@ UnZipBuffer (unsigned char *outbuffer, int method) int have = 0; char readbuffer[ZIPCHUNK]; char msg[128]; - u64 discoffset = 0; - // Read Zip Header - switch (method) + /*** Read Zip Header ***/ + switch (where) { - case METHOD_SD: - case METHOD_USB: - fseek(fatfile, 0, SEEK_SET); - fread (readbuffer, 1, ZIPCHUNK, fatfile); - break; - - case METHOD_DVD: - discoffset = dvddir; - dvd_read (readbuffer, ZIPCHUNK, discoffset); - break; - - case METHOD_SMB: - SMB_ReadFile(readbuffer, ZIPCHUNK, 0, smbfile); - break; + case 0: // SD Card + fseek(fatfile, 0, SEEK_SET); + fread (readbuffer, 1, ZIPCHUNK, fatfile); + break; + + case 1: // DVD + dvd_read (readbuffer, ZIPCHUNK, discoffset); + break; + + case 2: // From SMB + SMB_ReadFile(readbuffer, ZIPCHUNK, 0, smbfile); + break; } /*** Copy PKZip header to local, used as info ***/ @@ -175,26 +169,25 @@ UnZipBuffer (unsigned char *outbuffer, int method) } while (zs.avail_out == 0); - // Readup the next 2k block + /*** Readup the next 2k block ***/ zipoffset = 0; zipchunk = ZIPCHUNK; - switch (method) + switch (where) { - case METHOD_SD: - case METHOD_USB: - fread (readbuffer, 1, ZIPCHUNK, fatfile); - break; - - case METHOD_DVD: - readoffset += ZIPCHUNK; - dvd_read (readbuffer, ZIPCHUNK, discoffset+readoffset); - break; - - case METHOD_SMB: - readoffset += ZIPCHUNK; - SMB_ReadFile(readbuffer, ZIPCHUNK, readoffset, smbfile); - break; + case 0: // SD Card + fread (readbuffer, 1, ZIPCHUNK, fatfile); + break; + + case 1: // DVD + readoffset += ZIPCHUNK; + dvd_read (readbuffer, ZIPCHUNK, discoffset+readoffset); + break; + + case 2: // From SMB + readoffset += ZIPCHUNK; + SMB_ReadFile(readbuffer, ZIPCHUNK, readoffset, smbfile); + break; } } while (res != Z_STREAM_END); @@ -211,49 +204,36 @@ UnZipBuffer (unsigned char *outbuffer, int method) return 0; } - -/**************************************************************************** - * GetFirstZipFilename - * - * Returns the filename of the first file in the zipped archive - * The idea here is to do the least amount of work required - ***************************************************************************/ - -char * -GetFirstZipFilename (int method) +// Reading from FAT +int +UnZipFATFile (unsigned char *outbuffer, FILE* infile) { - char * firstFilename = NULL; - char tempbuffer[ZIPCHUNK]; - - // read start of ZIP - switch (method) - { - case METHOD_SD: // SD Card - case METHOD_USB: // USB - LoadFATFile (tempbuffer, ZIPCHUNK); - break; - - case METHOD_DVD: // DVD - LoadDVDFile ((unsigned char *)tempbuffer, ZIPCHUNK); - break; - - case METHOD_SMB: // From SMB - LoadSMBFile (tempbuffer, ZIPCHUNK); - break; - } + fatfile = infile; + return UnZipBuffer(outbuffer, 0); +} +// Reading from DVD +int +UnZipDVDFile (unsigned char *outbuffer, u64 inoffset) +{ + discoffset = inoffset; + return UnZipBuffer(outbuffer, 1); +} +// Reading from SMB +int +UnZipSMBFile (unsigned char *outbuffer, SMBFILE infile) +{ + smbfile = infile; + return UnZipBuffer(outbuffer, 2); +} - tempbuffer[28] = 0; // truncate - filename length is 2 bytes long (bytes 26-27) - int namelength = tempbuffer[26]; // filename length starts 26 bytes in +/* + * 7-zip functions are below. Have to be written to work with above. - firstFilename = &tempbuffer[30]; // first filename of a ZIP starts 31 bytes in - firstFilename[namelength] = 0; // truncate at filename length - return firstFilename; -} -/**************************************************************************** - * 7z functions - ***************************************************************************/ +#include "7zCrc.h" +#include "7zIn.h" +#include "7zExtract.h" typedef struct _SzFileInStream { @@ -263,6 +243,9 @@ typedef struct _SzFileInStream u64 pos; // current position of the file pointer } SzFileInStream; + + + // 7zip error list char szerrormsg[][30] = { "7z: Data error", @@ -270,8 +253,7 @@ char szerrormsg[][30] = { "7z: CRC Error", "7z: Not implemented", "7z: Fail", - "7z: Archive error", - "7z: Dictionary too large", + "7z: Archive error" }; SZ_RESULT SzRes; @@ -285,66 +267,159 @@ size_t SzBufferSize; size_t SzOffset; size_t SzOutSizeProcessed; CFileItem *SzF; - char sz_buffer[2048]; -int szMethod = 0; - -/**************************************************************************** - * Is7ZipFile - * - * Returns 1 when 7z signature is found - ****************************************************************************/ -int -Is7ZipFile (char *buffer) -{ - unsigned int *check; - check = (unsigned int *) buffer; - // 7z signature - static Byte Signature[6] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; - - int i; - for(i = 0; i < 6; i++) - if(buffer[i] != Signature[i]) - return 0; +// needed because there are no header files -.- +//#include +#define MAXFILES 1000 +#define MAXJOLIET 256 + +extern FILEENTRIES filelist[MAXFILES]; + +extern int selection; +extern int maxfiles; +extern int offset; + +// the GC's dvd drive only supports offsets and length which are a multiply of 32 bytes +// additionally the max length of a read is 2048 bytes +// this function removes these limitations +// additionally the 7zip SDK does often read data in 1 byte parts from the DVD even when +// it could read 32 bytes. the dvdsf_buffer has been added to avoid having to read the same sector +// over and over again +unsigned char dvdsf_buffer[DVD_SECTOR_SIZE]; +u64 dvdsf_last_offset = 0; +u64 dvdsf_last_length = 0; + +int dvd_buffered_read(void *dst, u32 len, u64 offset) { + int ret = 0; + + // only read data if the data inside dvdsf_buffer cannot be used + if(offset != dvdsf_last_offset || len > dvdsf_last_length) { + char msg[1024]; + sprintf(msg, "buff_read: len=%d, offset=%llX, UseSD=%d", len, offset, UseSDCARD); + //WaitPrompt(msg); + memset(&dvdsf_buffer, '\0', DVD_SECTOR_SIZE); + if (UseSDCARD) { + if (filehandle == NULL) + GetSDInfo(); + + fseek(filehandle, offset, SEEK_SET); + fread(&dvdsf_buffer, len, 1, filehandle); + } else if (!UseWiiSDCARD) + ret = dvd_read(&dvdsf_buffer, len, offset); + dvdsf_last_offset = offset; + dvdsf_last_length = len; + } - return 1; // 7z archive found + memcpy(dst, &dvdsf_buffer, len); + return ret; } -// display an error message -void SzDisplayError(SZ_RESULT res) -{ - WaitPrompt(szerrormsg[(res - 1)]); +int dvd_safe_read(void *dst_v, u32 len, u64 offset) { + unsigned char buffer[DVD_SECTOR_SIZE]; // buffer for one dvd sector + + // if read size and length are a multiply of DVD_(OFFSET,LENGTH)_MULTIPLY and length < DVD_MAX_READ_LENGTH + // we don't need to fix anything + if(len % DVD_LENGTH_MULTIPLY == 0 && offset % DVD_OFFSET_MULTIPLY == 0 && len <= DVD_MAX_READ_LENGTH) { + char msg[1024]; + sprintf(msg, "simple_safe_read: len=%d, offset=%llX, UseSD=%d", len, offset, UseSDCARD); + //WaitPrompt(msg); + int ret = dvd_buffered_read(buffer, len, offset); + memcpy(dst_v, &buffer, len); + return ret; + } else { + char msg[1024]; + sprintf(msg, "complex_safe_read: len=%d, offset=%llX, UseSD=%d", len, offset, UseSDCARD); + //WaitPrompt(msg); + // no errors yet -> ret = 0 + // the return value of dvd_read will be OR'd with ret + // because dvd_read does return 1 on error and 0 on success and + // because 0 | 1 = 1 ret will also contain 1 if at least one error + // occured and 0 otherwise ;) + int ret = 0; // return value of dvd_read + + // we might need to fix all 3 issues + unsigned char *dst = (unsigned char *)dst_v; // gcc will not allow to use var[num] on void* types + u64 bytesToRead; // the number of bytes we still need to read & copy to the output buffer + u64 currentOffset; // the current dvd offset + u64 bufferOffset; // the current buffer offset + u64 i, j, k; // temporary variables which might be used for different stuff + // unsigned char buffer[DVD_SECTOR_SIZE]; // buffer for one dvd sector + + currentOffset = offset; + bytesToRead = len; + bufferOffset = 0; + + // fix first issue (offset is not a multiply of 32) + if(offset % DVD_OFFSET_MULTIPLY) { + // calcualte offset of the prior 32 byte position + i = currentOffset - (currentOffset % DVD_OFFSET_MULTIPLY); + + // calculate the offset from which the data of the dvd buffer will be copied + j = currentOffset % DVD_OFFSET_MULTIPLY; + + // calculate the number of bytes needed to reach the next DVD_OFFSET_MULTIPLY byte mark + k = DVD_OFFSET_MULTIPLY - j; + + // maybe we'll only need to copy a few bytes and we therefore don't even reach the next sector + if(k > len) { + k = len; + } + + // read 32 bytes from the last 32 byte position + ret |= dvd_buffered_read(buffer, DVD_OFFSET_MULTIPLY, i); + + // copy the bytes to the output buffer and update currentOffset, bufferOffset and bytesToRead + memcpy(&dst[bufferOffset], &buffer[j], k); + currentOffset += k; + bufferOffset += k; + bytesToRead -= k; + } + + // fix second issue (more than 2048 bytes are needed) + if(bytesToRead > DVD_MAX_READ_LENGTH) { + // calculate the number of 2048 bytes sector needed to get all data + i = (bytesToRead - (bytesToRead % DVD_MAX_READ_LENGTH)) / DVD_MAX_READ_LENGTH; + + // read data in 2048 byte sector + for(j = 0; j < i; j++) { + ret |= dvd_buffered_read(buffer, DVD_MAX_READ_LENGTH, currentOffset); // read sector + memcpy(&dst[bufferOffset], buffer, DVD_MAX_READ_LENGTH); // copy to output buffer + + // update currentOffset, bufferOffset and bytesToRead + currentOffset += DVD_MAX_READ_LENGTH; + bufferOffset += DVD_MAX_READ_LENGTH; + bytesToRead -= DVD_MAX_READ_LENGTH; + } + } + + // fix third issue (length is not a multiply of 32) + if(bytesToRead) { + ret |= dvd_buffered_read(buffer, DVD_MAX_READ_LENGTH, currentOffset); // read 32 byte from the dvd + memcpy(&dst[bufferOffset], buffer, bytesToRead); // copy bytes to output buffer + } + + //free(tmp); + return ret; + } } -// function used by the 7zip SDK to read data from SD/USB/DVD/SMB -SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxRequiredSize, size_t *processedSize) +// function used by the 7zip SDK to read data from the DVD (fread) +SZ_RESULT SzDvdFileReadImp(void *object, void **buffer, size_t maxRequiredSize, size_t *processedSize) { // the void* object is a SzFileInStream SzFileInStream *s = (SzFileInStream *)object; - // calculate offset + // calculate dvd sector offset u64 offset = (u64)(s->offset + s->pos); - if(maxRequiredSize > 2048) - maxRequiredSize = 2048; + if(maxRequiredSize > 2048) + { + maxRequiredSize = 2048; + } // read data - switch(szMethod) - { - case METHOD_SD: - case METHOD_USB: - fseek(fatfile, offset, SEEK_SET); - fread (sz_buffer, 1, maxRequiredSize, fatfile); - break; - case METHOD_DVD: - dvd_safe_read(sz_buffer, maxRequiredSize, offset); - break; - case METHOD_SMB: - SMB_ReadFile(sz_buffer, maxRequiredSize, offset, smbfile); - break; - } - + dvd_safe_read(sz_buffer, maxRequiredSize, offset); *buffer = sz_buffer; *processedSize = maxRequiredSize; s->pos += *processedSize; @@ -352,8 +427,8 @@ SZ_RESULT SzFileReadImp(void *object, void **buffer, size_t maxRequiredSize, siz return SZ_OK; } -// function used by the 7zip SDK to change the filepointer -SZ_RESULT SzFileSeekImp(void *object, CFileSize pos) +// function used by the 7zip SDK to change the filepointer (fseek(object, pos, SEEK_SET)) +SZ_RESULT SzDvdFileSeekImp(void *object, CFileSize pos) { // the void* object is a SzFileInStream SzFileInStream *s = (SzFileInStream *)object; @@ -370,158 +445,126 @@ SZ_RESULT SzFileSeekImp(void *object, CFileSize pos) return SZ_OK; } -/**************************************************************************** - * SzParse - * - * Opens a 7z file, and parses it - * Right now doesn't parse 7z, since we'll always use the first file - * But it could parse the entire 7z for full browsing capability - ***************************************************************************/ - -int SzParse(char * filepath, int method) -{ - int nbfiles = 0; - - // save the offset and the length of this file inside the archive stream structure - SzArchiveStream.offset = filelist[selection].offset; - SzArchiveStream.len = filelist[selection].length; - SzArchiveStream.pos = 0; - - // open file - switch (method) - { - case METHOD_SD: - case METHOD_USB: - fatfile = fopen (filepath, "rb"); - if(!fatfile) - return 0; - break; - case METHOD_SMB: - smbfile = OpenSMBFile(filepath); - if(!smbfile) - return 0; - break; - } +SZ_RESULT SzDvdIsArchive(u64 dvd_offset) { + // 7z signautre + static Byte Signature[6] = {'7', 'z', 0xBC, 0xAF, 0x27, 0x1C}; + Byte Candidate[6]; - // set szMethod to current chosen load method - szMethod = method; + // read the data from the DVD + int res = dvd_safe_read (&Candidate, 6, dvd_offset); + char msg[1024]; - // set handler functions for reading data from FAT/SMB/DVD - SzArchiveStream.InStream.Read = SzFileReadImp; - SzArchiveStream.InStream.Seek = SzFileSeekImp; + size_t i; + for(i = 0; i < 6; i++) { + if(Candidate[i] != Signature[i]) { + return SZE_FAIL; + } + } - // set default 7Zip SDK handlers for allocation and freeing memory - SzAllocImp.Alloc = SzAlloc; - SzAllocImp.Free = SzFree; - SzAllocTempImp.Alloc = SzAllocTemp; - SzAllocTempImp.Free = SzFreeTemp; + return SZ_OK; +} - // prepare CRC and 7Zip database structures - InitCrcTable(); - SzArDbExInit(&SzDb); +// display an error message +void SzDisplayError(SZ_RESULT res) +{ + WaitPrompt(szerrormsg[(res - 1)]); +} - // open the archive - SzRes = SzArchiveOpen(&SzArchiveStream.InStream, &SzDb, &SzAllocImp, - &SzAllocTempImp); +static u64 rootdir; +static int rootdirlength; - if (SzRes != SZ_OK) - { - SzDisplayError(SzRes); - // free memory used by the 7z SDK - SzClose(); - } - else // archive opened successfully - { - if(SzDb.Database.NumFiles > 0) - { - // Parses the 7z into a full file listing +void SzParse(void) { + // save the offset and the length of this file inside the archive stream structure + SzArchiveStream.offset = filelist[selection].offset; + SzArchiveStream.len = filelist[selection].length; + SzArchiveStream.pos = 0; - // erase all previous entries - memset(&filelist, 0, sizeof(FILEENTRIES) * MAXFILES); + // set handler functions for reading data from DVD and setting the position + SzArchiveStream.InStream.Read = SzDvdFileReadImp; + SzArchiveStream.InStream.Seek = SzDvdFileSeekImp; - // add '..' folder in case the user wants exit the 7z - strncpy(filelist[0].displayname, "..", 2); - filelist[0].flags = 1; - filelist[0].offset = dvddir; - filelist[0].length = dvddirlength; + // set default 7Zip SDK handlers for allocation and freeing memory + SzAllocImp.Alloc = SzAlloc; + SzAllocImp.Free = SzFree; + SzAllocTempImp.Alloc = SzAllocTemp; + SzAllocTempImp.Free = SzFreeTemp; - // get contents and parse them into file list structure - unsigned int SzI, SzJ; - SzJ = 1; - for (SzI = 0; SzI < SzDb.Database.NumFiles; SzI++) - { - SzF = SzDb.Database.Files + SzI; - - // skip directories - if (SzF->IsDirectory) - continue; - - // do not exceed MAXFILES to avoid possible buffer overflows - if (SzJ == (MAXFILES - 1)) - break; - - // parse information about this file to the dvd file list structure - strncpy(filelist[SzJ].filename, SzF->Name, MAXJOLIET); // copy joliet name (useless...) - filelist[SzJ].filename[MAXJOLIET] = 0; // terminate string - strncpy(filelist[SzJ].displayname, SzF->Name, MAXDISPLAY+1); // crop name for display - filelist[SzJ].length = SzF->Size; // filesize - filelist[SzJ].offset = SzI; // the extraction function identifies the file with this number - filelist[SzJ].flags = 0; // only files will be displayed (-> no flags) - SzJ++; - } + // prepare CRC and 7Zip database structures + InitCrcTable(); + SzArDbExInit(&SzDb); - // update maxfiles and select the first entry - offset = selection = 0; - nbfiles = SzJ; - } - else - { - SzArDbExFree(&SzDb, SzAllocImp.Free); - } - } + // open the archive + SzRes = SzArchiveOpen(&SzArchiveStream.InStream, &SzDb, &SzAllocImp, &SzAllocTempImp); - // close file - switch (method) - { - case METHOD_SD: - case METHOD_USB: - fclose(fatfile); - break; - case METHOD_SMB: - SMB_CloseFile (smbfile); - break; - } - return nbfiles; + if(SzRes != SZ_OK) + { + // free memory used by the 7z SDK + SzArDbExFree(&SzDb, SzAllocImp.Free); + return; + } + else + { + // archive opened successfully + + // erase all previous entries + memset(&filelist, 0, sizeof(FILEENTRIES) * MAXFILES); + + // add '../' folder + strncpy(filelist[0].filename, "../", 3); + filelist[0].length = rootdirlength; // store rootdir in case the user wants to go one folder up + filelist[0].offset = rootdir; // -''- rootdir length -''- + filelist[0].flags = 0; + + // get contents and parse them into the dvd file list structure + unsigned int SzI, SzJ; + SzJ = 1; + for(SzI = 0; SzI < SzDb.Database.NumFiles; SzI++) + { + SzF = SzDb.Database.Files + SzI; + + // skip directories + if(SzF->IsDirectory) + { + continue; + } + + // do not exceed MAXFILES to avoid possible buffer overflows + if(SzJ == (MAXFILES - 1)) + { + break; + } + + // parse information about this file to the dvd file list structure + strncpy(filelist[SzJ].filename, SzF->Name, MAXJOLIET); // copy joliet name (useless...) + filelist[SzJ].filename[MAXJOLIET] = 0; // terminate string + filelist[SzJ].length = SzF->Size; // filesize + filelist[SzJ].offset = SzI; // the extraction function identifies the file with this number + filelist[SzJ].flags = 0; // only files will be displayed (-> no flags) + SzJ++; + } + + // update maxfiles and select the first entry + maxfiles = SzJ; + offset = selection = 0; + return; + } } -/**************************************************************************** - * SzClose - * - * Closes a 7z file - ***************************************************************************/ - -void SzClose() +void SzClose(void) { - if(SzDb.Database.NumFiles > 0) - SzArDbExFree(&SzDb, SzAllocImp.Free); + SzArDbExFree(&SzDb, SzAllocImp.Free); } -/**************************************************************************** - * SzExtractFile - * - * Extracts the given file # into the buffer specified - * Must parse the 7z BEFORE running this function - ***************************************************************************/ - -int SzExtractFile(int i, unsigned char *buffer) +bool SzExtractROM(int i, unsigned char *buffer) { + // prepare some variables SzBlockIndex = 0xFFFFFFFF; SzOffset = 0; // Unzip the file - ShowAction("Unzipping file. Please wait..."); - + //ShowAction("Un7zipping file. Please wait..."); + WaitPrompt("Un7zipping file. Please wait..."); SzRes = SzExtract2( &SzArchiveStream.InStream, &SzDb, @@ -534,18 +577,18 @@ int SzExtractFile(int i, unsigned char *buffer) &SzAllocImp, &SzAllocTempImp); - // close 7Zip archive and free memory - SzClose(); - // check for errors if(SzRes != SZ_OK) { - // display error message - SzDisplayError(SzRes); - return 0; + // display error message + WaitPrompt(szerrormsg[(SzRes - 1)]); + return false; } else { - return SzOutSizeProcessed; + // close 7Zip archive and free memory + SzArDbExFree(&SzDb, SzAllocImp.Free); + return true; } } +*/ diff --git a/source/ngc/gcunzip.h b/source/ngc/gcunzip.h index 89b8f5f7..907f59d4 100644 --- a/source/ngc/gcunzip.h +++ b/source/ngc/gcunzip.h @@ -15,11 +15,10 @@ #include extern int IsZipFile (char *buffer); -char * GetFirstZipFilename(int method); -int UnZipBuffer (unsigned char *outbuffer, int method); -int SzParse(char * filepath, int method); -int SzExtractFile(int i, unsigned char *buffer); -void SzClose(); + +int UnZipFATFile (unsigned char *outbuffer, FILE* infile); // Reading from FAT +int UnZipDVDFile (unsigned char *outbuffer, u64 inoffset); // Reading from DVD +int UnZipSMBFile (unsigned char *outbuffer, SMBFILE infile); // Reading from SMB /* * Zip file header definition diff --git a/source/ngc/gcvideo.c b/source/ngc/gcvideo.c index dcc75113..1a7eda72 100644 --- a/source/ngc/gcvideo.c +++ b/source/ngc/gcvideo.c @@ -16,14 +16,12 @@ #include #include -#include "driver.h" - #include "gcvideo.h" #include "images/nesback.h" extern unsigned int SMBTimer; -int FDSTimer = 0; -int FDSSwitchRequested; + +//#define FORCE_PAL50 1 #define TEX_WIDTH 256 #define TEX_HEIGHT 512 @@ -62,29 +60,6 @@ static void copy_to_xfb() { copynow = GX_FALSE; } SMBTimer++; - - // FDS switch disk requested - need to eject, select, and insert - // but not all at once! - if(FDSSwitchRequested) - { - switch(FDSSwitchRequested) - { - case 1: - FCEUI_FDSEject(); // eject disk - FDSSwitchRequested++; - break; - case 2: - if(FDSTimer > 60) - { - FCEUI_FDSSelect(); // select other side - FCEUI_FDSInsert(0); // insert disk - FDSSwitchRequested = 0; - FDSTimer = 0; - } - break; - } - FDSTimer++; - } } /**************************************************************************** @@ -241,15 +216,6 @@ void initDisplay() { VIDEO_Init(); vmode = VIDEO_GetPreferredMode(NULL); - -#ifdef HW_DOL -/* we have component cables, but the preferred mode is interlaced - * why don't we switch into progressive? - * on the Wii, the user can do this themselves on their Wii Settings */ - if(VIDEO_HaveComponentCable() && vmode == &TVNtsc480IntDf) - vmode = &TVNtsc480Prog; -#endif - VIDEO_Configure(vmode); screenheight = vmode->xfbHeight; diff --git a/source/ngc/gcvideo.h b/source/ngc/gcvideo.h index 1dcc0656..aafd71b1 100644 --- a/source/ngc/gcvideo.h +++ b/source/ngc/gcvideo.h @@ -26,6 +26,5 @@ struct st_palettes { }; extern struct st_palettes palettes[]; -extern int FDSSwitchRequested; #endif diff --git a/source/ngc/memcardop.c b/source/ngc/memcardop.c index 4f623cc9..5301e567 100644 --- a/source/ngc/memcardop.c +++ b/source/ngc/memcardop.c @@ -22,10 +22,10 @@ #include "menu.h" #include "memcardop.h" #include "fileop.h" -#include "filesel.h" #define VERIFBUFFERSIZE 65536 static u8 SysArea[CARD_WORKAREA] ATTRIBUTE_ALIGN (32); +extern unsigned char savebuffer[]; unsigned char verifbuffer[VERIFBUFFERSIZE] ATTRIBUTE_ALIGN (32); card_dir CardDir; card_file CardFile; diff --git a/source/ngc/menu.c b/source/ngc/menu.c index 4db8a43b..94bdaa9a 100644 --- a/source/ngc/menu.c +++ b/source/ngc/menu.c @@ -76,6 +76,9 @@ LoadManager () if ( loadROM == 1 ) // if ROM was loaded { + if(!GCMemROM()) // ROM was not valid + return 0; + // load the RAM if (GCSettings.AutoLoad == 1) LoadRAM(GCSettings.SaveMethod, SILENT); @@ -84,6 +87,7 @@ LoadManager () ResetNES(); } + return loadROM; } @@ -223,6 +227,12 @@ PreferencesMenu () GCSettings.SaveMethod++; #endif + // check if DVD access in Wii mode is disabled + #ifndef WII_DVD + if(GCSettings.LoadMethod == METHOD_DVD) + GCSettings.LoadMethod++; + #endif + // saving to DVD is impossible if(GCSettings.SaveMethod == METHOD_DVD) GCSettings.SaveMethod++; @@ -241,10 +251,6 @@ PreferencesMenu () GCSettings.SaveMethod++; if(GCSettings.SaveMethod == METHOD_MC_SLOTB) GCSettings.SaveMethod++; - prefmenu[6][0] = '\0'; - #else - sprintf (prefmenu[6], "Verify MC Saves %s", - GCSettings.VerifySaves == true ? " ON" : "OFF"); #endif // correct load/save methods out of bounds @@ -283,6 +289,9 @@ PreferencesMenu () else if (GCSettings.AutoSave == 2) sprintf (prefmenu[5],"Auto Save STATE"); else if (GCSettings.AutoSave == 3) sprintf (prefmenu[5],"Auto Save BOTH"); + sprintf (prefmenu[6], "Verify MC Saves %s", + GCSettings.VerifySaves == true ? " ON" : "OFF"); + ret = RunMenu (prefmenu, prefmenuCount, (char*)"Preferences", 16, -1); switch (ret) @@ -355,16 +364,6 @@ GameMenu () while (quit == 0) { - if(nesGameType == 4) // FDS game - { - // disable RAM saving/loading - gamemenu[3][0] = '\0'; - gamemenu[4][0] = '\0'; - - // disable ROM Information - gamemenu[2][0] = '\0'; - } - // disable RAM/STATE saving/loading if AUTO is on if (GCSettings.AutoLoad == 1) // Auto Load RAM gamemenu[3][0] = '\0'; @@ -534,17 +533,16 @@ GetButtonMap(u16 ctrlr_type, char* btn_name) return pressed; } // end getButtonMap() -int cfg_btns_count = 10; +int cfg_btns_count = 9; char cfg_btns_menu[][50] = { - "B - ", - "A - ", - "SELECT - ", - "START - ", - "UP - ", - "DOWN - ", - "LEFT - ", - "RIGHT - ", - "SPECIAL - ", + "B - ", + "A - ", + "SELECT - ", + "START - ", + "UP - ", + "DOWN - ", + "LEFT - ", + "RIGHT - ", "Return to previous" }; @@ -591,7 +589,7 @@ ConfigureButtons (u16 ctrlr_type) while (quit == 0) { /*** Update Menu with Current ButtonMap ***/ - for (i=0; i 0) - { - J |= nespadmap[i]; - } - else - { - if(nesGameType == 4) // FDS - { - /* the commands shouldn't be issued in parallel so - * we'll delay them so the virtual FDS has a chance - * to process them - */ - FDSSwitchRequested = 1; - } - else - FCEUI_VSUniCoin(); // insert coin for VS Games - } - } - } + J |= nespadmap[i]; } + // zapper enabled if(GCSettings.zapper) { @@ -415,7 +382,6 @@ unsigned char DecodeJoy( unsigned short pad ) #ifdef HW_RVL || (wp & WPAD_BUTTON_A) // wiimote || (wp & WPAD_BUTTON_B) - || (wp & WPAD_CLASSIC_BUTTON_A) // classic controller #endif ) { @@ -423,16 +389,6 @@ unsigned char DecodeJoy( unsigned short pad ) myzappers[z][2] |= 2; } - // VS zapper games - if ( (jp & PAD_BUTTON_B) // gamecube controller - #ifdef HW_RVL - || (wp & WPAD_BUTTON_1) // wiimote - #endif - ) - { - FCEUI_VSUniCoin(); // insert coin for VS zapper games - } - // cursor position UpdateCursorPosition(0); // update cursor for wiimote 1 myzappers[z][0] = pos_x; @@ -447,8 +403,7 @@ unsigned char DecodeJoy( unsigned short pad ) void GetJoy() { - JSReturn = 0; // reset buttons pressed - unsigned char pad[4]; + unsigned char pad[4]; short i; s8 gc_px = PAD_SubStickX (0); @@ -460,7 +415,7 @@ void GetJoy() #endif // request to go back to menu - if ((gc_px < -70) || ((jp & PAD_BUTTON_START) && (jp & PAD_BUTTON_A)) + if ((gc_px < -70) || (jp & PAD_BUTTON_START) #ifdef HW_RVL || (wm_pb & WPAD_BUTTON_HOME) || (wm_pb & WPAD_CLASSIC_BUTTON_HOME) diff --git a/source/ngc/pad.h b/source/ngc/pad.h index 4573b4f1..01e4282a 100644 --- a/source/ngc/pad.h +++ b/source/ngc/pad.h @@ -16,7 +16,7 @@ #define PI 3.14159265f #define PADCAL 50 -#define MAXJP 9 +#define MAXJP 8 extern unsigned int gcpadmap[]; extern unsigned int wmpadmap[]; @@ -27,8 +27,8 @@ s8 WPAD_StickX(u8 chan,u8 right); s8 WPAD_StickY(u8 chan, u8 right); void InitialisePads(); void GetJoy(); -void ToggleFourScore(int set, bool loaded); -void ToggleZapper(int set, bool loaded); +void ToggleFourScore(int set); +void ToggleZapper(int set); void DrawCursor(); #endif diff --git a/source/ngc/preferences.c b/source/ngc/preferences.c index 43d70287..513f4419 100644 --- a/source/ngc/preferences.c +++ b/source/ngc/preferences.c @@ -171,7 +171,6 @@ preparePrefsData (int method) createXMLSetting("FSDisable", "Four Score", toStr(GCSettings.FSDisable)); createXMLSetting("zapper", "Zapper", toStr(GCSettings.zapper)); - createXMLSetting("crosshair", "Zapper Crosshair", toStr(GCSettings.crosshair)); createXMLController(gcpadmap, "gcpadmap", "GameCube Pad"); createXMLController(wmpadmap, "wmpadmap", "Wiimote"); createXMLController(ccpadmap, "ccpadmap", "Classic Controller"); @@ -254,9 +253,9 @@ decodePrefsData (int method) char verMinor = version[15]; char verPoint = version[17]; - if(verMajor == '2' && verPoint < '3') // less than version 2.0.3 + if(verPoint < '2' && verMajor == '2') // less than version 2.0.2 return false; // reset settings - else if(verMajor > '2' || verMinor > '0' || verPoint > '4') // some future version + else if(verMajor > '2' || verMinor > '0' || verPoint > '2') // some future version return false; // reset settings // File Settings @@ -285,7 +284,6 @@ decodePrefsData (int method) loadXMLSettingInt(&GCSettings.slimit, "slimit"); loadXMLSettingInt(&GCSettings.screenscaler, "screenscaler"); loadXMLSettingInt(&GCSettings.zapper, "zapper"); - loadXMLSettingInt(&GCSettings.crosshair, "crosshair"); // Controller Settings loadXMLController(gcpadmap, "gcpadmap"); @@ -304,9 +302,7 @@ decodePrefsData (int method) bool SavePrefs (int method, bool silent) { - // there's no point in saving SMB settings TO SMB, because then we'll have no way to load them the next time! - // so instead we'll save using whatever other method is available (eg: SD) - if(method == METHOD_AUTO || method == METHOD_SMB) + if(method == METHOD_AUTO) method = autoSaveMethod(); char filepath[1024]; @@ -365,7 +361,7 @@ LoadPrefsFromMethod (int method) if(ChangeFATInterface(method, NOTSILENT)) { sprintf (filepath, "%s/%s/%s", ROOTFATDIR, GCSettings.SaveFolder, PREFS_FILE_NAME); - offset = LoadSaveBufferFromFAT (filepath, SILENT); + offset = LoadBufferFromFAT (filepath, SILENT); } } else if(method == METHOD_SMB) diff --git a/source/ngc/rom/ROM.NES b/source/ngc/rom/ROM.NES new file mode 100644 index 00000000..ae87c0d3 Binary files /dev/null and b/source/ngc/rom/ROM.NES differ diff --git a/source/ngc/smbop.c b/source/ngc/smbop.c index 68dd79fb..75db9f52 100644 --- a/source/ngc/smbop.c +++ b/source/ngc/smbop.c @@ -31,12 +31,17 @@ bool networkShareInit = false; unsigned int SMBTimer = 0; #define SMBTIMEOUT ( 3600 ) // Some implementations timeout in 10 minutes -// SMB connection/file handles - the only ones we should ever use! SMBCONN smbconn; -SMBFILE smbfile; - #define ZIPCHUNK 16384 +extern unsigned char savebuffer[]; +extern char output[16384]; +extern int offset; +extern int selection; +extern char currentdir[MAXPATHLEN]; +extern FILEENTRIES filelist[MAXFILES]; + + /**************************************************************************** * InitializeNetwork * Initializes the Wii/GameCube network interface @@ -82,18 +87,12 @@ ConnectShare (bool silent) return false; #endif - ShowAction ((char*) "Connecting..."); - // check that all parameter have been set if(strlen(GCSettings.smbuser) == 0 || strlen(GCSettings.smbpwd) == 0 || strlen(GCSettings.smbshare) == 0 || strlen(GCSettings.smbip) == 0) - { - if(!silent) - WaitPrompt((char*) "Invalid network settings. Check FCEUGX.xml."); return false; - } if(!networkInit) networkInit = InitializeNetwork(silent); @@ -204,7 +203,6 @@ ParseSMBdirectory () filelist[filecount].displayname[MAXDISPLAY] = 0; strcpy (filelist[filecount].filename, smbdir.name); - filelist[filecount].offset = 0; filecount++; } } while (SMB_FindNext (&smbdir, smbconn) == SMB_SUCCESS); @@ -218,58 +216,24 @@ ParseSMBdirectory () return filecount; } -/**************************************************************************** - * Open SMB file - ***************************************************************************/ - -SMBFILE OpenSMBFile(char * filepath) -{ - return SMB_OpenFile (SMBPath(filepath), SMB_OPEN_READING, SMB_OF_OPEN, smbconn); -} - /**************************************************************************** * Load SMB file - * rom - pointer to memory where ROM will be stored - * length - # bytes to read (0 for all) - ***************************************************************************/ + ****************************************************************************/ int -LoadSMBFile (char * rom, int length) +LoadSMBFile (char *filename, int length) { char filepath[MAXPATHLEN]; /* Check filename length */ - if (!MakeROMPath(filepath, METHOD_SMB)) + if ((strlen(currentdir)+1+strlen(filelist[selection].filename)) < MAXPATHLEN) + sprintf(filepath, "%s/%s",currentdir,filelist[selection].filename); + else { WaitPrompt((char*) "Maximum filepath length reached!"); return -1; } - return LoadBufferFromSMB(rom, filepath, length, NOTSILENT); -} - -/**************************************************************************** - * LoadSMBSzFile - * Loads the selected file # from the specified 7z into rbuffer - * Returns file size - ***************************************************************************/ -int -LoadSMBSzFile(char * filepath, unsigned char * rbuffer) -{ - if(!ConnectShare (NOTSILENT)) - return 0; - smbfile = OpenSMBFile(filepath); - - if (smbfile) - { - u32 size = SzExtractFile(filelist[selection].offset, rbuffer); - SMB_CloseFile (smbfile); - return size; - } - else - { - WaitPrompt((char*) "Error opening file"); - return 0; - } + return LoadBufferFromSMB((char *)nesromptr, SMBPath(filepath), NOTSILENT); } /**************************************************************************** @@ -281,6 +245,7 @@ SaveBufferToSMB (char *filepath, int datasize, bool silent) if(!ConnectShare (NOTSILENT)) return 0; + SMBFILE smbfile; int dsize = datasize; int wrote = 0; int boffset = 0; @@ -318,25 +283,29 @@ SaveBufferToSMB (char *filepath, int datasize, bool silent) /**************************************************************************** * Load up a buffer from SMB file - ***************************************************************************/ + ****************************************************************************/ // no buffer is specified - so use savebuffer int LoadSaveBufferFromSMB (char *filepath, bool silent) { - return LoadBufferFromSMB((char *)savebuffer, filepath, 0, silent); + ClearSaveBuffer (); + return LoadBufferFromSMB((char *)savebuffer, filepath, silent); } int -LoadBufferFromSMB (char * sbuffer, char *filepath, int length, bool silent) +LoadBufferFromSMB (char * sbuffer, char *filepath, bool silent) { if(!ConnectShare (NOTSILENT)) return 0; - smbfile = OpenSMBFile(filepath); + SMBFILE smbfile; int ret; int boffset = 0; + smbfile = + SMB_OpenFile (SMBPath(filepath), SMB_OPEN_READING, SMB_OF_OPEN, smbconn); + if (!smbfile) { if(!silent) @@ -348,24 +317,17 @@ LoadBufferFromSMB (char * sbuffer, char *filepath, int length, bool silent) return 0; } - if(length > 0) // do a partial read (eg: to check file header) + ret = SMB_ReadFile (sbuffer, 1024, boffset, smbfile); + + if (IsZipFile (sbuffer)) { - boffset = SMB_ReadFile (sbuffer, length, 0, smbfile); + boffset = UnZipSMBFile ((unsigned char *)sbuffer, smbfile); // unzip from SMB } - else // load whole file + else { - ret = SMB_ReadFile (sbuffer, 1024, boffset, smbfile); - - if (IsZipFile (sbuffer)) - { - boffset = UnZipBuffer ((unsigned char *)sbuffer, METHOD_SMB); // unzip from SMB - } - else - { - // Just load the file up - while ((ret = SMB_ReadFile (sbuffer + boffset, 1024, boffset, smbfile)) > 0) - boffset += ret; - } + // Just load the file up + while ((ret = SMB_ReadFile (sbuffer + boffset, 1024, boffset, smbfile)) > 0) + boffset += ret; } SMB_CloseFile (smbfile); diff --git a/source/ngc/smbop.h b/source/ngc/smbop.h index e356707b..033ca1c6 100644 --- a/source/ngc/smbop.h +++ b/source/ngc/smbop.h @@ -10,22 +10,17 @@ ****************************************************************************/ #ifndef _SMBOP_H_ -#define _SMBOP_H_ -#include +#define _SMBOP_H_ bool InitializeNetwork(bool silent); bool ConnectShare (bool silent); char * SMBPath(char * path); int UpdateSMBdirname(); int ParseSMBdirectory (); -SMBFILE OpenSMBFile(char * filepath); -int LoadSMBFile (char * fbuffer, int length); -int LoadSMBSzFile(char * filepath, unsigned char * rbuffer); +int LoadSMBFile (char *filename, int length); int LoadSaveBufferFromSMB (char *filepath, bool silent); -int LoadBufferFromSMB (char * sbuffer, char *filepath, int length, bool silent); +int LoadBufferFromSMB (char * sbuffer, char *filepath, bool silent); int SaveBufferToSMB (char *filepath, int datasize, bool silent); -extern SMBFILE smbfile; - #endif diff --git a/source/sz/7zDecode.c b/source/sz/7zDecode.c index 12198eea..7b583196 100644 --- a/source/sz/7zDecode.c +++ b/source/sz/7zDecode.c @@ -47,7 +47,7 @@ SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder, #else const Byte *inBuffer, #endif - Byte *outBuffer, size_t outSize, + Byte *outBuffer, size_t outSize, size_t *outSizeProcessed, ISzAlloc *allocMain) { UInt32 si; @@ -109,7 +109,7 @@ SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder, lzmaCallback.InCallback.Read = LzmaReadImp; #endif - if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items, + if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items, coder->Properties.Capacity) != LZMA_RESULT_OK) return SZE_FAIL; @@ -126,7 +126,7 @@ SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder, if (state.Dictionary == 0) { allocMain->Free(state.Probs); - return SZE_OUTOFMEMORYDIC; + return SZE_OUTOFMEMORY; } } LzmaDecoderInit(&state); @@ -157,7 +157,7 @@ SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder, // like SzDecode but uses less memory SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder, ISzInStream *inStream, - Byte *outBuffer, size_t outSize, + Byte *outBuffer, size_t outSize, size_t *outSizeProcessed, ISzAlloc *allocMain, size_t *fileOffset, size_t *fileSize) { @@ -220,7 +220,7 @@ SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder, lzmaCallback.InCallback.Read = LzmaReadImp; #endif - if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items, + if (LzmaDecodeProperties(&state.Properties, coder->Properties.Items, coder->Properties.Capacity) != LZMA_RESULT_OK) return SZE_FAIL; @@ -240,122 +240,116 @@ SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder, } } LzmaDecoderInit(&state); - + // allocate memory for the temporary buffer Byte *tmpBuffer = (Byte *)allocMain->Alloc(_LZMA_TEMP_BUFFER_SIZE); - + // variables containing the number of the first and the last bytes of the buffer - size_t bufferStart, bufferEnd; - bufferStart = bufferEnd = 0; - - // integers contains the offset, the size and the already copied data which will be - // copied from the tmpBuffer to outBuffer - size_t copyOffset, copySize, copyDone; - copyOffset = copySize = copyDone = 0; - - UInt32 i = 0; - int bytesToCopy = 0; - - // decompress data in _LZMA_TEMP_BUFFER_SIZE byte steps and copy the wanted file to outBuffer - do - { - if((*fileSize - copyDone) >= _LZMA_TEMP_BUFFER_SIZE) - bytesToCopy = _LZMA_TEMP_BUFFER_SIZE; - else - bytesToCopy = (*fileSize - copyDone); - - // decompress next bytes - result = LzmaDecode(&state, - #ifdef _LZMA_IN_CB - &lzmaCallback.InCallback, - #else - //inBuffer, (SizeT)inSize, &inProcessed, //TODO! - #endif - tmpBuffer, bytesToCopy, &outSizeProcessedLoc - ); - - // check result - if(result == LZMA_RESULT_DATA_ERROR) - { - return SZE_DATA_ERROR; - } - if(result != LZMA_RESULT_OK) - { - return SZE_FAIL; - } - - // normally this should never happen - if(outSizeProcessedLoc > _LZMA_TEMP_BUFFER_SIZE) - { - return SZE_FAIL; - } - - // update bufferStart and bufferEnd - bufferStart = _LZMA_TEMP_BUFFER_SIZE * i; - bufferEnd = bufferStart + outSizeProcessedLoc; - i++; - - // calculate copy offset and size - if(*fileOffset > bufferEnd) - { - // we haven't reached the start of the file yet - continue; - } - - // calculate offset - if(*fileOffset < bufferStart) - { - // the file has already started before this decompression step - copyOffset = 0; - } - else - { - // the file starts somewhere inside this buffer - copyDone = 0; - copyOffset = _LZMA_TEMP_BUFFER_SIZE - (bufferEnd - *fileOffset); - } - - // calculate size - if((*fileOffset + *fileSize) > bufferEnd) - { - // we'll need the whole buffer after copyOffset - copySize = _LZMA_TEMP_BUFFER_SIZE - copyOffset; - } - else - { - // we'll stop somewhere inside the buffer - copySize = (*fileOffset + *fileSize) - (bufferStart + copyOffset); - } - - // copy bytes to the real output buffer - if(copySize == 0) - { - continue; - } - // printf("memcpy(outBuffer + %d, tmpBuffer + %d, %d)\n", copyDone, copyOffset, copySize); - memcpy(outBuffer + copyDone, tmpBuffer + copyOffset, copySize); - copyDone += copySize; - } - while((*fileOffset + *fileSize) > bufferEnd); - - /* result = LzmaDecode(&state, - #ifdef _LZMA_IN_CB - &lzmaCallback.InCallback, - #else - inBuffer, (SizeT)inSize, &inProcessed, - #endif - outBuffer, (SizeT)outSize, &outSizeProcessedLoc);*/ - //*outSizeProcessed = (size_t)outSizeProcessedLoc; - *outSizeProcessed = copyDone; - allocMain->Free(tmpBuffer); // free the temporary buffer again - allocMain->Free(state.Probs); - allocMain->Free(state.Dictionary); - /* if (result == LZMA_RESULT_DATA_ERROR) - return SZE_DATA_ERROR; - if (result != LZMA_RESULT_OK) - return SZE_FAIL;*/ - return SZ_OK; - } - return SZE_NOTIMPL; - } - #endif + size_t bufferStart, bufferEnd; + bufferStart = bufferEnd = 0; + + // integers contains the offset, the size and the already copied data which will be + // copied from the tmpBuffer to outBuffer + size_t copyOffset, copySize, copyDone; + copyOffset = copySize = copyDone = 0; + + UInt32 i = 0; + + // decompress data in _LZMA_TEMP_BUFFER_SIZE byte steps and copy the wanted file to outBuffer + do + { + // decompress next bytes + result = LzmaDecode(&state, + #ifdef _LZMA_IN_CB + &lzmaCallback.InCallback, + #else + //inBuffer, (SizeT)inSize, &inProcessed, //TODO! + #endif + tmpBuffer, _LZMA_TEMP_BUFFER_SIZE, &outSizeProcessedLoc + ); + + // check result + if(result == LZMA_RESULT_DATA_ERROR) + { + return SZE_DATA_ERROR; + } + if(result != LZMA_RESULT_OK) + { + return SZE_FAIL; + } + + // normally this should never happen + if(outSizeProcessedLoc > _LZMA_TEMP_BUFFER_SIZE) + { + return SZE_FAIL; + } + + // update bufferStart and bufferEnd + bufferStart = _LZMA_TEMP_BUFFER_SIZE * i; + bufferEnd = bufferStart + outSizeProcessedLoc; + i++; + + // calculate copy offset and size + if(*fileOffset > bufferEnd) + { + // we haven't reached the start of the file yet + continue; + } + + // calculate offset + if(*fileOffset < bufferStart) + { + // the file has already started before this decompression step + copyOffset = 0; + } + else + { + // the file starts somewhere inside this buffer + copyDone = 0; + copyOffset = _LZMA_TEMP_BUFFER_SIZE - (bufferEnd - *fileOffset); + } + + // calculate size + if((*fileOffset + *fileSize) > bufferEnd) + { + // we'll need the whole buffer after copyOffset + copySize = _LZMA_TEMP_BUFFER_SIZE - copyOffset; + } + else + { + // we'll stop somewhere inside the buffer + copySize = (*fileOffset + *fileSize) - (bufferStart + copyOffset); + } + + // copy bytes to the real output buffer + if(copySize == 0) + { + continue; + } + // printf("memcpy(outBuffer + %d, tmpBuffer + %d, %d)\n", copyDone, copyOffset, copySize); + memcpy(outBuffer + copyDone, tmpBuffer + copyOffset, copySize); + copyDone += copySize; + } + while((*fileOffset + *fileSize) > bufferEnd); + +/* result = LzmaDecode(&state, + #ifdef _LZMA_IN_CB + &lzmaCallback.InCallback, + #else + inBuffer, (SizeT)inSize, &inProcessed, + #endif + outBuffer, (SizeT)outSize, &outSizeProcessedLoc);*/ + //*outSizeProcessed = (size_t)outSizeProcessedLoc; + *outSizeProcessed = copyDone; + allocMain->Free(tmpBuffer); // free the temporary buffer again + allocMain->Free(state.Probs); + allocMain->Free(state.Dictionary); +/* if (result == LZMA_RESULT_DATA_ERROR) + return SZE_DATA_ERROR; + if (result != LZMA_RESULT_OK) + return SZE_FAIL;*/ + return SZ_OK; + } + return SZE_NOTIMPL; +} +#endif diff --git a/source/sz/7zDecode.h b/source/sz/7zDecode.h index 9f15ba16..9506e59d 100644 --- a/source/sz/7zDecode.h +++ b/source/sz/7zDecode.h @@ -19,17 +19,17 @@ SZ_RESULT SzDecode(const CFileSize *packSizes, const CFolder *folder, #else const Byte *inBuffer, #endif - Byte *outBuffer, size_t outSize, + Byte *outBuffer, size_t outSize, size_t *outSizeProcessed, ISzAlloc *allocMain); #ifdef _LZMA_OUT_READ #ifndef _LZMA_TEMP_BUFFER_SIZE -#define _LZMA_TEMP_BUFFER_SIZE (2048) // size of the temporary buffer in bytes +#define _LZMA_TEMP_BUFFER_SIZE (1 << 15) // size of the temporary buffer in bytes #endif SZ_RESULT SzDecode2(const CFileSize *packSizes, const CFolder *folder, ISzInStream *stream, - Byte *outBuffer, size_t outSize, + Byte *outBuffer, size_t outSize, size_t *outSizeProcessed, ISzAlloc *allocMain, size_t *fileOffset, size_t *fileSize); #endif // #ifdef _LZMA_OUT_READ diff --git a/source/sz/7zExtract.c b/source/sz/7zExtract.c index 13ba62ce..9a82ea42 100644 --- a/source/sz/7zExtract.c +++ b/source/sz/7zExtract.c @@ -5,14 +5,14 @@ #include "7zCrc.h" SZ_RESULT SzExtract( - ISzInStream *inStream, + ISzInStream *inStream, CArchiveDatabaseEx *db, UInt32 fileIndex, UInt32 *blockIndex, - Byte **outBuffer, + Byte **outBuffer, size_t *outBufferSize, - size_t *offset, - size_t *outSizeProcessed, + size_t *offset, + size_t *outSizeProcessed, ISzAlloc *allocMain, ISzAlloc *allocTemp) { @@ -41,9 +41,9 @@ SZ_RESULT SzExtract( *blockIndex = folderIndex; allocMain->Free(*outBuffer); *outBuffer = 0; - + RINOK(inStream->Seek(inStream, SzArDbGetFolderStreamPos(db, folderIndex, 0))); - + #ifndef _LZMA_IN_CB if (packSize != 0) { @@ -67,12 +67,12 @@ SZ_RESULT SzExtract( if (res == SZ_OK) { size_t outRealSize; - res = SzDecode(db->Database.PackSizes + - db->FolderStartPackStreamIndex[folderIndex], folder, + res = SzDecode(db->Database.PackSizes + + db->FolderStartPackStreamIndex[folderIndex], folder, #ifdef _LZMA_IN_CB inStream, #else - inBuffer, + inBuffer, #endif *outBuffer, (size_t)unPackSize, &outRealSize, allocTemp); if (res == SZ_OK) @@ -96,7 +96,7 @@ SZ_RESULT SzExtract( } if (res == SZ_OK) { - UInt32 i; + UInt32 i; CFileItem *fileItem = db->Database.Files + fileIndex; *offset = 0; for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++) @@ -118,14 +118,14 @@ SZ_RESULT SzExtract( #ifdef _LZMA_OUT_READ // similar to SzExtract but needs less memory SZ_RESULT SzExtract2( - ISzInStream *inStream, + ISzInStream *inStream, CArchiveDatabaseEx *db, UInt32 fileIndex, UInt32 *blockIndex, - Byte **outBuffer, + Byte **outBuffer, size_t *outBufferSize, - size_t *offset, - size_t *outSizeProcessed, + size_t *offset, + size_t *outSizeProcessed, ISzAlloc *allocMain, ISzAlloc *allocTemp) { @@ -158,9 +158,9 @@ SZ_RESULT SzExtract2( allocMain->Free(*outBuffer); *outBuffer = 0; #endif - + RINOK(inStream->Seek(inStream, SzArDbGetFolderStreamPos(db, folderIndex, 0))); - + #ifndef _LZMA_IN_CB if (packSize != 0) { @@ -176,7 +176,7 @@ SZ_RESULT SzExtract2( { // calculate file offset and filesize CFileItem *fileItem = db->Database.Files + fileIndex; - UInt32 i; + UInt32 i; *offset = 0; for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++) *offset += (UInt32)db->Database.Files[i].Size; @@ -192,14 +192,14 @@ SZ_RESULT SzExtract2( } if (res == SZ_OK) { - + size_t outRealSize; - res = SzDecode2(db->Database.PackSizes + - db->FolderStartPackStreamIndex[folderIndex], folder, + res = SzDecode2(db->Database.PackSizes + + db->FolderStartPackStreamIndex[folderIndex], folder, #ifdef _LZMA_IN_CB inStream, #else - inBuffer, + inBuffer, #endif *outBuffer, (size_t)unPackSize, &outRealSize, allocTemp, offset, outSizeProcessed @@ -226,24 +226,24 @@ SZ_RESULT SzExtract2( } if (res == SZ_OK) { -/* UInt32 i; +/* UInt32 i; CFileItem *fileItem = db->Database.Files + fileIndex; *offset = 0; for(i = db->FolderStartFileIndex[folderIndex]; i < fileIndex; i++) *offset += (UInt32)db->Database.Files[i].Size; *outSizeProcessed = (size_t)fileItem->Size;*/ - //CFileItem *fileItem = db->Database.Files + fileIndex; + CFileItem *fileItem = db->Database.Files + fileIndex; if (/**offset +*/ *outSizeProcessed > *outBufferSize) return SZE_FAIL; { - //if (fileItem->IsFileCRCDefined) - //{ - // if (!CrcVerifyDigest(fileItem->FileCRC, *outBuffer/* + *offset*/, *outSizeProcessed)) - // res = SZE_CRC_ERROR; // why does SzExtract return SZE_FAIL when we can return SZE_CRC_ERROR? - //} + if (fileItem->IsFileCRCDefined) + { + if (!CrcVerifyDigest(fileItem->FileCRC, *outBuffer/* + *offset*/, *outSizeProcessed)) + res = SZE_CRC_ERROR; // why does SzExtract return SZE_FAIL when we can return SZE_CRC_ERROR? + } } } - + // change *offset to 0 because SzExtract normally decompresses the whole solid block // and sets *offset to the offset of the wanted file. // SzDecode2 does only copy the needed file to the output buffer and has to set *offset diff --git a/source/sz/7zTypes.h b/source/sz/7zTypes.h index fa4c5c3c..817d9215 100644 --- a/source/sz/7zTypes.h +++ b/source/sz/7zTypes.h @@ -5,15 +5,13 @@ #ifndef _7ZIP_BYTE_DEFINED #define _7ZIP_BYTE_DEFINED -#ifndef ZCONF_H typedef unsigned char Byte; -#endif -#endif +#endif #ifndef _7ZIP_UINT16_DEFINED #define _7ZIP_UINT16_DEFINED typedef unsigned short UInt16; -#endif +#endif #ifndef _7ZIP_UINT32_DEFINED #define _7ZIP_UINT32_DEFINED @@ -22,7 +20,7 @@ typedef unsigned long UInt32; #else typedef unsigned int UInt32; #endif -#endif +#endif /* #define _SZ_NO_INT_64 */ /* define it your compiler doesn't support long long int */ @@ -46,9 +44,9 @@ typedef unsigned long long int UInt64; #ifndef CFileSize #ifdef _SZ_FILE_SIZE_64 -typedef UInt64 CFileSize; +typedef UInt64 CFileSize; #else -typedef UInt32 CFileSize; +typedef UInt32 CFileSize; #endif #endif @@ -64,8 +62,6 @@ typedef UInt32 CFileSize; #define SZE_ARCHIVE_ERROR (6) -#define SZE_OUTOFMEMORYDIC (7) - #define RINOK(x) { int __result_ = (x); if(__result_ != 0) return __result_; } #endif