From 0d879dec9057f0c9e2e47406f6b4362622ff3c56 Mon Sep 17 00:00:00 2001 From: gigaherz Date: Sun, 12 Jul 2009 22:52:39 +0000 Subject: [PATCH] Remade CDVDisoReader from CDVDiso, without removing the blockdump stuff. Included CDVDiso's iso handing functions into core (with renamed filenames). Implemented block dumping into CDVDaccess so that it also dumps from a CDVD plugin. Made the blockdump creation use a timestamped filename (can be turned off in the code), but it needs implementing a linux version of the timestamp. The blockdump choice doesn't get saved (yet), and I'm not sure if I should make it save, or leave it as is. git-svn-id: http://pcsx2.googlecode.com/svn/trunk@1498 96395faa-99c1-11dd-bbfe-3dabce05a288 --- pcsx2/CDVD/CDVD.cpp | 10 +- pcsx2/CDVD/CDVDaccess.cpp | 166 +++- pcsx2/CDVD/CDVDaccess.h | 4 +- pcsx2/CDVD/CDVDisoReader.cpp | 336 ++++---- pcsx2/CDVD/CDVDisoReader.h | 77 +- pcsx2/CDVD/CdRom.cpp | 8 +- pcsx2/CDVD/IsoFStools.cpp | 9 +- pcsx2/CDVD/IsoFileFormats.cpp | 957 +++++++++++++++++++++ pcsx2/CDVD/IsoFileFormats.h | 68 ++ pcsx2/windows/VCprojects/pcsx2_2008.vcproj | 14 +- pcsx2/windows/WinMain.cpp | 5 +- pcsx2_suite_2008.sln | 1 + 12 files changed, 1418 insertions(+), 237 deletions(-) create mode 100644 pcsx2/CDVD/IsoFileFormats.cpp create mode 100644 pcsx2/CDVD/IsoFileFormats.h diff --git a/pcsx2/CDVD/CDVD.cpp b/pcsx2/CDVD/CDVD.cpp index 540cbb0362..a35a2e3358 100644 --- a/pcsx2/CDVD/CDVD.cpp +++ b/pcsx2/CDVD/CDVD.cpp @@ -28,6 +28,8 @@ static cdvdStruct cdvd; +static u8 tempbuf[2352]; + static __forceinline void SetResultSize(u8 size) { cdvd.ResultC = size; @@ -746,12 +748,16 @@ __forceinline void cdvdReadInterrupt() } else { + if (cdvd.RErr == 0) - cdr.pTransfer = DoCDVDgetBuffer(); + { + cdr.RErr = DoCDVDgetBuffer(tempbuf); + cdr.pTransfer = tempbuf; + } else cdr.pTransfer = NULL; - if (cdr.pTransfer == NULL) + if (cdr.RErr < 0) { cdvd.RetryCntP++; Console::Error("CDVD READ ERROR, sector=%d", params cdvd.Sector); diff --git a/pcsx2/CDVD/CDVDaccess.cpp b/pcsx2/CDVD/CDVDaccess.cpp index 9a1b544d08..b111bd3292 100644 --- a/pcsx2/CDVD/CDVDaccess.cpp +++ b/pcsx2/CDVD/CDVDaccess.cpp @@ -18,6 +18,9 @@ #include "PrecompiledHeader.h" +// TODO: fix this for linux! (hardcoded as _WIN32 only) +#define ENABLE_TIMESTAMPS + #include #include @@ -28,6 +31,11 @@ static int diskTypeCached=-1; +static int psize; +static int plsn=0; + +static isoFile *blockDumpFile; + ///////////////////////////////////////////////// // // Disk Type detection stuff (from cdvdGigaherz) @@ -98,7 +106,7 @@ int FindDiskType(int mType) { iCDType = CDVD_TYPE_DETCTDVDS; } - else if(DoCDVDreadSector((u8*)bleh,16)==0) + else if(DoCDVDreadSector((u8*)bleh,16,CDVD_MODE_2048)==0) { struct cdVolDesc* volDesc=(struct cdVolDesc *)bleh; if(volDesc) @@ -209,10 +217,78 @@ s32 DoCDVDinit() s32 DoCDVDopen(const char* pTitleFilename) { + int ret=0; if(loadFromISO) - return ISOopen(pTitleFilename); + ret = ISOopen(pTitleFilename); else - return CDVDopen(pTitleFilename); + ret = CDVDopen(pTitleFilename); + + if (Config.Blockdump) + { + char fname_only[MAX_PATH]; + + if(loadFromISO) + { +#ifdef _WIN32 + char fname[MAX_PATH], ext[MAX_PATH]; + _splitpath(isoFileName, NULL, NULL, fname, ext); + _makepath(fname_only, NULL, NULL, fname, NULL); +#else + char* p, *plast; + + plast = p = strchr(isoFileName, '/'); + while (p != NULL) + { + plast = p; + p = strchr(p + 1, '/'); + } + + // Lets not create dumps in the plugin directory. + strcpy(fname_only, "../"); + if (plast != NULL) + strcat(fname_only, plast + 1); + else + strcat(fname_only, isoFileName); + + plast = p = strchr(fname_only, '.'); + + while (p != NULL) + { + plast = p; + p = strchr(p + 1, '.'); + } + + if (plast != NULL) *plast = 0; +#endif + } + else + { + strcpy(fname_only, "Untitled"); + } + +#if defined(_WIN32) && defined(ENABLE_TIMESTAMPS) + SYSTEMTIME time; + GetLocalTime(&time); + + sprintf( + fname_only+strlen(fname_only), + " (%04d-%02d-%02d %02d-%02d-%02d).dump", + time.wYear, time.wMonth, time.wDay, + time.wHour, time.wMinute, time.wSecond); +#else + // TODO: implement this + strcat(fname_only, ".dump"); +#endif + + blockDumpFile = isoCreate(fname_only, ISOFLAGS_BLOCKDUMP); + if (blockDumpFile) isoSetFormat(blockDumpFile, iso->blockofs, iso->blocksize, iso->blocks); + } + else + { + blockDumpFile = NULL; + } + + return ret; } void DoCDVDclose() @@ -221,6 +297,8 @@ void DoCDVDclose() ISOclose(); else CDVDclose(); + + if (blockDumpFile != NULL) isoClose(blockDumpFile); } void DoCDVDshutdown() @@ -231,21 +309,47 @@ void DoCDVDshutdown() } } -s32 DoCDVDreadSector(u8* buffer, u32 lsn) +s32 DoCDVDreadSector(u8* buffer, u32 lsn, int mode) { + int ret; + if(loadFromISO) - return ISOreadSector(buffer,lsn); + ret = ISOreadSector(buffer,lsn,mode); else { - CDVDreadTrack(lsn,CDVD_MODE_2048); + CDVDreadTrack(lsn,mode); void* pbuffer = CDVDgetBuffer(); if(pbuffer!=NULL) { - memcpy(buffer,pbuffer,2048); - return 0; + switch(mode) + { + case CDVD_MODE_2048: + memcpy(buffer,pbuffer,2048); + break; + case CDVD_MODE_2328: + memcpy(buffer,pbuffer,2328); + break; + case CDVD_MODE_2340: + memcpy(buffer,pbuffer,2340); + break; + case CDVD_MODE_2352: + memcpy(buffer,pbuffer,2352); + break; + } + ret = 0; } - return -1; + else ret = -1; } + + + if(ret==0) + { + if (blockDumpFile != NULL) + { + isoWriteBlock(blockDumpFile, pbuffer, plsn); + } + } + return ret; } s32 DoCDVDreadTrack(u32 lsn, int mode) @@ -253,16 +357,54 @@ s32 DoCDVDreadTrack(u32 lsn, int mode) if(loadFromISO) return ISOreadTrack(lsn, mode); else + { + // TEMP: until I fix all the plugins to use the new CDVDgetBuffer style + switch (mode) + { + case CDVD_MODE_2352: + psize = 2352; + break; + case CDVD_MODE_2340: + psize = 2340; + break; + case CDVD_MODE_2328: + psize = 2328; + break; + case CDVD_MODE_2048: + psize = 2048; + break; + } return CDVDreadTrack(lsn, mode); + } } // return can be NULL (for async modes) -u8* DoCDVDgetBuffer() +s32 DoCDVDgetBuffer(u8* buffer) { + int ret; + if(loadFromISO) - return ISOgetBuffer(); + ret = ISOgetBuffer(buffer); else - return CDVDgetBuffer(); + { + // TEMP: until I fix all the plugins to use this function style + u8* pb = CDVDgetBuffer(); + if(pb!=NULL) + { + memcpy(buffer,pb,psize); + ret=0; + } + else ret= -1; + } + + if(ret==0) + { + if (blockDumpFile != NULL) + { + isoWriteBlock(blockDumpFile, pbuffer, plsn); + } + } + return ret; } s32 DoCDVDreadSubQ(u32 lsn, cdvdSubQ* subq) diff --git a/pcsx2/CDVD/CDVDaccess.h b/pcsx2/CDVD/CDVDaccess.h index f56add82e4..6dbafaad47 100644 --- a/pcsx2/CDVD/CDVDaccess.h +++ b/pcsx2/CDVD/CDVDaccess.h @@ -23,9 +23,9 @@ s32 DoCDVDinit(); s32 DoCDVDopen(const char* pTitleFilename); void DoCDVDclose(); void DoCDVDshutdown(); -s32 DoCDVDreadSector(u8* buffer, u32 lsn); +s32 DoCDVDreadSector(u8* buffer, u32 lsn, int mode); s32 DoCDVDreadTrack(u32 lsn, int mode); -u8* DoCDVDgetBuffer(); +s32 DoCDVDgetBuffer(u8* buffer); s32 DoCDVDreadSubQ(u32 lsn, cdvdSubQ* subq); s32 DoCDVDgetTN(cdvdTN *Buffer); s32 DoCDVDgetTD(u8 Track, cdvdTD *Buffer); diff --git a/pcsx2/CDVD/CDVDisoReader.cpp b/pcsx2/CDVD/CDVDisoReader.cpp index 7ef95fcbfb..58b784f06b 100644 --- a/pcsx2/CDVD/CDVDisoReader.cpp +++ b/pcsx2/CDVD/CDVDisoReader.cpp @@ -21,15 +21,9 @@ * Fixed CdRead by linuzappz */ #include "PrecompiledHeader.h" - -#ifdef __LINUX__ - // Just in case. -# define __USE_LARGEFILE64 -# define __USE_FILE_OFFSET64 -# define _FILE_OFFSET_BITS 64 -# define _LARGEFILE_SOURCE -# define _LARGEFILE64_SOURCE -#endif +#include +#include +#include #include "CDVDisoReader.h" @@ -37,32 +31,41 @@ #define MAX_PATH 255 #endif -bool loadFromISO; +bool loadFromISO=false; char isoFileName[256]; +char IsoCWD[256]; +char CdDev[256]; +_cdIso cdIso[8]; u8 *pbuffer; +int cdblocksize; +int cdblockofs; +int cdoffset; +int cdtype; +int cdblocks; + +int psize; + +int Zmode; // 1 Z - 2 bz2 +int fmode; // 0 - file / 1 - Zfile +char *Ztable; int BlockDump; -FILE* fdump; -FILE* isoFile; +isoFile *iso; FILE *cdvdLog = NULL; -int isoType; -int isoNumAudioTracks = 0; -int isoNumSectors = 0; -int isoSectorSize = 0; -int isoSectorOffset = 0; +// This var is used to detect resume-style behavior of the Pcsx2 emulator, +// and skip prompting the user for a new CD when it's likely they want to run the existing one. +static char cdvdCurrentIso[MAX_PATH]; -#ifndef _WIN32 -// if this doesn't work in linux, sorry. -gigaherz -// -// Hope this works. Think it will, but it isn't used yet. -// CDVDiso uses ftell, then switches to ftello64 if it fails. -arcum42 -#define _ftelli64 ftello64 -#define _fseeki64 fseeko64 -#endif +char *methods[] = +{ + ".Z - compress faster", + ".BZ - compress better", + NULL +}; u8 cdbuffer[CD_FRAMESIZE_RAW * 10] = {0}; @@ -86,6 +89,7 @@ void lba_to_msf(s32 lba, u8* m, u8* s, u8* f) #define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */ #define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */ + #ifdef PCSX2_DEBUG void __Log(char *fmt, ...) { @@ -97,13 +101,12 @@ void __Log(char *fmt, ...) vfprintf(cdvdLog, fmt, list); va_end(list); } -#define CDVD_LOG __Log #else #define __Log 0&& #endif -s32 CALLBACK ISOinit() +s32 ISOinit() { #ifdef PCSX2_DEBUG cdvdLog = fopen("logs/cdvdLog.txt", "w"); @@ -117,121 +120,53 @@ s32 CALLBACK ISOinit() } } setvbuf(cdvdLog, NULL, _IONBF, 0); - CDVD_LOG("ISOinit\n"); + CDVD_LOG("CDVDinit\n"); #endif + cdvdCurrentIso[0] = 0; + memset(cdIso, 0, sizeof(cdIso)); return 0; } -void CALLBACK ISOshutdown() +void ISOshutdown() { + cdvdCurrentIso[0] = 0; #ifdef CDVD_LOG if (cdvdLog != NULL) fclose(cdvdLog); #endif } -s32 CALLBACK ISOopen(const char* pTitle) +s32 ISOopen(const char* pTitle) { //if (pTitle != NULL) strcpy(isoFileName, pTitle); - isoFile = fopen(isoFileName,"rb"); - if (isoFile == NULL) + iso = isoOpen(isoFileName); + if (iso == NULL) { Console::Error("Error loading %s\n", params isoFileName); return -1; } - // pretend it's a ps2 dvd... for now - isoType=CDVD_TYPE_PS2DVD; - - isoSectorSize = 2048; - isoSectorOffset = 0; - - _fseeki64(isoFile,0,SEEK_END); - isoNumSectors = (int)(_ftelli64(isoFile)/isoSectorSize); - _fseeki64(isoFile,0,SEEK_SET); - - if (BlockDump) - { - char fname_only[MAX_PATH]; - -#ifdef _WIN32 - char fname[MAX_PATH], ext[MAX_PATH]; - _splitpath(isoFileName, NULL, NULL, fname, ext); - _makepath(fname_only, NULL, NULL, fname, NULL); -#else - char* p, *plast; - - plast = p = strchr(isoFileName, '/'); - while (p != NULL) - { - plast = p; - p = strchr(p + 1, '/'); - } - - // Lets not create dumps in the plugin directory. - strcpy(fname_only, "../"); - if (plast != NULL) - strcat(fname_only, plast + 1); - else - strcat(fname_only, isoFileName); - - plast = p = strchr(fname_only, '.'); - - while (p != NULL) - { - plast = p; - p = strchr(p + 1, '.'); - } - - if (plast != NULL) *plast = 0; - -#endif - strcat(fname_only, ".dump"); - fdump = fopen(fname_only, "wb"); - if(fdump) - { - if(isoNumAudioTracks) - { - int k; - fwrite("BDV2",4,1,fdump); - k=2352; - fwrite(&k,4,1,fdump); - k=isoNumSectors; - fwrite(&k,4,1,fdump); - k=0; - fwrite(&k,4,1,fdump); - } - else - { - int k; - fwrite("BDV2",4,1,fdump); - k=2048; - fwrite(&k,4,1,fdump); - k=isoNumSectors; - fwrite(&k,4,1,fdump); - k=0x18; - fwrite(&k,4,1,fdump); - } - } - } + if (iso->type == ISOTYPE_DVD) + cdtype = CDVD_TYPE_PS2DVD; + else if (iso->type == ISOTYPE_AUDIO) + cdtype = CDVD_TYPE_CDDA; else - { - fdump = NULL; - } + cdtype = CDVD_TYPE_PS2CD; return 0; } -void CALLBACK ISOclose() +void ISOclose() { - fclose(isoFile); - if (fdump != NULL) fclose(fdump); + strcpy(cdvdCurrentIso, isoFileName); + + isoClose(iso); } -s32 CALLBACK ISOreadSubQ(u32 lsn, cdvdSubQ* subq) +s32 ISOreadSubQ(u32 lsn, cdvdSubQ* subq) { - // fake it, until some kind of support for clonecd .sub files is implemented + // fake it u8 min, sec, frm; subq->ctrl = 4; subq->mode = 1; @@ -252,7 +187,7 @@ s32 CALLBACK ISOreadSubQ(u32 lsn, cdvdSubQ* subq) return 0; } -s32 CALLBACK ISOgetTN(cdvdTN *Buffer) +s32 ISOgetTN(cdvdTN *Buffer) { Buffer->strack = 1; Buffer->etrack = 1; @@ -260,56 +195,28 @@ s32 CALLBACK ISOgetTN(cdvdTN *Buffer) return 0; } -s32 CALLBACK ISOgetTD(u8 tn, cdvdTD *Buffer) +s32 ISOgetTD(u8 Track, cdvdTD *Buffer) { - if(tn==1) + if (Track == 0) { - Buffer->lsn = 0; - Buffer->type = CDVD_MODE1_TRACK; + Buffer->lsn = iso->blocks; } else { - Buffer->lsn = isoNumSectors; - Buffer->type = 0; + Buffer->type = CDVD_MODE1_TRACK; + Buffer->lsn = 0; } + return 0; } -s32 CALLBACK ISOgetDiskType() -{ - return isoType; -} - -s32 CALLBACK ISOgetTrayStatus() -{ - return CDVD_TRAY_CLOSE; -} - -s32 CALLBACK ISOctrlTrayOpen() -{ - return 0; -} -s32 CALLBACK ISOctrlTrayClose() -{ - return 0; -} - -s32 CALLBACK ISOreadSector(u8* tempbuffer, u32 lsn) -{ - // dummy function, doesn't create valid info for the data surrounding the userdata bytes! - - // probably vc++ only, CBA to figure out the unix equivalent of fseek with support for >2gb seeking - _fseeki64(isoFile, lsn * (s64)isoSectorSize, SEEK_SET); - return fread(tempbuffer+24, isoSectorSize, 1, isoFile)-1; -} - static s32 layer1start = -1; -s32 CALLBACK ISOgetTOC(void* toc) +s32 ISOgetTOC(void* toc) { - u8 type = ISOgetDiskType(); + u8 type = CDVDgetDiskType(); u8* tocBuff = (u8*)toc; - //__Log("ISOgetTOC\n"); + //__Log("CDVDgetTOC\n"); if (type == CDVD_TYPE_DVDV || type == CDVD_TYPE_PS2DVD) { @@ -317,9 +224,9 @@ s32 CALLBACK ISOgetTOC(void* toc) // scsi command 0x43 memset(tocBuff, 0, 2048); - if (layer1start != -2 && isoNumSectors >= 0x300000) + if (layer1start != -2 && iso->blocks >= 0x300000) { - int off = isoSectorOffset; + int off = iso->blockofs; u8* tempbuffer; // dual sided @@ -342,9 +249,9 @@ s32 CALLBACK ISOgetTOC(void* toc) { printf("CDVD: searching for layer1..."); tempbuffer = (u8*)malloc(CD_FRAMESIZE_RAW * 10); - for (layer1start = (isoNumSectors / 2 - 0x10) & ~0xf; layer1start < 0x200010; layer1start += 16) + for (layer1start = (iso->blocks / 2 - 0x10) & ~0xf; layer1start < 0x200010; layer1start += 16) { - ISOreadSector(tempbuffer, layer1start); + isoReadBlock(iso, tempbuffer, layer1start); // CD001 if (tempbuffer[off+1] == 0x43 && tempbuffer[off+2] == 0x44 && tempbuffer[off+3] == 0x30 && tempbuffer[off+4] == 0x30 && tempbuffer[off+5] == 0x31) break; @@ -396,7 +303,7 @@ s32 CALLBACK ISOgetTOC(void* toc) } } else if ((type == CDVD_TYPE_CDDA) || (type == CDVD_TYPE_PS2CDDA) || - (type == CDVD_TYPE_PS2CD) || (type == CDVD_TYPE_PSCDDA) || (type == CDVD_TYPE_PSCD)) + (type == CDVD_TYPE_PS2CD) || (type == CDVD_TYPE_PSCDDA) || (type == CDVD_TYPE_PSCD)) { // cd toc // (could be replaced by 1 command that reads the full toc) @@ -405,12 +312,12 @@ s32 CALLBACK ISOgetTOC(void* toc) cdvdTN diskInfo; cdvdTD trackInfo; memset(tocBuff, 0, 1024); - if (ISOgetTN(&diskInfo) == -1) + if (CDVDgetTN(&diskInfo) == -1) { diskInfo.etrack = 0; diskInfo.strack = 1; } - if (ISOgetTD(0, &trackInfo) == -1) trackInfo.lsn = 0; + if (CDVDgetTD(0, &trackInfo) == -1) trackInfo.lsn = 0; tocBuff[0] = 0x41; tocBuff[1] = 0x00; @@ -431,7 +338,7 @@ s32 CALLBACK ISOgetTOC(void* toc) for (i = diskInfo.strack; i <= diskInfo.etrack; i++) { - err = ISOgetTD(i, &trackInfo); + err = CDVDgetTD(i, &trackInfo); lba_to_msf(trackInfo.lsn, &min, &sec, &frm); tocBuff[i*10+30] = trackInfo.type; tocBuff[i*10+32] = err == -1 ? 0 : itob(i); //number @@ -446,45 +353,106 @@ s32 CALLBACK ISOgetTOC(void* toc) return 0; } -s32 CALLBACK ISOreadTrack(u32 lsn, int mode) +s32 ISOreadSector(u8* tempbuffer, u32 lsn, int mode) { int _lsn = lsn; - //__Log("ISOreadTrack: %x %x\n", lsn, mode); if (_lsn < 0) - { -// lsn = 2097152 + (-_lsn); - lsn = isoNumSectors - (-_lsn); - } -// printf ("CDRreadTrack %d\n", lsn); + lsn = iso->blocks + _lsn; - ISOreadSector(cdbuffer, lsn); - if (fdump != NULL) + if(lsn > iso->blocks) + return -1; + + if(mode == CDVD_MODE_2352) { - fwrite(&lsn,4,1,fdump); - fwrite(cdbuffer,isoSectorSize,1,fdump); + isoReadBlock(iso, tempbuffer, lsn); + return 0; } + isoReadBlock(iso, cdbuffer, lsn); + pbuffer = cdbuffer; switch (mode) { - case CDVD_MODE_2352: - break; - case CDVD_MODE_2340: - pbuffer += 12; - break; - case CDVD_MODE_2328: - pbuffer += 24; - break; - case CDVD_MODE_2048: - pbuffer += 24; - break; + case CDVD_MODE_2352: + psize = 2352; + break; + case CDVD_MODE_2340: + pbuffer += 12; + psize = 2340; + break; + case CDVD_MODE_2328: + pbuffer += 24; + psize = 2328; + break; + case CDVD_MODE_2048: + pbuffer += 24; + psize = 2048; + break; + } + + memcpy_fast(tempbuffer,pbuffer,psize); + + return 0; +} + +s32 ISOreadTrack(u32 lsn, int mode) +{ + int _lsn = lsn; + + if (_lsn < 0) + lsn = iso->blocks + _lsn; + + if(lsn > iso->blocks) + return -1; + + isoReadBlock(iso, cdbuffer, lsn); + + pbuffer = cdbuffer; + switch (mode) + { + case CDVD_MODE_2352: + psize = 2352; + break; + case CDVD_MODE_2340: + pbuffer += 12; + psize = 2340; + break; + case CDVD_MODE_2328: + pbuffer += 24; + psize = 2328; + break; + case CDVD_MODE_2048: + pbuffer += 24; + psize = 2048; + break; } return 0; } -u8* CALLBACK ISOgetBuffer() +s32 ISOgetBuffer(u8* buffer) { - return pbuffer; + memcpy_fast(buffer,pbuffer,psize); + return 0; } + +s32 ISOgetDiskType() +{ + return cdtype; +} + +s32 ISOgetTrayStatus() +{ + return CDVD_TRAY_CLOSE; +} + +s32 ISOctrlTrayOpen() +{ + return 0; +} +s32 ISOctrlTrayClose() +{ + return 0; +} + diff --git a/pcsx2/CDVD/CDVDisoReader.h b/pcsx2/CDVD/CDVDisoReader.h index 06843d91a4..98d7afe71d 100644 --- a/pcsx2/CDVD/CDVDisoReader.h +++ b/pcsx2/CDVD/CDVDisoReader.h @@ -25,8 +25,33 @@ #include +#ifdef _WIN32 +#include +#endif + #include "IopCommon.h" #include "IsoFStools.h" +#include "IsoFileFormats.h" + +#define CDVD_LOG __Log +extern FILE *cdvdLog; + +void __Log(char *fmt, ...); + +#define VERBOSE 1 + +typedef struct +{ + int slsn; + int elsn; +#ifdef _WIN32 + HANDLE handle; +#else + FILE *handle; +#endif +} _cdIso; + +extern _cdIso cdIso[8]; #define CD_FRAMESIZE_RAW 2352 #define DATA_SIZE (CD_FRAMESIZE_RAW-12) @@ -36,32 +61,46 @@ #define MSF2SECT(m,s,f) (((m)*60+(s)-2)*75+(f)) -extern bool loadFromISO; +extern const u8 version; +extern const u8 revision; +extern const u8 build; extern char isoFileName[256]; +extern char IsoCWD[256]; +extern char CdDev[256]; extern int BlockDump; -extern FILE* fdump; -extern FILE* isoFile; -extern int isoType; +extern isoFile *blockDumpFile; +extern isoFile *iso; extern u8 cdbuffer[]; extern u8 *pbuffer; +extern int cdblocksize; +extern int cdblockofs; +extern int cdoffset; +extern int cdtype; +extern int cdblocks; -s32 CALLBACK ISOinit(); -void CALLBACK ISOshutdown(); -s32 CALLBACK ISOopen(const char* pTitle); -void CALLBACK ISOclose(); -s32 CALLBACK ISOreadSubQ(u32 lsn, cdvdSubQ* subq); -s32 CALLBACK ISOgetTN(cdvdTN *Buffer); -s32 CALLBACK ISOgetTD(u8 tn, cdvdTD *Buffer); -s32 CALLBACK ISOgetDiskType(); -s32 CALLBACK ISOgetTrayStatus(); -s32 CALLBACK ISOctrlTrayOpen(); -s32 CALLBACK ISOctrlTrayClose(); -s32 CALLBACK ISOreadSector(u8* tempbuffer, u32 lsn); -s32 CALLBACK ISOgetTOC(void* toc); -s32 CALLBACK ISOreadTrack(u32 lsn, int mode); -u8* CALLBACK ISOgetBuffer(); +extern int Zmode; // 1 Z - 2 bz2 +extern int fmode; // 0 - file / 1 - Zfile +extern char *Ztable; + +extern char *methods[]; + +s32 ISOinit(); +void ISOshutdown(); +s32 ISOopen(const char* pTitle); +void ISOclose(); +s32 ISOreadSubQ(u32 lsn, cdvdSubQ* subq); +s32 ISOgetTN(cdvdTN *Buffer); +s32 ISOgetTD(u8 tn, cdvdTD *Buffer); +s32 ISOgetDiskType(); +s32 ISOgetTrayStatus(); +s32 ISOctrlTrayOpen(); +s32 ISOctrlTrayClose(); +s32 ISOreadSector(u8* tempbuffer, u32 lsn, int mode); +s32 ISOgetTOC(void* toc); +s32 ISOreadTrack(u32 lsn, int mode); +s32 ISOgetBuffer(u8* buffer); #endif \ No newline at end of file diff --git a/pcsx2/CDVD/CdRom.cpp b/pcsx2/CDVD/CdRom.cpp index 4e67cd6e1f..c5f2aa5959 100644 --- a/pcsx2/CDVD/CdRom.cpp +++ b/pcsx2/CDVD/CdRom.cpp @@ -496,7 +496,7 @@ void cdrInterrupt() { } void cdrReadInterrupt() { - u8 *buf; + u8 buf[2352]; if (!cdr.Reading) return; @@ -514,10 +514,10 @@ void cdrReadInterrupt() { cdr.Result[0] = cdr.StatP; SysPrintf("Reading From CDR"); - buf = DoCDVDgetBuffer(); - if (buf == NULL) cdr.RErr = -1; + cdr.RErr = DoCDVDgetBuffer(buf); - if (cdr.RErr == -1) { + if (cdr.RErr == -1) + { CDR_LOG(" err\n"); memzero_ptr<2340>(cdr.Transfer); cdr.Stat = DiskError; diff --git a/pcsx2/CDVD/IsoFStools.cpp b/pcsx2/CDVD/IsoFStools.cpp index bc54ba628b..743a83a4c1 100644 --- a/pcsx2/CDVD/IsoFStools.cpp +++ b/pcsx2/CDVD/IsoFStools.cpp @@ -172,17 +172,10 @@ int TocEntryCompare(char* filename, char* extensions){ int IsoFS_readSectors(u32 lsn, u32 sectors, void *buf) { u32 i; - u8* buff; for (i=0; i +#include +#include "bzip2\bzlib.h" + +#ifdef _WIN32 +#include + +void *_openfile(const char *filename, int flags) +{ + HANDLE handle; + +// printf("_openfile %s, %d\n", filename, flags & O_RDONLY); + if (flags & O_WRONLY) + { + int _flags = CREATE_NEW; + if (flags & O_CREAT) _flags = CREATE_ALWAYS; + handle = CreateFile(filename, GENERIC_WRITE, 0, NULL, _flags, 0, NULL); + } + else + { + handle = CreateFile(filename, GENERIC_READ, 0, NULL, OPEN_EXISTING, 0, NULL); + } + + return handle == INVALID_HANDLE_VALUE ? NULL : handle; +} + +u64 _tellfile(void *handle) +{ + u64 ofs; + PLONG _ofs = (LONG*) & ofs; + _ofs[1] = 0; + _ofs[0] = SetFilePointer(handle, 0, &_ofs[1], FILE_CURRENT); + return ofs; +} + +int _seekfile(void *handle, u64 offset, int whence) +{ + u64 ofs = (u64)offset; + PLONG _ofs = (LONG*) & ofs; +// printf("_seekfile %p, %d_%d\n", handle, _ofs[1], _ofs[0]); + if (whence == SEEK_SET) + { + SetFilePointer(handle, _ofs[0], &_ofs[1], FILE_BEGIN); + } + else + { + SetFilePointer(handle, _ofs[0], &_ofs[1], FILE_END); + } + return 0; +} + +int _readfile(void *handle, void *dst, int size) +{ + DWORD ret; + +// printf("_readfile %p %d\n", handle, size); + ReadFile(handle, dst, size, &ret, NULL); +// printf("_readfile ret %d; %d\n", ret, GetLastError()); + return ret; +} + +int _writefile(void *handle, void *src, int size) +{ + DWORD ret; + +// printf("_writefile %p, %d\n", handle, size); +// _seekfile(handle, _tellfile(handle)); + WriteFile(handle, src, size, &ret, NULL); +// printf("_writefile ret %d\n", ret); + return ret; +} + +void _closefile(void *handle) +{ + CloseHandle(handle); +} + +#else + +void *_openfile(const char *filename, int flags) +{ + printf("_openfile %s %x\n", filename, flags); + + if (flags & O_WRONLY) + return fopen64(filename, "wb"); + else + return fopen64(filename, "rb"); +} + +#include + +u64 _tellfile(void *handle) +{ + s64 cursize = ftell(handle); + if (cursize == -1) + { + // try 64bit + cursize = ftello64(handle); + if (cursize < -1) + { + // zero top 32 bits + cursize &= 0xffffffff; + } + } + return cursize; +} + +int _seekfile(void *handle, u64 offset, int whence) +{ + int seekerr = fseeko64(handle, offset, whence); + + if (seekerr == -1) printf("failed to seek\n"); + + return seekerr; +} + +int _readfile(void *handle, void *dst, int size) +{ + return fread(dst, 1, size, handle); +} + +int _writefile(void *handle, void *src, int size) +{ + return fwrite(src, 1, size, handle); +} + +void _closefile(void *handle) +{ + fclose(handle); +} + +#endif + +int detect(isoFile *iso) +{ + u8 buf[2448]; + struct cdVolDesc *volDesc; + + if (isoReadBlock(iso, buf, 16) == -1) return -1; + + volDesc = (struct cdVolDesc *)(buf + 24); + + if (strncmp((char*)volDesc->volID, "CD001", 5)) return 0; + + if (volDesc->rootToc.tocSize == 2048) + iso->type = ISOTYPE_CD; + else + iso->type = ISOTYPE_DVD; + + return 1; +} + +int _isoReadZtable(isoFile *iso) +{ + void *handle; + char table[256]; + int size; + + sprintf(table, "%s.table", iso->filename); + handle = _openfile(table, O_RDONLY); + if (handle == NULL) + { + printf("Error loading %s\n", table); + return -1; + } + + _seekfile(handle, 0, SEEK_END); + size = _tellfile(handle); + iso->Ztable = (char*)malloc(size); + + if (iso->Ztable == NULL) + { + return -1; + } + + _seekfile(handle, 0, SEEK_SET); + _readfile(handle, iso->Ztable, size); + _closefile(handle); + + iso->blocks = size / 6; + + return 0; +} + +int _isoReadZ2table(isoFile *iso) +{ + void *handle; + char table[256]; + u32 *Ztable; + int ofs, size, i; + + sprintf(table, "%s.table", iso->filename); + handle = _openfile(table, O_RDONLY); + + if (handle == NULL) + { + printf("Error loading %s\n", table); + return -1; + } + + _seekfile(handle, 0, SEEK_END); + size = _tellfile(handle); + Ztable = (u32*)malloc(size); + + if (Ztable == NULL) + { + return -1; + } + + _seekfile(handle, 0, SEEK_SET); + _readfile(handle, Ztable, size); + _closefile(handle); + + iso->Ztable = (char*)malloc(iso->blocks * 8); + + if (iso->Ztable == NULL) + { + return -1; + } + + ofs = 16; + + for (i = 0; i < iso->blocks; i++) + { + *(u32*)&iso->Ztable[i*8+0] = ofs; + *(u32*)&iso->Ztable[i*8+4] = Ztable[i]; + ofs += Ztable[i]; + } + + free(Ztable); + + return 0; +} + +int _isoReadBZ2table(isoFile *iso) +{ + void *handle; + char table[256]; + u32 *Ztable; + int ofs; + int size; + int i; + + sprintf(table, "%s.table", iso->filename); + handle = _openfile(table, O_RDONLY); + if (handle == NULL) + { + printf("Error loading %s\n", table); + return -1; + } + + _seekfile(handle, 0, SEEK_END); + size = _tellfile(handle); + Ztable = (u32*)malloc(size); + if (Ztable == NULL) return -1; + + _seekfile(handle, 0, SEEK_SET); + _readfile(handle, Ztable, size); + _closefile(handle); + + iso->Ztable = (char*)malloc(iso->blocks * 8); + if (iso->Ztable == NULL) return -1; + + ofs = 16; + + for (i = 0; i < iso->blocks / 16; i++) + { + *(u32*)&iso->Ztable[i*8+0] = ofs; + *(u32*)&iso->Ztable[i*8+4] = Ztable[i]; + ofs += Ztable[i]; + } + + if (iso->blocks & 0xf) + { + *(u32*)&iso->Ztable[i*8+0] = ofs; + *(u32*)&iso->Ztable[i*8+4] = Ztable[i]; + ofs += Ztable[i]; + } + + free(Ztable); + + return 0; +} + +int _isoReadDtable(isoFile *iso) +{ + int ret; + int i; + + _seekfile(iso->handle, 0, SEEK_END); + iso->dtablesize = (_tellfile(iso->handle) - 16) / (iso->blocksize + 4); + iso->dtable = (u32*)malloc(iso->dtablesize * 4); + + for (i = 0; i < iso->dtablesize; i++) + { + _seekfile(iso->handle, 16 + (iso->blocksize + 4)*i, SEEK_SET); + ret = _readfile(iso->handle, &iso->dtable[i], 4); + if (ret < 4) return -1; + } + + return 0; +} + +int isoDetect(isoFile *iso) // based on florin's CDVDbin detection code :) +{ + char buf[32]; + int len; + + iso->type = ISOTYPE_ILLEGAL; + + len = strlen(iso->filename); + if (len >= 2) + { + if (!strncmp(iso->filename + (len - 2), ".Z", 2)) + { + iso->flags = ISOFLAGS_Z; + iso->blocksize = 2352; + _isoReadZtable(iso); + return detect(iso) == 1 ? 0 : -1; + } + } + + _seekfile(iso->handle, 0, SEEK_SET); + _readfile(iso->handle, buf, 4); + + if (strncmp(buf, "BDV2", 4) == 0) + { + iso->flags = ISOFLAGS_BLOCKDUMP; + _readfile(iso->handle, &iso->blocksize, 4); + _readfile(iso->handle, &iso->blocks, 4); + _readfile(iso->handle, &iso->blockofs, 4); + _isoReadDtable(iso); + return detect(iso) == 1 ? 0 : -1; + } + else if (strncmp(buf, "Z V2", 4) == 0) + { + iso->flags = ISOFLAGS_Z2; + _readfile(iso->handle, &iso->blocksize, 4); + _readfile(iso->handle, &iso->blocks, 4); + _readfile(iso->handle, &iso->blockofs, 4); + _isoReadZ2table(iso); + return detect(iso) == 1 ? 0 : -1; + } + else if (strncmp(buf, "BZV2", 4) == 0) + { + iso->flags = ISOFLAGS_BZ2; + _readfile(iso->handle, &iso->blocksize, 4); + _readfile(iso->handle, &iso->blocks, 4); + _readfile(iso->handle, &iso->blockofs, 4); + iso->buflsn = -1; + iso->buffer = (u8*)malloc(iso->blocksize * 16); + if (iso->buffer == NULL) return -1; + _isoReadBZ2table(iso); + return detect(iso) == 1 ? 0 : -1; + } + else + { + iso->blocks = 16; + } + + // ISO 2048 + iso->blocksize = 2048; + iso->offset = 0; + iso->blockofs = 24; + if (detect(iso) == 1) return 0; + + // RAW 2336 + iso->blocksize = 2336; + iso->offset = 0; + iso->blockofs = 16; + if (detect(iso) == 1) return 0; + + // RAW 2352 + iso->blocksize = 2352; + iso->offset = 0; + iso->blockofs = 0; + if (detect(iso) == 1) return 0; + + // RAWQ 2448 + iso->blocksize = 2448; + iso->offset = 0; + iso->blockofs = 0; + if (detect(iso) == 1) return 0; + + // NERO ISO 2048 + iso->blocksize = 2048; + iso->offset = 150 * 2048; + iso->blockofs = 24; + if (detect(iso) == 1) return 0; + + // NERO RAW 2352 + iso->blocksize = 2352; + iso->offset = 150 * 2048; + iso->blockofs = 0; + if (detect(iso) == 1) return 0; + + // NERO RAWQ 2448 + iso->blocksize = 2448; + iso->offset = 150 * 2048; + iso->blockofs = 0; + if (detect(iso) == 1) return 0; + + // ISO 2048 + iso->blocksize = 2048; + iso->offset = -8; + iso->blockofs = 24; + if (detect(iso) == 1) return 0; + + // RAW 2352 + iso->blocksize = 2352; + iso->offset = -8; + iso->blockofs = 0; + if (detect(iso) == 1) return 0; + + // RAWQ 2448 + iso->blocksize = 2448; + iso->offset = -8; + iso->blockofs = 0; + if (detect(iso) == 1) return 0; + + iso->offset = 0; + iso->blocksize = 2352; + iso->type = ISOTYPE_AUDIO; + return 0; + + return -1; +} + +isoFile *isoOpen(const char *filename) +{ + isoFile *iso; + int i; + + iso = (isoFile*)malloc(sizeof(isoFile)); + if (iso == NULL) return NULL; + + memset(iso, 0, sizeof(isoFile)); + strcpy(iso->filename, filename); + + iso->handle = _openfile(iso->filename, O_RDONLY); + if (iso->handle == NULL) + { + printf("Error loading %s\n", iso->filename); + return NULL; + } + + if (isoDetect(iso) == -1) return NULL; + + printf("detected blocksize = %d\n", iso->blocksize); + + if (strlen(iso->filename) > 3 && strncmp(iso->filename + (strlen(iso->filename) - 3), "I00", 3) == 0) + { + _closefile(iso->handle); + iso->flags |= ISOFLAGS_MULTI; + iso->blocks = 0; + for (i = 0; i < 8; i++) + { + iso->filename[strlen(iso->filename) - 1] = '0' + i; + iso->multih[i].handle = _openfile(iso->filename, O_RDONLY); + if (iso->multih[i].handle == NULL) + { + break; + } + iso->multih[i].slsn = iso->blocks; + _seekfile(iso->multih[i].handle, 0, SEEK_END); + iso->blocks += (u32)((_tellfile(iso->multih[i].handle) - iso->offset) / + (iso->blocksize)); + iso->multih[i].elsn = iso->blocks - 1; + } + + if (i == 0) + { + return NULL; + } + } + + if (iso->flags == 0) + { + _seekfile(iso->handle, 0, SEEK_END); + iso->blocks = (u32)((_tellfile(iso->handle) - iso->offset) / + (iso->blocksize)); + } + + + printf("isoOpen: %s ok\n", iso->filename); + printf("offset = %d\n", iso->offset); + printf("blockofs = %d\n", iso->blockofs); + printf("blocksize = %d\n", iso->blocksize); + printf("blocks = %d\n", iso->blocks); + printf("type = %d\n", iso->type); + + return iso; +} + +isoFile *isoCreate(const char *filename, int flags) +{ + isoFile *iso; + char Zfile[256]; + + iso = (isoFile*)malloc(sizeof(isoFile)); + if (iso == NULL) return NULL; + + memset(iso, 0, sizeof(isoFile)); + strcpy(iso->filename, filename); + iso->flags = flags; + iso->offset = 0; + iso->blockofs = 24; + iso->blocksize = CD_FRAMESIZE_RAW; + iso->blocksize = 2048; + + if (iso->flags & (ISOFLAGS_Z | ISOFLAGS_Z2 | ISOFLAGS_BZ2)) + { + sprintf(Zfile, "%s.table", iso->filename); + iso->htable = _openfile(Zfile, O_WRONLY); + if (iso->htable == NULL) + { + return NULL; + } + } + + iso->handle = _openfile(iso->filename, O_WRONLY | O_CREAT); + if (iso->handle == NULL) + { + printf("Error loading %s\n", iso->filename); + return NULL; + } + printf("isoCreate: %s ok\n", iso->filename); + printf("offset = %d\n", iso->offset); + + return iso; +} + +int isoSetFormat(isoFile *iso, int blockofs, int blocksize, int blocks) +{ + iso->blocksize = blocksize; + iso->blocks = blocks; + iso->blockofs = blockofs; + printf("blockofs = %d\n", iso->blockofs); + printf("blocksize = %d\n", iso->blocksize); + printf("blocks = %d\n", iso->blocks); + if (iso->flags & ISOFLAGS_Z2) + { + if (_writefile(iso->handle, "Z V2", 4) < 4) return -1; + if (_writefile(iso->handle, &blocksize, 4) < 4) return -1; + if (_writefile(iso->handle, &blocks, 4) < 4) return -1; + if (_writefile(iso->handle, &blockofs, 4) < 4) return -1; + } + if (iso->flags & ISOFLAGS_BZ2) + { + if (_writefile(iso->handle, "BZV2", 4) < 4) return -1; + if (_writefile(iso->handle, &blocksize, 4) < 4) return -1; + if (_writefile(iso->handle, &blocks, 4) < 4) return -1; + if (_writefile(iso->handle, &blockofs, 4) < 4) return -1; + iso->buflsn = -1; + iso->buffer = (u8*)malloc(iso->blocksize * 16); + if (iso->buffer == NULL) return -1; + } + if (iso->flags & ISOFLAGS_BLOCKDUMP) + { + if (_writefile(iso->handle, "BDV2", 4) < 4) return -1; + if (_writefile(iso->handle, &blocksize, 4) < 4) return -1; + if (_writefile(iso->handle, &blocks, 4) < 4) return -1; + if (_writefile(iso->handle, &blockofs, 4) < 4) return -1; + } + + return 0; +} + +s32 MSFtoLSN(u8 *Time) +{ + u32 lsn; + + lsn = Time[2]; + lsn += (Time[1] - 2) * 75; + lsn += Time[0] * 75 * 60; + return lsn; +} + +void LSNtoMSF(u8 *Time, s32 lsn) +{ + u8 m, s, f; + + lsn += 150; + m = lsn / 4500; // minuten + lsn = lsn - m * 4500; // minuten rest + s = lsn / 75; // sekunden + f = lsn - (s * 75); // sekunden rest + Time[0] = itob(m); + Time[1] = itob(s); + Time[2] = itob(f); +} + +int _isoReadBlock(isoFile *iso, u8 *dst, int lsn) +{ + u64 ofs = (u64)lsn * iso->blocksize + iso->offset; + int ret; + +// printf("_isoReadBlock %d, blocksize=%d, blockofs=%d\n", lsn, iso->blocksize, iso->blockofs); + memset(dst, 0, iso->blockofs); + _seekfile(iso->handle, ofs, SEEK_SET); + ret = _readfile(iso->handle, dst + iso->blockofs, iso->blocksize); + if (ret < iso->blocksize) + { + printf("read error %d\n", ret); + return -1; + } + + return 0; +} + +int _isoReadBlockZ(isoFile *iso, u8 *dst, int lsn) +{ + u32 pos, p; + uLongf size; + u8 Zbuf[CD_FRAMESIZE_RAW*2]; + int ret; + +// printf("_isoReadBlockZ %d, %d\n", lsn, iso->blocksize); + pos = *(unsigned long*) & iso->Ztable[lsn * 6]; + p = *(unsigned short*) & iso->Ztable[lsn * 6 + 4]; +// printf("%d, %d\n", pos, p); + _seekfile(iso->handle, pos, SEEK_SET); + ret = _readfile(iso->handle, Zbuf, p); + if (ret < p) + { + printf("error reading block!!\n"); + return -1; + } + + size = CD_FRAMESIZE_RAW; + uncompress(dst, &size, Zbuf, p); + + return 0; +} + +int _isoReadBlockZ2(isoFile *iso, u8 *dst, int lsn) +{ + u32 pos, p; + uLongf size; + u8 Zbuf[16*1024]; + int ret; + +// printf("_isoReadBlockZ2 %d, %d\n", lsn, iso->blocksize); + pos = *(u32*) & iso->Ztable[lsn*8]; + p = *(u32*) & iso->Ztable[lsn*8+4]; +// printf("%d, %d\n", pos, p); + _seekfile(iso->handle, pos, SEEK_SET); + ret = _readfile(iso->handle, Zbuf, p); + if (ret < p) + { + printf("error reading block!!\n"); + return -1; + } + + size = iso->blocksize; + uncompress(dst + iso->blockofs, &size, Zbuf, p); + + return 0; +} + +int _isoReadBlockBZ2(isoFile *iso, u8 *dst, int lsn) +{ + u32 pos, p; + u32 size; + u8 Zbuf[64*1024]; + int ret; + + if ((lsn / 16) == iso->buflsn) + { + memset(dst, 0, iso->blockofs); + memcpy(dst + iso->blockofs, iso->buffer + (iso->blocksize*(lsn&0xf)), iso->blocksize); + return 0; + } + + iso->buflsn = lsn / 16; +// printf("_isoReadBlockBZ2 %d, %d\n", lsn, iso->blocksize); + pos = *(u32*) & iso->Ztable[(lsn/16)*8]; + p = *(u32*) & iso->Ztable[(lsn/16)*8+4]; +// printf("%d, %d\n", pos, p); + _seekfile(iso->handle, pos, SEEK_SET); + ret = _readfile(iso->handle, Zbuf, p); + + if (ret < p) + { + printf("error reading block!!\n"); + return -1; + } + + size = iso->blocksize * 64; + ret = BZ2_bzBuffToBuffDecompress((s8*)iso->buffer, &size, (s8*)Zbuf, p, 0, 0); + + if (ret != BZ_OK) + { + printf("_isoReadBlockBZ2 %d, %d\n", lsn, iso->blocksize); + printf("%d, %d\n", pos, p); + printf("error on BZ2: %d\n", ret); + } + + memset(dst, 0, iso->blockofs); + memcpy(dst + iso->blockofs, iso->buffer + (iso->blocksize*(lsn&0xf)), iso->blocksize); + + return 0; +} + +int _isoReadBlockD(isoFile *iso, u8 *dst, int lsn) +{ + int ret; + int i; + +// printf("_isoReadBlockD %d, blocksize=%d, blockofs=%d\n", lsn, iso->blocksize, iso->blockofs); + memset(dst, 0, iso->blockofs); + for (i = 0; i < iso->dtablesize;i++) + { + if (iso->dtable[i] != lsn) continue; + + _seekfile(iso->handle, 16 + i*(iso->blocksize + 4) + 4, SEEK_SET); + ret = _readfile(iso->handle, dst + iso->blockofs, iso->blocksize); + if (ret < iso->blocksize) return -1; + + return 0; + } + printf("block %d not found in dump\n", lsn); + + return -1; +} + +int _isoReadBlockM(isoFile *iso, u8 *dst, int lsn) +{ + u64 ofs; + int ret; + int i; + + for (i = 0; i < 8; i++) + { + if (lsn >= iso->multih[i].slsn && + lsn <= iso->multih[i].elsn) + { + break; + } + } + if (i == 8) return -1; + + ofs = (u64)(lsn - iso->multih[i].slsn) * iso->blocksize + iso->offset; +// printf("_isoReadBlock %d, blocksize=%d, blockofs=%d\n", lsn, iso->blocksize, iso->blockofs); + memset(dst, 0, iso->blockofs); + _seekfile(iso->multih[i].handle, ofs, SEEK_SET); + ret = _readfile(iso->multih[i].handle, dst + iso->blockofs, iso->blocksize); + + if (ret < iso->blocksize) + { + printf("read error %d\n", ret); + return -1; + } + + return 0; +} + +int isoReadBlock(isoFile *iso, u8 *dst, int lsn) +{ + int ret; + + if (lsn > iso->blocks) + { + printf("isoReadBlock: %d > %d\n", lsn, iso->blocks); + return -1; + } + + if (iso->flags & ISOFLAGS_Z) + ret = _isoReadBlockZ(iso, dst, lsn); + else if (iso->flags & ISOFLAGS_Z2) + ret = _isoReadBlockZ2(iso, dst, lsn); + else if (iso->flags & ISOFLAGS_BLOCKDUMP) + ret = _isoReadBlockD(iso, dst, lsn); + else if (iso->flags & ISOFLAGS_MULTI) + ret = _isoReadBlockM(iso, dst, lsn); + else if (iso->flags & ISOFLAGS_BZ2) + ret = _isoReadBlockBZ2(iso, dst, lsn); + else + ret = _isoReadBlock(iso, dst, lsn); + + if (ret == -1) return ret; + + if (iso->type == ISOTYPE_CD) + { + LSNtoMSF(dst + 12, lsn); + dst[15] = 2; + } + + return 0; +} + + +int _isoWriteBlock(isoFile *iso, u8 *src, int lsn) +{ + u64 ofs = (u64)lsn * iso->blocksize + iso->offset; + int ret; + +// printf("_isoWriteBlock %d (ofs=%d)\n", iso->blocksize, ofs); + _seekfile(iso->handle, ofs, SEEK_SET); + ret = _writefile(iso->handle, src + iso->blockofs, iso->blocksize); +// printf("_isoWriteBlock %d\n", ret); + if (ret < iso->blocksize) return -1; + + return 0; +} + +int _isoWriteBlockZ(isoFile *iso, u8 *src, int lsn) +{ + u32 pos; + uLongf size; + u8 Zbuf[CD_FRAMESIZE_RAW]; + int ret; + +// printf("_isoWriteBlockZ %d\n", iso->blocksize); + size = 2352; + compress(Zbuf, &size, src, 2352); +// printf("_isoWriteBlockZ %d\n", size); + + pos = (u32)_tellfile(iso->handle); + ret = _writefile(iso->htable, &pos, 4); + if (ret < 4) return -1; + ret = _writefile(iso->htable, &size, 2); + if (ret < 2) return -1; + + ret = _writefile(iso->handle, Zbuf, size); +// printf("_isoWriteBlockZ %d\n", ret); + if (ret < size) + { + printf("error writing block!!\n"); + return -1; + } + + return 0; +} + +int _isoWriteBlockZ2(isoFile *iso, u8 *src, int lsn) +{ + uLongf size; + u8 Zbuf[1024*16]; + int ret; + +// printf("_isoWriteBlockZ %d\n", iso->blocksize); + size = 1024 * 16; + compress(Zbuf, &size, src + iso->blockofs, iso->blocksize); +// printf("_isoWriteBlockZ %d\n", size); + + ret = _writefile(iso->htable, (u8*) & size, 4); + if (ret < 4) return -1; + ret = _writefile(iso->handle, Zbuf, size); +// printf("_isoWriteBlockZ %d\n", ret); + if (ret < size) + { + printf("error writing block!!\n"); + return -1; + } + + return 0; +} + +int _isoWriteBlockD(isoFile *iso, u8 *src, int lsn) +{ + int ret; + +// printf("_isoWriteBlock %d (ofs=%d)\n", iso->blocksize, ofs); + ret = _writefile(iso->handle, &lsn, 4); + if (ret < 4) return -1; + ret = _writefile(iso->handle, src + iso->blockofs, iso->blocksize); +// printf("_isoWriteBlock %d\n", ret); + if (ret < iso->blocksize) return -1; + + return 0; +} + +int _isoWriteBlockBZ2(isoFile *iso, u8 *src, int lsn) +{ + u32 size; + u8 Zbuf[64*1024]; + int blocks; + int ret; + + memcpy(iso->buffer + (iso->blocksize*(lsn&0xf)), src + iso->blockofs, iso->blocksize); + + if (lsn == (iso->blocks - 1)) + { + blocks = (lsn & 0xf) + 1; + } + else + { + blocks = 16; + if ((lsn & 0xf) != 0xf) return 0; + } + +// printf("_isoWriteBlockBZ2 %d\n", iso->blocksize); + size = 64 * 1024; + ret = BZ2_bzBuffToBuffCompress((s8*)Zbuf, (u32*) & size, (s8*)iso->buffer, iso->blocksize * blocks, 9, 0, 30); + + if (ret != BZ_OK) + { + printf("error on BZ2: %d\n", ret); + } + +// printf("_isoWriteBlockBZ2 %d\n", size); + + ret = _writefile(iso->htable, (u8*) & size, 4); + if (ret < 4) return -1; + ret = _writefile(iso->handle, Zbuf, size); +// printf("_isoWriteBlockZ %d\n", ret); + + if (ret < size) + { + printf("error writing block!!\n"); + return -1; + } + + return 0; +} + +int isoWriteBlock(isoFile *iso, u8 *src, int lsn) +{ + int ret; + + if (iso->flags & ISOFLAGS_Z) + ret = _isoWriteBlockZ(iso, src, lsn); + else if (iso->flags & ISOFLAGS_Z2) + ret = _isoWriteBlockZ2(iso, src, lsn); + else if (iso->flags & ISOFLAGS_BLOCKDUMP) + ret = _isoWriteBlockD(iso, src, lsn); + else if (iso->flags & ISOFLAGS_BZ2) + ret = _isoWriteBlockBZ2(iso, src, lsn); + else + ret = _isoWriteBlock(iso, src, lsn); + + if (ret == -1) return ret; + return 0; +} + +void isoClose(isoFile *iso) +{ + if (iso->handle) _closefile(iso->handle); + if (iso->htable) _closefile(iso->htable); + if (iso->buffer) free(iso->buffer); + + free(iso); +} + diff --git a/pcsx2/CDVD/IsoFileFormats.h b/pcsx2/CDVD/IsoFileFormats.h new file mode 100644 index 0000000000..3187b2ded0 --- /dev/null +++ b/pcsx2/CDVD/IsoFileFormats.h @@ -0,0 +1,68 @@ +#ifndef __LIBISO_H__ +#define __LIBISO_H__ + +#ifdef _MSC_VER +#pragma warning(disable:4018) +#endif + +#define ISOTYPE_ILLEGAL 0 +#define ISOTYPE_CD 1 +#define ISOTYPE_DVD 2 +#define ISOTYPE_AUDIO 3 +#define ISOTYPE_DVDDL 4 + +#define ISOFLAGS_Z 0x0001 +#define ISOFLAGS_Z2 0x0002 +#define ISOFLAGS_BLOCKDUMP 0x0004 +#define ISOFLAGS_MULTI 0x0008 +#define ISOFLAGS_BZ2 0x0010 + +#define CD_FRAMESIZE_RAW 2352 +#define DATA_SIZE (CD_FRAMESIZE_RAW-12) + +#define itob(i) ((i)/10*16 + (i)%10) /* u_char to BCD */ +#define btoi(b) ((b)/16*10 + (b)%16) /* BCD to u_char */ + +typedef struct +{ + u32 slsn; + u32 elsn; + void *handle; +} _multih; + +typedef struct +{ + char filename[256]; + u32 type; + u32 flags; + u32 offset; + u32 blockofs; + u32 blocksize; + u32 blocks; + void *handle; + void *htable; + char *Ztable; + u32 *dtable; + int dtablesize; + _multih multih[8]; + int buflsn; + u8 *buffer; +} isoFile; + + +isoFile *isoOpen(const char *filename); +isoFile *isoCreate(const char *filename, int mode); +int isoSetFormat(isoFile *iso, int blockofs, int blocksize, int blocks); +int isoDetect(isoFile *iso); +int isoReadBlock(isoFile *iso, u8 *dst, int lsn); +int isoWriteBlock(isoFile *iso, u8 *src, int lsn); +void isoClose(isoFile *iso); + +void *_openfile(const char *filename, int flags); +u64 _tellfile(void *handle); +int _seekfile(void *handle, u64 offset, int whence); +int _readfile(void *handle, void *dst, int size); +int _writefile(void *handle, void *src, int size); +void _closefile(void *handle); + +#endif /* __LIBISO_H__ */ diff --git a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj index f2a5705e8d..26638377ed 100644 --- a/pcsx2/windows/VCprojects/pcsx2_2008.vcproj +++ b/pcsx2/windows/VCprojects/pcsx2_2008.vcproj @@ -71,7 +71,7 @@ @@ -232,7 +232,7 @@ /> + + + + diff --git a/pcsx2/windows/WinMain.cpp b/pcsx2/windows/WinMain.cpp index 48da33b0af..5a4b0f5ed1 100644 --- a/pcsx2/windows/WinMain.cpp +++ b/pcsx2/windows/WinMain.cpp @@ -454,7 +454,7 @@ BOOL Open_Iso_File_Proc( std::string& outstr ) OPENFILENAME ofn; char szFileName[ g_MaxPath ]; char szFileTitle[ g_MaxPath ]; - char * filter = "ISO Files (*.ISO)\0*.ISO\0ALL Files (*.*)\0*.*\0"; + char * filter = "ISO Files (*.ISO)\0*.ISO\0Blockdump Files (*.dump)\0*.dump\0ALL Files (*.*)\0*.*\0"; memzero_obj( szFileName ); memzero_obj( szFileTitle ); @@ -1059,8 +1059,7 @@ void CreateMainMenu() { ADDMENUITEM(0,_("Enable &Profiler"), ID_PROFILER); ADDMENUITEM(0,_("Enable &Patches"), ID_PATCHES); ADDMENUITEM(0,_("Enable &Console"), ID_CONSOLE); - //TODO - //ADDMENUITEM(0,_("Enable &Block Dumping"), ID_BLOCKDUMP); + ADDMENUITEM(0,_("Enable &Block Dumping"), ID_BLOCKDUMP); ADDSEPARATOR(0); ADDMENUITEM(0,_("Patch &Finder..."), ID_CHEAT_FINDER_SHOW); ADDMENUITEM(0,_("Patch &Browser..."), ID_CHEAT_BROWSER_SHOW); diff --git a/pcsx2_suite_2008.sln b/pcsx2_suite_2008.sln index 08e73f0225..07f4455fb8 100644 --- a/pcsx2_suite_2008.sln +++ b/pcsx2_suite_2008.sln @@ -5,6 +5,7 @@ Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "pcsx2", "pcsx2\windows\VCpr ProjectSection(ProjectDependencies) = postProject {26511268-2902-4997-8421-ECD7055F9E28} = {26511268-2902-4997-8421-ECD7055F9E28} {2F6C0388-20CB-4242-9F6C-A6EBB6A83F47} = {2F6C0388-20CB-4242-9F6C-A6EBB6A83F47} + {F4EB4AB2-C595-4B05-8BC0-059024BC796C} = {F4EB4AB2-C595-4B05-8BC0-059024BC796C} EndProjectSection EndProject Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "ZeroGS", "plugins\zerogs\dx\Windows\zerogs_2008.vcproj", "{5C6B7D28-E73D-4F71-8FC0-17ADA640EBD8}"