diff options
| -rw-r--r-- | ExporterTest/RoomExporter.cpp | 2 | ||||
| -rw-r--r-- | ZAPD/ZAPD.vcxproj | 2 | ||||
| -rw-r--r-- | ZAPD/ZActorList.cpp | 194 | ||||
| -rw-r--r-- | ZAPD/ZActorList.h | 52 | ||||
| -rw-r--r-- | ZAPD/ZResource.h | 1 | ||||
| -rw-r--r-- | ZAPD/ZRoom/Commands/SetActorList.cpp | 158 | ||||
| -rw-r--r-- | ZAPD/ZRoom/Commands/SetActorList.h | 32 |
7 files changed, 275 insertions, 166 deletions
diff --git a/ExporterTest/RoomExporter.cpp b/ExporterTest/RoomExporter.cpp index 6c5552d..9a5ea19 100644 --- a/ExporterTest/RoomExporter.cpp +++ b/ExporterTest/RoomExporter.cpp @@ -334,7 +334,7 @@ void ExporterExample_Room::Save(ZResource* res, fs::path outPath, BinaryWriter* writer->Write(entry.rotX); writer->Write(entry.rotY); writer->Write(entry.rotZ); - writer->Write(entry.initVar); + writer->Write(entry.params); } writer->Seek(oldOffset, SeekOffsetType::Start); diff --git a/ZAPD/ZAPD.vcxproj b/ZAPD/ZAPD.vcxproj index da3328e..505e411 100644 --- a/ZAPD/ZAPD.vcxproj +++ b/ZAPD/ZAPD.vcxproj @@ -190,6 +190,7 @@ mkdir build\ZAPD <ClCompile Include="OtherStructs\SkinLimbStructs.cpp" />
<ClCompile Include="OutputFormatter.cpp" />
<ClCompile Include="WarningHandler.cpp" />
+ <ClCompile Include="ZActorList.cpp" />
<ClCompile Include="ZArray.cpp" />
<ClCompile Include="ZBackground.cpp" />
<ClCompile Include="ZCollisionPoly.cpp" />
@@ -279,6 +280,7 @@ mkdir build\ZAPD <ClInclude Include="OtherStructs\SkinLimbStructs.h" />
<ClInclude Include="OutputFormatter.h" />
<ClInclude Include="WarningHandler.h" />
+ <ClInclude Include="ZActorList.h" />
<ClInclude Include="ZAnimation.h" />
<ClInclude Include="ZArray.h" />
<ClInclude Include="ZBackground.h" />
diff --git a/ZAPD/ZActorList.cpp b/ZAPD/ZActorList.cpp new file mode 100644 index 0000000..ee5cb4d --- /dev/null +++ b/ZAPD/ZActorList.cpp @@ -0,0 +1,194 @@ +#include "ZActorList.h"
+
+#include "Globals.h"
+#include "Utils/BitConverter.h"
+#include "WarningHandler.h"
+#include "ZFile.h"
+#include "ZRoom/ZNames.h"
+
+REGISTER_ZFILENODE(ActorList, ZActorList);
+
+ZActorList::ZActorList(ZFile* nParent) : ZResource(nParent)
+{
+ RegisterRequiredAttribute("Count");
+}
+
+void ZActorList::ExtractFromBinary(uint32_t nRawDataIndex, uint8_t nNumActors)
+{
+ rawDataIndex = nRawDataIndex;
+ numActors = nNumActors;
+
+ // Don't parse raw data of external files
+ if (parent->GetMode() == ZFileMode::ExternalFile)
+ return;
+
+ ParseRawData();
+}
+
+void ZActorList::ParseXML(tinyxml2::XMLElement* reader)
+{
+ ZResource::ParseXML(reader);
+
+ numActors = StringHelper::StrToL(registeredAttributes.at("Count").value);
+
+ if (numActors < 1)
+ {
+ HANDLE_ERROR_RESOURCE(
+ WarningType::InvalidAttributeValue, parent, this, rawDataIndex,
+ StringHelper::Sprintf("invalid value '%d' found for 'NumPaths' attribute", numActors),
+ "Should be at least '1'");
+ }
+}
+
+void ZActorList::ParseRawData()
+{
+ ZResource::ParseRawData();
+
+ offset_t currentPtr = rawDataIndex;
+ size_t largestlength = 0;
+
+ for (size_t i = 0; i < numActors; i++)
+ {
+ ActorSpawnEntry entry(parent->GetRawData(), currentPtr);
+
+ currentPtr += entry.GetRawDataSize();
+ actors.push_back(entry);
+
+ size_t actorNameLength = ZNames::GetActorName(entry.GetActorId()).size();
+ if (actorNameLength > largestlength)
+ largestlength = actorNameLength;
+ }
+
+ for (auto& entry : actors)
+ {
+ entry.SetLargestActorName(largestlength);
+ }
+}
+
+Declaration* ZActorList::DeclareVar(const std::string& prefix, const std::string& bodyStr)
+{
+ std::string auxName = name;
+
+ if (name == "")
+ auxName = GetDefaultName(prefix);
+
+ Declaration* decl =
+ parent->AddDeclarationArray(rawDataIndex, GetDeclarationAlignment(), GetRawDataSize(),
+ GetSourceTypeName(), name, GetActorListArraySize(), bodyStr);
+ decl->staticConf = staticConf;
+
+ return decl;
+}
+
+std::string ZActorList::GetBodySourceCode() const
+{
+ std::string declaration;
+
+ size_t index = 0;
+ for (auto& entry : actors)
+ {
+ declaration += StringHelper::Sprintf("\t{ %s },", entry.GetBodySourceCode().c_str());
+
+ if (index < actors.size() - 1)
+ declaration += "\n";
+
+ index++;
+ }
+
+ return declaration;
+}
+
+std::string ZActorList::GetSourceTypeName() const
+{
+ return actors.front().GetSourceTypeName();
+}
+
+ZResourceType ZActorList::GetResourceType() const
+{
+ return ZResourceType::ActorList;
+}
+
+size_t ZActorList::GetRawDataSize() const
+{
+ return actors.size() * actors.front().GetRawDataSize();
+}
+
+size_t ZActorList::GetActorListArraySize() const
+{
+ size_t actorCount = 0;
+
+ // Doing an else-if here so we only do the loop when the game is SW97.
+ // Actor 0x22 is removed from SW97, so we need to ensure that we don't increment the actor count
+ // for it.
+ if (Globals::Instance->game == ZGame::OOT_SW97)
+ {
+ actorCount = 0;
+
+ for (const auto& entry : actors)
+ if (entry.GetActorId() != 0x22)
+ actorCount++;
+ }
+ else
+ {
+ actorCount = actors.size();
+ }
+
+ return actorCount;
+}
+
+/* ActorSpawnEntry */
+
+ActorSpawnEntry::ActorSpawnEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex)
+{
+ actorNum = BitConverter::ToInt16BE(rawData, rawDataIndex + 0);
+ posX = BitConverter::ToInt16BE(rawData, rawDataIndex + 2);
+ posY = BitConverter::ToInt16BE(rawData, rawDataIndex + 4);
+ posZ = BitConverter::ToInt16BE(rawData, rawDataIndex + 6);
+ rotX = BitConverter::ToUInt16BE(rawData, rawDataIndex + 8);
+ rotY = BitConverter::ToUInt16BE(rawData, rawDataIndex + 10);
+ rotZ = BitConverter::ToUInt16BE(rawData, rawDataIndex + 12);
+ params = BitConverter::ToInt16BE(rawData, rawDataIndex + 14);
+}
+
+std::string ActorSpawnEntry::GetBodySourceCode() const
+{
+ std::string body;
+
+ std::string actorNameFmt = StringHelper::Sprintf("%%-%zus ", largestActorName + 1);
+ body =
+ StringHelper::Sprintf(actorNameFmt.c_str(), (ZNames::GetActorName(actorNum) + ",").c_str());
+
+ body += StringHelper::Sprintf("{ %6i, %6i, %6i }, ", posX, posY, posZ);
+ if (Globals::Instance->game == ZGame::MM_RETAIL)
+ body += StringHelper::Sprintf("{ SPAWN_ROT_FLAGS(%#5hX, 0x%04X)"
+ ", SPAWN_ROT_FLAGS(%#5hX, 0x%04X)"
+ ", SPAWN_ROT_FLAGS(%#5hX, 0x%04X) }, ",
+ (rotX >> 7) & 0b111111111, rotX & 0b1111111,
+ (rotY >> 7) & 0b111111111, rotY & 0b1111111,
+ (rotZ >> 7) & 0b111111111, rotZ & 0b1111111);
+ else
+ body += StringHelper::Sprintf("{ %#6hX, %#6hX, %#6hX }, ", rotX, rotY, rotZ);
+ body += StringHelper::Sprintf("0x%04X", params);
+
+ return body;
+}
+
+std::string ActorSpawnEntry::GetSourceTypeName() const
+{
+ return "ActorEntry";
+}
+
+size_t ActorSpawnEntry::GetRawDataSize() const
+{
+ return 16;
+}
+
+uint16_t ActorSpawnEntry::GetActorId() const
+{
+ return actorNum;
+}
+
+void ActorSpawnEntry::SetLargestActorName(size_t nameSize)
+{
+ largestActorName = nameSize;
+}
diff --git a/ZAPD/ZActorList.h b/ZAPD/ZActorList.h new file mode 100644 index 0000000..7cc63da --- /dev/null +++ b/ZAPD/ZActorList.h @@ -0,0 +1,52 @@ +#pragma once
+
+#include "ZResource.h"
+
+class ActorSpawnEntry
+{
+public:
+ uint16_t actorNum;
+ int16_t posX;
+ int16_t posY;
+ int16_t posZ;
+ uint16_t rotX;
+ uint16_t rotY;
+ uint16_t rotZ;
+ uint16_t params;
+ size_t largestActorName = 16;
+
+ ActorSpawnEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex);
+
+ std::string GetBodySourceCode() const;
+
+ std::string GetSourceTypeName() const;
+ size_t GetRawDataSize() const;
+
+ uint16_t GetActorId() const;
+ void SetLargestActorName(size_t nameSize);
+};
+
+class ZActorList : public ZResource
+{
+public:
+ std::vector<ActorSpawnEntry> actors;
+ uint32_t numActors = 0;
+
+ ZActorList(ZFile* nParent);
+
+ void ExtractFromBinary(offset_t nRawDataIndex, uint8_t nNumActors);
+
+ void ParseXML(tinyxml2::XMLElement* reader) override;
+ void ParseRawData() override;
+
+ Declaration* DeclareVar(const std::string& prefix, const std::string& bodyStr) override;
+ std::string GetBodySourceCode() const override;
+
+ std::string GetSourceTypeName() const override;
+ ZResourceType GetResourceType() const override;
+
+ size_t GetRawDataSize() const override;
+
+protected:
+ size_t GetActorListArraySize() const;
+};
diff --git a/ZAPD/ZResource.h b/ZAPD/ZResource.h index 3bb2012..f97b259 100644 --- a/ZAPD/ZResource.h +++ b/ZAPD/ZResource.h @@ -25,6 +25,7 @@ class ZFile; enum class ZResourceType { Error, + ActorList, Animation, Array, AltHeader, diff --git a/ZAPD/ZRoom/Commands/SetActorList.cpp b/ZAPD/ZRoom/Commands/SetActorList.cpp index 719b336..b3c186f 100644 --- a/ZAPD/ZRoom/Commands/SetActorList.cpp +++ b/ZAPD/ZRoom/Commands/SetActorList.cpp @@ -1,117 +1,56 @@ #include "SetActorList.h" +#include <cassert> + #include "Globals.h" #include "Utils/BitConverter.h" #include "Utils/StringHelper.h" -#include "ZFile.h" -#include "ZRoom/ZNames.h" #include "ZRoom/ZRoom.h" SetActorList::SetActorList(ZFile* nParent) : ZRoomCommand(nParent) { } +SetActorList::~SetActorList() +{ + if (actorList != nullptr) + delete actorList; +} + void SetActorList::ParseRawData() { ZRoomCommand::ParseRawData(); numActors = cmdArg1; -} -void SetActorList::DeclareReferences(const std::string& prefix) -{ - if (numActors != 0 && cmdArg2 != 0) - { - std::string varName = - StringHelper::Sprintf("%sActorList_%06X", prefix.c_str(), segmentOffset); - parent->AddDeclarationPlaceholder(segmentOffset, varName); - } + actorList = new ZActorList(parent); + actorList->ExtractFromBinary(segmentOffset, numActors); } -void SetActorList::ParseRawDataLate() +void SetActorList::DeclareReferences(const std::string& prefix) { - ZRoomCommand::ParseRawDataLate(); - size_t actorsAmount = zRoom->GetDeclarationSizeFromNeighbor(segmentOffset) / 0x10; - - uint32_t currentPtr = segmentOffset; - - actors.reserve(actorsAmount); - for (size_t i = 0; i < actorsAmount; i++) + if (parent->HasDeclaration(segmentOffset)) { - ActorSpawnEntry entry(parent->GetRawData(), currentPtr); - - currentPtr += entry.GetRawDataSize(); - actors.push_back(entry); - } -} - -void SetActorList::DeclareReferencesLate(const std::string& prefix) -{ - if (actors.empty()) + delete actorList; + actorList = static_cast<ZActorList*>(parent->FindResource(segmentOffset)); + assert(actorList != nullptr); + assert(actorList->GetResourceType() == ZResourceType::ActorList); return; - - std::string declaration; - - size_t largestlength = 0; - for (const auto& entry : actors) - { - size_t actorNameLength = ZNames::GetActorName(entry.GetActorId()).size(); - if (actorNameLength > largestlength) - largestlength = actorNameLength; } - size_t index = 0; - for (auto& entry : actors) + if (actorList->GetName() == "") { - entry.SetLargestActorName(largestlength); - declaration += StringHelper::Sprintf("\t{ %s },", entry.GetBodySourceCode().c_str()); - - if (index < actors.size() - 1) - declaration += "\n"; - - index++; + actorList->SetName(actorList->GetDefaultName(prefix)); } - - const auto& entry = actors.front(); - - std::string varName = StringHelper::Sprintf("%sActorList_%06X", prefix.c_str(), segmentOffset); - parent->AddDeclarationArray(segmentOffset, DeclarationAlignment::Align4, - actors.size() * entry.GetRawDataSize(), entry.GetSourceTypeName(), - varName, GetActorListArraySize(), declaration); + actorList->DeclareVar(prefix, ""); + parent->AddResource(actorList); } std::string SetActorList::GetBodySourceCode() const { std::string listName; Globals::Instance->GetSegmentedPtrName(cmdArg2, parent, "ActorEntry", listName); - if (numActors != actors.size()) - { - printf("%s: numActors(%i) ~ actors(%li)\n", parent->GetName().c_str(), numActors, - actors.size()); - } - return StringHelper::Sprintf("SCENE_CMD_ACTOR_LIST(%i, %s)", numActors, listName.c_str()); -} - -size_t SetActorList::GetActorListArraySize() const -{ - size_t actorCount = 0; - - // Doing an else-if here so we only do the loop when the game is SW97. - // Actor 0x22 is removed from SW97, so we need to ensure that we don't increment the actor count - // for it. - if (Globals::Instance->game == ZGame::OOT_SW97) - { - actorCount = 0; - - for (const auto& entry : actors) - if (entry.GetActorId() != 0x22) - actorCount++; - } - else - { - actorCount = actors.size(); - } - return actorCount; + return StringHelper::Sprintf("SCENE_CMD_ACTOR_LIST(%i, %s)", numActors, listName.c_str()); } std::string SetActorList::GetCommandCName() const @@ -123,58 +62,3 @@ RoomCommand SetActorList::GetRoomCommand() const { return RoomCommand::SetActorList; } - -ActorSpawnEntry::ActorSpawnEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex) -{ - actorNum = BitConverter::ToInt16BE(rawData, rawDataIndex + 0); - posX = BitConverter::ToInt16BE(rawData, rawDataIndex + 2); - posY = BitConverter::ToInt16BE(rawData, rawDataIndex + 4); - posZ = BitConverter::ToInt16BE(rawData, rawDataIndex + 6); - rotX = BitConverter::ToUInt16BE(rawData, rawDataIndex + 8); - rotY = BitConverter::ToUInt16BE(rawData, rawDataIndex + 10); - rotZ = BitConverter::ToUInt16BE(rawData, rawDataIndex + 12); - initVar = BitConverter::ToInt16BE(rawData, rawDataIndex + 14); -} - -std::string ActorSpawnEntry::GetBodySourceCode() const -{ - std::string body; - - std::string actorNameFmt = StringHelper::Sprintf("%%-%zus ", largestActorName + 1); - body = - StringHelper::Sprintf(actorNameFmt.c_str(), (ZNames::GetActorName(actorNum) + ",").c_str()); - - body += StringHelper::Sprintf("{ %6i, %6i, %6i }, ", posX, posY, posZ); - if (Globals::Instance->game == ZGame::MM_RETAIL) - body += StringHelper::Sprintf("{ SPAWN_ROT_FLAGS(%#5hX, 0x%04X)" - ", SPAWN_ROT_FLAGS(%#5hX, 0x%04X)" - ", SPAWN_ROT_FLAGS(%#5hX, 0x%04X) }, ", - (rotX >> 7) & 0b111111111, rotX & 0b1111111, - (rotY >> 7) & 0b111111111, rotY & 0b1111111, - (rotZ >> 7) & 0b111111111, rotZ & 0b1111111); - else - body += StringHelper::Sprintf("{ %#6hX, %#6hX, %#6hX }, ", rotX, rotY, rotZ); - body += StringHelper::Sprintf("0x%04X", initVar); - - return body; -} - -std::string ActorSpawnEntry::GetSourceTypeName() const -{ - return "ActorEntry"; -} - -int32_t ActorSpawnEntry::GetRawDataSize() const -{ - return 16; -} - -uint16_t ActorSpawnEntry::GetActorId() const -{ - return actorNum; -} - -void ActorSpawnEntry::SetLargestActorName(size_t nameSize) -{ - largestActorName = nameSize; -} diff --git a/ZAPD/ZRoom/Commands/SetActorList.h b/ZAPD/ZRoom/Commands/SetActorList.h index 7b34125..f3eed93 100644 --- a/ZAPD/ZRoom/Commands/SetActorList.h +++ b/ZAPD/ZRoom/Commands/SetActorList.h @@ -1,44 +1,20 @@ #pragma once #include "ZRoom/ZRoomCommand.h" - -class ActorSpawnEntry -{ -public: - uint16_t actorNum; - int16_t posX; - int16_t posY; - int16_t posZ; - uint16_t rotX; - uint16_t rotY; - uint16_t rotZ; - uint16_t initVar; - size_t largestActorName = 16; - - ActorSpawnEntry(const std::vector<uint8_t>& rawData, uint32_t rawDataIndex); - - std::string GetBodySourceCode() const; - - std::string GetSourceTypeName() const; - int32_t GetRawDataSize() const; - - uint16_t GetActorId() const; - void SetLargestActorName(size_t nameSize); -}; +#include "ZActorList.h" class SetActorList : public ZRoomCommand { public: - uint8_t numActors; - std::vector<ActorSpawnEntry> actors; + uint32_t numActors; + ZActorList* actorList = nullptr; SetActorList(ZFile* nParent); + ~SetActorList(); void ParseRawData() override; void DeclareReferences(const std::string& prefix) override; - void ParseRawDataLate() override; - void DeclareReferencesLate(const std::string& prefix) override; std::string GetBodySourceCode() const override; |
