From a61f864fb112d6dd6ee708db6b5ac47036970dbb Mon Sep 17 00:00:00 2001 From: MonsterDruide1 <5958456@gmail.com> Date: Wed, 15 Mar 2023 22:26:11 +0100 Subject: [PATCH] common: Copy aglRes-Files from WiiU-Decomp --- CMakeLists.txt | 11 ++ include/common/aglResBinaryShaderArchive.h | 75 +++++++++ include/common/aglResBinaryShaderProgram.h | 43 +++++ include/common/aglResCommon.h | 182 +++++++++++++++++++++ include/common/aglResShaderArchive.h | 62 +++++++ include/common/aglResShaderBinary.h | 36 ++++ include/common/aglResShaderMacro.h | 29 ++++ include/common/aglResShaderProgram.h | 41 +++++ include/common/aglResShaderSource.h | 30 ++++ include/common/aglResShaderSymbol.h | 58 +++++++ include/common/aglResShaderVariation.h | 32 ++++ include/common/aglShader.h | 7 - include/common/aglShaderEnum.h | 26 +++ 13 files changed, 625 insertions(+), 7 deletions(-) create mode 100644 include/common/aglResBinaryShaderArchive.h create mode 100644 include/common/aglResBinaryShaderProgram.h create mode 100644 include/common/aglResCommon.h create mode 100644 include/common/aglResShaderArchive.h create mode 100644 include/common/aglResShaderBinary.h create mode 100644 include/common/aglResShaderMacro.h create mode 100644 include/common/aglResShaderProgram.h create mode 100644 include/common/aglResShaderSource.h create mode 100644 include/common/aglResShaderSymbol.h create mode 100644 include/common/aglResShaderVariation.h create mode 100644 include/common/aglShaderEnum.h diff --git a/CMakeLists.txt b/CMakeLists.txt index 30ac9c5..f4dbbff 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -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 diff --git a/include/common/aglResBinaryShaderArchive.h b/include/common/aglResBinaryShaderArchive.h new file mode 100644 index 0000000..38c7484 --- /dev/null +++ b/include/common/aglResBinaryShaderArchive.h @@ -0,0 +1,75 @@ +#pragma once + +#include +#include +#include + +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; + friend class ResBinaryShaderArchive; +}; +static_assert(sizeof(ResBinaryShaderArchiveData) == 0x18, "agl::ResBinaryShaderArchiveData size mismatch"); + +class ResBinaryShaderArchive : public ResCommon +{ + AGL_RES_COMMON(ResBinaryShaderArchive) + AGL_RES_FILE_HEADER() + +public: + 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); +}; + +} diff --git a/include/common/aglResBinaryShaderProgram.h b/include/common/aglResBinaryShaderProgram.h new file mode 100644 index 0000000..4cef214 --- /dev/null +++ b/include/common/aglResBinaryShaderProgram.h @@ -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 { + AGL_RES_COMMON(ResBinaryShaderProgram) + +public: + 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; +}; + +typedef ResArray ResBinaryShaderProgramArray; + +typedef ResBinaryShaderProgramArray::DataType ResBinaryShaderProgramArrayData; +static_assert(sizeof(ResBinaryShaderProgramArrayData) == 8, + "agl::ResBinaryShaderProgramArrayData size mismatch"); + +} // namespace agl diff --git a/include/common/aglResCommon.h b/include/common/aglResCommon.h new file mode 100644 index 0000000..001b8d7 --- /dev/null +++ b/include/common/aglResCommon.h @@ -0,0 +1,182 @@ +#pragma once + +#include + +namespace agl { + +void ModifyEndianU32(bool is_le, void* p_data, size_t size); + +template +class ResCommon { +public: + typedef _DataType DataType; + +public: + ResCommon() : mpData(nullptr) {} + + ResCommon(const void* data) : mpData(static_cast(data)) {} + + bool isValid() const { return mpData != nullptr; } + + void verify() const { + if (ref().mSigWord != DataType::cSignature) { + const char* signature = ptr()->mSignature; + // SEAD_ASSERT_MSG(false, "Wrong binary. [%c%c%c%c].", + // signature[0], signature[1], + // signature[2], signature[3]); + } + + if (ref().mVersion != DataType::cVersion) { + // SEAD_ASSERT_MSG(false, "Version error.current:%d binary:%d", + // DataType::cVersion, + // ref().mVersion); + } + } + + DataType* ptr() { return const_cast(mpData); } + + const DataType* ptr() const { return mpData; } + + DataType& ref() { + // SEAD_ASSERT(isValid()); + return *ptr(); + } + + const DataType& ref() const { + // SEAD_ASSERT(isValid()); + return *ptr(); + } + +private: + const DataType* mpData; +}; + +#define AGL_RES_COMMON(class_name) \ +public: \ + class_name() : ResCommon() {} \ + \ + class_name(const void* data) : ResCommon(data) {} + +#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 +struct ResArrayData { + u32 mSize; + u32 mNum; + // DataType mData[]; + + typedef DataType ElemType; +}; + +template +class ResArray : public ResCommon> { + AGL_RES_COMMON(ResArray) + +public: + typedef Type ElemType; + typedef typename Type::DataType ElemDataType; + typedef typename ResArray::DataType DataType; + typedef ResCommon Base; + +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 { + // SEAD_ASSERT(0 <= n && n <= static_cast< int >( this->getNum() )); + + 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)); + } +}; + +#define AGL_RES_ARRAY(class_name) \ +public: \ + class_name() : ResArray() {} \ + \ + class_name(const void* data) : ResArray(data) {} + +} // namespace agl diff --git a/include/common/aglResShaderArchive.h b/include/common/aglResShaderArchive.h new file mode 100644 index 0000000..b02a485 --- /dev/null +++ b/include/common/aglResShaderArchive.h @@ -0,0 +1,62 @@ +#pragma once + +#include "common/aglResCommon.h" +#include "common/aglResShaderProgram.h" +#include "common/aglResShaderSource.h" + +namespace agl { + +struct ResShaderArchiveData { + union { + char mSignature[4]; + u32 mSigWord; + }; + u32 mVersion; + u32 mFileSize; + u32 mEndian; + u32 mNameLen; + // char mName[]; + +public: + static u32 getVersion(); + static u32 getSignature(); + static const char* getExtension(); + +private: + static const u32 cVersion = 11; + static const u32 cSignature = 0x53484141; // SHAA + static const u32 cEndianCheckBit = 0x01000001; + + friend class ResCommon; + friend class ResShaderArchive; +}; +static_assert(sizeof(ResShaderArchiveData) == 0x14, "agl::ResShaderArchiveData size mismatch"); + +class ResShaderArchive : public ResCommon { + AGL_RES_COMMON(ResShaderArchive) + AGL_RES_FILE_HEADER() + +public: + const char* getName() const { + const DataType* const data = ptr(); + return (const char*)(data + 1); + } + + ResShaderProgramArray getResShaderProgramArray() const { + const DataType* const data = ptr(); + return (const ResShaderProgramArrayData*)((uintptr_t)(data + 1) + data->mNameLen); + } + + s32 getResShaderProgramNum() const { return getResShaderProgramArray().getNum(); } + + ResShaderSourceArray getResShaderSourceArray() const { + const ResShaderProgramArrayData* const data = getResShaderProgramArray().ptr(); + return (const ResShaderSourceArrayData*)((uintptr_t)data + data->mSize); + } + + s32 getResShaderSourceNum() const { return getResShaderSourceArray().getNum(); } + + bool setUp(); +}; + +} // namespace agl diff --git a/include/common/aglResShaderBinary.h b/include/common/aglResShaderBinary.h new file mode 100644 index 0000000..88710e6 --- /dev/null +++ b/include/common/aglResShaderBinary.h @@ -0,0 +1,36 @@ +#pragma once + +#include "common/aglResCommon.h" +#include "common/aglShaderEnum.h" + +namespace agl { + +struct ResShaderBinaryData { + u32 mSize; + u32 mShaderType; + s32 mDataOffset; // Relative to end of struct + u32 mDataSize; +}; +static_assert(sizeof(ResShaderBinaryData) == 0x10, "agl::ResShaderBinaryData size mismatch"); + +class ResShaderBinary : public ResCommon { + AGL_RES_COMMON(ResShaderBinary) + +public: + ShaderType getShaderType() const { return ShaderType(ref().mShaderType); } + + void* getData() const { + const DataType* const data = ptr(); + return (void*)((uintptr_t)(data + 1) + data->mDataOffset); + } + + void modifyBinaryEndian(); + void setUp(); +}; + +typedef ResArray ResShaderBinaryArray; + +typedef ResShaderBinaryArray::DataType ResShaderBinaryArrayData; +static_assert(sizeof(ResShaderBinaryArrayData) == 8, "agl::ResShaderBinaryArrayData size mismatch"); + +} // namespace agl diff --git a/include/common/aglResShaderMacro.h b/include/common/aglResShaderMacro.h new file mode 100644 index 0000000..21176a7 --- /dev/null +++ b/include/common/aglResShaderMacro.h @@ -0,0 +1,29 @@ +#pragma once + +#include "common/aglResCommon.h" + +namespace agl { + +struct ResShaderMacroData { + u32 mSize; + u32 mNameLen; + u32 mValueLen; + // char mName[]; +}; +static_assert(sizeof(ResShaderMacroData) == 0xC, "agl::ResShaderMacroData size mismatch"); + +class ResShaderMacro : public ResCommon { + AGL_RES_COMMON(ResShaderMacro) + +public: + const char* getName() const { return (const char*)(ptr() + 1); } + + const char* getValue() const { return getName() + ptr()->mNameLen; } +}; + +typedef ResArray ResShaderMacroArray; + +typedef ResShaderMacroArray::DataType ResShaderMacroArrayData; +static_assert(sizeof(ResShaderMacroArrayData) == 8, "agl::ResShaderMacroArrayData size mismatch"); + +} // namespace agl diff --git a/include/common/aglResShaderProgram.h b/include/common/aglResShaderProgram.h new file mode 100644 index 0000000..f1afbe6 --- /dev/null +++ b/include/common/aglResShaderProgram.h @@ -0,0 +1,41 @@ +#pragma once + +#include "common/aglResShaderMacro.h" +#include "common/aglResShaderSymbol.h" +#include "common/aglResShaderVariation.h" + +namespace agl { + +struct ResShaderProgramData { + u32 mSize; + u32 mNameLen; + s32 mSourceIndex[cShaderType_Num]; + // char mName[]; +}; +static_assert(sizeof(ResShaderProgramData) == 0x14, "agl::ResShaderProgramData size mismatch"); + +class ResShaderProgram : public ResCommon { + AGL_RES_COMMON(ResShaderProgram) + +public: + const char* getName() const { return (const char*)(ptr() + 1); } + + ResShaderMacroArray getResShaderMacroArray(ShaderType type) const; + + ResShaderVariationArray getResShaderVariationArray() const; + + ResShaderVariationArray getResShaderVariationDefaultArray() const { + return (const ResShaderVariationArrayData*)((uintptr_t)getResShaderVariationArray().ptr() + + getResShaderVariationArray().ref().mSize); + } + + ResShaderSymbolArray getResShaderSymbolArray(ShaderSymbolType type) const; +}; + +typedef ResArray ResShaderProgramArray; + +typedef ResShaderProgramArray::DataType ResShaderProgramArrayData; +static_assert(sizeof(ResShaderProgramArrayData) == 8, + "agl::ResShaderProgramArrayData size mismatch"); + +} // namespace agl diff --git a/include/common/aglResShaderSource.h b/include/common/aglResShaderSource.h new file mode 100644 index 0000000..6153bb0 --- /dev/null +++ b/include/common/aglResShaderSource.h @@ -0,0 +1,30 @@ +#pragma once + +#include "common/aglResCommon.h" + +namespace agl { + +struct ResShaderSourceData { + u32 mSize; + u32 mNameLen; + u32 mTextLen; // Text Length + u32 _c; // Text Length... 2 + // char mName[]; +}; +static_assert(sizeof(ResShaderSourceData) == 0x10, "agl::ResShaderSourceData size mismatch"); + +class ResShaderSource : public ResCommon { + AGL_RES_COMMON(ResShaderSource) + +public: + const char* getName() const { return (const char*)(ptr() + 1); } + + const char* getText() const { return getName() + ptr()->mNameLen; } +}; + +typedef ResArray ResShaderSourceArray; + +typedef ResShaderSourceArray::DataType ResShaderSourceArrayData; +static_assert(sizeof(ResShaderSourceArrayData) == 8, "agl::ResShaderSourceArrayData size mismatch"); + +} // namespace agl diff --git a/include/common/aglResShaderSymbol.h b/include/common/aglResShaderSymbol.h new file mode 100644 index 0000000..efb556b --- /dev/null +++ b/include/common/aglResShaderSymbol.h @@ -0,0 +1,58 @@ +#pragma once + +#include +#include "common/aglResCommon.h" +#include "common/aglShaderEnum.h" + +namespace agl { + +struct ResShaderSymbolData { + u32 mSize; + s32 mOffset; + u32 mNameLen; + u32 mIDLen; + u32 mDefaultValueSize; + u32 mVariationNum; + // char mName[]; +}; +static_assert(sizeof(ResShaderSymbolData) == 0x18, "agl::ResShaderSymbolData size mismatch"); + +class ResShaderSymbol : public ResCommon { + AGL_RES_COMMON(ResShaderSymbol) + +public: + const char* getName() const { + const DataType* const data = ptr(); + return (const char*)(data + 1); + } + + const char* getID() const { + const DataType* const data = ptr(); + return (const char*)((uintptr_t)(data + 1) + data->mNameLen); + } + + void* getDefaultValue() const { + const DataType* const data = ptr(); + return (void*)((uintptr_t)(data + 1) + data->mNameLen + data->mIDLen); + } + + const u8* getVariationEnableArray() const { + const DataType* const data = ptr(); + return (const u8*)((uintptr_t)(data + 1) + data->mNameLen + data->mIDLen + + data->mDefaultValueSize); + } + + bool isVariationEnable(s32 index) const { return getVariationEnableArray()[index]; } +}; + +class ResShaderSymbolArray : public ResArray { + AGL_RES_ARRAY(ResShaderSymbolArray) + +public: + ResShaderSymbol searchResShaderSymbolByID(const sead::SafeString& id) const; +}; + +typedef ResShaderSymbolArray::DataType ResShaderSymbolArrayData; +static_assert(sizeof(ResShaderSymbolArrayData) == 8, "agl::ResShaderSymbolArrayData size mismatch"); + +} // namespace agl diff --git a/include/common/aglResShaderVariation.h b/include/common/aglResShaderVariation.h new file mode 100644 index 0000000..a8fd23a --- /dev/null +++ b/include/common/aglResShaderVariation.h @@ -0,0 +1,32 @@ +#pragma once + +#include "common/aglResCommon.h" + +namespace agl { + +struct ResShaderVariationData { + u32 mSize; + u32 mNameLen; + s32 mValueNum; + u32 mIDLen; + // char name[]; +}; +static_assert(sizeof(ResShaderVariationData) == 0x10, "agl::ResShaderVariationData size mismatch"); + +class ResShaderVariation : public ResCommon { + AGL_RES_COMMON(ResShaderVariation) + +public: + const char* getName() const { return (const char*)(ptr() + 1); } + + const char* getID() const; + const char* getValue(s32 index) const; +}; + +typedef ResArray ResShaderVariationArray; + +typedef ResShaderVariationArray::DataType ResShaderVariationArrayData; +static_assert(sizeof(ResShaderVariationArrayData) == 8, + "agl::ResShaderVariationArrayData size mismatch"); + +} // namespace agl diff --git a/include/common/aglShader.h b/include/common/aglShader.h index bd431f7..b312f1e 100644 --- a/include/common/aglShader.h +++ b/include/common/aglShader.h @@ -4,13 +4,6 @@ namespace agl { -enum ShaderType { - ShaderType_Vertex = 0, - ShaderType_Fragment = 1, - ShaderType_Geometry = 2, - ShaderType_Compute = 3 -}; - class Shader { public: Shader(); diff --git a/include/common/aglShaderEnum.h b/include/common/aglShaderEnum.h new file mode 100644 index 0000000..db26fbd --- /dev/null +++ b/include/common/aglShaderEnum.h @@ -0,0 +1,26 @@ +#pragma once + +#include + +namespace agl { + +// No idea which headers these are actually supposed to go in + +enum ShaderType { cShaderType_Vertex, cShaderType_Fragment, cShaderType_Geometry, cShaderType_Num }; + +enum ShaderSymbolType { + cShaderSymbolType_Uniform, + cShaderSymbolType_UniformBlock, + cShaderSymbolType_Sampler, + cShaderSymbolType_Attribute, + cShaderSymbolType_Num, +}; + +enum ShaderMode { + cShaderMode_UniformRegister, + cShaderMode_UniformBlock, + cShaderMode_GeometryShader, + cShaderMode_Invalid +}; + +} // namespace agl