ksys/res: Implement OffsetReadFileDevice

This commit is contained in:
Léo Lam 2020-09-24 21:05:33 +02:00
parent 7d51cbac51
commit 72d100323c
No known key found for this signature in database
GPG Key ID: 0DF30F9081000741
4 changed files with 146 additions and 9 deletions

View File

@ -94588,15 +94588,15 @@
0x0000007101307abc,sub_7101307ABC,24,
0x0000007101307ad4,sub_7101307AD4,48,
0x0000007101307b04,sub_7101307B04,92,
0x0000007101307b60,MainFileDevice::ctor,64,
0x0000007101307ba0,j__ZN4sead14MainFileDeviceD2Ev,4,
0x0000007101307ba4,sub_7101307BA4,8,
0x0000007101307bac,_ZN4sead14MainFileDeviceD0Ev_0,36,
0x0000007101307bd0,sub_7101307BD0,40,
0x0000007101307bf8,sub_7101307BF8,8,
0x0000007101307c00,sub_7101307C00,476,
0x0000007101307ddc,_ZNK4sead14MainFileDevice27checkDerivedRuntimeTypeInfoEPKNS_15RuntimeTypeInfo9InterfaceE,288,
0x0000007101307efc,_ZNK4sead14MainFileDevice18getRuntimeTypeInfoEv_0,92,
0x0000007101307b60,MainFileDevice::ctor,64,_ZN4ksys3res20OffsetReadFileDeviceC1EPN4sead4HeapE
0x0000007101307ba0,j__ZN4sead14MainFileDeviceD2Ev,4,_ZN4ksys3res20OffsetReadFileDeviceD2Ev
0x0000007101307ba4,sub_7101307BA4,8,_ZThn136_N4ksys3res20OffsetReadFileDeviceD1Ev
0x0000007101307bac,_ZN4sead14MainFileDeviceD0Ev_0,36,_ZN4ksys3res20OffsetReadFileDeviceD0Ev
0x0000007101307bd0,sub_7101307BD0,40,_ZThn136_N4ksys3res20OffsetReadFileDeviceD0Ev
0x0000007101307bf8,sub_7101307BF8,8,_ZN4ksys3res20OffsetReadFileDevice13setFileDeviceEPN4sead10FileDeviceE
0x0000007101307c00,sub_7101307C00,476,_ZN4ksys3res20OffsetReadFileDevice7doLoad_ERN4sead10FileDevice7LoadArgE
0x0000007101307ddc,_ZNK4sead14MainFileDevice27checkDerivedRuntimeTypeInfoEPKNS_15RuntimeTypeInfo9InterfaceE,288,_ZNK4ksys3res20OffsetReadFileDevice27checkDerivedRuntimeTypeInfoEPKN4sead15RuntimeTypeInfo9InterfaceE
0x0000007101307efc,_ZNK4sead14MainFileDevice18getRuntimeTypeInfoEv_0,92,_ZNK4ksys3res20OffsetReadFileDevice18getRuntimeTypeInfoEv
0x0000007101307f58,sub_7101307F58,140,
0x0000007101307fe4,sub_7101307FE4,32,
0x0000007101308004,sub_7101308004,192,

Can't render this file because it is too large.

View File

@ -90,6 +90,8 @@ target_sources(uking PRIVATE
resHandle.h
resLoadRequest.cpp
resLoadRequest.h
resOffsetReadFileDevice.cpp
resOffsetReadFileDevice.h
resResource.cpp
resResource.h

View File

@ -0,0 +1,94 @@
#include "KingSystem/Resource/resOffsetReadFileDevice.h"
#include <heap/seadHeapMgr.h>
#include <math/seadMathCalcCommon.h>
#include "KingSystem/Resource/resSystem.h"
namespace ksys::res {
OffsetReadFileDevice::OffsetReadFileDevice(sead::Heap* heap) : sead::MainFileDevice(heap) {
resetOffsetRead();
}
void OffsetReadFileDevice::setFileDevice(sead::FileDevice* device) {
OffsetRead::setFileDevice(device);
}
/// This is a modified version of `sead::FileDevice::doLoad_`.
u8* OffsetReadFileDevice::doLoad_(sead::FileDevice::LoadArg& arg) {
if (arg.buffer && arg.buffer_size == 0) {
stubbedLogFunction();
return nullptr;
}
sead::FileDevice* device = mOffsetReadFileDevice;
if (!device)
device = this;
sead::FileHandle handle;
if (!device->tryOpen(&handle, arg.path, FileDevice::cFileOpenFlag_ReadOnly, arg.div_size))
return nullptr;
u32 bytesToRead = arg.buffer_size;
if (!arg.buffer || arg.check_read_entire_file) {
u32 fileSize = 0;
if (!device->tryGetFileSize(&fileSize, &handle))
return nullptr;
if (fileSize == 0) {
stubbedLogFunction();
return nullptr;
}
if (bytesToRead != 0) {
if (bytesToRead < fileSize) {
stubbedLogFunction();
return nullptr;
}
} else {
bytesToRead = mOffsetReadOffset + sead::Mathi::roundUpPow2Positive(
fileSize, FileDevice::cBufferMinAlignment);
}
}
u8* buf = arg.buffer;
bool allocated = false;
if (buf == nullptr) {
const s32 sign = (arg.alignment < 0) ? -1 : 1;
s32 alignment = sead::abs(arg.alignment);
alignment = sign * ((alignment < cBufferMinAlignment) ? cBufferMinAlignment : alignment);
sead::Heap* heap = arg.heap;
if (!heap)
heap = sead::HeapMgr::instance()->getCurrentHeap();
void* raw_buf = heap->tryAlloc(bytesToRead, alignment);
if (!raw_buf)
return nullptr;
buf = new (raw_buf) u8[bytesToRead];
allocated = true;
}
u32 bytesRead = 0;
if (!device->tryRead(&bytesRead, &handle, buf + mOffsetReadOffset,
bytesToRead - mOffsetReadOffset)) {
if (allocated)
delete[] buf;
return nullptr;
}
if (!device->tryClose(&handle)) {
if (allocated)
delete[] buf;
return nullptr;
}
arg.read_size = bytesRead;
arg.roundup_size = bytesToRead;
arg.need_unload = allocated;
return buf;
}
} // namespace ksys::res

View File

@ -0,0 +1,41 @@
#pragma once
#include <filedevice/seadMainFileDevice.h>
#include "KingSystem/Utils/Types.h"
namespace ksys::res {
class OffsetRead {
public:
OffsetRead() { resetOffsetRead(); }
virtual ~OffsetRead() = default;
void setReadOffset(u32 offset) { mOffsetReadOffset = offset; }
void setFileDevice(sead::FileDevice* device) { mOffsetReadFileDevice = device; }
void resetOffsetRead() {
mOffsetReadOffset = 0;
mOffsetReadFileDevice = nullptr;
}
protected:
u32 mOffsetReadOffset;
sead::FileDevice* mOffsetReadFileDevice;
};
KSYS_CHECK_SIZE_NX150(OffsetRead, 0x18);
class OffsetReadFileDevice : public sead::MainFileDevice, public OffsetRead {
SEAD_RTTI_OVERRIDE(OffsetReadFileDevice, sead::MainFileDevice)
public:
explicit OffsetReadFileDevice(sead::Heap* heap);
~OffsetReadFileDevice() override = default;
void setReadOffset(u32 offset) { OffsetRead::setReadOffset(offset); }
void setFileDevice(sead::FileDevice* device);
protected:
u8* doLoad_(LoadArg& arg) override;
};
KSYS_CHECK_SIZE_NX150(OffsetReadFileDevice, 0xa0);
} // namespace ksys::res