diff --git a/OTRExporter b/OTRExporter index d70db9806..2cfdb3960 160000 --- a/OTRExporter +++ b/OTRExporter @@ -1 +1 @@ -Subproject commit d70db9806c02c229ca3ed928ad0bdae128fe4ac7 +Subproject commit 2cfdb3960900ba059f570b2ded2fed3494a96a9b diff --git a/libultraship b/libultraship index fb10cd2fe..c7974d6a2 160000 --- a/libultraship +++ b/libultraship @@ -1 +1 @@ -Subproject commit fb10cd2feb488cf58899a7d5283195fc50b07b23 +Subproject commit c7974d6a25853d65b44905df728a0e0249636947 diff --git a/soh/soh/OTRGlobals.cpp b/soh/soh/OTRGlobals.cpp index 11ea494d5..2d7e1fcd5 100644 --- a/soh/soh/OTRGlobals.cpp +++ b/soh/soh/OTRGlobals.cpp @@ -22,7 +22,6 @@ #else #include #endif -#include #include #include "Enhancements/speechsynthesizer/SpeechSynthesizer.h" #include "Enhancements/controls/SohInputEditorWindow.h" @@ -108,12 +107,12 @@ GameInteractorSail* GameInteractorSail::Instance; #include "soh/resource/type/Skeleton.h" #include "soh/resource/type/SkeletonLimb.h" #include "soh/resource/type/Text.h" -#include "resource/factory/ArrayFactory.h" #include "resource/factory/BlobFactory.h" #include "resource/factory/DisplayListFactory.h" #include "resource/factory/MatrixFactory.h" #include "resource/factory/TextureFactory.h" #include "resource/factory/VertexFactory.h" +#include "soh/resource/importer/ArrayFactory.h" #include "soh/resource/importer/AnimationFactory.h" #include "soh/resource/importer/AudioSampleFactory.h" #include "soh/resource/importer/AudioSequenceFactory.h" @@ -351,8 +350,8 @@ OTRGlobals::OTRGlobals() { loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "DisplayList", static_cast(LUS::ResourceType::DisplayList), 0); loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_XML, "DisplayList", static_cast(LUS::ResourceType::DisplayList), 0); loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Matrix", static_cast(LUS::ResourceType::Matrix), 0); - loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Array", static_cast(LUS::ResourceType::Array), 0); loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Blob", static_cast(LUS::ResourceType::Blob), 0); + loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Array", static_cast(SOH::ResourceType::SOH_Array), 0); loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Animation", static_cast(SOH::ResourceType::SOH_Animation), 0); loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "PlayerAnimation", static_cast(SOH::ResourceType::SOH_PlayerAnimation), 0); loader->RegisterResourceFactory(std::make_shared(), RESOURCE_FORMAT_BINARY, "Room", static_cast(SOH::ResourceType::SOH_Room), 0); // Is room scene? maybe? @@ -1697,8 +1696,8 @@ extern "C" char* ResourceMgr_LoadTexOrDListByName(const char* filePath) { if (res->GetInitData()->Type == static_cast(LUS::ResourceType::DisplayList)) return (char*)&((std::static_pointer_cast(res))->Instructions[0]); - else if (res->GetInitData()->Type == static_cast(LUS::ResourceType::Array)) - return (char*)(std::static_pointer_cast(res))->Vertices.data(); + else if (res->GetInitData()->Type == static_cast(SOH::ResourceType::SOH_Array)) + return (char*)(std::static_pointer_cast(res))->Vertices.data(); else { return (char*)GetResourceDataByNameHandlingMQ(filePath); } @@ -1828,13 +1827,13 @@ extern "C" void ResourceMgr_UnpatchGfxByName(const char* path, const char* patch extern "C" char* ResourceMgr_LoadArrayByName(const char* path) { - auto res = std::static_pointer_cast(GetResourceByNameHandlingMQ(path)); + auto res = std::static_pointer_cast(GetResourceByNameHandlingMQ(path)); return (char*)res->Scalars.data(); } extern "C" char* ResourceMgr_LoadArrayByNameAsVec3s(const char* path) { - auto res = std::static_pointer_cast(GetResourceByNameHandlingMQ(path)); + auto res = std::static_pointer_cast(GetResourceByNameHandlingMQ(path)); // if (res->CachedGameAsset != nullptr) // return (char*)res->CachedGameAsset; diff --git a/soh/soh/resource/importer/ArrayFactory.cpp b/soh/soh/resource/importer/ArrayFactory.cpp new file mode 100644 index 000000000..39be7c093 --- /dev/null +++ b/soh/soh/resource/importer/ArrayFactory.cpp @@ -0,0 +1,64 @@ +#include "soh/resource/importer/ArrayFactory.h" +#include "soh/resource/type/Array.h" +#include "spdlog/spdlog.h" +#include "graphic/Fast3D/lus_gbi.h" + +namespace SOH { +std::shared_ptr ResourceFactoryBinaryArrayV0::ReadResource(std::shared_ptr file) { + if (!FileHasValidFormatAndReader(file)) { + return nullptr; + } + + auto array = std::make_shared(file->InitData); + auto reader = std::get>(file->Reader); + + array->ArrayType = (ArrayResourceType)reader->ReadUInt32(); + array->ArrayCount = reader->ReadUInt32(); + + for (uint32_t i = 0; i < array->ArrayCount; i++) { + if (array->ArrayType == ArrayResourceType::Vertex) { + // OTRTODO: Implement Vertex arrays as just a vertex resource. + F3DVtx data; + data.v.ob[0] = reader->ReadInt16(); + data.v.ob[1] = reader->ReadInt16(); + data.v.ob[2] = reader->ReadInt16(); + data.v.flag = reader->ReadUInt16(); + data.v.tc[0] = reader->ReadInt16(); + data.v.tc[1] = reader->ReadInt16(); + data.v.cn[0] = reader->ReadUByte(); + data.v.cn[1] = reader->ReadUByte(); + data.v.cn[2] = reader->ReadUByte(); + data.v.cn[3] = reader->ReadUByte(); + array->Vertices.push_back(data); + } else { + array->ArrayScalarType = (ScalarType)reader->ReadUInt32(); + + int iter = 1; + + if (array->ArrayType == ArrayResourceType::Vector) { + iter = reader->ReadUInt32(); + } + + for (int k = 0; k < iter; k++) { + ScalarData data; + + switch (array->ArrayScalarType) { + case ScalarType::ZSCALAR_S16: + data.s16 = reader->ReadInt16(); + break; + case ScalarType::ZSCALAR_U16: + data.u16 = reader->ReadUInt16(); + break; + default: + // OTRTODO: IMPLEMENT OTHER TYPES! + break; + } + + array->Scalars.push_back(data); + } + } + } + + return array; +} +} // namespace LUS diff --git a/soh/soh/resource/importer/ArrayFactory.h b/soh/soh/resource/importer/ArrayFactory.h new file mode 100644 index 000000000..b9f5ca75b --- /dev/null +++ b/soh/soh/resource/importer/ArrayFactory.h @@ -0,0 +1,11 @@ +#pragma once + +#include "resource/Resource.h" +#include "resource/ResourceFactoryBinary.h" + +namespace SOH { +class ResourceFactoryBinaryArrayV0 : public Ship::ResourceFactoryBinary { + public: + std::shared_ptr ReadResource(std::shared_ptr file) override; +}; +} // namespace LUS diff --git a/soh/soh/resource/type/Array.cpp b/soh/soh/resource/type/Array.cpp new file mode 100644 index 000000000..70d5d42ba --- /dev/null +++ b/soh/soh/resource/type/Array.cpp @@ -0,0 +1,45 @@ +#include "Array.h" +#include "graphic/Fast3D/lus_gbi.h" +namespace SOH { +Array::Array() : Resource(std::shared_ptr()) { +} + +void* Array::GetPointer() { + void* dataPointer = nullptr; + switch (ArrayType) { + case ArrayResourceType::Vertex: + dataPointer = Vertices.data(); + break; + case ArrayResourceType::Scalar: + default: + dataPointer = Scalars.data(); + break; + } + + return dataPointer; +} + +size_t Array::GetPointerSize() { + size_t typeSize = 0; + switch (ArrayType) { + case ArrayResourceType::Vertex: + typeSize = sizeof(F3DVtx); + break; + case ArrayResourceType::Scalar: + default: + switch (ArrayScalarType) { + case ScalarType::ZSCALAR_S16: + typeSize = sizeof(int16_t); + break; + case ScalarType::ZSCALAR_U16: + typeSize = sizeof(uint16_t); + break; + default: + // OTRTODO: IMPLEMENT OTHER TYPES! + break; + } + break; + } + return ArrayCount * typeSize; +} +} // namespace LUS diff --git a/soh/soh/resource/type/Array.h b/soh/soh/resource/type/Array.h new file mode 100644 index 000000000..ba41ec049 --- /dev/null +++ b/soh/soh/resource/type/Array.h @@ -0,0 +1,85 @@ +#pragma once + +#include "resource/Resource.h" + +union F3DVtx; +namespace SOH { +typedef union ScalarData { + uint8_t u8; + int8_t s8; + uint16_t u16; + int16_t s16; + uint32_t u32; + int32_t s32; + uint64_t u64; + int64_t s64; + float f32; + double f64; +} ScalarData; + +enum class ScalarType { + ZSCALAR_NONE, + ZSCALAR_S8, + ZSCALAR_U8, + ZSCALAR_X8, + ZSCALAR_S16, + ZSCALAR_U16, + ZSCALAR_X16, + ZSCALAR_S32, + ZSCALAR_U32, + ZSCALAR_X32, + ZSCALAR_S64, + ZSCALAR_U64, + ZSCALAR_X64, + ZSCALAR_F32, + ZSCALAR_F64 +}; + +// OTRTODO: Replace this with something that can be shared between the exporter and importer... +enum class ArrayResourceType { + Error, + Animation, + Array, + AltHeader, + Background, + Blob, + CollisionHeader, + Cutscene, + DisplayList, + Limb, + LimbTable, + Mtx, + Path, + PlayerAnimationData, + Room, + RoomCommand, + Scalar, + Scene, + Skeleton, + String, + Symbol, + Texture, + TextureAnimation, + TextureAnimationParams, + Vector, + Vertex, + Audio +}; + +class Array : public Ship::Resource { + public: + using Resource::Resource; + + Array(); + + void* GetPointer() override; + size_t GetPointerSize() override; + + ArrayResourceType ArrayType; + ScalarType ArrayScalarType; + size_t ArrayCount; + // OTRTODO: Should be a vector of resource pointers... + std::vector Scalars; + std::vector Vertices; +}; +} // namespace LUS diff --git a/soh/soh/resource/type/SohResourceType.h b/soh/soh/resource/type/SohResourceType.h index fdf39031e..6455c28c7 100644 --- a/soh/soh/resource/type/SohResourceType.h +++ b/soh/soh/resource/type/SohResourceType.h @@ -2,6 +2,7 @@ namespace SOH { enum class ResourceType { + SOH_Array = 0x4F415252, // OARR SOH_Animation = 0x4F414E4D, // OANM SOH_PlayerAnimation = 0x4F50414D, // OPAM SOH_Room = 0x4F524F4D, // OROM