mirror of https://github.com/PCSX2/pcsx2.git
CDVD: Use ThreadedFileReader for block dumps
This commit is contained in:
parent
89c4e2c1a4
commit
f0ae33d61e
|
@ -95,40 +95,3 @@ public:
|
||||||
void SetBlockSize(u32 bytes) override { m_blocksize = bytes; }
|
void SetBlockSize(u32 bytes) override { m_blocksize = bytes; }
|
||||||
void SetDataOffset(u32 bytes) override { m_dataoffset = bytes; }
|
void SetDataOffset(u32 bytes) override { m_dataoffset = bytes; }
|
||||||
};
|
};
|
||||||
|
|
||||||
class BlockdumpFileReader : public AsyncFileReader
|
|
||||||
{
|
|
||||||
DeclareNoncopyableObject(BlockdumpFileReader);
|
|
||||||
|
|
||||||
std::FILE* m_file;
|
|
||||||
|
|
||||||
// total number of blocks in the ISO image (including all parts)
|
|
||||||
u32 m_blocks;
|
|
||||||
s32 m_blockofs;
|
|
||||||
|
|
||||||
// index table
|
|
||||||
std::unique_ptr<u32[]> m_dtable;
|
|
||||||
int m_dtablesize;
|
|
||||||
|
|
||||||
int m_lresult;
|
|
||||||
|
|
||||||
public:
|
|
||||||
BlockdumpFileReader();
|
|
||||||
~BlockdumpFileReader() override;
|
|
||||||
|
|
||||||
bool Open(std::string filename, Error* error) override;
|
|
||||||
|
|
||||||
int ReadSync(void* pBuffer, u32 sector, u32 count) override;
|
|
||||||
|
|
||||||
void BeginRead(void* pBuffer, u32 sector, u32 count) override;
|
|
||||||
int FinishRead() override;
|
|
||||||
void CancelRead() override;
|
|
||||||
|
|
||||||
void Close() override;
|
|
||||||
|
|
||||||
u32 GetBlockCount() const override;
|
|
||||||
|
|
||||||
static bool DetectBlockdump(AsyncFileReader* reader);
|
|
||||||
|
|
||||||
s32 GetBlockOffset() { return m_blockofs; }
|
|
||||||
};
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
// SPDX-FileCopyrightText: 2002-2023 PCSX2 Dev Team
|
// SPDX-FileCopyrightText: 2002-2023 PCSX2 Dev Team
|
||||||
// SPDX-License-Identifier: LGPL-3.0+
|
// SPDX-License-Identifier: LGPL-3.0+
|
||||||
|
|
||||||
#include "AsyncFileReader.h"
|
#include "BlockdumpFileReader.h"
|
||||||
#include "IsoFileFormats.h"
|
#include "IsoFileFormats.h"
|
||||||
|
|
||||||
#include "common/Assertions.h"
|
#include "common/Assertions.h"
|
||||||
|
@ -27,8 +27,7 @@ bool BlockdumpFileReader::DetectBlockdump(AsyncFileReader* reader)
|
||||||
reader->SetBlockSize(1);
|
reader->SetBlockSize(1);
|
||||||
|
|
||||||
char buf[4] = {0};
|
char buf[4] = {0};
|
||||||
bool isbd = (reader->ReadSync(buf, 0, sizeof(buf)) == 4
|
bool isbd = (reader->ReadSync(buf, 0, sizeof(buf)) == 4 && std::memcmp(buf, "BDV2", sizeof(buf)) == 0);
|
||||||
&& std::memcmp(buf, "BDV2", sizeof(buf)) == 0);
|
|
||||||
|
|
||||||
if (!isbd)
|
if (!isbd)
|
||||||
reader->SetBlockSize(oldbs);
|
reader->SetBlockSize(oldbs);
|
||||||
|
@ -36,21 +35,14 @@ bool BlockdumpFileReader::DetectBlockdump(AsyncFileReader* reader)
|
||||||
return isbd;
|
return isbd;
|
||||||
}
|
}
|
||||||
|
|
||||||
BlockdumpFileReader::BlockdumpFileReader()
|
BlockdumpFileReader::BlockdumpFileReader() = default;
|
||||||
: m_file(NULL)
|
|
||||||
, m_blocks(0)
|
|
||||||
, m_blockofs(0)
|
|
||||||
, m_dtablesize(0)
|
|
||||||
, m_lresult(0)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
BlockdumpFileReader::~BlockdumpFileReader()
|
BlockdumpFileReader::~BlockdumpFileReader()
|
||||||
{
|
{
|
||||||
Close();
|
Close();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool BlockdumpFileReader::Open(std::string filename, Error* error)
|
bool BlockdumpFileReader::Open2(std::string filename, Error* error)
|
||||||
{
|
{
|
||||||
char signature[4];
|
char signature[4];
|
||||||
|
|
||||||
|
@ -60,30 +52,32 @@ bool BlockdumpFileReader::Open(std::string filename, Error* error)
|
||||||
|
|
||||||
if (std::fread(signature, sizeof(signature), 1, m_file) != 1 || std::memcmp(signature, "BDV2", sizeof(signature)) != 0)
|
if (std::fread(signature, sizeof(signature), 1, m_file) != 1 || std::memcmp(signature, "BDV2", sizeof(signature)) != 0)
|
||||||
{
|
{
|
||||||
Error::SetString(error, "Block dump signature is invalid.");
|
Error::SetStringView(error, "Block dump signature is invalid.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
//m_flags = ISOFLAGS_BLOCKDUMP_V2;
|
//m_flags = ISOFLAGS_BLOCKDUMP_V2;
|
||||||
if (std::fread(&m_blocksize, sizeof(m_blocksize), 1, m_file) != 1
|
if (std::fread(&m_dblocksize, sizeof(m_dblocksize), 1, m_file) != 1 ||
|
||||||
|| std::fread(&m_blocks, sizeof(m_blocks), 1, m_file) != 1
|
std::fread(&m_blocks, sizeof(m_blocks), 1, m_file) != 1 ||
|
||||||
|| std::fread(&m_blockofs, sizeof(m_blockofs), 1, m_file) != 1)
|
std::fread(&m_blockofs, sizeof(m_blockofs), 1, m_file) != 1)
|
||||||
{
|
{
|
||||||
Error::SetString(error, "Failed to read block dump information.");
|
Error::SetStringView(error, "Failed to read block dump information.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_blocksize = m_dblocksize;
|
||||||
|
|
||||||
const s64 flen = FileSystem::FSize64(m_file);
|
const s64 flen = FileSystem::FSize64(m_file);
|
||||||
const s64 datalen = flen - BlockDumpHeaderSize;
|
const s64 datalen = flen - BlockDumpHeaderSize;
|
||||||
|
|
||||||
pxAssert((datalen % (m_blocksize + 4)) == 0);
|
pxAssert((datalen % (m_dblocksize + 4)) == 0);
|
||||||
|
|
||||||
m_dtablesize = datalen / (m_blocksize + 4);
|
m_dtablesize = datalen / (m_dblocksize + 4);
|
||||||
m_dtable = std::make_unique<u32[]>(m_dtablesize);
|
m_dtable = std::make_unique_for_overwrite<u32[]>(m_dtablesize);
|
||||||
|
|
||||||
if (FileSystem::FSeek64(m_file, BlockDumpHeaderSize, SEEK_SET) != 0)
|
if (FileSystem::FSeek64(m_file, BlockDumpHeaderSize, SEEK_SET) != 0)
|
||||||
{
|
{
|
||||||
Error::SetString(error, "Failed to seek to block dump data.");
|
Error::SetStringView(error, "Failed to seek to block dump data.");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -100,7 +94,7 @@ bool BlockdumpFileReader::Open(std::string filename, Error* error)
|
||||||
{
|
{
|
||||||
m_dtable[i++] = *reinterpret_cast<u32*>(buffer.get() + off);
|
m_dtable[i++] = *reinterpret_cast<u32*>(buffer.get() + off);
|
||||||
off += 4;
|
off += 4;
|
||||||
off += m_blocksize;
|
off += m_dblocksize;
|
||||||
}
|
}
|
||||||
|
|
||||||
off -= has;
|
off -= has;
|
||||||
|
@ -110,74 +104,60 @@ bool BlockdumpFileReader::Open(std::string filename, Error* error)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
int BlockdumpFileReader::ReadSync(void* pBuffer, u32 lsn, u32 count)
|
ThreadedFileReader::Chunk BlockdumpFileReader::ChunkForOffset(u64 offset)
|
||||||
{
|
{
|
||||||
u8* dst = (u8*)pBuffer;
|
Chunk chunk = {};
|
||||||
// Console.WriteLn("_isoReadBlockD %u, blocksize=%u, blockofs=%u\n", lsn, iso->blocksize, iso->blockofs);
|
chunk.chunkID = offset / m_dblocksize;
|
||||||
|
chunk.length = m_dblocksize;
|
||||||
|
chunk.offset = chunk.chunkID * m_dblocksize;
|
||||||
|
return chunk;
|
||||||
|
}
|
||||||
|
|
||||||
while (count > 0)
|
int BlockdumpFileReader::ReadChunk(void* dst, s64 blockID)
|
||||||
|
{
|
||||||
|
pxAssert(blockID >= 0 && blockID < static_cast<s64>(m_blocks));
|
||||||
|
const u32 lsn = static_cast<u32>(blockID);
|
||||||
|
// Console.WriteLn("_isoReadBlockD %u, blocksize=%u, blockofs=%u\n", static_cast<u32>(blockID), iso->blocksize, iso->blockofs);
|
||||||
|
|
||||||
|
for (int i = 0; i < m_dtablesize; ++i)
|
||||||
{
|
{
|
||||||
bool ok = false;
|
if (m_dtable[i] != lsn)
|
||||||
for (int i = 0; i < m_dtablesize; ++i)
|
continue;
|
||||||
{
|
|
||||||
if (m_dtable[i] != lsn)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
// We store the LSN (u32) along with each block inside of blockdumps, so the
|
// We store the LSN (u32) along with each block inside of blockdumps, so the
|
||||||
// seek position ends up being based on (m_blocksize + 4) instead of just m_blocksize.
|
// seek position ends up being based on (m_blocksize + 4) instead of just m_blocksize.
|
||||||
|
|
||||||
#ifdef PCSX2_DEBUG
|
#ifdef PCSX2_DEBUG
|
||||||
u32 check_lsn = 0;
|
u32 check_lsn = 0;
|
||||||
FileSystem::FSeek64(m_file, BlockDumpHeaderSize + (i * (m_blocksize + 4)), SEEK_SET);
|
FileSystem::FSeek64(m_file, BlockDumpHeaderSize + (i * (m_blocksize + 4)), SEEK_SET);
|
||||||
std::fread(&check_lsn, sizeof(check_lsn), 1, m_file);
|
std::fread(&check_lsn, sizeof(check_lsn), 1, m_file);
|
||||||
pxAssert(check_lsn == lsn);
|
pxAssert(check_lsn == lsn);
|
||||||
#else
|
#else
|
||||||
if (FileSystem::FSeek64(m_file, BlockDumpHeaderSize + (i * (m_blocksize + 4)) + 4, SEEK_SET) != 0)
|
if (FileSystem::FSeek64(m_file, BlockDumpHeaderSize + (i * (m_blocksize + 4)) + 4, SEEK_SET) != 0)
|
||||||
break;
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (std::fread(dst, m_blocksize, 1, m_file) != 1)
|
if (std::fread(dst, m_blocksize, 1, m_file) != 1)
|
||||||
break;
|
return 0;
|
||||||
|
else
|
||||||
ok = true;
|
return m_blocksize;
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!ok)
|
|
||||||
{
|
|
||||||
Console.WriteLn("Block %u not found in dump", lsn);
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
count--;
|
|
||||||
lsn++;
|
|
||||||
dst += m_blocksize;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
// Either we hit a sector that's not in the dump, and needed, or the threaded reader is just reading ahead.
|
||||||
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void BlockdumpFileReader::BeginRead(void* pBuffer, u32 sector, u32 count)
|
void BlockdumpFileReader::Close2()
|
||||||
{
|
{
|
||||||
m_lresult = ReadSync(pBuffer, sector, count);
|
if (!m_file)
|
||||||
}
|
return;
|
||||||
|
|
||||||
int BlockdumpFileReader::FinishRead()
|
std::fclose(m_file);
|
||||||
{
|
m_file = nullptr;
|
||||||
return m_lresult;
|
m_dtable.reset();
|
||||||
}
|
m_dtablesize = 0;
|
||||||
|
m_dblocksize = 0;
|
||||||
void BlockdumpFileReader::CancelRead()
|
m_blocks = 0;
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
void BlockdumpFileReader::Close(void)
|
|
||||||
{
|
|
||||||
if (m_file)
|
|
||||||
{
|
|
||||||
std::fclose(m_file);
|
|
||||||
m_file = nullptr;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 BlockdumpFileReader::GetBlockCount() const
|
u32 BlockdumpFileReader::GetBlockCount() const
|
||||||
|
|
|
@ -0,0 +1,39 @@
|
||||||
|
// SPDX-FileCopyrightText: 2002-2024 PCSX2 Dev Team
|
||||||
|
// SPDX-License-Identifier: LGPL-3.0+
|
||||||
|
|
||||||
|
#include "CDVD/ThreadedFileReader.h"
|
||||||
|
|
||||||
|
#include <cstdio>
|
||||||
|
|
||||||
|
class BlockdumpFileReader final : public ThreadedFileReader
|
||||||
|
{
|
||||||
|
DeclareNoncopyableObject(BlockdumpFileReader);
|
||||||
|
|
||||||
|
std::FILE* m_file = nullptr;
|
||||||
|
|
||||||
|
// total number of blocks in the ISO image (including all parts)
|
||||||
|
u32 m_dblocksize = 0;
|
||||||
|
u32 m_blocks = 0;
|
||||||
|
s32 m_blockofs = 0;
|
||||||
|
|
||||||
|
// index table
|
||||||
|
std::unique_ptr<u32[]> m_dtable;
|
||||||
|
int m_dtablesize = 0;
|
||||||
|
|
||||||
|
public:
|
||||||
|
BlockdumpFileReader();
|
||||||
|
~BlockdumpFileReader() override;
|
||||||
|
|
||||||
|
bool Open2(std::string filename, Error* error) override;
|
||||||
|
|
||||||
|
Chunk ChunkForOffset(u64 offset) override;
|
||||||
|
int ReadChunk(void* dst, s64 blockID) override;
|
||||||
|
|
||||||
|
void Close2() override;
|
||||||
|
|
||||||
|
u32 GetBlockCount() const override;
|
||||||
|
|
||||||
|
static bool DetectBlockdump(AsyncFileReader* reader);
|
||||||
|
|
||||||
|
s32 GetBlockOffset() { return m_blockofs; }
|
||||||
|
};
|
|
@ -1,6 +1,7 @@
|
||||||
// SPDX-FileCopyrightText: 2002-2023 PCSX2 Dev Team
|
// SPDX-FileCopyrightText: 2002-2023 PCSX2 Dev Team
|
||||||
// SPDX-License-Identifier: LGPL-3.0+
|
// SPDX-License-Identifier: LGPL-3.0+
|
||||||
|
|
||||||
|
#include "CDVD/BlockdumpFileReader.h"
|
||||||
#include "CDVD/IsoFileFormats.h"
|
#include "CDVD/IsoFileFormats.h"
|
||||||
#include "Config.h"
|
#include "Config.h"
|
||||||
#include "Host.h"
|
#include "Host.h"
|
||||||
|
|
|
@ -225,6 +225,7 @@ set(pcsx2CDVDSources
|
||||||
|
|
||||||
# CDVD headers
|
# CDVD headers
|
||||||
set(pcsx2CDVDHeaders
|
set(pcsx2CDVDHeaders
|
||||||
|
CDVD/BlockdumpFileReader.h
|
||||||
CDVD/Ps1CD.h
|
CDVD/Ps1CD.h
|
||||||
CDVD/CDVDcommon.h
|
CDVD/CDVDcommon.h
|
||||||
CDVD/CDVD.h
|
CDVD/CDVD.h
|
||||||
|
|
|
@ -465,6 +465,7 @@
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ClInclude Include="Achievements.h" />
|
<ClInclude Include="Achievements.h" />
|
||||||
<ClInclude Include="AsyncFileReader.h" />
|
<ClInclude Include="AsyncFileReader.h" />
|
||||||
|
<ClInclude Include="CDVD\BlockdumpFileReader.h" />
|
||||||
<ClInclude Include="CDVD\CDVDdiscReader.h" />
|
<ClInclude Include="CDVD\CDVDdiscReader.h" />
|
||||||
<ClInclude Include="CDVD\ChunksCache.h" />
|
<ClInclude Include="CDVD\ChunksCache.h" />
|
||||||
<ClInclude Include="CDVD\CompressedFileReader.h" />
|
<ClInclude Include="CDVD\CompressedFileReader.h" />
|
||||||
|
|
|
@ -2318,6 +2318,9 @@
|
||||||
<ClInclude Include="Host\AudioStreamTypes.h">
|
<ClInclude Include="Host\AudioStreamTypes.h">
|
||||||
<Filter>Misc\Host</Filter>
|
<Filter>Misc\Host</Filter>
|
||||||
</ClInclude>
|
</ClInclude>
|
||||||
|
<ClInclude Include="CDVD\BlockdumpFileReader.h">
|
||||||
|
<Filter>System\ISO</Filter>
|
||||||
|
</ClInclude>
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<CustomBuildStep Include="rdebug\deci2.h">
|
<CustomBuildStep Include="rdebug\deci2.h">
|
||||||
|
|
Loading…
Reference in New Issue