CDVD: Simplify ISO opening

This commit is contained in:
Stenzek 2024-05-16 21:33:51 +10:00 committed by Connor McLaughlin
parent d099f7afd6
commit a6f7159537
10 changed files with 44 additions and 182 deletions

View File

@ -20,21 +20,6 @@ enum isoFlags
static constexpr u32 BlockDumpHeaderSize = 16;
bool BlockdumpFileReader::DetectBlockdump(ThreadedFileReader* reader)
{
u32 oldbs = reader->GetBlockSize();
reader->SetBlockSize(1);
char buf[4] = {0};
bool isbd = (reader->ReadSync(buf, 0, sizeof(buf)) == 4 && std::memcmp(buf, "BDV2", sizeof(buf)) == 0);
if (!isbd)
reader->SetBlockSize(oldbs);
return isbd;
}
BlockdumpFileReader::BlockdumpFileReader() = default;
BlockdumpFileReader::~BlockdumpFileReader()

View File

@ -33,7 +33,5 @@ public:
u32 GetBlockCount() const override;
static bool DetectBlockdump(ThreadedFileReader* reader);
s32 GetBlockOffset() { return m_blockofs; }
};

View File

@ -33,7 +33,7 @@ static bool ISOopen(std::string filename, Error* error)
return false;
}
if (!iso.Open(std::move(filename), error, false))
if (!iso.Open(std::move(filename), error))
return false;
switch (iso.GetType())

View File

@ -1,34 +0,0 @@
// SPDX-FileCopyrightText: 2002-2023 PCSX2 Dev Team
// SPDX-License-Identifier: LGPL-3.0+
#include "CompressedFileReader.h"
#include "ChdFileReader.h"
#include "CsoFileReader.h"
#include "GzippedFileReader.h"
#include "common/FileSystem.h"
#include "common/Path.h"
#include "common/StringUtil.h"
#include <algorithm>
#include <cctype>
ThreadedFileReader* CompressedFileReader::GetNewReader(const std::string& fileName)
{
if (!FileSystem::FileExists(fileName.c_str()))
return nullptr;
const std::string_view extension = Path::GetExtension(fileName);
if (StringUtil::compareNoCase(extension, "chd"))
return new ChdFileReader();
if (StringUtil::compareNoCase(extension, "cso") || StringUtil::compareNoCase(extension, "zso"))
return new CsoFileReader();
if (StringUtil::compareNoCase(extension, "gz"))
return new GzippedFileReader();
// Not a known compressed format.
return nullptr;
}

View File

@ -1,21 +0,0 @@
// SPDX-FileCopyrightText: 2002-2023 PCSX2 Dev Team
// SPDX-License-Identifier: LGPL-3.0+
#pragma once
#include <string>
class ThreadedFileReader;
// Factory - creates an AsyncFileReader derived instance which can read a compressed file
class CompressedFileReader
{
public:
// fileName and its contents may be used to choose the compressed reader.
// If no matching handler is found, NULL is returned.
// The returned instance still needs ->Open(filename) before usage.
// Open(filename) may still fail.
static ThreadedFileReader* GetNewReader(const std::string& fileName);
private:
virtual ~CompressedFileReader() = 0;
};

View File

@ -2,8 +2,10 @@
// SPDX-License-Identifier: LGPL-3.0+
#include "CDVD/BlockdumpFileReader.h"
#include "CDVD/CompressedFileReader.h"
#include "CDVD/ChdFileReader.h"
#include "CDVD/CsoFileReader.h"
#include "CDVD/FlatFileReader.h"
#include "CDVD/GzippedFileReader.h"
#include "CDVD/IsoFileFormats.h"
#include "Config.h"
#include "Host.h"
@ -11,6 +13,8 @@
#include "common/Assertions.h"
#include "common/Console.h"
#include "common/Error.h"
#include "common/Path.h"
#include "common/StringUtil.h"
#include "fmt/format.h"
@ -33,13 +37,30 @@ static const char* nameFromType(int type)
}
}
static std::unique_ptr<ThreadedFileReader> GetFileReader(const std::string& path)
{
const std::string_view extension = Path::GetExtension(path);
if (StringUtil::compareNoCase(extension, "chd"))
return std::make_unique<ChdFileReader>();
if (StringUtil::compareNoCase(extension, "cso") || StringUtil::compareNoCase(extension, "zso"))
return std::make_unique<CsoFileReader>();
if (StringUtil::compareNoCase(extension, "gz"))
return std::make_unique<GzippedFileReader>();
if (StringUtil::compareNoCase(extension, "dump"))
return std::make_unique<BlockdumpFileReader>();
return std::make_unique<FlatFileReader>();
}
int InputIsoFile::ReadSync(u8* dst, uint lsn)
{
if (lsn >= m_blocks)
{
std::string msg(fmt::format("isoFile error: Block index is past the end of file! ({} >= {}).", lsn, m_blocks));
pxAssertMsg(false, msg.c_str());
Console.Error(msg.c_str());
ERROR_LOG("isoFile error: Block index is past the end of file! ({} >= {}).", lsn, m_blocks);
return -1;
}
@ -54,27 +75,17 @@ void InputIsoFile::BeginRead2(uint lsn)
{
// 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.
Console.WriteLn("isoFile error: Block index is past the end of file! (%u >= %u).", lsn, m_blocks);
ERROR_LOG("isoFile error: Block index is past the end of file! (%u >= %u).", lsn, m_blocks);
return;
}
if (lsn >= m_read_lsn && lsn < (m_read_lsn + m_read_count))
{
// Already buffered
// same sector?
if (lsn == m_read_lsn)
return;
}
m_read_lsn = lsn;
m_read_count = 1;
if (ReadUnit > 1)
{
//m_read_lsn = lsn - (lsn % ReadUnit);
m_read_count = std::min(ReadUnit, m_blocks - m_read_lsn);
}
m_reader->BeginRead(m_readbuffer, m_read_lsn, m_read_count);
m_reader->BeginRead(m_readbuffer, m_read_lsn, 1);
m_read_inprogress = true;
}
@ -95,7 +106,6 @@ int InputIsoFile::FinishRead3(u8* dst, uint mode)
if (ret <= 0)
{
m_read_lsn = -1;
m_read_count = 0;
return -1;
}
}
@ -131,7 +141,7 @@ int InputIsoFile::FinishRead3(u8* dst, uint mode)
int ndiff = 0;
if (diff > 0)
{
memset(dst, 0, diff);
std::memset(dst, 0, diff);
_offset = m_blockofs;
}
else
@ -142,8 +152,7 @@ int InputIsoFile::FinishRead3(u8* dst, uint mode)
length = end - _offset;
uint read_offset = (m_current_lsn - m_read_lsn) * m_blocksize;
memcpy(dst + diff, m_readbuffer + ndiff + read_offset, length);
std::memcpy(dst + diff, m_readbuffer + ndiff, length);
if (m_type == ISOTYPE_CD && diff >= 12)
{
@ -175,84 +184,27 @@ void InputIsoFile::_init()
m_blocks = 0;
m_read_inprogress = false;
m_read_count = 0;
ReadUnit = 0;
m_current_lsn = -1;
m_read_lsn = -1;
m_reader = NULL;
m_reader.reset();
}
// Tests the specified filename to see if it is a supported ISO type. This function typically
// executes faster than IsoFile::Open since it does not do the following:
// * check for multi-part ISOs. I tests for header info in the main/root ISO only.
// * load blockdump indexes.
//
// Note that this is a member method, and that it will clobber any existing ISO state.
// (assertions are generated in debug mode if the object state is not already closed).
bool InputIsoFile::Test(std::string srcfile)
{
Close();
return Open(std::move(srcfile), nullptr, true);
}
bool InputIsoFile::Open(std::string srcfile, Error* error, bool testOnly)
bool InputIsoFile::Open(std::string srcfile, Error* error)
{
Close();
m_filename = std::move(srcfile);
bool isBlockdump = false;
bool isCompressed = false;
// First try using a compressed reader. If it works, go with it.
m_reader = CompressedFileReader::GetNewReader(m_filename);
isCompressed = m_reader != nullptr;
// If it wasn't compressed, let's open it has a FlatFileReader.
if (!isCompressed)
m_reader = new FlatFileReader();
m_reader = GetFileReader(m_filename);
if (!m_reader->Open(m_filename, error))
return false;
// It might actually be a blockdump file.
// Check that before continuing with the FlatFileReader.
isBlockdump = BlockdumpFileReader::DetectBlockdump(m_reader);
if (isBlockdump)
{
delete m_reader;
BlockdumpFileReader* bdr = new BlockdumpFileReader();
bdr->Open(m_filename, error);
m_blockofs = bdr->GetBlockOffset();
m_blocksize = bdr->GetBlockSize();
m_reader = bdr;
ReadUnit = 1;
}
bool detected = Detect();
if (testOnly)
{
Close();
return detected;
}
if (!detected)
{
Error::SetString(error, fmt::format("Unable to identify the ISO image type for '{}'", m_filename));
Close();
m_reader.reset();
return false;
}
if (!isBlockdump && !isCompressed)
if (!Detect())
{
ReadUnit = MaxReadUnit;
m_reader->SetDataOffset(m_offset);
m_reader->SetBlockSize(m_blocksize);
Error::SetStringFmt(error, "Unable to identify the ISO image type for '{}'", Path::GetFileName(m_filename));
Close();
return false;
}
m_blocks = m_reader->GetBlockCount();
@ -274,8 +226,7 @@ void InputIsoFile::Close()
if (m_reader)
{
m_reader->Close();
delete m_reader;
m_reader = nullptr;
m_reader.reset();
}
_init();

View File

@ -29,14 +29,9 @@ class InputIsoFile final
{
DeclareNoncopyableObject(InputIsoFile);
static const uint MaxReadUnit = 128;
protected:
uint ReadUnit;
protected:
std::string m_filename;
ThreadedFileReader* m_reader;
std::unique_ptr<ThreadedFileReader> m_reader;
u32 m_current_lsn;
@ -52,8 +47,7 @@ protected:
bool m_read_inprogress;
uint m_read_lsn;
uint m_read_count;
u8 m_readbuffer[MaxReadUnit * CD_FRAMESIZE_RAW];
u8 m_readbuffer[CD_FRAMESIZE_RAW];
public:
InputIsoFile();
@ -70,8 +64,7 @@ public:
return m_filename;
}
bool Test(std::string srcfile);
bool Open(std::string srcfile, Error* error, bool testOnly);
bool Open(std::string srcfile, Error* error);
void Close();
bool Detect(bool readType = true);

View File

@ -215,7 +215,6 @@ set(pcsx2CDVDSources
CDVD/IsoHasher.cpp
CDVD/IsoReader.cpp
CDVD/OutputIsoFile.cpp
CDVD/CompressedFileReader.cpp
CDVD/ChdFileReader.cpp
CDVD/CsoFileReader.cpp
CDVD/GzippedFileReader.cpp
@ -230,7 +229,6 @@ set(pcsx2CDVDHeaders
CDVD/CDVD.h
CDVD/CDVD_internal.h
CDVD/CDVDdiscReader.h
CDVD/CompressedFileReader.h
CDVD/ChdFileReader.h
CDVD/CsoFileReader.h
CDVD/FlatFileReader.h

View File

@ -112,7 +112,6 @@
<ClCompile Include="CDVD\CDVDdiscReader.cpp" />
<ClCompile Include="CDVD\CDVDdiscThread.cpp" />
<ClCompile Include="CDVD\ChdFileReader.cpp" />
<ClCompile Include="CDVD\CompressedFileReader.cpp" />
<ClCompile Include="CDVD\CsoFileReader.cpp" />
<ClCompile Include="CDVD\FlatFileReader.cpp" />
<ClCompile Include="CDVD\GzippedFileReader.cpp" />
@ -462,7 +461,6 @@
<ClInclude Include="Achievements.h" />
<ClInclude Include="CDVD\BlockdumpFileReader.h" />
<ClInclude Include="CDVD\CDVDdiscReader.h" />
<ClInclude Include="CDVD\CompressedFileReader.h" />
<ClInclude Include="CDVD\CsoFileReader.h" />
<ClInclude Include="CDVD\ChdFileReader.h" />
<ClInclude Include="CDVD\FlatFileReader.h" />

View File

@ -743,9 +743,6 @@
<ClCompile Include="sif2.cpp">
<Filter>System\Ps2\EmotionEngine\DMAC\Sif</Filter>
</ClCompile>
<ClCompile Include="CDVD\CompressedFileReader.cpp">
<Filter>System\ISO</Filter>
</ClCompile>
<ClCompile Include="DebugTools\MipsAssemblerTables.cpp">
<Filter>System\Ps2\Debug</Filter>
</ClCompile>
@ -1670,9 +1667,6 @@
<ClInclude Include="CDVD\CsoFileReader.h">
<Filter>System\ISO</Filter>
</ClInclude>
<ClInclude Include="CDVD\CompressedFileReader.h">
<Filter>System\ISO</Filter>
</ClInclude>
<ClInclude Include="CDVD\GzippedFileReader.h">
<Filter>System\ISO</Filter>
</ClInclude>