mirror of https://github.com/PCSX2/pcsx2.git
CDVD: Simplify ISO opening
This commit is contained in:
parent
d099f7afd6
commit
a6f7159537
|
@ -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()
|
||||
|
|
|
@ -33,7 +33,5 @@ public:
|
|||
|
||||
u32 GetBlockCount() const override;
|
||||
|
||||
static bool DetectBlockdump(ThreadedFileReader* reader);
|
||||
|
||||
s32 GetBlockOffset() { return m_blockofs; }
|
||||
};
|
||||
|
|
|
@ -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())
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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;
|
||||
};
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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" />
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue