mirror of https://github.com/PCSX2/pcsx2.git
cdvd: Fix end-of-disc issues (#3051)
* cdvd: Fix off-by-one end of file checks * cdvd: Fix loading for games that attempt to read non-existent sectors Some games will hang when attempting to read non-existent sectors. Just do nothing when it occurs instead of erroring out. * cdvdgigaherz: Fix loading for games that attempt to read non-existent sectors Some games will hang when attempting to read non-existent sectors. Just do nothing when it occurs instead of erroring out. * cdvd: Don't write non-existent sectors to blockdump
This commit is contained in:
parent
014753894a
commit
92aa43fe91
|
@ -56,7 +56,7 @@ static int diskTypeCached = -1;
|
|||
|
||||
// used to bridge the gap between the old getBuffer api and the new getBuffer2 api.
|
||||
int lastReadSize;
|
||||
int lastLSN; // needed for block dumping
|
||||
u32 lastLSN; // needed for block dumping
|
||||
|
||||
// Records last read block length for block dumping
|
||||
//static int plsn = 0;
|
||||
|
@ -490,6 +490,12 @@ s32 DoCDVDgetBuffer(u8* buffer)
|
|||
|
||||
if (ret == 0 && blockDumpFile.IsOpened())
|
||||
{
|
||||
cdvdTD td;
|
||||
CDVD->getTD(0, &td);
|
||||
|
||||
if (lastLSN >= td.lsn)
|
||||
return 0;
|
||||
|
||||
if (blockDumpFile.GetBlockSize() == CD_FRAMESIZE_RAW && lastReadSize != 2352)
|
||||
{
|
||||
u8 blockDumpBuffer[CD_FRAMESIZE_RAW];
|
||||
|
|
|
@ -315,7 +315,7 @@ s32 CALLBACK ISOreadSector(u8* tempbuffer, u32 lsn, int mode)
|
|||
int _lsn = lsn;
|
||||
|
||||
if (_lsn < 0) lsn = iso.GetBlockCount() + _lsn;
|
||||
if (lsn > iso.GetBlockCount()) return -1;
|
||||
if (lsn >= iso.GetBlockCount()) return -1;
|
||||
|
||||
if(mode == CDVD_MODE_2352)
|
||||
{
|
||||
|
@ -362,7 +362,6 @@ s32 CALLBACK ISOreadTrack(u32 lsn, int mode)
|
|||
int _lsn = lsn;
|
||||
|
||||
if (_lsn < 0) lsn = iso.GetBlockCount() + _lsn;
|
||||
if (lsn > iso.GetBlockCount()) return -1;
|
||||
|
||||
iso.BeginRead2(lsn);
|
||||
|
||||
|
|
|
@ -35,10 +35,10 @@ static const char* nameFromType(int type)
|
|||
|
||||
int InputIsoFile::ReadSync(u8* dst, uint lsn)
|
||||
{
|
||||
if (lsn > m_blocks)
|
||||
if (lsn >= m_blocks)
|
||||
{
|
||||
FastFormatUnicode msg;
|
||||
msg.Write("isoFile error: Block index is past the end of file! (%u > %u).", lsn, m_blocks);
|
||||
msg.Write("isoFile error: Block index is past the end of file! (%u >= %u).", lsn, m_blocks);
|
||||
|
||||
pxAssertDev(false, msg);
|
||||
Console.Error(msg.c_str());
|
||||
|
@ -50,24 +50,16 @@ int InputIsoFile::ReadSync(u8* dst, uint lsn)
|
|||
|
||||
void InputIsoFile::BeginRead2(uint lsn)
|
||||
{
|
||||
if (lsn > m_blocks)
|
||||
m_current_lsn = lsn;
|
||||
|
||||
if (lsn >= m_blocks)
|
||||
{
|
||||
FastFormatUnicode msg;
|
||||
msg.Write("isoFile error: Block index is past the end of file! (%u > %u).", lsn, m_blocks);
|
||||
|
||||
pxAssertDev(false, msg);
|
||||
Console.Error(msg.c_str());
|
||||
|
||||
// [TODO] : Throw exception?
|
||||
// Typically an error like this is bad; indicating an invalid dump or corrupted
|
||||
// iso file.
|
||||
|
||||
m_current_lsn = -1;
|
||||
// While this usually indicates that the ISO is corrupted, some games do attempt
|
||||
// to read past the end of the disc, so don't error here.
|
||||
DevCon.Warning("isoFile error: Block index is past the end of file! (%u >= %u).", lsn, m_blocks);
|
||||
return;
|
||||
}
|
||||
|
||||
m_current_lsn = lsn;
|
||||
|
||||
if(lsn >= m_read_lsn && lsn < (m_read_lsn+m_read_count))
|
||||
{
|
||||
// Already buffered
|
||||
|
@ -90,13 +82,17 @@ void InputIsoFile::BeginRead2(uint lsn)
|
|||
|
||||
int InputIsoFile::FinishRead3(u8* dst, uint mode)
|
||||
{
|
||||
// Do nothing for out of bounds disc sector reads. It prevents some games
|
||||
// from hanging (All-Star Baseball 2005, Hello Kitty: Roller Rescue,
|
||||
// Hot Wheels: Beat That! (NTSC), Ratchet & Clank 3 (PAL),
|
||||
// Test Drive: Eve of Destruction, etc.).
|
||||
if (m_current_lsn >= m_blocks)
|
||||
return 0;
|
||||
|
||||
int _offset = 0;
|
||||
int length = 0;
|
||||
int ret = 0;
|
||||
|
||||
if(m_current_lsn < 0)
|
||||
return -1;
|
||||
|
||||
if(m_read_inprogress)
|
||||
{
|
||||
ret = m_reader->FinishRead();
|
||||
|
|
|
@ -48,7 +48,7 @@ protected:
|
|||
wxString m_filename;
|
||||
AsyncFileReader* m_reader;
|
||||
|
||||
s32 m_current_lsn;
|
||||
u32 m_current_lsn;
|
||||
|
||||
isoType m_type;
|
||||
u32 m_flags;
|
||||
|
|
|
@ -452,7 +452,8 @@ static const LegacyApi_OptMethod s_MethMessOpt_PAD[] =
|
|||
// ----------------------------------------------------------------------------
|
||||
void CALLBACK CDVD_newDiskCB(void (*callback)()) {}
|
||||
|
||||
extern int lastReadSize, lastLSN;
|
||||
extern int lastReadSize;
|
||||
extern u32 lastLSN;
|
||||
static s32 CALLBACK CDVD_getBuffer2(u8* buffer)
|
||||
{
|
||||
// TEMP: until I fix all the plugins to use this function style
|
||||
|
|
|
@ -40,7 +40,7 @@ track tracks[100];
|
|||
int curDiskType;
|
||||
int curTrayStatus;
|
||||
|
||||
int csector;
|
||||
static u32 csector;
|
||||
int cmode;
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
|
@ -252,7 +252,9 @@ EXPORT s32 CALLBACK CDVDreadTrack(u32 lsn, int mode)
|
|||
return ret;
|
||||
}
|
||||
|
||||
return lsn < src->GetSectorCount() ? cdvdRequestSector(lsn, mode) : -1;
|
||||
cdvdRequestSector(lsn, mode);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
// return can be NULL (for async modes)
|
||||
|
@ -269,6 +271,13 @@ EXPORT u8 *CALLBACK CDVDgetBuffer()
|
|||
// return can be NULL (for async modes)
|
||||
EXPORT int CALLBACK CDVDgetBuffer2(u8 *dest)
|
||||
{
|
||||
// Do nothing for out of bounds disc sector reads. It prevents some games
|
||||
// from hanging (All-Star Baseball 2005, Hello Kitty: Roller Rescue,
|
||||
// Hot Wheels: Beat That! (NTSC), Ratchet & Clank 3 (PAL),
|
||||
// Test Drive: Eve of Destruction, etc.).
|
||||
if (csector >= src->GetSectorCount())
|
||||
return 0;
|
||||
|
||||
int csize = 2352;
|
||||
switch (cmode) {
|
||||
case CDVD_MODE_2048:
|
||||
|
|
|
@ -113,7 +113,7 @@ extern void (*newDiscCB)();
|
|||
|
||||
bool cdvdStartThread();
|
||||
void cdvdStopThread();
|
||||
s32 cdvdRequestSector(u32 sector, s32 mode);
|
||||
void cdvdRequestSector(u32 sector, s32 mode);
|
||||
u8 *cdvdGetSector(u32 sector, s32 mode);
|
||||
s32 cdvdDirectReadSector(u32 sector, s32 mode, u8 *buffer);
|
||||
s32 cdvdGetMediaType();
|
||||
|
|
|
@ -257,16 +257,16 @@ void cdvdStopThread()
|
|||
s_thread.join();
|
||||
}
|
||||
|
||||
s32 cdvdRequestSector(u32 sector, s32 mode)
|
||||
void cdvdRequestSector(u32 sector, s32 mode)
|
||||
{
|
||||
if (sector >= src->GetSectorCount())
|
||||
return -1;
|
||||
return;
|
||||
|
||||
// Align to cache block
|
||||
sector &= ~(sectors_per_read - 1);
|
||||
|
||||
if (cdvdCacheCheck(sector))
|
||||
return 0;
|
||||
return;
|
||||
|
||||
{
|
||||
std::lock_guard<std::mutex> guard(s_request_lock);
|
||||
|
@ -274,8 +274,6 @@ s32 cdvdRequestSector(u32 sector, s32 mode)
|
|||
}
|
||||
|
||||
s_notify_cv.notify_one();
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
u8 *cdvdGetSector(u32 sector, s32 mode)
|
||||
|
|
Loading…
Reference in New Issue