Skip to content

Commit

Permalink
Core: Future proof CSO support a bit.
Browse files Browse the repository at this point in the history
For CSO versions >= 2, respect the header size field and uncompressed
frame size behavior.  This will allow more options for future files, like
adding a field for the CRC or otherwise.
  • Loading branch information
unknownbrackets committed Jan 26, 2020
1 parent 3474339 commit 931dff6
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 23 deletions.
40 changes: 17 additions & 23 deletions Core/FileSystems/BlockDevices.cpp
Expand Up @@ -134,18 +134,11 @@ CISOFileBlockDevice::CISOFileBlockDevice(FileLoader *fileLoader)

CISO_H hdr;
size_t readSize = fileLoader->ReadAt(0, sizeof(CISO_H), 1, &hdr);
if (readSize != 1 || memcmp(hdr.magic, "CISO", 4) != 0)
{
if (readSize != 1 || memcmp(hdr.magic, "CISO", 4) != 0) {
WARN_LOG(LOADER, "Invalid CSO!");
}
else
{
VERBOSE_LOG(LOADER, "Valid CSO!");
}
if (hdr.ver > 1)
{
ERROR_LOG(LOADER, "CSO version too high!");
//ARGH!
if (hdr.ver > 1) {
WARN_LOG(LOADER, "CSO version too high!");
}

frameSize = hdr.block_size;
Expand Down Expand Up @@ -174,18 +167,19 @@ CISOFileBlockDevice::CISOFileBlockDevice(FileLoader *fileLoader)
zlibBufferFrame = numFrames;

const u32 indexSize = numFrames + 1;
const size_t headerEnd = hdr.ver > 1 ? (size_t)hdr.header_size : sizeof(hdr);

#if COMMON_LITTLE_ENDIAN
index = new u32[indexSize];
if (fileLoader->ReadAt(sizeof(hdr), sizeof(u32), indexSize, index) != indexSize) {
if (fileLoader->ReadAt(headerEnd, sizeof(u32), indexSize, index) != indexSize) {
NotifyReadError();
memset(index, 0, indexSize * sizeof(u32));
}
#else
index = new u32[indexSize];
u32_le *indexTemp = new u32_le[indexSize];

if (fileLoader->ReadAt(sizeof(hdr), sizeof(u32), indexSize, indexTemp) != indexSize) {
if (fileLoader->ReadAt(headerEnd, sizeof(u32), indexSize, indexTemp) != indexSize) {
NotifyReadError();
memset(indexTemp, 0, indexSize * sizeof(u32_le));
}
Expand All @@ -196,6 +190,8 @@ CISOFileBlockDevice::CISOFileBlockDevice(FileLoader *fileLoader)
delete[] indexTemp;
#endif

ver_ = hdr.ver;

// Double check that the CSO is not truncated. In most cases, this will be the exact size.
u64 fileSize = fileLoader->FileSize();
u64 lastIndexPos = index[indexSize - 1] & 0x7FFFFFFF;
Expand All @@ -216,8 +212,7 @@ CISOFileBlockDevice::~CISOFileBlockDevice()
bool CISOFileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr, bool uncached)
{
FileLoader::Flags flags = uncached ? FileLoader::Flags::HINT_UNCACHED : FileLoader::Flags::NONE;
if ((u32)blockNumber >= numBlocks)
{
if ((u32)blockNumber >= numBlocks) {
memset(outPtr, 0, GetBlockSize());
return false;
}
Expand All @@ -233,20 +228,19 @@ bool CISOFileBlockDevice::ReadBlock(int blockNumber, u8 *outPtr, bool uncached)
const size_t compressedReadSize = (size_t)(compressedReadEnd - compressedReadPos);
const u32 compressedOffset = (blockNumber & ((1 << blockShift) - 1)) * GetBlockSize();

const int plain = idx & 0x80000000;
if (plain)
{
bool plain = (idx & 0x80000000) != 0;
if (ver_ >= 2) {
// CSO v2+ requires blocks be uncompressed if large enough to be. High bit means other things.
plain = compressedReadSize >= frameSize;
}
if (plain) {
int readSize = (u32)fileLoader_->ReadAt(compressedReadPos + compressedOffset, 1, GetBlockSize(), outPtr, flags);
if (readSize < GetBlockSize())
memset(outPtr + readSize, 0, GetBlockSize() - readSize);
}
else if (zlibBufferFrame == frameNumber)
{
} else if (zlibBufferFrame == frameNumber) {
// We already have it. Just apply the offset and copy.
memcpy(outPtr, zlibBuffer + compressedOffset, GetBlockSize());
}
else
{
} else {
const u32 readSize = (u32)fileLoader_->ReadAt(compressedReadPos, 1, compressedReadSize, readBuffer, flags);

z.zalloc = Z_NULL;
Expand Down
1 change: 1 addition & 0 deletions Core/FileSystems/BlockDevices.h
Expand Up @@ -72,6 +72,7 @@ class CISOFileBlockDevice : public BlockDevice {
u32 frameSize;
u32 numBlocks;
u32 numFrames;
int ver_;
};


Expand Down

0 comments on commit 931dff6

Please sign in to comment.