diff --git a/common/include/PS2Edefs.h b/common/include/PS2Edefs.h index e148f508fa..ada9202739 100644 --- a/common/include/PS2Edefs.h +++ b/common/include/PS2Edefs.h @@ -674,6 +674,7 @@ typedef s32 (CALLBACK* _CDVDctrlTrayOpen)(); typedef s32 (CALLBACK* _CDVDctrlTrayClose)(); typedef s32 (CALLBACK* _CDVDreadSector)(u8* buffer, u32 lsn, int mode); typedef s32 (CALLBACK* _CDVDgetDualInfo)(s32* dualType, u32* _layer1start); +typedef void (CALLBACK* _CDVDnotifyReadLength)(s32 readLength); typedef void (CALLBACK* _CDVDnewDiskCB)(void (*callback)()); diff --git a/pcsx2/AsyncFileReader.h b/pcsx2/AsyncFileReader.h index 22a09f5bb2..25ffa0b615 100644 --- a/pcsx2/AsyncFileReader.h +++ b/pcsx2/AsyncFileReader.h @@ -10,12 +10,14 @@ class AsyncFileReader { protected: - AsyncFileReader(void) {} + AsyncFileReader(void) { m_nextExpectedRead = -1; } wxString m_filename; uint m_blocksize; + uint m_nextExpectedRead; + public: virtual ~AsyncFileReader(void) {}; @@ -32,6 +34,8 @@ public: virtual uint GetBlockCount(void) const=0; virtual void SetBlockSize(uint bytes) {} + + uint GetReadAheadHint() const { return m_nextExpectedRead; } uint GetBlockSize() const { return m_blocksize; } @@ -73,7 +77,7 @@ public: virtual void Close(void); virtual uint GetBlockCount(void) const; - + void SetBlockSize(uint bytes) { m_blocksize = bytes; } }; diff --git a/pcsx2/CDVD/CDVD.cpp b/pcsx2/CDVD/CDVD.cpp index f0b531d42a..e230eedb6c 100644 --- a/pcsx2/CDVD/CDVD.cpp +++ b/pcsx2/CDVD/CDVD.cpp @@ -598,9 +598,12 @@ void SaveStateBase::cdvdFreeze() // Make sure the Cdvd plugin has the expected track loaded into the buffer. // If cdvd.Readed is cleared it means we need to load the SeekToSector (ie, a // seek is in progress!) - + if( cdvd.Reading ) + { + DoCDVDnotifyReadLength(cdvd.nSectors); cdvd.RErr = DoCDVDreadTrack( cdvd.Readed ? cdvd.Sector : cdvd.SeekToSector, cdvd.ReadMode); + } } } @@ -1218,6 +1221,8 @@ static void cdvdWrite04(u8 rt) { // NCOMMAND cdvd.ReadTime = cdvdBlockReadTime( MODE_CDROM ); CDVDREAD_INT( cdvdStartSeek( cdvd.SeekToSector,MODE_CDROM ) ); + + DoCDVDnotifyReadLength(cdvd.nSectors); // Read-ahead by telling the plugin about the track now. // This helps improve performance on actual from-cd emulation @@ -1266,6 +1271,8 @@ static void cdvdWrite04(u8 rt) { // NCOMMAND cdvd.ReadTime = cdvdBlockReadTime( MODE_CDROM ); CDVDREAD_INT( cdvdStartSeek( cdvd.SeekToSector, MODE_CDROM ) ); + + DoCDVDnotifyReadLength(cdvd.nSectors); // Read-ahead by telling the plugin about the track now. // This helps improve performance on actual from-cd emulation @@ -1302,6 +1309,8 @@ static void cdvdWrite04(u8 rt) { // NCOMMAND cdvd.ReadTime = cdvdBlockReadTime( MODE_DVDROM ); CDVDREAD_INT( cdvdStartSeek( cdvd.SeekToSector, MODE_DVDROM ) ); + + DoCDVDnotifyReadLength(cdvd.nSectors); // Read-ahead by telling the plugin about the track now. // This helps improve performance on actual from-cd emulation diff --git a/pcsx2/CDVD/CDVDaccess.cpp b/pcsx2/CDVD/CDVDaccess.cpp index cf71955a22..e3282338d9 100644 --- a/pcsx2/CDVD/CDVDaccess.cpp +++ b/pcsx2/CDVD/CDVDaccess.cpp @@ -419,6 +419,11 @@ s32 DoCDVDreadSector(u8* buffer, u32 lsn, int mode) return ret; } +void DoCDVDnotifyReadLength(s32 length) +{ + CDVD->notifyReadLength(length); +} + s32 DoCDVDreadTrack(u32 lsn, int mode) { CheckNullCDVD(); diff --git a/pcsx2/CDVD/CDVDaccess.h b/pcsx2/CDVD/CDVDaccess.h index f4b35fe591..20803802de 100644 --- a/pcsx2/CDVD/CDVDaccess.h +++ b/pcsx2/CDVD/CDVDaccess.h @@ -51,6 +51,7 @@ struct CDVD_API _CDVDreadSector readSector; _CDVDgetBuffer2 getBuffer2; _CDVDgetDualInfo getDualInfo; + _CDVDnotifyReadLength notifyReadLength; }; // ---------------------------------------------------------------------------- @@ -80,3 +81,4 @@ extern s32 DoCDVDgetBuffer(u8* buffer); extern s32 DoCDVDdetectDiskType(); extern void DoCDVDresetDiskTypeCache(); +extern void DoCDVDnotifyReadLength(s32 length); diff --git a/pcsx2/CDVD/CDVDisoReader.cpp b/pcsx2/CDVD/CDVDisoReader.cpp index 4cc5b0c14b..08bfc4d8dc 100644 --- a/pcsx2/CDVD/CDVDisoReader.cpp +++ b/pcsx2/CDVD/CDVDisoReader.cpp @@ -475,6 +475,11 @@ void CALLBACK ISOnewDiskCB(void(* /* callback */)()) { } +void CALLBACK ISOnotifyReadLength(s32 readLength) +{ + iso.NotifyReadLength(readLength); +} + CDVD_API CDVDapi_Iso = { ISOclose, @@ -496,4 +501,5 @@ CDVD_API CDVDapi_Iso = ISOreadSector, ISOgetBuffer2, ISOgetDualInfo, + ISOnotifyReadLength }; diff --git a/pcsx2/CDVD/InputIsoFile.cpp b/pcsx2/CDVD/InputIsoFile.cpp index 4fccad37e8..dabbab3405 100644 --- a/pcsx2/CDVD/InputIsoFile.cpp +++ b/pcsx2/CDVD/InputIsoFile.cpp @@ -50,6 +50,18 @@ int InputIsoFile::ReadSync(u8* dst, uint lsn) void InputIsoFile::BeginRead2(uint lsn) { + if(m_read_inprogress) + { + if(lsn >= m_read_lsn && lsn < (m_read_lsn+m_read_count)) + { + // read already in progress + return; + } + + FinishRead3(NULL, 0); + m_is_reading_ahead = false; + } + if (lsn > m_blocks) { FastFormatUnicode msg; @@ -98,12 +110,22 @@ int InputIsoFile::FinishRead3(u8* dst, uint mode) if(m_read_inprogress) { - ret = m_reader->FinishRead(); + if(dst) + ret = m_reader->FinishRead(); + else + { + m_reader->CancelRead(); + return -1; + } + m_read_inprogress = false; if(ret < 0) return ret; } + + if(!dst) + return -1; switch (mode) { @@ -153,6 +175,22 @@ int InputIsoFile::FinishRead3(u8* dst, uint mode) dst[diff - 9] = 2; } + if(m_expected_sequential_remaining > 0) + m_expected_sequential_remaining --; + + if(m_read_ahead > 0 && (m_expected_sequential_remaining > 0 || m_read_length > 1)) + { + uint lsn = (m_expected_sequential_remaining > 0) ? + m_read_lsn + 1 : + m_reader->GetReadAheadHint(); + + if(lsn >= 0) + { + m_is_reading_ahead = true; + BeginRead2(lsn); + } + } + return 0; } @@ -179,6 +217,11 @@ void InputIsoFile::_init() m_read_inprogress = false; m_read_count = 0; m_read_lsn = -1; + + m_read_length = 0; + m_expected_sequential_remaining = 0; + + m_is_reading_ahead = false; } // Tests the specified filename to see if it is a supported ISO type. This function typically @@ -218,7 +261,9 @@ bool InputIsoFile::Open( const wxString& srcfile, bool testOnly ) m_reader = bdr; - ReadUnit = 1; + ReadUnit = 1; + + m_read_ahead = 0; } bool detected = Detect(); @@ -239,6 +284,8 @@ bool InputIsoFile::Open( const wxString& srcfile, bool testOnly ) // Returns the original reader if single-part or a Multipart reader otherwise m_reader = MultipartFileReader::DetectMultipart(m_reader); + + m_read_ahead = MaxReadAhead; } m_blocks = m_reader->GetBlockCount(); diff --git a/pcsx2/CDVD/IsoFileFormats.h b/pcsx2/CDVD/IsoFileFormats.h index dc1bd03ec9..2774de96c8 100644 --- a/pcsx2/CDVD/IsoFileFormats.h +++ b/pcsx2/CDVD/IsoFileFormats.h @@ -37,7 +37,8 @@ class InputIsoFile { DeclareNoncopyableObject( InputIsoFile ); - static const uint MaxReadUnit = 128; + static const uint MaxReadUnit = 1; + static const uint MaxReadAhead = 1; protected: uint ReadUnit; @@ -63,7 +64,13 @@ protected: uint m_read_lsn; uint m_read_count; u8 m_readbuffer[MaxReadUnit * CD_FRAMESIZE_RAW]; + + uint m_read_ahead; + uint m_read_length; + bool m_is_reading_ahead; + uint m_expected_sequential_remaining; + public: InputIsoFile(); virtual ~InputIsoFile() throw(); @@ -88,6 +95,8 @@ public: void BeginRead2(uint lsn); int FinishRead3(u8* dest, uint mode); + + void NotifyReadLength(s32 length) { m_expected_sequential_remaining = m_read_length = length; } protected: void _init(); diff --git a/pcsx2/windows/FlatFileReaderWindows.cpp b/pcsx2/windows/FlatFileReaderWindows.cpp index 8e0c908c1b..6bb05c052e 100644 --- a/pcsx2/windows/FlatFileReaderWindows.cpp +++ b/pcsx2/windows/FlatFileReaderWindows.cpp @@ -34,16 +34,6 @@ bool FlatFileReader::Open(const wxString& fileName) int FlatFileReader::ReadSync(void* pBuffer, uint sector, uint count) { - //LARGE_INTEGER offset; - //offset.QuadPart = sector * (__int64)m_blocksize; - // - //DWORD bytesToRead = count * m_blocksize; - //DWORD bytes; - - //if(!ReadFile(hOverlappedFile, pBuffer, bytesToRead, &bytes, NULL)) - // return -1; - - //return bytes; BeginRead(pBuffer, sector, count); return FinishRead(); } @@ -62,6 +52,8 @@ void FlatFileReader::BeginRead(void* pBuffer, uint sector, uint count) ReadFile(hOverlappedFile, pBuffer, bytesToRead, NULL, &asyncOperationContext); asyncInProgress = true; + + m_nextExpectedRead = sector + count; } int FlatFileReader::FinishRead(void)