mirror of
https://github.com/hrydgard/ppsspp.git
synced 2025-04-02 11:01:50 -04:00
Add an interface to read multiple blocks at once.
This commit is contained in:
parent
bf50baf698
commit
9c5ad44000
2 changed files with 42 additions and 27 deletions
|
@ -31,6 +31,15 @@ class BlockDevice
|
||||||
public:
|
public:
|
||||||
virtual ~BlockDevice() {}
|
virtual ~BlockDevice() {}
|
||||||
virtual bool ReadBlock(int blockNumber, u8 *outPtr) = 0;
|
virtual bool ReadBlock(int blockNumber, u8 *outPtr) = 0;
|
||||||
|
virtual bool ReadBlocks(int minBlock, int count, u8 *outPtr) {
|
||||||
|
for (int b = 0; b < count; ++b) {
|
||||||
|
if (!ReadBlock(minBlock + b, outPtr)) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
outPtr += GetBlockSize();
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
int GetBlockSize() const { return 2048;} // forced, it cannot be changed by subclasses
|
int GetBlockSize() const { return 2048;} // forced, it cannot be changed by subclasses
|
||||||
virtual u32 GetNumBlocks() = 0;
|
virtual u32 GetNumBlocks() = 0;
|
||||||
};
|
};
|
||||||
|
|
|
@ -18,6 +18,7 @@
|
||||||
#include <cstring>
|
#include <cstring>
|
||||||
#include <cstdio>
|
#include <cstdio>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <algorithm>
|
||||||
|
|
||||||
#include "Common/Common.h"
|
#include "Common/Common.h"
|
||||||
#include "Common/CommonTypes.h"
|
#include "Common/CommonTypes.h"
|
||||||
|
@ -494,10 +495,10 @@ int ISOFileSystem::Ioctl(u32 handle, u32 cmd, u32 indataPtr, u32 inlen, u32 outd
|
||||||
u32 size = (u32)desc.pathTableLengthLE;
|
u32 size = (u32)desc.pathTableLengthLE;
|
||||||
u8 *out = Memory::GetPointer(outdataPtr);
|
u8 *out = Memory::GetPointer(outdataPtr);
|
||||||
|
|
||||||
while (size >= 2048) {
|
int blocks = size / blockDevice->GetBlockSize();
|
||||||
blockDevice->ReadBlock(block++, out);
|
blockDevice->ReadBlocks(block, blocks, out);
|
||||||
out += 2048;
|
size -= blocks * blockDevice->GetBlockSize();
|
||||||
}
|
out += blocks * blockDevice->GetBlockSize();
|
||||||
|
|
||||||
// The remaining (or, usually, only) partial sector.
|
// The remaining (or, usually, only) partial sector.
|
||||||
if (size > 0) {
|
if (size > 0) {
|
||||||
|
@ -527,12 +528,9 @@ size_t ISOFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size)
|
||||||
if (e.isBlockSectorMode)
|
if (e.isBlockSectorMode)
|
||||||
{
|
{
|
||||||
// Whole sectors! Shortcut to this simple code.
|
// Whole sectors! Shortcut to this simple code.
|
||||||
for (int i = 0; i < size; i++)
|
blockDevice->ReadBlocks(e.seekPos, (int)size, pointer);
|
||||||
{
|
e.seekPos += (int)size;
|
||||||
blockDevice->ReadBlock(e.seekPos, pointer + i * 2048);
|
return (int)size;
|
||||||
e.seekPos++;
|
|
||||||
}
|
|
||||||
return (size_t)size;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u32 positionOnIso;
|
u32 positionOnIso;
|
||||||
|
@ -559,29 +557,37 @@ size_t ISOFileSystem::ReadFile(u32 handle, u8 *pointer, s64 size)
|
||||||
}
|
}
|
||||||
//okay, we have size and position, let's rock
|
//okay, we have size and position, let's rock
|
||||||
|
|
||||||
u32 totalRead = 0;
|
const int firstBlockOffset = positionOnIso & 2047;
|
||||||
|
const int firstBlockSize = firstBlockOffset == 0 ? 0 : (int)std::min(size, 2048LL - firstBlockOffset);
|
||||||
|
const int lastBlockSize = (size - firstBlockSize) & 2047;
|
||||||
|
const s64 middleSize = size - firstBlockSize - lastBlockSize;
|
||||||
int secNum = positionOnIso / 2048;
|
int secNum = positionOnIso / 2048;
|
||||||
int posInSector = positionOnIso & 2047;
|
|
||||||
s64 remain = size;
|
|
||||||
|
|
||||||
u8 theSector[2048];
|
u8 theSector[2048];
|
||||||
|
|
||||||
while (remain > 0)
|
_dbg_assert_msg_(FILESYS, (middleSize & 2047) == 0, "Remaining size should be aligned");
|
||||||
{
|
|
||||||
blockDevice->ReadBlock(secNum, theSector);
|
|
||||||
size_t bytesToCopy = 2048 - posInSector;
|
|
||||||
if ((s64)bytesToCopy > remain)
|
|
||||||
bytesToCopy = (size_t)remain;
|
|
||||||
|
|
||||||
memcpy(pointer, theSector + posInSector, bytesToCopy);
|
if (firstBlockSize != 0)
|
||||||
totalRead += (u32)bytesToCopy;
|
{
|
||||||
pointer += bytesToCopy;
|
blockDevice->ReadBlock(secNum++, theSector);
|
||||||
remain -= bytesToCopy;
|
memcpy(pointer, theSector + firstBlockOffset, firstBlockSize);
|
||||||
posInSector = 0;
|
pointer += firstBlockSize;
|
||||||
secNum++;
|
|
||||||
}
|
}
|
||||||
|
if (middleSize != 0)
|
||||||
|
{
|
||||||
|
const u32 sectors = (u32)(middleSize / 2048);
|
||||||
|
blockDevice->ReadBlocks(secNum, sectors, pointer);
|
||||||
|
secNum += sectors;
|
||||||
|
pointer += middleSize;
|
||||||
|
}
|
||||||
|
if (lastBlockSize != 0)
|
||||||
|
{
|
||||||
|
blockDevice->ReadBlock(secNum++, theSector);
|
||||||
|
memcpy(pointer, theSector, lastBlockSize);
|
||||||
|
pointer += lastBlockSize;
|
||||||
|
}
|
||||||
|
|
||||||
e.seekPos += (unsigned int)size;
|
e.seekPos += (unsigned int)size;
|
||||||
return totalRead;
|
return (size_t)size;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
|
Loading…
Add table
Reference in a new issue