Skip to content
Permalink
Browse files

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
  • Loading branch information...
turtleli authored and ramapcsx2 committed Aug 25, 2019
1 parent 0147538 commit 92aa43fe913fd9f5255c0d872071075f70c54642
@@ -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,23 +50,15 @@ int InputIsoFile::ReadSync(u8* dst, uint lsn)

void InputIsoFile::BeginRead2(uint 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 = lsn;

m_current_lsn = -1;
if (lsn >= m_blocks)
{
// 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))
{
@@ -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 @@ class InputIsoFile
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,25 +257,23 @@ 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);
s_request_queue.push(sector);
}

s_notify_cv.notify_one();

return 0;
}

u8 *cdvdGetSector(u32 sector, s32 mode)

0 comments on commit 92aa43f

Please sign in to comment.
You can’t perform that action at this time.