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
11 changes: 11 additions & 0 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
64 changes: 64 additions & 0 deletions include/common/aglResBinaryShaderArchive.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,64 @@
#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_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);
};

} // 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> {
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<ResBinaryShaderProgram> ResBinaryShaderProgramArray;
MonsterDruide1 marked this conversation as resolved.
Show resolved Hide resolved

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

} // namespace agl
182 changes: 182 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,182 @@
#pragma once

#include <basis/seadTypes.h>

namespace agl {

void ModifyEndianU32(bool is_le, void* p_data, size_t size);
MonsterDruide1 marked this conversation as resolved.
Show resolved Hide resolved

template <typename _DataType>
MonsterDruide1 marked this conversation as resolved.
Show resolved Hide resolved
class ResCommon {
public:
typedef _DataType DataType;
MonsterDruide1 marked this conversation as resolved.
Show resolved Hide resolved

public:
MonsterDruide1 marked this conversation as resolved.
Show resolved Hide resolved
ResCommon() : mpData(nullptr) {}

ResCommon(const void* data) : mpData(static_cast<const DataType*>(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<DataType*>(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) \
MonsterDruide1 marked this conversation as resolved.
Show resolved Hide resolved
public: \
class_name() : ResCommon<typename class_name::DataType>() {} \
\
class_name(const void* data) : ResCommon<typename class_name::DataType>(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 <typename DataType>
struct ResArrayData {
u32 mSize;
u32 mNum;
// DataType mData[];

typedef DataType ElemType;
MonsterDruide1 marked this conversation as resolved.
Show resolved Hide resolved
};

template <typename Type>
class ResArray : public ResCommon<ResArrayData<typename Type::DataType>> {
AGL_RES_COMMON(ResArray<Type>)

public:
typedef Type ElemType;
typedef typename Type::DataType ElemDataType;
typedef typename ResArray<Type>::DataType DataType;
typedef ResCommon<DataType> Base;
MonsterDruide1 marked this conversation as resolved.
Show resolved Hide resolved

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::ElemType>() {} \
\
class_name(const void* data) : ResArray<class_name::ElemType>(data) {}

} // namespace agl
62 changes: 62 additions & 0 deletions include/common/aglResShaderArchive.h
Original file line number Diff line number Diff line change
@@ -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<ResShaderArchiveData>;
friend class ResShaderArchive;
};
static_assert(sizeof(ResShaderArchiveData) == 0x14, "agl::ResShaderArchiveData size mismatch");

class ResShaderArchive : public ResCommon<ResShaderArchiveData> {
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
Loading