mirror of https://github.com/zeldaret/oot.git
				
				
				
			Zapd hotfix (#1009)
* remove fake match * git subrepo pull --force tools/ZAPD subrepo: subdir: "tools/ZAPD" merged: "4f7b8393e" upstream: origin: "https://github.com/zeldaret/ZAPD.git" branch: "master" commit: "4f7b8393e" git-subrepo: version: "0.4.3" origin: "https://github.com/ingydotnet/git-subrepo.git" commit: "2f68596"
This commit is contained in:
		
							parent
							
								
									ceb571423d
								
							
						
					
					
						commit
						42b8cec3d0
					
				| 
						 | 
				
			
			@ -6,7 +6,7 @@
 | 
			
		|||
[subrepo]
 | 
			
		||||
	remote = https://github.com/zeldaret/ZAPD.git
 | 
			
		||||
	branch = master
 | 
			
		||||
	commit = d0cd6b3974706fc4d89c9b6545b8c17dd424b664
 | 
			
		||||
	parent = c0e02913038e871221b2fcfc8be65b8dc281aa4a
 | 
			
		||||
	commit = 4f7b8393ec8a3abd59649c2ba669e951fb61f3d2
 | 
			
		||||
	parent = efb9badbf211c5d5065c1b25b58f0e0fe2d17ec4
 | 
			
		||||
	method = merge
 | 
			
		||||
	cmdver = 0.4.3
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -76,4 +76,4 @@ static void ImportExporters()
 | 
			
		|||
 | 
			
		||||
// When ZAPD starts up, it will automatically call the below function, which in turn sets up our
 | 
			
		||||
// exporters.
 | 
			
		||||
REGISTER_EXPORTER(ImportExporters)
 | 
			
		||||
REGISTER_EXPORTER(ImportExporters);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -23,6 +23,16 @@ Globals::Globals()
 | 
			
		|||
	outputPath = Directory::GetCurrentDirectory();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
Globals::~Globals()
 | 
			
		||||
{
 | 
			
		||||
	auto& exporters = GetExporterMap();
 | 
			
		||||
 | 
			
		||||
	for (auto& it : exporters)
 | 
			
		||||
	{
 | 
			
		||||
		delete it.second;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Globals::AddSegment(int32_t segment, ZFile* file)
 | 
			
		||||
{
 | 
			
		||||
	if (std::find(segments.begin(), segments.end(), segment) == segments.end())
 | 
			
		||||
| 
						 | 
				
			
			@ -38,21 +48,21 @@ bool Globals::HasSegment(int32_t segment)
 | 
			
		|||
	return std::find(segments.begin(), segments.end(), segment) != segments.end();
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
std::map<std::string, ExporterSet*>* Globals::GetExporterMap()
 | 
			
		||||
std::map<std::string, ExporterSet*>& Globals::GetExporterMap()
 | 
			
		||||
{
 | 
			
		||||
	static std::map<std::string, ExporterSet*> exporters;
 | 
			
		||||
	return &exporters;
 | 
			
		||||
	return exporters;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
void Globals::AddExporter(std::string exporterName, ExporterSet* exporterSet)
 | 
			
		||||
{
 | 
			
		||||
	auto exporters = GetExporterMap();
 | 
			
		||||
	(*exporters)[exporterName] = exporterSet;
 | 
			
		||||
	auto& exporters = GetExporterMap();
 | 
			
		||||
	exporters[exporterName] = exporterSet;
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ZResourceExporter* Globals::GetExporter(ZResourceType resType)
 | 
			
		||||
{
 | 
			
		||||
	auto exporters = *GetExporterMap();
 | 
			
		||||
	auto& exporters = GetExporterMap();
 | 
			
		||||
 | 
			
		||||
	if (currentExporter != "" && exporters[currentExporter]->exporters.find(resType) !=
 | 
			
		||||
	                                 exporters[currentExporter]->exporters.end())
 | 
			
		||||
| 
						 | 
				
			
			@ -63,7 +73,7 @@ ZResourceExporter* Globals::GetExporter(ZResourceType resType)
 | 
			
		|||
 | 
			
		||||
ExporterSet* Globals::GetExporterSet()
 | 
			
		||||
{
 | 
			
		||||
	auto exporters = *GetExporterMap();
 | 
			
		||||
	auto& exporters = GetExporterMap();
 | 
			
		||||
 | 
			
		||||
	if (currentExporter != "")
 | 
			
		||||
		return exporters[currentExporter];
 | 
			
		||||
| 
						 | 
				
			
			@ -193,3 +203,11 @@ ExternalFile::ExternalFile(fs::path nXmlPath, fs::path nOutPath)
 | 
			
		|||
	: xmlPath{nXmlPath}, outPath{nOutPath}
 | 
			
		||||
{
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
ExporterSet::~ExporterSet()
 | 
			
		||||
{
 | 
			
		||||
	for (auto& it : exporters)
 | 
			
		||||
	{
 | 
			
		||||
		delete it.second;
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -24,6 +24,8 @@ typedef void (*ExporterSetFuncVoid3)();
 | 
			
		|||
class ExporterSet
 | 
			
		||||
{
 | 
			
		||||
public:
 | 
			
		||||
	~ExporterSet();
 | 
			
		||||
 | 
			
		||||
	std::map<ZResourceType, ZResourceExporter*> exporters;
 | 
			
		||||
	ExporterSetFuncVoid parseArgsFunc = nullptr;
 | 
			
		||||
	ExporterSetFuncVoid2 parseFileModeFunc = nullptr;
 | 
			
		||||
| 
						 | 
				
			
			@ -64,10 +66,11 @@ public:
 | 
			
		|||
	std::map<uint32_t, std::string> symbolMap;
 | 
			
		||||
 | 
			
		||||
	std::string currentExporter;
 | 
			
		||||
	static std::map<std::string, ExporterSet*>* GetExporterMap();
 | 
			
		||||
	static std::map<std::string, ExporterSet*>& GetExporterMap();
 | 
			
		||||
	static void AddExporter(std::string exporterName, ExporterSet* exporterSet);
 | 
			
		||||
 | 
			
		||||
	Globals();
 | 
			
		||||
	~Globals();
 | 
			
		||||
 | 
			
		||||
	void AddSegment(int32_t segment, ZFile* file);
 | 
			
		||||
	bool HasSegment(int32_t segment);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -82,7 +82,7 @@ public:
 | 
			
		|||
	std::vector<PolygonEntry> polygons;
 | 
			
		||||
	std::vector<uint64_t> polygonTypes;
 | 
			
		||||
	std::vector<WaterBoxHeader> waterBoxes;
 | 
			
		||||
	CameraDataList* camData;
 | 
			
		||||
	CameraDataList* camData = nullptr;
 | 
			
		||||
 | 
			
		||||
	ZCollisionHeader(ZFile* nParent);
 | 
			
		||||
	~ZCollisionHeader();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -1836,15 +1836,9 @@ std::string ZDisplayList::GetSourceOutputCode(const std::string& prefix)
 | 
			
		|||
 | 
			
		||||
			std::string declaration;
 | 
			
		||||
 | 
			
		||||
			int32_t curAddr = vtxKeys[i];
 | 
			
		||||
 | 
			
		||||
			for (auto& vtx : item)
 | 
			
		||||
			{
 | 
			
		||||
				declaration += StringHelper::Sprintf("\t%s,\n", vtx.GetBodySourceCode().c_str());
 | 
			
		||||
 | 
			
		||||
				curAddr += 16;
 | 
			
		||||
			}
 | 
			
		||||
 | 
			
		||||
			// Ensure there's always a trailing line feed to prevent dumb warnings.
 | 
			
		||||
			// Please don't remove this line, unless you somehow made a way to prevent
 | 
			
		||||
			// that warning when building the OoT repo.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -5,13 +5,14 @@
 | 
			
		|||
#include <string_view>
 | 
			
		||||
#include <unordered_set>
 | 
			
		||||
 | 
			
		||||
#include <Utils/BinaryWriter.h>
 | 
			
		||||
#include <Utils/MemoryStream.h>
 | 
			
		||||
#include "Globals.h"
 | 
			
		||||
#include "OutputFormatter.h"
 | 
			
		||||
#include "Utils/BinaryWriter.h"
 | 
			
		||||
#include "Utils/Directory.h"
 | 
			
		||||
#include "Utils/File.h"
 | 
			
		||||
#include "Utils/MemoryStream.h"
 | 
			
		||||
#include "Utils/Path.h"
 | 
			
		||||
#include "Utils/StringHelper.h"
 | 
			
		||||
#include "ZAnimation.h"
 | 
			
		||||
#include "ZArray.h"
 | 
			
		||||
#include "ZBackground.h"
 | 
			
		||||
| 
						 | 
				
			
			@ -129,17 +130,47 @@ void ZFile::ParseXML(tinyxml2::XMLElement* reader, const std::string& filename)
 | 
			
		|||
	if (rangeStart > rangeEnd)
 | 
			
		||||
		throw std::runtime_error("Error: RangeStart must be before than RangeEnd.");
 | 
			
		||||
 | 
			
		||||
	// Not every XML may have a segment number, so this doesn't make much sense anymore.
 | 
			
		||||
	// if (reader->Attribute("Segment") == nullptr)
 | 
			
		||||
	// 	throw std::runtime_error(
 | 
			
		||||
	// 		StringHelper::Sprintf("ZFile::ParseXML: Error in '%s'.\n"
 | 
			
		||||
	// 	                          "\t Missing 'Segment' attribute in File node. \n",
 | 
			
		||||
	// 	                          name.c_str()));
 | 
			
		||||
 | 
			
		||||
	if (reader->Attribute("Segment") != nullptr)
 | 
			
		||||
	const char* segmentXml = reader->Attribute("Segment");
 | 
			
		||||
	if (segmentXml != nullptr)
 | 
			
		||||
	{
 | 
			
		||||
		segment = StringHelper::StrToL(reader->Attribute("Segment"), 10);
 | 
			
		||||
		Globals::Instance->AddSegment(segment, this);
 | 
			
		||||
		if (!StringHelper::HasOnlyDigits(segmentXml))
 | 
			
		||||
		{
 | 
			
		||||
			throw std::runtime_error(StringHelper::Sprintf(
 | 
			
		||||
				"error: Invalid segment value '%s': must be a decimal between 0 and 15 inclusive",
 | 
			
		||||
				segmentXml));
 | 
			
		||||
		}
 | 
			
		||||
 | 
			
		||||
		segment = StringHelper::StrToL(segmentXml, 10);
 | 
			
		||||
		if (segment > 15)
 | 
			
		||||
		{
 | 
			
		||||
			if (segment == 128)
 | 
			
		||||
			{
 | 
			
		||||
#ifdef DEPRECATION_ON
 | 
			
		||||
				fprintf(stderr, "warning: segment 128 is deprecated.\n\tRemove "
 | 
			
		||||
				                "'Segment=\"128\"' from the xml to use virtual addresses\n");
 | 
			
		||||
#endif
 | 
			
		||||
			}
 | 
			
		||||
			else
 | 
			
		||||
			{
 | 
			
		||||
				throw std::runtime_error(
 | 
			
		||||
					StringHelper::Sprintf("error: invalid segment value '%s': must be a decimal "
 | 
			
		||||
				                          "number between 0 and 15 inclusive",
 | 
			
		||||
				                          segmentXml));
 | 
			
		||||
			}
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
	Globals::Instance->AddSegment(segment, this);
 | 
			
		||||
 | 
			
		||||
	if (Globals::Instance->verbosity >= VerbosityLevel::VERBOSITY_INFO)
 | 
			
		||||
	{
 | 
			
		||||
		if (segment == 0x80)
 | 
			
		||||
		{
 | 
			
		||||
			printf("File '%s' using virtual addresses.\n", GetName().c_str());
 | 
			
		||||
		}
 | 
			
		||||
		else
 | 
			
		||||
		{
 | 
			
		||||
			printf("File '%s' using segment %X.\n", GetName().c_str(), segment);
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (mode == ZFileMode::Extract || mode == ZFileMode::ExternalFile)
 | 
			
		||||
| 
						 | 
				
			
			@ -938,6 +969,7 @@ std::string ZFile::ProcessDeclarations()
 | 
			
		|||
							lastItem.second->text += "\n" + curItem.second->text;
 | 
			
		||||
							declarations.erase(curItem.first);
 | 
			
		||||
							declarationKeys.erase(declarationKeys.begin() + i);
 | 
			
		||||
							delete curItem.second;
 | 
			
		||||
							i--;
 | 
			
		||||
							continue;
 | 
			
		||||
						}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -34,7 +34,9 @@ public:
 | 
			
		|||
	std::map<offset_t, Declaration*> declarations;
 | 
			
		||||
	std::string defines;
 | 
			
		||||
	std::vector<ZResource*> resources;
 | 
			
		||||
	uint32_t segment;
 | 
			
		||||
 | 
			
		||||
	// Default to using virtual addresses
 | 
			
		||||
	uint32_t segment = 0x80;
 | 
			
		||||
	uint32_t baseAddress, rangeStart, rangeEnd;
 | 
			
		||||
	bool isExternalFile = false;
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -209,6 +209,7 @@ class ZResourceExporter
 | 
			
		|||
{
 | 
			
		||||
public:
 | 
			
		||||
	ZResourceExporter() = default;
 | 
			
		||||
	virtual ~ZResourceExporter() = default;
 | 
			
		||||
 | 
			
		||||
	virtual void Save(ZResource* res, fs::path outPath, BinaryWriter* writer) = 0;
 | 
			
		||||
};
 | 
			
		||||
| 
						 | 
				
			
			@ -239,4 +240,4 @@ typedef ZResource*(ZResourceFactoryFunc)(ZFile* nParent);
 | 
			
		|||
	public:                                                                                        \
 | 
			
		||||
		ZResExp_##expFunc() { expFunc(); }                                                         \
 | 
			
		||||
	};                                                                                             \
 | 
			
		||||
	static ZResExp_##expFunc inst_ZResExp_##expFunc;
 | 
			
		||||
	static ZResExp_##expFunc inst_ZResExp_##expFunc
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -208,6 +208,7 @@ ZDisplayList* PolygonDlist::MakeDlist(segptr_t ptr, [[maybe_unused]] const std::
 | 
			
		|||
		parent->GetRawData(), dlistAddress,
 | 
			
		||||
		Globals::Instance->game == ZGame::OOT_SW97 ? DListType::F3DEX : DListType::F3DZEX);
 | 
			
		||||
	ZDisplayList* dlist = new ZDisplayList(parent);
 | 
			
		||||
	parent->AddResource(dlist);
 | 
			
		||||
	dlist->ExtractFromBinary(dlistAddress, dlistLength);
 | 
			
		||||
	dlist->SetName(dlist->GetDefaultName(prefix));
 | 
			
		||||
	GenDListDeclarations(zRoom, parent, dlist);
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -49,7 +49,11 @@ void ZSkeleton::ParseRawData()
 | 
			
		|||
	const auto& rawData = parent->GetRawData();
 | 
			
		||||
	limbsArrayAddress = BitConverter::ToUInt32BE(rawData, rawDataIndex);
 | 
			
		||||
	limbCount = BitConverter::ToUInt8BE(rawData, rawDataIndex + 4);
 | 
			
		||||
	dListCount = BitConverter::ToUInt8BE(rawData, rawDataIndex + 8);
 | 
			
		||||
 | 
			
		||||
	if (type == ZSkeletonType::Flex)
 | 
			
		||||
	{
 | 
			
		||||
		dListCount = BitConverter::ToUInt8BE(rawData, rawDataIndex + 8);
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if (limbsArrayAddress != 0 && GETSEGNUM(limbsArrayAddress) == parent->segment)
 | 
			
		||||
	{
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -98,7 +98,7 @@ This table summarizes if the asset will be marked `static` (✅) or not (❌)
 | 
			
		|||
 | 
			
		||||
  - `Name`: Required. The name of the file in `baserom/` which will be extracted.
 | 
			
		||||
  - `OutName`: Optional. The output name of the generated C source file. Defaults to the value passed to `Name`.
 | 
			
		||||
  - `Segment`: Required. This is the segment number of the current file. Expects a decimal number, usually 6 if it is an object, or 128 for overlays (It's kinda a whacky hack to get around of the `0x80` addresses).
 | 
			
		||||
  - `Segment`: Optional. This is the segment number of the current file. Expects a decimal number between 0 and 15 inclusive, usually 6 if it is an object. If not specified, the file will use VRAM instead of segmented addresses.
 | 
			
		||||
  - `BaseAddress`: Optional. RAM address of the file. Expects a hex number (with `0x` prefix). Default value: `0`.
 | 
			
		||||
  - `RangeStart`: Optional. File offset where the extraction will begin. Hex. Default value: `0x000000000`.
 | 
			
		||||
  - `RangeEnd`: Optional. File offset where the extraction will end. Hex. Default value: `0xFFFFFFFF`.
 | 
			
		||||
| 
						 | 
				
			
			@ -106,6 +106,27 @@ This table summarizes if the asset will be marked `static` (✅) or not (❌)
 | 
			
		|||
 | 
			
		||||
-------------------------
 | 
			
		||||
 | 
			
		||||
### ExternalFile
 | 
			
		||||
 | 
			
		||||
Allows ZAPD to map segmented addresses to variables declared in other files by using its XML.
 | 
			
		||||
 | 
			
		||||
It is useful for objects that use variables from `gameplay_keep`, `gameplay_dangeon_keep`, `gameplay_field_keep`, etc.
 | 
			
		||||
 | 
			
		||||
This tag can be used in the global `config.xml` file.
 | 
			
		||||
 | 
			
		||||
- Example of this tag:
 | 
			
		||||
 | 
			
		||||
```xml
 | 
			
		||||
<ExternalFile XmlPath="objects/gameplay_keep.xml" OutPath="objects/gameplay_keep/"/>
 | 
			
		||||
```
 | 
			
		||||
 | 
			
		||||
- Attributes:
 | 
			
		||||
 | 
			
		||||
  - `XmlPath`: Required. The path of the XML, relative to the value set by `ExternalXMLFolder` in the configuration file.
 | 
			
		||||
  - `OutPath`: Required. The path were the header for the corresponding external file is. It is used to `#include` it in the generated `.c` file.
 | 
			
		||||
 | 
			
		||||
-------------------------
 | 
			
		||||
 | 
			
		||||
### Texture
 | 
			
		||||
 | 
			
		||||
Textures are extracted as `.png` files.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue