Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

common: Copy aglRes-Files from WiiU-Decomp #15

Merged
merged 13 commits into from
Aug 19, 2023
16 changes: 14 additions & 2 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,19 @@ add_library(agl OBJECT
include/common/aglGPUMemBlock.h
include/common/aglRenderBuffer.h
include/common/aglRenderTarget.h
include/common/aglResBinaryShaderArchive.h
include/common/aglResBinaryShaderProgram.h
include/common/aglResCommon.h
include/common/aglResShaderArchive.h
include/common/aglResShaderBinary.h
include/common/aglResShaderMacro.h
include/common/aglResShaderProgram.h
include/common/aglResShaderSource.h
include/common/aglResShaderSymbol.h
include/common/aglResShaderVariation.h
include/common/aglShader.h
include/common/aglShaderCompileInfo.h
include/common/aglShaderEnum.h
include/common/aglShaderProgram.h
include/common/aglShaderProgramArchive.h
include/common/aglTextureData.h
Expand Down Expand Up @@ -58,7 +69,6 @@ add_library(agl OBJECT
include/utility/aglParameterList.h
include/utility/aglParameterObj.h
include/utility/aglParameterStringMgr.h
include/utility/aglResCommon.h
include/utility/aglResParameter.h
include/utility/aglScreenShotMgr.h

Expand All @@ -73,8 +83,10 @@ add_library(agl OBJECT
src/utility/aglParameterList.cpp
src/utility/aglParameterObj.cpp
src/utility/aglParameterStringMgr.cpp
src/utility/aglResCommon.cpp
src/utility/aglResParameter.cpp

src/utility/common/aglResCommon.cpp
src/utility/common/aglResShaderArchive.cpp
)

target_compile_options(agl PRIVATE -fno-exceptions)
Expand Down
65 changes: 65 additions & 0 deletions include/common/aglResBinaryShaderArchive.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,65 @@
#pragma once

#include "common/aglResBinaryShaderProgram.h"
#include "common/aglResShaderBinary.h"
#include "common/aglResShaderProgram.h"

namespace agl {

struct ResBinaryShaderArchiveData {
union {
char mSignature[4];
u32 mSigWord;
};
u32 mVersion;
u32 mFileSize;
u32 mEndian;
u32 mResolved;
u32 mNameLen;
// char mName[];

public:
static u32 getVersion();
static u32 getSignature();
static const char* getExtension();

private:
static const u32 cVersion = 8;
static const u32 cSignature = 0x53484142; // SHAB
static const u32 cEndianCheckBit = 0x01000001;

friend class ResCommon<ResBinaryShaderArchiveData>;
friend class ResBinaryShaderArchive;
};
static_assert(sizeof(ResBinaryShaderArchiveData) == 0x18,
"agl::ResBinaryShaderArchiveData size mismatch");

class ResBinaryShaderArchive : public ResCommon<ResBinaryShaderArchiveData> {
AGL_RES_FILE_HEADER()

public:
using ResCommon::ResCommon;

const char* getName() const {
const DataType* const data = ptr();
return (const char*)(data + 1);
}

ResShaderBinaryArray getResShaderBinaryArray() const {
const DataType* const data = ptr();
return (const ResShaderBinaryArrayData*)((uintptr_t)(data + 1) + data->mNameLen);
}

s32 getResShaderBinaryNum() const { return getResShaderBinaryArray().getNum(); }

ResBinaryShaderProgramArray getResBinaryShaderProgramArray() const {
const ResShaderBinaryArrayData* const data = getResShaderBinaryArray().ptr();
return (const ResBinaryShaderProgramArrayData*)((uintptr_t)data + data->mSize);
}

s32 getResBinaryShaderProgramNum() const { return getResBinaryShaderProgramArray().getNum(); }

bool setUp(bool le_resolve_pointers);
};

} // namespace agl
43 changes: 43 additions & 0 deletions include/common/aglResBinaryShaderProgram.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#pragma once

#include "common/aglResShaderSymbol.h"
#include "common/aglResShaderVariation.h"

namespace agl {

struct ResBinaryShaderProgramData {
u32 mSize;
u32 mNameLen;
u32 mKind;
u32 mBaseIndex;
// char mName[];
};
static_assert(sizeof(ResBinaryShaderProgramData) == 0x10,
"agl::ResBinaryShaderProgramData size mismatch");

class ResBinaryShaderProgram : public ResCommon<ResBinaryShaderProgramData> {
public:
using ResCommon::ResCommon;

const char* getName() const { return (const char*)(ptr() + 1); }

ResShaderVariationArray getResShaderVariationArray() const {
const DataType* const data = ptr();
return (const ResShaderVariationArrayData*)((uintptr_t)(data + 1) + data->mNameLen);
}

ResShaderVariationArray getResShaderVariationDefaultArray() const {
const ResShaderVariationArrayData* const data = getResShaderVariationArray().ptr();
return (const ResShaderVariationArrayData*)((uintptr_t)data + data->mSize);
}

ResShaderSymbolArray getResShaderSymbolArray(ShaderSymbolType type) const;
};

using ResBinaryShaderProgramArray = ResArray<ResBinaryShaderProgram>;

using ResBinaryShaderProgramArrayData = ResBinaryShaderProgramArray::DataType;
static_assert(sizeof(ResBinaryShaderProgramArrayData) == 8,
"agl::ResBinaryShaderProgramArrayData size mismatch");

} // namespace agl
187 changes: 187 additions & 0 deletions include/common/aglResCommon.h
MonsterDruide1 marked this conversation as resolved.
Show resolved Hide resolved
Original file line number Diff line number Diff line change
@@ -0,0 +1,187 @@
#pragma once

#include <basis/seadRawPrint.h>
#include <prim/seadBitUtil.h>

namespace agl {

// maybe first parameter is is_le, maybe it is big_endian - different between decomps
void ModifyEndianU32(bool is_le, void* p_data, size_t size);
MonsterDruide1 marked this conversation as resolved.
Show resolved Hide resolved

template <typename DataType_>
class ResCommon {
public:
using DataType = DataType_;

ResCommon() : mpData(nullptr) {}

ResCommon(const void* data) : mpData(static_cast<const DataType*>(data)) {}

bool isValid() const { return mpData != nullptr; }

void verify() const {
if (isValidMagic()) {
const char* b = reinterpret_cast<const char*>(mpData);
SEAD_ASSERT_MSG(false, "Wrong binary. [%c%c%c%c].", b[0], b[1], b[2], b[3]);
}

if (isValidVersion()) {
SEAD_ASSERT_MSG(false, "Version error.current:%d binary:%d", DataType::getVersion(),
sead::BitUtil::bitCastPtr<u32>(ptr(), 4));
}
}

DataType* ptr() {
assertValid();
return const_cast<DataType*>(mpData);
}

const DataType* ptr() const {
assertValid();
return mpData;
}

u8* ptrBytes() const { return const_cast<u8*>(reinterpret_cast<const u8*>(mpData)); }

DataType& ref() {
assertValid();
return *ptr();
}

const DataType& ref() const {
assertValid();
return *ptr();
}

bool isValidMagic() const {
return sead::BitUtil::bitCastPtr<u32>(ptr(), 0) == DataType::getSignature();
}

bool isValidVersion() const {
return sead::BitUtil::bitCastPtr<u32>(ptr(), 4) == DataType::getVersion();
}

void assertValid() const { SEAD_ASSERT(isValid()); }

protected:
const DataType* mpData;
};

#define AGL_RES_FILE_HEADER() \
public: \
bool modifyEndian() const { return ref().mEndian & DataType::cEndianCheckBit; } \
\
bool isEndianResolved() const { return !modifyEndian(); } \
\
void setEndianResolved() { ref().mEndian = 1 - ref().mEndian; }

template <typename DataType>
struct ResArrayData {
s32 mSize;
u32 mNum;
// DataType mData[];

using ElemType = DataType;
};

template <typename Type>
class ResArray : public ResCommon<ResArrayData<typename Type::DataType>> {
public:
using ElemType = Type;
using ElemDataType = typename Type::DataType;
using DataType = typename ResArray<Type>::DataType;
using Base = ResCommon<DataType>;

using ResCommon<DataType>::ResCommon;

public:
class iterator {
public:
iterator(s32 index, ElemDataType* elem) : mIndex(index), mElem(elem) {}

friend bool operator==(const iterator& lhs, const iterator& rhs) {
return lhs.mIndex == rhs.mIndex;
}

friend bool operator!=(const iterator& lhs, const iterator& rhs) {
return lhs.mIndex != rhs.mIndex;
}

iterator& operator++() {
++mIndex;
mElem = (ElemDataType*)((uintptr_t)mElem + Type(mElem).ref().mSize);
return *this;
}

ElemDataType& operator*() const { return *mElem; }
ElemDataType* operator->() const { return mElem; }
s32 getIndex() const { return mIndex; }

private:
s32 mIndex;
ElemDataType* mElem;
};

class constIterator {
public:
constIterator(s32 index, const ElemDataType* elem) : mIndex(index), mElem(elem) {}

friend bool operator==(const constIterator& lhs, const constIterator& rhs) {
return lhs.mIndex == rhs.mIndex;
}

friend bool operator!=(const constIterator& lhs, const constIterator& rhs) {
return lhs.mIndex != rhs.mIndex;
}

constIterator& operator++() {
++mIndex;
mElem = (const ElemDataType*)((uintptr_t)mElem + Type(mElem).ref().mSize);
return *this;
}

const ElemDataType& operator*() const { return *mElem; }
const ElemDataType* operator->() const { return mElem; }
s32 getIndex() const { return mIndex; }

private:
s32 mIndex;
const ElemDataType* mElem;
};

public:
iterator begin() { return iterator(0, (ElemDataType*)(Base::ptr() + 1)); }
constIterator begin() const { return constIterator(0, (const ElemDataType*)(Base::ptr() + 1)); }
constIterator constBegin() const {
return constIterator(0, (const ElemDataType*)(Base::ptr() + 1));
}

iterator end() { return iterator(getNum(), nullptr); }
constIterator end() const { return constIterator(getNum(), nullptr); }
constIterator constEnd() const { return constIterator(getNum(), nullptr); }

public:
u32 getNum() const { return Base::ref().mNum; }

ElemType get(s32 n) const {
// clang-format off
SEAD_ASSERT(0 <= n && n <= static_cast< int >( this->getNum() ));
// clang-format on

constIterator itr = constBegin();
constIterator itr_end = constIterator(n, nullptr);

while (itr != itr_end)
++itr;

return &(*itr);
}

void modifyEndianArray(bool is_le) {
ModifyEndianU32(is_le, Base::ptr(), sizeof(DataType));

for (iterator it = begin(), it_end = end(); it != it_end; ++it)
ModifyEndianU32(is_le, &(*it), sizeof(ElemDataType));
}
};
} // namespace agl
Loading
Loading