Skip to content

Commit

Permalink
common: Copy aglRes-Files from WiiU-Decomp (#15)
Browse files Browse the repository at this point in the history
  • Loading branch information
MonsterDruide1 committed Aug 19, 2023
1 parent 1e15224 commit 611fe02
Show file tree
Hide file tree
Showing 20 changed files with 1,042 additions and 64 deletions.
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
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);

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

0 comments on commit 611fe02

Please sign in to comment.