diff options
| author | MegaMech <MegaMech@users.noreply.github.com> | 2024-05-22 19:19:16 -0600 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2024-05-22 19:19:16 -0600 |
| commit | 78a7d156c9a080fab1c530d2aa8210c6d4cf5596 (patch) | |
| tree | d2ca24968a44ac59036945ae8a218e1a3b23cab2 /src/port | |
| parent | bd9f6b3e851c02edff594237109df01ceb336a09 (diff) | |
Changes for OTR (#15)
* Bunch of fixes
Diffstat (limited to 'src/port')
20 files changed, 400 insertions, 29 deletions
diff --git a/src/port/Engine.cpp b/src/port/Engine.cpp index 09658b207..0d18255bc 100644 --- a/src/port/Engine.cpp +++ b/src/port/Engine.cpp @@ -7,6 +7,11 @@ #include "resource/importers/GenericArrayFactory.h" #include "resource/importers/Vec3fFactory.h" #include "resource/importers/Vec3sFactory.h" +#include "resource/importers/KartAIFactory.h" +#include "resource/importers/TrackSectionsFactory.h" +#include "resource/importers/TrackWaypointFactory.h" +#include "resource/importers/ActorSpawnDataFactory.h" +#include <Fast3D/Fast3dWindow.h> #include <Fast3D/gfx_pc.h> #include <Fast3D/gfx_rendering_api.h> @@ -17,6 +22,12 @@ extern "C" { float gInterpolationStep = 0.0f; #include <macros.h> +#include <DisplayListFactory.h> +#include <TextureFactory.h> +#include <MatrixFactory.h> +#include <ArrayFactory.h> +#include <BlobFactory.h> +#include <VertexFactory.h> } GameEngine* GameEngine::Instance; @@ -45,6 +56,18 @@ GameEngine::GameEngine() { loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryBinaryVec3fV0>(), RESOURCE_FORMAT_BINARY, "Vec3f", static_cast<uint32_t>(SF64::ResourceType::Vec3f), 0); loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryBinaryVec3sV0>(), RESOURCE_FORMAT_BINARY, "Vec3s", static_cast<uint32_t>(SF64::ResourceType::Vec3s), 0); loader->RegisterResourceFactory(std::make_shared<SF64::ResourceFactoryBinaryGenericArrayV0>(), RESOURCE_FORMAT_BINARY, "GenericArray", static_cast<uint32_t>(SF64::ResourceType::GenericArray), 0); + loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryTextureV0>(), RESOURCE_FORMAT_BINARY, "Texture", static_cast<uint32_t>(LUS::ResourceType::Texture), 0); + loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryTextureV1>(), RESOURCE_FORMAT_BINARY, "Texture", static_cast<uint32_t>(LUS::ResourceType::Texture), 1); + loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryVertexV0>(), RESOURCE_FORMAT_BINARY, "Vertex", static_cast<uint32_t>(LUS::ResourceType::Vertex), 0); + loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryDisplayListV0>(), RESOURCE_FORMAT_BINARY, "DisplayList", static_cast<uint32_t>(LUS::ResourceType::DisplayList), 0); + loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryMatrixV0>(), RESOURCE_FORMAT_BINARY, "Matrix", static_cast<uint32_t>(LUS::ResourceType::Matrix), 0); + loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryArrayV0>(), RESOURCE_FORMAT_BINARY, "Array", static_cast<uint32_t>(LUS::ResourceType::Array), 0); + loader->RegisterResourceFactory(std::make_shared<LUS::ResourceFactoryBinaryBlobV0>(), RESOURCE_FORMAT_BINARY, "Blob", static_cast<uint32_t>(LUS::ResourceType::Blob), 0); + loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryKartAIV0>(), RESOURCE_FORMAT_BINARY, "KartAI", static_cast<uint32_t>(MK64::ResourceType::KartAI), 0); + loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryTrackSectionsV0>(), RESOURCE_FORMAT_BINARY, "TrackSections", static_cast<uint32_t>(MK64::ResourceType::TrackSection), 0); + loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryTrackWaypointsV0>(), RESOURCE_FORMAT_BINARY, "Waypoints", static_cast<uint32_t>(MK64::ResourceType::Waypoints), 0); + loader->RegisterResourceFactory(std::make_shared<MK64::ResourceFactoryBinaryActorSpawnDataV0>(), RESOURCE_FORMAT_BINARY, "SpawnData", static_cast<uint32_t>(MK64::ResourceType::SpawnData), 0); + } void GameEngine::Create(){ @@ -79,9 +102,10 @@ void GameEngine::StartFrame() const{ this->context->GetWindow()->StartFrame(); } -void GameEngine::ProcessFrame(void (*run_one_game_iter)()) const { - this->context->GetWindow()->MainLoop(run_one_game_iter); -} +// void GameEngine::ProcessFrame(void (*run_one_game_iter)()) const { +// //this->context->GetWindow()->MainLoop(run_one_game_iter); +// Instance->context->GetWindow()->MainLoop(run_one_game_iter); +// } void GameEngine::RunCommands(Gfx* Commands) { gfx_run(Commands, {}); @@ -95,8 +119,11 @@ void GameEngine::RunCommands(Gfx* Commands) { void GameEngine::ProcessGfxCommands(Gfx* commands) { RunCommands(commands); - Instance->context->GetWindow()->SetTargetFps(30); - Instance->context->GetWindow()->SetMaximumFrameLatency(1); + auto wnd = std::dynamic_pointer_cast<Fast::Fast3dWindow>(Ship::Context::GetInstance()->GetWindow()); + if (wnd != nullptr) { + wnd->SetTargetFps(30); + wnd->SetMaximumFrameLatency(1); + } } extern "C" uint32_t GameEngine_GetSampleRate() { @@ -129,10 +156,8 @@ extern "C" uint32_t GameEngine_GetGameVersion() { static const char* sOtrSignature = "__OTR__"; extern "C" uint8_t GameEngine_OTRSigCheck(const char* data) { - if(data == nullptr) { - return 0; - } - return strncmp(data, sOtrSignature, strlen(sOtrSignature)) == 0; + static const char* sOtrSignaturea = "__OTR__"; + return strncmp(data, sOtrSignaturea, strlen(sOtrSignaturea)) == 0; } // struct TimedEntry { diff --git a/src/port/GBIMiddleware.cpp b/src/port/GBIMiddleware.cpp index 13bda57fd..361ca24e0 100644 --- a/src/port/GBIMiddleware.cpp +++ b/src/port/GBIMiddleware.cpp @@ -13,9 +13,9 @@ extern "C" void gSPDisplayList(Gfx* pkt, Gfx* dl) { auto resource = Ship::Context::GetInstance()->GetResourceManager()->LoadResource(imgData); auto res = std::static_pointer_cast<LUS::DisplayList>(resource); dl = &res->Instructions[0]; - // dl->words.trace.file = imgData; - // dl->words.trace.idx = 0; - // dl->words.trace.valid = true; + dl->words.trace.file = imgData; + dl->words.trace.idx = 0; + dl->words.trace.valid = true; } __gSPDisplayList(pkt, dl); diff --git a/src/port/Game.cpp b/src/port/Game.cpp index cb62afb73..b8f27818f 100644 --- a/src/port/Game.cpp +++ b/src/port/Game.cpp @@ -38,7 +38,10 @@ int main(int argc, char *argv[]) { // audio_init(); // sound_init(); thread5_game_loop(); - GameEngine::Instance->ProcessFrame(push_frame); + while (WindowIsRunning()) { + push_frame(); + } + //GameEngine::Instance->ProcessFrame(push_frame); GameEngine::Instance->Destroy(); return 0; } diff --git a/src/port/resource/importers/ActorSpawnDataFactory.cpp b/src/port/resource/importers/ActorSpawnDataFactory.cpp new file mode 100644 index 000000000..e5a2ea485 --- /dev/null +++ b/src/port/resource/importers/ActorSpawnDataFactory.cpp @@ -0,0 +1,31 @@ +#include "ActorSpawnDataFactory.h" +#include "../type/SpawnData.h" +#include "spdlog/spdlog.h" +#include "libultraship/libultra/gbi.h" +#include <common_structs.h> + +namespace MK64 { + std::shared_ptr<Ship::IResource> ResourceFactoryBinaryActorSpawnDataV0::ReadResource(std::shared_ptr<Ship::File> file) { + if (!FileHasValidFormatAndReader(file)) { + return nullptr; + } + + auto section = std::make_shared<ActorSpawn>(file->InitData); + auto reader = std::get<std::shared_ptr<Ship::BinaryReader>>(file->Reader); + + uint32_t count = reader->ReadUInt32(); + section->ActorSpawnDataList.reserve(count); + + for (uint32_t i = 0; i < count; i++) { + ActorSpawnData data; + data.pos[0] = reader->ReadInt16(); + data.pos[1] = reader->ReadInt16(); + data.pos[2] = reader->ReadInt16(); + data.signedSomeId = reader->ReadUByte(); + + section->ActorSpawnDataList.push_back(data); + } + + return section; + } +}
\ No newline at end of file diff --git a/src/port/resource/importers/ActorSpawnDataFactory.h b/src/port/resource/importers/ActorSpawnDataFactory.h new file mode 100644 index 000000000..5b18717a1 --- /dev/null +++ b/src/port/resource/importers/ActorSpawnDataFactory.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Resource.h" +#include "ResourceFactoryBinary.h" + +namespace MK64 { +class ResourceFactoryBinaryActorSpawnDataV0 : public Ship::ResourceFactoryBinary { + public: + std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file) override; +}; + +} // namespace LUS diff --git a/src/port/resource/importers/KartAIFactory.cpp b/src/port/resource/importers/KartAIFactory.cpp new file mode 100644 index 000000000..f125e154a --- /dev/null +++ b/src/port/resource/importers/KartAIFactory.cpp @@ -0,0 +1,29 @@ +#include "KartAIFactory.h" +#include "../type/KartAI.h" +#include "spdlog/spdlog.h" +#include "libultraship/libultra/gbi.h" + +namespace MK64 { + std::shared_ptr<Ship::IResource> ResourceFactoryBinaryKartAIV0::ReadResource(std::shared_ptr<Ship::File> file) { + if (!FileHasValidFormatAndReader(file)) { + return nullptr; + } + + auto ai = std::make_shared<KartAI>(file->InitData); + auto reader = std::get<std::shared_ptr<Ship::BinaryReader>>(file->Reader); + + uint32_t count = reader->ReadUInt32(); + ai->KartAIList.reserve(count); + + for (uint32_t i = 0; i < count; i++) { + KartAIBehaviour data; + data.waypointStart = reader->ReadInt16(); + data.waypointEnd = reader->ReadInt16(); + data.type = reader->ReadInt32(); + + ai->KartAIList.push_back(data); + } + + return ai; + } +}
\ No newline at end of file diff --git a/src/port/resource/importers/KartAIFactory.h b/src/port/resource/importers/KartAIFactory.h new file mode 100644 index 000000000..5bf6b6ea6 --- /dev/null +++ b/src/port/resource/importers/KartAIFactory.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Resource.h" +#include "ResourceFactoryBinary.h" + +namespace MK64 { +class ResourceFactoryBinaryKartAIV0 : public Ship::ResourceFactoryBinary { + public: + std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file) override; +}; + +} // namespace LUS diff --git a/src/port/resource/importers/TrackSectionsFactory.cpp b/src/port/resource/importers/TrackSectionsFactory.cpp new file mode 100644 index 000000000..512d2c7e3 --- /dev/null +++ b/src/port/resource/importers/TrackSectionsFactory.cpp @@ -0,0 +1,30 @@ +#include "TrackSectionsFactory.h" +#include "../type/TrackSections.h" +#include "spdlog/spdlog.h" +#include "libultraship/libultra/gbi.h" + +namespace MK64 { + std::shared_ptr<Ship::IResource> ResourceFactoryBinaryTrackSectionsV0::ReadResource(std::shared_ptr<Ship::File> file) { + if (!FileHasValidFormatAndReader(file)) { + return nullptr; + } + + auto section = std::make_shared<TrackSectionsClass>(file->InitData); + auto reader = std::get<std::shared_ptr<Ship::BinaryReader>>(file->Reader); + + uint32_t count = reader->ReadUInt32(); + section->TrackSectionsList.reserve(count); + + for (uint32_t i = 0; i < count; i++) { + TrackSectionsI data; + data.addr = reader->ReadUInt32(); + data.surfaceType = reader->ReadUByte(); + data.sectionId = reader->ReadUByte(); + data.flags = reader->ReadUInt16(); + + section->TrackSectionsList.push_back(data); + } + + return section; + } +}
\ No newline at end of file diff --git a/src/port/resource/importers/TrackSectionsFactory.h b/src/port/resource/importers/TrackSectionsFactory.h new file mode 100644 index 000000000..f3cabbdb2 --- /dev/null +++ b/src/port/resource/importers/TrackSectionsFactory.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Resource.h" +#include "ResourceFactoryBinary.h" + +namespace MK64 { +class ResourceFactoryBinaryTrackSectionsV0 : public Ship::ResourceFactoryBinary { + public: + std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file) override; +}; + +} // namespace LUS diff --git a/src/port/resource/importers/TrackWaypointFactory.cpp b/src/port/resource/importers/TrackWaypointFactory.cpp new file mode 100644 index 000000000..a24e88931 --- /dev/null +++ b/src/port/resource/importers/TrackWaypointFactory.cpp @@ -0,0 +1,30 @@ +#include "TrackWaypointFactory.h" +#include "../type/TrackWaypoint.h" +#include "spdlog/spdlog.h" +#include "libultraship/libultra/gbi.h" + +namespace MK64 { + std::shared_ptr<Ship::IResource> ResourceFactoryBinaryTrackWaypointsV0::ReadResource(std::shared_ptr<Ship::File> file) { + if (!FileHasValidFormatAndReader(file)) { + return nullptr; + } + + auto section = std::make_shared<TrackWaypoints>(file->InitData); + auto reader = std::get<std::shared_ptr<Ship::BinaryReader>>(file->Reader); + + uint32_t count = reader->ReadUInt32(); + section->TrackWaypointList.reserve(count); + + for (uint32_t i = 0; i < count; i++) { + TrackWaypoint data; + data.posX = reader->ReadInt16(); + data.posY = reader->ReadInt16(); + data.posZ = reader->ReadInt16(); + data.trackSegment = reader->ReadUInt16(); + + section->TrackWaypointList.push_back(data); + } + + return section; + } +}
\ No newline at end of file diff --git a/src/port/resource/importers/TrackWaypointFactory.h b/src/port/resource/importers/TrackWaypointFactory.h new file mode 100644 index 000000000..f75f07023 --- /dev/null +++ b/src/port/resource/importers/TrackWaypointFactory.h @@ -0,0 +1,12 @@ +#pragma once + +#include "Resource.h" +#include "ResourceFactoryBinary.h" + +namespace MK64 { +class ResourceFactoryBinaryTrackWaypointsV0 : public Ship::ResourceFactoryBinary { + public: + std::shared_ptr<Ship::IResource> ReadResource(std::shared_ptr<Ship::File> file) override; +}; + +} // namespace LUS diff --git a/src/port/resource/type/KartAI.cpp b/src/port/resource/type/KartAI.cpp new file mode 100644 index 000000000..d99b5c091 --- /dev/null +++ b/src/port/resource/type/KartAI.cpp @@ -0,0 +1,15 @@ +#include "KartAI.h" +#include "libultraship/libultra/gbi.h" + +namespace MK64 { +KartAI::KartAI() : Resource(std::shared_ptr<Ship::ResourceInitData>()) { +} + +KartAIBehaviour* KartAI::GetPointer() { + return KartAIList.data(); +} + +size_t KartAI::GetPointerSize() { + return KartAIList.size() * sizeof(KartAIBehaviour); +} +} // namespace LUS diff --git a/src/port/resource/type/KartAI.h b/src/port/resource/type/KartAI.h new file mode 100644 index 000000000..8872b5ee9 --- /dev/null +++ b/src/port/resource/type/KartAI.h @@ -0,0 +1,24 @@ +#pragma once + +#include "resource/Resource.h" +#include <vector> + +struct KartAIBehaviour { + /* 0x0 */ int16_t waypointStart; + /* 0x2 */ int16_t waypointEnd; + /* 0x4 */ int32_t type; +}; // size = 0x8 + +namespace MK64 { +class KartAI : public Ship::Resource<KartAIBehaviour> { + public: + using Resource::Resource; + + KartAI(); + + KartAIBehaviour* GetPointer() override; + size_t GetPointerSize() override; + + std::vector<KartAIBehaviour> KartAIList; +}; +} // namespace LUS diff --git a/src/port/resource/type/ResourceType.h b/src/port/resource/type/ResourceType.h index c143457d2..e8d7d91aa 100644 --- a/src/port/resource/type/ResourceType.h +++ b/src/port/resource/type/ResourceType.h @@ -1,21 +1,32 @@ #pragma once namespace SF64 { -enum class ResourceType { + enum class ResourceType { // SF64 - AnimData = 0x414E494D, // ANIM - ColPoly = 0x43504C59, // CPLY - EnvSettings = 0x454E5653, // ENVS - Limb = 0x4C494D42, // LIMB - Message = 0x4D534720, // MSG - MessageTable = 0x4D534754, // MSGT - Skeleton = 0x534B454C, // SKEL - Script = 0x53435250, // SCRP - ScriptCmd = 0x53434D44, // SCMD - Hitbox = 0x48544258, // HTBX - ObjectInit = 0x4F42494E, // OBIN - Vec3f = 0x56433346, // VC3F - Vec3s = 0x56433353, // VC3S - GenericArray = 0x47415252, // GARR -}; + AnimData = 0x414E494D, // ANIM + ColPoly = 0x43504C59, // CPLY + EnvSettings = 0x454E5653, // ENVS + Limb = 0x4C494D42, // LIMB + Message = 0x4D534720, // MSG + MessageTable = 0x4D534754, // MSGT + Skeleton = 0x534B454C, // SKEL + Script = 0x53435250, // SCRP + ScriptCmd = 0x53434D44, // SCMD + Hitbox = 0x48544258, // HTBX + ObjectInit = 0x4F42494E, // OBIN + Vec3f = 0x56433346, // VC3F + Vec3s = 0x56433353, // VC3S + GenericArray = 0x47415252, // GARR + }; } // namespace SOH + +namespace MK64 { + enum class ResourceType { + CourseVertex = 0x43565458, // CVTX + TrackSection = 0x5343544E, // SCTN + Waypoints = 0x57505453, // WPTS + Metadata = 0x4D444154, // MDAT + SpawnData = 0x53444154, // SDAT + KartAI = 0x44424856, // DBHV + }; +}
\ No newline at end of file diff --git a/src/port/resource/type/SpawnData.cpp b/src/port/resource/type/SpawnData.cpp new file mode 100644 index 000000000..9db940b16 --- /dev/null +++ b/src/port/resource/type/SpawnData.cpp @@ -0,0 +1,15 @@ +#include "SpawnData.h" +#include "libultraship/libultra/gbi.h" + +namespace MK64 { +ActorSpawn::ActorSpawn() : Resource(std::shared_ptr<Ship::ResourceInitData>()) { +} + +ActorSpawnData* ActorSpawn::GetPointer() { + return ActorSpawnDataList.data(); +} + +size_t ActorSpawn::GetPointerSize() { + return ActorSpawnDataList.size() * sizeof(ActorSpawnData); +} +} // namespace LUS diff --git a/src/port/resource/type/SpawnData.h b/src/port/resource/type/SpawnData.h new file mode 100644 index 000000000..185050d8d --- /dev/null +++ b/src/port/resource/type/SpawnData.h @@ -0,0 +1,28 @@ +#pragma once + +#include "resource/Resource.h" +#include <vector> +#include <libultra/gbi.h> +#include <common_structs.h> + +struct ActorSpawnData { + /* 0x00 */ Vec3s pos; + union { + /* 0x06 */ u16 someId; // Usually populated, but not necessarily used by all actors types + /* 0x06 */ s16 signedSomeId; + }; +}; + +namespace MK64 { +class ActorSpawn : public Ship::Resource<ActorSpawnData> { + public: + using Resource::Resource; + + ActorSpawn(); + + ActorSpawnData* GetPointer() override; + size_t GetPointerSize() override; + + std::vector<ActorSpawnData> ActorSpawnDataList; +}; +} // namespace LUS diff --git a/src/port/resource/type/TrackSections.cpp b/src/port/resource/type/TrackSections.cpp new file mode 100644 index 000000000..c0121961b --- /dev/null +++ b/src/port/resource/type/TrackSections.cpp @@ -0,0 +1,15 @@ +#include "TrackSections.h" +#include "libultraship/libultra/gbi.h" + +namespace MK64 { +TrackSectionsClass::TrackSectionsClass() : Resource(std::shared_ptr<Ship::ResourceInitData>()) { +} + +TrackSectionsI* TrackSectionsClass::GetPointer() { + return TrackSectionsList.data(); +} + +size_t TrackSectionsClass::GetPointerSize() { + return TrackSectionsList.size() * sizeof(TrackSectionsI); +} +} // namespace LUS diff --git a/src/port/resource/type/TrackSections.h b/src/port/resource/type/TrackSections.h new file mode 100644 index 000000000..50a70c3bf --- /dev/null +++ b/src/port/resource/type/TrackSections.h @@ -0,0 +1,26 @@ +#pragma once + +#include "resource/Resource.h" +#include <vector> +#include <libultra/gbi.h> + +typedef struct { + uintptr_t addr; + uint8_t surfaceType; + uint8_t sectionId; + uint16_t flags; +} TrackSectionsI; + +namespace MK64 { +class TrackSectionsClass : public Ship::Resource<TrackSectionsI> { + public: + using Resource::Resource; + + TrackSectionsClass(); + + TrackSectionsI* GetPointer() override; + size_t GetPointerSize() override; + + std::vector<TrackSectionsI> TrackSectionsList; +}; +} // namespace LUS diff --git a/src/port/resource/type/TrackWaypoint.cpp b/src/port/resource/type/TrackWaypoint.cpp new file mode 100644 index 000000000..d8515c4a9 --- /dev/null +++ b/src/port/resource/type/TrackWaypoint.cpp @@ -0,0 +1,15 @@ +#include "TrackWaypoint.h" +#include "libultraship/libultra/gbi.h" + +namespace MK64 { +TrackWaypoints::TrackWaypoints() : Resource(std::shared_ptr<Ship::ResourceInitData>()) { +} + +TrackWaypoint* TrackWaypoints::GetPointer() { + return TrackWaypointList.data(); +} + +size_t TrackWaypoints::GetPointerSize() { + return TrackWaypointList.size() * sizeof(TrackWaypoint); +} +} // namespace LUS diff --git a/src/port/resource/type/TrackWaypoint.h b/src/port/resource/type/TrackWaypoint.h new file mode 100644 index 000000000..a1e7ce4ee --- /dev/null +++ b/src/port/resource/type/TrackWaypoint.h @@ -0,0 +1,26 @@ +#pragma once + +#include "resource/Resource.h" +#include <vector> +#include <libultra/gbi.h> + +struct TrackWaypoint { + int16_t posX; + int16_t posY; + int16_t posZ; + uint16_t trackSegment; +}; + +namespace MK64 { +class TrackWaypoints : public Ship::Resource<TrackWaypoint> { + public: + using Resource::Resource; + + TrackWaypoints(); + + TrackWaypoint* GetPointer() override; + size_t GetPointerSize() override; + + std::vector<TrackWaypoint> TrackWaypointList; +}; +} // namespace LUS |
